Changeset View
Changeset View
Standalone View
Standalone View
sys/opencrypto/ktls_ocf.c
Show First 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | ktls_ocf_tls12_gcm_encrypt(struct ktls_session *tls, | ||||
struct iovec *outiov, int iovcnt, uint64_t seqno, | struct iovec *outiov, int iovcnt, uint64_t seqno, | ||||
uint8_t record_type __unused) | uint8_t record_type __unused) | ||||
{ | { | ||||
struct uio uio, out_uio, *tag_uio; | struct uio uio, out_uio, *tag_uio; | ||||
struct tls_aead_data ad; | struct tls_aead_data ad; | ||||
struct cryptop *crp; | struct cryptop *crp; | ||||
struct ocf_session *os; | struct ocf_session *os; | ||||
struct ocf_operation *oo; | struct ocf_operation *oo; | ||||
struct iovec *iov, *out_iov; | |||||
int i, error; | int i, error; | ||||
uint16_t tls_comp_len; | uint16_t tls_comp_len; | ||||
bool inplace; | bool inplace; | ||||
os = tls->cipher; | os = tls->cipher; | ||||
oo = malloc(sizeof(*oo) + (iovcnt + 2) * sizeof(*iov) * 2, M_KTLS_OCF, | oo = malloc(sizeof(*oo) + (iovcnt + 1) * sizeof(struct iovec), | ||||
M_WAITOK | M_ZERO); | M_KTLS_OCF, M_WAITOK | M_ZERO); | ||||
oo->os = os; | 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_offset = 0; | ||||
uio.uio_segflg = UIO_SYSSPACE; | uio.uio_segflg = UIO_SYSSPACE; | ||||
uio.uio_td = curthread; | 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_offset = 0; | ||||
out_uio.uio_segflg = UIO_SYSSPACE; | out_uio.uio_segflg = UIO_SYSSPACE; | ||||
out_uio.uio_td = curthread; | out_uio.uio_td = curthread; | ||||
crp = crypto_getreq(os->sid, M_WAITOK); | crp = crypto_getreq(os->sid, M_WAITOK); | ||||
/* Setup the IV. */ | /* Setup the IV. */ | ||||
memcpy(crp->crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); | memcpy(crp->crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN); | ||||
memcpy(crp->crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, sizeof(uint64_t)); | memcpy(crp->crp_iv + TLS_AEAD_GCM_LEN, hdr + 1, sizeof(uint64_t)); | ||||
/* Setup the AAD. */ | /* Setup the AAD. */ | ||||
tls_comp_len = ntohs(hdr->tls_length) - | tls_comp_len = ntohs(hdr->tls_length) - | ||||
(AES_GMAC_HASH_LEN + sizeof(uint64_t)); | (AES_GMAC_HASH_LEN + sizeof(uint64_t)); | ||||
ad.seq = htobe64(seqno); | ad.seq = htobe64(seqno); | ||||
ad.type = hdr->tls_type; | ad.type = hdr->tls_type; | ||||
ad.tls_vmajor = hdr->tls_vmajor; | ad.tls_vmajor = hdr->tls_vmajor; | ||||
ad.tls_vminor = hdr->tls_vminor; | ad.tls_vminor = hdr->tls_vminor; | ||||
ad.tls_length = htons(tls_comp_len); | ad.tls_length = htons(tls_comp_len); | ||||
iov[0].iov_base = &ad; | crp->crp_aad = &ad; | ||||
iov[0].iov_len = sizeof(ad); | |||||
crp->crp_aad_start = 0; | |||||
crp->crp_aad_length = sizeof(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. */ | /* Compute payload length and determine if encryption is in place. */ | ||||
inplace = true; | inplace = true; | ||||
crp->crp_payload_start = sizeof(ad); | crp->crp_payload_start = 0; | ||||
for (i = 0; i < iovcnt; i++) { | for (i = 0; i < iovcnt; i++) { | ||||
if (iniov[i].iov_base != outiov[i].iov_base) | if (iniov[i].iov_base != outiov[i].iov_base) | ||||
inplace = false; | inplace = false; | ||||
crp->crp_payload_length += iniov[i].iov_len; | 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; | out_uio.uio_resid = crp->crp_payload_length; | ||||
if (inplace) | if (inplace) | ||||
tag_uio = &uio; | tag_uio = &uio; | ||||
else | else | ||||
tag_uio = &out_uio; | tag_uio = &out_uio; | ||||
tag_uio->uio_iov[tag_uio->uio_iovcnt].iov_base = trailer; | /* Duplicate iovec and append vector for tag. */ | ||||
tag_uio->uio_iov[tag_uio->uio_iovcnt].iov_len = AES_GMAC_HASH_LEN; | 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++; | tag_uio->uio_iovcnt++; | ||||
crp->crp_digest_start = tag_uio->uio_resid; | crp->crp_digest_start = tag_uio->uio_resid; | ||||
tag_uio->uio_resid += AES_GMAC_HASH_LEN; | tag_uio->uio_resid += AES_GMAC_HASH_LEN; | ||||
crp->crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; | crp->crp_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; | ||||
crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; | crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; | ||||
crypto_use_uio(crp, &uio); | crypto_use_uio(crp, &uio); | ||||
if (!inplace) | if (!inplace) | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | ktls_ocf_tls13_gcm_encrypt(struct ktls_session *tls, | ||||
struct ocf_session *os; | struct ocf_session *os; | ||||
struct ocf_operation *oo; | struct ocf_operation *oo; | ||||
struct iovec *iov, *out_iov; | struct iovec *iov, *out_iov; | ||||
int i, error; | int i, error; | ||||
bool inplace; | bool inplace; | ||||
os = tls->cipher; | 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); | M_WAITOK | M_ZERO); | ||||
oo->os = os; | oo->os = os; | ||||
iov = oo->iov; | iov = oo->iov; | ||||
out_iov = iov + iovcnt + 2; | 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); | crp = crypto_getreq(os->sid, M_WAITOK); | ||||
/* Setup the nonce. */ | /* Setup the nonce. */ | ||||
memcpy(nonce, tls->params.iv, tls->params.iv_len); | memcpy(nonce, tls->params.iv, tls->params.iv_len); | ||||
*(uint64_t *)(nonce + 4) ^= htobe64(seqno); | *(uint64_t *)(nonce + 4) ^= htobe64(seqno); | ||||
/* Setup the AAD. */ | /* Setup the AAD. */ | ||||
ad.type = hdr->tls_type; | ad.type = hdr->tls_type; | ||||
ad.tls_vmajor = hdr->tls_vmajor; | ad.tls_vmajor = hdr->tls_vmajor; | ||||
ad.tls_vminor = hdr->tls_vminor; | ad.tls_vminor = hdr->tls_vminor; | ||||
ad.tls_length = hdr->tls_length; | ad.tls_length = hdr->tls_length; | ||||
iov[0].iov_base = &ad; | crp->crp_aad = &ad; | ||||
iov[0].iov_len = sizeof(ad); | |||||
crp->crp_aad_start = 0; | |||||
crp->crp_aad_length = sizeof(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. */ | /* Compute payload length and determine if encryption is in place. */ | ||||
inplace = true; | inplace = true; | ||||
crp->crp_payload_start = sizeof(ad); | crp->crp_payload_start = 0; | ||||
for (i = 0; i < iovcnt; i++) { | for (i = 0; i < iovcnt; i++) { | ||||
if (iniov[i].iov_base != outiov[i].iov_base) | if (iniov[i].iov_base != outiov[i].iov_base) | ||||
inplace = false; | inplace = false; | ||||
crp->crp_payload_length += iniov[i].iov_len; | 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; | |||||
/* | /* Store the record type as the first byte of the trailer. */ | ||||
* Always include the full trailer as input to get the | |||||
* record_type even if only the first byte is used. | |||||
*/ | |||||
trailer[0] = record_type; | trailer[0] = record_type; | ||||
crp->crp_payload_length++; | crp->crp_payload_length++; | ||||
iov[iovcnt + 1].iov_base = trailer; | crp->crp_digest_start = crp->crp_payload_length; | ||||
iov[iovcnt + 1].iov_len = AES_GMAC_HASH_LEN + 1; | |||||
uio.uio_iovcnt++; | /* | ||||
uio.uio_resid += AES_GMAC_HASH_LEN + 1; | * Duplicate the input iov to append the trailer. Always | ||||
if (inplace) { | * include the full trailer as input to get the record_type | ||||
crp->crp_digest_start = uio.uio_resid - AES_GMAC_HASH_LEN; | * even if only the first byte is used. | ||||
} else { | */ | ||||
out_iov[iovcnt] = iov[iovcnt + 1]; | memcpy(iov, iniov, iovcnt * sizeof(*iov)); | ||||
out_uio.uio_iovcnt++; | iov[iovcnt].iov_base = trailer; | ||||
out_uio.uio_resid += AES_GMAC_HASH_LEN + 1; | iov[iovcnt].iov_len = AES_GMAC_HASH_LEN + 1; | ||||
crp->crp_digest_start = out_uio.uio_resid - AES_GMAC_HASH_LEN; | 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_op = CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST; | ||||
crp->crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE; | 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_opaque = oo; | ||||
crp->crp_callback = ktls_ocf_callback; | crp->crp_callback = ktls_ocf_callback; | ||||
memcpy(crp->crp_iv, nonce, sizeof(nonce)); | memcpy(crp->crp_iv, nonce, sizeof(nonce)); | ||||
counter_u64_add(ocf_tls13_gcm_crypts, 1); | counter_u64_add(ocf_tls13_gcm_crypts, 1); | ||||
if (inplace) | if (inplace) | ||||
counter_u64_add(ocf_inplace, 1); | counter_u64_add(ocf_inplace, 1); | ||||
Show All 40 Lines | |||||
static int | static int | ||||
ktls_ocf_try(struct socket *so, struct ktls_session *tls) | ktls_ocf_try(struct socket *so, struct ktls_session *tls) | ||||
{ | { | ||||
struct crypto_session_params csp; | struct crypto_session_params csp; | ||||
struct ocf_session *os; | struct ocf_session *os; | ||||
int error; | int error; | ||||
memset(&csp, 0, sizeof(csp)); | 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) { | switch (tls->params.cipher_algorithm) { | ||||
case CRYPTO_AES_NIST_GCM_16: | case CRYPTO_AES_NIST_GCM_16: | ||||
switch (tls->params.cipher_key_len) { | switch (tls->params.cipher_key_len) { | ||||
case 128 / 8: | case 128 / 8: | ||||
case 256 / 8: | case 256 / 8: | ||||
break; | break; | ||||
default: | default: | ||||
▲ Show 20 Lines • Show All 81 Lines • Show Last 20 Lines |