00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <sys/types.h>
00036 #include <string.h>
00037
00038 #include <stdio.h>
00039 #include <sysexits.h>
00040 #include <sys/uio.h>
00041 #include <unistd.h>
00042 #include <inttypes.h>
00043
00044 #include "sha2.h"
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 #define SHA2_UNROLL_TRANSFORM
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 typedef uint8_t sha2_byte;
00114 typedef uint32_t sha2_word32;
00115 typedef uint64_t sha2_word64;
00116
00117
00118
00119
00120 #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
00121 #define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
00122 #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
00123
00124
00125
00126 #ifndef WORDS_BIGENDIAN
00127 #define REVERSE32(w,x) { \
00128 sha2_word32 tmp = (w); \
00129 tmp = (tmp >> 16) | (tmp << 16); \
00130 (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
00131 }
00132 #define REVERSE64(w,x) { \
00133 sha2_word64 tmp = (w); \
00134 tmp = (tmp >> 32) | (tmp << 32); \
00135 tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
00136 ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
00137 (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
00138 ((tmp & 0x0000ffff0000ffffULL) << 16); \
00139 }
00140 #endif
00141
00142
00143
00144
00145
00146
00147 #define ADDINC128(w,n) { \
00148 (w)[0] += (sha2_word64)(n); \
00149 if ((w)[0] < (n)) { \
00150 (w)[1]++; \
00151 } \
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
00164
00165 #define SHA2_USE_MEMSET_MEMCPY 1
00166 #endif
00167 #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
00168
00169 #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
00170 #endif
00171
00172 #ifdef SHA2_USE_MEMSET_MEMCPY
00173 #define MEMSET_BZERO(p,l) memset((p), 0, (l))
00174 #define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
00175 #endif
00176 #ifdef SHA2_USE_BZERO_BCOPY
00177 #define MEMSET_BZERO(p,l) bzero((p), (l))
00178 #define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l))
00179 #endif
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 #define R(b,x) ((x) >> (b))
00193
00194 #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
00195
00196 #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
00197
00198
00199 #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
00200 #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
00201
00202
00203 #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
00204 #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
00205 #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
00206 #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
00207
00208
00209 #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
00210 #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
00211 #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
00212 #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
00213
00214
00215
00216
00217
00218
00219 static void SHA512_Last(SHA512_CTX*);
00220 static void SHA256_Transform(SHA256_CTX*, const sha2_word32*);
00221 static void SHA512_Transform(SHA512_CTX*, const sha2_word64*);
00222
00223
00224
00225
00226 const static sha2_word32 K256[64] = {
00227 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
00228 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
00229 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
00230 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
00231 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
00232 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
00233 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
00234 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
00235 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
00236 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
00237 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
00238 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
00239 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
00240 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
00241 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
00242 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
00243 };
00244
00245
00246 const static sha2_word32 sha256_initial_hash_value[8] = {
00247 0x6a09e667UL,
00248 0xbb67ae85UL,
00249 0x3c6ef372UL,
00250 0xa54ff53aUL,
00251 0x510e527fUL,
00252 0x9b05688cUL,
00253 0x1f83d9abUL,
00254 0x5be0cd19UL
00255 };
00256
00257
00258 const static sha2_word64 K512[80] = {
00259 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
00260 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
00261 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
00262 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
00263 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
00264 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
00265 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
00266 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
00267 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
00268 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
00269 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
00270 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
00271 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
00272 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
00273 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
00274 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
00275 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
00276 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
00277 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
00278 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
00279 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
00280 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
00281 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
00282 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
00283 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
00284 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
00285 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
00286 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
00287 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
00288 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
00289 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
00290 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
00291 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
00292 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
00293 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
00294 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
00295 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
00296 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
00297 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
00298 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
00299 };
00300
00301
00302 const static sha2_word64 sha384_initial_hash_value[8] = {
00303 0xcbbb9d5dc1059ed8ULL,
00304 0x629a292a367cd507ULL,
00305 0x9159015a3070dd17ULL,
00306 0x152fecd8f70e5939ULL,
00307 0x67332667ffc00b31ULL,
00308 0x8eb44a8768581511ULL,
00309 0xdb0c2e0d64f98fa7ULL,
00310 0x47b5481dbefa4fa4ULL
00311 };
00312
00313
00314 const static sha2_word64 sha512_initial_hash_value[8] = {
00315 0x6a09e667f3bcc908ULL,
00316 0xbb67ae8584caa73bULL,
00317 0x3c6ef372fe94f82bULL,
00318 0xa54ff53a5f1d36f1ULL,
00319 0x510e527fade682d1ULL,
00320 0x9b05688c2b3e6c1fULL,
00321 0x1f83d9abfb41bd6bULL,
00322 0x5be0cd19137e2179ULL
00323 };
00324
00325
00326
00327
00328
00329 static const char *sha2_hex_digits = "0123456789abcdef";
00330
00331
00332
00333 void sat_SHA256_Init(SHA256_CTX* context) {
00334 if (context == (SHA256_CTX*)0) {
00335 return;
00336 }
00337 MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
00338 MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
00339 context->bitcount = 0;
00340 }
00341
00342 #ifdef SHA2_UNROLL_TRANSFORM
00343
00344
00345
00346 #ifndef WORDS_BIGENDIAN
00347
00348 #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
00349 REVERSE32(*data++, W256[j]); \
00350 T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
00351 K256[j] + W256[j]; \
00352 (d) += T1; \
00353 (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
00354 j++
00355
00356
00357 #else
00358
00359 #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
00360 T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
00361 K256[j] + (W256[j] = *data++); \
00362 (d) += T1; \
00363 (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
00364 j++
00365
00366 #endif
00367
00368 #define ROUND256(a,b,c,d,e,f,g,h) \
00369 s0 = W256[(j+1)&0x0f]; \
00370 s0 = sigma0_256(s0); \
00371 s1 = W256[(j+14)&0x0f]; \
00372 s1 = sigma1_256(s1); \
00373 T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
00374 (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
00375 (d) += T1; \
00376 (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
00377 j++
00378
00379 static void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
00380 sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
00381 sha2_word32 T1, *W256;
00382 int j;
00383
00384 W256 = (sha2_word32*)context->buffer;
00385
00386
00387 a = context->state[0];
00388 b = context->state[1];
00389 c = context->state[2];
00390 d = context->state[3];
00391 e = context->state[4];
00392 f = context->state[5];
00393 g = context->state[6];
00394 h = context->state[7];
00395
00396 j = 0;
00397 do {
00398
00399 ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
00400 ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
00401 ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
00402 ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
00403 ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
00404 ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
00405 ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
00406 ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
00407 } while (j < 16);
00408
00409
00410 do {
00411 ROUND256(a,b,c,d,e,f,g,h);
00412 ROUND256(h,a,b,c,d,e,f,g);
00413 ROUND256(g,h,a,b,c,d,e,f);
00414 ROUND256(f,g,h,a,b,c,d,e);
00415 ROUND256(e,f,g,h,a,b,c,d);
00416 ROUND256(d,e,f,g,h,a,b,c);
00417 ROUND256(c,d,e,f,g,h,a,b);
00418 ROUND256(b,c,d,e,f,g,h,a);
00419 } while (j < 64);
00420
00421
00422 context->state[0] += a;
00423 context->state[1] += b;
00424 context->state[2] += c;
00425 context->state[3] += d;
00426 context->state[4] += e;
00427 context->state[5] += f;
00428 context->state[6] += g;
00429 context->state[7] += h;
00430
00431
00432 a = b = c = d = e = f = g = h = T1 = 0;
00433 }
00434
00435 #else
00436
00437 static void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
00438 sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
00439 sha2_word32 T1, T2, *W256;
00440 int j;
00441
00442 W256 = (sha2_word32*)context->buffer;
00443
00444
00445 a = context->state[0];
00446 b = context->state[1];
00447 c = context->state[2];
00448 d = context->state[3];
00449 e = context->state[4];
00450 f = context->state[5];
00451 g = context->state[6];
00452 h = context->state[7];
00453
00454 j = 0;
00455 do {
00456 #ifndef WORDS_BIGENDIAN
00457
00458 REVERSE32(*data++,W256[j]);
00459
00460 T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
00461 #else
00462
00463 T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
00464 #endif
00465 T2 = Sigma0_256(a) + Maj(a, b, c);
00466 h = g;
00467 g = f;
00468 f = e;
00469 e = d + T1;
00470 d = c;
00471 c = b;
00472 b = a;
00473 a = T1 + T2;
00474
00475 j++;
00476 } while (j < 16);
00477
00478 do {
00479
00480 s0 = W256[(j+1)&0x0f];
00481 s0 = sigma0_256(s0);
00482 s1 = W256[(j+14)&0x0f];
00483 s1 = sigma1_256(s1);
00484
00485
00486 T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
00487 (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
00488 T2 = Sigma0_256(a) + Maj(a, b, c);
00489 h = g;
00490 g = f;
00491 f = e;
00492 e = d + T1;
00493 d = c;
00494 c = b;
00495 b = a;
00496 a = T1 + T2;
00497
00498 j++;
00499 } while (j < 64);
00500
00501
00502 context->state[0] += a;
00503 context->state[1] += b;
00504 context->state[2] += c;
00505 context->state[3] += d;
00506 context->state[4] += e;
00507 context->state[5] += f;
00508 context->state[6] += g;
00509 context->state[7] += h;
00510
00511
00512 a = b = c = d = e = f = g = h = T1 = T2 = 0;
00513 }
00514
00515 #endif
00516
00517 void sat_SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
00518 unsigned int freespace, usedspace;
00519
00520 if (len == 0) {
00521
00522 return;
00523 }
00524
00525
00526
00527
00528 usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
00529 if (usedspace > 0) {
00530
00531 freespace = SHA256_BLOCK_LENGTH - usedspace;
00532
00533 if (len >= freespace) {
00534
00535 MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
00536 context->bitcount += freespace << 3;
00537 len -= freespace;
00538 data += freespace;
00539 SHA256_Transform(context, (sha2_word32*)context->buffer);
00540 } else {
00541
00542 MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
00543 context->bitcount += len << 3;
00544
00545 usedspace = freespace = 0;
00546 return;
00547 }
00548 }
00549 while (len >= SHA256_BLOCK_LENGTH) {
00550
00551 SHA256_Transform(context, (sha2_word32*)data);
00552 context->bitcount += SHA256_BLOCK_LENGTH << 3;
00553 len -= SHA256_BLOCK_LENGTH;
00554 data += SHA256_BLOCK_LENGTH;
00555 }
00556 if (len > 0) {
00557
00558 MEMCPY_BCOPY(context->buffer, data, len);
00559 context->bitcount += len << 3;
00560 }
00561
00562 usedspace = freespace = 0;
00563 }
00564
00565 void sat_SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
00566 sha2_word32 *d = (sha2_word32*)digest;
00567 unsigned int usedspace;
00568
00569
00570
00571
00572
00573 if (digest != (sha2_byte*)0) {
00574 usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
00575 #ifndef WORDS_BIGENDIAN
00576
00577 REVERSE64(context->bitcount,context->bitcount);
00578 #endif
00579 if (usedspace > 0) {
00580
00581 context->buffer[usedspace++] = 0x80;
00582
00583 if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
00584
00585 MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
00586 } else {
00587 if (usedspace < SHA256_BLOCK_LENGTH) {
00588 MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
00589 }
00590
00591 SHA256_Transform(context, (sha2_word32*)context->buffer);
00592
00593
00594 MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
00595 }
00596 } else {
00597
00598 MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
00599
00600
00601 *context->buffer = 0x80;
00602 }
00603
00604 *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
00605
00606
00607 SHA256_Transform(context, (sha2_word32*)context->buffer);
00608
00609 #ifndef WORDS_BIGENDIAN
00610 {
00611
00612 int j;
00613 for (j = 0; j < 8; j++) {
00614 REVERSE32(context->state[j],context->state[j]);
00615 *d++ = context->state[j];
00616 }
00617 }
00618 #else
00619 MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
00620 #endif
00621 }
00622
00623
00624 MEMSET_BZERO(context, sizeof(context));
00625 usedspace = 0;
00626 }
00627
00628 char *sat_SHA256_End(SHA256_CTX* context, char buffer[]) {
00629 sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest;
00630 int i;
00631
00632
00633
00634
00635 if (buffer != (char*)0) {
00636 sat_SHA256_Final(digest, context);
00637
00638 for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
00639 *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
00640 *buffer++ = sha2_hex_digits[*d & 0x0f];
00641 d++;
00642 }
00643 *buffer = (char)0;
00644 } else {
00645 MEMSET_BZERO(context, sizeof(context));
00646 }
00647 MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
00648 return buffer;
00649 }
00650
00651 char* sat_SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
00652 SHA256_CTX context;
00653
00654 sat_SHA256_Init(&context);
00655 sat_SHA256_Update(&context, data, len);
00656 return sat_SHA256_End(&context, digest);
00657 }
00658
00659
00660
00661 void sat_SHA512_Init(SHA512_CTX* context) {
00662 if (context == (SHA512_CTX*)0) {
00663 return;
00664 }
00665 MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
00666 MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
00667 context->bitcount[0] = context->bitcount[1] = 0;
00668 }
00669
00670 #ifdef SHA2_UNROLL_TRANSFORM
00671
00672
00673 #ifndef WORDS_BIGENDIAN
00674
00675 #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
00676 REVERSE64(*data++, W512[j]); \
00677 T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
00678 K512[j] + W512[j]; \
00679 (d) += T1, \
00680 (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
00681 j++
00682
00683
00684 #else
00685
00686 #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
00687 T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
00688 K512[j] + (W512[j] = *data++); \
00689 (d) += T1; \
00690 (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
00691 j++
00692
00693 #endif
00694
00695 #define ROUND512(a,b,c,d,e,f,g,h) \
00696 s0 = W512[(j+1)&0x0f]; \
00697 s0 = sigma0_512(s0); \
00698 s1 = W512[(j+14)&0x0f]; \
00699 s1 = sigma1_512(s1); \
00700 T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
00701 (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
00702 (d) += T1; \
00703 (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
00704 j++
00705
00706 static void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
00707 sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
00708 sha2_word64 T1, *W512 = (sha2_word64*)context->buffer;
00709 int j;
00710
00711
00712 a = context->state[0];
00713 b = context->state[1];
00714 c = context->state[2];
00715 d = context->state[3];
00716 e = context->state[4];
00717 f = context->state[5];
00718 g = context->state[6];
00719 h = context->state[7];
00720
00721 j = 0;
00722 do {
00723 ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
00724 ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
00725 ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
00726 ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
00727 ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
00728 ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
00729 ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
00730 ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
00731 } while (j < 16);
00732
00733
00734 do {
00735 ROUND512(a,b,c,d,e,f,g,h);
00736 ROUND512(h,a,b,c,d,e,f,g);
00737 ROUND512(g,h,a,b,c,d,e,f);
00738 ROUND512(f,g,h,a,b,c,d,e);
00739 ROUND512(e,f,g,h,a,b,c,d);
00740 ROUND512(d,e,f,g,h,a,b,c);
00741 ROUND512(c,d,e,f,g,h,a,b);
00742 ROUND512(b,c,d,e,f,g,h,a);
00743 } while (j < 80);
00744
00745
00746 context->state[0] += a;
00747 context->state[1] += b;
00748 context->state[2] += c;
00749 context->state[3] += d;
00750 context->state[4] += e;
00751 context->state[5] += f;
00752 context->state[6] += g;
00753 context->state[7] += h;
00754
00755
00756 a = b = c = d = e = f = g = h = T1 = 0;
00757 }
00758
00759 #else
00760
00761 static void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
00762 sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
00763 sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer;
00764 int j;
00765
00766
00767 a = context->state[0];
00768 b = context->state[1];
00769 c = context->state[2];
00770 d = context->state[3];
00771 e = context->state[4];
00772 f = context->state[5];
00773 g = context->state[6];
00774 h = context->state[7];
00775
00776 j = 0;
00777 do {
00778 #ifndef WORDS_BIGENDIAN
00779
00780 REVERSE64(*data++, W512[j]);
00781
00782 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
00783 #else
00784
00785 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
00786 #endif
00787 T2 = Sigma0_512(a) + Maj(a, b, c);
00788 h = g;
00789 g = f;
00790 f = e;
00791 e = d + T1;
00792 d = c;
00793 c = b;
00794 b = a;
00795 a = T1 + T2;
00796
00797 j++;
00798 } while (j < 16);
00799
00800 do {
00801
00802 s0 = W512[(j+1)&0x0f];
00803 s0 = sigma0_512(s0);
00804 s1 = W512[(j+14)&0x0f];
00805 s1 = sigma1_512(s1);
00806
00807
00808 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
00809 (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
00810 T2 = Sigma0_512(a) + Maj(a, b, c);
00811 h = g;
00812 g = f;
00813 f = e;
00814 e = d + T1;
00815 d = c;
00816 c = b;
00817 b = a;
00818 a = T1 + T2;
00819
00820 j++;
00821 } while (j < 80);
00822
00823
00824 context->state[0] += a;
00825 context->state[1] += b;
00826 context->state[2] += c;
00827 context->state[3] += d;
00828 context->state[4] += e;
00829 context->state[5] += f;
00830 context->state[6] += g;
00831 context->state[7] += h;
00832
00833
00834 a = b = c = d = e = f = g = h = T1 = T2 = 0;
00835 }
00836
00837 #endif
00838
00839 void sat_SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
00840 unsigned int freespace, usedspace;
00841
00842 if (len == 0) {
00843
00844 return;
00845 }
00846
00847
00848
00849
00850 usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
00851 if (usedspace > 0) {
00852
00853 freespace = SHA512_BLOCK_LENGTH - usedspace;
00854
00855 if (len >= freespace) {
00856
00857 MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
00858 ADDINC128(context->bitcount, freespace << 3);
00859 len -= freespace;
00860 data += freespace;
00861 SHA512_Transform(context, (sha2_word64*)context->buffer);
00862 } else {
00863
00864 MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
00865 ADDINC128(context->bitcount, len << 3);
00866
00867 usedspace = freespace = 0;
00868 return;
00869 }
00870 }
00871 while (len >= SHA512_BLOCK_LENGTH) {
00872
00873 SHA512_Transform(context, (sha2_word64*)data);
00874 ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
00875 len -= SHA512_BLOCK_LENGTH;
00876 data += SHA512_BLOCK_LENGTH;
00877 }
00878 if (len > 0) {
00879
00880 MEMCPY_BCOPY(context->buffer, data, len);
00881 ADDINC128(context->bitcount, len << 3);
00882 }
00883
00884 usedspace = freespace = 0;
00885 }
00886
00887 static void SHA512_Last(SHA512_CTX* context) {
00888 unsigned int usedspace;
00889
00890 usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
00891 #ifndef WORDS_BIGENDIAN
00892
00893 REVERSE64(context->bitcount[0],context->bitcount[0]);
00894 REVERSE64(context->bitcount[1],context->bitcount[1]);
00895 #endif
00896 if (usedspace > 0) {
00897
00898 context->buffer[usedspace++] = 0x80;
00899
00900 if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
00901
00902 MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
00903 } else {
00904 if (usedspace < SHA512_BLOCK_LENGTH) {
00905 MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
00906 }
00907
00908 SHA512_Transform(context, (sha2_word64*)context->buffer);
00909
00910
00911 MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
00912 }
00913 } else {
00914
00915 MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
00916
00917
00918 *context->buffer = 0x80;
00919 }
00920
00921 *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
00922 *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
00923
00924
00925 SHA512_Transform(context, (sha2_word64*)context->buffer);
00926 }
00927
00928 void sat_SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
00929 sha2_word64 *d = (sha2_word64*)digest;
00930
00931
00932
00933
00934
00935 if (digest != (sha2_byte*)0) {
00936 SHA512_Last(context);
00937
00938
00939 #ifndef WORDS_BIGENDIAN
00940 {
00941
00942 int j;
00943 for (j = 0; j < 8; j++) {
00944 REVERSE64(context->state[j],context->state[j]);
00945 *d++ = context->state[j];
00946 }
00947 }
00948 #else
00949 MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
00950 #endif
00951 }
00952
00953
00954 MEMSET_BZERO(context, sizeof(context));
00955 }
00956
00957 char *sat_SHA512_End(SHA512_CTX* context, char buffer[]) {
00958 sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest;
00959 int i;
00960
00961
00962
00963
00964 if (buffer != (char*)0) {
00965 sat_SHA512_Final(digest, context);
00966
00967 for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
00968 *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
00969 *buffer++ = sha2_hex_digits[*d & 0x0f];
00970 d++;
00971 }
00972 *buffer = (char)0;
00973 } else {
00974 MEMSET_BZERO(context, sizeof(context));
00975 }
00976 MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
00977 return buffer;
00978 }
00979
00980 char* sat_SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
00981 SHA512_CTX context;
00982
00983 sat_SHA512_Init(&context);
00984 sat_SHA512_Update(&context, data, len);
00985 return sat_SHA512_End(&context, digest);
00986 }
00987
00988
00989
00990 void sat_SHA384_Init(SHA384_CTX* context) {
00991 if (context == (SHA384_CTX*)0) {
00992 return;
00993 }
00994 MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
00995 MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH);
00996 context->bitcount[0] = context->bitcount[1] = 0;
00997 }
00998
00999 void sat_SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {
01000 sat_SHA512_Update((SHA512_CTX*)context, data, len);
01001 }
01002
01003 void sat_SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
01004 sha2_word64 *d = (sha2_word64*)digest;
01005
01006
01007
01008
01009
01010 if (digest != (sha2_byte*)0) {
01011 SHA512_Last((SHA512_CTX*)context);
01012
01013
01014 #ifndef WORDS_BIGENDIAN
01015 {
01016
01017 int j;
01018 for (j = 0; j < 6; j++) {
01019 REVERSE64(context->state[j],context->state[j]);
01020 *d++ = context->state[j];
01021 }
01022 }
01023 #else
01024 MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH);
01025 #endif
01026 }
01027
01028
01029 MEMSET_BZERO(context, sizeof(context));
01030 }
01031
01032 char *sat_SHA384_End(SHA384_CTX* context, char buffer[]) {
01033 sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest;
01034 int i;
01035
01036
01037
01038
01039 if (buffer != (char*)0) {
01040 sat_SHA384_Final(digest, context);
01041
01042 for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
01043 *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
01044 *buffer++ = sha2_hex_digits[*d & 0x0f];
01045 d++;
01046 }
01047 *buffer = (char)0;
01048 } else {
01049 MEMSET_BZERO(context, sizeof(context));
01050 }
01051 MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
01052 return buffer;
01053 }
01054
01055 char* sat_SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
01056 SHA384_CTX context;
01057
01058 sat_SHA384_Init(&context);
01059 sat_SHA384_Update(&context, data, len);
01060 return sat_SHA384_End(&context, digest);
01061 }