2 * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved.
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
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"
18 #ifndef OPENSSL_NO_KTLS_RX
20 * Count the number of records that were not processed yet from record boundary.
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
26 static int count_unprocessed_records(SSL_CONNECTION *s)
28 SSL3_BUFFER *rbuf = s->rrlmethod->get0_rbuf(s->rrl);
32 if (!PACKET_buf_init(&pkt, rbuf->buf + rbuf->offset, rbuf->left))
35 while (PACKET_remaining(&pkt) > 0) {
36 /* Skip record type and version */
37 if (!PACKET_forward(&pkt, 3))
40 /* Read until next record */
41 if (!PACKET_get_length_prefixed_2(&pkt, &subpkt))
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.
56 static int check_rx_read_ahead(SSL_CONNECTION *s, unsigned char *rec_seq)
58 int bit, count_unprocessed;
60 count_unprocessed = count_unprocessed_records(s);
61 if (count_unprocessed < 0)
64 /* increment the crypto_info record sequence */
65 while (count_unprocessed) {
66 for (bit = 7; bit >= 0; bit--) { /* increment */
68 if (rec_seq[bit] != 0)
79 #if defined(__FreeBSD__)
80 # include "crypto/cryptodev.h"
83 * Check if a given cipher is supported by the KTLS interface.
84 * The kernel might still fail the setsockopt() if no suitable
85 * provider is found, but this checks if the socket option
86 * supports the cipher suite used at all.
88 int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c,
102 switch (s->s3.tmp.new_cipher->algorithm_enc) {
106 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
107 case SSL_CHACHA20POLY1305:
114 switch (s->s3.tmp.new_cipher->algorithm_mac) {
127 /* Function to configure kernel TLS structure */
128 int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c,
129 void *rl_sequence, ktls_crypto_info_t *crypto_info,
130 int is_tx, unsigned char *iv, size_t ivlen,
131 unsigned char *key, size_t keylen,
132 unsigned char *mac_key, size_t mac_secret_size)
134 memset(crypto_info, 0, sizeof(*crypto_info));
135 switch (s->s3.tmp.new_cipher->algorithm_enc) {
138 crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16;
139 crypto_info->iv_len = ivlen;
141 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
142 case SSL_CHACHA20POLY1305:
143 crypto_info->cipher_algorithm = CRYPTO_CHACHA20_POLY1305;
144 crypto_info->iv_len = ivlen;
149 switch (s->s3.tmp.new_cipher->algorithm_mac) {
151 crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC;
154 crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC;
157 crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC;
162 crypto_info->cipher_algorithm = CRYPTO_AES_CBC;
163 crypto_info->iv_len = ivlen;
164 crypto_info->auth_key = mac_key;
165 crypto_info->auth_key_len = mac_secret_size;
170 crypto_info->cipher_key = key;
171 crypto_info->cipher_key_len = keylen;
172 crypto_info->iv = iv;
173 crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff;
174 crypto_info->tls_vminor = (s->version & 0x000000ff);
175 # ifdef TCP_RXTLS_ENABLE
176 memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq));
177 if (!is_tx && !check_rx_read_ahead(s, crypto_info->rec_seq))
186 #endif /* __FreeBSD__ */
188 #if defined(OPENSSL_SYS_LINUX)
190 /* Function to check supported ciphers in Linux */
191 int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c,
194 switch (s->version) {
202 /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128
203 * or Chacha20-Poly1305
205 # ifdef OPENSSL_KTLS_AES_CCM_128
206 if (EVP_CIPHER_is_a(c, "AES-128-CCM")) {
207 if (s->version == TLS_1_3_VERSION /* broken on 5.x kernels */
208 || taglen != EVP_CCM_TLS_TAG_LEN)
214 # ifdef OPENSSL_KTLS_AES_GCM_128
215 || EVP_CIPHER_is_a(c, "AES-128-GCM")
217 # ifdef OPENSSL_KTLS_AES_GCM_256
218 || EVP_CIPHER_is_a(c, "AES-256-GCM")
220 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
221 || EVP_CIPHER_is_a(c, "ChaCha20-Poly1305")
229 /* Function to configure kernel TLS structure */
230 int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c,
231 void *rl_sequence, ktls_crypto_info_t *crypto_info,
232 int is_tx, unsigned char *iv, size_t ivlen,
233 unsigned char *key, size_t keylen,
234 unsigned char *mac_key, size_t mac_secret_size)
236 unsigned char geniv[EVP_GCM_TLS_EXPLICIT_IV_LEN];
237 unsigned char *eiv = NULL;
238 SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
240 # ifdef OPENSSL_NO_KTLS_RX
245 if (EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE
246 || EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) {
247 if (!ossl_assert(EVP_GCM_TLS_FIXED_IV_LEN == EVP_CCM_TLS_FIXED_IV_LEN)
248 || !ossl_assert(EVP_GCM_TLS_EXPLICIT_IV_LEN
249 == EVP_CCM_TLS_EXPLICIT_IV_LEN))
251 if (s->version == TLS1_2_VERSION) {
252 if (!ossl_assert(ivlen == EVP_GCM_TLS_FIXED_IV_LEN))
255 if (RAND_bytes_ex(sctx->libctx, geniv,
256 EVP_GCM_TLS_EXPLICIT_IV_LEN, 0) <= 0)
259 memset(geniv, 0, EVP_GCM_TLS_EXPLICIT_IV_LEN);
263 if (!ossl_assert(ivlen == EVP_GCM_TLS_FIXED_IV_LEN
264 + EVP_GCM_TLS_EXPLICIT_IV_LEN))
266 eiv = iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE;
270 memset(crypto_info, 0, sizeof(*crypto_info));
271 switch (EVP_CIPHER_get_nid(c))
273 # ifdef OPENSSL_KTLS_AES_GCM_128
274 case NID_aes_128_gcm:
275 if (!ossl_assert(TLS_CIPHER_AES_GCM_128_SALT_SIZE == EVP_GCM_TLS_FIXED_IV_LEN)
276 || !ossl_assert(TLS_CIPHER_AES_GCM_128_IV_SIZE == EVP_GCM_TLS_EXPLICIT_IV_LEN))
278 crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128;
279 crypto_info->gcm128.info.version = s->version;
280 crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128);
281 memcpy(crypto_info->gcm128.iv, eiv, TLS_CIPHER_AES_GCM_128_IV_SIZE);
282 memcpy(crypto_info->gcm128.salt, iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
283 memcpy(crypto_info->gcm128.key, key, keylen);
284 memcpy(crypto_info->gcm128.rec_seq, rl_sequence,
285 TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
286 if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm128.rec_seq))
290 # ifdef OPENSSL_KTLS_AES_GCM_256
291 case NID_aes_256_gcm:
292 if (!ossl_assert(TLS_CIPHER_AES_GCM_256_SALT_SIZE == EVP_GCM_TLS_FIXED_IV_LEN)
293 || !ossl_assert(TLS_CIPHER_AES_GCM_256_IV_SIZE == EVP_GCM_TLS_EXPLICIT_IV_LEN))
295 crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256;
296 crypto_info->gcm256.info.version = s->version;
297 crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256);
298 memcpy(crypto_info->gcm256.iv, eiv, TLS_CIPHER_AES_GCM_256_IV_SIZE);
299 memcpy(crypto_info->gcm256.salt, iv, TLS_CIPHER_AES_GCM_256_SALT_SIZE);
300 memcpy(crypto_info->gcm256.key, key, keylen);
301 memcpy(crypto_info->gcm256.rec_seq, rl_sequence,
302 TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
303 if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm256.rec_seq))
308 # ifdef OPENSSL_KTLS_AES_CCM_128
309 case NID_aes_128_ccm:
310 if (!ossl_assert(TLS_CIPHER_AES_CCM_128_SALT_SIZE == EVP_CCM_TLS_FIXED_IV_LEN)
311 || !ossl_assert(TLS_CIPHER_AES_CCM_128_IV_SIZE == EVP_CCM_TLS_EXPLICIT_IV_LEN))
313 crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128;
314 crypto_info->ccm128.info.version = s->version;
315 crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128);
316 memcpy(crypto_info->ccm128.iv, eiv, TLS_CIPHER_AES_CCM_128_IV_SIZE);
317 memcpy(crypto_info->ccm128.salt, iv, TLS_CIPHER_AES_CCM_128_SALT_SIZE);
318 memcpy(crypto_info->ccm128.key, key, keylen);
319 memcpy(crypto_info->ccm128.rec_seq, rl_sequence,
320 TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
321 if (!is_tx && !check_rx_read_ahead(s, crypto_info->ccm128.rec_seq))
325 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
326 case NID_chacha20_poly1305:
327 if (!ossl_assert(ivlen == TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE))
329 crypto_info->chacha20poly1305.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305;
330 crypto_info->chacha20poly1305.info.version = s->version;
331 crypto_info->tls_crypto_info_len = sizeof(crypto_info->chacha20poly1305);
332 memcpy(crypto_info->chacha20poly1305.iv, iv, ivlen);
333 memcpy(crypto_info->chacha20poly1305.key, key, keylen);
334 memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence,
335 TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
337 && !check_rx_read_ahead(s,
338 crypto_info->chacha20poly1305.rec_seq))
348 #endif /* OPENSSL_SYS_LINUX */
350 /* TODO(RECLAYER): Handle OPENSSL_NO_COMP */
351 static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
352 unsigned char *key, size_t keylen,
353 unsigned char *iv, size_t ivlen,
354 unsigned char *mackey, size_t mackeylen,
355 const EVP_CIPHER *ciph,
357 /* TODO(RECLAYER): This probably should not be an int */
360 const SSL_COMP *comp,
361 /* TODO(RECLAYER): Remove me */
365 ktls_crypto_info_t crypto_info;
368 * Check if we are suitable for KTLS. If not suitable we return
369 * OSSL_RECORD_RETURN_NON_FATAL_ERR so that other record layers can be tried
374 return OSSL_RECORD_RETURN_NON_FATAL_ERR;
376 /* ktls supports only the maximum fragment size */
377 if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH)
378 return OSSL_RECORD_RETURN_NON_FATAL_ERR;
380 /* check that cipher is supported */
381 if (!ktls_check_supported_cipher(s, ciph, taglen))
382 return OSSL_RECORD_RETURN_NON_FATAL_ERR;
385 * TODO(RECLAYER): For the write side we need to add a check for
386 * use of s->record_padding_cb
389 /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */
390 if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) {
391 if (BIO_flush(rl->bio) <= 0)
392 return OSSL_RECORD_RETURN_NON_FATAL_ERR;
395 if (rl->direction == OSSL_RECORD_DIRECTION_WRITE)
396 rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer);
398 rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer);
400 if (!ktls_configure_crypto(s, ciph, rl_sequence, &crypto_info,
401 rl->direction == OSSL_RECORD_DIRECTION_WRITE,
402 iv, ivlen, key, keylen, mackey, mackeylen))
403 return OSSL_RECORD_RETURN_NON_FATAL_ERR;
405 if (!BIO_set_ktls(rl->bio, &crypto_info, rl->direction))
406 return OSSL_RECORD_RETURN_NON_FATAL_ERR;
408 return OSSL_RECORD_RETURN_SUCCESS;
411 static int ktls_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *inrecs, size_t n_recs,
412 int sending, SSL_MAC_BUF *mac, size_t macsize,
413 /* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
418 struct record_functions_st ossl_ktls_funcs = {
419 ktls_set_crypto_state,