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