aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-12 15:39:11 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-12 15:39:11 +0000
commit6a5d9faa29e5ccf9467d25388dfaabaf0794e7bd (patch)
tree105b2d5b765a73028e5f4e474d36ad3dd3af1bcb
parent4abaec50a260f7d1d704ab33d54e0148e4f8626e (diff)
downloadbusybox-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.c2
-rw-r--r--libbb/sha1.c81
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. */
407void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx) 407void 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
427void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) 426void 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
518void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx) 517void 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