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