summaryrefslogtreecommitdiffstats
path: root/lib/libssl/tls12_record_layer.c
diff options
context:
space:
mode:
authorjsing <jsing@openbsd.org>2021-01-19 19:07:39 +0000
committerjsing <jsing@openbsd.org>2021-01-19 19:07:39 +0000
commita802a16adaa92c0a0d3b8521ebf2eaf7341efd30 (patch)
tree3594e3ea263f5f0bcfcab515c135e3ce2ebf446b /lib/libssl/tls12_record_layer.c
parentProvide functions to determine if TLSv1.2 record protection is engaged. (diff)
downloadwireguard-openbsd-a802a16adaa92c0a0d3b8521ebf2eaf7341efd30.tar.xz
wireguard-openbsd-a802a16adaa92c0a0d3b8521ebf2eaf7341efd30.zip
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@
Diffstat (limited to 'lib/libssl/tls12_record_layer.c')
-rw-r--r--lib/libssl/tls12_record_layer.c107
1 files changed, 102 insertions, 5 deletions
diff --git a/lib/libssl/tls12_record_layer.c b/lib/libssl/tls12_record_layer.c
index affc5375a2e..83d71d1c7a0 100644
--- a/lib/libssl/tls12_record_layer.c
+++ b/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 <jsing@openbsd.org>
*
@@ -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)