xref: /openssl/ssl/record/methods/ktls_meth.c (revision 1704961c)
1 /*
2  * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <openssl/evp.h>
11 #include <openssl/core_names.h>
12 #include <openssl/rand.h>
13 #include "../../ssl_local.h"
14 #include "../record_local.h"
15 #include "recmethod_local.h"
16 #include "internal/ktls.h"
17 
18 #if defined(__FreeBSD__)
19 # include "crypto/cryptodev.h"
20 
21 /*
22  * TODO(RECLAYER): This is essentially a copy of ktls_int_check_supported_cipher
23  * but using an SSL object instead of an OSSL_RECORD_LAYER object. Once
24  * the write side has been moved to the record layer this can be deleted
25  */
ktls_check_supported_cipher(const SSL_CONNECTION * s,const EVP_CIPHER * c,const EVP_MD * md,size_t taglen)26 int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c,
27                                 const EVP_MD *md, size_t taglen)
28 {
29 
30     switch (s->version) {
31     case TLS1_VERSION:
32     case TLS1_1_VERSION:
33     case TLS1_2_VERSION:
34     case TLS1_3_VERSION:
35         break;
36     default:
37         return 0;
38     }
39 
40     if (EVP_CIPHER_is_a(c, "AES-128-GCM")
41             || EVP_CIPHER_is_a(c, "AES-256-GCM")
42 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
43             || EVP_CIPHER_is_a(c, "CHACHA20-POLY1305")
44 # endif
45        )
46         return 1;
47 
48     if (!EVP_CIPHER_is_a(c, "AES-128-CBC")
49             && !EVP_CIPHER_is_a(c, "AES-256-CBC"))
50         return 0;
51 
52     if (s->ext.use_etm)
53         return 0;
54 
55     if (md == NULL
56             || EVP_MD_is_a(md, "SHA1")
57             || EVP_MD_is_a(md, "SHA2-256")
58             || EVP_MD_is_a(md, "SHA2-384"))
59         return 1;
60 
61     return 0;
62 }
63 
64 /*-
65  * Check if a given cipher is supported by the KTLS interface.
66  * The kernel might still fail the setsockopt() if no suitable
67  * provider is found, but this checks if the socket option
68  * supports the cipher suite used at all.
69  */
ktls_int_check_supported_cipher(OSSL_RECORD_LAYER * rl,const EVP_CIPHER * c,const EVP_MD * md,size_t taglen)70 static int ktls_int_check_supported_cipher(OSSL_RECORD_LAYER *rl,
71                                            const EVP_CIPHER *c,
72                                            const EVP_MD *md,
73                                            size_t taglen)
74 {
75     switch (rl->version) {
76     case TLS1_VERSION:
77     case TLS1_1_VERSION:
78     case TLS1_2_VERSION:
79     case TLS1_3_VERSION:
80         break;
81     default:
82         return 0;
83     }
84 
85     if (EVP_CIPHER_is_a(c, "AES-128-GCM")
86             || EVP_CIPHER_is_a(c, "AES-256-GCM")
87 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
88             || EVP_CIPHER_is_a(c, "CHACHA20-POLY1305")
89 # endif
90        )
91         return 1;
92 
93     if (!EVP_CIPHER_is_a(c, "AES-128-CBC")
94             && !EVP_CIPHER_is_a(c, "AES-256-CBC"))
95         return 0;
96 
97     if (rl->use_etm)
98         return 0;
99 
100     if (md == NULL)
101         return 0;
102 
103     if (EVP_MD_is_a(md, "SHA1")
104             || EVP_MD_is_a(md, "SHA2-256")
105             || EVP_MD_is_a(md, "SHA2-384"))
106         return 1;
107 
108     return 0;
109 }
110 
111 /* Function to configure kernel TLS structure */
ktls_configure_crypto(OSSL_LIB_CTX * libctx,int version,const EVP_CIPHER * c,EVP_MD * md,void * rl_sequence,ktls_crypto_info_t * crypto_info,int is_tx,unsigned char * iv,size_t ivlen,unsigned char * key,size_t keylen,unsigned char * mac_key,size_t mac_secret_size)112 int ktls_configure_crypto(OSSL_LIB_CTX *libctx, int version, const EVP_CIPHER *c,
113                           EVP_MD *md, void *rl_sequence,
114                           ktls_crypto_info_t *crypto_info, int is_tx,
115                           unsigned char *iv, size_t ivlen,
116                           unsigned char *key, size_t keylen,
117                           unsigned char *mac_key, size_t mac_secret_size)
118 {
119     memset(crypto_info, 0, sizeof(*crypto_info));
120     if (EVP_CIPHER_is_a(c, "AES-128-GCM")
121             || EVP_CIPHER_is_a(c, "AES-256-GCM")) {
122         crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16;
123         crypto_info->iv_len = ivlen;
124     } else
125 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
126     if (EVP_CIPHER_is_a(c, "CHACHA20-POLY1305")) {
127         crypto_info->cipher_algorithm = CRYPTO_CHACHA20_POLY1305;
128         crypto_info->iv_len = ivlen;
129     } else
130 # endif
131     if (EVP_CIPHER_is_a(c, "AES-128-CBC") || EVP_CIPHER_is_a(c, "AES-256-CBC")) {
132         if (md == NULL)
133             return 0;
134         if (EVP_MD_is_a(md, "SHA1"))
135             crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC;
136         else if (EVP_MD_is_a(md, "SHA2-256")) {
137             crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC;
138         else if (EVP_MD_is_a(md, "SHA2-384"))
139             crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC;
140         else
141             return 0;
142         crypto_info->cipher_algorithm = CRYPTO_AES_CBC;
143         crypto_info->iv_len = ivlen;
144         crypto_info->auth_key = mac_key;
145         crypto_info->auth_key_len = mac_secret_size;
146     } else {
147         return 0;
148     }
149     crypto_info->cipher_key = key;
150     crypto_info->cipher_key_len = keylen;
151     crypto_info->iv = iv;
152     crypto_info->tls_vmajor = (version >> 8) & 0x000000ff;
153     crypto_info->tls_vminor = (version & 0x000000ff);
154 # ifdef TCP_RXTLS_ENABLE
155     memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq));
156 # else
157     if (!is_tx)
158         return 0;
159 # endif
160     return 1;
161 };
162 
163 #endif                         /* __FreeBSD__ */
164 
165 #if defined(OPENSSL_SYS_LINUX)
166 
167 /*
168  * TODO(RECLAYER): This is essentially a copy of ktls_int_check_supported_cipher
169  * but using an SSL object instead of an OSSL_RECORD_LAYER object. Once
170  * the write side has been moved to the record layer this can be deleted
171  */
172 int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c,
173                                 const EVP_MD *md, size_t taglen)
174 {
175     switch (s->version) {
176     case TLS1_2_VERSION:
177     case TLS1_3_VERSION:
178         break;
179     default:
180         return 0;
181     }
182 
183     /*
184      * Check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128
185      * or Chacha20-Poly1305
186      */
187 # ifdef OPENSSL_KTLS_AES_CCM_128
188     if (EVP_CIPHER_is_a(c, "AES-128-CCM")) {
189         if (s->version == TLS_1_3_VERSION /* broken on 5.x kernels */
190             || taglen != EVP_CCM_TLS_TAG_LEN)
191             return 0;
192         return 1;
193     } else
194 # endif
195     if (0
196 # ifdef OPENSSL_KTLS_AES_GCM_128
197         || EVP_CIPHER_is_a(c, "AES-128-GCM")
198 # endif
199 # ifdef OPENSSL_KTLS_AES_GCM_256
200         || EVP_CIPHER_is_a(c, "AES-256-GCM")
201 # endif
202 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
203         || EVP_CIPHER_is_a(c, "ChaCha20-Poly1305")
204 # endif
205         ) {
206         return 1;
207     }
208     return 0;
209 }
210 
211 /* Function to check supported ciphers in Linux */
212 static int ktls_int_check_supported_cipher(OSSL_RECORD_LAYER *rl,
213                                            const EVP_CIPHER *c,
214                                            const EVP_MD *md,
215                                            size_t taglen)
216 {
217     switch (rl->version) {
218     case TLS1_2_VERSION:
219     case TLS1_3_VERSION:
220         break;
221     default:
222         return 0;
223     }
224 
225     /*
226      * Check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128
227      * or Chacha20-Poly1305
228      */
229 # ifdef OPENSSL_KTLS_AES_CCM_128
230     if (EVP_CIPHER_is_a(c, "AES-128-CCM")) {
231         if (rl->version == TLS_1_3_VERSION /* broken on 5.x kernels */
232             || taglen != EVP_CCM_TLS_TAG_LEN)
233             return 0;
234         return 1;
235     } else
236 # endif
237     if (0
238 # ifdef OPENSSL_KTLS_AES_GCM_128
239         || EVP_CIPHER_is_a(c, "AES-128-GCM")
240 # endif
241 # ifdef OPENSSL_KTLS_AES_GCM_256
242         || EVP_CIPHER_is_a(c, "AES-256-GCM")
243 # endif
244 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
245         || EVP_CIPHER_is_a(c, "ChaCha20-Poly1305")
246 # endif
247         ) {
248         return 1;
249     }
250     return 0;
251 }
252 
253 /* Function to configure kernel TLS structure */
254 int ktls_configure_crypto(OSSL_LIB_CTX *libctx, int version, const EVP_CIPHER *c,
255                           const EVP_MD *md, void *rl_sequence,
256                           ktls_crypto_info_t *crypto_info, int is_tx,
257                           unsigned char *iv, size_t ivlen,
258                           unsigned char *key, size_t keylen,
259                           unsigned char *mac_key, size_t mac_secret_size)
260 {
261     unsigned char geniv[EVP_GCM_TLS_EXPLICIT_IV_LEN];
262     unsigned char *eiv = NULL;
263 
264 # ifdef OPENSSL_NO_KTLS_RX
265     if (!is_tx)
266         return 0;
267 # endif
268 
269     if (EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE
270             || EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) {
271         if (!ossl_assert(EVP_GCM_TLS_FIXED_IV_LEN == EVP_CCM_TLS_FIXED_IV_LEN)
272                 || !ossl_assert(EVP_GCM_TLS_EXPLICIT_IV_LEN
273                                 == EVP_CCM_TLS_EXPLICIT_IV_LEN))
274             return 0;
275         if (version == TLS1_2_VERSION) {
276             if (!ossl_assert(ivlen == EVP_GCM_TLS_FIXED_IV_LEN))
277                 return 0;
278             if (is_tx) {
279                 if (RAND_bytes_ex(libctx, geniv,
280                                 EVP_GCM_TLS_EXPLICIT_IV_LEN, 0) <= 0)
281                     return 0;
282             } else {
283                 memset(geniv, 0, EVP_GCM_TLS_EXPLICIT_IV_LEN);
284             }
285             eiv = geniv;
286         } else {
287             if (!ossl_assert(ivlen == EVP_GCM_TLS_FIXED_IV_LEN
288                                       + EVP_GCM_TLS_EXPLICIT_IV_LEN))
289                 return 0;
290             eiv = iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE;
291         }
292     }
293 
294     memset(crypto_info, 0, sizeof(*crypto_info));
295     switch (EVP_CIPHER_get_nid(c)) {
296 # ifdef OPENSSL_KTLS_AES_GCM_128
297     case NID_aes_128_gcm:
298         if (!ossl_assert(TLS_CIPHER_AES_GCM_128_SALT_SIZE
299                          == EVP_GCM_TLS_FIXED_IV_LEN)
300                 || !ossl_assert(TLS_CIPHER_AES_GCM_128_IV_SIZE
301                                 == EVP_GCM_TLS_EXPLICIT_IV_LEN))
302             return 0;
303         crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128;
304         crypto_info->gcm128.info.version = version;
305         crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128);
306         memcpy(crypto_info->gcm128.iv, eiv, TLS_CIPHER_AES_GCM_128_IV_SIZE);
307         memcpy(crypto_info->gcm128.salt, iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
308         memcpy(crypto_info->gcm128.key, key, keylen);
309         memcpy(crypto_info->gcm128.rec_seq, rl_sequence,
310                TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
311         return 1;
312 # endif
313 # ifdef OPENSSL_KTLS_AES_GCM_256
314     case NID_aes_256_gcm:
315         if (!ossl_assert(TLS_CIPHER_AES_GCM_256_SALT_SIZE
316                          == EVP_GCM_TLS_FIXED_IV_LEN)
317                 || !ossl_assert(TLS_CIPHER_AES_GCM_256_IV_SIZE
318                                 == EVP_GCM_TLS_EXPLICIT_IV_LEN))
319             return 0;
320         crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256;
321         crypto_info->gcm256.info.version = version;
322         crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256);
323         memcpy(crypto_info->gcm256.iv, eiv, TLS_CIPHER_AES_GCM_256_IV_SIZE);
324         memcpy(crypto_info->gcm256.salt, iv, TLS_CIPHER_AES_GCM_256_SALT_SIZE);
325         memcpy(crypto_info->gcm256.key, key, keylen);
326         memcpy(crypto_info->gcm256.rec_seq, rl_sequence,
327                TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
328 
329         return 1;
330 # endif
331 # ifdef OPENSSL_KTLS_AES_CCM_128
332     case NID_aes_128_ccm:
333         if (!ossl_assert(TLS_CIPHER_AES_CCM_128_SALT_SIZE
334                          == EVP_CCM_TLS_FIXED_IV_LEN)
335                 || !ossl_assert(TLS_CIPHER_AES_CCM_128_IV_SIZE
336                                 == EVP_CCM_TLS_EXPLICIT_IV_LEN))
337             return 0;
338         crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128;
339         crypto_info->ccm128.info.version = version;
340         crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128);
341         memcpy(crypto_info->ccm128.iv, eiv, TLS_CIPHER_AES_CCM_128_IV_SIZE);
342         memcpy(crypto_info->ccm128.salt, iv, TLS_CIPHER_AES_CCM_128_SALT_SIZE);
343         memcpy(crypto_info->ccm128.key, key, keylen);
344         memcpy(crypto_info->ccm128.rec_seq, rl_sequence,
345                TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
346         return 1;
347 # endif
348 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
349     case NID_chacha20_poly1305:
350         if (!ossl_assert(ivlen == TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE))
351             return 0;
352         crypto_info->chacha20poly1305.info.cipher_type
353             = TLS_CIPHER_CHACHA20_POLY1305;
354         crypto_info->chacha20poly1305.info.version = version;
355         crypto_info->tls_crypto_info_len = sizeof(crypto_info->chacha20poly1305);
356         memcpy(crypto_info->chacha20poly1305.iv, iv, ivlen);
357         memcpy(crypto_info->chacha20poly1305.key, key, keylen);
358         memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence,
359                TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
360         return 1;
361 # endif
362     default:
363         return 0;
364     }
365 
366 }
367 
368 #endif /* OPENSSL_SYS_LINUX */
369 
370 static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
371                                  unsigned char *key, size_t keylen,
372                                  unsigned char *iv, size_t ivlen,
373                                  unsigned char *mackey, size_t mackeylen,
374                                  const EVP_CIPHER *ciph,
375                                  size_t taglen,
376                                  int mactype,
377                                  const EVP_MD *md,
378                                  const SSL_COMP *comp)
379 {
380     ktls_crypto_info_t crypto_info;
381 
382     /*
383      * Check if we are suitable for KTLS. If not suitable we return
384      * OSSL_RECORD_RETURN_NON_FATAL_ERR so that other record layers can be tried
385      * instead
386      */
387 
388     if (comp != NULL)
389         return OSSL_RECORD_RETURN_NON_FATAL_ERR;
390 
391     /* ktls supports only the maximum fragment size */
392     if (rl->max_frag_len > 0 && rl->max_frag_len != SSL3_RT_MAX_PLAIN_LENGTH)
393         return OSSL_RECORD_RETURN_NON_FATAL_ERR;
394 #if 0
395     /*
396      * TODO(RECLAYER): We will need to reintroduce the check of the send
397      * fragment for KTLS once we do the record write side implementation
398      */
399     if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH)
400         return OSSL_RECORD_RETURN_NON_FATAL_ERR;
401 #endif
402 
403     /* check that cipher is supported */
404     if (!ktls_int_check_supported_cipher(rl, ciph, md, taglen))
405         return OSSL_RECORD_RETURN_NON_FATAL_ERR;
406 
407     /*
408      * TODO(RECLAYER): For the write side we need to add a check for
409      * use of s->record_padding_cb
410      */
411 
412     /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */
413     if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) {
414        if (BIO_flush(rl->bio) <= 0)
415            return OSSL_RECORD_RETURN_NON_FATAL_ERR;
416     }
417 
418     if (!ktls_configure_crypto(rl->libctx, rl->version, ciph, md, rl->sequence,
419                                &crypto_info,
420                                rl->direction == OSSL_RECORD_DIRECTION_WRITE,
421                                iv, ivlen, key, keylen, mackey, mackeylen))
422        return OSSL_RECORD_RETURN_NON_FATAL_ERR;
423 
424     if (!BIO_set_ktls(rl->bio, &crypto_info, rl->direction))
425         return OSSL_RECORD_RETURN_NON_FATAL_ERR;
426 
427     return OSSL_RECORD_RETURN_SUCCESS;
428 }
429 
430 static int ktls_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
431                        int clearold, size_t *readbytes)
432 {
433     int ret;
434 
435     ret = tls_default_read_n(rl, n, max, extend, clearold, readbytes);
436 
437     if (ret < OSSL_RECORD_RETURN_RETRY) {
438         switch (errno) {
439         case EBADMSG:
440             RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC,
441                         SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
442             break;
443         case EMSGSIZE:
444             RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
445                         SSL_R_PACKET_LENGTH_TOO_LONG);
446             break;
447         case EINVAL:
448             RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
449                         SSL_R_WRONG_VERSION_NUMBER);
450             break;
451         default:
452             break;
453         }
454     }
455 
456     return ret;
457 }
458 
459 static int ktls_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *inrecs, size_t n_recs,
460                        int sending, SSL_MAC_BUF *mac, size_t macsize)
461 {
462     return 1;
463 }
464 
465 static int ktls_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
466 {
467     if (rec->rec_version != TLS1_2_VERSION) {
468         RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_WRONG_VERSION_NUMBER);
469         return 0;
470     }
471 
472     return 1;
473 }
474 
475 static int ktls_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
476 {
477     if (rl->version == TLS1_3_VERSION)
478         return tls13_common_post_process_record(rl, rec);
479 
480     return 1;
481 }
482 
483 static struct record_functions_st ossl_ktls_funcs = {
484     ktls_set_crypto_state,
485     ktls_read_n,
486     tls_get_more_records,
487     ktls_cipher,
488     NULL,
489     tls_default_set_protocol_version,
490     ktls_validate_record_header,
491     ktls_post_process_record
492 };
493 
494 static int
495 ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
496                       int role, int direction, int level, uint16_t epoch,
497                       unsigned char *key, size_t keylen, unsigned char *iv,
498                       size_t ivlen, unsigned char *mackey, size_t mackeylen,
499                       const EVP_CIPHER *ciph, size_t taglen,
500                       int mactype,
501                       const EVP_MD *md, const SSL_COMP *comp, BIO *prev,
502                       BIO *transport, BIO *next, BIO_ADDR *local, BIO_ADDR *peer,
503                       const OSSL_PARAM *settings, const OSSL_PARAM *options,
504                       const OSSL_DISPATCH *fns, void *cbarg,
505                       OSSL_RECORD_LAYER **retrl)
506 {
507     int ret;
508 
509     ret = tls_int_new_record_layer(libctx, propq, vers, role, direction, level,
510                                    key, keylen, iv, ivlen, mackey, mackeylen,
511                                    ciph, taglen, mactype, md, comp, prev,
512                                    transport, next, local, peer, settings,
513                                    options, fns, cbarg, retrl);
514 
515     if (ret != OSSL_RECORD_RETURN_SUCCESS)
516         return ret;
517 
518     (*retrl)->funcs = &ossl_ktls_funcs;
519 
520     ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv,
521                                             ivlen, mackey, mackeylen, ciph,
522                                             taglen, mactype, md, comp);
523 
524     if (ret != OSSL_RECORD_RETURN_SUCCESS) {
525         OPENSSL_free(*retrl);
526         *retrl = NULL;
527     } else {
528         /*
529          * With KTLS we always try and read as much as possible and fill the
530          * buffer
531          */
532         (*retrl)->read_ahead = 1;
533     }
534     return ret;
535 }
536 
537 const OSSL_RECORD_METHOD ossl_ktls_record_method = {
538     ktls_new_record_layer,
539     tls_free,
540     tls_reset,
541     tls_unprocessed_read_pending,
542     tls_processed_read_pending,
543     tls_app_data_pending,
544     tls_write_pending,
545     tls_get_max_record_len,
546     tls_get_max_records,
547     tls_write_records,
548     tls_retry_write_records,
549     tls_read_record,
550     tls_release_record,
551     tls_get_alert_code,
552     tls_set1_bio,
553     tls_set_protocol_version,
554     tls_set_plain_alerts,
555     tls_set_first_handshake,
556     tls_set_max_pipelines,
557     NULL,
558     tls_get_state,
559     tls_set_options
560 };
561