Blame view

crypto/sha512_generic.c 7.99 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
  /* SHA-512 code by Jean-Luc Cooke <jlcooke@certainkey.com>
   *
   * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
   * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
   * Copyright (c) 2003 Kyle McMartin <kyle@debian.org>
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the
   * Free Software Foundation; either version 2, or (at your option) any
   * later version.
   *
   */
bd9d20dba   Adrian-Ken Rueegsegger   crypto: sha512 - ...
13
  #include <crypto/internal/hash.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
  #include <linux/kernel.h>
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
18
  #include <linux/mm.h>
  #include <linux/init.h>
  #include <linux/crypto.h>
06ace7a9b   Herbert Xu   [CRYPTO] Use stan...
19
  #include <linux/types.h>
5265eeb2b   Jan Glauber   [CRYPTO] sha: Add...
20
  #include <crypto/sha.h>
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
21
  #include <crypto/sha512_base.h>
f9e2bca6c   Adrian-Ken Rueegsegger   crypto: sha512 - ...
22
  #include <linux/percpu.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
  #include <asm/byteorder.h>
be34c4ef6   David S. Miller   crypto: sha - Han...
24
  #include <asm/unaligned.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25

26f7120b8   Antoine Tenart   crypto: sha512_ge...
26
27
28
29
30
31
32
33
34
  const u8 sha384_zero_message_hash[SHA384_DIGEST_SIZE] = {
  	0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38,
  	0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a,
  	0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43,
  	0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda,
  	0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
  	0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b
  };
  EXPORT_SYMBOL_GPL(sha384_zero_message_hash);
30c217ef6   Antoine Tenart   crypto: sha512_ge...
35
36
37
38
39
40
41
42
43
44
45
  const u8 sha512_zero_message_hash[SHA512_DIGEST_SIZE] = {
  	0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
  	0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
  	0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
  	0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
  	0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
  	0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
  	0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
  	0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e
  };
  EXPORT_SYMBOL_GPL(sha512_zero_message_hash);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
49
50
51
52
53
54
  static inline u64 Ch(u64 x, u64 y, u64 z)
  {
          return z ^ (x & (y ^ z));
  }
  
  static inline u64 Maj(u64 x, u64 y, u64 z)
  {
          return (x & y) | (z & (x | y));
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
  static const u64 sha512_K[80] = {
          0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
          0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
          0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
          0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
          0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
          0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
          0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
          0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
          0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
          0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
          0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
          0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
          0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
          0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
          0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
          0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
          0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
          0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
          0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
          0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
          0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
          0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
          0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
          0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
          0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
          0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
          0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
  };
f2ea0f5f0   Alexey Dobriyan   crypto: sha512 - ...
84
85
86
87
  #define e0(x)       (ror64(x,28) ^ ror64(x,34) ^ ror64(x,39))
  #define e1(x)       (ror64(x,14) ^ ror64(x,18) ^ ror64(x,41))
  #define s0(x)       (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
  #define s1(x)       (ror64(x,19) ^ ror64(x,61) ^ (x >> 6))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
  static inline void LOAD_OP(int I, u64 *W, const u8 *input)
  {
be34c4ef6   David S. Miller   crypto: sha - Han...
91
  	W[I] = get_unaligned_be64((__u64 *)input + I);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
93
94
95
  }
  
  static inline void BLEND_OP(int I, u64 *W)
  {
58d7d18b5   Herbert Xu   crypto: sha512 - ...
96
  	W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
  }
  
  static void
f9e2bca6c   Adrian-Ken Rueegsegger   crypto: sha512 - ...
100
  sha512_transform(u64 *state, const u8 *input)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
  {
  	u64 a, b, c, d, e, f, g, h, t1, t2;
  
  	int i;
51fc6dc8f   Alexey Dobriyan   crypto: sha512 - ...
105
  	u64 W[16];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
  	/* load the state into our registers */
78f8b3a24   Jan Glauber   [CRYPTO] sha512: ...
108
109
  	a=state[0];   b=state[1];   c=state[2];   d=state[3];
  	e=state[4];   f=state[5];   g=state[6];   h=state[7];
3a92d687c   Herbert Xu   crypto: sha512 - ...
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  	/* now iterate */
  	for (i=0; i<80; i+=8) {
  		if (!(i & 8)) {
  			int j;
  
  			if (i < 16) {
  				/* load the input */
  				for (j = 0; j < 16; j++)
  					LOAD_OP(i + j, W, input);
  			} else {
  				for (j = 0; j < 16; j++) {
  					BLEND_OP(i + j, W);
  				}
  			}
  		}
  
  		t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i  ] + W[(i & 15)];
  		t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
  		t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[(i & 15) + 1];
  		t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
  		t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[(i & 15) + 2];
  		t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
  		t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[(i & 15) + 3];
  		t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
  		t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[(i & 15) + 4];
  		t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
  		t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[(i & 15) + 5];
  		t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
  		t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[(i & 15) + 6];
  		t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
  		t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[(i & 15) + 7];
  		t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
  	}
78f8b3a24   Jan Glauber   [CRYPTO] sha512: ...
143
144
145
  
  	state[0] += a; state[1] += b; state[2] += c; state[3] += d;
  	state[4] += e; state[5] += f; state[6] += g; state[7] += h;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
147
148
149
  
  	/* erase our data */
  	a = b = c = d = e = f = g = h = t1 = t2 = 0;
  }
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
150
151
  static void sha512_generic_block_fn(struct sha512_state *sst, u8 const *src,
  				    int blocks)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
  {
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
153
154
155
156
  	while (blocks--) {
  		sha512_transform(sst->state, src);
  		src += SHA512_BLOCK_SIZE;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  }
bf70fa9d9   Tim Chen   crypto: sha512 - ...
158
159
  int crypto_sha512_update(struct shash_desc *desc, const u8 *data,
  			unsigned int len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
  {
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
161
  	return sha512_base_do_update(desc, data, len, sha512_generic_block_fn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
  }
bf70fa9d9   Tim Chen   crypto: sha512 - ...
163
  EXPORT_SYMBOL(crypto_sha512_update);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164

ca142584b   Ard Biesheuvel   crypto: sha512-ge...
165
  static int sha512_final(struct shash_desc *desc, u8 *hash)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
  {
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
167
168
  	sha512_base_do_finalize(desc, sha512_generic_block_fn);
  	return sha512_base_finish(desc, hash);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
  }
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
170
171
  int crypto_sha512_finup(struct shash_desc *desc, const u8 *data,
  			unsigned int len, u8 *hash)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
  {
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
173
174
  	sha512_base_do_update(desc, data, len, sha512_generic_block_fn);
  	return sha512_final(desc, hash);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
  }
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
176
  EXPORT_SYMBOL(crypto_sha512_finup);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177

648b2a102   Jussi Kivilinna   crypto: sha512 - ...
178
  static struct shash_alg sha512_algs[2] = { {
bd9d20dba   Adrian-Ken Rueegsegger   crypto: sha512 - ...
179
  	.digestsize	=	SHA512_DIGEST_SIZE,
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
180
  	.init		=	sha512_base_init,
bf70fa9d9   Tim Chen   crypto: sha512 - ...
181
  	.update		=	crypto_sha512_update,
bd9d20dba   Adrian-Ken Rueegsegger   crypto: sha512 - ...
182
  	.final		=	sha512_final,
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
183
  	.finup		=	crypto_sha512_finup,
1f38ad838   Herbert Xu   crypto: sha512 - ...
184
  	.descsize	=	sizeof(struct sha512_state),
bd9d20dba   Adrian-Ken Rueegsegger   crypto: sha512 - ...
185
186
  	.base		=	{
  		.cra_name	=	"sha512",
d32958149   Jussi Kivilinna   crypto: sha512_ge...
187
  		.cra_driver_name =	"sha512-generic",
e47890163   Eric Biggers   crypto: sha512_ge...
188
  		.cra_priority	=	100,
bd9d20dba   Adrian-Ken Rueegsegger   crypto: sha512 - ...
189
190
191
  		.cra_blocksize	=	SHA512_BLOCK_SIZE,
  		.cra_module	=	THIS_MODULE,
  	}
648b2a102   Jussi Kivilinna   crypto: sha512 - ...
192
  }, {
bd9d20dba   Adrian-Ken Rueegsegger   crypto: sha512 - ...
193
  	.digestsize	=	SHA384_DIGEST_SIZE,
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
194
  	.init		=	sha384_base_init,
bf70fa9d9   Tim Chen   crypto: sha512 - ...
195
  	.update		=	crypto_sha512_update,
ca142584b   Ard Biesheuvel   crypto: sha512-ge...
196
197
  	.final		=	sha512_final,
  	.finup		=	crypto_sha512_finup,
1f38ad838   Herbert Xu   crypto: sha512 - ...
198
  	.descsize	=	sizeof(struct sha512_state),
bd9d20dba   Adrian-Ken Rueegsegger   crypto: sha512 - ...
199
200
  	.base		=	{
  		.cra_name	=	"sha384",
d32958149   Jussi Kivilinna   crypto: sha512_ge...
201
  		.cra_driver_name =	"sha384-generic",
e47890163   Eric Biggers   crypto: sha512_ge...
202
  		.cra_priority	=	100,
bd9d20dba   Adrian-Ken Rueegsegger   crypto: sha512 - ...
203
204
205
  		.cra_blocksize	=	SHA384_BLOCK_SIZE,
  		.cra_module	=	THIS_MODULE,
  	}
648b2a102   Jussi Kivilinna   crypto: sha512 - ...
206
  } };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207

3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
208
  static int __init sha512_generic_mod_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
  {
648b2a102   Jussi Kivilinna   crypto: sha512 - ...
210
  	return crypto_register_shashes(sha512_algs, ARRAY_SIZE(sha512_algs));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
  }
3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
212
  static void __exit sha512_generic_mod_fini(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
  {
648b2a102   Jussi Kivilinna   crypto: sha512 - ...
214
  	crypto_unregister_shashes(sha512_algs, ARRAY_SIZE(sha512_algs));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
  }
3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
216
217
  module_init(sha512_generic_mod_init);
  module_exit(sha512_generic_mod_fini);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
219
220
  
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms");
78f8b3a24   Jan Glauber   [CRYPTO] sha512: ...
221

5d26a105b   Kees Cook   crypto: prefix mo...
222
  MODULE_ALIAS_CRYPTO("sha384");
3e14dcf7c   Mathias Krause   crypto: add missi...
223
  MODULE_ALIAS_CRYPTO("sha384-generic");
5d26a105b   Kees Cook   crypto: prefix mo...
224
  MODULE_ALIAS_CRYPTO("sha512");
3e14dcf7c   Mathias Krause   crypto: add missi...
225
  MODULE_ALIAS_CRYPTO("sha512-generic");