• 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 #ifdef HITLS_CRYPTO_DRBG_HASH
18 
19 #include <stdlib.h>
20 #include <securec.h>
21 #include "crypt_errno.h"
22 #include "crypt_local_types.h"
23 #include "crypt_utils.h"
24 #include "bsl_sal.h"
25 #include "crypt_types.h"
26 #include "bsl_err_internal.h"
27 #include "drbg_local.h"
28 
29 #define DRBG_HASH_MAX_SEEDLEN  (111)
30 
31 typedef enum {
32     DRBG_SHA1MDSIZE = 20,
33     DRBG_SHA224MDSIZE = 28,
34     DRBG_SHA256MDSIZE = 32,
35     DRBG_SHA384MDSIZE = 48,
36     DRBG_SHA512MDSIZE = 64,
37     DRBG_SM3MDSIZE = 32,
38 } DRBG_MdSize;
39 
40 typedef struct {
41     uint8_t v[DRBG_HASH_MAX_SEEDLEN];
42     uint8_t c[DRBG_HASH_MAX_SEEDLEN];
43     uint32_t seedLen;
44     const EAL_MdMethod *md;
45     void *mdCtx;
46 } DRBG_HashCtx;
47 
48 // This function performs the ctx->V += xxx operation.
DRBG_HashAddV(uint8_t * v,uint32_t vLen,uint8_t * src,uint32_t srcLen)49 static void DRBG_HashAddV(uint8_t *v, uint32_t vLen, uint8_t *src, uint32_t srcLen)
50 {
51     uint8_t *d = v + vLen - 1;
52     uint8_t *s = src + srcLen - 1;
53     uint8_t c = 0;
54     uint32_t r;
55 
56     while (s >= src) {
57         r = (uint32_t)(*d) + (*s) + c;
58         *d = (uint8_t)(r & 0xff);
59         c = (r > 0xff) ? 1 : 0;
60         d--;
61         s--;
62     }
63 
64     while (d >= v && c > 0) {
65         r = (uint32_t)(*d) + c;
66         *d = (uint8_t)(r & 0xff);
67         c = (r > 0xff) ? 1 : 0;
68         d--;
69     }
70     return;
71 }
72 
DRBG_UpdateDataInHashDf(DRBG_HashCtx * ctx,const CRYPT_Data * in1,const CRYPT_Data * in2,const CRYPT_Data * in3,const CRYPT_Data * in4)73 static int32_t DRBG_UpdateDataInHashDf(DRBG_HashCtx *ctx,
74                                        const CRYPT_Data *in1, const CRYPT_Data *in2,
75                                        const CRYPT_Data *in3, const CRYPT_Data *in4)
76 {
77     const EAL_MdMethod *meth = ctx->md;
78     void *mdCtx = ctx->mdCtx;
79     int32_t ret = CRYPT_SUCCESS;
80 
81     if (!CRYPT_IsDataNull(in1)) {
82         ret = meth->update(mdCtx, in1->data, in1->len);
83         if (ret != CRYPT_SUCCESS) {
84             BSL_ERR_PUSH_ERROR(ret);
85             return ret;
86         }
87     }
88 
89     if (!CRYPT_IsDataNull(in2)) {
90         ret = meth->update(mdCtx, in2->data, in2->len);
91         if (ret != CRYPT_SUCCESS) {
92             BSL_ERR_PUSH_ERROR(ret);
93             return ret;
94         }
95     }
96 
97     if (!CRYPT_IsDataNull(in3)) {
98         ret = meth->update(mdCtx, in3->data, in3->len);
99         if (ret != CRYPT_SUCCESS) {
100             BSL_ERR_PUSH_ERROR(ret);
101             return ret;
102         }
103     }
104 
105     if (!CRYPT_IsDataNull(in4)) {
106         ret = meth->update(mdCtx, in4->data, in4->len);
107         if (ret != CRYPT_SUCCESS) {
108             BSL_ERR_PUSH_ERROR(ret);
109         }
110     }
111 
112     return ret;
113 }
114 
DRBG_HashDfValuesAssig(uint8_t values[5],uint32_t len)115 static void DRBG_HashDfValuesAssig(uint8_t values[5], uint32_t len)
116 {
117     // The value of values is the same as that of counter || no_of_bits_to_return in Hash_df Process
118     // in section 10.3.1 in NIST 800-90a.
119     values[0] = 0x1;
120     // len is shifted leftward by 3, then byte-to-bit. Shift rightwards by 24 bits to get the highest 8 bits.
121     values[1] = (uint8_t)(((len << 3) >> 24) & 0xff);
122     // 2nd, len is shifted leftward by 3, then byte-to-bit. Shift rightwards by 16 bits to get the second 8 bits.
123     values[2] = (uint8_t)(((len << 3) >> 16) & 0xff);
124     // 3rd, len is shifted leftward by 3, then byte-to-bit. Shift rightwards by 8 bits to get the third 8 bits.
125     values[3] = (uint8_t)(((len << 3) >> 8) & 0xff);
126     values[4] = (uint8_t)((len << 3) & 0xff);           // 4th, len is shifted leftward by 3, then byte-to-bit.
127 }
128 
DRBG_HashDf(DRBG_HashCtx * ctx,uint8_t * out,uint32_t outLen,const CRYPT_Data * in1,const CRYPT_Data * in2,const CRYPT_Data * in3,const CRYPT_Data * in4)129 static int32_t DRBG_HashDf(DRBG_HashCtx *ctx, uint8_t *out, uint32_t outLen,  const CRYPT_Data *in1,
130     const CRYPT_Data *in2, const CRYPT_Data *in3, const CRYPT_Data *in4)
131 {
132     const EAL_MdMethod *meth = ctx->md;
133     void *mdCtx = ctx->mdCtx;
134     uint32_t mdSize = meth->mdSize;
135     uint8_t *buf = out;
136     uint32_t len = outLen;
137     int32_t ret;
138     // The temp is the same as that of counter || no_of_bits_to_return in Hash_df Process
139     // in section 10.3.1 in NIST 800-90a.
140     uint8_t temp[5];
141     // len = floor(no_of_bits_to_return / outlen)
142     DRBG_HashDfValuesAssig(temp, len);
143 
144     do {
145         // temp = temp || Hash (counter || no_of_bits_to_return || input_string).
146         if ((ret = meth->init(mdCtx, NULL)) != CRYPT_SUCCESS) {
147             BSL_ERR_PUSH_ERROR(ret);
148             return ret;
149         }
150 
151         // 5 indicates the maximum length of temp. For details, see the temp statement.
152         if ((ret = meth->update(mdCtx, temp, 5)) != CRYPT_SUCCESS) {
153             BSL_ERR_PUSH_ERROR(ret);
154             goto EXIT;
155         }
156 
157         if ((ret = DRBG_UpdateDataInHashDf(ctx, in1, in2, in3, in4)) != CRYPT_SUCCESS) {
158             BSL_ERR_PUSH_ERROR(ret);
159             goto EXIT;
160         }
161 
162         uint8_t tmpOut[DRBG_HASH_MAX_MDSIZE];
163         uint32_t tmpOutLen = DRBG_HASH_MAX_MDSIZE;
164         if (len < mdSize) {
165             if ((ret = meth->final(mdCtx, tmpOut, &tmpOutLen)) != CRYPT_SUCCESS) {
166                 BSL_ERR_PUSH_ERROR(ret);
167                 goto EXIT;
168             }
169             // tmpOutLen is the maximum supported MD length,
170             // and len is the actual length, which must be smaller than tmpOutLen.
171             // Only the len length needs to be truncated as the output.
172             (void)memcpy_s(buf, len, tmpOut, len);
173             break;
174         }
175         if ((ret = meth->final(mdCtx, buf, &tmpOutLen)) != CRYPT_SUCCESS) {
176             BSL_ERR_PUSH_ERROR(ret);
177             goto EXIT;
178         }
179 
180         buf += mdSize;
181         len -= mdSize;
182         temp[0]++;
183     } while (len > 0);
184 
185 EXIT:
186     meth->deinit(mdCtx);
187     return ret;
188 }
189 
DRBG_Hashgen(DRBG_HashCtx * ctx,uint8_t * out,uint32_t outLen)190 static int32_t DRBG_Hashgen(DRBG_HashCtx *ctx, uint8_t *out, uint32_t outLen)
191 {
192     uint8_t data[DRBG_HASH_MAX_SEEDLEN];
193     const EAL_MdMethod *md = ctx->md;
194     void *mdCtx = ctx->mdCtx;
195     int32_t ret = CRYPT_SUCCESS;
196     uint32_t mdSize = md->mdSize;
197     uint32_t tmpLen = mdSize;
198     uint32_t len = outLen;
199     uint8_t *buf = out;
200 
201     // The length of the V array is the longest seedLen. Therefore, there is no failure.
202     (void)memcpy_s(data, sizeof(data), ctx->v, ctx->seedLen);
203 
204     while (len > 0) {
205         uint8_t n = 1;
206         if ((ret = md->init(mdCtx, NULL)) != CRYPT_SUCCESS) {
207             BSL_ERR_PUSH_ERROR(ret);
208             return ret;
209         }
210 
211         if ((ret = md->update(mdCtx, data, ctx->seedLen)) != CRYPT_SUCCESS) {
212             BSL_ERR_PUSH_ERROR(ret);
213             goto EXIT;
214         }
215 
216         if (len >= mdSize) {
217             if ((ret = md->final(mdCtx, buf, &tmpLen)) != CRYPT_SUCCESS) {
218                 BSL_ERR_PUSH_ERROR(ret);
219                 goto EXIT;
220             }
221         } else {
222             uint8_t temp[DRBG_HASH_MAX_SEEDLEN];
223             uint32_t tempLen = DRBG_HASH_MAX_SEEDLEN;
224             if ((ret = md->final(mdCtx, temp, &tempLen)) != CRYPT_SUCCESS) {
225                 BSL_ERR_PUSH_ERROR(ret);
226                 goto EXIT;
227             }
228 
229             (void)memcpy_s(buf, len, temp, len);
230             break;
231         }
232         buf += mdSize;
233         len -= mdSize;
234 
235         DRBG_HashAddV(data, ctx->seedLen, &n, 1);
236     }
237 
238 EXIT:
239     // Clear MD data.
240     md->deinit(mdCtx);
241     return ret;
242 }
243 
DRBG_HashInstantiate(DRBG_Ctx * drbg,const CRYPT_Data * entropy,const CRYPT_Data * nonce,const CRYPT_Data * pers)244 int32_t DRBG_HashInstantiate(DRBG_Ctx *drbg, const CRYPT_Data *entropy,
245                              const CRYPT_Data *nonce, const CRYPT_Data *pers)
246 {
247     DRBG_HashCtx *ctx = (DRBG_HashCtx*)drbg->ctx;
248     CRYPT_Data seed = {ctx->v, (uint32_t)(ctx->seedLen)};
249     int32_t ret;
250     uint8_t c = 0;
251     CRYPT_Data temp = {&c, 1};
252 
253     /**
254     1. seed_material = entropy || nonce || pers
255     2. seed = Hash_df(seed_material)
256     3. V = seed
257     4. C = Hash_df(0x00 || V)
258     */
259     ret = DRBG_HashDf(ctx, ctx->v, ctx->seedLen, entropy, nonce, pers, NULL);
260     if (ret != CRYPT_SUCCESS) {
261         BSL_ERR_PUSH_ERROR(ret);
262         return ret;
263     }
264 
265     ret = DRBG_HashDf(ctx, ctx->c, ctx->seedLen, &temp, &seed, NULL, NULL);
266     if (ret != CRYPT_SUCCESS) {
267         BSL_ERR_PUSH_ERROR(ret);
268     }
269     return ret;
270 }
271 
DRBG_HashAdinInHashGenerate(DRBG_HashCtx * ctx,const CRYPT_Data * adin)272 static int32_t DRBG_HashAdinInHashGenerate(DRBG_HashCtx *ctx, const CRYPT_Data *adin)
273 {
274     void *mdCtx = ctx->mdCtx;
275     const EAL_MdMethod *md = ctx->md;
276     uint32_t mdSize = md->mdSize;
277     int32_t ret;
278     uint8_t temp = 0x2;
279     uint8_t w[DRBG_HASH_MAX_MDSIZE];
280     uint32_t wLen = DRBG_HASH_MAX_MDSIZE;
281 
282     ret = md->init(mdCtx, NULL);
283     if (ret != CRYPT_SUCCESS) {
284         BSL_ERR_PUSH_ERROR(ret);
285         return ret;
286     }
287     ret = md->update(mdCtx, &temp, 1);
288     if (ret != CRYPT_SUCCESS) {
289         BSL_ERR_PUSH_ERROR(ret);
290         goto EXIT;
291     }
292     ret = md->update(mdCtx, ctx->v, ctx->seedLen);
293     if (ret != CRYPT_SUCCESS) {
294         BSL_ERR_PUSH_ERROR(ret);
295         goto EXIT;
296     }
297     ret = md->update(mdCtx, adin->data, adin->len);
298     if (ret != CRYPT_SUCCESS) {
299         BSL_ERR_PUSH_ERROR(ret);
300         goto EXIT;
301     }
302 
303     ret = md->final(mdCtx, w, &wLen);
304     if (ret != CRYPT_SUCCESS) {
305         BSL_ERR_PUSH_ERROR(ret);
306         goto EXIT;
307     }
308 
309     DRBG_HashAddV(ctx->v, ctx->seedLen, w, mdSize);
310 
311 EXIT:
312     // Clear MD data.
313     md->deinit(mdCtx);
314     return ret;
315 }
316 
DRBG_HashGenerate(DRBG_Ctx * drbg,uint8_t * out,uint32_t outLen,const CRYPT_Data * adin)317 int32_t DRBG_HashGenerate(DRBG_Ctx *drbg, uint8_t *out, uint32_t outLen, const CRYPT_Data *adin)
318 {
319     DRBG_HashCtx *ctx = (DRBG_HashCtx*)drbg->ctx;
320     const EAL_MdMethod *md = ctx->md;
321     void *mdCtx = ctx->mdCtx;
322     uint32_t mdSize = md->mdSize;
323     uint8_t h[DRBG_HASH_MAX_MDSIZE];
324     uint32_t len = outLen;
325     int32_t ret;
326     uint32_t reseedCtrBe;
327 
328     /* if adin :
329             w = HASH(0x02 || V || adin)
330             V = (V + w) mod 2^seedLen
331     */
332     if (!CRYPT_IsDataNull(adin)) {
333         ret = DRBG_HashAdinInHashGenerate(ctx, adin);
334         if (ret != CRYPT_SUCCESS) {
335             BSL_ERR_PUSH_ERROR(ret);
336             return ret;
337         }
338     }
339 
340     // Hashgen(V, out, len)
341     ret = DRBG_Hashgen(ctx, out, len);
342     if (ret != CRYPT_SUCCESS) {
343         BSL_ERR_PUSH_ERROR(ret);
344         return ret;
345     }
346 
347     // H = HASH(0x03 || V)
348     uint8_t temp = 0x3;
349 
350     ret = md->init(mdCtx, NULL);
351     if (ret != CRYPT_SUCCESS) {
352         BSL_ERR_PUSH_ERROR(ret);
353         return ret;
354     }
355 
356     ret = md->update(mdCtx, &temp, 1);
357     if (ret != CRYPT_SUCCESS) {
358         BSL_ERR_PUSH_ERROR(ret);
359         goto EXIT;
360     }
361     ret = md->update(mdCtx, ctx->v, ctx->seedLen);
362     if (ret != CRYPT_SUCCESS) {
363         BSL_ERR_PUSH_ERROR(ret);
364         goto EXIT;
365     }
366 
367     ret = md->final(mdCtx, h, &mdSize);
368     if (ret != CRYPT_SUCCESS) {
369         BSL_ERR_PUSH_ERROR(ret);
370         goto EXIT;
371     }
372 
373     // V = (V + H + C + reseed_counter) mod 2^seedlen
374     DRBG_HashAddV(ctx->v, ctx->seedLen, h, mdSize);
375     DRBG_HashAddV(ctx->v, ctx->seedLen, ctx->c, ctx->seedLen);
376     reseedCtrBe = CRYPT_HTONL((uint32_t)(drbg->reseedCtr));
377     DRBG_HashAddV(ctx->v, ctx->seedLen, (uint8_t*)&reseedCtrBe, sizeof(reseedCtrBe));
378 
379 EXIT:
380     // Clear MD data.
381     md->deinit(mdCtx);
382     return ret;
383 }
384 
DRBG_HashReseed(DRBG_Ctx * drbg,const CRYPT_Data * entropy,const CRYPT_Data * adin)385 int32_t DRBG_HashReseed(DRBG_Ctx *drbg, const CRYPT_Data *entropy, const CRYPT_Data *adin)
386 {
387     int32_t ret;
388     DRBG_HashCtx *ctx = (DRBG_HashCtx*)drbg->ctx;
389     CRYPT_Data v = {ctx->v, ctx->seedLen};
390     uint8_t c = 0x1;
391     CRYPT_Data temp = {&c, 1};
392 
393     /**
394     seed_material = 0x01 || V || entropy_input || additional_input.
395     seed = Hash_Df(seed_material) // The memory of C is reused.
396     V = seed
397     C = Hash_Df(0x00 || V)
398     */
399     if (drbg->isGm) {
400         ret = DRBG_HashDf(ctx, ctx->c, ctx->seedLen, &temp, entropy, &v, adin);
401     } else {
402         ret = DRBG_HashDf(ctx, ctx->c, ctx->seedLen, &temp, &v, entropy, adin);
403     }
404     if (ret != CRYPT_SUCCESS) {
405         BSL_ERR_PUSH_ERROR(ret);
406         return ret;
407     }
408 
409     // The length of the C array is the longest seedLen. Therefore, there is no failure.
410     (void)memcpy_s(ctx->v, sizeof(ctx->v), ctx->c, ctx->seedLen);
411 
412     c = 0x0;
413     ret = DRBG_HashDf(ctx, ctx->c, ctx->seedLen, &temp, &v, NULL, NULL);
414     if (ret != CRYPT_SUCCESS) {
415         BSL_ERR_PUSH_ERROR(ret);
416     }
417 
418     return ret;
419 }
420 
DRBG_HashUnInstantiate(DRBG_Ctx * drbg)421 void DRBG_HashUnInstantiate(DRBG_Ctx *drbg)
422 {
423     DRBG_HashCtx *ctx = (DRBG_HashCtx*)drbg->ctx;
424 
425     ctx->md->deinit(ctx->mdCtx);
426     BSL_SAL_CleanseData((void *)(ctx->c), sizeof(ctx->c));
427     BSL_SAL_CleanseData((void *)(ctx->v), sizeof(ctx->v));
428 }
429 
DRBG_HashDup(DRBG_Ctx * drbg)430 DRBG_Ctx *DRBG_HashDup(DRBG_Ctx *drbg)
431 {
432     DRBG_HashCtx *ctx = NULL;
433 
434     if (drbg == NULL) {
435         return NULL;
436     }
437 
438     ctx = (DRBG_HashCtx*)drbg->ctx;
439     return DRBG_NewHashCtx(ctx->md, drbg->isGm, &(drbg->seedMeth), drbg->seedCtx);
440 }
441 
DRBG_HashFree(DRBG_Ctx * drbg)442 void DRBG_HashFree(DRBG_Ctx *drbg)
443 {
444     if (drbg == NULL) {
445         return;
446     }
447 
448     DRBG_HashUnInstantiate(drbg);
449     DRBG_HashCtx *ctx = (DRBG_HashCtx*)drbg->ctx;
450     ctx->md->freeCtx(ctx->mdCtx);
451     BSL_SAL_FREE(drbg);
452     return;
453 }
454 
DRBG_NewHashCtxBase(uint32_t mdSize,DRBG_Ctx * drbg,DRBG_HashCtx * ctx)455 static int32_t DRBG_NewHashCtxBase(uint32_t mdSize, DRBG_Ctx *drbg, DRBG_HashCtx *ctx)
456 {
457     switch (mdSize) {
458         case DRBG_SHA1MDSIZE:
459             drbg->strength = 128;   // 128 is the standard content length of nist 800-90a.
460             ctx->seedLen = 55;      // 55 is the standard content length of nist 800-90a.
461             return CRYPT_SUCCESS;
462         case DRBG_SHA224MDSIZE:
463             drbg->strength = 192;   // 192 is the standard content length of nist 800-90a.
464             ctx->seedLen = 55;      // 55 is the standard content length of nist 800-90a.
465             return CRYPT_SUCCESS;
466         case DRBG_SHA256MDSIZE:
467             drbg->strength = 256;   // 256 is the standard content length of nist 800-90a.
468             ctx->seedLen = 55;      // 55 is the standard content length of nist 800-90a.
469             return CRYPT_SUCCESS;
470         case DRBG_SHA384MDSIZE:
471         case DRBG_SHA512MDSIZE:
472             drbg->strength = 256;   // 256 is the standard content length of nist 800-90a.
473             ctx->seedLen = 111;     // 111 is the standard content length of nist 800-90a.
474             return CRYPT_SUCCESS;
475         default:
476             BSL_ERR_PUSH_ERROR(CRYPT_DRBG_ALG_NOT_SUPPORT);
477             return CRYPT_DRBG_ALG_NOT_SUPPORT;
478     }
479 }
480 
DRBG_NewHashCtx(const EAL_MdMethod * md,bool isGm,const CRYPT_RandSeedMethod * seedMeth,void * seedCtx)481 DRBG_Ctx *DRBG_NewHashCtx(const EAL_MdMethod *md, bool isGm, const CRYPT_RandSeedMethod *seedMeth, void *seedCtx)
482 {
483     DRBG_Ctx *drbg = NULL;
484     DRBG_HashCtx *ctx = NULL;
485     static DRBG_Method meth = {
486         DRBG_HashInstantiate,
487         DRBG_HashGenerate,
488         DRBG_HashReseed,
489         DRBG_HashUnInstantiate,
490         DRBG_HashDup,
491         DRBG_HashFree
492     };
493 
494     if (md == NULL || md->newCtx == NULL || md->freeCtx == NULL || seedMeth == NULL) {
495         return NULL;
496     }
497 
498     drbg = (DRBG_Ctx*)BSL_SAL_Malloc(sizeof(DRBG_Ctx) + sizeof(DRBG_HashCtx));
499     if (drbg == NULL) {
500         return NULL;
501     }
502 
503     ctx = (DRBG_HashCtx*)(drbg + 1);
504     ctx->md = md;
505     ctx->mdCtx = md->newCtx();
506     if (ctx->mdCtx == NULL) {
507         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
508         BSL_SAL_FREE(drbg);
509         return NULL;
510     }
511     if (DRBG_NewHashCtxBase(md->mdSize, drbg, ctx) != CRYPT_SUCCESS) {
512         BSL_SAL_FREE(drbg);
513         md->freeCtx(ctx->mdCtx);
514         ctx->mdCtx = NULL;
515         return NULL;
516     }
517 
518     drbg->state = DRBG_STATE_UNINITIALISED;
519     drbg->isGm = isGm;
520     drbg->reseedInterval = (drbg->isGm) ? HITLS_CRYPTO_RESEED_INTERVAL_GM : DRBG_MAX_RESEED_INTERVAL;
521 #if defined(HITLS_CRYPTO_DRBG_GM)
522     drbg->reseedIntervalTime = (drbg->isGm) ? HITLS_CRYPTO_DRBG_RESEED_TIME_GM : 0;
523 #endif
524 
525     drbg->meth = &meth;
526     drbg->ctx = ctx;
527     drbg->seedMeth = *seedMeth;
528     drbg->seedCtx = seedCtx;
529 
530     // Shift right by 3, from bit length to byte length
531     drbg->entropyRange.min = drbg->strength >> 3;
532     drbg->entropyRange.max = DRBG_MAX_LEN;
533 
534     drbg->nonceRange.min = drbg->entropyRange.min / DRBG_NONCE_FROM_ENTROPY;
535     drbg->nonceRange.max = DRBG_MAX_LEN;
536 
537     drbg->maxPersLen = DRBG_MAX_LEN;
538     drbg->maxAdinLen = DRBG_MAX_LEN;
539     drbg->maxRequest = (drbg->isGm) ? DRBG_MAX_REQUEST_SM3 : DRBG_MAX_REQUEST;
540 
541     return drbg;
542 }
543 #endif
544