summaryrefslogtreecommitdiffstats
path: root/crypto/evp
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 /crypto/evp
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)
Diffstat (limited to 'crypto/evp')
-rw-r--r--crypto/evp/p_lib.c89
-rw-r--r--crypto/evp/pmeth_lib.c41
2 files changed, 84 insertions, 46 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;
}