]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/sha/sha512.c
SHA-224/-256/-384/-512 implementation. This is just sheer code commit.
[thirdparty/openssl.git] / crypto / sha / sha512.c
1 /* crypto/sha/sha512.c */
2 /* ====================================================================
3 * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
4 * ====================================================================
5 */
6 /*
7 * IMPLEMENTATION NOTES.
8 *
9 * As you might have noticed 32-bit hash algorithms:
10 *
11 * - permit SHA_LONG to be wider than 32-bit (case on CRAY);
12 * - optimized versions implement two transform functions: one operating
13 * on [aligned] data in host byte order and one - on data in input
14 * stream byte order;
15 * - share common byte-order neutral collector and padding function
16 * implementations, ../md32_common.h;
17 *
18 * Neither of the above applies to this SHA-512 implementations. Reasons
19 * [in reverse order] are:
20 *
21 * - it's the only 64-bit hash algorithm for the moment of this writing,
22 * there is no need for common collector/padding implementation [yet];
23 * - by supporting only one transform function [which operates on
24 * *aligned* data in input stream byte order, big-endian in this case]
25 * we minimize burden of maintenance in two ways: a) collector/padding
26 * function is simpler; b) only one transform function to stare at;
27 * - SHA_LONG64 is required to be exactly 64-bit in order to be able to
28 * apply a number of optimizations to mitigate potential performance
29 * penalties caused by previous design decision;
30 *
31 * Caveat lector.
32 *
33 * Implementation relies on the fact that "long long" is 64-bit on
34 * both 32- and 64-bit platforms. If some compiler vendor comes up
35 * with 128-bit long long, adjustment to sha.h would be required.
36 * As this implementation relies on 64-bit integer type, it's totally
37 * inappropriate for platforms which don't support it, most notably
38 * 16-bit platforms.
39 * <appro@fy.chalmers.se>
40 */
41 #include <stdlib.h>
42 #include <string.h>
43
44 #include <openssl/opensslconf.h>
45 #include <openssl/crypto.h>
46 #include <openssl/sha.h>
47 #include <openssl/opensslv.h>
48
49 const char *SHA512_version="SHA-512" OPENSSL_VERSION_PTEXT;
50
51 int SHA384_Init (SHA512_CTX *c)
52 {
53 c->h[0]=U64(0xcbbb9d5dc1059ed8);
54 c->h[1]=U64(0x629a292a367cd507);
55 c->h[2]=U64(0x9159015a3070dd17);
56 c->h[3]=U64(0x152fecd8f70e5939);
57 c->h[4]=U64(0x67332667ffc00b31);
58 c->h[5]=U64(0x8eb44a8768581511);
59 c->h[6]=U64(0xdb0c2e0d64f98fa7);
60 c->h[7]=U64(0x47b5481dbefa4fa4);
61 c->Nl=0; c->Nh=0;
62 c->num=0;
63 return 1;
64 }
65
66 int SHA512_Init (SHA512_CTX *c)
67 {
68 c->h[0]=U64(0x6a09e667f3bcc908);
69 c->h[1]=U64(0xbb67ae8584caa73b);
70 c->h[2]=U64(0x3c6ef372fe94f82b);
71 c->h[3]=U64(0xa54ff53a5f1d36f1);
72 c->h[4]=U64(0x510e527fade682d1);
73 c->h[5]=U64(0x9b05688c2b3e6c1f);
74 c->h[6]=U64(0x1f83d9abfb41bd6b);
75 c->h[7]=U64(0x5be0cd19137e2179);
76 c->Nl=0; c->Nh=0;
77 c->num=0;
78 return 1;
79 }
80
81 static void sha512_block (SHA512_CTX *ctx, const void *in, size_t num);
82
83 static int sha512_final (unsigned char *md, SHA512_CTX *c, size_t msz)
84 {
85 unsigned char *p=(unsigned char *)c->u.p;
86 size_t n=c->num;
87
88 p[n]=0x80;
89 n++;
90 if (n > (sizeof(c->u)-16))
91 memset (p+n,0,sizeof(c->u)-n), n=0,
92 sha512_block (c,p,1);
93
94 memset (p+n,0,sizeof(c->u)-16-n);
95 #ifdef B_ENDIAN
96 c->u.d[SHA_LBLOCK-2] = c->Nh;
97 c->u.d[SHA_LBLOCK-1] = c->Nl;
98 #else
99 p[sizeof(c->u)-1] = (c->Nl)&0xFF;
100 p[sizeof(c->u)-2] = (c->Nl>>8)&0xFF;
101 p[sizeof(c->u)-3] = (c->Nl>>16)&0xFF;
102 p[sizeof(c->u)-4] = (c->Nl>>24)&0xFF;
103 p[sizeof(c->u)-5] = (c->Nl>>32)&0xFF;
104 p[sizeof(c->u)-6] = (c->Nl>>40)&0xFF;
105 p[sizeof(c->u)-7] = (c->Nl>>48)&0xFF;
106 p[sizeof(c->u)-8] = (c->Nl>>56)&0xFF;
107 p[sizeof(c->u)-9] = (c->Nh)&0xFF;
108 p[sizeof(c->u)-10] = (c->Nh>>8)&0xFF;
109 p[sizeof(c->u)-11] = (c->Nh>>16)&0xFF;
110 p[sizeof(c->u)-12] = (c->Nh>>24)&0xFF;
111 p[sizeof(c->u)-13] = (c->Nh>>32)&0xFF;
112 p[sizeof(c->u)-14] = (c->Nh>>40)&0xFF;
113 p[sizeof(c->u)-15] = (c->Nh>>48)&0xFF;
114 p[sizeof(c->u)-16] = (c->Nh>>56)&0xFF;
115 #endif
116
117 sha512_block (c,p,1);
118
119 if (md==0) return 0;
120
121 for (n=0;msz>0;n++,msz-=8)
122 {
123 SHA_LONG64 t = c->h[n];
124
125 *(md++) = (t>>56)&0xFF; *(md++) = (t>>48)&0xFF;
126 *(md++) = (t>>40)&0xFF; *(md++) = (t>>32)&0xFF;
127 *(md++) = (t>>24)&0xFF; *(md++) = (t>>16)&0xFF;
128 *(md++) = (t>>8)&0xFF; *(md++) = (t)&0xFF;
129 }
130
131 return 1;
132 }
133
134 int SHA384_Final (unsigned char *md,SHA512_CTX *c)
135 { return sha512_final (md,c,SHA384_DIGEST_LENGTH); }
136 int SHA512_Final (unsigned char *md,SHA512_CTX *c)
137 { return sha512_final (md,c,SHA512_DIGEST_LENGTH); }
138
139 int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len)
140 {
141 SHA_LONG64 l;
142 unsigned char *p=c->u.p,*data=(unsigned char *)_data;
143
144 if (len==0) return 1;
145
146 l = (c->Nl+(((SHA_LONG64)len)<<3))&U64(0xffffffffffffffff);
147 if (l < c->Nl) c->Nh++;
148 if (sizeof(len)>=8) c->Nh+=(((SHA_LONG64)len)>>61);
149 c->Nl=l;
150
151 if (c->num != 0)
152 {
153 size_t n = sizeof(c->u) - c->num;
154
155 if (len < n)
156 {
157 memcpy (p+c->num,data,len), c->num += len;
158 return 1;
159 }
160 else {
161 memcpy (p+c->num,data,n), c->num = 0;
162 len-=n, data+=n;
163 sha512_block (c,p,1);
164 }
165 }
166
167 if (len >= sizeof(c->u))
168 {
169 #ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
170 if ((int)data%sizeof(c->u.d[0]) != 0)
171 while (len >= sizeof(c->u))
172 memcpy (p,data,sizeof(c->u)),
173 sha512_block (c,p,1),
174 len -= sizeof(c->u),
175 data += sizeof(c->u);
176 else
177 #endif
178 sha512_block (c,data,len/sizeof(c->u)),
179 data += len,
180 len %= sizeof(c->u),
181 data -= len;
182 }
183
184 if (len != 0) memcpy (p,data,len), c->num = (int)len;
185
186 return 1;
187 }
188
189 int SHA384_Update (SHA512_CTX *c, const void *data, size_t len)
190 { return SHA512_Update (c,data,len); }
191
192 void SHA512_Transform (SHA512_CTX *c, const unsigned char *data)
193 { sha512_block (c,data,1); }
194
195 unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md)
196 {
197 SHA512_CTX c;
198 static unsigned char m[SHA384_DIGEST_LENGTH];
199
200 if (md == NULL) md=m;
201 SHA384_Init(&c);
202 SHA512_Update(&c,d,n);
203 sha512_final(md,&c,sizeof(m));
204 OPENSSL_cleanse(&c,sizeof(c));
205 return(md);
206 }
207
208 unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md)
209 {
210 SHA512_CTX c;
211 static unsigned char m[SHA512_DIGEST_LENGTH];
212
213 if (md == NULL) md=m;
214 SHA512_Init(&c);
215 SHA512_Update(&c,d,n);
216 sha512_final(md,&c,sizeof(m));
217 OPENSSL_cleanse(&c,sizeof(c));
218 return(md);
219 }
220
221 static const SHA_LONG64 K512[80] = {
222 U64(0x428a2f98d728ae22),U64(0x7137449123ef65cd),
223 U64(0xb5c0fbcfec4d3b2f),U64(0xe9b5dba58189dbbc),
224 U64(0x3956c25bf348b538),U64(0x59f111f1b605d019),
225 U64(0x923f82a4af194f9b),U64(0xab1c5ed5da6d8118),
226 U64(0xd807aa98a3030242),U64(0x12835b0145706fbe),
227 U64(0x243185be4ee4b28c),U64(0x550c7dc3d5ffb4e2),
228 U64(0x72be5d74f27b896f),U64(0x80deb1fe3b1696b1),
229 U64(0x9bdc06a725c71235),U64(0xc19bf174cf692694),
230 U64(0xe49b69c19ef14ad2),U64(0xefbe4786384f25e3),
231 U64(0x0fc19dc68b8cd5b5),U64(0x240ca1cc77ac9c65),
232 U64(0x2de92c6f592b0275),U64(0x4a7484aa6ea6e483),
233 U64(0x5cb0a9dcbd41fbd4),U64(0x76f988da831153b5),
234 U64(0x983e5152ee66dfab),U64(0xa831c66d2db43210),
235 U64(0xb00327c898fb213f),U64(0xbf597fc7beef0ee4),
236 U64(0xc6e00bf33da88fc2),U64(0xd5a79147930aa725),
237 U64(0x06ca6351e003826f),U64(0x142929670a0e6e70),
238 U64(0x27b70a8546d22ffc),U64(0x2e1b21385c26c926),
239 U64(0x4d2c6dfc5ac42aed),U64(0x53380d139d95b3df),
240 U64(0x650a73548baf63de),U64(0x766a0abb3c77b2a8),
241 U64(0x81c2c92e47edaee6),U64(0x92722c851482353b),
242 U64(0xa2bfe8a14cf10364),U64(0xa81a664bbc423001),
243 U64(0xc24b8b70d0f89791),U64(0xc76c51a30654be30),
244 U64(0xd192e819d6ef5218),U64(0xd69906245565a910),
245 U64(0xf40e35855771202a),U64(0x106aa07032bbd1b8),
246 U64(0x19a4c116b8d2d0c8),U64(0x1e376c085141ab53),
247 U64(0x2748774cdf8eeb99),U64(0x34b0bcb5e19b48a8),
248 U64(0x391c0cb3c5c95a63),U64(0x4ed8aa4ae3418acb),
249 U64(0x5b9cca4f7763e373),U64(0x682e6ff3d6b2b8a3),
250 U64(0x748f82ee5defb2fc),U64(0x78a5636f43172f60),
251 U64(0x84c87814a1f0ab72),U64(0x8cc702081a6439ec),
252 U64(0x90befffa23631e28),U64(0xa4506cebde82bde9),
253 U64(0xbef9a3f7b2c67915),U64(0xc67178f2e372532b),
254 U64(0xca273eceea26619c),U64(0xd186b8c721c0c207),
255 U64(0xeada7dd6cde0eb1e),U64(0xf57d4f7fee6ed178),
256 U64(0x06f067aa72176fba),U64(0x0a637dc5a2c898a6),
257 U64(0x113f9804bef90dae),U64(0x1b710b35131c471b),
258 U64(0x28db77f523047d84),U64(0x32caab7b40c72493),
259 U64(0x3c9ebe0a15c9bebc),U64(0x431d67c49c100d4c),
260 U64(0x4cc5d4becb3e42b6),U64(0x597f299cfc657e2a),
261 U64(0x5fcb6fab3ad6faec),U64(0x6c44198c4a475817) };
262
263 #define B(x,j) (((SHA_LONG64)(*(((unsigned char *)(&x))+j)))<<((7-j)*8))
264 #define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7))
265
266 #define ROTR(x,s) (((x)>>s) | (x)<<(64-s))
267 #define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
268 #define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
269 #define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
270 #define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
271
272 #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
273 #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
274
275 #ifdef OPENSSL_SMALL_FOOTPRINT
276
277 static void sha512_block (SHA512_CTX *ctx, const void *in, size_t num)
278 {
279 const SHA_LONG64 *W=in;
280 SHA_LONG64 a,b,c,d,e,f,g,h,s0,s1,T1,T2;
281 SHA_LONG64 X[16];
282 int i;
283
284 while (num--) {
285
286 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
287 e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7];
288
289 for (i=0;i<16;i++)
290 {
291 #ifdef B_ENDIAN
292 T1 = X[i] = W[i];
293 #else
294 T1 = X[i] = PULL64(W[i]);
295 #endif
296 T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];
297 T2 = Sigma0(a) + Maj(a,b,c);
298 h = g; g = f; f = e; e = d + T1;
299 d = c; c = b; b = a; a = T1 + T2;
300 }
301
302 for (;i<80;i++)
303 {
304 s0 = X[(i+1)&0x0f]; s0 = sigma0(s0);
305 s1 = X[(i+14)&0x0f]; s1 = sigma1(s1);
306
307 T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf];
308 T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];
309 T2 = Sigma0(a) + Maj(a,b,c);
310 h = g; g = f; f = e; e = d + T1;
311 d = c; c = b; b = a; a = T1 + T2;
312 }
313
314 ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
315 ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;
316
317 }
318 }
319
320 #else
321
322 #define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \
323 T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; \
324 h = Sigma0(a) + Maj(a,b,c); \
325 d += T1; h += T1; } while (0)
326
327 #define ROUND_16_80(i,a,b,c,d,e,f,g,h,X) do { \
328 s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \
329 s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \
330 T1 = X[i&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \
331 ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0)
332
333 static void sha512_block (SHA512_CTX *ctx, const void *in, size_t num)
334 {
335 const SHA_LONG64 *W=in;
336 SHA_LONG64 a,b,c,d,e,f,g,h,s0,s1,T1;
337 SHA_LONG64 X[16];
338 int i;
339
340 while (num--) {
341
342 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
343 e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7];
344
345 #ifdef B_ENDIAN
346 T1 = X[0] = W[0]; ROUND_00_15(0,a,b,c,d,e,f,g,h);
347 T1 = X[1] = W[1]; ROUND_00_15(1,h,a,b,c,d,e,f,g);
348 T1 = X[2] = W[2]; ROUND_00_15(2,g,h,a,b,c,d,e,f);
349 T1 = X[3] = W[3]; ROUND_00_15(3,f,g,h,a,b,c,d,e);
350 T1 = X[4] = W[4]; ROUND_00_15(4,e,f,g,h,a,b,c,d);
351 T1 = X[5] = W[5]; ROUND_00_15(5,d,e,f,g,h,a,b,c);
352 T1 = X[6] = W[6]; ROUND_00_15(6,c,d,e,f,g,h,a,b);
353 T1 = X[7] = W[7]; ROUND_00_15(7,b,c,d,e,f,g,h,a);
354 T1 = X[8] = W[8]; ROUND_00_15(8,a,b,c,d,e,f,g,h);
355 T1 = X[9] = W[9]; ROUND_00_15(9,h,a,b,c,d,e,f,g);
356 T1 = X[10] = W[10]; ROUND_00_15(10,g,h,a,b,c,d,e,f);
357 T1 = X[11] = W[11]; ROUND_00_15(11,f,g,h,a,b,c,d,e);
358 T1 = X[12] = W[12]; ROUND_00_15(12,e,f,g,h,a,b,c,d);
359 T1 = X[13] = W[13]; ROUND_00_15(13,d,e,f,g,h,a,b,c);
360 T1 = X[14] = W[14]; ROUND_00_15(14,c,d,e,f,g,h,a,b);
361 T1 = X[15] = W[15]; ROUND_00_15(15,b,c,d,e,f,g,h,a);
362 #else
363 T1 = X[0] = PULL64(W[0]); ROUND_00_15(0,a,b,c,d,e,f,g,h);
364 T1 = X[1] = PULL64(W[1]); ROUND_00_15(1,h,a,b,c,d,e,f,g);
365 T1 = X[2] = PULL64(W[2]); ROUND_00_15(2,g,h,a,b,c,d,e,f);
366 T1 = X[3] = PULL64(W[3]); ROUND_00_15(3,f,g,h,a,b,c,d,e);
367 T1 = X[4] = PULL64(W[4]); ROUND_00_15(4,e,f,g,h,a,b,c,d);
368 T1 = X[5] = PULL64(W[5]); ROUND_00_15(5,d,e,f,g,h,a,b,c);
369 T1 = X[6] = PULL64(W[6]); ROUND_00_15(6,c,d,e,f,g,h,a,b);
370 T1 = X[7] = PULL64(W[7]); ROUND_00_15(7,b,c,d,e,f,g,h,a);
371 T1 = X[8] = PULL64(W[8]); ROUND_00_15(8,a,b,c,d,e,f,g,h);
372 T1 = X[9] = PULL64(W[9]); ROUND_00_15(9,h,a,b,c,d,e,f,g);
373 T1 = X[10] = PULL64(W[10]); ROUND_00_15(10,g,h,a,b,c,d,e,f);
374 T1 = X[11] = PULL64(W[11]); ROUND_00_15(11,f,g,h,a,b,c,d,e);
375 T1 = X[12] = PULL64(W[12]); ROUND_00_15(12,e,f,g,h,a,b,c,d);
376 T1 = X[13] = PULL64(W[13]); ROUND_00_15(13,d,e,f,g,h,a,b,c);
377 T1 = X[14] = PULL64(W[14]); ROUND_00_15(14,c,d,e,f,g,h,a,b);
378 T1 = X[15] = PULL64(W[15]); ROUND_00_15(15,b,c,d,e,f,g,h,a);
379 #endif
380
381 for (i=16;i<80;i+=8)
382 {
383 ROUND_16_80(i+0,a,b,c,d,e,f,g,h,X);
384 ROUND_16_80(i+1,h,a,b,c,d,e,f,g,X);
385 ROUND_16_80(i+2,g,h,a,b,c,d,e,f,X);
386 ROUND_16_80(i+3,f,g,h,a,b,c,d,e,X);
387 ROUND_16_80(i+4,e,f,g,h,a,b,c,d,X);
388 ROUND_16_80(i+5,d,e,f,g,h,a,b,c,X);
389 ROUND_16_80(i+6,c,d,e,f,g,h,a,b,X);
390 ROUND_16_80(i+7,b,c,d,e,f,g,h,a,X);
391 }
392
393 ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
394 ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;
395
396 }
397 }
398
399 #endif