diff options
Diffstat (limited to 'src/lib/libssl/tls12_record_layer.c')
-rw-r--r-- | src/lib/libssl/tls12_record_layer.c | 167 |
1 files changed, 110 insertions, 57 deletions
diff --git a/src/lib/libssl/tls12_record_layer.c b/src/lib/libssl/tls12_record_layer.c index f090e2d940..b7e891d268 100644 --- a/src/lib/libssl/tls12_record_layer.c +++ b/src/lib/libssl/tls12_record_layer.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls12_record_layer.c,v 1.18 2021/02/27 13:38:35 jsing Exp $ */ | 1 | /* $OpenBSD: tls12_record_layer.c,v 1.19 2021/02/27 14:20:50 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -33,10 +33,6 @@ struct tls12_record_protection { | |||
33 | uint8_t *mac_key; | 33 | uint8_t *mac_key; |
34 | size_t mac_key_len; | 34 | size_t mac_key_len; |
35 | 35 | ||
36 | /* | ||
37 | * XXX - for now these are just pointers to externally managed | ||
38 | * structs/memory. These should eventually be owned by the record layer. | ||
39 | */ | ||
40 | EVP_CIPHER_CTX *cipher_ctx; | 36 | EVP_CIPHER_CTX *cipher_ctx; |
41 | EVP_MD_CTX *hash_ctx; | 37 | EVP_MD_CTX *hash_ctx; |
42 | }; | 38 | }; |
@@ -58,6 +54,12 @@ tls12_record_protection_clear(struct tls12_record_protection *rp) | |||
58 | rp->aead_ctx = NULL; | 54 | rp->aead_ctx = NULL; |
59 | } | 55 | } |
60 | 56 | ||
57 | EVP_CIPHER_CTX_free(rp->cipher_ctx); | ||
58 | rp->cipher_ctx = NULL; | ||
59 | |||
60 | EVP_MD_CTX_free(rp->hash_ctx); | ||
61 | rp->hash_ctx = NULL; | ||
62 | |||
61 | freezero(rp->mac_key, rp->mac_key_len); | 63 | freezero(rp->mac_key, rp->mac_key_len); |
62 | rp->mac_key = NULL; | 64 | rp->mac_key = NULL; |
63 | rp->mac_key_len = 0; | 65 | rp->mac_key_len = 0; |
@@ -149,6 +151,9 @@ struct tls12_record_layer { | |||
149 | uint8_t alert_desc; | 151 | uint8_t alert_desc; |
150 | 152 | ||
151 | const EVP_AEAD *aead; | 153 | const EVP_AEAD *aead; |
154 | const EVP_CIPHER *cipher; | ||
155 | const EVP_MD *handshake_hash; | ||
156 | const EVP_MD *mac_hash; | ||
152 | 157 | ||
153 | /* Pointers to active record protection (memory is not owned). */ | 158 | /* Pointers to active record protection (memory is not owned). */ |
154 | struct tls12_record_protection *read; | 159 | struct tls12_record_protection *read; |
@@ -247,6 +252,16 @@ tls12_record_layer_set_aead(struct tls12_record_layer *rl, const EVP_AEAD *aead) | |||
247 | } | 252 | } |
248 | 253 | ||
249 | void | 254 | void |
255 | tls12_record_layer_set_cipher_hash(struct tls12_record_layer *rl, | ||
256 | const EVP_CIPHER *cipher, const EVP_MD *handshake_hash, | ||
257 | const EVP_MD *mac_hash) | ||
258 | { | ||
259 | rl->cipher = cipher; | ||
260 | rl->handshake_hash = handshake_hash; | ||
261 | rl->mac_hash = mac_hash; | ||
262 | } | ||
263 | |||
264 | void | ||
250 | tls12_record_layer_set_version(struct tls12_record_layer *rl, uint16_t version) | 265 | tls12_record_layer_set_version(struct tls12_record_layer *rl, uint16_t version) |
251 | { | 266 | { |
252 | rl->version = version; | 267 | rl->version = version; |
@@ -290,35 +305,15 @@ tls12_record_layer_write_epoch_done(struct tls12_record_layer *rl, uint16_t epoc | |||
290 | rl->write_previous = NULL; | 305 | rl->write_previous = NULL; |
291 | } | 306 | } |
292 | 307 | ||
293 | static void | ||
294 | tls12_record_layer_set_read_state(struct tls12_record_layer *rl, | ||
295 | EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac) | ||
296 | { | ||
297 | rl->read->cipher_ctx = cipher_ctx; | ||
298 | rl->read->hash_ctx = hash_ctx; | ||
299 | rl->read->stream_mac = stream_mac; | ||
300 | } | ||
301 | |||
302 | static void | ||
303 | tls12_record_layer_set_write_state(struct tls12_record_layer *rl, | ||
304 | EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac) | ||
305 | { | ||
306 | rl->write->cipher_ctx = cipher_ctx; | ||
307 | rl->write->hash_ctx = hash_ctx; | ||
308 | rl->write->stream_mac = stream_mac; | ||
309 | } | ||
310 | |||
311 | void | 308 | void |
312 | tls12_record_layer_clear_read_state(struct tls12_record_layer *rl) | 309 | tls12_record_layer_clear_read_state(struct tls12_record_layer *rl) |
313 | { | 310 | { |
314 | tls12_record_layer_set_read_state(rl, NULL, NULL, 0); | ||
315 | tls12_record_protection_clear(rl->read); | 311 | tls12_record_protection_clear(rl->read); |
316 | } | 312 | } |
317 | 313 | ||
318 | void | 314 | void |
319 | tls12_record_layer_clear_write_state(struct tls12_record_layer *rl) | 315 | tls12_record_layer_clear_write_state(struct tls12_record_layer *rl) |
320 | { | 316 | { |
321 | tls12_record_layer_set_write_state(rl, NULL, NULL, 0); | ||
322 | tls12_record_protection_clear(rl->write); | 317 | tls12_record_protection_clear(rl->write); |
323 | 318 | ||
324 | tls12_record_protection_free(rl->write_previous); | 319 | tls12_record_protection_free(rl->write_previous); |
@@ -326,48 +321,36 @@ tls12_record_layer_clear_write_state(struct tls12_record_layer *rl) | |||
326 | } | 321 | } |
327 | 322 | ||
328 | void | 323 | void |
329 | tls12_record_layer_reflect_seq_num(struct tls12_record_layer *rl) | 324 | tls12_record_layer_read_cipher_hash(struct tls12_record_layer *rl, |
330 | { | 325 | EVP_CIPHER_CTX **cipher, EVP_MD_CTX **hash) |
331 | memcpy(rl->write->seq_num, rl->read->seq_num, | ||
332 | sizeof(rl->write->seq_num)); | ||
333 | } | ||
334 | |||
335 | int | ||
336 | tls12_record_layer_set_read_cipher_hash(struct tls12_record_layer *rl, | ||
337 | EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac) | ||
338 | { | 326 | { |
339 | tls12_record_layer_set_read_state(rl, cipher_ctx, hash_ctx, | 327 | *cipher = rl->read->cipher_ctx; |
340 | stream_mac); | 328 | *hash = rl->read->hash_ctx; |
341 | |||
342 | return 1; | ||
343 | } | 329 | } |
344 | 330 | ||
345 | int | 331 | void |
346 | tls12_record_layer_set_write_cipher_hash(struct tls12_record_layer *rl, | 332 | tls12_record_layer_reflect_seq_num(struct tls12_record_layer *rl) |
347 | EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac) | ||
348 | { | 333 | { |
349 | tls12_record_layer_set_write_state(rl, cipher_ctx, hash_ctx, | 334 | memcpy(rl->write->seq_num, rl->read->seq_num, |
350 | stream_mac); | 335 | sizeof(rl->write->seq_num)); |
351 | |||
352 | return 1; | ||
353 | } | 336 | } |
354 | 337 | ||
355 | int | 338 | static int |
356 | tls12_record_layer_set_read_mac_key(struct tls12_record_layer *rl, | 339 | tls12_record_layer_set_mac_key(struct tls12_record_protection *rp, |
357 | const uint8_t *mac_key, size_t mac_key_len) | 340 | const uint8_t *mac_key, size_t mac_key_len) |
358 | { | 341 | { |
359 | freezero(rl->read->mac_key, rl->read->mac_key_len); | 342 | freezero(rp->mac_key, rp->mac_key_len); |
360 | rl->read->mac_key = NULL; | 343 | rp->mac_key = NULL; |
361 | rl->read->mac_key_len = 0; | 344 | rp->mac_key_len = 0; |
362 | 345 | ||
363 | if (mac_key == NULL || mac_key_len == 0) | 346 | if (mac_key == NULL || mac_key_len == 0) |
364 | return 1; | 347 | return 1; |
365 | 348 | ||
366 | if ((rl->read->mac_key = calloc(1, mac_key_len)) == NULL) | 349 | if ((rp->mac_key = calloc(1, mac_key_len)) == NULL) |
367 | return 0; | 350 | return 0; |
368 | 351 | ||
369 | memcpy(rl->read->mac_key, mac_key, mac_key_len); | 352 | memcpy(rp->mac_key, mac_key, mac_key_len); |
370 | rl->read->mac_key_len = mac_key_len; | 353 | rp->mac_key_len = mac_key_len; |
371 | 354 | ||
372 | return 1; | 355 | return 1; |
373 | } | 356 | } |
@@ -421,6 +404,76 @@ tls12_record_layer_ccs_aead(struct tls12_record_layer *rl, | |||
421 | } | 404 | } |
422 | 405 | ||
423 | static int | 406 | static int |
407 | tls12_record_layer_ccs_cipher(struct tls12_record_layer *rl, | ||
408 | struct tls12_record_protection *rp, int is_write, const uint8_t *mac_key, | ||
409 | size_t mac_key_len, const uint8_t *key, size_t key_len, const uint8_t *iv, | ||
410 | size_t iv_len) | ||
411 | { | ||
412 | EVP_PKEY *mac_pkey = NULL; | ||
413 | int gost_param_nid; | ||
414 | int mac_type; | ||
415 | int ret = 0; | ||
416 | |||
417 | mac_type = EVP_PKEY_HMAC; | ||
418 | rp->stream_mac = 0; | ||
419 | |||
420 | /* Special handling for GOST... */ | ||
421 | if (EVP_MD_type(rl->mac_hash) == NID_id_Gost28147_89_MAC) { | ||
422 | if (mac_key_len != 32) | ||
423 | goto err; | ||
424 | mac_type = EVP_PKEY_GOSTIMIT; | ||
425 | rp->stream_mac = 1; | ||
426 | } else { | ||
427 | if (EVP_MD_size(rl->mac_hash) != mac_key_len) | ||
428 | goto err; | ||
429 | } | ||
430 | |||
431 | if ((rp->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) | ||
432 | goto err; | ||
433 | if ((rp->hash_ctx = EVP_MD_CTX_new()) == NULL) | ||
434 | goto err; | ||
435 | |||
436 | if (!tls12_record_layer_set_mac_key(rp, mac_key, mac_key_len)) | ||
437 | goto err; | ||
438 | |||
439 | if ((mac_pkey = EVP_PKEY_new_mac_key(mac_type, NULL, mac_key, | ||
440 | mac_key_len)) == NULL) | ||
441 | goto err; | ||
442 | |||
443 | if (!EVP_CipherInit_ex(rp->cipher_ctx, rl->cipher, NULL, key, iv, | ||
444 | is_write)) | ||
445 | goto err; | ||
446 | |||
447 | if (EVP_DigestSignInit(rp->hash_ctx, NULL, rl->mac_hash, NULL, | ||
448 | mac_pkey) <= 0) | ||
449 | goto err; | ||
450 | |||
451 | /* More special handling for GOST... */ | ||
452 | if (EVP_CIPHER_type(rl->cipher) == NID_gost89_cnt) { | ||
453 | gost_param_nid = NID_id_tc26_gost_28147_param_Z; | ||
454 | if (EVP_MD_type(rl->handshake_hash) == NID_id_GostR3411_94) | ||
455 | gost_param_nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; | ||
456 | |||
457 | if (EVP_CIPHER_CTX_ctrl(rp->cipher_ctx, EVP_CTRL_GOST_SET_SBOX, | ||
458 | gost_param_nid, 0) <= 0) | ||
459 | goto err; | ||
460 | |||
461 | if (EVP_MD_type(rl->mac_hash) == NID_id_Gost28147_89_MAC) { | ||
462 | if (EVP_MD_CTX_ctrl(rp->hash_ctx, EVP_MD_CTRL_GOST_SET_SBOX, | ||
463 | gost_param_nid, 0) <= 0) | ||
464 | goto err; | ||
465 | } | ||
466 | } | ||
467 | |||
468 | ret = 1; | ||
469 | |||
470 | err: | ||
471 | EVP_PKEY_free(mac_pkey); | ||
472 | |||
473 | return ret; | ||
474 | } | ||
475 | |||
476 | static int | ||
424 | tls12_record_layer_change_cipher_state(struct tls12_record_layer *rl, | 477 | tls12_record_layer_change_cipher_state(struct tls12_record_layer *rl, |
425 | struct tls12_record_protection *rp, int is_write, const uint8_t *mac_key, | 478 | struct tls12_record_protection *rp, int is_write, const uint8_t *mac_key, |
426 | size_t mac_key_len, const uint8_t *key, size_t key_len, const uint8_t *iv, | 479 | size_t mac_key_len, const uint8_t *key, size_t key_len, const uint8_t *iv, |
@@ -433,11 +486,11 @@ tls12_record_layer_change_cipher_state(struct tls12_record_layer *rl, | |||
433 | if (mac_key_len > INT_MAX || key_len > INT_MAX || iv_len > INT_MAX) | 486 | if (mac_key_len > INT_MAX || key_len > INT_MAX || iv_len > INT_MAX) |
434 | return 0; | 487 | return 0; |
435 | 488 | ||
436 | /* XXX - only aead for now. */ | 489 | if (rl->aead != NULL) |
437 | if (rl->aead == NULL) | 490 | return tls12_record_layer_ccs_aead(rl, rp, is_write, mac_key, |
438 | return 1; | 491 | mac_key_len, key, key_len, iv, iv_len); |
439 | 492 | ||
440 | return tls12_record_layer_ccs_aead(rl, rp, is_write, mac_key, | 493 | return tls12_record_layer_ccs_cipher(rl, rp, is_write, mac_key, |
441 | mac_key_len, key, key_len, iv, iv_len); | 494 | mac_key_len, key, key_len, iv, iv_len); |
442 | } | 495 | } |
443 | 496 | ||