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/rand.h>
11 #include "ssl_local.h"
12 #include "internal/ktls.h"
14 #ifndef OPENSSL_NO_KTLS_RX
16 * Count the number of records that were not processed yet from record boundary.
18 * This function assumes that there are only fully formed records read in the
19 * record layer. If read_ahead is enabled, then this might be false and this
22 static int count_unprocessed_records(SSL_CONNECTION *s)
24 SSL3_BUFFER *rbuf = s->rrlmethod->get0_rbuf(s->rrl);
28 if (!PACKET_buf_init(&pkt, rbuf->buf + rbuf->offset, rbuf->left))
31 while (PACKET_remaining(&pkt) > 0) {
32 /* Skip record type and version */
33 if (!PACKET_forward(&pkt, 3))
36 /* Read until next record */
37 if (!PACKET_get_length_prefixed_2(&pkt, &subpkt))
47 * The kernel cannot offload receive if a partial TLS record has been read.
48 * Check the read buffer for unprocessed records. If the buffer contains a
49 * partial record, fail and return 0. Otherwise, update the sequence
50 * number at *rec_seq for the count of unprocessed records and return 1.
52 static int check_rx_read_ahead(SSL_CONNECTION *s, unsigned char *rec_seq)
54 int bit, count_unprocessed;
56 count_unprocessed = count_unprocessed_records(s);
57 if (count_unprocessed < 0)
60 /* increment the crypto_info record sequence */
61 while (count_unprocessed) {
62 for (bit = 7; bit >= 0; bit--) { /* increment */
64 if (rec_seq[bit] != 0)
75 #if defined(__FreeBSD__)
76 # include "crypto/cryptodev.h"
79 * Check if a given cipher is supported by the KTLS interface.
80 * The kernel might still fail the setsockopt() if no suitable
81 * provider is found, but this checks if the socket option
82 * supports the cipher suite used at all.
84 int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c,
98 switch (s->s3.tmp.new_cipher->algorithm_enc) {
102 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
103 case SSL_CHACHA20POLY1305:
110 switch (s->s3.tmp.new_cipher->algorithm_mac) {
123 /* Function to configure kernel TLS structure */
124 int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, void *rl_sequence,
125 ktls_crypto_info_t *crypto_info, int is_tx,
126 unsigned char *iv, size_t ivlen, unsigned char *key,
127 size_t keylen, unsigned char *mac_key,
128 size_t mac_secret_size)
130 memset(crypto_info, 0, sizeof(*crypto_info));
131 switch (s->s3.tmp.new_cipher->algorithm_enc) {
134 crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16;
135 crypto_info->iv_len = ivlen;
137 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
138 case SSL_CHACHA20POLY1305:
139 crypto_info->cipher_algorithm = CRYPTO_CHACHA20_POLY1305;
140 crypto_info->iv_len = ivlen;
145 switch (s->s3.tmp.new_cipher->algorithm_mac) {
147 crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC;
150 crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC;
153 crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC;
158 crypto_info->cipher_algorithm = CRYPTO_AES_CBC;
159 crypto_info->iv_len = ivlen;
160 crypto_info->auth_key = mac_key;
161 crypto_info->auth_key_len = mac_secret_size;
166 crypto_info->cipher_key = key;
167 crypto_info->cipher_key_len = keylen;
168 crypto_info->iv = iv;
169 crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff;
170 crypto_info->tls_vminor = (s->version & 0x000000ff);
171 # ifdef TCP_RXTLS_ENABLE
172 memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq));
173 if (!is_tx && !check_rx_read_ahead(s, crypto_info->rec_seq))
182 #endif /* __FreeBSD__ */
184 #if defined(OPENSSL_SYS_LINUX)
186 /* Function to check supported ciphers in Linux */
187 int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c,
190 switch (s->version) {
198 /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128
199 * or Chacha20-Poly1305
201 # ifdef OPENSSL_KTLS_AES_CCM_128
202 if (EVP_CIPHER_is_a(c, "AES-128-CCM")) {
203 if (s->version == TLS_1_3_VERSION /* broken on 5.x kernels */
204 || taglen != EVP_CCM_TLS_TAG_LEN)
210 # ifdef OPENSSL_KTLS_AES_GCM_128
211 || EVP_CIPHER_is_a(c, "AES-128-GCM")
213 # ifdef OPENSSL_KTLS_AES_GCM_256
214 || EVP_CIPHER_is_a(c, "AES-256-GCM")
216 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
217 || EVP_CIPHER_is_a(c, "ChaCha20-Poly1305")
225 /* Function to configure kernel TLS structure */
226 int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, void *rl_sequence,
227 ktls_crypto_info_t *crypto_info, int is_tx,
228 unsigned char *iv, size_t ivlen, unsigned char *key,
229 size_t keylen, unsigned char *mac_key,
230 size_t mac_secret_size)
232 unsigned char geniv[EVP_GCM_TLS_EXPLICIT_IV_LEN];
234 SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
236 # ifdef OPENSSL_NO_KTLS_RX
241 if (EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE
242 || EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) {
243 if (!ossl_assert(EVP_GCM_TLS_FIXED_IV_LEN == EVP_CCM_TLS_FIXED_IV_LEN)
244 || !ossl_assert(EVP_GCM_TLS_EXPLICIT_IV_LEN
245 == EVP_CCM_TLS_EXPLICIT_IV_LEN))
247 if (s->version == TLS1_2_VERSION) {
248 if (!ossl_assert(ivlen == EVP_GCM_TLS_FIXED_IV_LEN))
251 if (RAND_bytes_ex(sctx->libctx, geniv,
252 EVP_GCM_TLS_EXPLICIT_IV_LEN, 0) <= 0)
255 memset(geniv, 0, EVP_GCM_TLS_EXPLICIT_IV_LEN);
259 if (!ossl_assert(ivlen == EVP_GCM_TLS_FIXED_IV_LEN
260 + EVP_GCM_TLS_EXPLICIT_IV_LEN))
262 eiv = iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE;
266 memset(crypto_info, 0, sizeof(*crypto_info));
267 switch (EVP_CIPHER_get_nid(c))
269 # ifdef OPENSSL_KTLS_AES_GCM_128
270 case NID_aes_128_gcm:
271 if (!ossl_assert(TLS_CIPHER_AES_GCM_128_SALT_SIZE == EVP_GCM_TLS_FIXED_IV_LEN)
272 || !ossl_assert(TLS_CIPHER_AES_GCM_128_IV_SIZE == EVP_GCM_TLS_EXPLICIT_IV_LEN))
274 crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128;
275 crypto_info->gcm128.info.version = s->version;
276 crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128);
277 memcpy(crypto_info->gcm128.iv, eiv, TLS_CIPHER_AES_GCM_128_IV_SIZE);
278 memcpy(crypto_info->gcm128.salt, iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
279 memcpy(crypto_info->gcm128.key, key, keylen);
280 memcpy(crypto_info->gcm128.rec_seq, rl_sequence,
281 TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
282 if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm128.rec_seq))
286 # ifdef OPENSSL_KTLS_AES_GCM_256
287 case NID_aes_256_gcm:
288 if (!ossl_assert(TLS_CIPHER_AES_GCM_256_SALT_SIZE == EVP_GCM_TLS_FIXED_IV_LEN)
289 || !ossl_assert(TLS_CIPHER_AES_GCM_256_IV_SIZE == EVP_GCM_TLS_EXPLICIT_IV_LEN))
291 crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256;
292 crypto_info->gcm256.info.version = s->version;
293 crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256);
294 memcpy(crypto_info->gcm256.iv, eiv, TLS_CIPHER_AES_GCM_256_IV_SIZE);
295 memcpy(crypto_info->gcm256.salt, iv, TLS_CIPHER_AES_GCM_256_SALT_SIZE);
296 memcpy(crypto_info->gcm256.key, key, keylen);
297 memcpy(crypto_info->gcm256.rec_seq, rl_sequence,
298 TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
299 if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm256.rec_seq))
304 # ifdef OPENSSL_KTLS_AES_CCM_128
305 case NID_aes_128_ccm:
306 if (!ossl_assert(TLS_CIPHER_AES_CCM_128_SALT_SIZE == EVP_CCM_TLS_FIXED_IV_LEN)
307 || !ossl_assert(TLS_CIPHER_AES_CCM_128_IV_SIZE == EVP_CCM_TLS_EXPLICIT_IV_LEN))
309 crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128;
310 crypto_info->ccm128.info.version = s->version;
311 crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128);
312 memcpy(crypto_info->ccm128.iv, eiv, TLS_CIPHER_AES_CCM_128_IV_SIZE);
313 memcpy(crypto_info->ccm128.salt, iv, TLS_CIPHER_AES_CCM_128_SALT_SIZE);
314 memcpy(crypto_info->ccm128.key, key, keylen);
315 memcpy(crypto_info->ccm128.rec_seq, rl_sequence,
316 TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
317 if (!is_tx && !check_rx_read_ahead(s, crypto_info->ccm128.rec_seq))
321 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
322 case NID_chacha20_poly1305:
323 if (!ossl_assert(ivlen == TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE))
325 crypto_info->chacha20poly1305.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305;
326 crypto_info->chacha20poly1305.info.version = s->version;
327 crypto_info->tls_crypto_info_len = sizeof(crypto_info->chacha20poly1305);
328 memcpy(crypto_info->chacha20poly1305.iv, iv, ivlen);
329 memcpy(crypto_info->chacha20poly1305.key, key, keylen);
330 memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence,
331 TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
333 && !check_rx_read_ahead(s,
334 crypto_info->chacha20poly1305.rec_seq))
344 #endif /* OPENSSL_SYS_LINUX */