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