diff --git a/sys/opencrypto/ktls_ocf.c b/sys/opencrypto/ktls_ocf.c --- a/sys/opencrypto/ktls_ocf.c +++ b/sys/opencrypto/ktls_ocf.c @@ -638,10 +638,16 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ *(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);