1/* $OpenBSD: tls13_key_schedule.c,v 1.18 2022/11/26 16:08:56 tb Exp $ */
2/*
3 * Copyright (c) 2018, Bob Beck <beck@openbsd.org>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <string.h>
19#include <stdlib.h>
20
21#include <openssl/hkdf.h>
22
23#include "bytestring.h"
24#include "ssl_local.h"
25#include "tls13_internal.h"
26
27int
28tls13_secret_init(struct tls13_secret *secret, size_t len)
29{
30	if (secret->data != NULL)
31		return 0;
32
33	if ((secret->data = calloc(1, len)) == NULL)
34		return 0;
35	secret->len = len;
36
37	return 1;
38}
39
40void
41tls13_secret_cleanup(struct tls13_secret *secret)
42{
43	freezero(secret->data, secret->len);
44	secret->data = NULL;
45	secret->len = 0;
46}
47
48/*
49 * Allocate a set of secrets for a key schedule using
50 * a size of hash_length from RFC 8446 section 7.1.
51 */
52struct tls13_secrets *
53tls13_secrets_create(const EVP_MD *digest, int resumption)
54{
55	struct tls13_secrets *secrets = NULL;
56	EVP_MD_CTX *mdctx = NULL;
57	unsigned int mdlen;
58	size_t hash_length;
59
60	hash_length = EVP_MD_size(digest);
61
62	if ((secrets = calloc(1, sizeof(struct tls13_secrets))) == NULL)
63		goto err;
64
65	if (!tls13_secret_init(&secrets->zeros, hash_length))
66		goto err;
67	if (!tls13_secret_init(&secrets->empty_hash, hash_length))
68		goto err;
69
70	if (!tls13_secret_init(&secrets->extracted_early, hash_length))
71		goto err;
72	if (!tls13_secret_init(&secrets->binder_key, hash_length))
73		goto err;
74	if (!tls13_secret_init(&secrets->client_early_traffic, hash_length))
75		goto err;
76	if (!tls13_secret_init(&secrets->early_exporter_master, hash_length))
77		goto err;
78	if (!tls13_secret_init(&secrets->derived_early, hash_length))
79		goto err;
80	if (!tls13_secret_init(&secrets->extracted_handshake, hash_length))
81		goto err;
82	if (!tls13_secret_init(&secrets->client_handshake_traffic, hash_length))
83		goto err;
84	if (!tls13_secret_init(&secrets->server_handshake_traffic, hash_length))
85		goto err;
86	if (!tls13_secret_init(&secrets->derived_handshake, hash_length))
87		goto err;
88	if (!tls13_secret_init(&secrets->extracted_master, hash_length))
89		goto err;
90	if (!tls13_secret_init(&secrets->client_application_traffic, hash_length))
91		goto err;
92	if (!tls13_secret_init(&secrets->server_application_traffic, hash_length))
93		goto err;
94	if (!tls13_secret_init(&secrets->exporter_master, hash_length))
95		goto err;
96	if (!tls13_secret_init(&secrets->resumption_master, hash_length))
97		goto err;
98
99	/*
100	 * Calculate the hash of a zero-length string - this is needed during
101	 * the "derived" step for key extraction.
102	 */
103	if ((mdctx = EVP_MD_CTX_new()) == NULL)
104		goto err;
105	if (!EVP_DigestInit_ex(mdctx, digest, NULL))
106		goto err;
107	if (!EVP_DigestUpdate(mdctx, secrets->zeros.data, 0))
108		goto err;
109	if (!EVP_DigestFinal_ex(mdctx, secrets->empty_hash.data, &mdlen))
110		goto err;
111	EVP_MD_CTX_free(mdctx);
112	mdctx = NULL;
113
114	if (secrets->empty_hash.len != mdlen)
115		goto err;
116
117	secrets->digest = digest;
118	secrets->resumption = resumption;
119	secrets->init_done = 1;
120
121	return secrets;
122
123 err:
124	tls13_secrets_destroy(secrets);
125	EVP_MD_CTX_free(mdctx);
126
127	return NULL;
128}
129
130void
131tls13_secrets_destroy(struct tls13_secrets *secrets)
132{
133	if (secrets == NULL)
134		return;
135
136	/* you can never be too sure :) */
137	tls13_secret_cleanup(&secrets->zeros);
138	tls13_secret_cleanup(&secrets->empty_hash);
139
140	tls13_secret_cleanup(&secrets->extracted_early);
141	tls13_secret_cleanup(&secrets->binder_key);
142	tls13_secret_cleanup(&secrets->client_early_traffic);
143	tls13_secret_cleanup(&secrets->early_exporter_master);
144	tls13_secret_cleanup(&secrets->derived_early);
145	tls13_secret_cleanup(&secrets->extracted_handshake);
146	tls13_secret_cleanup(&secrets->client_handshake_traffic);
147	tls13_secret_cleanup(&secrets->server_handshake_traffic);
148	tls13_secret_cleanup(&secrets->derived_handshake);
149	tls13_secret_cleanup(&secrets->extracted_master);
150	tls13_secret_cleanup(&secrets->client_application_traffic);
151	tls13_secret_cleanup(&secrets->server_application_traffic);
152	tls13_secret_cleanup(&secrets->exporter_master);
153	tls13_secret_cleanup(&secrets->resumption_master);
154
155	freezero(secrets, sizeof(struct tls13_secrets));
156}
157
158int
159tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
160    const struct tls13_secret *secret, const char *label,
161    const struct tls13_secret *context)
162{
163	return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
164	    strlen(label), context);
165}
166
167int
168tls13_hkdf_expand_label_with_length(struct tls13_secret *out,
169    const EVP_MD *digest, const struct tls13_secret *secret,
170    const uint8_t *label, size_t label_len, const struct tls13_secret *context)
171{
172	const char tls13_plabel[] = "tls13 ";
173	uint8_t *hkdf_label = NULL;
174	size_t hkdf_label_len;
175	CBB cbb, child;
176	int ret;
177
178	if (!CBB_init(&cbb, 256))
179		goto err;
180
181	if (out->data == NULL || out->len == 0)
182		goto err;
183
184	if (!CBB_add_u16(&cbb, out->len))
185		goto err;
186	if (!CBB_add_u8_length_prefixed(&cbb, &child))
187		goto err;
188	if (!CBB_add_bytes(&child, tls13_plabel, strlen(tls13_plabel)))
189		goto err;
190	if (!CBB_add_bytes(&child, label, label_len))
191		goto err;
192	if (!CBB_add_u8_length_prefixed(&cbb, &child))
193		goto err;
194	if (!CBB_add_bytes(&child, context->data, context->len))
195		goto err;
196	if (!CBB_finish(&cbb, &hkdf_label, &hkdf_label_len))
197		goto err;
198
199	ret = HKDF_expand(out->data, out->len, digest, secret->data,
200	    secret->len, hkdf_label, hkdf_label_len);
201
202	free(hkdf_label);
203	return(ret);
204 err:
205	CBB_cleanup(&cbb);
206	return(0);
207}
208
209int
210tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest,
211    const struct tls13_secret *secret, const char *label,
212    const struct tls13_secret *context)
213{
214	return tls13_hkdf_expand_label(out, digest, secret, label, context);
215}
216
217int
218tls13_derive_secret_with_label_length(struct tls13_secret *out,
219    const EVP_MD *digest, const struct tls13_secret *secret, const uint8_t *label,
220    size_t label_len, const struct tls13_secret *context)
221{
222	return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
223	    label_len, context);
224}
225
226int
227tls13_derive_early_secrets(struct tls13_secrets *secrets,
228    uint8_t *psk, size_t psk_len, const struct tls13_secret *context)
229{
230	if (!secrets->init_done || secrets->early_done)
231		return 0;
232
233	if (!HKDF_extract(secrets->extracted_early.data,
234	    &secrets->extracted_early.len, secrets->digest, psk, psk_len,
235	    secrets->zeros.data, secrets->zeros.len))
236		return 0;
237
238	if (secrets->extracted_early.len != secrets->zeros.len)
239		return 0;
240
241	if (!tls13_derive_secret(&secrets->binder_key, secrets->digest,
242	    &secrets->extracted_early,
243	    secrets->resumption ? "res binder" : "ext binder",
244	    &secrets->empty_hash))
245		return 0;
246	if (!tls13_derive_secret(&secrets->client_early_traffic,
247	    secrets->digest, &secrets->extracted_early, "c e traffic",
248	    context))
249		return 0;
250	if (!tls13_derive_secret(&secrets->early_exporter_master,
251	    secrets->digest, &secrets->extracted_early, "e exp master",
252	    context))
253		return 0;
254	if (!tls13_derive_secret(&secrets->derived_early,
255	    secrets->digest, &secrets->extracted_early, "derived",
256	    &secrets->empty_hash))
257		return 0;
258
259	/* RFC 8446 recommends */
260	if (!secrets->insecure)
261		explicit_bzero(secrets->extracted_early.data,
262		    secrets->extracted_early.len);
263	secrets->early_done = 1;
264	return 1;
265}
266
267int
268tls13_derive_handshake_secrets(struct tls13_secrets *secrets,
269    const uint8_t *ecdhe, size_t ecdhe_len,
270    const struct tls13_secret *context)
271{
272	if (!secrets->init_done || !secrets->early_done ||
273	    secrets->handshake_done)
274		return 0;
275
276	if (!HKDF_extract(secrets->extracted_handshake.data,
277	    &secrets->extracted_handshake.len, secrets->digest,
278	    ecdhe, ecdhe_len, secrets->derived_early.data,
279	    secrets->derived_early.len))
280		return 0;
281
282	if (secrets->extracted_handshake.len != secrets->zeros.len)
283		return 0;
284
285	/* XXX */
286	if (!secrets->insecure)
287		explicit_bzero(secrets->derived_early.data,
288		    secrets->derived_early.len);
289
290	if (!tls13_derive_secret(&secrets->client_handshake_traffic,
291	    secrets->digest, &secrets->extracted_handshake, "c hs traffic",
292	    context))
293		return 0;
294	if (!tls13_derive_secret(&secrets->server_handshake_traffic,
295	    secrets->digest, &secrets->extracted_handshake, "s hs traffic",
296	    context))
297		return 0;
298	if (!tls13_derive_secret(&secrets->derived_handshake,
299	    secrets->digest, &secrets->extracted_handshake, "derived",
300	    &secrets->empty_hash))
301		return 0;
302
303	/* RFC 8446 recommends */
304	if (!secrets->insecure)
305		explicit_bzero(secrets->extracted_handshake.data,
306		    secrets->extracted_handshake.len);
307
308	secrets->handshake_done = 1;
309
310	return 1;
311}
312
313int
314tls13_derive_application_secrets(struct tls13_secrets *secrets,
315    const struct tls13_secret *context)
316{
317	if (!secrets->init_done || !secrets->early_done ||
318	    !secrets->handshake_done || secrets->schedule_done)
319		return 0;
320
321	if (!HKDF_extract(secrets->extracted_master.data,
322	    &secrets->extracted_master.len, secrets->digest,
323	    secrets->zeros.data, secrets->zeros.len,
324	    secrets->derived_handshake.data, secrets->derived_handshake.len))
325		return 0;
326
327	if (secrets->extracted_master.len != secrets->zeros.len)
328		return 0;
329
330	/* XXX */
331	if (!secrets->insecure)
332		explicit_bzero(secrets->derived_handshake.data,
333		    secrets->derived_handshake.len);
334
335	if (!tls13_derive_secret(&secrets->client_application_traffic,
336	    secrets->digest, &secrets->extracted_master, "c ap traffic",
337	    context))
338		return 0;
339	if (!tls13_derive_secret(&secrets->server_application_traffic,
340	    secrets->digest, &secrets->extracted_master, "s ap traffic",
341	    context))
342		return 0;
343	if (!tls13_derive_secret(&secrets->exporter_master,
344	    secrets->digest, &secrets->extracted_master, "exp master",
345	    context))
346		return 0;
347	if (!tls13_derive_secret(&secrets->resumption_master,
348	    secrets->digest, &secrets->extracted_master, "res master",
349	    context))
350		return 0;
351
352	/* RFC 8446 recommends */
353	if (!secrets->insecure)
354		explicit_bzero(secrets->extracted_master.data,
355		    secrets->extracted_master.len);
356
357	secrets->schedule_done = 1;
358
359	return 1;
360}
361
362int
363tls13_update_client_traffic_secret(struct tls13_secrets *secrets)
364{
365	struct tls13_secret context = { .data = "", .len = 0 };
366
367	if (!secrets->init_done || !secrets->early_done ||
368	    !secrets->handshake_done || !secrets->schedule_done)
369		return 0;
370
371	return tls13_hkdf_expand_label(&secrets->client_application_traffic,
372	    secrets->digest, &secrets->client_application_traffic,
373	    "traffic upd", &context);
374}
375
376int
377tls13_update_server_traffic_secret(struct tls13_secrets *secrets)
378{
379	struct tls13_secret context = { .data = "", .len = 0 };
380
381	if (!secrets->init_done || !secrets->early_done ||
382	    !secrets->handshake_done || !secrets->schedule_done)
383		return 0;
384
385	return tls13_hkdf_expand_label(&secrets->server_application_traffic,
386	    secrets->digest, &secrets->server_application_traffic,
387	    "traffic upd", &context);
388}
389
390int
391tls13_exporter(struct tls13_ctx *ctx, const uint8_t *label, size_t label_len,
392    const uint8_t *context_value, size_t context_value_len, uint8_t *out,
393    size_t out_len)
394{
395	struct tls13_secret context, export_out, export_secret;
396	struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
397	EVP_MD_CTX *md_ctx = NULL;
398	unsigned int md_out_len;
399	int md_len;
400	int ret = 0;
401
402	/*
403	 * RFC 8446 Section 7.5.
404	 */
405
406	memset(&context, 0, sizeof(context));
407	memset(&export_secret, 0, sizeof(export_secret));
408
409	export_out.data = out;
410	export_out.len = out_len;
411
412	if (!ctx->handshake_completed)
413		return 0;
414
415	md_len = EVP_MD_size(secrets->digest);
416	if (md_len <= 0 || md_len > EVP_MAX_MD_SIZE)
417		goto err;
418
419	if (!tls13_secret_init(&export_secret, md_len))
420		goto err;
421	if (!tls13_secret_init(&context, md_len))
422		goto err;
423
424	/* In TLSv1.3 no context is equivalent to an empty context. */
425	if (context_value == NULL) {
426		context_value = "";
427		context_value_len = 0;
428	}
429
430	if ((md_ctx = EVP_MD_CTX_new()) == NULL)
431		goto err;
432	if (!EVP_DigestInit_ex(md_ctx, secrets->digest, NULL))
433		goto err;
434	if (!EVP_DigestUpdate(md_ctx, context_value, context_value_len))
435		goto err;
436	if (!EVP_DigestFinal_ex(md_ctx, context.data, &md_out_len))
437		goto err;
438	if (md_len != md_out_len)
439		goto err;
440
441	if (!tls13_derive_secret_with_label_length(&export_secret,
442	    secrets->digest, &secrets->exporter_master, label, label_len,
443	    &secrets->empty_hash))
444		goto err;
445
446	if (!tls13_hkdf_expand_label(&export_out, secrets->digest,
447	    &export_secret, "exporter", &context))
448		goto err;
449
450	ret = 1;
451
452 err:
453	EVP_MD_CTX_free(md_ctx);
454	tls13_secret_cleanup(&context);
455	tls13_secret_cleanup(&export_secret);
456
457	return ret;
458}
459