diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-08-29 14:05:25 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-08-29 14:05:25 +0200 |
commit | 71a090f1871f165ebf3c31f733b36aafca71a6b4 (patch) | |
tree | 4f0b38ba12a6e5b80aa829574f999ae1efd9f17a /libbb/hash_md5_sha.c | |
parent | d3d7f085ebf2898b62d4bb75566122c65be96454 (diff) | |
download | busybox-w32-71a090f1871f165ebf3c31f733b36aafca71a6b4.tar.gz busybox-w32-71a090f1871f165ebf3c31f733b36aafca71a6b4.tar.bz2 busybox-w32-71a090f1871f165ebf3c31f733b36aafca71a6b4.zip |
sha3: fix to conform to final SHA3 padding standard, add -a BITS option
function old new delta
hash_file 331 396 +65
md5_sha1_sum_main 485 538 +53
packed_usage 30423 30464 +41
sha3_begin 17 31 +14
sha3_hash 101 110 +9
sha3_end 41 49 +8
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb/hash_md5_sha.c')
-rw-r--r-- | libbb/hash_md5_sha.c | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index d08c6b2f7..7e7d8da2f 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -941,10 +941,6 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | |||
941 | # define OPTIMIZE_SHA3_FOR_32 1 | 941 | # define OPTIMIZE_SHA3_FOR_32 1 |
942 | #endif | 942 | #endif |
943 | 943 | ||
944 | enum { | ||
945 | SHA3_IBLK_BYTES = 72, /* 576 bits / 8 */ | ||
946 | }; | ||
947 | |||
948 | #if OPTIMIZE_SHA3_FOR_32 | 944 | #if OPTIMIZE_SHA3_FOR_32 |
949 | /* This splits every 64-bit word into a pair of 32-bit words, | 945 | /* This splits every 64-bit word into a pair of 32-bit words, |
950 | * even bits go into first word, odd bits go to second one. | 946 | * even bits go into first word, odd bits go to second one. |
@@ -1352,6 +1348,8 @@ static void sha3_process_block72(uint64_t *state) | |||
1352 | void FAST_FUNC sha3_begin(sha3_ctx_t *ctx) | 1348 | void FAST_FUNC sha3_begin(sha3_ctx_t *ctx) |
1353 | { | 1349 | { |
1354 | memset(ctx, 0, sizeof(*ctx)); | 1350 | memset(ctx, 0, sizeof(*ctx)); |
1351 | /* SHA3-512, user can override */ | ||
1352 | ctx->input_block_bytes = (1600 - 512*2) / 8; /* 72 bytes */ | ||
1355 | } | 1353 | } |
1356 | 1354 | ||
1357 | void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) | 1355 | void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) |
@@ -1361,7 +1359,7 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) | |||
1361 | unsigned bufpos = ctx->bytes_queued; | 1359 | unsigned bufpos = ctx->bytes_queued; |
1362 | 1360 | ||
1363 | while (1) { | 1361 | while (1) { |
1364 | unsigned remaining = SHA3_IBLK_BYTES - bufpos; | 1362 | unsigned remaining = ctx->input_block_bytes - bufpos; |
1365 | if (remaining > len) | 1363 | if (remaining > len) |
1366 | remaining = len; | 1364 | remaining = len; |
1367 | len -= remaining; | 1365 | len -= remaining; |
@@ -1373,38 +1371,41 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) | |||
1373 | remaining--; | 1371 | remaining--; |
1374 | } | 1372 | } |
1375 | /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */ | 1373 | /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */ |
1376 | bufpos -= SHA3_IBLK_BYTES; | 1374 | bufpos -= ctx->input_block_bytes; |
1377 | if (bufpos != 0) | 1375 | if (bufpos != 0) |
1378 | break; | 1376 | break; |
1379 | /* Buffer is filled up, process it */ | 1377 | /* Buffer is filled up, process it */ |
1380 | sha3_process_block72(ctx->state); | 1378 | sha3_process_block72(ctx->state); |
1381 | /*bufpos = 0; - already is */ | 1379 | /*bufpos = 0; - already is */ |
1382 | } | 1380 | } |
1383 | ctx->bytes_queued = bufpos + SHA3_IBLK_BYTES; | 1381 | ctx->bytes_queued = bufpos + ctx->input_block_bytes; |
1384 | #else | 1382 | #else |
1385 | /* +50 bytes code size, but a bit faster because of long-sized XORs */ | 1383 | /* +50 bytes code size, but a bit faster because of long-sized XORs */ |
1386 | const uint8_t *data = buffer; | 1384 | const uint8_t *data = buffer; |
1387 | unsigned bufpos = ctx->bytes_queued; | 1385 | unsigned bufpos = ctx->bytes_queued; |
1386 | unsigned iblk_bytes = ctx->input_block_bytes; | ||
1388 | 1387 | ||
1389 | /* If already data in queue, continue queuing first */ | 1388 | /* If already data in queue, continue queuing first */ |
1390 | while (len != 0 && bufpos != 0) { | 1389 | if (bufpos != 0) { |
1391 | uint8_t *buf = (uint8_t*)ctx->state; | 1390 | while (len != 0) { |
1392 | buf[bufpos] ^= *data++; | 1391 | uint8_t *buf = (uint8_t*)ctx->state; |
1393 | len--; | 1392 | buf[bufpos] ^= *data++; |
1394 | bufpos++; | 1393 | len--; |
1395 | if (bufpos == SHA3_IBLK_BYTES) { | 1394 | bufpos++; |
1396 | bufpos = 0; | 1395 | if (bufpos == iblk_bytes) { |
1397 | goto do_block; | 1396 | bufpos = 0; |
1397 | goto do_block; | ||
1398 | } | ||
1398 | } | 1399 | } |
1399 | } | 1400 | } |
1400 | 1401 | ||
1401 | /* Absorb complete blocks */ | 1402 | /* Absorb complete blocks */ |
1402 | while (len >= SHA3_IBLK_BYTES) { | 1403 | while (len >= iblk_bytes) { |
1403 | /* XOR data onto beginning of state[]. | 1404 | /* XOR data onto beginning of state[]. |
1404 | * We try to be efficient - operate one word at a time, not byte. | 1405 | * We try to be efficient - operate one word at a time, not byte. |
1405 | * Careful wrt unaligned access: can't just use "*(long*)data"! | 1406 | * Careful wrt unaligned access: can't just use "*(long*)data"! |
1406 | */ | 1407 | */ |
1407 | unsigned count = SHA3_IBLK_BYTES / sizeof(long); | 1408 | unsigned count = iblk_bytes / sizeof(long); |
1408 | long *buf = (long*)ctx->state; | 1409 | long *buf = (long*)ctx->state; |
1409 | do { | 1410 | do { |
1410 | long v; | 1411 | long v; |
@@ -1412,7 +1413,7 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) | |||
1412 | *buf++ ^= v; | 1413 | *buf++ ^= v; |
1413 | data += sizeof(long); | 1414 | data += sizeof(long); |
1414 | } while (--count); | 1415 | } while (--count); |
1415 | len -= SHA3_IBLK_BYTES; | 1416 | len -= iblk_bytes; |
1416 | do_block: | 1417 | do_block: |
1417 | sha3_process_block72(ctx->state); | 1418 | sha3_process_block72(ctx->state); |
1418 | } | 1419 | } |
@@ -1433,8 +1434,22 @@ void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) | |||
1433 | { | 1434 | { |
1434 | /* Padding */ | 1435 | /* Padding */ |
1435 | uint8_t *buf = (uint8_t*)ctx->state; | 1436 | uint8_t *buf = (uint8_t*)ctx->state; |
1436 | buf[ctx->bytes_queued] ^= 1; | 1437 | /* |
1437 | buf[SHA3_IBLK_BYTES - 1] ^= 0x80; | 1438 | * Keccak block padding is: add 1 bit after last bit of input, |
1439 | * then add zero bits until the end of block, and add the last 1 bit | ||
1440 | * (the last bit in the block) - the "10*1" pattern. | ||
1441 | * SHA3 standard appends additional two bits, 01, before that padding: | ||
1442 | * | ||
1443 | * SHA3-224(M) = KECCAK[448](M||01, 224) | ||
1444 | * SHA3-256(M) = KECCAK[512](M||01, 256) | ||
1445 | * SHA3-384(M) = KECCAK[768](M||01, 384) | ||
1446 | * SHA3-512(M) = KECCAK[1024](M||01, 512) | ||
1447 | * (M is the input, || is bit concatenation) | ||
1448 | * | ||
1449 | * The 6 below contains 01 "SHA3" bits and the first 1 "Keccak" bit: | ||
1450 | */ | ||
1451 | buf[ctx->bytes_queued] ^= 6; /* bit pattern 00000110 */ | ||
1452 | buf[ctx->input_block_bytes - 1] ^= 0x80; | ||
1438 | 1453 | ||
1439 | sha3_process_block72(ctx->state); | 1454 | sha3_process_block72(ctx->state); |
1440 | 1455 | ||