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 #ifdef HITLS_CRYPTO_DRBG
18
19 #include <stdlib.h>
20 #include <stdbool.h>
21 #include <securec.h>
22 #include "crypt_types.h"
23 #include "crypt_errno.h"
24 #include "crypt_utils.h"
25 #include "crypt_ealinit.h"
26 #include "eal_entropy.h"
27 #include "bsl_err_internal.h"
28 #include "drbg_local.h"
29 #include "crypt_drbg_local.h"
30 #include "bsl_params.h"
31 #include "crypt_params_key.h"
32
33 #define DRBG_NONCE_FROM_ENTROPY (2)
34
35 // According to the definition of DRBG_Ctx, ctx->seedMeth is not NULL
DRBG_CleanEntropy(DRBG_Ctx * ctx,CRYPT_Data * entropy)36 static void DRBG_CleanEntropy(DRBG_Ctx *ctx, CRYPT_Data *entropy)
37 {
38 CRYPT_RandSeedMethod *seedMeth = NULL;
39
40 if (ctx == NULL || CRYPT_IsDataNull(entropy)) {
41 return;
42 }
43
44 seedMeth = &ctx->seedMeth;
45
46 if (seedMeth->cleanEntropy != NULL) {
47 seedMeth->cleanEntropy(ctx->seedCtx, entropy);
48 }
49
50 entropy->data = NULL;
51 entropy->len = 0;
52
53 return;
54 }
55
56 // According to the definition of DRBG_Ctx, ctx->seedMeth is not NULL
DRBG_GetEntropy(DRBG_Ctx * ctx,CRYPT_Data * entropy,bool addEntropy)57 static int32_t DRBG_GetEntropy(DRBG_Ctx *ctx, CRYPT_Data *entropy, bool addEntropy)
58 {
59 int32_t ret;
60 CRYPT_RandSeedMethod *seedMeth = NULL;
61 CRYPT_Range entropyRange = ctx->entropyRange;
62 uint32_t strength = ctx->strength;
63
64 seedMeth = &ctx->seedMeth;
65
66 if (addEntropy) {
67 strength += strength / DRBG_NONCE_FROM_ENTROPY;
68 entropyRange.min += ctx->nonceRange.min;
69 entropyRange.max += ctx->nonceRange.max;
70 }
71
72 if (seedMeth->getEntropy == NULL) {
73 BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_ENTROPY);
74 return CRYPT_DRBG_FAIL_GET_ENTROPY;
75 }
76
77 // CPRNG is implemented by hooks, in DRBG, the CPRNG is not verified,
78 // but only the entropy source pointer and its length are verified.
79 ret = seedMeth->getEntropy(ctx->seedCtx, entropy, strength, &entropyRange);
80 if (ret != CRYPT_SUCCESS) {
81 BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_ENTROPY);
82 return CRYPT_DRBG_FAIL_GET_ENTROPY;
83 }
84
85 if (CRYPT_CHECK_DATA_INVALID(entropy)) {
86 goto ERR;
87 }
88
89 if (!CRYPT_IN_RANGE(entropy->len, &entropyRange)) {
90 goto ERR;
91 }
92 return CRYPT_SUCCESS;
93
94 ERR:
95 DRBG_CleanEntropy(ctx, entropy);
96 BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_ENTROPY);
97 return CRYPT_DRBG_FAIL_GET_ENTROPY;
98 }
99
100 // According to the definition of DRBG_Ctx, ctx->seedMeth is not NULL
DRBG_CleanNonce(DRBG_Ctx * ctx,CRYPT_Data * nonce)101 static void DRBG_CleanNonce(DRBG_Ctx *ctx, CRYPT_Data *nonce)
102 {
103 CRYPT_RandSeedMethod *seedMeth = NULL;
104
105 if (ctx == NULL || CRYPT_IsDataNull(nonce)) {
106 return;
107 }
108
109 seedMeth = &ctx->seedMeth;
110
111 if (seedMeth->cleanNonce != NULL) {
112 seedMeth->cleanNonce(ctx->seedCtx, nonce);
113 }
114 nonce->data = NULL;
115 nonce->len = 0;
116 return;
117 }
118
119 // According to the definition of DRBG_Ctx, ctx->seedMeth is not NULL
DRBG_GetNonce(DRBG_Ctx * ctx,CRYPT_Data * nonce,bool * addEntropy)120 static int32_t DRBG_GetNonce(DRBG_Ctx *ctx, CRYPT_Data *nonce, bool *addEntropy)
121 {
122 int32_t ret;
123 CRYPT_RandSeedMethod *seedMeth = NULL;
124
125 seedMeth = &ctx->seedMeth;
126
127 // Allowed nonce which entered by the user can be NULL.
128 // In this case, set *addEntropy to true to obtain the nonce from the entropy.
129 if (seedMeth->getNonce == NULL || ctx->nonceRange.max == 0) {
130 if (ctx->nonceRange.min > 0) {
131 *addEntropy = true;
132 }
133 return CRYPT_SUCCESS;
134 }
135
136 ret = seedMeth->getNonce(ctx->seedCtx, nonce, ctx->strength, &ctx->nonceRange);
137 if (ret != CRYPT_SUCCESS) {
138 BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_NONCE);
139 return CRYPT_DRBG_FAIL_GET_NONCE;
140 }
141
142 if (CRYPT_CHECK_DATA_INVALID(nonce)) {
143 goto ERR;
144 }
145
146 if (!CRYPT_IN_RANGE(nonce->len, &ctx->nonceRange)) {
147 goto ERR;
148 }
149
150 return CRYPT_SUCCESS;
151
152 ERR:
153 DRBG_CleanNonce(ctx, nonce);
154 BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_NONCE);
155 return CRYPT_DRBG_FAIL_GET_NONCE;
156 }
157
158 #ifdef HITLS_CRYPTO_DRBG_CTR
159 #define RAND_AES128_KEYLEN 16
160 #define RAND_AES192_KEYLEN 24
161 #define RAND_AES256_KEYLEN 32
162 #define RAND_SM4_KEYLEN 16
163
GetCipherKeyLen(int32_t id,uint32_t * keyLen)164 static int32_t GetCipherKeyLen(int32_t id, uint32_t *keyLen)
165 {
166 switch (id) {
167 case CRYPT_CIPHER_AES128_CTR:
168 *keyLen = RAND_AES128_KEYLEN;
169 break;
170 case CRYPT_CIPHER_AES192_CTR:
171 *keyLen = RAND_AES192_KEYLEN;
172 break;
173 case CRYPT_CIPHER_AES256_CTR:
174 *keyLen = RAND_AES256_KEYLEN;
175 break;
176 case CRYPT_CIPHER_SM4_CTR:
177 *keyLen = RAND_SM4_KEYLEN;
178 break;
179 default:
180 BSL_ERR_PUSH_ERROR(CRYPT_DRBG_ALG_NOT_SUPPORT);
181 return CRYPT_DRBG_ALG_NOT_SUPPORT;
182 }
183 return CRYPT_SUCCESS;
184 }
185 #endif
186
DRBG_Restart(DRBG_Ctx * ctx)187 static int32_t DRBG_Restart(DRBG_Ctx *ctx)
188 {
189 if (ctx->state == DRBG_STATE_ERROR) {
190 (void)DRBG_Uninstantiate(ctx);
191 }
192 if (ctx->state == DRBG_STATE_UNINITIALISED) {
193 int32_t ret = DRBG_Instantiate(ctx, NULL, 0, NULL);
194 if (ret != CRYPT_SUCCESS) {
195 BSL_ERR_PUSH_ERROR(ret);
196 return ret;
197 }
198 }
199 return CRYPT_SUCCESS;
200 }
201
DRBG_New(int32_t algId,BSL_Param * param)202 DRBG_Ctx *DRBG_New(int32_t algId, BSL_Param *param)
203 {
204 int32_t ret;
205
206 CRYPT_RandSeedMethod seedMethArray = {0};
207 CRYPT_RandSeedMethod *seedMeth = &seedMethArray;
208 void *seedCtx = NULL;
209
210 const BSL_Param *temp = NULL;
211 if ((temp = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_RAND_SEED_GETENTROPY)) != NULL) {
212 GOTO_ERR_IF(BSL_PARAM_GetPtrValue(temp, CRYPT_PARAM_RAND_SEED_GETENTROPY, BSL_PARAM_TYPE_FUNC_PTR,
213 (void **)&(seedMethArray.getEntropy), NULL), ret);
214 }
215 if ((temp = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_RAND_SEED_CLEANENTROPY)) != NULL) {
216 GOTO_ERR_IF(BSL_PARAM_GetPtrValue(temp, CRYPT_PARAM_RAND_SEED_CLEANENTROPY, BSL_PARAM_TYPE_FUNC_PTR,
217 (void **)&(seedMethArray.cleanEntropy), NULL), ret);
218 }
219 if ((temp = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_RAND_SEED_GETNONCE)) != NULL) {
220 GOTO_ERR_IF(BSL_PARAM_GetPtrValue(temp, CRYPT_PARAM_RAND_SEED_GETNONCE, BSL_PARAM_TYPE_FUNC_PTR,
221 (void **)&(seedMethArray.getNonce), NULL), ret);
222 }
223 if ((temp = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_RAND_SEED_CLEANNONCE)) != NULL) {
224 GOTO_ERR_IF(BSL_PARAM_GetPtrValue(temp, CRYPT_PARAM_RAND_SEED_CLEANNONCE, BSL_PARAM_TYPE_FUNC_PTR,
225 (void **)&(seedMethArray.cleanNonce), NULL), ret);
226 }
227
228 if ((temp = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_RAND_SEEDCTX)) != NULL) {
229 GOTO_ERR_IF(BSL_PARAM_GetPtrValue(temp, CRYPT_PARAM_RAND_SEEDCTX, BSL_PARAM_TYPE_CTX_PTR, &seedCtx, NULL), ret);
230 }
231
232 DRBG_Ctx *drbg = NULL;
233 EAL_RandMethLookup lu = { 0 };
234 if (EAL_RandFindMethod(algId, &lu) != CRYPT_SUCCESS) {
235 return NULL;
236 }
237 switch (lu.type) {
238 #ifdef HITLS_CRYPTO_DRBG_HASH
239 case RAND_TYPE_MD:
240 drbg = DRBG_NewHashCtx((const EAL_MdMethod *)(lu.method), algId == CRYPT_RAND_SM3, seedMeth, seedCtx);
241 break;
242 #endif
243 #ifdef HITLS_CRYPTO_DRBG_HMAC
244 case RAND_TYPE_MAC:
245 drbg = DRBG_NewHmacCtx((const EAL_MacMethod *)(lu.method), lu.methodId, seedMeth, seedCtx);
246 break;
247 #endif
248 #ifdef HITLS_CRYPTO_DRBG_CTR
249 case RAND_TYPE_SM4_DF:
250 case RAND_TYPE_AES:
251 case RAND_TYPE_AES_DF: {
252 bool isUsedDF = (lu.type == RAND_TYPE_AES_DF || lu.type == RAND_TYPE_SM4_DF) ? true : false;
253 uint32_t keyLen;
254 if (GetCipherKeyLen(lu.methodId, &keyLen) != CRYPT_SUCCESS) {
255 return NULL;
256 }
257 drbg = DRBG_NewCtrCtx((const EAL_SymMethod *)(lu.method), keyLen, algId == CRYPT_RAND_SM4_CTR_DF, isUsedDF,
258 seedMeth, seedCtx);
259 break;
260 }
261 #endif
262 default:
263 BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID);
264 return NULL;
265 }
266 return drbg;
267
268 ERR:
269 return NULL;
270 }
271
DRBG_Free(DRBG_Ctx * ctx)272 void DRBG_Free(DRBG_Ctx *ctx)
273 {
274 if (ctx == NULL || ctx->meth == NULL || ctx->meth->free == NULL) {
275 return;
276 }
277
278 void (*ctxFree)(DRBG_Ctx *ctx) = ctx->meth->free;
279
280 DRBG_Uninstantiate(ctx);
281 ctxFree(ctx);
282
283 return;
284 }
285
DRBG_Instantiate(DRBG_Ctx * ctx,const uint8_t * person,uint32_t persLen,BSL_Param * param)286 int32_t DRBG_Instantiate(DRBG_Ctx *ctx, const uint8_t *person, uint32_t persLen, BSL_Param *param)
287 {
288 (void) param;
289 int32_t ret;
290 CRYPT_Data entropy = {NULL, 0};
291 CRYPT_Data nonce = {NULL, 0};
292 CRYPT_Data pers = {(uint8_t *)(uintptr_t)person, persLen};
293 bool addEntropy = false;
294
295 if (ctx == NULL) {
296 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
297 return CRYPT_NULL_INPUT;
298 }
299
300 if (CRYPT_CHECK_DATA_INVALID(&pers)) {
301 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
302 return CRYPT_NULL_INPUT;
303 }
304
305 if (persLen > ctx->maxPersLen) {
306 BSL_ERR_PUSH_ERROR(CRYPT_DRBG_INVALID_LEN);
307 return CRYPT_DRBG_INVALID_LEN;
308 }
309
310 if (ctx->state != DRBG_STATE_UNINITIALISED) {
311 BSL_ERR_PUSH_ERROR(CRYPT_DRBG_ERR_STATE);
312 return CRYPT_DRBG_ERR_STATE;
313 }
314
315 ctx->state = DRBG_STATE_ERROR;
316
317 ret = DRBG_GetNonce(ctx, &nonce, &addEntropy);
318 if (ret != CRYPT_SUCCESS) {
319 goto ERR_NONCE;
320 }
321
322 ret = DRBG_GetEntropy(ctx, &entropy, addEntropy);
323 if (ret != CRYPT_SUCCESS) {
324 goto ERR_ENTROPY;
325 }
326
327 ret = ctx->meth->instantiate(ctx, &entropy, &nonce, &pers);
328 if (ret != CRYPT_SUCCESS) {
329 BSL_ERR_PUSH_ERROR(ret);
330 goto ERR_ENTROPY;
331 }
332
333 ctx->state = DRBG_STATE_READY;
334 ctx->reseedCtr = 1;
335 #if defined(HITLS_CRYPTO_DRBG_GM)
336 if (ctx->reseedIntervalTime != 0) {
337 ctx->lastReseedTime = BSL_SAL_CurrentSysTimeGet();
338 }
339 #endif
340 ERR_ENTROPY:
341 DRBG_CleanEntropy(ctx, &entropy);
342 ERR_NONCE:
343 DRBG_CleanNonce(ctx, &nonce);
344
345 return ret;
346 }
347
DRBG_IsNeedReseed(const DRBG_Ctx * ctx,bool pr)348 static inline bool DRBG_IsNeedReseed(const DRBG_Ctx *ctx, bool pr)
349 {
350 if (pr) {
351 return true;
352 }
353
354 if (ctx->reseedCtr > ctx->reseedInterval) {
355 return true;
356 }
357 #if defined(HITLS_CRYPTO_DRBG_GM)
358 if (ctx->reseedIntervalTime != 0) {
359 int64_t time = BSL_SAL_CurrentSysTimeGet();
360 return ((time - ctx->lastReseedTime) > ctx->reseedIntervalTime) ? true : false;
361 }
362 #endif
363 return false;
364 }
365
DRBG_Reseed(DRBG_Ctx * ctx,const uint8_t * adin,uint32_t adinLen,BSL_Param * param)366 int32_t DRBG_Reseed(DRBG_Ctx *ctx, const uint8_t *adin, uint32_t adinLen, BSL_Param *param)
367 {
368 (void) param;
369 int32_t ret;
370 CRYPT_Data entropy = {NULL, 0};
371 CRYPT_Data adinData = {(uint8_t*)(uintptr_t)adin, adinLen};
372
373 if (ctx == NULL) {
374 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
375 return CRYPT_NULL_INPUT;
376 }
377
378 if (CRYPT_CHECK_BUF_INVALID(adin, adinLen)) {
379 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
380 return CRYPT_NULL_INPUT;
381 }
382
383 if (adinLen > ctx->maxAdinLen) {
384 BSL_ERR_PUSH_ERROR(CRYPT_DRBG_INVALID_LEN);
385 return CRYPT_DRBG_INVALID_LEN;
386 }
387
388 if (ctx->state != DRBG_STATE_READY) {
389 if (DRBG_Restart(ctx) != CRYPT_SUCCESS) {
390 return CRYPT_DRBG_ERR_STATE;
391 }
392 }
393
394 ctx->state = DRBG_STATE_ERROR;
395
396 ret = DRBG_GetEntropy(ctx, &entropy, false);
397 if (ret != CRYPT_SUCCESS) {
398 BSL_ERR_PUSH_ERROR(ret);
399 goto ERR;
400 }
401
402 ret = ctx->meth->reseed(ctx, &entropy, &adinData);
403 if (ret != CRYPT_SUCCESS) {
404 BSL_ERR_PUSH_ERROR(ret);
405 goto ERR;
406 }
407
408 ctx->reseedCtr = 1;
409 #if defined(HITLS_CRYPTO_DRBG_GM)
410 if (ctx->reseedIntervalTime != 0) {
411 ctx->lastReseedTime = BSL_SAL_CurrentSysTimeGet();
412 }
413 #endif
414 ctx->state = DRBG_STATE_READY;
415
416 ERR:
417 DRBG_CleanEntropy(ctx, &entropy);
418
419 return ret;
420 }
421
DRBG_Generate(DRBG_Ctx * ctx,uint8_t * out,uint32_t outLen,const uint8_t * adin,uint32_t adinLen,bool pr)422 int32_t DRBG_Generate(DRBG_Ctx *ctx, uint8_t *out, uint32_t outLen,
423 const uint8_t *adin, uint32_t adinLen, bool pr)
424 {
425 int32_t ret;
426 CRYPT_Data adinData = {(uint8_t*)(uintptr_t)adin, adinLen};
427 if (CRYPT_CHECK_BUF_INVALID(adin, adinLen)) {
428 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
429 return CRYPT_NULL_INPUT;
430 }
431
432 if (outLen > ctx->maxRequest || adinLen > ctx->maxAdinLen) {
433 BSL_ERR_PUSH_ERROR(CRYPT_DRBG_INVALID_LEN);
434 return CRYPT_DRBG_INVALID_LEN;
435 }
436
437 if (ctx->state != DRBG_STATE_READY) {
438 if (DRBG_Restart(ctx) != CRYPT_SUCCESS) {
439 return CRYPT_DRBG_ERR_STATE;
440 }
441 }
442
443 if (DRBG_IsNeedReseed(ctx, pr)) {
444 ret = DRBG_Reseed(ctx, adin, adinLen, NULL);
445 if (ret != CRYPT_SUCCESS) {
446 BSL_ERR_PUSH_ERROR(ret);
447 return ret;
448 }
449 adinData.data = NULL;
450 adinData.len = 0;
451 }
452
453 ret = ctx->meth->generate(ctx, out, outLen, &adinData);
454 if (ret != CRYPT_SUCCESS) {
455 BSL_ERR_PUSH_ERROR(ret);
456 return ret;
457 }
458
459 ctx->reseedCtr++;
460
461 return ret;
462 }
463
DRBG_GenerateBytes(DRBG_Ctx * ctx,uint8_t * out,uint32_t outLen,const uint8_t * adin,uint32_t adinLen,BSL_Param * param)464 int32_t DRBG_GenerateBytes(DRBG_Ctx *ctx, uint8_t *out, uint32_t outLen,
465 const uint8_t *adin, uint32_t adinLen, BSL_Param *param)
466 {
467 if (ctx == NULL || out == NULL) {
468 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
469 return CRYPT_NULL_INPUT;
470 }
471 int32_t ret;
472 bool pr = false;
473 const BSL_Param *temp = NULL;
474 if ((temp = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_RAND_PR)) != NULL) {
475 uint32_t boolSize = sizeof(bool);
476 ret = BSL_PARAM_GetValue(temp, CRYPT_PARAM_RAND_PR, BSL_PARAM_TYPE_BOOL, (void *)&pr, &boolSize);
477 if (ret != CRYPT_SUCCESS) {
478 BSL_ERR_PUSH_ERROR(ret);
479 return ret;
480 }
481 }
482 uint32_t block = ctx->maxRequest;
483 if (block == 0) {
484 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
485 return CRYPT_INVALID_ARG;
486 }
487 for (uint32_t leftLen = outLen; leftLen > 0; leftLen -= block, out += block) {
488 block = leftLen > block ? block : leftLen;
489 ret = DRBG_Generate(ctx, out, block, adin, adinLen, pr);
490 if (ret != CRYPT_SUCCESS) {
491 BSL_ERR_PUSH_ERROR(ret);
492 return ret;
493 }
494 }
495 return CRYPT_SUCCESS;
496 }
497
DRBG_Uninstantiate(DRBG_Ctx * ctx)498 int32_t DRBG_Uninstantiate(DRBG_Ctx *ctx)
499 {
500 if (ctx == NULL) {
501 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
502 return CRYPT_NULL_INPUT;
503 }
504
505 ctx->meth->uninstantiate(ctx);
506
507 ctx->reseedCtr = 0;
508 ctx->state = DRBG_STATE_UNINITIALISED;
509
510 return CRYPT_SUCCESS;
511 }
512
513 #if defined(HITLS_CRYPTO_DRBG_GM)
DRBG_SetGmlevel(DRBG_Ctx * ctx,const void * val,uint32_t len)514 static int32_t DRBG_SetGmlevel(DRBG_Ctx *ctx, const void *val, uint32_t len)
515 {
516 if (val == NULL || len != sizeof(uint32_t)) {
517 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
518 return CRYPT_INVALID_ARG;
519 }
520 if (*(const uint32_t *)val == 1) {
521 ctx->reseedInterval = DRBG_RESEED_INTERVAL_GM1;
522 ctx->reseedIntervalTime = DRBG_RESEED_TIME_GM1;
523 } else {
524 ctx->reseedInterval = DRBG_RESEED_INTERVAL_GM2;
525 ctx->reseedIntervalTime = DRBG_RESEED_TIME_GM2;
526 }
527 return CRYPT_SUCCESS;
528 }
529
DRBG_SetReseedIntervalTime(DRBG_Ctx * ctx,const void * val,uint32_t len)530 static int32_t DRBG_SetReseedIntervalTime(DRBG_Ctx *ctx, const void *val, uint32_t len)
531 {
532 if (val == NULL || len != sizeof(uint64_t)) {
533 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
534 return CRYPT_INVALID_ARG;
535 }
536 ctx->reseedIntervalTime = *(const uint64_t *)val;
537 return CRYPT_SUCCESS;
538 }
539 #endif // HITLS_CRYPTO_DRBG_GM
540
DRBG_SetReseedInterval(DRBG_Ctx * ctx,const void * val,uint32_t len)541 static int32_t DRBG_SetReseedInterval(DRBG_Ctx *ctx, const void *val, uint32_t len)
542 {
543 if (val == NULL || len != sizeof(uint32_t)) {
544 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
545 return CRYPT_INVALID_ARG;
546 }
547 ctx->reseedInterval = *(const uint32_t *)val;
548 return CRYPT_SUCCESS;
549 }
550
DRBG_Ctrl(DRBG_Ctx * ctx,int32_t opt,void * val,uint32_t len)551 int32_t DRBG_Ctrl(DRBG_Ctx *ctx, int32_t opt, void *val, uint32_t len)
552 {
553 if (ctx == NULL) {
554 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
555 return CRYPT_NULL_INPUT;
556 }
557 switch (opt) {
558 #if defined(HITLS_CRYPTO_DRBG_GM)
559 case CRYPT_CTRL_SET_GM_LEVEL:
560 return DRBG_SetGmlevel(ctx, val, len);
561 case CRYPT_CTRL_SET_RESEED_TIME:
562 return DRBG_SetReseedIntervalTime(ctx, val, len);
563 #endif // HITLS_CRYPTO_DRBG_GM
564 case CRYPT_CTRL_SET_RESEED_INTERVAL:
565 return DRBG_SetReseedInterval(ctx, val, len);
566 default:
567 break;
568 }
569 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
570 return CRYPT_INVALID_ARG;
571 }
572
573 static const DrbgIdMap DRBG_METHOD_MAP[] = {
574 #if defined(HITLS_CRYPTO_DRBG_HASH)
575 { CRYPT_RAND_SHA1, CRYPT_MD_SHA1, RAND_TYPE_MD },
576 { CRYPT_RAND_SHA224, CRYPT_MD_SHA224, RAND_TYPE_MD },
577 { CRYPT_RAND_SHA256, CRYPT_MD_SHA256, RAND_TYPE_MD },
578 { CRYPT_RAND_SHA384, CRYPT_MD_SHA384, RAND_TYPE_MD },
579 { CRYPT_RAND_SHA512, CRYPT_MD_SHA512, RAND_TYPE_MD },
580 #ifdef HITLS_CRYPTO_DRBG_GM
581 { CRYPT_RAND_SM3, CRYPT_MD_SM3, RAND_TYPE_MD },
582 #endif
583 #endif
584 #if defined(HITLS_CRYPTO_DRBG_HMAC)
585 { CRYPT_RAND_HMAC_SHA1, CRYPT_MAC_HMAC_SHA1, RAND_TYPE_MAC },
586 { CRYPT_RAND_HMAC_SHA224, CRYPT_MAC_HMAC_SHA224, RAND_TYPE_MAC },
587 { CRYPT_RAND_HMAC_SHA256, CRYPT_MAC_HMAC_SHA256, RAND_TYPE_MAC },
588 { CRYPT_RAND_HMAC_SHA384, CRYPT_MAC_HMAC_SHA384, RAND_TYPE_MAC },
589 { CRYPT_RAND_HMAC_SHA512, CRYPT_MAC_HMAC_SHA512, RAND_TYPE_MAC },
590 #endif
591 #if defined(HITLS_CRYPTO_DRBG_CTR)
592 { CRYPT_RAND_AES128_CTR, CRYPT_CIPHER_AES128_CTR, RAND_TYPE_AES },
593 { CRYPT_RAND_AES192_CTR, CRYPT_CIPHER_AES192_CTR, RAND_TYPE_AES },
594 { CRYPT_RAND_AES256_CTR, CRYPT_CIPHER_AES256_CTR, RAND_TYPE_AES },
595 { CRYPT_RAND_AES128_CTR_DF, CRYPT_CIPHER_AES128_CTR, RAND_TYPE_AES_DF },
596 { CRYPT_RAND_AES192_CTR_DF, CRYPT_CIPHER_AES192_CTR, RAND_TYPE_AES_DF },
597 { CRYPT_RAND_AES256_CTR_DF, CRYPT_CIPHER_AES256_CTR, RAND_TYPE_AES_DF },
598 #ifdef HITLS_CRYPTO_DRBG_GM
599 { CRYPT_RAND_SM4_CTR_DF, CRYPT_CIPHER_SM4_CTR, RAND_TYPE_SM4_DF }
600 #endif
601 #endif
602 };
603
DRBG_GetIdMap(CRYPT_RAND_AlgId id)604 const DrbgIdMap *DRBG_GetIdMap(CRYPT_RAND_AlgId id)
605 {
606 uint32_t num = sizeof(DRBG_METHOD_MAP) / sizeof(DRBG_METHOD_MAP[0]);
607 for (uint32_t i = 0; i < num; i++) {
608 if (DRBG_METHOD_MAP[i].drbgId == id) {
609 return &DRBG_METHOD_MAP[i];
610 }
611 }
612 return NULL;
613 }
614
615 #endif /* HITLS_CRYPTO_DRBG */
616