[git commit] libbb/yescrypt: remove redundant SHA256 HMAC implementation
Denys Vlasenko
vda.linux at googlemail.com
Mon Jul 7 06:21:44 UTC 2025
commit: https://git.busybox.net/busybox/commit/?id=c11730490ad68737120d569b9760e2c35e28977e
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master
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 at googlemail.com>
---
include/libbb.h | 10 ++++-
libbb/hash_hmac.c | 10 ++++-
libbb/yescrypt/alg-sha256.c | 94 ++++-----------------------------------
libbb/yescrypt/alg-yescrypt-kdf.c | 24 +++++++---
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
@@ -25,82 +25,6 @@
* SUCH DAMAGE.
*/
-/**
- * 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
@@ -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,
More information about the busybox-cvs
mailing list