Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109804218
D37370.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D37370.diff
View Options
diff --git a/sys/kern/uipc_ktls.c b/sys/kern/uipc_ktls.c
--- a/sys/kern/uipc_ktls.c
+++ b/sys/kern/uipc_ktls.c
@@ -149,7 +149,7 @@
static bool ktls_cbc_enable = true;
SYSCTL_BOOL(_kern_ipc_tls, OID_AUTO, cbc_enable, CTLFLAG_RWTUN,
&ktls_cbc_enable, 1,
- "Enable Support of AES-CBC crypto for kernel TLS");
+ "Enable support of AES-CBC crypto for kernel TLS");
static bool ktls_sw_buffer_cache = true;
SYSCTL_BOOL(_kern_ipc_tls, OID_AUTO, sw_buffer_cache, CTLFLAG_RDTUN,
@@ -2444,8 +2444,10 @@
sb->sb_ccc -= tls_len;
sb->sb_tlsdcc = 0;
+ if (error != EMSGSIZE)
+ error = EBADMSG;
CURVNET_SET(so->so_vnet);
- so->so_error = EBADMSG;
+ so->so_error = error;
sorwakeup_locked(so);
CURVNET_RESTORE();
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
@@ -101,6 +101,11 @@
CTLFLAG_RD, &ocf_tls10_cbc_encrypts,
"Total number of OCF TLS 1.0 CBC encryption operations");
+static COUNTER_U64_DEFINE_EARLY(ocf_tls11_cbc_decrypts);
+SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls11_cbc_decrypts,
+ CTLFLAG_RD, &ocf_tls11_cbc_decrypts,
+ "Total number of OCF TLS 1.1/1.2 CBC decryption operations");
+
static COUNTER_U64_DEFINE_EARLY(ocf_tls11_cbc_encrypts);
SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls11_cbc_encrypts,
CTLFLAG_RD, &ocf_tls11_cbc_encrypts,
@@ -416,8 +421,129 @@
return (error);
}
+static int
+check_padding(void *arg, void *data, u_int len)
+{
+ uint8_t pad = *(uint8_t *)arg;
+ const char *cp = data;
+
+ while (len > 0) {
+ if (*cp != pad)
+ return (EBADMSG);
+ cp++;
+ len--;
+ }
+ return (0);
+}
+
+static int
+ktls_ocf_tls_cbc_decrypt(struct ktls_session *tls,
+ const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno,
+ int *trailer_len)
+{
+ struct tls_mac_data ad;
+ struct cryptop crp;
+ struct uio uio;
+ struct ktls_ocf_session *os;
+ struct iovec *iov;
+ struct mbuf *n;
+ u_int iovcnt;
+ int i, error, skip;
+ uint16_t tls_len, tls_comp_len;
+ uint8_t pad;
+
+ os = tls->ocf_session;
+
+ /*
+ * Ensure record is a multiple of the cipher block size and
+ * contains at least an explicit IV, MAC, and at least one
+ * padding byte.
+ */
+ tls_len = ntohs(hdr->tls_length);
+ if (tls_len % AES_BLOCK_LEN != 0 ||
+ tls_len < AES_BLOCK_LEN + roundup2(os->mac_len + 1, AES_BLOCK_LEN))
+ return (EMSGSIZE);
+
+ /* First, decrypt the record. */
+ crypto_initreq(&crp, os->sid);
+ crp.crp_iv_start = sizeof(*hdr);
+ crp.crp_payload_start = tls->params.tls_hlen;
+ crp.crp_payload_length = tls_len - AES_BLOCK_LEN;
+ crypto_use_mbuf(&crp, m);
+ crp.crp_op = CRYPTO_OP_DECRYPT;
+ crp.crp_flags = CRYPTO_F_CBIMM;
+
+ counter_u64_add(ocf_tls11_cbc_decrypts, 1);
+
+ error = ktls_ocf_dispatch(os, &crp);
+ crypto_destroyreq(&crp);
+ if (error)
+ return (error);
+
+ /* Verify the padding. */
+ m_copydata(m, sizeof(*hdr) + tls_len - 1, 1, &pad);
+ *trailer_len = os->mac_len + pad + 1;
+ if (AES_BLOCK_LEN + *trailer_len > tls_len)
+ return (EBADMSG);
+ error = m_apply(m, sizeof(*hdr) + tls_len - (pad + 1), pad + 1,
+ check_padding, &pad);
+ if (error)
+ return (error);
+
+ /* Verify the MAC. */
+ tls_comp_len = tls_len - (AES_BLOCK_LEN + *trailer_len);
+ memset(&uio, 0, sizeof(uio));
+
+ /*
+ * Allocate and populate the iov. Have to skip over the TLS
+ * header in 'm' as it is not part of the MAC input.
+ */
+ iovcnt = 1;
+ for (n = m; n != NULL; n = n->m_next)
+ iovcnt++;
+ iov = malloc(iovcnt * sizeof(*iov), M_KTLS_OCF, M_WAITOK);
+ iov[0].iov_base = &ad;
+ iov[0].iov_len = sizeof(ad);
+ skip = sizeof(*hdr) + AES_BLOCK_LEN;
+ for (i = 1, n = m; n != NULL; i++, n = n->m_next) {
+ if (n->m_len < skip) {
+ skip -= n->m_len;
+ continue;
+ }
+ iov[i].iov_base = mtod(n, char *) + skip;
+ iov[i].iov_len = n->m_len - skip;
+ skip = 0;
+ }
+ uio.uio_iov = iov;
+ uio.uio_iovcnt = i;
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_td = curthread;
+ uio.uio_resid = sizeof(ad) + tls_len - AES_BLOCK_LEN;
+
+ /* Initialize the AAD. */
+ ad.seq = htobe64(seqno);
+ ad.type = hdr->tls_type;
+ ad.tls_vmajor = hdr->tls_vmajor;
+ ad.tls_vminor = hdr->tls_vminor;
+ ad.tls_length = htons(tls_comp_len);
+
+ crypto_initreq(&crp, os->mac_sid);
+ crp.crp_payload_start = 0;
+ crp.crp_payload_length = sizeof(ad) + tls_comp_len;
+ crp.crp_digest_start = crp.crp_payload_length;
+ crp.crp_op = CRYPTO_OP_VERIFY_DIGEST;
+ crp.crp_flags = CRYPTO_F_CBIMM;
+ crypto_use_uio(&crp, &uio);
+ error = ktls_ocf_dispatch(os, &crp);
+
+ crypto_destroyreq(&crp);
+ free(iov, M_KTLS_OCF);
+ return (error);
+}
+
static const struct ktls_ocf_sw ktls_ocf_tls_cbc_sw = {
- .encrypt = ktls_ocf_tls_cbc_encrypt
+ .encrypt = ktls_ocf_tls_cbc_encrypt,
+ .decrypt = ktls_ocf_tls_cbc_decrypt
};
static int
@@ -912,8 +1038,9 @@
tls->params.tls_vminor > TLS_MINOR_VER_TWO)
return (EPROTONOSUPPORT);
- /* AES-CBC is not supported for receive. */
- if (direction == KTLS_RX)
+ /* AES-CBC is not supported for receive for TLS 1.0. */
+ if (direction == KTLS_RX &&
+ tls->params.tls_vminor == TLS_MINOR_VER_ZERO)
return (EPROTONOSUPPORT);
csp.csp_flags |= CSP_F_SEPARATE_OUTPUT;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 10, 6:23 PM (7 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16581568
Default Alt Text
D37370.diff (5 KB)
Attached To
Mode
D37370: ktls: Add software support for AES-CBC decryption for TLS 1.1+.
Attached
Detach File
Event Timeline
Log In to Comment