xref: /freebsd/crypto/openssl/ssl/ktls.c (revision 658a47d1ef6a0e8d56d346c5c16dcb2e001c3a40)
1 /*
2  * Copyright 2018-2020 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 "ssl_local.h"
11 #include "internal/ktls.h"
12 
13 #if defined(__FreeBSD__)
14 # include <crypto/cryptodev.h>
15 
16 /*-
17  * Check if a given cipher is supported by the KTLS interface.
18  * The kernel might still fail the setsockopt() if no suitable
19  * provider is found, but this checks if the socket option
20  * supports the cipher suite used at all.
21  */
22 int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c,
23                                 const EVP_CIPHER_CTX *dd)
24 {
25 
26     switch (s->version) {
27     case TLS1_VERSION:
28     case TLS1_1_VERSION:
29     case TLS1_2_VERSION:
30     case TLS1_3_VERSION:
31         break;
32     default:
33         return 0;
34     }
35 
36     switch (s->s3->tmp.new_cipher->algorithm_enc) {
37     case SSL_AES128GCM:
38     case SSL_AES256GCM:
39         return 1;
40 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
41     case SSL_CHACHA20POLY1305:
42         return 1;
43 # endif
44     case SSL_AES128:
45     case SSL_AES256:
46         if (s->ext.use_etm)
47             return 0;
48         switch (s->s3->tmp.new_cipher->algorithm_mac) {
49         case SSL_SHA1:
50         case SSL_SHA256:
51         case SSL_SHA384:
52             return 1;
53         default:
54             return 0;
55         }
56     default:
57         return 0;
58     }
59 }
60 
61 /* Function to configure kernel TLS structure */
62 int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
63                           void *rl_sequence, ktls_crypto_info_t *crypto_info,
64                           unsigned char **rec_seq, unsigned char *iv,
65                           unsigned char *key, unsigned char *mac_key,
66                           size_t mac_secret_size)
67 {
68     memset(crypto_info, 0, sizeof(*crypto_info));
69     switch (s->s3->tmp.new_cipher->algorithm_enc) {
70     case SSL_AES128GCM:
71     case SSL_AES256GCM:
72         crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16;
73         if (s->version == TLS1_3_VERSION)
74             crypto_info->iv_len = EVP_CIPHER_CTX_iv_length(dd);
75         else
76             crypto_info->iv_len = EVP_GCM_TLS_FIXED_IV_LEN;
77         break;
78 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
79     case SSL_CHACHA20POLY1305:
80         crypto_info->cipher_algorithm = CRYPTO_CHACHA20_POLY1305;
81         crypto_info->iv_len = EVP_CIPHER_CTX_iv_length(dd);
82         break;
83 # endif
84     case SSL_AES128:
85     case SSL_AES256:
86         switch (s->s3->tmp.new_cipher->algorithm_mac) {
87         case SSL_SHA1:
88             crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC;
89             break;
90         case SSL_SHA256:
91             crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC;
92             break;
93         case SSL_SHA384:
94             crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC;
95             break;
96         default:
97             return 0;
98         }
99         crypto_info->cipher_algorithm = CRYPTO_AES_CBC;
100         crypto_info->iv_len = EVP_CIPHER_iv_length(c);
101         crypto_info->auth_key = mac_key;
102         crypto_info->auth_key_len = mac_secret_size;
103         break;
104     default:
105         return 0;
106     }
107     crypto_info->cipher_key = key;
108     crypto_info->cipher_key_len = EVP_CIPHER_key_length(c);
109     crypto_info->iv = iv;
110     crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff;
111     crypto_info->tls_vminor = (s->version & 0x000000ff);
112 # ifdef TCP_RXTLS_ENABLE
113     memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq));
114     if (rec_seq != NULL)
115         *rec_seq = crypto_info->rec_seq;
116 # else
117     if (rec_seq != NULL)
118         *rec_seq = NULL;
119 # endif
120     return 1;
121 };
122 
123 #endif                         /* __FreeBSD__ */
124 
125 #if defined(OPENSSL_SYS_LINUX)
126 
127 /* Function to check supported ciphers in Linux */
128 int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c,
129                                 const EVP_CIPHER_CTX *dd)
130 {
131     switch (s->version) {
132     case TLS1_2_VERSION:
133     case TLS1_3_VERSION:
134         break;
135     default:
136         return 0;
137     }
138 
139     /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128
140      * or Chacha20-Poly1305
141      */
142     switch (EVP_CIPHER_nid(c))
143     {
144 # ifdef OPENSSL_KTLS_AES_CCM_128
145     case NID_aes_128_ccm:
146         if (EVP_CIPHER_CTX_tag_length(dd) != EVP_CCM_TLS_TAG_LEN)
147           return 0;
148 # endif
149 # ifdef OPENSSL_KTLS_AES_GCM_128
150         /* Fall through */
151     case NID_aes_128_gcm:
152 # endif
153 # ifdef OPENSSL_KTLS_AES_GCM_256
154     case NID_aes_256_gcm:
155 # endif
156 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
157     case NID_chacha20_poly1305:
158 # endif
159         return 1;
160     default:
161         return 0;
162     }
163 }
164 
165 /* Function to configure kernel TLS structure */
166 int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
167                           void *rl_sequence, ktls_crypto_info_t *crypto_info,
168                           unsigned char **rec_seq, unsigned char *iv,
169                           unsigned char *key, unsigned char *mac_key,
170                           size_t mac_secret_size)
171 {
172     unsigned char geniv[12];
173     unsigned char *iiv = iv;
174 
175     if (s->version == TLS1_2_VERSION &&
176         EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) {
177         EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV,
178                             EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN,
179                             geniv);
180         iiv = geniv;
181     }
182 
183     memset(crypto_info, 0, sizeof(*crypto_info));
184     switch (EVP_CIPHER_nid(c))
185     {
186 # ifdef OPENSSL_KTLS_AES_GCM_128
187     case NID_aes_128_gcm:
188         crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128;
189         crypto_info->gcm128.info.version = s->version;
190         crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128);
191         memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN,
192                 TLS_CIPHER_AES_GCM_128_IV_SIZE);
193         memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
194         memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_key_length(c));
195         memcpy(crypto_info->gcm128.rec_seq, rl_sequence,
196                 TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
197         if (rec_seq != NULL)
198             *rec_seq = crypto_info->gcm128.rec_seq;
199         return 1;
200 # endif
201 # ifdef OPENSSL_KTLS_AES_GCM_256
202     case NID_aes_256_gcm:
203         crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256;
204         crypto_info->gcm256.info.version = s->version;
205         crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256);
206         memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN,
207                 TLS_CIPHER_AES_GCM_256_IV_SIZE);
208         memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE);
209         memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_key_length(c));
210         memcpy(crypto_info->gcm256.rec_seq, rl_sequence,
211                 TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
212         if (rec_seq != NULL)
213             *rec_seq = crypto_info->gcm256.rec_seq;
214         return 1;
215 # endif
216 # ifdef OPENSSL_KTLS_AES_CCM_128
217     case NID_aes_128_ccm:
218         crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128;
219         crypto_info->ccm128.info.version = s->version;
220         crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128);
221         memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN,
222                 TLS_CIPHER_AES_CCM_128_IV_SIZE);
223         memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE);
224         memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_key_length(c));
225         memcpy(crypto_info->ccm128.rec_seq, rl_sequence,
226                 TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
227         if (rec_seq != NULL)
228             *rec_seq = crypto_info->ccm128.rec_seq;
229         return 1;
230 # endif
231 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
232     case NID_chacha20_poly1305:
233         crypto_info->chacha20poly1305.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305;
234         crypto_info->chacha20poly1305.info.version = s->version;
235         crypto_info->tls_crypto_info_len = sizeof(crypto_info->chacha20poly1305);
236         memcpy(crypto_info->chacha20poly1305.iv, iiv,
237 		TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
238         memcpy(crypto_info->chacha20poly1305.key, key, EVP_CIPHER_key_length(c));
239         memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence,
240                 TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
241         if (rec_seq != NULL)
242             *rec_seq = crypto_info->chacha20poly1305.rec_seq;
243         return 1;
244 # endif
245     default:
246         return 0;
247     }
248 
249 }
250 
251 #endif /* OPENSSL_SYS_LINUX */
252