@@ -48,6 +48,9 @@ the transmit and the receive into the kernel.
48
48
49
49
setsockopt(sock, SOL_TLS, TLS_TX, &crypto_info, sizeof(crypto_info));
50
50
51
+ Transmit and receive are set separately, but the setup is the same, using either
52
+ TLS_TX or TLS_RX.
53
+
51
54
Sending TLS application data
52
55
----------------------------
53
56
@@ -79,6 +82,28 @@ for memory), or the encryption will always succeed. If send() returns
79
82
-ENOMEM and some data was left on the socket buffer from a previous
80
83
call using MSG_MORE, the MSG_MORE data is left on the socket buffer.
81
84
85
+ Receiving TLS application data
86
+ ------------------------------
87
+
88
+ After setting the TLS_RX socket option, all recv family socket calls
89
+ are decrypted using TLS parameters provided. A full TLS record must
90
+ be received before decryption can happen.
91
+
92
+ char buffer[16384];
93
+ recv(sock, buffer, 16384);
94
+
95
+ Received data is decrypted directly in to the user buffer if it is
96
+ large enough, and no additional allocations occur. If the userspace
97
+ buffer is too small, data is decrypted in the kernel and copied to
98
+ userspace.
99
+
100
+ EINVAL is returned if the TLS version in the received message does not
101
+ match the version passed in setsockopt.
102
+
103
+ EMSGSIZE is returned if the received message is too big.
104
+
105
+ EBADMSG is returned if decryption failed for any other reason.
106
+
82
107
Send TLS control messages
83
108
-------------------------
84
109
@@ -118,6 +143,43 @@ using a record of type @record_type.
118
143
Control message data should be provided unencrypted, and will be
119
144
encrypted by the kernel.
120
145
146
+ Receiving TLS control messages
147
+ ------------------------------
148
+
149
+ TLS control messages are passed in the userspace buffer, with message
150
+ type passed via cmsg. If no cmsg buffer is provided, an error is
151
+ returned if a control message is received. Data messages may be
152
+ received without a cmsg buffer set.
153
+
154
+ char buffer[16384];
155
+ char cmsg[CMSG_SPACE(sizeof(unsigned char))];
156
+ struct msghdr msg = {0};
157
+ msg.msg_control = cmsg;
158
+ msg.msg_controllen = sizeof(cmsg);
159
+
160
+ struct iovec msg_iov;
161
+ msg_iov.iov_base = buffer;
162
+ msg_iov.iov_len = 16384;
163
+
164
+ msg.msg_iov = &msg_iov;
165
+ msg.msg_iovlen = 1;
166
+
167
+ int ret = recvmsg(sock, &msg, 0 /* flags */);
168
+
169
+ struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
170
+ if (cmsg->cmsg_level == SOL_TLS &&
171
+ cmsg->cmsg_type == TLS_GET_RECORD_TYPE) {
172
+ int record_type = *((unsigned char *)CMSG_DATA(cmsg));
173
+ // Do something with record_type, and control message data in
174
+ // buffer.
175
+ //
176
+ // Note that record_type may be == to application data (23).
177
+ } else {
178
+ // Buffer contains application data.
179
+ }
180
+
181
+ recv will never return data from mixed types of TLS records.
182
+
121
183
Integrating in to userspace TLS library
122
184
---------------------------------------
123
185
@@ -126,10 +188,10 @@ layer of a userspace TLS library.
126
188
127
189
A patchset to OpenSSL to use ktls as the record layer is here:
128
190
129
- https://github.com/Mellanox/tls- openssl
191
+ https://github.com/Mellanox/openssl/commits/tls_rx2
130
192
131
193
An example of calling send directly after a handshake using
132
194
gnutls. Since it doesn't implement a full record layer, control
133
195
messages are not supported:
134
196
135
- https://github.com/Mellanox/tls-af_ktls_tool
197
+ https://github.com/ktls/af_ktls-tool/commits/RX
0 commit comments