freebsd-dev/sys/opencrypto
John Baldwin 3c0e568505 Add support for KTLS RX via software decryption.
Allow TLS records to be decrypted in the kernel after being received
by a NIC.  At a high level this is somewhat similar to software KTLS
for the transmit path except in reverse.  Protocols enqueue mbufs
containing encrypted TLS records (or portions of records) into the
tail of a socket buffer and the KTLS layer decrypts those records
before returning them to userland applications.  However, there is an
important difference:

- In the transmit case, the socket buffer is always a single "record"
  holding a chain of mbufs.  Not-yet-encrypted mbufs are marked not
  ready (M_NOTREADY) and released to protocols for transmit by marking
  mbufs ready once their data is encrypted.

- In the receive case, incoming (encrypted) data appended to the
  socket buffer is still a single stream of data from the protocol,
  but decrypted TLS records are stored as separate records in the
  socket buffer and read individually via recvmsg().

Initially I tried to make this work by marking incoming mbufs as
M_NOTREADY, but there didn't seemed to be a non-gross way to deal with
picking a portion of the mbuf chain and turning it into a new record
in the socket buffer after decrypting the TLS record it contained
(along with prepending a control message).  Also, such mbufs would
also need to be "pinned" in some way while they are being decrypted
such that a concurrent sbcut() wouldn't free them out from under the
thread performing decryption.

As such, I settled on the following solution:

- Socket buffers now contain an additional chain of mbufs (sb_mtls,
  sb_mtlstail, and sb_tlscc) containing encrypted mbufs appended by
  the protocol layer.  These mbufs are still marked M_NOTREADY, but
  soreceive*() generally don't know about them (except that they will
  block waiting for data to be decrypted for a blocking read).

- Each time a new mbuf is appended to this TLS mbuf chain, the socket
  buffer peeks at the TLS record header at the head of the chain to
  determine the encrypted record's length.  If enough data is queued
  for the TLS record, the socket is placed on a per-CPU TLS workqueue
  (reusing the existing KTLS workqueues and worker threads).

- The worker thread loops over the TLS mbuf chain decrypting records
  until it runs out of data.  Each record is detached from the TLS
  mbuf chain while it is being decrypted to keep the mbufs "pinned".
  However, a new sb_dtlscc field tracks the character count of the
  detached record and sbcut()/sbdrop() is updated to account for the
  detached record.  After the record is decrypted, the worker thread
  first checks to see if sbcut() dropped the record.  If so, it is
  freed (can happen when a socket is closed with pending data).
  Otherwise, the header and trailer are stripped from the original
  mbufs, a control message is created holding the decrypted TLS
  header, and the decrypted TLS record is appended to the "normal"
  socket buffer chain.

(Side note: the SBCHECK() infrastucture was very useful as I was
 able to add assertions there about the TLS chain that caught several
 bugs during development.)

Tested by:	rmacklem (various versions)
Relnotes:	yes
Sponsored by:	Chelsio Communications
Differential Revision:	https://reviews.freebsd.org/D24628
2020-07-23 23:48:18 +00:00
..
_cryptodev.h OpenCrypto: Convert sessions to opaque handles instead of integers 2018-07-18 00:56:25 +00:00
cbc_mac.c Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
cbc_mac.h Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
criov.c Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
crypto.c Clean up crypto_init(). 2020-07-17 14:45:16 +00:00
cryptodeflate.c Allow Kernel to link in both legacy libkern/zlib and new sys/contrib/zlib, 2019-08-01 06:35:33 +00:00
cryptodev_if.m Refactor driver and consumer interfaces for OCF (in-kernel crypto). 2020-03-27 18:25:23 +00:00
cryptodev.c crypto(9): Stop checking for failures from malloc(M_WAITOK). 2020-07-20 17:44:13 +00:00
cryptodev.h Add crypto_initreq() and crypto_destroyreq(). 2020-07-16 21:30:46 +00:00
cryptosoft.c Use zfree() instead of explicit_bzero() and free(). 2020-06-25 20:17:34 +00:00
deflate.h Allow Kernel to link in both legacy libkern/zlib and new sys/contrib/zlib, 2019-08-01 06:35:33 +00:00
gfmult.c
gfmult.h
gmac.c Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
gmac.h Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
ktls_ocf.c Add support for KTLS RX via software decryption. 2020-07-23 23:48:18 +00:00
rmd160.c
rmd160.h
xform_aes_icm.c Improve support for stream ciphers in the software encryption interface. 2020-05-22 16:29:09 +00:00
xform_aes_xts.c Various cleanups to the software encryption transform interface. 2020-05-20 21:21:01 +00:00
xform_auth.h Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
xform_cbc_mac.c Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
xform_cml.c Various cleanups to the software encryption transform interface. 2020-05-20 21:21:01 +00:00
xform_comp.h Various cleanups to the software encryption transform interface. 2020-05-20 21:21:01 +00:00
xform_deflate.c
xform_enc.h Improve support for stream ciphers in the software encryption interface. 2020-05-22 16:29:09 +00:00
xform_gmac.c Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
xform_null.c Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
xform_poly1305.c Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
xform_poly1305.h Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
xform_rijndael.c Various cleanups to the software encryption transform interface. 2020-05-20 21:21:01 +00:00
xform_rmd160.c Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
xform_sha1.c Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
xform_sha2.c Adjust crypto_apply function callbacks for OCF. 2020-06-10 21:18:19 +00:00
xform.c Remove MD5 HMAC from OCF. 2020-05-11 22:08:08 +00:00
xform.h Remove MD5 HMAC from OCF. 2020-05-11 22:08:08 +00:00