Coverage Report

Created: 2023-09-25 06:15

/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