Store the AAD in a separate buffer for KTLS.
For TLS 1.2 this permits reusing one of the existing iovecs without always having to duplicate both. While here, only duplicate the output iovec for TLS 1.3 if it will be used. Reviewed by: gallatin Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D25291
This commit is contained in:
parent
6deb4131b8
commit
5b750b9a68
@ -112,25 +112,24 @@ ktls_ocf_tls12_gcm_encrypt(struct ktls_session *tls,
|
||||
struct cryptop *crp;
|
||||
struct ocf_session *os;
|
||||
struct ocf_operation *oo;
|
||||
struct iovec *iov, *out_iov;
|
||||
int i, error;
|
||||
uint16_t tls_comp_len;
|
||||
bool inplace;
|
||||
|
||||
os = tls->cipher;
|
||||
|
||||
oo = malloc(sizeof(*oo) + (iovcnt + 2) * sizeof(*iov) * 2, M_KTLS_OCF,
|
||||
M_WAITOK | M_ZERO);
|
||||
oo = malloc(sizeof(*oo) + (iovcnt + 1) * sizeof(struct iovec),
|
||||
M_KTLS_OCF, M_WAITOK | M_ZERO);
|
||||
oo->os = os;
|
||||
iov = oo->iov;
|
||||
out_iov = iov + iovcnt + 2;
|
||||
|
||||
uio.uio_iov = iov;
|
||||
uio.uio_iov = iniov;
|
||||
uio.uio_iovcnt = iovcnt;
|
||||
uio.uio_offset = 0;
|
||||
uio.uio_segflg = UIO_SYSSPACE;
|
||||
uio.uio_td = curthread;
|
||||
|
||||
out_uio.uio_iov = out_iov;
|
||||
out_uio.uio_iov = outiov;
|
||||
out_uio.uio_iovcnt = iovcnt;
|
||||
out_uio.uio_offset = 0;
|
||||
out_uio.uio_segflg = UIO_SYSSPACE;
|
||||
out_uio.uio_td = curthread;
|
||||
@ -149,26 +148,18 @@ ktls_ocf_tls12_gcm_encrypt(struct ktls_session *tls,
|
||||
ad.tls_vmajor = hdr->tls_vmajor;
|
||||
ad.tls_vminor = hdr->tls_vminor;
|
||||
ad.tls_length = htons(tls_comp_len);
|
||||
iov[0].iov_base = &ad;
|
||||
iov[0].iov_len = sizeof(ad);
|
||||
crp->crp_aad_start = 0;
|
||||
crp->crp_aad = &ad;
|
||||
crp->crp_aad_length = sizeof(ad);
|
||||
|
||||
/* Copy iov's. */
|
||||
memcpy(iov + 1, iniov, iovcnt * sizeof(*iov));
|
||||
uio.uio_iovcnt = iovcnt + 1;
|
||||
memcpy(out_iov, outiov, iovcnt * sizeof(*out_iov));
|
||||
out_uio.uio_iovcnt = iovcnt;
|
||||
|
||||
/* Compute payload length and determine if encryption is in place. */
|
||||
inplace = true;
|
||||
crp->crp_payload_start = sizeof(ad);
|
||||
crp->crp_payload_start = 0;
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
if (iniov[i].iov_base != outiov[i].iov_base)
|
||||
inplace = false;
|
||||
crp->crp_payload_length += iniov[i].iov_len;
|
||||
}
|
||||
uio.uio_resid = sizeof(ad) + crp->crp_payload_length;
|
||||
uio.uio_resid = crp->crp_payload_length;
|
||||
out_uio.uio_resid = crp->crp_payload_length;
|
||||
|
||||
if (inplace)
|
||||
@ -176,8 +167,11 @@ ktls_ocf_tls12_gcm_encrypt(struct ktls_session *tls,
|
||||
else
|
||||
tag_uio = &out_uio;
|
||||
|
||||
tag_uio->uio_iov[tag_uio->uio_iovcnt].iov_base = trailer;
|
||||
tag_uio->uio_iov[tag_uio->uio_iovcnt].iov_len = AES_GMAC_HASH_LEN;
|
||||
/* Duplicate iovec and append vector for tag. */
|
||||
memcpy(oo->iov, tag_uio->uio_iov, iovcnt * sizeof(struct iovec));
|
||||
tag_uio->uio_iov = oo->iov;
|
||||
tag_uio->uio_iov[iovcnt].iov_base = trailer;
|
||||
tag_uio->uio_iov[iovcnt].iov_len = AES_GMAC_HASH_LEN;
|
||||
tag_uio->uio_iovcnt++;
|
||||
crp->crp_digest_start = tag_uio->uio_resid;
|
||||
tag_uio->uio_resid += AES_GMAC_HASH_LEN;
|
||||
@ -238,23 +232,12 @@ ktls_ocf_tls13_gcm_encrypt(struct ktls_session *tls,
|
||||
|
||||
os = tls->cipher;
|
||||
|
||||
oo = malloc(sizeof(*oo) + (iovcnt + 2) * sizeof(*iov) * 2, M_KTLS_OCF,
|
||||
oo = malloc(sizeof(*oo) + (iovcnt + 1) * sizeof(*iov) * 2, M_KTLS_OCF,
|
||||
M_WAITOK | M_ZERO);
|
||||
oo->os = os;
|
||||
iov = oo->iov;
|
||||
|
||||
out_iov = iov + iovcnt + 2;
|
||||
|
||||
uio.uio_iov = iov;
|
||||
uio.uio_offset = 0;
|
||||
uio.uio_segflg = UIO_SYSSPACE;
|
||||
uio.uio_td = curthread;
|
||||
|
||||
out_uio.uio_iov = out_iov;
|
||||
out_uio.uio_offset = 0;
|
||||
out_uio.uio_segflg = UIO_SYSSPACE;
|
||||
out_uio.uio_td = curthread;
|
||||
|
||||
crp = crypto_getreq(os->sid, M_WAITOK);
|
||||
|
||||
/* Setup the nonce. */
|
||||
@ -266,52 +249,56 @@ ktls_ocf_tls13_gcm_encrypt(struct ktls_session *tls,
|
||||
ad.tls_vmajor = hdr->tls_vmajor;
|
||||
ad.tls_vminor = hdr->tls_vminor;
|
||||
ad.tls_length = hdr->tls_length;
|
||||
iov[0].iov_base = &ad;
|
||||
iov[0].iov_len = sizeof(ad);
|
||||
crp->crp_aad_start = 0;
|
||||
crp->crp_aad = &ad;
|
||||
crp->crp_aad_length = sizeof(ad);
|
||||
|
||||
/* Copy iov's. */
|
||||
memcpy(iov + 1, iniov, iovcnt * sizeof(*iov));
|
||||
uio.uio_iovcnt = iovcnt + 1;
|
||||
memcpy(out_iov, outiov, iovcnt * sizeof(*out_iov));
|
||||
out_uio.uio_iovcnt = iovcnt;
|
||||
|
||||
/* Compute payload length and determine if encryption is in place. */
|
||||
inplace = true;
|
||||
crp->crp_payload_start = sizeof(ad);
|
||||
crp->crp_payload_start = 0;
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
if (iniov[i].iov_base != outiov[i].iov_base)
|
||||
inplace = false;
|
||||
crp->crp_payload_length += iniov[i].iov_len;
|
||||
}
|
||||
uio.uio_resid = sizeof(ad) + crp->crp_payload_length;
|
||||
out_uio.uio_resid = crp->crp_payload_length;
|
||||
|
||||
/*
|
||||
* Always include the full trailer as input to get the
|
||||
* record_type even if only the first byte is used.
|
||||
*/
|
||||
/* Store the record type as the first byte of the trailer. */
|
||||
trailer[0] = record_type;
|
||||
crp->crp_payload_length++;
|
||||
iov[iovcnt + 1].iov_base = trailer;
|
||||
iov[iovcnt + 1].iov_len = AES_GMAC_HASH_LEN + 1;
|
||||
uio.uio_iovcnt++;
|
||||
uio.uio_resid += AES_GMAC_HASH_LEN + 1;
|
||||
if (inplace) {
|
||||
crp->crp_digest_start = uio.uio_resid - AES_GMAC_HASH_LEN;
|
||||
} else {
|
||||
out_iov[iovcnt] = iov[iovcnt + 1];
|
||||
out_uio.uio_iovcnt++;
|
||||
out_uio.uio_resid += AES_GMAC_HASH_LEN + 1;
|
||||
crp->crp_digest_start = out_uio.uio_resid - AES_GMAC_HASH_LEN;
|
||||
crp->crp_digest_start = crp->crp_payload_length;
|
||||
|
||||
/*
|
||||
* Duplicate the input iov to append the trailer. Always
|
||||
* include the full trailer as input to get the record_type
|
||||
* even if only the first byte is used.
|
||||
*/
|
||||
memcpy(iov, iniov, iovcnt * sizeof(*iov));
|
||||
iov[iovcnt].iov_base = trailer;
|
||||
iov[iovcnt].iov_len = AES_GMAC_HASH_LEN + 1;
|
||||
uio.uio_iov = iov;
|
||||
uio.uio_iovcnt = iovcnt + 1;
|
||||
uio.uio_offset = 0;
|
||||
uio.uio_resid = crp->crp_payload_length + AES_GMAC_HASH_LEN;
|
||||
uio.uio_segflg = UIO_SYSSPACE;
|
||||
uio.uio_td = curthread;
|
||||
crypto_use_uio(crp, &uio);
|
||||
|
||||
if (!inplace) {
|
||||
/* Duplicate the output iov to append the trailer. */
|
||||
memcpy(out_iov, outiov, iovcnt * sizeof(*out_iov));
|
||||
out_iov[iovcnt] = iov[iovcnt];
|
||||
|
||||
out_uio.uio_iov = out_iov;
|
||||
out_uio.uio_iovcnt = iovcnt + 1;
|
||||
out_uio.uio_offset = 0;
|
||||
out_uio.uio_resid = crp->crp_payload_length +
|
||||
AES_GMAC_HASH_LEN;
|
||||
out_uio.uio_segflg = UIO_SYSSPACE;
|
||||
out_uio.uio_td = curthread;
|
||||
crypto_use_output_uio(crp, &out_uio);
|
||||
}
|
||||
|
||||
crp->crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST;
|
||||
crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE;
|
||||
crypto_use_uio(crp, &uio);
|
||||
if (!inplace)
|
||||
crypto_use_output_uio(crp, &out_uio);
|
||||
crp->crp_opaque = oo;
|
||||
crp->crp_callback = ktls_ocf_callback;
|
||||
|
||||
@ -368,7 +355,7 @@ ktls_ocf_try(struct socket *so, struct ktls_session *tls)
|
||||
int error;
|
||||
|
||||
memset(&csp, 0, sizeof(csp));
|
||||
csp.csp_flags |= CSP_F_SEPARATE_OUTPUT;
|
||||
csp.csp_flags |= CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD;
|
||||
|
||||
switch (tls->params.cipher_algorithm) {
|
||||
case CRYPTO_AES_NIST_GCM_16:
|
||||
|
Loading…
Reference in New Issue
Block a user