]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Extend the provider MAC bridge for CMAC
authorMatt Caswell <matt@openssl.org>
Tue, 11 Aug 2020 15:17:00 +0000 (16:17 +0100)
committerPauli <paul.dale@oracle.com>
Sat, 29 Aug 2020 07:40:11 +0000 (17:40 +1000)
The previous commits added support for HMAC, SIPHASH and Poly1305 into
the provider MAC bridge. We now extend that for CMAC too.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12637)

13 files changed:
crypto/evp/p_lib.c
crypto/evp/pmeth_lib.c
include/openssl/core_names.h
include/openssl/evp.h
providers/common/provider_util.c
providers/defltprov.c
providers/fips/fipsprov.c
providers/implementations/include/prov/implementations.h
providers/implementations/include/prov/macsignature.h
providers/implementations/keymgmt/mac_legacy_kmgmt.c
providers/implementations/signature/mac_legacy.c
test/evp_test.c
util/libcrypto.num

index 503009dd931e458d6160dbf99609aad7c690f6ad..a742f4c0928a3365cc4f27f87ac4cb1633c7ae72 100644 (file)
@@ -586,64 +586,79 @@ int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
     return 1;
 }
 
-EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
-                                size_t len, const EVP_CIPHER *cipher)
+static EVP_PKEY *new_cmac_key_int(const unsigned char *priv, size_t len,
+                                  const char *cipher_name,
+                                  const EVP_CIPHER *cipher, OPENSSL_CTX *libctx,
+                                  const char *propq, ENGINE *e)
 {
 # ifndef OPENSSL_NO_CMAC
 #  ifndef OPENSSL_NO_ENGINE
     const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL;
 #  endif
-    const char *cipher_name = EVP_CIPHER_name(cipher);
-    const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher);
-    OPENSSL_CTX *libctx =
-        prov == NULL ? NULL : ossl_provider_library_context(prov);
-    EVP_PKEY *ret = EVP_PKEY_new();
-    EVP_MAC *cmac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, NULL);
-    EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL;
-    OSSL_PARAM params[4];
-    size_t paramsn = 0;
-
-    if (ret == NULL
-        || cmctx == NULL
-        || !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1, NULL)) {
-        /* EVPerr already called */
+    OSSL_PARAM params[4], *p = params;
+    EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *ctx;
+
+    if (cipher != NULL)
+        cipher_name = EVP_CIPHER_name(cipher);
+
+    if (cipher_name == NULL) {
+        EVPerr(0, EVP_R_KEY_SETUP_FAILED);
+        return NULL;
+    }
+
+    ctx = EVP_PKEY_CTX_new_from_name(libctx, "CMAC", propq);
+    if (ctx == NULL) {
+        EVPerr(0, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
+    if (!EVP_PKEY_key_fromdata_init(ctx)) {
+        EVPerr(0, EVP_R_KEY_SETUP_FAILED);
+        goto err;
+    }
+
+    *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
+                                            (void *)priv, len);
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_CIPHER,
+                                            (char *)cipher_name, 0);
 #  ifndef OPENSSL_NO_ENGINE
     if (engine_id != NULL)
-        params[paramsn++] =
-            OSSL_PARAM_construct_utf8_string("engine", (char *)engine_id, 0);
+        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_ENGINE,
+                                                (char *)engine_id, 0);
 #  endif
+    *p = OSSL_PARAM_construct_end();
 
-    params[paramsn++] =
-        OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
-                                         (char *)cipher_name, 0);
-    params[paramsn++] =
-        OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
-                                          (char *)priv, len);
-    params[paramsn] = OSSL_PARAM_construct_end();
-
-    if (!EVP_MAC_CTX_set_params(cmctx, params)) {
-        EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
+    if (!EVP_PKEY_fromdata(ctx, &pkey, params)) {
+        EVPerr(0, EVP_R_KEY_SETUP_FAILED);
         goto err;
     }
 
-    ret->pkey.ptr = cmctx;
-    return ret;
-
  err:
-    EVP_PKEY_free(ret);
-    EVP_MAC_CTX_free(cmctx);
-    EVP_MAC_free(cmac);
-    return NULL;
+    EVP_PKEY_CTX_free(ctx);
+
+    return pkey;
 # else
-    EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
-           EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+    EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
     return NULL;
 # endif
 }
 
+EVP_PKEY *EVP_PKEY_new_CMAC_key_with_libctx(const unsigned char *priv,
+                                            size_t len,
+                                            const char *cipher_name,
+                                            OPENSSL_CTX *libctx,
+                                            const char *propq)
+{
+    return new_cmac_key_int(priv, len, cipher_name, NULL, libctx, propq, NULL);
+}
+
+EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
+                                size_t len, const EVP_CIPHER *cipher)
+{
+    return new_cmac_key_int(priv, len, NULL, cipher, NULL, NULL, e);
+}
+
 int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
 {
     return pkey_set_type(pkey, NULL, type, NULL, -1, NULL);
index dab1b15ab9f1d9d11162fb65d919aad9ca43f5c3..6a5a24288dca665d76e8d76bca0d49a3a386ba0d 100644 (file)
@@ -150,7 +150,6 @@ static int is_legacy_alg(int id, const char *keytype)
      * support
      */
     case EVP_PKEY_SM2:
-    case EVP_PKEY_CMAC:
         return 1;
     default:
         return 0;
@@ -1037,14 +1036,6 @@ int EVP_PKEY_CTX_set_mac_key(EVP_PKEY_CTX *ctx, const unsigned char *key,
 static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
                                 int cmd, int p1, void *p2)
 {
-    /*
-     * GOST CMS format is different for different cipher algorithms.
-     * Most of other algorithms don't have such a difference
-     * so this ctrl is just ignored.
-     */
-    if (cmd == EVP_PKEY_CTRL_CIPHER)
-        return -2;
-
 # ifndef OPENSSL_NO_DH
     if (keytype == EVP_PKEY_DHX) {
         switch (cmd) {
@@ -1193,6 +1184,29 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
             case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES:
                 return EVP_PKEY_CTX_set_scrypt_maxmem_bytes(ctx, p1);
             }
+        } else if (optype == EVP_PKEY_OP_KEYGEN) {
+            OSSL_PARAM params[2], *p = params;
+
+            switch (cmd) {
+            case EVP_PKEY_CTRL_CIPHER:
+                {
+                    char *ciphname = (char *)EVP_CIPHER_name(p2);
+
+                    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_CIPHER,
+                                                            ciphname, 0);
+                    *p = OSSL_PARAM_construct_end();
+
+                    return EVP_PKEY_CTX_set_params(ctx, params);
+                }
+            case EVP_PKEY_CTRL_SET_MAC_KEY:
+                {
+                    *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
+                                                             p2, p1);
+                    *p = OSSL_PARAM_construct_end();
+
+                    return EVP_PKEY_CTX_set_params(ctx, params);
+                }
+            }
         }
         switch (cmd) {
         case EVP_PKEY_CTRL_MD:
@@ -1223,6 +1237,15 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
             return -2;
         }
     }
+
+    /*
+     * GOST CMS format is different for different cipher algorithms.
+     * Most of other algorithms don't have such a difference
+     * so this ctrl is just ignored.
+     */
+    if (cmd == EVP_PKEY_CTRL_CIPHER)
+        return -2;
+
     return 0;
 }
 
index 4ca794fd50f602e1702f010f2ff560038b0d4055..3be69d5774152c3cc78dc2a3c5142505955bbf5f 100644 (file)
@@ -56,6 +56,7 @@ extern "C" {
  */
 #define OSSL_ALG_PARAM_DIGEST       "digest"    /* utf8_string */
 #define OSSL_ALG_PARAM_CIPHER       "cipher"    /* utf8_string */
+#define OSSL_ALG_PARAM_ENGINE       "engine"    /* utf8_string */
 #define OSSL_ALG_PARAM_MAC          "mac"       /* utf8_string */
 #define OSSL_ALG_PARAM_PROPERTIES   "properties"/* utf8_string */
 
@@ -247,6 +248,8 @@ extern "C" {
 #define OSSL_PKEY_PARAM_MAX_SIZE            "max-size" /* integer */
 #define OSSL_PKEY_PARAM_SECURITY_BITS       "security-bits" /* integer */
 #define OSSL_PKEY_PARAM_DIGEST              OSSL_ALG_PARAM_DIGEST
+#define OSSL_PKEY_PARAM_CIPHER              OSSL_ALG_PARAM_CIPHER /* utf8 string */
+#define OSSL_PKEY_PARAM_ENGINE              OSSL_ALG_PARAM_ENGINE /* utf8 string */
 #define OSSL_PKEY_PARAM_PROPERTIES          OSSL_ALG_PARAM_PROPERTIES
 #define OSSL_PKEY_PARAM_DEFAULT_DIGEST      "default-digest" /* utf8 string */
 #define OSSL_PKEY_PARAM_MANDATORY_DIGEST    "mandatory-digest" /* utf8 string */
@@ -257,8 +260,6 @@ extern "C" {
 #define OSSL_PKEY_PARAM_MGF1_PROPERTIES     "mgf1-properties"
 #define OSSL_PKEY_PARAM_TLS_ENCODED_PT      "tls-encoded-pt"
 #define OSSL_PKEY_PARAM_GROUP_NAME          "group"
-
-/* Diffie-Hellman/DSA public/private key */
 #define OSSL_PKEY_PARAM_PUB_KEY             "pub"
 #define OSSL_PKEY_PARAM_PRIV_KEY            "priv"
 
index 290ccf56fb52f2c6e0055ad2034cee75df3f14ed..6bd6e26edf915429c37ae98491a0e08e230ec617 100644 (file)
@@ -1635,6 +1635,11 @@ int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
 int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
                                 size_t *len);
 
+EVP_PKEY *EVP_PKEY_new_CMAC_key_with_libctx(const unsigned char *priv,
+                                            size_t len,
+                                            const char *cipher_name,
+                                            OPENSSL_CTX *libctx,
+                                            const char *propq);
 EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
                                 size_t len, const EVP_CIPHER *cipher);
 
index f6155e7dce33e57eab60aee79383ba4c9077a6e6..1b02d70b7829978f5f30377b0f2b947a31859e6c 100644 (file)
@@ -50,7 +50,7 @@ static int load_common(const OSSL_PARAM params[], const char **propquery,
     /* TODO legacy stuff, to be removed */
     /* Inside the FIPS module, we don't support legacy ciphers */
 #if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
-    p = OSSL_PARAM_locate_const(params, "engine");
+    p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_ENGINE);
     if (p != NULL) {
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
index 34d2fb29f409876febb5238c1faba9d815491456..ff5768af74e24a1748a0c48bce59dc8cc46d79e6 100644 (file)
@@ -368,6 +368,9 @@ static const OSSL_ALGORITHM deflt_signature[] = {
     { "SIPHASH", "provider=default", mac_siphash_signature_functions },
 #ifndef OPENSSL_NO_POLY1305
     { "POLY1305", "provider=default", mac_poly1305_signature_functions },
+#endif
+#ifndef OPENSSL_NO_CMAC
+    { "CMAC", "provider=default", mac_cmac_signature_functions },
 #endif
     { NULL, NULL, NULL }
 };
@@ -401,6 +404,9 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = {
     { "SIPHASH", "provider=default", mac_keymgmt_functions },
 #ifndef OPENSSL_NO_POLY1305
     { "POLY1305", "provider=default", mac_keymgmt_functions },
+#endif
+#ifndef OPENSSL_NO_CMAC
+    { "CMAC", "provider=default", cmac_keymgmt_functions },
 #endif
     { NULL, NULL, NULL }
 };
index 745d5320ba6805d4174ec19744382175efbef1e8..0ab24434ba1b169e96d0d46bf1a02433a9ec5c0b 100644 (file)
@@ -437,6 +437,9 @@ static const OSSL_ALGORITHM fips_signature[] = {
     { "ECDSA", FIPS_DEFAULT_PROPERTIES, ecdsa_signature_functions },
 #endif
     { "HMAC", FIPS_DEFAULT_PROPERTIES, mac_hmac_signature_functions },
+#ifndef OPENSSL_NO_CMAC
+    { "CMAC", FIPS_DEFAULT_PROPERTIES, mac_cmac_signature_functions },
+#endif
     { NULL, NULL, NULL }
 };
 
@@ -466,6 +469,9 @@ static const OSSL_ALGORITHM fips_keymgmt[] = {
     { "TLS1-PRF", FIPS_DEFAULT_PROPERTIES, kdf_keymgmt_functions },
     { "HKDF", FIPS_DEFAULT_PROPERTIES, kdf_keymgmt_functions },
     { "HMAC", FIPS_DEFAULT_PROPERTIES, mac_keymgmt_functions },
+#ifndef OPENSSL_NO_CMAC
+    { "CMAC", FIPS_DEFAULT_PROPERTIES, cmac_keymgmt_functions },
+#endif
     { NULL, NULL, NULL }
 };
 
index fe5fbef57a29e31127f35279c0cde82e664f134e..e266bd7554557fa99027cfdc4622b6fbf023f305 100644 (file)
@@ -279,6 +279,7 @@ extern const OSSL_DISPATCH ed448_keymgmt_functions[];
 extern const OSSL_DISPATCH ec_keymgmt_functions[];
 extern const OSSL_DISPATCH kdf_keymgmt_functions[];
 extern const OSSL_DISPATCH mac_keymgmt_functions[];
+extern const OSSL_DISPATCH cmac_keymgmt_functions[];
 
 /* Key Exchange */
 extern const OSSL_DISPATCH dh_keyexch_functions[];
@@ -298,6 +299,7 @@ extern const OSSL_DISPATCH ecdsa_signature_functions[];
 extern const OSSL_DISPATCH mac_hmac_signature_functions[];
 extern const OSSL_DISPATCH mac_siphash_signature_functions[];
 extern const OSSL_DISPATCH mac_poly1305_signature_functions[];
+extern const OSSL_DISPATCH mac_cmac_signature_functions[];
 
 /* Asym Cipher */
 extern const OSSL_DISPATCH rsa_asym_cipher_functions[];
index 39a57416c8b3c6aab5f0bac6341761ecf4b31d67..57adf7d7ba87cba446be18f81ddff25e35f44408 100644 (file)
@@ -17,10 +17,13 @@ struct mac_key_st {
     CRYPTO_REF_COUNT refcnt;
     unsigned char *priv_key;
     size_t priv_key_len;
+    char *cipher_name;
+    char *engine_name;
+    int cmac;
 };
 
 typedef struct mac_key_st MAC_KEY;
 
-MAC_KEY *mac_key_new(OPENSSL_CTX *libctx);
+MAC_KEY *mac_key_new(OPENSSL_CTX *libctx, int cmac);
 void mac_key_free(MAC_KEY *mackey);
 int mac_key_up_ref(MAC_KEY *mackey);
index 246a6bc8909980b25d9b2baf9c137cfd9c4abead..fadf379f67b195e1efac26100c37b731deba0ac4 100644 (file)
@@ -19,7 +19,7 @@
 #include "prov/providercommon.h"
 #include "prov/provider_ctx.h"
 #include "prov/macsignature.h"
-
+#include "e_os.h" /* strcasecmp */
 
 static OSSL_FUNC_keymgmt_new_fn mac_new;
 static OSSL_FUNC_keymgmt_free_fn mac_free;
@@ -42,9 +42,10 @@ struct mac_gen_ctx {
     int selection;
     unsigned char *priv_key;
     size_t priv_key_len;
+    char *cipher_name;
 };
 
-MAC_KEY *mac_key_new(OPENSSL_CTX *libctx)
+MAC_KEY *mac_key_new(OPENSSL_CTX *libctx, int cmac)
 {
     MAC_KEY *mackey = OPENSSL_zalloc(sizeof(*mackey));
 
@@ -58,6 +59,7 @@ MAC_KEY *mac_key_new(OPENSSL_CTX *libctx)
     }
     mackey->libctx = libctx;
     mackey->refcnt = 1;
+    mackey->cmac = cmac;
 
     return mackey;
 }
@@ -74,6 +76,8 @@ void mac_key_free(MAC_KEY *mackey)
         return;
 
     OPENSSL_secure_clear_free(mackey->priv_key, mackey->priv_key_len);
+    OPENSSL_free(mackey->cipher_name);
+    OPENSSL_free(mackey->engine_name);
     CRYPTO_THREAD_lock_free(mackey->lock);
     OPENSSL_free(mackey);
 }
@@ -88,7 +92,12 @@ int mac_key_up_ref(MAC_KEY *mackey)
 
 static void *mac_new(void *provctx)
 {
-    return mac_key_new(PROV_LIBRARY_CONTEXT_OF(provctx));
+    return mac_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), 0);
+}
+
+static void *mac_new_cmac(void *provctx)
+{
+    return mac_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), 1);
 }
 
 static void mac_free(void *mackey)
@@ -124,12 +133,16 @@ static int mac_match(const void *keydata1, const void *keydata2, int selection)
     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
         if ((key1->priv_key == NULL && key2->priv_key != NULL)
                 || (key1->priv_key != NULL && key2->priv_key == NULL)
-                || key1->priv_key_len != key2->priv_key_len)
+                || key1->priv_key_len != key2->priv_key_len
+                || (key1->cipher_name == NULL && key2->cipher_name != NULL)
+                || (key1->cipher_name != NULL && key2->cipher_name == NULL))
             ok = 0;
         else
             ok = ok && (key1->priv_key == NULL /* implies key2->privkey == NULL */
                         || CRYPTO_memcmp(key1->priv_key, key2->priv_key,
                                          key1->priv_key_len) == 0);
+        if (key1->cipher_name != NULL)
+            ok = ok && (strcasecmp(key1->cipher_name, key2->cipher_name) == 0);
     }
     return ok;
 }
@@ -152,9 +165,38 @@ static int mac_key_fromdata(MAC_KEY *key, const OSSL_PARAM params[])
         }
         memcpy(key->priv_key, p->data, p->data_size);
         key->priv_key_len = p->data_size;
+    }
 
-        return 1;
+    if (key->cmac) {
+        p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_CIPHER);
+        if (p != NULL) {
+            if (p->data_type != OSSL_PARAM_UTF8_STRING) {
+                ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+                return 0;
+            }
+            key->cipher_name = OPENSSL_strdup(p->data);
+            if (key->cipher_name == NULL) {
+                ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+        }
+        p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENGINE);
+        if (p != NULL) {
+            if (p->data_type != OSSL_PARAM_UTF8_STRING) {
+                ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+                return 0;
+            }
+            key->engine_name = OPENSSL_strdup(p->data);
+            if (key->engine_name == NULL) {
+                ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+        }
     }
+
+    if (key->priv_key != NULL && (!key->cmac || key->cipher_name != NULL))
+        return 1;
+
     return 0;
 }
 
@@ -183,6 +225,18 @@ static int key_to_params(MAC_KEY *key, OSSL_PARAM_BLD *tmpl,
                                               key->priv_key, key->priv_key_len))
         return 0;
 
+    if (key->cipher_name != NULL
+        && !ossl_param_build_set_utf8_string(tmpl, params,
+                                             OSSL_PKEY_PARAM_CIPHER,
+                                             key->cipher_name))
+        return 0;
+
+    if (key->engine_name != NULL
+        && !ossl_param_build_set_utf8_string(tmpl, params,
+                                             OSSL_PKEY_PARAM_ENGINE,
+                                             key->engine_name))
+        return 0;
+
     return 1;
 }
 
@@ -227,6 +281,19 @@ static const OSSL_PARAM *mac_imexport_types(int selection)
     return NULL;
 }
 
+static const OSSL_PARAM cmac_key_types[] = {
+    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_ENGINE, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *cmac_imexport_types(int selection)
+{
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
+        return cmac_key_types;
+    return NULL;
+}
+
 static int mac_get_params(void *key, OSSL_PARAM params[])
 {
     return key_to_params(key, NULL, params);
@@ -241,6 +308,18 @@ static const OSSL_PARAM *mac_gettable_params(void *provctx)
     return gettable_params;
 }
 
+static const OSSL_PARAM *cmac_gettable_params(void *provctx)
+{
+    static const OSSL_PARAM gettable_params[] = {
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_ENGINE, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return gettable_params;
+}
+
+
 static int mac_set_params(void *keydata, const OSSL_PARAM params[])
 {
     MAC_KEY *key = keydata;
@@ -270,14 +349,13 @@ static void *mac_gen_init(void *provctx, int selection)
     OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
     struct mac_gen_ctx *gctx = NULL;
 
-    if ((gctx = OPENSSL_malloc(sizeof(*gctx))) != NULL) {
+    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
         gctx->libctx = libctx;
         gctx->selection = selection;
     }
     return gctx;
 }
 
-
 static int mac_gen_set_params(void *genctx, const OSSL_PARAM params[])
 {
     struct mac_gen_ctx *gctx = genctx;
@@ -304,6 +382,30 @@ static int mac_gen_set_params(void *genctx, const OSSL_PARAM params[])
     return 1;
 }
 
+static int cmac_gen_set_params(void *genctx, const OSSL_PARAM params[])
+{
+    struct mac_gen_ctx *gctx = genctx;
+    const OSSL_PARAM *p;
+
+    if (!mac_gen_set_params(genctx, params))
+        return 0;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_CIPHER);
+    if (p != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+            return 0;
+        }
+        gctx->cipher_name = OPENSSL_strdup(p->data);
+        if (gctx->cipher_name == NULL) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
 static const OSSL_PARAM *mac_gen_settable_params(void *provctx)
 {
     static OSSL_PARAM settable[] = {
@@ -313,6 +415,16 @@ static const OSSL_PARAM *mac_gen_settable_params(void *provctx)
     return settable;
 }
 
+static const OSSL_PARAM *cmac_gen_settable_params(void *provctx)
+{
+    static OSSL_PARAM settable[] = {
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return settable;
+}
+
 static void *mac_gen(void *genctx, OSSL_CALLBACK *cb, void *cbarg)
 {
     struct mac_gen_ctx *gctx = genctx;
@@ -321,7 +433,7 @@ static void *mac_gen(void *genctx, OSSL_CALLBACK *cb, void *cbarg)
     if (gctx == NULL)
         return NULL;
 
-    if ((key = mac_key_new(gctx->libctx)) == NULL) {
+    if ((key = mac_key_new(gctx->libctx, 0)) == NULL) {
         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
@@ -344,8 +456,10 @@ static void *mac_gen(void *genctx, OSSL_CALLBACK *cb, void *cbarg)
      */
     key->priv_key = gctx->priv_key;
     key->priv_key_len = gctx->priv_key_len;
+    key->cipher_name = gctx->cipher_name;
     gctx->priv_key_len = 0;
     gctx->priv_key = NULL;
+    gctx->cipher_name = NULL;
 
     return key;
 }
@@ -355,6 +469,7 @@ static void mac_gen_cleanup(void *genctx)
     struct mac_gen_ctx *gctx = genctx;
 
     OPENSSL_secure_clear_free(gctx->priv_key, gctx->priv_key_len);
+    OPENSSL_free(gctx->cipher_name);
     OPENSSL_free(gctx);
 }
 
@@ -379,3 +494,25 @@ const OSSL_DISPATCH mac_keymgmt_functions[] = {
     { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup },
     { 0, NULL }
 };
+
+const OSSL_DISPATCH cmac_keymgmt_functions[] = {
+    { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))mac_new_cmac },
+    { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))mac_free },
+    { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))mac_get_params },
+    { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))cmac_gettable_params },
+    { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))mac_set_params },
+    { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))mac_settable_params },
+    { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))mac_has },
+    { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))mac_match },
+    { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))mac_import },
+    { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))cmac_imexport_types },
+    { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))mac_export },
+    { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))cmac_imexport_types },
+    { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))mac_gen_init },
+    { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))cmac_gen_set_params },
+    { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
+        (void (*)(void))cmac_gen_settable_params },
+    { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))mac_gen },
+    { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup },
+    { 0, NULL }
+};
index cf440efc059dae7a338f93b21eb9f3c1c6182dc1..eaf2c7566b30076ae34b06e76d77333e149d97c0 100644 (file)
@@ -72,11 +72,12 @@ static void *mac_newctx(void *provctx, const char *propq, const char *macname)
 MAC_NEWCTX(hmac, "HMAC")
 MAC_NEWCTX(siphash, "SIPHASH")
 MAC_NEWCTX(poly1305, "POLY1305")
+MAC_NEWCTX(cmac, "CMAC")
 
 static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey)
 {
     PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
-    OSSL_PARAM params[4], *p = params;
+    OSSL_PARAM params[5], *p = params;
 
     if (pmacctx == NULL || vkey == NULL || !mac_key_up_ref(vkey))
         return 0;
@@ -89,6 +90,12 @@ static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey)
     if (mdname != NULL)
         *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
                                                 (char *)mdname, 0);
+    if (pmacctx->key->cipher_name != NULL)
+        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
+                                                pmacctx->key->cipher_name, 0);
+    if (pmacctx->key->engine_name != NULL)
+        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_ENGINE,
+                                                pmacctx->key->engine_name, 0);
     *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
                                              pmacctx->key->priv_key,
                                              pmacctx->key->priv_key_len);
@@ -181,3 +188,4 @@ static void *mac_dupctx(void *vpmacctx)
 MAC_SIGNATURE_FUNCTIONS(hmac)
 MAC_SIGNATURE_FUNCTIONS(siphash)
 MAC_SIGNATURE_FUNCTIONS(poly1305)
+MAC_SIGNATURE_FUNCTIONS(cmac)
index adcfea0038320e5f2d870a3e0ff2743d7a138956..238bbaf3d5c6b4b68fd3e7236db860f5919b748a 100644 (file)
@@ -1161,8 +1161,10 @@ static int mac_test_run_pkey(EVP_TEST *t)
             t->err = "MAC_KEY_CREATE_ERROR";
             goto err;
         }
-        key = EVP_PKEY_new_CMAC_key(NULL, expected->key, expected->key_len,
-                                    cipher);
+        key = EVP_PKEY_new_CMAC_key_with_libctx(expected->key,
+                                                expected->key_len,
+                                                EVP_CIPHER_name(cipher),
+                                                libctx, NULL);
     } else {
         key = EVP_PKEY_new_raw_private_key_with_libctx(libctx,
                                                        OBJ_nid2sn(expected->type),
index 99790a1b74c64cba9dee94fb9a6c01ec35e2fec0..96f834500d9950918b2ec74ceff50f03b739e39b 100644 (file)
@@ -5284,3 +5284,5 @@ OSSL_STORE_LOADER_names_do_all          ? 3_0_0   EXIST::FUNCTION:
 OSSL_PARAM_get_utf8_string_ptr          ?      3_0_0   EXIST::FUNCTION:
 OSSL_PARAM_get_octet_string_ptr         ?      3_0_0   EXIST::FUNCTION:
 OSSL_DECODER_CTX_set_passphrase_cb      ?      3_0_0   EXIST::FUNCTION:
+EVP_PKEY_CTX_set_mac_key                ?      3_0_0   EXIST::FUNCTION:
+EVP_PKEY_new_CMAC_key_with_libctx       ?      3_0_0   EXIST::FUNCTION: