* Copyright (C) 2022-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "asy_key_generator.h"
#include <securec.h>
#include "asy_key_generator_spi.h"
#include "config.h"
#include "detailed_alg_25519_key_params.h"
#include "detailed_dh_key_params.h"
#include "detailed_dsa_key_params.h"
#include "detailed_rsa_key_params.h"
#include "detailed_ecc_key_params.h"
#include "dh_asy_key_generator_openssl.h"
#include "dsa_asy_key_generator_openssl.h"
#include "alg_25519_asy_key_generator_openssl.h"
#include "ml_kem_asy_key_generator_openssl.h"
#include "ml_dsa_asy_key_generator_openssl.h"
#include "ecc_asy_key_generator_openssl.h"
#include "key_utils.h"
#include "params_parser.h"
#include "rsa_asy_key_generator_openssl.h"
#include "sm2_asy_key_generator_openssl.h"
#include "log.h"
#include "memory.h"
#include "utils.h"
#define ALG_NAME_DSA "DSA"
#define ALG_NAME_ECC "ECC"
#define ALG_NAME_SM2 "SM2"
#define ALG_NAME_RSA "RSA"
#define ALG_NAME_DH "DH"
#define ALG_NAME_X25519 "X25519"
#define ALG_NAME_ED25519 "Ed25519"
#define ALG_NAME_ML_KEM "ML-KEM"
#define ALG_NAME_ML_DSA "ML-DSA"
#define ASY_KEY_GENERATOR_CLASS "HcfAsyKeyGenerator"
#define ASY_KEY_GENERATOR_BY_SPEC_CLASS "HcfAsyKeyGeneratorBySpec"
typedef HcfResult (*HcfAsyKeyGeneratorSpiCreateFunc)(HcfAsyKeyGenParams *, HcfAsyKeyGeneratorSpi **);
typedef struct {
HcfAsyKeyGenerator base;
HcfAsyKeyGeneratorSpi *spiObj;
char algoName[HCF_MAX_ALGO_NAME_LEN];
} HcfAsyKeyGeneratorImpl;
typedef struct {
HcfAsyKeyGeneratorBySpec base;
HcfAsyKeyGeneratorSpi *spiObj;
HcfAsyKeyParamsSpec *paramsSpec;
} HcfAsyKeyGeneratorBySpecImpl;
typedef struct {
HcfAlgValue algo;
HcfAsyKeyGeneratorSpiCreateFunc createSpiFunc;
} HcfAsyKeyGenAbility;
static const HcfAsyKeyGenAbility ASY_KEY_GEN_ABILITY_SET[] = {
{ HCF_ALG_RSA, HcfAsyKeyGeneratorSpiRsaCreate },
{ HCF_ALG_ECC, HcfAsyKeyGeneratorSpiEccCreate },
{ HCF_ALG_DSA, HcfAsyKeyGeneratorSpiDsaCreate },
{ HCF_ALG_SM2, HcfAsyKeyGeneratorSpiSm2Create },
{ HCF_ALG_ED25519, HcfAsyKeyGeneratorSpiEd25519Create },
{ HCF_ALG_X25519, HcfAsyKeyGeneratorSpiX25519Create },
{ HCF_ALG_DH, HcfAsyKeyGeneratorSpiDhCreate },
{ HCF_ALG_ML_KEM, HcfAsyKeyGeneratorSpiMlKemCreate },
{ HCF_ALG_ML_DSA, HcfAsyKeyGeneratorSpiMlDsaCreate }
};
typedef struct {
HcfAlgParaValue value;
int32_t bits;
HcfAlgValue algo;
} KeyTypeAlg;
static const KeyTypeAlg KEY_TYPE_MAP[] = {
{ HCF_ALG_ECC_192, HCF_ALG_ECC_192, HCF_ALG_ECC },
{ HCF_ALG_ECC_224, HCF_ALG_ECC_224, HCF_ALG_ECC },
{ HCF_ALG_ECC_256, HCF_ALG_ECC_256, HCF_ALG_ECC },
{ HCF_ALG_ECC_384, HCF_ALG_ECC_384, HCF_ALG_ECC },
{ HCF_ALG_ECC_521, HCF_ALG_ECC_521, HCF_ALG_ECC },
{ HCF_OPENSSL_RSA_512, HCF_RSA_KEY_SIZE_512, HCF_ALG_RSA },
{ HCF_OPENSSL_RSA_768, HCF_RSA_KEY_SIZE_768, HCF_ALG_RSA },
{ HCF_OPENSSL_RSA_1024, HCF_RSA_KEY_SIZE_1024, HCF_ALG_RSA },
{ HCF_OPENSSL_RSA_2048, HCF_RSA_KEY_SIZE_2048, HCF_ALG_RSA },
{ HCF_OPENSSL_RSA_3072, HCF_RSA_KEY_SIZE_3072, HCF_ALG_RSA },
{ HCF_OPENSSL_RSA_4096, HCF_RSA_KEY_SIZE_4096, HCF_ALG_RSA },
{ HCF_OPENSSL_RSA_4096, HCF_RSA_KEY_SIZE_4096, HCF_ALG_RSA },
{ HCF_OPENSSL_RSA_8192, HCF_RSA_KEY_SIZE_8192, HCF_ALG_RSA },
{ HCF_ALG_DSA_1024, HCF_DSA_KEY_SIZE_1024, HCF_ALG_DSA },
{ HCF_ALG_DSA_2048, HCF_DSA_KEY_SIZE_2048, HCF_ALG_DSA },
{ HCF_ALG_DSA_3072, HCF_DSA_KEY_SIZE_3072, HCF_ALG_DSA },
{ HCF_ALG_SM2_256, HCF_ALG_SM2_256, HCF_ALG_SM2 },
{ HCF_ALG_ECC_BP160R1, HCF_ALG_ECC_BP160R1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP160T1, HCF_ALG_ECC_BP160T1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP192R1, HCF_ALG_ECC_BP192R1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP192T1, HCF_ALG_ECC_BP192T1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP224R1, HCF_ALG_ECC_BP224R1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP224T1, HCF_ALG_ECC_BP224T1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP256R1, HCF_ALG_ECC_BP256R1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP256T1, HCF_ALG_ECC_BP256T1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP320R1, HCF_ALG_ECC_BP320R1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP320T1, HCF_ALG_ECC_BP320T1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP384R1, HCF_ALG_ECC_BP384R1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP384T1, HCF_ALG_ECC_BP384T1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP512R1, HCF_ALG_ECC_BP512R1, HCF_ALG_ECC },
{ HCF_ALG_ECC_BP512T1, HCF_ALG_ECC_BP512T1, HCF_ALG_ECC },
{ HCF_ALG_ECC_SECP256K1, HCF_ALG_ECC_SECP256K1, HCF_ALG_ECC },
{ HCF_ALG_ED25519_256, HCF_ALG_ED25519_256, HCF_ALG_ED25519 },
{ HCF_ALG_X25519_256, HCF_ALG_X25519_256, HCF_ALG_X25519 },
{ HCF_OPENSSL_DH_MODP_1536, HCF_DH_MODP_SIZE_1536, HCF_ALG_DH },
{ HCF_OPENSSL_DH_MODP_2048, HCF_DH_MODP_SIZE_2048, HCF_ALG_DH },
{ HCF_OPENSSL_DH_MODP_3072, HCF_DH_MODP_SIZE_3072, HCF_ALG_DH },
{ HCF_OPENSSL_DH_MODP_4096, HCF_DH_MODP_SIZE_4096, HCF_ALG_DH },
{ HCF_OPENSSL_DH_MODP_6144, HCF_DH_MODP_SIZE_6144, HCF_ALG_DH },
{ HCF_OPENSSL_DH_MODP_8192, HCF_DH_MODP_SIZE_8192, HCF_ALG_DH },
{ HCF_OPENSSL_DH_FFDHE_2048, HCF_DH_FFDHE_SIZE_2048, HCF_ALG_DH },
{ HCF_OPENSSL_DH_FFDHE_3072, HCF_DH_FFDHE_SIZE_3072, HCF_ALG_DH },
{ HCF_OPENSSL_DH_FFDHE_4096, HCF_DH_FFDHE_SIZE_4096, HCF_ALG_DH },
{ HCF_OPENSSL_DH_FFDHE_6144, HCF_DH_FFDHE_SIZE_6144, HCF_ALG_DH },
{ HCF_OPENSSL_DH_FFDHE_8192, HCF_DH_FFDHE_SIZE_8192, HCF_ALG_DH },
{ HCF_ALG_ML_KEM_512, HCF_ALG_ML_KEM_512, HCF_ALG_ML_KEM },
{ HCF_ALG_ML_KEM_768, HCF_ALG_ML_KEM_768, HCF_ALG_ML_KEM },
{ HCF_ALG_ML_KEM_1024, HCF_ALG_ML_KEM_1024, HCF_ALG_ML_KEM },
{ HCF_ALG_ML_DSA_44, HCF_ALG_ML_DSA_44, HCF_ALG_ML_DSA },
{ HCF_ALG_ML_DSA_65, HCF_ALG_ML_DSA_65, HCF_ALG_ML_DSA },
{ HCF_ALG_ML_DSA_87, HCF_ALG_ML_DSA_87, HCF_ALG_ML_DSA }
};
static bool IsDsaCommParamsSpecValid(HcfDsaCommParamsSpec *paramsSpec)
{
if ((paramsSpec->p.data == NULL) || (paramsSpec->p.len == 0)) {
LOGE("BigInteger p is invalid");
return false;
}
if ((paramsSpec->q.data == NULL) || (paramsSpec->q.len == 0)) {
LOGE("BigInteger q is invalid");
return false;
}
if ((paramsSpec->g.data == NULL) || (paramsSpec->g.len == 0)) {
LOGE("BigInteger g is invalid");
return false;
}
return true;
}
static bool IsDsaPubKeySpecValid(HcfDsaPubKeyParamsSpec *paramsSpec)
{
if (!IsDsaCommParamsSpecValid(&(paramsSpec->base))) {
LOGE("DSA common params spec is invalid");
return false;
}
if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) {
LOGE("BigInteger pk is invalid");
return false;
}
return true;
}
static bool IsDsaKeyPairSpecValid(HcfDsaKeyPairParamsSpec *paramsSpec)
{
if (!IsDsaCommParamsSpecValid(&(paramsSpec->base))) {
LOGE("DSA common params spec is invalid");
return false;
}
if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) {
LOGE("BigInteger pk is invalid");
return false;
}
if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) {
LOGE("BigInteger sk is invalid");
return false;
}
return true;
}
static bool IsDsaParamsSpecValid(const HcfAsyKeyParamsSpec *paramsSpec)
{
bool ret = false;
switch (paramsSpec->specType) {
case HCF_COMMON_PARAMS_SPEC:
ret = IsDsaCommParamsSpecValid((HcfDsaCommParamsSpec *)paramsSpec);
break;
case HCF_PUBLIC_KEY_SPEC:
ret = IsDsaPubKeySpecValid((HcfDsaPubKeyParamsSpec *)paramsSpec);
break;
case HCF_KEY_PAIR_SPEC:
ret = IsDsaKeyPairSpecValid((HcfDsaKeyPairParamsSpec *)paramsSpec);
break;
default:
LOGE("SpecType not support! [SpecType]: %{public}d", paramsSpec->specType);
break;
}
return ret;
}
static bool IsDhCommParamsSpecValid(HcfDhCommParamsSpec *paramsSpec)
{
if ((paramsSpec->p.data == NULL) || (paramsSpec->p.len == 0)) {
LOGE("BigInteger p is invalid");
return false;
}
if ((paramsSpec->g.data == NULL) || (paramsSpec->g.len == 0)) {
LOGE("BigInteger g is invalid");
return false;
}
return true;
}
static bool IsDhPriKeySpecValid(HcfDhPriKeyParamsSpec *paramsSpec)
{
if (!IsDhCommParamsSpecValid(&(paramsSpec->base))) {
LOGE("DH common params spec is invalid");
return false;
}
if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) {
LOGE("BigInteger sk is invalid");
return false;
}
return true;
}
static bool IsDhPubKeySpecValid(HcfDhPubKeyParamsSpec *paramsSpec)
{
if (!IsDhCommParamsSpecValid(&(paramsSpec->base))) {
LOGE("DH common params spec is invalid");
return false;
}
if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) {
LOGE("BigInteger pk is invalid");
return false;
}
return true;
}
static bool IsDhKeyPairSpecValid(HcfDhKeyPairParamsSpec *paramsSpec)
{
if (!IsDhCommParamsSpecValid(&(paramsSpec->base))) {
LOGE("DH common params spec is invalid");
return false;
}
if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) {
LOGE("BigInteger pk is invalid");
return false;
}
if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) {
LOGE("BigInteger sk is invalid");
return false;
}
return true;
}
static bool IsDhParamsSpecValid(const HcfAsyKeyParamsSpec *paramsSpec)
{
bool ret = false;
switch (paramsSpec->specType) {
case HCF_COMMON_PARAMS_SPEC:
ret = IsDhCommParamsSpecValid((HcfDhCommParamsSpec *)paramsSpec);
break;
case HCF_PRIVATE_KEY_SPEC:
ret = IsDhPriKeySpecValid((HcfDhPriKeyParamsSpec *)paramsSpec);
break;
case HCF_PUBLIC_KEY_SPEC:
ret = IsDhPubKeySpecValid((HcfDhPubKeyParamsSpec *)paramsSpec);
break;
case HCF_KEY_PAIR_SPEC:
ret = IsDhKeyPairSpecValid((HcfDhKeyPairParamsSpec *)paramsSpec);
break;
default:
LOGE("SpecType not support! [SpecType]: %{public}d", paramsSpec->specType);
break;
}
return ret;
}
static bool IsEccCommParamsSpecValid(HcfEccCommParamsSpec *paramsSpec)
{
if ((paramsSpec->a.data == NULL) || (paramsSpec->a.len == 0)) {
LOGE("BigInteger a is invalid");
return false;
}
if ((paramsSpec->b.data == NULL) || (paramsSpec->b.len == 0)) {
LOGE("BigInteger b is invalid");
return false;
}
if ((paramsSpec->n.data == NULL) || (paramsSpec->n.len == 0)) {
LOGE("BigInteger n is invalid");
return false;
}
if ((paramsSpec->g.x.data == NULL) || (paramsSpec->g.x.len == 0) ||
(paramsSpec->g.y.data == NULL) || (paramsSpec->g.y.len == 0)) {
LOGE("Point g is invalid");
return false;
}
if (paramsSpec->field == NULL) {
LOGE("Field is null.");
return false;
}
if (strcmp(paramsSpec->field->fieldType, "Fp") != 0) {
LOGE("Unknown field type.");
return false;
}
HcfECFieldFp *tmp = (HcfECFieldFp *)(paramsSpec->field);
if ((tmp->p.data == NULL) || (tmp->p.len == 0)) {
LOGE("EcFieldFp p is invalid");
return false;
}
return true;
}
static bool IsEccPriKeySpecValid(HcfEccPriKeyParamsSpec *paramsSpec)
{
if (!IsEccCommParamsSpecValid(&(paramsSpec->base))) {
LOGE("ECC common params spec is invalid");
return false;
}
if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) {
LOGE("BigInteger sk is invalid");
return false;
}
return true;
}
static bool IsEccPubKeySpecValid(HcfEccPubKeyParamsSpec *paramsSpec)
{
if (!IsEccCommParamsSpecValid(&(paramsSpec->base))) {
LOGE("ECC common params spec is invalid");
return false;
}
if ((paramsSpec->pk.x.data == NULL) || (paramsSpec->pk.x.len == 0) ||
(paramsSpec->pk.y.data == NULL) || (paramsSpec->pk.y.len == 0)) {
LOGE("Point pk is invalid");
return false;
}
return true;
}
static bool IsEccKeyPairSpecValid(HcfEccKeyPairParamsSpec *paramsSpec)
{
if (!IsEccCommParamsSpecValid(&(paramsSpec->base))) {
LOGE("ECC common params spec is invalid");
return false;
}
if ((paramsSpec->pk.x.data == NULL) || (paramsSpec->pk.x.len == 0) ||
(paramsSpec->pk.y.data == NULL) || (paramsSpec->pk.y.len == 0)) {
LOGE("Point pk is invalid");
return false;
}
if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) {
LOGE("BigInteger sk is invalid");
return false;
}
return true;
}
static bool IsEccParamsSpecValid(const HcfAsyKeyParamsSpec *paramsSpec)
{
bool ret = false;
switch (paramsSpec->specType) {
case HCF_COMMON_PARAMS_SPEC:
ret = IsEccCommParamsSpecValid((HcfEccCommParamsSpec *)paramsSpec);
break;
case HCF_PRIVATE_KEY_SPEC:
ret = IsEccPriKeySpecValid((HcfEccPriKeyParamsSpec *)paramsSpec);
break;
case HCF_PUBLIC_KEY_SPEC:
ret = IsEccPubKeySpecValid((HcfEccPubKeyParamsSpec *)paramsSpec);
break;
case HCF_KEY_PAIR_SPEC:
ret = IsEccKeyPairSpecValid((HcfEccKeyPairParamsSpec *)paramsSpec);
break;
default:
LOGE("SpecType not support! [SpecType]: %{public}d", paramsSpec->specType);
break;
}
return ret;
}
static bool IsAlg25519PriKeySpecValid(HcfAlg25519PriKeyParamsSpec *paramsSpec)
{
if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) {
LOGE("Uint8Array sk is invalid");
return false;
}
return true;
}
static bool IsAlg25519PubKeySpecValid(HcfAlg25519PubKeyParamsSpec *paramsSpec)
{
if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) {
LOGE("Uint8Array pk is invalid");
return false;
}
return true;
}
static bool IsAlg25519KeyPairSpecValid(HcfAlg25519KeyPairParamsSpec *paramsSpec)
{
if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) {
LOGE("Uint8Array pk is invalid");
return false;
}
if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) {
LOGE("Uint8Array sk is invalid");
return false;
}
return true;
}
static bool IsAlg25519ParamsSpecValid(const HcfAsyKeyParamsSpec *paramsSpec)
{
bool ret = false;
switch (paramsSpec->specType) {
case HCF_PRIVATE_KEY_SPEC:
ret = IsAlg25519PriKeySpecValid((HcfAlg25519PriKeyParamsSpec *)paramsSpec);
break;
case HCF_PUBLIC_KEY_SPEC:
ret = IsAlg25519PubKeySpecValid((HcfAlg25519PubKeyParamsSpec *)paramsSpec);
break;
case HCF_KEY_PAIR_SPEC:
ret = IsAlg25519KeyPairSpecValid((HcfAlg25519KeyPairParamsSpec *)paramsSpec);
break;
default:
LOGE("SpecType not support! [SpecType]: %{public}d", paramsSpec->specType);
break;
}
return ret;
}
static bool IsRsaCommParamsSpecValid(HcfRsaCommParamsSpec *paramsSpec)
{
if ((paramsSpec->n.data == NULL) || (paramsSpec->n.len == 0)) {
LOGE("BigInteger n is invalid");
return false;
}
return true;
}
static bool IsRsaPubKeySpecValid(HcfRsaPubKeyParamsSpec *paramsSpec)
{
if (!IsRsaCommParamsSpecValid(&(paramsSpec->base))) {
LOGE("RSA common params spec is invalid");
return false;
}
if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) {
LOGE("BigInteger pk is invalid");
return false;
}
return true;
}
static bool IsRsaKeyPairSpecValid(HcfRsaKeyPairParamsSpec *paramsSpec)
{
if (!IsRsaCommParamsSpecValid(&(paramsSpec->base))) {
LOGE("RSA common params spec is invalid");
return false;
}
if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) {
LOGE("BigInteger pk is invalid");
return false;
}
if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) {
LOGE("BigInteger sk is invalid");
return false;
}
return true;
}
static bool IsRsaParamsSpecValid(const HcfAsyKeyParamsSpec *paramsSpec)
{
bool ret = false;
switch (paramsSpec->specType) {
case HCF_COMMON_PARAMS_SPEC:
ret = IsRsaCommParamsSpecValid((HcfRsaCommParamsSpec *)paramsSpec);
break;
case HCF_PUBLIC_KEY_SPEC:
ret = IsRsaPubKeySpecValid((HcfRsaPubKeyParamsSpec *)paramsSpec);
break;
case HCF_KEY_PAIR_SPEC:
ret = IsRsaKeyPairSpecValid((HcfRsaKeyPairParamsSpec *)paramsSpec);
break;
default:
LOGE("SpecType not support! [SpecType]: %{public}d", paramsSpec->specType);
break;
}
return ret;
}
static bool IsParamsSpecValid(const HcfAsyKeyParamsSpec *paramsSpec)
{
if ((paramsSpec == NULL) || (paramsSpec->algName == NULL)) {
LOGE("Params spec is null");
return false;
}
if (strcmp(paramsSpec->algName, ALG_NAME_DSA) == 0) {
return IsDsaParamsSpecValid(paramsSpec);
} else if (strcmp(paramsSpec->algName, ALG_NAME_ECC) == 0 || strcmp(paramsSpec->algName, ALG_NAME_SM2) == 0) {
return IsEccParamsSpecValid(paramsSpec);
} else if (strcmp(paramsSpec->algName, ALG_NAME_RSA) == 0) {
return IsRsaParamsSpecValid(paramsSpec);
} else if (strcmp(paramsSpec->algName, ALG_NAME_X25519) == 0 ||
strcmp(paramsSpec->algName, ALG_NAME_ED25519) == 0) {
return IsAlg25519ParamsSpecValid(paramsSpec);
} else if (strcmp(paramsSpec->algName, ALG_NAME_DH) == 0) {
return IsDhParamsSpecValid(paramsSpec);
} else if (strcmp(paramsSpec->algName, ALG_NAME_ML_KEM) == 0) {
LOGE("ML-KEM not support params spec.");
return false;
} else if (strcmp(paramsSpec->algName, ALG_NAME_ML_DSA) == 0) {
LOGE("ML-DSA not support params spec.");
return false;
} else {
LOGE("AlgName not support! [AlgName]: %{public}s", paramsSpec->algName);
return false;
}
}
static HcfAsyKeyGeneratorSpiCreateFunc FindAbility(HcfAsyKeyGenParams *params)
{
for (uint32_t i = 0; i < sizeof(ASY_KEY_GEN_ABILITY_SET) / sizeof(ASY_KEY_GEN_ABILITY_SET[0]); i++) {
if (ASY_KEY_GEN_ABILITY_SET[i].algo == params->algo) {
return ASY_KEY_GEN_ABILITY_SET[i].createSpiFunc;
}
}
LOGE("Algo not support! [Algo]: %{public}d", params->algo);
return NULL;
}
static void SetPrimes(HcfAlgParaValue value, HcfAsyKeyGenParams *params)
{
if (params == NULL) {
LOGE("Params is null.");
return;
}
switch (value) {
case HCF_OPENSSL_PRIMES_2:
params->primes = (int32_t)HCF_RSA_PRIMES_SIZE_2;
break;
case HCF_OPENSSL_PRIMES_3:
params->primes = (int32_t)HCF_RSA_PRIMES_SIZE_3;
break;
case HCF_OPENSSL_PRIMES_4:
params->primes = (int32_t)HCF_RSA_PRIMES_SIZE_4;
break;
case HCF_OPENSSL_PRIMES_5:
params->primes = (int32_t)HCF_RSA_PRIMES_SIZE_5;
break;
default:
params->primes = (int32_t)HCF_RSA_PRIMES_SIZE_2;
LOGD("User default primes 2");
break;
}
LOGD("Set primes:%{public}d!", params->primes);
}
static void SetKeyType(HcfAlgParaValue value, HcfAsyKeyGenParams *params)
{
for (uint32_t i = 0; i < sizeof(KEY_TYPE_MAP) / sizeof(KEY_TYPE_MAP[0]); i++) {
if (KEY_TYPE_MAP[i].value == value) {
params->bits = KEY_TYPE_MAP[i].bits;
params->algo = KEY_TYPE_MAP[i].algo;
return;
}
}
LOGE("There is not matched algorithm.");
}
static HcfResult ParseAsyKeyGenParams(const HcfParaConfig* config, void *params)
{
if (config == NULL || params == NULL) {
LOGE("Config or params is null");
return HCF_INVALID_PARAMS;
}
HcfResult ret = HCF_SUCCESS;
HcfAsyKeyGenParams *paramsObj = (HcfAsyKeyGenParams *)params;
LOGD("Set Parameter: %{public}s", config->tag);
switch (config->paraType) {
case HCF_ALG_KEY_TYPE:
SetKeyType(config->paraValue, paramsObj);
break;
case HCF_ALG_PRIMES:
SetPrimes(config->paraValue, paramsObj);
break;
default:
LOGE("Unsupported parameter type in asy key gen params");
ret = HCF_INVALID_PARAMS;
break;
}
return ret;
}
static HcfResult CopyDsaCommonSpec(const HcfDsaCommParamsSpec *srcSpec, HcfDsaCommParamsSpec *destSpec)
{
if (CopyAsyKeyParamsSpec(&(srcSpec->base), &(destSpec->base)) != HCF_SUCCESS) {
LOGE("Failed to copy asy key params spec");
return HCF_INVALID_PARAMS;
}
destSpec->p.data = (unsigned char *)HcfMalloc(srcSpec->p.len, 0);
if (destSpec->p.data == NULL) {
LOGE("Failed to allocate p data memory");
FreeDsaCommParamsSpec(destSpec);
return HCF_ERR_MALLOC;
}
destSpec->q.data = (unsigned char *)HcfMalloc(srcSpec->q.len, 0);
if (destSpec->q.data == NULL) {
LOGE("Failed to allocate q data memory");
FreeDsaCommParamsSpec(destSpec);
return HCF_ERR_MALLOC;
}
destSpec->g.data = (unsigned char *)HcfMalloc(srcSpec->g.len, 0);
if (destSpec->g.data == NULL) {
LOGE("Failed to allocate g data memory");
FreeDsaCommParamsSpec(destSpec);
return HCF_ERR_MALLOC;
}
(void)memcpy_s(destSpec->p.data, srcSpec->p.len, srcSpec->p.data, srcSpec->p.len);
(void)memcpy_s(destSpec->q.data, srcSpec->q.len, srcSpec->q.data, srcSpec->q.len);
(void)memcpy_s(destSpec->g.data, srcSpec->g.len, srcSpec->g.data, srcSpec->g.len);
destSpec->p.len = srcSpec->p.len;
destSpec->q.len = srcSpec->q.len;
destSpec->g.len = srcSpec->g.len;
return HCF_SUCCESS;
}
static HcfResult CreateDsaCommonSpecImpl(const HcfDsaCommParamsSpec *srcSpec, HcfDsaCommParamsSpec **destSpec)
{
HcfDsaCommParamsSpec *spec = (HcfDsaCommParamsSpec *)HcfMalloc(sizeof(HcfDsaCommParamsSpec), 0);
if (spec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyDsaCommonSpec(srcSpec, spec) != HCF_SUCCESS) {
HcfFree(spec);
spec = NULL;
LOGE("Failed to copy DSA common spec");
return HCF_INVALID_PARAMS;
}
*destSpec = spec;
return HCF_SUCCESS;
}
static HcfResult CreateDsaPubKeySpecImpl(const HcfDsaPubKeyParamsSpec *srcSpec, HcfDsaPubKeyParamsSpec **destSpec)
{
HcfDsaPubKeyParamsSpec *spec = (HcfDsaPubKeyParamsSpec *)HcfMalloc(sizeof(HcfDsaPubKeyParamsSpec), 0);
if (spec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyDsaCommonSpec(&(srcSpec->base), &(spec->base)) != HCF_SUCCESS) {
HcfFree(spec);
spec = NULL;
LOGE("Failed to copy DSA common spec");
return HCF_INVALID_PARAMS;
}
spec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0);
if (spec->pk.data == NULL) {
LOGE("Failed to allocate public key memory");
FreeDsaCommParamsSpec(&(spec->base));
HcfFree(spec);
spec = NULL;
return HCF_ERR_MALLOC;
}
(void)memcpy_s(spec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len);
spec->pk.len = srcSpec->pk.len;
*destSpec = spec;
return HCF_SUCCESS;
}
static HcfResult CreateDsaKeyPairSpecImpl(const HcfDsaKeyPairParamsSpec *srcSpec, HcfDsaKeyPairParamsSpec **destSpec)
{
HcfDsaKeyPairParamsSpec *spec = (HcfDsaKeyPairParamsSpec *)HcfMalloc(sizeof(HcfDsaKeyPairParamsSpec), 0);
if (spec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyDsaCommonSpec(&(srcSpec->base), &(spec->base)) != HCF_SUCCESS) {
HcfFree(spec);
spec = NULL;
LOGE("Failed to copy DSA common spec");
return HCF_INVALID_PARAMS;
}
spec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0);
if (spec->pk.data == NULL) {
LOGE("Failed to allocate public key memory");
FreeDsaCommParamsSpec(&(spec->base));
HcfFree(spec);
spec = NULL;
return HCF_ERR_MALLOC;
}
spec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0);
if (spec->sk.data == NULL) {
LOGE("Failed to allocate private key memory");
FreeDsaCommParamsSpec(&(spec->base));
HcfFree(spec->pk.data);
spec->pk.data = NULL;
HcfFree(spec);
spec = NULL;
return HCF_ERR_MALLOC;
}
(void)memcpy_s(spec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len);
(void)memcpy_s(spec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len);
spec->pk.len = srcSpec->pk.len;
spec->sk.len = srcSpec->sk.len;
*destSpec = spec;
return HCF_SUCCESS;
}
static HcfResult CreateDsaParamsSpecImpl(const HcfAsyKeyParamsSpec *paramsSpec, HcfAsyKeyParamsSpec **impl)
{
HcfResult ret = HCF_SUCCESS;
HcfDsaCommParamsSpec *spec = NULL;
switch (paramsSpec->specType) {
case HCF_COMMON_PARAMS_SPEC:
ret = CreateDsaCommonSpecImpl((HcfDsaCommParamsSpec *)paramsSpec, &spec);
break;
case HCF_PUBLIC_KEY_SPEC:
ret = CreateDsaPubKeySpecImpl((HcfDsaPubKeyParamsSpec *)paramsSpec, (HcfDsaPubKeyParamsSpec **)&spec);
break;
case HCF_KEY_PAIR_SPEC:
ret = CreateDsaKeyPairSpecImpl((HcfDsaKeyPairParamsSpec *)paramsSpec, (HcfDsaKeyPairParamsSpec **)&spec);
break;
default:
LOGE("Unsupported DSA params spec type");
ret = HCF_INVALID_PARAMS;
break;
}
if (ret == HCF_SUCCESS) {
*impl = (HcfAsyKeyParamsSpec *)spec;
}
return ret;
}
static HcfResult CreateDhPubKeySpecImpl(const HcfDhPubKeyParamsSpec *srcSpec, HcfDhPubKeyParamsSpec **destSpec)
{
HcfDhPubKeyParamsSpec *spec = (HcfDhPubKeyParamsSpec *)HcfMalloc(sizeof(HcfDhPubKeyParamsSpec), 0);
if (spec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyDhCommonSpec(&(srcSpec->base), &(spec->base)) != HCF_SUCCESS) {
LOGE("Failed to copy src spec");
HcfFree(spec);
spec = NULL;
return HCF_INVALID_PARAMS;
}
spec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0);
if (spec->pk.data == NULL) {
LOGE("Failed to allocate public key memory");
DestroyDhPubKeySpec(spec);
return HCF_ERR_MALLOC;
}
(void)memcpy_s(spec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len);
spec->pk.len = srcSpec->pk.len;
*destSpec = spec;
return HCF_SUCCESS;
}
static HcfResult CreateDhPriKeySpecImpl(const HcfDhPriKeyParamsSpec *srcSpec, HcfDhPriKeyParamsSpec **destSpec)
{
HcfDhPriKeyParamsSpec *spec = (HcfDhPriKeyParamsSpec *)HcfMalloc(sizeof(HcfDhPriKeyParamsSpec), 0);
if (spec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyDhCommonSpec(&(srcSpec->base), &(spec->base)) != HCF_SUCCESS) {
LOGE("Failed to copy src spec");
HcfFree(spec);
spec = NULL;
return HCF_INVALID_PARAMS;
}
spec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0);
if (spec->sk.data == NULL) {
LOGE("Failed to allocate private key memory");
FreeDhCommParamsSpec(&(spec->base));
HcfFree(spec);
spec = NULL;
return HCF_ERR_MALLOC;
}
(void)memcpy_s(spec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len);
spec->sk.len = srcSpec->sk.len;
*destSpec = spec;
return HCF_SUCCESS;
}
static HcfResult CreateDhKeyPairSpecImpl(const HcfDhKeyPairParamsSpec *srcSpec, HcfDhKeyPairParamsSpec **destSpec)
{
HcfDhKeyPairParamsSpec *spec = (HcfDhKeyPairParamsSpec *)HcfMalloc(sizeof(HcfDhKeyPairParamsSpec), 0);
if (spec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyDhCommonSpec(&(srcSpec->base), &(spec->base)) != HCF_SUCCESS) {
LOGE("Failed to copy src spec");
HcfFree(spec);
spec = NULL;
return HCF_INVALID_PARAMS;
}
spec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0);
if (spec->pk.data == NULL) {
LOGE("Failed to allocate public key memory");
FreeDhCommParamsSpec(&(spec->base));
HcfFree(spec);
spec = NULL;
return HCF_ERR_MALLOC;
}
spec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0);
if (spec->sk.data == NULL) {
LOGE("Failed to allocate private key memory");
FreeDhCommParamsSpec(&(spec->base));
HcfFree(spec->pk.data);
spec->pk.data = NULL;
HcfFree(spec);
spec = NULL;
return HCF_ERR_MALLOC;
}
(void)memcpy_s(spec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len);
(void)memcpy_s(spec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len);
spec->pk.len = srcSpec->pk.len;
spec->sk.len = srcSpec->sk.len;
*destSpec = spec;
return HCF_SUCCESS;
}
static HcfResult CreateDhParamsSpecImpl(const HcfAsyKeyParamsSpec *paramsSpec, HcfAsyKeyParamsSpec **impl)
{
HcfResult ret = HCF_SUCCESS;
HcfDhCommParamsSpec *spec = NULL;
switch (paramsSpec->specType) {
case HCF_COMMON_PARAMS_SPEC:
ret = CreateDhCommonSpecImpl((HcfDhCommParamsSpec *)paramsSpec, &spec);
break;
case HCF_PUBLIC_KEY_SPEC:
ret = CreateDhPubKeySpecImpl((HcfDhPubKeyParamsSpec *)paramsSpec, (HcfDhPubKeyParamsSpec **)&spec);
break;
case HCF_PRIVATE_KEY_SPEC:
ret = CreateDhPriKeySpecImpl((HcfDhPriKeyParamsSpec *)paramsSpec, (HcfDhPriKeyParamsSpec **)&spec);
break;
case HCF_KEY_PAIR_SPEC:
ret = CreateDhKeyPairSpecImpl((HcfDhKeyPairParamsSpec *)paramsSpec, (HcfDhKeyPairParamsSpec **)&spec);
break;
default:
LOGE("Invalid spec type [%{public}d]", paramsSpec->specType);
ret = HCF_INVALID_PARAMS;
break;
}
if (ret == HCF_SUCCESS) {
*impl = (HcfAsyKeyParamsSpec *)spec;
}
return ret;
}
static HcfResult CreateEccPubKeySpecImpl(const HcfEccPubKeyParamsSpec *srcSpec, HcfEccPubKeyParamsSpec **destSpec)
{
HcfEccPubKeyParamsSpec *tmpSpec = (HcfEccPubKeyParamsSpec *)HcfMalloc(sizeof(HcfEccPubKeyParamsSpec), 0);
if (tmpSpec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyEccCommonSpec(&(srcSpec->base), &(tmpSpec->base)) != HCF_SUCCESS) {
HcfFree(tmpSpec);
tmpSpec = NULL;
LOGE("Failed to copy ECC common spec");
return HCF_INVALID_PARAMS;
}
HcfResult res = CopyPoint(&(srcSpec->pk), &(tmpSpec->pk));
if (res != HCF_SUCCESS) {
LOGE("Failed to allocate public key memory");
FreeEccCommParamsSpec(&(tmpSpec->base));
HcfFree(tmpSpec);
tmpSpec = NULL;
return res;
}
*destSpec = tmpSpec;
return HCF_SUCCESS;
}
static HcfResult CreateEccPriKeySpecImpl(const HcfEccPriKeyParamsSpec *srcSpec, HcfEccPriKeyParamsSpec **destSpec)
{
HcfEccPriKeyParamsSpec *tmpSpec = (HcfEccPriKeyParamsSpec *)HcfMalloc(sizeof(HcfEccPriKeyParamsSpec), 0);
if (tmpSpec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyEccCommonSpec(&(srcSpec->base), &(tmpSpec->base)) != HCF_SUCCESS) {
HcfFree(tmpSpec);
tmpSpec = NULL;
LOGE("Failed to copy ECC common spec");
return HCF_INVALID_PARAMS;
}
tmpSpec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0);
if (tmpSpec->sk.data == NULL) {
LOGE("Failed to allocate private key memory");
FreeEccCommParamsSpec(&(tmpSpec->base));
HcfFree(tmpSpec);
tmpSpec = NULL;
return HCF_ERR_MALLOC;
}
(void)memcpy_s(tmpSpec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len);
tmpSpec->sk.len = srcSpec->sk.len;
*destSpec = tmpSpec;
return HCF_SUCCESS;
}
static HcfResult CreateEccKeyPairSpecImpl(const HcfEccKeyPairParamsSpec *srcSpec, HcfEccKeyPairParamsSpec **destSpec)
{
HcfEccKeyPairParamsSpec *tmpSpec = (HcfEccKeyPairParamsSpec *)HcfMalloc(sizeof(HcfEccKeyPairParamsSpec), 0);
if (tmpSpec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyEccCommonSpec(&(srcSpec->base), &(tmpSpec->base)) != HCF_SUCCESS) {
HcfFree(tmpSpec);
tmpSpec = NULL;
LOGE("Failed to copy ECC common spec");
return HCF_INVALID_PARAMS;
}
HcfResult res = CopyPoint(&(srcSpec->pk), &(tmpSpec->pk));
if (res != HCF_SUCCESS) {
LOGE("Failed to allocate public key memory");
FreeEccCommParamsSpec(&(tmpSpec->base));
HcfFree(tmpSpec);
tmpSpec = NULL;
return res;
}
tmpSpec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0);
if (tmpSpec->sk.data == NULL) {
LOGE("Failed to allocate private key memory");
FreeEccCommParamsSpec(&(tmpSpec->base));
HcfFree(tmpSpec->pk.x.data);
tmpSpec->pk.x.data = NULL;
HcfFree(tmpSpec->pk.y.data);
tmpSpec->pk.y.data = NULL;
HcfFree(tmpSpec);
tmpSpec = NULL;
return HCF_ERR_MALLOC;
}
(void)memcpy_s(tmpSpec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len);
tmpSpec->sk.len = srcSpec->sk.len;
*destSpec = tmpSpec;
return HCF_SUCCESS;
}
static HcfResult CreateEccParamsSpecImpl(const HcfAsyKeyParamsSpec *paramsSpec, HcfAsyKeyParamsSpec **impl)
{
HcfResult ret = HCF_SUCCESS;
HcfEccCommParamsSpec *spec = NULL;
switch (paramsSpec->specType) {
case HCF_COMMON_PARAMS_SPEC:
ret = CreateEccCommonSpecImpl((HcfEccCommParamsSpec *)paramsSpec, &spec);
break;
case HCF_PUBLIC_KEY_SPEC:
ret = CreateEccPubKeySpecImpl((HcfEccPubKeyParamsSpec *)paramsSpec, (HcfEccPubKeyParamsSpec **)(&spec));
break;
case HCF_PRIVATE_KEY_SPEC:
ret = CreateEccPriKeySpecImpl((HcfEccPriKeyParamsSpec *)paramsSpec, (HcfEccPriKeyParamsSpec **)(&spec));
break;
case HCF_KEY_PAIR_SPEC:
ret = CreateEccKeyPairSpecImpl((HcfEccKeyPairParamsSpec *)paramsSpec, (HcfEccKeyPairParamsSpec **)(&spec));
break;
default:
LOGE("Unsupported ECC params spec type");
ret = HCF_INVALID_PARAMS;
break;
}
if (ret == HCF_SUCCESS) {
*impl = (HcfAsyKeyParamsSpec *)spec;
}
return ret;
}
static HcfResult CopyRsaCommonSpec(const HcfRsaCommParamsSpec *srcSpec, HcfRsaCommParamsSpec *destSpec)
{
if (CopyAsyKeyParamsSpec(&(srcSpec->base), &(destSpec->base)) != HCF_SUCCESS) {
LOGE("Failed to copy asy key params spec");
return HCF_INVALID_PARAMS;
}
destSpec->n.data = (unsigned char *)HcfMalloc(srcSpec->n.len, 0);
if (destSpec->n.data == NULL) {
LOGE("Failed to allocate n data memory");
HcfFree(destSpec->base.algName);
destSpec->base.algName = NULL;
return HCF_ERR_MALLOC;
}
(void)memcpy_s(destSpec->n.data, srcSpec->n.len, srcSpec->n.data, srcSpec->n.len);
destSpec->n.len = srcSpec->n.len;
return HCF_SUCCESS;
}
static HcfResult CreateRsaPubKeySpecImpl(const HcfRsaPubKeyParamsSpec *srcSpec, HcfRsaPubKeyParamsSpec **destSpec)
{
HcfRsaPubKeyParamsSpec *spec = (HcfRsaPubKeyParamsSpec *)HcfMalloc(sizeof(HcfRsaPubKeyParamsSpec), 0);
if (spec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyRsaCommonSpec(&(srcSpec->base), &(spec->base)) != HCF_SUCCESS) {
HcfFree(spec);
spec = NULL;
LOGE("Failed to copy RSA common spec");
return HCF_INVALID_PARAMS;
}
spec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0);
if (spec->pk.data == NULL) {
LOGE("Failed to allocate public key memory");
DestroyRsaPubKeySpec(spec);
return HCF_ERR_MALLOC;
}
(void)memcpy_s(spec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len);
spec->pk.len = srcSpec->pk.len;
*destSpec = spec;
return HCF_SUCCESS;
}
static HcfResult CreateRsaKeyPairSpecImpl(const HcfRsaKeyPairParamsSpec *srcSpec, HcfRsaKeyPairParamsSpec **destSpec)
{
HcfRsaKeyPairParamsSpec *spec = (HcfRsaKeyPairParamsSpec *)HcfMalloc(sizeof(HcfRsaKeyPairParamsSpec), 0);
if (spec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyRsaCommonSpec(&(srcSpec->base), &(spec->base)) != HCF_SUCCESS) {
HcfFree(spec);
spec = NULL;
LOGE("Failed to copy RSA common spec");
return HCF_INVALID_PARAMS;
}
spec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0);
if (spec->pk.data == NULL) {
LOGE("Failed to allocate public key memory");
FreeRsaCommParamsSpec(&(spec->base));
HcfFree(spec);
spec = NULL;
return HCF_ERR_MALLOC;
}
spec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0);
if (spec->sk.data == NULL) {
LOGE("Failed to allocate private key memory");
FreeRsaCommParamsSpec(&(spec->base));
HcfFree(spec->pk.data);
spec->pk.data = NULL;
HcfFree(spec);
spec = NULL;
return HCF_ERR_MALLOC;
}
(void)memcpy_s(spec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len);
(void)memcpy_s(spec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len);
spec->pk.len = srcSpec->pk.len;
spec->sk.len = srcSpec->sk.len;
*destSpec = spec;
return HCF_SUCCESS;
}
static HcfResult CreateRsaParamsSpecImpl(const HcfAsyKeyParamsSpec *paramsSpec, HcfAsyKeyParamsSpec **impl)
{
HcfResult ret = HCF_SUCCESS;
HcfRsaCommParamsSpec *spec = NULL;
switch (paramsSpec->specType) {
case HCF_COMMON_PARAMS_SPEC:
LOGE("RSA not support comm spec");
ret = HCF_INVALID_PARAMS;
break;
case HCF_PUBLIC_KEY_SPEC:
ret = CreateRsaPubKeySpecImpl((HcfRsaPubKeyParamsSpec *)paramsSpec, (HcfRsaPubKeyParamsSpec **)&spec);
break;
case HCF_KEY_PAIR_SPEC:
ret = CreateRsaKeyPairSpecImpl((HcfRsaKeyPairParamsSpec *)paramsSpec, (HcfRsaKeyPairParamsSpec **)&spec);
break;
default:
LOGE("Unsupported RSA params spec type");
ret = HCF_INVALID_PARAMS;
break;
}
if (ret == HCF_SUCCESS) {
*impl = (HcfAsyKeyParamsSpec *)spec;
}
return ret;
}
static HcfResult CreateAlg25519PubKeySpecImpl(const HcfAlg25519PubKeyParamsSpec *srcSpec,
HcfAlg25519PubKeyParamsSpec **destSpec)
{
HcfAlg25519PubKeyParamsSpec *tmpSpec =
(HcfAlg25519PubKeyParamsSpec *)HcfMalloc(sizeof(HcfAlg25519PubKeyParamsSpec), 0);
if (tmpSpec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyAsyKeyParamsSpec(&(srcSpec->base), &(tmpSpec->base)) != HCF_SUCCESS) {
DestroyAlg25519PubKeySpec(tmpSpec);
LOGE("Copy alg25519 commonSpec memory");
return HCF_INVALID_PARAMS;
}
tmpSpec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0);
if (tmpSpec->pk.data == NULL) {
LOGE("Failed to allocate private key memory");
DestroyAlg25519PubKeySpec(tmpSpec);
return HCF_ERR_MALLOC;
}
(void)memcpy_s(tmpSpec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len);
tmpSpec->pk.len = srcSpec->pk.len;
*destSpec = tmpSpec;
return HCF_SUCCESS;
}
static HcfResult CreateAlg25519PriKeySpecImpl(const HcfAlg25519PriKeyParamsSpec *srcSpec,
HcfAlg25519PriKeyParamsSpec **destSpec)
{
HcfAlg25519PriKeyParamsSpec *tmpSpec =
(HcfAlg25519PriKeyParamsSpec *)HcfMalloc(sizeof(HcfAlg25519PriKeyParamsSpec), 0);
if (tmpSpec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyAsyKeyParamsSpec(&(srcSpec->base), &(tmpSpec->base)) != HCF_SUCCESS) {
DestroyAlg25519PriKeySpec(tmpSpec);
LOGE("Copy alg25519 commonSpec memory");
return HCF_INVALID_PARAMS;
}
tmpSpec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0);
if (tmpSpec->sk.data == NULL) {
LOGE("Failed to allocate private key memory");
DestroyAlg25519PriKeySpec(tmpSpec);
return HCF_ERR_MALLOC;
}
(void)memcpy_s(tmpSpec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len);
tmpSpec->sk.len = srcSpec->sk.len;
*destSpec = tmpSpec;
return HCF_SUCCESS;
}
static HcfResult CreateAlg25519KeyPairSpecImpl(const HcfAlg25519KeyPairParamsSpec *srcSpec,
HcfAlg25519KeyPairParamsSpec **destSpec)
{
HcfAlg25519KeyPairParamsSpec *tmpSpec =
(HcfAlg25519KeyPairParamsSpec *)HcfMalloc(sizeof(HcfAlg25519KeyPairParamsSpec), 0);
if (tmpSpec == NULL) {
LOGE("Failed to allocate dest spec memory");
return HCF_ERR_MALLOC;
}
if (CopyAsyKeyParamsSpec(&(srcSpec->base), &(tmpSpec->base)) != HCF_SUCCESS) {
DestroyAlg25519KeyPairSpec(tmpSpec);
LOGE("Copy alg25519 commonSpec memory");
return HCF_INVALID_PARAMS;
}
tmpSpec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0);
if (tmpSpec->pk.data == NULL) {
LOGE("Failed to allocate private key memory");
DestroyAlg25519KeyPairSpec(tmpSpec);
return HCF_ERR_MALLOC;
}
tmpSpec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0);
if (tmpSpec->sk.data == NULL) {
LOGE("Failed to allocate private key memory");
DestroyAlg25519KeyPairSpec(tmpSpec);
return HCF_ERR_MALLOC;
}
(void)memcpy_s(tmpSpec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len);
tmpSpec->pk.len = srcSpec->pk.len;
(void)memcpy_s(tmpSpec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len);
tmpSpec->sk.len = srcSpec->sk.len;
*destSpec = tmpSpec;
return HCF_SUCCESS;
}
static HcfResult CreateAlg25519ParamsSpecImpl(const HcfAsyKeyParamsSpec *paramsSpec, HcfAsyKeyParamsSpec **impl)
{
HcfResult ret = HCF_SUCCESS;
HcfAlg25519PubKeyParamsSpec *pubKeySpec = NULL;
HcfAlg25519PriKeyParamsSpec *priKeySpec = NULL;
HcfAlg25519KeyPairParamsSpec *keyPairSpec = NULL;
switch (paramsSpec->specType) {
case HCF_PUBLIC_KEY_SPEC:
ret = CreateAlg25519PubKeySpecImpl((HcfAlg25519PubKeyParamsSpec *)paramsSpec, &pubKeySpec);
if (ret == HCF_SUCCESS) {
*impl = (HcfAsyKeyParamsSpec *)pubKeySpec;
}
break;
case HCF_PRIVATE_KEY_SPEC:
ret = CreateAlg25519PriKeySpecImpl((HcfAlg25519PriKeyParamsSpec *)paramsSpec, &priKeySpec);
if (ret == HCF_SUCCESS) {
*impl = (HcfAsyKeyParamsSpec *)priKeySpec;
}
break;
case HCF_KEY_PAIR_SPEC:
ret = CreateAlg25519KeyPairSpecImpl((HcfAlg25519KeyPairParamsSpec *)paramsSpec, &keyPairSpec);
if (ret == HCF_SUCCESS) {
*impl = (HcfAsyKeyParamsSpec *)keyPairSpec;
}
break;
default:
LOGE("SpecType not support! [SpecType]: %{public}d", paramsSpec->specType);
ret = HCF_INVALID_PARAMS;
break;
}
return ret;
}
static HcfResult CreateAsyKeyParamsSpecImpl(const HcfAsyKeyParamsSpec *paramsSpec, HcfAlgValue alg,
HcfAsyKeyParamsSpec **impl)
{
HcfResult ret = HCF_SUCCESS;
switch (alg) {
case HCF_ALG_DSA:
ret = CreateDsaParamsSpecImpl(paramsSpec, impl);
break;
case HCF_ALG_SM2:
case HCF_ALG_ECC:
ret = CreateEccParamsSpecImpl(paramsSpec, impl);
break;
case HCF_ALG_RSA:
ret = CreateRsaParamsSpecImpl(paramsSpec, impl);
break;
case HCF_ALG_ED25519:
case HCF_ALG_X25519:
ret = CreateAlg25519ParamsSpecImpl(paramsSpec, impl);
break;
case HCF_ALG_DH:
ret = CreateDhParamsSpecImpl(paramsSpec, impl);
break;
case HCF_ALG_ML_KEM:
case HCF_ALG_ML_DSA:
LOGE("ML-KEM/ML-DSA does not support params spec creation");
ret = HCF_INVALID_PARAMS;
break;
default:
LOGE("Unsupported algorithm for asy key params spec creation");
ret = HCF_INVALID_PARAMS;
break;
}
return ret;
}
static const char *GetAsyKeyGeneratorClass(void)
{
return ASY_KEY_GENERATOR_CLASS;
}
static const char *GetAsyKeyGeneratorBySpecClass(void)
{
return ASY_KEY_GENERATOR_BY_SPEC_CLASS;
}
static const char *GetAlgoName(HcfAsyKeyGenerator *self)
{
if (self == NULL) {
LOGE("The input self ptr is NULL!");
return NULL;
}
if (!HcfIsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) {
return NULL;
}
HcfAsyKeyGeneratorImpl *impl = (HcfAsyKeyGeneratorImpl *)self;
return impl->algoName;
}
static const char *GetAlgNameBySpec(const HcfAsyKeyGeneratorBySpec *self)
{
if (self == NULL) {
LOGE("The input self ptr is NULL!");
return NULL;
}
if (!HcfIsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorBySpecClass())) {
return NULL;
}
HcfAsyKeyGeneratorBySpecImpl *impl = (HcfAsyKeyGeneratorBySpecImpl *)self;
return impl->paramsSpec->algName;
}
static HcfResult ConvertKey(HcfAsyKeyGenerator *self, HcfParamsSpec *params, HcfBlob *pubKeyBlob,
HcfBlob *priKeyBlob, HcfKeyPair **returnKeyPair)
{
if (self == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
if (!HcfIsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) {
return HCF_INVALID_PARAMS;
}
HcfAsyKeyGeneratorImpl *impl = (HcfAsyKeyGeneratorImpl *)self;
if (impl->spiObj == NULL || impl->spiObj->engineConvertKey == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
return impl->spiObj->engineConvertKey(impl->spiObj, params, pubKeyBlob, priKeyBlob, returnKeyPair);
}
static HcfResult ConvertPemKey(HcfAsyKeyGenerator *self, HcfParamsSpec *params, const char *pubKeyStr,
const char *priKeyStr, HcfKeyPair **returnKeyPair)
{
if (self == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
if (!HcfIsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) {
return HCF_INVALID_PARAMS;
}
HcfAsyKeyGeneratorImpl *impl = (HcfAsyKeyGeneratorImpl *)self;
if (impl->spiObj == NULL || impl->spiObj->engineConvertPemKey == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
return impl->spiObj->engineConvertPemKey(impl->spiObj, params, pubKeyStr, priKeyStr, returnKeyPair);
}
static HcfResult GenerateKeyPair(HcfAsyKeyGenerator *self, HcfParamsSpec *params,
HcfKeyPair **returnKeyPair)
{
(void)params;
if (self == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
if (!HcfIsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) {
return HCF_INVALID_PARAMS;
}
HcfAsyKeyGeneratorImpl *impl = (HcfAsyKeyGeneratorImpl *)self;
if (impl->spiObj == NULL || impl->spiObj->engineGenerateKeyPair == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
return impl->spiObj->engineGenerateKeyPair(impl->spiObj, returnKeyPair);
}
static HcfResult GenerateKeyPairBySpec(const HcfAsyKeyGeneratorBySpec *self, HcfKeyPair **returnKeyPair)
{
if (self == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
if (!HcfIsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorBySpecClass())) {
return HCF_INVALID_PARAMS;
}
HcfAsyKeyGeneratorBySpecImpl *impl = (HcfAsyKeyGeneratorBySpecImpl *)self;
if (impl->spiObj == NULL || impl->spiObj->engineGenerateKeyPairBySpec == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
return impl->spiObj->engineGenerateKeyPairBySpec(impl->spiObj, impl->paramsSpec, returnKeyPair);
}
static HcfResult GeneratePubKeyBySpec(const HcfAsyKeyGeneratorBySpec *self, HcfPubKey **returnPubKey)
{
if (self == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
if (!HcfIsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorBySpecClass())) {
return HCF_INVALID_PARAMS;
}
HcfAsyKeyGeneratorBySpecImpl *impl = (HcfAsyKeyGeneratorBySpecImpl *)self;
if (impl->spiObj == NULL || impl->spiObj->engineGeneratePubKeyBySpec == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
return impl->spiObj->engineGeneratePubKeyBySpec(impl->spiObj, impl->paramsSpec, returnPubKey);
}
static HcfResult GeneratePriKeyBySpec(const HcfAsyKeyGeneratorBySpec *self, HcfPriKey **returnPriKey)
{
if (self == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
if (!HcfIsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorBySpecClass())) {
return HCF_INVALID_PARAMS;
}
HcfAsyKeyGeneratorBySpecImpl *impl = (HcfAsyKeyGeneratorBySpecImpl *)self;
if (impl->spiObj == NULL || impl->spiObj->engineGeneratePriKeyBySpec == NULL) {
LOGE("Invalid input parameter.");
return HCF_INVALID_PARAMS;
}
return impl->spiObj->engineGeneratePriKeyBySpec(impl->spiObj, impl->paramsSpec, returnPriKey);
}
static void DestroyAsyKeyGenerator(HcfObjectBase *self)
{
if (self == NULL) {
return;
}
if (!HcfIsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) {
return;
}
HcfAsyKeyGeneratorImpl *impl = (HcfAsyKeyGeneratorImpl *)self;
HcfObjDestroy(impl->spiObj);
impl->spiObj = NULL;
HcfFree(impl);
}
static void DestroyAsyKeyGeneratorBySpec(HcfObjectBase *self)
{
if (self == NULL) {
return;
}
if (!HcfIsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorBySpecClass())) {
return;
}
HcfAsyKeyGeneratorBySpecImpl *impl = (HcfAsyKeyGeneratorBySpecImpl *)self;
HcfObjDestroy(impl->spiObj);
impl->spiObj = NULL;
FreeAsyKeySpec(impl->paramsSpec);
impl->paramsSpec = NULL;
HcfFree(impl);
}
HcfResult HcfAsyKeyGeneratorCreate(const char *algoName, HcfAsyKeyGenerator **returnObj)
{
if ((!HcfIsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) {
LOGE("AlgoName is invalid or returnObj is null");
return HCF_INVALID_PARAMS;
}
HcfAsyKeyGenParams params = { 0 };
if (ParseAndSetParameter(algoName, ¶ms, ParseAsyKeyGenParams) != HCF_SUCCESS) {
LOGE("Failed to parse params!");
return HCF_INVALID_PARAMS;
}
HcfAsyKeyGeneratorSpiCreateFunc createSpiFunc = FindAbility(¶ms);
if (createSpiFunc == NULL) {
LOGE("No matching asy key generator ability found");
return HCF_NOT_SUPPORT;
}
HcfAsyKeyGeneratorImpl *returnGenerator = (HcfAsyKeyGeneratorImpl *)HcfMalloc(sizeof(HcfAsyKeyGeneratorImpl), 0);
if (returnGenerator == NULL) {
LOGE("Failed to allocate returnGenerator memory!");
return HCF_ERR_MALLOC;
}
if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) {
LOGE("Failed to copy algoName!");
HcfFree(returnGenerator);
returnGenerator = NULL;
return HCF_INVALID_PARAMS;
}
HcfAsyKeyGeneratorSpi *spiObj = NULL;
HcfResult res = HCF_SUCCESS;
res = createSpiFunc(¶ms, &spiObj);
if (res != HCF_SUCCESS) {
LOGE("Failed to create spi object!");
HcfFree(returnGenerator);
returnGenerator = NULL;
return res;
}
returnGenerator->base.base.destroy = DestroyAsyKeyGenerator;
returnGenerator->base.base.getClass = GetAsyKeyGeneratorClass;
returnGenerator->base.convertKey = ConvertKey;
returnGenerator->base.convertPemKey = ConvertPemKey;
returnGenerator->base.generateKeyPair = GenerateKeyPair;
returnGenerator->base.getAlgoName = GetAlgoName;
returnGenerator->spiObj = spiObj;
*returnObj = (HcfAsyKeyGenerator *)returnGenerator;
return HCF_SUCCESS;
}
HcfResult HcfAsyKeyGeneratorBySpecCreate(const HcfAsyKeyParamsSpec *paramsSpec, HcfAsyKeyGeneratorBySpec **returnObj)
{
if ((!IsParamsSpecValid(paramsSpec)) || (returnObj == NULL)) {
LOGE("ParamsSpec is invalid or returnObj is null");
return HCF_INVALID_PARAMS;
}
HcfAsyKeyGenParams params = { 0 };
if (ParseAlgNameToParams(paramsSpec->algName, ¶ms) != HCF_SUCCESS) {
LOGE("Failed to parse params!");
return HCF_INVALID_PARAMS;
}
HcfAsyKeyGeneratorSpiCreateFunc createSpiFunc = FindAbility(¶ms);
if (createSpiFunc == NULL) {
LOGE("No matching asy key generator by spec ability found");
return HCF_NOT_SUPPORT;
}
HcfAsyKeyGeneratorBySpecImpl *returnGenerator =
(HcfAsyKeyGeneratorBySpecImpl *)HcfMalloc(sizeof(HcfAsyKeyGeneratorBySpecImpl), 0);
if (returnGenerator == NULL) {
LOGE("Failed to allocate returnGenerator memory!");
return HCF_ERR_MALLOC;
}
HcfAsyKeyParamsSpec *paramsSpecImpl = NULL;
HcfResult ret = CreateAsyKeyParamsSpecImpl(paramsSpec, params.algo, ¶msSpecImpl);
if (ret != HCF_SUCCESS) {
LOGE("Failed to create asy key params spec impl!");
HcfFree(returnGenerator);
returnGenerator = NULL;
return ret;
}
HcfAsyKeyGeneratorSpi *spiObj = NULL;
ret = createSpiFunc(¶ms, &spiObj);
if (ret != HCF_SUCCESS) {
LOGE("Failed to create spi object!");
HcfFree(returnGenerator);
returnGenerator = NULL;
FreeAsyKeySpec(paramsSpecImpl);
paramsSpecImpl = NULL;
return ret;
}
returnGenerator->base.base.destroy = DestroyAsyKeyGeneratorBySpec;
returnGenerator->base.base.getClass = GetAsyKeyGeneratorBySpecClass;
returnGenerator->base.generateKeyPair = GenerateKeyPairBySpec;
returnGenerator->base.generatePubKey = GeneratePubKeyBySpec;
returnGenerator->base.generatePriKey = GeneratePriKeyBySpec;
returnGenerator->base.getAlgName = GetAlgNameBySpec;
returnGenerator->paramsSpec = paramsSpecImpl;
returnGenerator->spiObj = spiObj;
*returnObj = (HcfAsyKeyGeneratorBySpec *)returnGenerator;
return HCF_SUCCESS;
}