示例#1
0
文件: drbg.c 项目: emaldona/nss
static PRStatus
rng_init(void)
{
    PRUint8 bytes[PRNG_SEEDLEN * 2]; /* entropy + nonce */
    unsigned int numBytes;
    SECStatus rv = SECSuccess;

    if (globalrng == NULL) {
        /* bytes needs to have enough space to hold
     * a SHA256 hash value. Blow up at compile time if this isn't true */
        PR_STATIC_ASSERT(sizeof(bytes) >= SHA256_LENGTH);
        /* create a new global RNG context */
        globalrng = &theGlobalRng;
        PORT_Assert(NULL == globalrng->lock);
        /* create a lock for it */
        globalrng->lock = PZ_NewLock(nssILockOther);
        if (globalrng->lock == NULL) {
            globalrng = NULL;
            PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
            return PR_FAILURE;
        }

        /* Try to get some seed data for the RNG */
        numBytes = (unsigned int)RNG_SystemRNG(bytes, sizeof bytes);
        PORT_Assert(numBytes == 0 || numBytes == sizeof bytes);
        if (numBytes != 0) {
            /* if this is our first call,  instantiate, otherwise reseed
             * prng_instantiate gets a new clean state, we want to mix
             * any previous entropy we may have collected */
            if (V(globalrng)[0] == 0) {
                rv = prng_instantiate(globalrng, bytes, numBytes);
            } else {
                rv = prng_reseed_test(globalrng, bytes, numBytes, NULL, 0);
            }
            memset(bytes, 0, numBytes);
        } else {
            PZ_DestroyLock(globalrng->lock);
            globalrng->lock = NULL;
            globalrng = NULL;
            return PR_FAILURE;
        }
        if (rv != SECSuccess) {
            return PR_FAILURE;
        }

        /* the RNG is in a valid state */
        globalrng->isValid = PR_TRUE;
        globalrng->isKatTest = PR_FALSE;

        /* fetch one random value so that we can populate rng->oldV for our
         * continous random number test. */
        prng_generateNewBytes(globalrng, bytes, SHA256_LENGTH, NULL, 0);

        /* Fetch more entropy into the PRNG */
        RNG_SystemInfoForRNG();
    }
    return PR_SUCCESS;
}
示例#2
0
/*
 * Test vector API. Use NIST SP 800-90 general interface so one of the
 * other NIST SP 800-90 algorithms may be used in the future.
 */
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)
{
   int bytes_len = entropy_len + nonce_len + ps_len;
   PRUint8 *bytes = NULL;
   SECStatus rv;

   if (entropy_len < 256/PR_BITS_PER_BYTE) {
	PORT_SetError(SEC_ERROR_NEED_RANDOM);
	return SECFailure;
   }

   bytes = PORT_Alloc(bytes_len);
   if (bytes == NULL) {
	PORT_SetError(SEC_ERROR_NO_MEMORY);
	return SECFailure;
   }
   /* concatenate the various inputs, internally NSS only instantiates with
    * a single long string */
   PORT_Memcpy(bytes, entropy, entropy_len);
   if (nonce) {
	PORT_Memcpy(&bytes[entropy_len], nonce, nonce_len);
   } else {
	PORT_Assert(nonce_len == 0);
   }
   if (personal_string) {
       PORT_Memcpy(&bytes[entropy_len+nonce_len], personal_string, ps_len);
   } else {
	PORT_Assert(ps_len == 0);
   }
   rv = prng_instantiate(&testContext, bytes, bytes_len);
   PORT_ZFree(bytes, bytes_len);
   if (rv == SECFailure) {
	return SECFailure;
   }
   testContext.isValid = PR_TRUE;
   return SECSuccess;
}