diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-12 15:40:27 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-12 15:40:27 +0000 |
commit | cd2cd312b70e53b2095827d84c675b85cef4d2f6 (patch) | |
tree | a005300276c4c0943319c70a957474108ac89ef2 | |
parent | 6a5d9faa29e5ccf9467d25388dfaabaf0794e7bd (diff) | |
download | busybox-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.h | 6 | ||||
-rw-r--r-- | libbb/md5.c | 19 | ||||
-rw-r--r-- | libbb/sha1.c | 224 |
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; | |||
1329 | void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC; | 1329 | void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC; |
1330 | void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC; | 1330 | void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC; |
1331 | typedef struct sha256_ctx_t { | 1331 | typedef 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; |
1337 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; | 1336 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; |
1338 | void sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) FAST_FUNC; | 1337 | void sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) FAST_FUNC; |
1339 | void sha256_end(void *resbuf, sha256_ctx_t *ctx) FAST_FUNC; | 1338 | void sha256_end(void *resbuf, sha256_ctx_t *ctx) FAST_FUNC; |
1340 | typedef struct sha512_ctx_t { | 1339 | typedef 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; |
1346 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; | 1344 | void 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] = { | |||
200 | static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t *ctx) | 200 | static 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 | |||
278 | static void sha512_process_block128(const void *buffer, size_t len, sha512_ctx_t *ctx) | 272 | static 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) */ |
387 | void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | 373 | void 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. */ |
407 | void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx) | 391 | void 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 | ||
426 | void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) | 410 | void 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 | ||
476 | void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) | 465 | void 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 | ||
517 | void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx) | 513 | void 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. */ | ||
562 | void FAST_FUNC sha256_end(void *resbuf, sha256_ctx_t *ctx) | 549 | void 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. */ | ||
597 | void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx) | 578 | void 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 | } |