security/nss/lib/freebl/drbg.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial