1
/* ***** BEGIN LICENSE BLOCK *****
2
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
* The contents of this file are subject to the Mozilla Public License Version
5
* 1.1 (the "License"); you may not use this file except in compliance with
6
* the License. You may obtain a copy of the License at
7
* http://www.mozilla.org/MPL/
9
* Software distributed under the License is distributed on an "AS IS" basis,
10
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
* for the specific language governing rights and limitations under the
14
* The Original Code is the Network Security Services libraries.
16
* The Initial Developer of the Original Code is Red Hat, Inc.
17
* Portions created by the Initial Developer are Copyright (C) 2009
18
* the Initial Developer. All Rights Reserved.
20
* Portions created by Netscape Communications Corporation
21
* are Copyright (C) 1994-2000 Netscape Communications Corporation.
22
* All Rights Reserved.
26
* Alternatively, the contents of this file may be used under the terms of
27
* either the GNU General Public License Version 2 or later (the "GPL"), or
28
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
* in which case the provisions of the GPL or the LGPL are applicable instead
30
* of those above. If you wish to allow use of your version of this file only
31
* under the terms of either the GPL or the LGPL, and not to allow others to
32
* use your version of this file under the terms of the MPL, indicate your
33
* decision by deleting the provisions above and replace them with the notice
34
* and other provisions required by the GPL or the LGPL. If you do not delete
35
* the provisions above, a recipient may use your version of this file under
36
* the terms of any one of the MPL, the GPL or the LGPL.
38
* ***** END LICENSE BLOCK ***** */
39
/* $Id: drbg.c,v 1.8 2009/04/01 03:37:29 wtc%google.com Exp $ */
41
#ifdef FREEBL_NO_DEPEND
56
#include "secrng.h" /* for RNG_SystemRNG() */
59
/* PRNG_SEEDLEN defined in NIST SP 800-90 section 10.1
60
* for SHA-1, SHA-224, and SHA-256 it's 440 bits.
61
* for SHA-384 and SHA-512 it's 888 bits */
62
#define PRNG_SEEDLEN (440/PR_BITS_PER_BYTE)
63
static const PRInt64 PRNG_MAX_ADDITIONAL_BYTES = LL_INIT(0x1, 0x0);
64
/* 2^35 bits or 2^32 bytes */
65
#define PRNG_MAX_REQUEST_SIZE 0x10000 /* 2^19 bits or 2^16 bytes */
66
#define PRNG_ADDITONAL_DATA_CACHE_SIZE (8*1024) /* must be less than
67
* PRNG_MAX_ADDITIONAL_BYTES
71
/* RESEED_COUNT is how many calls to the prng before we need to reseed
72
* under normal NIST rules, you must return an error. In the NSS case, we
73
* self-reseed with RNG_SystemRNG(). Count can be a large number. For code
74
* simplicity, we specify count with 2 components: RESEED_BYTE (which is
75
* the same as LOG256(RESEED_COUNT)) and RESEED_VALUE (which is the same as
76
* RESEED_COUNT / (256 ^ RESEED_BYTE)). Another way to look at this is
77
* RESEED_COUNT = RESEED_VALUE * (256 ^ RESEED_BYTE). For Hash based DRBG
78
* we use the maximum count value, 2^48, or RESEED_BYTE=6 and RESEED_VALUE=1
81
#define RESEED_VALUE 1
83
#define PRNG_RESET_RESEED_COUNT(rng) \
84
PORT_Memset((rng)->reseed_counter, 0, sizeof (rng)->reseed_counter); \
85
(rng)->reseed_counter[RESEED_BYTE] = 1;
89
* The actual values of this enum are specified in SP 800-90, 10.1.1.*
90
* The spec does not name the types, it only uses bare values
93
prngCGenerateType = 0, /* used when creating a new 'C' */
94
prngReseedType = 1, /* used in reseeding */
95
prngAdditionalDataType = 2, /* used in mixing additional data */
96
prngGenerateByteType = 3 /* used when mixing internal state while
103
struct RNGContextStr {
104
PZLock *lock; /* Lock to serialize access to global rng */
106
* NOTE, a number of steps in the drbg algorithm need to hash
107
* V_type || V. The code, therefore, depends on the V array following
108
* immediately after V_type to avoid extra copies. To accomplish this
109
* in a way that compiliers can't perturb, we declare V_type and V
110
* as a V_Data array and reference them by macros */
111
PRUint8 V_Data[PRNG_SEEDLEN+1]; /* internal state variables */
112
#define V_type V_Data[0]
113
#define V(rng) (((rng)->V_Data)+1)
114
#define VSize(rng) ((sizeof (rng)->V_Data) -1)
115
PRUint8 C[PRNG_SEEDLEN]; /* internal state variables */
116
PRUint8 oldV[PRNG_SEEDLEN]; /* for continuous rng checking */
117
/* If we get calls for the PRNG to return less than the length of our
118
* hash, we extend the request for a full hash (since we'll be doing
119
* the full hash anyway). Future requests for random numbers are fulfilled
120
* from the remainder of the bytes we generated. Requests for bytes longer
121
* than the hash size are fulfilled directly from the HashGen function
122
* of the random number generator. */
123
PRUint8 reseed_counter[RESEED_BYTE+1]; /* number of requests since the
124
* last reseed. Need only be
125
* big enough to hold the whole
127
PRUint8 data[SHA256_LENGTH]; /* when we request less than a block
128
* save the rest of the rng output for
129
* another partial block */
130
PRUint8 dataAvail; /* # bytes of output available in our cache,
131
* [0...SHA256_LENGTH] */
132
/* store additional data that has been shovelled off to us by
133
* RNG_RandomUpdate. */
134
PRUint8 additionalDataCache[PRNG_ADDITONAL_DATA_CACHE_SIZE];
135
PRUint32 additionalAvail;
136
PRBool isValid; /* false if RNG reaches an invalid state */
139
typedef struct RNGContextStr RNGContext;
140
static RNGContext *globalrng = NULL;
141
static RNGContext theGlobalRng;
145
* The next several functions are derived from the NIST SP 800-90
146
* spec. In these functions, an attempt was made to use names consistent
147
* with the names in the spec, even if they differ from normal NSS usage.
151
* Hash Derive function defined in NISP SP 800-90 Section 10.4.1.
152
* This function is used in the Instantiate and Reseed functions.
154
* NOTE: requested_bytes cannot overlap with input_string_1 or input_string_2.
155
* input_string_1 and input_string_2 are logically concatentated.
156
* input_string_1 must be supplied.
157
* if input_string_2 is not supplied, NULL should be passed for this parameter.
160
prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
161
const PRUint8 *input_string_1, unsigned int input_string_1_len,
162
const PRUint8 *input_string_2, unsigned int input_string_2_len)
168
tmp=SHA_HTONL(no_of_bytes_to_return*8);
170
for (counter = 1 ; no_of_bytes_to_return > 0; counter++) {
171
unsigned int hash_return_len;
173
SHA256_Update(&ctx, &counter, 1);
174
SHA256_Update(&ctx, (unsigned char *)&tmp, sizeof tmp);
175
SHA256_Update(&ctx, input_string_1, input_string_1_len);
176
if (input_string_2) {
177
SHA256_Update(&ctx, input_string_2, input_string_2_len);
179
SHA256_End(&ctx, requested_bytes, &hash_return_len,
180
no_of_bytes_to_return);
181
requested_bytes += hash_return_len;
182
no_of_bytes_to_return -= hash_return_len;
189
* Hash_DRBG Instantiate NIST SP 800-80 10.1.1.2
191
* NOTE: bytes & len are entropy || nonce || personalization_string. In
192
* normal operation, NSS calculates them all together in a single call.
195
prng_instantiate(RNGContext *rng, PRUint8 *bytes, unsigned int len)
197
prng_Hash_df(V(rng), VSize(rng), bytes, len, NULL, 0);
198
rng->V_type = prngCGenerateType;
199
prng_Hash_df(rng->C,sizeof rng->C,rng->V_Data,sizeof rng->V_Data,NULL,0);
200
PRNG_RESET_RESEED_COUNT(rng)
206
* Update the global random number generator with more seeding
207
* material. Use the Hash_DRBG reseed algorithm from NIST SP-800-90
210
* If entropy is NULL, it is fetched from the noise generator.
214
prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len,
215
const PRUint8 *additional_input, unsigned int additional_input_len)
217
PRUint8 noiseData[(sizeof rng->V_Data)+PRNG_SEEDLEN];
218
PRUint8 *noise = &noiseData[0];
220
/* if entropy wasn't supplied, fetch it. (normal operation case) */
221
if (entropy == NULL) {
222
entropy_len = (unsigned int) RNG_SystemRNG(
223
&noiseData[sizeof rng->V_Data], PRNG_SEEDLEN);
225
/* NOTE: this code is only available for testing, not to applications */
226
/* if entropy was too big for the stack variable, get it from malloc */
227
if (entropy_len > PRNG_SEEDLEN) {
228
noise = PORT_Alloc(entropy_len + (sizeof rng->V_Data));
233
PORT_Memcpy(&noise[sizeof rng->V_Data],entropy, entropy_len);
236
rng->V_type = prngReseedType;
237
PORT_Memcpy(noise, rng->V_Data, sizeof rng->V_Data);
238
prng_Hash_df(V(rng), VSize(rng), noise, (sizeof rng->V_Data) + entropy_len,
239
additional_input, additional_input_len);
240
/* clear potential CSP */
241
PORT_Memset(noise, 0, (sizeof rng->V_Data) + entropy_len);
242
rng->V_type = prngCGenerateType;
243
prng_Hash_df(rng->C,sizeof rng->C,rng->V_Data,sizeof rng->V_Data,NULL,0);
244
PRNG_RESET_RESEED_COUNT(rng)
246
if (noise != &noiseData[0]) {
253
* build some fast inline functions for adding.
255
#define PRNG_ADD_CARRY_ONLY(dest, start, cy) \
257
for (k1=start; carry && k1 >=0 ; k1--) { \
258
carry = !(++dest[k1]); \
262
* NOTE: dest must be an array for the following to work.
264
#define PRNG_ADD_BITS(dest, dest_len, add, len) \
266
for (k1=dest_len -1, k2=len-1; k2 >= 0; --k1, --k2) { \
267
carry += dest[k1]+ add[k2]; \
268
dest[k1] = (PRUint8) carry; \
272
#define PRNG_ADD_BITS_AND_CARRY(dest, dest_len, add, len) \
273
PRNG_ADD_BITS(dest, dest_len, add, len) \
274
PRNG_ADD_CARRY_ONLY(dest, k1, carry)
277
* This function expands the internal state of the prng to fulfill any number
278
* of bytes we need for this request. We only use this call if we need more
279
* than can be supplied by a single call to SHA256_HashBuf.
281
* This function is specified in NIST SP 800-90 section 10.1.1.4, Hashgen
284
prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
285
unsigned int no_of_returned_bytes)
287
PRUint8 data[VSize(rng)];
289
PORT_Memcpy(data, V(rng), VSize(rng));
290
while (no_of_returned_bytes) {
297
SHA256_Update(&ctx, data, sizeof data);
298
SHA256_End(&ctx, returned_bytes, &len, no_of_returned_bytes);
299
returned_bytes += len;
300
no_of_returned_bytes -= len;
301
/* The carry parameter is a bool (increment or not).
302
* This increments data if no_of_returned_bytes is not zero */
303
PRNG_ADD_CARRY_ONLY(data, (sizeof data)- 1, no_of_returned_bytes);
305
PORT_Memset(data, 0, sizeof data);
309
* Generates new random bytes and advances the internal prng state.
310
* additional bytes are only used in algorithm testing.
312
* This function is specified in NIST SP 800-90 section 10.1.1.4
315
prng_generateNewBytes(RNGContext *rng,
316
PRUint8 *returned_bytes, unsigned int no_of_returned_bytes,
317
const PRUint8 *additional_input,
318
unsigned int additional_input_len)
320
PRUint8 H[SHA256_LENGTH]; /* both H and w since they
321
* aren't used concurrently */
326
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
329
/* This code only triggers during tests, normal
330
* prng operation does not use additional_input */
331
if (additional_input){
333
/* NIST SP 800-90 defines two temporaries in their calculations,
334
* w and H. These temporaries are the same lengths, and used
335
* at different times, so we use the following macro to collapse
336
* them to the same variable, but keeping their unique names for
337
* easy comparison to the spec */
339
rng->V_type = prngAdditionalDataType;
341
SHA256_Update(&ctx, rng->V_Data, sizeof rng->V_Data);
342
SHA256_Update(&ctx, additional_input, additional_input_len);
343
SHA256_End(&ctx, w, NULL, sizeof w);
344
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w)
345
PORT_Memset(w, 0, sizeof w);
349
if (no_of_returned_bytes == SHA256_LENGTH) {
350
/* short_cut to hashbuf and save a copy and a clear */
351
SHA256_HashBuf(returned_bytes, V(rng), VSize(rng) );
353
prng_Hashgen(rng, returned_bytes, no_of_returned_bytes);
355
/* advance our internal state... */
356
rng->V_type = prngGenerateByteType;
357
SHA256_HashBuf(H, rng->V_Data, sizeof rng->V_Data);
358
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), H, sizeof H)
359
PRNG_ADD_BITS(V(rng), VSize(rng), rng->C, sizeof rng->C);
360
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter,
361
sizeof rng->reseed_counter)
362
PRNG_ADD_CARRY_ONLY(rng->reseed_counter,(sizeof rng->reseed_counter)-1, 1);
364
/* continuous rng check */
365
if (memcmp(V(rng), rng->oldV, sizeof rng->oldV) == 0) {
366
rng->isValid = PR_FALSE;
367
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
370
PORT_Memcpy(rng->oldV, V(rng), sizeof rng->oldV);
374
/* Use NSPR to prevent RNG_RNGInit from being called from separate
375
* threads, creating a race condition.
377
static const PRCallOnceType pristineCallOnce;
378
static PRCallOnceType coRNGInit;
379
static PRStatus rng_init(void)
381
PRUint8 bytes[PRNG_SEEDLEN*2]; /* entropy + nonce */
382
unsigned int numBytes;
383
if (globalrng == NULL) {
384
/* create a new global RNG context */
385
globalrng = &theGlobalRng;
386
PORT_Assert(NULL == globalrng->lock);
387
/* create a lock for it */
388
globalrng->lock = PZ_NewLock(nssILockOther);
389
if (globalrng->lock == NULL) {
391
PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
395
/* Try to get some seed data for the RNG */
396
numBytes = (unsigned int) RNG_SystemRNG(bytes, sizeof bytes);
397
PORT_Assert(numBytes == 0 || numBytes == sizeof bytes);
399
/* if this is our first call, instantiate, otherwise reseed
400
* prng_instantiate gets a new clean state, we want to mix
401
* any previous entropy we may have collected */
402
if (V(globalrng)[0] == 0) {
403
prng_instantiate(globalrng, bytes, numBytes);
405
prng_reseed(globalrng, bytes, numBytes, NULL, 0);
407
memset(bytes, 0, numBytes);
409
PZ_DestroyLock(globalrng->lock);
410
globalrng->lock = NULL;
414
/* the RNG is in a valid state */
415
globalrng->isValid = PR_TRUE;
417
/* Fetch more entropy into the PRNG */
418
RNG_SystemInfoForRNG();
424
* Clean up the global RNG context
427
prng_freeRNGContext(RNGContext *rng)
429
PRUint8 inputhash[VSize(rng) + (sizeof rng->C)];
431
/* destroy context lock */
432
SKIP_AFTER_FORK(PZ_DestroyLock(globalrng->lock));
434
/* zero global RNG context except for C & V to preserve entropy */
435
prng_Hash_df(inputhash, sizeof rng->C, rng->C, sizeof rng->C, NULL, 0);
436
prng_Hash_df(&inputhash[sizeof rng->C], VSize(rng), V(rng), VSize(rng),
438
memset(rng, 0, sizeof *rng);
439
memcpy(rng->C, inputhash, sizeof rng->C);
440
memcpy(V(rng), &inputhash[sizeof rng->C], VSize(rng));
442
memset(inputhash, 0, sizeof inputhash);
450
* Initialize the global RNG context and give it some seed input taken
451
* from the system. This function is thread-safe and will only allow
452
* the global context to be initialized once. The seed input is likely
453
* small, so it is imperative that RNG_RandomUpdate() be called with
454
* additional seed data before the generator is used. A good way to
455
* provide the generator with additional entropy is to call
456
* RNG_SystemInfoForRNG(). Note that C_Initialize() does exactly that.
461
/* Allow only one call to initialize the context */
462
PR_CallOnce(&coRNGInit, rng_init);
463
/* Make sure there is a context */
464
return (globalrng != NULL) ? PR_SUCCESS : PR_FAILURE;
468
** Update the global random number generator with more seeding
472
RNG_RandomUpdate(const void *data, size_t bytes)
476
/* Make sure our assumption that size_t is unsigned is true */
477
PR_STATIC_ASSERT(((size_t)-1) > (size_t)1);
479
#if defined(NS_PTR_GT_32) || (defined(NSS_USE_64) && !defined(NS_PTR_LE_32))
481
* NIST 800-90 requires us to verify our inputs. This value can
482
* come from the application, so we need to make sure it's within the
483
* spec. The spec says it must be less than 2^32 bytes (2^35 bits).
484
* This can only happen if size_t is greater than 32 bits (i.e. on
485
* most 64 bit platforms). The 90% case (perhaps 100% case), size_t
486
* is less than or equal to 32 bits if the platform is not 64 bits, and
487
* greater than 32 bits if it is a 64 bit platform. The corner
488
* cases are handled with explicit defines NS_PTR_GT_32 and NS_PTR_LE_32.
490
* In general, neither NS_PTR_GT_32 nor NS_PTR_LE_32 will need to be
491
* defined. If you trip over the next two size ASSERTS at compile time,
492
* you will need to define them for your platform.
494
* if 'sizeof(size_t) > 4' is triggered it means that we were expecting
495
* sizeof(size_t) to be greater than 4, but it wasn't. Setting
496
* NS_PTR_LE_32 will correct that mistake.
498
* if 'sizeof(size_t) <= 4' is triggered, it means that we were expecting
499
* sizeof(size_t) to be less than or equal to 4, but it wasn't. Setting
500
* NS_PTR_GT_32 will correct that mistake.
503
PR_STATIC_ASSERT(sizeof(size_t) > 4);
505
if (bytes > PRNG_MAX_ADDITIONAL_BYTES) {
506
bytes = PRNG_MAX_ADDITIONAL_BYTES;
509
PR_STATIC_ASSERT(sizeof(size_t) <= 4);
512
PZ_Lock(globalrng->lock);
513
/* if we're passed more than our additionalDataCache, simply
514
* call reseed with that data */
515
if (bytes > sizeof (globalrng->additionalDataCache)) {
516
rv = prng_reseed(globalrng, NULL, 0, data, (unsigned int) bytes);
517
/* if we aren't going to fill or overflow the buffer, just cache it */
518
} else if (bytes < ((sizeof globalrng->additionalDataCache)
519
- globalrng->additionalAvail)) {
520
PORT_Memcpy(globalrng->additionalDataCache+globalrng->additionalAvail,
522
globalrng->additionalAvail += (PRUint32) bytes;
525
/* we are going to fill or overflow the buffer. In this case we will
526
* fill the entropy buffer, reseed with it, start a new buffer with the
527
* remainder. We know the remainder will fit in the buffer because
528
* we already handled the case where bytes > the size of the buffer.
530
size_t bufRemain = (sizeof globalrng->additionalDataCache)
531
- globalrng->additionalAvail;
532
/* fill the rest of the buffer */
534
PORT_Memcpy(globalrng->additionalDataCache
535
+globalrng->additionalAvail,
537
data = ((unsigned char *)data) + bufRemain;
540
/* reseed from buffer */
541
rv = prng_reseed(globalrng, NULL, 0, globalrng->additionalDataCache,
542
sizeof globalrng->additionalDataCache);
544
/* copy the rest into the cache */
545
PORT_Memcpy(globalrng->additionalDataCache, data, bytes);
546
globalrng->additionalAvail = (PRUint32) bytes;
549
PZ_Unlock(globalrng->lock);
554
** Generate some random bytes, using the global random number generator
558
prng_GenerateGlobalRandomBytes(RNGContext *rng,
559
void *dest, size_t len)
561
SECStatus rv = SECSuccess;
562
PRUint8 *output = dest;
563
/* check for a valid global RNG context */
564
PORT_Assert(rng != NULL);
566
PORT_SetError(SEC_ERROR_INVALID_ARGS);
569
/* FIPS limits the amount of entropy available in a single request */
570
if (len > PRNG_MAX_REQUEST_SIZE) {
571
PORT_SetError(SEC_ERROR_INVALID_ARGS);
576
/* Check the amount of seed data in the generator. If not enough,
577
* don't produce any data.
579
if (rng->reseed_counter[0] >= RESEED_VALUE) {
580
rv = prng_reseed(rng, NULL, 0, NULL, 0);
581
PZ_Unlock(rng->lock);
582
if (rv != SECSuccess) {
585
RNG_SystemInfoForRNG();
589
* see if we have enough bytes to fulfill the request.
591
if (len <= rng->dataAvail) {
592
memcpy(output, rng->data + ((sizeof rng->data) - rng->dataAvail), len);
593
memset(rng->data + ((sizeof rng->data) - rng->dataAvail), 0, len);
594
rng->dataAvail -= len;
596
/* if we are asking for a small number of bytes, cache the rest of
598
} else if (len < sizeof rng->data) {
599
rv = prng_generateNewBytes(rng, rng->data, sizeof rng->data,
600
rng->additionalAvail ? rng->additionalDataCache : NULL,
601
rng->additionalAvail);
602
rng->additionalAvail = 0;
603
if (rv == SECSuccess) {
604
memcpy(output, rng->data, len);
605
memset(rng->data, 0, len);
606
rng->dataAvail = (sizeof rng->data) - len;
608
/* we are asking for lots of bytes, just ask the generator to pass them */
610
rv = prng_generateNewBytes(rng, output, len,
611
rng->additionalAvail ? rng->additionalDataCache : NULL,
612
rng->additionalAvail);
613
rng->additionalAvail = 0;
615
PZ_Unlock(rng->lock);
616
/* --- UNLOCKED --- */
621
** Generate some random bytes, using the global random number generator
625
RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
627
return prng_GenerateGlobalRandomBytes(globalrng, dest, len);
631
RNG_RNGShutdown(void)
633
/* check for a valid global RNG context */
634
PORT_Assert(globalrng != NULL);
635
if (globalrng == NULL) {
636
/* Should set a "not initialized" error code. */
637
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
641
prng_freeRNGContext(globalrng);
643
/* reset the callonce struct to allow a new call to RNG_RNGInit() */
644
coRNGInit = pristineCallOnce;
648
* Test case interface. used by fips testing and power on self test
650
/* make sure the test context is separate from the global context, This
651
* allows us to test the internal random number generator without losing
652
* entropy we may have previously collected. */
653
RNGContext testContext;
656
* Test vector API. Use NIST SP 800-90 general interface so one of the
657
* other NIST SP 800-90 algorithms may be used in the future.
660
PRNGTEST_Instantiate(const PRUint8 *entropy, unsigned int entropy_len,
661
const PRUint8 *nonce, unsigned int nonce_len,
662
const PRUint8 *personal_string, unsigned int ps_len)
664
int bytes_len = entropy_len + nonce_len + ps_len;
665
PRUint8 *bytes = PORT_Alloc(bytes_len);
670
/* concatenate the various inputs, internally NSS only instantiates with
671
* a single long string */
672
PORT_Memcpy(bytes, entropy, entropy_len);
674
PORT_Memcpy(&bytes[entropy_len], nonce, nonce_len);
676
PORT_Assert(nonce_len == 0);
678
if (personal_string) {
679
PORT_Memcpy(&bytes[entropy_len+nonce_len], personal_string, ps_len);
681
PORT_Assert(ps_len == 0);
683
prng_instantiate(&testContext, bytes, bytes_len);
684
testContext.isValid = PR_TRUE;
685
PORT_ZFree(bytes, bytes_len);
690
PRNGTEST_Reseed(const PRUint8 *entropy, unsigned int entropy_len,
691
const PRUint8 *additional, unsigned int additional_len)
693
if (!testContext.isValid) {
694
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
697
return prng_reseed(&testContext, entropy, entropy_len, additional,
703
PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len,
704
const PRUint8 *additional, unsigned int additional_len)
706
if (!testContext.isValid) {
707
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
710
return prng_generateNewBytes(&testContext, bytes, bytes_len,
711
additional, additional_len);
716
PRNGTEST_Uninstantiate()
718
PORT_Memset(&testContext, 0, sizeof testContext);