mirror of
https://github.com/openssl/openssl.git
synced 2025-04-06 20:20:50 +08:00
Implement KTLS in the new read record layer code
Reviewed-by: Hugo Landau <hlandau@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/18132)
This commit is contained in:
parent
50023e9b7e
commit
cc110a0aae
@ -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
|
||||
|
@ -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
|
||||
|
113
ssl/ktls.c
113
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
|
||||
|
@ -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
|
||||
|
84
ssl/record/methods/ktls_meth.c
Normal file
84
ssl/record/methods/ktls_meth.c
Normal file
@ -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
|
||||
};
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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) */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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"},
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
77
ssl/t1_enc.c
77
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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user