diff options
-rw-r--r-- | crypto/err/openssl.txt | 1 | ||||
-rw-r--r-- | include/openssl/sslerr.h | 1 | ||||
-rw-r--r-- | ssl/ktls.c | 113 | ||||
-rw-r--r-- | ssl/record/methods/build.info | 4 | ||||
-rw-r--r-- | ssl/record/methods/ktls_meth.c | 84 | ||||
-rw-r--r-- | ssl/record/methods/recmethod_local.h | 1 | ||||
-rw-r--r-- | ssl/record/methods/tls_common.c | 201 | ||||
-rw-r--r-- | ssl/record/rec_layer_s3.c | 75 | ||||
-rw-r--r-- | ssl/record/record.h | 5 | ||||
-rw-r--r-- | ssl/record/recordmethod.h | 3 | ||||
-rw-r--r-- | ssl/s3_enc.c | 4 | ||||
-rw-r--r-- | ssl/ssl_err.c | 2 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 4 | ||||
-rw-r--r-- | ssl/ssl_local.h | 9 | ||||
-rw-r--r-- | ssl/t1_enc.c | 77 | ||||
-rw-r--r-- | ssl/tls13_enc.c | 28 | ||||
-rw-r--r-- | test/tls13secretstest.c | 5 |
17 files changed, 443 insertions, 174 deletions
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index b9f0f88f4f..8c0d2f4793 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -1434,6 +1434,7 @@ SSL_R_NO_SRTP_PROFILES:359:no srtp profiles SSL_R_NO_SUITABLE_DIGEST_ALGORITHM:297:no suitable digest algorithm SSL_R_NO_SUITABLE_GROUPS:295:no suitable groups SSL_R_NO_SUITABLE_KEY_SHARE:101:no suitable key share +SSL_R_NO_SUITABLE_RECORD_LAYER:322:no suitable record layer SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM:118:no suitable signature algorithm SSL_R_NO_VALID_SCTS:216:no valid scts SSL_R_NO_VERIFY_COOKIE_CALLBACK:403:no verify cookie callback diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h index 01a79ee48b..0e46b7b026 100644 --- a/include/openssl/sslerr.h +++ b/include/openssl/sslerr.h @@ -200,6 +200,7 @@ # define SSL_R_NO_SUITABLE_DIGEST_ALGORITHM 297 # define SSL_R_NO_SUITABLE_GROUPS 295 # define SSL_R_NO_SUITABLE_KEY_SHARE 101 +# define SSL_R_NO_SUITABLE_RECORD_LAYER 322 # define SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM 118 # define SSL_R_NO_VALID_SCTS 216 # define SSL_R_NO_VERIFY_COOKIE_CALLBACK 403 diff --git a/ssl/ktls.c b/ssl/ktls.c index 78e6ecd554..602aa78e93 100644 --- a/ssl/ktls.c +++ b/ssl/ktls.c @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include <openssl/rand.h> #include "ssl_local.h" #include "internal/ktls.h" @@ -81,7 +82,7 @@ static int check_rx_read_ahead(SSL_CONNECTION *s, unsigned char *rec_seq) * supports the cipher suite used at all. */ int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c, - const EVP_CIPHER_CTX *dd) + size_t taglen) { switch (s->version) { @@ -120,11 +121,10 @@ int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c, } /* Function to configure kernel TLS structure */ -int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, - EVP_CIPHER_CTX *dd, - void *rl_sequence, ktls_crypto_info_t *crypto_info, - int is_tx, unsigned char *iv, - unsigned char *key, unsigned char *mac_key, +int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, void *rl_sequence, + ktls_crypto_info_t *crypto_info, int is_tx, + unsigned char *iv, size_t ivlen, unsigned char *key, + size_t keylen, unsigned char *mac_key, size_t mac_secret_size) { memset(crypto_info, 0, sizeof(*crypto_info)); @@ -132,20 +132,12 @@ int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, case SSL_AES128GCM: case SSL_AES256GCM: crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16; - if (s->version == TLS1_3_VERSION) { - crypto_info->iv_len = EVP_CIPHER_CTX_get_iv_length(dd); - if (crypto_info->iv_len < 0) - return 0; - } - else - crypto_info->iv_len = EVP_GCM_TLS_FIXED_IV_LEN; + crypto_info->iv_len = ivlen; break; # ifdef OPENSSL_KTLS_CHACHA20_POLY1305 case SSL_CHACHA20POLY1305: crypto_info->cipher_algorithm = CRYPTO_CHACHA20_POLY1305; - crypto_info->iv_len = EVP_CIPHER_CTX_get_iv_length(dd); - if (crypto_info->iv_len < 0) - return 0; + crypto_info->iv_len = ivlen; break; # endif case SSL_AES128: @@ -164,7 +156,7 @@ int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, return 0; } crypto_info->cipher_algorithm = CRYPTO_AES_CBC; - crypto_info->iv_len = EVP_CIPHER_get_iv_length(c); + crypto_info->iv_len = ivlen; crypto_info->auth_key = mac_key; crypto_info->auth_key_len = mac_secret_size; break; @@ -172,7 +164,7 @@ int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, return 0; } crypto_info->cipher_key = key; - crypto_info->cipher_key_len = EVP_CIPHER_get_key_length(c); + crypto_info->cipher_key_len = keylen; crypto_info->iv = iv; crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff; crypto_info->tls_vminor = (s->version & 0x000000ff); @@ -193,7 +185,7 @@ int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, /* Function to check supported ciphers in Linux */ int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c, - const EVP_CIPHER_CTX *dd) + size_t taglen) { switch (s->version) { case TLS1_2_VERSION: @@ -209,7 +201,7 @@ int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c, # ifdef OPENSSL_KTLS_AES_CCM_128 if (EVP_CIPHER_is_a(c, "AES-128-CCM")) { if (s->version == TLS_1_3_VERSION /* broken on 5.x kernels */ - || EVP_CIPHER_CTX_get_tag_length(dd) != EVP_CCM_TLS_TAG_LEN) + || taglen != EVP_CCM_TLS_TAG_LEN) return 0; return 1; } else @@ -231,28 +223,44 @@ int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c, } /* Function to configure kernel TLS structure */ -int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, - EVP_CIPHER_CTX *dd, - void *rl_sequence, ktls_crypto_info_t *crypto_info, - int is_tx, unsigned char *iv, - unsigned char *key, unsigned char *mac_key, +int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, void *rl_sequence, + ktls_crypto_info_t *crypto_info, int is_tx, + unsigned char *iv, size_t ivlen, unsigned char *key, + size_t keylen, unsigned char *mac_key, size_t mac_secret_size) { - unsigned char geniv[12]; - unsigned char *iiv = iv; + unsigned char geniv[EVP_GCM_TLS_EXPLICIT_IV_LEN]; + unsigned char *eiv; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); # ifdef OPENSSL_NO_KTLS_RX if (!is_tx) return 0; # endif - if (s->version == TLS1_2_VERSION && - EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE) { - if (!EVP_CIPHER_CTX_get_updated_iv(dd, geniv, - EVP_GCM_TLS_FIXED_IV_LEN - + EVP_GCM_TLS_EXPLICIT_IV_LEN)) + if (EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE + || EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) { + if (!ossl_assert(EVP_GCM_TLS_FIXED_IV_LEN == EVP_CCM_TLS_FIXED_IV_LEN) + || !ossl_assert(EVP_GCM_TLS_EXPLICIT_IV_LEN + == EVP_CCM_TLS_EXPLICIT_IV_LEN)) return 0; - iiv = geniv; + if (s->version == TLS1_2_VERSION) { + if (!ossl_assert(ivlen == EVP_GCM_TLS_FIXED_IV_LEN)) + return 0; + if (is_tx) { + if (RAND_bytes_ex(sctx->libctx, geniv, + EVP_GCM_TLS_EXPLICIT_IV_LEN, 0) <= 0) + return 0; + } else { + memset(geniv, 0, EVP_GCM_TLS_EXPLICIT_IV_LEN); + } + eiv = geniv; + } else { + if (!ossl_assert(ivlen == EVP_GCM_TLS_FIXED_IV_LEN + + EVP_GCM_TLS_EXPLICIT_IV_LEN)) + return 0; + eiv = iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE; + } } memset(crypto_info, 0, sizeof(*crypto_info)); @@ -260,13 +268,15 @@ int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, { # ifdef OPENSSL_KTLS_AES_GCM_128 case NID_aes_128_gcm: + if (!ossl_assert(TLS_CIPHER_AES_GCM_128_SALT_SIZE == EVP_GCM_TLS_FIXED_IV_LEN) + || !ossl_assert(TLS_CIPHER_AES_GCM_128_IV_SIZE == EVP_GCM_TLS_EXPLICIT_IV_LEN)) + return 0; crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128; crypto_info->gcm128.info.version = s->version; crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128); - memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, - TLS_CIPHER_AES_GCM_128_IV_SIZE); - memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); - memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_get_key_length(c)); + memcpy(crypto_info->gcm128.iv, eiv, TLS_CIPHER_AES_GCM_128_IV_SIZE); + memcpy(crypto_info->gcm128.salt, iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); + memcpy(crypto_info->gcm128.key, key, keylen); memcpy(crypto_info->gcm128.rec_seq, rl_sequence, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm128.rec_seq)) @@ -275,28 +285,33 @@ int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, # endif # ifdef OPENSSL_KTLS_AES_GCM_256 case NID_aes_256_gcm: + if (!ossl_assert(TLS_CIPHER_AES_GCM_256_SALT_SIZE == EVP_GCM_TLS_FIXED_IV_LEN) + || !ossl_assert(TLS_CIPHER_AES_GCM_256_IV_SIZE == EVP_GCM_TLS_EXPLICIT_IV_LEN)) + return 0; crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256; crypto_info->gcm256.info.version = s->version; crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256); - memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, - TLS_CIPHER_AES_GCM_256_IV_SIZE); - memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE); - memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_get_key_length(c)); + memcpy(crypto_info->gcm256.iv, eiv, TLS_CIPHER_AES_GCM_256_IV_SIZE); + memcpy(crypto_info->gcm256.salt, iv, TLS_CIPHER_AES_GCM_256_SALT_SIZE); + memcpy(crypto_info->gcm256.key, key, keylen); memcpy(crypto_info->gcm256.rec_seq, rl_sequence, TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm256.rec_seq)) return 0; + return 1; # endif # ifdef OPENSSL_KTLS_AES_CCM_128 case NID_aes_128_ccm: + if (!ossl_assert(TLS_CIPHER_AES_CCM_128_SALT_SIZE == EVP_CCM_TLS_FIXED_IV_LEN) + || !ossl_assert(TLS_CIPHER_AES_CCM_128_IV_SIZE == EVP_CCM_TLS_EXPLICIT_IV_LEN)) + return 0; crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128; crypto_info->ccm128.info.version = s->version; crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128); - memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN, - TLS_CIPHER_AES_CCM_128_IV_SIZE); - memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE); - memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_get_key_length(c)); + memcpy(crypto_info->ccm128.iv, eiv, TLS_CIPHER_AES_CCM_128_IV_SIZE); + memcpy(crypto_info->ccm128.salt, iv, TLS_CIPHER_AES_CCM_128_SALT_SIZE); + memcpy(crypto_info->ccm128.key, key, keylen); memcpy(crypto_info->ccm128.rec_seq, rl_sequence, TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); if (!is_tx && !check_rx_read_ahead(s, crypto_info->ccm128.rec_seq)) @@ -305,13 +320,13 @@ int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, # endif # ifdef OPENSSL_KTLS_CHACHA20_POLY1305 case NID_chacha20_poly1305: + if (!ossl_assert(ivlen == TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE)) + return 0; crypto_info->chacha20poly1305.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305; crypto_info->chacha20poly1305.info.version = s->version; crypto_info->tls_crypto_info_len = sizeof(crypto_info->chacha20poly1305); - memcpy(crypto_info->chacha20poly1305.iv, iiv, - TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE); - memcpy(crypto_info->chacha20poly1305.key, key, - EVP_CIPHER_get_key_length(c)); + memcpy(crypto_info->chacha20poly1305.iv, iv, ivlen); + memcpy(crypto_info->chacha20poly1305.key, key, keylen); memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence, TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE); if (!is_tx diff --git a/ssl/record/methods/build.info b/ssl/record/methods/build.info index dfe7d9c808..162739259c 100644 --- a/ssl/record/methods/build.info +++ b/ssl/record/methods/build.info @@ -7,4 +7,8 @@ IF[{- !$disabled{'deprecated-3.0'} -}] SHARED_SOURCE[../../../libssl]=ssl3_cbc.c ENDIF +IF[{- !$disabled{'ktls'} -}] + SOURCE[../../../libssl]=ktls_meth.c +ENDIF + SOURCE[../../../providers/libdefault.a ../../../providers/libfips.a]=ssl3_cbc.c diff --git a/ssl/record/methods/ktls_meth.c b/ssl/record/methods/ktls_meth.c new file mode 100644 index 0000000000..18576cee26 --- /dev/null +++ b/ssl/record/methods/ktls_meth.c @@ -0,0 +1,84 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/evp.h> +#include <openssl/core_names.h> +#include "../../ssl_local.h" +#include "../record_local.h" +#include "recmethod_local.h" + +/* TODO(RECLAYER): Handle OPENSSL_NO_COMP */ +static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, + size_t taglen, + /* TODO(RECLAYER): This probably should not be an int */ + int mactype, + const EVP_MD *md, + const SSL_COMP *comp, + /* TODO(RECLAYER): Remove me */ + SSL_CONNECTION *s) +{ + void *rl_sequence; + ktls_crypto_info_t crypto_info; + + /* Check if we are suitable for KTLS */ + + if (comp != NULL) + return 0; + + /* ktls supports only the maximum fragment size */ + if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) + return 0; + + /* check that cipher is supported */ + if (!ktls_check_supported_cipher(s, ciph, taglen)) + return 0; + + /* + * TODO(RECLAYER): For the write side we need to add a check for + * use of s->record_padding_cb + */ + + /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */ + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) { + if (BIO_flush(rl->bio) <= 0) + return 0; + } + + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) + rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); + else + rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); + + if (!ktls_configure_crypto(s, ciph, rl_sequence, &crypto_info, + rl->direction == OSSL_RECORD_DIRECTION_WRITE, + iv, ivlen, key, keylen, mackey, mackeylen)) + return 0; + + if (!BIO_set_ktls(rl->bio, &crypto_info, rl->direction)) + return 0; + + return 1; +} + +static int ktls_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *inrecs, size_t n_recs, + int sending, SSL_MAC_BUF *mac, size_t macsize, + /* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s) +{ + return 1; +} + +struct record_functions_st ossl_ktls_funcs = { + ktls_set_crypto_state, + ktls_cipher, + NULL +}; diff --git a/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h index ec4001587d..b5d1bc2305 100644 --- a/ssl/record/methods/recmethod_local.h +++ b/ssl/record/methods/recmethod_local.h @@ -113,6 +113,7 @@ struct ossl_record_layer_st extern struct record_functions_st ssl_3_0_funcs; extern struct record_functions_st tls_1_funcs; extern struct record_functions_st tls_1_3_funcs; +extern struct record_functions_st ossl_ktls_funcs; extern struct record_functions_st tls_any_funcs; void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason, diff --git a/ssl/record/methods/tls_common.c b/ssl/record/methods/tls_common.c index b693fcf5db..5106224c6c 100644 --- a/ssl/record/methods/tls_common.c +++ b/ssl/record/methods/tls_common.c @@ -185,6 +185,11 @@ static int tls_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend, return OSSL_RECORD_RETURN_NON_FATAL_ERR; rb = &rl->rbuf; + /* + * TODO(RECLAYER): Once this function is only called from inside the rlayer + * directly, we can probably remove this since it is initialised in + * tls_get_more_records + */ if (rb->buf == NULL) { if (!rlayer_setup_read_buffer(rl)) { /* RLAYERfatal() already called */ @@ -421,6 +426,12 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl, rr = rl->rrec; rbuf = &rl->rbuf; + if (rbuf->buf == NULL) { + if (!rlayer_setup_read_buffer(rl)) { + /* RLAYERfatal() already called */ + return OSSL_RECORD_RETURN_FATAL; + } + } max_recs = s->max_pipelines; if (max_recs == 0) @@ -1091,27 +1102,19 @@ static int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle) return OSSL_RECORD_RETURN_SUCCESS; } -static OSSL_RECORD_LAYER *tls_new_record_layer(OSSL_LIB_CTX *libctx, - const char *propq, int vers, - int role, int direction, - int level, unsigned char *key, - size_t keylen, - unsigned char *iv, - size_t ivlen, - unsigned char *mackey, - size_t mackeylen, - const EVP_CIPHER *ciph, - size_t taglen, - /* TODO(RECLAYER): This probably should not be an int */ - int mactype, - const EVP_MD *md, - const SSL_COMP *comp, - BIO *transport, BIO_ADDR *local, - BIO_ADDR *peer, - const OSSL_PARAM *settings, - const OSSL_PARAM *options, - /* TODO(RECLAYER): Remove me */ - SSL_CONNECTION *s) +static OSSL_RECORD_LAYER * +tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, + int role, int direction, int level, unsigned char *key, + size_t keylen, unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + /* TODO(RECLAYER): This probably should not be an int */ + int mactype, + const EVP_MD *md, const SSL_COMP *comp, BIO *transport, + BIO_ADDR *local, BIO_ADDR *peer, + const OSSL_PARAM *settings, const OSSL_PARAM *options, + /* TODO(RECLAYER): Remove me */ + SSL_CONNECTION *s) { OSSL_RECORD_LAYER *rl = OPENSSL_zalloc(sizeof(*rl)); const OSSL_PARAM *p; @@ -1173,6 +1176,37 @@ static OSSL_RECORD_LAYER *tls_new_record_layer(OSSL_LIB_CTX *libctx, if (!tls_set1_bio(rl, transport)) goto err; + return rl; + err: + OPENSSL_free(rl); + return NULL; +} + +static OSSL_RECORD_LAYER * +tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, + int role, int direction, int level, unsigned char *key, + size_t keylen, unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + /* TODO(RECLAYER): This probably should not be an int */ + int mactype, + const EVP_MD *md, const SSL_COMP *comp, BIO *transport, + BIO_ADDR *local, BIO_ADDR *peer, + const OSSL_PARAM *settings, const OSSL_PARAM *options, + /* TODO(RECLAYER): Remove me */ + SSL_CONNECTION *s) +{ + OSSL_RECORD_LAYER *rl = tls_int_new_record_layer(libctx, propq, vers, role, + direction, level, key, + keylen, iv, ivlen, mackey, + mackeylen, ciph, taglen, + mactype, md, comp, + transport, local, peer, + settings, options, s); + + if (rl == NULL) + return NULL; + switch (vers) { case TLS_ANY_VERSION: rl->funcs = &tls_any_funcs; @@ -1196,45 +1230,37 @@ static OSSL_RECORD_LAYER *tls_new_record_layer(OSSL_LIB_CTX *libctx, if (!rl->funcs->set_crypto_state(rl, level, key, keylen, iv, ivlen, mackey, mackeylen, ciph, taglen, - mactype, md, comp, s)) { - /* RLAYERfatal already called */ + mactype, md, comp, s)) goto err; - } return rl; err: + /* TODO(RECLAYER): How do we distinguish between fatal and non-fatal errors? */ OPENSSL_free(rl); return NULL; } -static OSSL_RECORD_LAYER *dtls_new_record_layer(OSSL_LIB_CTX *libctx, - const char *propq, int vers, - int role, int direction, - int level, unsigned char *key, - size_t keylen, - unsigned char *iv, - size_t ivlen, - unsigned char *mackey, - size_t mackeylen, - const EVP_CIPHER *ciph, - size_t taglen, - /* TODO(RECLAYER): This probably should not be an int */ - int mactype, - const EVP_MD *md, - const SSL_COMP *comp, - BIO *transport, BIO_ADDR *local, - BIO_ADDR *peer, - const OSSL_PARAM *settings, - const OSSL_PARAM *options, - /* TODO(RECLAYER): Remove me */ - SSL_CONNECTION *s) +static OSSL_RECORD_LAYER * +dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, + int role, int direction, int level, unsigned char *key, + size_t keylen, unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + /* TODO(RECLAYER): This probably should not be an int */ + int mactype, + const EVP_MD *md, const SSL_COMP *comp, BIO *transport, + BIO_ADDR *local, BIO_ADDR *peer, + const OSSL_PARAM *settings, const OSSL_PARAM *options, + /* TODO(RECLAYER): Remove me */ + SSL_CONNECTION *s) { - OSSL_RECORD_LAYER *rl = tls_new_record_layer(libctx, propq, vers, role, - direction, level, key, keylen, - iv, ivlen, mackey, mackeylen, - ciph, taglen, mactype, md, - comp, transport, local, peer, - settings, options, s); + OSSL_RECORD_LAYER *rl = tls_int_new_record_layer(libctx, propq, vers, role, + direction, level, key, + keylen, iv, ivlen, mackey, + mackeylen, ciph, taglen, + mactype, md, comp, + transport, local, peer, + settings, options, s); if (rl == NULL) return NULL; @@ -1244,6 +1270,47 @@ static OSSL_RECORD_LAYER *dtls_new_record_layer(OSSL_LIB_CTX *libctx, return rl; } +#ifndef OPENSSL_NO_KTLS +static OSSL_RECORD_LAYER * +ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, + int role, int direction, int level, unsigned char *key, + size_t keylen, unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + /* TODO(RECLAYER): This probably should not be an int */ + int mactype, + const EVP_MD *md, const SSL_COMP *comp, BIO *transport, + BIO_ADDR *local, BIO_ADDR *peer, + const OSSL_PARAM *settings, const OSSL_PARAM *options, + /* TODO(RECLAYER): Remove me */ + SSL_CONNECTION *s) +{ + OSSL_RECORD_LAYER *rl = tls_int_new_record_layer(libctx, propq, vers, role, + direction, level, key, + keylen, iv, ivlen, mackey, + mackeylen, ciph, taglen, + mactype, md, comp, + transport, local, peer, + settings, options, s); + + if (rl == NULL) + return NULL; + + rl->funcs = &ossl_ktls_funcs; + + if (!rl->funcs->set_crypto_state(rl, level, key, keylen, iv, ivlen, + mackey, mackeylen, ciph, taglen, + mactype, md, comp, s)) + goto err; + + return rl; + err: + /* TODO(RECLAYER): How do we distinguish between fatal and non-fatal errors? */ + OPENSSL_free(rl); + return NULL; +} +#endif + static void tls_free(OSSL_RECORD_LAYER *rl) { /* TODO(RECLAYER): Cleanse sensitive fields */ @@ -1368,6 +1435,38 @@ const OSSL_RECORD_METHOD ossl_tls_record_method = { tls_reset_packet_length }; +#ifndef OPENSSL_NO_KTLS +const OSSL_RECORD_METHOD ossl_ktls_record_method = { + ktls_new_record_layer, + tls_free, + tls_reset, + tls_unprocessed_read_pending, + tls_processed_read_pending, + tls_app_data_pending, + tls_write_pending, + tls_get_max_record_len, + tls_get_max_records, + tls_write_records, + tls_retry_write_records, + tls_read_record, + tls_release_record, + tls_get_alert_code, + tls_set1_bio, + + /* + * TODO(RECLAYER): Remove these. These function pointers are temporary hacks + * during the record layer refactoring. They need to be removed before the + * refactor is complete. + */ + tls_read_n, + tls_get0_rbuf, + tls_get0_packet, + tls_set0_packet, + tls_get_packet_length, + tls_reset_packet_length +}; +#endif + const OSSL_RECORD_METHOD ossl_dtls_record_method = { dtls_new_record_layer, tls_free, diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 61a4316704..a9e0baa687 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -1750,8 +1750,44 @@ size_t RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl) return SSL3_RECORD_get_length(&rl->rrec[0]); } -int ssl_set_new_record_layer(SSL_CONNECTION *s, const OSSL_RECORD_METHOD *meth, - int version, int direction, int level, +static const OSSL_RECORD_METHOD *ssl_select_next_record_layer(SSL_CONNECTION *s, + int level) +{ + + if (level == OSSL_RECORD_PROTECTION_LEVEL_NONE) { + if (SSL_CONNECTION_IS_DTLS(s)) + return &ossl_dtls_record_method; + + return &ossl_tls_record_method; + } + +#ifndef OPENSSL_NO_KTLS + /* KTLS does not support renegotiation */ + if (level == OSSL_RECORD_PROTECTION_LEVEL_APPLICATION + && (s->options & SSL_OP_ENABLE_KTLS) != 0 + && (SSL_CONNECTION_IS_TLS13(s) || SSL_IS_FIRST_HANDSHAKE(s))) + return &ossl_ktls_record_method; +#endif + + /* Default to the current OSSL_RECORD_METHOD */ + return s->rrlmethod; +} + +static int ssl_post_record_layer_select(SSL_CONNECTION *s) +{ +#ifndef OPENSSL_NO_KTLS + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + + if (s->rrlmethod == &ossl_ktls_record_method) { + /* KTLS does not support renegotiation so disallow it */ + SSL_set_options(ssl, SSL_OP_NO_RENEGOTIATION); + } +#endif + return 1; +} + +int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, + int direction, int level, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, @@ -1761,8 +1797,12 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, const OSSL_RECORD_METHOD *meth, { OSSL_PARAM_BLD *tmpl = NULL; OSSL_PARAM *options = NULL; + const OSSL_RECORD_METHOD *origmeth = s->rrlmethod; int ret = 0; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + const OSSL_RECORD_METHOD *meth; + + meth = ssl_select_next_record_layer(s, level); if (s->rrlmethod != NULL) s->rrlmethod->free(s->rrl); @@ -1790,18 +1830,29 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, const OSSL_RECORD_METHOD *meth, goto err; } - s->rrl = s->rrlmethod->new_record_layer(sctx->libctx, sctx->propq, - version, s->server, direction, - level, key, keylen, iv, ivlen, - mackey, mackeylen, ciph, taglen, - mactype, md, comp, s->rbio, - NULL, NULL, NULL, options, s); - if (s->rrl == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); - goto err; + for (;;) { + s->rrl = s->rrlmethod->new_record_layer(sctx->libctx, sctx->propq, + version, s->server, direction, + level, key, keylen, iv, ivlen, + mackey, mackeylen, ciph, taglen, + mactype, md, comp, s->rbio, + NULL, NULL, NULL, options, s); + if (s->rrl == NULL) { + if (s->rrlmethod != origmeth && origmeth != NULL) { + /* + * We tried a new record layer method, but it didn't work out, + * so we fallback to the original method and try again + */ + s->rrlmethod = origmeth; + continue; + } + ERR_raise(ERR_LIB_SSL, SSL_R_NO_SUITABLE_RECORD_LAYER); + goto err; + } + break; } - ret = 1; + ret = ssl_post_record_layer_select(s); err: OSSL_PARAM_free(options); OSSL_PARAM_BLD_free(tmpl); diff --git a/ssl/record/record.h b/ssl/record/record.h index fb836716fa..39b44e1682 100644 --- a/ssl/record/record.h +++ b/ssl/record/record.h @@ -283,9 +283,8 @@ int dtls_buffer_listen_record(SSL_CONNECTION *s, size_t len, unsigned char *seq, int ossl_tls_handle_rlayer_return(SSL_CONNECTION *s, int ret, char *file, int line); -int ssl_set_new_record_layer(SSL_CONNECTION *s, const OSSL_RECORD_METHOD *meth, - int version, int direction, int level, - unsigned char *key, size_t keylen, +int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int direction, + int level, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, const EVP_CIPHER *ciph, size_t taglen, diff --git a/ssl/record/recordmethod.h b/ssl/record/recordmethod.h index a14737836d..157b154805 100644 --- a/ssl/record/recordmethod.h +++ b/ssl/record/recordmethod.h @@ -294,6 +294,9 @@ struct ossl_record_method_st { /* Standard built-in record methods */ extern const OSSL_RECORD_METHOD ossl_tls_record_method; +# ifndef OPENSSL_NO_KTLS +extern const OSSL_RECORD_METHOD ossl_ktls_record_method; +# endif extern const OSSL_RECORD_METHOD ossl_dtls_record_method; #endif /* !defined(OSSL_INTERNAL_RECORDMETHOD_H) */ diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index bd66f300ef..fc9002b8e5 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -146,12 +146,12 @@ int ssl3_change_cipher_state(SSL_CONNECTION *s, int which) } if (which & SSL3_CC_READ) { - if (!ssl_set_new_record_layer(s, NULL, SSL3_VERSION, + if (!ssl_set_new_record_layer(s, SSL3_VERSION, OSSL_RECORD_DIRECTION_READ, OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, key, key_len, iv, iv_len, mac_secret, md_len, ciph, 0, NID_undef, md, comp)) { - /* SSLfatal already called */ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER); goto err; } diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 8910b81952..7abd6de4a2 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -307,6 +307,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_GROUPS), "no suitable groups"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_KEY_SHARE), "no suitable key share"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_RECORD_LAYER), + "no suitable record layer"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM), "no suitable signature algorithm"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_VALID_SCTS), "no valid scts"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index e076a27560..4688aaa327 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -663,14 +663,12 @@ int ossl_ssl_connection_reset(SSL *s) * assign it. */ if (!ssl_set_new_record_layer(sc, - SSL_CONNECTION_IS_DTLS(sc) ? &ossl_dtls_record_method - : &ossl_tls_record_method, TLS_ANY_VERSION, OSSL_RECORD_DIRECTION_READ, OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NID_undef, NULL, NULL)) { - /* SSLfatal already called */ + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER); return 0; } diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 5648014f18..90fb9516ab 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -2860,13 +2860,12 @@ __owur int ssl_log_secret(SSL_CONNECTION *s, const char *label, # ifndef OPENSSL_NO_KTLS /* ktls.c */ int ktls_check_supported_cipher(const SSL_CONNECTION *s, const EVP_CIPHER *c, - const EVP_CIPHER_CTX *dd); + size_t taglen); int ktls_configure_crypto(SSL_CONNECTION *s, const EVP_CIPHER *c, - EVP_CIPHER_CTX *dd, void *rl_sequence, ktls_crypto_info_t *crypto_info, - int is_tx, unsigned char *iv, - unsigned char *key, unsigned char *mac_key, - size_t mac_secret_size); + int is_tx, unsigned char *iv, size_t ivlen, + unsigned char *key, size_t keylen, + unsigned char *mac_key, size_t mac_secret_size); # endif __owur int srp_generate_server_master_secret(SSL_CONNECTION *s); diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 6fee020f32..20964dfd61 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -165,6 +165,7 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) EVP_MD_CTX *mac_ctx; EVP_PKEY *mac_key; size_t n, i, j, k, cl; + int iivlen; int reuse_dd = 0; #ifndef OPENSSL_NO_KTLS ktls_crypto_info_t crypto_info; @@ -172,6 +173,11 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) BIO *bio; #endif SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + /* + * Taglen is only relevant for CCM ciphersuites. Other ciphersuites + * ignore this value so we can default it to 0. + */ + size_t taglen = 0; c = s->s3.tmp.new_sym_enc; m = s->s3.tmp.new_hash; @@ -185,7 +191,12 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) cl = EVP_CIPHER_get_key_length(c); j = cl; - k = tls_iv_length_within_key_block(c); + iivlen = tls_iv_length_within_key_block(c); + if (iivlen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + k = iivlen; if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { mac_secret = &(p[0]); @@ -209,6 +220,14 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) goto err; } + if (EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) { + if ((s->s3.tmp.new_cipher->algorithm_enc + & (SSL_AES128CCM8 | SSL_AES256CCM8)) != 0) + taglen = EVP_CCM8_TLS_TAG_LEN; + else + taglen = EVP_CCM_TLS_TAG_LEN; + } + if (which & SSL3_CC_READ) { if (SSL_CONNECTION_IS_DTLS(s)) { if (s->ext.use_etm) @@ -261,32 +280,18 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) if (!SSL_CONNECTION_IS_DTLS(s)) RECORD_LAYER_reset_read_sequence(&s->rlayer); } else { - /* - * Taglen is only relevant for CCM ciphersuites. Other ciphersuites - * ignore this value so we can default it to 0. - */ - size_t taglen = 0; - - if (EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) { - if ((s->s3.tmp. new_cipher->algorithm_enc - & (SSL_AES128CCM8 | SSL_AES256CCM8)) != 0) - taglen = EVP_CCM8_TLS_TAG_LEN; - else - taglen = EVP_CCM_TLS_TAG_LEN; - } - - if (!ssl_set_new_record_layer(s, NULL, s->version, - OSSL_RECORD_DIRECTION_READ, - OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, - key, cl, iv, (size_t)k, mac_secret, - mac_secret_size, c, taglen, mac_type, m, - comp)) { - /* SSLfatal already called */ + if (!ssl_set_new_record_layer(s, s->version, + OSSL_RECORD_DIRECTION_READ, + OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, + key, cl, iv, (size_t)k, mac_secret, + mac_secret_size, c, taglen, mac_type, + m, comp)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER); goto err; } /* TODO(RECLAYER): Temporary - remove me */ - goto check_ktls; + goto skip_ktls; } } else { s->statem.enc_write_state = ENC_WRITE_STATE_INVALID; @@ -385,12 +390,6 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) goto err; } } else if (EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) { - int taglen; - if (s->s3.tmp. - new_cipher->algorithm_enc & (SSL_AES128CCM8 | SSL_AES256CCM8)) - taglen = EVP_CCM8_TLS_TAG_LEN; - else - taglen = EVP_CCM_TLS_TAG_LEN; if (!EVP_CipherInit_ex(dd, c, NULL, NULL, NULL, (which & SSL3_CC_WRITE)) || (EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL) <= 0) || (EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_TAG, taglen, NULL) <= 0) @@ -419,7 +418,6 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) goto err; } - check_ktls: #ifndef OPENSSL_NO_KTLS if (s->compress || (s->options & SSL_OP_ENABLE_KTLS) == 0) goto skip_ktls; @@ -429,7 +427,7 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) goto skip_ktls; /* check that cipher is supported */ - if (!ktls_check_supported_cipher(s, c, dd)) + if (!ktls_check_supported_cipher(s, c, taglen)) goto skip_ktls; if (which & SSL3_CC_WRITE) @@ -460,9 +458,9 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) else rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); - if (!ktls_configure_crypto(s, c, dd, rl_sequence, &crypto_info, - which & SSL3_CC_WRITE, iv, key, mac_secret, - mac_secret_size)) + if (!ktls_configure_crypto(s, c, rl_sequence, &crypto_info, + which & SSL3_CC_WRITE, iv, (size_t)k, key, cl, + mac_secret, mac_secret_size)) goto skip_ktls; /* ktls works with user provided buffers directly */ @@ -472,8 +470,8 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) SSL_set_options(SSL_CONNECTION_GET_SSL(s), SSL_OP_NO_RENEGOTIATION); } - skip_ktls: #endif /* OPENSSL_NO_KTLS */ + skip_ktls: s->statem.enc_write_state = ENC_WRITE_STATE_VALID; OSSL_TRACE_BEGIN(TLS) { @@ -497,6 +495,7 @@ int tls1_setup_key_block(SSL_CONNECTION *s) int mac_type = NID_undef; size_t num, mac_secret_size = 0; int ret = 0; + int ivlen; if (s->s3.tmp.key_block_length != 0) return 1; @@ -515,8 +514,12 @@ int tls1_setup_key_block(SSL_CONNECTION *s) s->s3.tmp.new_hash = hash; s->s3.tmp.new_mac_pkey_type = mac_type; s->s3.tmp.new_mac_secret_size = mac_secret_size; - num = mac_secret_size + EVP_CIPHER_get_key_length(c) - + tls_iv_length_within_key_block(c); + ivlen = tls_iv_length_within_key_block(c); + if (ivlen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + num = mac_secret_size + EVP_CIPHER_get_key_length(c) + ivlen; num *= 2; ssl3_cleanup_key_block(s); diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index 8ef0ca6981..d6069c492a 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -390,13 +390,20 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, int sending, else *taglen = EVP_CCM_TLS_TAG_LEN; } else { + int iivlen; + if (mode == EVP_CIPH_GCM_MODE) { *taglen = EVP_GCM_TLS_TAG_LEN; } else { /* CHACHA20P-POLY1305 */ *taglen = EVP_CHACHAPOLY_TLS_TAG_LEN; } - *ivlen = EVP_CIPHER_get_iv_length(ciph); + iivlen = EVP_CIPHER_get_iv_length(ciph); + if (iivlen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return 0; + } + *ivlen = iivlen; } if (!tls13_derive_key(s, md, secret, key, *keylen) @@ -710,13 +717,15 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) ? OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE : OSSL_RECORD_PROTECTION_LEVEL_APPLICATION); - if (!ssl_set_new_record_layer(s, NULL, s->version, + if (!ssl_set_new_record_layer(s, s->version, OSSL_RECORD_DIRECTION_READ, level, key, keylen, iv, ivlen, NULL, 0, cipher, taglen, NID_undef, NULL, NULL)) { - /* SSLfatal already called */ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER); goto err; } + /* TODO(RECLAYER): Remove me */ + goto skip_ktls; } #ifndef OPENSSL_NO_KTLS @@ -734,7 +743,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) goto skip_ktls; /* check that cipher is supported */ - if (!ktls_check_supported_cipher(s, cipher, ciph_ctx)) + if (!ktls_check_supported_cipher(s, cipher, taglen)) goto skip_ktls; if (which & SSL3_CC_WRITE) @@ -759,8 +768,9 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) else rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); - if (!ktls_configure_crypto(s, cipher, ciph_ctx, rl_sequence, &crypto_info, - which & SSL3_CC_WRITE, iv, key, NULL, 0)) + if (!ktls_configure_crypto(s, cipher, rl_sequence, &crypto_info, + which & SSL3_CC_WRITE, iv, ivlen, key, keylen, + NULL, 0)) goto skip_ktls; /* ktls works with user provided buffers directly */ @@ -768,9 +778,9 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) if (which & SSL3_CC_WRITE) ssl3_release_write_buffer(s); } -skip_ktls: # endif #endif +skip_ktls: ret = 1; err: if ((which & SSL3_CC_EARLY) != 0) { @@ -826,13 +836,13 @@ int tls13_update_key(SSL_CONNECTION *s, int sending) memcpy(insecret, secret, hashlen); if (!sending) { - if (!ssl_set_new_record_layer(s, NULL, s->version, + if (!ssl_set_new_record_layer(s, s->version, OSSL_RECORD_DIRECTION_READ, OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, key, keylen, iv, ivlen, NULL, 0, s->s3.tmp.new_sym_enc, taglen, NID_undef, NULL, NULL)) { - /* SSLfatal already called */ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER); goto err; } } diff --git a/test/tls13secretstest.c b/test/tls13secretstest.c index f8d14777b3..ae5702d3a6 100644 --- a/test/tls13secretstest.c +++ b/test/tls13secretstest.c @@ -225,9 +225,8 @@ void ssl_evp_md_free(const EVP_MD *md) { } -int ssl_set_new_record_layer(SSL_CONNECTION *s, const OSSL_RECORD_METHOD *meth, - int version, int direction, int level, - unsigned char *key, size_t keylen, +int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int direction, + int level, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, const EVP_CIPHER *ciph, size_t taglen, |