1/*
2 * Copyright 2018-2022 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#ifndef OPENSSL_NO_KTLS_RX
14 /*
15  * Count the number of records that were not processed yet from record boundary.
16  *
17  * This function assumes that there are only fully formed records read in the
18  * record layer. If read_ahead is enabled, then this might be false and this
19  * function will fail.
20  */
21static int count_unprocessed_records(SSL *s)
22{
23    SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
24    PACKET pkt, subpkt;
25    int count = 0;
26
27    if (!PACKET_buf_init(&pkt, rbuf->buf + rbuf->offset, rbuf->left))
28        return -1;
29
30    while (PACKET_remaining(&pkt) > 0) {
31        /* Skip record type and version */
32        if (!PACKET_forward(&pkt, 3))
33            return -1;
34
35        /* Read until next record */
36        if (!PACKET_get_length_prefixed_2(&pkt, &subpkt))
37            return -1;
38
39        count += 1;
40    }
41
42    return count;
43}
44
45/*
46 * The kernel cannot offload receive if a partial TLS record has been read.
47 * Check the read buffer for unprocessed records.  If the buffer contains a
48 * partial record, fail and return 0.  Otherwise, update the sequence
49 * number at *rec_seq for the count of unprocessed records and return 1.
50 */
51static int check_rx_read_ahead(SSL *s, unsigned char *rec_seq)
52{
53    int bit, count_unprocessed;
54
55    count_unprocessed = count_unprocessed_records(s);
56    if (count_unprocessed < 0)
57        return 0;
58
59    /* increment the crypto_info record sequence */
60    while (count_unprocessed) {
61        for (bit = 7; bit >= 0; bit--) { /* increment */
62            ++rec_seq[bit];
63            if (rec_seq[bit] != 0)
64                break;
65        }
66        count_unprocessed--;
67
68    }
69
70    return 1;
71}
72#endif
73
74#if defined(__FreeBSD__)
75# include "crypto/cryptodev.h"
76
77/*-
78 * Check if a given cipher is supported by the KTLS interface.
79 * The kernel might still fail the setsockopt() if no suitable
80 * provider is found, but this checks if the socket option
81 * supports the cipher suite used at all.
82 */
83int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c,
84                                const EVP_CIPHER_CTX *dd)
85{
86
87    switch (s->version) {
88    case TLS1_VERSION:
89    case TLS1_1_VERSION:
90    case TLS1_2_VERSION:
91    case TLS1_3_VERSION:
92        break;
93    default:
94        return 0;
95    }
96
97    switch (s->s3.tmp.new_cipher->algorithm_enc) {
98    case SSL_AES128GCM:
99    case SSL_AES256GCM:
100        return 1;
101# ifdef OPENSSL_KTLS_CHACHA20_POLY1305
102    case SSL_CHACHA20POLY1305:
103        return 1;
104# endif
105    case SSL_AES128:
106    case SSL_AES256:
107        if (s->ext.use_etm)
108            return 0;
109        switch (s->s3.tmp.new_cipher->algorithm_mac) {
110        case SSL_SHA1:
111        case SSL_SHA256:
112        case SSL_SHA384:
113            return 1;
114        default:
115            return 0;
116        }
117    default:
118        return 0;
119    }
120}
121
122/* Function to configure kernel TLS structure */
123int ktls_configure_crypto(SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
124                          void *rl_sequence, ktls_crypto_info_t *crypto_info,
125                          int is_tx, unsigned char *iv,
126                          unsigned char *key, unsigned char *mac_key,
127                          size_t mac_secret_size)
128{
129    memset(crypto_info, 0, sizeof(*crypto_info));
130    switch (s->s3.tmp.new_cipher->algorithm_enc) {
131    case SSL_AES128GCM:
132    case SSL_AES256GCM:
133        crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16;
134        if (s->version == TLS1_3_VERSION) {
135            crypto_info->iv_len = EVP_CIPHER_CTX_get_iv_length(dd);
136            if (crypto_info->iv_len < 0)
137                return 0;
138        }
139        else
140            crypto_info->iv_len = EVP_GCM_TLS_FIXED_IV_LEN;
141        break;
142# ifdef OPENSSL_KTLS_CHACHA20_POLY1305
143    case SSL_CHACHA20POLY1305:
144        crypto_info->cipher_algorithm = CRYPTO_CHACHA20_POLY1305;
145        crypto_info->iv_len = EVP_CIPHER_CTX_get_iv_length(dd);
146        break;
147# endif
148    case SSL_AES128:
149    case SSL_AES256:
150        switch (s->s3.tmp.new_cipher->algorithm_mac) {
151        case SSL_SHA1:
152            crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC;
153            break;
154        case SSL_SHA256:
155            crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC;
156            break;
157        case SSL_SHA384:
158            crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC;
159            break;
160        default:
161            return 0;
162        }
163        crypto_info->cipher_algorithm = CRYPTO_AES_CBC;
164        crypto_info->iv_len = EVP_CIPHER_get_iv_length(c);
165        crypto_info->auth_key = mac_key;
166        crypto_info->auth_key_len = mac_secret_size;
167        break;
168    default:
169        return 0;
170    }
171    crypto_info->cipher_key = key;
172    crypto_info->cipher_key_len = EVP_CIPHER_get_key_length(c);
173    crypto_info->iv = iv;
174    crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff;
175    crypto_info->tls_vminor = (s->version & 0x000000ff);
176# ifdef TCP_RXTLS_ENABLE
177    memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq));
178    if (!is_tx && !check_rx_read_ahead(s, crypto_info->rec_seq))
179        return 0;
180# else
181    if (!is_tx)
182        return 0;
183# endif
184    return 1;
185};
186
187#endif                         /* __FreeBSD__ */
188
189#if defined(OPENSSL_SYS_LINUX)
190
191/* Function to check supported ciphers in Linux */
192int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c,
193                                const EVP_CIPHER_CTX *dd)
194{
195    switch (s->version) {
196    case TLS1_2_VERSION:
197    case TLS1_3_VERSION:
198        break;
199    default:
200        return 0;
201    }
202
203    /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128
204     * or Chacha20-Poly1305
205     */
206# ifdef OPENSSL_KTLS_AES_CCM_128
207    if (EVP_CIPHER_is_a(c, "AES-128-CCM")) {
208        if (s->version == TLS_1_3_VERSION /* broken on 5.x kernels */
209            || EVP_CIPHER_CTX_get_tag_length(dd) != EVP_CCM_TLS_TAG_LEN)
210            return 0;
211        return 1;
212    } else
213# endif
214    if (0
215# ifdef OPENSSL_KTLS_AES_GCM_128
216        || EVP_CIPHER_is_a(c, "AES-128-GCM")
217# endif
218# ifdef OPENSSL_KTLS_AES_GCM_256
219        || EVP_CIPHER_is_a(c, "AES-256-GCM")
220# endif
221# ifdef OPENSSL_KTLS_CHACHA20_POLY1305
222        || EVP_CIPHER_is_a(c, "ChaCha20-Poly1305")
223# endif
224        ) {
225        return 1;
226    }
227    return 0;
228}
229
230/* Function to configure kernel TLS structure */
231int ktls_configure_crypto(SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd,
232                          void *rl_sequence, ktls_crypto_info_t *crypto_info,
233                          int is_tx, unsigned char *iv,
234                          unsigned char *key, unsigned char *mac_key,
235                          size_t mac_secret_size)
236{
237    unsigned char geniv[12];
238    unsigned char *iiv = iv;
239
240# ifdef OPENSSL_NO_KTLS_RX
241    if (!is_tx)
242        return 0;
243# endif
244
245    if (s->version == TLS1_2_VERSION &&
246        EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE) {
247        if (!EVP_CIPHER_CTX_get_updated_iv(dd, geniv,
248                                           EVP_GCM_TLS_FIXED_IV_LEN
249                                           + EVP_GCM_TLS_EXPLICIT_IV_LEN))
250            return 0;
251        iiv = geniv;
252    }
253
254    memset(crypto_info, 0, sizeof(*crypto_info));
255    switch (EVP_CIPHER_get_nid(c))
256    {
257# ifdef OPENSSL_KTLS_AES_GCM_128
258    case NID_aes_128_gcm:
259        crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128;
260        crypto_info->gcm128.info.version = s->version;
261        crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128);
262        memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN,
263               TLS_CIPHER_AES_GCM_128_IV_SIZE);
264        memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
265        memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_get_key_length(c));
266        memcpy(crypto_info->gcm128.rec_seq, rl_sequence,
267               TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
268        if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm128.rec_seq))
269            return 0;
270        return 1;
271# endif
272# ifdef OPENSSL_KTLS_AES_GCM_256
273    case NID_aes_256_gcm:
274        crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256;
275        crypto_info->gcm256.info.version = s->version;
276        crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256);
277        memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN,
278               TLS_CIPHER_AES_GCM_256_IV_SIZE);
279        memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE);
280        memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_get_key_length(c));
281        memcpy(crypto_info->gcm256.rec_seq, rl_sequence,
282               TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
283        if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm256.rec_seq))
284            return 0;
285        return 1;
286# endif
287# ifdef OPENSSL_KTLS_AES_CCM_128
288    case NID_aes_128_ccm:
289        crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128;
290        crypto_info->ccm128.info.version = s->version;
291        crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128);
292        memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN,
293               TLS_CIPHER_AES_CCM_128_IV_SIZE);
294        memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE);
295        memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_get_key_length(c));
296        memcpy(crypto_info->ccm128.rec_seq, rl_sequence,
297               TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
298        if (!is_tx && !check_rx_read_ahead(s, crypto_info->ccm128.rec_seq))
299            return 0;
300        return 1;
301# endif
302# ifdef OPENSSL_KTLS_CHACHA20_POLY1305
303    case NID_chacha20_poly1305:
304        crypto_info->chacha20poly1305.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305;
305        crypto_info->chacha20poly1305.info.version = s->version;
306        crypto_info->tls_crypto_info_len = sizeof(crypto_info->chacha20poly1305);
307        memcpy(crypto_info->chacha20poly1305.iv, iiv,
308               TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
309        memcpy(crypto_info->chacha20poly1305.key, key,
310               EVP_CIPHER_get_key_length(c));
311        memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence,
312               TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
313        if (!is_tx
314                && !check_rx_read_ahead(s,
315                                        crypto_info->chacha20poly1305.rec_seq))
316            return 0;
317        return 1;
318# endif
319    default:
320        return 0;
321    }
322
323}
324
325#endif /* OPENSSL_SYS_LINUX */
326