11b8d9b87Sopenharmony_ci/*
21b8d9b87Sopenharmony_ci * Copyright (C) 2022-2023 Huawei Device Co., Ltd.
31b8d9b87Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
41b8d9b87Sopenharmony_ci * you may not use this file except in compliance with the License.
51b8d9b87Sopenharmony_ci * You may obtain a copy of the License at
61b8d9b87Sopenharmony_ci *
71b8d9b87Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
81b8d9b87Sopenharmony_ci *
91b8d9b87Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
101b8d9b87Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
111b8d9b87Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121b8d9b87Sopenharmony_ci * See the License for the specific language governing permissions and
131b8d9b87Sopenharmony_ci * limitations under the License.
141b8d9b87Sopenharmony_ci */
151b8d9b87Sopenharmony_ci
161b8d9b87Sopenharmony_ci#include "cipher.h"
171b8d9b87Sopenharmony_ci#include "aes_openssl.h"
181b8d9b87Sopenharmony_ci#include "config.h"
191b8d9b87Sopenharmony_ci#include "securec.h"
201b8d9b87Sopenharmony_ci#include "result.h"
211b8d9b87Sopenharmony_ci#include "string.h"
221b8d9b87Sopenharmony_ci#include "log.h"
231b8d9b87Sopenharmony_ci#include "memory.h"
241b8d9b87Sopenharmony_ci#include "cipher_rsa_openssl.h"
251b8d9b87Sopenharmony_ci#include "cipher_sm2_openssl.h"
261b8d9b87Sopenharmony_ci#include "sm4_openssl.h"
271b8d9b87Sopenharmony_ci#include "utils.h"
281b8d9b87Sopenharmony_ci
291b8d9b87Sopenharmony_citypedef HcfResult (*HcfCipherGeneratorSpiCreateFunc)(CipherAttr *, HcfCipherGeneratorSpi **);
301b8d9b87Sopenharmony_ci
311b8d9b87Sopenharmony_citypedef struct {
321b8d9b87Sopenharmony_ci    HcfCipher super;
331b8d9b87Sopenharmony_ci    HcfCipherGeneratorSpi *spiObj;
341b8d9b87Sopenharmony_ci    char algoName[HCF_MAX_ALGO_NAME_LEN];
351b8d9b87Sopenharmony_ci} CipherGenImpl;
361b8d9b87Sopenharmony_ci
371b8d9b87Sopenharmony_citypedef struct {
381b8d9b87Sopenharmony_ci    HcfCipherGeneratorSpiCreateFunc createFunc;
391b8d9b87Sopenharmony_ci} HcfCipherGenFuncSet;
401b8d9b87Sopenharmony_ci
411b8d9b87Sopenharmony_citypedef struct {
421b8d9b87Sopenharmony_ci    HcfAlgValue algo;
431b8d9b87Sopenharmony_ci    HcfCipherGenFuncSet funcSet;
441b8d9b87Sopenharmony_ci} HcfCipherGenAbility;
451b8d9b87Sopenharmony_ci
461b8d9b87Sopenharmony_cistatic const HcfCipherGenAbility CIPHER_ABILITY_SET[] = {
471b8d9b87Sopenharmony_ci    { HCF_ALG_RSA, { HcfCipherRsaCipherSpiCreate } },
481b8d9b87Sopenharmony_ci    { HCF_ALG_SM2, { HcfCipherSm2CipherSpiCreate } },
491b8d9b87Sopenharmony_ci    { HCF_ALG_AES, { HcfCipherAesGeneratorSpiCreate } },
501b8d9b87Sopenharmony_ci    { HCF_ALG_DES, { HcfCipherDesGeneratorSpiCreate } },
511b8d9b87Sopenharmony_ci    { HCF_ALG_SM4, { HcfCipherSm4GeneratorSpiCreate } }
521b8d9b87Sopenharmony_ci};
531b8d9b87Sopenharmony_ci
541b8d9b87Sopenharmony_cistatic void SetKeyType(HcfAlgParaValue value, void *cipher)
551b8d9b87Sopenharmony_ci{
561b8d9b87Sopenharmony_ci    CipherAttr *cipherAttr = (CipherAttr *)cipher;
571b8d9b87Sopenharmony_ci
581b8d9b87Sopenharmony_ci    cipherAttr->keySize = 0;
591b8d9b87Sopenharmony_ci
601b8d9b87Sopenharmony_ci    switch (value) {
611b8d9b87Sopenharmony_ci        case HCF_ALG_AES_DEFAULT:
621b8d9b87Sopenharmony_ci            cipherAttr->algo = HCF_ALG_AES;
631b8d9b87Sopenharmony_ci            break;
641b8d9b87Sopenharmony_ci        case HCF_ALG_SM4_DEFAULT:
651b8d9b87Sopenharmony_ci            cipherAttr->algo = HCF_ALG_SM4;
661b8d9b87Sopenharmony_ci            break;
671b8d9b87Sopenharmony_ci        case HCF_ALG_3DES_DEFAULT:
681b8d9b87Sopenharmony_ci            cipherAttr->algo = HCF_ALG_DES;
691b8d9b87Sopenharmony_ci            break;
701b8d9b87Sopenharmony_ci        case HCF_ALG_RSA_DEFAULT:
711b8d9b87Sopenharmony_ci            cipherAttr->algo = HCF_ALG_RSA;
721b8d9b87Sopenharmony_ci            break;
731b8d9b87Sopenharmony_ci        case HCF_ALG_SM2_DEFAULT:
741b8d9b87Sopenharmony_ci            cipherAttr->algo = HCF_ALG_SM2;
751b8d9b87Sopenharmony_ci            break;
761b8d9b87Sopenharmony_ci        default:
771b8d9b87Sopenharmony_ci            LOGE("Invalid algo %u.", value);
781b8d9b87Sopenharmony_ci            break;
791b8d9b87Sopenharmony_ci    }
801b8d9b87Sopenharmony_ci}
811b8d9b87Sopenharmony_ci
821b8d9b87Sopenharmony_cistatic void SetKeyLength(HcfAlgParaValue value, void *cipher)
831b8d9b87Sopenharmony_ci{
841b8d9b87Sopenharmony_ci    CipherAttr *cipherAttr = (CipherAttr *)cipher;
851b8d9b87Sopenharmony_ci
861b8d9b87Sopenharmony_ci    cipherAttr->keySize = value;
871b8d9b87Sopenharmony_ci
881b8d9b87Sopenharmony_ci    switch (value) {
891b8d9b87Sopenharmony_ci        case HCF_ALG_AES_128:
901b8d9b87Sopenharmony_ci        case HCF_ALG_AES_192:
911b8d9b87Sopenharmony_ci        case HCF_ALG_AES_256:
921b8d9b87Sopenharmony_ci            cipherAttr->algo = HCF_ALG_AES;
931b8d9b87Sopenharmony_ci            break;
941b8d9b87Sopenharmony_ci        case HCF_ALG_SM4_128:
951b8d9b87Sopenharmony_ci            cipherAttr->algo = HCF_ALG_SM4;
961b8d9b87Sopenharmony_ci            break;
971b8d9b87Sopenharmony_ci        case HCF_ALG_3DES_192:
981b8d9b87Sopenharmony_ci            cipherAttr->algo = HCF_ALG_DES;
991b8d9b87Sopenharmony_ci            break;
1001b8d9b87Sopenharmony_ci        case HCF_OPENSSL_RSA_512:
1011b8d9b87Sopenharmony_ci        case HCF_OPENSSL_RSA_768:
1021b8d9b87Sopenharmony_ci        case HCF_OPENSSL_RSA_1024:
1031b8d9b87Sopenharmony_ci        case HCF_OPENSSL_RSA_2048:
1041b8d9b87Sopenharmony_ci        case HCF_OPENSSL_RSA_3072:
1051b8d9b87Sopenharmony_ci        case HCF_OPENSSL_RSA_4096:
1061b8d9b87Sopenharmony_ci        case HCF_OPENSSL_RSA_8192:
1071b8d9b87Sopenharmony_ci            cipherAttr->algo = HCF_ALG_RSA;
1081b8d9b87Sopenharmony_ci            break;
1091b8d9b87Sopenharmony_ci        case HCF_ALG_SM2_256:
1101b8d9b87Sopenharmony_ci            cipherAttr->algo = HCF_ALG_SM2;
1111b8d9b87Sopenharmony_ci            break;
1121b8d9b87Sopenharmony_ci        default:
1131b8d9b87Sopenharmony_ci            LOGE("Invalid algo %u.", value);
1141b8d9b87Sopenharmony_ci            break;
1151b8d9b87Sopenharmony_ci    }
1161b8d9b87Sopenharmony_ci}
1171b8d9b87Sopenharmony_ci
1181b8d9b87Sopenharmony_cistatic void SetMode(HcfAlgParaValue value, void *cipher)
1191b8d9b87Sopenharmony_ci{
1201b8d9b87Sopenharmony_ci    CipherAttr *cipherAttr = (CipherAttr *)cipher;
1211b8d9b87Sopenharmony_ci    cipherAttr->mode = value ;
1221b8d9b87Sopenharmony_ci}
1231b8d9b87Sopenharmony_ci
1241b8d9b87Sopenharmony_cistatic void SetPadding(HcfAlgParaValue value, void *cipher)
1251b8d9b87Sopenharmony_ci{
1261b8d9b87Sopenharmony_ci    CipherAttr *cipherAttr = (CipherAttr *)cipher;
1271b8d9b87Sopenharmony_ci    cipherAttr->paddingMode = value;
1281b8d9b87Sopenharmony_ci}
1291b8d9b87Sopenharmony_ci
1301b8d9b87Sopenharmony_cistatic void SetDigest(HcfAlgParaValue value, CipherAttr *cipher)
1311b8d9b87Sopenharmony_ci{
1321b8d9b87Sopenharmony_ci    cipher->md = value;
1331b8d9b87Sopenharmony_ci}
1341b8d9b87Sopenharmony_ci
1351b8d9b87Sopenharmony_cistatic void SetMgf1Digest(HcfAlgParaValue value, CipherAttr *cipher)
1361b8d9b87Sopenharmony_ci{
1371b8d9b87Sopenharmony_ci    cipher->mgf1md = value;
1381b8d9b87Sopenharmony_ci}
1391b8d9b87Sopenharmony_ci
1401b8d9b87Sopenharmony_cistatic HcfResult OnSetParameter(const HcfParaConfig *config, void *cipher)
1411b8d9b87Sopenharmony_ci{
1421b8d9b87Sopenharmony_ci    if ((config == NULL) || (cipher == NULL)) {
1431b8d9b87Sopenharmony_ci        LOGE("Invalid cipher params");
1441b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
1451b8d9b87Sopenharmony_ci    }
1461b8d9b87Sopenharmony_ci    HcfResult ret = HCF_SUCCESS;
1471b8d9b87Sopenharmony_ci    LOGD("Set Parameter:%s", config->tag);
1481b8d9b87Sopenharmony_ci    switch (config->paraType) {
1491b8d9b87Sopenharmony_ci        case HCF_ALG_TYPE:
1501b8d9b87Sopenharmony_ci            SetKeyType(config->paraValue, cipher);
1511b8d9b87Sopenharmony_ci            break;
1521b8d9b87Sopenharmony_ci        case HCF_ALG_KEY_TYPE:
1531b8d9b87Sopenharmony_ci            SetKeyLength(config->paraValue, cipher);
1541b8d9b87Sopenharmony_ci            break;
1551b8d9b87Sopenharmony_ci        case HCF_ALG_MODE:
1561b8d9b87Sopenharmony_ci            SetMode(config->paraValue, cipher);
1571b8d9b87Sopenharmony_ci            break;
1581b8d9b87Sopenharmony_ci        case HCF_ALG_PADDING_TYPE:
1591b8d9b87Sopenharmony_ci            SetPadding(config->paraValue, cipher);
1601b8d9b87Sopenharmony_ci            break;
1611b8d9b87Sopenharmony_ci        case HCF_ALG_DIGEST:
1621b8d9b87Sopenharmony_ci            SetDigest(config->paraValue, cipher);
1631b8d9b87Sopenharmony_ci            break;
1641b8d9b87Sopenharmony_ci        case HCF_ALG_MGF1_DIGEST:
1651b8d9b87Sopenharmony_ci            SetMgf1Digest(config->paraValue, cipher);
1661b8d9b87Sopenharmony_ci            break;
1671b8d9b87Sopenharmony_ci        case HCF_ALG_TEXT_FORMAT:
1681b8d9b87Sopenharmony_ci            if (config->paraValue == HCF_ALG_TEXT_FORMAT_C1C2C3) {
1691b8d9b87Sopenharmony_ci                LOGE("Not Support C1C2C3 Format");
1701b8d9b87Sopenharmony_ci                ret = HCF_INVALID_PARAMS;
1711b8d9b87Sopenharmony_ci            }
1721b8d9b87Sopenharmony_ci            break;
1731b8d9b87Sopenharmony_ci        default:
1741b8d9b87Sopenharmony_ci            ret = HCF_INVALID_PARAMS;
1751b8d9b87Sopenharmony_ci            break;
1761b8d9b87Sopenharmony_ci    }
1771b8d9b87Sopenharmony_ci    return ret;
1781b8d9b87Sopenharmony_ci}
1791b8d9b87Sopenharmony_ci
1801b8d9b87Sopenharmony_cistatic const char *GetCipherGeneratorClass(void)
1811b8d9b87Sopenharmony_ci{
1821b8d9b87Sopenharmony_ci    return "HcfCipherGenerator";
1831b8d9b87Sopenharmony_ci}
1841b8d9b87Sopenharmony_ci
1851b8d9b87Sopenharmony_cistatic const char *GetAlgorithm(HcfCipher *self)
1861b8d9b87Sopenharmony_ci{
1871b8d9b87Sopenharmony_ci    if (self == NULL) {
1881b8d9b87Sopenharmony_ci        LOGE("The input self ptr is NULL!");
1891b8d9b87Sopenharmony_ci        return NULL;
1901b8d9b87Sopenharmony_ci    }
1911b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
1921b8d9b87Sopenharmony_ci        LOGE("Class is not match.");
1931b8d9b87Sopenharmony_ci        return NULL;
1941b8d9b87Sopenharmony_ci    }
1951b8d9b87Sopenharmony_ci    return ((CipherGenImpl *)self)->algoName;
1961b8d9b87Sopenharmony_ci}
1971b8d9b87Sopenharmony_ci
1981b8d9b87Sopenharmony_cistatic void CipherDestroy(HcfObjectBase *self)
1991b8d9b87Sopenharmony_ci{
2001b8d9b87Sopenharmony_ci    if (self == NULL) {
2011b8d9b87Sopenharmony_ci        return;
2021b8d9b87Sopenharmony_ci    }
2031b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch(self, GetCipherGeneratorClass())) {
2041b8d9b87Sopenharmony_ci        LOGE("Class not match.");
2051b8d9b87Sopenharmony_ci        return;
2061b8d9b87Sopenharmony_ci    }
2071b8d9b87Sopenharmony_ci    CipherGenImpl *impl = (CipherGenImpl *)self;
2081b8d9b87Sopenharmony_ci    HcfObjDestroy(impl->spiObj);
2091b8d9b87Sopenharmony_ci    impl->spiObj = NULL;
2101b8d9b87Sopenharmony_ci    HcfFree(impl);
2111b8d9b87Sopenharmony_ci}
2121b8d9b87Sopenharmony_ci
2131b8d9b87Sopenharmony_cistatic HcfResult SetCipherSpecUint8Array(HcfCipher *self, CipherSpecItem item, HcfBlob pSource)
2141b8d9b87Sopenharmony_ci{
2151b8d9b87Sopenharmony_ci    // only implemented for OAEP_MGF1_PSRC_UINT8ARR
2161b8d9b87Sopenharmony_ci    // if pSource == NULL or len == 0, it means cleaning the pSource
2171b8d9b87Sopenharmony_ci    if (self == NULL) {
2181b8d9b87Sopenharmony_ci        LOGE("Invalid input parameter.");
2191b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2201b8d9b87Sopenharmony_ci    }
2211b8d9b87Sopenharmony_ci    if (item != OAEP_MGF1_PSRC_UINT8ARR) {
2221b8d9b87Sopenharmony_ci        LOGE("Spec item not support.");
2231b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2241b8d9b87Sopenharmony_ci    }
2251b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
2261b8d9b87Sopenharmony_ci        LOGE("Class not match.");
2271b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2281b8d9b87Sopenharmony_ci    }
2291b8d9b87Sopenharmony_ci    CipherGenImpl *impl = (CipherGenImpl *)self;
2301b8d9b87Sopenharmony_ci    return impl->spiObj->setCipherSpecUint8Array(impl->spiObj, item, pSource);
2311b8d9b87Sopenharmony_ci}
2321b8d9b87Sopenharmony_ci
2331b8d9b87Sopenharmony_cistatic bool CheckCipherSpecString(CipherSpecItem item)
2341b8d9b87Sopenharmony_ci{
2351b8d9b87Sopenharmony_ci    return ((item == OAEP_MD_NAME_STR) || (item == OAEP_MGF_NAME_STR) ||
2361b8d9b87Sopenharmony_ci        (item == OAEP_MGF1_MD_STR) || (item == SM2_MD_NAME_STR));
2371b8d9b87Sopenharmony_ci}
2381b8d9b87Sopenharmony_ci
2391b8d9b87Sopenharmony_cistatic HcfResult GetCipherSpecString(HcfCipher *self, CipherSpecItem item, char **returnString)
2401b8d9b87Sopenharmony_ci{
2411b8d9b87Sopenharmony_ci    if (self == NULL || returnString == NULL) {
2421b8d9b87Sopenharmony_ci        LOGE("Invalid input parameter.");
2431b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2441b8d9b87Sopenharmony_ci    }
2451b8d9b87Sopenharmony_ci    if (!CheckCipherSpecString(item)) {
2461b8d9b87Sopenharmony_ci        LOGE("Spec item not support.");
2471b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2481b8d9b87Sopenharmony_ci    }
2491b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
2501b8d9b87Sopenharmony_ci        LOGE("Class not match.");
2511b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2521b8d9b87Sopenharmony_ci    }
2531b8d9b87Sopenharmony_ci    CipherGenImpl *impl = (CipherGenImpl *)self;
2541b8d9b87Sopenharmony_ci    return impl->spiObj->getCipherSpecString(impl->spiObj, item, returnString);
2551b8d9b87Sopenharmony_ci}
2561b8d9b87Sopenharmony_ci
2571b8d9b87Sopenharmony_cistatic HcfResult GetCipherSpecUint8Array(HcfCipher *self, CipherSpecItem item, HcfBlob *returnUint8Array)
2581b8d9b87Sopenharmony_ci{
2591b8d9b87Sopenharmony_ci    if (self == NULL || returnUint8Array == NULL) {
2601b8d9b87Sopenharmony_ci        LOGE("Invalid input parameter.");
2611b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2621b8d9b87Sopenharmony_ci    }
2631b8d9b87Sopenharmony_ci    if (item != OAEP_MGF1_PSRC_UINT8ARR) {
2641b8d9b87Sopenharmony_ci        LOGE("Spec item not support.");
2651b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2661b8d9b87Sopenharmony_ci    }
2671b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
2681b8d9b87Sopenharmony_ci        LOGE("Class not match.");
2691b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2701b8d9b87Sopenharmony_ci    }
2711b8d9b87Sopenharmony_ci    CipherGenImpl *impl = (CipherGenImpl *)self;
2721b8d9b87Sopenharmony_ci    return impl->spiObj->getCipherSpecUint8Array(impl->spiObj, item, returnUint8Array);
2731b8d9b87Sopenharmony_ci}
2741b8d9b87Sopenharmony_ci
2751b8d9b87Sopenharmony_cistatic HcfResult CipherInit(HcfCipher *self, enum HcfCryptoMode opMode,
2761b8d9b87Sopenharmony_ci    HcfKey *key, HcfParamsSpec *params)
2771b8d9b87Sopenharmony_ci{
2781b8d9b87Sopenharmony_ci    if (self == NULL || key == NULL) { /* params maybe is NULL */
2791b8d9b87Sopenharmony_ci        LOGE("Invalid input parameter.");
2801b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2811b8d9b87Sopenharmony_ci    }
2821b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
2831b8d9b87Sopenharmony_ci        LOGE("Class is not match.");
2841b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2851b8d9b87Sopenharmony_ci    }
2861b8d9b87Sopenharmony_ci    CipherGenImpl *impl = (CipherGenImpl *)self;
2871b8d9b87Sopenharmony_ci    return impl->spiObj->init(impl->spiObj, opMode, key, params);
2881b8d9b87Sopenharmony_ci}
2891b8d9b87Sopenharmony_ci
2901b8d9b87Sopenharmony_cistatic HcfResult CipherUpdate(HcfCipher *self, HcfBlob *input, HcfBlob *output)
2911b8d9b87Sopenharmony_ci{
2921b8d9b87Sopenharmony_ci    if ((self == NULL) || (input == NULL) || (output == NULL)) {
2931b8d9b87Sopenharmony_ci        LOGE("Invalid input parameter.");
2941b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2951b8d9b87Sopenharmony_ci    }
2961b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
2971b8d9b87Sopenharmony_ci        LOGE("Class is not match.");
2981b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
2991b8d9b87Sopenharmony_ci    }
3001b8d9b87Sopenharmony_ci    CipherGenImpl *impl = (CipherGenImpl *)self;
3011b8d9b87Sopenharmony_ci    return impl->spiObj->update(impl->spiObj, input, output);
3021b8d9b87Sopenharmony_ci}
3031b8d9b87Sopenharmony_ci
3041b8d9b87Sopenharmony_cistatic HcfResult CipherFinal(HcfCipher *self, HcfBlob *input, HcfBlob *output)
3051b8d9b87Sopenharmony_ci{
3061b8d9b87Sopenharmony_ci    if ((self == NULL) || (output == NULL)) {
3071b8d9b87Sopenharmony_ci        LOGE("Invalid input parameter!");
3081b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
3091b8d9b87Sopenharmony_ci    }
3101b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
3111b8d9b87Sopenharmony_ci        LOGE("Class is not match.");
3121b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
3131b8d9b87Sopenharmony_ci    }
3141b8d9b87Sopenharmony_ci    CipherGenImpl *impl = (CipherGenImpl *)self;
3151b8d9b87Sopenharmony_ci    return impl->spiObj->doFinal(impl->spiObj, input, output);
3161b8d9b87Sopenharmony_ci}
3171b8d9b87Sopenharmony_ci
3181b8d9b87Sopenharmony_cistatic void InitCipher(HcfCipherGeneratorSpi *spiObj, CipherGenImpl *cipher)
3191b8d9b87Sopenharmony_ci{
3201b8d9b87Sopenharmony_ci    cipher->super.init = CipherInit;
3211b8d9b87Sopenharmony_ci    cipher->super.update = CipherUpdate;
3221b8d9b87Sopenharmony_ci    cipher->super.doFinal = CipherFinal;
3231b8d9b87Sopenharmony_ci    cipher->super.getAlgorithm = GetAlgorithm;
3241b8d9b87Sopenharmony_ci    cipher->super.base.destroy = CipherDestroy;
3251b8d9b87Sopenharmony_ci    cipher->super.base.getClass = GetCipherGeneratorClass;
3261b8d9b87Sopenharmony_ci    cipher->super.getCipherSpecString = GetCipherSpecString;
3271b8d9b87Sopenharmony_ci    cipher->super.getCipherSpecUint8Array = GetCipherSpecUint8Array;
3281b8d9b87Sopenharmony_ci    cipher->super.setCipherSpecUint8Array = SetCipherSpecUint8Array;
3291b8d9b87Sopenharmony_ci}
3301b8d9b87Sopenharmony_ci
3311b8d9b87Sopenharmony_cistatic const HcfCipherGenFuncSet *FindAbility(CipherAttr *attr)
3321b8d9b87Sopenharmony_ci{
3331b8d9b87Sopenharmony_ci    if (attr == NULL) {
3341b8d9b87Sopenharmony_ci        return NULL;
3351b8d9b87Sopenharmony_ci    }
3361b8d9b87Sopenharmony_ci    for (uint32_t i = 0; i < sizeof(CIPHER_ABILITY_SET) / sizeof(HcfCipherGenAbility); i++) {
3371b8d9b87Sopenharmony_ci        if (CIPHER_ABILITY_SET[i].algo == attr->algo) {
3381b8d9b87Sopenharmony_ci            return &(CIPHER_ABILITY_SET[i].funcSet);
3391b8d9b87Sopenharmony_ci        }
3401b8d9b87Sopenharmony_ci    }
3411b8d9b87Sopenharmony_ci    LOGE("Algo not support! [Algo]: %d", attr->algo);
3421b8d9b87Sopenharmony_ci    return NULL;
3431b8d9b87Sopenharmony_ci}
3441b8d9b87Sopenharmony_ci
3451b8d9b87Sopenharmony_ciHcfResult HcfCipherCreate(const char *transformation, HcfCipher **returnObj)
3461b8d9b87Sopenharmony_ci{
3471b8d9b87Sopenharmony_ci    CipherAttr attr = {0};
3481b8d9b87Sopenharmony_ci    if (!HcfIsStrValid(transformation, HCF_MAX_ALGO_NAME_LEN) || (returnObj == NULL)) {
3491b8d9b87Sopenharmony_ci        LOGE("Invalid input params while creating cipher!");
3501b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
3511b8d9b87Sopenharmony_ci    }
3521b8d9b87Sopenharmony_ci    if (ParseAndSetParameter(transformation, (void *)&attr, OnSetParameter) != HCF_SUCCESS) {
3531b8d9b87Sopenharmony_ci        LOGE("ParseAndSetParameter failed!");
3541b8d9b87Sopenharmony_ci        return HCF_NOT_SUPPORT;
3551b8d9b87Sopenharmony_ci    }
3561b8d9b87Sopenharmony_ci
3571b8d9b87Sopenharmony_ci    const HcfCipherGenFuncSet *funcSet = FindAbility(&attr);
3581b8d9b87Sopenharmony_ci    if (funcSet == NULL) {
3591b8d9b87Sopenharmony_ci        LOGE("FindAbility failed!");
3601b8d9b87Sopenharmony_ci        return HCF_NOT_SUPPORT;
3611b8d9b87Sopenharmony_ci    }
3621b8d9b87Sopenharmony_ci    CipherGenImpl *returnGenerator = (CipherGenImpl *)HcfMalloc(sizeof(CipherGenImpl), 0);
3631b8d9b87Sopenharmony_ci    if (returnGenerator == NULL) {
3641b8d9b87Sopenharmony_ci        LOGE("failed to allocate returnGenerator memory!");
3651b8d9b87Sopenharmony_ci        return HCF_ERR_MALLOC;
3661b8d9b87Sopenharmony_ci    }
3671b8d9b87Sopenharmony_ci    if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, transformation) != EOK) {
3681b8d9b87Sopenharmony_ci        LOGE("Failed to copy algoName!");
3691b8d9b87Sopenharmony_ci        HcfFree(returnGenerator);
3701b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
3711b8d9b87Sopenharmony_ci    }
3721b8d9b87Sopenharmony_ci    HcfCipherGeneratorSpi *spiObj = NULL;
3731b8d9b87Sopenharmony_ci    HcfResult res = funcSet->createFunc(&attr, &spiObj);
3741b8d9b87Sopenharmony_ci    if (res != HCF_SUCCESS) {
3751b8d9b87Sopenharmony_ci        LOGE("Failed to create spi object!");
3761b8d9b87Sopenharmony_ci        HcfFree(returnGenerator);
3771b8d9b87Sopenharmony_ci        return res;
3781b8d9b87Sopenharmony_ci    }
3791b8d9b87Sopenharmony_ci    returnGenerator->spiObj = spiObj;
3801b8d9b87Sopenharmony_ci    InitCipher(spiObj, returnGenerator);
3811b8d9b87Sopenharmony_ci
3821b8d9b87Sopenharmony_ci    *returnObj = (HcfCipher *)returnGenerator;
3831b8d9b87Sopenharmony_ci    return res;
3841b8d9b87Sopenharmony_ci}
385