git: 50722514280a - main - cryptosoft: Avoid referencing end-of-buffer cursors
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 18 Jan 2022 00:01:48 UTC
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=50722514280a6d044fe93fdbcccd0ee521f08f1d commit 50722514280a6d044fe93fdbcccd0ee521f08f1d Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2022-01-18 00:01:24 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2022-01-18 00:01:24 +0000 cryptosoft: Avoid referencing end-of-buffer cursors Once a crypto cursor has reached the end of its buffer, it is invalid to call crypto_cursor_segment() for at least some crypto buffer types. Reorganize loops to avoid this. Fixes: cfb7b942bed7 ("cryptosoft: Use multi-block encrypt/decrypt for non-AEAD ciphers.") Fixes: a221a8f4a0de ("cryptosoft: Use multi-block encrypt/decrypt for AES-GCM.") Fixes: f8580fcaa1e1 ("cryptosoft: Use multi-block encrypt/decrypt for AES-CCM.") Fixes: 5022c68732e6 ("cryptosoft: Use multi-block encrypt/decrypt for ChaCha20-Poly1305.") Reported and tested by: madpilot Discussed with: jhb Sponsored by: The FreeBSD Foundation --- sys/opencrypto/cryptosoft.c | 93 +++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c index 4d0f7d8718cc..2aa7aecef146 100644 --- a/sys/opencrypto/cryptosoft.c +++ b/sys/opencrypto/cryptosoft.c @@ -146,13 +146,11 @@ swcr_encdec(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_init(&cc_in, &crp->crp_buf); crypto_cursor_advance(&cc_in, crp->crp_payload_start); - inblk = crypto_cursor_segment(&cc_in, &inlen); if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { crypto_cursor_init(&cc_out, &crp->crp_obuf); crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); } else cc_out = cc_in; - outblk = crypto_cursor_segment(&cc_out, &outlen); encrypting = CRYPTO_OP_IS_ENCRYPT(crp->crp_op); @@ -162,7 +160,13 @@ swcr_encdec(const struct swcr_session *ses, struct cryptop *crp) * 'outlen' is the remaining length of current segment in the * output buffer. */ + inlen = outlen = 0; for (resid = crp->crp_payload_length; resid >= blksz; resid -= todo) { + if (inlen == 0) + inblk = crypto_cursor_segment(&cc_in, &inlen); + if (outlen == 0) + outblk = crypto_cursor_segment(&cc_out, &outlen); + /* * If the current block is not contained within the * current input/output segment, use 'blk' as a local @@ -191,8 +195,6 @@ swcr_encdec(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_in, todo); inlen -= todo; inblk += todo; - if (inlen == 0) - inblk = crypto_cursor_segment(&cc_in, &inlen); } if (outblk == blk) { @@ -202,9 +204,6 @@ swcr_encdec(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_out, todo); outlen -= todo; outblk += todo; - if (outlen == 0) - outblk = crypto_cursor_segment(&cc_out, - &outlen); } } @@ -476,15 +475,19 @@ swcr_gcm(const struct swcr_session *ses, struct cryptop *crp) /* Do encryption with MAC */ crypto_cursor_init(&cc_in, &crp->crp_buf); crypto_cursor_advance(&cc_in, crp->crp_payload_start); - inblk = crypto_cursor_segment(&cc_in, &inlen); if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { crypto_cursor_init(&cc_out, &crp->crp_obuf); crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); } else cc_out = cc_in; - outblk = crypto_cursor_segment(&cc_out, &outlen); + inlen = outlen = 0; for (resid = crp->crp_payload_length; resid >= blksz; resid -= todo) { + if (inlen == 0) + inblk = crypto_cursor_segment(&cc_in, &inlen); + if (outlen == 0) + outblk = crypto_cursor_segment(&cc_out, &outlen); + if (inlen < blksz) { crypto_cursor_copydata(&cc_in, blksz, blk); inblk = blk; @@ -510,9 +513,6 @@ swcr_gcm(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_out, todo); outlen -= todo; outblk += todo; - if (outlen == 0) - outblk = crypto_cursor_segment(&cc_out, - &outlen); } } else { todo = rounddown2(MIN(resid, inlen), blksz); @@ -525,8 +525,6 @@ swcr_gcm(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_in, todo); inlen -= todo; inblk += todo; - if (inlen == 0) - inblk = crypto_cursor_segment(&cc_in, &inlen); } } if (resid > 0) { @@ -563,10 +561,14 @@ swcr_gcm(const struct swcr_session *ses, struct cryptop *crp) /* tag matches, decrypt data */ crypto_cursor_init(&cc_in, &crp->crp_buf); crypto_cursor_advance(&cc_in, crp->crp_payload_start); - inblk = crypto_cursor_segment(&cc_in, &inlen); + inlen = 0; for (resid = crp->crp_payload_length; resid > blksz; resid -= todo) { + if (inlen == 0) + inblk = crypto_cursor_segment(&cc_in, &inlen); + if (outlen == 0) + outblk = crypto_cursor_segment(&cc_out, &outlen); if (inlen < blksz) { crypto_cursor_copydata(&cc_in, blksz, blk); inblk = blk; @@ -588,9 +590,6 @@ swcr_gcm(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_in, todo); inlen -= todo; inblk += todo; - if (inlen == 0) - inblk = crypto_cursor_segment(&cc_in, - &inlen); } if (outblk == blk) { @@ -601,9 +600,6 @@ swcr_gcm(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_out, todo); outlen -= todo; outblk += todo; - if (outlen == 0) - outblk = crypto_cursor_segment(&cc_out, - &outlen); } } if (resid > 0) { @@ -809,15 +805,19 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp) /* Do encryption/decryption with MAC */ crypto_cursor_init(&cc_in, &crp->crp_buf); crypto_cursor_advance(&cc_in, crp->crp_payload_start); - inblk = crypto_cursor_segment(&cc_in, &inlen); if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { crypto_cursor_init(&cc_out, &crp->crp_obuf); crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); } else cc_out = cc_in; - outblk = crypto_cursor_segment(&cc_out, &outlen); + inlen = outlen = 0; for (resid = crp->crp_payload_length; resid >= blksz; resid -= todo) { + if (inlen == 0) + inblk = crypto_cursor_segment(&cc_in, &inlen); + if (outlen == 0) + outblk = crypto_cursor_segment(&cc_out, &outlen); + if (inlen < blksz) { crypto_cursor_copydata(&cc_in, blksz, blk); inblk = blk; @@ -843,9 +843,6 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_out, todo); outlen -= todo; outblk += todo; - if (outlen == 0) - outblk = crypto_cursor_segment(&cc_out, - &outlen); } } else { /* @@ -867,8 +864,6 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_in, todo); inlen -= todo; inblk += todo; - if (inlen == 0) - inblk = crypto_cursor_segment(&cc_in, &inlen); } } if (resid > 0) { @@ -901,10 +896,16 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp) exf->reinit(ctx, crp->crp_iv, ivlen); crypto_cursor_init(&cc_in, &crp->crp_buf); crypto_cursor_advance(&cc_in, crp->crp_payload_start); - inblk = crypto_cursor_segment(&cc_in, &inlen); + inlen = 0; for (resid = crp->crp_payload_length; resid >= blksz; resid -= todo) { + if (inlen == 0) + inblk = crypto_cursor_segment(&cc_in, &inlen); + if (outlen == 0) + outblk = crypto_cursor_segment(&cc_out, + &outlen); + if (inlen < blksz) { crypto_cursor_copydata(&cc_in, blksz, blk); inblk = blk; @@ -926,9 +927,6 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_in, todo); inlen -= todo; inblk += todo; - if (inlen == 0) - inblk = crypto_cursor_segment(&cc_in, - &inlen); } if (outblk == blk) { @@ -939,9 +937,6 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_out, todo); outlen -= todo; outblk += todo; - if (outlen == 0) - outblk = crypto_cursor_segment(&cc_out, - &outlen); } } if (resid > 0) { @@ -1017,17 +1012,22 @@ swcr_chacha20_poly1305(const struct swcr_session *ses, struct cryptop *crp) /* Do encryption with MAC */ crypto_cursor_init(&cc_in, &crp->crp_buf); crypto_cursor_advance(&cc_in, crp->crp_payload_start); - inblk = crypto_cursor_segment(&cc_in, &inlen); if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { crypto_cursor_init(&cc_out, &crp->crp_obuf); crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); } else cc_out = cc_in; - outblk = crypto_cursor_segment(&cc_out, &outlen); + inlen = outlen = 0; if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { for (resid = crp->crp_payload_length; resid >= blksz; resid -= todo) { + if (inlen == 0) + inblk = crypto_cursor_segment(&cc_in, &inlen); + if (outlen == 0) + outblk = crypto_cursor_segment(&cc_out, + &outlen); + if (inlen < blksz) { crypto_cursor_copydata(&cc_in, blksz, blk); inblk = blk; @@ -1051,9 +1051,6 @@ swcr_chacha20_poly1305(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_in, todo); inlen -= todo; inblk += todo; - if (inlen == 0) - inblk = crypto_cursor_segment(&cc_in, - &inlen); } if (outblk == blk) { @@ -1063,9 +1060,6 @@ swcr_chacha20_poly1305(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_out, todo); outlen -= todo; outblk += todo; - if (outlen == 0) - outblk = crypto_cursor_segment(&cc_out, - &outlen); } } if (resid > 0) { @@ -1107,10 +1101,15 @@ swcr_chacha20_poly1305(const struct swcr_session *ses, struct cryptop *crp) /* tag matches, decrypt data */ crypto_cursor_init(&cc_in, &crp->crp_buf); crypto_cursor_advance(&cc_in, crp->crp_payload_start); - inblk = crypto_cursor_segment(&cc_in, &inlen); + inlen = 0; for (resid = crp->crp_payload_length; resid > blksz; resid -= todo) { + if (inlen == 0) + inblk = crypto_cursor_segment(&cc_in, &inlen); + if (outlen == 0) + outblk = crypto_cursor_segment(&cc_out, + &outlen); if (inlen < blksz) { crypto_cursor_copydata(&cc_in, blksz, blk); inblk = blk; @@ -1132,9 +1131,6 @@ swcr_chacha20_poly1305(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_in, todo); inlen -= todo; inblk += todo; - if (inlen == 0) - inblk = crypto_cursor_segment(&cc_in, - &inlen); } if (outblk == blk) { @@ -1145,9 +1141,6 @@ swcr_chacha20_poly1305(const struct swcr_session *ses, struct cryptop *crp) crypto_cursor_advance(&cc_out, todo); outlen -= todo; outblk += todo; - if (outlen == 0) - outblk = crypto_cursor_segment(&cc_out, - &outlen); } } if (resid > 0) {