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