// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014
//#define __TPM_RNG_FOR_DEBUG__
//
//
// Introduction
//
// This file contains the interface to the OpenSSL() random number functions.
//
// Includes
//
#include "OsslCryptoEngine.h"
int s_entropyFailure;
//
//
// Functions
//
// _cpri__RngStartup()
//
// This function is called to initialize the random number generator. It collects entropy from the platform to
// seed the OpenSSL() random number generator.
//
LIB_EXPORT BOOL
_cpri__RngStartup(void)
{
UINT32 entropySize;
BYTE entropy[MAX_RNG_ENTROPY_SIZE];
INT32 returnedSize = 0;
// Initialize the entropy source
s_entropyFailure = FALSE;
_plat__GetEntropy(NULL, 0);
// Collect entropy until we have enough
for(entropySize = 0;
entropySize < MAX_RNG_ENTROPY_SIZE && returnedSize >= 0;
entropySize += returnedSize)
{
returnedSize = _plat__GetEntropy(&entropy[entropySize],
MAX_RNG_ENTROPY_SIZE - entropySize);
}
// Got some entropy on the last call and did not get an error
if(returnedSize > 0)
{
// Seed OpenSSL with entropy
RAND_seed(entropy, entropySize);
}
else
{
s_entropyFailure = TRUE;
}
return s_entropyFailure == FALSE;
}
//
//
// _cpri__DrbgGetPutState()
//
// This function is used to set the state of the RNG (direction == PUT_STATE) or to recover the state of the
// RNG (direction == GET_STATE).
//
//
//
// NOTE: This not currently supported on OpenSSL() version.
//
LIB_EXPORT CRYPT_RESULT
_cpri__DrbgGetPutState(
GET_PUT direction,
int bufferSize,
BYTE *buffer
)
{
UNREFERENCED_PARAMETER(direction);
UNREFERENCED_PARAMETER(bufferSize);
UNREFERENCED_PARAMETER(buffer);
return CRYPT_SUCCESS; // Function is not implemented
}
//
//
// _cpri__StirRandom()
//
// This function is called to add external entropy to the OpenSSL() random number generator.
//
LIB_EXPORT CRYPT_RESULT
_cpri__StirRandom(
INT32 entropySize,
BYTE *entropy
)
{
if (entropySize >= 0)
{
RAND_add((const void *)entropy, (int) entropySize, 0.0);
}
return CRYPT_SUCCESS;
}
//
//
// _cpri__GenerateRandom()
//
// This function is called to get a string of random bytes from the OpenSSL() random number generator. The
// return value is the number of bytes placed in the buffer. If the number of bytes returned is not equal to the
// number of bytes requested (randomSize) it is indicative of a failure of the OpenSSL() random number
// generator and is probably fatal.
//
LIB_EXPORT UINT16
_cpri__GenerateRandom(
INT32 randomSize,
BYTE *buffer
)
{
//
// We don't do negative sizes or ones that are too large
if (randomSize < 0 || randomSize > UINT16_MAX)
return 0;
// RAND_bytes uses 1 for success and we use 0
if(RAND_bytes(buffer, randomSize) == 1)
return (UINT16)randomSize;
else
return 0;
}
//
//
//
// _cpri__GenerateSeededRandom()
//
// This funciton is used to generate a pseudo-random number from some seed values This funciton returns
// the same result each time it is called with the same parameters
//
LIB_EXPORT UINT16
_cpri__GenerateSeededRandom(
INT32 randomSize, // IN: the size of the request
BYTE *random, // OUT: receives the data
TPM_ALG_ID hashAlg, // IN: used by KDF version but not here
TPM2B *seed, // IN: the seed value
const char *label, // IN: a label string (optional)
TPM2B *partyU, // IN: other data (oprtional)
TPM2B *partyV // IN: still more (optional)
)
{
return (_cpri__KDFa(hashAlg, seed, label, partyU, partyV,
randomSize * 8, random, NULL, FALSE));
}