• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include "hitls_build.h"
17 #if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_KDF)
18 
19 #include <stdint.h>
20 #include "crypt_eal_kdf.h"
21 #include "securec.h"
22 #include "bsl_err_internal.h"
23 #include "crypt_local_types.h"
24 #include "crypt_eal_mac.h"
25 #ifdef HITLS_CRYPTO_PROVIDER
26 #include "crypt_eal_implprovider.h"
27 #include "crypt_provider.h"
28 #endif
29 #include "crypt_algid.h"
30 #include "crypt_errno.h"
31 #include "eal_mac_local.h"
32 #include "eal_kdf_local.h"
33 #ifdef HITLS_CRYPTO_HMAC
34 #include "crypt_hmac.h"
35 #endif
36 #ifdef HITLS_CRYPTO_PBKDF2
37 #include "crypt_pbkdf2.h"
38 #endif
39 #ifdef HITLS_CRYPTO_HKDF
40 #include "crypt_hkdf.h"
41 #endif
42 #ifdef HITLS_CRYPTO_KDFTLS12
43 #include "crypt_kdf_tls12.h"
44 #endif
45 #ifdef HITLS_CRYPTO_SCRYPT
46 #include "crypt_scrypt.h"
47 #endif
48 #include "eal_common.h"
49 #include "crypt_utils.h"
50 #include "bsl_sal.h"
51 
KdfAllocCtx(CRYPT_KDF_AlgId id,EAL_KdfUnitaryMethod * method)52 static CRYPT_EAL_KdfCTX *KdfAllocCtx(CRYPT_KDF_AlgId id, EAL_KdfUnitaryMethod *method)
53 {
54     CRYPT_EAL_KdfCTX *ctx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_KdfCTX));
55     if (ctx == NULL) {
56         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
57         return NULL;
58     }
59     void *data = method->newCtx();
60     if (data == NULL) {
61         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, id, CRYPT_MEM_ALLOC_FAIL);
62         BSL_SAL_FREE(ctx);
63         return NULL;
64     }
65     ctx->data = data;
66     return ctx;
67 }
68 
EalKdfCopyMethod(const EAL_KdfMethod * method,EAL_KdfUnitaryMethod * dest)69 static void EalKdfCopyMethod(const EAL_KdfMethod *method, EAL_KdfUnitaryMethod *dest)
70 {
71     dest->newCtx = method->newCtx;
72     dest->setParam = method->setParam;
73     dest->derive = method->derive;
74     dest->deinit = method->deinit;
75     dest->freeCtx = method->freeCtx;
76     dest->ctrl = method->ctrl;
77 }
78 
79 #ifdef HITLS_CRYPTO_PROVIDER
CRYPT_EAL_SetKdfMethod(CRYPT_EAL_KdfCTX * ctx,const CRYPT_EAL_Func * funcs)80 static int32_t CRYPT_EAL_SetKdfMethod(CRYPT_EAL_KdfCTX *ctx, const CRYPT_EAL_Func *funcs)
81 {
82     int32_t index = 0;
83     EAL_KdfUnitaryMethod *method = BSL_SAL_Calloc(1, sizeof(EAL_KdfUnitaryMethod));
84     if (method == NULL) {
85         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
86         return BSL_MALLOC_FAIL;
87     }
88 
89     while (funcs[index].id != 0) {
90         switch (funcs[index].id) {
91             case CRYPT_EAL_IMPLKDF_NEWCTX:
92                 method->provNewCtx = funcs[index].func;
93                 break;
94             case CRYPT_EAL_IMPLKDF_SETPARAM:
95                 method->setParam = funcs[index].func;
96                 break;
97             case CRYPT_EAL_IMPLKDF_DERIVE:
98                 method->derive = funcs[index].func;
99                 break;
100             case CRYPT_EAL_IMPLKDF_DEINITCTX:
101                 method->deinit = funcs[index].func;
102                 break;
103             case CRYPT_EAL_IMPLKDF_CTRL:
104                 method->ctrl = funcs[index].func;
105                 break;
106             case CRYPT_EAL_IMPLKDF_FREECTX:
107                 method->freeCtx = funcs[index].func;
108                 break;
109             default:
110                 BSL_SAL_FREE(method);
111                 BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_ERR_UNEXPECTED_IMPL);
112                 return CRYPT_PROVIDER_ERR_UNEXPECTED_IMPL;
113         }
114         index++;
115     }
116     ctx->method = method;
117     return CRYPT_SUCCESS;
118 }
119 
CRYPT_EAL_ProviderKdfNewCtxInner(CRYPT_EAL_LibCtx * libCtx,int32_t algId,const char * attrName)120 CRYPT_EAL_KdfCTX *CRYPT_EAL_ProviderKdfNewCtxInner(CRYPT_EAL_LibCtx *libCtx, int32_t algId, const char *attrName)
121 {
122     const CRYPT_EAL_Func *funcs = NULL;
123     void *provCtx = NULL;
124     int32_t ret = CRYPT_EAL_ProviderGetFuncs(libCtx, CRYPT_EAL_OPERAID_KDF, algId, attrName,
125         &funcs, &provCtx);
126     if (ret != CRYPT_SUCCESS) {
127         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, algId, ret);
128         return NULL;
129     }
130     CRYPT_EAL_KdfCTX *ctx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_KdfCTX));
131     if (ctx == NULL) {
132         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, algId, CRYPT_MEM_ALLOC_FAIL);
133         return NULL;
134     }
135 
136     ret = CRYPT_EAL_SetKdfMethod(ctx, funcs);
137     if (ret != BSL_SUCCESS) {
138         BSL_SAL_FREE(ctx);
139         return NULL;
140     }
141     if (ctx->method->provNewCtx == NULL) {
142         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, algId, CRYPT_PROVIDER_ERR_IMPL_NULL);
143         BSL_SAL_FREE(ctx->method);
144         BSL_SAL_FREE(ctx);
145         return NULL;
146     }
147     ctx->data = ctx->method->provNewCtx(provCtx, algId);
148     if (ctx->data == NULL) {
149         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, algId, CRYPT_MEM_ALLOC_FAIL);
150         BSL_SAL_FREE(ctx->method);
151         BSL_SAL_FREE(ctx);
152         return NULL;
153     }
154     ctx->id = algId;
155     ctx->isProvider = true;
156     return ctx;
157 }
158 #endif // HITLS_CRYPTO_PROVIDER
159 
CRYPT_EAL_ProviderKdfNewCtx(CRYPT_EAL_LibCtx * libCtx,int32_t algId,const char * attrName)160 CRYPT_EAL_KdfCTX *CRYPT_EAL_ProviderKdfNewCtx(CRYPT_EAL_LibCtx *libCtx, int32_t algId, const char *attrName)
161 {
162 #ifdef HITLS_CRYPTO_PROVIDER
163     return CRYPT_EAL_ProviderKdfNewCtxInner(libCtx, algId, attrName);
164 #else
165     (void)libCtx;
166     (void)attrName;
167     return CRYPT_EAL_KdfNewCtx(algId);
168     return NULL;
169 #endif
170 }
171 
CRYPT_EAL_KdfNewCtx(CRYPT_KDF_AlgId algId)172 CRYPT_EAL_KdfCTX *CRYPT_EAL_KdfNewCtx(CRYPT_KDF_AlgId algId)
173 {
174     const EAL_KdfMethod *method = EAL_KdfFindMethod(algId);
175     if (method == NULL) {
176         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, algId, CRYPT_EAL_ERR_ALGID);
177         return NULL;
178     }
179     EAL_KdfUnitaryMethod *temp = BSL_SAL_Calloc(1, sizeof(EAL_KdfUnitaryMethod));
180     if (temp == NULL) {
181         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, algId, BSL_MALLOC_FAIL);
182         return NULL;
183     }
184     EalKdfCopyMethod(method, temp);
185     CRYPT_EAL_KdfCTX *ctx = KdfAllocCtx(algId, temp);
186     if (ctx == NULL) {
187         BSL_SAL_FREE(temp);
188         return NULL;
189     }
190 
191     ctx->id = algId;
192     ctx->method = temp;
193     return ctx;
194 }
195 
CRYPT_EAL_KdfSetParam(CRYPT_EAL_KdfCTX * ctx,const BSL_Param * param)196 int32_t CRYPT_EAL_KdfSetParam(CRYPT_EAL_KdfCTX *ctx, const BSL_Param *param)
197 {
198     int32_t ret;
199     if (ctx == NULL) {
200         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_MAX, CRYPT_NULL_INPUT);
201         return CRYPT_NULL_INPUT;
202     }
203     if (ctx->method == NULL || ctx->method->setParam == NULL) {
204         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
205         return CRYPT_EAL_ALG_NOT_SUPPORT;
206     }
207 
208     ret = ctx->method->setParam(ctx->data, param);
209     if (ret != CRYPT_SUCCESS) {
210         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, ctx->id, ret);
211     }
212     return ret;
213 }
214 
CRYPT_EAL_KdfDerive(CRYPT_EAL_KdfCTX * ctx,uint8_t * key,uint32_t keyLen)215 int32_t CRYPT_EAL_KdfDerive(CRYPT_EAL_KdfCTX *ctx, uint8_t *key, uint32_t keyLen)
216 {
217     if (ctx == NULL) {
218         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_MAX, CRYPT_NULL_INPUT);
219         return CRYPT_NULL_INPUT;
220     }
221     if (ctx->method == NULL || ctx->method->derive == NULL) {
222         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
223         return CRYPT_EAL_ALG_NOT_SUPPORT;
224     }
225 
226     int32_t ret = ctx->method->derive(ctx->data, key, keyLen);
227     if (ret != CRYPT_SUCCESS) {
228         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, ctx->id, ret);
229         return ret;
230     }
231     EAL_EventReport(CRYPT_EVENT_KDF, CRYPT_ALGO_KDF, ctx->id, CRYPT_SUCCESS);
232     return CRYPT_SUCCESS;
233 }
234 
CRYPT_EAL_KdfDeInitCtx(CRYPT_EAL_KdfCTX * ctx)235 int32_t CRYPT_EAL_KdfDeInitCtx(CRYPT_EAL_KdfCTX *ctx)
236 {
237     if (ctx == NULL || ctx->method == NULL || ctx->method->deinit == NULL) {
238         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_MAX, CRYPT_NULL_INPUT);
239         return CRYPT_NULL_INPUT;
240     }
241 
242     ctx->method->deinit(ctx->data);
243     return CRYPT_SUCCESS;
244 }
245 
CRYPT_EAL_KdfFreeCtx(CRYPT_EAL_KdfCTX * ctx)246 void CRYPT_EAL_KdfFreeCtx(CRYPT_EAL_KdfCTX *ctx)
247 {
248     if (ctx == NULL) {
249         return;
250     }
251     if (ctx->method == NULL || ctx->method->freeCtx == NULL) {
252         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
253         BSL_SAL_FREE(ctx->method);
254         BSL_SAL_FREE(ctx);
255         return;
256     }
257     EAL_EventReport(CRYPT_EVENT_ZERO, CRYPT_ALGO_KDF, ctx->id, CRYPT_SUCCESS);
258     ctx->method->freeCtx(ctx->data);
259     BSL_SAL_FREE(ctx->method);
260     BSL_SAL_FREE(ctx);
261     return;
262 }
263 
264 #endif
265