From e99005f53b351b3c662664891d988adaa02c4d0b Mon Sep 17 00:00:00 2001 From: jsing <> Date: Tue, 19 Jan 2021 19:07:39 +0000 Subject: Add code to handle change of cipher state in the new TLSv1.2 record layer. This provides the basic framework for handling change of cipher state in the new TLSv1.2 record layer, creating new record protection. In the DTLS case we retain the previous write record protection and can switch back to it when retransmitting. This will allow the record layer to start owning sequence numbers and encryption/decryption state. ok inoguchi@ tb@ --- src/lib/libssl/tls12_record_layer.c | 107 ++++++++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 5 deletions(-) (limited to 'src/lib/libssl/tls12_record_layer.c') diff --git a/src/lib/libssl/tls12_record_layer.c b/src/lib/libssl/tls12_record_layer.c index affc5375a2..83d71d1c7a 100644 --- a/src/lib/libssl/tls12_record_layer.c +++ b/src/lib/libssl/tls12_record_layer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls12_record_layer.c,v 1.12 2021/01/19 18:57:09 jsing Exp $ */ +/* $OpenBSD: tls12_record_layer.c,v 1.13 2021/01/19 19:07:39 jsing Exp $ */ /* * Copyright (c) 2020 Joel Sing * @@ -132,8 +132,13 @@ struct tls12_record_layer { uint8_t alert_desc; + /* Pointers to active record protection (memory is not owned). */ struct tls12_record_protection *read; struct tls12_record_protection *write; + + struct tls12_record_protection *read_current; + struct tls12_record_protection *write_current; + struct tls12_record_protection *write_previous; }; struct tls12_record_layer * @@ -143,11 +148,14 @@ tls12_record_layer_new(void) if ((rl = calloc(1, sizeof(struct tls12_record_layer))) == NULL) goto err; - if ((rl->read = tls12_record_protection_new()) == NULL) + if ((rl->read_current = tls12_record_protection_new()) == NULL) goto err; - if ((rl->write = tls12_record_protection_new()) == NULL) + if ((rl->write_current = tls12_record_protection_new()) == NULL) goto err; + rl->read = rl->read_current; + rl->write = rl->write_current; + return rl; err: @@ -162,8 +170,9 @@ tls12_record_layer_free(struct tls12_record_layer *rl) if (rl == NULL) return; - tls12_record_protection_free(rl->read); - tls12_record_protection_free(rl->write); + tls12_record_protection_free(rl->read_current); + tls12_record_protection_free(rl->write_current); + tls12_record_protection_free(rl->write_previous); freezero(rl, sizeof(struct tls12_record_layer)); } @@ -226,6 +235,37 @@ tls12_record_layer_set_write_epoch(struct tls12_record_layer *rl, uint16_t epoch rl->write->epoch = epoch; } +int +tls12_record_layer_use_write_epoch(struct tls12_record_layer *rl, uint16_t epoch) +{ + if (rl->write->epoch == epoch) + return 1; + + if (rl->write_current->epoch == epoch) { + rl->write = rl->write_current; + return 1; + } + + if (rl->write_previous != NULL && rl->write_previous->epoch == epoch) { + rl->write = rl->write_previous; + return 1; + } + + return 0; +} + +void +tls12_record_layer_write_epoch_done(struct tls12_record_layer *rl, uint16_t epoch) +{ + if (rl->write_previous == NULL || rl->write_previous->epoch != epoch) + return; + + rl->write = rl->write_current; + + tls12_record_protection_free(rl->write_previous); + rl->write_previous = NULL; +} + static void tls12_record_layer_set_read_state(struct tls12_record_layer *rl, SSL_AEAD_CTX *aead_ctx, EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, @@ -263,6 +303,9 @@ tls12_record_layer_clear_write_state(struct tls12_record_layer *rl) { tls12_record_layer_set_write_state(rl, NULL, NULL, NULL, 0); rl->write->seq_num = NULL; + + tls12_record_protection_free(rl->write_previous); + rl->write_previous = NULL; } void @@ -337,6 +380,60 @@ tls12_record_layer_set_read_mac_key(struct tls12_record_layer *rl, return 1; } +int +tls12_record_layer_change_read_cipher_state(struct tls12_record_layer *rl, + const uint8_t *mac_key, size_t mac_key_len, const uint8_t *key, + size_t key_len, const uint8_t *iv, size_t iv_len) +{ + struct tls12_record_protection *read_new = NULL; + int ret = 0; + + if ((read_new = tls12_record_protection_new()) == NULL) + goto err; + + /* XXX - change cipher state. */ + + tls12_record_protection_free(rl->read_current); + rl->read = rl->read_current = read_new; + read_new = NULL; + + ret = 1; + + err: + tls12_record_protection_free(read_new); + + return ret; +} + +int +tls12_record_layer_change_write_cipher_state(struct tls12_record_layer *rl, + const uint8_t *mac_key, size_t mac_key_len, const uint8_t *key, + size_t key_len, const uint8_t *iv, size_t iv_len) +{ + struct tls12_record_protection *write_new; + int ret = 0; + + if ((write_new = tls12_record_protection_new()) == NULL) + goto err; + + /* XXX - change cipher state. */ + + if (rl->dtls) { + tls12_record_protection_free(rl->write_previous); + rl->write_previous = rl->write_current; + rl->write_current = NULL; + } + tls12_record_protection_free(rl->write_current); + rl->write = rl->write_current = write_new; + write_new = NULL; + + ret = 1; + + err: + tls12_record_protection_free(write_new); + + return ret; +} static int tls12_record_layer_build_seq_num(struct tls12_record_layer *rl, CBB *cbb, uint16_t epoch, uint8_t *seq_num, size_t seq_num_len) -- cgit v1.2.3-55-g6feb