Path: blob/main/crypto/openssl/providers/implementations/keymgmt/mac_legacy_kmgmt.c
48292 views
/*1* Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89/* We need to use some engine deprecated APIs */10#define OPENSSL_SUPPRESS_DEPRECATED1112#include <string.h>13#include <openssl/core_dispatch.h>14#include <openssl/core_names.h>15#include <openssl/params.h>16#include <openssl/err.h>17#include <openssl/evp.h>18#include <openssl/proverr.h>19#include <openssl/param_build.h>20#ifndef FIPS_MODULE21# include <openssl/engine.h>22#endif23#include "internal/param_build_set.h"24#include "prov/implementations.h"25#include "prov/providercommon.h"26#include "prov/provider_ctx.h"27#include "prov/macsignature.h"2829static OSSL_FUNC_keymgmt_new_fn mac_new;30static OSSL_FUNC_keymgmt_free_fn mac_free;31static OSSL_FUNC_keymgmt_gen_init_fn mac_gen_init;32static OSSL_FUNC_keymgmt_gen_fn mac_gen;33static OSSL_FUNC_keymgmt_gen_cleanup_fn mac_gen_cleanup;34static OSSL_FUNC_keymgmt_gen_set_params_fn mac_gen_set_params;35static OSSL_FUNC_keymgmt_gen_settable_params_fn mac_gen_settable_params;36static OSSL_FUNC_keymgmt_get_params_fn mac_get_params;37static OSSL_FUNC_keymgmt_gettable_params_fn mac_gettable_params;38static OSSL_FUNC_keymgmt_set_params_fn mac_set_params;39static OSSL_FUNC_keymgmt_settable_params_fn mac_settable_params;40static OSSL_FUNC_keymgmt_has_fn mac_has;41static OSSL_FUNC_keymgmt_match_fn mac_match;42static OSSL_FUNC_keymgmt_import_fn mac_import;43static OSSL_FUNC_keymgmt_import_types_fn mac_imexport_types;44static OSSL_FUNC_keymgmt_export_fn mac_export;45static OSSL_FUNC_keymgmt_export_types_fn mac_imexport_types;4647static OSSL_FUNC_keymgmt_new_fn mac_new_cmac;48static OSSL_FUNC_keymgmt_gettable_params_fn cmac_gettable_params;49static OSSL_FUNC_keymgmt_import_types_fn cmac_imexport_types;50static OSSL_FUNC_keymgmt_export_types_fn cmac_imexport_types;51static OSSL_FUNC_keymgmt_gen_init_fn cmac_gen_init;52static OSSL_FUNC_keymgmt_gen_set_params_fn cmac_gen_set_params;53static OSSL_FUNC_keymgmt_gen_settable_params_fn cmac_gen_settable_params;5455struct mac_gen_ctx {56OSSL_LIB_CTX *libctx;57int selection;58unsigned char *priv_key;59size_t priv_key_len;60PROV_CIPHER cipher;61};6263MAC_KEY *ossl_mac_key_new(OSSL_LIB_CTX *libctx, int cmac)64{65MAC_KEY *mackey;6667if (!ossl_prov_is_running())68return NULL;6970mackey = OPENSSL_zalloc(sizeof(*mackey));71if (mackey == NULL)72return NULL;7374if (!CRYPTO_NEW_REF(&mackey->refcnt, 1)) {75OPENSSL_free(mackey);76return NULL;77}78mackey->libctx = libctx;79mackey->cmac = cmac;8081return mackey;82}8384void ossl_mac_key_free(MAC_KEY *mackey)85{86int ref = 0;8788if (mackey == NULL)89return;9091CRYPTO_DOWN_REF(&mackey->refcnt, &ref);92if (ref > 0)93return;9495OPENSSL_secure_clear_free(mackey->priv_key, mackey->priv_key_len);96OPENSSL_free(mackey->properties);97ossl_prov_cipher_reset(&mackey->cipher);98CRYPTO_FREE_REF(&mackey->refcnt);99OPENSSL_free(mackey);100}101102int ossl_mac_key_up_ref(MAC_KEY *mackey)103{104int ref = 0;105106/* This is effectively doing a new operation on the MAC_KEY and should be107* adequately guarded again modules' error states. However, both current108* calls here are guarded properly in signature/mac_legacy.c. Thus, it109* could be removed here. The concern is that something in the future110* might call this function without adequate guards. It's a cheap call,111* it seems best to leave it even though it is currently redundant.112*/113if (!ossl_prov_is_running())114return 0;115116CRYPTO_UP_REF(&mackey->refcnt, &ref);117return 1;118}119120static void *mac_new(void *provctx)121{122return ossl_mac_key_new(PROV_LIBCTX_OF(provctx), 0);123}124125static void *mac_new_cmac(void *provctx)126{127return ossl_mac_key_new(PROV_LIBCTX_OF(provctx), 1);128}129130static void mac_free(void *mackey)131{132ossl_mac_key_free(mackey);133}134135static int mac_has(const void *keydata, int selection)136{137const MAC_KEY *key = keydata;138int ok = 0;139140if (ossl_prov_is_running() && key != NULL) {141/*142* MAC keys always have all the parameters they need (i.e. none).143* Therefore we always return with 1, if asked about parameters.144* Similarly for public keys.145*/146ok = 1;147148if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)149ok = key->priv_key != NULL;150}151return ok;152}153154static int mac_match(const void *keydata1, const void *keydata2, int selection)155{156const MAC_KEY *key1 = keydata1;157const MAC_KEY *key2 = keydata2;158int ok = 1;159160if (!ossl_prov_is_running())161return 0;162163if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {164if ((key1->priv_key == NULL && key2->priv_key != NULL)165|| (key1->priv_key != NULL && key2->priv_key == NULL)166|| key1->priv_key_len != key2->priv_key_len167|| (key1->cipher.cipher == NULL && key2->cipher.cipher != NULL)168|| (key1->cipher.cipher != NULL && key2->cipher.cipher == NULL))169ok = 0;170else171ok = ok && (key1->priv_key == NULL /* implies key2->privkey == NULL */172|| CRYPTO_memcmp(key1->priv_key, key2->priv_key,173key1->priv_key_len) == 0);174if (key1->cipher.cipher != NULL)175ok = ok && EVP_CIPHER_is_a(key1->cipher.cipher,176EVP_CIPHER_get0_name(key2->cipher.cipher));177}178return ok;179}180181static int mac_key_fromdata(MAC_KEY *key, const OSSL_PARAM params[])182{183const OSSL_PARAM *p;184185p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);186if (p != NULL) {187if (p->data_type != OSSL_PARAM_OCTET_STRING) {188ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);189return 0;190}191OPENSSL_secure_clear_free(key->priv_key, key->priv_key_len);192/* allocate at least one byte to distinguish empty key from no key set */193key->priv_key = OPENSSL_secure_malloc(p->data_size > 0 ? p->data_size : 1);194if (key->priv_key == NULL)195return 0;196memcpy(key->priv_key, p->data, p->data_size);197key->priv_key_len = p->data_size;198}199200p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES);201if (p != NULL) {202if (p->data_type != OSSL_PARAM_UTF8_STRING) {203ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);204return 0;205}206OPENSSL_free(key->properties);207key->properties = OPENSSL_strdup(p->data);208if (key->properties == NULL)209return 0;210}211212if (key->cmac && !ossl_prov_cipher_load_from_params(&key->cipher, params,213key->libctx)) {214ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);215return 0;216}217218if (key->priv_key != NULL)219return 1;220221return 0;222}223224static int mac_import(void *keydata, int selection, const OSSL_PARAM params[])225{226MAC_KEY *key = keydata;227228if (!ossl_prov_is_running() || key == NULL)229return 0;230231if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) == 0)232return 0;233234return mac_key_fromdata(key, params);235}236237static int key_to_params(MAC_KEY *key, OSSL_PARAM_BLD *tmpl,238OSSL_PARAM params[])239{240if (key == NULL)241return 0;242243if (key->priv_key != NULL244&& !ossl_param_build_set_octet_string(tmpl, params,245OSSL_PKEY_PARAM_PRIV_KEY,246key->priv_key, key->priv_key_len))247return 0;248249if (key->cipher.cipher != NULL250&& !ossl_param_build_set_utf8_string(tmpl, params,251OSSL_PKEY_PARAM_CIPHER,252EVP_CIPHER_get0_name(key->cipher.cipher)))253return 0;254255#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)256if (key->cipher.engine != NULL257&& !ossl_param_build_set_utf8_string(tmpl, params,258OSSL_PKEY_PARAM_ENGINE,259ENGINE_get_id(key->cipher.engine)))260return 0;261#endif262263return 1;264}265266static int mac_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,267void *cbarg)268{269MAC_KEY *key = keydata;270OSSL_PARAM_BLD *tmpl;271OSSL_PARAM *params = NULL;272int ret = 0;273274if (!ossl_prov_is_running() || key == NULL)275return 0;276277if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) == 0)278return 0;279280tmpl = OSSL_PARAM_BLD_new();281if (tmpl == NULL)282return 0;283284if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0285&& !key_to_params(key, tmpl, NULL))286goto err;287288params = OSSL_PARAM_BLD_to_param(tmpl);289if (params == NULL)290goto err;291292ret = param_cb(params, cbarg);293OSSL_PARAM_free(params);294err:295OSSL_PARAM_BLD_free(tmpl);296return ret;297}298299static const OSSL_PARAM mac_key_types[] = {300OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),301OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0),302OSSL_PARAM_END303};304static const OSSL_PARAM *mac_imexport_types(int selection)305{306if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)307return mac_key_types;308return NULL;309}310311static const OSSL_PARAM cmac_key_types[] = {312OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),313OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0),314OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_ENGINE, NULL, 0),315OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0),316OSSL_PARAM_END317};318static const OSSL_PARAM *cmac_imexport_types(int selection)319{320if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)321return cmac_key_types;322return NULL;323}324325static int mac_get_params(void *key, OSSL_PARAM params[])326{327return key_to_params(key, NULL, params);328}329330static const OSSL_PARAM *mac_gettable_params(void *provctx)331{332static const OSSL_PARAM gettable_params[] = {333OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),334OSSL_PARAM_END335};336return gettable_params;337}338339static const OSSL_PARAM *cmac_gettable_params(void *provctx)340{341static const OSSL_PARAM gettable_params[] = {342OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),343OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0),344OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_ENGINE, NULL, 0),345OSSL_PARAM_END346};347return gettable_params;348}349350static int mac_set_params(void *keydata, const OSSL_PARAM params[])351{352MAC_KEY *key = keydata;353const OSSL_PARAM *p;354355if (key == NULL)356return 0;357358p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);359if (p != NULL)360return mac_key_fromdata(key, params);361362return 1;363}364365static const OSSL_PARAM *mac_settable_params(void *provctx)366{367static const OSSL_PARAM settable_params[] = {368OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),369OSSL_PARAM_END370};371return settable_params;372}373374static void *mac_gen_init_common(void *provctx, int selection)375{376OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);377struct mac_gen_ctx *gctx = NULL;378379if (!ossl_prov_is_running())380return NULL;381382if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {383gctx->libctx = libctx;384gctx->selection = selection;385}386return gctx;387}388389static void *mac_gen_init(void *provctx, int selection,390const OSSL_PARAM params[])391{392struct mac_gen_ctx *gctx = mac_gen_init_common(provctx, selection);393394if (gctx != NULL && !mac_gen_set_params(gctx, params)) {395mac_gen_cleanup(gctx);396gctx = NULL;397}398return gctx;399}400401static void *cmac_gen_init(void *provctx, int selection,402const OSSL_PARAM params[])403{404struct mac_gen_ctx *gctx = mac_gen_init_common(provctx, selection);405406if (gctx != NULL && !cmac_gen_set_params(gctx, params)) {407mac_gen_cleanup(gctx);408gctx = NULL;409}410return gctx;411}412413static int mac_gen_set_params(void *genctx, const OSSL_PARAM params[])414{415struct mac_gen_ctx *gctx = genctx;416const OSSL_PARAM *p;417418if (gctx == NULL)419return 0;420421p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);422if (p != NULL) {423if (p->data_type != OSSL_PARAM_OCTET_STRING) {424ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);425return 0;426}427gctx->priv_key = OPENSSL_secure_malloc(p->data_size);428if (gctx->priv_key == NULL)429return 0;430memcpy(gctx->priv_key, p->data, p->data_size);431gctx->priv_key_len = p->data_size;432}433434return 1;435}436437static int cmac_gen_set_params(void *genctx, const OSSL_PARAM params[])438{439struct mac_gen_ctx *gctx = genctx;440441if (!mac_gen_set_params(genctx, params))442return 0;443444if (!ossl_prov_cipher_load_from_params(&gctx->cipher, params,445gctx->libctx)) {446ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);447return 0;448}449450return 1;451}452453static const OSSL_PARAM *mac_gen_settable_params(ossl_unused void *genctx,454ossl_unused void *provctx)455{456static OSSL_PARAM settable[] = {457OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),458OSSL_PARAM_END459};460return settable;461}462463static const OSSL_PARAM *cmac_gen_settable_params(ossl_unused void *genctx,464ossl_unused void *provctx)465{466static OSSL_PARAM settable[] = {467OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),468OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0),469OSSL_PARAM_END470};471return settable;472}473474static void *mac_gen(void *genctx, OSSL_CALLBACK *cb, void *cbarg)475{476struct mac_gen_ctx *gctx = genctx;477MAC_KEY *key;478479if (!ossl_prov_is_running() || gctx == NULL)480return NULL;481482if ((key = ossl_mac_key_new(gctx->libctx, 0)) == NULL) {483ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB);484return NULL;485}486487/* If we're doing parameter generation then we just return a blank key */488if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)489return key;490491if (gctx->priv_key == NULL) {492ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);493ossl_mac_key_free(key);494return NULL;495}496497/*498* This is horrible but required for backwards compatibility. We don't499* actually do real key generation at all. We simply copy the key that was500* previously set in the gctx. Hopefully at some point in the future all501* of this can be removed and we will only support the EVP_KDF APIs.502*/503if (!ossl_prov_cipher_copy(&key->cipher, &gctx->cipher)) {504ossl_mac_key_free(key);505ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);506return NULL;507}508ossl_prov_cipher_reset(&gctx->cipher);509key->priv_key = gctx->priv_key;510key->priv_key_len = gctx->priv_key_len;511gctx->priv_key_len = 0;512gctx->priv_key = NULL;513514return key;515}516517static void mac_gen_cleanup(void *genctx)518{519struct mac_gen_ctx *gctx = genctx;520521if (gctx == NULL)522return;523524OPENSSL_secure_clear_free(gctx->priv_key, gctx->priv_key_len);525ossl_prov_cipher_reset(&gctx->cipher);526OPENSSL_free(gctx);527}528529const OSSL_DISPATCH ossl_mac_legacy_keymgmt_functions[] = {530{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))mac_new },531{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))mac_free },532{ OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))mac_get_params },533{ OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))mac_gettable_params },534{ OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))mac_set_params },535{ OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))mac_settable_params },536{ OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))mac_has },537{ OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))mac_match },538{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))mac_import },539{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))mac_imexport_types },540{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))mac_export },541{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))mac_imexport_types },542{ OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))mac_gen_init },543{ OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))mac_gen_set_params },544{ OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,545(void (*)(void))mac_gen_settable_params },546{ OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))mac_gen },547{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup },548OSSL_DISPATCH_END549};550551const OSSL_DISPATCH ossl_cmac_legacy_keymgmt_functions[] = {552{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))mac_new_cmac },553{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))mac_free },554{ OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))mac_get_params },555{ OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))cmac_gettable_params },556{ OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))mac_set_params },557{ OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))mac_settable_params },558{ OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))mac_has },559{ OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))mac_match },560{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))mac_import },561{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))cmac_imexport_types },562{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))mac_export },563{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))cmac_imexport_types },564{ OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))cmac_gen_init },565{ OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))cmac_gen_set_params },566{ OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,567(void (*)(void))cmac_gen_settable_params },568{ OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))mac_gen },569{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup },570OSSL_DISPATCH_END571};572573574575