2025-06-22 Niels Möller <nisse@lysator.liu.se>
+ * hmac-internal.h (_NETTLE_HMAC_DIGEST): Do both inner and outer
+ digest. Update all callers.
+ (_NETTLE_HMAC_DIGEST_U): Variant for digest_size == block_size.
+
HMAC context reductions: hmac_sha256_ctx reduced from 336 bytes to
192, hmac_sha512_ctx from 648 to 376, hmac_sha1_ctx from 312 to 168.
hmac_gosthash94_digest(struct hmac_gosthash94_ctx *ctx,
uint8_t *digest)
{
- /* Using _NETTLE_HMAC_DIGEST doesn't work since
+ /* Needs a call to gosthash94_update, since
GOSTHASH94_DIGEST_SIZE == GOSTHASH94_BLOCK_SIZE. */
- gosthash94_digest (&ctx->state, ctx->state.block);
- memcpy (&ctx->state, ctx->outer, sizeof (ctx->outer));
- gosthash94_update (&ctx->state, GOSTHASH94_DIGEST_SIZE, ctx->state.block);
- gosthash94_digest (&ctx->state, digest);
- memcpy (&ctx->state, ctx->inner, sizeof (ctx->inner));
+ _NETTLE_HMAC_DIGEST_U (ctx->outer, ctx->inner, &ctx->state, gosthash94_digest,
+ gosthash94_update, digest);
}
void
hmac_gosthash94cp_digest(struct hmac_gosthash94cp_ctx *ctx,
uint8_t *digest)
{
- /* Using _NETTLE_HMAC_DIGEST doesn't work since
+ /* Needs a call to gosthash94cp_update, since
GOSTHASH94CP_DIGEST_SIZE == GOSTHASH94CP_BLOCK_SIZE. */
- gosthash94cp_digest (&ctx->state, ctx->state.block);
- memcpy (&ctx->state, ctx->outer, sizeof (ctx->outer));
- gosthash94cp_update (&ctx->state, GOSTHASH94CP_DIGEST_SIZE, ctx->state.block);
- gosthash94cp_digest (&ctx->state, digest);
- memcpy (&ctx->state, ctx->inner, sizeof (ctx->inner));
+ _NETTLE_HMAC_DIGEST_U (ctx->outer, ctx->inner, &ctx->state, gosthash94cp_digest,
+ gosthash94cp_update, digest);
}
const struct nettle_hash *hash,
size_t key_size, const uint8_t *key);
-#define _NETTLE_HMAC_DIGEST(outer, inner, ctx, f, digest) do { \
- memcpy ((ctx), (outer), sizeof (outer)); \
- f ((ctx), (digest)); \
- memcpy ((ctx), (inner), sizeof ((inner))); \
+/* Digest operation for the common case that digest_size < block_size. */
+#define _NETTLE_HMAC_DIGEST(outer, inner, ctx, digest, digest_size, out) do { \
+ digest((ctx), (ctx)->block); \
+ memcpy ((ctx), (outer), sizeof (outer)); \
+ (ctx)->index = (digest_size); \
+ digest ((ctx), (out)); \
+ memcpy ((ctx), (inner), sizeof (inner)); \
+ } while (0)
+
+/* Digest operation for the corner case that digest_size == block_size (e.g,
+ ghosthash and streebog512). */
+#define _NETTLE_HMAC_DIGEST_U(outer, inner, ctx, digest, update, out) do { \
+ digest((ctx), (ctx)->block); \
+ memcpy ((ctx), (outer), sizeof (outer)); \
+ update ((ctx), sizeof( (ctx)->block), (ctx)->block); \
+ digest ((ctx), (out)); \
+ memcpy ((ctx), (inner), sizeof (inner)); \
} while (0)
#endif /* NETTLE_HMAC_INTERNAL_H_INCLUDED */
hmac_md5_digest(struct hmac_md5_ctx *ctx,
uint8_t *digest)
{
- md5_digest (&ctx->state, ctx->state.block);
- ctx->state.index = MD5_DIGEST_SIZE;
- _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, md5_digest, digest);
+ _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, md5_digest,
+ MD5_DIGEST_SIZE, digest);
}
hmac_ripemd160_digest(struct hmac_ripemd160_ctx *ctx,
uint8_t *digest)
{
- ripemd160_digest (&ctx->state, ctx->state.block);
- ctx->state.index = RIPEMD160_DIGEST_SIZE;
- _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, ripemd160_digest, digest);
+ _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, ripemd160_digest,
+ RIPEMD160_DIGEST_SIZE, digest);
}
hmac_sha1_digest(struct hmac_sha1_ctx *ctx,
uint8_t *digest)
{
- sha1_digest (&ctx->state, ctx->state.block);
- ctx->state.index = SHA1_DIGEST_SIZE;
- _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha1_digest, digest);
+ _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha1_digest,
+ SHA1_DIGEST_SIZE, digest);
}
hmac_sha224_digest(struct hmac_sha224_ctx *ctx,
uint8_t *digest)
{
- sha224_digest (&ctx->state, ctx->state.block);
- ctx->state.index = SHA224_DIGEST_SIZE;
- _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha224_digest, digest);
+ _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha224_digest,
+ SHA224_DIGEST_SIZE, digest);
}
hmac_sha256_digest(struct hmac_sha256_ctx *ctx,
uint8_t *digest)
{
- sha256_digest (&ctx->state, ctx->state.block);
- ctx->state.index = SHA256_DIGEST_SIZE;
- _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha256_digest, digest);
+ _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha256_digest,
+ SHA256_DIGEST_SIZE, digest);
}
hmac_sha384_digest(struct hmac_sha512_ctx *ctx,
uint8_t *digest)
{
- sha384_digest (&ctx->state, ctx->state.block);
- ctx->state.index = SHA384_DIGEST_SIZE;
- _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha384_digest, digest);
+ _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha384_digest,
+ SHA384_DIGEST_SIZE, digest);
}
hmac_sha512_digest(struct hmac_sha512_ctx *ctx,
uint8_t *digest)
{
- sha512_digest (&ctx->state, ctx->state.block);
- ctx->state.index = SHA512_DIGEST_SIZE;
- _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha512_digest, digest);
+ _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha512_digest,
+ SHA512_DIGEST_SIZE, digest);
}
hmac_sm3_digest(struct hmac_sm3_ctx *ctx,
uint8_t *digest)
{
- sm3_digest (&ctx->state, ctx->state.block);
- ctx->state.index = SM3_DIGEST_SIZE;
- _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sm3_digest, digest);
+ _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sm3_digest,
+ SM3_DIGEST_SIZE, digest);
}
hmac_streebog512_digest(struct hmac_streebog512_ctx *ctx,
uint8_t *digest)
{
- /* Using _NETTLE_HMAC_DIGEST doesn't work since
- STREEBOG512_DIGEST_SIZE == STREEBOG512_BLOCK_SIZE. */
- streebog512_digest (&ctx->state, ctx->state.block);
- memcpy (&ctx->state, ctx->outer, sizeof (ctx->outer));
- streebog512_update (&ctx->state, STREEBOG512_DIGEST_SIZE, ctx->state.block);
- streebog512_digest (&ctx->state, digest);
- memcpy (&ctx->state, ctx->inner, sizeof (ctx->inner));
+ /* Needs a call to streebog512_update, since STREEBOG512_DIGEST_SIZE
+ == STREEBOG512_BLOCK_SIZE. */
+ _NETTLE_HMAC_DIGEST_U (ctx->outer, ctx->inner, &ctx->state, streebog512_digest,
+ streebog512_update, digest);
}
void
hmac_streebog256_digest(struct hmac_streebog256_ctx *ctx,
uint8_t *digest)
{
- streebog256_digest (&ctx->state, ctx->state.block);
- ctx->state.index = STREEBOG256_DIGEST_SIZE;
- _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, streebog256_digest, digest);
+ _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, streebog256_digest,
+ STREEBOG256_DIGEST_SIZE, digest);
}