1*c9675a23Stb /* $OpenBSD: tls13_key_schedule.c,v 1.18 2022/11/26 16:08:56 tb Exp $ */
2c1e21c9eStb /*
3c1e21c9eStb * Copyright (c) 2018, Bob Beck <beck@openbsd.org>
4af2a35e9Sbeck *
5af2a35e9Sbeck * Permission to use, copy, modify, and/or distribute this software for any
6af2a35e9Sbeck * purpose with or without fee is hereby granted, provided that the above
7af2a35e9Sbeck * copyright notice and this permission notice appear in all copies.
8af2a35e9Sbeck *
9af2a35e9Sbeck * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10af2a35e9Sbeck * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11af2a35e9Sbeck * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12af2a35e9Sbeck * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13af2a35e9Sbeck * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14af2a35e9Sbeck * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15af2a35e9Sbeck * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16af2a35e9Sbeck */
17af2a35e9Sbeck
18af2a35e9Sbeck #include <string.h>
19af2a35e9Sbeck #include <stdlib.h>
20af2a35e9Sbeck
21af2a35e9Sbeck #include <openssl/hkdf.h>
22af2a35e9Sbeck
23af2a35e9Sbeck #include "bytestring.h"
24*c9675a23Stb #include "ssl_local.h"
25af2a35e9Sbeck #include "tls13_internal.h"
26af2a35e9Sbeck
27631a1dd7Stb int
tls13_secret_init(struct tls13_secret * secret,size_t len)28631a1dd7Stb tls13_secret_init(struct tls13_secret *secret, size_t len)
29631a1dd7Stb {
30631a1dd7Stb if (secret->data != NULL)
31631a1dd7Stb return 0;
32631a1dd7Stb
33ef22f324Stb if ((secret->data = calloc(1, len)) == NULL)
34631a1dd7Stb return 0;
35631a1dd7Stb secret->len = len;
36631a1dd7Stb
37631a1dd7Stb return 1;
38631a1dd7Stb }
39631a1dd7Stb
40631a1dd7Stb void
tls13_secret_cleanup(struct tls13_secret * secret)41631a1dd7Stb tls13_secret_cleanup(struct tls13_secret *secret)
42631a1dd7Stb {
43631a1dd7Stb freezero(secret->data, secret->len);
44631a1dd7Stb secret->data = NULL;
45631a1dd7Stb secret->len = 0;
46631a1dd7Stb }
47631a1dd7Stb
48af2a35e9Sbeck /*
49af2a35e9Sbeck * Allocate a set of secrets for a key schedule using
50b928de21Sjsing * a size of hash_length from RFC 8446 section 7.1.
51af2a35e9Sbeck */
52af2a35e9Sbeck struct tls13_secrets *
tls13_secrets_create(const EVP_MD * digest,int resumption)53b928de21Sjsing tls13_secrets_create(const EVP_MD *digest, int resumption)
54af2a35e9Sbeck {
55af2a35e9Sbeck struct tls13_secrets *secrets = NULL;
56b928de21Sjsing EVP_MD_CTX *mdctx = NULL;
57b928de21Sjsing unsigned int mdlen;
58b928de21Sjsing size_t hash_length;
59b928de21Sjsing
60b928de21Sjsing hash_length = EVP_MD_size(digest);
61af2a35e9Sbeck
62af2a35e9Sbeck if ((secrets = calloc(1, sizeof(struct tls13_secrets))) == NULL)
63af2a35e9Sbeck goto err;
644717c1a8Sjsing
65dca96ec3Stb if (!tls13_secret_init(&secrets->zeros, hash_length))
66af2a35e9Sbeck goto err;
67dca96ec3Stb if (!tls13_secret_init(&secrets->empty_hash, hash_length))
68dca96ec3Stb goto err;
69af2a35e9Sbeck
70dca96ec3Stb if (!tls13_secret_init(&secrets->extracted_early, hash_length))
71b928de21Sjsing goto err;
72dca96ec3Stb if (!tls13_secret_init(&secrets->binder_key, hash_length))
73af2a35e9Sbeck goto err;
74dca96ec3Stb if (!tls13_secret_init(&secrets->client_early_traffic, hash_length))
75af2a35e9Sbeck goto err;
76dca96ec3Stb if (!tls13_secret_init(&secrets->early_exporter_master, hash_length))
77af2a35e9Sbeck goto err;
78dca96ec3Stb if (!tls13_secret_init(&secrets->derived_early, hash_length))
79af2a35e9Sbeck goto err;
80dca96ec3Stb if (!tls13_secret_init(&secrets->extracted_handshake, hash_length))
81af2a35e9Sbeck goto err;
82dca96ec3Stb if (!tls13_secret_init(&secrets->client_handshake_traffic, hash_length))
83af2a35e9Sbeck goto err;
84dca96ec3Stb if (!tls13_secret_init(&secrets->server_handshake_traffic, hash_length))
85af2a35e9Sbeck goto err;
86dca96ec3Stb if (!tls13_secret_init(&secrets->derived_handshake, hash_length))
87af2a35e9Sbeck goto err;
88dca96ec3Stb if (!tls13_secret_init(&secrets->extracted_master, hash_length))
89af2a35e9Sbeck goto err;
90dca96ec3Stb if (!tls13_secret_init(&secrets->client_application_traffic, hash_length))
91af2a35e9Sbeck goto err;
92dca96ec3Stb if (!tls13_secret_init(&secrets->server_application_traffic, hash_length))
93af2a35e9Sbeck goto err;
94dca96ec3Stb if (!tls13_secret_init(&secrets->exporter_master, hash_length))
95af2a35e9Sbeck goto err;
96dca96ec3Stb if (!tls13_secret_init(&secrets->resumption_master, hash_length))
97af2a35e9Sbeck goto err;
98af2a35e9Sbeck
99b928de21Sjsing /*
100b928de21Sjsing * Calculate the hash of a zero-length string - this is needed during
101b928de21Sjsing * the "derived" step for key extraction.
102b928de21Sjsing */
103b928de21Sjsing if ((mdctx = EVP_MD_CTX_new()) == NULL)
104b928de21Sjsing goto err;
105b928de21Sjsing if (!EVP_DigestInit_ex(mdctx, digest, NULL))
106b928de21Sjsing goto err;
107b928de21Sjsing if (!EVP_DigestUpdate(mdctx, secrets->zeros.data, 0))
108b928de21Sjsing goto err;
109b928de21Sjsing if (!EVP_DigestFinal_ex(mdctx, secrets->empty_hash.data, &mdlen))
110b928de21Sjsing goto err;
111b928de21Sjsing EVP_MD_CTX_free(mdctx);
1121200a20aSbeck mdctx = NULL;
113b928de21Sjsing
114b928de21Sjsing if (secrets->empty_hash.len != mdlen)
115b928de21Sjsing goto err;
116b928de21Sjsing
117b928de21Sjsing secrets->digest = digest;
118b928de21Sjsing secrets->resumption = resumption;
119b928de21Sjsing secrets->init_done = 1;
120b928de21Sjsing
121af2a35e9Sbeck return secrets;
122b928de21Sjsing
123af2a35e9Sbeck err:
124af2a35e9Sbeck tls13_secrets_destroy(secrets);
125b928de21Sjsing EVP_MD_CTX_free(mdctx);
126b928de21Sjsing
127af2a35e9Sbeck return NULL;
128af2a35e9Sbeck }
129af2a35e9Sbeck
130e679198cStb void
tls13_secrets_destroy(struct tls13_secrets * secrets)131e679198cStb tls13_secrets_destroy(struct tls13_secrets *secrets)
132e679198cStb {
133e679198cStb if (secrets == NULL)
134e679198cStb return;
135e679198cStb
136e679198cStb /* you can never be too sure :) */
137e679198cStb tls13_secret_cleanup(&secrets->zeros);
138e679198cStb tls13_secret_cleanup(&secrets->empty_hash);
139e679198cStb
140e679198cStb tls13_secret_cleanup(&secrets->extracted_early);
141e679198cStb tls13_secret_cleanup(&secrets->binder_key);
142e679198cStb tls13_secret_cleanup(&secrets->client_early_traffic);
143e679198cStb tls13_secret_cleanup(&secrets->early_exporter_master);
144e679198cStb tls13_secret_cleanup(&secrets->derived_early);
145e679198cStb tls13_secret_cleanup(&secrets->extracted_handshake);
146e679198cStb tls13_secret_cleanup(&secrets->client_handshake_traffic);
147e679198cStb tls13_secret_cleanup(&secrets->server_handshake_traffic);
148e679198cStb tls13_secret_cleanup(&secrets->derived_handshake);
149e679198cStb tls13_secret_cleanup(&secrets->extracted_master);
150e679198cStb tls13_secret_cleanup(&secrets->client_application_traffic);
151e679198cStb tls13_secret_cleanup(&secrets->server_application_traffic);
152e679198cStb tls13_secret_cleanup(&secrets->exporter_master);
153e679198cStb tls13_secret_cleanup(&secrets->resumption_master);
154e679198cStb
155e679198cStb freezero(secrets, sizeof(struct tls13_secrets));
156e679198cStb }
157e679198cStb
158b928de21Sjsing 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)159af2a35e9Sbeck tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
160af2a35e9Sbeck const struct tls13_secret *secret, const char *label,
161af2a35e9Sbeck const struct tls13_secret *context)
162af2a35e9Sbeck {
163607bf314Sjsing return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
164607bf314Sjsing strlen(label), context);
165607bf314Sjsing }
166607bf314Sjsing
167607bf314Sjsing 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)168607bf314Sjsing tls13_hkdf_expand_label_with_length(struct tls13_secret *out,
169607bf314Sjsing const EVP_MD *digest, const struct tls13_secret *secret,
170607bf314Sjsing const uint8_t *label, size_t label_len, const struct tls13_secret *context)
171607bf314Sjsing {
172af2a35e9Sbeck const char tls13_plabel[] = "tls13 ";
1735d392958Stb uint8_t *hkdf_label = NULL;
174af2a35e9Sbeck size_t hkdf_label_len;
175af2a35e9Sbeck CBB cbb, child;
176af2a35e9Sbeck int ret;
177af2a35e9Sbeck
178af2a35e9Sbeck if (!CBB_init(&cbb, 256))
17921af0d4aStb goto err;
18021af0d4aStb
18121af0d4aStb if (out->data == NULL || out->len == 0)
18221af0d4aStb goto err;
18321af0d4aStb
184af2a35e9Sbeck if (!CBB_add_u16(&cbb, out->len))
185af2a35e9Sbeck goto err;
186af2a35e9Sbeck if (!CBB_add_u8_length_prefixed(&cbb, &child))
187af2a35e9Sbeck goto err;
188af2a35e9Sbeck if (!CBB_add_bytes(&child, tls13_plabel, strlen(tls13_plabel)))
189af2a35e9Sbeck goto err;
190607bf314Sjsing if (!CBB_add_bytes(&child, label, label_len))
191af2a35e9Sbeck goto err;
192af2a35e9Sbeck if (!CBB_add_u8_length_prefixed(&cbb, &child))
193af2a35e9Sbeck goto err;
194af2a35e9Sbeck if (!CBB_add_bytes(&child, context->data, context->len))
195af2a35e9Sbeck goto err;
196af2a35e9Sbeck if (!CBB_finish(&cbb, &hkdf_label, &hkdf_label_len))
197af2a35e9Sbeck goto err;
198af2a35e9Sbeck
199af2a35e9Sbeck ret = HKDF_expand(out->data, out->len, digest, secret->data,
200af2a35e9Sbeck secret->len, hkdf_label, hkdf_label_len);
201b928de21Sjsing
202af2a35e9Sbeck free(hkdf_label);
203af2a35e9Sbeck return(ret);
204af2a35e9Sbeck err:
205af2a35e9Sbeck CBB_cleanup(&cbb);
206af2a35e9Sbeck return(0);
207af2a35e9Sbeck }
208af2a35e9Sbeck
209607bf314Sjsing 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)210af2a35e9Sbeck tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest,
211af2a35e9Sbeck const struct tls13_secret *secret, const char *label,
212af2a35e9Sbeck const struct tls13_secret *context)
213af2a35e9Sbeck {
214af2a35e9Sbeck return tls13_hkdf_expand_label(out, digest, secret, label, context);
215af2a35e9Sbeck }
216af2a35e9Sbeck
217af2a35e9Sbeck 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)218607bf314Sjsing tls13_derive_secret_with_label_length(struct tls13_secret *out,
219607bf314Sjsing const EVP_MD *digest, const struct tls13_secret *secret, const uint8_t *label,
220607bf314Sjsing size_t label_len, const struct tls13_secret *context)
221607bf314Sjsing {
222607bf314Sjsing return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
223607bf314Sjsing label_len, context);
224607bf314Sjsing }
225607bf314Sjsing
226607bf314Sjsing int
tls13_derive_early_secrets(struct tls13_secrets * secrets,uint8_t * psk,size_t psk_len,const struct tls13_secret * context)227b928de21Sjsing tls13_derive_early_secrets(struct tls13_secrets *secrets,
228af2a35e9Sbeck uint8_t *psk, size_t psk_len, const struct tls13_secret *context)
229af2a35e9Sbeck {
230af2a35e9Sbeck if (!secrets->init_done || secrets->early_done)
231af2a35e9Sbeck return 0;
232af2a35e9Sbeck
233af2a35e9Sbeck if (!HKDF_extract(secrets->extracted_early.data,
234b928de21Sjsing &secrets->extracted_early.len, secrets->digest, psk, psk_len,
235af2a35e9Sbeck secrets->zeros.data, secrets->zeros.len))
236af2a35e9Sbeck return 0;
237af2a35e9Sbeck
238af2a35e9Sbeck if (secrets->extracted_early.len != secrets->zeros.len)
239af2a35e9Sbeck return 0;
240af2a35e9Sbeck
241b928de21Sjsing if (!tls13_derive_secret(&secrets->binder_key, secrets->digest,
242b928de21Sjsing &secrets->extracted_early,
243af2a35e9Sbeck secrets->resumption ? "res binder" : "ext binder",
2442e60af7eSbeck &secrets->empty_hash))
245af2a35e9Sbeck return 0;
246af2a35e9Sbeck if (!tls13_derive_secret(&secrets->client_early_traffic,
247b928de21Sjsing secrets->digest, &secrets->extracted_early, "c e traffic",
248b928de21Sjsing context))
249af2a35e9Sbeck return 0;
250af2a35e9Sbeck if (!tls13_derive_secret(&secrets->early_exporter_master,
251b928de21Sjsing secrets->digest, &secrets->extracted_early, "e exp master",
252b928de21Sjsing context))
253af2a35e9Sbeck return 0;
254af2a35e9Sbeck if (!tls13_derive_secret(&secrets->derived_early,
255b928de21Sjsing secrets->digest, &secrets->extracted_early, "derived",
256b928de21Sjsing &secrets->empty_hash))
257af2a35e9Sbeck return 0;
258af2a35e9Sbeck
259af2a35e9Sbeck /* RFC 8446 recommends */
260af2a35e9Sbeck if (!secrets->insecure)
261af2a35e9Sbeck explicit_bzero(secrets->extracted_early.data,
262af2a35e9Sbeck secrets->extracted_early.len);
263af2a35e9Sbeck secrets->early_done = 1;
264af2a35e9Sbeck return 1;
265af2a35e9Sbeck }
266af2a35e9Sbeck
267af2a35e9Sbeck int
tls13_derive_handshake_secrets(struct tls13_secrets * secrets,const uint8_t * ecdhe,size_t ecdhe_len,const struct tls13_secret * context)268af2a35e9Sbeck tls13_derive_handshake_secrets(struct tls13_secrets *secrets,
269b928de21Sjsing const uint8_t *ecdhe, size_t ecdhe_len,
270af2a35e9Sbeck const struct tls13_secret *context)
271af2a35e9Sbeck {
272af2a35e9Sbeck if (!secrets->init_done || !secrets->early_done ||
273af2a35e9Sbeck secrets->handshake_done)
274af2a35e9Sbeck return 0;
275af2a35e9Sbeck
276af2a35e9Sbeck if (!HKDF_extract(secrets->extracted_handshake.data,
277b928de21Sjsing &secrets->extracted_handshake.len, secrets->digest,
278b928de21Sjsing ecdhe, ecdhe_len, secrets->derived_early.data,
279af2a35e9Sbeck secrets->derived_early.len))
280af2a35e9Sbeck return 0;
281af2a35e9Sbeck
282af2a35e9Sbeck if (secrets->extracted_handshake.len != secrets->zeros.len)
283af2a35e9Sbeck return 0;
284af2a35e9Sbeck
285af2a35e9Sbeck /* XXX */
286af2a35e9Sbeck if (!secrets->insecure)
287af2a35e9Sbeck explicit_bzero(secrets->derived_early.data,
288af2a35e9Sbeck secrets->derived_early.len);
289af2a35e9Sbeck
290af2a35e9Sbeck if (!tls13_derive_secret(&secrets->client_handshake_traffic,
291b928de21Sjsing secrets->digest, &secrets->extracted_handshake, "c hs traffic",
292b928de21Sjsing context))
293af2a35e9Sbeck return 0;
294af2a35e9Sbeck if (!tls13_derive_secret(&secrets->server_handshake_traffic,
295b928de21Sjsing secrets->digest, &secrets->extracted_handshake, "s hs traffic",
296b928de21Sjsing context))
297af2a35e9Sbeck return 0;
298af2a35e9Sbeck if (!tls13_derive_secret(&secrets->derived_handshake,
299b928de21Sjsing secrets->digest, &secrets->extracted_handshake, "derived",
3002e60af7eSbeck &secrets->empty_hash))
301af2a35e9Sbeck return 0;
302af2a35e9Sbeck
303af2a35e9Sbeck /* RFC 8446 recommends */
304af2a35e9Sbeck if (!secrets->insecure)
305af2a35e9Sbeck explicit_bzero(secrets->extracted_handshake.data,
306af2a35e9Sbeck secrets->extracted_handshake.len);
307b928de21Sjsing
308af2a35e9Sbeck secrets->handshake_done = 1;
309b928de21Sjsing
310af2a35e9Sbeck return 1;
311af2a35e9Sbeck }
312af2a35e9Sbeck
313af2a35e9Sbeck int
tls13_derive_application_secrets(struct tls13_secrets * secrets,const struct tls13_secret * context)314af2a35e9Sbeck tls13_derive_application_secrets(struct tls13_secrets *secrets,
315b928de21Sjsing const struct tls13_secret *context)
316af2a35e9Sbeck {
317af2a35e9Sbeck if (!secrets->init_done || !secrets->early_done ||
318af2a35e9Sbeck !secrets->handshake_done || secrets->schedule_done)
319af2a35e9Sbeck return 0;
320af2a35e9Sbeck
321af2a35e9Sbeck if (!HKDF_extract(secrets->extracted_master.data,
322b928de21Sjsing &secrets->extracted_master.len, secrets->digest,
323b928de21Sjsing secrets->zeros.data, secrets->zeros.len,
324b928de21Sjsing secrets->derived_handshake.data, secrets->derived_handshake.len))
325af2a35e9Sbeck return 0;
326af2a35e9Sbeck
327af2a35e9Sbeck if (secrets->extracted_master.len != secrets->zeros.len)
328af2a35e9Sbeck return 0;
329af2a35e9Sbeck
330af2a35e9Sbeck /* XXX */
331af2a35e9Sbeck if (!secrets->insecure)
332af2a35e9Sbeck explicit_bzero(secrets->derived_handshake.data,
333af2a35e9Sbeck secrets->derived_handshake.len);
334af2a35e9Sbeck
335af2a35e9Sbeck if (!tls13_derive_secret(&secrets->client_application_traffic,
336b928de21Sjsing secrets->digest, &secrets->extracted_master, "c ap traffic",
337b928de21Sjsing context))
338af2a35e9Sbeck return 0;
339af2a35e9Sbeck if (!tls13_derive_secret(&secrets->server_application_traffic,
340b928de21Sjsing secrets->digest, &secrets->extracted_master, "s ap traffic",
341b928de21Sjsing context))
342af2a35e9Sbeck return 0;
343af2a35e9Sbeck if (!tls13_derive_secret(&secrets->exporter_master,
344b928de21Sjsing secrets->digest, &secrets->extracted_master, "exp master",
345b928de21Sjsing context))
346af2a35e9Sbeck return 0;
347af2a35e9Sbeck if (!tls13_derive_secret(&secrets->resumption_master,
348b928de21Sjsing secrets->digest, &secrets->extracted_master, "res master",
349b928de21Sjsing context))
350af2a35e9Sbeck return 0;
351af2a35e9Sbeck
352af2a35e9Sbeck /* RFC 8446 recommends */
353af2a35e9Sbeck if (!secrets->insecure)
354af2a35e9Sbeck explicit_bzero(secrets->extracted_master.data,
355af2a35e9Sbeck secrets->extracted_master.len);
356b928de21Sjsing
357af2a35e9Sbeck secrets->schedule_done = 1;
358b928de21Sjsing
359af2a35e9Sbeck return 1;
360af2a35e9Sbeck }
361af2a35e9Sbeck
362af2a35e9Sbeck int
tls13_update_client_traffic_secret(struct tls13_secrets * secrets)363b928de21Sjsing tls13_update_client_traffic_secret(struct tls13_secrets *secrets)
364af2a35e9Sbeck {
3654022b873Sbeck struct tls13_secret context = { .data = "", .len = 0 };
3664022b873Sbeck
367af2a35e9Sbeck if (!secrets->init_done || !secrets->early_done ||
368af2a35e9Sbeck !secrets->handshake_done || !secrets->schedule_done)
369af2a35e9Sbeck return 0;
370af2a35e9Sbeck
371af2a35e9Sbeck return tls13_hkdf_expand_label(&secrets->client_application_traffic,
372b928de21Sjsing secrets->digest, &secrets->client_application_traffic,
3734022b873Sbeck "traffic upd", &context);
374af2a35e9Sbeck }
375af2a35e9Sbeck
376af2a35e9Sbeck int
tls13_update_server_traffic_secret(struct tls13_secrets * secrets)377b928de21Sjsing tls13_update_server_traffic_secret(struct tls13_secrets *secrets)
378af2a35e9Sbeck {
3794022b873Sbeck struct tls13_secret context = { .data = "", .len = 0 };
3804022b873Sbeck
381af2a35e9Sbeck if (!secrets->init_done || !secrets->early_done ||
382af2a35e9Sbeck !secrets->handshake_done || !secrets->schedule_done)
383af2a35e9Sbeck return 0;
384af2a35e9Sbeck
385af2a35e9Sbeck return tls13_hkdf_expand_label(&secrets->server_application_traffic,
386b928de21Sjsing secrets->digest, &secrets->server_application_traffic,
3874022b873Sbeck "traffic upd", &context);
388af2a35e9Sbeck }
3898bde4343Sjsing
3908bde4343Sjsing int
tls13_exporter(struct tls13_ctx * ctx,const uint8_t * label,size_t label_len,const uint8_t * context_value,size_t context_value_len,uint8_t * out,size_t out_len)3918bde4343Sjsing tls13_exporter(struct tls13_ctx *ctx, const uint8_t *label, size_t label_len,
3928bde4343Sjsing const uint8_t *context_value, size_t context_value_len, uint8_t *out,
3938bde4343Sjsing size_t out_len)
3948bde4343Sjsing {
3958bde4343Sjsing struct tls13_secret context, export_out, export_secret;
3968bde4343Sjsing struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
3978bde4343Sjsing EVP_MD_CTX *md_ctx = NULL;
3988bde4343Sjsing unsigned int md_out_len;
3998bde4343Sjsing int md_len;
4008bde4343Sjsing int ret = 0;
4018bde4343Sjsing
4028bde4343Sjsing /*
4038bde4343Sjsing * RFC 8446 Section 7.5.
4048bde4343Sjsing */
4058bde4343Sjsing
4068bde4343Sjsing memset(&context, 0, sizeof(context));
4078bde4343Sjsing memset(&export_secret, 0, sizeof(export_secret));
4088bde4343Sjsing
4098bde4343Sjsing export_out.data = out;
4108bde4343Sjsing export_out.len = out_len;
4118bde4343Sjsing
4128bde4343Sjsing if (!ctx->handshake_completed)
4138bde4343Sjsing return 0;
4148bde4343Sjsing
4158bde4343Sjsing md_len = EVP_MD_size(secrets->digest);
4168bde4343Sjsing if (md_len <= 0 || md_len > EVP_MAX_MD_SIZE)
4178bde4343Sjsing goto err;
4188bde4343Sjsing
4198bde4343Sjsing if (!tls13_secret_init(&export_secret, md_len))
4208bde4343Sjsing goto err;
4218bde4343Sjsing if (!tls13_secret_init(&context, md_len))
4228bde4343Sjsing goto err;
4238bde4343Sjsing
4248bde4343Sjsing /* In TLSv1.3 no context is equivalent to an empty context. */
4258bde4343Sjsing if (context_value == NULL) {
4268bde4343Sjsing context_value = "";
4278bde4343Sjsing context_value_len = 0;
4288bde4343Sjsing }
4298bde4343Sjsing
4308bde4343Sjsing if ((md_ctx = EVP_MD_CTX_new()) == NULL)
4318bde4343Sjsing goto err;
4328bde4343Sjsing if (!EVP_DigestInit_ex(md_ctx, secrets->digest, NULL))
4338bde4343Sjsing goto err;
4348bde4343Sjsing if (!EVP_DigestUpdate(md_ctx, context_value, context_value_len))
4358bde4343Sjsing goto err;
4368bde4343Sjsing if (!EVP_DigestFinal_ex(md_ctx, context.data, &md_out_len))
4378bde4343Sjsing goto err;
4388bde4343Sjsing if (md_len != md_out_len)
4398bde4343Sjsing goto err;
4408bde4343Sjsing
4418bde4343Sjsing if (!tls13_derive_secret_with_label_length(&export_secret,
4428bde4343Sjsing secrets->digest, &secrets->exporter_master, label, label_len,
4438bde4343Sjsing &secrets->empty_hash))
4448bde4343Sjsing goto err;
4458bde4343Sjsing
4468bde4343Sjsing if (!tls13_hkdf_expand_label(&export_out, secrets->digest,
4478bde4343Sjsing &export_secret, "exporter", &context))
4488bde4343Sjsing goto err;
4498bde4343Sjsing
4508bde4343Sjsing ret = 1;
4518bde4343Sjsing
4528bde4343Sjsing err:
4538bde4343Sjsing EVP_MD_CTX_free(md_ctx);
4548bde4343Sjsing tls13_secret_cleanup(&context);
4558bde4343Sjsing tls13_secret_cleanup(&export_secret);
4568bde4343Sjsing
4578bde4343Sjsing return ret;
4588bde4343Sjsing }
459