diff options
author | Matt Caswell <matt@openssl.org> | 2020-08-11 16:17:00 +0100 |
---|---|---|
committer | Pauli <paul.dale@oracle.com> | 2020-08-29 17:40:11 +1000 |
commit | a540ef90f55c1e10feb709d09332dfa352d9f33e (patch) | |
tree | 83e75d2fae109f51af8c0583e94f4252e9198412 /crypto/evp | |
parent | 4db71d0175ed42586bcd4e6527caacbd18602adf (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.c | 89 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 41 |
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; } |