0001
0002
0003
0004
0005
0006
0007
0008 #include <crypto/internal/hash.h>
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/mm.h>
0012 #include <linux/init.h>
0013 #include <linux/crypto.h>
0014 #include <linux/types.h>
0015 #include <crypto/sha2.h>
0016 #include <crypto/sha512_base.h>
0017 #include <linux/percpu.h>
0018 #include <asm/byteorder.h>
0019 #include <asm/unaligned.h>
0020
0021 const u8 sha384_zero_message_hash[SHA384_DIGEST_SIZE] = {
0022 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38,
0023 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a,
0024 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43,
0025 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda,
0026 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
0027 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b
0028 };
0029 EXPORT_SYMBOL_GPL(sha384_zero_message_hash);
0030
0031 const u8 sha512_zero_message_hash[SHA512_DIGEST_SIZE] = {
0032 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
0033 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
0034 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
0035 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
0036 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
0037 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
0038 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
0039 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e
0040 };
0041 EXPORT_SYMBOL_GPL(sha512_zero_message_hash);
0042
0043 static inline u64 Ch(u64 x, u64 y, u64 z)
0044 {
0045 return z ^ (x & (y ^ z));
0046 }
0047
0048 static inline u64 Maj(u64 x, u64 y, u64 z)
0049 {
0050 return (x & y) | (z & (x | y));
0051 }
0052
0053 static const u64 sha512_K[80] = {
0054 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
0055 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0056 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
0057 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0058 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
0059 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0060 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
0061 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0062 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
0063 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0064 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
0065 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0066 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
0067 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
0068 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
0069 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0070 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
0071 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0072 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
0073 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0074 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
0075 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
0076 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
0077 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0078 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
0079 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
0080 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
0081 };
0082
0083 #define e0(x) (ror64(x,28) ^ ror64(x,34) ^ ror64(x,39))
0084 #define e1(x) (ror64(x,14) ^ ror64(x,18) ^ ror64(x,41))
0085 #define s0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
0086 #define s1(x) (ror64(x,19) ^ ror64(x,61) ^ (x >> 6))
0087
0088 static inline void LOAD_OP(int I, u64 *W, const u8 *input)
0089 {
0090 W[I] = get_unaligned_be64((__u64 *)input + I);
0091 }
0092
0093 static inline void BLEND_OP(int I, u64 *W)
0094 {
0095 W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]);
0096 }
0097
0098 static void
0099 sha512_transform(u64 *state, const u8 *input)
0100 {
0101 u64 a, b, c, d, e, f, g, h, t1, t2;
0102
0103 int i;
0104 u64 W[16];
0105
0106
0107 a=state[0]; b=state[1]; c=state[2]; d=state[3];
0108 e=state[4]; f=state[5]; g=state[6]; h=state[7];
0109
0110
0111 for (i=0; i<80; i+=8) {
0112 if (!(i & 8)) {
0113 int j;
0114
0115 if (i < 16) {
0116
0117 for (j = 0; j < 16; j++)
0118 LOAD_OP(i + j, W, input);
0119 } else {
0120 for (j = 0; j < 16; j++) {
0121 BLEND_OP(i + j, W);
0122 }
0123 }
0124 }
0125
0126 t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[(i & 15)];
0127 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
0128 t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[(i & 15) + 1];
0129 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
0130 t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[(i & 15) + 2];
0131 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
0132 t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[(i & 15) + 3];
0133 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
0134 t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[(i & 15) + 4];
0135 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
0136 t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[(i & 15) + 5];
0137 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
0138 t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[(i & 15) + 6];
0139 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
0140 t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[(i & 15) + 7];
0141 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
0142 }
0143
0144 state[0] += a; state[1] += b; state[2] += c; state[3] += d;
0145 state[4] += e; state[5] += f; state[6] += g; state[7] += h;
0146 }
0147
0148 static void sha512_generic_block_fn(struct sha512_state *sst, u8 const *src,
0149 int blocks)
0150 {
0151 while (blocks--) {
0152 sha512_transform(sst->state, src);
0153 src += SHA512_BLOCK_SIZE;
0154 }
0155 }
0156
0157 int crypto_sha512_update(struct shash_desc *desc, const u8 *data,
0158 unsigned int len)
0159 {
0160 return sha512_base_do_update(desc, data, len, sha512_generic_block_fn);
0161 }
0162 EXPORT_SYMBOL(crypto_sha512_update);
0163
0164 static int sha512_final(struct shash_desc *desc, u8 *hash)
0165 {
0166 sha512_base_do_finalize(desc, sha512_generic_block_fn);
0167 return sha512_base_finish(desc, hash);
0168 }
0169
0170 int crypto_sha512_finup(struct shash_desc *desc, const u8 *data,
0171 unsigned int len, u8 *hash)
0172 {
0173 sha512_base_do_update(desc, data, len, sha512_generic_block_fn);
0174 return sha512_final(desc, hash);
0175 }
0176 EXPORT_SYMBOL(crypto_sha512_finup);
0177
0178 static struct shash_alg sha512_algs[2] = { {
0179 .digestsize = SHA512_DIGEST_SIZE,
0180 .init = sha512_base_init,
0181 .update = crypto_sha512_update,
0182 .final = sha512_final,
0183 .finup = crypto_sha512_finup,
0184 .descsize = sizeof(struct sha512_state),
0185 .base = {
0186 .cra_name = "sha512",
0187 .cra_driver_name = "sha512-generic",
0188 .cra_priority = 100,
0189 .cra_blocksize = SHA512_BLOCK_SIZE,
0190 .cra_module = THIS_MODULE,
0191 }
0192 }, {
0193 .digestsize = SHA384_DIGEST_SIZE,
0194 .init = sha384_base_init,
0195 .update = crypto_sha512_update,
0196 .final = sha512_final,
0197 .finup = crypto_sha512_finup,
0198 .descsize = sizeof(struct sha512_state),
0199 .base = {
0200 .cra_name = "sha384",
0201 .cra_driver_name = "sha384-generic",
0202 .cra_priority = 100,
0203 .cra_blocksize = SHA384_BLOCK_SIZE,
0204 .cra_module = THIS_MODULE,
0205 }
0206 } };
0207
0208 static int __init sha512_generic_mod_init(void)
0209 {
0210 return crypto_register_shashes(sha512_algs, ARRAY_SIZE(sha512_algs));
0211 }
0212
0213 static void __exit sha512_generic_mod_fini(void)
0214 {
0215 crypto_unregister_shashes(sha512_algs, ARRAY_SIZE(sha512_algs));
0216 }
0217
0218 subsys_initcall(sha512_generic_mod_init);
0219 module_exit(sha512_generic_mod_fini);
0220
0221 MODULE_LICENSE("GPL");
0222 MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms");
0223
0224 MODULE_ALIAS_CRYPTO("sha384");
0225 MODULE_ALIAS_CRYPTO("sha384-generic");
0226 MODULE_ALIAS_CRYPTO("sha512");
0227 MODULE_ALIAS_CRYPTO("sha512-generic");