Index: sys/opencrypto/ktls_ocf.c =================================================================== --- sys/opencrypto/ktls_ocf.c +++ sys/opencrypto/ktls_ocf.c @@ -112,25 +112,24 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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: