From e32b52a27e20a45f51f489e4efc04d1ca72b9609 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 5 Mar 2018 15:13:43 +0000 Subject: [PATCH 1/1] Add support for setting raw private HMAC keys Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/5520) --- apps/dgst.c | 4 ++-- crypto/evp/p_lib.c | 6 ++++-- crypto/hmac/hm_ameth.c | 37 +++++++++++++++++++++++++++++++++++- crypto/kdf/tls1_prf.c | 2 +- include/openssl/evp.h | 6 ++++-- ssl/statem/extensions.c | 3 ++- ssl/statem/extensions_srvr.c | 12 ++++++------ ssl/t1_enc.c | 4 ++-- ssl/tls13_enc.c | 4 ++-- 9 files changed, 59 insertions(+), 19 deletions(-) diff --git a/apps/dgst.c b/apps/dgst.c index 4574550796..d5646c91e2 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -277,8 +277,8 @@ int dgst_main(int argc, char **argv) } if (hmac_key != NULL) { - sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl, - (unsigned char *)hmac_key, -1); + sigkey = EVP_PKEY_new_private_key(EVP_PKEY_HMAC, impl, + (unsigned char *)hmac_key, -1); if (sigkey == NULL) goto end; } diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 7ec1dd7800..a92b169f7a 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -219,7 +219,8 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, return 1; } -EVP_PKEY *EVP_PKEY_new_private_key(int type, ENGINE *e, unsigned char *priv, +EVP_PKEY *EVP_PKEY_new_private_key(int type, ENGINE *e, + const unsigned char *priv, size_t len) { EVP_PKEY *ret = EVP_PKEY_new(); @@ -248,7 +249,8 @@ EVP_PKEY *EVP_PKEY_new_private_key(int type, ENGINE *e, unsigned char *priv, return NULL; } -EVP_PKEY *EVP_PKEY_new_public_key(int type, ENGINE *e, unsigned char *pub, +EVP_PKEY *EVP_PKEY_new_public_key(int type, ENGINE *e, + const unsigned char *pub, size_t len) { EVP_PKEY *ret = EVP_PKEY_new(); diff --git a/crypto/hmac/hm_ameth.c b/crypto/hmac/hm_ameth.c index 4d830b8ded..b8c13331cb 100644 --- a/crypto/hmac/hm_ameth.c +++ b/crypto/hmac/hm_ameth.c @@ -11,6 +11,7 @@ #include "internal/cryptlib.h" #include #include "internal/asn1_int.h" +#include "internal/evp_int.h" /* * HMAC "ASN1" method. This is just here to indicate the maximum HMAC output @@ -49,6 +50,28 @@ static int hmac_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b) return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b)); } +static int hmac_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, + size_t len) +{ + ASN1_OCTET_STRING *os; + + if (pkey->pkey.ptr != NULL) + return 0; + + os = ASN1_OCTET_STRING_new(); + if (os == NULL) + return 0; + + + if (!ASN1_OCTET_STRING_set(os, priv, len)) { + ASN1_OCTET_STRING_free(os); + return 0; + } + + pkey->pkey.ptr = os; + return 1; +} + const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = { EVP_PKEY_HMAC, EVP_PKEY_HMAC, @@ -67,5 +90,17 @@ const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = { hmac_key_free, hmac_pkey_ctrl, - 0, 0 + NULL, + NULL, + + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + + hmac_set_priv_key, + NULL, }; diff --git a/crypto/kdf/tls1_prf.c b/crypto/kdf/tls1_prf.c index 339e10c1b7..f618362c0a 100644 --- a/crypto/kdf/tls1_prf.c +++ b/crypto/kdf/tls1_prf.c @@ -193,7 +193,7 @@ static int tls1_prf_P_hash(const EVP_MD *md, if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL) goto err; EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len); + mac_key = EVP_PKEY_new_private_key(EVP_PKEY_HMAC, NULL, sec, sec_len); if (mac_key == NULL) goto err; if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key)) diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 04797635b9..d80ca41e65 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1337,9 +1337,11 @@ void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen); -EVP_PKEY *EVP_PKEY_new_private_key(int type, ENGINE *e, unsigned char *priv, +EVP_PKEY *EVP_PKEY_new_private_key(int type, ENGINE *e, + const unsigned char *priv, size_t len); -EVP_PKEY *EVP_PKEY_new_public_key(int type, ENGINE *e, unsigned char *pub, +EVP_PKEY *EVP_PKEY_new_public_key(int type, ENGINE *e, + const unsigned char *pub, size_t len); void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 3dc4e8ed94..9b8fc43bf1 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -1559,7 +1559,8 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, goto err; } - mackey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, finishedkey, hashsize); + mackey = EVP_PKEY_new_private_key(EVP_PKEY_HMAC, NULL, finishedkey, + hashsize); if (mackey == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, ERR_R_INTERNAL_ERROR); diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index a1f92b076d..0f997c40f5 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -752,9 +752,9 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* Verify the HMAC of the cookie */ hctx = EVP_MD_CTX_create(); - pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, - s->session_ctx->ext.cookie_hmac_key, - sizeof(s->session_ctx->ext.cookie_hmac_key)); + pkey = EVP_PKEY_new_private_key(EVP_PKEY_HMAC, NULL, + s->session_ctx->ext.cookie_hmac_key, + sizeof(s->session_ctx->ext.cookie_hmac_key)); if (hctx == NULL || pkey == NULL) { EVP_MD_CTX_free(hctx); EVP_PKEY_free(pkey); @@ -1762,9 +1762,9 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, /* HMAC the cookie */ hctx = EVP_MD_CTX_create(); - pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, - s->session_ctx->ext.cookie_hmac_key, - sizeof(s->session_ctx->ext.cookie_hmac_key)); + pkey = EVP_PKEY_new_private_key(EVP_PKEY_HMAC, NULL, + s->session_ctx->ext.cookie_hmac_key, + sizeof(s->session_ctx->ext.cookie_hmac_key)); if (hctx == NULL || pkey == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, ERR_R_MALLOC_FAILURE); diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 774625a202..a9e28bcd90 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -257,8 +257,8 @@ int tls1_change_cipher_state(SSL *s, int which) if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) { /* TODO(size_t): Convert this function */ - mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, - mac_secret, (int)*mac_secret_size); + mac_key = EVP_PKEY_new_private_key(mac_type, NULL, + mac_secret, (int)*mac_secret_size); if (mac_key == NULL || EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key) <= 0) { EVP_PKEY_free(mac_key); diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index 5982c8e93d..23a2c59ecf 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -248,10 +248,10 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, } if (str == s->method->ssl3_enc->server_finished_label) - key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, + key = EVP_PKEY_new_private_key(EVP_PKEY_HMAC, NULL, s->server_finished_secret, hashlen); else - key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, + key = EVP_PKEY_new_private_key(EVP_PKEY_HMAC, NULL, s->client_finished_secret, hashlen); if (key == NULL -- 2.34.1