diff options
author | jsing <> | 2018-11-09 23:56:20 +0000 |
---|---|---|
committer | jsing <> | 2018-11-09 23:56:20 +0000 |
commit | 3262ad497d2c29e5159b225d7e8ff30b7d137582 (patch) | |
tree | 28b24c2a886dd42cafa13a84759715759283543f /src/lib/libssl/tls13_key_schedule.c | |
parent | c74b72138c69c5ed97e26f34caaf48a998b6d507 (diff) | |
download | openbsd-3262ad497d2c29e5159b225d7e8ff30b7d137582.tar.gz openbsd-3262ad497d2c29e5159b225d7e8ff30b7d137582.tar.bz2 openbsd-3262ad497d2c29e5159b225d7e8ff30b7d137582.zip |
Fix the TLSv1.3 key schedule implementation.
When the RFC refers to ("") for key derivation, it is referring to the
transcript hash of an empty string, not an empty string. Rename
tls13_secrets_new() to tls13_secrets_create(), make it take an EVP_MD *
and calculate the hash of an empty string so that we have it available
for the "derived" and other steps. Merge tls13_secrets_init() into
the same function, remove the EVP_MD * from other functions and use the
empty string hash at the appropriate places.
ok beck@ tb@
Diffstat (limited to 'src/lib/libssl/tls13_key_schedule.c')
-rw-r--r-- | src/lib/libssl/tls13_key_schedule.c | 137 |
1 files changed, 81 insertions, 56 deletions
diff --git a/src/lib/libssl/tls13_key_schedule.c b/src/lib/libssl/tls13_key_schedule.c index 6984d20730..f20e9b741b 100644 --- a/src/lib/libssl/tls13_key_schedule.c +++ b/src/lib/libssl/tls13_key_schedule.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_key_schedule.c,v 1.3 2018/11/08 23:50:54 beck Exp $ */ | 1 | /* $OpenBSD: tls13_key_schedule.c,v 1.4 2018/11/09 23:56:20 jsing Exp $ */ |
2 | /* Copyright (c) 2018, Bob Beck <beck@openbsd.org> | 2 | /* Copyright (c) 2018, Bob Beck <beck@openbsd.org> |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
@@ -30,6 +30,7 @@ tls13_secrets_destroy(struct tls13_secrets *secrets) | |||
30 | 30 | ||
31 | /* you can never be too sure :) */ | 31 | /* you can never be too sure :) */ |
32 | freezero(secrets->zeros.data, secrets->zeros.len); | 32 | freezero(secrets->zeros.data, secrets->zeros.len); |
33 | freezero(secrets->empty_hash.data, secrets->empty_hash.len); | ||
33 | 34 | ||
34 | freezero(secrets->extracted_early.data, | 35 | freezero(secrets->extracted_early.data, |
35 | secrets->extracted_early.len); | 36 | secrets->extracted_early.len); |
@@ -65,12 +66,17 @@ tls13_secrets_destroy(struct tls13_secrets *secrets) | |||
65 | 66 | ||
66 | /* | 67 | /* |
67 | * Allocate a set of secrets for a key schedule using | 68 | * Allocate a set of secrets for a key schedule using |
68 | * a size of hash_length from RFC 8446 section 7.1 | 69 | * a size of hash_length from RFC 8446 section 7.1. |
69 | */ | 70 | */ |
70 | struct tls13_secrets * | 71 | struct tls13_secrets * |
71 | tls13_secrets_new(size_t hash_length) | 72 | tls13_secrets_create(const EVP_MD *digest, int resumption) |
72 | { | 73 | { |
73 | struct tls13_secrets *secrets = NULL; | 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); | ||
74 | 80 | ||
75 | if ((secrets = calloc(1, sizeof(struct tls13_secrets))) == NULL) | 81 | if ((secrets = calloc(1, sizeof(struct tls13_secrets))) == NULL) |
76 | goto err; | 82 | goto err; |
@@ -79,6 +85,10 @@ tls13_secrets_new(size_t hash_length) | |||
79 | goto err; | 85 | goto err; |
80 | secrets->zeros.len = hash_length; | 86 | secrets->zeros.len = hash_length; |
81 | 87 | ||
88 | if ((secrets->empty_hash.data = malloc(hash_length)) == NULL) | ||
89 | goto err; | ||
90 | secrets->empty_hash.len = hash_length; | ||
91 | |||
82 | if ((secrets->extracted_early.data = malloc(hash_length)) == NULL) | 92 | if ((secrets->extracted_early.data = malloc(hash_length)) == NULL) |
83 | goto err; | 93 | goto err; |
84 | secrets->extracted_early.len = hash_length; | 94 | secrets->extracted_early.len = hash_length; |
@@ -130,20 +140,37 @@ tls13_secrets_new(size_t hash_length) | |||
130 | goto err; | 140 | goto err; |
131 | secrets->resumption_master.len = hash_length; | 141 | secrets->resumption_master.len = hash_length; |
132 | 142 | ||
143 | /* | ||
144 | * Calculate the hash of a zero-length string - this is needed during | ||
145 | * the "derived" step for key extraction. | ||
146 | */ | ||
147 | if ((mdctx = EVP_MD_CTX_new()) == NULL) | ||
148 | goto err; | ||
149 | if (!EVP_DigestInit_ex(mdctx, digest, NULL)) | ||
150 | goto err; | ||
151 | if (!EVP_DigestUpdate(mdctx, secrets->zeros.data, 0)) | ||
152 | goto err; | ||
153 | if (!EVP_DigestFinal_ex(mdctx, secrets->empty_hash.data, &mdlen)) | ||
154 | goto err; | ||
155 | EVP_MD_CTX_free(mdctx); | ||
156 | |||
157 | if (secrets->empty_hash.len != mdlen) | ||
158 | goto err; | ||
159 | |||
160 | secrets->digest = digest; | ||
161 | secrets->resumption = resumption; | ||
162 | secrets->init_done = 1; | ||
163 | |||
133 | return secrets; | 164 | return secrets; |
165 | |||
134 | err: | 166 | err: |
135 | tls13_secrets_destroy(secrets); | 167 | tls13_secrets_destroy(secrets); |
136 | return NULL; | 168 | EVP_MD_CTX_free(mdctx); |
137 | } | ||
138 | 169 | ||
139 | void | 170 | return NULL; |
140 | tls13_secrets_init(struct tls13_secrets *secrets, int resumption) | ||
141 | { | ||
142 | secrets->resumption = resumption; | ||
143 | secrets->init_done = 1; | ||
144 | } | 171 | } |
145 | 172 | ||
146 | static int | 173 | int |
147 | tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest, | 174 | tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest, |
148 | const struct tls13_secret *secret, const char *label, | 175 | const struct tls13_secret *secret, const char *label, |
149 | const struct tls13_secret *context) | 176 | const struct tls13_secret *context) |
@@ -173,6 +200,7 @@ tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest, | |||
173 | 200 | ||
174 | ret = HKDF_expand(out->data, out->len, digest, secret->data, | 201 | ret = HKDF_expand(out->data, out->len, digest, secret->data, |
175 | secret->len, hkdf_label, hkdf_label_len); | 202 | secret->len, hkdf_label, hkdf_label_len); |
203 | |||
176 | free(hkdf_label); | 204 | free(hkdf_label); |
177 | return(ret); | 205 | return(ret); |
178 | err: | 206 | err: |
@@ -188,9 +216,8 @@ tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest, | |||
188 | return tls13_hkdf_expand_label(out, digest, secret, label, context); | 216 | return tls13_hkdf_expand_label(out, digest, secret, label, context); |
189 | } | 217 | } |
190 | 218 | ||
191 | |||
192 | int | 219 | int |
193 | tls13_derive_early_secrets(struct tls13_secrets *secrets, const EVP_MD *digest, | 220 | tls13_derive_early_secrets(struct tls13_secrets *secrets, |
194 | uint8_t *psk, size_t psk_len, const struct tls13_secret *context) | 221 | uint8_t *psk, size_t psk_len, const struct tls13_secret *context) |
195 | { | 222 | { |
196 | struct tls13_secret binder_context; | 223 | struct tls13_secret binder_context; |
@@ -204,7 +231,7 @@ tls13_derive_early_secrets(struct tls13_secrets *secrets, const EVP_MD *digest, | |||
204 | if ((mdctx = EVP_MD_CTX_new()) == NULL) | 231 | if ((mdctx = EVP_MD_CTX_new()) == NULL) |
205 | return 0; | 232 | return 0; |
206 | 233 | ||
207 | if (!EVP_DigestInit_ex(mdctx, digest, NULL) || | 234 | if (!EVP_DigestInit_ex(mdctx, secrets->digest, NULL) || |
208 | !EVP_DigestUpdate(mdctx, secrets->zeros.data, secrets->zeros.len) || | 235 | !EVP_DigestUpdate(mdctx, secrets->zeros.data, secrets->zeros.len) || |
209 | !EVP_DigestFinal_ex(mdctx, binder_context_data, | 236 | !EVP_DigestFinal_ex(mdctx, binder_context_data, |
210 | &binder_context_len)) { | 237 | &binder_context_len)) { |
@@ -220,29 +247,29 @@ tls13_derive_early_secrets(struct tls13_secrets *secrets, const EVP_MD *digest, | |||
220 | return 0; | 247 | return 0; |
221 | 248 | ||
222 | if (!HKDF_extract(secrets->extracted_early.data, | 249 | if (!HKDF_extract(secrets->extracted_early.data, |
223 | &secrets->extracted_early.len, digest, psk, psk_len, | 250 | &secrets->extracted_early.len, secrets->digest, psk, psk_len, |
224 | secrets->zeros.data, secrets->zeros.len)) | 251 | secrets->zeros.data, secrets->zeros.len)) |
225 | return 0; | 252 | return 0; |
226 | 253 | ||
227 | if (secrets->extracted_early.len != secrets->zeros.len) | 254 | if (secrets->extracted_early.len != secrets->zeros.len) |
228 | return 0; | 255 | return 0; |
229 | 256 | ||
230 | if (!tls13_derive_secret(&secrets->binder_key, | 257 | if (!tls13_derive_secret(&secrets->binder_key, secrets->digest, |
231 | digest, &secrets->extracted_early, | 258 | &secrets->extracted_early, |
232 | secrets->resumption ? "res binder" : "ext binder", | 259 | secrets->resumption ? "res binder" : "ext binder", |
233 | &binder_context)) | 260 | &binder_context)) |
234 | return 0; | 261 | return 0; |
235 | |||
236 | if (!tls13_derive_secret(&secrets->client_early_traffic, | 262 | if (!tls13_derive_secret(&secrets->client_early_traffic, |
237 | digest, &secrets->extracted_early, "c e traffic", context)) | 263 | secrets->digest, &secrets->extracted_early, "c e traffic", |
264 | context)) | ||
238 | return 0; | 265 | return 0; |
239 | |||
240 | if (!tls13_derive_secret(&secrets->early_exporter_master, | 266 | if (!tls13_derive_secret(&secrets->early_exporter_master, |
241 | digest, &secrets->extracted_early, "e exp master", context)) | 267 | secrets->digest, &secrets->extracted_early, "e exp master", |
268 | context)) | ||
242 | return 0; | 269 | return 0; |
243 | |||
244 | if (!tls13_derive_secret(&secrets->derived_early, | 270 | if (!tls13_derive_secret(&secrets->derived_early, |
245 | digest, &secrets->extracted_early, "derived", context)) | 271 | secrets->digest, &secrets->extracted_early, "derived", |
272 | &secrets->empty_hash)) | ||
246 | return 0; | 273 | return 0; |
247 | 274 | ||
248 | /* RFC 8446 recommends */ | 275 | /* RFC 8446 recommends */ |
@@ -255,7 +282,7 @@ tls13_derive_early_secrets(struct tls13_secrets *secrets, const EVP_MD *digest, | |||
255 | 282 | ||
256 | int | 283 | int |
257 | tls13_derive_handshake_secrets(struct tls13_secrets *secrets, | 284 | tls13_derive_handshake_secrets(struct tls13_secrets *secrets, |
258 | const EVP_MD *digest, const uint8_t *ecdhe, size_t ecdhe_len, | 285 | const uint8_t *ecdhe, size_t ecdhe_len, |
259 | const struct tls13_secret *context) | 286 | const struct tls13_secret *context) |
260 | { | 287 | { |
261 | if (!secrets->init_done || !secrets->early_done || | 288 | if (!secrets->init_done || !secrets->early_done || |
@@ -263,8 +290,8 @@ tls13_derive_handshake_secrets(struct tls13_secrets *secrets, | |||
263 | return 0; | 290 | return 0; |
264 | 291 | ||
265 | if (!HKDF_extract(secrets->extracted_handshake.data, | 292 | if (!HKDF_extract(secrets->extracted_handshake.data, |
266 | &secrets->extracted_handshake.len, | 293 | &secrets->extracted_handshake.len, secrets->digest, |
267 | digest, ecdhe, ecdhe_len, secrets->derived_early.data, | 294 | ecdhe, ecdhe_len, secrets->derived_early.data, |
268 | secrets->derived_early.len)) | 295 | secrets->derived_early.len)) |
269 | return 0; | 296 | return 0; |
270 | 297 | ||
@@ -277,36 +304,40 @@ tls13_derive_handshake_secrets(struct tls13_secrets *secrets, | |||
277 | secrets->derived_early.len); | 304 | secrets->derived_early.len); |
278 | 305 | ||
279 | if (!tls13_derive_secret(&secrets->client_handshake_traffic, | 306 | if (!tls13_derive_secret(&secrets->client_handshake_traffic, |
280 | digest, &secrets->extracted_handshake, "c hs traffic", context)) | 307 | secrets->digest, &secrets->extracted_handshake, "c hs traffic", |
308 | context)) | ||
281 | return 0; | 309 | return 0; |
282 | if (!tls13_derive_secret(&secrets->server_handshake_traffic, | 310 | if (!tls13_derive_secret(&secrets->server_handshake_traffic, |
283 | digest, &secrets->extracted_handshake, "s hs traffic", context)) | 311 | secrets->digest, &secrets->extracted_handshake, "s hs traffic", |
312 | context)) | ||
284 | return 0; | 313 | return 0; |
285 | if (!tls13_derive_secret(&secrets->derived_handshake, | 314 | if (!tls13_derive_secret(&secrets->derived_handshake, |
286 | digest, &secrets->extracted_handshake, "derived", context)) | 315 | secrets->digest, &secrets->extracted_handshake, "derived", |
316 | context)) | ||
287 | return 0; | 317 | return 0; |
288 | 318 | ||
289 | /* RFC 8446 recommends */ | 319 | /* RFC 8446 recommends */ |
290 | if (!secrets->insecure) | 320 | if (!secrets->insecure) |
291 | explicit_bzero(secrets->extracted_handshake.data, | 321 | explicit_bzero(secrets->extracted_handshake.data, |
292 | secrets->extracted_handshake.len); | 322 | secrets->extracted_handshake.len); |
323 | |||
293 | secrets->handshake_done = 1; | 324 | secrets->handshake_done = 1; |
325 | |||
294 | return 1; | 326 | return 1; |
295 | } | 327 | } |
296 | 328 | ||
297 | int | 329 | int |
298 | tls13_derive_application_secrets(struct tls13_secrets *secrets, | 330 | tls13_derive_application_secrets(struct tls13_secrets *secrets, |
299 | const EVP_MD *digest, const struct tls13_secret *context) | 331 | const struct tls13_secret *context) |
300 | { | 332 | { |
301 | if (!secrets->init_done || !secrets->early_done || | 333 | if (!secrets->init_done || !secrets->early_done || |
302 | !secrets->handshake_done || secrets->schedule_done) | 334 | !secrets->handshake_done || secrets->schedule_done) |
303 | return 0; | 335 | return 0; |
304 | 336 | ||
305 | if (!HKDF_extract(secrets->extracted_master.data, | 337 | if (!HKDF_extract(secrets->extracted_master.data, |
306 | &secrets->extracted_master.len, | 338 | &secrets->extracted_master.len, secrets->digest, |
307 | digest, secrets->zeros.data, secrets->zeros.len, // XXX ? | 339 | secrets->zeros.data, secrets->zeros.len, |
308 | secrets->derived_handshake.data, | 340 | secrets->derived_handshake.data, secrets->derived_handshake.len)) |
309 | secrets->derived_handshake.len)) | ||
310 | return 0; | 341 | return 0; |
311 | 342 | ||
312 | if (secrets->extracted_master.len != secrets->zeros.len) | 343 | if (secrets->extracted_master.len != secrets->zeros.len) |
@@ -318,58 +349,52 @@ tls13_derive_application_secrets(struct tls13_secrets *secrets, | |||
318 | secrets->derived_handshake.len); | 349 | secrets->derived_handshake.len); |
319 | 350 | ||
320 | if (!tls13_derive_secret(&secrets->client_application_traffic, | 351 | if (!tls13_derive_secret(&secrets->client_application_traffic, |
321 | digest, &secrets->extracted_master, "c ap traffic", context)) | 352 | secrets->digest, &secrets->extracted_master, "c ap traffic", |
353 | context)) | ||
322 | return 0; | 354 | return 0; |
323 | if (!tls13_derive_secret(&secrets->server_application_traffic, | 355 | if (!tls13_derive_secret(&secrets->server_application_traffic, |
324 | digest, &secrets->extracted_master, "s ap traffic", context)) | 356 | secrets->digest, &secrets->extracted_master, "s ap traffic", |
357 | context)) | ||
325 | return 0; | 358 | return 0; |
326 | if (!tls13_derive_secret(&secrets->exporter_master, | 359 | if (!tls13_derive_secret(&secrets->exporter_master, |
327 | digest, &secrets->extracted_master, "exp master", context)) | 360 | secrets->digest, &secrets->extracted_master, "exp master", |
361 | context)) | ||
328 | return 0; | 362 | return 0; |
329 | if (!tls13_derive_secret(&secrets->resumption_master, | 363 | if (!tls13_derive_secret(&secrets->resumption_master, |
330 | digest, &secrets->extracted_master, "res master", context)) | 364 | secrets->digest, &secrets->extracted_master, "res master", |
365 | context)) | ||
331 | return 0; | 366 | return 0; |
332 | 367 | ||
333 | /* RFC 8446 recommends */ | 368 | /* RFC 8446 recommends */ |
334 | if (!secrets->insecure) | 369 | if (!secrets->insecure) |
335 | explicit_bzero(secrets->extracted_master.data, | 370 | explicit_bzero(secrets->extracted_master.data, |
336 | secrets->extracted_master.len); | 371 | secrets->extracted_master.len); |
372 | |||
337 | secrets->schedule_done = 1; | 373 | secrets->schedule_done = 1; |
374 | |||
338 | return 1; | 375 | return 1; |
339 | } | 376 | } |
340 | 377 | ||
341 | int | 378 | int |
342 | tls13_update_client_traffic_secret(struct tls13_secrets *secrets, | 379 | tls13_update_client_traffic_secret(struct tls13_secrets *secrets) |
343 | const EVP_MD *digest) | ||
344 | { | 380 | { |
345 | const struct tls13_secret empty = { | ||
346 | .data = "", | ||
347 | .len = 0, | ||
348 | }; | ||
349 | |||
350 | if (!secrets->init_done || !secrets->early_done || | 381 | if (!secrets->init_done || !secrets->early_done || |
351 | !secrets->handshake_done || !secrets->schedule_done) | 382 | !secrets->handshake_done || !secrets->schedule_done) |
352 | return 0; | 383 | return 0; |
353 | 384 | ||
354 | return tls13_hkdf_expand_label(&secrets->client_application_traffic, | 385 | return tls13_hkdf_expand_label(&secrets->client_application_traffic, |
355 | digest, &secrets->client_application_traffic, "traffic upd", | 386 | secrets->digest, &secrets->client_application_traffic, |
356 | &empty); | 387 | "traffic upd", &secrets->empty_hash); |
357 | } | 388 | } |
358 | 389 | ||
359 | int | 390 | int |
360 | tls13_update_server_traffic_secret(struct tls13_secrets *secrets, | 391 | tls13_update_server_traffic_secret(struct tls13_secrets *secrets) |
361 | const EVP_MD *digest) | ||
362 | { | 392 | { |
363 | const struct tls13_secret empty = { | ||
364 | .data = "", | ||
365 | .len = 0, | ||
366 | }; | ||
367 | |||
368 | if (!secrets->init_done || !secrets->early_done || | 393 | if (!secrets->init_done || !secrets->early_done || |
369 | !secrets->handshake_done || !secrets->schedule_done) | 394 | !secrets->handshake_done || !secrets->schedule_done) |
370 | return 0; | 395 | return 0; |
371 | 396 | ||
372 | return tls13_hkdf_expand_label(&secrets->server_application_traffic, | 397 | return tls13_hkdf_expand_label(&secrets->server_application_traffic, |
373 | digest, &secrets->server_application_traffic, "traffic upd", | 398 | secrets->digest, &secrets->server_application_traffic, |
374 | &empty); | 399 | "traffic upd", &secrets->empty_hash); |
375 | } | 400 | } |