aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-12 15:40:27 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-12 15:40:27 +0000
commitcd2cd312b70e53b2095827d84c675b85cef4d2f6 (patch)
treea005300276c4c0943319c70a957474108ac89ef2
parent6a5d9faa29e5ccf9467d25388dfaabaf0794e7bd (diff)
downloadbusybox-w32-cd2cd312b70e53b2095827d84c675b85cef4d2f6.tar.gz
busybox-w32-cd2cd312b70e53b2095827d84c675b85cef4d2f6.tar.bz2
busybox-w32-cd2cd312b70e53b2095827d84c675b85cef4d2f6.zip
shrink sha hashing a bit more (remove wbuflen field from ctx),
remove the requirement for aligned buffer function old new delta sha512_hash 262 297 +35 sha1_end 136 143 +7 passwd_main 1019 1023 +4 sha256_end 135 137 +2 count_lines 72 74 +2 sha256_hash 259 260 +1 popstring 164 158 -6 sha512_begin 88 81 -7 sha256_begin 44 37 -7 parse_expr 832 824 -8 bbunpack 446 438 -8 sha256_process_block64 529 520 -9 md5_end 166 151 -15 evaltreenr 817 802 -15 evaltree 817 802 -15 sha512_end 204 182 -22 sha512_process_block128 1444 1405 -39 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 6/11 up/down: 51/-151) Total: -100 bytes
-rw-r--r--include/libbb.h6
-rw-r--r--libbb/md5.c19
-rw-r--r--libbb/sha1.c224
3 files changed, 113 insertions, 136 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 4c9901027..3f566f8af 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1329,18 +1329,16 @@ void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
1329void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC; 1329void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC;
1330void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC; 1330void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC;
1331typedef struct sha256_ctx_t { 1331typedef struct sha256_ctx_t {
1332 unsigned wbuflen;
1333 uint32_t H[8];
1334 uint64_t total64; 1332 uint64_t total64;
1333 uint32_t hash[8];
1335 char wbuffer[64*2]; /* NB: always correctly aligned for uint64_t */ 1334 char wbuffer[64*2]; /* NB: always correctly aligned for uint64_t */
1336} sha256_ctx_t; 1335} sha256_ctx_t;
1337void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; 1336void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
1338void sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) FAST_FUNC; 1337void sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) FAST_FUNC;
1339void sha256_end(void *resbuf, sha256_ctx_t *ctx) FAST_FUNC; 1338void sha256_end(void *resbuf, sha256_ctx_t *ctx) FAST_FUNC;
1340typedef struct sha512_ctx_t { 1339typedef struct sha512_ctx_t {
1341 unsigned wbuflen;
1342 uint64_t H[8];
1343 uint64_t total64[2]; 1340 uint64_t total64[2];
1341 uint64_t hash[8];
1344 char wbuffer[128*2]; /* NB: always correctly aligned for uint64_t */ 1342 char wbuffer[128*2]; /* NB: always correctly aligned for uint64_t */
1345} sha512_ctx_t; 1343} sha512_ctx_t;
1346void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; 1344void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
diff --git a/libbb/md5.c b/libbb/md5.c
index eb15d758d..768dfbcb7 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -416,15 +416,14 @@ void FAST_FUNC md5_end(void *resbuf, md5_ctx_t *ctx)
416 md5_hash_block(ctx->buffer, ctx); 416 md5_hash_block(ctx->buffer, ctx);
417 md5_hash_block(buf, ctx); 417 md5_hash_block(buf, ctx);
418 418
419 /* Put result from CTX in first 16 bytes following RESBUF. The result is 419 /* The MD5 result is in little endian byte order.
420 * always in little endian byte order, so that a byte-wise output yields 420 * We (ab)use the fact that A-D are consecutive in memory.
421 * to the wanted ASCII representation of the message digest.
422 *
423 * IMPORTANT: On some systems it is required that RESBUF is correctly
424 * aligned for a 32 bits value.
425 */ 421 */
426 ((uint32_t *) resbuf)[0] = SWAP_LE32(ctx->A); 422#if BB_BIG_ENDIAN
427 ((uint32_t *) resbuf)[1] = SWAP_LE32(ctx->B); 423 ctx->A = SWAP_LE32(ctx->A);
428 ((uint32_t *) resbuf)[2] = SWAP_LE32(ctx->C); 424 ctx->B = SWAP_LE32(ctx->B);
429 ((uint32_t *) resbuf)[3] = SWAP_LE32(ctx->D); 425 ctx->C = SWAP_LE32(ctx->C);
426 ctx->D = SWAP_LE32(ctx->D);
427#endif
428 memcpy(resbuf, &ctx->A, sizeof(ctx->A) * 4);
430} 429}
diff --git a/libbb/sha1.c b/libbb/sha1.c
index 38be575a6..1584e98cd 100644
--- a/libbb/sha1.c
+++ b/libbb/sha1.c
@@ -200,20 +200,14 @@ static const uint32_t K512_lo[80] = {
200static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t *ctx) 200static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t *ctx)
201{ 201{
202 const uint32_t *words = buffer; 202 const uint32_t *words = buffer;
203 uint32_t a = ctx->H[0]; 203 uint32_t a = ctx->hash[0];
204 uint32_t b = ctx->H[1]; 204 uint32_t b = ctx->hash[1];
205 uint32_t c = ctx->H[2]; 205 uint32_t c = ctx->hash[2];
206 uint32_t d = ctx->H[3]; 206 uint32_t d = ctx->hash[3];
207 uint32_t e = ctx->H[4]; 207 uint32_t e = ctx->hash[4];
208 uint32_t f = ctx->H[5]; 208 uint32_t f = ctx->hash[5];
209 uint32_t g = ctx->H[6]; 209 uint32_t g = ctx->hash[6];
210 uint32_t h = ctx->H[7]; 210 uint32_t h = ctx->hash[7];
211
212 /* First increment the byte count. FIPS 180-2 specifies the possible
213 length of the file up to 2^64 _bits_.
214 We compute the number of _bytes_ and convert to bits later. */
215 len &= ~(size_t)(sizeof(uint32_t) * 16 - 1);
216 ctx->total64 += len;
217 211
218 /* Process all bytes in the buffer with 64 bytes in each round of 212 /* Process all bytes in the buffer with 64 bytes in each round of
219 the loop. */ 213 the loop. */
@@ -260,14 +254,14 @@ static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t
260#undef R1 254#undef R1
261 /* Add the starting values of the context according to FIPS 180-2:6.2.2 255 /* Add the starting values of the context according to FIPS 180-2:6.2.2
262 step 4. */ 256 step 4. */
263 ctx->H[0] = a += ctx->H[0]; 257 ctx->hash[0] = a += ctx->hash[0];
264 ctx->H[1] = b += ctx->H[1]; 258 ctx->hash[1] = b += ctx->hash[1];
265 ctx->H[2] = c += ctx->H[2]; 259 ctx->hash[2] = c += ctx->hash[2];
266 ctx->H[3] = d += ctx->H[3]; 260 ctx->hash[3] = d += ctx->hash[3];
267 ctx->H[4] = e += ctx->H[4]; 261 ctx->hash[4] = e += ctx->hash[4];
268 ctx->H[5] = f += ctx->H[5]; 262 ctx->hash[5] = f += ctx->hash[5];
269 ctx->H[6] = g += ctx->H[6]; 263 ctx->hash[6] = g += ctx->hash[6];
270 ctx->H[7] = h += ctx->H[7]; 264 ctx->hash[7] = h += ctx->hash[7];
271 265
272 /* Prepare for the next round. */ 266 /* Prepare for the next round. */
273 len--; 267 len--;
@@ -278,22 +272,14 @@ static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t
278static void sha512_process_block128(const void *buffer, size_t len, sha512_ctx_t *ctx) 272static void sha512_process_block128(const void *buffer, size_t len, sha512_ctx_t *ctx)
279{ 273{
280 const uint64_t *words = buffer; 274 const uint64_t *words = buffer;
281 uint64_t a = ctx->H[0]; 275 uint64_t a = ctx->hash[0];
282 uint64_t b = ctx->H[1]; 276 uint64_t b = ctx->hash[1];
283 uint64_t c = ctx->H[2]; 277 uint64_t c = ctx->hash[2];
284 uint64_t d = ctx->H[3]; 278 uint64_t d = ctx->hash[3];
285 uint64_t e = ctx->H[4]; 279 uint64_t e = ctx->hash[4];
286 uint64_t f = ctx->H[5]; 280 uint64_t f = ctx->hash[5];
287 uint64_t g = ctx->H[6]; 281 uint64_t g = ctx->hash[6];
288 uint64_t h = ctx->H[7]; 282 uint64_t h = ctx->hash[7];
289
290 /* First increment the byte count. FIPS 180-2 specifies the possible
291 length of the file up to 2^128 _bits_.
292 We compute the number of _bytes_ and convert to bits later. */
293 len &= ~(size_t)(sizeof(uint64_t) * 16 - 1);
294 ctx->total64[0] += len;
295 if (ctx->total64[0] < len)
296 ctx->total64[1]++;
297 283
298 len /= (sizeof(uint64_t) * 16); 284 len /= (sizeof(uint64_t) * 16);
299 while (len) { 285 while (len) {
@@ -338,14 +324,14 @@ static void sha512_process_block128(const void *buffer, size_t len, sha512_ctx_t
338#undef R1 324#undef R1
339 /* Add the starting values of the context according to FIPS 180-2:6.3.2 325 /* Add the starting values of the context according to FIPS 180-2:6.3.2
340 step 4. */ 326 step 4. */
341 ctx->H[0] = a += ctx->H[0]; 327 ctx->hash[0] = a += ctx->hash[0];
342 ctx->H[1] = b += ctx->H[1]; 328 ctx->hash[1] = b += ctx->hash[1];
343 ctx->H[2] = c += ctx->H[2]; 329 ctx->hash[2] = c += ctx->hash[2];
344 ctx->H[3] = d += ctx->H[3]; 330 ctx->hash[3] = d += ctx->hash[3];
345 ctx->H[4] = e += ctx->H[4]; 331 ctx->hash[4] = e += ctx->hash[4];
346 ctx->H[5] = f += ctx->H[5]; 332 ctx->hash[5] = f += ctx->hash[5];
347 ctx->H[6] = g += ctx->H[6]; 333 ctx->hash[6] = g += ctx->hash[6];
348 ctx->H[7] = h += ctx->H[7]; 334 ctx->hash[7] = h += ctx->hash[7];
349 335
350 len--; 336 len--;
351 } 337 }
@@ -386,9 +372,8 @@ static const uint32_t init512_lo[] = {
386 (FIPS 180-2:5.3.2) */ 372 (FIPS 180-2:5.3.2) */
387void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) 373void FAST_FUNC sha256_begin(sha256_ctx_t *ctx)
388{ 374{
389 memcpy(ctx->H, init256, sizeof(init256)); 375 memcpy(ctx->hash, init256, sizeof(init256));
390 ctx->total64 = 0; 376 ctx->total64 = 0;
391 ctx->wbuflen = 0;
392} 377}
393/* Initialize structure containing state of computation. 378/* Initialize structure containing state of computation.
394 (FIPS 180-2:5.3.3) */ 379 (FIPS 180-2:5.3.3) */
@@ -396,9 +381,8 @@ void FAST_FUNC sha512_begin(sha512_ctx_t *ctx)
396{ 381{
397 int i; 382 int i;
398 for (i = 0; i < 8; i++) 383 for (i = 0; i < 8; i++)
399 ctx->H[i] = ((uint64_t)(init256[i]) << 32) + init512_lo[i]; 384 ctx->hash[i] = ((uint64_t)(init256[i]) << 32) + init512_lo[i];
400 ctx->total64[0] = ctx->total64[1] = 0; 385 ctx->total64[0] = ctx->total64[1] = 0;
401 ctx->wbuflen = 0;
402} 386}
403 387
404 388
@@ -406,28 +390,35 @@ void FAST_FUNC sha512_begin(sha512_ctx_t *ctx)
406/* hash_compile function as required. */ 390/* hash_compile function as required. */
407void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx) 391void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx)
408{ 392{
409 unsigned wbuflen = ctx->total64 & SHA1_MASK; 393 unsigned in_buf = ctx->total64 & SHA1_MASK;
410 unsigned add = SHA1_BLOCK_SIZE - wbuflen; 394 unsigned add = SHA1_BLOCK_SIZE - in_buf;
411 395
412 ctx->total64 += len; 396 ctx->total64 += len;
413 397
414 while (len >= add) { /* transfer whole blocks while possible */ 398 while (len >= add) { /* transfer whole blocks while possible */
415 memcpy(((unsigned char *) ctx->wbuffer) + wbuflen, buffer, add); 399 memcpy(((unsigned char *) ctx->wbuffer) + in_buf, buffer, add);
416 buffer = (const char *)buffer + add; 400 buffer = (const char *)buffer + add;
417 len -= add; 401 len -= add;
418 add = SHA1_BLOCK_SIZE; 402 add = SHA1_BLOCK_SIZE;
419 wbuflen = 0; 403 in_buf = 0;
420 sha1_process_block64(ctx); 404 sha1_process_block64(ctx);
421 } 405 }
422 406
423 memcpy(((unsigned char *) ctx->wbuffer) + wbuflen, buffer, len); 407 memcpy(((unsigned char *) ctx->wbuffer) + in_buf, buffer, len);
424} 408}
425 409
426void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) 410void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx)
427{ 411{
412 unsigned in_buf = ctx->total64 & 63;
413
414 /* First increment the byte count. FIPS 180-2 specifies the possible
415 length of the file up to 2^64 _bits_.
416 We compute the number of _bytes_ and convert to bits later. */
417 ctx->total64 += len;
418
428 /* When we already have some bits in our internal buffer concatenate 419 /* When we already have some bits in our internal buffer concatenate
429 both inputs first. */ 420 both inputs first. */
430 if (ctx->wbuflen != 0) { 421 if (in_buf != 0) {
431 unsigned add; 422 unsigned add;
432 423
433 /* NB: 1/2 of wbuffer is used only in sha256_end 424 /* NB: 1/2 of wbuffer is used only in sha256_end
@@ -435,18 +426,17 @@ void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx)
435 * With buffer twice as small, it may happen that 426 * With buffer twice as small, it may happen that
436 * we have it almost full and can't add length field. */ 427 * we have it almost full and can't add length field. */
437 428
438 add = sizeof(ctx->wbuffer)/2 - ctx->wbuflen; 429 add = sizeof(ctx->wbuffer)/2 - in_buf;
439 if (add > len) 430 if (add > len)
440 add = len; 431 add = len;
441 memcpy(&ctx->wbuffer[ctx->wbuflen], buffer, add); 432 memcpy(&ctx->wbuffer[in_buf], buffer, add);
442 ctx->wbuflen += add; 433 in_buf += add;
443 434
444 /* If we still didn't collect full wbuffer, bail out */ 435 /* If we still didn't collect full wbuffer, bail out */
445 if (ctx->wbuflen < sizeof(ctx->wbuffer)/2) 436 if (in_buf < sizeof(ctx->wbuffer)/2)
446 return; 437 return;
447 438
448 sha256_process_block64(ctx->wbuffer, 64, ctx); 439 sha256_process_block64(ctx->wbuffer, 64, ctx);
449 ctx->wbuflen = 0;
450 buffer = (const char *)buffer + add; 440 buffer = (const char *)buffer + add;
451 len -= add; 441 len -= add;
452 } 442 }
@@ -454,7 +444,7 @@ void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx)
454 /* Process available complete blocks. */ 444 /* Process available complete blocks. */
455 if (len >= 64) { 445 if (len >= 64) {
456 if (UNALIGNED_P(buffer, uint32_t)) { 446 if (UNALIGNED_P(buffer, uint32_t)) {
457 while (len > 64) { 447 while (len >= 64) {
458 sha256_process_block64(memcpy(ctx->wbuffer, buffer, 64), 64, ctx); 448 sha256_process_block64(memcpy(ctx->wbuffer, buffer, 64), 64, ctx);
459 buffer = (const char *)buffer + 64; 449 buffer = (const char *)buffer + 64;
460 len -= 64; 450 len -= 64;
@@ -469,33 +459,40 @@ void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx)
469 /* Move remaining bytes into internal buffer. */ 459 /* Move remaining bytes into internal buffer. */
470 if (len > 0) { 460 if (len > 0) {
471 memcpy(ctx->wbuffer, buffer, len); 461 memcpy(ctx->wbuffer, buffer, len);
472 ctx->wbuflen = len;
473 } 462 }
474} 463}
475 464
476void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) 465void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx)
477{ 466{
478 if (ctx->wbuflen != 0) { 467 unsigned in_buf = ctx->total64[0] & 127;
468
469 /* First increment the byte count. FIPS 180-2 specifies the possible
470 length of the file up to 2^128 _bits_.
471 We compute the number of _bytes_ and convert to bits later. */
472 ctx->total64[0] += len;
473 if (ctx->total64[0] < len)
474 ctx->total64[1]++;
475
476 if (in_buf != 0) {
479 unsigned add; 477 unsigned add;
480 478
481 add = sizeof(ctx->wbuffer)/2 - ctx->wbuflen; 479 add = sizeof(ctx->wbuffer)/2 - in_buf;
482 if (add > len) 480 if (add > len)
483 add = len; 481 add = len;
484 memcpy(&ctx->wbuffer[ctx->wbuflen], buffer, add); 482 memcpy(&ctx->wbuffer[in_buf], buffer, add);
485 ctx->wbuflen += add; 483 in_buf += add;
486 484
487 if (ctx->wbuflen < sizeof(ctx->wbuffer)/2) 485 if (in_buf < sizeof(ctx->wbuffer)/2)
488 return; 486 return;
489 487
490 sha512_process_block128(ctx->wbuffer, 128, ctx); 488 sha512_process_block128(ctx->wbuffer, 128, ctx);
491 ctx->wbuflen = 0;
492 buffer = (const char *)buffer + add; 489 buffer = (const char *)buffer + add;
493 len -= add; 490 len -= add;
494 } 491 }
495 492
496 if (len >= 128) { 493 if (len >= 128) {
497 if (UNALIGNED_P(buffer, uint64_t)) { 494 if (UNALIGNED_P(buffer, uint64_t)) {
498 while (len > 128) { 495 while (len >= 128) {
499 sha512_process_block128(memcpy(ctx->wbuffer, buffer, 128), 128, ctx); 496 sha512_process_block128(memcpy(ctx->wbuffer, buffer, 128), 128, ctx);
500 buffer = (const char *)buffer + 128; 497 buffer = (const char *)buffer + 128;
501 len -= 128; 498 len -= 128;
@@ -509,20 +506,19 @@ void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx)
509 506
510 if (len > 0) { 507 if (len > 0) {
511 memcpy(ctx->wbuffer, buffer, len); 508 memcpy(ctx->wbuffer, buffer, len);
512 ctx->wbuflen = len;
513 } 509 }
514} 510}
515 511
516 512
517void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx) 513void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx)
518{ 514{
519 unsigned i, wbuflen, pad; 515 unsigned i, pad, in_buf;
520 516
521 /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ 517 /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
522 wbuflen = ctx->total64 & SHA1_MASK; 518 in_buf = ctx->total64 & SHA1_MASK;
523 ((uint8_t *)ctx->wbuffer)[wbuflen++] = 0x80; 519 ((uint8_t *)ctx->wbuffer)[in_buf++] = 0x80;
524 pad = SHA1_BLOCK_SIZE - wbuflen; 520 pad = SHA1_BLOCK_SIZE - in_buf;
525 memset(((uint8_t *)ctx->wbuffer) + wbuflen, 0, pad); 521 memset(((uint8_t *)ctx->wbuffer) + in_buf, 0, pad);
526 522
527 /* We need 1+8 or more empty positions, one for the padding byte 523 /* We need 1+8 or more empty positions, one for the padding byte
528 * (above) and eight for the length count. 524 * (above) and eight for the length count.
@@ -543,77 +539,61 @@ void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx)
543 539
544 sha1_process_block64(ctx); 540 sha1_process_block64(ctx);
545 541
546 /* Extract the hash value as bytes in case resbuf is 542#if BB_LITTLE_ENDIAN
547 * misaligned for 32-bit words */ 543 for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
548 for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i) { 544 ctx->hash[i] = htonl(ctx->hash[i]);
549 uint32_t t = ctx->hash[i]; 545#endif
550 t = ntohl(t); /* paranoia. this can be a macro */ 546 memcpy(resbuf, ctx->hash, sizeof(ctx->hash));
551 move_to_unaligned32(resbuf, t); /* ditto */
552 resbuf = (char*)resbuf + 4;
553 }
554} 547}
555 548
556
557/* Process the remaining bytes in the internal buffer and the usual
558 prolog according to the standard and write the result to RESBUF.
559
560 IMPORTANT: On some systems it is required that RESBUF is correctly
561 aligned for a 32 bits value. */
562void FAST_FUNC sha256_end(void *resbuf, sha256_ctx_t *ctx) 549void FAST_FUNC sha256_end(void *resbuf, sha256_ctx_t *ctx)
563{ 550{
564 /* Take yet unprocessed bytes into account. */ 551 unsigned i, pad, in_buf;
565 unsigned bytes = ctx->wbuflen;
566 unsigned pad;
567
568 /* Now count remaining bytes. */
569 ctx->total64 += bytes;
570 552
571 /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... 553 /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0...
572 (FIPS 180-2:5.1.1) */ 554 (FIPS 180-2:5.1.1) */
573 pad = (bytes >= 56 ? 64 + 56 - bytes : 56 - bytes); 555 in_buf = ctx->total64 & 63;
574 memset(&ctx->wbuffer[bytes], 0, pad); 556 pad = (in_buf >= 56 ? 64 + 56 - in_buf : 56 - in_buf);
575 ctx->wbuffer[bytes] = 0x80; 557 memset(&ctx->wbuffer[in_buf], 0, pad);
558 ctx->wbuffer[in_buf] = 0x80;
576 559
577 /* Put the 64-bit file length in *bits* at the end of the buffer. */ 560 /* Put the 64-bit file length in *bits* at the end of the buffer. */
578 { 561 {
579 uint64_t t = ctx->total64 << 3; 562 uint64_t t = ctx->total64 << 3;
580 t = hton64(t); 563 t = hton64(t);
581 /* wbuffer is suitably aligned for this */ 564 /* wbuffer is suitably aligned for this */
582 *(uint64_t *) &ctx->wbuffer[bytes + pad] = t; 565 *(uint64_t *) &ctx->wbuffer[in_buf + pad] = t;
583 } 566 }
584 567
585 /* Process last bytes. */ 568 /* Process last bytes. */
586 sha256_process_block64(ctx->wbuffer, bytes + pad + 8, ctx); 569 sha256_process_block64(ctx->wbuffer, in_buf + pad + 8, ctx);
587 570
588 for (unsigned i = 0; i < 8; ++i) 571#if BB_LITTLE_ENDIAN
589 ((uint32_t *) resbuf)[i] = ntohl(ctx->H[i]); 572 for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
573 ctx->hash[i] = htonl(ctx->hash[i]);
574#endif
575 memcpy(resbuf, ctx->hash, sizeof(ctx->hash));
590} 576}
591 577
592/* Process the remaining bytes in the internal buffer and the usual
593 prolog according to the standard and write the result to RESBUF.
594
595 IMPORTANT: On some systems it is required that RESBUF is correctly
596 aligned for a 64 bits value. */
597void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx) 578void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx)
598{ 579{
599 unsigned bytes = ctx->wbuflen; 580 unsigned i, pad, in_buf;
600 unsigned pad;
601
602 ctx->total64[0] += bytes;
603 if (ctx->total64[0] < bytes)
604 ctx->total64[1]++;
605 581
606 /* Pad the buffer to the next 128-byte boundary with 0x80,0,0,0... 582 /* Pad the buffer to the next 128-byte boundary with 0x80,0,0,0...
607 (FIPS 180-2:5.1.2) */ 583 (FIPS 180-2:5.1.2) */
608 pad = bytes >= 112 ? 128 + 112 - bytes : 112 - bytes; 584 in_buf = ctx->total64[0] & 127;
609 memset(&ctx->wbuffer[bytes], 0, pad); 585 pad = in_buf >= 112 ? 128 + 112 - in_buf : 112 - in_buf;
610 ctx->wbuffer[bytes] = 0x80; 586 memset(&ctx->wbuffer[in_buf], 0, pad);
587 ctx->wbuffer[in_buf] = 0x80;
611 588
612 *(uint64_t *) &ctx->wbuffer[bytes + pad + 8] = hton64(ctx->total64[0] << 3); 589 *(uint64_t *) &ctx->wbuffer[in_buf + pad + 8] = hton64(ctx->total64[0] << 3);
613 *(uint64_t *) &ctx->wbuffer[bytes + pad] = hton64((ctx->total64[1] << 3) | (ctx->total64[0] >> 61)); 590 *(uint64_t *) &ctx->wbuffer[in_buf + pad] = hton64((ctx->total64[1] << 3) | (ctx->total64[0] >> 61));
614 591
615 sha512_process_block128(ctx->wbuffer, bytes + pad + 16, ctx); 592 sha512_process_block128(ctx->wbuffer, in_buf + pad + 16, ctx);
616 593
617 for (unsigned i = 0; i < 8; ++i) 594#if BB_LITTLE_ENDIAN
618 ((uint64_t *) resbuf)[i] = hton64(ctx->H[i]); 595 for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
596 ctx->hash[i] = hton64(ctx->hash[i]);
597#endif
598 memcpy(resbuf, ctx->hash, sizeof(ctx->hash));
619} 599}