summaryrefslogtreecommitdiff
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2017-06-27 14:57:15 +0100
committerMatt Caswell <matt@openssl.org>2017-06-29 10:15:49 +0100
commit0ca8d1ecf26b4a564222fc17e0e48053f2fd0843 (patch)
tree3982dfa368c1054db3123f548133068d28a2a481 /ssl
parent519a5d1ef2ca3ba0adf0bc1d7dff984e8523d813 (diff)
downloadopenssl-new-0ca8d1ecf26b4a564222fc17e0e48053f2fd0843.tar.gz
Update SSL_export_keying_material() for TLSv1.3
Fixes #3680 Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3782)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/ssl_locl.h5
-rw-r--r--ssl/t1_lib.c2
-rw-r--r--ssl/tls13_enc.c48
3 files changed, 54 insertions, 1 deletions
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 7889ab5b0e..1105416d96 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1073,6 +1073,7 @@ struct ssl_st {
unsigned char handshake_traffic_hash[EVP_MAX_MD_SIZE];
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];
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 */
@@ -2288,6 +2289,10 @@ __owur int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
const char *label, size_t llen,
const unsigned char *p, size_t plen,
int use_context);
+__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 tls1_alert_code(int code);
__owur int tls13_alert_code(int code);
__owur int ssl3_alert_code(int code);
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 4f28818c33..95b9b8b4d0 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -82,7 +82,7 @@ SSL3_ENC_METHOD const TLSv1_3_enc_data = {
TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
tls13_alert_code,
- tls1_export_keying_material,
+ tls13_export_keying_material,
SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF,
ssl3_set_handshake_header,
tls_close_construct_packet,
diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c
index bc1995e21f..67ae0a3541 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -337,6 +337,7 @@ int tls13_change_cipher_state(SSL *s, int which)
static const unsigned char client_application_traffic[] = "c ap traffic";
static const unsigned char server_handshake_traffic[] = "s hs traffic";
static const unsigned char server_application_traffic[] = "s ap traffic";
+ static const unsigned char exporter_master_secret[] = "exp master";
static const unsigned char resumption_master_secret[] = "res master";
unsigned char *iv;
unsigned char secret[EVP_MAX_MD_SIZE];
@@ -509,6 +510,15 @@ int tls13_change_cipher_state(SSL *s, int which)
goto err;
}
s->session->master_key_length = hashlen;
+
+ /* Now we create the exporter master secret */
+ if (!tls13_hkdf_expand(s, ssl_handshake_md(s), insecret,
+ exporter_master_secret,
+ sizeof(exporter_master_secret) - 1,
+ hash, s->exporter_master_secret, hashlen)) {
+ SSLerr(SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
}
if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher,
@@ -587,3 +597,41 @@ int tls13_alert_code(int code)
return tls1_alert_code(code);
}
+
+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)
+{
+ unsigned char exportsecret[EVP_MAX_MD_SIZE];
+ static const unsigned char exporterlabel[] = "exporter";
+ unsigned char hash[EVP_MAX_MD_SIZE];
+ const EVP_MD *md = ssl_handshake_md(s);
+ EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+ unsigned int hashsize;
+ int ret = 0;
+
+ if (ctx == NULL)
+ goto err;
+
+ if (!SSL_is_init_finished(s))
+ goto err;
+
+ if (!use_context)
+ contextlen = 0;
+
+ if (EVP_DigestInit_ex(ctx, md, NULL) <= 0
+ || EVP_DigestUpdate(ctx, context, contextlen) <= 0
+ || EVP_DigestFinal_ex(ctx, hash, &hashsize) <= 0
+ || !tls13_hkdf_expand(s, md, s->exporter_master_secret,
+ (const unsigned char *)label, llen, NULL,
+ exportsecret, 0)
+ || !tls13_hkdf_expand(s, md, exportsecret, exporterlabel,
+ sizeof(exporterlabel) - 1, hash, out, olen))
+ goto err;
+
+ ret = 1;
+ err:
+ EVP_MD_CTX_free(ctx);
+ return ret;
+}