Commit b38ede80 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa Committed by Matt Caswell
Browse files

Export keying material using early exporter master secret



This commit adds SSL_export_keying_material_early() which exports
keying material using early exporter master secret.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
Reviewed-by: default avatarMatt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5252)
parent e454f3ad
Loading
Loading
Loading
Loading
+27 −4
Original line number Diff line number Diff line
@@ -2,7 +2,9 @@

=head1 NAME

SSL_export_keying_material - obtain keying material for application use
SSL_export_keying_material,
SSL_export_keying_material_early
- obtain keying material for application use

=head1 SYNOPSIS

@@ -13,14 +15,29 @@ SSL_export_keying_material - obtain keying material for application use
                                const unsigned char *context,
                                size_t contextlen, int use_context);

 int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
                                      const char *label, size_t llen,
                                      const unsigned char *context,
                                      size_t contextlen);

=head1 DESCRIPTION

During the creation of a TLS or DTLS connection shared keying material is
established between the two endpoints. The function SSL_export_keying_material()
enables an application to use some of this keying material for its own purposes
in accordance with RFC5705 (for TLSv1.2 and below) or RFCXXXX (for TLSv1.3).
established between the two endpoints. The functions
SSL_export_keying_material() and SSL_export_keying_material_early() enable an
application to use some of this keying material for its own purposes in
accordance with RFC5705 (for TLSv1.2 and below) or RFCXXXX (for TLSv1.3).
TODO(TLS1.3): Update the RFC number when the RFC is published.

SSL_export_keying_material() derives keying material using
the F<exporter_master_secret> established in the handshake.

SSL_export_keying_material_early() is only usable with TLSv1.3, and derives
keying material using the F<early_exporter_master_secret> (as defined in the
TLS 1.3 RFC). For the client, the F<early_exporter_master_secret> is only
available when the client attempts to send 0-RTT data. For the server, it is
only available when the server accepts 0-RTT data.

An application may need to securely establish the context within which this
keying material will be used. For example this may include identifiers for the
application session, application algorithms or parameters, or the lifetime of
@@ -52,6 +69,12 @@ above. Attempting to use it in SSLv3 will result in an error.

SSL_export_keying_material() returns 0 or -1 on failure or 1 on success.

SSL_export_keying_material_early() returns 0 on failure or 1 on success.

=head1 HISTORY

SSL_export_keying_material_early() was first added in OpenSSL 1.1.1.

=head1 COPYRIGHT

Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+13 −0
Original line number Diff line number Diff line
@@ -232,6 +232,19 @@ __owur int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
                                      const unsigned char *context,
                                      size_t contextlen, int use_context);

/*
 * SSL_export_keying_material_early exports a value derived from the
 * early exporter master secret, as specified in
 * https://tools.ietf.org/html/draft-ietf-tls-tls13-23. It writes
 * |olen| bytes to |out| given a label and optional context. It
 * returns 1 on success and 0 otherwise.
 */
__owur int SSL_export_keying_material_early(SSL *s, unsigned char *out,
                                            size_t olen, const char *label,
                                            size_t llen,
                                            const unsigned char *context,
                                            size_t contextlen);

int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid);

int SSL_get_sigalgs(SSL *s, int idx,
+12 −0
Original line number Diff line number Diff line
@@ -2810,6 +2810,18 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
                                                       contextlen, use_context);
}

int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
                                     const char *label, size_t llen,
                                     const unsigned char *context,
                                     size_t contextlen)
{
    if (s->version != TLS1_3_VERSION)
        return 0;

    return tls13_export_keying_material_early(s, out, olen, label, llen,
                                              context, contextlen);
}

static unsigned long ssl_session_hash(const SSL_SESSION *a)
{
    const unsigned char *session_id = a->session_id;
+6 −0
Original line number Diff line number Diff line
@@ -1111,6 +1111,7 @@ struct ssl_st {
    unsigned char client_app_traffic_secret[EVP_MAX_MD_SIZE];
    unsigned char server_app_traffic_secret[EVP_MAX_MD_SIZE];
    unsigned char exporter_master_secret[EVP_MAX_MD_SIZE];
    unsigned char early_exporter_master_secret[EVP_MAX_MD_SIZE];
    EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
    unsigned char read_iv[EVP_MAX_IV_LENGTH]; /* TLSv1.3 static read IV */
    EVP_MD_CTX *read_hash;      /* used for mac generation */
@@ -2406,6 +2407,11 @@ __owur int tls13_export_keying_material(SSL *s, unsigned char *out, size_t olen,
                                        const char *label, size_t llen,
                                        const unsigned char *context,
                                        size_t contextlen, int use_context);
__owur int tls13_export_keying_material_early(SSL *s, unsigned char *out,
                                              size_t olen, const char *label,
                                              size_t llen,
                                              const unsigned char *context,
                                              size_t contextlen);
__owur int tls1_alert_code(int code);
__owur int tls13_alert_code(int code);
__owur int ssl3_alert_code(int code);
+15 −0
Original line number Diff line number Diff line
@@ -951,3 +951,18 @@ int ossl_statem_export_allowed(SSL *s)
    return s->s3->previous_server_finished_len != 0
           && s->statem.hand_state != TLS_ST_SW_FINISHED;
}

/*
 * Return 1 if early TLS exporter is ready to export keying material,
 * or 0 if otherwise.
 */
int ossl_statem_export_early_allowed(SSL *s)
{
    /*
     * The early exporter secret is only present on the server if we
     * have accepted early_data. It is present on the client as long
     * as we have sent early_data.
     */
    return s->ext.early_data == SSL_EARLY_DATA_ACCEPTED
           || (!s->server && s->ext.early_data != SSL_EARLY_DATA_NOT_SENT);
}
Loading