xref: /dragonfly/crypto/libressl/ssl/tls13_key_schedule.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1 /* $OpenBSD: tls13_key_schedule.c,v 1.15 2022/07/07 17:09:45 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 "tls13_internal.h"
25 
26 int
tls13_secret_init(struct tls13_secret * secret,size_t len)27 tls13_secret_init(struct tls13_secret *secret, size_t len)
28 {
29           if (secret->data != NULL)
30                     return 0;
31 
32           if ((secret->data = calloc(1, len)) == NULL)
33                     return 0;
34           secret->len = len;
35 
36           return 1;
37 }
38 
39 void
tls13_secret_cleanup(struct tls13_secret * secret)40 tls13_secret_cleanup(struct tls13_secret *secret)
41 {
42           freezero(secret->data, secret->len);
43           secret->data = NULL;
44           secret->len = 0;
45 }
46 
47 /*
48  * Allocate a set of secrets for a key schedule using
49  * a size of hash_length from RFC 8446 section 7.1.
50  */
51 struct tls13_secrets *
tls13_secrets_create(const EVP_MD * digest,int resumption)52 tls13_secrets_create(const EVP_MD *digest, int resumption)
53 {
54           struct tls13_secrets *secrets = NULL;
55           EVP_MD_CTX *mdctx = NULL;
56           unsigned int mdlen;
57           size_t hash_length;
58 
59           hash_length = EVP_MD_size(digest);
60 
61           if ((secrets = calloc(1, sizeof(struct tls13_secrets))) == NULL)
62                     goto err;
63 
64           if (!tls13_secret_init(&secrets->zeros, hash_length))
65                     goto err;
66           if (!tls13_secret_init(&secrets->empty_hash, hash_length))
67                     goto err;
68 
69           if (!tls13_secret_init(&secrets->extracted_early, hash_length))
70                     goto err;
71           if (!tls13_secret_init(&secrets->binder_key, hash_length))
72                     goto err;
73           if (!tls13_secret_init(&secrets->client_early_traffic, hash_length))
74                     goto err;
75           if (!tls13_secret_init(&secrets->early_exporter_master, hash_length))
76                     goto err;
77           if (!tls13_secret_init(&secrets->derived_early, hash_length))
78                     goto err;
79           if (!tls13_secret_init(&secrets->extracted_handshake, hash_length))
80                     goto err;
81           if (!tls13_secret_init(&secrets->client_handshake_traffic, hash_length))
82                     goto err;
83           if (!tls13_secret_init(&secrets->server_handshake_traffic, hash_length))
84                     goto err;
85           if (!tls13_secret_init(&secrets->derived_handshake, hash_length))
86                     goto err;
87           if (!tls13_secret_init(&secrets->extracted_master, hash_length))
88                     goto err;
89           if (!tls13_secret_init(&secrets->client_application_traffic, hash_length))
90                     goto err;
91           if (!tls13_secret_init(&secrets->server_application_traffic, hash_length))
92                     goto err;
93           if (!tls13_secret_init(&secrets->exporter_master, hash_length))
94                     goto err;
95           if (!tls13_secret_init(&secrets->resumption_master, hash_length))
96                     goto err;
97 
98           /*
99            * Calculate the hash of a zero-length string - this is needed during
100            * the "derived" step for key extraction.
101            */
102           if ((mdctx = EVP_MD_CTX_new()) == NULL)
103                     goto err;
104           if (!EVP_DigestInit_ex(mdctx, digest, NULL))
105                     goto err;
106           if (!EVP_DigestUpdate(mdctx, secrets->zeros.data, 0))
107                     goto err;
108           if (!EVP_DigestFinal_ex(mdctx, secrets->empty_hash.data, &mdlen))
109                     goto err;
110           EVP_MD_CTX_free(mdctx);
111           mdctx = NULL;
112 
113           if (secrets->empty_hash.len != mdlen)
114                     goto err;
115 
116           secrets->digest = digest;
117           secrets->resumption = resumption;
118           secrets->init_done = 1;
119 
120           return secrets;
121 
122  err:
123           tls13_secrets_destroy(secrets);
124           EVP_MD_CTX_free(mdctx);
125 
126           return NULL;
127 }
128 
129 void
tls13_secrets_destroy(struct tls13_secrets * secrets)130 tls13_secrets_destroy(struct tls13_secrets *secrets)
131 {
132           if (secrets == NULL)
133                     return;
134 
135           /* you can never be too sure :) */
136           tls13_secret_cleanup(&secrets->zeros);
137           tls13_secret_cleanup(&secrets->empty_hash);
138 
139           tls13_secret_cleanup(&secrets->extracted_early);
140           tls13_secret_cleanup(&secrets->binder_key);
141           tls13_secret_cleanup(&secrets->client_early_traffic);
142           tls13_secret_cleanup(&secrets->early_exporter_master);
143           tls13_secret_cleanup(&secrets->derived_early);
144           tls13_secret_cleanup(&secrets->extracted_handshake);
145           tls13_secret_cleanup(&secrets->client_handshake_traffic);
146           tls13_secret_cleanup(&secrets->server_handshake_traffic);
147           tls13_secret_cleanup(&secrets->derived_handshake);
148           tls13_secret_cleanup(&secrets->extracted_master);
149           tls13_secret_cleanup(&secrets->client_application_traffic);
150           tls13_secret_cleanup(&secrets->server_application_traffic);
151           tls13_secret_cleanup(&secrets->exporter_master);
152           tls13_secret_cleanup(&secrets->resumption_master);
153 
154           freezero(secrets, sizeof(struct tls13_secrets));
155 }
156 
157 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)158 tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
159     const struct tls13_secret *secret, const char *label,
160     const struct tls13_secret *context)
161 {
162           return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
163               strlen(label), context);
164 }
165 
166 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)167 tls13_hkdf_expand_label_with_length(struct tls13_secret *out,
168     const EVP_MD *digest, const struct tls13_secret *secret,
169     const uint8_t *label, size_t label_len, const struct tls13_secret *context)
170 {
171           const char tls13_plabel[] = "tls13 ";
172           uint8_t *hkdf_label = NULL;
173           size_t hkdf_label_len;
174           CBB cbb, child;
175           int ret;
176 
177           if (!CBB_init(&cbb, 256))
178                     return 0;
179           if (!CBB_add_u16(&cbb, out->len))
180                     goto err;
181           if (!CBB_add_u8_length_prefixed(&cbb, &child))
182                     goto err;
183           if (!CBB_add_bytes(&child, tls13_plabel, strlen(tls13_plabel)))
184                     goto err;
185           if (!CBB_add_bytes(&child, label, label_len))
186                     goto err;
187           if (!CBB_add_u8_length_prefixed(&cbb, &child))
188                     goto err;
189           if (!CBB_add_bytes(&child, context->data, context->len))
190                     goto err;
191           if (!CBB_finish(&cbb, &hkdf_label, &hkdf_label_len))
192                     goto err;
193 
194           ret = HKDF_expand(out->data, out->len, digest, secret->data,
195               secret->len, hkdf_label, hkdf_label_len);
196 
197           free(hkdf_label);
198           return(ret);
199  err:
200           CBB_cleanup(&cbb);
201           return(0);
202 }
203 
204 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)205 tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest,
206     const struct tls13_secret *secret, const char *label,
207     const struct tls13_secret *context)
208 {
209           return tls13_hkdf_expand_label(out, digest, secret, label, context);
210 }
211 
212 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)213 tls13_derive_secret_with_label_length(struct tls13_secret *out,
214     const EVP_MD *digest, const struct tls13_secret *secret, const uint8_t *label,
215     size_t label_len, const struct tls13_secret *context)
216 {
217           return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
218               label_len, context);
219 }
220 
221 int
tls13_derive_early_secrets(struct tls13_secrets * secrets,uint8_t * psk,size_t psk_len,const struct tls13_secret * context)222 tls13_derive_early_secrets(struct tls13_secrets *secrets,
223     uint8_t *psk, size_t psk_len, const struct tls13_secret *context)
224 {
225           if (!secrets->init_done || secrets->early_done)
226                     return 0;
227 
228           if (!HKDF_extract(secrets->extracted_early.data,
229               &secrets->extracted_early.len, secrets->digest, psk, psk_len,
230               secrets->zeros.data, secrets->zeros.len))
231                     return 0;
232 
233           if (secrets->extracted_early.len != secrets->zeros.len)
234                     return 0;
235 
236           if (!tls13_derive_secret(&secrets->binder_key, secrets->digest,
237               &secrets->extracted_early,
238               secrets->resumption ? "res binder" : "ext binder",
239               &secrets->empty_hash))
240                     return 0;
241           if (!tls13_derive_secret(&secrets->client_early_traffic,
242               secrets->digest, &secrets->extracted_early, "c e traffic",
243               context))
244                     return 0;
245           if (!tls13_derive_secret(&secrets->early_exporter_master,
246               secrets->digest, &secrets->extracted_early, "e exp master",
247               context))
248                     return 0;
249           if (!tls13_derive_secret(&secrets->derived_early,
250               secrets->digest, &secrets->extracted_early, "derived",
251               &secrets->empty_hash))
252                     return 0;
253 
254           /* RFC 8446 recommends */
255           if (!secrets->insecure)
256                     explicit_bzero(secrets->extracted_early.data,
257                         secrets->extracted_early.len);
258           secrets->early_done = 1;
259           return 1;
260 }
261 
262 int
tls13_derive_handshake_secrets(struct tls13_secrets * secrets,const uint8_t * ecdhe,size_t ecdhe_len,const struct tls13_secret * context)263 tls13_derive_handshake_secrets(struct tls13_secrets *secrets,
264     const uint8_t *ecdhe, size_t ecdhe_len,
265     const struct tls13_secret *context)
266 {
267           if (!secrets->init_done || !secrets->early_done ||
268               secrets->handshake_done)
269                     return 0;
270 
271           if (!HKDF_extract(secrets->extracted_handshake.data,
272               &secrets->extracted_handshake.len, secrets->digest,
273               ecdhe, ecdhe_len, secrets->derived_early.data,
274               secrets->derived_early.len))
275                     return 0;
276 
277           if (secrets->extracted_handshake.len != secrets->zeros.len)
278                     return 0;
279 
280           /* XXX */
281           if (!secrets->insecure)
282                     explicit_bzero(secrets->derived_early.data,
283                         secrets->derived_early.len);
284 
285           if (!tls13_derive_secret(&secrets->client_handshake_traffic,
286               secrets->digest, &secrets->extracted_handshake, "c hs traffic",
287               context))
288                     return 0;
289           if (!tls13_derive_secret(&secrets->server_handshake_traffic,
290               secrets->digest, &secrets->extracted_handshake, "s hs traffic",
291               context))
292                     return 0;
293           if (!tls13_derive_secret(&secrets->derived_handshake,
294               secrets->digest, &secrets->extracted_handshake, "derived",
295               &secrets->empty_hash))
296                     return 0;
297 
298           /* RFC 8446 recommends */
299           if (!secrets->insecure)
300                     explicit_bzero(secrets->extracted_handshake.data,
301                         secrets->extracted_handshake.len);
302 
303           secrets->handshake_done = 1;
304 
305           return 1;
306 }
307 
308 int
tls13_derive_application_secrets(struct tls13_secrets * secrets,const struct tls13_secret * context)309 tls13_derive_application_secrets(struct tls13_secrets *secrets,
310     const struct tls13_secret *context)
311 {
312           if (!secrets->init_done || !secrets->early_done ||
313               !secrets->handshake_done || secrets->schedule_done)
314                     return 0;
315 
316           if (!HKDF_extract(secrets->extracted_master.data,
317               &secrets->extracted_master.len, secrets->digest,
318               secrets->zeros.data, secrets->zeros.len,
319               secrets->derived_handshake.data, secrets->derived_handshake.len))
320                     return 0;
321 
322           if (secrets->extracted_master.len != secrets->zeros.len)
323                     return 0;
324 
325           /* XXX */
326           if (!secrets->insecure)
327                     explicit_bzero(secrets->derived_handshake.data,
328                         secrets->derived_handshake.len);
329 
330           if (!tls13_derive_secret(&secrets->client_application_traffic,
331               secrets->digest, &secrets->extracted_master, "c ap traffic",
332               context))
333                     return 0;
334           if (!tls13_derive_secret(&secrets->server_application_traffic,
335               secrets->digest, &secrets->extracted_master, "s ap traffic",
336               context))
337                     return 0;
338           if (!tls13_derive_secret(&secrets->exporter_master,
339               secrets->digest, &secrets->extracted_master, "exp master",
340               context))
341                     return 0;
342           if (!tls13_derive_secret(&secrets->resumption_master,
343               secrets->digest, &secrets->extracted_master, "res master",
344               context))
345                     return 0;
346 
347           /* RFC 8446 recommends */
348           if (!secrets->insecure)
349                     explicit_bzero(secrets->extracted_master.data,
350                         secrets->extracted_master.len);
351 
352           secrets->schedule_done = 1;
353 
354           return 1;
355 }
356 
357 int
tls13_update_client_traffic_secret(struct tls13_secrets * secrets)358 tls13_update_client_traffic_secret(struct tls13_secrets *secrets)
359 {
360           struct tls13_secret context = { .data = "", .len = 0 };
361 
362           if (!secrets->init_done || !secrets->early_done ||
363               !secrets->handshake_done || !secrets->schedule_done)
364                     return 0;
365 
366           return tls13_hkdf_expand_label(&secrets->client_application_traffic,
367               secrets->digest, &secrets->client_application_traffic,
368               "traffic upd", &context);
369 }
370 
371 int
tls13_update_server_traffic_secret(struct tls13_secrets * secrets)372 tls13_update_server_traffic_secret(struct tls13_secrets *secrets)
373 {
374           struct tls13_secret context = { .data = "", .len = 0 };
375 
376           if (!secrets->init_done || !secrets->early_done ||
377               !secrets->handshake_done || !secrets->schedule_done)
378                     return 0;
379 
380           return tls13_hkdf_expand_label(&secrets->server_application_traffic,
381               secrets->digest, &secrets->server_application_traffic,
382               "traffic upd", &context);
383 }
384