mirror of
https://github.com/openssl/openssl.git
synced 2025-02-05 14:10:53 +08:00
Convert TLSv1.3 code to use the new read side record layer
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
10560aed15
commit
2b891e30ce
@ -104,6 +104,11 @@ struct ossl_record_layer_st
|
|||||||
/* Only used by SSLv3 */
|
/* Only used by SSLv3 */
|
||||||
unsigned char mac_secret[EVP_MAX_MD_SIZE];
|
unsigned char mac_secret[EVP_MAX_MD_SIZE];
|
||||||
|
|
||||||
|
/* TLSv1.3 static IV */
|
||||||
|
unsigned char iv[EVP_MAX_IV_LENGTH];
|
||||||
|
|
||||||
|
size_t taglen;
|
||||||
|
|
||||||
/* Function pointers for version specific functions */
|
/* Function pointers for version specific functions */
|
||||||
/* Function pointers for version specific functions */
|
/* Function pointers for version specific functions */
|
||||||
struct record_functions_st *funcs;
|
struct record_functions_st *funcs;
|
||||||
@ -169,23 +174,6 @@ static int tls_provider_set_tls_parameters(OSSL_RECORD_LAYER *rl,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tls_fail_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)
|
|
||||||
{
|
|
||||||
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tls_any_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
static int tls_any_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
||||||
unsigned char *key, size_t keylen,
|
unsigned char *key, size_t keylen,
|
||||||
unsigned char *iv, size_t ivlen,
|
unsigned char *iv, size_t ivlen,
|
||||||
@ -410,6 +398,51 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tls13_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)
|
||||||
|
{
|
||||||
|
EVP_CIPHER_CTX *ciph_ctx;
|
||||||
|
int mode;
|
||||||
|
|
||||||
|
if (ivlen > sizeof(rl->iv)) {
|
||||||
|
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(rl->iv, iv, ivlen);
|
||||||
|
|
||||||
|
ciph_ctx = rl->enc_read_ctx = EVP_CIPHER_CTX_new();
|
||||||
|
if (ciph_ctx == NULL) {
|
||||||
|
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECORD_LAYER_reset_read_sequence(&s->rlayer);
|
||||||
|
rl->taglen = taglen;
|
||||||
|
|
||||||
|
mode = EVP_CIPHER_get_mode(ciph);
|
||||||
|
|
||||||
|
if (EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, NULL, NULL) <= 0
|
||||||
|
|| !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL)
|
||||||
|
|| (mode == EVP_CIPH_CCM_MODE
|
||||||
|
&& !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, taglen, NULL))
|
||||||
|
|| EVP_DecryptInit_ex(ciph_ctx, NULL, NULL, key, NULL) <= 0) {
|
||||||
|
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int tls_any_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
|
static int tls_any_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
|
||||||
int sending, SSL_MAC_BUF *macs, size_t macsize,
|
int sending, SSL_MAC_BUF *macs, size_t macsize,
|
||||||
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
|
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
|
||||||
@ -875,6 +908,139 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tls13_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
|
||||||
|
int sending, SSL_MAC_BUF *mac, size_t macsize,
|
||||||
|
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
|
||||||
|
{
|
||||||
|
EVP_CIPHER_CTX *ctx;
|
||||||
|
unsigned char iv[EVP_MAX_IV_LENGTH], recheader[SSL3_RT_HEADER_LENGTH];
|
||||||
|
size_t ivlen, offset, loop, hdrlen;
|
||||||
|
unsigned char *staticiv;
|
||||||
|
unsigned char *seq;
|
||||||
|
int lenu, lenf;
|
||||||
|
SSL3_RECORD *rec = &recs[0];
|
||||||
|
WPACKET wpkt;
|
||||||
|
const EVP_CIPHER *cipher;
|
||||||
|
int mode;
|
||||||
|
|
||||||
|
if (n_recs != 1) {
|
||||||
|
/* Should not happen */
|
||||||
|
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sending) {
|
||||||
|
ctx = s->enc_write_ctx;
|
||||||
|
staticiv = s->write_iv;
|
||||||
|
seq = RECORD_LAYER_get_write_sequence(&s->rlayer);
|
||||||
|
} else {
|
||||||
|
ctx = rl->enc_read_ctx;
|
||||||
|
staticiv = rl->iv;
|
||||||
|
seq = RECORD_LAYER_get_read_sequence(&s->rlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
cipher = EVP_CIPHER_CTX_get0_cipher(ctx);
|
||||||
|
if (cipher == NULL) {
|
||||||
|
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
mode = EVP_CIPHER_get_mode(cipher);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're sending an alert and ctx != NULL then we must be forcing
|
||||||
|
* plaintext alerts. If we're reading and ctx != NULL then we allow
|
||||||
|
* plaintext alerts at certain points in the handshake. If we've got this
|
||||||
|
* far then we have already validated that a plaintext alert is ok here.
|
||||||
|
*/
|
||||||
|
if (ctx == NULL || rec->type == SSL3_RT_ALERT) {
|
||||||
|
memmove(rec->data, rec->input, rec->length);
|
||||||
|
rec->input = rec->data;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
|
||||||
|
|
||||||
|
if (!sending) {
|
||||||
|
/*
|
||||||
|
* Take off tag. There must be at least one byte of content type as
|
||||||
|
* well as the tag
|
||||||
|
*/
|
||||||
|
if (rec->length < rl->taglen + 1)
|
||||||
|
return 0;
|
||||||
|
rec->length -= rl->taglen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up IV */
|
||||||
|
if (ivlen < SEQ_NUM_SIZE) {
|
||||||
|
/* Should not happen */
|
||||||
|
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
offset = ivlen - SEQ_NUM_SIZE;
|
||||||
|
memcpy(iv, staticiv, offset);
|
||||||
|
for (loop = 0; loop < SEQ_NUM_SIZE; loop++)
|
||||||
|
iv[offset + loop] = staticiv[offset + loop] ^ seq[loop];
|
||||||
|
|
||||||
|
/* Increment the sequence counter */
|
||||||
|
for (loop = SEQ_NUM_SIZE; loop > 0; loop--) {
|
||||||
|
++seq[loop - 1];
|
||||||
|
if (seq[loop - 1] != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (loop == 0) {
|
||||||
|
/* Sequence has wrapped */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, sending) <= 0
|
||||||
|
|| (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
|
||||||
|
rl->taglen,
|
||||||
|
rec->data + rec->length) <= 0)) {
|
||||||
|
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up the AAD */
|
||||||
|
if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0)
|
||||||
|
|| !WPACKET_put_bytes_u8(&wpkt, rec->type)
|
||||||
|
|| !WPACKET_put_bytes_u16(&wpkt, rec->rec_version)
|
||||||
|
|| !WPACKET_put_bytes_u16(&wpkt, rec->length + rl->taglen)
|
||||||
|
|| !WPACKET_get_total_written(&wpkt, &hdrlen)
|
||||||
|
|| hdrlen != SSL3_RT_HEADER_LENGTH
|
||||||
|
|| !WPACKET_finish(&wpkt)) {
|
||||||
|
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||||
|
WPACKET_cleanup(&wpkt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For CCM we must explicitly set the total plaintext length before we add
|
||||||
|
* any AAD.
|
||||||
|
*/
|
||||||
|
if ((mode == EVP_CIPH_CCM_MODE
|
||||||
|
&& EVP_CipherUpdate(ctx, NULL, &lenu, NULL,
|
||||||
|
(unsigned int)rec->length) <= 0)
|
||||||
|
|| EVP_CipherUpdate(ctx, NULL, &lenu, recheader,
|
||||||
|
sizeof(recheader)) <= 0
|
||||||
|
|| EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input,
|
||||||
|
(unsigned int)rec->length) <= 0
|
||||||
|
|| EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0
|
||||||
|
|| (size_t)(lenu + lenf) != rec->length) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (sending) {
|
||||||
|
/* Add the tag */
|
||||||
|
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, rl->taglen,
|
||||||
|
rec->data + rec->length) <= 0) {
|
||||||
|
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
rec->length += rl->taglen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static const unsigned char ssl3_pad_1[48] = {
|
static const unsigned char ssl3_pad_1[48] = {
|
||||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
@ -1102,7 +1268,6 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct record_functions_st tls_any_funcs = {
|
struct record_functions_st tls_any_funcs = {
|
||||||
tls_any_set_crypto_state,
|
tls_any_set_crypto_state,
|
||||||
tls_any_cipher,
|
tls_any_cipher,
|
||||||
@ -1110,8 +1275,8 @@ struct record_functions_st tls_any_funcs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct record_functions_st tls_1_3_funcs = {
|
struct record_functions_st tls_1_3_funcs = {
|
||||||
tls_fail_set_crypto_state,
|
tls13_set_crypto_state,
|
||||||
NULL,
|
tls13_cipher,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1648,7 +1813,7 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (SSL_CONNECTION_IS_TLS13(s)
|
if (SSL_CONNECTION_IS_TLS13(s)
|
||||||
&& s->enc_read_ctx != NULL
|
&& rl->enc_read_ctx != NULL
|
||||||
&& !using_ktls) {
|
&& !using_ktls) {
|
||||||
if (thisrr->type != SSL3_RT_APPLICATION_DATA
|
if (thisrr->type != SSL3_RT_APPLICATION_DATA
|
||||||
&& (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC
|
&& (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC
|
||||||
@ -1866,10 +2031,7 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
|
|||||||
* TODO(RECLAYER): Only call rl functions once TLSv1.3/SSLv3 is moved to new
|
* TODO(RECLAYER): Only call rl functions once TLSv1.3/SSLv3 is moved to new
|
||||||
* record layer code
|
* record layer code
|
||||||
*/
|
*/
|
||||||
if (!SSL_CONNECTION_IS_TLS13(s))
|
enc_err = rl->funcs->cipher(rl, rr, num_recs, 0, macbufs, mac_size, s);
|
||||||
enc_err = rl->funcs->cipher(rl, rr, num_recs, 0, macbufs, mac_size, s);
|
|
||||||
else
|
|
||||||
enc_err = ssl->method->ssl3_enc->enc(s, rr, num_recs, 0, macbufs, mac_size);
|
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* enc_err is:
|
* enc_err is:
|
||||||
@ -1970,7 +2132,7 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (SSL_CONNECTION_IS_TLS13(s)
|
if (SSL_CONNECTION_IS_TLS13(s)
|
||||||
&& s->enc_read_ctx != NULL
|
&& rl->enc_read_ctx != NULL
|
||||||
&& thisrr->type != SSL3_RT_ALERT) {
|
&& thisrr->type != SSL3_RT_ALERT) {
|
||||||
/*
|
/*
|
||||||
* The following logic are irrelevant in KTLS: the kernel provides
|
* The following logic are irrelevant in KTLS: the kernel provides
|
||||||
@ -2288,6 +2450,7 @@ static OSSL_RECORD_LAYER *dtls_new_record_layer(OSSL_LIB_CTX *libctx,
|
|||||||
|
|
||||||
static void tls_free(OSSL_RECORD_LAYER *rl)
|
static void tls_free(OSSL_RECORD_LAYER *rl)
|
||||||
{
|
{
|
||||||
|
/* TODO(RECLAYER): Cleanse sensitive fields */
|
||||||
BIO_free(rl->bio);
|
BIO_free(rl->bio);
|
||||||
OPENSSL_free(rl);
|
OPENSSL_free(rl);
|
||||||
}
|
}
|
||||||
|
124
ssl/tls13_enc.c
124
ssl/tls13_enc.c
@ -344,12 +344,14 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, int sending,
|
|||||||
const unsigned char *hash,
|
const unsigned char *hash,
|
||||||
const unsigned char *label,
|
const unsigned char *label,
|
||||||
size_t labellen, unsigned char *secret,
|
size_t labellen, unsigned char *secret,
|
||||||
unsigned char *key, unsigned char *iv,
|
unsigned char *key, size_t *keylen,
|
||||||
|
unsigned char *iv, size_t *ivlen,
|
||||||
|
size_t *taglen,
|
||||||
EVP_CIPHER_CTX *ciph_ctx)
|
EVP_CIPHER_CTX *ciph_ctx)
|
||||||
{
|
{
|
||||||
size_t ivlen, keylen, taglen;
|
|
||||||
int hashleni = EVP_MD_get_size(md);
|
int hashleni = EVP_MD_get_size(md);
|
||||||
size_t hashlen;
|
size_t hashlen;
|
||||||
|
int mode;
|
||||||
|
|
||||||
/* Ensure cast to size_t is safe */
|
/* Ensure cast to size_t is safe */
|
||||||
if (!ossl_assert(hashleni >= 0)) {
|
if (!ossl_assert(hashleni >= 0)) {
|
||||||
@ -364,11 +366,13 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, int sending,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
keylen = EVP_CIPHER_get_key_length(ciph);
|
*keylen = EVP_CIPHER_get_key_length(ciph);
|
||||||
if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_CCM_MODE) {
|
|
||||||
|
mode = EVP_CIPHER_get_mode(ciph);
|
||||||
|
if (mode == EVP_CIPH_CCM_MODE) {
|
||||||
uint32_t algenc;
|
uint32_t algenc;
|
||||||
|
|
||||||
ivlen = EVP_CCM_TLS_IV_LEN;
|
*ivlen = EVP_CCM_TLS_IV_LEN;
|
||||||
if (s->s3.tmp.new_cipher != NULL) {
|
if (s->s3.tmp.new_cipher != NULL) {
|
||||||
algenc = s->s3.tmp.new_cipher->algorithm_enc;
|
algenc = s->s3.tmp.new_cipher->algorithm_enc;
|
||||||
} else if (s->session->cipher != NULL) {
|
} else if (s->session->cipher != NULL) {
|
||||||
@ -382,27 +386,34 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, int sending,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8))
|
if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8))
|
||||||
taglen = EVP_CCM8_TLS_TAG_LEN;
|
*taglen = EVP_CCM8_TLS_TAG_LEN;
|
||||||
else
|
else
|
||||||
taglen = EVP_CCM_TLS_TAG_LEN;
|
*taglen = EVP_CCM_TLS_TAG_LEN;
|
||||||
} else {
|
} else {
|
||||||
ivlen = EVP_CIPHER_get_iv_length(ciph);
|
if (mode == EVP_CIPH_GCM_MODE) {
|
||||||
taglen = 0;
|
*taglen = EVP_GCM_TLS_TAG_LEN;
|
||||||
|
} else {
|
||||||
|
/* CHACHA20P-POLY1305 */
|
||||||
|
*taglen = EVP_CHACHAPOLY_TLS_TAG_LEN;
|
||||||
|
}
|
||||||
|
*ivlen = EVP_CIPHER_get_iv_length(ciph);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tls13_derive_key(s, md, secret, key, keylen)
|
if (!tls13_derive_key(s, md, secret, key, *keylen)
|
||||||
|| !tls13_derive_iv(s, md, secret, iv, ivlen)) {
|
|| !tls13_derive_iv(s, md, secret, iv, *ivlen)) {
|
||||||
/* SSLfatal() already called */
|
/* SSLfatal() already called */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0
|
if (sending) {
|
||||||
|| EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL) <= 0
|
if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0
|
||||||
|| (taglen != 0 && EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG,
|
|| EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, *ivlen, NULL) <= 0
|
||||||
taglen, NULL) <= 0)
|
|| (mode == EVP_CIPH_CCM_MODE
|
||||||
|| EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) {
|
&& EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, *taglen, NULL) <= 0)
|
||||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
|
|| EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) {
|
||||||
return 0;
|
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -411,14 +422,14 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, int sending,
|
|||||||
int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
|
int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
|
||||||
{
|
{
|
||||||
#ifdef CHARSET_EBCDIC
|
#ifdef CHARSET_EBCDIC
|
||||||
static const unsigned char client_early_traffic[] = {0x63, 0x20, 0x65, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
static const unsigned char client_early_traffic[] = {0x63, 0x20, 0x65, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||||
static const unsigned char client_handshake_traffic[] = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
static const unsigned char client_handshake_traffic[] = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||||
static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||||
static const unsigned char server_handshake_traffic[] = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
static const unsigned char server_handshake_traffic[] = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||||
static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||||
static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
||||||
static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
||||||
static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
||||||
#else
|
#else
|
||||||
static const unsigned char client_early_traffic[] = "c e traffic";
|
static const unsigned char client_early_traffic[] = "c e traffic";
|
||||||
static const unsigned char client_handshake_traffic[] = "c hs traffic";
|
static const unsigned char client_handshake_traffic[] = "c hs traffic";
|
||||||
@ -437,7 +448,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
|
|||||||
unsigned char *insecret;
|
unsigned char *insecret;
|
||||||
unsigned char *finsecret = NULL;
|
unsigned char *finsecret = NULL;
|
||||||
const char *log_label = NULL;
|
const char *log_label = NULL;
|
||||||
EVP_CIPHER_CTX *ciph_ctx;
|
EVP_CIPHER_CTX *ciph_ctx = NULL;
|
||||||
size_t finsecretlen = 0;
|
size_t finsecretlen = 0;
|
||||||
const unsigned char *label;
|
const unsigned char *label;
|
||||||
size_t labellen, hashlen = 0;
|
size_t labellen, hashlen = 0;
|
||||||
@ -445,6 +456,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
|
|||||||
const EVP_MD *md = NULL;
|
const EVP_MD *md = NULL;
|
||||||
const EVP_CIPHER *cipher = NULL;
|
const EVP_CIPHER *cipher = NULL;
|
||||||
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
|
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
|
||||||
|
size_t keylen, ivlen, taglen;
|
||||||
#if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13)
|
#if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13)
|
||||||
ktls_crypto_info_t crypto_info;
|
ktls_crypto_info_t crypto_info;
|
||||||
void *rl_sequence;
|
void *rl_sequence;
|
||||||
@ -452,16 +464,6 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (which & SSL3_CC_READ) {
|
if (which & SSL3_CC_READ) {
|
||||||
if (s->enc_read_ctx != NULL) {
|
|
||||||
EVP_CIPHER_CTX_reset(s->enc_read_ctx);
|
|
||||||
} else {
|
|
||||||
s->enc_read_ctx = EVP_CIPHER_CTX_new();
|
|
||||||
if (s->enc_read_ctx == NULL) {
|
|
||||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ciph_ctx = s->enc_read_ctx;
|
|
||||||
iv = s->read_iv;
|
iv = s->read_iv;
|
||||||
|
|
||||||
RECORD_LAYER_reset_read_sequence(&s->rlayer);
|
RECORD_LAYER_reset_read_sequence(&s->rlayer);
|
||||||
@ -659,7 +661,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
|
|||||||
|
|
||||||
if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher,
|
if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher,
|
||||||
insecret, hash, label, labellen, secret, key,
|
insecret, hash, label, labellen, secret, key,
|
||||||
iv, ciph_ctx)) {
|
&keylen, iv, &ivlen, &taglen, ciph_ctx)) {
|
||||||
/* SSLfatal() already called */
|
/* SSLfatal() already called */
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -700,6 +702,29 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
|
|||||||
s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS;
|
s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS;
|
||||||
else
|
else
|
||||||
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
|
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
|
||||||
|
|
||||||
|
if ((which & SSL3_CC_READ) != 0) {
|
||||||
|
int level = (which & SSL3_CC_EARLY) != 0
|
||||||
|
? OSSL_RECORD_PROTECTION_LEVEL_EARLY
|
||||||
|
: ((which &SSL3_CC_HANDSHAKE) != 0
|
||||||
|
? OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE
|
||||||
|
: OSSL_RECORD_PROTECTION_LEVEL_APPLICATION);
|
||||||
|
s->rrlmethod->free(s->rrl);
|
||||||
|
s->rrl = s->rrlmethod->new_record_layer(sctx->libctx,
|
||||||
|
sctx->propq,
|
||||||
|
s->version, s->server,
|
||||||
|
OSSL_RECORD_DIRECTION_READ,
|
||||||
|
level, key, keylen, iv, ivlen,
|
||||||
|
NULL, 0, cipher, taglen,
|
||||||
|
NID_undef, NULL, NULL, s->rbio,
|
||||||
|
NULL, NULL, NULL, NULL, s);
|
||||||
|
if (s->rrl == NULL) {
|
||||||
|
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_KTLS
|
#ifndef OPENSSL_NO_KTLS
|
||||||
# if defined(OPENSSL_KTLS_TLS13)
|
# if defined(OPENSSL_KTLS_TLS13)
|
||||||
if (!(which & SSL3_CC_APPLICATION)
|
if (!(which & SSL3_CC_APPLICATION)
|
||||||
@ -776,7 +801,9 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
|
|||||||
unsigned char *insecret, *iv;
|
unsigned char *insecret, *iv;
|
||||||
unsigned char secret[EVP_MAX_MD_SIZE];
|
unsigned char secret[EVP_MAX_MD_SIZE];
|
||||||
EVP_CIPHER_CTX *ciph_ctx;
|
EVP_CIPHER_CTX *ciph_ctx;
|
||||||
|
size_t keylen, ivlen, taglen;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
|
||||||
|
|
||||||
if (s->server == sending)
|
if (s->server == sending)
|
||||||
insecret = s->server_app_traffic_secret;
|
insecret = s->server_app_traffic_secret;
|
||||||
@ -798,13 +825,32 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
|
|||||||
s->s3.tmp.new_sym_enc, insecret, NULL,
|
s->s3.tmp.new_sym_enc, insecret, NULL,
|
||||||
application_traffic,
|
application_traffic,
|
||||||
sizeof(application_traffic) - 1, secret, key,
|
sizeof(application_traffic) - 1, secret, key,
|
||||||
iv, ciph_ctx)) {
|
&keylen, iv, &ivlen, &taglen, ciph_ctx)) {
|
||||||
/* SSLfatal() already called */
|
/* SSLfatal() already called */
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(insecret, secret, hashlen);
|
memcpy(insecret, secret, hashlen);
|
||||||
|
|
||||||
|
if (!sending) {
|
||||||
|
s->rrlmethod->free(s->rrl);
|
||||||
|
s->rrl = s->rrlmethod->new_record_layer(sctx->libctx,
|
||||||
|
sctx->propq,
|
||||||
|
s->version, s->server,
|
||||||
|
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,
|
||||||
|
s->rbio, NULL, NULL, NULL, NULL,
|
||||||
|
s);
|
||||||
|
if (s->rrl == NULL) {
|
||||||
|
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
|
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
err:
|
err:
|
||||||
|
Loading…
Reference in New Issue
Block a user