• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "scrypt_openssl.h"
28 #include "utils.h"
29 
30 typedef HcfResult (*HcfKdfSpiCreateFunc)(HcfKdfDeriveParams *, HcfKdfSpi **);
31 
32 typedef struct {
33     HcfKdf base;
34     HcfKdfSpi *spiObj;
35     char algoName[HCF_MAX_ALGO_NAME_LEN];
36 } HcfKdfImpl;
37 
38 typedef struct {
39     HcfAlgValue algo;
40     HcfKdfSpiCreateFunc createSpiFunc;
41 } HcfKdfGenAbility;
42 
SetKdfType(HcfAlgParaValue value,HcfKdfDeriveParams * kdf)43 static void SetKdfType(HcfAlgParaValue value, HcfKdfDeriveParams *kdf)
44 {
45     switch (value) {
46         case HCF_ALG_PBKDF2_DEFAULT:
47             kdf->algo = HCF_ALG_PKBDF2;
48             break;
49         case HCF_ALG_HKDF_DEFAULT:
50             kdf->algo = HCF_ALG_HKDF;
51             break;
52         case HCF_ALG_SCRYPT_DEFAULT:
53             kdf->algo = HCF_ALG_SCRYPT;
54             break;
55         default:
56             LOGE("Invalid algo %{public}u.", value);
57             break;
58     }
59 }
60 
SetDigest(HcfAlgParaValue value,HcfKdfDeriveParams * kdf)61 static void SetDigest(HcfAlgParaValue value, HcfKdfDeriveParams *kdf)
62 {
63     kdf->md = value;
64 }
65 
SetMode(HcfAlgParaValue value,HcfKdfDeriveParams * kdf)66 static void SetMode(HcfAlgParaValue value, HcfKdfDeriveParams *kdf)
67 {
68     kdf->mode = value;
69 }
70 
ParseKdfParams(const HcfParaConfig * config,void * params)71 static HcfResult ParseKdfParams(const HcfParaConfig *config, void *params)
72 {
73     if (config == NULL || params == NULL) {
74         LOGE("Invalid Kdf params");
75         return HCF_INVALID_PARAMS;
76     }
77     HcfResult ret = HCF_SUCCESS;
78     HcfKdfDeriveParams *paramsObj = (HcfKdfDeriveParams *)params;
79     LOGD("Set Parameter: %s", config->tag);
80     switch (config->paraType) {
81         case HCF_ALG_TYPE:
82             SetKdfType(config->paraValue, paramsObj);
83             break;
84         case HCF_ALG_DIGEST:
85             SetDigest(config->paraValue, paramsObj);
86             break;
87         case HCF_ALG_MODE:
88             SetMode(config->paraValue, paramsObj);
89             break;
90         default:
91             ret = HCF_INVALID_PARAMS;
92             break;
93     }
94     return ret;
95 }
96 
97 static const HcfKdfGenAbility KDF_ABILITY_SET[] = {
98     { HCF_ALG_PKBDF2, HcfKdfPBKDF2SpiCreate },
99     { HCF_ALG_HKDF, HcfKdfHkdfSpiCreate},
100     { HCF_ALG_SCRYPT, HcfKdfScryptSpiCreate },
101 };
102 
FindAbility(HcfKdfDeriveParams * params)103 static HcfKdfSpiCreateFunc FindAbility(HcfKdfDeriveParams* params)
104 {
105     for (uint32_t i = 0; i < (sizeof(KDF_ABILITY_SET) / sizeof(KDF_ABILITY_SET[0])); i++) {
106         if (KDF_ABILITY_SET[i].algo == params->algo) {
107             return KDF_ABILITY_SET[i].createSpiFunc;
108         }
109     }
110     LOGE("Algo not support! [Algo]: %{public}d", params->algo);
111     return NULL;
112 }
113 
114 // export interfaces
GetKdfGeneratorClass(void)115 static const char *GetKdfGeneratorClass(void)
116 {
117     return "HcfKdfGenerator";
118 }
119 
GetAlgoName(HcfKdf * self)120 static const char *GetAlgoName(HcfKdf *self)
121 {
122     if (self == NULL) {
123         LOGE("The input self ptr is NULL!");
124         return NULL;
125     }
126     if (!HcfIsClassMatch((HcfObjectBase *)self, GetKdfGeneratorClass())) {
127         return NULL;
128     }
129     return ((HcfKdfImpl *)self)->algoName;
130 }
131 
GenerateSecret(HcfKdf * self,HcfKdfParamsSpec * paramsSpec)132 static HcfResult GenerateSecret(HcfKdf *self, HcfKdfParamsSpec *paramsSpec)
133 {
134     if (self == NULL || paramsSpec == NULL) {
135         LOGE("Invalid input parameter.");
136         return HCF_INVALID_PARAMS;
137     }
138     if (!HcfIsClassMatch((HcfObjectBase *)self, GetKdfGeneratorClass())) {
139         return HCF_INVALID_PARAMS;
140     }
141 
142     HcfKdfImpl *tmp = (HcfKdfImpl *)self;
143     return tmp->spiObj->generateSecret(tmp->spiObj, paramsSpec);
144 }
145 
DestroyKdf(HcfObjectBase * self)146 static void DestroyKdf(HcfObjectBase *self)
147 {
148     if (self == NULL) {
149         return;
150     }
151     if (!HcfIsClassMatch((HcfObjectBase *)self, GetKdfGeneratorClass())) {
152         return;
153     }
154     HcfKdfImpl *impl = (HcfKdfImpl *)self;
155     HcfObjDestroy(impl->spiObj);
156     impl->spiObj = NULL;
157     HcfFree(impl);
158 }
159 
HcfKdfCreate(const char * transformation,HcfKdf ** returnObj)160 HcfResult HcfKdfCreate(const char *transformation, HcfKdf **returnObj)
161 {
162     if ((!HcfIsStrValid(transformation, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) {
163         LOGE("Invalid input params while creating kdf!");
164         return HCF_INVALID_PARAMS;
165     }
166 
167     HcfKdfDeriveParams params = { 0 };
168     if (ParseAndSetParameter(transformation, &params, ParseKdfParams) != HCF_SUCCESS) {
169         LOGE("Failed to parse params!");
170         return HCF_INVALID_PARAMS;
171     }
172     HcfKdfSpiCreateFunc createSpiFunc = FindAbility(&params);
173     if (createSpiFunc == NULL) {
174         LOGE("Not support this KDF func");
175         return HCF_NOT_SUPPORT;
176     }
177 
178     HcfKdfImpl *returnGenerator = (HcfKdfImpl *)HcfMalloc(sizeof(HcfKdfImpl), 0);
179     if (returnGenerator == NULL) {
180         LOGE("Failed to allocate returnGenerator memory!");
181         return HCF_ERR_MALLOC;
182     }
183     if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, transformation) != EOK) {
184         LOGE("Failed to copy algoName!");
185         HcfFree(returnGenerator);
186         returnGenerator = NULL;
187         return HCF_INVALID_PARAMS;
188     }
189     HcfKdfSpi *spiObj = NULL;
190     HcfResult res = createSpiFunc(&params, &spiObj);
191     if (res != HCF_SUCCESS) {
192         LOGE("Failed to create spi object!");
193         HcfFree(returnGenerator);
194         returnGenerator = NULL;
195         return res;
196     }
197     returnGenerator->base.base.destroy = DestroyKdf;
198     returnGenerator->base.base.getClass = GetKdfGeneratorClass;
199     returnGenerator->base.generateSecret = GenerateSecret;
200     returnGenerator->base.getAlgorithm = GetAlgoName;
201     returnGenerator->spiObj = spiObj;
202 
203     *returnObj = (HcfKdf *)returnGenerator;
204     return HCF_SUCCESS;
205 }
206