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 | } |
