Merge remote-tracking branch 'origin/vendor/XZ'
[dragonfly.git] / crypto / libressl / ssl / tls13_key_schedule.c
1 /* $OpenBSD: tls13_key_schedule.c,v 1.7 2018/11/13 01:25:13 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         if (!secrets->init_done || !secrets->early_done ||
358             !secrets->handshake_done || !secrets->schedule_done)
359                 return 0;
360
361         return tls13_hkdf_expand_label(&secrets->client_application_traffic,
362             secrets->digest, &secrets->client_application_traffic,
363             "traffic upd", &secrets->empty_hash);
364 }
365
366 int
367 tls13_update_server_traffic_secret(struct tls13_secrets *secrets)
368 {
369         if (!secrets->init_done || !secrets->early_done ||
370             !secrets->handshake_done || !secrets->schedule_done)
371                 return 0;
372
373         return tls13_hkdf_expand_label(&secrets->server_application_traffic,
374             secrets->digest, &secrets->server_application_traffic,
375             "traffic upd", &secrets->empty_hash);
376 }