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 
29 typedef HcfResult (*HcfKdfSpiCreateFunc)(HcfKdfDeriveParams *, HcfKdfSpi **);
30 
31 typedef struct {
32     HcfKdf base;
33     HcfKdfSpi *spiObj;
34     char algoName[HCF_MAX_ALGO_NAME_LEN];
35 } HcfKdfImpl;
36 
37 typedef struct {
38     HcfAlgValue algo;
39     HcfKdfSpiCreateFunc createSpiFunc;
40 } HcfKdfGenAbility;
41 
SetKdfType(HcfAlgParaValue value,HcfKdfDeriveParams * kdf)42 static 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 
SetDigest(HcfAlgParaValue value,HcfKdfDeriveParams * kdf)57 static void SetDigest(HcfAlgParaValue value, HcfKdfDeriveParams *kdf)
58 {
59     kdf->md = value;
60 }
61 
SetMode(HcfAlgParaValue value,HcfKdfDeriveParams * kdf)62 static void SetMode(HcfAlgParaValue value, HcfKdfDeriveParams *kdf)
63 {
64     kdf->mode = value;
65 }
66 
ParseKdfParams(const HcfParaConfig * config,void * params)67 static 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 
93 static const HcfKdfGenAbility KDF_ABILITY_SET[] = {
94     { HCF_ALG_PKBDF2, HcfKdfPBKDF2SpiCreate },
95     { HCF_ALG_HKDF, HcfKdfHkdfSpiCreate},
96 };
97 
FindAbility(HcfKdfDeriveParams * params)98 static 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
GetKdfGeneratorClass(void)110 static const char *GetKdfGeneratorClass(void)
111 {
112     return "HcfKdfGenerator";
113 }
114 
GetAlgoName(HcfKdf * self)115 static 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 
GenerateSecret(HcfKdf * self,HcfKdfParamsSpec * paramsSpec)127 static 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 
DestroyKdf(HcfObjectBase * self)141 static 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 
HcfKdfCreate(const char * transformation,HcfKdf ** returnObj)155 HcfResult 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, &params, ParseKdfParams) != HCF_SUCCESS) {
164         LOGE("Failed to parse params!");
165         return HCF_INVALID_PARAMS;
166     }
167     HcfKdfSpiCreateFunc createSpiFunc = FindAbility(&params);
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(&params, &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