mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 12:54:27 +00:00
ktls_ocf: Reject encrypted TLS records using AEAD that are too small.
If a TLS record is too small to contain the required explicit IV, record_type (TLS 1.3), and MAC, reject attempts to decrypt it with EMSGSIZE without submitting it to OCF. OCF drivers may not properly detect that regions in the crypto request are outside the bounds of the mbuf chain. The caller isn't supposed to submit such requests. Reviewed by: markj Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D37372
This commit is contained in:
parent
64811651aa
commit
4e47414648
|
@ -638,10 +638,16 @@ ktls_ocf_tls12_aead_decrypt(struct ktls_session *tls,
|
|||
struct cryptop crp;
|
||||
struct ktls_ocf_session *os;
|
||||
int error;
|
||||
uint16_t tls_comp_len;
|
||||
uint16_t tls_comp_len, tls_len;
|
||||
|
||||
os = tls->ocf_session;
|
||||
|
||||
/* Ensure record contains at least an explicit IV and tag. */
|
||||
tls_len = ntohs(hdr->tls_length);
|
||||
if (tls_len + sizeof(*hdr) < tls->params.tls_hlen +
|
||||
tls->params.tls_tlen)
|
||||
return (EMSGSIZE);
|
||||
|
||||
crypto_initreq(&crp, os->sid);
|
||||
|
||||
/* Setup the IV. */
|
||||
|
@ -661,10 +667,10 @@ ktls_ocf_tls12_aead_decrypt(struct ktls_session *tls,
|
|||
|
||||
/* Setup the AAD. */
|
||||
if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16)
|
||||
tls_comp_len = ntohs(hdr->tls_length) -
|
||||
tls_comp_len = tls_len -
|
||||
(AES_GMAC_HASH_LEN + sizeof(uint64_t));
|
||||
else
|
||||
tls_comp_len = ntohs(hdr->tls_length) - POLY1305_HASH_LEN;
|
||||
tls_comp_len = tls_len - POLY1305_HASH_LEN;
|
||||
ad.seq = htobe64(seqno);
|
||||
ad.type = hdr->tls_type;
|
||||
ad.tls_vmajor = hdr->tls_vmajor;
|
||||
|
@ -730,9 +736,15 @@ ktls_ocf_tls12_aead_recrypt(struct ktls_session *tls,
|
|||
char *buf;
|
||||
u_int payload_len;
|
||||
int error;
|
||||
uint16_t tls_len;
|
||||
|
||||
os = tls->ocf_session;
|
||||
|
||||
/* Ensure record contains at least an explicit IV and tag. */
|
||||
tls_len = ntohs(hdr->tls_length);
|
||||
if (tls_len < sizeof(uint64_t) + AES_GMAC_HASH_LEN)
|
||||
return (EMSGSIZE);
|
||||
|
||||
crypto_initreq(&crp, os->recrypt_sid);
|
||||
|
||||
KASSERT(tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16,
|
||||
|
@ -743,8 +755,7 @@ ktls_ocf_tls12_aead_recrypt(struct ktls_session *tls,
|
|||
memcpy(crp.crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, sizeof(uint64_t));
|
||||
be32enc(crp.crp_iv + AES_GCM_IV_LEN, 2);
|
||||
|
||||
payload_len = ntohs(hdr->tls_length) -
|
||||
(AES_GMAC_HASH_LEN + sizeof(uint64_t));
|
||||
payload_len = tls_len - (AES_GMAC_HASH_LEN + sizeof(uint64_t));
|
||||
crp.crp_op = CRYPTO_OP_ENCRYPT;
|
||||
crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE;
|
||||
crypto_use_mbuf(&crp, m);
|
||||
|
@ -858,14 +869,16 @@ ktls_ocf_tls13_aead_decrypt(struct ktls_session *tls,
|
|||
struct ktls_ocf_session *os;
|
||||
int error;
|
||||
u_int tag_len;
|
||||
uint16_t tls_len;
|
||||
|
||||
os = tls->ocf_session;
|
||||
|
||||
tag_len = tls->params.tls_tlen - 1;
|
||||
|
||||
/* Payload must contain at least one byte for the record type. */
|
||||
if (ntohs(hdr->tls_length) < tag_len + 1)
|
||||
return (EBADMSG);
|
||||
tls_len = ntohs(hdr->tls_length);
|
||||
if (tls_len < tag_len + 1)
|
||||
return (EMSGSIZE);
|
||||
|
||||
crypto_initreq(&crp, os->sid);
|
||||
|
||||
|
@ -882,7 +895,7 @@ ktls_ocf_tls13_aead_decrypt(struct ktls_session *tls,
|
|||
crp.crp_aad_length = sizeof(ad);
|
||||
|
||||
crp.crp_payload_start = tls->params.tls_hlen;
|
||||
crp.crp_payload_length = ntohs(hdr->tls_length) - tag_len;
|
||||
crp.crp_payload_length = tls_len - tag_len;
|
||||
crp.crp_digest_start = crp.crp_payload_start + crp.crp_payload_length;
|
||||
|
||||
crp.crp_op = CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST;
|
||||
|
@ -910,9 +923,15 @@ ktls_ocf_tls13_aead_recrypt(struct ktls_session *tls,
|
|||
char *buf;
|
||||
u_int payload_len;
|
||||
int error;
|
||||
uint16_t tls_len;
|
||||
|
||||
os = tls->ocf_session;
|
||||
|
||||
/* Payload must contain at least one byte for the record type. */
|
||||
tls_len = ntohs(hdr->tls_length);
|
||||
if (tls_len < AES_GMAC_HASH_LEN + 1)
|
||||
return (EMSGSIZE);
|
||||
|
||||
crypto_initreq(&crp, os->recrypt_sid);
|
||||
|
||||
KASSERT(tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16,
|
||||
|
@ -923,7 +942,7 @@ ktls_ocf_tls13_aead_recrypt(struct ktls_session *tls,
|
|||
*(uint64_t *)(crp.crp_iv + 4) ^= htobe64(seqno);
|
||||
be32enc(crp.crp_iv + 12, 2);
|
||||
|
||||
payload_len = ntohs(hdr->tls_length) - AES_GMAC_HASH_LEN;
|
||||
payload_len = tls_len - AES_GMAC_HASH_LEN;
|
||||
crp.crp_op = CRYPTO_OP_ENCRYPT;
|
||||
crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE;
|
||||
crypto_use_mbuf(&crp, m);
|
||||
|
|
Loading…
Reference in a new issue