Skip to content

Commit

Permalink
Remove unneccesary KTLS code from non-KTLS specific files
Browse files Browse the repository at this point in the history
This also moves other protocol specific code to the protocol specific
files.

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #18132)
  • Loading branch information
mattcaswell committed Aug 18, 2022
1 parent 5b24990 commit 1853d20
Show file tree
Hide file tree
Showing 12 changed files with 639 additions and 377 deletions.
133 changes: 131 additions & 2 deletions ssl/record/methods/ktls_meth.c
Expand Up @@ -408,15 +408,144 @@ static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
return OSSL_RECORD_RETURN_SUCCESS;
}

static int ktls_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int clearold, size_t *readbytes)
{
int ret;

ret = tls_default_read_n(rl, n, max, extend, clearold, readbytes);

if (ret < OSSL_RECORD_RETURN_RETRY) {
switch (errno) {
case EBADMSG:
RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC,
SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
break;
case EMSGSIZE:
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_PACKET_LENGTH_TOO_LONG);
break;
case EINVAL:
RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
SSL_R_WRONG_VERSION_NUMBER);
break;
default:
break;
}
}

return ret;
}

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 = {
static int ktls_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
{
if (rec->rec_version != TLS1_2_VERSION) {
RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_WRONG_VERSION_NUMBER);
return 0;
}

return 1;
}

static int ktls_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec,
SSL_CONNECTION *s)
{
if (rl->version == TLS1_3_VERSION)
return tls13_common_post_process_record(rl, rec, s);

return 1;
}

static struct record_functions_st ossl_ktls_funcs = {
ktls_set_crypto_state,
ktls_read_n,
ktls_cipher,
NULL
NULL,
tls_default_set_protocol_version,
ktls_validate_record_header,
ktls_post_process_record
};

static int
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,
OSSL_RECORD_LAYER **retrl,
/* TODO(RECLAYER): Remove me */
SSL_CONNECTION *s)
{
int ret;

ret = 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, retrl, s);

if (ret != OSSL_RECORD_RETURN_SUCCESS)
return ret;

(*retrl)->funcs = &ossl_ktls_funcs;

ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv,
ivlen, mackey, mackeylen, ciph,
taglen, mactype, md, comp, s);

if (ret != OSSL_RECORD_RETURN_SUCCESS) {
OPENSSL_free(*retrl);
*retrl = NULL;
} else {
/*
* With KTLS we always try and read as much as possible and fill the
* buffer
*/
(*retrl)->read_ahead = 1;
}
return ret;
}

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,
tls_set_protocol_version,
tls_set_plain_alerts,
tls_set_first_handshake,

/*
* 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_default_read_n,
tls_get0_rbuf,
tls_get0_packet,
tls_set0_packet,
tls_get_packet_length,
tls_reset_packet_length
};
86 changes: 79 additions & 7 deletions ssl/record/methods/recmethod_local.h
Expand Up @@ -33,6 +33,9 @@ struct record_functions_st
const SSL_COMP *comp,
/* TODO(RECLAYER): Remove me */
SSL_CONNECTION *s);

int (*read_n)(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int clearold, size_t *readbytes);
/*
* Returns:
* 0: if the record is publicly invalid, or an internal error, or AEAD
Expand All @@ -45,6 +48,16 @@ struct record_functions_st
/* Returns 1 for success or 0 for error */
int (*mac)(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
int sending, /* TODO(RECLAYER): Remove me */SSL_CONNECTION *ssl);

/* Return 1 for success or 0 for error */
int (*set_protocol_version)(OSSL_RECORD_LAYER *rl, int version);

/* Return 1 for success or 0 for error */
int (*validate_record_header)(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec);

/* Return 1 for success or 0 for error */
int (*post_process_record)(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec,
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s);
};

struct ossl_record_layer_st
Expand Down Expand Up @@ -78,9 +91,6 @@ struct ossl_record_layer_st
/* The number of records that have been released via tls_release_record */
size_t num_released;

/* Set to true if this is the first record in a connection */
unsigned int is_first_record;

/* where we are when reading */
int rstate;

Expand All @@ -102,18 +112,28 @@ struct ossl_record_layer_st

/* cryptographic state */
EVP_CIPHER_CTX *enc_read_ctx;
/* TLSv1.3 static read IV */
unsigned char read_iv[EVP_MAX_IV_LENGTH];

/* used for mac generation */
EVP_MD_CTX *read_hash;
/* uncompress */
COMP_CTX *expand;

/* Set to 1 if this is the first handshake. 0 otherwise */
int is_first_handshake;

/* Only used by SSLv3 */
unsigned char mac_secret[EVP_MAX_MD_SIZE];

/* TLSv1.3 static IV */
/* TLSv1.3 fields */
/* static IV */
unsigned char iv[EVP_MAX_IV_LENGTH];
/* static read IV */
unsigned char read_iv[EVP_MAX_IV_LENGTH];
int allow_plain_alerts;

/* TLS "any" fields */
/* Set to true if this is the first record in a connection */
unsigned int is_first_record;

size_t taglen;

Expand All @@ -125,7 +145,6 @@ 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,
Expand Down Expand Up @@ -153,3 +172,56 @@ __owur int ssl3_cbc_digest_record(const EVP_MD *md,
size_t data_plus_mac_plus_padding_size,
const unsigned char *mac_secret,
size_t mac_secret_length, char is_sslv3);

int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int clearold, size_t *readbytes);

int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
int tls_default_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *re);
int tls_default_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, SSL_CONNECTION *s);
int tls13_common_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec,
SSL_CONNECTION *s);

int
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,
OSSL_RECORD_LAYER **retrl,
/* TODO(RECLAYER): Remove me */
SSL_CONNECTION *s);
void tls_free(OSSL_RECORD_LAYER *rl);
int tls_reset(OSSL_RECORD_LAYER *rl);
int tls_unprocessed_read_pending(OSSL_RECORD_LAYER *rl);
int tls_processed_read_pending(OSSL_RECORD_LAYER *rl);
size_t tls_app_data_pending(OSSL_RECORD_LAYER *rl);
int tls_write_pending(OSSL_RECORD_LAYER *rl);
size_t tls_get_max_record_len(OSSL_RECORD_LAYER *rl);
size_t tls_get_max_records(OSSL_RECORD_LAYER *rl);
int tls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE **templates,
size_t numtempl, size_t allowance, size_t *sent);
int tls_retry_write_records(OSSL_RECORD_LAYER *rl, size_t allowance,
size_t *sent);
int tls_get_alert_code(OSSL_RECORD_LAYER *rl);
int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio);
int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion,
int *type, unsigned char **data, size_t *datalen,
uint16_t *epoch, unsigned char *seq_num,
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s);
int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle);
int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
int tls_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
void tls_set_plain_alerts(OSSL_RECORD_LAYER *rl, int allow);
void tls_set_first_handshake(OSSL_RECORD_LAYER *rl, int first);
SSL3_BUFFER *tls_get0_rbuf(OSSL_RECORD_LAYER *rl);
unsigned char *tls_get0_packet(OSSL_RECORD_LAYER *rl);
void tls_set0_packet(OSSL_RECORD_LAYER *rl, unsigned char *packet,
size_t packetlen);
size_t tls_get_packet_length(OSSL_RECORD_LAYER *rl);
void tls_reset_packet_length(OSSL_RECORD_LAYER *rl);
6 changes: 5 additions & 1 deletion ssl/record/methods/ssl3_meth.c
Expand Up @@ -315,6 +315,10 @@ static int ssl3_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,

struct record_functions_st ssl_3_0_funcs = {
ssl3_set_crypto_state,
tls_default_read_n,
ssl3_cipher,
ssl3_mac
ssl3_mac,
tls_default_set_protocol_version,
tls_default_validate_record_header,
tls_default_post_process_record
};
65 changes: 64 additions & 1 deletion ssl/record/methods/tls13_meth.c
Expand Up @@ -191,8 +191,71 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
return 1;
}

static int tls13_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
{
if (rec->type != SSL3_RT_APPLICATION_DATA
&& (rec->type != SSL3_RT_CHANGE_CIPHER_SPEC
|| !rl->is_first_handshake)
&& (rec->type != SSL3_RT_ALERT || !rl->allow_plain_alerts)) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE);
return 0;
}

if (rec->rec_version != TLS1_2_VERSION) {
RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_WRONG_VERSION_NUMBER);
return 0;
}

if (rec->length > SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
return 0;
}
return 1;
}

static int tls13_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec,
SSL_CONNECTION *s)
{
/* Skip this if we've received a plaintext alert */
if (rec->type != SSL3_RT_ALERT) {
size_t end;

if (rec->length == 0
|| rec->type != SSL3_RT_APPLICATION_DATA) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE,
SSL_R_BAD_RECORD_TYPE);
return 0;
}

/* Strip trailing padding */
for (end = rec->length - 1; end > 0 && rec->data[end] == 0;
end--)
continue;

rec->length = end;
rec->type = rec->data[end];
}

if (rec->length > SSL3_RT_MAX_PLAIN_LENGTH) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}

if (!tls13_common_post_process_record(rl, rec, s)) {
/* RLAYERfatal already called */
return 0;
}

return 1;
}

struct record_functions_st tls_1_3_funcs = {
tls13_set_crypto_state,
tls_default_read_n,
tls13_cipher,
NULL
NULL,
tls_default_set_protocol_version,
tls13_validate_record_header,
tls13_post_process_record
};
6 changes: 5 additions & 1 deletion ssl/record/methods/tls1_meth.c
Expand Up @@ -591,6 +591,10 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
/* TLSv1.0, TLSv1.1 and TLSv1.2 all use the same funcs */
struct record_functions_st tls_1_funcs = {
tls1_set_crypto_state,
tls_default_read_n,
tls1_cipher,
tls1_mac
tls1_mac,
tls_default_set_protocol_version,
tls_default_validate_record_header,
tls_default_post_process_record
};

0 comments on commit 1853d20

Please sign in to comment.