1// This file was extracted from the TCG Published 2// Trusted Platform Module Library 3// Part 4: Supporting Routines 4// Family "2.0" 5// Level 00 Revision 01.16 6// October 30, 2014 7 8//#define __TPM_RNG_FOR_DEBUG__ 9// 10// 11// Introduction 12// 13// This file contains the interface to the OpenSSL() random number functions. 14// 15// Includes 16// 17#include "OsslCryptoEngine.h" 18int s_entropyFailure; 19// 20// 21// Functions 22// 23// _cpri__RngStartup() 24// 25// This function is called to initialize the random number generator. It collects entropy from the platform to 26// seed the OpenSSL() random number generator. 27// 28LIB_EXPORT BOOL 29_cpri__RngStartup(void) 30{ 31 UINT32 entropySize; 32 BYTE entropy[MAX_RNG_ENTROPY_SIZE]; 33 INT32 returnedSize = 0; 34 // Initialize the entropy source 35 s_entropyFailure = FALSE; 36 _plat__GetEntropy(NULL, 0); 37 // Collect entropy until we have enough 38 for(entropySize = 0; 39 entropySize < MAX_RNG_ENTROPY_SIZE && returnedSize >= 0; 40 entropySize += returnedSize) 41 { 42 returnedSize = _plat__GetEntropy(&entropy[entropySize], 43 MAX_RNG_ENTROPY_SIZE - entropySize); 44 } 45 // Got some entropy on the last call and did not get an error 46 if(returnedSize > 0) 47 { 48 // Seed OpenSSL with entropy 49 RAND_seed(entropy, entropySize); 50 } 51 else 52 { 53 s_entropyFailure = TRUE; 54 } 55 return s_entropyFailure == FALSE; 56} 57// 58// 59// _cpri__DrbgGetPutState() 60// 61// This function is used to set the state of the RNG (direction == PUT_STATE) or to recover the state of the 62// RNG (direction == GET_STATE). 63// 64// 65// 66// NOTE: This not currently supported on OpenSSL() version. 67// 68LIB_EXPORT CRYPT_RESULT 69_cpri__DrbgGetPutState( 70 GET_PUT direction, 71 int bufferSize, 72 BYTE *buffer 73 ) 74{ 75 UNREFERENCED_PARAMETER(direction); 76 UNREFERENCED_PARAMETER(bufferSize); 77 UNREFERENCED_PARAMETER(buffer); 78 return CRYPT_SUCCESS; // Function is not implemented 79} 80// 81// 82// _cpri__StirRandom() 83// 84// This function is called to add external entropy to the OpenSSL() random number generator. 85// 86LIB_EXPORT CRYPT_RESULT 87_cpri__StirRandom( 88 INT32 entropySize, 89 BYTE *entropy 90 ) 91{ 92 if (entropySize >= 0) 93 { 94 RAND_add((const void *)entropy, (int) entropySize, 0.0); 95 } 96 return CRYPT_SUCCESS; 97} 98// 99// 100// _cpri__GenerateRandom() 101// 102// This function is called to get a string of random bytes from the OpenSSL() random number generator. The 103// return value is the number of bytes placed in the buffer. If the number of bytes returned is not equal to the 104// number of bytes requested (randomSize) it is indicative of a failure of the OpenSSL() random number 105// generator and is probably fatal. 106// 107LIB_EXPORT UINT16 108_cpri__GenerateRandom( 109 INT32 randomSize, 110 BYTE *buffer 111 ) 112{ 113 // 114 // We don't do negative sizes or ones that are too large 115 if (randomSize < 0 || randomSize > UINT16_MAX) 116 return 0; 117 // RAND_bytes uses 1 for success and we use 0 118 if(RAND_bytes(buffer, randomSize) == 1) 119 return (UINT16)randomSize; 120 else 121 return 0; 122} 123// 124// 125// 126// _cpri__GenerateSeededRandom() 127// 128// This funciton is used to generate a pseudo-random number from some seed values This funciton returns 129// the same result each time it is called with the same parameters 130// 131LIB_EXPORT UINT16 132_cpri__GenerateSeededRandom( 133 INT32 randomSize, // IN: the size of the request 134 BYTE *random, // OUT: receives the data 135 TPM_ALG_ID hashAlg, // IN: used by KDF version but not here 136 TPM2B *seed, // IN: the seed value 137 const char *label, // IN: a label string (optional) 138 TPM2B *partyU, // IN: other data (oprtional) 139 TPM2B *partyV // IN: still more (optional) 140 ) 141{ 142 return (_cpri__KDFa(hashAlg, seed, label, partyU, partyV, 143 randomSize * 8, random, NULL, FALSE)); 144} 145