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"
18 int 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 //
28 LIB_EXPORT BOOL
_cpri__RngStartup(void)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 //
68 LIB_EXPORT CRYPT_RESULT
_cpri__DrbgGetPutState(GET_PUT direction,int bufferSize,BYTE * buffer)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 //
86 LIB_EXPORT CRYPT_RESULT
_cpri__StirRandom(INT32 entropySize,BYTE * entropy)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 //
107 LIB_EXPORT UINT16
_cpri__GenerateRandom(INT32 randomSize,BYTE * buffer)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 //
131 LIB_EXPORT UINT16
_cpri__GenerateSeededRandom(INT32 randomSize,BYTE * random,TPM_ALG_ID hashAlg,TPM2B * seed,const char * label,TPM2B * partyU,TPM2B * partyV)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