• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "crypto_kdf.h"
17 #include <stdlib.h>
18 #include <string.h>
19 #include <securec.h>
20 #include "crypto_common.h"
21 #include "native_common.h"
22 #include "memory.h"
23 #include "kdf.h"
24 #include "kdf_params.h"
25 #include "detailed_hkdf_params.h"
26 #include "detailed_pbkdf2_params.h"
27 #include "detailed_scrypt_params.h"
28 
29 typedef struct OH_CryptoKdf {
30     HcfObjectBase base;
31 
32     const char *(*getAlgorithm)(HcfKdf *self);
33 
34     HcfResult (*generateSecret)(HcfKdf *self, HcfKdfParamsSpec* paramsSpec);
35 } OH_CryptoKdf;
36 
37 
38 typedef struct OH_CryptoKdfParams {
39     const char *algName;
40 } OH_CryptoKdfParams;
41 
42 static const char *g_hkdfName = "HKDF";
43 static const char *g_pbkdf2Name = "PBKDF2";
44 static const char *g_scryptName = "SCRYPT";
45 
OH_CryptoKdfParams_Create(const char * algoName,OH_CryptoKdfParams ** params)46 OH_Crypto_ErrCode OH_CryptoKdfParams_Create(const char *algoName, OH_CryptoKdfParams **params)
47 {
48     if ((algoName == NULL) || (params == NULL)) {
49         return CRYPTO_PARAMETER_CHECK_FAILED;
50     }
51 
52     OH_CryptoKdfParams *tmParams = NULL;
53     const char *algName = NULL;
54     if (strcmp(algoName, g_hkdfName) == 0) {
55         tmParams = (OH_CryptoKdfParams *)HcfMalloc(sizeof(HcfHkdfParamsSpec), 0);
56         algName = g_hkdfName;
57     } else if (strcmp(algoName, g_pbkdf2Name) == 0) {
58         tmParams = (OH_CryptoKdfParams *)HcfMalloc(sizeof(HcfPBKDF2ParamsSpec), 0);
59         algName = g_pbkdf2Name;
60     } else if (strcmp(algoName, g_scryptName) == 0) {
61         tmParams = (OH_CryptoKdfParams *)HcfMalloc(sizeof(HcfScryptParamsSpec), 0);
62         algName = g_scryptName;
63     } else {
64         return CRYPTO_PARAMETER_CHECK_FAILED;
65     }
66     if (tmParams == NULL) {
67         return CRYPTO_MEMORY_ERROR;
68     }
69     tmParams->algName = algName;
70     *params = tmParams;
71     return CRYPTO_SUCCESS;
72 }
73 
SetHkdfParam(HcfHkdfParamsSpec * params,CryptoKdf_ParamType type,Crypto_DataBlob * value)74 static OH_Crypto_ErrCode SetHkdfParam(HcfHkdfParamsSpec *params, CryptoKdf_ParamType type, Crypto_DataBlob *value)
75 {
76     uint8_t *data = (uint8_t *)HcfMalloc(value->len, 0);
77     if (data == NULL) {
78         return CRYPTO_MEMORY_ERROR;
79     }
80     (void)memcpy_s(data, value->len, value->data, value->len);
81     switch (type) {
82         case CRYPTO_KDF_KEY_DATABLOB:
83             HcfBlobDataClearAndFree(&(params->key));
84             params->key.data = data;
85             params->key.len = value->len;
86             break;
87         case CRYPTO_KDF_SALT_DATABLOB:
88             HcfBlobDataClearAndFree(&(params->salt));
89             params->salt.data = data;
90             params->salt.len = value->len;
91             break;
92         case CRYPTO_KDF_INFO_DATABLOB:
93             HcfBlobDataClearAndFree(&(params->info));
94             params->info.data = data;
95             params->info.len = value->len;
96             break;
97         default:
98             HcfFree(data);
99             data = NULL;
100             return CRYPTO_PARAMETER_CHECK_FAILED;
101     }
102     return CRYPTO_SUCCESS;
103 }
104 
SetPbkdf2Param(HcfPBKDF2ParamsSpec * params,CryptoKdf_ParamType type,Crypto_DataBlob * value)105 static OH_Crypto_ErrCode SetPbkdf2Param(HcfPBKDF2ParamsSpec *params, CryptoKdf_ParamType type, Crypto_DataBlob *value)
106 {
107     switch (type) {
108         case CRYPTO_KDF_KEY_DATABLOB: {
109             uint8_t *data = (uint8_t *)HcfMalloc(value->len, 0);
110             if (data == NULL) {
111                 return CRYPTO_MEMORY_ERROR;
112             }
113             (void)memcpy_s(data, value->len, value->data, value->len);
114             HcfBlobDataClearAndFree(&(params->password));
115             params->password.data = data;
116             params->password.len = value->len;
117             break;
118         }
119         case CRYPTO_KDF_SALT_DATABLOB: {
120             uint8_t *data = (uint8_t *)HcfMalloc(value->len, 0);
121             if (data == NULL) {
122                 return CRYPTO_MEMORY_ERROR;
123             }
124             (void)memcpy_s(data, value->len, value->data, value->len);
125             HcfBlobDataClearAndFree(&(params->salt));
126             params->salt.data = data;
127             params->salt.len = value->len;
128             break;
129         }
130         case CRYPTO_KDF_ITER_COUNT_INT: {
131             if (value->len != sizeof(int)) {
132                 return CRYPTO_PARAMETER_CHECK_FAILED;
133             }
134             params->iterations = *(int *)(value->data);
135             break;
136         }
137         default:
138             return CRYPTO_PARAMETER_CHECK_FAILED;
139     }
140     return CRYPTO_SUCCESS;
141 }
142 
SetScryptKeyParam(HcfScryptParamsSpec * params,Crypto_DataBlob * value)143 static OH_Crypto_ErrCode SetScryptKeyParam(HcfScryptParamsSpec *params, Crypto_DataBlob *value)
144 {
145     uint8_t *data = (uint8_t *)HcfMalloc(value->len, 0);
146     if (data == NULL) {
147         return CRYPTO_MEMORY_ERROR;
148     }
149     (void)memcpy_s(data, value->len, value->data, value->len);
150     HcfBlobDataClearAndFree(&(params->passPhrase));
151     params->passPhrase.data = data;
152     params->passPhrase.len = value->len;
153     return CRYPTO_SUCCESS;
154 }
155 
SetScryptSaltParam(HcfScryptParamsSpec * params,Crypto_DataBlob * value)156 static OH_Crypto_ErrCode SetScryptSaltParam(HcfScryptParamsSpec *params, Crypto_DataBlob *value)
157 {
158     uint8_t *data = (uint8_t *)HcfMalloc(value->len, 0);
159     if (data == NULL) {
160         return CRYPTO_MEMORY_ERROR;
161     }
162     (void)memcpy_s(data, value->len, value->data, value->len);
163     HcfBlobDataClearAndFree(&(params->salt));
164     params->salt.data = data;
165     params->salt.len = value->len;
166     return CRYPTO_SUCCESS;
167 }
168 
SetScryptUint64Param(HcfScryptParamsSpec * params,Crypto_DataBlob * value,uint64_t * target)169 static OH_Crypto_ErrCode SetScryptUint64Param(HcfScryptParamsSpec *params, Crypto_DataBlob *value, uint64_t *target)
170 {
171     if (value->len != sizeof(uint64_t)) {
172         return CRYPTO_PARAMETER_CHECK_FAILED;
173     }
174     *target = *(uint64_t *)(value->data);
175     return CRYPTO_SUCCESS;
176 }
177 
SetScryptParam(HcfScryptParamsSpec * params,CryptoKdf_ParamType type,Crypto_DataBlob * value)178 static OH_Crypto_ErrCode SetScryptParam(HcfScryptParamsSpec *params, CryptoKdf_ParamType type, Crypto_DataBlob *value)
179 {
180     switch (type) {
181         case CRYPTO_KDF_KEY_DATABLOB:
182             return SetScryptKeyParam(params, value);
183         case CRYPTO_KDF_SALT_DATABLOB:
184             return SetScryptSaltParam(params, value);
185         case CRYPTO_KDF_SCRYPT_N_UINT64:
186             return SetScryptUint64Param(params, value, &params->n);
187         case CRYPTO_KDF_SCRYPT_R_UINT64:
188             return SetScryptUint64Param(params, value, &params->r);
189         case CRYPTO_KDF_SCRYPT_P_UINT64:
190             return SetScryptUint64Param(params, value, &params->p);
191         case CRYPTO_KDF_SCRYPT_MAX_MEM_UINT64:
192             return SetScryptUint64Param(params, value, &params->maxMem);
193         default:
194             return CRYPTO_PARAMETER_CHECK_FAILED;
195     }
196 }
197 
OH_CryptoKdfParams_SetParam(OH_CryptoKdfParams * params,CryptoKdf_ParamType type,Crypto_DataBlob * value)198 OH_Crypto_ErrCode OH_CryptoKdfParams_SetParam(OH_CryptoKdfParams *params, CryptoKdf_ParamType type,
199     Crypto_DataBlob *value)
200 {
201     if ((params == NULL) || (params->algName == NULL) || (value == NULL) || (value->data == NULL)) {
202         return CRYPTO_PARAMETER_CHECK_FAILED;
203     }
204     if (strcmp(params->algName, g_hkdfName) == 0) {
205         return SetHkdfParam((HcfHkdfParamsSpec*)params, type, value);
206     } else if (strcmp(params->algName, g_pbkdf2Name) == 0) {
207         return SetPbkdf2Param((HcfPBKDF2ParamsSpec*)params, type, value);
208     } else if (strcmp(params->algName, g_scryptName) == 0) {
209         return SetScryptParam((HcfScryptParamsSpec*)params, type, value);
210     } else {
211         return CRYPTO_PARAMETER_CHECK_FAILED;
212     }
213 }
214 
FreeHkdfParamSpec(HcfHkdfParamsSpec * params)215 static void FreeHkdfParamSpec(HcfHkdfParamsSpec *params)
216 {
217     HcfBlobDataClearAndFree(&(params->key));
218     HcfBlobDataClearAndFree(&(params->salt));
219     HcfBlobDataClearAndFree(&(params->info));
220     HcfBlobDataClearAndFree(&(params->output));
221 }
222 
FreePbkdf2ParamSpec(HcfPBKDF2ParamsSpec * params)223 static void FreePbkdf2ParamSpec(HcfPBKDF2ParamsSpec *params)
224 {
225     HcfBlobDataClearAndFree(&(params->password));
226     HcfBlobDataClearAndFree(&(params->salt));
227     HcfBlobDataClearAndFree(&(params->output));
228 }
229 
FreeScryptParamSpec(HcfScryptParamsSpec * params)230 static void FreeScryptParamSpec(HcfScryptParamsSpec *params)
231 {
232     HcfBlobDataClearAndFree(&(params->passPhrase));
233     HcfBlobDataClearAndFree(&(params->salt));
234     HcfBlobDataClearAndFree(&(params->output));
235 }
236 
FreeParamSpec(OH_CryptoKdfParams * params)237 static void FreeParamSpec(OH_CryptoKdfParams *params)
238 {
239     if (params->algName == NULL) {
240         return;
241     }
242     if (strcmp(params->algName, g_hkdfName) == 0) {
243         FreeHkdfParamSpec((HcfHkdfParamsSpec*)params);
244     } else if (strcmp(params->algName, g_pbkdf2Name) == 0) {
245         FreePbkdf2ParamSpec((HcfPBKDF2ParamsSpec*)params);
246     } else if (strcmp(params->algName, g_scryptName) == 0) {
247         FreeScryptParamSpec((HcfScryptParamsSpec*)params);
248     }
249 }
250 
OH_CryptoKdfParams_Destroy(OH_CryptoKdfParams * params)251 void OH_CryptoKdfParams_Destroy(OH_CryptoKdfParams *params)
252 {
253     if (params == NULL) {
254         return;
255     }
256     FreeParamSpec(params);
257     params->algName = NULL;
258     HcfFree(params);
259 }
260 
OH_CryptoKdf_Create(const char * algoName,OH_CryptoKdf ** ctx)261 OH_Crypto_ErrCode OH_CryptoKdf_Create(const char *algoName, OH_CryptoKdf **ctx)
262 {
263     if ((algoName == NULL) || (ctx == NULL)) {
264         return CRYPTO_PARAMETER_CHECK_FAILED;
265     }
266     HcfResult ret = HcfKdfCreate(algoName, (HcfKdf **)ctx);
267     return GetOhCryptoErrCodeNew(ret);
268 }
269 
HkdfDerive(HcfKdf * ctx,const HcfHkdfParamsSpec * params,uint32_t keyLen,HcfBlob * key)270 static OH_Crypto_ErrCode HkdfDerive(HcfKdf *ctx, const HcfHkdfParamsSpec *params, uint32_t keyLen, HcfBlob *key)
271 {
272     uint8_t *out = (uint8_t *)HcfMalloc(keyLen, 0);
273     if (out == NULL) {
274         return CRYPTO_MEMORY_ERROR;
275     }
276     HcfBlob output = {.data = out, .len = keyLen};
277     HcfHkdfParamsSpec hkdfParams = {
278         .base = { .algName = g_hkdfName, },
279         .key = params->key,
280         .salt = params->salt,
281         .info = params->info,
282         .output = output,
283     };
284     HcfResult ret = ctx->generateSecret(ctx, &(hkdfParams.base));
285     if (ret != HCF_SUCCESS) {
286         HcfBlobDataClearAndFree(&output);
287         return GetOhCryptoErrCodeNew(ret);
288     }
289     key->data = hkdfParams.output.data;
290     key->len = hkdfParams.output.len;
291     return CRYPTO_SUCCESS;
292 }
293 
Pbkdf2Derive(HcfKdf * ctx,const HcfPBKDF2ParamsSpec * params,uint32_t keyLen,HcfBlob * key)294 static OH_Crypto_ErrCode Pbkdf2Derive(HcfKdf *ctx, const HcfPBKDF2ParamsSpec *params, uint32_t keyLen, HcfBlob *key)
295 {
296     uint8_t *out = (uint8_t *)HcfMalloc(keyLen, 0);
297     if (out == NULL) {
298         return CRYPTO_MEMORY_ERROR;
299     }
300     HcfBlob output = {.data = out, .len = keyLen};
301     HcfPBKDF2ParamsSpec pbkdf2Params = {
302         .base = { .algName = g_pbkdf2Name, },
303         .password = params->password,
304         .salt = params->salt,
305         .iterations = params->iterations,
306         .output = output,
307     };
308     HcfResult ret = ctx->generateSecret(ctx, &(pbkdf2Params.base));
309     if (ret != HCF_SUCCESS) {
310         HcfBlobDataClearAndFree(&output);
311         return GetOhCryptoErrCodeNew(ret);
312     }
313     key->data = pbkdf2Params.output.data;
314     key->len = pbkdf2Params.output.len;
315     return CRYPTO_SUCCESS;
316 }
317 
ScryptDerive(HcfKdf * ctx,const HcfScryptParamsSpec * params,uint32_t keyLen,HcfBlob * key)318 static OH_Crypto_ErrCode ScryptDerive(HcfKdf *ctx, const HcfScryptParamsSpec *params, uint32_t keyLen, HcfBlob *key)
319 {
320     uint8_t *out = (uint8_t *)HcfMalloc(keyLen, 0);
321     if (out == NULL) {
322         return CRYPTO_MEMORY_ERROR;
323     }
324     HcfBlob output = {.data = out, .len = keyLen};
325     HcfScryptParamsSpec scryptParams = {
326         .base = { .algName = g_scryptName, },
327         .passPhrase = params->passPhrase,
328         .salt = params->salt,
329         .n = params->n,
330         .p = params->p,
331         .r = params->r,
332         .maxMem = params->maxMem,
333         .output = output,
334     };
335     HcfResult ret = ctx->generateSecret(ctx, &(scryptParams.base));
336     if (ret != HCF_SUCCESS) {
337         HcfBlobDataClearAndFree(&output);
338         return GetOhCryptoErrCodeNew(ret);
339     }
340     key->data = scryptParams.output.data;
341     key->len = scryptParams.output.len;
342     return CRYPTO_SUCCESS;
343 }
344 
OH_CryptoKdf_Derive(OH_CryptoKdf * ctx,const OH_CryptoKdfParams * params,int keyLen,Crypto_DataBlob * key)345 OH_Crypto_ErrCode OH_CryptoKdf_Derive(OH_CryptoKdf *ctx, const OH_CryptoKdfParams *params, int keyLen,
346     Crypto_DataBlob *key)
347 {
348     if ((ctx == NULL) || (params == NULL) || (params->algName == NULL) || (key == NULL) || (keyLen <= 0)) {
349         return CRYPTO_PARAMETER_CHECK_FAILED;
350     }
351 
352     if (strcmp(params->algName, g_hkdfName) == 0) {
353         return HkdfDerive((HcfKdf *)ctx, (HcfHkdfParamsSpec *)params, (uint32_t)keyLen, (HcfBlob *)key);
354     } else if (strcmp(params->algName, g_pbkdf2Name) == 0) {
355         return Pbkdf2Derive((HcfKdf *)ctx, (HcfPBKDF2ParamsSpec*)params, (uint32_t)keyLen, (HcfBlob *)key);
356     } else if (strcmp(params->algName, g_scryptName) == 0) {
357         return ScryptDerive((HcfKdf *)ctx, (HcfScryptParamsSpec*)params, (uint32_t)keyLen, (HcfBlob *)key);
358     } else {
359         return CRYPTO_PARAMETER_CHECK_FAILED;
360     }
361 }
362 
OH_CryptoKdf_Destroy(OH_CryptoKdf * ctx)363 void OH_CryptoKdf_Destroy(OH_CryptoKdf *ctx)
364 {
365     HcfObjDestroy((HcfKdf *)ctx);
366 }