diff options
-rw-r--r-- | libbb/hash_md5_sha.c | 105 |
1 files changed, 51 insertions, 54 deletions
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index aeacddef8..5e4078ae6 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -473,20 +473,13 @@ void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | |||
473 | 473 | ||
474 | 474 | ||
475 | /* | 475 | /* |
476 | * Based on shasum from http://www.netsw.org/crypto/hash/ | 476 | * SHA1 part is: |
477 | * Majorly hacked up to use Dr Brian Gladman's sha1 code | 477 | * Copyright 2007 Rob Landley <rob@landley.net> |
478 | * | 478 | * |
479 | * Copyright (C) 2002 Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. | 479 | * Based on the public domain SHA-1 in C by Steve Reid <steve@edmweb.com> |
480 | * Copyright (C) 2003 Glenn L. McGrath | 480 | * from http://www.mirrors.wiretapped.net/security/cryptography/hashes/sha1/ |
481 | * Copyright (C) 2003 Erik Andersen | ||
482 | * | ||
483 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
484 | * | ||
485 | * --------------------------------------------------------------------------- | ||
486 | * Issue Date: 10/11/2002 | ||
487 | * | 481 | * |
488 | * This is a byte oriented version of SHA1 that operates on arrays of bytes | 482 | * Licensed under GPLv2, see file LICENSE in this source tree. |
489 | * stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor | ||
490 | * | 483 | * |
491 | * --------------------------------------------------------------------------- | 484 | * --------------------------------------------------------------------------- |
492 | * | 485 | * |
@@ -503,16 +496,18 @@ void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | |||
503 | 496 | ||
504 | static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx) | 497 | static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx) |
505 | { | 498 | { |
506 | unsigned t; | 499 | static const uint32_t rconsts[] = { |
507 | uint32_t W[80], a, b, c, d, e; | 500 | 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 |
508 | const uint32_t *words = (uint32_t*) ctx->wbuffer; | 501 | }; |
502 | int i, j; | ||
503 | int cnt; | ||
504 | uint32_t W[16+16]; | ||
505 | uint32_t a, b, c, d, e; | ||
509 | 506 | ||
510 | for (t = 0; t < 16; ++t) | 507 | /* On-stack work buffer frees up one register in the main loop |
511 | W[t] = SWAP_BE32(words[t]); | 508 | * which otherwise will be needed to hold ctx pointer */ |
512 | for (/*t = 16*/; t < 80; ++t) { | 509 | for (i = 0; i < 16; i++) |
513 | uint32_t T = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]; | 510 | W[i] = W[i+16] = SWAP_BE32(((uint32_t*)ctx->wbuffer)[i]); |
514 | W[t] = rotl32(T, 1); | ||
515 | } | ||
516 | 511 | ||
517 | a = ctx->hash[0]; | 512 | a = ctx->hash[0]; |
518 | b = ctx->hash[1]; | 513 | b = ctx->hash[1]; |
@@ -520,39 +515,41 @@ static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx) | |||
520 | d = ctx->hash[3]; | 515 | d = ctx->hash[3]; |
521 | e = ctx->hash[4]; | 516 | e = ctx->hash[4]; |
522 | 517 | ||
523 | #undef ch | 518 | /* 4 rounds of 20 operations each */ |
524 | #undef parity | 519 | cnt = 0; |
525 | #undef maj | 520 | for (i = 0; i < 4; i++) { |
526 | #undef rnd | 521 | j = 19; |
527 | #define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) | 522 | do { |
528 | #define parity(x,y,z) ((x) ^ (y) ^ (z)) | 523 | uint32_t work; |
529 | #define maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) | 524 | |
530 | /* A normal version as set out in the FIPS. */ | 525 | work = c ^ d; |
531 | #define rnd(f,k) \ | 526 | if (i == 0) { |
532 | do { \ | 527 | work = (work & b) ^ d; |
533 | uint32_t T = a; \ | 528 | if (j <= 3) |
534 | a = rotl32(a, 5) + f(b, c, d) + e + k + W[t]; \ | 529 | goto ge16; |
535 | e = d; \ | 530 | /* Used to do SWAP_BE32 here, but this |
536 | d = c; \ | 531 | * requires ctx (see comment above) */ |
537 | c = rotl32(b, 30); \ | 532 | work += W[cnt]; |
538 | b = T; \ | 533 | } else { |
539 | } while (0) | 534 | if (i == 2) |
540 | 535 | work = ((b | c) & d) | (b & c); | |
541 | for (t = 0; t < 20; ++t) | 536 | else /* i = 1 or 3 */ |
542 | rnd(ch, 0x5a827999); | 537 | work ^= b; |
543 | 538 | ge16: | |
544 | for (/*t = 20*/; t < 40; ++t) | 539 | W[cnt] = W[cnt+16] = rotl32(W[cnt+13] ^ W[cnt+8] ^ W[cnt+2] ^ W[cnt], 1); |
545 | rnd(parity, 0x6ed9eba1); | 540 | work += W[cnt]; |
546 | 541 | } | |
547 | for (/*t = 40*/; t < 60; ++t) | 542 | work = e + work + rotl32(a, 5) + rconsts[i]; |
548 | rnd(maj, 0x8f1bbcdc); | 543 | |
549 | 544 | /* Rotate by one for next time */ | |
550 | for (/*t = 60*/; t < 80; ++t) | 545 | e = d; |
551 | rnd(parity, 0xca62c1d6); | 546 | d = c; |
552 | #undef ch | 547 | c = /* b = */ rotl32(b, 30); |
553 | #undef parity | 548 | b = a; |
554 | #undef maj | 549 | a = work; |
555 | #undef rnd | 550 | cnt = (cnt + 1) & 15; |
551 | } while (--j >= 0); | ||
552 | } | ||
556 | 553 | ||
557 | ctx->hash[0] += a; | 554 | ctx->hash[0] += a; |
558 | ctx->hash[1] += b; | 555 | ctx->hash[1] += b; |