1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: tls13_key_schedule.c,v 1.15 2022/07/07 17:09:45 tb Exp $ */
2*de0e0e4dSAntonio Huete Jimenez /*
3*de0e0e4dSAntonio Huete Jimenez  * Copyright (c) 2018, Bob Beck <beck@openbsd.org>
472c33676SMaxim Ag  *
572c33676SMaxim Ag  * Permission to use, copy, modify, and/or distribute this software for any
672c33676SMaxim Ag  * purpose with or without fee is hereby granted, provided that the above
772c33676SMaxim Ag  * copyright notice and this permission notice appear in all copies.
872c33676SMaxim Ag  *
972c33676SMaxim Ag  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1072c33676SMaxim Ag  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1172c33676SMaxim Ag  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1272c33676SMaxim Ag  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1372c33676SMaxim Ag  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
1472c33676SMaxim Ag  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1572c33676SMaxim Ag  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1672c33676SMaxim Ag  */
1772c33676SMaxim Ag 
1872c33676SMaxim Ag #include <string.h>
1972c33676SMaxim Ag #include <stdlib.h>
2072c33676SMaxim Ag 
2172c33676SMaxim Ag #include <openssl/hkdf.h>
2272c33676SMaxim Ag 
2372c33676SMaxim Ag #include "bytestring.h"
2472c33676SMaxim Ag #include "tls13_internal.h"
2572c33676SMaxim Ag 
26*de0e0e4dSAntonio Huete Jimenez int
tls13_secret_init(struct tls13_secret * secret,size_t len)27*de0e0e4dSAntonio Huete Jimenez tls13_secret_init(struct tls13_secret *secret, size_t len)
2872c33676SMaxim Ag {
29*de0e0e4dSAntonio Huete Jimenez 	if (secret->data != NULL)
30*de0e0e4dSAntonio Huete Jimenez 		return 0;
3172c33676SMaxim Ag 
32*de0e0e4dSAntonio Huete Jimenez 	if ((secret->data = calloc(1, len)) == NULL)
33*de0e0e4dSAntonio Huete Jimenez 		return 0;
34*de0e0e4dSAntonio Huete Jimenez 	secret->len = len;
3572c33676SMaxim Ag 
36*de0e0e4dSAntonio Huete Jimenez 	return 1;
37*de0e0e4dSAntonio Huete Jimenez }
3872c33676SMaxim Ag 
39*de0e0e4dSAntonio Huete Jimenez void
tls13_secret_cleanup(struct tls13_secret * secret)40*de0e0e4dSAntonio Huete Jimenez tls13_secret_cleanup(struct tls13_secret *secret)
41*de0e0e4dSAntonio Huete Jimenez {
42*de0e0e4dSAntonio Huete Jimenez 	freezero(secret->data, secret->len);
43*de0e0e4dSAntonio Huete Jimenez 	secret->data = NULL;
44*de0e0e4dSAntonio Huete Jimenez 	secret->len = 0;
4572c33676SMaxim Ag }
4672c33676SMaxim Ag 
4772c33676SMaxim Ag /*
4872c33676SMaxim Ag  * Allocate a set of secrets for a key schedule using
4972c33676SMaxim Ag  * a size of hash_length from RFC 8446 section 7.1.
5072c33676SMaxim Ag  */
5172c33676SMaxim Ag struct tls13_secrets *
tls13_secrets_create(const EVP_MD * digest,int resumption)5272c33676SMaxim Ag tls13_secrets_create(const EVP_MD *digest, int resumption)
5372c33676SMaxim Ag {
5472c33676SMaxim Ag 	struct tls13_secrets *secrets = NULL;
5572c33676SMaxim Ag 	EVP_MD_CTX *mdctx = NULL;
5672c33676SMaxim Ag 	unsigned int mdlen;
5772c33676SMaxim Ag 	size_t hash_length;
5872c33676SMaxim Ag 
5972c33676SMaxim Ag 	hash_length = EVP_MD_size(digest);
6072c33676SMaxim Ag 
6172c33676SMaxim Ag 	if ((secrets = calloc(1, sizeof(struct tls13_secrets))) == NULL)
6272c33676SMaxim Ag 		goto err;
6372c33676SMaxim Ag 
64*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->zeros, hash_length))
6572c33676SMaxim Ag 		goto err;
66*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->empty_hash, hash_length))
67*de0e0e4dSAntonio Huete Jimenez 		goto err;
6872c33676SMaxim Ag 
69*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->extracted_early, hash_length))
7072c33676SMaxim Ag 		goto err;
71*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->binder_key, hash_length))
7272c33676SMaxim Ag 		goto err;
73*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->client_early_traffic, hash_length))
7472c33676SMaxim Ag 		goto err;
75*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->early_exporter_master, hash_length))
7672c33676SMaxim Ag 		goto err;
77*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->derived_early, hash_length))
7872c33676SMaxim Ag 		goto err;
79*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->extracted_handshake, hash_length))
8072c33676SMaxim Ag 		goto err;
81*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->client_handshake_traffic, hash_length))
8272c33676SMaxim Ag 		goto err;
83*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->server_handshake_traffic, hash_length))
8472c33676SMaxim Ag 		goto err;
85*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->derived_handshake, hash_length))
8672c33676SMaxim Ag 		goto err;
87*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->extracted_master, hash_length))
8872c33676SMaxim Ag 		goto err;
89*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->client_application_traffic, hash_length))
9072c33676SMaxim Ag 		goto err;
91*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->server_application_traffic, hash_length))
9272c33676SMaxim Ag 		goto err;
93*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->exporter_master, hash_length))
9472c33676SMaxim Ag 		goto err;
95*de0e0e4dSAntonio Huete Jimenez 	if (!tls13_secret_init(&secrets->resumption_master, hash_length))
9672c33676SMaxim Ag 		goto err;
9772c33676SMaxim Ag 
9872c33676SMaxim Ag 	/*
9972c33676SMaxim Ag 	 * Calculate the hash of a zero-length string - this is needed during
10072c33676SMaxim Ag 	 * the "derived" step for key extraction.
10172c33676SMaxim Ag 	 */
10272c33676SMaxim Ag 	if ((mdctx = EVP_MD_CTX_new()) == NULL)
10372c33676SMaxim Ag 		goto err;
10472c33676SMaxim Ag 	if (!EVP_DigestInit_ex(mdctx, digest, NULL))
10572c33676SMaxim Ag 		goto err;
10672c33676SMaxim Ag 	if (!EVP_DigestUpdate(mdctx, secrets->zeros.data, 0))
10772c33676SMaxim Ag 		goto err;
10872c33676SMaxim Ag 	if (!EVP_DigestFinal_ex(mdctx, secrets->empty_hash.data, &mdlen))
10972c33676SMaxim Ag 		goto err;
11072c33676SMaxim Ag 	EVP_MD_CTX_free(mdctx);
11172c33676SMaxim Ag 	mdctx = NULL;
11272c33676SMaxim Ag 
11372c33676SMaxim Ag 	if (secrets->empty_hash.len != mdlen)
11472c33676SMaxim Ag 		goto err;
11572c33676SMaxim Ag 
11672c33676SMaxim Ag 	secrets->digest = digest;
11772c33676SMaxim Ag 	secrets->resumption = resumption;
11872c33676SMaxim Ag 	secrets->init_done = 1;
11972c33676SMaxim Ag 
12072c33676SMaxim Ag 	return secrets;
12172c33676SMaxim Ag 
12272c33676SMaxim Ag  err:
12372c33676SMaxim Ag 	tls13_secrets_destroy(secrets);
12472c33676SMaxim Ag 	EVP_MD_CTX_free(mdctx);
12572c33676SMaxim Ag 
12672c33676SMaxim Ag 	return NULL;
12772c33676SMaxim Ag }
12872c33676SMaxim Ag 
129*de0e0e4dSAntonio Huete Jimenez void
tls13_secrets_destroy(struct tls13_secrets * secrets)130*de0e0e4dSAntonio Huete Jimenez tls13_secrets_destroy(struct tls13_secrets *secrets)
131*de0e0e4dSAntonio Huete Jimenez {
132*de0e0e4dSAntonio Huete Jimenez 	if (secrets == NULL)
133*de0e0e4dSAntonio Huete Jimenez 		return;
134*de0e0e4dSAntonio Huete Jimenez 
135*de0e0e4dSAntonio Huete Jimenez 	/* you can never be too sure :) */
136*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->zeros);
137*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->empty_hash);
138*de0e0e4dSAntonio Huete Jimenez 
139*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->extracted_early);
140*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->binder_key);
141*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->client_early_traffic);
142*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->early_exporter_master);
143*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->derived_early);
144*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->extracted_handshake);
145*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->client_handshake_traffic);
146*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->server_handshake_traffic);
147*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->derived_handshake);
148*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->extracted_master);
149*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->client_application_traffic);
150*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->server_application_traffic);
151*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->exporter_master);
152*de0e0e4dSAntonio Huete Jimenez 	tls13_secret_cleanup(&secrets->resumption_master);
153*de0e0e4dSAntonio Huete Jimenez 
154*de0e0e4dSAntonio Huete Jimenez 	freezero(secrets, sizeof(struct tls13_secrets));
155*de0e0e4dSAntonio Huete Jimenez }
156*de0e0e4dSAntonio Huete Jimenez 
15772c33676SMaxim Ag int
tls13_hkdf_expand_label(struct tls13_secret * out,const EVP_MD * digest,const struct tls13_secret * secret,const char * label,const struct tls13_secret * context)15872c33676SMaxim Ag tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
15972c33676SMaxim Ag     const struct tls13_secret *secret, const char *label,
16072c33676SMaxim Ag     const struct tls13_secret *context)
16172c33676SMaxim Ag {
1622eb7d3b8SDaniel Fojt 	return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
1632eb7d3b8SDaniel Fojt 	    strlen(label), context);
1642eb7d3b8SDaniel Fojt }
1652eb7d3b8SDaniel Fojt 
1662eb7d3b8SDaniel Fojt int
tls13_hkdf_expand_label_with_length(struct tls13_secret * out,const EVP_MD * digest,const struct tls13_secret * secret,const uint8_t * label,size_t label_len,const struct tls13_secret * context)1672eb7d3b8SDaniel Fojt tls13_hkdf_expand_label_with_length(struct tls13_secret *out,
1682eb7d3b8SDaniel Fojt     const EVP_MD *digest, const struct tls13_secret *secret,
1692eb7d3b8SDaniel Fojt     const uint8_t *label, size_t label_len, const struct tls13_secret *context)
1702eb7d3b8SDaniel Fojt {
17172c33676SMaxim Ag 	const char tls13_plabel[] = "tls13 ";
172*de0e0e4dSAntonio Huete Jimenez 	uint8_t *hkdf_label = NULL;
17372c33676SMaxim Ag 	size_t hkdf_label_len;
17472c33676SMaxim Ag 	CBB cbb, child;
17572c33676SMaxim Ag 	int ret;
17672c33676SMaxim Ag 
17772c33676SMaxim Ag 	if (!CBB_init(&cbb, 256))
17872c33676SMaxim Ag 		return 0;
17972c33676SMaxim Ag 	if (!CBB_add_u16(&cbb, out->len))
18072c33676SMaxim Ag 		goto err;
18172c33676SMaxim Ag 	if (!CBB_add_u8_length_prefixed(&cbb, &child))
18272c33676SMaxim Ag 		goto err;
18372c33676SMaxim Ag 	if (!CBB_add_bytes(&child, tls13_plabel, strlen(tls13_plabel)))
18472c33676SMaxim Ag 		goto err;
1852eb7d3b8SDaniel Fojt 	if (!CBB_add_bytes(&child, label, label_len))
18672c33676SMaxim Ag 		goto err;
18772c33676SMaxim Ag 	if (!CBB_add_u8_length_prefixed(&cbb, &child))
18872c33676SMaxim Ag 		goto err;
18972c33676SMaxim Ag 	if (!CBB_add_bytes(&child, context->data, context->len))
19072c33676SMaxim Ag 		goto err;
19172c33676SMaxim Ag 	if (!CBB_finish(&cbb, &hkdf_label, &hkdf_label_len))
19272c33676SMaxim Ag 		goto err;
19372c33676SMaxim Ag 
19472c33676SMaxim Ag 	ret = HKDF_expand(out->data, out->len, digest, secret->data,
19572c33676SMaxim Ag 	    secret->len, hkdf_label, hkdf_label_len);
19672c33676SMaxim Ag 
19772c33676SMaxim Ag 	free(hkdf_label);
19872c33676SMaxim Ag 	return(ret);
19972c33676SMaxim Ag  err:
20072c33676SMaxim Ag 	CBB_cleanup(&cbb);
20172c33676SMaxim Ag 	return(0);
20272c33676SMaxim Ag }
20372c33676SMaxim Ag 
2042eb7d3b8SDaniel Fojt int
tls13_derive_secret(struct tls13_secret * out,const EVP_MD * digest,const struct tls13_secret * secret,const char * label,const struct tls13_secret * context)20572c33676SMaxim Ag tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest,
20672c33676SMaxim Ag     const struct tls13_secret *secret, const char *label,
20772c33676SMaxim Ag     const struct tls13_secret *context)
20872c33676SMaxim Ag {
20972c33676SMaxim Ag 	return tls13_hkdf_expand_label(out, digest, secret, label, context);
21072c33676SMaxim Ag }
21172c33676SMaxim Ag 
21272c33676SMaxim Ag int
tls13_derive_secret_with_label_length(struct tls13_secret * out,const EVP_MD * digest,const struct tls13_secret * secret,const uint8_t * label,size_t label_len,const struct tls13_secret * context)2132eb7d3b8SDaniel Fojt tls13_derive_secret_with_label_length(struct tls13_secret *out,
2142eb7d3b8SDaniel Fojt     const EVP_MD *digest, const struct tls13_secret *secret, const uint8_t *label,
2152eb7d3b8SDaniel Fojt     size_t label_len, const struct tls13_secret *context)
2162eb7d3b8SDaniel Fojt {
2172eb7d3b8SDaniel Fojt 	return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
2182eb7d3b8SDaniel Fojt 	    label_len, context);
2192eb7d3b8SDaniel Fojt }
2202eb7d3b8SDaniel Fojt 
2212eb7d3b8SDaniel Fojt int
tls13_derive_early_secrets(struct tls13_secrets * secrets,uint8_t * psk,size_t psk_len,const struct tls13_secret * context)22272c33676SMaxim Ag tls13_derive_early_secrets(struct tls13_secrets *secrets,
22372c33676SMaxim Ag     uint8_t *psk, size_t psk_len, const struct tls13_secret *context)
22472c33676SMaxim Ag {
22572c33676SMaxim Ag 	if (!secrets->init_done || secrets->early_done)
22672c33676SMaxim Ag 		return 0;
22772c33676SMaxim Ag 
22872c33676SMaxim Ag 	if (!HKDF_extract(secrets->extracted_early.data,
22972c33676SMaxim Ag 	    &secrets->extracted_early.len, secrets->digest, psk, psk_len,
23072c33676SMaxim Ag 	    secrets->zeros.data, secrets->zeros.len))
23172c33676SMaxim Ag 		return 0;
23272c33676SMaxim Ag 
23372c33676SMaxim Ag 	if (secrets->extracted_early.len != secrets->zeros.len)
23472c33676SMaxim Ag 		return 0;
23572c33676SMaxim Ag 
23672c33676SMaxim Ag 	if (!tls13_derive_secret(&secrets->binder_key, secrets->digest,
23772c33676SMaxim Ag 	    &secrets->extracted_early,
23872c33676SMaxim Ag 	    secrets->resumption ? "res binder" : "ext binder",
23972c33676SMaxim Ag 	    &secrets->empty_hash))
24072c33676SMaxim Ag 		return 0;
24172c33676SMaxim Ag 	if (!tls13_derive_secret(&secrets->client_early_traffic,
24272c33676SMaxim Ag 	    secrets->digest, &secrets->extracted_early, "c e traffic",
24372c33676SMaxim Ag 	    context))
24472c33676SMaxim Ag 		return 0;
24572c33676SMaxim Ag 	if (!tls13_derive_secret(&secrets->early_exporter_master,
24672c33676SMaxim Ag 	    secrets->digest, &secrets->extracted_early, "e exp master",
24772c33676SMaxim Ag 	    context))
24872c33676SMaxim Ag 		return 0;
24972c33676SMaxim Ag 	if (!tls13_derive_secret(&secrets->derived_early,
25072c33676SMaxim Ag 	    secrets->digest, &secrets->extracted_early, "derived",
25172c33676SMaxim Ag 	    &secrets->empty_hash))
25272c33676SMaxim Ag 		return 0;
25372c33676SMaxim Ag 
25472c33676SMaxim Ag 	/* RFC 8446 recommends */
25572c33676SMaxim Ag 	if (!secrets->insecure)
25672c33676SMaxim Ag 		explicit_bzero(secrets->extracted_early.data,
25772c33676SMaxim Ag 		    secrets->extracted_early.len);
25872c33676SMaxim Ag 	secrets->early_done = 1;
25972c33676SMaxim Ag 	return 1;
26072c33676SMaxim Ag }
26172c33676SMaxim Ag 
26272c33676SMaxim Ag int
tls13_derive_handshake_secrets(struct tls13_secrets * secrets,const uint8_t * ecdhe,size_t ecdhe_len,const struct tls13_secret * context)26372c33676SMaxim Ag tls13_derive_handshake_secrets(struct tls13_secrets *secrets,
26472c33676SMaxim Ag     const uint8_t *ecdhe, size_t ecdhe_len,
26572c33676SMaxim Ag     const struct tls13_secret *context)
26672c33676SMaxim Ag {
26772c33676SMaxim Ag 	if (!secrets->init_done || !secrets->early_done ||
26872c33676SMaxim Ag 	    secrets->handshake_done)
26972c33676SMaxim Ag 		return 0;
27072c33676SMaxim Ag 
27172c33676SMaxim Ag 	if (!HKDF_extract(secrets->extracted_handshake.data,
27272c33676SMaxim Ag 	    &secrets->extracted_handshake.len, secrets->digest,
27372c33676SMaxim Ag 	    ecdhe, ecdhe_len, secrets->derived_early.data,
27472c33676SMaxim Ag 	    secrets->derived_early.len))
27572c33676SMaxim Ag 		return 0;
27672c33676SMaxim Ag 
27772c33676SMaxim Ag 	if (secrets->extracted_handshake.len != secrets->zeros.len)
27872c33676SMaxim Ag 		return 0;
27972c33676SMaxim Ag 
28072c33676SMaxim Ag 	/* XXX */
28172c33676SMaxim Ag 	if (!secrets->insecure)
28272c33676SMaxim Ag 		explicit_bzero(secrets->derived_early.data,
28372c33676SMaxim Ag 		    secrets->derived_early.len);
28472c33676SMaxim Ag 
28572c33676SMaxim Ag 	if (!tls13_derive_secret(&secrets->client_handshake_traffic,
28672c33676SMaxim Ag 	    secrets->digest, &secrets->extracted_handshake, "c hs traffic",
28772c33676SMaxim Ag 	    context))
28872c33676SMaxim Ag 		return 0;
28972c33676SMaxim Ag 	if (!tls13_derive_secret(&secrets->server_handshake_traffic,
29072c33676SMaxim Ag 	    secrets->digest, &secrets->extracted_handshake, "s hs traffic",
29172c33676SMaxim Ag 	    context))
29272c33676SMaxim Ag 		return 0;
29372c33676SMaxim Ag 	if (!tls13_derive_secret(&secrets->derived_handshake,
29472c33676SMaxim Ag 	    secrets->digest, &secrets->extracted_handshake, "derived",
29572c33676SMaxim Ag 	    &secrets->empty_hash))
29672c33676SMaxim Ag 		return 0;
29772c33676SMaxim Ag 
29872c33676SMaxim Ag 	/* RFC 8446 recommends */
29972c33676SMaxim Ag 	if (!secrets->insecure)
30072c33676SMaxim Ag 		explicit_bzero(secrets->extracted_handshake.data,
30172c33676SMaxim Ag 		    secrets->extracted_handshake.len);
30272c33676SMaxim Ag 
30372c33676SMaxim Ag 	secrets->handshake_done = 1;
30472c33676SMaxim Ag 
30572c33676SMaxim Ag 	return 1;
30672c33676SMaxim Ag }
30772c33676SMaxim Ag 
30872c33676SMaxim Ag int
tls13_derive_application_secrets(struct tls13_secrets * secrets,const struct tls13_secret * context)30972c33676SMaxim Ag tls13_derive_application_secrets(struct tls13_secrets *secrets,
31072c33676SMaxim Ag     const struct tls13_secret *context)
31172c33676SMaxim Ag {
31272c33676SMaxim Ag 	if (!secrets->init_done || !secrets->early_done ||
31372c33676SMaxim Ag 	    !secrets->handshake_done || secrets->schedule_done)
31472c33676SMaxim Ag 		return 0;
31572c33676SMaxim Ag 
31672c33676SMaxim Ag 	if (!HKDF_extract(secrets->extracted_master.data,
31772c33676SMaxim Ag 	    &secrets->extracted_master.len, secrets->digest,
31872c33676SMaxim Ag 	    secrets->zeros.data, secrets->zeros.len,
31972c33676SMaxim Ag 	    secrets->derived_handshake.data, secrets->derived_handshake.len))
32072c33676SMaxim Ag 		return 0;
32172c33676SMaxim Ag 
32272c33676SMaxim Ag 	if (secrets->extracted_master.len != secrets->zeros.len)
32372c33676SMaxim Ag 		return 0;
32472c33676SMaxim Ag 
32572c33676SMaxim Ag 	/* XXX */
32672c33676SMaxim Ag 	if (!secrets->insecure)
32772c33676SMaxim Ag 		explicit_bzero(secrets->derived_handshake.data,
32872c33676SMaxim Ag 		    secrets->derived_handshake.len);
32972c33676SMaxim Ag 
33072c33676SMaxim Ag 	if (!tls13_derive_secret(&secrets->client_application_traffic,
33172c33676SMaxim Ag 	    secrets->digest, &secrets->extracted_master, "c ap traffic",
33272c33676SMaxim Ag 	    context))
33372c33676SMaxim Ag 		return 0;
33472c33676SMaxim Ag 	if (!tls13_derive_secret(&secrets->server_application_traffic,
33572c33676SMaxim Ag 	    secrets->digest, &secrets->extracted_master, "s ap traffic",
33672c33676SMaxim Ag 	    context))
33772c33676SMaxim Ag 		return 0;
33872c33676SMaxim Ag 	if (!tls13_derive_secret(&secrets->exporter_master,
33972c33676SMaxim Ag 	    secrets->digest, &secrets->extracted_master, "exp master",
34072c33676SMaxim Ag 	    context))
34172c33676SMaxim Ag 		return 0;
34272c33676SMaxim Ag 	if (!tls13_derive_secret(&secrets->resumption_master,
34372c33676SMaxim Ag 	    secrets->digest, &secrets->extracted_master, "res master",
34472c33676SMaxim Ag 	    context))
34572c33676SMaxim Ag 		return 0;
34672c33676SMaxim Ag 
34772c33676SMaxim Ag 	/* RFC 8446 recommends */
34872c33676SMaxim Ag 	if (!secrets->insecure)
34972c33676SMaxim Ag 		explicit_bzero(secrets->extracted_master.data,
35072c33676SMaxim Ag 		    secrets->extracted_master.len);
35172c33676SMaxim Ag 
35272c33676SMaxim Ag 	secrets->schedule_done = 1;
35372c33676SMaxim Ag 
35472c33676SMaxim Ag 	return 1;
35572c33676SMaxim Ag }
35672c33676SMaxim Ag 
35772c33676SMaxim Ag int
tls13_update_client_traffic_secret(struct tls13_secrets * secrets)35872c33676SMaxim Ag tls13_update_client_traffic_secret(struct tls13_secrets *secrets)
35972c33676SMaxim Ag {
360cca6fc52SDaniel Fojt 	struct tls13_secret context = { .data = "", .len = 0 };
361cca6fc52SDaniel Fojt 
36272c33676SMaxim Ag 	if (!secrets->init_done || !secrets->early_done ||
36372c33676SMaxim Ag 	    !secrets->handshake_done || !secrets->schedule_done)
36472c33676SMaxim Ag 		return 0;
36572c33676SMaxim Ag 
36672c33676SMaxim Ag 	return tls13_hkdf_expand_label(&secrets->client_application_traffic,
36772c33676SMaxim Ag 	    secrets->digest, &secrets->client_application_traffic,
368cca6fc52SDaniel Fojt 	    "traffic upd", &context);
36972c33676SMaxim Ag }
37072c33676SMaxim Ag 
37172c33676SMaxim Ag int
tls13_update_server_traffic_secret(struct tls13_secrets * secrets)37272c33676SMaxim Ag tls13_update_server_traffic_secret(struct tls13_secrets *secrets)
37372c33676SMaxim Ag {
374cca6fc52SDaniel Fojt 	struct tls13_secret context = { .data = "", .len = 0 };
375cca6fc52SDaniel Fojt 
37672c33676SMaxim Ag 	if (!secrets->init_done || !secrets->early_done ||
37772c33676SMaxim Ag 	    !secrets->handshake_done || !secrets->schedule_done)
37872c33676SMaxim Ag 		return 0;
37972c33676SMaxim Ag 
38072c33676SMaxim Ag 	return tls13_hkdf_expand_label(&secrets->server_application_traffic,
38172c33676SMaxim Ag 	    secrets->digest, &secrets->server_application_traffic,
382cca6fc52SDaniel Fojt 	    "traffic upd", &context);
38372c33676SMaxim Ag }
384