summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/sha/sha512.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/sha/sha512.c')
-rw-r--r--src/lib/libcrypto/sha/sha512.c184
1 files changed, 139 insertions, 45 deletions
diff --git a/src/lib/libcrypto/sha/sha512.c b/src/lib/libcrypto/sha/sha512.c
index f5ed468b85..cbc0e58c48 100644
--- a/src/lib/libcrypto/sha/sha512.c
+++ b/src/lib/libcrypto/sha/sha512.c
@@ -5,10 +5,6 @@
5 * ==================================================================== 5 * ====================================================================
6 */ 6 */
7#include <openssl/opensslconf.h> 7#include <openssl/opensslconf.h>
8#ifdef OPENSSL_FIPS
9#include <openssl/fips.h>
10#endif
11
12#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) 8#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
13/* 9/*
14 * IMPLEMENTATION NOTES. 10 * IMPLEMENTATION NOTES.
@@ -65,9 +61,19 @@ const char SHA512_version[]="SHA-512" OPENSSL_VERSION_PTEXT;
65 61
66int SHA384_Init (SHA512_CTX *c) 62int SHA384_Init (SHA512_CTX *c)
67 { 63 {
68#ifdef OPENSSL_FIPS 64#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
69 FIPS_selftest_check(); 65 /* maintain dword order required by assembler module */
70#endif 66 unsigned int *h = (unsigned int *)c->h;
67
68 h[0] = 0xcbbb9d5d; h[1] = 0xc1059ed8;
69 h[2] = 0x629a292a; h[3] = 0x367cd507;
70 h[4] = 0x9159015a; h[5] = 0x3070dd17;
71 h[6] = 0x152fecd8; h[7] = 0xf70e5939;
72 h[8] = 0x67332667; h[9] = 0xffc00b31;
73 h[10] = 0x8eb44a87; h[11] = 0x68581511;
74 h[12] = 0xdb0c2e0d; h[13] = 0x64f98fa7;
75 h[14] = 0x47b5481d; h[15] = 0xbefa4fa4;
76#else
71 c->h[0]=U64(0xcbbb9d5dc1059ed8); 77 c->h[0]=U64(0xcbbb9d5dc1059ed8);
72 c->h[1]=U64(0x629a292a367cd507); 78 c->h[1]=U64(0x629a292a367cd507);
73 c->h[2]=U64(0x9159015a3070dd17); 79 c->h[2]=U64(0x9159015a3070dd17);
@@ -76,6 +82,7 @@ int SHA384_Init (SHA512_CTX *c)
76 c->h[5]=U64(0x8eb44a8768581511); 82 c->h[5]=U64(0x8eb44a8768581511);
77 c->h[6]=U64(0xdb0c2e0d64f98fa7); 83 c->h[6]=U64(0xdb0c2e0d64f98fa7);
78 c->h[7]=U64(0x47b5481dbefa4fa4); 84 c->h[7]=U64(0x47b5481dbefa4fa4);
85#endif
79 c->Nl=0; c->Nh=0; 86 c->Nl=0; c->Nh=0;
80 c->num=0; c->md_len=SHA384_DIGEST_LENGTH; 87 c->num=0; c->md_len=SHA384_DIGEST_LENGTH;
81 return 1; 88 return 1;
@@ -83,9 +90,19 @@ int SHA384_Init (SHA512_CTX *c)
83 90
84int SHA512_Init (SHA512_CTX *c) 91int SHA512_Init (SHA512_CTX *c)
85 { 92 {
86#ifdef OPENSSL_FIPS 93#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
87 FIPS_selftest_check(); 94 /* maintain dword order required by assembler module */
88#endif 95 unsigned int *h = (unsigned int *)c->h;
96
97 h[0] = 0x6a09e667; h[1] = 0xf3bcc908;
98 h[2] = 0xbb67ae85; h[3] = 0x84caa73b;
99 h[4] = 0x3c6ef372; h[5] = 0xfe94f82b;
100 h[6] = 0xa54ff53a; h[7] = 0x5f1d36f1;
101 h[8] = 0x510e527f; h[9] = 0xade682d1;
102 h[10] = 0x9b05688c; h[11] = 0x2b3e6c1f;
103 h[12] = 0x1f83d9ab; h[13] = 0xfb41bd6b;
104 h[14] = 0x5be0cd19; h[15] = 0x137e2179;
105#else
89 c->h[0]=U64(0x6a09e667f3bcc908); 106 c->h[0]=U64(0x6a09e667f3bcc908);
90 c->h[1]=U64(0xbb67ae8584caa73b); 107 c->h[1]=U64(0xbb67ae8584caa73b);
91 c->h[2]=U64(0x3c6ef372fe94f82b); 108 c->h[2]=U64(0x3c6ef372fe94f82b);
@@ -94,6 +111,7 @@ int SHA512_Init (SHA512_CTX *c)
94 c->h[5]=U64(0x9b05688c2b3e6c1f); 111 c->h[5]=U64(0x9b05688c2b3e6c1f);
95 c->h[6]=U64(0x1f83d9abfb41bd6b); 112 c->h[6]=U64(0x1f83d9abfb41bd6b);
96 c->h[7]=U64(0x5be0cd19137e2179); 113 c->h[7]=U64(0x5be0cd19137e2179);
114#endif
97 c->Nl=0; c->Nh=0; 115 c->Nl=0; c->Nh=0;
98 c->num=0; c->md_len=SHA512_DIGEST_LENGTH; 116 c->num=0; c->md_len=SHA512_DIGEST_LENGTH;
99 return 1; 117 return 1;
@@ -142,6 +160,24 @@ int SHA512_Final (unsigned char *md, SHA512_CTX *c)
142 160
143 if (md==0) return 0; 161 if (md==0) return 0;
144 162
163#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
164 /* recall assembler dword order... */
165 n = c->md_len;
166 if (n == SHA384_DIGEST_LENGTH || n == SHA512_DIGEST_LENGTH)
167 {
168 unsigned int *h = (unsigned int *)c->h, t;
169
170 for (n/=4;n;n--)
171 {
172 t = *(h++);
173 *(md++) = (unsigned char)(t>>24);
174 *(md++) = (unsigned char)(t>>16);
175 *(md++) = (unsigned char)(t>>8);
176 *(md++) = (unsigned char)(t);
177 }
178 }
179 else return 0;
180#else
145 switch (c->md_len) 181 switch (c->md_len)
146 { 182 {
147 /* Let compiler decide if it's appropriate to unroll... */ 183 /* Let compiler decide if it's appropriate to unroll... */
@@ -178,7 +214,7 @@ int SHA512_Final (unsigned char *md, SHA512_CTX *c)
178 /* ... as well as make sure md_len is not abused. */ 214 /* ... as well as make sure md_len is not abused. */
179 default: return 0; 215 default: return 0;
180 } 216 }
181 217#endif
182 return 1; 218 return 1;
183 } 219 }
184 220
@@ -204,7 +240,7 @@ int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len)
204 240
205 if (len < n) 241 if (len < n)
206 { 242 {
207 memcpy (p+c->num,data,len), c->num += len; 243 memcpy (p+c->num,data,len), c->num += (unsigned int)len;
208 return 1; 244 return 1;
209 } 245 }
210 else { 246 else {
@@ -314,7 +350,7 @@ static const SHA_LONG64 K512[80] = {
314#ifndef PEDANTIC 350#ifndef PEDANTIC
315# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 351# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
316# if defined(__x86_64) || defined(__x86_64__) 352# if defined(__x86_64) || defined(__x86_64__)
317# define ROTR(a,n) ({ unsigned long ret; \ 353# define ROTR(a,n) ({ SHA_LONG64 ret; \
318 asm ("rorq %1,%0" \ 354 asm ("rorq %1,%0" \
319 : "=r"(ret) \ 355 : "=r"(ret) \
320 : "J"(n),"0"(a) \ 356 : "J"(n),"0"(a) \
@@ -337,20 +373,21 @@ static const SHA_LONG64 K512[80] = {
337 ((SHA_LONG64)hi)<<32|lo; }) 373 ((SHA_LONG64)hi)<<32|lo; })
338# else 374# else
339# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ 375# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
340 unsigned int hi=p[0],lo=p[1]; \ 376 unsigned int hi=p[0],lo=p[1]; \
341 asm ("bswapl %0; bswapl %1;" \ 377 asm ("bswapl %0; bswapl %1;" \
342 : "=r"(lo),"=r"(hi) \ 378 : "=r"(lo),"=r"(hi) \
343 : "0"(lo),"1"(hi)); \ 379 : "0"(lo),"1"(hi)); \
344 ((SHA_LONG64)hi)<<32|lo; }) 380 ((SHA_LONG64)hi)<<32|lo; })
345# endif 381# endif
346# elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) 382# elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
347# define ROTR(a,n) ({ unsigned long ret; \ 383# define ROTR(a,n) ({ SHA_LONG64 ret; \
348 asm ("rotrdi %0,%1,%2" \ 384 asm ("rotrdi %0,%1,%2" \
349 : "=r"(ret) \ 385 : "=r"(ret) \
350 : "r"(a),"K"(n)); ret; }) 386 : "r"(a),"K"(n)); ret; })
351# endif 387# endif
352# elif defined(_MSC_VER) 388# elif defined(_MSC_VER)
353# if defined(_WIN64) /* applies to both IA-64 and AMD64 */ 389# if defined(_WIN64) /* applies to both IA-64 and AMD64 */
390# pragma intrinsic(_rotr64)
354# define ROTR(a,n) _rotr64((a),n) 391# define ROTR(a,n) _rotr64((a),n)
355# endif 392# endif
356# if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 393# if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
@@ -398,15 +435,66 @@ static const SHA_LONG64 K512[80] = {
398#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) 435#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
399#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 436#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
400 437
401#if defined(OPENSSL_IA32_SSE2) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) 438
402#define GO_FOR_SSE2(ctx,in,num) do { \ 439#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
403 void sha512_block_sse2(void *,const void *,size_t); \ 440/*
404 if (!(OPENSSL_ia32cap_P & (1<<26))) break; \ 441 * This code should give better results on 32-bit CPU with less than
405 sha512_block_sse2(ctx->h,in,num); return; \ 442 * ~24 registers, both size and performance wise...
406 } while (0) 443 */
444static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
445 {
446 const SHA_LONG64 *W=in;
447 SHA_LONG64 A,E,T;
448 SHA_LONG64 X[9+80],*F;
449 int i;
450
451 while (num--) {
452
453 F = X+80;
454 A = ctx->h[0]; F[1] = ctx->h[1];
455 F[2] = ctx->h[2]; F[3] = ctx->h[3];
456 E = ctx->h[4]; F[5] = ctx->h[5];
457 F[6] = ctx->h[6]; F[7] = ctx->h[7];
458
459 for (i=0;i<16;i++,F--)
460 {
461#ifdef B_ENDIAN
462 T = W[i];
463#else
464 T = PULL64(W[i]);
407#endif 465#endif
466 F[0] = A;
467 F[4] = E;
468 F[8] = T;
469 T += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
470 E = F[3] + T;
471 A = T + Sigma0(A) + Maj(A,F[1],F[2]);
472 }
473
474 for (;i<80;i++,F--)
475 {
476 T = sigma0(F[8+16-1]);
477 T += sigma1(F[8+16-14]);
478 T += F[8+16] + F[8+16-9];
479
480 F[0] = A;
481 F[4] = E;
482 F[8] = T;
483 T += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
484 E = F[3] + T;
485 A = T + Sigma0(A) + Maj(A,F[1],F[2]);
486 }
408 487
409#ifdef OPENSSL_SMALL_FOOTPRINT 488 ctx->h[0] += A; ctx->h[1] += F[1];
489 ctx->h[2] += F[2]; ctx->h[3] += F[3];
490 ctx->h[4] += E; ctx->h[5] += F[5];
491 ctx->h[6] += F[6]; ctx->h[7] += F[7];
492
493 W+=SHA_LBLOCK;
494 }
495 }
496
497#elif defined(OPENSSL_SMALL_FOOTPRINT)
410 498
411static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) 499static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
412 { 500 {
@@ -415,10 +503,6 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num
415 SHA_LONG64 X[16]; 503 SHA_LONG64 X[16];
416 int i; 504 int i;
417 505
418#ifdef GO_FOR_SSE2
419 GO_FOR_SSE2(ctx,in,num);
420#endif
421
422 while (num--) { 506 while (num--) {
423 507
424 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; 508 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
@@ -463,11 +547,11 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num
463 h = Sigma0(a) + Maj(a,b,c); \ 547 h = Sigma0(a) + Maj(a,b,c); \
464 d += T1; h += T1; } while (0) 548 d += T1; h += T1; } while (0)
465 549
466#define ROUND_16_80(i,a,b,c,d,e,f,g,h,X) do { \ 550#define ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X) do { \
467 s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ 551 s0 = X[(j+1)&0x0f]; s0 = sigma0(s0); \
468 s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ 552 s1 = X[(j+14)&0x0f]; s1 = sigma1(s1); \
469 T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ 553 T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f]; \
470 ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) 554 ROUND_00_15(i+j,a,b,c,d,e,f,g,h); } while (0)
471 555
472static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) 556static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
473 { 557 {
@@ -476,10 +560,6 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num
476 SHA_LONG64 X[16]; 560 SHA_LONG64 X[16];
477 int i; 561 int i;
478 562
479#ifdef GO_FOR_SSE2
480 GO_FOR_SSE2(ctx,in,num);
481#endif
482
483 while (num--) { 563 while (num--) {
484 564
485 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; 565 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
@@ -521,16 +601,24 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num
521 T1 = X[15] = PULL64(W[15]); ROUND_00_15(15,b,c,d,e,f,g,h,a); 601 T1 = X[15] = PULL64(W[15]); ROUND_00_15(15,b,c,d,e,f,g,h,a);
522#endif 602#endif
523 603
524 for (i=16;i<80;i+=8) 604 for (i=16;i<80;i+=16)
525 { 605 {
526 ROUND_16_80(i+0,a,b,c,d,e,f,g,h,X); 606 ROUND_16_80(i, 0,a,b,c,d,e,f,g,h,X);
527 ROUND_16_80(i+1,h,a,b,c,d,e,f,g,X); 607 ROUND_16_80(i, 1,h,a,b,c,d,e,f,g,X);
528 ROUND_16_80(i+2,g,h,a,b,c,d,e,f,X); 608 ROUND_16_80(i, 2,g,h,a,b,c,d,e,f,X);
529 ROUND_16_80(i+3,f,g,h,a,b,c,d,e,X); 609 ROUND_16_80(i, 3,f,g,h,a,b,c,d,e,X);
530 ROUND_16_80(i+4,e,f,g,h,a,b,c,d,X); 610 ROUND_16_80(i, 4,e,f,g,h,a,b,c,d,X);
531 ROUND_16_80(i+5,d,e,f,g,h,a,b,c,X); 611 ROUND_16_80(i, 5,d,e,f,g,h,a,b,c,X);
532 ROUND_16_80(i+6,c,d,e,f,g,h,a,b,X); 612 ROUND_16_80(i, 6,c,d,e,f,g,h,a,b,X);
533 ROUND_16_80(i+7,b,c,d,e,f,g,h,a,X); 613 ROUND_16_80(i, 7,b,c,d,e,f,g,h,a,X);
614 ROUND_16_80(i, 8,a,b,c,d,e,f,g,h,X);
615 ROUND_16_80(i, 9,h,a,b,c,d,e,f,g,X);
616 ROUND_16_80(i,10,g,h,a,b,c,d,e,f,X);
617 ROUND_16_80(i,11,f,g,h,a,b,c,d,e,X);
618 ROUND_16_80(i,12,e,f,g,h,a,b,c,d,X);
619 ROUND_16_80(i,13,d,e,f,g,h,a,b,c,X);
620 ROUND_16_80(i,14,c,d,e,f,g,h,a,b,X);
621 ROUND_16_80(i,15,b,c,d,e,f,g,h,a,X);
534 } 622 }
535 623
536 ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; 624 ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
@@ -544,4 +632,10 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num
544 632
545#endif /* SHA512_ASM */ 633#endif /* SHA512_ASM */
546 634
547#endif /* OPENSSL_NO_SHA512 */ 635#else /* !OPENSSL_NO_SHA512 */
636
637#if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX)
638static void *dummy=&dummy;
639#endif
640
641#endif /* !OPENSSL_NO_SHA512 */