mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
cryptosoft: Use multi-block encrypt/decrypt for AES-CCM.
Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D33757
This commit is contained in:
parent
a221a8f4a0
commit
f8580fcaa1
1 changed files with 79 additions and 25 deletions
|
|
@ -748,6 +748,7 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp)
|
||||||
struct crypto_buffer_cursor cc_in, cc_out;
|
struct crypto_buffer_cursor cc_in, cc_out;
|
||||||
const u_char *inblk;
|
const u_char *inblk;
|
||||||
u_char *outblk;
|
u_char *outblk;
|
||||||
|
size_t inlen, outlen, todo;
|
||||||
const struct swcr_auth *swa;
|
const struct swcr_auth *swa;
|
||||||
const struct swcr_encdec *swe;
|
const struct swcr_encdec *swe;
|
||||||
const struct enc_xform *exf;
|
const struct enc_xform *exf;
|
||||||
|
|
@ -808,28 +809,44 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp)
|
||||||
/* Do encryption/decryption with MAC */
|
/* Do encryption/decryption with MAC */
|
||||||
crypto_cursor_init(&cc_in, &crp->crp_buf);
|
crypto_cursor_init(&cc_in, &crp->crp_buf);
|
||||||
crypto_cursor_advance(&cc_in, crp->crp_payload_start);
|
crypto_cursor_advance(&cc_in, crp->crp_payload_start);
|
||||||
|
inblk = crypto_cursor_segment(&cc_in, &inlen);
|
||||||
if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
|
if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
|
||||||
crypto_cursor_init(&cc_out, &crp->crp_obuf);
|
crypto_cursor_init(&cc_out, &crp->crp_obuf);
|
||||||
crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
|
crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
|
||||||
} else
|
} else
|
||||||
cc_out = cc_in;
|
cc_out = cc_in;
|
||||||
for (resid = crp->crp_payload_length; resid >= blksz; resid -= blksz) {
|
outblk = crypto_cursor_segment(&cc_out, &outlen);
|
||||||
inblk = crypto_cursor_segment(&cc_in, &len);
|
|
||||||
if (len < blksz) {
|
for (resid = crp->crp_payload_length; resid >= blksz; resid -= todo) {
|
||||||
|
if (inlen < blksz) {
|
||||||
crypto_cursor_copydata(&cc_in, blksz, blk);
|
crypto_cursor_copydata(&cc_in, blksz, blk);
|
||||||
inblk = blk;
|
inblk = blk;
|
||||||
} else
|
inlen = blksz;
|
||||||
crypto_cursor_advance(&cc_in, blksz);
|
}
|
||||||
|
|
||||||
if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
|
if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
|
||||||
outblk = crypto_cursor_segment(&cc_out, &len);
|
if (outlen < blksz) {
|
||||||
if (len < blksz)
|
|
||||||
outblk = blk;
|
outblk = blk;
|
||||||
exf->update(ctx, inblk, blksz);
|
outlen = blksz;
|
||||||
exf->encrypt(ctx, inblk, outblk);
|
}
|
||||||
if (outblk == blk)
|
|
||||||
|
todo = rounddown2(MIN(resid, MIN(inlen, outlen)),
|
||||||
|
blksz);
|
||||||
|
|
||||||
|
exf->update(ctx, inblk, todo);
|
||||||
|
exf->encrypt_multi(ctx, inblk, outblk, todo);
|
||||||
|
|
||||||
|
if (outblk == blk) {
|
||||||
crypto_cursor_copyback(&cc_out, blksz, blk);
|
crypto_cursor_copyback(&cc_out, blksz, blk);
|
||||||
else
|
outblk = crypto_cursor_segment(&cc_out, &outlen);
|
||||||
crypto_cursor_advance(&cc_out, blksz);
|
} else {
|
||||||
|
crypto_cursor_advance(&cc_out, todo);
|
||||||
|
outlen -= todo;
|
||||||
|
outblk += todo;
|
||||||
|
if (outlen == 0)
|
||||||
|
outblk = crypto_cursor_segment(&cc_out,
|
||||||
|
&outlen);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* One of the problems with CCM+CBC is that
|
* One of the problems with CCM+CBC is that
|
||||||
|
|
@ -839,8 +856,19 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp)
|
||||||
* the tag and a second time after the tag is
|
* the tag and a second time after the tag is
|
||||||
* verified.
|
* verified.
|
||||||
*/
|
*/
|
||||||
|
todo = blksz;
|
||||||
exf->decrypt(ctx, inblk, blk);
|
exf->decrypt(ctx, inblk, blk);
|
||||||
exf->update(ctx, blk, blksz);
|
exf->update(ctx, blk, todo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inblk == blk) {
|
||||||
|
inblk = crypto_cursor_segment(&cc_in, &inlen);
|
||||||
|
} else {
|
||||||
|
crypto_cursor_advance(&cc_in, todo);
|
||||||
|
inlen -= todo;
|
||||||
|
inblk += todo;
|
||||||
|
if (inlen == 0)
|
||||||
|
inblk = crypto_cursor_segment(&cc_in, &inlen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (resid > 0) {
|
if (resid > 0) {
|
||||||
|
|
@ -873,22 +901,48 @@ swcr_ccm(const struct swcr_session *ses, struct cryptop *crp)
|
||||||
exf->reinit(ctx, crp->crp_iv, ivlen);
|
exf->reinit(ctx, crp->crp_iv, ivlen);
|
||||||
crypto_cursor_init(&cc_in, &crp->crp_buf);
|
crypto_cursor_init(&cc_in, &crp->crp_buf);
|
||||||
crypto_cursor_advance(&cc_in, crp->crp_payload_start);
|
crypto_cursor_advance(&cc_in, crp->crp_payload_start);
|
||||||
for (resid = crp->crp_payload_length; resid > blksz;
|
inblk = crypto_cursor_segment(&cc_in, &inlen);
|
||||||
resid -= blksz) {
|
|
||||||
inblk = crypto_cursor_segment(&cc_in, &len);
|
for (resid = crp->crp_payload_length; resid >= blksz;
|
||||||
if (len < blksz) {
|
resid -= todo) {
|
||||||
|
if (inlen < blksz) {
|
||||||
crypto_cursor_copydata(&cc_in, blksz, blk);
|
crypto_cursor_copydata(&cc_in, blksz, blk);
|
||||||
inblk = blk;
|
inblk = blk;
|
||||||
} else
|
inlen = blksz;
|
||||||
crypto_cursor_advance(&cc_in, blksz);
|
}
|
||||||
outblk = crypto_cursor_segment(&cc_out, &len);
|
if (outlen < blksz) {
|
||||||
if (len < blksz)
|
|
||||||
outblk = blk;
|
outblk = blk;
|
||||||
exf->decrypt(ctx, inblk, outblk);
|
outlen = blksz;
|
||||||
if (outblk == blk)
|
}
|
||||||
|
|
||||||
|
todo = rounddown2(MIN(resid, MIN(inlen, outlen)),
|
||||||
|
blksz);
|
||||||
|
|
||||||
|
exf->decrypt_multi(ctx, inblk, outblk, todo);
|
||||||
|
|
||||||
|
if (inblk == blk) {
|
||||||
|
inblk = crypto_cursor_segment(&cc_in, &inlen);
|
||||||
|
} else {
|
||||||
|
crypto_cursor_advance(&cc_in, todo);
|
||||||
|
inlen -= todo;
|
||||||
|
inblk += todo;
|
||||||
|
if (inlen == 0)
|
||||||
|
inblk = crypto_cursor_segment(&cc_in,
|
||||||
|
&inlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outblk == blk) {
|
||||||
crypto_cursor_copyback(&cc_out, blksz, blk);
|
crypto_cursor_copyback(&cc_out, blksz, blk);
|
||||||
else
|
outblk = crypto_cursor_segment(&cc_out,
|
||||||
crypto_cursor_advance(&cc_out, blksz);
|
&outlen);
|
||||||
|
} else {
|
||||||
|
crypto_cursor_advance(&cc_out, todo);
|
||||||
|
outlen -= todo;
|
||||||
|
outblk += todo;
|
||||||
|
if (outlen == 0)
|
||||||
|
outblk = crypto_cursor_segment(&cc_out,
|
||||||
|
&outlen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (resid > 0) {
|
if (resid > 0) {
|
||||||
crypto_cursor_copydata(&cc_in, resid, blk);
|
crypto_cursor_copydata(&cc_in, resid, blk);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue