[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Thu Mar 15 12:49:43 UTC 2018


The branch master has been updated
       via  f929439f61e7e4cf40e06de56880758b5344f198 (commit)
       via  e8f9f08f17e4f15ee737115d336d110dc8dea0ec (commit)
       via  0bcc8ec9d386bc067410f169682cef6b5da4455b (commit)
       via  82dd65a2a74c151cf62723609510d83d32c83a52 (commit)
       via  0f987bdab8c2e83d0bd4868c596903445d0ff12c (commit)
       via  4665244ce28add625d28c9ee9c52e39b42024705 (commit)
       via  d45a97f475d944c9d4ce1103fb1d3f3a68ccd8cd (commit)
       via  9442c8d7636a2bb257e76d4137a5d7305dedf28f (commit)
       via  b3831fbb0bf63f77ce45e359b5031cd3f6c56fa2 (commit)
       via  2621c8479e468d29419640c2bd900786612b4ade (commit)
       via  5539c5d63445e722b96bfe2798c0733a8e690b3c (commit)
       via  e32b52a27e20a45f51f489e4efc04d1ca72b9609 (commit)
       via  cc8b15c7e1934ba710fbce32676451acc9cbe8a0 (commit)
       via  a08802ce296a90d8cf9032987b0dac959ccf00ad (commit)
      from  9e381e8a018592a2a42e83df402e1ef921469e9f (commit)


- Log -----------------------------------------------------------------
commit f929439f61e7e4cf40e06de56880758b5344f198
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Mar 15 12:19:16 2018 +0000

    Rename EVP_PKEY_new_private_key()/EVP_PKEY_new_public_key()
    
    Renamed to EVP_PKEY_new_raw_private_key()/EVP_new_raw_public_key() as per
    feedback.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit e8f9f08f17e4f15ee737115d336d110dc8dea0ec
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Mar 9 11:02:28 2018 +0000

    Add functions for setting the new EVP_PKEY_ASN1_METHOD functions
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit 0bcc8ec9d386bc067410f169682cef6b5da4455b
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Mar 5 19:26:36 2018 +0000

    Make sure all errors go on the stack in the EVP_PKEY_new*() functions
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit 82dd65a2a74c151cf62723609510d83d32c83a52
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Mar 5 19:16:35 2018 +0000

    Expand the 25519/448 overview man pages
    
    Include more information about how to create keys for these algorithms.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit 0f987bdab8c2e83d0bd4868c596903445d0ff12c
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Mar 5 18:39:44 2018 +0000

    Add some test vectors for testing raw 448/25519 keys
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit 4665244ce28add625d28c9ee9c52e39b42024705
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Dec 1 17:57:42 2017 +0000

    Add PrivateKeyRaw and PublicKeyRaw support to evp_test
    
    Previously private and public keys had to be pem encoded to be read by
    evp_test. This enables us to embed the raw private/public key values
    in the test file. The algorithm has to support EVP_PKEY_new_private_key()
    and EVP_PKEY_new_public_key() for this to work.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit d45a97f475d944c9d4ce1103fb1d3f3a68ccd8cd
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Mar 5 17:41:49 2018 +0000

    Add documentation for the newly added EVP_PKEY_new*() functions
    
    Also adds some documentation for related existing functions/macros
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit 9442c8d7636a2bb257e76d4137a5d7305dedf28f
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Mar 5 16:22:41 2018 +0000

    Update the tests to use the new EVP_PKEY_new_private_key() function
    
    Also to use the new EVP_PKEY_new_CMAC_key()
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit b3831fbb0bf63f77ce45e359b5031cd3f6c56fa2
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Mar 5 17:23:57 2018 +0000

    Add the function EVP_PKEY_new_CMAC_key()
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit 2621c8479e468d29419640c2bd900786612b4ade
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Mar 5 16:22:24 2018 +0000

    Add support for setting raw private Poly1305 keys
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit 5539c5d63445e722b96bfe2798c0733a8e690b3c
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Mar 5 16:17:24 2018 +0000

    Add support for setting raw private SIPHASH keys
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit e32b52a27e20a45f51f489e4efc04d1ca72b9609
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Mar 5 15:13:43 2018 +0000

    Add support for setting raw private HMAC keys
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit cc8b15c7e1934ba710fbce32676451acc9cbe8a0
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Mar 5 13:58:46 2018 +0000

    Add support for setting raw private/public 25519/448 keys
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

commit a08802ce296a90d8cf9032987b0dac959ccf00ad
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Mar 5 14:06:41 2018 +0000

    Add functions to create an EVP_PKEY from raw private/public key data
    
    Not all algorithms will support this, since their keys are not a simple
    block of data. But many can.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5520)

-----------------------------------------------------------------------

Summary of changes:
 apps/dgst.c                               |   4 +-
 crypto/asn1/ameth_lib.c                   |  17 +++++
 crypto/ec/ecx_meth.c                      |  57 ++++++++++++++--
 crypto/err/openssl.txt                    |   4 ++
 crypto/evp/evp_err.c                      |   7 ++
 crypto/evp/p_lib.c                        | 105 ++++++++++++++++++++++++++++--
 crypto/hmac/hm_ameth.c                    |  37 ++++++++++-
 crypto/include/internal/asn1_int.h        |   3 +
 crypto/kdf/tls1_prf.c                     |   2 +-
 crypto/poly1305/poly1305_ameth.c          |  36 +++++++++-
 crypto/siphash/siphash_ameth.c            |  36 +++++++++-
 doc/man3/EVP_PKEY_ASN1_METHOD.pod         |  26 +++++++-
 doc/man3/EVP_PKEY_CTX_ctrl.pod            |  41 +++++++++---
 doc/man3/EVP_PKEY_new.pod                 |  49 +++++++++++++-
 doc/man7/Ed25519.pod                      |  10 +++
 doc/man7/X25519.pod                       |  10 +++
 include/openssl/evp.h                     |  18 +++++
 include/openssl/evperr.h                  |   4 ++
 ssl/statem/extensions.c                   |   3 +-
 ssl/statem/extensions_srvr.c              |  14 ++--
 ssl/t1_enc.c                              |   4 +-
 ssl/tls13_enc.c                           |   8 +--
 test/evp_test.c                           |  77 +++++++++++++++-------
 test/recipes/30-test_evp_data/evppkey.txt |  79 ++++++++++++++++++++++
 util/libcrypto.num                        |   5 ++
 util/private.num                          |   2 +
 26 files changed, 590 insertions(+), 68 deletions(-)

diff --git a/apps/dgst.c b/apps/dgst.c
index 4574550..4bf20f3 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_raw_private_key(EVP_PKEY_HMAC, impl,
+                                              (unsigned char *)hmac_key, -1);
         if (sigkey == NULL)
             goto end;
     }
diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c
index f817198..b5f0293 100644
--- a/crypto/asn1/ameth_lib.c
+++ b/crypto/asn1/ameth_lib.c
@@ -400,3 +400,20 @@ void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth,
 {
     ameth->pkey_param_check = pkey_param_check;
 }
+
+void EVP_PKEY_asn1_set_set_priv_key(EVP_PKEY_ASN1_METHOD *ameth,
+                                    int (*set_priv_key) (EVP_PKEY *pk,
+                                                         const unsigned char
+                                                            *priv,
+                                                         size_t len))
+{
+    ameth->set_priv_key = set_priv_key;
+}
+
+void EVP_PKEY_asn1_set_set_pub_key(EVP_PKEY_ASN1_METHOD *ameth,
+                                   int (*set_pub_key) (EVP_PKEY *pk,
+                                                       const unsigned char *pub,
+                                                       size_t len))
+{
+    ameth->set_pub_key = set_pub_key;
+}
diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c
index 272dfc6..69f0015 100644
--- a/crypto/ec/ecx_meth.c
+++ b/crypto/ec/ecx_meth.c
@@ -341,6 +341,19 @@ static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
     }
 }
 
+static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
+                            size_t len)
+{
+    return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
+                       KEY_OP_PRIVATE);
+}
+
+static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
+{
+    return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
+                      KEY_OP_PUBLIC);
+}
+
 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
     EVP_PKEY_X25519,
     EVP_PKEY_X25519,
@@ -368,7 +381,18 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
     ecx_free,
     ecx_ctrl,
     NULL,
-    NULL
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    ecx_set_priv_key,
+    ecx_set_pub_key,
 };
 
 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
@@ -398,7 +422,18 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
     ecx_free,
     ecx_ctrl,
     NULL,
-    NULL
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    ecx_set_priv_key,
+    ecx_set_pub_key,
 };
 
 static int ecd_size25519(const EVP_PKEY *pkey)
@@ -504,7 +539,14 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
     NULL,
     ecd_item_verify,
     ecd_item_sign25519,
-    ecd_sig_info_set25519
+    ecd_sig_info_set25519,
+
+    NULL,
+    NULL,
+    NULL,
+
+    ecx_set_priv_key,
+    ecx_set_pub_key,
 };
 
 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
@@ -537,7 +579,14 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
     NULL,
     ecd_item_verify,
     ecd_item_sign448,
-    ecd_sig_info_set448
+    ecd_sig_info_set448,
+
+    NULL,
+    NULL,
+    NULL,
+
+    ecx_set_priv_key,
+    ecx_set_pub_key,
 };
 
 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 3f6169e..896c089 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -703,6 +703,9 @@ EVP_F_EVP_PKEY_GET0_SIPHASH:172:EVP_PKEY_get0_siphash
 EVP_F_EVP_PKEY_KEYGEN:146:EVP_PKEY_keygen
 EVP_F_EVP_PKEY_KEYGEN_INIT:147:EVP_PKEY_keygen_init
 EVP_F_EVP_PKEY_NEW:106:EVP_PKEY_new
+EVP_F_EVP_PKEY_NEW_CMAC_KEY:193:EVP_PKEY_new_CMAC_key
+EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY:191:EVP_PKEY_new_raw_private_key
+EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY:192:EVP_PKEY_new_raw_public_key
 EVP_F_EVP_PKEY_PARAMGEN:148:EVP_PKEY_paramgen
 EVP_F_EVP_PKEY_PARAMGEN_INIT:149:EVP_PKEY_paramgen_init
 EVP_F_EVP_PKEY_PARAM_CHECK:189:EVP_PKEY_param_check
@@ -2083,6 +2086,7 @@ EVP_R_INVALID_KEY:163:invalid key
 EVP_R_INVALID_KEY_LENGTH:130:invalid key length
 EVP_R_INVALID_OPERATION:148:invalid operation
 EVP_R_KEYGEN_FAILURE:120:keygen failure
+EVP_R_KEY_SETUP_FAILED:180:key setup failed
 EVP_R_MEMORY_LIMIT_EXCEEDED:172:memory limit exceeded
 EVP_R_MESSAGE_DIGEST_IS_NULL:159:message digest is null
 EVP_R_METHOD_NOT_SUPPORTED:144:method not supported
diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c
index a43de74..8678abd 100644
--- a/crypto/evp/evp_err.c
+++ b/crypto/evp/evp_err.c
@@ -93,6 +93,12 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN_INIT, 0),
      "EVP_PKEY_keygen_init"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW, 0), "EVP_PKEY_new"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_CMAC_KEY, 0),
+     "EVP_PKEY_new_CMAC_key"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, 0),
+     "EVP_PKEY_new_raw_private_key"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, 0),
+     "EVP_PKEY_new_raw_public_key"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN, 0), "EVP_PKEY_paramgen"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN_INIT, 0),
      "EVP_PKEY_paramgen_init"},
@@ -183,6 +189,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYGEN_FAILURE), "keygen failure"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEY_SETUP_FAILED), "key setup failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MEMORY_LIMIT_EXCEEDED),
     "memory limit exceeded"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MESSAGE_DIGEST_IS_NULL),
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 6177e04..c1b3393 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -18,6 +18,7 @@
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
 #include <openssl/dh.h>
+#include <openssl/cmac.h>
 #include <openssl/engine.h>
 
 #include "internal/asn1_int.h"
@@ -174,10 +175,12 @@ int EVP_PKEY_up_ref(EVP_PKEY *pkey)
  * is NULL just return 1 or 0 if the algorithm exists.
  */
 
-static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
+static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
+                         int len)
 {
     const EVP_PKEY_ASN1_METHOD *ameth;
-    ENGINE *e = NULL;
+    ENGINE **eptr = (e == NULL) ? &e :  NULL;
+
     if (pkey) {
         if (pkey->pkey.ptr)
             EVP_PKEY_free_it(pkey);
@@ -196,11 +199,11 @@ static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
 #endif
     }
     if (str)
-        ameth = EVP_PKEY_asn1_find_str(&e, str, len);
+        ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
     else
-        ameth = EVP_PKEY_asn1_find(&e, type);
+        ameth = EVP_PKEY_asn1_find(eptr, type);
 #ifndef OPENSSL_NO_ENGINE
-    if (pkey == NULL)
+    if (pkey == NULL && eptr != NULL)
         ENGINE_finish(e);
 #endif
     if (ameth == NULL) {
@@ -217,14 +220,102 @@ static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
     return 1;
 }
 
+EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
+                                       const unsigned char *priv,
+                                       size_t len)
+{
+    EVP_PKEY *ret = EVP_PKEY_new();
+
+    if (ret == NULL
+            || !pkey_set_type(ret, e, type, NULL, -1)) {
+        /* EVPerr already called */
+        goto err;
+    }
+
+    if (ret->ameth->set_priv_key == NULL) {
+        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        goto err;
+    }
+
+    if (!ret->ameth->set_priv_key(ret, priv, len)) {
+        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, EVP_R_KEY_SETUP_FAILED);
+        goto err;
+    }
+
+    return ret;
+
+ err:
+    EVP_PKEY_free(ret);
+    return NULL;
+}
+
+EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
+                                      const unsigned char *pub,
+                                      size_t len)
+{
+    EVP_PKEY *ret = EVP_PKEY_new();
+
+    if (ret == NULL
+            || !pkey_set_type(ret, e, type, NULL, -1)) {
+        /* EVPerr already called */
+        goto err;
+    }
+
+    if (ret->ameth->set_pub_key == NULL) {
+        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        goto err;
+    }
+
+    if (!ret->ameth->set_pub_key(ret, pub, len)) {
+        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, EVP_R_KEY_SETUP_FAILED);
+        goto err;
+    }
+
+    return ret;
+
+ err:
+    EVP_PKEY_free(ret);
+    return NULL;
+}
+
+EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
+                                size_t len, const EVP_CIPHER *cipher)
+{
+    EVP_PKEY *ret = EVP_PKEY_new();
+    CMAC_CTX *cmctx = CMAC_CTX_new();
+
+    if (ret == NULL
+            || cmctx == NULL
+            || !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1)) {
+        /* EVPerr already called */
+        goto err;
+    }
+
+    if (!CMAC_Init(cmctx, priv, len, cipher, e)) {
+        EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
+        goto err;
+    }
+
+    ret->pkey.ptr = cmctx;
+    return ret;
+
+ err:
+    EVP_PKEY_free(ret);
+    CMAC_CTX_free(cmctx);
+    return NULL;
+
+}
+
 int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
 {
-    return pkey_set_type(pkey, type, NULL, -1);
+    return pkey_set_type(pkey, NULL, type, NULL, -1);
 }
 
 int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
 {
-    return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
+    return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len);
 }
 #ifndef OPENSSL_NO_ENGINE
 int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
diff --git a/crypto/hmac/hm_ameth.c b/crypto/hmac/hm_ameth.c
index 4d830b8..b8c1333 100644
--- a/crypto/hmac/hm_ameth.c
+++ b/crypto/hmac/hm_ameth.c
@@ -11,6 +11,7 @@
 #include "internal/cryptlib.h"
 #include <openssl/evp.h>
 #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/include/internal/asn1_int.h b/crypto/include/internal/asn1_int.h
index 664d4d6..90673ab 100644
--- a/crypto/include/internal/asn1_int.h
+++ b/crypto/include/internal/asn1_int.h
@@ -58,6 +58,9 @@ struct evp_pkey_asn1_method_st {
     int (*pkey_check) (const EVP_PKEY *pk);
     int (*pkey_public_check) (const EVP_PKEY *pk);
     int (*pkey_param_check) (const EVP_PKEY *pk);
+    /* Get/set raw private/public key data */
+    int (*set_priv_key) (EVP_PKEY *pk, const unsigned char *priv, size_t len);
+    int (*set_pub_key) (EVP_PKEY *pk, const unsigned char *pub, size_t len);
 } /* EVP_PKEY_ASN1_METHOD */ ;
 
 DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD)
diff --git a/crypto/kdf/tls1_prf.c b/crypto/kdf/tls1_prf.c
index 339e10c..fb7d2ce 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_raw_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/crypto/poly1305/poly1305_ameth.c b/crypto/poly1305/poly1305_ameth.c
index 93c6bc0..3fbb24d 100644
--- a/crypto/poly1305/poly1305_ameth.c
+++ b/crypto/poly1305/poly1305_ameth.c
@@ -13,6 +13,7 @@
 #include "internal/asn1_int.h"
 #include "internal/poly1305.h"
 #include "poly1305_local.h"
+#include "internal/evp_int.h"
 
 /*
  * POLY1305 "ASN1" method. This is just here to indicate the maximum
@@ -45,6 +46,27 @@ static int poly1305_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 poly1305_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
+                                 size_t len)
+{
+    ASN1_OCTET_STRING *os;
+
+    if (pkey->pkey.ptr != NULL || len != POLY1305_KEY_SIZE)
+        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 poly1305_asn1_meth = {
     EVP_PKEY_POLY1305,
     EVP_PKEY_POLY1305,
@@ -63,5 +85,17 @@ const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth = {
 
     poly1305_key_free,
     poly1305_pkey_ctrl,
-    0, 0
+    NULL,
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    poly1305_set_priv_key,
+    NULL,
 };
diff --git a/crypto/siphash/siphash_ameth.c b/crypto/siphash/siphash_ameth.c
index d819461..078eb54 100644
--- a/crypto/siphash/siphash_ameth.c
+++ b/crypto/siphash/siphash_ameth.c
@@ -13,6 +13,7 @@
 #include "internal/asn1_int.h"
 #include "internal/siphash.h"
 #include "siphash_local.h"
+#include "internal/evp_int.h"
 
 /*
  * SIPHASH "ASN1" method. This is just here to indicate the maximum
@@ -46,6 +47,27 @@ static int siphash_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 siphash_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
+                                size_t len)
+{
+    ASN1_OCTET_STRING *os;
+
+    if (pkey->pkey.ptr != NULL || len != SIPHASH_KEY_SIZE)
+        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 siphash_asn1_meth = {
     EVP_PKEY_SIPHASH,
     EVP_PKEY_SIPHASH,
@@ -64,5 +86,17 @@ const EVP_PKEY_ASN1_METHOD siphash_asn1_meth = {
 
     siphash_key_free,
     siphash_pkey_ctrl,
-    0, 0
+    NULL,
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    siphash_set_priv_key,
+    NULL,
 };
diff --git a/doc/man3/EVP_PKEY_ASN1_METHOD.pod b/doc/man3/EVP_PKEY_ASN1_METHOD.pod
index cb03b47..eb15e42 100644
--- a/doc/man3/EVP_PKEY_ASN1_METHOD.pod
+++ b/doc/man3/EVP_PKEY_ASN1_METHOD.pod
@@ -19,6 +19,8 @@ EVP_PKEY_asn1_set_check,
 EVP_PKEY_asn1_set_public_check,
 EVP_PKEY_asn1_set_param_check,
 EVP_PKEY_asn1_set_security_bits,
+EVP_PKEY_asn1_set_set_priv_key,
+EVP_PKEY_asn1_set_set_pub_key,
 EVP_PKEY_get0_asn1
 - manipulating and registering EVP_PKEY_ASN1_METHOD structure
 
@@ -112,6 +114,17 @@ EVP_PKEY_get0_asn1
                                       int (*pkey_security_bits) (const EVP_PKEY
                                                                  *pk));
 
+ void EVP_PKEY_asn1_set_set_priv_key(EVP_PKEY_ASN1_METHOD *ameth,
+                                     int (*set_priv_key) (EVP_PKEY *pk,
+                                                          const unsigned char
+                                                             *priv,
+                                                          size_t len));
+
+ void EVP_PKEY_asn1_set_set_pub_key(EVP_PKEY_ASN1_METHOD *ameth,
+                                    int (*set_pub_key) (EVP_PKEY *pk,
+                                                        const unsigned char *pub,
+                                                        size_t len));
+
  const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey);
 
 =head1 DESCRIPTION
@@ -327,6 +340,14 @@ They MUST return 0 for an invalid key, or 1 for a valid key.
 They are called by L<EVP_PKEY_check(3)>, L<EVP_PKEY_public_check(3)> and
 L<EVP_PKEY_param_check(3)> respectively.
 
+ int (*set_priv_key) (EVP_PKEY *pk, const unsigned char *priv, size_t len);
+ int (*set_pub_key) (EVP_PKEY *pk, const unsigned char *pub, size_t len);
+
+The set_priv_key() and set_pub_key() methods are used to set the raw private and
+public key data for an EVP_PKEY. They MUST return 0 on error, or 1 on success.
+They are called by L<EVP_PKEY_new_raw_private_key(3)>, and
+L<EVP_PKEY_new_raw_public_key(3)> respectively.
+
 =head2 Functions
 
 EVP_PKEY_asn1_new() creates and returns a new B<EVP_PKEY_ASN1_METHOD>
@@ -368,8 +389,9 @@ EVP_PKEY_asn1_set_public(), EVP_PKEY_asn1_set_private(),
 EVP_PKEY_asn1_set_param(), EVP_PKEY_asn1_set_free(),
 EVP_PKEY_asn1_set_ctrl(), EVP_PKEY_asn1_set_item(),
 EVP_PKEY_asn1_set_siginf(), EVP_PKEY_asn1_set_check(),
-EVP_PKEY_asn1_set_public_check(), EVP_PKEY_asn1_set_param_check() and
-EVP_PKEY_asn1_set_security_bits() set the diverse methods of the given
+EVP_PKEY_asn1_set_public_check(), EVP_PKEY_asn1_set_param_check(),
+EVP_PKEY_asn1_set_security_bits(), EVP_PKEY_asn1_set_set_priv_key() and
+EVP_PKEY_asn1_set_set_pub_key() set the diverse methods of the given
 B<EVP_PKEY_ASN1_METHOD> object.
 
 EVP_PKEY_get0_asn1() finds the B<EVP_PKEY_ASN1_METHOD> associated
diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod
index 2ad470b..bfc5c85 100644
--- a/doc/man3/EVP_PKEY_CTX_ctrl.pod
+++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod
@@ -2,13 +2,20 @@
 
 =head1 NAME
 
-EVP_PKEY_CTX_ctrl, EVP_PKEY_CTX_ctrl_str,
-EVP_PKEY_CTX_set_signature_md, EVP_PKEY_CTX_set_rsa_padding,
-EVP_PKEY_CTX_set_rsa_pss_saltlen, EVP_PKEY_CTX_set_rsa_keygen_bits,
-EVP_PKEY_CTX_set_rsa_keygen_pubexp, EVP_PKEY_CTX_set_dsa_paramgen_bits,
+EVP_PKEY_CTX_ctrl,
+EVP_PKEY_CTX_ctrl_str,
+EVP_PKEY_CTX_set_signature_md,
+EVP_PKEY_CTX_get_signature_md,
+EVP_PKEY_CTX_set_mac_key,
+EVP_PKEY_CTX_set_rsa_padding,
+EVP_PKEY_CTX_set_rsa_pss_saltlen,
+EVP_PKEY_CTX_set_rsa_keygen_bits,
+EVP_PKEY_CTX_set_rsa_keygen_pubexp,
+EVP_PKEY_CTX_set_dsa_paramgen_bits,
 EVP_PKEY_CTX_set_dh_paramgen_prime_len,
 EVP_PKEY_CTX_set_dh_paramgen_generator,
-EVP_PKEY_CTX_set_dh_pad, EVP_PKEY_CTX_set_dh_nid,
+EVP_PKEY_CTX_set_dh_pad,
+EVP_PKEY_CTX_set_dh_nid,
 EVP_PKEY_CTX_set_ec_paramgen_curve_nid,
 EVP_PKEY_CTX_set_ec_param_enc - algorithm specific control operations
 
@@ -21,9 +28,12 @@ EVP_PKEY_CTX_set_ec_param_enc - algorithm specific control operations
  int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
                            const char *value);
 
- #include <openssl/rsa.h>
-
  int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
+ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd);
+
+ int EVP_PKEY_CTX_set_mac_key(EVP_PKEY_CTX *ctx, unsigned char *key, int len);
+
+ #include <openssl/rsa.h>
 
  int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad);
  int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len);
@@ -67,8 +77,21 @@ B<pkeyutl>, B<genpkey> and B<req> commands.
 All the remaining "functions" are implemented as macros.
 
 The EVP_PKEY_CTX_set_signature_md() macro sets the message digest type used
-in a signature. It can be used with any public key algorithm supporting
-signature operations.
+in a signature. It can be used in the RSA, DSA and ECDSA algorithms.
+
+The EVP_PKEY_CTX_get_signature_md() macro gets the message digest type used in a
+signature. It can be used in the RSA, DSA and ECDSA algorithms.
+
+Key generation typically involves setting up parameters to be used and
+generating the private and public key data. Some algorithm implementations
+allow private key data to be set explicitly using the EVP_PKEY_CTX_set_mac_key()
+macro. In this case key generation is simply the process of setting up the
+parameters for the key and then setting the raw key data to the value explicitly
+provided by that macro. Normally applications would call
+L<EVP_PKEY_new_raw_private_key(3)> or similar functions instead of this macro.
+
+The EVP_PKEY_CTX_set_mac_key() macro can be used with any of the algorithms
+supported by the L<EVP_PKEY_new_raw_private_key(3)> function.
 
 The macro EVP_PKEY_CTX_set_rsa_padding() sets the RSA padding mode for B<ctx>.
 The B<pad> parameter can take the value RSA_PKCS1_PADDING for PKCS#1 padding,
diff --git a/doc/man3/EVP_PKEY_new.pod b/doc/man3/EVP_PKEY_new.pod
index 956d699..98a0dd1 100644
--- a/doc/man3/EVP_PKEY_new.pod
+++ b/doc/man3/EVP_PKEY_new.pod
@@ -2,7 +2,14 @@
 
 =head1 NAME
 
-EVP_PKEY_new, EVP_PKEY_up_ref, EVP_PKEY_free - private key allocation functions
+EVP_PKEY_new,
+EVP_PKEY_up_ref,
+EVP_PKEY_free,
+EVP_PKEY_new_raw_private_key,
+EVP_PKEY_new_raw_public_key,
+EVP_PKEY_new_CMAC_key,
+EVP_PKEY_new_mac_key
+- public/private key allocation functions
 
 =head1 SYNOPSIS
 
@@ -12,6 +19,14 @@ EVP_PKEY_new, EVP_PKEY_up_ref, EVP_PKEY_free - private key allocation functions
  int EVP_PKEY_up_ref(EVP_PKEY *key);
  void EVP_PKEY_free(EVP_PKEY *key);
 
+ EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
+                                        const unsigned char *key, size_t keylen);
+ EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
+                                       const unsigned char *key, size_t keylen);
+ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
+                                 size_t len, const EVP_CIPHER *cipher);
+ EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key,
+                                int keylen);
 
 =head1 DESCRIPTION
 
@@ -23,6 +38,31 @@ EVP_PKEY_up_ref() increments the reference count of B<key>.
 EVP_PKEY_free() decrements the reference count of B<key> and, if the reference
 count is zero, frees it up. If B<key> is NULL, nothing is done.
 
+EVP_PKEY_new_raw_private_key() allocates a new B<EVP_PKEY>. If B<e> is non-NULL
+then the new B<EVP_PKEY> structure is associated with the engine B<e>. The
+B<type> argument indicates what kind of key this is. The value should be a NID
+for a public key algorithm that supports raw private keys, i.e. one of
+B<EVP_PKEY_HMAC>, B<EVP_PKEY_POLY1305>, B<EVP_PKEY_SIPHASH>, B<EVP_PKEY_X25519>,
+B<EVP_PKEY_ED25519>, B<EVP_PKEY_X448> or B<EVP_PKEY_ED448>. B<key> points to the
+raw private key data for this B<EVP_PKEY> which should be of length B<keylen>.
+The length should be appropriate for the type of the key. The public key data
+will be automatically derived from the given private key data (if appropriate
+for the algorithm type).
+
+EVP_PKEY_new_raw_public_key() works in the same way as
+EVP_PKEY_new_raw_private_key() except that B<key> points to the raw public key
+data. The B<EVP_PKEY> structure will be initialised without any private key
+information. Algorithm types that support raw public keys are
+B<EVP_PKEY_X25519>, B<EVP_PKEY_ED25519>, B<EVP_PKEY_X448> or B<EVP_PKEY_ED448>.
+
+EVP_PKEY_new_CMAC_key() works in the same way as EVP_PKEY_new_raw_private_key()
+except it is only for the B<EVP_PKEY_CMAC> algorithm type. In addition to the
+raw private key data, it also takes a cipher algorithm to be used during
+creation of a CMAC in the B<cipher> argument.
+
+EVP_PKEY_new_mac_key() works in the same way as EVP_PKEY_new_raw_private_key().
+New applications should use EVP_PKEY_new_raw_private_key() instead.
+
 =head1 NOTES
 
 The B<EVP_PKEY> structure is used by various OpenSSL functions which require a
@@ -34,8 +74,9 @@ used.
 
 =head1 RETURN VALUES
 
-EVP_PKEY_new() returns either the newly allocated B<EVP_PKEY> structure or
-B<NULL> if an error occurred.
+EVP_PKEY_new(), EVP_PKEY_new_raw_private_key(), EVP_PKEY_new_raw_public_key(),
+EVP_PKEY_new_CMAC_key() and EVP_PKEY_new_mac_key() return either the newly
+allocated B<EVP_PKEY> structure or B<NULL> if an error occurred.
 
 EVP_PKEY_up_ref() returns 1 for success and 0 for failure.
 
@@ -48,6 +89,8 @@ L<EVP_PKEY_set1_RSA(3)>
 EVP_PKEY_new() and EVP_PKEY_free() exist in all versions of OpenSSL.
 
 EVP_PKEY_up_ref() was first added to OpenSSL 1.1.0.
+EVP_PKEY_new_raw_private_key(), EVP_PKEY_new_raw_public_key() and
+EVP_PKEY_new_CMAC_key() were first added to OpenSSL 1.1.1.
 
 =head1 COPYRIGHT
 
diff --git a/doc/man7/Ed25519.pod b/doc/man7/Ed25519.pod
index da6cbc0..eacc05f 100644
--- a/doc/man7/Ed25519.pod
+++ b/doc/man7/Ed25519.pod
@@ -39,6 +39,16 @@ For the B<Ed448> algorithm a context can be obtained by calling:
 
  EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED448, NULL);
 
+Ed25519 or Ed448 private keys can be set directly using
+L<EVP_PKEY_new_raw_private_key(3)> or loaded from a PKCS#8 private key file
+using L<PEM_read_bio_PrivateKey(3)> (or similar function). Completely new keys
+can also be generated (see the example below). Setting a private key also sets
+the associated public key.
+
+Ed25519 or Ed448 public keys can be set directly using
+L<EVP_PKEY_new_raw_public_key(3)> or loaded from a SubjectPublicKeyInfo
+structure in a PEM file using L<PEM_read_bio_PUBKEY(3)> (or similar function).
+
 =head1 EXAMPLE
 
 This example generates an B<ED25519> private key and writes it to standard
diff --git a/doc/man7/X25519.pod b/doc/man7/X25519.pod
index 69ab0b4..7cb6ff6 100644
--- a/doc/man7/X25519.pod
+++ b/doc/man7/X25519.pod
@@ -27,6 +27,16 @@ For the B<X448> algorithm a context can be obtained by calling:
 
  EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X448, NULL);
 
+X25519 or X448 private keys can be set directly using
+L<EVP_PKEY_new_raw_private_key(3)> or loaded from a PKCS#8 private key file
+using L<PEM_read_bio_PrivateKey(3)> (or similar function). Completely new keys
+can also be generated (see the example below). Setting a private key also sets
+the associated public key.
+
+X25519 or X448 public keys can be set directly using
+L<EVP_PKEY_new_raw_public_key(3)> or loaded from a SubjectPublicKeyInfo
+structure in a PEM file using L<PEM_read_bio_PUBKEY(3)> (or similar function).
+
 =head1 EXAMPLE
 
 This example generates an B<X25519> private key and writes it to standard
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 9727e9d..8b81b12 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1230,6 +1230,16 @@ void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth,
 void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth,
                                    int (*pkey_param_check) (const EVP_PKEY *pk));
 
+void EVP_PKEY_asn1_set_set_priv_key(EVP_PKEY_ASN1_METHOD *ameth,
+                                    int (*set_priv_key) (EVP_PKEY *pk,
+                                                         const unsigned char
+                                                            *priv,
+                                                         size_t len));
+void EVP_PKEY_asn1_set_set_pub_key(EVP_PKEY_ASN1_METHOD *ameth,
+                                   int (*set_pub_key) (EVP_PKEY *pk,
+                                                       const unsigned char *pub,
+                                                       size_t len));
+
 void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
                                      int (*pkey_security_bits) (const EVP_PKEY
                                                                 *pk));
@@ -1337,6 +1347,14 @@ 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_raw_private_key(int type, ENGINE *e,
+                                       const unsigned char *priv,
+                                       size_t len);
+EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
+                                      const unsigned char *pub,
+                                      size_t len);
+EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
+                                size_t len, const EVP_CIPHER *cipher);
 
 void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
 void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h
index 45e9fcf..b269a8e 100644
--- a/include/openssl/evperr.h
+++ b/include/openssl/evperr.h
@@ -78,6 +78,9 @@ int ERR_load_EVP_strings(void);
 # define EVP_F_EVP_PKEY_KEYGEN                            146
 # define EVP_F_EVP_PKEY_KEYGEN_INIT                       147
 # define EVP_F_EVP_PKEY_NEW                               106
+# define EVP_F_EVP_PKEY_NEW_CMAC_KEY                      193
+# define EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY               191
+# define EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY                192
 # define EVP_F_EVP_PKEY_PARAMGEN                          148
 # define EVP_F_EVP_PKEY_PARAMGEN_INIT                     149
 # define EVP_F_EVP_PKEY_PARAM_CHECK                       189
@@ -137,6 +140,7 @@ int ERR_load_EVP_strings(void);
 # define EVP_R_INVALID_KEY_LENGTH                         130
 # define EVP_R_INVALID_OPERATION                          148
 # define EVP_R_KEYGEN_FAILURE                             120
+# define EVP_R_KEY_SETUP_FAILED                           180
 # define EVP_R_MEMORY_LIMIT_EXCEEDED                      172
 # define EVP_R_MESSAGE_DIGEST_IS_NULL                     159
 # define EVP_R_METHOD_NOT_SUPPORTED                       144
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 3dc4e8e..7f9fd5f 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_raw_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 a1f92b0..7c9a3f7 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -752,9 +752,10 @@ 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_raw_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 +1763,10 @@ 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_raw_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 774625a..bd7ff50 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_raw_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 5982c8e..08fbee5 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -248,11 +248,11 @@ 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,
-                                   s->server_finished_secret, hashlen);
+        key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
+                                           s->server_finished_secret, hashlen);
     else
-        key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
-                                   s->client_finished_secret, hashlen);
+        key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
+                                           s->client_finished_secret, hashlen);
 
     if (key == NULL
             || ctx == NULL
diff --git a/test/evp_test.c b/test/evp_test.c
index 265a4c3..3e237b0 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -911,31 +911,17 @@ static int mac_test_run(EVP_TEST *t)
     }
 #endif
 
-    if (!TEST_ptr(genctx = EVP_PKEY_CTX_new_id(expected->type, NULL))) {
-        t->err = "MAC_PKEY_CTX_ERROR";
-        goto err;
-    }
-
-    if (EVP_PKEY_keygen_init(genctx) <= 0) {
-        t->err = "MAC_KEYGEN_INIT_ERROR";
-        goto err;
-    }
-    if (expected->type == EVP_PKEY_CMAC
-             && EVP_PKEY_CTX_ctrl_str(genctx, "cipher", expected->alg) <= 0) {
-        t->err = "MAC_ALGORITHM_SET_ERROR";
-        goto err;
-    }
-
-    if (EVP_PKEY_CTX_set_mac_key(genctx, expected->key,
-                                 expected->key_len) <= 0) {
-        t->err = "MAC_KEY_SET_ERROR";
+    if (expected->type == EVP_PKEY_CMAC)
+        key = EVP_PKEY_new_CMAC_key(NULL, expected->key, expected->key_len,
+                                    EVP_get_cipherbyname(expected->alg));
+    else
+        key = EVP_PKEY_new_raw_private_key(expected->type, NULL, expected->key,
+                                           expected->key_len);
+    if (key == NULL) {
+        t->err = "MAC_KEY_CREATE_ERROR";
         goto err;
     }
 
-    if (EVP_PKEY_keygen(genctx, &key) <= 0) {
-        t->err = "MAC_KEY_GENERATE_ERROR";
-        goto err;
-    }
     if (expected->type == EVP_PKEY_HMAC) {
         if (!TEST_ptr(md = EVP_get_digestbyname(expected->alg))) {
             t->err = "MAC_ALGORITHM_SET_ERROR";
@@ -2458,8 +2444,7 @@ top:
             return 0;
         }
         klist = &private_keys;
-    }
-    else if (strcmp(pp->key, "PublicKey") == 0) {
+    } else if (strcmp(pp->key, "PublicKey") == 0) {
         pkey = PEM_read_bio_PUBKEY(t->s.key, NULL, 0, NULL);
         if (pkey == NULL && !key_unsupported()) {
             TEST_info("Can't read public key %s", pp->value);
@@ -2467,6 +2452,50 @@ top:
             return 0;
         }
         klist = &public_keys;
+    } else if (strcmp(pp->key, "PrivateKeyRaw") == 0
+               || strcmp(pp->key, "PublicKeyRaw") == 0 ) {
+        char *strnid = NULL, *keydata = NULL;
+        unsigned char *keybin;
+        size_t keylen;
+        int nid;
+
+        if (strcmp(pp->key, "PrivateKeyRaw") == 0)
+            klist = &private_keys;
+        else
+            klist = &public_keys;
+
+        strnid = strchr(pp->value, ':');
+        if (strnid != NULL) {
+            *strnid++ = '\0';
+            keydata = strchr(strnid, ':');
+            if (keydata != NULL)
+                *keydata++ = '\0';
+        }
+        if (keydata == NULL) {
+            TEST_info("Failed to parse %s value", pp->key);
+            return 0;
+        }
+
+        nid = OBJ_txt2nid(strnid);
+        if (nid == NID_undef) {
+            TEST_info("Uncrecognised algorithm NID");
+            return 0;
+        }
+        if (!parse_bin(keydata, &keybin, &keylen)) {
+            TEST_info("Failed to create binary key");
+            return 0;
+        }
+        if (klist == &private_keys)
+            pkey = EVP_PKEY_new_raw_private_key(nid, NULL, keybin, keylen);
+        else
+            pkey = EVP_PKEY_new_raw_public_key(nid, NULL, keybin, keylen);
+        if (pkey == NULL) {
+            TEST_info("Can't read %s data", pp->key);
+            OPENSSL_free(keybin);
+            TEST_openssl_errors();
+            return 0;
+        }
+        OPENSSL_free(keybin);
     }
 
     /* If we have a key add to list */
diff --git a/test/recipes/30-test_evp_data/evppkey.txt b/test/recipes/30-test_evp_data/evppkey.txt
index 017ab41..fa395af 100644
--- a/test/recipes/30-test_evp_data/evppkey.txt
+++ b/test/recipes/30-test_evp_data/evppkey.txt
@@ -726,8 +726,21 @@ PublicKey=Bob-25519-PUBLIC
 MCowBQYDK2VuAyEA3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08=
 -----END PUBLIC KEY-----
 
+#Raw  versions of the same keys as above
+
+PrivateKeyRaw=Alice-25519-Raw:X25519:77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a
+
+PublicKeyRaw=Alice-25519-PUBLIC-Raw:X25519:8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a
+
+PrivPubKeyPair = Alice-25519-Raw:Alice-25519-PUBLIC-Raw
+
+PrivateKeyRaw=Bob-25519-Raw:X25519:5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb
+
+PublicKeyRaw=Bob-25519-PUBLIC-Raw:X25519:de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f
 PrivPubKeyPair = Bob-25519:Bob-25519-PUBLIC
 
+PrivPubKeyPair = Bob-25519-Raw:Bob-25519-PUBLIC-Raw
+
 Derive=Alice-25519
 PeerKey=Bob-25519-PUBLIC
 SharedSecret=4A5D9D5BA4CE2DE1728E3BF480350F25E07E21C947D19E3376F09B3C1E161742
@@ -736,6 +749,14 @@ Derive=Bob-25519
 PeerKey=Alice-25519-PUBLIC
 SharedSecret=4A5D9D5BA4CE2DE1728E3BF480350F25E07E21C947D19E3376F09B3C1E161742
 
+Derive=Alice-25519-Raw
+PeerKey=Bob-25519-PUBLIC-Raw
+SharedSecret=4A5D9D5BA4CE2DE1728E3BF480350F25E07E21C947D19E3376F09B3C1E161742
+
+Derive=Bob-25519-Raw
+PeerKey=Alice-25519-PUBLIC-Raw
+SharedSecret=4A5D9D5BA4CE2DE1728E3BF480350F25E07E21C947D19E3376F09B3C1E161742
+
 # Illegal sign/verify operations with X25519 key
 
 Sign=Alice-25519
@@ -778,6 +799,20 @@ QjKhPKcG3LV67D2uB73BxnvzNgk=
 
 PrivPubKeyPair = Bob-448:Bob-448-PUBLIC
 
+#Raw  versions of the same keys as above
+
+PrivateKeyRaw=Alice-448-Raw:X448:9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b
+
+PublicKeyRaw=Alice-448-PUBLIC-Raw:X448:9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0
+
+PrivPubKeyPair = Alice-448-Raw:Alice-448-PUBLIC-Raw
+
+PrivateKeyRaw=Bob-448-Raw:X448:1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d
+
+PublicKeyRaw=Bob-448-PUBLIC-Raw:X448:3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609
+
+PrivPubKeyPair = Bob-448-Raw:Bob-448-PUBLIC-Raw
+
 Derive=Alice-448
 PeerKey=Bob-448-PUBLIC
 SharedSecret=07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d
@@ -786,6 +821,14 @@ Derive=Bob-448
 PeerKey=Alice-448-PUBLIC
 SharedSecret=07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d
 
+Derive=Alice-448-Raw
+PeerKey=Bob-448-PUBLIC-Raw
+SharedSecret=07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d
+
+Derive=Bob-448-Raw
+PeerKey=Alice-448-PUBLIC-Raw
+SharedSecret=07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d
+
 # Illegal sign/verify operations with X448 key
 
 Sign=Alice-448
@@ -17433,8 +17476,15 @@ PublicKey=ED25519-5-PUBLIC
 MCowBQYDK2VwAyEA7Bcrk61eVjv0kyxw4SRQNMNUZ+8u/U1k6/gZaDRn4r8=
 -----END PUBLIC KEY-----
 
+#Raw versions of the ED25519-1 keys
+PrivateKeyRaw=ED25519-1-Raw:ED25519:9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
+
+PublicKeyRaw=ED25519-1-PUBLIC-Raw:ED25519:d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
+
 PrivPubKeyPair = ED25519-1:ED25519-1-PUBLIC
 
+PrivPubKeyPair = ED25519-1-Raw:ED25519-1-PUBLIC-Raw
+
 OneShotDigestSign = NULL
 Key = ED25519-1
 Input = ""
@@ -17507,6 +17557,17 @@ DigestSign = SHA256
 Key = ED25519-1
 Result = DIGESTSIGNINIT_ERROR
 
+# Raw tests
+
+OneShotDigestSign = NULL
+Key = ED25519-1-Raw
+Input = ""
+Output = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b
+
+OneShotDigestVerify = NULL
+Key = ED25519-1-PUBLIC-Raw
+Input = ""
+Output = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b
 
 Title = ED448 tests from RFC8032
 
@@ -17606,6 +17667,11 @@ MEMwBQYDK2VxAzoAqBsuinClrJT/28ybrfw/6wgB8lhXi7EUrUTs4ewOeZ2gjv+4
 HF1oXAxW9k7srvjN8RzDhzeDjPQA
 -----END PUBLIC KEY-----
 
+#Raw versions of the ED448-1 keys
+PrivateKeyRaw=ED448-1-Raw:ED448:6c82a562cb808d10d632be89c8513ebf6c929f34ddfa8c9f63c9960ef6e348a3528c8a3fcc2f044e39a3fc5b94492f8f032e7549a20098f95b
+
+PublicKeyRaw=ED448-1-PUBLIC-Raw:ED448:5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180
+
 PrivPubKeyPair = ED448-1:ED448-1-PUBLIC
 
 PrivPubKeyPair = ED448-2:ED448-2-PUBLIC
@@ -17622,6 +17688,8 @@ PrivPubKeyPair = ED448-7:ED448-7-PUBLIC
 
 PrivPubKeyPair = ED448-8:ED448-8-PUBLIC
 
+PrivPubKeyPair = ED448-1-Raw:ED448-1-PUBLIC-Raw
+
 OneShotDigestSign = NULL
 Key = ED448-1
 Input = ""
@@ -17698,6 +17766,17 @@ DigestSign = SHA256
 Key = ED448-1
 Result = DIGESTSIGNINIT_ERROR
 
+# Raw keys
+OneShotDigestSign = NULL
+Key = ED448-1-Raw
+Input = ""
+Output = 533a37f6bbe457251f023c0d88f976ae2dfb504a843e34d2074fd823d41a591f2b233f034f628281f2fd7a22ddd47d7828c59bd0a21bfd3980ff0d2028d4b18a9df63e006c5d1c2d345b925d8dc00b4104852db99ac5c7cdda8530a113a0f4dbb61149f05a7363268c71d95808ff2e652600
+
+OneShotDigestVerify = NULL
+Key = ED448-1-PUBLIC-Raw
+Input = ""
+Output = 533a37f6bbe457251f023c0d88f976ae2dfb504a843e34d2074fd823d41a591f2b233f034f628281f2fd7a22ddd47d7828c59bd0a21bfd3980ff0d2028d4b18a9df63e006c5d1c2d345b925d8dc00b4104852db99ac5c7cdda8530a113a0f4dbb61149f05a7363268c71d95808ff2e652600
+
 
 # Key generation tests
 KeyGen = rsaEncryption
diff --git a/util/libcrypto.num b/util/libcrypto.num
index a96bd2f..a965bb5 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4522,3 +4522,8 @@ OSSL_STORE_LOADER_set_find              4463	1_1_1	EXIST::FUNCTION:
 OSSL_STORE_SEARCH_free                  4464	1_1_1	EXIST::FUNCTION:
 OSSL_STORE_SEARCH_get0_digest           4465	1_1_1	EXIST::FUNCTION:
 RAND_DRBG_set_reseed_defaults           4466	1_1_1	EXIST::FUNCTION:
+EVP_PKEY_new_raw_private_key            4467	1_1_1	EXIST::FUNCTION:
+EVP_PKEY_new_raw_public_key             4468	1_1_1	EXIST::FUNCTION:
+EVP_PKEY_new_CMAC_key                   4469	1_1_1	EXIST::FUNCTION:
+EVP_PKEY_asn1_set_set_priv_key          4470	1_1_1	EXIST::FUNCTION:
+EVP_PKEY_asn1_set_set_pub_key           4471	1_1_1	EXIST::FUNCTION:
diff --git a/util/private.num b/util/private.num
index 6c1a0ef..dea5cc2 100644
--- a/util/private.num
+++ b/util/private.num
@@ -173,6 +173,7 @@ EVP_MD_CTX_type                         define
 EVP_OpenUpdate                          define
 EVP_PKEY_CTX_add1_hkdf_info             define
 EVP_PKEY_CTX_add1_tls1_prf_seed         define
+EVP_PKEY_CTX_get_signature_md           define
 EVP_PKEY_CTX_hkdf_mode                  define
 EVP_PKEY_CTX_set1_hkdf_key              define
 EVP_PKEY_CTX_set1_hkdf_salt             define
@@ -185,6 +186,7 @@ EVP_PKEY_CTX_set_dsa_paramgen_bits      define
 EVP_PKEY_CTX_set_ec_param_enc           define
 EVP_PKEY_CTX_set_ec_paramgen_curve_nid  define
 EVP_PKEY_CTX_set_hkdf_md                define
+EVP_PKEY_CTX_set_mac_key                define
 EVP_PKEY_CTX_set_rsa_keygen_pubexp      define
 EVP_PKEY_CTX_set_rsa_padding            define
 EVP_PKEY_CTX_set_rsa_pss_saltlen        define


More information about the openssl-commits mailing list