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 typedef union _ldns_sha2_buffer_union {
00550 uint8_t* theChars;
00551 uint64_t* theLongs;
00552 } ldns_sha2_buffer_union;
00553
00554 void ldns_sha256_final(sha2_byte digest[], ldns_sha256_CTX* context) {
00555 sha2_word32 *d = (sha2_word32*)digest;
00556 size_t usedspace;
00557 ldns_sha2_buffer_union cast_var;
00558
00559
00560 assert(context != (ldns_sha256_CTX*)0);
00561
00562
00563 if (digest != (sha2_byte*)0) {
00564 usedspace = (context->bitcount >> 3) % LDNS_SHA256_BLOCK_LENGTH;
00565 #if BYTE_ORDER == LITTLE_ENDIAN
00566
00567 REVERSE64(context->bitcount,context->bitcount);
00568 #endif
00569 if (usedspace > 0) {
00570
00571 context->buffer[usedspace++] = 0x80;
00572
00573 if (usedspace <= ldns_sha256_SHORT_BLOCK_LENGTH) {
00574
00575 MEMSET_BZERO(&context->buffer[usedspace], ldns_sha256_SHORT_BLOCK_LENGTH - usedspace);
00576 } else {
00577 if (usedspace < LDNS_SHA256_BLOCK_LENGTH) {
00578 MEMSET_BZERO(&context->buffer[usedspace], LDNS_SHA256_BLOCK_LENGTH - usedspace);
00579 }
00580
00581 ldns_sha256_Transform(context, (sha2_word32*)context->buffer);
00582
00583
00584 MEMSET_BZERO(context->buffer, ldns_sha256_SHORT_BLOCK_LENGTH);
00585 }
00586 } else {
00587
00588 MEMSET_BZERO(context->buffer, ldns_sha256_SHORT_BLOCK_LENGTH);
00589
00590
00591 *context->buffer = 0x80;
00592 }
00593
00594 cast_var.theChars = context->buffer;
00595 cast_var.theLongs[ldns_sha256_SHORT_BLOCK_LENGTH / 8] = context->bitcount;
00596
00597
00598 ldns_sha256_Transform(context, (sha2_word32*)context->buffer);
00599
00600 #if BYTE_ORDER == LITTLE_ENDIAN
00601 {
00602
00603 int j;
00604 for (j = 0; j < 8; j++) {
00605 REVERSE32(context->state[j],context->state[j]);
00606 *d++ = context->state[j];
00607 }
00608 }
00609 #else
00610 MEMCPY_BCOPY(d, context->state, LDNS_SHA256_DIGEST_LENGTH);
00611 #endif
00612 }
00613
00614
00615 MEMSET_BZERO(context, sizeof(ldns_sha256_CTX));
00616 usedspace = 0;
00617 }
00618
00619 unsigned char *
00620 ldns_sha256(unsigned char *data, unsigned int data_len, unsigned char *digest)
00621 {
00622 ldns_sha256_CTX ctx;
00623 ldns_sha256_init(&ctx);
00624 ldns_sha256_update(&ctx, data, data_len);
00625 ldns_sha256_final(digest, &ctx);
00626 return digest;
00627 }
00628
00629
00630 void ldns_sha512_init(ldns_sha512_CTX* context) {
00631 if (context == (ldns_sha512_CTX*)0) {
00632 return;
00633 }
00634 MEMCPY_BCOPY(context->state, sha512_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH);
00635 MEMSET_BZERO(context->buffer, LDNS_SHA512_BLOCK_LENGTH);
00636 context->bitcount[0] = context->bitcount[1] = 0;
00637 }
00638
00639 #ifdef SHA2_UNROLL_TRANSFORM
00640
00641
00642 #if BYTE_ORDER == LITTLE_ENDIAN
00643
00644 #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
00645 REVERSE64(*data++, W512[j]); \
00646 T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
00647 K512[j] + W512[j]; \
00648 (d) += T1, \
00649 (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
00650 j++
00651
00652
00653 #else
00654
00655 #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
00656 T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
00657 K512[j] + (W512[j] = *data++); \
00658 (d) += T1; \
00659 (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
00660 j++
00661
00662 #endif
00663
00664 #define ROUND512(a,b,c,d,e,f,g,h) \
00665 s0 = W512[(j+1)&0x0f]; \
00666 s0 = sigma0_512(s0); \
00667 s1 = W512[(j+14)&0x0f]; \
00668 s1 = sigma1_512(s1); \
00669 T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
00670 (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
00671 (d) += T1; \
00672 (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
00673 j++
00674
00675 static void ldns_sha512_Transform(ldns_sha512_CTX* context,
00676 const sha2_word64* data) {
00677 sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
00678 sha2_word64 T1, *W512 = (sha2_word64*)context->buffer;
00679 int j;
00680
00681
00682 a = context->state[0];
00683 b = context->state[1];
00684 c = context->state[2];
00685 d = context->state[3];
00686 e = context->state[4];
00687 f = context->state[5];
00688 g = context->state[6];
00689 h = context->state[7];
00690
00691 j = 0;
00692 do {
00693 ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
00694 ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
00695 ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
00696 ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
00697 ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
00698 ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
00699 ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
00700 ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
00701 } while (j < 16);
00702
00703
00704 do {
00705 ROUND512(a,b,c,d,e,f,g,h);
00706 ROUND512(h,a,b,c,d,e,f,g);
00707 ROUND512(g,h,a,b,c,d,e,f);
00708 ROUND512(f,g,h,a,b,c,d,e);
00709 ROUND512(e,f,g,h,a,b,c,d);
00710 ROUND512(d,e,f,g,h,a,b,c);
00711 ROUND512(c,d,e,f,g,h,a,b);
00712 ROUND512(b,c,d,e,f,g,h,a);
00713 } while (j < 80);
00714
00715
00716 context->state[0] += a;
00717 context->state[1] += b;
00718 context->state[2] += c;
00719 context->state[3] += d;
00720 context->state[4] += e;
00721 context->state[5] += f;
00722 context->state[6] += g;
00723 context->state[7] += h;
00724
00725
00726 a = b = c = d = e = f = g = h = T1 = 0;
00727 }
00728
00729 #else
00730
00731 static void ldns_sha512_Transform(ldns_sha512_CTX* context,
00732 const sha2_word64* data) {
00733 sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
00734 sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer;
00735 int j;
00736
00737
00738 a = context->state[0];
00739 b = context->state[1];
00740 c = context->state[2];
00741 d = context->state[3];
00742 e = context->state[4];
00743 f = context->state[5];
00744 g = context->state[6];
00745 h = context->state[7];
00746
00747 j = 0;
00748 do {
00749 #if BYTE_ORDER == LITTLE_ENDIAN
00750
00751 REVERSE64(*data++, W512[j]);
00752
00753 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
00754 #else
00755
00756 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
00757 #endif
00758 T2 = Sigma0_512(a) + Maj(a, b, c);
00759 h = g;
00760 g = f;
00761 f = e;
00762 e = d + T1;
00763 d = c;
00764 c = b;
00765 b = a;
00766 a = T1 + T2;
00767
00768 j++;
00769 } while (j < 16);
00770
00771 do {
00772
00773 s0 = W512[(j+1)&0x0f];
00774 s0 = sigma0_512(s0);
00775 s1 = W512[(j+14)&0x0f];
00776 s1 = sigma1_512(s1);
00777
00778
00779 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
00780 (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
00781 T2 = Sigma0_512(a) + Maj(a, b, c);
00782 h = g;
00783 g = f;
00784 f = e;
00785 e = d + T1;
00786 d = c;
00787 c = b;
00788 b = a;
00789 a = T1 + T2;
00790
00791 j++;
00792 } while (j < 80);
00793
00794
00795 context->state[0] += a;
00796 context->state[1] += b;
00797 context->state[2] += c;
00798 context->state[3] += d;
00799 context->state[4] += e;
00800 context->state[5] += f;
00801 context->state[6] += g;
00802 context->state[7] += h;
00803
00804
00805 a = b = c = d = e = f = g = h = T1 = T2 = 0;
00806 }
00807
00808 #endif
00809
00810 void ldns_sha512_update(ldns_sha512_CTX* context, const sha2_byte *data, size_t len) {
00811 size_t freespace, usedspace;
00812
00813 if (len == 0) {
00814
00815 return;
00816 }
00817
00818
00819 assert(context != (ldns_sha512_CTX*)0 && data != (sha2_byte*)0);
00820
00821 usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH;
00822 if (usedspace > 0) {
00823
00824 freespace = LDNS_SHA512_BLOCK_LENGTH - usedspace;
00825
00826 if (len >= freespace) {
00827
00828 MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
00829 ADDINC128(context->bitcount, freespace << 3);
00830 len -= freespace;
00831 data += freespace;
00832 ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
00833 } else {
00834
00835 MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
00836 ADDINC128(context->bitcount, len << 3);
00837
00838 usedspace = freespace = 0;
00839 return;
00840 }
00841 }
00842 while (len >= LDNS_SHA512_BLOCK_LENGTH) {
00843
00844 ldns_sha512_Transform(context, (sha2_word64*)data);
00845 ADDINC128(context->bitcount, LDNS_SHA512_BLOCK_LENGTH << 3);
00846 len -= LDNS_SHA512_BLOCK_LENGTH;
00847 data += LDNS_SHA512_BLOCK_LENGTH;
00848 }
00849 if (len > 0) {
00850
00851 MEMCPY_BCOPY(context->buffer, data, len);
00852 ADDINC128(context->bitcount, len << 3);
00853 }
00854
00855 usedspace = freespace = 0;
00856 }
00857
00858 static void ldns_sha512_Last(ldns_sha512_CTX* context) {
00859 size_t usedspace;
00860 ldns_sha2_buffer_union cast_var;
00861
00862 usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH;
00863 #if BYTE_ORDER == LITTLE_ENDIAN
00864
00865 REVERSE64(context->bitcount[0],context->bitcount[0]);
00866 REVERSE64(context->bitcount[1],context->bitcount[1]);
00867 #endif
00868 if (usedspace > 0) {
00869
00870 context->buffer[usedspace++] = 0x80;
00871
00872 if (usedspace <= ldns_sha512_SHORT_BLOCK_LENGTH) {
00873
00874 MEMSET_BZERO(&context->buffer[usedspace], ldns_sha512_SHORT_BLOCK_LENGTH - usedspace);
00875 } else {
00876 if (usedspace < LDNS_SHA512_BLOCK_LENGTH) {
00877 MEMSET_BZERO(&context->buffer[usedspace], LDNS_SHA512_BLOCK_LENGTH - usedspace);
00878 }
00879
00880 ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
00881
00882
00883 MEMSET_BZERO(context->buffer, LDNS_SHA512_BLOCK_LENGTH - 2);
00884 }
00885 } else {
00886
00887 MEMSET_BZERO(context->buffer, ldns_sha512_SHORT_BLOCK_LENGTH);
00888
00889
00890 *context->buffer = 0x80;
00891 }
00892
00893 cast_var.theChars = context->buffer;
00894 cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8] = context->bitcount[1];
00895 cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8 + 1] = context->bitcount[0];
00896
00897
00898 ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
00899 }
00900
00901 void ldns_sha512_final(sha2_byte digest[], ldns_sha512_CTX* context) {
00902 sha2_word64 *d = (sha2_word64*)digest;
00903
00904
00905 assert(context != (ldns_sha512_CTX*)0);
00906
00907
00908 if (digest != (sha2_byte*)0) {
00909 ldns_sha512_Last(context);
00910
00911
00912 #if BYTE_ORDER == LITTLE_ENDIAN
00913 {
00914
00915 int j;
00916 for (j = 0; j < 8; j++) {
00917 REVERSE64(context->state[j],context->state[j]);
00918 *d++ = context->state[j];
00919 }
00920 }
00921 #else
00922 MEMCPY_BCOPY(d, context->state, LDNS_SHA512_DIGEST_LENGTH);
00923 #endif
00924 }
00925
00926
00927 MEMSET_BZERO(context, sizeof(ldns_sha512_CTX));
00928 }
00929
00930 unsigned char *
00931 ldns_sha512(unsigned char *data, unsigned int data_len, unsigned char *digest)
00932 {
00933 ldns_sha512_CTX ctx;
00934 ldns_sha512_init(&ctx);
00935 ldns_sha512_update(&ctx, data, data_len);
00936 ldns_sha512_final(digest, &ctx);
00937 return digest;
00938 }
00939
00940
00941 void ldns_sha384_init(ldns_sha384_CTX* context) {
00942 if (context == (ldns_sha384_CTX*)0) {
00943 return;
00944 }
00945 MEMCPY_BCOPY(context->state, sha384_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH);
00946 MEMSET_BZERO(context->buffer, LDNS_SHA384_BLOCK_LENGTH);
00947 context->bitcount[0] = context->bitcount[1] = 0;
00948 }
00949
00950 void ldns_sha384_update(ldns_sha384_CTX* context, const sha2_byte* data, size_t len) {
00951 ldns_sha512_update((ldns_sha512_CTX*)context, data, len);
00952 }
00953
00954 void ldns_sha384_final(sha2_byte digest[], ldns_sha384_CTX* context) {
00955 sha2_word64 *d = (sha2_word64*)digest;
00956
00957
00958 assert(context != (ldns_sha384_CTX*)0);
00959
00960
00961 if (digest != (sha2_byte*)0) {
00962 ldns_sha512_Last((ldns_sha512_CTX*)context);
00963
00964
00965 #if BYTE_ORDER == LITTLE_ENDIAN
00966 {
00967
00968 int j;
00969 for (j = 0; j < 6; j++) {
00970 REVERSE64(context->state[j],context->state[j]);
00971 *d++ = context->state[j];
00972 }
00973 }
00974 #else
00975 MEMCPY_BCOPY(d, context->state, LDNS_SHA384_DIGEST_LENGTH);
00976 #endif
00977 }
00978
00979
00980 MEMSET_BZERO(context, sizeof(ldns_sha384_CTX));
00981 }
00982
00983 unsigned char *
00984 ldns_sha384(unsigned char *data, unsigned int data_len, unsigned char *digest)
00985 {
00986 ldns_sha384_CTX ctx;
00987 ldns_sha384_init(&ctx);
00988 ldns_sha384_update(&ctx, data, data_len);
00989 ldns_sha384_final(digest, &ctx);
00990 return digest;
00991 }