git: 7051c5796ff4 - main - cryptosoft: Consolidate calls to explicit_bzero.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 17 Dec 2021 22:00:09 UTC
The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=7051c5796ff44e7883f93dccc06e25f0711937e1 commit 7051c5796ff44e7883f93dccc06e25f0711937e1 Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2021-12-17 21:58:58 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2021-12-17 21:58:58 +0000 cryptosoft: Consolidate calls to explicit_bzero. Group sensitive on-stack variables into anonymous structs so that they can be cleared with a single call to explicit_bzero rather than multiple calls. Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D33527 --- sys/opencrypto/cryptosoft.c | 209 ++++++++++++++++++++++---------------------- 1 file changed, 103 insertions(+), 106 deletions(-) diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c index 8d39eec19b88..0cc4e56550f3 100644 --- a/sys/opencrypto/cryptosoft.c +++ b/sys/opencrypto/cryptosoft.c @@ -237,11 +237,14 @@ swcr_encdec(const struct swcr_session *ses, struct cryptop *crp) static int swcr_authcompute(const struct swcr_session *ses, struct cryptop *crp) { - u_char aalg[HASH_MAX_LEN]; + struct { + union authctx ctx; + u_char aalg[HASH_MAX_LEN]; + u_char uaalg[HASH_MAX_LEN]; + } s; const struct crypto_session_params *csp; const struct swcr_auth *sw; const struct auth_hash *axf; - union authctx ctx; int err; sw = &ses->swcr_auth; @@ -252,20 +255,20 @@ swcr_authcompute(const struct swcr_session *ses, struct cryptop *crp) if (crp->crp_auth_key != NULL) { if (sw->sw_hmac) { hmac_init_ipad(axf, crp->crp_auth_key, - csp->csp_auth_klen, &ctx); + csp->csp_auth_klen, &s.ctx); } else { - axf->Init(&ctx); - axf->Setkey(&ctx, crp->crp_auth_key, + axf->Init(&s.ctx); + axf->Setkey(&s.ctx, crp->crp_auth_key, csp->csp_auth_klen); } } else - memcpy(&ctx, sw->sw_ictx, axf->ctxsize); + memcpy(&s.ctx, sw->sw_ictx, axf->ctxsize); if (crp->crp_aad != NULL) - err = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length); + err = axf->Update(&s.ctx, crp->crp_aad, crp->crp_aad_length); else err = crypto_apply(crp, crp->crp_aad_start, crp->crp_aad_length, - axf->Update, &ctx); + axf->Update, &s.ctx); if (err) goto out; @@ -273,41 +276,37 @@ swcr_authcompute(const struct swcr_session *ses, struct cryptop *crp) CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) err = crypto_apply_buf(&crp->crp_obuf, crp->crp_payload_output_start, crp->crp_payload_length, - axf->Update, &ctx); + axf->Update, &s.ctx); else err = crypto_apply(crp, crp->crp_payload_start, - crp->crp_payload_length, axf->Update, &ctx); + crp->crp_payload_length, axf->Update, &s.ctx); if (err) goto out; if (csp->csp_flags & CSP_F_ESN) - axf->Update(&ctx, crp->crp_esn, 4); + axf->Update(&s.ctx, crp->crp_esn, 4); - axf->Final(aalg, &ctx); + axf->Final(s.aalg, &s.ctx); if (sw->sw_hmac) { if (crp->crp_auth_key != NULL) hmac_init_opad(axf, crp->crp_auth_key, - csp->csp_auth_klen, &ctx); + csp->csp_auth_klen, &s.ctx); else - memcpy(&ctx, sw->sw_octx, axf->ctxsize); - axf->Update(&ctx, aalg, axf->hashsize); - axf->Final(aalg, &ctx); + memcpy(&s.ctx, sw->sw_octx, axf->ctxsize); + axf->Update(&s.ctx, s.aalg, axf->hashsize); + axf->Final(s.aalg, &s.ctx); } if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { - u_char uaalg[HASH_MAX_LEN]; - - crypto_copydata(crp, crp->crp_digest_start, sw->sw_mlen, uaalg); - if (timingsafe_bcmp(aalg, uaalg, sw->sw_mlen) != 0) + crypto_copydata(crp, crp->crp_digest_start, sw->sw_mlen, s.uaalg); + if (timingsafe_bcmp(s.aalg, s.uaalg, sw->sw_mlen) != 0) err = EBADMSG; - explicit_bzero(uaalg, sizeof(uaalg)); } else { /* Inject the authentication data */ - crypto_copyback(crp, crp->crp_digest_start, sw->sw_mlen, aalg); + crypto_copyback(crp, crp->crp_digest_start, sw->sw_mlen, s.aalg); } - explicit_bzero(aalg, sizeof(aalg)); out: - explicit_bzero(&ctx, sizeof(ctx)); + explicit_bzero(&s, sizeof(s)); return (err); } @@ -317,12 +316,15 @@ CTASSERT(INT_MAX <= (uint64_t)-1); /* GCM: associated data <= 2^64-1 */ static int swcr_gmac(const struct swcr_session *ses, struct cryptop *crp) { - uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; - u_char *blk = (u_char *)blkbuf; - u_char tag[GMAC_DIGEST_LEN]; + struct { + union authctx ctx; + uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; + u_char tag[GMAC_DIGEST_LEN]; + u_char tag2[GMAC_DIGEST_LEN]; + } s; + u_char *blk = (u_char *)s.blkbuf; struct crypto_buffer_cursor cc; const u_char *inblk; - union authctx ctx; const struct swcr_auth *swa; const struct auth_hash *axf; uint32_t *blkp; @@ -336,17 +338,17 @@ swcr_gmac(const struct swcr_session *ses, struct cryptop *crp) __func__)); if (crp->crp_auth_key != NULL) { - axf->Init(&ctx); - axf->Setkey(&ctx, crp->crp_auth_key, + axf->Init(&s.ctx); + axf->Setkey(&s.ctx, crp->crp_auth_key, crypto_get_params(crp->crp_session)->csp_auth_klen); } else - memcpy(&ctx, swa->sw_ictx, axf->ctxsize); + memcpy(&s.ctx, swa->sw_ictx, axf->ctxsize); /* Initialize the IV */ ivlen = AES_GCM_IV_LEN; crypto_read_iv(crp, blk); - axf->Reinit(&ctx, blk, ivlen); + axf->Reinit(&s.ctx, blk, ivlen); crypto_cursor_init(&cc, &crp->crp_buf); crypto_cursor_advance(&cc, crp->crp_payload_start); for (resid = crp->crp_payload_length; resid >= blksz; resid -= len) { @@ -359,47 +361,46 @@ swcr_gmac(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_copydata(&cc, len, blk); inblk = blk; } - axf->Update(&ctx, inblk, len); + axf->Update(&s.ctx, inblk, len); } if (resid > 0) { memset(blk, 0, blksz); crypto_cursor_copydata(&cc, resid, blk); - axf->Update(&ctx, blk, blksz); + axf->Update(&s.ctx, blk, blksz); } /* length block */ memset(blk, 0, blksz); blkp = (uint32_t *)blk + 1; *blkp = htobe32(crp->crp_payload_length * 8); - axf->Update(&ctx, blk, blksz); + axf->Update(&s.ctx, blk, blksz); /* Finalize MAC */ - axf->Final(tag, &ctx); + axf->Final(s.tag, &s.ctx); error = 0; if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { - u_char tag2[GMAC_DIGEST_LEN]; - crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, - tag2); - if (timingsafe_bcmp(tag, tag2, swa->sw_mlen) != 0) + s.tag2); + if (timingsafe_bcmp(s.tag, s.tag2, swa->sw_mlen) != 0) error = EBADMSG; - explicit_bzero(tag2, sizeof(tag2)); } else { /* Inject the authentication data */ - crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); + crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, s.tag); } - explicit_bzero(blkbuf, sizeof(blkbuf)); - explicit_bzero(tag, sizeof(tag)); + explicit_bzero(&s, sizeof(s)); return (error); } static int swcr_gcm(const struct swcr_session *ses, struct cryptop *crp) { - uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; - u_char *blk = (u_char *)blkbuf; - u_char tag[GMAC_DIGEST_LEN]; + struct { + uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; + u_char tag[GMAC_DIGEST_LEN]; + u_char tag2[GMAC_DIGEST_LEN]; + } s; + u_char *blk = (u_char *)s.blkbuf; struct crypto_buffer_cursor cc_in, cc_out; const u_char *inblk; u_char *outblk; @@ -513,17 +514,14 @@ swcr_gcm(const struct swcr_session *ses, struct cryptop *crp) exf->update(ctx, blk, blksz); /* Finalize MAC */ - exf->final(tag, ctx); + exf->final(s.tag, ctx); /* Validate tag */ error = 0; if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { - u_char tag2[GMAC_DIGEST_LEN]; - - crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, tag2); - - r = timingsafe_bcmp(tag, tag2, swa->sw_mlen); - explicit_bzero(tag2, sizeof(tag2)); + crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, + s.tag2); + r = timingsafe_bcmp(s.tag, s.tag2, swa->sw_mlen); if (r != 0) { error = EBADMSG; goto out; @@ -556,13 +554,13 @@ swcr_gcm(const struct swcr_session *ses, struct cryptop *crp) } } else { /* Inject the authentication data */ - crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); + crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, + s.tag); } out: explicit_bzero(ctx, exf->ctxsize); - explicit_bzero(blkbuf, sizeof(blkbuf)); - explicit_bzero(tag, sizeof(tag)); + explicit_bzero(&s, sizeof(s)); return (error); } @@ -622,9 +620,12 @@ build_ccm_aad_length(u_int aad_length, uint8_t *blk) static int swcr_ccm_cbc_mac(const struct swcr_session *ses, struct cryptop *crp) { - u_char blk[CCM_CBC_BLOCK_LEN]; - u_char tag[AES_CBC_MAC_HASH_LEN]; - union authctx ctx; + struct { + union authctx ctx; + u_char blk[CCM_CBC_BLOCK_LEN]; + u_char tag[AES_CBC_MAC_HASH_LEN]; + u_char tag2[AES_CBC_MAC_HASH_LEN]; + } s; const struct crypto_session_params *csp; const struct swcr_auth *swa; const struct auth_hash *axf; @@ -635,46 +636,43 @@ swcr_ccm_cbc_mac(const struct swcr_session *ses, struct cryptop *crp) axf = swa->sw_axf; if (crp->crp_auth_key != NULL) { - axf->Init(&ctx); - axf->Setkey(&ctx, crp->crp_auth_key, csp->csp_auth_klen); + axf->Init(&s.ctx); + axf->Setkey(&s.ctx, crp->crp_auth_key, csp->csp_auth_klen); } else - memcpy(&ctx, swa->sw_ictx, axf->ctxsize); + memcpy(&s.ctx, swa->sw_ictx, axf->ctxsize); /* Initialize the IV */ ivlen = csp->csp_ivlen; /* Supply MAC with IV */ - axf->Reinit(&ctx, crp->crp_iv, ivlen); + axf->Reinit(&s.ctx, crp->crp_iv, ivlen); /* Supply MAC with b0. */ build_ccm_b0(crp->crp_iv, ivlen, crp->crp_payload_length, 0, - swa->sw_mlen, blk); - axf->Update(&ctx, blk, CCM_CBC_BLOCK_LEN); + swa->sw_mlen, s.blk); + axf->Update(&s.ctx, s.blk, CCM_CBC_BLOCK_LEN); - len = build_ccm_aad_length(crp->crp_payload_length, blk); - axf->Update(&ctx, blk, len); + len = build_ccm_aad_length(crp->crp_payload_length, s.blk); + axf->Update(&s.ctx, s.blk, len); crypto_apply(crp, crp->crp_payload_start, crp->crp_payload_length, - axf->Update, &ctx); + axf->Update, &s.ctx); /* Finalize MAC */ - axf->Final(tag, &ctx); + axf->Final(s.tag, &s.ctx); error = 0; if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { - u_char tag2[AES_CBC_MAC_HASH_LEN]; - crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, - tag2); - if (timingsafe_bcmp(tag, tag2, swa->sw_mlen) != 0) + s.tag2); + if (timingsafe_bcmp(s.tag, s.tag2, swa->sw_mlen) != 0) error = EBADMSG; - explicit_bzero(tag2, sizeof(tag)); } else { /* Inject the authentication data */ - crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); + crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, + s.tag); } - explicit_bzero(tag, sizeof(tag)); - explicit_bzero(blk, sizeof(blk)); + explicit_bzero(&s, sizeof(s)); return (error); } @@ -682,9 +680,12 @@ static int swcr_ccm(const struct swcr_session *ses, struct cryptop *crp) { const struct crypto_session_params *csp; - uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; - u_char *blk = (u_char *)blkbuf; - u_char tag[AES_CBC_MAC_HASH_LEN]; + struct { + uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; + u_char tag[AES_CBC_MAC_HASH_LEN]; + u_char tag2[AES_CBC_MAC_HASH_LEN]; + } s; + u_char *blk = (u_char *)s.blkbuf; struct crypto_buffer_cursor cc_in, cc_out; const u_char *inblk; u_char *outblk; @@ -720,7 +721,7 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp) exf->reinit(ctx, crp->crp_iv, ivlen); /* Supply MAC with b0. */ - _Static_assert(sizeof(blkbuf) >= CCM_CBC_BLOCK_LEN, + _Static_assert(sizeof(s.blkbuf) >= CCM_CBC_BLOCK_LEN, "blkbuf too small for b0"); build_ccm_b0(crp->crp_iv, ivlen, crp->crp_aad_length, crp->crp_payload_length, swa->sw_mlen, blk); @@ -796,18 +797,14 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp) } /* Finalize MAC */ - exf->final(tag, ctx); + exf->final(s.tag, ctx); /* Validate tag */ error = 0; if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { - u_char tag2[AES_CBC_MAC_HASH_LEN]; - crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, - tag2); - - r = timingsafe_bcmp(tag, tag2, swa->sw_mlen); - explicit_bzero(tag2, sizeof(tag2)); + s.tag2); + r = timingsafe_bcmp(s.tag, s.tag2, swa->sw_mlen); if (r != 0) { error = EBADMSG; goto out; @@ -841,13 +838,13 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp) } } else { /* Inject the authentication data */ - crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); + crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, + s.tag); } out: explicit_bzero(ctx, exf->ctxsize); - explicit_bzero(blkbuf, sizeof(blkbuf)); - explicit_bzero(tag, sizeof(tag)); + explicit_bzero(&s, sizeof(s)); return (error); } @@ -855,9 +852,12 @@ static int swcr_chacha20_poly1305(const struct swcr_session *ses, struct cryptop *crp) { const struct crypto_session_params *csp; - uint64_t blkbuf[howmany(CHACHA20_NATIVE_BLOCK_LEN, sizeof(uint64_t))]; - u_char *blk = (u_char *)blkbuf; - u_char tag[POLY1305_HASH_LEN]; + struct { + uint64_t blkbuf[howmany(CHACHA20_NATIVE_BLOCK_LEN, sizeof(uint64_t))]; + u_char tag[POLY1305_HASH_LEN]; + u_char tag2[POLY1305_HASH_LEN]; + } s; + u_char *blk = (u_char *)s.blkbuf; struct crypto_buffer_cursor cc_in, cc_out; const u_char *inblk; u_char *outblk; @@ -873,7 +873,7 @@ swcr_chacha20_poly1305(const struct swcr_session *ses, struct cryptop *crp) swe = &ses->swcr_encdec; exf = swe->sw_exf; blksz = exf->native_blocksize; - KASSERT(blksz <= sizeof(blkbuf), ("%s: blocksize mismatch", __func__)); + KASSERT(blksz <= sizeof(s.blkbuf), ("%s: blocksize mismatch", __func__)); if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) return (EINVAL); @@ -950,17 +950,14 @@ swcr_chacha20_poly1305(const struct swcr_session *ses, struct cryptop *crp) exf->update(ctx, blk, sizeof(uint64_t) * 2); /* Finalize MAC */ - exf->final(tag, ctx); + exf->final(s.tag, ctx); /* Validate tag */ error = 0; if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { - u_char tag2[POLY1305_HASH_LEN]; - - crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, tag2); - - r = timingsafe_bcmp(tag, tag2, swa->sw_mlen); - explicit_bzero(tag2, sizeof(tag2)); + crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, + s.tag2); + r = timingsafe_bcmp(s.tag, s.tag2, swa->sw_mlen); if (r != 0) { error = EBADMSG; goto out; @@ -993,13 +990,13 @@ swcr_chacha20_poly1305(const struct swcr_session *ses, struct cryptop *crp) } } else { /* Inject the authentication data */ - crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); + crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, + s.tag); } out: explicit_bzero(ctx, exf->ctxsize); - explicit_bzero(blkbuf, sizeof(blkbuf)); - explicit_bzero(tag, sizeof(tag)); + explicit_bzero(&s, sizeof(s)); return (error); }