1 /* $OpenBSD: tls13_key_schedule.c,v 1.8 2019/11/17 21:01:08 beck 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 	const char tls13_plabel[] = "tls13 ";
178 	uint8_t *hkdf_label;
179 	size_t hkdf_label_len;
180 	CBB cbb, child;
181 	int ret;
182 
183 	if (!CBB_init(&cbb, 256))
184 		return 0;
185 	if (!CBB_add_u16(&cbb, out->len))
186 		goto err;
187 	if (!CBB_add_u8_length_prefixed(&cbb, &child))
188 		goto err;
189 	if (!CBB_add_bytes(&child, tls13_plabel, strlen(tls13_plabel)))
190 		goto err;
191 	if (!CBB_add_bytes(&child, label, strlen(label)))
192 		goto err;
193 	if (!CBB_add_u8_length_prefixed(&cbb, &child))
194 		goto err;
195 	if (!CBB_add_bytes(&child, context->data, context->len))
196 		goto err;
197 	if (!CBB_finish(&cbb, &hkdf_label, &hkdf_label_len))
198 		goto err;
199 
200 	ret = HKDF_expand(out->data, out->len, digest, secret->data,
201 	    secret->len, hkdf_label, hkdf_label_len);
202 
203 	free(hkdf_label);
204 	return(ret);
205  err:
206 	CBB_cleanup(&cbb);
207 	return(0);
208 }
209 
210 static int
211 tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest,
212     const struct tls13_secret *secret, const char *label,
213     const struct tls13_secret *context)
214 {
215 	return tls13_hkdf_expand_label(out, digest, secret, label, context);
216 }
217 
218 int
219 tls13_derive_early_secrets(struct tls13_secrets *secrets,
220     uint8_t *psk, size_t psk_len, const struct tls13_secret *context)
221 {
222 	if (!secrets->init_done || secrets->early_done)
223 		return 0;
224 
225 	if (!HKDF_extract(secrets->extracted_early.data,
226 	    &secrets->extracted_early.len, secrets->digest, psk, psk_len,
227 	    secrets->zeros.data, secrets->zeros.len))
228 		return 0;
229 
230 	if (secrets->extracted_early.len != secrets->zeros.len)
231 		return 0;
232 
233 	if (!tls13_derive_secret(&secrets->binder_key, secrets->digest,
234 	    &secrets->extracted_early,
235 	    secrets->resumption ? "res binder" : "ext binder",
236 	    &secrets->empty_hash))
237 		return 0;
238 	if (!tls13_derive_secret(&secrets->client_early_traffic,
239 	    secrets->digest, &secrets->extracted_early, "c e traffic",
240 	    context))
241 		return 0;
242 	if (!tls13_derive_secret(&secrets->early_exporter_master,
243 	    secrets->digest, &secrets->extracted_early, "e exp master",
244 	    context))
245 		return 0;
246 	if (!tls13_derive_secret(&secrets->derived_early,
247 	    secrets->digest, &secrets->extracted_early, "derived",
248 	    &secrets->empty_hash))
249 		return 0;
250 
251 	/* RFC 8446 recommends */
252 	if (!secrets->insecure)
253 		explicit_bzero(secrets->extracted_early.data,
254 		    secrets->extracted_early.len);
255 	secrets->early_done = 1;
256 	return 1;
257 }
258 
259 int
260 tls13_derive_handshake_secrets(struct tls13_secrets *secrets,
261     const uint8_t *ecdhe, size_t ecdhe_len,
262     const struct tls13_secret *context)
263 {
264 	if (!secrets->init_done || !secrets->early_done ||
265 	    secrets->handshake_done)
266 		return 0;
267 
268 	if (!HKDF_extract(secrets->extracted_handshake.data,
269 	    &secrets->extracted_handshake.len, secrets->digest,
270 	    ecdhe, ecdhe_len, secrets->derived_early.data,
271 	    secrets->derived_early.len))
272 		return 0;
273 
274 	if (secrets->extracted_handshake.len != secrets->zeros.len)
275 		return 0;
276 
277 	/* XXX */
278 	if (!secrets->insecure)
279 		explicit_bzero(secrets->derived_early.data,
280 		    secrets->derived_early.len);
281 
282 	if (!tls13_derive_secret(&secrets->client_handshake_traffic,
283 	    secrets->digest, &secrets->extracted_handshake, "c hs traffic",
284 	    context))
285 		return 0;
286 	if (!tls13_derive_secret(&secrets->server_handshake_traffic,
287 	    secrets->digest, &secrets->extracted_handshake, "s hs traffic",
288 	    context))
289 		return 0;
290 	if (!tls13_derive_secret(&secrets->derived_handshake,
291 	    secrets->digest, &secrets->extracted_handshake, "derived",
292 	    &secrets->empty_hash))
293 		return 0;
294 
295 	/* RFC 8446 recommends */
296 	if (!secrets->insecure)
297 		explicit_bzero(secrets->extracted_handshake.data,
298 		    secrets->extracted_handshake.len);
299 
300 	secrets->handshake_done = 1;
301 
302 	return 1;
303 }
304 
305 int
306 tls13_derive_application_secrets(struct tls13_secrets *secrets,
307     const struct tls13_secret *context)
308 {
309 	if (!secrets->init_done || !secrets->early_done ||
310 	    !secrets->handshake_done || secrets->schedule_done)
311 		return 0;
312 
313 	if (!HKDF_extract(secrets->extracted_master.data,
314 	    &secrets->extracted_master.len, secrets->digest,
315 	    secrets->zeros.data, secrets->zeros.len,
316 	    secrets->derived_handshake.data, secrets->derived_handshake.len))
317 		return 0;
318 
319 	if (secrets->extracted_master.len != secrets->zeros.len)
320 		return 0;
321 
322 	/* XXX */
323 	if (!secrets->insecure)
324 		explicit_bzero(secrets->derived_handshake.data,
325 		    secrets->derived_handshake.len);
326 
327 	if (!tls13_derive_secret(&secrets->client_application_traffic,
328 	    secrets->digest, &secrets->extracted_master, "c ap traffic",
329 	    context))
330 		return 0;
331 	if (!tls13_derive_secret(&secrets->server_application_traffic,
332 	    secrets->digest, &secrets->extracted_master, "s ap traffic",
333 	    context))
334 		return 0;
335 	if (!tls13_derive_secret(&secrets->exporter_master,
336 	    secrets->digest, &secrets->extracted_master, "exp master",
337 	    context))
338 		return 0;
339 	if (!tls13_derive_secret(&secrets->resumption_master,
340 	    secrets->digest, &secrets->extracted_master, "res master",
341 	    context))
342 		return 0;
343 
344 	/* RFC 8446 recommends */
345 	if (!secrets->insecure)
346 		explicit_bzero(secrets->extracted_master.data,
347 		    secrets->extracted_master.len);
348 
349 	secrets->schedule_done = 1;
350 
351 	return 1;
352 }
353 
354 int
355 tls13_update_client_traffic_secret(struct tls13_secrets *secrets)
356 {
357 	struct tls13_secret context = { .data = "", .len = 0 };
358 
359 	if (!secrets->init_done || !secrets->early_done ||
360 	    !secrets->handshake_done || !secrets->schedule_done)
361 		return 0;
362 
363 	return tls13_hkdf_expand_label(&secrets->client_application_traffic,
364 	    secrets->digest, &secrets->client_application_traffic,
365 	    "traffic upd", &context);
366 }
367 
368 int
369 tls13_update_server_traffic_secret(struct tls13_secrets *secrets)
370 {
371 	struct tls13_secret context = { .data = "", .len = 0 };
372 
373 	if (!secrets->init_done || !secrets->early_done ||
374 	    !secrets->handshake_done || !secrets->schedule_done)
375 		return 0;
376 
377 	return tls13_hkdf_expand_label(&secrets->server_application_traffic,
378 	    secrets->digest, &secrets->server_application_traffic,
379 	    "traffic upd", &context);
380 }
381