2 * Copyright 2018-2021 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 "ssl_local.h"
11 #include "internal/ktls.h"
13 #if defined(__FreeBSD__)
14 # include <crypto/cryptodev.h>
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.
22 int ktls_check_supported_cipher(const SSL
*s
, const EVP_CIPHER
*c
,
23 const EVP_CIPHER_CTX
*dd
)
36 switch (s
->s3
.tmp
.new_cipher
->algorithm_enc
) {
44 switch (s
->s3
.tmp
.new_cipher
->algorithm_mac
) {
57 /* Function to configure kernel TLS structure */
58 int ktls_configure_crypto(const SSL
*s
, const EVP_CIPHER
*c
, EVP_CIPHER_CTX
*dd
,
59 void *rl_sequence
, ktls_crypto_info_t
*crypto_info
,
60 unsigned char **rec_seq
, unsigned char *iv
,
61 unsigned char *key
, unsigned char *mac_key
,
62 size_t mac_secret_size
)
64 memset(crypto_info
, 0, sizeof(*crypto_info
));
65 switch (s
->s3
.tmp
.new_cipher
->algorithm_enc
) {
68 crypto_info
->cipher_algorithm
= CRYPTO_AES_NIST_GCM_16
;
69 if (s
->version
== TLS1_3_VERSION
)
70 crypto_info
->iv_len
= EVP_CIPHER_CTX_iv_length(dd
);
72 crypto_info
->iv_len
= EVP_GCM_TLS_FIXED_IV_LEN
;
76 switch (s
->s3
.tmp
.new_cipher
->algorithm_mac
) {
78 crypto_info
->auth_algorithm
= CRYPTO_SHA1_HMAC
;
81 crypto_info
->auth_algorithm
= CRYPTO_SHA2_256_HMAC
;
84 crypto_info
->auth_algorithm
= CRYPTO_SHA2_384_HMAC
;
89 crypto_info
->cipher_algorithm
= CRYPTO_AES_CBC
;
90 crypto_info
->iv_len
= EVP_CIPHER_iv_length(c
);
91 crypto_info
->auth_key
= mac_key
;
92 crypto_info
->auth_key_len
= mac_secret_size
;
97 crypto_info
->cipher_key
= key
;
98 crypto_info
->cipher_key_len
= EVP_CIPHER_key_length(c
);
100 crypto_info
->tls_vmajor
= (s
->version
>> 8) & 0x000000ff;
101 crypto_info
->tls_vminor
= (s
->version
& 0x000000ff);
102 # ifdef TCP_RXTLS_ENABLE
103 memcpy(crypto_info
->rec_seq
, rl_sequence
, sizeof(crypto_info
->rec_seq
));
105 *rec_seq
= crypto_info
->rec_seq
;
113 #endif /* __FreeBSD__ */
115 #if defined(OPENSSL_SYS_LINUX)
117 /* Function to check supported ciphers in Linux */
118 int ktls_check_supported_cipher(const SSL
*s
, const EVP_CIPHER
*c
,
119 const EVP_CIPHER_CTX
*dd
)
121 switch (s
->version
) {
129 /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128
130 * or Chacha20-Poly1305
132 switch (EVP_CIPHER_nid(c
))
134 # ifdef OPENSSL_KTLS_AES_CCM_128
135 case NID_aes_128_ccm
:
136 if (EVP_CIPHER_CTX_tag_length(dd
) != EVP_CCM_TLS_TAG_LEN
)
139 # ifdef OPENSSL_KTLS_AES_GCM_128
140 case NID_aes_128_gcm
:
142 # ifdef OPENSSL_KTLS_AES_GCM_256
143 case NID_aes_256_gcm
:
145 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
146 case NID_chacha20_poly1305
:
154 /* Function to configure kernel TLS structure */
155 int ktls_configure_crypto(const SSL
*s
, const EVP_CIPHER
*c
, EVP_CIPHER_CTX
*dd
,
156 void *rl_sequence
, ktls_crypto_info_t
*crypto_info
,
157 unsigned char **rec_seq
, unsigned char *iv
,
158 unsigned char *key
, unsigned char *mac_key
,
159 size_t mac_secret_size
)
161 unsigned char geniv
[12];
162 unsigned char *iiv
= iv
;
164 if (s
->version
== TLS1_2_VERSION
&&
165 EVP_CIPHER_mode(c
) == EVP_CIPH_GCM_MODE
) {
166 if (!EVP_CIPHER_CTX_get_updated_iv(dd
, geniv
,
167 EVP_GCM_TLS_FIXED_IV_LEN
168 + EVP_GCM_TLS_EXPLICIT_IV_LEN
))
173 memset(crypto_info
, 0, sizeof(*crypto_info
));
174 switch (EVP_CIPHER_nid(c
))
176 # ifdef OPENSSL_KTLS_AES_GCM_128
177 case NID_aes_128_gcm
:
178 crypto_info
->gcm128
.info
.cipher_type
= TLS_CIPHER_AES_GCM_128
;
179 crypto_info
->gcm128
.info
.version
= s
->version
;
180 crypto_info
->tls_crypto_info_len
= sizeof(crypto_info
->gcm128
);
181 memcpy(crypto_info
->gcm128
.iv
, iiv
+ EVP_GCM_TLS_FIXED_IV_LEN
,
182 TLS_CIPHER_AES_GCM_128_IV_SIZE
);
183 memcpy(crypto_info
->gcm128
.salt
, iiv
, TLS_CIPHER_AES_GCM_128_SALT_SIZE
);
184 memcpy(crypto_info
->gcm128
.key
, key
, EVP_CIPHER_key_length(c
));
185 memcpy(crypto_info
->gcm128
.rec_seq
, rl_sequence
,
186 TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE
);
188 *rec_seq
= crypto_info
->gcm128
.rec_seq
;
191 # ifdef OPENSSL_KTLS_AES_GCM_256
192 case NID_aes_256_gcm
:
193 crypto_info
->gcm256
.info
.cipher_type
= TLS_CIPHER_AES_GCM_256
;
194 crypto_info
->gcm256
.info
.version
= s
->version
;
195 crypto_info
->tls_crypto_info_len
= sizeof(crypto_info
->gcm256
);
196 memcpy(crypto_info
->gcm256
.iv
, iiv
+ EVP_GCM_TLS_FIXED_IV_LEN
,
197 TLS_CIPHER_AES_GCM_256_IV_SIZE
);
198 memcpy(crypto_info
->gcm256
.salt
, iiv
, TLS_CIPHER_AES_GCM_256_SALT_SIZE
);
199 memcpy(crypto_info
->gcm256
.key
, key
, EVP_CIPHER_key_length(c
));
200 memcpy(crypto_info
->gcm256
.rec_seq
, rl_sequence
,
201 TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE
);
203 *rec_seq
= crypto_info
->gcm256
.rec_seq
;
206 # ifdef OPENSSL_KTLS_AES_CCM_128
207 case NID_aes_128_ccm
:
208 crypto_info
->ccm128
.info
.cipher_type
= TLS_CIPHER_AES_CCM_128
;
209 crypto_info
->ccm128
.info
.version
= s
->version
;
210 crypto_info
->tls_crypto_info_len
= sizeof(crypto_info
->ccm128
);
211 memcpy(crypto_info
->ccm128
.iv
, iiv
+ EVP_CCM_TLS_FIXED_IV_LEN
,
212 TLS_CIPHER_AES_CCM_128_IV_SIZE
);
213 memcpy(crypto_info
->ccm128
.salt
, iiv
, TLS_CIPHER_AES_CCM_128_SALT_SIZE
);
214 memcpy(crypto_info
->ccm128
.key
, key
, EVP_CIPHER_key_length(c
));
215 memcpy(crypto_info
->ccm128
.rec_seq
, rl_sequence
,
216 TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE
);
218 *rec_seq
= crypto_info
->ccm128
.rec_seq
;
221 # ifdef OPENSSL_KTLS_CHACHA20_POLY1305
222 case NID_chacha20_poly1305
:
223 crypto_info
->chacha20poly1305
.info
.cipher_type
= TLS_CIPHER_CHACHA20_POLY1305
;
224 crypto_info
->chacha20poly1305
.info
.version
= s
->version
;
225 crypto_info
->tls_crypto_info_len
= sizeof(crypto_info
->chacha20poly1305
);
226 memcpy(crypto_info
->chacha20poly1305
.iv
, iiv
,
227 TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE
);
228 memcpy(crypto_info
->chacha20poly1305
.key
, key
, EVP_CIPHER_key_length(c
));
229 memcpy(crypto_info
->chacha20poly1305
.rec_seq
, rl_sequence
,
230 TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE
);
232 *rec_seq
= crypto_info
->chacha20poly1305
.rec_seq
;
241 #endif /* OPENSSL_SYS_LINUX */