From 71c7f71de5789daff5bc6dedba82544fa97eec84 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 26 Apr 2021 20:04:25 -0400 Subject: [PATCH] aesni: Avoid modifying session keys in hmac_update() Otherwise aesni_process() is not thread-safe for AES+SHA-HMAC transforms, since hmac_update() updates the caller-supplied key directly to create the derived key. Use a buffer on the stack to store a copy of the key used for computing inner and outer digests. This is a direct commit to stable/12 as the bug is not present in later branches. Approved by: so Security: EN-21:11.aesni Reviewed by: kib (cherry picked from commit 62e32cf9140e6c13663dcd69ec3b3c7ca4579782) --- sys/crypto/aesni/aesni.c | 18 ++++++++++-------- sys/crypto/aesni/aesni.h | 6 ++++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/sys/crypto/aesni/aesni.c b/sys/crypto/aesni/aesni.c index 76e63786187..594aa59b704 100644 --- a/sys/crypto/aesni/aesni.c +++ b/sys/crypto/aesni/aesni.c @@ -655,10 +655,10 @@ hmac_internal(void *ctx, uint32_t *res, { size_t i; - for (i = 0; i < 64; i++) + for (i = 0; i < AESNI_SHA_BLOCK_LEN; i++) key[i] ^= xorbyte; - update(ctx, key, 64); - for (i = 0; i < 64; i++) + update(ctx, key, AESNI_SHA_BLOCK_LEN); + for (i = 0; i < AESNI_SHA_BLOCK_LEN; i++) key[i] ^= xorbyte; crypto_apply(crpflags, __DECONST(void *, buf), off, buflen, @@ -883,6 +883,7 @@ aesni_cipher_mac(struct aesni_session *ses, struct cryptodesc *crd, struct SHA256Context sha2 __aligned(16); struct sha1_ctxt sha1 __aligned(16); } sctx; + uint8_t hmac_key[AESNI_SHA_BLOCK_LEN] __aligned(16); uint32_t res[SHA2_256_HASH_LEN / sizeof(uint32_t)]; int hashlen, error; void *ctx; @@ -946,15 +947,16 @@ aesni_cipher_mac(struct aesni_session *ses, struct cryptodesc *crd, } if (hmac) { + memcpy(hmac_key, ses->hmac_key, AESNI_SHA_BLOCK_LEN); + /* Inner hash: (K ^ IPAD) || data */ InitFn(ctx); - hmac_internal(ctx, res, UpdateFn, FinalizeFn, ses->hmac_key, - 0x36, crp->crp_buf, crd->crd_skip, crd->crd_len, - crp->crp_flags); + hmac_internal(ctx, res, UpdateFn, FinalizeFn, hmac_key, 0x36, + crp->crp_buf, crd->crd_skip, crd->crd_len, crp->crp_flags); /* Outer hash: (K ^ OPAD) || inner hash */ InitFn(ctx); - hmac_internal(ctx, res, UpdateFn, FinalizeFn, ses->hmac_key, - 0x5C, res, 0, hashlen, 0); + hmac_internal(ctx, res, UpdateFn, FinalizeFn, hmac_key, 0x5C, + res, 0, hashlen, 0); } else { InitFn(ctx); crypto_apply(crp->crp_flags, crp->crp_buf, crd->crd_skip, diff --git a/sys/crypto/aesni/aesni.h b/sys/crypto/aesni/aesni.h index eeb5b436187..d1e7abaa606 100644 --- a/sys/crypto/aesni/aesni.h +++ b/sys/crypto/aesni/aesni.h @@ -52,12 +52,14 @@ #define AES256_ROUNDS 14 #define AES_SCHED_LEN ((AES256_ROUNDS + 1) * AES_BLOCK_LEN) +/* SHA1, SHA2-224 and SHA2-256 only. */ +#define AESNI_SHA_BLOCK_LEN 64 + struct aesni_session { uint8_t enc_schedule[AES_SCHED_LEN] __aligned(16); uint8_t dec_schedule[AES_SCHED_LEN] __aligned(16); uint8_t xts_schedule[AES_SCHED_LEN] __aligned(16); - /* Same as the SHA256 Blocksize. */ - uint8_t hmac_key[SHA1_BLOCK_LEN] __aligned(16); + uint8_t hmac_key[AESNI_SHA_BLOCK_LEN]; int algo; int rounds; /* uint8_t *ses_ictx; */ -- 2.45.0