Add a prepare for encryption step

This applies any mac that might be necessary, ensures that we have
enough space in the WPACKET to perform the encryption and sets up the
SSL3_RECORD ready for that encryption.

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19343)
This commit is contained in:
Matt Caswell 2022-09-27 16:43:23 +01:00
parent 2582de2590
commit 757ef3bab0
7 changed files with 97 additions and 44 deletions

View File

@ -492,6 +492,15 @@ static int ktls_prepare_record_header(OSSL_RECORD_LAYER *rl,
return 1;
}
static int ktls_prepare_for_encryption(OSSL_RECORD_LAYER *rl,
size_t mac_size,
WPACKET *thispkt,
SSL3_RECORD *thiswr)
{
/* No encryption, so nothing to do */
return 1;
}
static struct record_functions_st ossl_ktls_funcs = {
ktls_set_crypto_state,
ktls_cipher,
@ -507,7 +516,8 @@ static struct record_functions_st ossl_ktls_funcs = {
ktls_initialise_write_packets,
NULL,
ktls_prepare_record_header,
NULL
NULL,
ktls_prepare_for_encryption
};
const OSSL_RECORD_METHOD ossl_ktls_record_method = {

View File

@ -110,6 +110,16 @@ struct record_functions_st
OSSL_RECORD_TEMPLATE *thistempl,
WPACKET *thispkt,
SSL3_RECORD *thiswr);
/*
* This applies any mac that might be necessary, ensures that we have enough
* space in the WPACKET to perform the encryption and sets up the
* SSL3_RECORD ready for that encryption.
*/
int (*prepare_for_encryption)(OSSL_RECORD_LAYER *rl,
size_t mac_size,
WPACKET *thispkt,
SSL3_RECORD *thiswr);
};
struct ossl_record_layer_st
@ -407,6 +417,10 @@ int tls_prepare_record_header_default(OSSL_RECORD_LAYER *rl,
OSSL_RECORD_TEMPLATE *templ,
unsigned int rectype,
unsigned char **recdata);
int tls_prepare_for_encryption_default(OSSL_RECORD_LAYER *rl,
size_t mac_size,
WPACKET *thispkt,
SSL3_RECORD *thiswr);
int tls_write_records_default(OSSL_RECORD_LAYER *rl,
OSSL_RECORD_TEMPLATE *templates,
size_t numtempl);

View File

@ -316,5 +316,6 @@ struct record_functions_st ssl_3_0_funcs = {
tls1_initialise_write_packets,
NULL,
tls_prepare_record_header_default,
NULL
NULL,
tls_prepare_for_encryption_default
};

View File

@ -324,5 +324,6 @@ struct record_functions_st tls_1_3_funcs = {
tls_initialise_write_packets_default,
tls13_get_record_type,
tls_prepare_record_header_default,
tls13_add_record_padding
tls13_add_record_padding,
tls_prepare_for_encryption_default
};

View File

@ -657,7 +657,8 @@ struct record_functions_st tls_1_funcs = {
tls1_initialise_write_packets,
NULL,
tls_prepare_record_header_default,
NULL
NULL,
tls_prepare_for_encryption_default
};
struct record_functions_st dtls_1_funcs = {
@ -674,5 +675,6 @@ struct record_functions_st dtls_1_funcs = {
NULL,
NULL,
NULL,
NULL,
NULL
};

View File

@ -1562,6 +1562,56 @@ int tls_prepare_record_header_default(OSSL_RECORD_LAYER *rl,
return 1;
}
int tls_prepare_for_encryption_default(OSSL_RECORD_LAYER *rl,
size_t mac_size,
WPACKET *thispkt,
SSL3_RECORD *thiswr)
{
size_t len;
unsigned char *recordstart;
/*
* we should still have the output to thiswr->data and the input from
* wr->input. Length should be thiswr->length. thiswr->data still points
* in the wb->buf
*/
if (!rl->use_etm && mac_size != 0) {
unsigned char *mac;
if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
|| !rl->funcs->mac(rl, thiswr, mac, 1)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
}
/*
* Reserve some bytes for any growth that may occur during encryption.
* This will be at most one cipher block or the tag length if using
* AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case.
*/
if (!WPACKET_reserve_bytes(thispkt,
SSL_RT_MAX_CIPHER_BLOCK_SIZE,
NULL)
/*
* We also need next the amount of bytes written to this
* sub-packet
*/
|| !WPACKET_get_length(thispkt, &len)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
/* Get a pointer to the start of this record excluding header */
recordstart = WPACKET_get_curr(thispkt) - len;
SSL3_RECORD_set_data(thiswr, recordstart);
SSL3_RECORD_reset_input(thiswr);
SSL3_RECORD_set_length(thiswr, len);
return 1;
}
int tls_write_records_default(OSSL_RECORD_LAYER *rl,
OSSL_RECORD_TEMPLATE *templates,
size_t numtempl)
@ -1665,45 +1715,9 @@ int tls_write_records_default(OSSL_RECORD_LAYER *rl,
goto err;
}
/*
* we should still have the output to thiswr->data and the input from
* wr->input. Length should be thiswr->length. thiswr->data still points
* in the wb->buf
*/
if (!using_ktls && !rl->use_etm && mac_size != 0) {
unsigned char *mac;
if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
|| !rl->funcs->mac(rl, thiswr, mac, 1)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
}
/*
* Reserve some bytes for any growth that may occur during encryption.
* This will be at most one cipher block or the tag length if using
* AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case.
*/
if (!using_ktls) {
if (!WPACKET_reserve_bytes(thispkt,
SSL_RT_MAX_CIPHER_BLOCK_SIZE,
NULL)
/*
* We also need next the amount of bytes written to this
* sub-packet
*/
|| !WPACKET_get_length(thispkt, &len)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
/* Get a pointer to the start of this record excluding header */
recordstart = WPACKET_get_curr(thispkt) - len;
SSL3_RECORD_set_data(thiswr, recordstart);
SSL3_RECORD_reset_input(thiswr);
SSL3_RECORD_set_length(thiswr, len);
if (!rl->funcs->prepare_for_encryption(rl, mac_size, thispkt, thiswr)) {
/* RLAYERfatal() already called */
goto err;
}
}

View File

@ -134,6 +134,15 @@ static int tls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers)
return 1;
}
static int tls_any_prepare_for_encryption(OSSL_RECORD_LAYER *rl,
size_t mac_size,
WPACKET *thispkt,
SSL3_RECORD *thiswr)
{
/* No encryption, so nothing to do */
return 1;
}
struct record_functions_st tls_any_funcs = {
tls_any_set_crypto_state,
tls_any_cipher,
@ -149,7 +158,8 @@ struct record_functions_st tls_any_funcs = {
tls_initialise_write_packets_default,
NULL,
tls_prepare_record_header_default,
NULL
NULL,
tls_any_prepare_for_encryption
};
static int dtls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers)
@ -176,5 +186,6 @@ struct record_functions_st dtls_any_funcs = {
NULL,
NULL,
NULL,
NULL,
NULL
};