diff options
Diffstat (limited to 'src/lib/libssl/tls12_record_layer.c')
-rw-r--r-- | src/lib/libssl/tls12_record_layer.c | 348 |
1 files changed, 343 insertions, 5 deletions
diff --git a/src/lib/libssl/tls12_record_layer.c b/src/lib/libssl/tls12_record_layer.c index 10d0f1194b..56ff94d95c 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.4 2020/09/16 17:15:01 jsing Exp $ */ | 1 | /* $OpenBSD: tls12_record_layer.c,v 1.5 2020/10/03 17:35:17 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -25,6 +25,8 @@ struct tls12_record_layer { | |||
25 | uint16_t version; | 25 | uint16_t version; |
26 | int dtls; | 26 | int dtls; |
27 | 27 | ||
28 | uint8_t alert_desc; | ||
29 | |||
28 | uint16_t read_epoch; | 30 | uint16_t read_epoch; |
29 | uint16_t write_epoch; | 31 | uint16_t write_epoch; |
30 | 32 | ||
@@ -43,6 +45,9 @@ struct tls12_record_layer { | |||
43 | EVP_CIPHER_CTX *write_cipher_ctx; | 45 | EVP_CIPHER_CTX *write_cipher_ctx; |
44 | EVP_MD_CTX *write_hash_ctx; | 46 | EVP_MD_CTX *write_hash_ctx; |
45 | 47 | ||
48 | const uint8_t *read_mac_key; | ||
49 | size_t read_mac_key_len; | ||
50 | |||
46 | uint8_t *read_seq_num; | 51 | uint8_t *read_seq_num; |
47 | uint8_t *write_seq_num; | 52 | uint8_t *write_seq_num; |
48 | }; | 53 | }; |
@@ -65,6 +70,12 @@ tls12_record_layer_free(struct tls12_record_layer *rl) | |||
65 | } | 70 | } |
66 | 71 | ||
67 | void | 72 | void |
73 | tls12_record_layer_alert(struct tls12_record_layer *rl, uint8_t *alert_desc) | ||
74 | { | ||
75 | *alert_desc = rl->alert_desc; | ||
76 | } | ||
77 | |||
78 | void | ||
68 | tls12_record_layer_set_version(struct tls12_record_layer *rl, uint16_t version) | 79 | tls12_record_layer_set_version(struct tls12_record_layer *rl, uint16_t version) |
69 | { | 80 | { |
70 | rl->version = version; | 81 | rl->version = version; |
@@ -111,6 +122,7 @@ void | |||
111 | tls12_record_layer_clear_read_state(struct tls12_record_layer *rl) | 122 | tls12_record_layer_clear_read_state(struct tls12_record_layer *rl) |
112 | { | 123 | { |
113 | tls12_record_layer_set_read_state(rl, NULL, NULL, NULL, 0); | 124 | tls12_record_layer_set_read_state(rl, NULL, NULL, NULL, 0); |
125 | tls12_record_layer_set_read_mac_key(rl, NULL, 0); | ||
114 | rl->read_seq_num = NULL; | 126 | rl->read_seq_num = NULL; |
115 | } | 127 | } |
116 | 128 | ||
@@ -173,6 +185,16 @@ tls12_record_layer_set_write_cipher_hash(struct tls12_record_layer *rl, | |||
173 | return 1; | 185 | return 1; |
174 | } | 186 | } |
175 | 187 | ||
188 | int | ||
189 | tls12_record_layer_set_read_mac_key(struct tls12_record_layer *rl, | ||
190 | const uint8_t *mac_key, size_t mac_key_len) | ||
191 | { | ||
192 | rl->read_mac_key = mac_key; | ||
193 | rl->read_mac_key_len = mac_key_len; | ||
194 | |||
195 | return 1; | ||
196 | } | ||
197 | |||
176 | static int | 198 | static int |
177 | tls12_record_layer_build_seq_num(struct tls12_record_layer *rl, CBB *cbb, | 199 | tls12_record_layer_build_seq_num(struct tls12_record_layer *rl, CBB *cbb, |
178 | uint16_t epoch, uint8_t *seq_num, size_t seq_num_len) | 200 | uint16_t epoch, uint8_t *seq_num, size_t seq_num_len) |
@@ -234,7 +256,7 @@ tls12_record_layer_mac(struct tls12_record_layer *rl, CBB *cbb, | |||
234 | { | 256 | { |
235 | EVP_MD_CTX *mac_ctx = NULL; | 257 | EVP_MD_CTX *mac_ctx = NULL; |
236 | uint8_t *header = NULL; | 258 | uint8_t *header = NULL; |
237 | size_t header_len; | 259 | size_t header_len = 0; |
238 | size_t mac_len; | 260 | size_t mac_len; |
239 | uint8_t *mac; | 261 | uint8_t *mac; |
240 | int ret = 0; | 262 | int ret = 0; |
@@ -258,6 +280,8 @@ tls12_record_layer_mac(struct tls12_record_layer *rl, CBB *cbb, | |||
258 | goto err; | 280 | goto err; |
259 | if (EVP_DigestSignFinal(mac_ctx, mac, &mac_len) <= 0) | 281 | if (EVP_DigestSignFinal(mac_ctx, mac, &mac_len) <= 0) |
260 | goto err; | 282 | goto err; |
283 | if (mac_len == 0) | ||
284 | goto err; | ||
261 | 285 | ||
262 | if (stream_mac) { | 286 | if (stream_mac) { |
263 | if (!EVP_MD_CTX_copy(hash_ctx, mac_ctx)) | 287 | if (!EVP_MD_CTX_copy(hash_ctx, mac_ctx)) |
@@ -269,12 +293,67 @@ tls12_record_layer_mac(struct tls12_record_layer *rl, CBB *cbb, | |||
269 | 293 | ||
270 | err: | 294 | err: |
271 | EVP_MD_CTX_free(mac_ctx); | 295 | EVP_MD_CTX_free(mac_ctx); |
272 | free(header); | 296 | freezero(header, header_len); |
273 | 297 | ||
274 | return ret; | 298 | return ret; |
275 | } | 299 | } |
276 | 300 | ||
277 | static int | 301 | static int |
302 | tls12_record_layer_read_mac_cbc(struct tls12_record_layer *rl, CBB *cbb, | ||
303 | uint8_t content_type, const uint8_t *content, size_t content_len, | ||
304 | size_t mac_len, size_t padding_len) | ||
305 | { | ||
306 | uint8_t *header = NULL; | ||
307 | size_t header_len = 0; | ||
308 | uint8_t *mac = NULL; | ||
309 | size_t out_mac_len = 0; | ||
310 | int ret = 0; | ||
311 | |||
312 | /* | ||
313 | * Must be constant time to avoid leaking details about CBC padding. | ||
314 | */ | ||
315 | |||
316 | if (!ssl3_cbc_record_digest_supported(rl->read_hash_ctx)) | ||
317 | goto err; | ||
318 | |||
319 | if (!tls12_record_layer_pseudo_header(rl, content_type, content_len, | ||
320 | rl->read_epoch, rl->read_seq_num, SSL3_SEQUENCE_SIZE, | ||
321 | &header, &header_len)) | ||
322 | goto err; | ||
323 | |||
324 | if (!CBB_add_space(cbb, &mac, mac_len)) | ||
325 | goto err; | ||
326 | if (!ssl3_cbc_digest_record(rl->read_hash_ctx, mac, &out_mac_len, header, | ||
327 | content, content_len + mac_len, content_len + mac_len + padding_len, | ||
328 | rl->read_mac_key, rl->read_mac_key_len)) | ||
329 | goto err; | ||
330 | if (mac_len != out_mac_len) | ||
331 | goto err; | ||
332 | |||
333 | ret = 1; | ||
334 | |||
335 | err: | ||
336 | freezero(header, header_len); | ||
337 | |||
338 | return ret; | ||
339 | } | ||
340 | |||
341 | static int | ||
342 | tls12_record_layer_read_mac(struct tls12_record_layer *rl, CBB *cbb, | ||
343 | uint8_t content_type, const uint8_t *content, size_t content_len) | ||
344 | { | ||
345 | EVP_CIPHER_CTX *enc = rl->read_cipher_ctx; | ||
346 | size_t out_len; | ||
347 | |||
348 | if (EVP_CIPHER_CTX_mode(enc) == EVP_CIPH_CBC_MODE) | ||
349 | return 0; | ||
350 | |||
351 | return tls12_record_layer_mac(rl, cbb, rl->read_hash_ctx, | ||
352 | rl->read_stream_mac, rl->read_epoch, rl->read_seq_num, | ||
353 | SSL3_SEQUENCE_SIZE, content_type, content, content_len, &out_len); | ||
354 | } | ||
355 | |||
356 | static int | ||
278 | tls12_record_layer_write_mac(struct tls12_record_layer *rl, CBB *cbb, | 357 | tls12_record_layer_write_mac(struct tls12_record_layer *rl, CBB *cbb, |
279 | uint8_t content_type, const uint8_t *content, size_t content_len, | 358 | uint8_t content_type, const uint8_t *content, size_t content_len, |
280 | size_t *out_len) | 359 | size_t *out_len) |
@@ -286,7 +365,8 @@ tls12_record_layer_write_mac(struct tls12_record_layer *rl, CBB *cbb, | |||
286 | 365 | ||
287 | static int | 366 | static int |
288 | tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, | 367 | tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, |
289 | const SSL_AEAD_CTX *aead, uint8_t *seq_num, uint8_t **out, size_t *out_len) | 368 | const SSL_AEAD_CTX *aead, const uint8_t *seq_num, |
369 | uint8_t **out, size_t *out_len) | ||
290 | { | 370 | { |
291 | CBB cbb; | 371 | CBB cbb; |
292 | 372 | ||
@@ -314,7 +394,8 @@ tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, | |||
314 | 394 | ||
315 | static int | 395 | static int |
316 | tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, | 396 | tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, |
317 | const SSL_AEAD_CTX *aead, uint8_t *seq_num, uint8_t **out, size_t *out_len) | 397 | const SSL_AEAD_CTX *aead, const uint8_t *seq_num, |
398 | uint8_t **out, size_t *out_len) | ||
318 | { | 399 | { |
319 | uint8_t *nonce = NULL; | 400 | uint8_t *nonce = NULL; |
320 | size_t nonce_len = 0; | 401 | size_t nonce_len = 0; |
@@ -357,6 +438,263 @@ tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, | |||
357 | } | 438 | } |
358 | 439 | ||
359 | static int | 440 | static int |
441 | tls12_record_layer_open_record_plaintext(struct tls12_record_layer *rl, | ||
442 | uint8_t content_type, CBS *fragment, uint8_t **out, size_t *out_len) | ||
443 | { | ||
444 | if (rl->read_aead_ctx != NULL || rl->read_cipher_ctx != NULL) | ||
445 | return 0; | ||
446 | |||
447 | /* XXX - decrypt/process in place for now. */ | ||
448 | *out = (uint8_t *)CBS_data(fragment); | ||
449 | *out_len = CBS_len(fragment); | ||
450 | |||
451 | return 1; | ||
452 | } | ||
453 | |||
454 | static int | ||
455 | tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl, | ||
456 | uint8_t content_type, CBS *fragment, uint8_t **out, size_t *out_len) | ||
457 | { | ||
458 | const SSL_AEAD_CTX *aead = rl->read_aead_ctx; | ||
459 | uint8_t *header = NULL, *nonce = NULL; | ||
460 | size_t header_len = 0, nonce_len = 0; | ||
461 | uint8_t *plain; | ||
462 | size_t plain_len; | ||
463 | uint16_t epoch = 0; | ||
464 | CBS var_nonce; | ||
465 | int ret = 0; | ||
466 | |||
467 | /* XXX - move to nonce allocated in record layer, matching TLSv1.3 */ | ||
468 | if (aead->xor_fixed_nonce) { | ||
469 | if (!tls12_record_layer_aead_xored_nonce(rl, aead, | ||
470 | rl->read_seq_num, &nonce, &nonce_len)) | ||
471 | goto err; | ||
472 | } else if (aead->variable_nonce_in_record) { | ||
473 | if (!CBS_get_bytes(fragment, &var_nonce, | ||
474 | aead->variable_nonce_len)) | ||
475 | goto err; | ||
476 | if (!tls12_record_layer_aead_concat_nonce(rl, aead, | ||
477 | CBS_data(&var_nonce), &nonce, &nonce_len)) | ||
478 | goto err; | ||
479 | } else { | ||
480 | if (!tls12_record_layer_aead_concat_nonce(rl, aead, | ||
481 | rl->read_seq_num, &nonce, &nonce_len)) | ||
482 | goto err; | ||
483 | } | ||
484 | |||
485 | /* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */ | ||
486 | if (CBS_len(fragment) < aead->tag_len) { | ||
487 | rl->alert_desc = SSL_AD_BAD_RECORD_MAC; | ||
488 | goto err; | ||
489 | } | ||
490 | if (CBS_len(fragment) > SSL3_RT_MAX_ENCRYPTED_LENGTH) { | ||
491 | rl->alert_desc = SSL_AD_RECORD_OVERFLOW; | ||
492 | goto err; | ||
493 | } | ||
494 | |||
495 | /* XXX - decrypt/process in place for now. */ | ||
496 | plain = (uint8_t *)CBS_data(fragment); | ||
497 | plain_len = CBS_len(fragment) - aead->tag_len; | ||
498 | |||
499 | if (!tls12_record_layer_pseudo_header(rl, content_type, plain_len, | ||
500 | epoch, rl->read_seq_num, SSL3_SEQUENCE_SIZE, &header, &header_len)) | ||
501 | goto err; | ||
502 | |||
503 | if (!EVP_AEAD_CTX_open(&aead->ctx, plain, out_len, plain_len, | ||
504 | nonce, nonce_len, CBS_data(fragment), CBS_len(fragment), | ||
505 | header, header_len)) { | ||
506 | rl->alert_desc = SSL_AD_BAD_RECORD_MAC; | ||
507 | goto err; | ||
508 | } | ||
509 | |||
510 | if (*out_len > SSL3_RT_MAX_PLAIN_LENGTH) { | ||
511 | rl->alert_desc = SSL_AD_RECORD_OVERFLOW; | ||
512 | goto err; | ||
513 | } | ||
514 | |||
515 | if (*out_len != plain_len) | ||
516 | goto err; | ||
517 | |||
518 | *out = plain; | ||
519 | |||
520 | ret = 1; | ||
521 | |||
522 | err: | ||
523 | freezero(header, header_len); | ||
524 | freezero(nonce, nonce_len); | ||
525 | |||
526 | return ret; | ||
527 | } | ||
528 | |||
529 | static int | ||
530 | tls12_record_layer_open_record_protected_cipher(struct tls12_record_layer *rl, | ||
531 | uint8_t content_type, CBS *fragment, uint8_t **out, size_t *out_len) | ||
532 | { | ||
533 | EVP_CIPHER_CTX *enc = rl->read_cipher_ctx; | ||
534 | SSL3_RECORD_INTERNAL rrec; | ||
535 | int block_size, eiv_len; | ||
536 | uint8_t *mac = NULL; | ||
537 | int mac_len = 0; | ||
538 | uint8_t *out_mac = NULL; | ||
539 | size_t out_mac_len = 0; | ||
540 | uint8_t *plain; | ||
541 | size_t plain_len; | ||
542 | size_t min_len; | ||
543 | CBB cbb_mac; | ||
544 | int ret = 0; | ||
545 | |||
546 | memset(&cbb_mac, 0, sizeof(cbb_mac)); | ||
547 | |||
548 | block_size = EVP_CIPHER_CTX_block_size(enc); | ||
549 | if (block_size < 0 || block_size > EVP_MAX_BLOCK_LENGTH) | ||
550 | goto err; | ||
551 | |||
552 | /* Determine explicit IV length. */ | ||
553 | eiv_len = 0; | ||
554 | if (rl->version != TLS1_VERSION && | ||
555 | EVP_CIPHER_CTX_mode(enc) == EVP_CIPH_CBC_MODE) | ||
556 | eiv_len = EVP_CIPHER_CTX_iv_length(enc); | ||
557 | if (eiv_len < 0 || eiv_len > EVP_MAX_IV_LENGTH) | ||
558 | goto err; | ||
559 | |||
560 | mac_len = 0; | ||
561 | if (rl->read_hash_ctx != NULL) { | ||
562 | mac_len = EVP_MD_CTX_size(rl->read_hash_ctx); | ||
563 | if (mac_len <= 0 || mac_len > EVP_MAX_MD_SIZE) | ||
564 | goto err; | ||
565 | } | ||
566 | |||
567 | /* CBC has at least one padding byte. */ | ||
568 | min_len = eiv_len + mac_len; | ||
569 | if (EVP_CIPHER_CTX_mode(enc) == EVP_CIPH_CBC_MODE) | ||
570 | min_len += 1; | ||
571 | |||
572 | if (CBS_len(fragment) < min_len) { | ||
573 | rl->alert_desc = SSL_AD_BAD_RECORD_MAC; | ||
574 | goto err; | ||
575 | } | ||
576 | if (CBS_len(fragment) > SSL3_RT_MAX_ENCRYPTED_LENGTH) { | ||
577 | rl->alert_desc = SSL_AD_RECORD_OVERFLOW; | ||
578 | goto err; | ||
579 | } | ||
580 | if (CBS_len(fragment) % block_size != 0) { | ||
581 | rl->alert_desc = SSL_AD_BAD_RECORD_MAC; | ||
582 | goto err; | ||
583 | } | ||
584 | |||
585 | /* XXX - decrypt/process in place for now. */ | ||
586 | plain = (uint8_t *)CBS_data(fragment); | ||
587 | plain_len = CBS_len(fragment); | ||
588 | |||
589 | if (!EVP_Cipher(enc, plain, CBS_data(fragment), plain_len)) | ||
590 | goto err; | ||
591 | |||
592 | rrec.data = plain; | ||
593 | rrec.input = plain; | ||
594 | rrec.length = plain_len; | ||
595 | |||
596 | /* | ||
597 | * We now have to remove padding, extract MAC, calculate MAC | ||
598 | * and compare MAC in constant time. | ||
599 | */ | ||
600 | if (block_size > 1) | ||
601 | ssl3_cbc_remove_padding(&rrec, eiv_len, mac_len); | ||
602 | |||
603 | if ((mac = calloc(1, mac_len)) == NULL) | ||
604 | goto err; | ||
605 | |||
606 | if (!CBB_init(&cbb_mac, EVP_MAX_MD_SIZE)) | ||
607 | goto err; | ||
608 | if (EVP_CIPHER_CTX_mode(enc) == EVP_CIPH_CBC_MODE) { | ||
609 | ssl3_cbc_copy_mac(mac, &rrec, mac_len, rrec.length + | ||
610 | rrec.padding_length); | ||
611 | rrec.length -= mac_len; | ||
612 | if (!tls12_record_layer_read_mac_cbc(rl, &cbb_mac, content_type, | ||
613 | rrec.input, rrec.length, mac_len, rrec.padding_length)) | ||
614 | goto err; | ||
615 | } else { | ||
616 | rrec.length -= mac_len; | ||
617 | memcpy(mac, rrec.data + rrec.length, mac_len); | ||
618 | if (!tls12_record_layer_read_mac(rl, &cbb_mac, content_type, | ||
619 | rrec.input, rrec.length)) | ||
620 | goto err; | ||
621 | } | ||
622 | if (!CBB_finish(&cbb_mac, &out_mac, &out_mac_len)) | ||
623 | goto err; | ||
624 | if (mac_len != out_mac_len) | ||
625 | goto err; | ||
626 | |||
627 | if (timingsafe_memcmp(mac, out_mac, mac_len) != 0) { | ||
628 | rl->alert_desc = SSL_AD_BAD_RECORD_MAC; | ||
629 | goto err; | ||
630 | } | ||
631 | |||
632 | if (rrec.length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_len) { | ||
633 | rl->alert_desc = SSL_AD_BAD_RECORD_MAC; | ||
634 | goto err; | ||
635 | } | ||
636 | if (rrec.length > SSL3_RT_MAX_PLAIN_LENGTH) { | ||
637 | rl->alert_desc = SSL_AD_RECORD_OVERFLOW; | ||
638 | goto err; | ||
639 | } | ||
640 | |||
641 | *out = rrec.data; | ||
642 | *out_len = rrec.length; | ||
643 | |||
644 | ret = 1; | ||
645 | |||
646 | err: | ||
647 | CBB_cleanup(&cbb_mac); | ||
648 | freezero(mac, mac_len); | ||
649 | freezero(out_mac, out_mac_len); | ||
650 | |||
651 | return ret; | ||
652 | } | ||
653 | |||
654 | int | ||
655 | tls12_record_layer_open_record(struct tls12_record_layer *rl, uint8_t *buf, | ||
656 | size_t buf_len, uint8_t **out, size_t *out_len) | ||
657 | { | ||
658 | CBS cbs, fragment, seq_no; | ||
659 | uint16_t epoch, version; | ||
660 | uint8_t content_type; | ||
661 | |||
662 | CBS_init(&cbs, buf, buf_len); | ||
663 | |||
664 | if (!CBS_get_u8(&cbs, &content_type)) | ||
665 | return 0; | ||
666 | if (!CBS_get_u16(&cbs, &version)) | ||
667 | return 0; | ||
668 | if (rl->dtls) { | ||
669 | if (!CBS_get_u16(&cbs, &epoch)) | ||
670 | return 0; | ||
671 | if (!CBS_get_bytes(&cbs, &seq_no, 6)) | ||
672 | return 0; | ||
673 | } | ||
674 | if (!CBS_get_u16_length_prefixed(&cbs, &fragment)) | ||
675 | return 0; | ||
676 | |||
677 | if (rl->read_aead_ctx != NULL) { | ||
678 | if (!tls12_record_layer_open_record_protected_aead(rl, | ||
679 | content_type, &fragment, out, out_len)) | ||
680 | return 0; | ||
681 | } else if (rl->read_cipher_ctx != NULL) { | ||
682 | if (!tls12_record_layer_open_record_protected_cipher(rl, | ||
683 | content_type, &fragment, out, out_len)) | ||
684 | return 0; | ||
685 | } else { | ||
686 | if (!tls12_record_layer_open_record_plaintext(rl, | ||
687 | content_type, &fragment, out, out_len)) | ||
688 | return 0; | ||
689 | } | ||
690 | |||
691 | if (!rl->dtls) | ||
692 | tls1_record_sequence_increment(rl->read_seq_num); | ||
693 | |||
694 | return 1; | ||
695 | } | ||
696 | |||
697 | static int | ||
360 | tls12_record_layer_seal_record_plaintext(struct tls12_record_layer *rl, | 698 | tls12_record_layer_seal_record_plaintext(struct tls12_record_layer *rl, |
361 | uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out) | 699 | uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out) |
362 | { | 700 | { |