diff --git a/sys/crypto/aesni/aesni.h b/sys/crypto/aesni/aesni.h --- a/sys/crypto/aesni/aesni.h +++ b/sys/crypto/aesni/aesni.h @@ -112,12 +112,12 @@ /* 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.c b/sys/crypto/aesni/aesni.c --- a/sys/crypto/aesni/aesni.c +++ b/sys/crypto/aesni/aesni.c @@ -319,9 +319,6 @@ 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 @@ 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 @@ 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_ccm.c b/sys/crypto/aesni/aesni_ccm.c --- a/sys/crypto/aesni/aesni_ccm.c +++ b/sys/crypto/aesni/aesni_ccm.c @@ -185,10 +185,6 @@ * 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 @@ 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 @@ 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;