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) { testContext.isKatTest = PR_TRUE; return PRNGTEST_Instantiate(entropy, entropy_len, nonce, nonce_len, personal_string, ps_len); }
SECStatus PRNGTEST_RunHealthTests() { static const PRUint8 entropy[] = { 0x8e,0x9c,0x0d,0x25,0x75,0x22,0x04,0xf9, 0xc5,0x79,0x10,0x8b,0x23,0x79,0x37,0x14, 0x9f,0x2c,0xc7,0x0b,0x39,0xf8,0xee,0xef, 0x95,0x0c,0x97,0x59,0xfc,0x0a,0x85,0x41, 0x76,0x9d,0x6d,0x67,0x00,0x4e,0x19,0x12, 0x02,0x16,0x53,0xea,0xf2,0x73,0xd7,0xd6, 0x7f,0x7e,0xc8,0xae,0x9c,0x09,0x99,0x7d, 0xbb,0x9e,0x48,0x7f,0xbb,0x96,0x46,0xb3, 0x03,0x75,0xf8,0xc8,0x69,0x45,0x3f,0x97, 0x5e,0x2e,0x48,0xe1,0x5d,0x58,0x97,0x4c }; static const PRUint8 rng_known_result[] = { 0x16,0xe1,0x8c,0x57,0x21,0xd8,0xf1,0x7e, 0x5a,0xa0,0x16,0x0b,0x7e,0xa6,0x25,0xb4, 0x24,0x19,0xdb,0x54,0xfa,0x35,0x13,0x66, 0xbb,0xaa,0x2a,0x1b,0x22,0x33,0x2e,0x4a, 0x14,0x07,0x9d,0x52,0xfc,0x73,0x61,0x48, 0xac,0xc1,0x22,0xfc,0xa4,0xfc,0xac,0xa4, 0xdb,0xda,0x5b,0x27,0x33,0xc4,0xb3 }; static const PRUint8 reseed_entropy[] = { 0xc6,0x0b,0x0a,0x30,0x67,0x07,0xf4,0xe2, 0x24,0xa7,0x51,0x6f,0x5f,0x85,0x3e,0x5d, 0x67,0x97,0xb8,0x3b,0x30,0x9c,0x7a,0xb1, 0x52,0xc6,0x1b,0xc9,0x46,0xa8,0x62,0x79 }; static const PRUint8 additional_input[] = { 0x86,0x82,0x28,0x98,0xe7,0xcb,0x01,0x14, 0xae,0x87,0x4b,0x1d,0x99,0x1b,0xc7,0x41, 0x33,0xff,0x33,0x66,0x40,0x95,0x54,0xc6, 0x67,0x4d,0x40,0x2a,0x1f,0xf9,0xeb,0x65 }; static const PRUint8 rng_reseed_result[] = { 0x02,0x0c,0xc6,0x17,0x86,0x49,0xba,0xc4, 0x7b,0x71,0x35,0x05,0xf0,0xdb,0x4a,0xc2, 0x2c,0x38,0xc1,0xa4,0x42,0xe5,0x46,0x4a, 0x7d,0xf0,0xbe,0x47,0x88,0xb8,0x0e,0xc6, 0x25,0x2b,0x1d,0x13,0xef,0xa6,0x87,0x96, 0xa3,0x7d,0x5b,0x80,0xc2,0x38,0x76,0x61, 0xc7,0x80,0x5d,0x0f,0x05,0x76,0x85 }; static const PRUint8 rng_no_reseed_result[] = { 0xc4,0x40,0x41,0x8c,0xbf,0x2f,0x70,0x23, 0x88,0xf2,0x7b,0x30,0xc3,0xca,0x1e,0xf3, 0xef,0x53,0x81,0x5d,0x30,0xed,0x4c,0xf1, 0xff,0x89,0xa5,0xee,0x92,0xf8,0xc0,0x0f, 0x88,0x53,0xdf,0xb6,0x76,0xf0,0xaa,0xd3, 0x2e,0x1d,0x64,0x37,0x3e,0xe8,0x4a,0x02, 0xff,0x0a,0x7f,0xe5,0xe9,0x2b,0x6d }; SECStatus rng_status = SECSuccess; PR_STATIC_ASSERT(sizeof(rng_known_result) >= sizeof(rng_reseed_result)); PRUint8 result[sizeof(rng_known_result)]; /********************************************/ /* First test instantiate error path. */ /* In this case we supply enough entropy, */ /* but not enough seed. This will trigger */ /* the code that checks for a entropy */ /* source failure. */ /********************************************/ rng_status = PRNGTEST_Instantiate(entropy, 256/PR_BITS_PER_BYTE, NULL, 0, NULL, 0); if (rng_status == SECSuccess) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } if (PORT_GetError() != SEC_ERROR_NEED_RANDOM) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } /* we failed with the proper error code, we can continue */ /********************************************/ /* Generate random bytes with a known seed. */ /********************************************/ rng_status = PRNGTEST_Instantiate(entropy, sizeof entropy, NULL, 0, NULL, 0); if (rng_status != SECSuccess) { /* Error set by PRNGTEST_Instantiate */ return SECFailure; } rng_status = PRNGTEST_Generate(result, sizeof rng_known_result, NULL, 0); if ( ( rng_status != SECSuccess) || ( PORT_Memcmp( result, rng_known_result, sizeof rng_known_result ) != 0 ) ) { PRNGTEST_Uninstantiate(); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } rng_status = PRNGTEST_Reseed(reseed_entropy, sizeof reseed_entropy, additional_input, sizeof additional_input); if (rng_status != SECSuccess) { /* Error set by PRNG_Reseed */ PRNGTEST_Uninstantiate(); return SECFailure; } rng_status = PRNGTEST_Generate(result, sizeof rng_reseed_result, NULL, 0); if ( ( rng_status != SECSuccess) || ( PORT_Memcmp( result, rng_reseed_result, sizeof rng_reseed_result ) != 0 ) ) { PRNGTEST_Uninstantiate(); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } /* This magic forces the reseed count to it's max count, so we can see if * PRNGTEST_Generate will actually when it reaches it's count */ rng_status = PRNGTEST_Reseed(NULL, 0, NULL, 0); if (rng_status != SECSuccess) { PRNGTEST_Uninstantiate(); /* Error set by PRNG_Reseed */ return SECFailure; } /* This generate should now reseed */ rng_status = PRNGTEST_Generate(result, sizeof rng_reseed_result, NULL, 0); if ( ( rng_status != SECSuccess) || /* NOTE we fail if the result is equal to the no_reseed_result. * no_reseed_result is the value we would have gotten if we didn't * do an automatic reseed in PRNGTEST_Generate */ ( PORT_Memcmp( result, rng_no_reseed_result, sizeof rng_no_reseed_result ) == 0 ) ) { PRNGTEST_Uninstantiate(); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } /* make sure reseed fails when we don't supply enough entropy */ rng_status = PRNGTEST_Reseed(reseed_entropy, 4, NULL, 0); if (rng_status == SECSuccess) { PRNGTEST_Uninstantiate(); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } if (PORT_GetError() != SEC_ERROR_NEED_RANDOM) { PRNGTEST_Uninstantiate(); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } rng_status = PRNGTEST_Uninstantiate(); if (rng_status != SECSuccess) { /* Error set by PRNG_Uninstantiate */ return rng_status; } /* make sure uninstantiate fails if the contest is not initiated (also tests * if the context was cleared in the previous Uninstantiate) */ rng_status = PRNGTEST_Uninstantiate(); if (rng_status == SECSuccess) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } if (PORT_GetError() != SEC_ERROR_LIBRARY_FAILURE) { return rng_status; } return SECSuccess; }