diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-12 15:39:11 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-12 15:39:11 +0000 |
commit | 6a5d9faa29e5ccf9467d25388dfaabaf0794e7bd (patch) | |
tree | 105b2d5b765a73028e5f4e474d36ad3dd3af1bcb | |
parent | 4abaec50a260f7d1d704ab33d54e0148e4f8626e (diff) | |
download | busybox-w32-6a5d9faa29e5ccf9467d25388dfaabaf0794e7bd.tar.gz busybox-w32-6a5d9faa29e5ccf9467d25388dfaabaf0794e7bd.tar.bz2 busybox-w32-6a5d9faa29e5ccf9467d25388dfaabaf0794e7bd.zip |
shrink sha hashing
function old new delta
sha512_hash 262 281 +19
sha512_end 204 221 +17
sha1_hash 128 113 -15
static.mask 16 - -16
static.bits 16 - -16
sha1_end 160 136 -24
------------------------------------------------------------------------------
(add/remove: 0/2 grow/shrink: 2/2 up/down: 36/-71) Total: -35 bytes
-rw-r--r-- | libbb/pw_encrypt_sha.c | 2 | ||||
-rw-r--r-- | libbb/sha1.c | 81 |
2 files changed, 34 insertions, 49 deletions
diff --git a/libbb/pw_encrypt_sha.c b/libbb/pw_encrypt_sha.c index e71f96fdc..070e0d442 100644 --- a/libbb/pw_encrypt_sha.c +++ b/libbb/pw_encrypt_sha.c | |||
@@ -20,7 +20,7 @@ sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) | |||
20 | { | 20 | { |
21 | void (*sha_begin)(void *ctx) FAST_FUNC; | 21 | void (*sha_begin)(void *ctx) FAST_FUNC; |
22 | void (*sha_hash)(const void *buffer, size_t len, void *ctx) FAST_FUNC; | 22 | void (*sha_hash)(const void *buffer, size_t len, void *ctx) FAST_FUNC; |
23 | void* (*sha_end)(void *resbuf, void *ctx) FAST_FUNC; | 23 | void (*sha_end)(void *resbuf, void *ctx) FAST_FUNC; |
24 | int _32or64; | 24 | int _32or64; |
25 | 25 | ||
26 | char *result, *resptr; | 26 | char *result, *resptr; |
diff --git a/libbb/sha1.c b/libbb/sha1.c index 5fc312393..38be575a6 100644 --- a/libbb/sha1.c +++ b/libbb/sha1.c | |||
@@ -406,22 +406,21 @@ void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) | |||
406 | /* hash_compile function as required. */ | 406 | /* hash_compile function as required. */ |
407 | void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx) | 407 | void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx) |
408 | { | 408 | { |
409 | uint32_t pos = (uint32_t) (ctx->total64 & SHA1_MASK); | 409 | unsigned wbuflen = ctx->total64 & SHA1_MASK; |
410 | uint32_t freeb = SHA1_BLOCK_SIZE - pos; | 410 | unsigned add = SHA1_BLOCK_SIZE - wbuflen; |
411 | const unsigned char *sp = buffer; | ||
412 | 411 | ||
413 | ctx->total64 += len; | 412 | ctx->total64 += len; |
414 | 413 | ||
415 | while (len >= freeb) { /* transfer whole blocks while possible */ | 414 | while (len >= add) { /* transfer whole blocks while possible */ |
416 | memcpy(((unsigned char *) ctx->wbuffer) + pos, sp, freeb); | 415 | memcpy(((unsigned char *) ctx->wbuffer) + wbuflen, buffer, add); |
417 | sp += freeb; | 416 | buffer = (const char *)buffer + add; |
418 | len -= freeb; | 417 | len -= add; |
419 | freeb = SHA1_BLOCK_SIZE; | 418 | add = SHA1_BLOCK_SIZE; |
420 | pos = 0; | 419 | wbuflen = 0; |
421 | sha1_process_block64(ctx); | 420 | sha1_process_block64(ctx); |
422 | } | 421 | } |
423 | 422 | ||
424 | memcpy(((unsigned char *) ctx->wbuffer) + pos, sp, len); | 423 | memcpy(((unsigned char *) ctx->wbuffer) + wbuflen, buffer, len); |
425 | } | 424 | } |
426 | 425 | ||
427 | void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) | 426 | void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) |
@@ -517,42 +516,24 @@ void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) | |||
517 | 516 | ||
518 | void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx) | 517 | void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx) |
519 | { | 518 | { |
520 | /* SHA1 Final padding and digest calculation */ | 519 | unsigned i, wbuflen, pad; |
521 | #if BB_BIG_ENDIAN | 520 | |
522 | static const uint32_t mask[4] = { 0x00000000, 0xff000000, 0xffff0000, 0xffffff00 }; | 521 | /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ |
523 | static const uint32_t bits[4] = { 0x80000000, 0x00800000, 0x00008000, 0x00000080 }; | 522 | wbuflen = ctx->total64 & SHA1_MASK; |
524 | #else | 523 | ((uint8_t *)ctx->wbuffer)[wbuflen++] = 0x80; |
525 | static const uint32_t mask[4] = { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff }; | 524 | pad = SHA1_BLOCK_SIZE - wbuflen; |
526 | static const uint32_t bits[4] = { 0x00000080, 0x00008000, 0x00800000, 0x80000000 }; | 525 | memset(((uint8_t *)ctx->wbuffer) + wbuflen, 0, pad); |
527 | #endif | 526 | |
528 | 527 | /* We need 1+8 or more empty positions, one for the padding byte | |
529 | uint8_t *hval = resbuf; | 528 | * (above) and eight for the length count. |
530 | uint32_t i, cnt = (uint32_t) (ctx->total64 & SHA1_MASK); | 529 | * If there is not enough space, empty the buffer. */ |
531 | 530 | if (pad < 8) { | |
532 | /* mask out the rest of any partial 32-bit word and then set */ | ||
533 | /* the next byte to 0x80. On big-endian machines any bytes in */ | ||
534 | /* the buffer will be at the top end of 32 bit words, on little */ | ||
535 | /* endian machines they will be at the bottom. Hence the AND */ | ||
536 | /* and OR masks above are reversed for little endian systems */ | ||
537 | ctx->wbuffer[cnt >> 2] = | ||
538 | (ctx->wbuffer[cnt >> 2] & mask[cnt & 3]) | bits[cnt & 3]; | ||
539 | |||
540 | /* we need 9 or more empty positions, one for the padding byte */ | ||
541 | /* (above) and eight for the length count. If there is not */ | ||
542 | /* enough space pad and empty the buffer */ | ||
543 | if (cnt > SHA1_BLOCK_SIZE - 9) { | ||
544 | if (cnt < 60) | ||
545 | ctx->wbuffer[15] = 0; | ||
546 | sha1_process_block64(ctx); | 531 | sha1_process_block64(ctx); |
547 | cnt = 0; | 532 | memset(ctx->wbuffer, 0, SHA1_BLOCK_SIZE - 8); |
548 | } else /* compute a word index for the empty buffer positions */ | 533 | ((uint8_t *)ctx->wbuffer)[0] = 0x80; |
549 | cnt = (cnt >> 2) + 1; | 534 | } |
550 | |||
551 | while (cnt < 14) /* and zero pad all but last two positions */ | ||
552 | ctx->wbuffer[cnt++] = 0; | ||
553 | 535 | ||
554 | /* assemble the 64-bit counter of bits in the buffer in BE */ | 536 | /* Store the 64-bit counter of bits in the buffer in BE format */ |
555 | /* format */ | ||
556 | { | 537 | { |
557 | uint64_t t = ctx->total64 << 3; | 538 | uint64_t t = ctx->total64 << 3; |
558 | t = hton64(t); | 539 | t = hton64(t); |
@@ -562,10 +543,14 @@ void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx) | |||
562 | 543 | ||
563 | sha1_process_block64(ctx); | 544 | sha1_process_block64(ctx); |
564 | 545 | ||
565 | /* extract the hash value as bytes in case the hash buffer is */ | 546 | /* Extract the hash value as bytes in case resbuf is |
566 | /* misaligned for 32-bit words */ | 547 | * misaligned for 32-bit words */ |
567 | for (i = 0; i < SHA1_DIGEST_SIZE; ++i) | 548 | for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i) { |
568 | hval[i] = (unsigned char) (ctx->hash[i >> 2] >> 8 * (~i & 3)); | 549 | uint32_t t = ctx->hash[i]; |
550 | t = ntohl(t); /* paranoia. this can be a macro */ | ||
551 | move_to_unaligned32(resbuf, t); /* ditto */ | ||
552 | resbuf = (char*)resbuf + 4; | ||
553 | } | ||
569 | } | 554 | } |
570 | 555 | ||
571 | 556 | ||