/src/ibmswtpm2/src/CryptRand.c
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************************/ |
2 | | /* */ |
3 | | /* DRBG with a behavior according to SP800-90A */ |
4 | | /* Written by Ken Goldman */ |
5 | | /* IBM Thomas J. Watson Research Center */ |
6 | | /* $Id: CryptRand.c 1311 2018-08-23 21:39:29Z kgoldman $ */ |
7 | | /* */ |
8 | | /* Licenses and Notices */ |
9 | | /* */ |
10 | | /* 1. Copyright Licenses: */ |
11 | | /* */ |
12 | | /* - Trusted Computing Group (TCG) grants to the user of the source code in */ |
13 | | /* this specification (the "Source Code") a worldwide, irrevocable, */ |
14 | | /* nonexclusive, royalty free, copyright license to reproduce, create */ |
15 | | /* derivative works, distribute, display and perform the Source Code and */ |
16 | | /* derivative works thereof, and to grant others the rights granted herein. */ |
17 | | /* */ |
18 | | /* - The TCG grants to the user of the other parts of the specification */ |
19 | | /* (other than the Source Code) the rights to reproduce, distribute, */ |
20 | | /* display, and perform the specification solely for the purpose of */ |
21 | | /* developing products based on such documents. */ |
22 | | /* */ |
23 | | /* 2. Source Code Distribution Conditions: */ |
24 | | /* */ |
25 | | /* - Redistributions of Source Code must retain the above copyright licenses, */ |
26 | | /* this list of conditions and the following disclaimers. */ |
27 | | /* */ |
28 | | /* - Redistributions in binary form must reproduce the above copyright */ |
29 | | /* licenses, this list of conditions and the following disclaimers in the */ |
30 | | /* documentation and/or other materials provided with the distribution. */ |
31 | | /* */ |
32 | | /* 3. Disclaimers: */ |
33 | | /* */ |
34 | | /* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ |
35 | | /* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ |
36 | | /* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ |
37 | | /* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ |
38 | | /* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ |
39 | | /* information on specification licensing rights available through TCG */ |
40 | | /* membership agreements. */ |
41 | | /* */ |
42 | | /* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ |
43 | | /* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ |
44 | | /* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ |
45 | | /* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ |
46 | | /* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ |
47 | | /* */ |
48 | | /* - Without limitation, TCG and its members and licensors disclaim all */ |
49 | | /* liability, including liability for infringement of any proprietary */ |
50 | | /* rights, relating to use of information in this specification and to the */ |
51 | | /* implementation of this specification, and TCG disclaims all liability for */ |
52 | | /* cost of procurement of substitute goods or services, lost profits, loss */ |
53 | | /* of use, loss of data or any incidental, consequential, direct, indirect, */ |
54 | | /* or special damages, whether under contract, tort, warranty or otherwise, */ |
55 | | /* arising in any way out of use or reliance upon this specification or any */ |
56 | | /* information herein. */ |
57 | | /* */ |
58 | | /* (c) Copyright IBM Corp. and others, 2016 - 2018 */ |
59 | | /* */ |
60 | | /********************************************************************************/ |
61 | | |
62 | | #include "Tpm.h" |
63 | | #include "PRNG_TestVectors.h" |
64 | | const BYTE DRBG_NistTestVector_Entropy[] = {DRBG_TEST_INITIATE_ENTROPY}; |
65 | | const BYTE DRBG_NistTestVector_GeneratedInterm[] = |
66 | | {DRBG_TEST_GENERATED_INTERM}; |
67 | | const BYTE DRBG_NistTestVector_EntropyReseed[] = |
68 | | {DRBG_TEST_RESEED_ENTROPY}; |
69 | | const BYTE DRBG_NistTestVector_Generated[] = {DRBG_TEST_GENERATED}; |
70 | | /* 10.2.18.3.2 Derivation Function Defines and Structures */ |
71 | 0 | #define DF_COUNT (DRBG_KEY_SIZE_WORDS / DRBG_IV_SIZE_WORDS + 1) |
72 | | #if DRBG_KEY_SIZE_BITS != 128 && DRBG_KEY_SIZE_BITS != 256 |
73 | | # error "CryptRand.c only written for AES with 128- or 256-bit keys." |
74 | | #endif |
75 | | typedef struct |
76 | | { |
77 | | DRBG_KEY_SCHEDULE keySchedule; |
78 | | DRBG_IV iv[DF_COUNT]; |
79 | | DRBG_IV out1; |
80 | | DRBG_IV buf; |
81 | | int contents; |
82 | | } DF_STATE, *PDF_STATE; |
83 | | /* 10.2.18.3.3 DfCompute() */ |
84 | | /* This function does the incremental update of the derivation function state. It encrypts the iv |
85 | | value and XOR's the results into each of the blocks of the output. This is equivalent to |
86 | | processing all of input data for each output block. */ |
87 | | static void |
88 | | DfCompute( |
89 | | PDF_STATE dfState |
90 | | ) |
91 | 0 | { |
92 | 0 | int i; |
93 | 0 | int iv; |
94 | 0 | crypt_uword_t *pIv; |
95 | 0 | crypt_uword_t temp[DRBG_IV_SIZE_WORDS] = {0}; |
96 | | // |
97 | 0 | for(iv = 0; iv < DF_COUNT; iv++) |
98 | 0 | { |
99 | 0 | pIv = (crypt_uword_t *)&dfState->iv[iv].words[0]; |
100 | 0 | for(i = 0; i < DRBG_IV_SIZE_WORDS; i++) |
101 | 0 | { |
102 | 0 | temp[i] ^= pIv[i] ^ dfState->buf.words[i]; |
103 | 0 | } |
104 | 0 | DRBG_ENCRYPT(&dfState->keySchedule, &temp, pIv); |
105 | 0 | } |
106 | 0 | for(i = 0; i < DRBG_IV_SIZE_WORDS; i++) |
107 | 0 | dfState->buf.words[i] = 0; |
108 | 0 | dfState->contents = 0; |
109 | 0 | } |
110 | | /* 10.2.18.3.4 DfStart() */ |
111 | | /* This initializes the output blocks with an encrypted counter value and initializes the key |
112 | | schedule. */ |
113 | | static void |
114 | | DfStart( |
115 | | PDF_STATE dfState, |
116 | | uint32_t inputLength |
117 | | ) |
118 | 0 | { |
119 | 0 | BYTE init[8]; |
120 | 0 | int i; |
121 | 0 | UINT32 drbgSeedSize = sizeof(DRBG_SEED); |
122 | 0 | const BYTE dfKey[DRBG_KEY_SIZE_BYTES] = { |
123 | 0 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
124 | 0 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f |
125 | 0 | #if DRBG_KEY_SIZE_BYTES > 16 |
126 | 0 | ,0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
127 | 0 | 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f |
128 | 0 | #endif |
129 | 0 | }; |
130 | 0 | memset(dfState, 0, sizeof(DF_STATE)); |
131 | 0 | DRBG_ENCRYPT_SETUP(&dfKey[0], DRBG_KEY_SIZE_BITS, &dfState->keySchedule); |
132 | | // Create the first chaining values |
133 | 0 | for(i = 0; i < DF_COUNT; i++) |
134 | 0 | ((BYTE *)&dfState->iv[i])[3] = (BYTE)i; |
135 | 0 | DfCompute(dfState); |
136 | | // initialize the first 64 bits of the IV in a way that doesn't depend |
137 | | // on the size of the words used. |
138 | 0 | UINT32_TO_BYTE_ARRAY(inputLength, init); |
139 | 0 | UINT32_TO_BYTE_ARRAY(drbgSeedSize, &init[4]); |
140 | 0 | memcpy(&dfState->iv[0], init, 8); |
141 | 0 | dfState->contents = 4; |
142 | 0 | } |
143 | | /* 10.2.18.3.5 DfUpdate() */ |
144 | | /* This updates the state with the input data. A byte at a time is moved into the state buffer until |
145 | | it is full and then that block is encrypted by DfCompute(). */ |
146 | | static void |
147 | | DfUpdate( |
148 | | PDF_STATE dfState, |
149 | | int size, |
150 | | const BYTE *data |
151 | | ) |
152 | 0 | { |
153 | 0 | while(size > 0) |
154 | 0 | { |
155 | 0 | int toFill = DRBG_IV_SIZE_BYTES - dfState->contents; |
156 | 0 | if(size < toFill) |
157 | 0 | toFill = size; |
158 | | // Copy as many bytes as there are or until the state buffer is full |
159 | 0 | memcpy(&dfState->buf.bytes[dfState->contents], data, toFill); |
160 | | // Reduce the size left by the amount copied |
161 | 0 | size -= toFill; |
162 | | // Advance the data pointer by the amount copied |
163 | 0 | data += toFill; |
164 | | // increase the buffer contents count by the amount copied |
165 | 0 | dfState->contents += toFill; |
166 | 0 | pAssert(dfState->contents <= DRBG_IV_SIZE_BYTES); |
167 | | // If we have a full buffer, do a computation pass. |
168 | 0 | if(dfState->contents == DRBG_IV_SIZE_BYTES) |
169 | 0 | DfCompute(dfState); |
170 | 0 | } |
171 | 0 | } |
172 | | /* 10.2.18.3.6 DfEnd() */ |
173 | | /* This function is called to get the result of the derivation function computation. If the buffer |
174 | | is not full, it is padded with zeros. The output buffer is structured to be the same as a |
175 | | DRBG_SEED value so that the function can return a pointer to the DRBG_SEED value in the DF_STATE |
176 | | structure. */ |
177 | | static DRBG_SEED * |
178 | | DfEnd( |
179 | | PDF_STATE dfState |
180 | | ) |
181 | 0 | { |
182 | | // Since DfCompute is always called when a buffer is full, there is always |
183 | | // space in the buffer for the terminator |
184 | 0 | dfState->buf.bytes[dfState->contents++] = 0x80; |
185 | | // If the buffer is not full, pad with zeros |
186 | 0 | while(dfState->contents < DRBG_IV_SIZE_BYTES) |
187 | 0 | dfState->buf.bytes[dfState->contents++] = 0; |
188 | | // Do a final state update |
189 | 0 | DfCompute(dfState); |
190 | 0 | return (DRBG_SEED *)&dfState->iv; |
191 | 0 | } |
192 | | /* 10.2.18.3.7 DfBuffer() */ |
193 | | /* Function to take an input buffer and do the derivation function to produce a DRBG_SEED value that |
194 | | can be used in DRBG_Reseed(); */ |
195 | | static DRBG_SEED * |
196 | | DfBuffer( |
197 | | DRBG_SEED *output, // OUT: receives the result |
198 | | int size, // IN: size of the buffer to add |
199 | | BYTE *buf // IN: address of the buffer |
200 | | ) |
201 | 721 | { |
202 | 721 | DF_STATE dfState; |
203 | 721 | if(size == 0 || buf == NULL) |
204 | 721 | return NULL; |
205 | | // Initialize the derivation function |
206 | 0 | DfStart(&dfState, size); |
207 | 0 | DfUpdate(&dfState, size, buf); |
208 | 0 | DfEnd(&dfState); |
209 | 0 | memcpy(output, &dfState.iv[0], sizeof(DRBG_SEED)); |
210 | 0 | return output; |
211 | 721 | } |
212 | | /* 10.2.18.3.8 DRBG_GetEntropy() */ |
213 | | /* Even though this implementation never fails, it may get blocked indefinitely long in the call to |
214 | | get entropy from the platform (DRBG_GetEntropy32()). This function is only used during |
215 | | instantiation of the DRBG for manufacturing and on each start-up after an non-orderly |
216 | | shutdown. */ |
217 | | /* Return Values Meaning */ |
218 | | /* TRUE Requested entropy returned */ |
219 | | /* FALSE Entropy Failure */ |
220 | | BOOL |
221 | | DRBG_GetEntropy( |
222 | | UINT32 requiredEntropy, // IN: requested number of bytes of full |
223 | | // entropy |
224 | | BYTE *entropy // OUT: buffer to return collected entropy |
225 | | ) |
226 | 1.08k | { |
227 | 1.08k | #if !USE_DEBUG_RNG |
228 | 1.08k | UINT32 obtainedEntropy; |
229 | 1.08k | INT32 returnedEntropy; |
230 | | // If in debug mode, always use the self-test values for initialization |
231 | 1.08k | if(IsSelfTest()) |
232 | 361 | { |
233 | 361 | #endif |
234 | | // If doing simulated DRBG, then check to see if the |
235 | | // entropyFailure condition is being tested |
236 | 361 | if(!IsEntropyBad()) |
237 | 361 | { |
238 | | // In self-test, the caller should be asking for exactly the seed |
239 | | // size of entropy. |
240 | 361 | pAssert(requiredEntropy == sizeof(DRBG_NistTestVector_Entropy)); |
241 | 361 | memcpy(entropy, DRBG_NistTestVector_Entropy, |
242 | 361 | sizeof(DRBG_NistTestVector_Entropy)); |
243 | 361 | } |
244 | 361 | #if !USE_DEBUG_RNG |
245 | 361 | } |
246 | 721 | else if(!IsEntropyBad()) |
247 | 360 | { |
248 | | // Collect entropy |
249 | | // Note: In debug mode, the only "entropy" value ever returned |
250 | | // is the value of the self-test vector. |
251 | 360 | for(returnedEntropy = 1, obtainedEntropy = 0; |
252 | 4.68k | obtainedEntropy < requiredEntropy && !IsEntropyBad(); |
253 | 4.32k | obtainedEntropy += returnedEntropy) |
254 | 4.32k | { |
255 | 4.32k | returnedEntropy = _plat__GetEntropy(&entropy[obtainedEntropy], |
256 | 4.32k | requiredEntropy - obtainedEntropy); |
257 | 4.32k | if(returnedEntropy <= 0) |
258 | 4.32k | SetEntropyBad(); |
259 | 4.32k | } |
260 | 360 | } |
261 | 1.08k | #endif |
262 | 1.08k | return !IsEntropyBad(); |
263 | 1.08k | } |
264 | | /* 10.2.18.3.9 IncrementIv() */ |
265 | | /* Used by EncryptDRBG() */ |
266 | | void |
267 | | IncrementIv( |
268 | | DRBG_IV *iv |
269 | | ) |
270 | 23.7k | { |
271 | 23.7k | BYTE *ivP = ((BYTE *)iv) + DRBG_IV_SIZE_BYTES; |
272 | 23.8k | while((--ivP >= (BYTE *)iv) && ((*ivP = ((*ivP + 1) & 0xFF)) == 0)); |
273 | 23.7k | } |
274 | | /* 10.2.18.3.10 EncryptDRBG() */ |
275 | | /* This does the encryption operation for the DRBG. It will encrypt the input state counter (IV) |
276 | | using the state key. Into the output buffer for as many times as it takes to generate the |
277 | | required number of bytes. */ |
278 | | void |
279 | | EncryptDRBG( |
280 | | BYTE *dOut, |
281 | | UINT32 dOutBytes, |
282 | | DRBG_KEY_SCHEDULE *keySchedule, |
283 | | DRBG_IV *iv, |
284 | | UINT32 *lastValue // Points to the last output value |
285 | | ) |
286 | 7.56k | { |
287 | 7.56k | #if FIPS_COMPLIANT |
288 | | // For FIPS compliance, the DRBG has to do a continuous self-test to make sure that |
289 | | // no two consecutive values are the same. This overhead is not incurred if the TPM |
290 | | // is not required to be FIPS compliant |
291 | | // |
292 | 7.56k | UINT32 temp[DRBG_IV_SIZE_BYTES / sizeof(UINT32)]; |
293 | 7.56k | int i; |
294 | 7.56k | BYTE *p; |
295 | 31.3k | for(; dOutBytes > 0;) |
296 | 23.7k | { |
297 | | // Increment the IV before each encryption (this is what makes this |
298 | | // different from normal counter-mode encryption |
299 | 23.7k | IncrementIv(iv); |
300 | 23.7k | DRBG_ENCRYPT(keySchedule, iv, temp); |
301 | | // Expect a 16 byte block |
302 | | #if DRBG_IV_SIZE_BITS != 128 |
303 | | #error "Unsuppored IV size in DRBG" |
304 | | #endif |
305 | 23.7k | if((lastValue[0] == temp[0]) |
306 | 23.7k | && (lastValue[1] == temp[1]) |
307 | 23.7k | && (lastValue[2] == temp[2]) |
308 | 23.7k | && (lastValue[3] == temp[3]) |
309 | 23.7k | ) |
310 | 0 | FAIL(FATAL_ERROR_DRBG); |
311 | 23.7k | lastValue[0] = temp[0]; |
312 | 23.7k | lastValue[1] = temp[1]; |
313 | 23.7k | lastValue[2] = temp[2]; |
314 | 23.7k | lastValue[3] = temp[3]; |
315 | 23.7k | i = MIN(dOutBytes, DRBG_IV_SIZE_BYTES); |
316 | 23.7k | dOutBytes -= i; |
317 | 404k | for(p = (BYTE *)temp; i > 0; i--) |
318 | 380k | *dOut++ = *p++; |
319 | 23.7k | } |
320 | | #else // version without continuous self-test |
321 | | NOT_REFERENCED(lastValue); |
322 | | for(; dOutBytes >= DRBG_IV_SIZE_BYTES; |
323 | | dOut = &dOut[DRBG_IV_SIZE_BYTES], dOutBytes -= DRBG_IV_SIZE_BYTES) |
324 | | { |
325 | | // Increment the IV |
326 | | IncrementIv(iv); |
327 | | DRBG_ENCRYPT(keySchedule, iv, dOut); |
328 | | } |
329 | | // If there is a partial, generate into a block-sized |
330 | | // temp buffer and copy to the output. |
331 | | if(dOutBytes != 0) |
332 | | { |
333 | | BYTE temp[DRBG_IV_SIZE_BYTES]; |
334 | | // Increment the IV |
335 | | IncrementIv(iv); |
336 | | DRBG_ENCRYPT(keySchedule, iv, temp); |
337 | | memcpy(dOut, temp, dOutBytes); |
338 | | } |
339 | | #endif |
340 | 7.56k | } |
341 | | /* 10.2.18.3.11 DRBG_Update() */ |
342 | | /* This function performs the state update function. According to SP800-90A, a temp value is created |
343 | | by doing CTR mode encryption of providedData and replacing the key and IV with these values. The |
344 | | one difference is that, with counter mode, the IV is incremented after each block is encrypted |
345 | | and in this operation, the counter is incremented before each block is encrypted. This function |
346 | | implements an optimized version of the algorithm in that it does the update of the |
347 | | drbgState->seed in place and then providedData is XORed() into drbgState->seed to complete the |
348 | | encryption of providedData. This works because the IV is the last thing that gets encrypted. */ |
349 | | void |
350 | | DRBG_Update( |
351 | | DRBG_STATE *drbgState, // IN:OUT state to update |
352 | | DRBG_KEY_SCHEDULE *keySchedule, // IN: the key schedule (optional) |
353 | | DRBG_SEED *providedData // IN: additional data |
354 | | ) |
355 | 4.32k | { |
356 | 4.32k | UINT32 i; |
357 | 4.32k | BYTE *temp = (BYTE *)&drbgState->seed; |
358 | 4.32k | DRBG_KEY *key = pDRBG_KEY(&drbgState->seed); |
359 | 4.32k | DRBG_IV *iv = pDRBG_IV(&drbgState->seed); |
360 | 4.32k | DRBG_KEY_SCHEDULE localKeySchedule; |
361 | | // |
362 | 4.32k | pAssert(drbgState->magic == DRBG_MAGIC); |
363 | | // If an key schedule was not provided, make one |
364 | 4.32k | if(keySchedule == NULL) |
365 | 1.08k | { |
366 | 1.08k | if(DRBG_ENCRYPT_SETUP((BYTE *)key, |
367 | 1.08k | DRBG_KEY_SIZE_BITS, &localKeySchedule) != 0) |
368 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
369 | 1.08k | keySchedule = &localKeySchedule; |
370 | 1.08k | } |
371 | | // Encrypt the temp value |
372 | 4.32k | EncryptDRBG(temp, sizeof(DRBG_SEED), keySchedule, iv, |
373 | 4.32k | drbgState->lastValue); |
374 | 4.32k | if(providedData != NULL) |
375 | 1.08k | { |
376 | 1.08k | BYTE *pP = (BYTE *)providedData; |
377 | 53.0k | for(i = DRBG_SEED_SIZE_BYTES; i != 0; i--) |
378 | 51.9k | *temp++ ^= *pP++; |
379 | 1.08k | } |
380 | | // Since temp points to the input key and IV, we are done and |
381 | | // don't need to copy the resulting 'temp' to drbgState->seed |
382 | 4.32k | } |
383 | | /* 10.2.18.3.12 DRBG_Reseed() */ |
384 | | /* This function is used when reseeding of the DRBG is required. If entropy is provided, it is used |
385 | | in lieu of using hardware entropy. */ |
386 | | /* NOTE: the provided entropy must be the required size. */ |
387 | | /* Return Values Meaning */ |
388 | | /* TRUE reseed succeeded */ |
389 | | /* FALSE reseed failed, probably due to the entropy generation */ |
390 | | BOOL |
391 | | DRBG_Reseed( |
392 | | DRBG_STATE *drbgState, // IN: the state to update |
393 | | DRBG_SEED *providedEntropy, // IN: entropy |
394 | | DRBG_SEED *additionalData // IN: |
395 | | ) |
396 | 1.08k | { |
397 | 1.08k | DRBG_SEED seed; |
398 | 1.08k | pAssert((drbgState != NULL) && (drbgState->magic == DRBG_MAGIC)); |
399 | 1.08k | if(providedEntropy == NULL) |
400 | 0 | { |
401 | 0 | providedEntropy = &seed; |
402 | 0 | if(!DRBG_GetEntropy(sizeof(DRBG_SEED), (BYTE *)providedEntropy)) |
403 | 0 | return FALSE; |
404 | 0 | } |
405 | 1.08k | if(additionalData != NULL) |
406 | 0 | { |
407 | 0 | unsigned int i; |
408 | | // XOR the provided data into the provided entropy |
409 | 0 | for(i = 0; i < sizeof(DRBG_SEED); i++) |
410 | 0 | ((BYTE *)providedEntropy)[i] ^= ((BYTE *)additionalData)[i]; |
411 | 0 | } |
412 | 1.08k | DRBG_Update(drbgState, NULL, providedEntropy); |
413 | 1.08k | drbgState->reseedCounter = 1; |
414 | 1.08k | return TRUE; |
415 | 1.08k | } |
416 | | /* 10.2.18.3.13 DRBG_SelfTest() */ |
417 | | /* This is run when the DRBG is instantiated and at startup */ |
418 | | /* Return Values Meaning */ |
419 | | /* FALSE test failed */ |
420 | | /* TRUE test OK */ |
421 | | BOOL |
422 | | DRBG_SelfTest( |
423 | | void |
424 | | ) |
425 | 361 | { |
426 | 361 | BYTE buf[sizeof(DRBG_NistTestVector_Generated)]; |
427 | 361 | DRBG_SEED seed; |
428 | 361 | UINT32 i; |
429 | 361 | BYTE *p; |
430 | 361 | DRBG_STATE testState; |
431 | | // |
432 | 361 | pAssert(!IsSelfTest()); |
433 | 361 | SetSelfTest(); |
434 | 361 | SetDrbgTested(); |
435 | | // Do an instantiate |
436 | 361 | if(!DRBG_Instantiate(&testState, 0, NULL)) |
437 | 0 | return FALSE; |
438 | | #if DRBG_DEBUG_PRINT |
439 | | dbgDumpMemBlock(pDRBG_KEY(&testState), DRBG_KEY_SIZE_BYTES, |
440 | | "Key after Instantiate"); |
441 | | dbgDumpMemBlock(pDRBG_IV(&testState), DRBG_IV_SIZE_BYTES, |
442 | | "Value after Instantiate"); |
443 | | #endif |
444 | 361 | if(DRBG_Generate((RAND_STATE *)&testState, buf, sizeof(buf)) == 0) |
445 | 0 | return FALSE; |
446 | | #if DRBG_DEBUG_PRINT |
447 | | dbgDumpMemBlock(pDRBG_KEY(&testState.seed), DRBG_KEY_SIZE_BYTES, |
448 | | "Key after 1st Generate"); |
449 | | dbgDumpMemBlock(pDRBG_IV(&testState.seed), DRBG_IV_SIZE_BYTES, |
450 | | "Value after 1st Generate"); |
451 | | #endif |
452 | 361 | if(memcmp(buf, DRBG_NistTestVector_GeneratedInterm, sizeof(buf)) != 0) |
453 | 0 | return FALSE; |
454 | 361 | memcpy(seed.bytes, DRBG_NistTestVector_EntropyReseed, sizeof(seed)); |
455 | 361 | DRBG_Reseed(&testState, &seed, NULL); |
456 | | #if DRBG_DEBUG_PRINT |
457 | | dbgDumpMemBlock((BYTE *)pDRBG_KEY(&testState.seed), DRBG_KEY_SIZE_BYTES, |
458 | | "Key after 2nd Generate"); |
459 | | dbgDumpMemBlock((BYTE *)pDRBG_IV(&testState.seed), DRBG_IV_SIZE_BYTES, |
460 | | "Value after 2nd Generate"); |
461 | | dbgDumpMemBlock(buf, sizeof(buf), "2nd Generated"); |
462 | | #endif |
463 | 361 | if(DRBG_Generate((RAND_STATE *)&testState, buf, sizeof(buf)) == 0) |
464 | 0 | return FALSE; |
465 | 361 | if(memcmp(buf, DRBG_NistTestVector_Generated, sizeof(buf)) != 0) |
466 | 0 | return FALSE; |
467 | 361 | ClearSelfTest(); |
468 | 361 | DRBG_Uninstantiate(&testState); |
469 | 29.2k | for(p = (BYTE *)&testState, i = 0; i < sizeof(DRBG_STATE); i++) |
470 | 28.8k | { |
471 | 28.8k | if(*p++) |
472 | 0 | return FALSE; |
473 | 28.8k | } |
474 | | // Simulate hardware failure to make sure that we get an error when |
475 | | // trying to instantiate |
476 | 361 | SetEntropyBad(); |
477 | 361 | if(DRBG_Instantiate(&testState, 0, NULL)) |
478 | 0 | return FALSE; |
479 | 361 | ClearEntropyBad(); |
480 | 361 | return TRUE; |
481 | 361 | } |
482 | | /* 10.2.18.4 Public Interface */ |
483 | | /* 10.2.18.4.1 Description */ |
484 | | /* The functions in this section are the interface to the RNG. These are the functions that are used |
485 | | by TPM.lib. Other functions are only visible to programs in the LtcCryptoEngine(). */ |
486 | | /* 10.2.18.4.2 CryptRandomStir() */ |
487 | | /* This function is used to cause a reseed. A DRBG_SEED amount of entropy is collected from the |
488 | | hardware and then additional data is added. */ |
489 | | /* Error Returns Meaning */ |
490 | | /* TPM_RC_NO_RESULT failure of the entropy generator */ |
491 | | LIB_EXPORT TPM_RC |
492 | | CryptRandomStir( |
493 | | UINT16 additionalDataSize, |
494 | | BYTE *additionalData |
495 | | ) |
496 | 0 | { |
497 | 0 | #if !USE_DEBUG_RNG |
498 | 0 | DRBG_SEED tmpBuf; |
499 | 0 | DRBG_SEED dfResult; |
500 | | // |
501 | | // All reseed with outside data starts with a buffer full of entropy |
502 | 0 | if(!DRBG_GetEntropy(sizeof(tmpBuf), (BYTE *)&tmpBuf)) |
503 | 0 | return TPM_RC_NO_RESULT; |
504 | 0 | DRBG_Reseed(&drbgDefault, &tmpBuf, |
505 | 0 | DfBuffer(&dfResult, additionalDataSize, additionalData)); |
506 | 0 | drbgDefault.reseedCounter = 1; |
507 | 0 | return TPM_RC_SUCCESS; |
508 | | #else |
509 | | // If doing debug, use the input data as the initial setting for the RNG state |
510 | | // so that the test can be reset at any time. |
511 | | // Note: If this is called with a data size of 0 or less, nothing happens. The |
512 | | // presumption is that, in a debug environment, the caller will have specific |
513 | | // values for initialization, so this check is just a simple way to prevent |
514 | | // inadvertent programming errors from screwing things up. This doesn't use an |
515 | | // pAssert() because the non-debug version of this function will accept these |
516 | | // parameters as meaning that there is no additionalData and only hardware |
517 | | // entropy is used. |
518 | | if((additionalDataSize > 0) && (additionalData != NULL)) |
519 | | { |
520 | | memset(drbgDefault.seed.bytes, 0, sizeof(drbgDefault.seed.bytes)); |
521 | | memcpy(drbgDefault.seed.bytes, additionalData, |
522 | | MIN(additionalDataSize, sizeof(drbgDefault.seed.bytes))); |
523 | | } |
524 | | drbgDefault.reseedCounter = 1; |
525 | | return TPM_RC_SUCCESS; |
526 | | #endif |
527 | 0 | } |
528 | | /* 10.2.18.4.3 CryptRandomGenerate() */ |
529 | | /* Generate a randomSize number or random bytes. */ |
530 | | LIB_EXPORT UINT16 |
531 | | CryptRandomGenerate( |
532 | | INT32 randomSize, |
533 | | BYTE *buffer |
534 | | ) |
535 | 2.52k | { |
536 | 2.52k | if(randomSize > UINT16_MAX) |
537 | 0 | randomSize = UINT16_MAX; |
538 | 2.52k | return DRBG_Generate((RAND_STATE *)&drbgDefault, buffer, (UINT16)randomSize); |
539 | 2.52k | } |
540 | | /* 10.2.18.4.4 DRBG_InstantiateSeededKdf() */ |
541 | | /* Function used to instantiate a KDF-based RNG. This is used for derivations */ |
542 | | LIB_EXPORT BOOL |
543 | | DRBG_InstantiateSeededKdf( |
544 | | KDF_STATE *state, // OUT: buffer to hold the state |
545 | | TPM_ALG_ID hashAlg, // IN: hash algorithm |
546 | | TPM_ALG_ID kdf, // IN: the KDF to use |
547 | | TPM2B *seed, // IN: the seed to use |
548 | | const TPM2B *label, // IN: a label for the generation process. |
549 | | TPM2B *context, // IN: the context value |
550 | | UINT32 limit // IN: Maximum number of bits from the KDF |
551 | | ) |
552 | 0 | { |
553 | 0 | state->magic = KDF_MAGIC; |
554 | 0 | state->limit = limit; |
555 | 0 | state->seed = seed; |
556 | 0 | state->hash = hashAlg; |
557 | 0 | state->kdf = kdf; |
558 | 0 | state->label = label; |
559 | 0 | state->context = context; |
560 | 0 | state->digestSize = CryptHashGetDigestSize(hashAlg); |
561 | 0 | state->counter = 0; |
562 | 0 | state->residual.t.size = 0; |
563 | 0 | return TRUE; |
564 | 0 | } |
565 | | /* 10.2.18.4.5 DRBG_AdditionalData() */ |
566 | | /* Function to reseed the DRBG with additional entropy. This is normally called before computing the |
567 | | protection value of a primary key in the Endorsement hierarchy. */ |
568 | | LIB_EXPORT void |
569 | | DRBG_AdditionalData( |
570 | | DRBG_STATE *drbgState, // IN:OUT state to update |
571 | | TPM2B *additionalData // IN: value to incorporate |
572 | | ) |
573 | 0 | { |
574 | 0 | DRBG_SEED dfResult; |
575 | 0 | if(drbgState->magic == DRBG_MAGIC) |
576 | 0 | { |
577 | 0 | DfBuffer(&dfResult, additionalData->size, additionalData->buffer); |
578 | 0 | DRBG_Reseed(drbgState, &dfResult, NULL); |
579 | 0 | } |
580 | 0 | } |
581 | | /* 10.2.18.4.6 DRBG_InstantiateSeeded() */ |
582 | | /* This function is used to instantiate a random number generator from seed values. The nominal use |
583 | | of this generator is to create sequences of pseudo-random numbers from a seed value. */ |
584 | | LIB_EXPORT BOOL |
585 | | DRBG_InstantiateSeeded( |
586 | | DRBG_STATE *drbgState, // IN/OUT: buffer to hold the state |
587 | | const TPM2B *seed, // IN: the seed to use |
588 | | const TPM2B *purpose, // IN: a label for the generation process. |
589 | | const TPM2B *name, // IN: name of the object |
590 | | const TPM2B *additional // IN: additional data |
591 | | ) |
592 | 0 | { |
593 | 0 | DF_STATE dfState; |
594 | 0 | int totalInputSize; |
595 | | // DRBG should have been tested, but... |
596 | 0 | if(!IsDrbgTested() && !DRBG_SelfTest()) |
597 | 0 | FAIL(FATAL_ERROR_SELF_TEST); |
598 | | // Initialize the DRBG state |
599 | 0 | memset(drbgState, 0, sizeof(DRBG_STATE)); |
600 | 0 | drbgState->magic = DRBG_MAGIC; |
601 | | // Size all of the values |
602 | 0 | totalInputSize = (seed != NULL) ? seed->size : 0; |
603 | 0 | totalInputSize += (purpose != NULL) ? purpose->size : 0; |
604 | 0 | totalInputSize += (name != NULL) ? name->size : 0; |
605 | 0 | totalInputSize += (additional != NULL) ? additional->size : 0; |
606 | | // Initialize the derivation |
607 | 0 | DfStart(&dfState, totalInputSize); |
608 | | // Run all the input strings through the derivation function |
609 | 0 | if(seed != NULL) |
610 | 0 | DfUpdate(&dfState, seed->size, seed->buffer); |
611 | 0 | if(purpose != NULL) |
612 | 0 | DfUpdate(&dfState, purpose->size, purpose->buffer); |
613 | 0 | if(name != NULL) |
614 | 0 | DfUpdate(&dfState, name->size, name->buffer); |
615 | 0 | if(additional != NULL) |
616 | 0 | DfUpdate(&dfState, additional->size, additional->buffer); |
617 | | // Used the derivation function output as the "entropy" input. This is not |
618 | | // how it is described in SP800-90A but this is the equivalent function |
619 | 0 | DRBG_Reseed(((DRBG_STATE *)drbgState), DfEnd(&dfState), NULL); |
620 | 0 | return TRUE; |
621 | 0 | } |
622 | | /* 10.2.18.4.7 CryptRandStartup() */ |
623 | | /* This function is called when TPM_Startup() is executed. */ |
624 | | LIB_EXPORT BOOL |
625 | | CryptRandStartup( |
626 | | void |
627 | | ) |
628 | 360 | { |
629 | | #if ! _DRBG_STATE_SAVE |
630 | | // If not saved in NV, re-instantiate on each startup |
631 | | DRBG_Instantiate(&drbgDefault, 0, NULL); |
632 | | #else |
633 | | // If the running state is saved in NV, NV has to be loaded before it can |
634 | | // be updated |
635 | 360 | if(go.drbgState.magic == DRBG_MAGIC) |
636 | 0 | DRBG_Reseed(&go.drbgState, NULL, NULL); |
637 | 360 | else |
638 | 360 | DRBG_Instantiate(&go.drbgState, 0, NULL); |
639 | 360 | #endif |
640 | 360 | return TRUE; |
641 | 360 | } |
642 | | /* 10.2.18.4.8 CryptRandInit() */ |
643 | | /* This function is called when _TPM_Init() is being processed */ |
644 | | LIB_EXPORT BOOL |
645 | | CryptRandInit( |
646 | | void |
647 | | ) |
648 | 361 | { |
649 | 361 | #if !USE_DEBUG_RNG |
650 | 361 | _plat__GetEntropy(NULL, 0); |
651 | 361 | #endif |
652 | 361 | return DRBG_SelfTest(); |
653 | 361 | } |
654 | | /* 10.2.18.5 DRBG_Generate() */ |
655 | | /* This function generates a random sequence according SP800-90A. If random is not NULL, then |
656 | | randomSize bytes of random values are generated. If random is NULL or randomSize is zero, then |
657 | | the function returns TRUE without generating any bits or updating the reseed counter. This |
658 | | function returns 0 if a reseed is required. Otherwise, it returns the number of bytes produced |
659 | | which could be less than the number requested if the request is too large. */ |
660 | | LIB_EXPORT UINT16 |
661 | | DRBG_Generate( |
662 | | RAND_STATE *state, |
663 | | BYTE *random, // OUT: buffer to receive the random values |
664 | | UINT16 randomSize // IN: the number of bytes to generate |
665 | | ) |
666 | 3.24k | { |
667 | 3.24k | if(state == NULL) |
668 | 0 | state = (RAND_STATE *)&drbgDefault; |
669 | | // If the caller used a KDF state, generate a sequence from the KDF not to |
670 | | // exceed the limit. |
671 | 3.24k | if(state->kdf.magic == KDF_MAGIC) |
672 | 0 | { |
673 | 0 | KDF_STATE *kdf = (KDF_STATE *)state; |
674 | 0 | UINT32 counter = (UINT32)kdf->counter; |
675 | 0 | INT32 bytesLeft = randomSize; |
676 | 0 | if(random == NULL) |
677 | 0 | return 0; |
678 | | // If the number of bytes to be returned would put the generator |
679 | | // over the limit, then return 0 |
680 | 0 | if((((kdf->counter * kdf->digestSize) + randomSize) * 8) > kdf->limit) |
681 | 0 | return 0; |
682 | | // Process partial and full blocks until all requested bytes provided |
683 | 0 | while(bytesLeft > 0) |
684 | 0 | { |
685 | | // If there is any residual data in the buffer, copy it to the output |
686 | | // buffer |
687 | 0 | if(kdf->residual.t.size > 0) |
688 | 0 | { |
689 | 0 | INT32 size; |
690 | | // |
691 | | // Don't use more of the residual than will fit or more than are |
692 | | // available |
693 | 0 | size = MIN(kdf->residual.t.size, bytesLeft); |
694 | | // Copy some or all of the residual to the output. The residual is |
695 | | // at the end of the buffer. The residual might be a full buffer. |
696 | 0 | MemoryCopy(random, |
697 | 0 | &kdf->residual.t.buffer |
698 | 0 | [kdf->digestSize - kdf->residual.t.size], size); |
699 | | // Advance the buffer pointer |
700 | 0 | random += size; |
701 | | // Reduce the number of bytes left to get |
702 | 0 | bytesLeft -= size; |
703 | | // And reduce the residual size appropriately |
704 | 0 | kdf->residual.t.size -= (UINT16)size; |
705 | 0 | } |
706 | 0 | else |
707 | 0 | { |
708 | 0 | UINT16 blocks = (UINT16)(bytesLeft / kdf->digestSize); |
709 | | // |
710 | | // Get the number of required full blocks |
711 | 0 | if(blocks > 0) |
712 | 0 | { |
713 | 0 | UINT16 size = blocks * kdf->digestSize; |
714 | | // Get some number of full blocks and put them in the return buffer |
715 | 0 | CryptKDFa(kdf->hash, kdf->seed, kdf->label, kdf->context, NULL, |
716 | 0 | kdf->limit, random, &counter, blocks); |
717 | | // reduce the size remaining to be moved and advance the pointer |
718 | 0 | bytesLeft -= size; |
719 | 0 | random += size; |
720 | 0 | } |
721 | 0 | else |
722 | 0 | { |
723 | | // Fill the residual buffer with a full block and then loop to |
724 | | // top to get part of it copied to the output. |
725 | 0 | kdf->residual.t.size = CryptKDFa(kdf->hash, kdf->seed, |
726 | 0 | kdf->label, kdf->context, NULL, |
727 | 0 | kdf->limit, |
728 | 0 | kdf->residual.t.buffer, |
729 | 0 | &counter, 1); |
730 | 0 | } |
731 | 0 | } |
732 | 0 | } |
733 | 0 | kdf->counter = counter; |
734 | 0 | return randomSize; |
735 | 0 | } |
736 | 3.24k | else if(state->drbg.magic == DRBG_MAGIC) |
737 | 3.24k | { |
738 | 3.24k | DRBG_STATE *drbgState = (DRBG_STATE *)state; |
739 | 3.24k | DRBG_KEY_SCHEDULE keySchedule; |
740 | 3.24k | DRBG_SEED *seed = &drbgState->seed; |
741 | 3.24k | if(drbgState->reseedCounter >= CTR_DRBG_MAX_REQUESTS_PER_RESEED) |
742 | 0 | { |
743 | 0 | if(drbgState == &drbgDefault) |
744 | 0 | { |
745 | 0 | DRBG_Reseed(drbgState, NULL, NULL); |
746 | 0 | if(IsEntropyBad() && !IsSelfTest()) |
747 | 0 | return 0; |
748 | 0 | } |
749 | 0 | else |
750 | | // If this is a PRNG then the only way to get |
751 | | // here is if the SW has run away. |
752 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
753 | 0 | } |
754 | | // if the allowed number of bytes in a request is larger than the |
755 | | // less than the number of bytes that can be requested, then check |
756 | | #if UINT16_MAX >= CTR_DRBG_MAX_BYTES_PER_REQUEST |
757 | | if(randomSize > CTR_DRBG_MAX_BYTES_PER_REQUEST) |
758 | | randomSize = CTR_DRBG_MAX_BYTES_PER_REQUEST; |
759 | | #endif |
760 | | // Create encryption schedule |
761 | 3.24k | if(DRBG_ENCRYPT_SETUP((BYTE *)pDRBG_KEY(seed), |
762 | 3.24k | DRBG_KEY_SIZE_BITS, &keySchedule) != 0) |
763 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
764 | | // Generate the random data |
765 | 3.24k | EncryptDRBG(random, randomSize, &keySchedule, pDRBG_IV(seed), |
766 | 3.24k | drbgState->lastValue); |
767 | | // Do a key update |
768 | 3.24k | DRBG_Update(drbgState, &keySchedule, NULL); |
769 | | // Increment the reseed counter |
770 | 3.24k | drbgState->reseedCounter += 1; |
771 | 3.24k | } |
772 | 0 | else |
773 | 0 | { |
774 | 0 | FAIL(FATAL_ERROR_INTERNAL); |
775 | 0 | } |
776 | 3.24k | return randomSize; |
777 | 3.24k | } |
778 | | /* 10.2.18.6 DRBG_Instantiate() */ |
779 | | /* This is CTR_DRBG_Instantiate_algorithm() from [SP 800-90A 10.2.1.3.1]. This is called when a the |
780 | | TPM DRBG is to be instantiated. This is called to instantiate a DRBG used by the TPM for normal |
781 | | operations. */ |
782 | | /* Return Values Meaning */ |
783 | | /* TRUE instantiation succeeded */ |
784 | | /* FALSE instantiation failed */ |
785 | | LIB_EXPORT BOOL |
786 | | DRBG_Instantiate( |
787 | | DRBG_STATE *drbgState, // OUT: the instantiated value |
788 | | UINT16 pSize, // IN: Size of personalization string |
789 | | BYTE *personalization // IN: The personalization string |
790 | | ) |
791 | 1.08k | { |
792 | 1.08k | DRBG_SEED seed; |
793 | 1.08k | DRBG_SEED dfResult; |
794 | | // |
795 | 1.08k | pAssert((pSize == 0) || (pSize <= sizeof(seed)) || (personalization != NULL)); |
796 | | // If the DRBG has not been tested, test when doing an instantiation. Since |
797 | | // Instantiation is called during self test, make sure we don't get stuck in a |
798 | | // loop. |
799 | 1.08k | if(!IsDrbgTested() && !IsSelfTest() && !DRBG_SelfTest()) |
800 | 0 | return FALSE; |
801 | | // If doing a self test, DRBG_GetEntropy will return the NIST |
802 | | // test vector value. |
803 | 1.08k | if(!DRBG_GetEntropy(sizeof(seed), (BYTE *)&seed)) |
804 | 361 | return FALSE; |
805 | | // set everything to zero |
806 | 721 | memset(drbgState, 0, sizeof(DRBG_STATE)); |
807 | 721 | drbgState->magic = DRBG_MAGIC; |
808 | | // Steps 1, 2, 3, 6, 7 of SP 800-90A 10.2.1.3.1 are exactly what |
809 | | // reseeding does. So, do a reduction on the personalization value (if any) |
810 | | // and do a reseed. |
811 | 721 | DRBG_Reseed(drbgState, &seed, DfBuffer(&dfResult, pSize, personalization)); |
812 | 721 | return TRUE; |
813 | 1.08k | } |
814 | | /* 10.2.18.7 DRBG_Uninstantiate() */ |
815 | | /* This is Uninstantiate_function() from [SP 800-90A 9.4]. */ |
816 | | LIB_EXPORT TPM_RC |
817 | | DRBG_Uninstantiate( |
818 | | DRBG_STATE *drbgState // IN/OUT: working state to erase |
819 | | ) |
820 | 361 | { |
821 | 361 | if((drbgState == NULL) || (drbgState->magic != DRBG_MAGIC)) |
822 | 0 | return TPM_RC_VALUE; |
823 | 361 | memset(drbgState, 0, sizeof(DRBG_STATE)); |
824 | 361 | return TPM_RC_SUCCESS; |
825 | 361 | } |
826 | | |