diff options
Diffstat (limited to 'ssl/record/methods')
-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 |
4 files changed, 239 insertions, 51 deletions
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, |