diff options
author | jsing <> | 2020-11-16 18:55:15 +0000 |
---|---|---|
committer | jsing <> | 2020-11-16 18:55:15 +0000 |
commit | 7edbb85fb63bc248e3633a6d70bd4e49c811e451 (patch) | |
tree | 23027db55bc9d45c4690d13e3be7302ff83c4055 /src/lib/libssl/tls13_lib.c | |
parent | abffca736d5ed1aaca940a97ae97979bc46699f8 (diff) | |
download | openbsd-7edbb85fb63bc248e3633a6d70bd4e49c811e451.tar.gz openbsd-7edbb85fb63bc248e3633a6d70bd4e49c811e451.tar.bz2 openbsd-7edbb85fb63bc248e3633a6d70bd4e49c811e451.zip |
Implement exporter for TLSv1.3.
This implements the key material exporter for TLSv1.3, as defined in
RFC8446 section 7.5.
Issue reported by nmathewson on github.
ok inoguchi@ tb@
Diffstat (limited to '')
-rw-r--r-- | src/lib/libssl/tls13_lib.c | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/src/lib/libssl/tls13_lib.c b/src/lib/libssl/tls13_lib.c index 590426ad8a..6b6ddce4d6 100644 --- a/src/lib/libssl/tls13_lib.c +++ b/src/lib/libssl/tls13_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_lib.c,v 1.54 2020/09/11 15:03:36 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_lib.c,v 1.55 2020/11/16 18:55:15 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2019 Bob Beck <beck@openbsd.org> | 4 | * Copyright (c) 2019 Bob Beck <beck@openbsd.org> |
@@ -579,3 +579,75 @@ tls13_clienthello_hash_validate(struct tls13_ctx *ctx) | |||
579 | return 1; | 579 | return 1; |
580 | } | 580 | } |
581 | 581 | ||
582 | int | ||
583 | tls13_exporter(struct tls13_ctx *ctx, const uint8_t *label, size_t label_len, | ||
584 | const uint8_t *context_value, size_t context_value_len, uint8_t *out, | ||
585 | size_t out_len) | ||
586 | { | ||
587 | struct tls13_secret context, export_out, export_secret; | ||
588 | struct tls13_secrets *secrets = ctx->hs->secrets; | ||
589 | EVP_MD_CTX *md_ctx = NULL; | ||
590 | unsigned int md_out_len; | ||
591 | int md_len; | ||
592 | int ret = 0; | ||
593 | |||
594 | /* | ||
595 | * RFC 8446 Section 7.5. | ||
596 | */ | ||
597 | |||
598 | memset(&context, 0, sizeof(context)); | ||
599 | memset(&export_secret, 0, sizeof(export_secret)); | ||
600 | |||
601 | export_out.data = out; | ||
602 | export_out.len = out_len; | ||
603 | |||
604 | if (!ctx->handshake_completed) | ||
605 | return 0; | ||
606 | |||
607 | md_len = EVP_MD_size(secrets->digest); | ||
608 | if (md_len <= 0 || md_len > EVP_MAX_MD_SIZE) | ||
609 | goto err; | ||
610 | |||
611 | if ((export_secret.data = calloc(1, md_len)) == NULL) | ||
612 | goto err; | ||
613 | export_secret.len = md_len; | ||
614 | |||
615 | if ((context.data = calloc(1, md_len)) == NULL) | ||
616 | goto err; | ||
617 | context.len = md_len; | ||
618 | |||
619 | /* In TLSv1.3 no context is equivalent to an empty context. */ | ||
620 | if (context_value == NULL) { | ||
621 | context_value = ""; | ||
622 | context_value_len = 0; | ||
623 | } | ||
624 | |||
625 | if ((md_ctx = EVP_MD_CTX_new()) == NULL) | ||
626 | goto err; | ||
627 | if (!EVP_DigestInit_ex(md_ctx, secrets->digest, NULL)) | ||
628 | goto err; | ||
629 | if (!EVP_DigestUpdate(md_ctx, context_value, context_value_len)) | ||
630 | goto err; | ||
631 | if (!EVP_DigestFinal_ex(md_ctx, context.data, &md_out_len)) | ||
632 | goto err; | ||
633 | if (md_len != md_out_len) | ||
634 | goto err; | ||
635 | |||
636 | if (!tls13_derive_secret_with_label_length(&export_secret, | ||
637 | secrets->digest, &secrets->exporter_master, label, label_len, | ||
638 | &secrets->empty_hash)) | ||
639 | goto err; | ||
640 | |||
641 | if (!tls13_hkdf_expand_label(&export_out, secrets->digest, | ||
642 | &export_secret, "exporter", &context)) | ||
643 | goto err; | ||
644 | |||
645 | ret = 1; | ||
646 | |||
647 | err: | ||
648 | EVP_MD_CTX_free(md_ctx); | ||
649 | freezero(context.data, context.len); | ||
650 | freezero(export_secret.data, export_secret.len); | ||
651 | |||
652 | return ret; | ||
653 | } | ||