tls: Add receive path documentation

Add documentation on rx path setup and cmsg interface.

Signed-off-by: Dave Watson <davejwatson@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Dave Watson 2018-03-22 10:10:44 -07:00 committed by David S. Miller
parent c46234ebb4
commit b6c535b163

View File

@ -48,6 +48,9 @@ the transmit and the receive into the kernel.
setsockopt(sock, SOL_TLS, TLS_TX, &crypto_info, sizeof(crypto_info));
Transmit and receive are set separately, but the setup is the same, using either
TLS_TX or TLS_RX.
Sending TLS application data
----------------------------
@ -79,6 +82,28 @@ for memory), or the encryption will always succeed. If send() returns
-ENOMEM and some data was left on the socket buffer from a previous
call using MSG_MORE, the MSG_MORE data is left on the socket buffer.
Receiving TLS application data
------------------------------
After setting the TLS_RX socket option, all recv family socket calls
are decrypted using TLS parameters provided. A full TLS record must
be received before decryption can happen.
char buffer[16384];
recv(sock, buffer, 16384);
Received data is decrypted directly in to the user buffer if it is
large enough, and no additional allocations occur. If the userspace
buffer is too small, data is decrypted in the kernel and copied to
userspace.
EINVAL is returned if the TLS version in the received message does not
match the version passed in setsockopt.
EMSGSIZE is returned if the received message is too big.
EBADMSG is returned if decryption failed for any other reason.
Send TLS control messages
-------------------------
@ -118,6 +143,43 @@ using a record of type @record_type.
Control message data should be provided unencrypted, and will be
encrypted by the kernel.
Receiving TLS control messages
------------------------------
TLS control messages are passed in the userspace buffer, with message
type passed via cmsg. If no cmsg buffer is provided, an error is
returned if a control message is received. Data messages may be
received without a cmsg buffer set.
char buffer[16384];
char cmsg[CMSG_SPACE(sizeof(unsigned char))];
struct msghdr msg = {0};
msg.msg_control = cmsg;
msg.msg_controllen = sizeof(cmsg);
struct iovec msg_iov;
msg_iov.iov_base = buffer;
msg_iov.iov_len = 16384;
msg.msg_iov = &msg_iov;
msg.msg_iovlen = 1;
int ret = recvmsg(sock, &msg, 0 /* flags */);
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
if (cmsg->cmsg_level == SOL_TLS &&
cmsg->cmsg_type == TLS_GET_RECORD_TYPE) {
int record_type = *((unsigned char *)CMSG_DATA(cmsg));
// Do something with record_type, and control message data in
// buffer.
//
// Note that record_type may be == to application data (23).
} else {
// Buffer contains application data.
}
recv will never return data from mixed types of TLS records.
Integrating in to userspace TLS library
---------------------------------------
@ -126,10 +188,10 @@ layer of a userspace TLS library.
A patchset to OpenSSL to use ktls as the record layer is here:
https://github.com/Mellanox/tls-openssl
https://github.com/Mellanox/openssl/commits/tls_rx2
An example of calling send directly after a handshake using
gnutls. Since it doesn't implement a full record layer, control
messages are not supported:
https://github.com/Mellanox/tls-af_ktls_tool
https://github.com/ktls/af_ktls-tool/commits/RX