From 61ec18da26d0571bc925e8f60b9f8b60ce5ca1fb Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Wed, 5 May 2021 10:05:27 +0000
Subject: Rewrite TLSv1.2 key block handling.

For TLSv1.2 a single key block is generated, then partitioned into
individual secrets for use as IVs and keys. The previous implementation
splits this across two functions tls1_setup_key_block() and
tls1_change_cipher_state(), which means that the IV and key sizes have to
be known in multiple places.

This implementation generates and partitions the key block in a single
step, meaning that the secrets are then simply handed out when requested.

ok inoguchi@ tb@
---
 src/lib/libssl/Makefile             |   3 +-
 src/lib/libssl/ssl_locl.h           |  28 +++---
 src/lib/libssl/t1_enc.c             |  97 +++++---------------
 src/lib/libssl/tls12_key_schedule.c | 175 ++++++++++++++++++++++++++++++++++++
 src/lib/libssl/tls12_record_layer.c |  78 +++++++---------
 5 files changed, 247 insertions(+), 134 deletions(-)
 create mode 100644 src/lib/libssl/tls12_key_schedule.c

(limited to 'src')

diff --git a/src/lib/libssl/Makefile b/src/lib/libssl/Makefile
index d6730a5e04..6171194629 100644
--- a/src/lib/libssl/Makefile
+++ b/src/lib/libssl/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.69 2021/04/25 13:15:22 jsing Exp $
+# $OpenBSD: Makefile,v 1.70 2021/05/05 10:05:27 jsing Exp $
 
 .include <bsd.own.mk>
 .ifndef NOMAN
@@ -67,6 +67,7 @@ SRCS= \
 	ssl_versions.c \
 	t1_enc.c \
 	t1_lib.c \
+	tls12_key_schedule.c \
 	tls12_lib.c \
 	tls12_record_layer.c \
 	tls13_buffer.c \
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 9dfa1243c9..1f7e1fa587 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.341 2021/05/02 17:46:58 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.342 2021/05/05 10:05:27 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -431,12 +431,8 @@ typedef struct ssl_handshake_tls12_st {
 	int cert_request;
 	STACK_OF(X509_NAME) *ca_names;
 
-	/* Size of the MAC secret. */
-	int mac_secret_size;
-
 	/* Record-layer key block for TLS 1.2 and earlier. */
-	unsigned char *key_block;
-	size_t key_block_len;
+	struct tls12_key_block *key_block;
 
 	/* Transcript hash prior to sending certificate verify message. */
 	uint8_t cert_verify[EVP_MAX_MD_SIZE];
@@ -522,6 +518,17 @@ typedef struct ssl_handshake_st {
 	SSL_HANDSHAKE_TLS13 tls13;
 } SSL_HANDSHAKE;
 
+struct tls12_key_block;
+
+struct tls12_key_block *tls12_key_block_new(void);
+void tls12_key_block_free(struct tls12_key_block *kb);
+void tls12_key_block_client_write(struct tls12_key_block *kb, CBS *mac_key,
+    CBS *key, CBS *iv);
+void tls12_key_block_server_write(struct tls12_key_block *kb, CBS *mac_key,
+    CBS *key, CBS *iv);
+int tls12_key_block_generate(struct tls12_key_block *kb, SSL *s,
+    const EVP_AEAD *aead, const EVP_CIPHER *cipher, const EVP_MD *mac_hash);
+
 struct tls12_record_layer;
 
 struct tls12_record_layer *tls12_record_layer_new(void);
@@ -532,8 +539,6 @@ int tls12_record_layer_write_overhead(struct tls12_record_layer *rl,
     size_t *overhead);
 int tls12_record_layer_read_protected(struct tls12_record_layer *rl);
 int tls12_record_layer_write_protected(struct tls12_record_layer *rl);
-const EVP_AEAD *tls12_record_layer_aead(struct tls12_record_layer *rl);
-const EVP_CIPHER *tls12_record_layer_cipher(struct tls12_record_layer *rl);
 void tls12_record_layer_set_aead(struct tls12_record_layer *rl,
     const EVP_AEAD *aead);
 void tls12_record_layer_set_cipher_hash(struct tls12_record_layer *rl,
@@ -553,11 +558,9 @@ void tls12_record_layer_reflect_seq_num(struct tls12_record_layer *rl);
 void tls12_record_layer_read_cipher_hash(struct tls12_record_layer *rl,
     EVP_CIPHER_CTX **cipher, EVP_MD_CTX **hash);
 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);
+    CBS *mac_key, CBS *key, CBS *iv);
 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);
+    CBS *mac_key, CBS *key, CBS *iv);
 int tls12_record_layer_open_record(struct tls12_record_layer *rl,
     uint8_t *buf, size_t buf_len, uint8_t **out, size_t *out_len);
 int tls12_record_layer_seal_record(struct tls12_record_layer *rl,
@@ -1381,6 +1384,7 @@ void tls1_cleanup_key_block(SSL *s);
 int tls1_change_read_cipher_state(SSL *s);
 int tls1_change_write_cipher_state(SSL *s);
 int tls1_setup_key_block(SSL *s);
+int tls1_generate_key_block(SSL *s, uint8_t *key_block, size_t key_block_len);
 int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
     const char *label, size_t llen, const unsigned char *p, size_t plen,
     int use_context);
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index e3cdcc134b..5a626fb880 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: t1_enc.c,v 1.142 2021/05/02 17:46:58 jsing Exp $ */
+/* $OpenBSD: t1_enc.c,v 1.143 2021/05/05 10:05:27 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -147,9 +147,8 @@
 void
 tls1_cleanup_key_block(SSL *s)
 {
-	freezero(S3I(s)->hs.tls12.key_block, S3I(s)->hs.tls12.key_block_len);
+	tls12_key_block_free(S3I(s)->hs.tls12.key_block);
 	S3I(s)->hs.tls12.key_block = NULL;
-	S3I(s)->hs.tls12.key_block_len = 0;
 }
 
 /*
@@ -283,7 +282,7 @@ tls1_PRF(SSL *s, const unsigned char *secret, size_t secret_len,
 	return (1);
 }
 
-static int
+int
 tls1_generate_key_block(SSL *s, uint8_t *key_block, size_t key_block_len)
 {
 	return tls1_PRF(s,
@@ -297,62 +296,20 @@ tls1_generate_key_block(SSL *s, uint8_t *key_block, size_t key_block_len)
 static int
 tls1_change_cipher_state(SSL *s, int is_write)
 {
-	const unsigned char *client_write_mac_secret, *server_write_mac_secret;
-	const unsigned char *client_write_key, *server_write_key;
-	const unsigned char *client_write_iv, *server_write_iv;
-	const unsigned char *mac_secret, *key, *iv;
-	int mac_secret_size, key_len, iv_len;
-	unsigned char *key_block;
-	const EVP_CIPHER *cipher;
-	const EVP_AEAD *aead;
-
-	aead = tls12_record_layer_aead(s->internal->rl);
-	cipher = tls12_record_layer_cipher(s->internal->rl);
-
-	if (aead != NULL) {
-		key_len = EVP_AEAD_key_length(aead);
-		iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(S3I(s)->hs.cipher);
-	} else {
-		key_len = EVP_CIPHER_key_length(cipher);
-		iv_len = EVP_CIPHER_iv_length(cipher);
-	}
-
-	mac_secret_size = S3I(s)->hs.tls12.mac_secret_size;
-
-	key_block = S3I(s)->hs.tls12.key_block;
-	client_write_mac_secret = key_block;
-	key_block += mac_secret_size;
-	server_write_mac_secret = key_block;
-	key_block += mac_secret_size;
-	client_write_key = key_block;
-	key_block += key_len;
-	server_write_key = key_block;
-	key_block += key_len;
-	client_write_iv = key_block;
-	key_block += iv_len;
-	server_write_iv = key_block;
-	key_block += iv_len;
+	CBS mac_key, key, iv;
 
 	/* Use client write keys on client write and server read. */
 	if ((!s->server && is_write) || (s->server && !is_write)) {
-		mac_secret = client_write_mac_secret;
-		key = client_write_key;
-		iv = client_write_iv;
+		tls12_key_block_client_write(S3I(s)->hs.tls12.key_block,
+		    &mac_key, &key, &iv);
 	} else {
-		mac_secret = server_write_mac_secret;
-		key = server_write_key;
-		iv = server_write_iv;
-	}
-
-	if (key_block - S3I(s)->hs.tls12.key_block !=
-	    S3I(s)->hs.tls12.key_block_len) {
-		SSLerror(s, ERR_R_INTERNAL_ERROR);
-		goto err;
+		tls12_key_block_server_write(S3I(s)->hs.tls12.key_block,
+		    &mac_key, &key, &iv);
 	}
 
 	if (!is_write) {
 		if (!tls12_record_layer_change_read_cipher_state(s->internal->rl,
-		    mac_secret, mac_secret_size, key, key_len, iv, iv_len))
+		    &mac_key, &key, &iv))
 			goto err;
 		if (SSL_is_dtls(s))
 			dtls1_reset_read_seq_numbers(s);
@@ -360,7 +317,7 @@ tls1_change_cipher_state(SSL *s, int is_write)
 		    &s->enc_read_ctx, &s->read_hash);
 	} else {
 		if (!tls12_record_layer_change_write_cipher_state(s->internal->rl,
-		    mac_secret, mac_secret_size, key, key_len, iv, iv_len))
+		    &mac_key, &key, &iv))
 			goto err;
 		if (SSL_is_dtls(s))
 			dtls1_reset_write_seq_numbers(s);
@@ -386,17 +343,19 @@ tls1_change_write_cipher_state(SSL *s)
 int
 tls1_setup_key_block(SSL *s)
 {
-	unsigned char *key_block;
+	struct tls12_key_block *key_block;
 	int mac_type = NID_undef, mac_secret_size = 0;
-	size_t key_block_len;
-	int key_len, iv_len;
 	const EVP_CIPHER *cipher = NULL;
 	const EVP_AEAD *aead = NULL;
 	const EVP_MD *handshake_hash = NULL;
 	const EVP_MD *mac_hash = NULL;
 	int ret = 0;
 
-	if (S3I(s)->hs.tls12.key_block_len != 0)
+	/*
+	 * XXX - callers should be changed so that they only call this
+	 * function once.
+	 */
+	if (S3I(s)->hs.tls12.key_block != NULL)
 		return (1);
 
 	if (s->session->cipher &&
@@ -405,41 +364,29 @@ tls1_setup_key_block(SSL *s)
 			SSLerror(s, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
 			return (0);
 		}
-		key_len = EVP_AEAD_key_length(aead);
-		iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->session->cipher);
 	} else {
+		/* XXX - mac_type and mac_secret_size are now unused. */
 		if (!ssl_cipher_get_evp(s->session, &cipher, &mac_hash,
 		    &mac_type, &mac_secret_size)) {
 			SSLerror(s, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
 			return (0);
 		}
-		key_len = EVP_CIPHER_key_length(cipher);
-		iv_len = EVP_CIPHER_iv_length(cipher);
 	}
 
 	if (!ssl_get_handshake_evp_md(s, &handshake_hash))
 		return (0);
 
-	S3I(s)->hs.tls12.mac_secret_size = mac_secret_size;
-
 	tls12_record_layer_set_aead(s->internal->rl, aead);
 	tls12_record_layer_set_cipher_hash(s->internal->rl, cipher,
 	    handshake_hash, mac_hash);
 
-	tls1_cleanup_key_block(s);
-
-	if ((key_block = reallocarray(NULL, mac_secret_size + key_len + iv_len,
-	    2)) == NULL) {
-		SSLerror(s, ERR_R_MALLOC_FAILURE);
+	if ((key_block = tls12_key_block_new()) == NULL)
+		goto err;
+	if (!tls12_key_block_generate(key_block, s, aead, cipher, mac_hash))
 		goto err;
-	}
-	key_block_len = (mac_secret_size + key_len + iv_len) * 2;
 
-	S3I(s)->hs.tls12.key_block_len = key_block_len;
 	S3I(s)->hs.tls12.key_block = key_block;
-
-	if (!tls1_generate_key_block(s, key_block, key_block_len))
-		goto err;
+	key_block = NULL;
 
 	if (!(s->internal->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) &&
 	    s->method->internal->version <= TLS1_VERSION) {
@@ -463,6 +410,8 @@ tls1_setup_key_block(SSL *s)
 	ret = 1;
 
  err:
+	tls12_key_block_free(key_block);
+
 	return (ret);
 }
 
diff --git a/src/lib/libssl/tls12_key_schedule.c b/src/lib/libssl/tls12_key_schedule.c
new file mode 100644
index 0000000000..c206460d95
--- /dev/null
+++ b/src/lib/libssl/tls12_key_schedule.c
@@ -0,0 +1,175 @@
+/* $OpenBSD: tls12_key_schedule.c,v 1.1 2021/05/05 10:05:27 jsing Exp $ */
+/*
+ * Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+
+#include <openssl/evp.h>
+
+#include "bytestring.h"
+#include "ssl_locl.h"
+
+struct tls12_key_block {
+	CBS client_write_mac_key;
+	CBS server_write_mac_key;
+	CBS client_write_key;
+	CBS server_write_key;
+	CBS client_write_iv;
+	CBS server_write_iv;
+
+	uint8_t *key_block;
+	size_t key_block_len;
+};
+
+struct tls12_key_block *
+tls12_key_block_new(void)
+{
+	return calloc(1, sizeof(struct tls12_key_block));
+}
+
+static void
+tls12_key_block_clear(struct tls12_key_block *kb)
+{
+	CBS_init(&kb->client_write_mac_key, NULL, 0);
+	CBS_init(&kb->server_write_mac_key, NULL, 0);
+	CBS_init(&kb->client_write_key, NULL, 0);
+	CBS_init(&kb->server_write_key, NULL, 0);
+	CBS_init(&kb->client_write_iv, NULL, 0);
+	CBS_init(&kb->server_write_iv, NULL, 0);
+
+	freezero(kb->key_block, kb->key_block_len);
+	kb->key_block = NULL;
+	kb->key_block_len = 0;
+}
+
+void
+tls12_key_block_free(struct tls12_key_block *kb)
+{
+	if (kb == NULL)
+		return;
+
+	tls12_key_block_clear(kb);
+
+	freezero(kb, sizeof(struct tls12_key_block));
+}
+
+void
+tls12_key_block_client_write(struct tls12_key_block *kb, CBS *mac_key,
+    CBS *key, CBS *iv)
+{
+	CBS_dup(&kb->client_write_mac_key, mac_key);
+	CBS_dup(&kb->client_write_key, key);
+	CBS_dup(&kb->client_write_iv, iv);
+}
+
+void
+tls12_key_block_server_write(struct tls12_key_block *kb, CBS *mac_key,
+    CBS *key, CBS *iv)
+{
+	CBS_dup(&kb->server_write_mac_key, mac_key);
+	CBS_dup(&kb->server_write_key, key);
+	CBS_dup(&kb->server_write_iv, iv);
+}
+
+int
+tls12_key_block_generate(struct tls12_key_block *kb, SSL *s,
+    const EVP_AEAD *aead, const EVP_CIPHER *cipher, const EVP_MD *mac_hash)
+{
+	size_t mac_key_len = 0, key_len = 0, iv_len = 0;
+	uint8_t *key_block = NULL;
+	size_t key_block_len = 0;
+	CBS cbs;
+
+	/*
+	 * Generate a TLSv1.2 key block and partition into individual secrets,
+	 * as per RFC 5246 section 6.3.
+	 */
+
+	tls12_key_block_clear(kb);
+
+	/* Must have AEAD or cipher/MAC pair. */
+	if (aead == NULL && (cipher == NULL || mac_hash == NULL))
+		goto err;
+
+	if (aead != NULL) {
+		key_len = EVP_AEAD_key_length(aead);
+
+		/* AEAD fixed nonce length. */
+		if (aead == EVP_aead_aes_128_gcm() ||
+		    aead == EVP_aead_aes_256_gcm())
+			iv_len = 4;
+		else if (aead == EVP_aead_chacha20_poly1305())
+			iv_len = 12;
+		else
+			goto err;
+	} else if (cipher != NULL && mac_hash != NULL) {
+		/*
+		 * A negative integer return value will be detected via the
+		 * EVP_MAX_* checks against the size_t variables below.
+		 */
+		mac_key_len = EVP_MD_size(mac_hash);
+		key_len = EVP_CIPHER_key_length(cipher);
+		iv_len = EVP_CIPHER_iv_length(cipher);
+
+		/* Special handling for GOST... */
+		if (EVP_MD_type(mac_hash) == NID_id_Gost28147_89_MAC)
+			mac_key_len = 32;
+	}
+
+	if (mac_key_len > EVP_MAX_MD_SIZE)
+		goto err;
+	if (key_len > EVP_MAX_KEY_LENGTH)
+		goto err;
+	if (iv_len > EVP_MAX_IV_LENGTH)
+		goto err;
+
+	key_block_len = 2 * mac_key_len + 2 * key_len + 2 * iv_len;
+	if ((key_block = calloc(1, key_block_len)) == NULL)
+		goto err;
+
+	if (!tls1_generate_key_block(s, key_block, key_block_len))
+		goto err;
+
+	kb->key_block = key_block;
+	kb->key_block_len = key_block_len;
+	key_block = NULL;
+	key_block_len = 0;
+
+	/* Partition key block into individual secrets. */
+	CBS_init(&cbs, kb->key_block, kb->key_block_len);
+	if (!CBS_get_bytes(&cbs, &kb->client_write_mac_key, mac_key_len))
+		goto err;
+	if (!CBS_get_bytes(&cbs, &kb->server_write_mac_key, mac_key_len))
+		goto err;
+	if (!CBS_get_bytes(&cbs, &kb->client_write_key, key_len))
+		goto err;
+	if (!CBS_get_bytes(&cbs, &kb->server_write_key, key_len))
+		goto err;
+	if (!CBS_get_bytes(&cbs, &kb->client_write_iv, iv_len))
+		goto err;
+	if (!CBS_get_bytes(&cbs, &kb->server_write_iv, iv_len))
+		goto err;
+	if (CBS_len(&cbs) != 0)
+		goto err;
+
+	return 1;
+
+ err:
+	tls12_key_block_clear(kb);
+	freezero(key_block, key_block_len);
+
+	return 0;
+}
diff --git a/src/lib/libssl/tls12_record_layer.c b/src/lib/libssl/tls12_record_layer.c
index 7e29f4ed65..b9a3320de8 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.26 2021/04/19 17:26:39 jsing Exp $ */
+/* $OpenBSD: tls12_record_layer.c,v 1.27 2021/05/05 10:05:27 jsing Exp $ */
 /*
  * Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
  *
@@ -254,18 +254,6 @@ tls12_record_layer_write_protected(struct tls12_record_layer *rl)
 	return tls12_record_protection_engaged(rl->write);
 }
 
-const EVP_AEAD *
-tls12_record_layer_aead(struct tls12_record_layer *rl)
-{
-	return rl->aead;
-}
-
-const EVP_CIPHER *
-tls12_record_layer_cipher(struct tls12_record_layer *rl)
-{
-	return rl->cipher;
-}
-
 void
 tls12_record_layer_set_aead(struct tls12_record_layer *rl, const EVP_AEAD *aead)
 {
@@ -410,11 +398,10 @@ tls12_record_layer_set_mac_key(struct tls12_record_protection *rp,
 
 static int
 tls12_record_layer_ccs_aead(struct tls12_record_layer *rl,
-    struct tls12_record_protection *rp, int is_write, 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 *rp, int is_write, CBS *mac_key, CBS *key,
+    CBS *iv)
 {
-	size_t aead_nonce_len;
+	size_t aead_nonce_len, fixed_nonce_len;
 
 	if (!tls12_record_protection_unused(rp))
 		return 0;
@@ -431,11 +418,11 @@ tls12_record_layer_ccs_aead(struct tls12_record_layer *rl,
 	if (rl->aead == EVP_aead_chacha20_poly1305())
 		rp->aead_ctx->xor_fixed_nonce = 1;
 
-	if (iv_len > sizeof(rp->aead_ctx->fixed_nonce))
+	if (!CBS_write_bytes(iv, rp->aead_ctx->fixed_nonce,
+	    sizeof(rp->aead_ctx->fixed_nonce), &fixed_nonce_len))
 		return 0;
 
-	memcpy(rp->aead_ctx->fixed_nonce, iv, iv_len);
-	rp->aead_ctx->fixed_nonce_len = iv_len;
+	rp->aead_ctx->fixed_nonce_len = fixed_nonce_len;
 	rp->aead_ctx->tag_len = EVP_AEAD_max_overhead(rl->aead);
 	rp->aead_ctx->variable_nonce_len = 8;
 
@@ -454,8 +441,8 @@ tls12_record_layer_ccs_aead(struct tls12_record_layer *rl,
 			return 0;
 	}
 
-	if (!EVP_AEAD_CTX_init(&rp->aead_ctx->ctx, rl->aead, key, key_len,
-	    EVP_AEAD_DEFAULT_TAG_LENGTH, NULL))
+	if (!EVP_AEAD_CTX_init(&rp->aead_ctx->ctx, rl->aead, CBS_data(key),
+	    CBS_len(key), EVP_AEAD_DEFAULT_TAG_LENGTH, NULL))
 		return 0;
 
 	return 1;
@@ -463,9 +450,8 @@ tls12_record_layer_ccs_aead(struct tls12_record_layer *rl,
 
 static int
 tls12_record_layer_ccs_cipher(struct tls12_record_layer *rl,
-    struct tls12_record_protection *rp, int is_write, 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 *rp, int is_write, CBS *mac_key, CBS *key,
+    CBS *iv)
 {
 	EVP_PKEY *mac_pkey = NULL;
 	int gost_param_nid;
@@ -478,23 +464,23 @@ tls12_record_layer_ccs_cipher(struct tls12_record_layer *rl,
 	mac_type = EVP_PKEY_HMAC;
 	rp->stream_mac = 0;
 
-	if (iv_len > INT_MAX || key_len > INT_MAX)
+	if (CBS_len(iv) > INT_MAX || CBS_len(key) > INT_MAX)
 		goto err;
-	if (EVP_CIPHER_iv_length(rl->cipher) != iv_len)
+	if (EVP_CIPHER_iv_length(rl->cipher) != CBS_len(iv))
 		goto err;
-	if (EVP_CIPHER_key_length(rl->cipher) != key_len)
+	if (EVP_CIPHER_key_length(rl->cipher) != CBS_len(key))
 		goto err;
 
 	/* Special handling for GOST... */
 	if (EVP_MD_type(rl->mac_hash) == NID_id_Gost28147_89_MAC) {
-		if (mac_key_len != 32)
+		if (CBS_len(mac_key) != 32)
 			goto err;
 		mac_type = EVP_PKEY_GOSTIMIT;
 		rp->stream_mac = 1;
 	} else {
-		if (mac_key_len > INT_MAX)
+		if (CBS_len(mac_key) > INT_MAX)
 			goto err;
-		if (EVP_MD_size(rl->mac_hash) != mac_key_len)
+		if (EVP_MD_size(rl->mac_hash) != CBS_len(mac_key))
 			goto err;
 	}
 
@@ -503,15 +489,16 @@ tls12_record_layer_ccs_cipher(struct tls12_record_layer *rl,
 	if ((rp->hash_ctx = EVP_MD_CTX_new()) == NULL)
 		goto err;
 
-	if (!tls12_record_layer_set_mac_key(rp, mac_key, mac_key_len))
+	if (!tls12_record_layer_set_mac_key(rp, CBS_data(mac_key),
+	    CBS_len(mac_key)))
 		goto err;
 
-	if ((mac_pkey = EVP_PKEY_new_mac_key(mac_type, NULL, mac_key,
-	    mac_key_len)) == NULL)
+	if ((mac_pkey = EVP_PKEY_new_mac_key(mac_type, NULL, CBS_data(mac_key),
+	    CBS_len(mac_key))) == NULL)
 		goto err;
 
-	if (!EVP_CipherInit_ex(rp->cipher_ctx, rl->cipher, NULL, key, iv,
-	    is_write))
+	if (!EVP_CipherInit_ex(rp->cipher_ctx, rl->cipher, NULL, CBS_data(key),
+	    CBS_data(iv), is_write))
 		goto err;
 
 	if (EVP_DigestSignInit(rp->hash_ctx, NULL, rl->mac_hash, NULL,
@@ -545,22 +532,20 @@ tls12_record_layer_ccs_cipher(struct tls12_record_layer *rl,
 
 static int
 tls12_record_layer_change_cipher_state(struct tls12_record_layer *rl,
-    struct tls12_record_protection *rp, int is_write, 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 *rp, int is_write, CBS *mac_key, CBS *key,
+    CBS *iv)
 {
 	if (rl->aead != NULL)
 		return tls12_record_layer_ccs_aead(rl, rp, is_write, mac_key,
-		    mac_key_len, key, key_len, iv, iv_len);
+		    key, iv);
 
 	return tls12_record_layer_ccs_cipher(rl, rp, is_write, mac_key,
-	    mac_key_len, key, key_len, iv, iv_len);
+	    key, iv);
 }
 
 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)
+    CBS *mac_key, CBS *key, CBS *iv)
 {
 	struct tls12_record_protection *read_new = NULL;
 	int ret = 0;
@@ -571,7 +556,7 @@ tls12_record_layer_change_read_cipher_state(struct tls12_record_layer *rl,
 	/* Read sequence number gets reset to zero. */
 
 	if (!tls12_record_layer_change_cipher_state(rl, read_new, 0,
-	    mac_key, mac_key_len, key, key_len, iv, iv_len))
+	    mac_key, key, iv))
 		goto err;
 
 	tls12_record_protection_free(rl->read_current);
@@ -588,8 +573,7 @@ tls12_record_layer_change_read_cipher_state(struct tls12_record_layer *rl,
 
 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)
+    CBS *mac_key, CBS *key, CBS *iv)
 {
 	struct tls12_record_protection *write_new;
 	int ret = 0;
@@ -600,7 +584,7 @@ tls12_record_layer_change_write_cipher_state(struct tls12_record_layer *rl,
 	/* Write sequence number gets reset to zero. */
 
 	if (!tls12_record_layer_change_cipher_state(rl, write_new, 1,
-	    mac_key, mac_key_len, key, key_len, iv, iv_len))
+	    mac_key, key, iv))
 		goto err;
 
 	if (rl->dtls) {
-- 
cgit v1.2.3-55-g6feb