1/* 2 * Copyright (C) 2023-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "kdf.h" 17 18#include <securec.h> 19#include "memory.h" 20 21#include "config.h" 22#include "kdf_spi.h" 23#include "log.h" 24#include "params_parser.h" 25#include "pbkdf2_openssl.h" 26#include "hkdf_openssl.h" 27#include "utils.h" 28 29typedef HcfResult (*HcfKdfSpiCreateFunc)(HcfKdfDeriveParams *, HcfKdfSpi **); 30 31typedef struct { 32 HcfKdf base; 33 HcfKdfSpi *spiObj; 34 char algoName[HCF_MAX_ALGO_NAME_LEN]; 35} HcfKdfImpl; 36 37typedef struct { 38 HcfAlgValue algo; 39 HcfKdfSpiCreateFunc createSpiFunc; 40} HcfKdfGenAbility; 41 42static void SetKdfType(HcfAlgParaValue value, HcfKdfDeriveParams *kdf) 43{ 44 switch (value) { 45 case HCF_ALG_PBKDF2_DEFAULT: 46 kdf->algo = HCF_ALG_PKBDF2; 47 break; 48 case HCF_ALG_HKDF_DEFAULT: 49 kdf->algo = HCF_ALG_HKDF; 50 break; 51 default: 52 LOGE("Invalid algo %u.", value); 53 break; 54 } 55} 56 57static void SetDigest(HcfAlgParaValue value, HcfKdfDeriveParams *kdf) 58{ 59 kdf->md = value; 60} 61 62static void SetMode(HcfAlgParaValue value, HcfKdfDeriveParams *kdf) 63{ 64 kdf->mode = value; 65} 66 67static HcfResult ParseKdfParams(const HcfParaConfig *config, void *params) 68{ 69 if (config == NULL || params == NULL) { 70 LOGE("Invalid Kdf params"); 71 return HCF_INVALID_PARAMS; 72 } 73 HcfResult ret = HCF_SUCCESS; 74 HcfKdfDeriveParams *paramsObj = (HcfKdfDeriveParams *)params; 75 LOGD("Set Parameter: %s", config->tag); 76 switch (config->paraType) { 77 case HCF_ALG_TYPE: 78 SetKdfType(config->paraValue, paramsObj); 79 break; 80 case HCF_ALG_DIGEST: 81 SetDigest(config->paraValue, paramsObj); 82 break; 83 case HCF_ALG_MODE: 84 SetMode(config->paraValue, paramsObj); 85 break; 86 default: 87 ret = HCF_INVALID_PARAMS; 88 break; 89 } 90 return ret; 91} 92 93static const HcfKdfGenAbility KDF_ABILITY_SET[] = { 94 { HCF_ALG_PKBDF2, HcfKdfPBKDF2SpiCreate }, 95 { HCF_ALG_HKDF, HcfKdfHkdfSpiCreate}, 96}; 97 98static HcfKdfSpiCreateFunc FindAbility(HcfKdfDeriveParams* params) 99{ 100 for (uint32_t i = 0; i < (sizeof(KDF_ABILITY_SET) / sizeof(KDF_ABILITY_SET[0])); i++) { 101 if (KDF_ABILITY_SET[i].algo == params->algo) { 102 return KDF_ABILITY_SET[i].createSpiFunc; 103 } 104 } 105 LOGE("Algo not support! [Algo]: %d", params->algo); 106 return NULL; 107} 108 109// export interfaces 110static const char *GetKdfGeneratorClass(void) 111{ 112 return "HcfKdfGenerator"; 113} 114 115static const char *GetAlgoName(HcfKdf *self) 116{ 117 if (self == NULL) { 118 LOGE("The input self ptr is NULL!"); 119 return NULL; 120 } 121 if (!HcfIsClassMatch((HcfObjectBase *)self, GetKdfGeneratorClass())) { 122 return NULL; 123 } 124 return ((HcfKdfImpl *)self)->algoName; 125} 126 127static HcfResult GenerateSecret(HcfKdf *self, HcfKdfParamsSpec *paramsSpec) 128{ 129 if (self == NULL || paramsSpec == NULL) { 130 LOGE("Invalid input parameter."); 131 return HCF_INVALID_PARAMS; 132 } 133 if (!HcfIsClassMatch((HcfObjectBase *)self, GetKdfGeneratorClass())) { 134 return HCF_INVALID_PARAMS; 135 } 136 137 HcfKdfImpl *tmp = (HcfKdfImpl *)self; 138 return tmp->spiObj->generateSecret(tmp->spiObj, paramsSpec); 139} 140 141static void DestroyKdf(HcfObjectBase *self) 142{ 143 if (self == NULL) { 144 return; 145 } 146 if (!HcfIsClassMatch((HcfObjectBase *)self, GetKdfGeneratorClass())) { 147 return; 148 } 149 HcfKdfImpl *impl = (HcfKdfImpl *)self; 150 HcfObjDestroy(impl->spiObj); 151 impl->spiObj = NULL; 152 HcfFree(impl); 153} 154 155HcfResult HcfKdfCreate(const char *transformation, HcfKdf **returnObj) 156{ 157 if ((!HcfIsStrValid(transformation, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) { 158 LOGE("Invalid input params while creating kdf!"); 159 return HCF_INVALID_PARAMS; 160 } 161 162 HcfKdfDeriveParams params = { 0 }; 163 if (ParseAndSetParameter(transformation, ¶ms, ParseKdfParams) != HCF_SUCCESS) { 164 LOGE("Failed to parse params!"); 165 return HCF_INVALID_PARAMS; 166 } 167 HcfKdfSpiCreateFunc createSpiFunc = FindAbility(¶ms); 168 if (createSpiFunc == NULL) { 169 LOGE("Not support this KDF func"); 170 return HCF_NOT_SUPPORT; 171 } 172 173 HcfKdfImpl *returnGenerator = (HcfKdfImpl *)HcfMalloc(sizeof(HcfKdfImpl), 0); 174 if (returnGenerator == NULL) { 175 LOGE("Failed to allocate returnGenerator memory!"); 176 return HCF_ERR_MALLOC; 177 } 178 if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, transformation) != EOK) { 179 LOGE("Failed to copy algoName!"); 180 HcfFree(returnGenerator); 181 return HCF_INVALID_PARAMS; 182 } 183 HcfKdfSpi *spiObj = NULL; 184 HcfResult res = createSpiFunc(¶ms, &spiObj); 185 if (res != HCF_SUCCESS) { 186 LOGE("Failed to create spi object!"); 187 HcfFree(returnGenerator); 188 return res; 189 } 190 returnGenerator->base.base.destroy = DestroyKdf; 191 returnGenerator->base.base.getClass = GetKdfGeneratorClass; 192 returnGenerator->base.generateSecret = GenerateSecret; 193 returnGenerator->base.getAlgorithm = GetAlgoName; 194 returnGenerator->spiObj = spiObj; 195 196 *returnObj = (HcfKdf *)returnGenerator; 197 return HCF_SUCCESS; 198} 199