diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2025-07-07 08:21:44 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2025-07-07 08:21:44 +0200 |
| commit | c11730490ad68737120d569b9760e2c35e28977e (patch) | |
| tree | 199c6e305cfe96a74616865e80aadc52696e607a | |
| parent | 1a0913d57ce8287703cfe666d9240e3a147ea30d (diff) | |
libbb/yescrypt: remove redundant SHA256 HMAC implementation
function old new delta
hmac_blocks - 88 +88
static.PBKDF2_SHA256 176 213 +37
yescrypt_kdf32_body 1046 1052 +6
static.smix 759 762 +3
hmac_block 88 64 -24
HMAC_SHA256_Final 53 - -53
HMAC_SHA256_Buf 58 - -58
HMAC_SHA256_Init 159 - -159
------------------------------------------------------------------------------
(add/remove: 1/3 grow/shrink: 3/1 up/down: 134/-294) Total: -160 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | include/libbb.h | 10 | ||||
| -rw-r--r-- | libbb/hash_hmac.c | 10 | ||||
| -rw-r--r-- | libbb/yescrypt/alg-sha256.c | 94 | ||||
| -rw-r--r-- | libbb/yescrypt/alg-yescrypt-kdf.c | 24 | ||||
| -rw-r--r-- | networking/tls.c | 8 |
5 files changed, 48 insertions, 98 deletions
diff --git a/include/libbb.h b/include/libbb.h index 3f60acaa0..cbf723f7e 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -2253,12 +2253,20 @@ typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC; #define hmac_begin(ctx,key,key_size,begin) \ hmac_begin(ctx,key,key_size) #endif -void FAST_FUNC hmac_begin(hmac_ctx_t *ctx, uint8_t *key, unsigned key_size, md5sha_begin_func *begin); +void FAST_FUNC hmac_begin(hmac_ctx_t *ctx, const uint8_t *key, unsigned key_size, md5sha_begin_func *begin); static ALWAYS_INLINE void hmac_hash(hmac_ctx_t *ctx, const void *in, size_t len) { md5sha_hash(&ctx->hashed_key_xor_ipad, in, len); } unsigned FAST_FUNC hmac_end(hmac_ctx_t *ctx, uint8_t *out); +#if HMAC_ONLY_SHA256 +#define hmac_block(key,key_size,begin,in,sz,out) \ + hmac_block(key,key_size,in,sz,out) +#endif +unsigned FAST_FUNC hmac_block(const uint8_t *key, unsigned key_size, + md5sha_begin_func *begin, + const void *in, unsigned sz, + uint8_t *out); /* HMAC helpers for TLS: */ void FAST_FUNC hmac_hash_v(hmac_ctx_t *ctx, va_list va); unsigned FAST_FUNC hmac_peek_hash(hmac_ctx_t *ctx, uint8_t *out, ...); diff --git a/libbb/hash_hmac.c b/libbb/hash_hmac.c index 8cf936949..9e48e0f51 100644 --- a/libbb/hash_hmac.c +++ b/libbb/hash_hmac.c @@ -18,7 +18,7 @@ // if we often need HMAC hmac with the same key. // // text is often given in disjoint pieces. -void FAST_FUNC hmac_begin(hmac_ctx_t *ctx, uint8_t *key, unsigned key_size, md5sha_begin_func *begin) +void FAST_FUNC hmac_begin(hmac_ctx_t *ctx, const uint8_t *key, unsigned key_size, md5sha_begin_func *begin) { #if HMAC_ONLY_SHA256 #define begin sha256_begin @@ -64,6 +64,14 @@ unsigned FAST_FUNC hmac_end(hmac_ctx_t *ctx, uint8_t *out) return sha_end(&ctx->hashed_key_xor_opad, out); } +unsigned FAST_FUNC hmac_block(const uint8_t *key, unsigned key_size, md5sha_begin_func *begin, const void *in, unsigned sz, uint8_t *out) +{ + hmac_ctx_t ctx; + hmac_begin(&ctx, key, key_size, begin); + hmac_hash(&ctx, in, sz); + return hmac_end(&ctx, out); +} + /* TLS helpers */ void FAST_FUNC hmac_hash_v( diff --git a/libbb/yescrypt/alg-sha256.c b/libbb/yescrypt/alg-sha256.c index f56b905ad..1ccffa1e5 100644 --- a/libbb/yescrypt/alg-sha256.c +++ b/libbb/yescrypt/alg-sha256.c @@ -26,82 +26,6 @@ */ /** - * HMAC_SHA256_Init(ctx, K, Klen): - * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from - * ${K}. - */ -static void -HMAC_SHA256_Init(HMAC_SHA256_CTX *ctx, const void *_K, size_t Klen) -{ - uint8_t pad[64]; - uint8_t khash[32]; - const uint8_t *K = _K; - size_t i; - - /* If Klen > 64, the key is really SHA256(K). */ - if (Klen > 64) { - sha256_block(K, Klen, khash); - K = khash; - Klen = 32; - } - - /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */ - sha256_begin(&ctx->ictx); - memset(pad, 0x36, 64); - for (i = 0; i < Klen; i++) - pad[i] ^= K[i]; - sha256_hash(&ctx->ictx, pad, 64); - - /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */ - sha256_begin(&ctx->octx); - memset(pad, 0x5c, 64); - for (i = 0; i < Klen; i++) - pad[i] ^= K[i]; - sha256_hash(&ctx->octx, pad, 64); -} - -/** - * HMAC_SHA256_Update(ctx, in, len): - * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. - */ -static void -HMAC_SHA256_Update(HMAC_SHA256_CTX *ctx, const void *in, size_t len) -{ - /* Feed data to the inner SHA256 operation. */ - sha256_hash(&ctx->ictx, in, len); -} - -/** - * HMAC_SHA256_Final(ctx, digest): - * Output the HMAC-SHA256 of the data input to the context ${ctx} into the - * buffer ${digest}. - */ -static void -HMAC_SHA256_Final(HMAC_SHA256_CTX *ctx, void *digest) -{ - /* Finish the inner SHA256 operation. */ - sha256_end(&ctx->ictx, digest); /* using digest[] as scratch space */ - /* Feed the inner hash to the outer SHA256 operation. */ - sha256_hash(&ctx->octx, digest, 32); /* using digest[] as scratch space */ - /* Finish the outer SHA256 operation. */ - sha256_end(&ctx->octx, digest); -} - -/** - * HMAC_SHA256_Buf(K, Klen, in, len, digest): - * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of - * length ${Klen}, and write the result to ${digest}. - */ -static void -HMAC_SHA256_Buf(const void *K, size_t Klen, const void *in, size_t len, void *digest) -{ - HMAC_SHA256_CTX ctx; - HMAC_SHA256_Init(&ctx, K, Klen); - HMAC_SHA256_Update(&ctx, in, len); - HMAC_SHA256_Final(&ctx, digest); -} - -/** * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). @@ -111,15 +35,15 @@ PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt, size_t saltlen, uint64_t c, uint8_t *buf, size_t dkLen) { - HMAC_SHA256_CTX Phctx, PShctx, hctx; + hmac_ctx_t Phctx, PShctx; size_t i; /* Compute HMAC state after processing P. */ - HMAC_SHA256_Init(&Phctx, passwd, passwdlen); + hmac_begin(&Phctx, passwd, passwdlen, sha256_begin); /* Compute HMAC state after processing P and S. */ - memcpy(&PShctx, &Phctx, sizeof(HMAC_SHA256_CTX)); - HMAC_SHA256_Update(&PShctx, salt, saltlen); + PShctx = Phctx; + hmac_hash(&PShctx, salt, saltlen); /* Iterate through the blocks. */ for (i = 0; dkLen != 0; i++) { @@ -134,18 +58,16 @@ PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, ivec = SWAP_BE32((uint32_t)(i + 1)); /* Compute U_1 = PRF(P, S || INT(i)). */ - hctx = PShctx; - HMAC_SHA256_Update(&hctx, &ivec, 4); - HMAC_SHA256_Final(&hctx, T); + hmac_peek_hash(&PShctx, (void*)T, &ivec, 4, NULL); +//TODO: the above is a vararg function, might incur some ABI pain +//does libbb need a non-vararg version with just one (buf,len)? if (c > 1) { /* T_i = U_1 ... */ memcpy(U, T, 32); for (j = 2; j <= c; j++) { /* Compute U_j. */ - hctx = Phctx; - HMAC_SHA256_Update(&hctx, U, 32); - HMAC_SHA256_Final(&hctx, U); + hmac_peek_hash(&Phctx, (void*)U, U, 32, NULL); /* ... xor U_j ... */ for (k = 0; k < 32 / 8; k++) T[k] ^= U[k]; diff --git a/libbb/yescrypt/alg-yescrypt-kdf.c b/libbb/yescrypt/alg-yescrypt-kdf.c index 27ef2caa4..f1f06621e 100644 --- a/libbb/yescrypt/alg-yescrypt-kdf.c +++ b/libbb/yescrypt/alg-yescrypt-kdf.c @@ -735,8 +735,12 @@ static void smix(uint8_t *B, size_t r, uint32_t N, uint32_t p, uint32_t t, ctx_i->S0 = Si + Sbytes / 3 * 2; ctx_i->w = 0; if (i == 0) - HMAC_SHA256_Buf(Bp + (128 * r - 64), 64, - passwd, 32, passwd); + hmac_block( + /* key,len: */ Bp + (128 * r - 64), 64, + /* hash fn: */ sha256_begin, + /* in,len: */ passwd, 32, + /* outbuf: */ passwd + ); } smix1(Bp, r, Np, flags, Vp, NROM, VROM, XYp, ctx_i); smix2(Bp, r, p2floor(Np), Nloop_rw, flags, Vp, @@ -907,9 +911,12 @@ static int yescrypt_kdf32_body( S = (uint8_t *)XY + XY_size; if (flags) { - HMAC_SHA256_Buf("yescrypt-prehash", - (flags & YESCRYPT_PREHASH) ? 16 : 8, - passwd, passwdlen, sha256); + hmac_block( + /* key,len: */ (const void*)"yescrypt-prehash", (flags & YESCRYPT_PREHASH) ? 16 : 8, + /* hash fn: */ sha256_begin, + /* in,len: */ passwd, passwdlen, + /* outbuf: */ sha256 + ); passwd = sha256; passwdlen = sizeof(sha256); } @@ -946,7 +953,12 @@ static int yescrypt_kdf32_body( */ if (flags && !(flags & YESCRYPT_PREHASH)) { /* Compute ClientKey */ - HMAC_SHA256_Buf(dkp, sizeof(dk), "Client Key", 10, sha256); + hmac_block( + /* key,len: */ dkp, sizeof(dk), + /* hash fn: */ sha256_begin, + /* in,len: */ "Client Key", 10, + /* outbuf: */ sha256 + ); /* Compute StoredKey */ { size_t clen = /*buflen:*/32; diff --git a/networking/tls.c b/networking/tls.c index b8caf1e4b..098cf7cac 100644 --- a/networking/tls.c +++ b/networking/tls.c @@ -533,10 +533,10 @@ static void *tls_get_zeroed_outbuf(tls_state_t *tls, int len) /* Calculate the HMAC over the list of blocks */ #if !ENABLE_FEATURE_TLS_SHA1 -#define hmac_block(tls,out,key,key_size,...) \ - hmac_block(out,key,key_size, __VA_ARGS__) +#define hmac_blocks(tls,out,key,key_size,...) \ + hmac_blocks(out,key,key_size, __VA_ARGS__) #endif -static unsigned hmac_block(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...) +static unsigned hmac_blocks(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...) { hmac_ctx_t ctx; va_list va; @@ -575,7 +575,7 @@ static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, un xhdr->len16_lo = size & 0xff; /* Calculate MAC signature */ - hmac_block(tls, buf + size, /* result */ + hmac_blocks(tls, buf + size, /* result */ tls->client_write_MAC_key, TLS_MAC_SIZE(tls), &tls->write_seq64_be, sizeof(tls->write_seq64_be), xhdr, RECHDR_LEN, |
