summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2020-08-11 16:17:00 +0100
committerPauli <paul.dale@oracle.com>2020-08-29 17:40:11 +1000
commita540ef90f55c1e10feb709d09332dfa352d9f33e (patch)
tree83e75d2fae109f51af8c0583e94f4252e9198412
parent4db71d0175ed42586bcd4e6527caacbd18602adf (diff)
Extend the provider MAC bridge for CMAC
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)
-rw-r--r--crypto/evp/p_lib.c89
-rw-r--r--crypto/evp/pmeth_lib.c41
-rw-r--r--include/openssl/core_names.h5
-rw-r--r--include/openssl/evp.h5
-rw-r--r--providers/common/provider_util.c2
-rw-r--r--providers/defltprov.c6
-rw-r--r--providers/fips/fipsprov.c6
-rw-r--r--providers/implementations/include/prov/implementations.h2
-rw-r--r--providers/implementations/include/prov/macsignature.h5
-rw-r--r--providers/implementations/keymgmt/mac_legacy_kmgmt.c153
-rw-r--r--providers/implementations/signature/mac_legacy.c10
-rw-r--r--test/evp_test.c6
-rw-r--r--util/libcrypto.num2
13 files changed, 271 insertions, 61 deletions
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 503009dd93..a742f4c092 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -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);
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index dab1b15ab9..6a5a24288d 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -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;
}
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 4ca794fd50..3be69d5774 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -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"
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 290ccf56fb..6bd6e26edf 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -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);
diff --git a/providers/common/provider_util.c b/providers/common/provider_util.c
index f6155e7dce..1b02d70b78 100644
--- a/providers/common/provider_util.c
+++ b/providers/common/provider_util.c
@@ -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;
diff --git a/providers/defltprov.c b/providers/defltprov.c
index 34d2fb29f4..ff5768af74 100644
--- a/providers/defltprov.c
+++ b/providers/defltprov.c
@@ -369,6 +369,9 @@ static const OSSL_ALGORITHM deflt_signature[] = {
#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 }
};
@@ -402,6 +405,9 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = {
#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 }
};
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 745d5320ba..0ab24434ba 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -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 }
};
diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h
index fe5fbef57a..e266bd7554 100644
--- a/providers/implementations/include/prov/implementations.h
+++ b/providers/implementations/include/prov/implementations.h
@@ -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[];
diff --git a/providers/implementations/include/prov/macsignature.h b/providers/implementations/include/prov/macsignature.h
index 39a57416c8..57adf7d7ba 100644
--- a/providers/implementations/include/prov/macsignature.h
+++ b/providers/implementations/include/prov/macsignature.h
@@ -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);
diff --git a/providers/implementations/keymgmt/mac_legacy_kmgmt.c b/providers/implementations/keymgmt/mac_legacy_kmgmt.c
index 246a6bc890..fadf379f67 100644
--- a/providers/implementations/keymgmt/mac_legacy_kmgmt.c
+++ b/providers/implementations/keymgmt/mac_legacy_kmgmt.c
@@ -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 }
+};
diff --git a/providers/implementations/signature/mac_legacy.c b/providers/implementations/signature/mac_legacy.c
index cf440efc05..eaf2c7566b 100644
--- a/providers/implementations/signature/mac_legacy.c
+++ b/providers/implementations/signature/mac_legacy.c
@@ -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)
diff --git a/test/evp_test.c b/test/evp_test.c
index adcfea0038..238bbaf3d5 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -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),
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 99790a1b74..96f834500d 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -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: