git: 6113a08b98e4 - main - cryptosoft: Fully support per-operation keys for auth algorithms.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 09 Dec 2021 20:17:47 UTC
The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=6113a08b98e403de5b92cc0a30fdc60489eccc48 commit 6113a08b98e403de5b92cc0a30fdc60489eccc48 Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2021-12-09 19:52:42 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2021-12-09 19:52:42 +0000 cryptosoft: Fully support per-operation keys for auth algorithms. Only pre-allocate auth contexts when a session-wide key is provided or for sessions without keys. For sessions with per-operation keys, always initialize the on-stack context directly rather than initializing the session context in swcr_authprepare (now removed) and then copying that session context into the on-stack context. This approach permits parallel auth operations without needing a serializing lock. In addition, the previous code assumed that auth sessions always provided an initial key unlike cipher sessions which assume either an initial key or per-op keys. While here, fix the Blake2 auth transforms to function like other auth transforms where Setkey is invoked after Init rather than before. Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D33316 --- sys/crypto/blake2/blake2-sw.c | 38 +++++------- sys/opencrypto/cryptosoft.c | 140 +++++++++++++++++++++--------------------- 2 files changed, 83 insertions(+), 95 deletions(-) diff --git a/sys/crypto/blake2/blake2-sw.c b/sys/crypto/blake2/blake2-sw.c index 449ef2be94f5..dafe0e3f84a4 100644 --- a/sys/crypto/blake2/blake2-sw.c +++ b/sys/crypto/blake2/blake2-sw.c @@ -28,8 +28,6 @@ extern int blake2s_ref(uint8_t *out, const void *in, const void *key, struct blake2b_xform_ctx { blake2b_state state; - uint8_t key[BLAKE2B_KEYBYTES]; - uint16_t klen; }; CTASSERT(sizeof(union authctx) >= sizeof(struct blake2b_xform_ctx)); @@ -39,24 +37,21 @@ blake2b_xform_init(void *vctx) struct blake2b_xform_ctx *ctx = vctx; int rc; - if (ctx->klen > 0) - rc = blake2b_init_key_ref(&ctx->state, BLAKE2B_OUTBYTES, - ctx->key, ctx->klen); - else - rc = blake2b_init_ref(&ctx->state, BLAKE2B_OUTBYTES); + rc = blake2b_init_ref(&ctx->state, BLAKE2B_OUTBYTES); if (rc != 0) - panic("blake2b_init_key: invalid arguments"); + panic("blake2b_init: invalid arguments"); } static void blake2b_xform_setkey(void *vctx, const uint8_t *key, u_int klen) { struct blake2b_xform_ctx *ctx = vctx; + int rc; - if (klen > sizeof(ctx->key)) - panic("invalid klen %u", (unsigned)klen); - memcpy(ctx->key, key, klen); - ctx->klen = klen; + rc = blake2b_init_key_ref(&ctx->state, BLAKE2B_OUTBYTES, key, + klen); + if (rc != 0) + panic("blake2b_init_key: invalid arguments"); } static int @@ -96,8 +91,6 @@ const struct auth_hash auth_hash_blake2b = { struct blake2s_xform_ctx { blake2s_state state; - uint8_t key[BLAKE2S_KEYBYTES]; - uint16_t klen; }; CTASSERT(sizeof(union authctx) >= sizeof(struct blake2s_xform_ctx)); @@ -107,24 +100,21 @@ blake2s_xform_init(void *vctx) struct blake2s_xform_ctx *ctx = vctx; int rc; - if (ctx->klen > 0) - rc = blake2s_init_key_ref(&ctx->state, BLAKE2S_OUTBYTES, - ctx->key, ctx->klen); - else - rc = blake2s_init_ref(&ctx->state, BLAKE2S_OUTBYTES); + rc = blake2s_init_ref(&ctx->state, BLAKE2S_OUTBYTES); if (rc != 0) - panic("blake2s_init_key: invalid arguments"); + panic("blake2s_init: invalid arguments"); } static void blake2s_xform_setkey(void *vctx, const uint8_t *key, u_int klen) { struct blake2s_xform_ctx *ctx = vctx; + int rc; - if (klen > sizeof(ctx->key)) - panic("invalid klen %u", (unsigned)klen); - memcpy(ctx->key, key, klen); - ctx->klen = klen; + rc = blake2s_init_key_ref(&ctx->state, BLAKE2S_OUTBYTES, key, + klen); + if (rc != 0) + panic("blake2s_init_key: invalid arguments"); } static int diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c index b6bb7979c536..576efeaec20f 100644 --- a/sys/opencrypto/cryptosoft.c +++ b/sys/opencrypto/cryptosoft.c @@ -65,6 +65,7 @@ struct swcr_auth { void *sw_octx; const struct auth_hash *sw_axf; uint16_t sw_mlen; + bool sw_hmac; }; struct swcr_encdec { @@ -283,33 +284,6 @@ swcr_encdec(struct swcr_session *ses, struct cryptop *crp) return (0); } -static void -swcr_authprepare(const struct auth_hash *axf, struct swcr_auth *sw, - const uint8_t *key, int klen) -{ - - switch (axf->type) { - case CRYPTO_SHA1_HMAC: - case CRYPTO_SHA2_224_HMAC: - case CRYPTO_SHA2_256_HMAC: - case CRYPTO_SHA2_384_HMAC: - case CRYPTO_SHA2_512_HMAC: - case CRYPTO_NULL_HMAC: - case CRYPTO_RIPEMD160_HMAC: - hmac_init_ipad(axf, key, klen, sw->sw_ictx); - hmac_init_opad(axf, key, klen, sw->sw_octx); - break; - case CRYPTO_POLY1305: - case CRYPTO_BLAKE2B: - case CRYPTO_BLAKE2S: - axf->Setkey(sw->sw_ictx, key, klen); - axf->Init(sw->sw_ictx); - break; - default: - panic("%s: algorithm %d doesn't use keys", __func__, axf->type); - } -} - /* * Compute or verify hash. */ @@ -318,7 +292,7 @@ swcr_authcompute(struct swcr_session *ses, struct cryptop *crp) { u_char aalg[HASH_MAX_LEN]; const struct crypto_session_params *csp; - struct swcr_auth *sw; + const struct swcr_auth *sw; const struct auth_hash *axf; union authctx ctx; int err; @@ -329,11 +303,16 @@ swcr_authcompute(struct swcr_session *ses, struct cryptop *crp) csp = crypto_get_params(crp->crp_session); if (crp->crp_auth_key != NULL) { - swcr_authprepare(axf, sw, crp->crp_auth_key, - csp->csp_auth_klen); - } - - bcopy(sw->sw_ictx, &ctx, axf->ctxsize); + if (sw->sw_hmac) { + hmac_init_ipad(axf, crp->crp_auth_key, + csp->csp_auth_klen, &ctx); + } else { + axf->Init(&ctx); + axf->Setkey(&ctx, crp->crp_auth_key, + csp->csp_auth_klen); + } + } else + memcpy(&ctx, sw->sw_ictx, axf->ctxsize); if (crp->crp_aad != NULL) err = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length); @@ -358,8 +337,12 @@ swcr_authcompute(struct swcr_session *ses, struct cryptop *crp) axf->Update(&ctx, crp->crp_esn, 4); axf->Final(aalg, &ctx); - if (sw->sw_octx != NULL) { - bcopy(sw->sw_octx, &ctx, axf->ctxsize); + if (sw->sw_hmac) { + if (crp->crp_auth_key != NULL) + hmac_init_opad(axf, crp->crp_auth_key, + csp->csp_auth_klen, &ctx); + else + memcpy(&ctx, sw->sw_octx, axf->ctxsize); axf->Update(&ctx, aalg, axf->hashsize); axf->Final(aalg, &ctx); } @@ -394,7 +377,7 @@ swcr_gmac(struct swcr_session *ses, struct cryptop *crp) struct crypto_buffer_cursor cc; const u_char *inblk; union authctx ctx; - struct swcr_auth *swa; + const struct swcr_auth *swa; const struct auth_hash *axf; uint32_t *blkp; size_t len; @@ -402,12 +385,17 @@ swcr_gmac(struct swcr_session *ses, struct cryptop *crp) swa = &ses->swcr_auth; axf = swa->sw_axf; - - bcopy(swa->sw_ictx, &ctx, axf->ctxsize); blksz = GMAC_BLOCK_LEN; KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch", __func__)); + if (crp->crp_auth_key != NULL) { + axf->Init(&ctx); + axf->Setkey(&ctx, crp->crp_auth_key, + crypto_get_params(crp->crp_session)->csp_auth_klen); + } else + memcpy(&ctx, swa->sw_ictx, axf->ctxsize); + /* Initialize the IV */ ivlen = AES_GCM_IV_LEN; crypto_read_iv(crp, iv); @@ -694,7 +682,7 @@ swcr_ccm_cbc_mac(struct swcr_session *ses, struct cryptop *crp) u_char tag[AES_CBC_MAC_HASH_LEN]; union authctx ctx; const struct crypto_session_params *csp; - struct swcr_auth *swa; + const struct swcr_auth *swa; const struct auth_hash *axf; int error, ivlen, len; @@ -702,7 +690,11 @@ swcr_ccm_cbc_mac(struct swcr_session *ses, struct cryptop *crp) swa = &ses->swcr_auth; axf = swa->sw_axf; - bcopy(swa->sw_ictx, &ctx, axf->ctxsize); + if (crp->crp_auth_key != NULL) { + axf->Init(&ctx); + axf->Setkey(&ctx, crp->crp_auth_key, csp->csp_auth_klen); + } else + memcpy(&ctx, swa->sw_ictx, axf->ctxsize); /* Initialize the IV */ ivlen = csp->csp_ivlen; @@ -1218,9 +1210,12 @@ swcr_setup_auth(struct swcr_session *ses, swa->sw_mlen = axf->hashsize; else swa->sw_mlen = csp->csp_auth_mlen; - swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); - if (swa->sw_ictx == NULL) - return (ENOBUFS); + if (csp->csp_auth_klen == 0 || csp->csp_auth_key != NULL) { + swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, + M_NOWAIT); + if (swa->sw_ictx == NULL) + return (ENOBUFS); + } switch (csp->csp_auth_alg) { case CRYPTO_SHA1_HMAC: @@ -1230,18 +1225,17 @@ swcr_setup_auth(struct swcr_session *ses, case CRYPTO_SHA2_512_HMAC: case CRYPTO_NULL_HMAC: case CRYPTO_RIPEMD160_HMAC: - swa->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA, - M_NOWAIT); - if (swa->sw_octx == NULL) - return (ENOBUFS); - + swa->sw_hmac = true; if (csp->csp_auth_key != NULL) { - swcr_authprepare(axf, swa, csp->csp_auth_key, - csp->csp_auth_klen); + swa->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA, + M_NOWAIT); + if (swa->sw_octx == NULL) + return (ENOBUFS); + hmac_init_ipad(axf, csp->csp_auth_key, + csp->csp_auth_klen, swa->sw_ictx); + hmac_init_opad(axf, csp->csp_auth_key, + csp->csp_auth_klen, swa->sw_octx); } - - if (csp->csp_mode == CSP_MODE_DIGEST) - ses->swcr_process = swcr_authcompute; break; case CRYPTO_SHA1: case CRYPTO_SHA2_224: @@ -1249,37 +1243,41 @@ swcr_setup_auth(struct swcr_session *ses, case CRYPTO_SHA2_384: case CRYPTO_SHA2_512: axf->Init(swa->sw_ictx); - if (csp->csp_mode == CSP_MODE_DIGEST) - ses->swcr_process = swcr_authcompute; break; case CRYPTO_AES_NIST_GMAC: - axf->Init(swa->sw_ictx); - axf->Setkey(swa->sw_ictx, csp->csp_auth_key, - csp->csp_auth_klen); - if (csp->csp_mode == CSP_MODE_DIGEST) - ses->swcr_process = swcr_gmac; - break; + case CRYPTO_AES_CCM_CBC_MAC: case CRYPTO_POLY1305: + if (csp->csp_auth_key != NULL) { + axf->Init(swa->sw_ictx); + axf->Setkey(swa->sw_ictx, csp->csp_auth_key, + csp->csp_auth_klen); + } + break; case CRYPTO_BLAKE2B: case CRYPTO_BLAKE2S: /* * Blake2b and Blake2s support an optional key but do * not require one. */ - if (csp->csp_auth_klen == 0 || csp->csp_auth_key != NULL) + if (csp->csp_auth_klen == 0) + axf->Init(swa->sw_ictx); + else if (csp->csp_auth_key != NULL) axf->Setkey(swa->sw_ictx, csp->csp_auth_key, csp->csp_auth_klen); - axf->Init(swa->sw_ictx); - if (csp->csp_mode == CSP_MODE_DIGEST) - ses->swcr_process = swcr_authcompute; break; - case CRYPTO_AES_CCM_CBC_MAC: - axf->Init(swa->sw_ictx); - axf->Setkey(swa->sw_ictx, csp->csp_auth_key, - csp->csp_auth_klen); - if (csp->csp_mode == CSP_MODE_DIGEST) + } + + if (csp->csp_mode == CSP_MODE_DIGEST) { + switch (csp->csp_auth_alg) { + case CRYPTO_AES_NIST_GMAC: + ses->swcr_process = swcr_gmac; + break; + case CRYPTO_AES_CCM_CBC_MAC: ses->swcr_process = swcr_ccm_cbc_mac; - break; + break; + default: + ses->swcr_process = swcr_authcompute; + } } return (0);