1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #ifdef FREEBL_NO_DEPEND
6 #include "stubs.h"
7 #endif
8
9 #include "prerror.h"
10 #include "secerr.h"
11
12 #include "prtypes.h"
13 #include "prinit.h"
14 #include "blapi.h"
15 #include "blapii.h"
16 #include "nssilock.h"
17 #include "secitem.h"
18 #include "sha_fast.h"
19 #include "sha256.h"
20 #include "secrng.h" /* for RNG_SystemRNG() */
21 #include "secmpi.h"
22
23 /* PRNG_SEEDLEN defined in NIST SP 800-90 section 10.1
24 * for SHA-1, SHA-224, and SHA-256 it's 440 bits.
25 * for SHA-384 and SHA-512 it's 888 bits */
26 #define PRNG_SEEDLEN (440 / PR_BITS_PER_BYTE)
27 #define PRNG_MAX_ADDITIONAL_BYTES PR_INT64(0x100000000)
28 /* 2^35 bits or 2^32 bytes */
29 #define PRNG_MAX_REQUEST_SIZE 0x10000 /* 2^19 bits or 2^16 bytes */
30 #define PRNG_ADDITONAL_DATA_CACHE_SIZE (8 * 1024) /* must be less than \
31 * PRNG_MAX_ADDITIONAL_BYTES \
32 */
33 #define PRNG_ENTROPY_BLOCK_SIZE SHA256_LENGTH
34
35 /* RESEED_COUNT is how many calls to the prng before we need to reseed
36 * under normal NIST rules, you must return an error. In the NSS case, we
37 * self-reseed with RNG_SystemRNG(). Count can be a large number. For code
38 * simplicity, we specify count with 2 components: RESEED_BYTE (which is
39 * the same as LOG256(RESEED_COUNT)) and RESEED_VALUE (which is the same as
40 * RESEED_COUNT / (256 ^ RESEED_BYTE)). Another way to look at this is
41 * RESEED_COUNT = RESEED_VALUE * (256 ^ RESEED_BYTE). For Hash based DRBG
42 * we use the maximum count value, 2^48, or RESEED_BYTE=6 and RESEED_VALUE=1
43 */
44 #define RESEED_BYTE 6
45 #define RESEED_VALUE 1
46
47 #define PRNG_RESET_RESEED_COUNT(rng) \
48 PORT_Memset((rng)->reseed_counter, 0, sizeof(rng)->reseed_counter); \
49 (rng)->reseed_counter[RESEED_BYTE] = 1;
50
51 /*
52 * The actual values of this enum are specified in SP 800-90, 10.1.1.*
53 * The spec does not name the types, it only uses bare values
54 */
55 typedef enum {
56 prngCGenerateType = 0, /* used when creating a new 'C' */
57 prngReseedType = 1, /* used in reseeding */
58 prngAdditionalDataType = 2, /* used in mixing additional data */
59 prngGenerateByteType = 3 /* used when mixing internal state while
60 * generating bytes */
61 } prngVTypes;
62
63 /*
64 * Global RNG context
65 */
66 struct RNGContextStr {
67 PZLock *lock; /* Lock to serialize access to global rng */
68 /*
69 * NOTE, a number of steps in the drbg algorithm need to hash
70 * V_type || V. The code, therefore, depends on the V array following
71 * immediately after V_type to avoid extra copies. To accomplish this
72 * in a way that compiliers can't perturb, we declare V_type and V
73 * as a V_Data array and reference them by macros */
74 PRUint8 V_Data[PRNG_SEEDLEN + 1]; /* internal state variables */
75 #define V_type V_Data[0]
76 #define V(rng) (((rng)->V_Data) + 1)
77 #define VSize(rng) ((sizeof(rng)->V_Data) - 1)
78 PRUint8 C[PRNG_SEEDLEN]; /* internal state variables */
79 /* If we get calls for the PRNG to return less than the length of our
80 * hash, we extend the request for a full hash (since we'll be doing
81 * the full hash anyway). Future requests for random numbers are fulfilled
82 * from the remainder of the bytes we generated. Requests for bytes longer
83 * than the hash size are fulfilled directly from the HashGen function
84 * of the random number generator. */
85 PRUint8 reseed_counter[RESEED_BYTE + 1]; /* number of requests since the
86 * last reseed. Need only be
87 * big enough to hold the whole
88 * reseed count */
89 PRUint8 data[SHA256_LENGTH]; /* when we request less than a block
90 * save the rest of the rng output for
91 * another partial block */
92 PRUint8 dataAvail; /* # bytes of output available in our cache,
93 * [0...SHA256_LENGTH] */
94 /* store additional data that has been shovelled off to us by
95 * RNG_RandomUpdate. */
96 PRUint8 additionalDataCache[PRNG_ADDITONAL_DATA_CACHE_SIZE];
97 PRUint32 additionalAvail;
98 PRBool isValid; /* false if RNG reaches an invalid state */
99 PRBool isKatTest; /* true if running NIST PRNG KAT tests */
100 /* for continuous entropy check */
101 PRUint8 previousEntropyHash[SHA256_LENGTH];
102 };
103
104 typedef struct RNGContextStr RNGContext;
105 static RNGContext *globalrng = NULL;
106 static RNGContext theGlobalRng;
107
108 /*
109 * The next several functions are derived from the NIST SP 800-90
110 * spec. In these functions, an attempt was made to use names consistent
111 * with the names in the spec, even if they differ from normal NSS usage.
112 */
113
114 /*
115 * Hash Derive function defined in NISP SP 800-90 Section 10.4.1.
116 * This function is used in the Instantiate and Reseed functions.
117 *
118 * NOTE: requested_bytes cannot overlap with input_string_1 or input_string_2.
119 * input_string_1 and input_string_2 are logically concatentated.
120 * input_string_1 must be supplied.
121 * if input_string_2 is not supplied, NULL should be passed for this parameter.
122 */
123 static SECStatus
prng_Hash_df(PRUint8 * requested_bytes,unsigned int no_of_bytes_to_return,const PRUint8 * input_string_1,unsigned int input_string_1_len,const PRUint8 * input_string_2,unsigned int input_string_2_len)124 prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
125 const PRUint8 *input_string_1, unsigned int input_string_1_len,
126 const PRUint8 *input_string_2, unsigned int input_string_2_len)
127 {
128 SHA256Context ctx;
129 PRUint32 tmp;
130 PRUint8 counter;
131
132 tmp = SHA_HTONL(no_of_bytes_to_return * 8);
133
134 for (counter = 1; no_of_bytes_to_return > 0; counter++) {
135 unsigned int hash_return_len;
136 SHA256_Begin(&ctx);
137 SHA256_Update(&ctx, &counter, 1);
138 SHA256_Update(&ctx, (unsigned char *)&tmp, sizeof tmp);
139 SHA256_Update(&ctx, input_string_1, input_string_1_len);
140 if (input_string_2) {
141 SHA256_Update(&ctx, input_string_2, input_string_2_len);
142 }
143 SHA256_End(&ctx, requested_bytes, &hash_return_len,
144 no_of_bytes_to_return);
145 requested_bytes += hash_return_len;
146 no_of_bytes_to_return -= hash_return_len;
147 }
148 SHA256_DestroyContext(&ctx, PR_FALSE);
149 return SECSuccess;
150 }
151
152 /*
153 * Hash_DRBG Instantiate NIST SP 800-90 10.1.1.2
154 *
155 * NOTE: bytes & len are entropy || nonce || personalization_string. In
156 * normal operation, NSS calculates them all together in a single call.
157 */
158 static SECStatus
prng_instantiate(RNGContext * rng,const PRUint8 * bytes,unsigned int len)159 prng_instantiate(RNGContext *rng, const PRUint8 *bytes, unsigned int len)
160 {
161 if (!rng->isKatTest && len < PRNG_SEEDLEN) {
162 /* If the seedlen is too small, it's probably because we failed to get
163 * enough random data.
164 * This is stricter than NIST SP800-90A requires. Don't enforce it for
165 * tests. */
166 PORT_SetError(SEC_ERROR_NEED_RANDOM);
167 return SECFailure;
168 }
169 prng_Hash_df(V(rng), VSize(rng), bytes, len, NULL, 0);
170 rng->V_type = prngCGenerateType;
171 prng_Hash_df(rng->C, sizeof rng->C, rng->V_Data, sizeof rng->V_Data, NULL, 0);
172 PRNG_RESET_RESEED_COUNT(rng)
173 return SECSuccess;
174 }
175
176 static PRCallOnceType coRNGInitEntropy;
177
178 static PRStatus
prng_initEntropy(void)179 prng_initEntropy(void)
180 {
181 size_t length;
182 PRUint8 block[PRNG_ENTROPY_BLOCK_SIZE];
183 SHA256Context ctx;
184
185 /* For FIPS 140-2 4.9.2 continuous random number generator test,
186 * fetch the initial entropy from the system RNG and keep it for
187 * later comparison. */
188 length = RNG_SystemRNG(block, sizeof(block));
189 if (length == 0) {
190 return PR_FAILURE; /* error is already set */
191 }
192 PORT_Assert(length == sizeof(block));
193
194 /* Store the hash of the entropy block rather than the block
195 * itself for backward secrecy. */
196 SHA256_Begin(&ctx);
197 SHA256_Update(&ctx, block, sizeof(block));
198 SHA256_End(&ctx, globalrng->previousEntropyHash, NULL,
199 sizeof(globalrng->previousEntropyHash));
200 PORT_Memset(block, 0, sizeof(block));
201 SHA256_DestroyContext(&ctx, PR_FALSE);
202 return PR_SUCCESS;
203 }
204
205 static SECStatus
prng_getEntropy(PRUint8 * buffer,size_t requestLength)206 prng_getEntropy(PRUint8 *buffer, size_t requestLength)
207 {
208 size_t total = 0;
209 PRUint8 block[PRNG_ENTROPY_BLOCK_SIZE];
210 PRUint8 hash[SHA256_LENGTH];
211 SHA256Context ctx;
212 SECStatus rv = SECSuccess;
213
214 if (PR_CallOnce(&coRNGInitEntropy, prng_initEntropy) != PR_SUCCESS) {
215 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
216 return SECFailure;
217 }
218
219 /* For FIPS 140-2 4.9.2 continuous random generator test,
220 * iteratively fetch fixed sized blocks from the system and
221 * compare consecutive blocks. */
222 while (total < requestLength) {
223 size_t length = RNG_SystemRNG(block, sizeof(block));
224 if (length == 0) {
225 rv = SECFailure; /* error is already set */
226 goto out;
227 }
228 PORT_Assert(length == sizeof(block));
229
230 /* Store the hash of the entropy block rather than the block
231 * itself for backward secrecy. */
232 SHA256_Begin(&ctx);
233 SHA256_Update(&ctx, block, sizeof(block));
234 SHA256_End(&ctx, hash, NULL, sizeof(hash));
235
236 if (PORT_Memcmp(globalrng->previousEntropyHash, hash, sizeof(hash)) == 0) {
237 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
238 rv = SECFailure;
239 goto out;
240 }
241 PORT_Memcpy(globalrng->previousEntropyHash, hash, sizeof(hash));
242 length = PR_MIN(requestLength - total, sizeof(block));
243 PORT_Memcpy(buffer, block, length);
244 total += length;
245 buffer += length;
246 }
247
248 out:
249 PORT_Memset(hash, 0, sizeof hash);
250 PORT_Memset(block, 0, sizeof block);
251 return rv;
252 }
253
254 /*
255 * Update the global random number generator with more seeding
256 * material. Use the Hash_DRBG reseed algorithm from NIST SP-800-90
257 * section 10.1.1.3
258 *
259 * If entropy is NULL, it is fetched from the noise generator.
260 */
261 static SECStatus
prng_reseed(RNGContext * rng,const PRUint8 * entropy,unsigned int entropy_len,const PRUint8 * additional_input,unsigned int additional_input_len)262 prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len,
263 const PRUint8 *additional_input, unsigned int additional_input_len)
264 {
265 PRUint8 noiseData[(sizeof rng->V_Data) + PRNG_SEEDLEN];
266 PRUint8 *noise = &noiseData[0];
267 SECStatus rv;
268
269 /* if entropy wasn't supplied, fetch it. (normal operation case) */
270 if (entropy == NULL) {
271 entropy_len = PRNG_SEEDLEN;
272 rv = prng_getEntropy(&noiseData[sizeof rng->V_Data], entropy_len);
273 if (rv != SECSuccess) {
274 return SECFailure; /* error is already set */
275 }
276 } else {
277 /* NOTE: this code is only available for testing, not to applications */
278 /* if entropy was too big for the stack variable, get it from malloc */
279 if (entropy_len > PRNG_SEEDLEN) {
280 noise = PORT_Alloc(entropy_len + (sizeof rng->V_Data));
281 if (noise == NULL) {
282 return SECFailure;
283 }
284 }
285 PORT_Memcpy(&noise[sizeof rng->V_Data], entropy, entropy_len);
286 }
287
288 if (entropy_len < 256 / PR_BITS_PER_BYTE) {
289 /* noise == &noiseData[0] at this point, so nothing to free */
290 PORT_SetError(SEC_ERROR_NEED_RANDOM);
291 return SECFailure;
292 }
293
294 rng->V_type = prngReseedType;
295 PORT_Memcpy(noise, rng->V_Data, sizeof rng->V_Data);
296 prng_Hash_df(V(rng), VSize(rng), noise, (sizeof rng->V_Data) + entropy_len,
297 additional_input, additional_input_len);
298 /* clear potential CSP */
299 PORT_Memset(noise, 0, (sizeof rng->V_Data) + entropy_len);
300 rng->V_type = prngCGenerateType;
301 prng_Hash_df(rng->C, sizeof rng->C, rng->V_Data, sizeof rng->V_Data, NULL, 0);
302 PRNG_RESET_RESEED_COUNT(rng)
303
304 if (noise != &noiseData[0]) {
305 PORT_Free(noise);
306 }
307 return SECSuccess;
308 }
309
310 /*
311 * SP 800-90 requires we rerun our health tests on reseed
312 */
313 static SECStatus
prng_reseed_test(RNGContext * rng,const PRUint8 * entropy,unsigned int entropy_len,const PRUint8 * additional_input,unsigned int additional_input_len)314 prng_reseed_test(RNGContext *rng, const PRUint8 *entropy,
315 unsigned int entropy_len, const PRUint8 *additional_input,
316 unsigned int additional_input_len)
317 {
318 SECStatus rv;
319
320 /* do health checks in FIPS mode */
321 rv = PRNGTEST_RunHealthTests();
322 if (rv != SECSuccess) {
323 /* error set by PRNGTEST_RunHealTests() */
324 rng->isValid = PR_FALSE;
325 return SECFailure;
326 }
327 return prng_reseed(rng, entropy, entropy_len,
328 additional_input, additional_input_len);
329 }
330
331 /*
332 * build some fast inline functions for adding.
333 */
334 #define PRNG_ADD_CARRY_ONLY(dest, start, carry) \
335 { \
336 int k1; \
337 for (k1 = start; carry && k1 >= 0; k1--) { \
338 carry = !(++dest[k1]); \
339 } \
340 }
341
342 /*
343 * NOTE: dest must be an array for the following to work.
344 */
345 #define PRNG_ADD_BITS(dest, dest_len, add, len, carry) \
346 carry = 0; \
347 PORT_Assert((dest_len) >= (len)); \
348 { \
349 int k1, k2; \
350 for (k1 = dest_len - 1, k2 = len - 1; k2 >= 0; --k1, --k2) { \
351 carry += dest[k1] + add[k2]; \
352 dest[k1] = (PRUint8)carry; \
353 carry >>= 8; \
354 } \
355 }
356
357 #define PRNG_ADD_BITS_AND_CARRY(dest, dest_len, add, len, carry) \
358 PRNG_ADD_BITS(dest, dest_len, add, len, carry) \
359 PRNG_ADD_CARRY_ONLY(dest, dest_len - len - 1, carry)
360
361 /*
362 * This function expands the internal state of the prng to fulfill any number
363 * of bytes we need for this request. We only use this call if we need more
364 * than can be supplied by a single call to SHA256_HashBuf.
365 *
366 * This function is specified in NIST SP 800-90 section 10.1.1.4, Hashgen
367 */
368 static void
prng_Hashgen(RNGContext * rng,PRUint8 * returned_bytes,unsigned int no_of_returned_bytes)369 prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
370 unsigned int no_of_returned_bytes)
371 {
372 PRUint8 data[VSize(rng)];
373 PRUint8 thisHash[SHA256_LENGTH];
374
375 PORT_Memcpy(data, V(rng), VSize(rng));
376 while (no_of_returned_bytes) {
377 SHA256Context ctx;
378 unsigned int len;
379 unsigned int carry;
380
381 SHA256_Begin(&ctx);
382 SHA256_Update(&ctx, data, sizeof data);
383 SHA256_End(&ctx, thisHash, &len, SHA256_LENGTH);
384 if (no_of_returned_bytes < SHA256_LENGTH) {
385 len = no_of_returned_bytes;
386 }
387 PORT_Memcpy(returned_bytes, thisHash, len);
388 returned_bytes += len;
389 no_of_returned_bytes -= len;
390 /* The carry parameter is a bool (increment or not).
391 * This increments data if no_of_returned_bytes is not zero */
392 carry = no_of_returned_bytes;
393 PRNG_ADD_CARRY_ONLY(data, (sizeof data) - 1, carry);
394 SHA256_DestroyContext(&ctx, PR_FALSE);
395 }
396 PORT_Memset(data, 0, sizeof data);
397 PORT_Memset(thisHash, 0, sizeof thisHash);
398 }
399
400 /*
401 * Generates new random bytes and advances the internal prng state.
402 * additional bytes are only used in algorithm testing.
403 *
404 * This function is specified in NIST SP 800-90 section 10.1.1.4
405 */
406 static SECStatus
prng_generateNewBytes(RNGContext * rng,PRUint8 * returned_bytes,unsigned int no_of_returned_bytes,const PRUint8 * additional_input,unsigned int additional_input_len)407 prng_generateNewBytes(RNGContext *rng,
408 PRUint8 *returned_bytes, unsigned int no_of_returned_bytes,
409 const PRUint8 *additional_input,
410 unsigned int additional_input_len)
411 {
412 PRUint8 H[SHA256_LENGTH]; /* both H and w since they
413 * aren't used concurrently */
414 unsigned int carry;
415
416 if (!rng->isValid) {
417 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
418 return SECFailure;
419 }
420 /* This code only triggers during tests, normal
421 * prng operation does not use additional_input */
422 if (additional_input) {
423 SHA256Context ctx;
424 /* NIST SP 800-90 defines two temporaries in their calculations,
425 * w and H. These temporaries are the same lengths, and used
426 * at different times, so we use the following macro to collapse
427 * them to the same variable, but keeping their unique names for
428 * easy comparison to the spec */
429 #define w H
430 rng->V_type = prngAdditionalDataType;
431 SHA256_Begin(&ctx);
432 SHA256_Update(&ctx, rng->V_Data, sizeof rng->V_Data);
433 SHA256_Update(&ctx, additional_input, additional_input_len);
434 SHA256_End(&ctx, w, NULL, sizeof w);
435 PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w, carry)
436 PORT_Memset(w, 0, sizeof w);
437 SHA256_DestroyContext(&ctx, PR_FALSE);
438 #undef w
439 }
440
441 if (no_of_returned_bytes == SHA256_LENGTH) {
442 /* short_cut to hashbuf and a couple of copies and clears */
443 SHA256_HashBuf(returned_bytes, V(rng), VSize(rng));
444 } else {
445 prng_Hashgen(rng, returned_bytes, no_of_returned_bytes);
446 }
447 /* advance our internal state... */
448 rng->V_type = prngGenerateByteType;
449 SHA256_HashBuf(H, rng->V_Data, sizeof rng->V_Data);
450 PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), H, sizeof H, carry)
451 PRNG_ADD_BITS(V(rng), VSize(rng), rng->C, sizeof rng->C, carry);
452 PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter,
453 sizeof rng->reseed_counter, carry)
454 carry = 1;
455 PRNG_ADD_CARRY_ONLY(rng->reseed_counter, (sizeof rng->reseed_counter) - 1, carry);
456
457 /* if the prng failed, don't return any output, signal softoken */
458 PORT_Memset(H, 0, sizeof H);
459 if (!rng->isValid) {
460 PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
461 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
462 return SECFailure;
463 }
464 return SECSuccess;
465 }
466
467 /* Use NSPR to prevent RNG_RNGInit from being called from separate
468 * threads, creating a race condition.
469 */
470 static const PRCallOnceType pristineCallOnce;
471 static PRCallOnceType coRNGInit;
472 static PRStatus
rng_init(void)473 rng_init(void)
474 {
475 PRUint8 bytes[PRNG_SEEDLEN * 2]; /* entropy + nonce */
476 SECStatus rv = SECSuccess;
477
478 if (globalrng == NULL) {
479 /* bytes needs to have enough space to hold
480 * a SHA256 hash value. Blow up at compile time if this isn't true */
481 PR_STATIC_ASSERT(sizeof(bytes) >= SHA256_LENGTH);
482 /* create a new global RNG context */
483 globalrng = &theGlobalRng;
484 PORT_Assert(NULL == globalrng->lock);
485 /* create a lock for it */
486 globalrng->lock = PZ_NewLock(nssILockOther);
487 if (globalrng->lock == NULL) {
488 globalrng = NULL;
489 PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
490 return PR_FAILURE;
491 }
492
493 /* Try to get some seed data for the RNG */
494 rv = prng_getEntropy(bytes, sizeof bytes);
495 if (rv == SECSuccess) {
496 /* if this is our first call, instantiate, otherwise reseed
497 * prng_instantiate gets a new clean state, we want to mix
498 * any previous entropy we may have collected */
499 if (V(globalrng)[0] == 0) {
500 rv = prng_instantiate(globalrng, bytes, sizeof bytes);
501 } else {
502 rv = prng_reseed_test(globalrng, bytes, sizeof bytes, NULL, 0);
503 }
504 memset(bytes, 0, sizeof bytes);
505 } else {
506 PZ_DestroyLock(globalrng->lock);
507 globalrng->lock = NULL;
508 globalrng = NULL;
509 return PR_FAILURE;
510 }
511 if (rv != SECSuccess) {
512 return PR_FAILURE;
513 }
514
515 /* the RNG is in a valid state */
516 globalrng->isValid = PR_TRUE;
517 globalrng->isKatTest = PR_FALSE;
518
519 /* fetch one random value so that we can populate rng->oldV for our
520 * continous random number test. */
521 prng_generateNewBytes(globalrng, bytes, SHA256_LENGTH, NULL, 0);
522
523 /* Fetch more entropy into the PRNG */
524 RNG_SystemInfoForRNG();
525 }
526 return PR_SUCCESS;
527 }
528
529 /*
530 * Clean up the global RNG context
531 */
532 static void
prng_freeRNGContext(RNGContext * rng)533 prng_freeRNGContext(RNGContext *rng)
534 {
535 PRUint8 inputhash[VSize(rng) + (sizeof rng->C)];
536
537 /* destroy context lock */
538 SKIP_AFTER_FORK(PZ_DestroyLock(globalrng->lock));
539
540 /* zero global RNG context except for C & V to preserve entropy */
541 prng_Hash_df(inputhash, sizeof rng->C, rng->C, sizeof rng->C, NULL, 0);
542 prng_Hash_df(&inputhash[sizeof rng->C], VSize(rng), V(rng), VSize(rng),
543 NULL, 0);
544 memset(rng, 0, sizeof *rng);
545 memcpy(rng->C, inputhash, sizeof rng->C);
546 memcpy(V(rng), &inputhash[sizeof rng->C], VSize(rng));
547
548 memset(inputhash, 0, sizeof inputhash);
549 }
550
551 /*
552 * Public functions
553 */
554
555 /*
556 * Initialize the global RNG context and give it some seed input taken
557 * from the system. This function is thread-safe and will only allow
558 * the global context to be initialized once. The seed input is likely
559 * small, so it is imperative that RNG_RandomUpdate() be called with
560 * additional seed data before the generator is used. A good way to
561 * provide the generator with additional entropy is to call
562 * RNG_SystemInfoForRNG(). Note that C_Initialize() does exactly that.
563 */
564 SECStatus
RNG_RNGInit(void)565 RNG_RNGInit(void)
566 {
567 /* Allow only one call to initialize the context */
568 PR_CallOnce(&coRNGInit, rng_init);
569 /* Make sure there is a context */
570 return (globalrng != NULL) ? SECSuccess : SECFailure;
571 }
572
573 /*
574 ** Update the global random number generator with more seeding
575 ** material.
576 */
577 SECStatus
RNG_RandomUpdate(const void * data,size_t bytes)578 RNG_RandomUpdate(const void *data, size_t bytes)
579 {
580 SECStatus rv;
581
582 /* Make sure our assumption that size_t is unsigned is true */
583 PR_STATIC_ASSERT(((size_t)-1) > (size_t)1);
584
585 #if defined(NS_PTR_GT_32) || (defined(NSS_USE_64) && !defined(NS_PTR_LE_32))
586 /*
587 * NIST 800-90 requires us to verify our inputs. This value can
588 * come from the application, so we need to make sure it's within the
589 * spec. The spec says it must be less than 2^32 bytes (2^35 bits).
590 * This can only happen if size_t is greater than 32 bits (i.e. on
591 * most 64 bit platforms). The 90% case (perhaps 100% case), size_t
592 * is less than or equal to 32 bits if the platform is not 64 bits, and
593 * greater than 32 bits if it is a 64 bit platform. The corner
594 * cases are handled with explicit defines NS_PTR_GT_32 and NS_PTR_LE_32.
595 *
596 * In general, neither NS_PTR_GT_32 nor NS_PTR_LE_32 will need to be
597 * defined. If you trip over the next two size ASSERTS at compile time,
598 * you will need to define them for your platform.
599 *
600 * if 'sizeof(size_t) > 4' is triggered it means that we were expecting
601 * sizeof(size_t) to be greater than 4, but it wasn't. Setting
602 * NS_PTR_LE_32 will correct that mistake.
603 *
604 * if 'sizeof(size_t) <= 4' is triggered, it means that we were expecting
605 * sizeof(size_t) to be less than or equal to 4, but it wasn't. Setting
606 * NS_PTR_GT_32 will correct that mistake.
607 */
608
609 PR_STATIC_ASSERT(sizeof(size_t) > 4);
610
611 if (bytes > (size_t)PRNG_MAX_ADDITIONAL_BYTES) {
612 bytes = PRNG_MAX_ADDITIONAL_BYTES;
613 }
614 #else
615 PR_STATIC_ASSERT(sizeof(size_t) <= 4);
616 #endif
617
618 PZ_Lock(globalrng->lock);
619 /* if we're passed more than our additionalDataCache, simply
620 * call reseed with that data */
621 if (bytes > sizeof(globalrng->additionalDataCache)) {
622 rv = prng_reseed_test(globalrng, NULL, 0, data, (unsigned int)bytes);
623 /* if we aren't going to fill or overflow the buffer, just cache it */
624 } else if (bytes < ((sizeof globalrng->additionalDataCache) - globalrng->additionalAvail)) {
625 PORT_Memcpy(globalrng->additionalDataCache + globalrng->additionalAvail,
626 data, bytes);
627 globalrng->additionalAvail += (PRUint32)bytes;
628 rv = SECSuccess;
629 } else {
630 /* we are going to fill or overflow the buffer. In this case we will
631 * fill the entropy buffer, reseed with it, start a new buffer with the
632 * remainder. We know the remainder will fit in the buffer because
633 * we already handled the case where bytes > the size of the buffer.
634 */
635 size_t bufRemain = (sizeof globalrng->additionalDataCache) - globalrng->additionalAvail;
636 /* fill the rest of the buffer */
637 if (bufRemain) {
638 PORT_Memcpy(globalrng->additionalDataCache + globalrng->additionalAvail,
639 data, bufRemain);
640 data = ((unsigned char *)data) + bufRemain;
641 bytes -= bufRemain;
642 }
643 /* reseed from buffer */
644 rv = prng_reseed_test(globalrng, NULL, 0,
645 globalrng->additionalDataCache,
646 sizeof globalrng->additionalDataCache);
647
648 /* copy the rest into the cache */
649 PORT_Memcpy(globalrng->additionalDataCache, data, bytes);
650 globalrng->additionalAvail = (PRUint32)bytes;
651 }
652
653 PZ_Unlock(globalrng->lock);
654 return rv;
655 }
656
657 /*
658 ** Generate some random bytes, using the global random number generator
659 ** object.
660 */
661 static SECStatus
prng_GenerateGlobalRandomBytes(RNGContext * rng,void * dest,size_t len)662 prng_GenerateGlobalRandomBytes(RNGContext *rng,
663 void *dest, size_t len)
664 {
665 SECStatus rv = SECSuccess;
666 PRUint8 *output = dest;
667 /* check for a valid global RNG context */
668 PORT_Assert(rng != NULL);
669 if (rng == NULL) {
670 PORT_SetError(SEC_ERROR_INVALID_ARGS);
671 return SECFailure;
672 }
673 /* FIPS limits the amount of entropy available in a single request */
674 if (len > PRNG_MAX_REQUEST_SIZE) {
675 PORT_SetError(SEC_ERROR_INVALID_ARGS);
676 return SECFailure;
677 }
678 /* --- LOCKED --- */
679 PZ_Lock(rng->lock);
680 /* Check the amount of seed data in the generator. If not enough,
681 * don't produce any data.
682 */
683 if (rng->reseed_counter[0] >= RESEED_VALUE) {
684 rv = prng_reseed_test(rng, NULL, 0, NULL, 0);
685 PZ_Unlock(rng->lock);
686 if (rv != SECSuccess) {
687 return rv;
688 }
689 RNG_SystemInfoForRNG();
690 PZ_Lock(rng->lock);
691 }
692 /*
693 * see if we have enough bytes to fulfill the request.
694 */
695 if (len <= rng->dataAvail) {
696 memcpy(output, rng->data + ((sizeof rng->data) - rng->dataAvail), len);
697 memset(rng->data + ((sizeof rng->data) - rng->dataAvail), 0, len);
698 rng->dataAvail -= len;
699 rv = SECSuccess;
700 /* if we are asking for a small number of bytes, cache the rest of
701 * the bytes */
702 } else if (len < sizeof rng->data) {
703 rv = prng_generateNewBytes(rng, rng->data, sizeof rng->data,
704 rng->additionalAvail ? rng->additionalDataCache : NULL,
705 rng->additionalAvail);
706 rng->additionalAvail = 0;
707 if (rv == SECSuccess) {
708 memcpy(output, rng->data, len);
709 memset(rng->data, 0, len);
710 rng->dataAvail = (sizeof rng->data) - len;
711 }
712 /* we are asking for lots of bytes, just ask the generator to pass them */
713 } else {
714 rv = prng_generateNewBytes(rng, output, len,
715 rng->additionalAvail ? rng->additionalDataCache : NULL,
716 rng->additionalAvail);
717 rng->additionalAvail = 0;
718 }
719 PZ_Unlock(rng->lock);
720 /* --- UNLOCKED --- */
721 return rv;
722 }
723
724 /*
725 ** Generate some random bytes, using the global random number generator
726 ** object.
727 */
728 SECStatus
RNG_GenerateGlobalRandomBytes(void * dest,size_t len)729 RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
730 {
731 return prng_GenerateGlobalRandomBytes(globalrng, dest, len);
732 }
733
734 void
RNG_RNGShutdown(void)735 RNG_RNGShutdown(void)
736 {
737 /* check for a valid global RNG context */
738 PORT_Assert(globalrng != NULL);
739 if (globalrng == NULL) {
740 /* Should set a "not initialized" error code. */
741 PORT_SetError(SEC_ERROR_NO_MEMORY);
742 return;
743 }
744 /* clear */
745 prng_freeRNGContext(globalrng);
746 globalrng = NULL;
747 /* reset the callonce struct to allow a new call to RNG_RNGInit() */
748 coRNGInit = pristineCallOnce;
749 }
750
751 /*
752 * Test case interface. used by fips testing and power on self test
753 */
754 /* make sure the test context is separate from the global context, This
755 * allows us to test the internal random number generator without losing
756 * entropy we may have previously collected. */
757 RNGContext testContext;
758
759 SECStatus
PRNGTEST_Instantiate_Kat(const PRUint8 * entropy,unsigned int entropy_len,const PRUint8 * nonce,unsigned int nonce_len,const PRUint8 * personal_string,unsigned int ps_len)760 PRNGTEST_Instantiate_Kat(const PRUint8 *entropy, unsigned int entropy_len,
761 const PRUint8 *nonce, unsigned int nonce_len,
762 const PRUint8 *personal_string, unsigned int ps_len)
763 {
764 testContext.isKatTest = PR_TRUE;
765 return PRNGTEST_Instantiate(entropy, entropy_len,
766 nonce, nonce_len,
767 personal_string, ps_len);
768 }
769
770 /*
771 * Test vector API. Use NIST SP 800-90 general interface so one of the
772 * other NIST SP 800-90 algorithms may be used in the future.
773 */
774 SECStatus
PRNGTEST_Instantiate(const PRUint8 * entropy,unsigned int entropy_len,const PRUint8 * nonce,unsigned int nonce_len,const PRUint8 * personal_string,unsigned int ps_len)775 PRNGTEST_Instantiate(const PRUint8 *entropy, unsigned int entropy_len,
776 const PRUint8 *nonce, unsigned int nonce_len,
777 const PRUint8 *personal_string, unsigned int ps_len)
778 {
779 int bytes_len = entropy_len + nonce_len + ps_len;
780 PRUint8 *bytes = NULL;
781 SECStatus rv;
782
783 if (entropy_len < 256 / PR_BITS_PER_BYTE) {
784 PORT_SetError(SEC_ERROR_NEED_RANDOM);
785 return SECFailure;
786 }
787
788 bytes = PORT_Alloc(bytes_len);
789 if (bytes == NULL) {
790 PORT_SetError(SEC_ERROR_NO_MEMORY);
791 return SECFailure;
792 }
793 /* concatenate the various inputs, internally NSS only instantiates with
794 * a single long string */
795 PORT_Memcpy(bytes, entropy, entropy_len);
796 if (nonce) {
797 PORT_Memcpy(&bytes[entropy_len], nonce, nonce_len);
798 } else {
799 PORT_Assert(nonce_len == 0);
800 }
801 if (personal_string) {
802 PORT_Memcpy(&bytes[entropy_len + nonce_len], personal_string, ps_len);
803 } else {
804 PORT_Assert(ps_len == 0);
805 }
806 rv = prng_instantiate(&testContext, bytes, bytes_len);
807 PORT_ZFree(bytes, bytes_len);
808 if (rv == SECFailure) {
809 return SECFailure;
810 }
811 testContext.isValid = PR_TRUE;
812 return SECSuccess;
813 }
814
815 SECStatus
PRNGTEST_Reseed(const PRUint8 * entropy,unsigned int entropy_len,const PRUint8 * additional,unsigned int additional_len)816 PRNGTEST_Reseed(const PRUint8 *entropy, unsigned int entropy_len,
817 const PRUint8 *additional, unsigned int additional_len)
818 {
819 if (!testContext.isValid) {
820 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
821 return SECFailure;
822 }
823 /* This magic input tells us to set the reseed count to it's max count,
824 * so we can simulate PRNGTEST_Generate reaching max reseed count */
825 if ((entropy == NULL) && (entropy_len == 0) &&
826 (additional == NULL) && (additional_len == 0)) {
827 testContext.reseed_counter[0] = RESEED_VALUE;
828 return SECSuccess;
829 }
830 return prng_reseed(&testContext, entropy, entropy_len, additional,
831 additional_len);
832 }
833
834 SECStatus
PRNGTEST_Generate(PRUint8 * bytes,unsigned int bytes_len,const PRUint8 * additional,unsigned int additional_len)835 PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len,
836 const PRUint8 *additional, unsigned int additional_len)
837 {
838 SECStatus rv;
839 if (!testContext.isValid) {
840 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
841 return SECFailure;
842 }
843 /* replicate reseed test from prng_GenerateGlobalRandomBytes */
844 if (testContext.reseed_counter[0] >= RESEED_VALUE) {
845 rv = prng_reseed(&testContext, NULL, 0, NULL, 0);
846 if (rv != SECSuccess) {
847 return rv;
848 }
849 }
850 return prng_generateNewBytes(&testContext, bytes, bytes_len,
851 additional, additional_len);
852 }
853
854 SECStatus
PRNGTEST_Uninstantiate()855 PRNGTEST_Uninstantiate()
856 {
857 if (!testContext.isValid) {
858 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
859 return SECFailure;
860 }
861 PORT_Memset(&testContext, 0, sizeof testContext);
862 return SECSuccess;
863 }
864
865 SECStatus
PRNGTEST_RunHealthTests()866 PRNGTEST_RunHealthTests()
867 {
868 static const PRUint8 entropy[] = {
869 0x8e, 0x9c, 0x0d, 0x25, 0x75, 0x22, 0x04, 0xf9,
870 0xc5, 0x79, 0x10, 0x8b, 0x23, 0x79, 0x37, 0x14,
871 0x9f, 0x2c, 0xc7, 0x0b, 0x39, 0xf8, 0xee, 0xef,
872 0x95, 0x0c, 0x97, 0x59, 0xfc, 0x0a, 0x85, 0x41,
873 0x76, 0x9d, 0x6d, 0x67, 0x00, 0x4e, 0x19, 0x12,
874 0x02, 0x16, 0x53, 0xea, 0xf2, 0x73, 0xd7, 0xd6,
875 0x7f, 0x7e, 0xc8, 0xae, 0x9c, 0x09, 0x99, 0x7d,
876 0xbb, 0x9e, 0x48, 0x7f, 0xbb, 0x96, 0x46, 0xb3,
877 0x03, 0x75, 0xf8, 0xc8, 0x69, 0x45, 0x3f, 0x97,
878 0x5e, 0x2e, 0x48, 0xe1, 0x5d, 0x58, 0x97, 0x4c
879 };
880 static const PRUint8 rng_known_result[] = {
881 0x16, 0xe1, 0x8c, 0x57, 0x21, 0xd8, 0xf1, 0x7e,
882 0x5a, 0xa0, 0x16, 0x0b, 0x7e, 0xa6, 0x25, 0xb4,
883 0x24, 0x19, 0xdb, 0x54, 0xfa, 0x35, 0x13, 0x66,
884 0xbb, 0xaa, 0x2a, 0x1b, 0x22, 0x33, 0x2e, 0x4a,
885 0x14, 0x07, 0x9d, 0x52, 0xfc, 0x73, 0x61, 0x48,
886 0xac, 0xc1, 0x22, 0xfc, 0xa4, 0xfc, 0xac, 0xa4,
887 0xdb, 0xda, 0x5b, 0x27, 0x33, 0xc4, 0xb3
888 };
889 static const PRUint8 reseed_entropy[] = {
890 0xc6, 0x0b, 0x0a, 0x30, 0x67, 0x07, 0xf4, 0xe2,
891 0x24, 0xa7, 0x51, 0x6f, 0x5f, 0x85, 0x3e, 0x5d,
892 0x67, 0x97, 0xb8, 0x3b, 0x30, 0x9c, 0x7a, 0xb1,
893 0x52, 0xc6, 0x1b, 0xc9, 0x46, 0xa8, 0x62, 0x79
894 };
895 static const PRUint8 additional_input[] = {
896 0x86, 0x82, 0x28, 0x98, 0xe7, 0xcb, 0x01, 0x14,
897 0xae, 0x87, 0x4b, 0x1d, 0x99, 0x1b, 0xc7, 0x41,
898 0x33, 0xff, 0x33, 0x66, 0x40, 0x95, 0x54, 0xc6,
899 0x67, 0x4d, 0x40, 0x2a, 0x1f, 0xf9, 0xeb, 0x65
900 };
901 static const PRUint8 rng_reseed_result[] = {
902 0x02, 0x0c, 0xc6, 0x17, 0x86, 0x49, 0xba, 0xc4,
903 0x7b, 0x71, 0x35, 0x05, 0xf0, 0xdb, 0x4a, 0xc2,
904 0x2c, 0x38, 0xc1, 0xa4, 0x42, 0xe5, 0x46, 0x4a,
905 0x7d, 0xf0, 0xbe, 0x47, 0x88, 0xb8, 0x0e, 0xc6,
906 0x25, 0x2b, 0x1d, 0x13, 0xef, 0xa6, 0x87, 0x96,
907 0xa3, 0x7d, 0x5b, 0x80, 0xc2, 0x38, 0x76, 0x61,
908 0xc7, 0x80, 0x5d, 0x0f, 0x05, 0x76, 0x85
909 };
910 static const PRUint8 rng_no_reseed_result[] = {
911 0xc4, 0x40, 0x41, 0x8c, 0xbf, 0x2f, 0x70, 0x23,
912 0x88, 0xf2, 0x7b, 0x30, 0xc3, 0xca, 0x1e, 0xf3,
913 0xef, 0x53, 0x81, 0x5d, 0x30, 0xed, 0x4c, 0xf1,
914 0xff, 0x89, 0xa5, 0xee, 0x92, 0xf8, 0xc0, 0x0f,
915 0x88, 0x53, 0xdf, 0xb6, 0x76, 0xf0, 0xaa, 0xd3,
916 0x2e, 0x1d, 0x64, 0x37, 0x3e, 0xe8, 0x4a, 0x02,
917 0xff, 0x0a, 0x7f, 0xe5, 0xe9, 0x2b, 0x6d
918 };
919
920 SECStatus rng_status = SECSuccess;
921 PR_STATIC_ASSERT(sizeof(rng_known_result) >= sizeof(rng_reseed_result));
922 PRUint8 result[sizeof(rng_known_result)];
923
924 /********************************************/
925 /* First test instantiate error path. */
926 /* In this case we supply enough entropy, */
927 /* but not enough seed. This will trigger */
928 /* the code that checks for a entropy */
929 /* source failure. */
930 /********************************************/
931 rng_status = PRNGTEST_Instantiate(entropy, 256 / PR_BITS_PER_BYTE,
932 NULL, 0, NULL, 0);
933 if (rng_status == SECSuccess) {
934 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
935 return SECFailure;
936 }
937 if (PORT_GetError() != SEC_ERROR_NEED_RANDOM) {
938 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
939 return SECFailure;
940 }
941 /* we failed with the proper error code, we can continue */
942
943 /********************************************/
944 /* Generate random bytes with a known seed. */
945 /********************************************/
946 rng_status = PRNGTEST_Instantiate(entropy, sizeof entropy,
947 NULL, 0, NULL, 0);
948 if (rng_status != SECSuccess) {
949 /* Error set by PRNGTEST_Instantiate */
950 return SECFailure;
951 }
952 rng_status = PRNGTEST_Generate(result, sizeof rng_known_result, NULL, 0);
953 if ((rng_status != SECSuccess) ||
954 (PORT_Memcmp(result, rng_known_result,
955 sizeof rng_known_result) != 0)) {
956 PRNGTEST_Uninstantiate();
957 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
958 return SECFailure;
959 }
960 rng_status = PRNGTEST_Reseed(reseed_entropy, sizeof reseed_entropy,
961 additional_input, sizeof additional_input);
962 if (rng_status != SECSuccess) {
963 /* Error set by PRNG_Reseed */
964 PRNGTEST_Uninstantiate();
965 return SECFailure;
966 }
967 rng_status = PRNGTEST_Generate(result, sizeof rng_reseed_result, NULL, 0);
968 if ((rng_status != SECSuccess) ||
969 (PORT_Memcmp(result, rng_reseed_result,
970 sizeof rng_reseed_result) != 0)) {
971 PRNGTEST_Uninstantiate();
972 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
973 return SECFailure;
974 }
975 /* This magic forces the reseed count to it's max count, so we can see if
976 * PRNGTEST_Generate will actually when it reaches it's count */
977 rng_status = PRNGTEST_Reseed(NULL, 0, NULL, 0);
978 if (rng_status != SECSuccess) {
979 PRNGTEST_Uninstantiate();
980 /* Error set by PRNG_Reseed */
981 return SECFailure;
982 }
983 /* This generate should now reseed */
984 rng_status = PRNGTEST_Generate(result, sizeof rng_reseed_result, NULL, 0);
985 if ((rng_status != SECSuccess) ||
986 /* NOTE we fail if the result is equal to the no_reseed_result.
987 * no_reseed_result is the value we would have gotten if we didn't
988 * do an automatic reseed in PRNGTEST_Generate */
989 (PORT_Memcmp(result, rng_no_reseed_result,
990 sizeof rng_no_reseed_result) == 0)) {
991 PRNGTEST_Uninstantiate();
992 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
993 return SECFailure;
994 }
995 /* make sure reseed fails when we don't supply enough entropy */
996 rng_status = PRNGTEST_Reseed(reseed_entropy, 4, NULL, 0);
997 if (rng_status == SECSuccess) {
998 PRNGTEST_Uninstantiate();
999 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1000 return SECFailure;
1001 }
1002 if (PORT_GetError() != SEC_ERROR_NEED_RANDOM) {
1003 PRNGTEST_Uninstantiate();
1004 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1005 return SECFailure;
1006 }
1007 rng_status = PRNGTEST_Uninstantiate();
1008 if (rng_status != SECSuccess) {
1009 /* Error set by PRNG_Uninstantiate */
1010 return rng_status;
1011 }
1012 /* make sure uninstantiate fails if the contest is not initiated (also tests
1013 * if the context was cleared in the previous Uninstantiate) */
1014 rng_status = PRNGTEST_Uninstantiate();
1015 if (rng_status == SECSuccess) {
1016 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1017 return SECFailure;
1018 }
1019 if (PORT_GetError() != SEC_ERROR_LIBRARY_FAILURE) {
1020 return rng_status;
1021 }
1022
1023 return SECSuccess;
1024 }
1025