/* * Copyright (C) 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 "crypto_asym_key.h" #include #include #include #include "key_pair.h" #include "detailed_ecc_key_params.h" #include "detailed_dh_key_params.h" #include "detailed_rsa_key_params.h" #include "detailed_dsa_key_params.h" #include "detailed_alg_25519_key_params.h" #include "params_parser.h" #include "ecc_key_util.h" #include "dh_key_util.h" #include "key_utils.h" #include "memory.h" #include "pub_key.h" #include "pri_key.h" #include "result.h" #include "blob.h" #include "object_base.h" #include "native_common.h" #include "crypto_common.h" #include "big_integer.h" #include "asy_key_generator.h" typedef struct OH_CryptoAsymKeyGenerator { HcfAsyKeyGenerator *base; HcfKeyDecodingParamsSpec *decSpec; } OH_CryptoAsymKeyGenerator; typedef struct OH_CryptoKeyPair { HcfObjectBase base; HcfPriKey *priKey; HcfPubKey *pubKey; } OH_CryptoKeyPair; typedef struct OH_CryptoPubKey { HcfKey base; HcfResult (*getAsyKeySpecBigInteger)(const HcfPubKey *self, const AsyKeySpecItem item, HcfBigInteger *returnBigInteger); HcfResult (*getAsyKeySpecString)(const HcfPubKey *self, const AsyKeySpecItem item, char **returnString); HcfResult (*getAsyKeySpecInt)(const HcfPubKey *self, const AsyKeySpecItem item, int *returnInt); HcfResult (*getEncodedDer)(const HcfPubKey *self, const char *format, HcfBlob *returnBlob); } OH_CryptoPubKey; typedef struct OH_CryptoPrivKey { HcfKey base; HcfResult (*getAsyKeySpecBigInteger)(const HcfPriKey *self, const AsyKeySpecItem item, HcfBigInteger *returnBigInteger); HcfResult (*getAsyKeySpecString)(const HcfPriKey *self, const AsyKeySpecItem item, char **returnString); HcfResult (*getAsyKeySpecInt)(const HcfPriKey *self, const AsyKeySpecItem item, int *returnInt); HcfResult (*getEncodedDer)(const HcfPriKey *self, const char *format, HcfBlob *returnBlob); HcfResult (*getEncodedPem)(const HcfPriKey *self, HcfParamsSpec *params, const char *format, char **returnString); void (*clearMem)(HcfPriKey *self); } OH_CryptoPrivKey; typedef struct OH_CryptoPrivKeyEncodingParams { HcfParamsSpec base; char *password; char *cipher; } OH_CryptoPrivKeyEncodingParams; typedef struct OH_CryptoAsymKeySpec { char *algName; HcfAsyKeySpecType specType; } OH_CryptoAsymKeySpec; typedef struct OH_CryptoAsymKeyGeneratorWithSpec { HcfAsyKeyGeneratorBySpec *generator; HcfAsyKeySpecType specType; } OH_CryptoAsymKeyGeneratorWithSpec; typedef struct OH_CryptoEcPoint { HcfPoint pointBase; char *curveName; } OH_CryptoEcPoint; OH_Crypto_ErrCode OH_CryptoAsymKeyGenerator_Create(const char *algoName, OH_CryptoAsymKeyGenerator **ctx) { if (ctx == NULL) { return CRYPTO_INVALID_PARAMS; } OH_CryptoAsymKeyGenerator *tmpCtx = HcfMalloc(sizeof(OH_CryptoAsymKeyGenerator), 0); if (tmpCtx == NULL) { return CRYPTO_MEMORY_ERROR; } HcfResult ret = HcfAsyKeyGeneratorCreate(algoName, &(tmpCtx->base)); if (ret != HCF_SUCCESS) { HcfFree(tmpCtx); tmpCtx = NULL; return GetOhCryptoErrCode(ret); } *ctx = tmpCtx; return GetOhCryptoErrCode(ret); } OH_Crypto_ErrCode OH_CryptoAsymKeyGenerator_Generate(OH_CryptoAsymKeyGenerator *ctx, OH_CryptoKeyPair **keyCtx) { if ((ctx == NULL) || (ctx->base == NULL) || (ctx->base->generateKeyPair == NULL) || (keyCtx == NULL)) { return CRYPTO_INVALID_PARAMS; } HcfResult ret = ctx->base->generateKeyPair((HcfAsyKeyGenerator *)(ctx->base), NULL, (HcfKeyPair **)keyCtx); return GetOhCryptoErrCode(ret); } OH_Crypto_ErrCode OH_CryptoAsymKeyGenerator_SetPassword(OH_CryptoAsymKeyGenerator *ctx, const unsigned char *password, uint32_t passwordLen) { if ((ctx == NULL) || (password == NULL) || (passwordLen == 0)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfKeyDecodingParamsSpec *decSpec = (HcfKeyDecodingParamsSpec *)HcfMalloc(sizeof(HcfKeyDecodingParamsSpec), 0); if (decSpec == NULL) { return CRYPTO_MEMORY_ERROR; } decSpec->password = (char *)HcfMalloc(passwordLen + 1, 0); if (decSpec->password == NULL) { HcfFree(decSpec); decSpec = NULL; return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(decSpec->password, passwordLen, password, passwordLen); ctx->decSpec = decSpec; return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode ProcessPriKeyData(Crypto_DataBlob *priKeyData, char **priKeyStr) { if (priKeyData == NULL) { return CRYPTO_SUCCESS; } *priKeyStr = (char *)HcfMalloc(priKeyData->len + 1, 0); if (*priKeyStr == NULL) { return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(*priKeyStr, priKeyData->len, priKeyData->data, priKeyData->len); return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode ProcessPubKeyData(Crypto_DataBlob *pubKeyData, char **pubKeyStr) { if (pubKeyData == NULL) { return CRYPTO_SUCCESS; } *pubKeyStr = (char *)HcfMalloc(pubKeyData->len + 1, 0); if (*pubKeyStr == NULL) { return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(*pubKeyStr, pubKeyData->len, pubKeyData->data, pubKeyData->len); return CRYPTO_SUCCESS; } static HcfResult ExecutePemConversion(OH_CryptoAsymKeyGenerator *ctx, char *pubKeyStr, char *priKeyStr, OH_CryptoKeyPair **keyCtx) { return ctx->base->convertPemKey == NULL ? HCF_INVALID_PARAMS : ctx->base->convertPemKey((HcfAsyKeyGenerator *)(ctx->base), (HcfParamsSpec *)(ctx->decSpec), pubKeyStr, priKeyStr, (HcfKeyPair **)keyCtx); } static void CleanupPemMemory(char *priKeyStr, char *pubKeyStr) { if (priKeyStr != NULL) { (void)memset_s(priKeyStr, strlen(priKeyStr), 0, strlen(priKeyStr)); HcfFree(priKeyStr); } if (pubKeyStr != NULL) { (void)memset_s(pubKeyStr, strlen(pubKeyStr), 0, strlen(pubKeyStr)); HcfFree(pubKeyStr); } } static OH_Crypto_ErrCode HandlePemConversion(OH_CryptoAsymKeyGenerator *ctx, Crypto_DataBlob *pubKeyData, Crypto_DataBlob *priKeyData, OH_CryptoKeyPair **keyCtx) { char *priKeyStr = NULL; char *pubKeyStr = NULL; OH_Crypto_ErrCode ret = ProcessPriKeyData(priKeyData, &priKeyStr); if (ret != CRYPTO_SUCCESS) { return ret; } ret = ProcessPubKeyData(pubKeyData, &pubKeyStr); if (ret != CRYPTO_SUCCESS) { CleanupPemMemory(priKeyStr, pubKeyStr); priKeyStr = NULL; pubKeyStr = NULL; return ret; } HcfResult hcfRet = ExecutePemConversion(ctx, pubKeyStr, priKeyStr, keyCtx); CleanupPemMemory(priKeyStr, pubKeyStr); priKeyStr = NULL; pubKeyStr = NULL; return GetOhCryptoErrCode(hcfRet); } OH_Crypto_ErrCode OH_CryptoAsymKeyGenerator_Convert(OH_CryptoAsymKeyGenerator *ctx, Crypto_EncodingType type, Crypto_DataBlob *pubKeyData, Crypto_DataBlob *priKeyData, OH_CryptoKeyPair **keyCtx) { if ((ctx == NULL) || (ctx->base == NULL) || (pubKeyData == NULL && priKeyData == NULL) || (keyCtx == NULL)) { return CRYPTO_INVALID_PARAMS; } switch (type) { case CRYPTO_PEM: return HandlePemConversion(ctx, pubKeyData, priKeyData, keyCtx); case CRYPTO_DER: return GetOhCryptoErrCode(ctx->base->convertKey == NULL ? HCF_INVALID_PARAMS : ctx->base->convertKey((HcfAsyKeyGenerator *)(ctx->base), (HcfParamsSpec *)(ctx->decSpec), (HcfBlob *)pubKeyData, (HcfBlob *)priKeyData, (HcfKeyPair **)keyCtx)); default: return CRYPTO_INVALID_PARAMS; } } const char *OH_CryptoAsymKeyGenerator_GetAlgoName(OH_CryptoAsymKeyGenerator *ctx) { if ((ctx == NULL) || (ctx->base == NULL) || (ctx->base->getAlgoName == NULL)) { return NULL; } return ctx->base->getAlgoName((HcfAsyKeyGenerator *)(ctx->base)); } static void FreeDecParamsSpec(HcfKeyDecodingParamsSpec *decSpec) { if (decSpec == NULL) { return; } if (decSpec->password != NULL) { (void)memset_s(decSpec->password, strlen(decSpec->password), 0, strlen(decSpec->password)); HcfFree(decSpec->password); decSpec->password = NULL; } HcfFree(decSpec); } void OH_CryptoAsymKeyGenerator_Destroy(OH_CryptoAsymKeyGenerator *ctx) { if (ctx == NULL) { return; } HcfObjDestroy(ctx->base); ctx->base = NULL; FreeDecParamsSpec(ctx->decSpec); ctx->decSpec = NULL; HcfFree(ctx); } void OH_CryptoKeyPair_Destroy(OH_CryptoKeyPair *keyCtx) { if (keyCtx == NULL) { return; } if (keyCtx->base.destroy != NULL) { keyCtx->base.destroy((HcfObjectBase *)keyCtx); return; } if ((keyCtx->priKey != NULL) && (keyCtx->priKey->base.base.destroy != NULL)) { HcfObjDestroy(keyCtx->priKey); keyCtx->priKey = NULL; HcfFree(keyCtx); return; } if ((keyCtx->pubKey != NULL) && (keyCtx->pubKey->base.base.destroy != NULL)) { HcfObjDestroy(keyCtx->pubKey); keyCtx->pubKey = NULL; HcfFree(keyCtx); return; } } OH_CryptoPubKey *OH_CryptoKeyPair_GetPubKey(OH_CryptoKeyPair *keyCtx) { if (keyCtx == NULL) { return NULL; } return (OH_CryptoPubKey *)keyCtx->pubKey; } OH_CryptoPrivKey *OH_CryptoKeyPair_GetPrivKey(OH_CryptoKeyPair *keyCtx) { if (keyCtx == NULL) { return NULL; } return (OH_CryptoPrivKey *)keyCtx->priKey; } OH_Crypto_ErrCode OH_CryptoPubKey_Encode(OH_CryptoPubKey *key, Crypto_EncodingType type, const char *encodingStandard, Crypto_DataBlob *out) { if ((key == NULL) || (out == NULL)) { return CRYPTO_INVALID_PARAMS; } HcfResult ret = HCF_SUCCESS; char *pemStr = NULL; switch (type) { case CRYPTO_PEM: if (key->base.getEncodedPem == NULL) { return CRYPTO_INVALID_PARAMS; } ret = key->base.getEncodedPem((HcfKey *)key, encodingStandard, &pemStr); if (ret != HCF_SUCCESS) { break; } out->data = (uint8_t *)pemStr; out->len = strlen(pemStr); break; case CRYPTO_DER: if (encodingStandard != NULL) { ret = key->getEncodedDer == NULL ? HCF_INVALID_PARAMS : key->getEncodedDer((HcfPubKey *)key, encodingStandard, (HcfBlob *)out); break; } else { ret = key->base.getEncoded == NULL ? HCF_INVALID_PARAMS : key->base.getEncoded((HcfKey *)key, (HcfBlob *)out); break; } default: return CRYPTO_INVALID_PARAMS; } return GetOhCryptoErrCode(ret); } OH_Crypto_ErrCode OH_CryptoPubKey_GetParam(OH_CryptoPubKey *key, CryptoAsymKey_ParamType item, Crypto_DataBlob *value) { if ((key == NULL) || (value == NULL)) { return CRYPTO_INVALID_PARAMS; } HcfResult ret = HCF_SUCCESS; int32_t *returnInt = NULL; char *returnStr = NULL; HcfBigInteger bigIntValue = {0}; switch (item) { case CRYPTO_DH_L_INT: case CRYPTO_ECC_H_INT: case CRYPTO_ECC_FIELD_SIZE_INT: returnInt = (int32_t *)HcfMalloc(sizeof(int32_t), 0); if (returnInt == NULL) { ret = HCF_ERR_MALLOC; break; } ret = key->getAsyKeySpecInt == NULL ? HCF_INVALID_PARAMS : key->getAsyKeySpecInt((HcfPubKey *)key, (AsyKeySpecItem)item, returnInt); if (ret != HCF_SUCCESS) { HCF_FREE_PTR(returnInt); break; } value->data = (uint8_t *)returnInt; value->len = sizeof(int32_t); ReverseUint8Arr(value->data, value->len); break; case CRYPTO_ECC_FIELD_TYPE_STR: case CRYPTO_ECC_CURVE_NAME_STR: ret = key->getAsyKeySpecString == NULL ? HCF_INVALID_PARAMS : key->getAsyKeySpecString((HcfPubKey *)key, (AsyKeySpecItem)item, &returnStr); if (ret != HCF_SUCCESS) { break; } value->data = (uint8_t *)returnStr; value->len = strlen(returnStr); break; default: ret = key->getAsyKeySpecBigInteger == NULL ? HCF_INVALID_PARAMS : key->getAsyKeySpecBigInteger((HcfPubKey *)key, (AsyKeySpecItem)item, &bigIntValue); if (ret != HCF_SUCCESS) { break; } value->data = (uint8_t *)bigIntValue.data; value->len = (size_t)bigIntValue.len; ReverseUint8Arr(value->data, value->len); break; } return GetOhCryptoErrCode(ret); } OH_Crypto_ErrCode OH_CryptoPrivKeyEncodingParams_Create(OH_CryptoPrivKeyEncodingParams **ctx) { if (ctx == NULL) { return CRYPTO_PARAMETER_CHECK_FAILED; } *ctx = (OH_CryptoPrivKeyEncodingParams *)HcfMalloc(sizeof(OH_CryptoPrivKeyEncodingParams), 0); if (*ctx == NULL) { return CRYPTO_MEMORY_ERROR; } return CRYPTO_SUCCESS; } OH_Crypto_ErrCode OH_CryptoPrivKeyEncodingParams_SetParam(OH_CryptoPrivKeyEncodingParams *ctx, CryptoPrivKeyEncoding_ParamType type, Crypto_DataBlob *value) { if ((ctx == NULL) || (value == NULL) || (value->data == NULL) || (value->len == 0)) { return CRYPTO_PARAMETER_CHECK_FAILED; } char *data = (char *)HcfMalloc(value->len + 1, 0); if (data == NULL) { return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(data, value->len, value->data, value->len); switch (type) { case CRYPTO_PRIVATE_KEY_ENCODING_PASSWORD_STR: HcfFree(ctx->password); ctx->password = data; break; case CRYPTO_PRIVATE_KEY_ENCODING_SYMMETRIC_CIPHER_STR: HcfFree(ctx->cipher); ctx->cipher = data; break; default: HcfFree(data); data = NULL; return CRYPTO_PARAMETER_CHECK_FAILED; } return CRYPTO_SUCCESS; } void OH_CryptoPrivKeyEncodingParams_Destroy(OH_CryptoPrivKeyEncodingParams *ctx) { if (ctx == NULL) { return; } HcfFree(ctx->password); ctx->password = NULL; HcfFree(ctx->cipher); ctx->cipher = NULL; HcfFree(ctx); } OH_Crypto_ErrCode OH_CryptoPrivKey_Encode(OH_CryptoPrivKey *key, Crypto_EncodingType type, const char *encodingStandard, OH_CryptoPrivKeyEncodingParams *params, Crypto_DataBlob *out) { if ((key == NULL) || (out == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfResult ret = HCF_SUCCESS; char *pemStr = NULL; switch (type) { case CRYPTO_PEM: if (key->getEncodedPem == NULL) { return CRYPTO_PARAMETER_CHECK_FAILED; } ret = key->getEncodedPem((HcfPriKey *)key, (HcfParamsSpec *)params, encodingStandard, &pemStr); if (ret != HCF_SUCCESS) { break; } out->data = (uint8_t *)pemStr; out->len = strlen(pemStr); break; case CRYPTO_DER: if (encodingStandard != NULL) { ret = key->getEncodedDer == NULL ? HCF_INVALID_PARAMS : key->getEncodedDer((HcfPriKey *)key, encodingStandard, (HcfBlob *)out); break; } else { ret = key->base.getEncoded == NULL ? HCF_INVALID_PARAMS : key->base.getEncoded((HcfKey *)key, (HcfBlob *)out); break; } default: return CRYPTO_PARAMETER_CHECK_FAILED; } return GetOhCryptoErrCodeNew(ret); } OH_Crypto_ErrCode OH_CryptoPrivKey_GetParam(OH_CryptoPrivKey *key, CryptoAsymKey_ParamType item, Crypto_DataBlob *value) { if ((key == NULL) || (value == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfResult ret = HCF_SUCCESS; int32_t *returnInt = NULL; char *returnStr = NULL; HcfBigInteger bigIntValue = {0}; switch (item) { case CRYPTO_DH_L_INT: case CRYPTO_ECC_H_INT: case CRYPTO_ECC_FIELD_SIZE_INT: returnInt = (int32_t *)HcfMalloc(sizeof(int32_t), 0); if (returnInt == NULL) { ret = HCF_ERR_MALLOC; break; } ret = key->getAsyKeySpecInt == NULL ? HCF_INVALID_PARAMS : key->getAsyKeySpecInt((HcfPriKey *)key, (AsyKeySpecItem)item, returnInt); if (ret != HCF_SUCCESS) { HCF_FREE_PTR(returnInt); break; } value->data = (uint8_t *)returnInt; value->len = sizeof(int32_t); ReverseUint8Arr(value->data, value->len); break; case CRYPTO_ECC_FIELD_TYPE_STR: case CRYPTO_ECC_CURVE_NAME_STR: ret = key->getAsyKeySpecString == NULL ? HCF_INVALID_PARAMS : key->getAsyKeySpecString((HcfPriKey *)key, (AsyKeySpecItem)item, &returnStr); if (ret != HCF_SUCCESS) { break; } value->data = (uint8_t *)returnStr; value->len = strlen(returnStr); break; default: ret = key->getAsyKeySpecBigInteger == NULL ? HCF_INVALID_PARAMS : key->getAsyKeySpecBigInteger((HcfPriKey *)key, (AsyKeySpecItem)item, &bigIntValue); if (ret != HCF_SUCCESS) { break; } value->data = (uint8_t *)bigIntValue.data; value->len = (size_t)bigIntValue.len; ReverseUint8Arr(value->data, value->len); break; } return GetOhCryptoErrCodeNew(ret); } OH_Crypto_ErrCode OH_CryptoAsymKeySpec_GenEcCommonParamsSpec(const char *curveName, OH_CryptoAsymKeySpec **spec) { if ((curveName == NULL) || (spec == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfResult ret = HcfEccKeyUtilCreate(curveName, (HcfEccCommParamsSpec **)spec); return GetOhCryptoErrCodeNew(ret); } OH_Crypto_ErrCode OH_CryptoAsymKeySpec_GenDhCommonParamsSpec(int pLen, int skLen, OH_CryptoAsymKeySpec **spec) { if (spec == NULL) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfResult ret = HcfDhKeyUtilCreate(pLen, skLen, (HcfDhCommParamsSpec **)spec); return GetOhCryptoErrCodeNew(ret); } typedef struct { CryptoAsymKeySpec_Type type; uint32_t memSize; } OH_CryptoAsymKeySpecInfo; typedef struct { HcfAlgValue algo; OH_CryptoAsymKeySpecInfo *specInfo; uint32_t specInfoSize; } OH_CryptoAsymKeySpecInfoMap; static OH_CryptoAsymKeySpecInfo g_rsaSpecInfo[] = { {CRYPTO_ASYM_KEY_PUBLIC_KEY_SPEC, sizeof(HcfRsaPubKeyParamsSpec)}, {CRYPTO_ASYM_KEY_KEY_PAIR_SPEC, sizeof(HcfRsaKeyPairParamsSpec)}, }; static OH_CryptoAsymKeySpecInfo g_dsaSpecInfo[] = { {CRYPTO_ASYM_KEY_COMMON_PARAMS_SPEC, sizeof(HcfDsaCommParamsSpec)}, {CRYPTO_ASYM_KEY_PUBLIC_KEY_SPEC, sizeof(HcfDsaPubKeyParamsSpec)}, {CRYPTO_ASYM_KEY_KEY_PAIR_SPEC, sizeof(HcfDsaKeyPairParamsSpec)}, }; static OH_CryptoAsymKeySpecInfo g_eccSpecInfo[] = { {CRYPTO_ASYM_KEY_COMMON_PARAMS_SPEC, sizeof(HcfEccCommParamsSpec)}, {CRYPTO_ASYM_KEY_PRIVATE_KEY_SPEC, sizeof(HcfEccPriKeyParamsSpec)}, {CRYPTO_ASYM_KEY_PUBLIC_KEY_SPEC, sizeof(HcfEccPubKeyParamsSpec)}, {CRYPTO_ASYM_KEY_KEY_PAIR_SPEC, sizeof(HcfEccKeyPairParamsSpec)}, }; static OH_CryptoAsymKeySpecInfo g_dhSpecInfo[] = { {CRYPTO_ASYM_KEY_COMMON_PARAMS_SPEC, sizeof(HcfDhCommParamsSpec)}, {CRYPTO_ASYM_KEY_PRIVATE_KEY_SPEC, sizeof(HcfDhPriKeyParamsSpec)}, {CRYPTO_ASYM_KEY_PUBLIC_KEY_SPEC, sizeof(HcfDhPubKeyParamsSpec)}, {CRYPTO_ASYM_KEY_KEY_PAIR_SPEC, sizeof(HcfDhKeyPairParamsSpec)}, }; static OH_CryptoAsymKeySpecInfo g_alg25519SpecInfo[] = { {CRYPTO_ASYM_KEY_PRIVATE_KEY_SPEC, sizeof(HcfAlg25519PriKeyParamsSpec)}, {CRYPTO_ASYM_KEY_PUBLIC_KEY_SPEC, sizeof(HcfAlg25519PubKeyParamsSpec)}, {CRYPTO_ASYM_KEY_KEY_PAIR_SPEC, sizeof(HcfAlg25519KeyPairParamsSpec)}, }; static OH_CryptoAsymKeySpecInfoMap g_asymKeySpecInfoMap[] = { {HCF_ALG_RSA, g_rsaSpecInfo, sizeof(g_rsaSpecInfo) / sizeof(g_rsaSpecInfo[0])}, {HCF_ALG_DSA, g_dsaSpecInfo, sizeof(g_dsaSpecInfo) / sizeof(g_dsaSpecInfo[0])}, {HCF_ALG_SM2, g_eccSpecInfo, sizeof(g_eccSpecInfo) / sizeof(g_eccSpecInfo[0])}, {HCF_ALG_ECC, g_eccSpecInfo, sizeof(g_eccSpecInfo) / sizeof(g_eccSpecInfo[0])}, {HCF_ALG_DH, g_dhSpecInfo, sizeof(g_dhSpecInfo) / sizeof(g_dhSpecInfo[0])}, {HCF_ALG_ED25519, g_alg25519SpecInfo, sizeof(g_alg25519SpecInfo) / sizeof(g_alg25519SpecInfo[0])}, {HCF_ALG_X25519, g_alg25519SpecInfo, sizeof(g_alg25519SpecInfo) / sizeof(g_alg25519SpecInfo[0])}, }; static OH_Crypto_ErrCode CreateAsymKeySpec(const char *algoName, CryptoAsymKeySpec_Type type, uint32_t memSize, OH_CryptoAsymKeySpec **spec) { OH_CryptoAsymKeySpec *tmpSpec = (OH_CryptoAsymKeySpec *)HcfMalloc(memSize, 0); if (tmpSpec == NULL) { return CRYPTO_MEMORY_ERROR; } char *algName = (char *)HcfMalloc(strlen(algoName) + 1, 0); if (algName == NULL) { HcfFree(tmpSpec); tmpSpec = NULL; return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(algName, strlen(algoName), algoName, strlen(algoName)); tmpSpec->specType = (HcfAsyKeySpecType)type; tmpSpec->algName = algName; *spec = tmpSpec; return CRYPTO_SUCCESS; } static const OH_CryptoAsymKeySpecInfoMap *FindAsymKeySpecInfoMapByAlgoName(const char *algoName) { HcfAsyKeyGenParams params = { 0 }; HcfResult ret = ParseAlgNameToParams(algoName, ¶ms); if (ret != HCF_SUCCESS) { return NULL; } for (uint32_t i = 0; i < (sizeof(g_asymKeySpecInfoMap) / sizeof(OH_CryptoAsymKeySpecInfoMap)); ++i) { if (g_asymKeySpecInfoMap[i].algo == params.algo) { return &g_asymKeySpecInfoMap[i]; } } return NULL; } OH_Crypto_ErrCode OH_CryptoAsymKeySpec_Create(const char *algoName, CryptoAsymKeySpec_Type type, OH_CryptoAsymKeySpec **spec) { if ((algoName == NULL) || (spec == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } const OH_CryptoAsymKeySpecInfoMap *infoMap = FindAsymKeySpecInfoMapByAlgoName(algoName); if (infoMap == NULL) { return CRYPTO_PARAMETER_CHECK_FAILED; } for (uint32_t i = 0; i < infoMap->specInfoSize; ++i) { if (infoMap->specInfo[i].type == type) { return CreateAsymKeySpec(algoName, type, infoMap->specInfo[i].memSize, spec); } } return CRYPTO_PARAMETER_CHECK_FAILED; } static OH_Crypto_ErrCode SetDataBlob(uint8_t **dest, uint32_t *destLen, Crypto_DataBlob *value) { if (value == NULL || value->data == NULL || value->len == 0) { return CRYPTO_PARAMETER_CHECK_FAILED; } uint8_t *tmp = (uint8_t *)HcfMalloc(value->len, 0); if (tmp == NULL) { return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(tmp, value->len, value->data, value->len); HcfFree(*dest); *dest = NULL; *dest = tmp; *destLen = value->len; ReverseUint8Arr(*dest, *destLen); return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode GetDataBlob(const uint8_t *src, uint32_t srcLen, Crypto_DataBlob *value) { if (src == NULL || srcLen == 0) { return CRYPTO_PARAMETER_CHECK_FAILED; } value->data = (uint8_t *)HcfMalloc(srcLen, 0); if (value->data == NULL) { return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(value->data, srcLen, src, srcLen); value->len = srcLen; ReverseUint8Arr(value->data, value->len); return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode SetDsaCommSpec(HcfDsaCommParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DSA_P_DATABLOB: return SetDataBlob(&(spec->p.data), &(spec->p.len), value); case CRYPTO_DSA_Q_DATABLOB: return SetDataBlob(&(spec->q.data), &(spec->q.len), value); case CRYPTO_DSA_G_DATABLOB: return SetDataBlob(&(spec->g.data), &(spec->g.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetDsaPubKeySpec(HcfDsaPubKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DSA_PK_DATABLOB: return SetDataBlob(&(spec->pk.data), &(spec->pk.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetDsaKeyPairSpec(HcfDsaKeyPairParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DSA_SK_DATABLOB: return SetDataBlob(&(spec->sk.data), &(spec->sk.len), value); case CRYPTO_DSA_PK_DATABLOB: return SetDataBlob(&(spec->pk.data), &(spec->pk.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetDsaSpec(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { if (SetDsaCommSpec((HcfDsaCommParamsSpec *)spec, type, value) == CRYPTO_SUCCESS) { return CRYPTO_SUCCESS; } switch (spec->specType) { case HCF_PUBLIC_KEY_SPEC: return SetDsaPubKeySpec((HcfDsaPubKeyParamsSpec *)spec, type, value); case HCF_KEY_PAIR_SPEC: return SetDsaKeyPairSpec((HcfDsaKeyPairParamsSpec *)spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetRsaCommSpec(HcfRsaCommParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_RSA_N_DATABLOB: return SetDataBlob(&(spec->n.data), &(spec->n.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetRsaPubKeySpec(HcfRsaPubKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_RSA_E_DATABLOB: return SetDataBlob(&(spec->pk.data), &(spec->pk.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetRsaKeyPairSpec(HcfRsaKeyPairParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_RSA_D_DATABLOB: return SetDataBlob(&(spec->sk.data), &(spec->sk.len), value); case CRYPTO_RSA_E_DATABLOB: return SetDataBlob(&(spec->pk.data), &(spec->pk.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetRsaSpec(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { if (SetRsaCommSpec((HcfRsaCommParamsSpec *)spec, type, value) == CRYPTO_SUCCESS) { return CRYPTO_SUCCESS; } switch (spec->specType) { case HCF_PUBLIC_KEY_SPEC: return SetRsaPubKeySpec((HcfRsaPubKeyParamsSpec *)spec, type, value); case HCF_KEY_PAIR_SPEC: return SetRsaKeyPairSpec((HcfRsaKeyPairParamsSpec *)spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetEccField(HcfEccCommParamsSpec *spec, Crypto_DataBlob *value) { HcfECFieldFp *field = (HcfECFieldFp *)HcfMalloc(sizeof(HcfECFieldFp), 0); if (field == NULL) { return CRYPTO_MEMORY_ERROR; } char *fieldType = "Fp"; size_t fieldTypeLen = strlen(fieldType); field->base.fieldType = (char *)HcfMalloc(fieldTypeLen + 1, 0); if (field->base.fieldType == NULL) { HcfFree(field); field = NULL; return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(field->base.fieldType, fieldTypeLen, fieldType, fieldTypeLen); field->p.data = (uint8_t *)HcfMalloc(value->len, 0); if (field->p.data == NULL) { HcfFree(field->base.fieldType); field->base.fieldType = NULL; HcfFree(field); field = NULL; return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(field->p.data, value->len, value->data, value->len); field->p.len = value->len; ReverseUint8Arr(field->p.data, field->p.len); spec->field = (HcfECField *)field; return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode SetEccCommSpec(HcfEccCommParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ECC_FP_P_DATABLOB: return SetEccField(spec, value); case CRYPTO_ECC_A_DATABLOB: return SetDataBlob(&(spec->a.data), &(spec->a.len), value); case CRYPTO_ECC_B_DATABLOB: return SetDataBlob(&(spec->b.data), &(spec->b.len), value); case CRYPTO_ECC_G_X_DATABLOB: return SetDataBlob(&(spec->g.x.data), &(spec->g.x.len), value); case CRYPTO_ECC_G_Y_DATABLOB: return SetDataBlob(&(spec->g.y.data), &(spec->g.y.len), value); case CRYPTO_ECC_N_DATABLOB: return SetDataBlob(&(spec->n.data), &(spec->n.len), value); case CRYPTO_ECC_H_INT: if (value->len != sizeof(spec->h)) { return CRYPTO_PARAMETER_CHECK_FAILED; } uint32_t tmp = BigEndianArrToUint32(value->data, value->len); if (tmp > INT32_MAX) { return CRYPTO_PARAMETER_CHECK_FAILED; } spec->h = (int32_t)tmp; break; default: return CRYPTO_PARAMETER_CHECK_FAILED; } return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode SetEccPriSpec(HcfEccPriKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ECC_SK_DATABLOB: return SetDataBlob(&(spec->sk.data), &(spec->sk.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetEccPubKeySpec(HcfEccPubKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ECC_PK_X_DATABLOB: return SetDataBlob(&(spec->pk.x.data), &(spec->pk.x.len), value); case CRYPTO_ECC_PK_Y_DATABLOB: return SetDataBlob(&(spec->pk.y.data), &(spec->pk.y.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetEccKeyPairSpec(HcfEccKeyPairParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ECC_SK_DATABLOB: return SetDataBlob(&(spec->sk.data), &(spec->sk.len), value); case CRYPTO_ECC_PK_X_DATABLOB: return SetDataBlob(&(spec->pk.x.data), &(spec->pk.x.len), value); case CRYPTO_ECC_PK_Y_DATABLOB: return SetDataBlob(&(spec->pk.y.data), &(spec->pk.y.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetEccSpec(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { if (SetEccCommSpec((HcfEccCommParamsSpec *)spec, type, value) == CRYPTO_SUCCESS) { return CRYPTO_SUCCESS; } switch (spec->specType) { case HCF_PRIVATE_KEY_SPEC: return SetEccPriSpec((HcfEccPriKeyParamsSpec *)spec, type, value); case HCF_PUBLIC_KEY_SPEC: return SetEccPubKeySpec((HcfEccPubKeyParamsSpec *)spec, type, value); case HCF_KEY_PAIR_SPEC: return SetEccKeyPairSpec((HcfEccKeyPairParamsSpec *)spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetDhCommSpec(HcfDhCommParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DH_P_DATABLOB: return SetDataBlob(&(spec->p.data), &(spec->p.len), value); case CRYPTO_DH_G_DATABLOB: return SetDataBlob(&(spec->g.data), &(spec->g.len), value); case CRYPTO_DH_L_INT: if (value->len != sizeof(spec->length)) { return CRYPTO_PARAMETER_CHECK_FAILED; } uint32_t tmp = BigEndianArrToUint32(value->data, value->len); if (tmp > INT32_MAX) { return CRYPTO_PARAMETER_CHECK_FAILED; } spec->length = (int)tmp; break; default: return CRYPTO_PARAMETER_CHECK_FAILED; } return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode SetDhPriSpec(HcfDhPriKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DH_SK_DATABLOB: return SetDataBlob(&(spec->sk.data), &(spec->sk.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetDhPubKeySpec(HcfDhPubKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DH_PK_DATABLOB: return SetDataBlob(&(spec->pk.data), &(spec->pk.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetDhKeyPairSpec(HcfDhKeyPairParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DH_SK_DATABLOB: return SetDataBlob(&(spec->sk.data), &(spec->sk.len), value); case CRYPTO_DH_PK_DATABLOB: return SetDataBlob(&(spec->pk.data), &(spec->pk.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetDhSpec(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { if (SetDhCommSpec((HcfDhCommParamsSpec *)spec, type, value) == CRYPTO_SUCCESS) { return CRYPTO_SUCCESS; } switch (spec->specType) { case HCF_PRIVATE_KEY_SPEC: return SetDhPriSpec((HcfDhPriKeyParamsSpec *)spec, type, value); case HCF_PUBLIC_KEY_SPEC: return SetDhPubKeySpec((HcfDhPubKeyParamsSpec *)spec, type, value); case HCF_KEY_PAIR_SPEC: return SetDhKeyPairSpec((HcfDhKeyPairParamsSpec *)spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetAlg25519PriSpec(HcfAlg25519PriKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ED25519_SK_DATABLOB: case CRYPTO_X25519_SK_DATABLOB: return SetDataBlob(&(spec->sk.data), &(spec->sk.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetAlg25519PubKeySpec(HcfAlg25519PubKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ED25519_PK_DATABLOB: case CRYPTO_X25519_PK_DATABLOB: return SetDataBlob(&(spec->pk.data), &(spec->pk.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetAlg25519KeyPairSpec(HcfAlg25519KeyPairParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ED25519_SK_DATABLOB: case CRYPTO_X25519_SK_DATABLOB: return SetDataBlob(&(spec->sk.data), &(spec->sk.len), value); case CRYPTO_ED25519_PK_DATABLOB: case CRYPTO_X25519_PK_DATABLOB: return SetDataBlob(&(spec->pk.data), &(spec->pk.len), value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetAlg25519Spec(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (spec->specType) { case HCF_PRIVATE_KEY_SPEC: return SetAlg25519PriSpec((HcfAlg25519PriKeyParamsSpec *)spec, type, value); case HCF_PUBLIC_KEY_SPEC: return SetAlg25519PubKeySpec((HcfAlg25519PubKeyParamsSpec *)spec, type, value); case HCF_KEY_PAIR_SPEC: return SetAlg25519KeyPairSpec((HcfAlg25519KeyPairParamsSpec *)spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } OH_Crypto_ErrCode OH_CryptoAsymKeySpec_SetParam(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { if ((spec == NULL) || (value == NULL) || (value->data == NULL) || (value->len == 0)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfAsyKeyGenParams params = { 0 }; HcfResult ret = ParseAlgNameToParams(spec->algName, ¶ms); if (ret != HCF_SUCCESS) { return GetOhCryptoErrCodeNew(ret); } switch (params.algo) { case HCF_ALG_DSA: return SetDsaSpec(spec, type, value); case HCF_ALG_RSA: return SetRsaSpec(spec, type, value); case HCF_ALG_ECC: case HCF_ALG_SM2: return SetEccSpec(spec, type, value); case HCF_ALG_DH: return SetDhSpec(spec, type, value); case HCF_ALG_ED25519: case HCF_ALG_X25519: return SetAlg25519Spec(spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetDsaCommonSpec(HcfDsaCommParamsSpec *commonParamsSpec, HcfDsaCommParamsSpec *spec) { spec->p.data = (unsigned char *)HcfMalloc(commonParamsSpec->p.len, 0); if (spec->p.data == NULL) { FreeDsaCommParamsSpec(spec); return CRYPTO_MEMORY_ERROR; } spec->q.data = (unsigned char *)HcfMalloc(commonParamsSpec->q.len, 0); if (spec->q.data == NULL) { FreeDsaCommParamsSpec(spec); return CRYPTO_MEMORY_ERROR; } spec->g.data = (unsigned char *)HcfMalloc(commonParamsSpec->g.len, 0); if (spec->g.data == NULL) { FreeDsaCommParamsSpec(spec); return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(spec->p.data, commonParamsSpec->p.len, commonParamsSpec->p.data, commonParamsSpec->p.len); (void)memcpy_s(spec->q.data, commonParamsSpec->q.len, commonParamsSpec->q.data, commonParamsSpec->q.len); (void)memcpy_s(spec->g.data, commonParamsSpec->g.len, commonParamsSpec->g.data, commonParamsSpec->g.len); spec->p.len = commonParamsSpec->p.len; spec->q.len = commonParamsSpec->q.len; spec->g.len = commonParamsSpec->g.len; return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode SetEccCommonSpec(HcfEccCommParamsSpec *commonParamsSpec, HcfEccCommParamsSpec *spec) { HcfEccCommParamsSpec eccCommParamsSpec = {}; HcfResult ret = CopyEccCommonSpec(commonParamsSpec, &eccCommParamsSpec); if (ret != HCF_SUCCESS) { return GetOhCryptoErrCodeNew(ret); } spec->field = eccCommParamsSpec.field; spec->field->fieldType = eccCommParamsSpec.field->fieldType; ((HcfECFieldFp *)(spec->field))->p.data = ((HcfECFieldFp *)(eccCommParamsSpec.field))->p.data; ((HcfECFieldFp *)(spec->field))->p.len = ((HcfECFieldFp *)(eccCommParamsSpec.field))->p.len; spec->a.data = eccCommParamsSpec.a.data; spec->a.len = eccCommParamsSpec.a.len; spec->b.data = eccCommParamsSpec.b.data; spec->b.len = eccCommParamsSpec.b.len; spec->g.x.data = eccCommParamsSpec.g.x.data; spec->g.x.len = eccCommParamsSpec.g.x.len; spec->g.y.data = eccCommParamsSpec.g.y.data; spec->g.y.len = eccCommParamsSpec.g.y.len; spec->n.data = eccCommParamsSpec.n.data; spec->n.len = eccCommParamsSpec.n.len; spec->h = eccCommParamsSpec.h; HcfFree(eccCommParamsSpec.base.algName); eccCommParamsSpec.base.algName = NULL; return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode SetDhCommonSpec(HcfDhCommParamsSpec *commonParamsSpec, HcfDhCommParamsSpec *spec) { HcfDhCommParamsSpec dhCommParamsSpec = {}; HcfResult ret = CopyDhCommonSpec(commonParamsSpec, &dhCommParamsSpec); if (ret != HCF_SUCCESS) { return GetOhCryptoErrCodeNew(ret); } spec->p.data = dhCommParamsSpec.p.data; spec->p.len = dhCommParamsSpec.p.len; spec->g.data = dhCommParamsSpec.g.data; spec->g.len = dhCommParamsSpec.g.len; spec->length = dhCommParamsSpec.length; HcfFree(dhCommParamsSpec.base.algName); dhCommParamsSpec.base.algName = NULL; return CRYPTO_SUCCESS; } OH_Crypto_ErrCode OH_CryptoAsymKeySpec_SetCommonParamsSpec(OH_CryptoAsymKeySpec *spec, OH_CryptoAsymKeySpec *commonParamsSpec) { if ((spec == NULL) || (commonParamsSpec == NULL) || (commonParamsSpec->specType != HCF_COMMON_PARAMS_SPEC)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfAsyKeyGenParams params = { 0 }; HcfResult ret = ParseAlgNameToParams(spec->algName, ¶ms); if (ret != HCF_SUCCESS) { return GetOhCryptoErrCodeNew(ret); } switch (params.algo) { case HCF_ALG_DSA: return SetDsaCommonSpec((HcfDsaCommParamsSpec *)commonParamsSpec, (HcfDsaCommParamsSpec *)spec); case HCF_ALG_ECC: case HCF_ALG_SM2: return SetEccCommonSpec((HcfEccCommParamsSpec *)commonParamsSpec, (HcfEccCommParamsSpec *)spec); case HCF_ALG_DH: return SetDhCommonSpec((HcfDhCommParamsSpec *)commonParamsSpec, (HcfDhCommParamsSpec *)spec); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetDsaCommSpec(HcfDsaCommParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DSA_P_DATABLOB: return GetDataBlob(spec->p.data, spec->p.len, value); case CRYPTO_DSA_Q_DATABLOB: return GetDataBlob(spec->q.data, spec->q.len, value); case CRYPTO_DSA_G_DATABLOB: return GetDataBlob(spec->g.data, spec->g.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetDsaPubKeySpec(HcfDsaPubKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DSA_PK_DATABLOB: return GetDataBlob(spec->pk.data, spec->pk.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetDsaKeyPairSpec(HcfDsaKeyPairParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DSA_SK_DATABLOB: return GetDataBlob(spec->sk.data, spec->sk.len, value); case CRYPTO_DSA_PK_DATABLOB: return GetDataBlob(spec->pk.data, spec->pk.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetDsaSpec(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { if (GetDsaCommSpec((HcfDsaCommParamsSpec *)spec, type, value) == CRYPTO_SUCCESS) { return CRYPTO_SUCCESS; } switch (spec->specType) { case HCF_PUBLIC_KEY_SPEC: return GetDsaPubKeySpec((HcfDsaPubKeyParamsSpec *)spec, type, value); case HCF_KEY_PAIR_SPEC: return GetDsaKeyPairSpec((HcfDsaKeyPairParamsSpec *)spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetRsaCommSpec(HcfRsaCommParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_RSA_N_DATABLOB: return GetDataBlob(spec->n.data, spec->n.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetRsaPubKeySpec(HcfRsaPubKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_RSA_E_DATABLOB: return GetDataBlob(spec->pk.data, spec->pk.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetRsaKeyPairSpec(HcfRsaKeyPairParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_RSA_D_DATABLOB: return GetDataBlob(spec->sk.data, spec->sk.len, value); case CRYPTO_RSA_E_DATABLOB: return GetDataBlob(spec->pk.data, spec->pk.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetRsaSpec(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { if (GetRsaCommSpec((HcfRsaCommParamsSpec *)spec, type, value) == CRYPTO_SUCCESS) { return CRYPTO_SUCCESS; } switch (spec->specType) { case HCF_PUBLIC_KEY_SPEC: return GetRsaPubKeySpec((HcfRsaPubKeyParamsSpec *)spec, type, value); case HCF_KEY_PAIR_SPEC: return GetRsaKeyPairSpec((HcfRsaKeyPairParamsSpec *)spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetEccField(HcfEccCommParamsSpec *spec, Crypto_DataBlob *value) { if ((spec->field == NULL) || (((HcfECFieldFp *)(spec->field))->p.data == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } return GetDataBlob(((HcfECFieldFp *)(spec->field))->p.data, ((HcfECFieldFp *)(spec->field))->p.len, value); } static OH_Crypto_ErrCode GetEccCommSpec(HcfEccCommParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ECC_FP_P_DATABLOB: return GetEccField(spec, value); case CRYPTO_ECC_A_DATABLOB: return GetDataBlob(spec->a.data, spec->a.len, value); case CRYPTO_ECC_B_DATABLOB: return GetDataBlob(spec->b.data, spec->b.len, value); case CRYPTO_ECC_G_X_DATABLOB: return GetDataBlob(spec->g.x.data, spec->g.x.len, value); case CRYPTO_ECC_G_Y_DATABLOB: return GetDataBlob(spec->g.y.data, spec->g.y.len, value); case CRYPTO_ECC_N_DATABLOB: return GetDataBlob(spec->n.data, spec->n.len, value); case CRYPTO_ECC_H_INT: value->data = (uint8_t *)HcfMalloc(sizeof(spec->h), 0); if (value->data == NULL) { return CRYPTO_MEMORY_ERROR; } value->len = sizeof(spec->h); if (spec->h < 0) { HcfFree(value->data); value->data = NULL; return CRYPTO_PARAMETER_CHECK_FAILED; } uint32_t tmp = (uint32_t)spec->h; Uint32TobigEndianArr(tmp, value->data, value->len); break; default: return CRYPTO_PARAMETER_CHECK_FAILED; } return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode GetEccPriSpec(HcfEccPriKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ECC_SK_DATABLOB: return GetDataBlob(spec->sk.data, spec->sk.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetEccPubKeySpec(HcfEccPubKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ECC_PK_X_DATABLOB: return GetDataBlob(spec->pk.x.data, spec->pk.x.len, value); case CRYPTO_ECC_PK_Y_DATABLOB: return GetDataBlob(spec->pk.y.data, spec->pk.y.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetEccKeyPairSpec(HcfEccKeyPairParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ECC_SK_DATABLOB: return GetDataBlob(spec->sk.data, spec->sk.len, value); case CRYPTO_ECC_PK_X_DATABLOB: return GetDataBlob(spec->pk.x.data, spec->pk.x.len, value); case CRYPTO_ECC_PK_Y_DATABLOB: return GetDataBlob(spec->pk.y.data, spec->pk.y.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetEccSpec(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { if (GetEccCommSpec((HcfEccCommParamsSpec *)spec, type, value) == CRYPTO_SUCCESS) { return CRYPTO_SUCCESS; } switch (spec->specType) { case HCF_PRIVATE_KEY_SPEC: return GetEccPriSpec((HcfEccPriKeyParamsSpec *)spec, type, value); case HCF_PUBLIC_KEY_SPEC: return GetEccPubKeySpec((HcfEccPubKeyParamsSpec *)spec, type, value); case HCF_KEY_PAIR_SPEC: return GetEccKeyPairSpec((HcfEccKeyPairParamsSpec *)spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetDhCommSpec(HcfDhCommParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DH_P_DATABLOB: return GetDataBlob(spec->p.data, spec->p.len, value); case CRYPTO_DH_G_DATABLOB: return GetDataBlob(spec->g.data, spec->g.len, value); case CRYPTO_DH_L_INT: value->data = (uint8_t *)HcfMalloc(sizeof(spec->length), 0); if (value->data == NULL) { return CRYPTO_MEMORY_ERROR; } value->len = sizeof(spec->length); if (spec->length < 0) { HcfFree(value->data); value->data = NULL; return CRYPTO_PARAMETER_CHECK_FAILED; } uint32_t tmp = (uint32_t)spec->length; Uint32TobigEndianArr(tmp, value->data, value->len); break; default: return CRYPTO_PARAMETER_CHECK_FAILED; } return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode GetDhPriSpec(HcfDhPriKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DH_SK_DATABLOB: return GetDataBlob(spec->sk.data, spec->sk.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetDhPubKeySpec(HcfDhPubKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DH_PK_DATABLOB: return GetDataBlob(spec->pk.data, spec->pk.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetDhKeyPairSpec(HcfDhKeyPairParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_DH_SK_DATABLOB: return GetDataBlob(spec->sk.data, spec->sk.len, value); case CRYPTO_DH_PK_DATABLOB: return GetDataBlob(spec->pk.data, spec->pk.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetDhSpec(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { if (GetDhCommSpec((HcfDhCommParamsSpec *)spec, type, value) == CRYPTO_SUCCESS) { return CRYPTO_SUCCESS; } switch (spec->specType) { case HCF_PRIVATE_KEY_SPEC: return GetDhPriSpec((HcfDhPriKeyParamsSpec *)spec, type, value); case HCF_PUBLIC_KEY_SPEC: return GetDhPubKeySpec((HcfDhPubKeyParamsSpec *)spec, type, value); case HCF_KEY_PAIR_SPEC: return GetDhKeyPairSpec((HcfDhKeyPairParamsSpec *)spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetAlg25519PriSpec(HcfAlg25519PriKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ED25519_SK_DATABLOB: case CRYPTO_X25519_SK_DATABLOB: return GetDataBlob(spec->sk.data, spec->sk.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetAlg25519PubKeySpec(HcfAlg25519PubKeyParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ED25519_PK_DATABLOB: case CRYPTO_X25519_PK_DATABLOB: return GetDataBlob(spec->pk.data, spec->pk.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetAlg25519KeyPairSpec(HcfAlg25519KeyPairParamsSpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (type) { case CRYPTO_ED25519_SK_DATABLOB: case CRYPTO_X25519_SK_DATABLOB: return GetDataBlob(spec->sk.data, spec->sk.len, value); case CRYPTO_ED25519_PK_DATABLOB: case CRYPTO_X25519_PK_DATABLOB: return GetDataBlob(spec->pk.data, spec->pk.len, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode GetAlg25519Spec(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { switch (spec->specType) { case HCF_PRIVATE_KEY_SPEC: return GetAlg25519PriSpec((HcfAlg25519PriKeyParamsSpec *)spec, type, value); case HCF_PUBLIC_KEY_SPEC: return GetAlg25519PubKeySpec((HcfAlg25519PubKeyParamsSpec *)spec, type, value); case HCF_KEY_PAIR_SPEC: return GetAlg25519KeyPairSpec((HcfAlg25519KeyPairParamsSpec *)spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } OH_Crypto_ErrCode OH_CryptoAsymKeySpec_GetParam(OH_CryptoAsymKeySpec *spec, CryptoAsymKey_ParamType type, Crypto_DataBlob *value) { if ((spec == NULL) || (value == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfAsyKeyGenParams params = { 0 }; HcfResult ret = ParseAlgNameToParams(spec->algName, ¶ms); if (ret != HCF_SUCCESS) { return GetOhCryptoErrCodeNew(ret); } switch (params.algo) { case HCF_ALG_DSA: return GetDsaSpec(spec, type, value); case HCF_ALG_RSA: return GetRsaSpec(spec, type, value); case HCF_ALG_ECC: case HCF_ALG_SM2: return GetEccSpec(spec, type, value); case HCF_ALG_DH: return GetDhSpec(spec, type, value); case HCF_ALG_ED25519: case HCF_ALG_X25519: return GetAlg25519Spec(spec, type, value); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } void OH_CryptoAsymKeySpec_Destroy(OH_CryptoAsymKeySpec *spec) { if (spec == NULL) { return; } FreeAsyKeySpec((HcfAsyKeyParamsSpec *)spec); } OH_Crypto_ErrCode OH_CryptoAsymKeyGeneratorWithSpec_Create(OH_CryptoAsymKeySpec *keySpec, OH_CryptoAsymKeyGeneratorWithSpec **generator) { if ((keySpec == NULL) || (generator == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } *generator = (OH_CryptoAsymKeyGeneratorWithSpec *)HcfMalloc(sizeof(OH_CryptoAsymKeyGeneratorWithSpec), 0); if (*generator == NULL) { return CRYPTO_MEMORY_ERROR; } HcfResult ret = HcfAsyKeyGeneratorBySpecCreate((HcfAsyKeyParamsSpec *)keySpec, &((*generator)->generator)); if (ret != HCF_SUCCESS) { HcfFree(*generator); *generator = NULL; return GetOhCryptoErrCodeNew(ret); } (*generator)->specType = keySpec->specType; return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode GenPriKeyPair(HcfAsyKeyGeneratorBySpec *generator, OH_CryptoKeyPair **keyPair) { HcfPriKey *priKey = NULL; if (generator->generatePriKey == NULL) { return CRYPTO_NOT_SUPPORTED; } HcfResult ret = generator->generatePriKey(generator, &priKey); if (ret != HCF_SUCCESS) { return GetOhCryptoErrCodeNew(ret); } *keyPair = (OH_CryptoKeyPair *)HcfMalloc(sizeof(OH_CryptoKeyPair), 0); if (*keyPair == NULL) { HcfFree(priKey); priKey = NULL; return CRYPTO_MEMORY_ERROR; } (*keyPair)->priKey = priKey; return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode GenPubKeyPair(HcfAsyKeyGeneratorBySpec *generator, OH_CryptoKeyPair **keyPair) { HcfPubKey *pubKey = NULL; if (generator->generatePubKey == NULL) { return CRYPTO_NOT_SUPPORTED; } HcfResult ret = generator->generatePubKey(generator, &pubKey); if (ret != HCF_SUCCESS) { return GetOhCryptoErrCodeNew(ret); } *keyPair = (OH_CryptoKeyPair *)HcfMalloc(sizeof(OH_CryptoKeyPair), 0); if (*keyPair == NULL) { HcfFree(pubKey); pubKey = NULL; return CRYPTO_MEMORY_ERROR; } (*keyPair)->pubKey = pubKey; return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode GenKeyPair(HcfAsyKeyGeneratorBySpec *generator, OH_CryptoKeyPair **keyPair) { if (generator->generateKeyPair == NULL) { return CRYPTO_NOT_SUPPORTED; } HcfResult ret = generator->generateKeyPair(generator, (HcfKeyPair **)keyPair); return GetOhCryptoErrCodeNew(ret); } OH_Crypto_ErrCode OH_CryptoAsymKeyGeneratorWithSpec_GenKeyPair(OH_CryptoAsymKeyGeneratorWithSpec *generator, OH_CryptoKeyPair **keyPair) { if ((generator == NULL) || (generator->generator == NULL) || (keyPair == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } switch (generator->specType) { case HCF_PRIVATE_KEY_SPEC: return GenPriKeyPair(generator->generator, keyPair); case HCF_PUBLIC_KEY_SPEC: return GenPubKeyPair(generator->generator, keyPair); case HCF_KEY_PAIR_SPEC: case HCF_COMMON_PARAMS_SPEC: return GenKeyPair(generator->generator, keyPair); default: return CRYPTO_PARAMETER_CHECK_FAILED; } } void OH_CryptoAsymKeyGeneratorWithSpec_Destroy(OH_CryptoAsymKeyGeneratorWithSpec *generator) { if (generator == NULL) { return; } HcfObjDestroy(generator->generator); generator->generator = NULL; HcfFree(generator); } OH_Crypto_ErrCode OH_CryptoEcPoint_Create(const char *curveName, Crypto_DataBlob *ecKeyData, OH_CryptoEcPoint **point) { if ((curveName == NULL) || (point == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } *point = (OH_CryptoEcPoint*)HcfMalloc(sizeof(OH_CryptoEcPoint), 0); if (*point == NULL) { return CRYPTO_MEMORY_ERROR; } (*point)->curveName = (char *)HcfMalloc(strlen(curveName) + 1, 0); if ((*point)->curveName == NULL) { HcfFree(*point); *point = NULL; return CRYPTO_MEMORY_ERROR; } (void)memcpy_s((*point)->curveName, strlen(curveName), curveName, strlen(curveName)); if (ecKeyData == NULL) { return CRYPTO_SUCCESS; } HcfResult ret = HcfConvertPoint(curveName, (HcfBlob *)ecKeyData, &((*point)->pointBase)); if (ret != HCF_SUCCESS) { OH_CryptoEcPoint_Destroy(*point); *point = NULL; } return GetOhCryptoErrCodeNew(ret); } OH_Crypto_ErrCode OH_CryptoEcPoint_GetCoordinate(OH_CryptoEcPoint *point, Crypto_DataBlob *x, Crypto_DataBlob *y) { if ((point == NULL) || (x == NULL) || (y == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfPoint dPoint = {}; HcfResult ret = CopyPoint(&(point->pointBase), &dPoint); if (ret != HCF_SUCCESS) { return GetOhCryptoErrCodeNew(ret); } x->data = dPoint.x.data; y->data = dPoint.y.data; x->len = dPoint.x.len; y->len = dPoint.y.len; ReverseUint8Arr(x->data, x->len); ReverseUint8Arr(y->data, y->len); return CRYPTO_SUCCESS; } OH_Crypto_ErrCode OH_CryptoEcPoint_SetCoordinate(OH_CryptoEcPoint *point, Crypto_DataBlob *x, Crypto_DataBlob *y) { if ((point == NULL) || (x == NULL) || (y == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfPoint sPoint = {}; sPoint.x.data = x->data; sPoint.x.len = x->len; sPoint.y.data = y->data; sPoint.y.len = y->len; HcfPoint dPoint = {}; HcfResult ret = CopyPoint(&sPoint, &dPoint); if (ret != HCF_SUCCESS) { return GetOhCryptoErrCodeNew(ret); } HcfFree(point->pointBase.x.data); point->pointBase.x.data = NULL; HcfFree(point->pointBase.y.data); point->pointBase.y.data = NULL; point->pointBase.x.data = dPoint.x.data; point->pointBase.x.len = dPoint.x.len; point->pointBase.y.data = dPoint.y.data; point->pointBase.y.len = dPoint.y.len; ReverseUint8Arr(point->pointBase.x.data, point->pointBase.x.len); ReverseUint8Arr(point->pointBase.y.data, point->pointBase.y.len); return CRYPTO_SUCCESS; } OH_Crypto_ErrCode OH_CryptoEcPoint_Encode(OH_CryptoEcPoint *point, const char *format, Crypto_DataBlob *out) { if ((point == NULL) || (format == NULL) || (out == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfResult ret = HcfGetEncodedPoint(point->curveName, &(point->pointBase), format, (HcfBlob *)out); return GetOhCryptoErrCodeNew(ret); } void OH_CryptoEcPoint_Destroy(OH_CryptoEcPoint *point) { if (point == NULL) { return; } HcfFree(point->curveName); point->curveName = NULL; FreeEcPointMem(&(point->pointBase)); HcfFree(point); }