aboutsummaryrefslogtreecommitdiff
path: root/sys/crypto
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2021-10-06 21:08:48 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2021-10-06 21:08:48 +0000
commit655eb762c31044a791e8c8c6355515e7c89c07ef (patch)
treece2b9c8731d316ed163e589b2cc9d23ae0a10207 /sys/crypto
parentc09c379c7aa7337680ff3cb73691ce12d627128b (diff)
downloadsrc-655eb762c31044a791e8c8c6355515e7c89c07ef.tar.gz
src-655eb762c31044a791e8c8c6355515e7c89c07ef.zip
aesni: Support AES-CCM requests with a truncated tag.
Reviewed by: sef Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D32115
Diffstat (limited to 'sys/crypto')
-rw-r--r--sys/crypto/aesni/aesni.c18
-rw-r--r--sys/crypto/aesni/aesni.h8
-rw-r--r--sys/crypto/aesni/aesni_ccm.c10
3 files changed, 17 insertions, 19 deletions
diff --git a/sys/crypto/aesni/aesni.c b/sys/crypto/aesni/aesni.c
index 7d4dbd2c1604..de797abd1af5 100644
--- a/sys/crypto/aesni/aesni.c
+++ b/sys/crypto/aesni/aesni.c
@@ -319,9 +319,6 @@ aesni_probesession(device_t dev, const struct crypto_session_params *csp)
CRYPTDEB("invalid CCM key length");
return (EINVAL);
}
- if (csp->csp_auth_mlen != 0 &&
- csp->csp_auth_mlen != AES_CBC_MAC_HASH_LEN)
- return (EINVAL);
if (!sc->has_aes)
return (EINVAL);
break;
@@ -610,6 +607,11 @@ aesni_cipher_setup(struct aesni_session *ses,
error = aesni_authprepare(ses, csp->csp_auth_klen);
if (error != 0)
return (error);
+ } else if (csp->csp_cipher_alg == CRYPTO_AES_CCM_16) {
+ if (csp->csp_auth_mlen == 0)
+ ses->mlen = AES_CBC_MAC_HASH_LEN;
+ else
+ ses->mlen = csp->csp_auth_mlen;
}
kt = is_fpu_kern_thread(0) || (csp->csp_cipher_alg == 0);
@@ -809,15 +811,17 @@ aesni_cipher_crypt(struct aesni_session *ses, struct cryptop *crp,
memset(tag, 0, sizeof(tag));
AES_CCM_encrypt(buf, outbuf, authbuf, iv, tag,
crp->crp_payload_length, crp->crp_aad_length,
- csp->csp_ivlen, ses->enc_schedule, ses->rounds);
- crypto_copyback(crp, crp->crp_digest_start, sizeof(tag),
+ csp->csp_ivlen, ses->mlen, ses->enc_schedule,
+ ses->rounds);
+ crypto_copyback(crp, crp->crp_digest_start, ses->mlen,
tag);
} else {
- crypto_copydata(crp, crp->crp_digest_start, sizeof(tag),
+ crypto_copydata(crp, crp->crp_digest_start, ses->mlen,
tag);
if (!AES_CCM_decrypt(buf, outbuf, authbuf, iv, tag,
crp->crp_payload_length, crp->crp_aad_length,
- csp->csp_ivlen, ses->enc_schedule, ses->rounds))
+ csp->csp_ivlen, ses->mlen, ses->enc_schedule,
+ ses->rounds))
error = EBADMSG;
}
break;
diff --git a/sys/crypto/aesni/aesni.h b/sys/crypto/aesni/aesni.h
index 284bf6fba0fc..77ceec7b382a 100644
--- a/sys/crypto/aesni/aesni.h
+++ b/sys/crypto/aesni/aesni.h
@@ -112,12 +112,12 @@ int AES_GCM_decrypt(const unsigned char *in, unsigned char *out,
/* CCM + CBC-MAC functions */
void AES_CCM_encrypt(const unsigned char *in, unsigned char *out,
const unsigned char *addt, const unsigned char *ivec,
- unsigned char *tag, uint32_t nbytes, uint32_t abytes, int ibytes,
- const unsigned char *key, int nr);
+ unsigned char *tag, uint32_t nbytes, uint32_t abytes, int nlen,
+ int tag_length, const unsigned char *key, int nr);
int AES_CCM_decrypt(const unsigned char *in, unsigned char *out,
const unsigned char *addt, const unsigned char *ivec,
- const unsigned char *tag, uint32_t nbytes, uint32_t abytes, int ibytes,
- const unsigned char *key, int nr);
+ const unsigned char *tag, uint32_t nbytes, uint32_t abytes, int nlen,
+ int tag_length, const unsigned char *key, int nr);
void aesni_cipher_setup_common(struct aesni_session *ses,
const struct crypto_session_params *csp, const uint8_t *key, int keylen);
diff --git a/sys/crypto/aesni/aesni_ccm.c b/sys/crypto/aesni/aesni_ccm.c
index 34b61a633907..c7edaa0b9d5c 100644
--- a/sys/crypto/aesni/aesni_ccm.c
+++ b/sys/crypto/aesni/aesni_ccm.c
@@ -185,10 +185,6 @@ cbc_mac_start(const unsigned char *auth_data, size_t auth_len,
* Implement AES CCM+CBC-MAC encryption and authentication.
*
* A couple of notes:
- * The specification allows for a different number of tag lengths;
- * however, they're always truncated from 16 bytes, and the tag
- * length isn't passed in. (This could be fixed by changing the
- * code in aesni.c:aesni_cipher_crypt().)
* Since abytes is limited to a 32 bit value here, the AAD is
* limited to 4 gigabytes or less.
*/
@@ -196,9 +192,8 @@ void
AES_CCM_encrypt(const unsigned char *in, unsigned char *out,
const unsigned char *addt, const unsigned char *nonce,
unsigned char *tag, uint32_t nbytes, uint32_t abytes, int nlen,
- const unsigned char *key, int nr)
+ int tag_length, const unsigned char *key, int nr)
{
- static const int tag_length = 16; /* 128 bits */
int L;
int counter = 1; /* S0 has 0, S1 has 1 */
size_t copy_amt, total = 0;
@@ -367,9 +362,8 @@ int
AES_CCM_decrypt(const unsigned char *in, unsigned char *out,
const unsigned char *addt, const unsigned char *nonce,
const unsigned char *tag, uint32_t nbytes, uint32_t abytes, int nlen,
- const unsigned char *key, int nr)
+ int tag_length, const unsigned char *key, int nr)
{
- static const int tag_length = 16; /* 128 bits */
int L;
__m128i s0, rolling_mac, staging_block;
uint8_t *byte_ptr;