+
+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 || !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;
+}