About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / networking / tls.txt


Based on kernel version 4.16.1. Page generated on 2018-04-09 11:53 EST.

1	Overview
2	========
3	
4	Transport Layer Security (TLS) is a Upper Layer Protocol (ULP) that runs over
5	TCP. TLS provides end-to-end data integrity and confidentiality.
6	
7	User interface
8	==============
9	
10	Creating a TLS connection
11	-------------------------
12	
13	First create a new TCP socket and set the TLS ULP.
14	
15	  sock = socket(AF_INET, SOCK_STREAM, 0);
16	  setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));
17	
18	Setting the TLS ULP allows us to set/get TLS socket options. Currently
19	only the symmetric encryption is handled in the kernel.  After the TLS
20	handshake is complete, we have all the parameters required to move the
21	data-path to the kernel. There is a separate socket option for moving
22	the transmit and the receive into the kernel.
23	
24	  /* From linux/tls.h */
25	  struct tls_crypto_info {
26	          unsigned short version;
27	          unsigned short cipher_type;
28	  };
29	
30	  struct tls12_crypto_info_aes_gcm_128 {
31	          struct tls_crypto_info info;
32	          unsigned char iv[TLS_CIPHER_AES_GCM_128_IV_SIZE];
33	          unsigned char key[TLS_CIPHER_AES_GCM_128_KEY_SIZE];
34	          unsigned char salt[TLS_CIPHER_AES_GCM_128_SALT_SIZE];
35	          unsigned char rec_seq[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
36	  };
37	
38	
39	  struct tls12_crypto_info_aes_gcm_128 crypto_info;
40	
41	  crypto_info.info.version = TLS_1_2_VERSION;
42	  crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128;
43	  memcpy(crypto_info.iv, iv_write, TLS_CIPHER_AES_GCM_128_IV_SIZE);
44	  memcpy(crypto_info.rec_seq, seq_number_write,
45						TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
46	  memcpy(crypto_info.key, cipher_key_write, TLS_CIPHER_AES_GCM_128_KEY_SIZE);
47	  memcpy(crypto_info.salt, implicit_iv_write, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
48	
49	  setsockopt(sock, SOL_TLS, TLS_TX, &crypto_info, sizeof(crypto_info));
50	
51	Sending TLS application data
52	----------------------------
53	
54	After setting the TLS_TX socket option all application data sent over this
55	socket is encrypted using TLS and the parameters provided in the socket option.
56	For example, we can send an encrypted hello world record as follows:
57	
58	  const char *msg = "hello world\n";
59	  send(sock, msg, strlen(msg));
60	
61	send() data is directly encrypted from the userspace buffer provided
62	to the encrypted kernel send buffer if possible.
63	
64	The sendfile system call will send the file's data over TLS records of maximum
65	length (2^14).
66	
67	  file = open(filename, O_RDONLY);
68	  fstat(file, &stat);
69	  sendfile(sock, file, &offset, stat.st_size);
70	
71	TLS records are created and sent after each send() call, unless
72	MSG_MORE is passed.  MSG_MORE will delay creation of a record until
73	MSG_MORE is not passed, or the maximum record size is reached.
74	
75	The kernel will need to allocate a buffer for the encrypted data.
76	This buffer is allocated at the time send() is called, such that
77	either the entire send() call will return -ENOMEM (or block waiting
78	for memory), or the encryption will always succeed.  If send() returns
79	-ENOMEM and some data was left on the socket buffer from a previous
80	call using MSG_MORE, the MSG_MORE data is left on the socket buffer.
81	
82	Send TLS control messages
83	-------------------------
84	
85	Other than application data, TLS has control messages such as alert
86	messages (record type 21) and handshake messages (record type 22), etc.
87	These messages can be sent over the socket by providing the TLS record type
88	via a CMSG. For example the following function sends @data of @length bytes
89	using a record of type @record_type.
90	
91	/* send TLS control message using record_type */
92	  static int klts_send_ctrl_message(int sock, unsigned char record_type,
93	                                  void *data, size_t length)
94	  {
95	        struct msghdr msg = {0};
96	        int cmsg_len = sizeof(record_type);
97	        struct cmsghdr *cmsg;
98	        char buf[CMSG_SPACE(cmsg_len)];
99	        struct iovec msg_iov;   /* Vector of data to send/receive into.  */
100	
101	        msg.msg_control = buf;
102	        msg.msg_controllen = sizeof(buf);
103	        cmsg = CMSG_FIRSTHDR(&msg);
104	        cmsg->cmsg_level = SOL_TLS;
105	        cmsg->cmsg_type = TLS_SET_RECORD_TYPE;
106	        cmsg->cmsg_len = CMSG_LEN(cmsg_len);
107	        *CMSG_DATA(cmsg) = record_type;
108	        msg.msg_controllen = cmsg->cmsg_len;
109	
110	        msg_iov.iov_base = data;
111	        msg_iov.iov_len = length;
112	        msg.msg_iov = &msg_iov;
113	        msg.msg_iovlen = 1;
114	
115	        return sendmsg(sock, &msg, 0);
116	  }
117	
118	Control message data should be provided unencrypted, and will be
119	encrypted by the kernel.
120	
121	Integrating in to userspace TLS library
122	---------------------------------------
123	
124	At a high level, the kernel TLS ULP is a replacement for the record
125	layer of a userspace TLS library.
126	
127	A patchset to OpenSSL to use ktls as the record layer is here:
128	
129	https://github.com/Mellanox/tls-openssl
130	
131	An example of calling send directly after a handshake using
132	gnutls.  Since it doesn't implement a full record layer, control
133	messages are not supported:
134	
135	https://github.com/Mellanox/tls-af_ktls_tool
Hide Line Numbers


About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog