Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102874048
D35012.id105242.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D35012.id105242.diff
View Options
Index: sys/opencrypto/ktls.h
===================================================================
--- sys/opencrypto/ktls.h
+++ sys/opencrypto/ktls.h
@@ -55,5 +55,8 @@
int ktls_ocf_decrypt(struct ktls_session *tls,
const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno,
int *trailer_len);
+int ktls_ocf_recrypt(struct ktls_session *tls,
+ const struct tls_record_layer *hdr, struct mbuf *m, uint64_t seqno);
+bool ktls_ocf_recrypt_supported(struct ktls_session *tls);
#endif /* !__OPENCRYPTO_KTLS_H__ */
Index: sys/opencrypto/ktls_ocf.c
===================================================================
--- sys/opencrypto/ktls_ocf.c
+++ sys/opencrypto/ktls_ocf.c
@@ -44,6 +44,7 @@
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_param.h>
+#include <netinet/in.h>
#include <opencrypto/cryptodev.h>
#include <opencrypto/ktls.h>
@@ -53,6 +54,11 @@
struct ktls_session *tls, struct mbuf *m,
struct iovec *outiov, int outiovcnt);
+ /* Re-encrypt a received TLS record that is partially decrypted. */
+ int (*recrypt)(struct ktls_session *tls,
+ const struct tls_record_layer *hdr, struct mbuf *m,
+ uint64_t seqno);
+
/* Decrypt a received TLS record. */
int (*decrypt)(struct ktls_session *tls,
const struct tls_record_layer *hdr, struct mbuf *m,
@@ -63,6 +69,7 @@
struct ktls_ocf_sw *sw;
crypto_session_t sid;
crypto_session_t mac_sid;
+ crypto_session_t recrypt_sid;
struct mtx lock;
int mac_len;
bool implicit_iv;
@@ -109,6 +116,11 @@
CTLFLAG_RD, &ocf_tls12_gcm_encrypts,
"Total number of OCF TLS 1.2 GCM encryption operations");
+static COUNTER_U64_DEFINE_EARLY(ocf_tls12_gcm_recrypts);
+SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_gcm_recrypts,
+ CTLFLAG_RD, &ocf_tls12_gcm_recrypts,
+ "Total number of OCF TLS 1.2 GCM re-encryption operations");
+
static COUNTER_U64_DEFINE_EARLY(ocf_tls12_chacha20_decrypts);
SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls12_chacha20_decrypts,
CTLFLAG_RD, &ocf_tls12_chacha20_decrypts,
@@ -129,6 +141,11 @@
CTLFLAG_RD, &ocf_tls13_gcm_encrypts,
"Total number of OCF TLS 1.3 GCM encryption operations");
+static COUNTER_U64_DEFINE_EARLY(ocf_tls13_gcm_recrypts);
+SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_gcm_recrypts,
+ CTLFLAG_RD, &ocf_tls13_gcm_recrypts,
+ "Total number of OCF TLS 1.3 GCM re-encryption operations");
+
static COUNTER_U64_DEFINE_EARLY(ocf_tls13_chacha20_decrypts);
SYSCTL_COUNTER_U64(_kern_ipc_tls_stats_ocf, OID_AUTO, tls13_chacha20_decrypts,
CTLFLAG_RD, &ocf_tls13_chacha20_decrypts,
@@ -549,8 +566,84 @@
return (error);
}
+/*
+ * Reconstruct encrypted mbuf data in input buffer.
+ */
+static void
+ktls_ocf_recrypt_fixup(struct mbuf *m, u_int skip, u_int len, char *buf)
+{
+ const char *src = buf;
+ u_int todo;
+
+ while (skip > m->m_len) {
+ skip -= m->m_len;
+ m = m->m_next;
+ }
+
+ while (len > 0) {
+ todo = m->m_len - skip;
+ if (todo > len)
+ todo = len;
+
+ if (m->m_flags & M_DECRYPTED)
+ memcpy(mtod(m, char *) + skip, src, todo);
+ src += todo;
+ len -= todo;
+ skip = 0;
+ m = m->m_next;
+ }
+}
+
+static int
+ktls_ocf_tls12_aead_recrypt(struct ktls_session *tls,
+ const struct tls_record_layer *hdr, struct mbuf *m,
+ uint64_t seqno)
+{
+ struct cryptop crp;
+ struct ktls_ocf_session *os;
+ char *buf;
+ u_int payload_len;
+ int error;
+
+ os = tls->ocf_session;
+
+ crypto_initreq(&crp, os->recrypt_sid);
+
+ KASSERT(tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16,
+ ("%s: only AES-GCM is supported", __func__));
+
+ /* Setup the IV. */
+ memcpy(crp.crp_iv, tls->params.iv, TLS_AEAD_GCM_LEN);
+ 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));
+ crp.crp_op = CRYPTO_OP_ENCRYPT;
+ crp.crp_flags = CRYPTO_F_CBIMM | CRYPTO_F_IV_SEPARATE;
+ crypto_use_mbuf(&crp, m);
+ crp.crp_payload_start = tls->params.tls_hlen;
+ crp.crp_payload_length = payload_len;
+
+ buf = malloc(payload_len, M_KTLS_OCF, M_WAITOK);
+ crypto_use_output_buf(&crp, buf, payload_len);
+
+ counter_u64_add(ocf_tls12_gcm_recrypts, 1);
+ error = ktls_ocf_dispatch(os, &crp);
+
+ crypto_destroyreq(&crp);
+
+ if (error == 0)
+ ktls_ocf_recrypt_fixup(m, tls->params.tls_hlen, payload_len,
+ buf);
+
+ free(buf, M_KTLS_OCF);
+ return (error);
+}
+
static struct ktls_ocf_sw ktls_ocf_tls12_aead_sw = {
.encrypt = ktls_ocf_tls12_aead_encrypt,
+ .recrypt = ktls_ocf_tls12_aead_recrypt,
.decrypt = ktls_ocf_tls12_aead_decrypt,
};
@@ -684,8 +777,57 @@
return (error);
}
+static int
+ktls_ocf_tls13_aead_recrypt(struct ktls_session *tls,
+ const struct tls_record_layer *hdr, struct mbuf *m,
+ uint64_t seqno)
+{
+ struct cryptop crp;
+ struct ktls_ocf_session *os;
+ char *buf;
+ char nonce[12];
+ u_int payload_len;
+ int error;
+
+ os = tls->ocf_session;
+
+ crypto_initreq(&crp, os->recrypt_sid);
+
+ KASSERT(tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16,
+ ("%s: only AES-GCM is supported", __func__));
+
+ /* Setup the IV. */
+ memcpy(nonce, tls->params.iv, tls->params.iv_len);
+ *(uint64_t *)(nonce + 4) ^= htobe64(seqno);
+ memcpy(crp.crp_iv, nonce, sizeof(nonce));
+ be32enc(crp.crp_iv + sizeof(nonce), 2);
+
+ payload_len = ntohs(hdr->tls_length) - 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);
+ crp.crp_payload_start = tls->params.tls_hlen;
+ crp.crp_payload_length = payload_len;
+
+ buf = malloc(payload_len, M_KTLS_OCF, M_WAITOK);
+ crypto_use_output_buf(&crp, buf, payload_len);
+
+ counter_u64_add(ocf_tls13_gcm_recrypts, 1);
+ error = ktls_ocf_dispatch(os, &crp);
+
+ crypto_destroyreq(&crp);
+
+ if (error == 0)
+ ktls_ocf_recrypt_fixup(m, tls->params.tls_hlen, payload_len,
+ buf);
+
+ free(buf, M_KTLS_OCF);
+ return (error);
+}
+
static struct ktls_ocf_sw ktls_ocf_tls13_aead_sw = {
.encrypt = ktls_ocf_tls13_aead_encrypt,
+ .recrypt = ktls_ocf_tls13_aead_recrypt,
.decrypt = ktls_ocf_tls13_aead_decrypt,
};
@@ -696,6 +838,8 @@
os = tls->ocf_session;
crypto_freesession(os->sid);
+ crypto_freesession(os->mac_sid);
+ crypto_freesession(os->recrypt_sid);
mtx_destroy(&os->lock);
zfree(os, M_KTLS_OCF);
}
@@ -703,7 +847,7 @@
int
ktls_ocf_try(struct socket *so, struct ktls_session *tls, int direction)
{
- struct crypto_session_params csp, mac_csp;
+ struct crypto_session_params csp, mac_csp, recrypt_csp;
struct ktls_ocf_session *os;
int error, mac_len;
@@ -711,6 +855,8 @@
memset(&mac_csp, 0, sizeof(mac_csp));
mac_csp.csp_mode = CSP_MODE_NONE;
mac_len = 0;
+ memset(&recrypt_csp, 0, sizeof(mac_csp));
+ recrypt_csp.csp_mode = CSP_MODE_NONE;
switch (tls->params.cipher_algorithm) {
case CRYPTO_AES_NIST_GCM_16:
@@ -734,6 +880,13 @@
csp.csp_cipher_key = tls->params.cipher_key;
csp.csp_cipher_klen = tls->params.cipher_key_len;
csp.csp_ivlen = AES_GCM_IV_LEN;
+
+ recrypt_csp.csp_flags |= CSP_F_SEPARATE_OUTPUT;
+ recrypt_csp.csp_mode = CSP_MODE_CIPHER;
+ recrypt_csp.csp_cipher_alg = CRYPTO_AES_ICM;
+ recrypt_csp.csp_cipher_key = tls->params.cipher_key;
+ recrypt_csp.csp_cipher_klen = tls->params.cipher_key_len;
+ recrypt_csp.csp_ivlen = AES_BLOCK_LEN;
break;
case CRYPTO_AES_CBC:
switch (tls->params.cipher_key_len) {
@@ -828,6 +981,16 @@
os->mac_len = mac_len;
}
+ if (recrypt_csp.csp_mode != CSP_MODE_NONE) {
+ error = crypto_newsession(&os->recrypt_sid, &recrypt_csp,
+ CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE);
+ if (error) {
+ crypto_freesession(os->sid);
+ free(os, M_KTLS_OCF);
+ return (error);
+ }
+ }
+
mtx_init(&os->lock, "ktls_ocf", NULL, MTX_DEF);
tls->ocf_session = os;
if (tls->params.cipher_algorithm == CRYPTO_AES_NIST_GCM_16 ||
@@ -872,3 +1035,17 @@
{
return (tls->ocf_session->sw->decrypt(tls, hdr, m, seqno, trailer_len));
}
+
+int
+ktls_ocf_recrypt(struct ktls_session *tls, const struct tls_record_layer *hdr,
+ struct mbuf *m, uint64_t seqno)
+{
+ return (tls->ocf_session->sw->recrypt(tls, hdr, m, seqno));
+}
+
+bool
+ktls_ocf_recrypt_supported(struct ktls_session *tls)
+{
+ return (tls->ocf_session->sw->recrypt != NULL &&
+ tls->ocf_session->recrypt_sid != NULL);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 19, 7:14 AM (19 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14712292
Default Alt Text
D35012.id105242.diff (8 KB)
Attached To
Mode
D35012: KTLS: Add a new recrypt operation to the software backend.
Attached
Detach File
Event Timeline
Log In to Comment