Coverage Report

Created: 2025-07-11 06:15

/src/tpm2/CryptUtil.c
Line
Count
Source (jump to first uncovered line)
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
#include        "TPM_Types.h"
9
#include        "CryptoEngine.h"        // types shared by CryptUtil and CryptoEngine.
10
                                       // Includes the function prototypes for the
11
                                       // CryptoEngine functions.
12
#include        "Global.h"
13
#include        "InternalRoutines.h"
14
#include        "MemoryLib_fp.h"
15
//#include        "CryptSelfTest_fp.h"
16
//
17
//
18
//     10.2.2     TranslateCryptErrors()
19
//
20
//     This function converts errors from the cryptographic library into TPM_RC_VALUES.
21
//
22
//     Error Returns                     Meaning
23
//
24
//     TPM_RC_VALUE                      CRYPT_FAIL
25
//     TPM_RC_NO_RESULT                  CRYPT_NO_RESULT
26
//     TPM_RC_SCHEME                     CRYPT_SCHEME
27
//     TPM_RC_VALUE                      CRYPT_PARAMETER
28
//     TPM_RC_SIZE                       CRYPT_UNDERFLOW
29
//     TPM_RC_ECC_POINT                  CRYPT_POINT
30
//     TPM_RC_CANCELLED                  CRYPT_CANCEL
31
//
32
static TPM_RC
33
TranslateCryptErrors (
34
      CRYPT_RESULT            retVal                 // IN: crypt error to evaluate
35
)
36
6
{
37
6
      switch (retVal)
38
6
      {
39
5
      case CRYPT_SUCCESS:
40
5
          return TPM_RC_SUCCESS;
41
0
      case CRYPT_FAIL:
42
0
          return TPM_RC_VALUE;
43
1
      case CRYPT_NO_RESULT:
44
1
          return TPM_RC_NO_RESULT;
45
0
      case CRYPT_SCHEME:
46
0
          return TPM_RC_SCHEME;
47
0
      case CRYPT_PARAMETER:
48
0
          return TPM_RC_RANGE;
49
0
      case CRYPT_UNDERFLOW:
50
0
          return TPM_RC_SIZE;
51
0
      case CRYPT_POINT:
52
0
          return TPM_RC_ECC_POINT;
53
0
      case CRYPT_CANCEL:
54
0
       return TPM_RC_CANCELED;
55
0
   default: // CRYPT_HW_FAILURE and other unknown warnings
56
0
       return TPM_RC_FAILURE;
57
6
   }
58
6
}
59
//
60
//
61
//     10.2.3     Random Number Generation Functions
62
//
63
#ifdef TPM_ALG_NULL //%
64
#ifdef _DRBG_STATE_SAVE //%
65
//
66
//
67
//     10.2.3.1    CryptDrbgGetPutState()
68
//
69
//     Read or write the current state from the DRBG in the cryptoEngine.
70
//
71
void
72
CryptDrbgGetPutState(
73
   GET_PUT              direction         // IN: Get from or put to DRBG
74
   )
75
462
{
76
462
   _cpri__DrbgGetPutState(direction,
77
462
                          sizeof(go.drbgState),
78
462
                          (BYTE *)&go.drbgState);
79
462
}
80
#else   //% 00
81
//%#define CryptDrbgGetPutState(ignored)            // If not doing state save, turn this
82
//%                                                  // into a null macro
83
#endif //%
84
//
85
//
86
//     10.2.3.2    CryptStirRandom()
87
//
88
//     Stir random entropy
89
//
90
void
91
CryptStirRandom(
92
   UINT32               entropySize,      // IN: size of entropy buffer
93
   BYTE                *buffer            // IN: entropy buffer
94
   )
95
1
{
96
   // RNG self testing code may be inserted here
97
   // Call crypto engine random number stirring function
98
1
   _cpri__StirRandom(entropySize, buffer);
99
1
   return;
100
1
}
101
//
102
//
103
//     10.2.3.3    CryptGenerateRandom()
104
//
105
//     This is the interface to _cpri__GenerateRandom().
106
//
107
UINT16
108
CryptGenerateRandom(
109
   UINT16               randomSize,       // IN: size of random number
110
   BYTE                *buffer            // OUT: buffer of random number
111
   )
112
1.84k
{
113
1.84k
   UINT16               result;
114
1.84k
   pAssert(randomSize <= MAX_RSA_KEY_BYTES || randomSize <= PRIMARY_SEED_SIZE);
115
1.84k
   if(randomSize == 0)
116
0
          return 0;
117
    // Call crypto engine random number generation
118
1.84k
    result = _cpri__GenerateRandom(randomSize, buffer);
119
1.84k
    if(result != randomSize)
120
0
        FAIL(FATAL_ERROR_INTERNAL);
121
1.84k
   return result;
122
1.84k
}
123
#endif //TPM_ALG_NULL //%
124
//
125
//
126
//      10.2.4     Hash/HMAC Functions
127
//
128
//      10.2.4.1    CryptGetContextAlg()
129
//
130
//      This function returns the hash algorithm associated with a hash context.
131
//
132
#ifdef TPM_ALG_KEYEDHASH                 //% 1
133
TPM_ALG_ID
134
CryptGetContextAlg(
135
    void                *state                // IN: the context to check
136
    )
137
0
{
138
0
    HASH_STATE *context = (HASH_STATE *)state;
139
0
    return _cpri__GetContextAlg(&context->state);
140
0
}
141
//
142
//
143
//      10.2.4.2    CryptStartHash()
144
//
145
//      This function starts a hash and return the size, in bytes, of the digest.
146
//
147
//      Return Value                      Meaning
148
//
149
//      >0                                the digest size of the algorithm
150
//      =0                                the hashAlg was TPM_ALG_NULL
151
//
152
UINT16
153
CryptStartHash(
154
    TPMI_ALG_HASH        hashAlg,             // IN: hash algorithm
155
    HASH_STATE          *hashState            // OUT: the state of hash stack. It will be used
156
                                              //     in hash update and completion
157
    )
158
78
{
159
78
    CRYPT_RESULT            retVal = 0;
160
78
    pAssert(hashState != NULL);
161
78
    TEST_HASH(hashAlg);
162
78
    hashState->type = HASH_STATE_EMPTY;
163
    // Call crypto engine start hash function
164
78
    if((retVal = _cpri__StartHash(hashAlg, FALSE, &hashState->state)) > 0)
165
78
        hashState->type = HASH_STATE_HASH;
166
78
    return retVal;
167
78
}
168
//
169
//
170
//
171
//      10.2.4.3    CryptStartHashSequence()
172
//
173
//      Start a hash stack for a sequence object and return the size, in bytes, of the digest. This call uses the
174
//      form of the hash state that requires context save and restored.
175
//
176
//      Return Value                    Meaning
177
//
178
//      >0                              the digest size of the algorithm
179
//      =0                              the hashAlg was TPM_ALG_NULL
180
//
181
UINT16
182
CryptStartHashSequence(
183
    TPMI_ALG_HASH       hashAlg,            // IN: hash algorithm
184
    HASH_STATE         *hashState           // OUT: the state of hash stack. It will be used
185
                                            //     in hash update and completion
186
    )
187
0
{
188
0
    CRYPT_RESULT      retVal = 0;
189
0
    pAssert(hashState != NULL);
190
0
    TEST_HASH(hashAlg);
191
0
    hashState->type = HASH_STATE_EMPTY;
192
    // Call crypto engine start hash function
193
0
    if((retVal = _cpri__StartHash(hashAlg, TRUE, &hashState->state)) > 0)
194
0
        hashState->type = HASH_STATE_HASH;
195
0
    return retVal;
196
0
}
197
//
198
//
199
//      10.2.4.4    CryptStartHMAC()
200
//
201
//      This function starts an HMAC sequence and returns the size of the digest that will be produced.
202
//      The caller must provide a block of memory in which the hash sequence state is kept. The caller should
203
//      not alter the contents of this buffer until the hash sequence is completed or abandoned.
204
//
205
//      Return Value                    Meaning
206
//
207
//      >0                              the digest size of the algorithm
208
//      =0                              the hashAlg was TPM_ALG_NULL
209
//
210
UINT16
211
CryptStartHMAC(
212
    TPMI_ALG_HASH       hashAlg,            //   IN: hash algorithm
213
    UINT16              keySize,            //   IN: the size of HMAC key in byte
214
    BYTE               *key,                //   IN: HMAC key
215
    HMAC_STATE         *hmacState           //   OUT: the state of HMAC stack. It will be used
216
                                            //       in HMAC update and completion
217
    )
218
3
{
219
3
    HASH_STATE         *hashState = (HASH_STATE *)hmacState;
220
3
    CRYPT_RESULT       retVal;
221
    // This has to come before the pAssert in case we             all calling this function
222
    // during testing. If so, the first instance will             have no arguments but the
223
    // hash algorithm. The call from the test routine             will have arguments. When
224
    // the second call is done, then we return to the             test dispatcher.
225
3
    TEST_HASH(hashAlg);
226
3
    pAssert(hashState != NULL);
227
3
    hashState->type = HASH_STATE_EMPTY;
228
3
    if((retVal =    _cpri__StartHMAC(hashAlg, FALSE, &hashState->state, keySize, key,
229
3
                                     &hmacState->hmacKey.b)) > 0)
230
3
          hashState->type = HASH_STATE_HMAC;
231
3
    return retVal;
232
3
}
233
//
234
//
235
//      10.2.4.5    CryptStartHMACSequence()
236
//
237
//      This function starts an HMAC sequence and returns the size of the digest that will be produced.
238
//      The caller must provide a block of memory in which the hash sequence state is kept. The caller should
239
//      not alter the contents of this buffer until the hash sequence is completed or abandoned.
240
//      This call is used to start a sequence HMAC that spans multiple TPM commands.
241
//
242
//      Return Value                      Meaning
243
//
244
//      >0                                the digest size of the algorithm
245
//      =0                                the hashAlg was TPM_ALG_NULL
246
//
247
UINT16
248
CryptStartHMACSequence(
249
    TPMI_ALG_HASH       hashAlg,              //   IN: hash algorithm
250
    UINT16              keySize,              //   IN: the size of HMAC key in byte
251
    BYTE               *key,                  //   IN: HMAC key
252
    HMAC_STATE         *hmacState             //   OUT: the state of HMAC stack. It will be used
253
                                              //       in HMAC update and completion
254
    )
255
0
{
256
0
    HASH_STATE         *hashState = (HASH_STATE *)hmacState;
257
0
    CRYPT_RESULT       retVal;
258
0
    TEST_HASH(hashAlg);
259
0
    hashState->type = HASH_STATE_EMPTY;
260
0
    if((retVal =    _cpri__StartHMAC(hashAlg, TRUE, &hashState->state,
261
0
                                     keySize, key, &hmacState->hmacKey.b)) > 0)
262
0
          hashState->type = HASH_STATE_HMAC;
263
0
    return retVal;
264
0
}
265
//
266
//
267
//      10.2.4.6    CryptStartHMAC2B()
268
//
269
//      This function starts an HMAC and returns the size of the digest that will be produced.
270
//      This function is provided to support the most common use of starting an HMAC with a TPM2B key.
271
//      The caller must provide a block of memory in which the hash sequence state is kept. The caller should
272
//      not alter the contents of this buffer until the hash sequence is completed or abandoned.
273
//
274
//
275
//
276
//
277
//      Return Value                    Meaning
278
//
279
//      >0                              the digest size of the algorithm
280
//      =0                              the hashAlg was TPM_ALG_NULL
281
//
282
LIB_EXPORT UINT16
283
CryptStartHMAC2B(
284
    TPMI_ALG_HASH       hashAlg,            // IN: hash algorithm
285
    TPM2B              *key,                // IN: HMAC key
286
    HMAC_STATE         *hmacState           // OUT: the state of HMAC stack. It will be used
287
                                            //     in HMAC update and completion
288
    )
289
3
{
290
3
    return CryptStartHMAC(hashAlg, key->size, key->buffer, hmacState);
291
3
}
292
//
293
//
294
//      10.2.4.7    CryptStartHMACSequence2B()
295
//
296
//      This function starts an HMAC sequence and returns the size of the digest that will be produced.
297
//      This function is provided to support the most common use of starting an HMAC with a TPM2B key.
298
//      The caller must provide a block of memory in which the hash sequence state is kept. The caller should
299
//      not alter the contents of this buffer until the hash sequence is completed or abandoned.
300
//
301
//      Return Value                    Meaning
302
//
303
//      >0                              the digest size of the algorithm
304
//      =0                              the hashAlg was TPM_ALG_NULL
305
//
306
UINT16
307
CryptStartHMACSequence2B(
308
    TPMI_ALG_HASH       hashAlg,            // IN: hash algorithm
309
    TPM2B              *key,                // IN: HMAC key
310
    HMAC_STATE         *hmacState           // OUT: the state of HMAC stack. It will be used
311
                                            //     in HMAC update and completion
312
    )
313
0
{
314
0
    return CryptStartHMACSequence(hashAlg, key->size, key->buffer, hmacState);
315
0
}
316
//
317
//
318
//      10.2.4.8    CryptUpdateDigest()
319
//
320
//      This function updates a digest (hash or HMAC) with an array of octets.
321
//      This function can be used for both HMAC and hash functions so the digestState is void so that either
322
//      state type can be passed.
323
//
324
LIB_EXPORT void
325
CryptUpdateDigest(
326
    void               *digestState,        // IN: the state of hash stack
327
    UINT32              dataSize,           // IN: the size of data
328
    BYTE               *data                // IN: data to be hashed
329
    )
330
110
{
331
110
    HASH_STATE         *hashState = (HASH_STATE *)digestState;
332
110
    pAssert(digestState != NULL);
333
110
    if(hashState->type != HASH_STATE_EMPTY && data != NULL && dataSize != 0)
334
110
    {
335
          // Call crypto engine update hash function
336
110
          _cpri__UpdateHash(&hashState->state, dataSize, data);
337
110
    }
338
110
    return;
339
110
}
340
//
341
//
342
//      10.2.4.9     CryptUpdateDigest2B()
343
//
344
//      This function updates a digest (hash or HMAC) with a TPM2B.
345
//      This function can be used for both HMAC and hash functions so the digestState is void so that either
346
//      state type can be passed.
347
//
348
LIB_EXPORT void
349
CryptUpdateDigest2B(
350
    void                *digestState,       // IN: the digest state
351
    TPM2B               *bIn                // IN: 2B containing the data
352
    )
353
60
{
354
    // Only compute the digest if a pointer to the 2B is provided.
355
    // In CryptUpdateDigest(), if size is zero or buffer is NULL, then no change
356
    // to the digest occurs. This function should not provide a buffer if bIn is
357
    // not provided.
358
60
    if(bIn != NULL)
359
60
        CryptUpdateDigest(digestState, bIn->size, bIn->buffer);
360
60
    return;
361
60
}
362
//
363
//
364
//      10.2.4.10 CryptUpdateDigestInt()
365
//
366
//      This function is used to include an integer value to a hash stack. The function marshals the integer into its
367
//      canonical form before calling CryptUpdateHash().
368
//
369
LIB_EXPORT void
370
CryptUpdateDigestInt(
371
    void                *state,             // IN: the state of hash stack
372
    UINT32               intSize,           // IN: the size of 'intValue' in byte
373
    void                *intValue           // IN: integer value to be hashed
374
    )
375
3
{
376
#if BIG_ENDIAN_TPM == YES
377
   pAssert(    intValue != NULL && (intSize == 1 || intSize == 2
378
           || intSize == 4 || intSize == 8));
379
   CryptUpdateHash(state, inSize, (BYTE *)intValue);
380
#else
381
3
    BYTE        marshalBuffer[8];
382
    // Point to the big end of an little-endian value
383
3
    BYTE        *p = &((BYTE *)intValue)[intSize - 1];
384
    // Point to the big end of an big-endian value
385
3
    BYTE        *q = marshalBuffer;
386
3
    pAssert(intValue != NULL);
387
3
    switch (intSize)
388
3
    {
389
0
    case 8:
390
0
        *q++ = *p--;
391
0
        *q++ = *p--;
392
0
        *q++ = *p--;
393
0
        *q++ = *p--;
394
0
    case 4:
395
0
        *q++ = *p--;
396
0
         *q++ = *p--;
397
3
     case 2:
398
3
         *q++ = *p--;
399
3
     case 1:
400
3
         *q = *p;
401
         // Call update the hash
402
3
         CryptUpdateDigest(state, intSize, marshalBuffer);
403
3
         break;
404
0
     default:
405
0
         FAIL(0);
406
3
     }
407
3
#endif
408
3
   return;
409
3
}
410
//
411
//
412
//      10.2.4.11 CryptCompleteHash()
413
//
414
//      This function completes a hash sequence and returns the digest.
415
//      This function can be called to complete either an HMAC or hash sequence. The state type determines if
416
//      the context type is a hash or HMAC. If an HMAC, then the call is forwarded to CryptCompleteHash().
417
//      If digestSize is smaller than the digest size of hash/HMAC algorithm, the most significant bytes of
418
//      required size will be returned
419
//
420
//      Return Value                     Meaning
421
//
422
//      >=0                              the number of bytes placed in digest
423
//
424
LIB_EXPORT UINT16
425
CryptCompleteHash(
426
     void               *state,             // IN: the state of hash stack
427
     UINT16              digestSize,        // IN: size of digest buffer
428
     BYTE               *digest             // OUT: hash digest
429
     )
430
78
{
431
78
     HASH_STATE         *hashState = (HASH_STATE *)state;              // local value
432
     // If the session type is HMAC, then could forward this to
433
     // the HMAC processing and not cause an error. However, if no
434
     // function calls this routine to forward it, then we can't get
435
     // test coverage. The decision is to assert if this is called with
436
     // the type == HMAC and fix anything that makes the wrong call.
437
78
     pAssert(hashState->type == HASH_STATE_HASH);
438
     // Set the state to empty so that it doesn't get used again
439
78
     hashState->type = HASH_STATE_EMPTY;
440
     // Call crypto engine complete hash function
441
78
     return     _cpri__CompleteHash(&hashState->state, digestSize, digest);
442
78
}
443
//
444
//
445
//      10.2.4.12 CryptCompleteHash2B()
446
//
447
//      This function is the same as CypteCompleteHash() but the digest is placed in a TPM2B. This is the most
448
//      common use and this is provided for specification clarity. 'digest.size' should be set to indicate the number
449
//      of bytes to place in the buffer
450
//
451
//
452
//
453
//
454
//      Return Value                      Meaning
455
//
456
//      >=0                               the number of bytes placed in 'digest.buffer'
457
//
458
LIB_EXPORT UINT16
459
CryptCompleteHash2B(
460
     void               *state,               // IN: the state of hash stack
461
     TPM2B              *digest               // IN: the size of the buffer Out: requested
462
                                              //     number of byte
463
     )
464
6
{
465
6
     UINT16                  retVal = 0;
466
6
     if(digest != NULL)
467
6
         retVal = CryptCompleteHash(state, digest->size, digest->buffer);
468
6
     return retVal;
469
6
}
470
//
471
//
472
//      10.2.4.13 CryptHashBlock()
473
//
474
//      Hash a block of data and return the results. If the digest is larger than retSize, it is truncated and with the
475
//      least significant octets dropped.
476
//
477
//      Return Value                      Meaning
478
//
479
//      >=0                               the number of bytes placed in ret
480
//
481
LIB_EXPORT UINT16
482
CryptHashBlock(
483
     TPM_ALG_ID          algId,               //   IN: the hash algorithm to use
484
     UINT16              blockSize,           //   IN: size of the data block
485
     BYTE               *block,               //   IN: address of the block to hash
486
     UINT16              retSize,             //   IN: size of the return buffer
487
     BYTE               *ret                  //   OUT: address of the buffer
488
     )
489
0
{
490
0
     TEST_HASH(algId);
491
0
     return _cpri__HashBlock(algId, blockSize, block, retSize, ret);
492
0
}
493
//
494
//
495
//      10.2.4.14 CryptCompleteHMAC()
496
//
497
//      This function completes a HMAC sequence and returns the digest. If digestSize is smaller than the digest
498
//      size of the HMAC algorithm, the most significant bytes of required size will be returned.
499
//
500
//      Return Value                      Meaning
501
//
502
//      >=0                               the number of bytes placed in digest
503
//
504
LIB_EXPORT UINT16
505
CryptCompleteHMAC(
506
     HMAC_STATE         *hmacState,           // IN: the state of HMAC stack
507
     UINT32              digestSize,          // IN: size of digest buffer
508
     BYTE               *digest               // OUT: HMAC digest
509
     )
510
3
{
511
3
     HASH_STATE         *hashState;
512
3
     pAssert(hmacState != NULL);
513
3
     hashState = &hmacState->hashState;
514
3
     pAssert(hashState->type == HASH_STATE_HMAC);
515
3
     hashState->type = HASH_STATE_EMPTY;
516
3
     return _cpri__CompleteHMAC(&hashState->state, &hmacState->hmacKey.b,
517
3
                                digestSize, digest);
518
3
}
519
//
520
//
521
//      10.2.4.15 CryptCompleteHMAC2B()
522
//
523
//      This function is the same as CryptCompleteHMAC() but the HMAC result is returned in a TPM2B which is
524
//      the most common use.
525
//
526
//      Return Value                     Meaning
527
//
528
//      >=0                              the number of bytes placed in digest
529
//
530
LIB_EXPORT UINT16
531
CryptCompleteHMAC2B(
532
     HMAC_STATE         *hmacState,           // IN: the state of HMAC stack
533
     TPM2B              *digest               // OUT: HMAC
534
     )
535
3
{
536
3
     UINT16               retVal = 0;
537
3
     if(digest != NULL)
538
3
         retVal = CryptCompleteHMAC(hmacState, digest->size, digest->buffer);
539
3
     return retVal;
540
3
}
541
//
542
//
543
//      10.2.4.16 CryptHashStateImportExport()
544
//
545
//      This function is used to prepare a hash state context for LIB_EXPORT or to import it into the internal
546
//      format. It is used by TPM2_ContextSave() and TPM2_ContextLoad() via SequenceDataImportExport().
547
//      This is just a pass-through function to the crypto library.
548
//
549
void
550
CryptHashStateImportExport(
551
     HASH_STATE         *internalFmt,         // IN: state to LIB_EXPORT
552
     HASH_STATE         *externalFmt,         // OUT: exported state
553
     IMPORT_EXPORT       direction
554
     )
555
0
{
556
0
     _cpri__ImportExportHashState(&internalFmt->state,
557
0
                                  (EXPORT_HASH_STATE *)&externalFmt->state,
558
0
                                  direction);
559
0
}
560
//
561
//
562
//      10.2.4.17 CryptGetHashDigestSize()
563
//
564
//      This function returns the digest size in bytes for a hash algorithm.
565
//
566
//      Return Value                     Meaning
567
//
568
//      0                                digest size for TPM_ALG_NULL
569
//      >0                               digest size
570
//
571
LIB_EXPORT UINT16
572
CryptGetHashDigestSize(
573
    TPM_ALG_ID           hashAlg              // IN: hash algorithm
574
    )
575
22.2k
{
576
22.2k
    return _cpri__GetDigestSize(hashAlg);
577
22.2k
}
578
//
579
//
580
//      10.2.4.18 CryptGetHashBlockSize()
581
//
582
//      Get the digest size in byte of a hash algorithm.
583
//
584
//      Return Value                      Meaning
585
//
586
//      0                                 block size for TPM_ALG_NULL
587
//      >0                                block size
588
//
589
LIB_EXPORT UINT16
590
CryptGetHashBlockSize(
591
    TPM_ALG_ID           hash                 // IN: hash algorithm to look up
592
    )
593
0
{
594
0
    return _cpri__GetHashBlockSize(hash);
595
0
}
596
//
597
//
598
//      10.2.4.19 CryptGetHashAlgByIndex()
599
//
600
//      This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes that are
601
//      not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return the first
602
//      implemented hash and an index value of 2 will return the last implemented hash. All other index values
603
//      will return TPM_ALG_NULL.
604
//
605
//      Return Value                      Meaning
606
//
607
//      TPM_ALG_xxx()                     a hash algorithm
608
//      TPM_ALG_NULL                      this can be used as a stop value
609
//
610
LIB_EXPORT TPM_ALG_ID
611
CryptGetHashAlgByIndex(
612
    UINT32               index                // IN: the index
613
    )
614
924
{
615
924
    return _cpri__GetHashAlgByIndex(index);
616
924
}
617
//
618
//
619
//      10.2.4.20 CryptSignHMAC()
620
//
621
//      Sign a digest using an HMAC key. This an HMAC of a digest, not an HMAC of a message.
622
//
623
//      Error Returns                     Meaning
624
//
625
static TPM_RC
626
CryptSignHMAC(
627
    OBJECT                   *signKey,              //   IN: HMAC key sign the hash
628
    TPMT_SIG_SCHEME          *scheme,               //   IN: signing scheme
629
    TPM2B_DIGEST             *hashData,             //   IN: hash to be signed
630
    TPMT_SIGNATURE           *signature             //   OUT: signature
631
    )
632
0
{
633
//
634
0
   HMAC_STATE           hmacState;
635
0
   UINT32               digestSize;
636
637
0
   if (signature->sigAlg != TPM_ALG_HMAC)
638
0
        return TPM_RC_SCHEME;
639
   // HMAC algorithm self testing code may be inserted here
640
0
   digestSize = CryptStartHMAC2B(scheme->details.hmac.hashAlg,
641
0
                                 &signKey->sensitive.sensitive.bits.b,
642
0
                                 &hmacState);
643
   // The hash algorithm must be a valid one.
644
0
   pAssert(digestSize > 0);
645
0
   CryptUpdateDigest2B(&hmacState, &hashData->b);
646
0
   CryptCompleteHMAC(&hmacState, digestSize,
647
0
                     (BYTE *) &signature->signature.hmac.digest);
648
   // Set HMAC algorithm
649
0
   signature->signature.hmac.hashAlg = scheme->details.hmac.hashAlg;
650
0
   return TPM_RC_SUCCESS;
651
0
}
652
//
653
//
654
//      10.2.4.21 CryptHMACVerifySignature()
655
//
656
//      This function will verify a signature signed by a HMAC key.
657
//
658
//      Error Returns                   Meaning
659
//
660
//      TPM_RC_SIGNATURE                if invalid input or signature is not genuine
661
//
662
static TPM_RC
663
CryptHMACVerifySignature(
664
   OBJECT              *signKey,            // IN: HMAC key signed the hash
665
   TPM2B_DIGEST        *hashData,           // IN: digest being verified
666
   TPMT_SIGNATURE      *signature           // IN: signature to be verified
667
   )
668
0
{
669
0
   HMAC_STATE                hmacState;
670
0
   TPM2B_DIGEST              digestToCompare;
671
0
   digestToCompare.t.size = CryptStartHMAC2B(signature->signature.hmac.hashAlg,
672
0
                            &signKey->sensitive.sensitive.bits.b, &hmacState);
673
0
   CryptUpdateDigest2B(&hmacState, &hashData->b);
674
0
   CryptCompleteHMAC2B(&hmacState, &digestToCompare.b);
675
   // Compare digest
676
0
   if(MemoryEqual(digestToCompare.t.buffer,
677
0
                  (BYTE *) &signature->signature.hmac.digest,
678
0
                  digestToCompare.t.size))
679
0
       return TPM_RC_SUCCESS;
680
0
   else
681
0
       return TPM_RC_SIGNATURE;
682
0
}
683
//
684
//
685
//      10.2.4.22 CryptGenerateKeyedHash()
686
//
687
//      This function creates a keyedHash object.
688
//
689
//
690
//
691
//      Error Returns                     Meaning
692
//
693
//      TPM_RC_SIZE                       sensitive data size is larger than allowed for the scheme
694
//      TPM_RC_VALUE                      the publicArea nameAlg is invalid
695
//
696
static TPM_RC
697
CryptGenerateKeyedHash(
698
   TPMT_PUBLIC                    *publicArea,                //   IN/OUT: the public area template
699
                                                              //       for the new key.
700
   TPMS_SENSITIVE_CREATE          *sensitiveCreate,           //   IN: sensitive creation data
701
   TPMT_SENSITIVE                 *sensitive,                 //   OUT: sensitive area
702
   TPM_ALG_ID                      kdfHashAlg,                //   IN: algorithm for the KDF
703
   TPM2B_SEED                     *seed,                      //   IN: the seed
704
   TPM2B_NAME                     *name                       //   IN: name of the object
705
   )
706
0
{
707
0
   TPMT_KEYEDHASH_SCHEME          *scheme;
708
0
   TPM_ALG_ID                      hashAlg;
709
0
   UINT16                          hashBlockSize;
710
   // Check parameter values
711
0
   if(publicArea->nameAlg == TPM_ALG_NULL)
712
0
   {
713
0
       return TPM_RC_VALUE;
714
0
   }
715
0
   scheme = &publicArea->parameters.keyedHashDetail.scheme;
716
0
   pAssert(publicArea->type == TPM_ALG_KEYEDHASH);
717
   // Pick the limiting hash algorithm
718
0
   if(scheme->scheme == TPM_ALG_NULL)
719
0
       hashAlg = publicArea->nameAlg;
720
0
   else if(scheme->scheme == TPM_ALG_XOR)
721
0
       hashAlg = scheme->details.xor_.hashAlg;
722
0
   else
723
0
       hashAlg = scheme->details.hmac.hashAlg;
724
0
   hashBlockSize = CryptGetHashBlockSize(hashAlg);
725
   // if this is a signing or a decryption key, then then the limit
726
   // for the data size is the block size of the hash. This limit
727
   // is set because larger values have lower entropy because of the
728
   // HMAC function.
729
0
   if(publicArea->objectAttributes.sensitiveDataOrigin == CLEAR)
730
0
   {
731
0
       if(    (    publicArea->objectAttributes.decrypt
732
0
                || publicArea->objectAttributes.sign)
733
0
           && sensitiveCreate->data.t.size > hashBlockSize)
734
0
           return TPM_RC_SIZE;
735
0
   }
736
0
   else
737
0
   {
738
       // If the TPM is going to generate the data, then set the size to be the
739
       // size of the digest of the algorithm
740
0
       sensitive->sensitive.sym.t.size = CryptGetHashDigestSize(hashAlg);
741
0
       sensitiveCreate->data.t.size = 0;
742
0
   }
743
   // Fill in the sensitive area
744
0
   CryptGenerateNewSymmetric(sensitiveCreate, sensitive, kdfHashAlg,
745
0
                             seed, name);
746
   // Create unique area in public
747
0
   CryptComputeSymmetricUnique(publicArea->nameAlg,
748
0
                               sensitive, &publicArea->unique.sym);
749
0
   return TPM_RC_SUCCESS;
750
0
}
751
//
752
//
753
//      10.2.4.25 KDFa()
754
//
755
//      This function is used by functions outside of CryptUtil() to access _cpri_KDFa().
756
//
757
void
758
KDFa(
759
   TPM_ALG_ID           hash,              //   IN: hash algorithm used in HMAC
760
   TPM2B               *key,               //   IN: HMAC key
761
   const char          *label,             //   IN: a null-terminated label for KDF
762
   TPM2B               *contextU,          //   IN: context U
763
   TPM2B               *contextV,          //   IN: context V
764
   UINT32               sizeInBits,        //   IN: size of generated key in bit
765
   BYTE                *keyStream,         //   OUT: key buffer
766
   UINT32              *counterInOut       //   IN/OUT: caller may provide the iteration
767
                                           //       counter for incremental operations to
768
                                           //       avoid large intermediate buffers.
769
   )
770
0
{
771
0
   CryptKDFa(hash, key, label, contextU, contextV, sizeInBits,
772
0
             keyStream, counterInOut);
773
0
}
774
#endif //TPM_ALG_KEYEDHASH     //% 1
775
//
776
//
777
//      10.2.5     RSA Functions
778
//
779
//      10.2.5.1    BuildRSA()
780
//
781
//      Function to set the cryptographic elements of an RSA key into a structure to simplify the interface to
782
//      _cpri__ RSA function. This can/should be eliminated by building this structure into the object structure.
783
//
784
#ifdef TPM_ALG_RSA                 //% 2
785
static void
786
BuildRSA(
787
   OBJECT              *rsaKey,
788
   RSA_KEY             *key
789
   )
790
0
{
791
0
   key->exponent = rsaKey->publicArea.parameters.rsaDetail.exponent;
792
0
   if(key->exponent == 0)
793
0
       key->exponent = RSA_DEFAULT_PUBLIC_EXPONENT;
794
0
   key->publicKey = &rsaKey->publicArea.unique.rsa.b;
795
0
   if(rsaKey->attributes.publicOnly || rsaKey->privateExponent.t.size == 0)
796
0
       key->privateKey = NULL;
797
0
   else
798
0
       key->privateKey = &(rsaKey->privateExponent.b);
799
0
}
800
//
801
//
802
//      10.2.5.2    CryptTestKeyRSA()
803
//
804
//      This function provides the interface to _cpri__TestKeyRSA(). If both p and q are provided, n will be set to
805
//      p*q.
806
//      If only p is provided, q is computed by q = n/p. If n mod p != 0, TPM_RC_BINDING is returned.
807
//      The key is validated by checking that a d can be found such that e d mod ((p-1)*(q-1)) = 1. If d is found
808
//      that satisfies this requirement, it will be placed in d.
809
//      Page 286                                     TCG Published                                   Family "2.0"
810
//      October 30, 2014                     Copyright © TCG 2006-2014                  Level 00 Revision 01.16
811
//      Part 4: Supporting Routines                                                    Trusted Platform Module Library
812
//
813
//
814
//      Error Returns                   Meaning
815
//
816
//      TPM_RC_BINDING                  the public and private portions of the key are not matched
817
//
818
TPM_RC
819
CryptTestKeyRSA(
820
   TPM2B              *d,                   //   OUT: receives the private exponent
821
   UINT32              e,                   //   IN: public exponent
822
   TPM2B              *n,                   //   IN/OUT: public modulu
823
   TPM2B              *p,                   //   IN: a first prime
824
   TPM2B              *q                    //   IN: an optional second prime
825
   )
826
32
{
827
32
   CRYPT_RESULT       retVal;
828
32
   TEST(ALG_NULL_VALUE);
829
32
   pAssert(d != NULL && n != NULL && p != NULL);
830
   // Set the exponent
831
32
   if(e == 0)
832
1
       e = RSA_DEFAULT_PUBLIC_EXPONENT;
833
   // CRYPT_PARAMETER
834
32
   retVal =_cpri__TestKeyRSA(d, e, n, p, q);
835
32
   if(retVal == CRYPT_SUCCESS)
836
1
       return TPM_RC_SUCCESS;
837
31
   else
838
31
       return TPM_RC_BINDING; // convert CRYPT_PARAMETER
839
32
}
840
//
841
//
842
//      10.2.5.3   CryptGenerateKeyRSA()
843
//
844
//      This function is called to generate an RSA key from a provided seed. It calls _cpri__GenerateKeyRSA()
845
//      to perform the computations. The implementation is vendor specific.
846
//
847
//      Error Returns                   Meaning
848
//
849
//      TPM_RC_RANGE                    the exponent value is not supported
850
//      TPM_RC_CANCELLED                key generation has been canceled
851
//      TPM_RC_VALUE                    exponent is not prime or is less than 3; or could not find a prime using
852
//                                      the provided parameters
853
//
854
static TPM_RC
855
CryptGenerateKeyRSA(
856
   TPMT_PUBLIC               *publicArea,              //   IN/OUT: The public area template for
857
                                                       //        the new key. The public key
858
                                                       //        area will be replaced by the
859
                                                       //        product of two primes found by
860
                                                       //        this function
861
   TPMT_SENSITIVE            *sensitive,               //   OUT: the sensitive area will be
862
                                                       //        updated to contain the first
863
                                                       //        prime and the symmetric
864
                                                       //        encryption key
865
   TPM_ALG_ID                 hashAlg,                 //   IN: the hash algorithm for the KDF
866
   TPM2B_SEED                *seed,                    //   IN: Seed for the creation
867
   TPM2B_NAME                *name,                    //   IN: Object name
868
   UINT32                    *counter                  //   OUT: last iteration of the counter
869
)
870
3
{
871
3
   CRYPT_RESULT       retVal;
872
3
   UINT32             exponent = publicArea->parameters.rsaDetail.exponent;
873
3
   TEST_HASH(hashAlg);
874
3
   TEST(ALG_NULL_VALUE);
875
   // In this implementation, only the default exponent is allowed
876
3
   if(exponent != 0 && exponent != RSA_DEFAULT_PUBLIC_EXPONENT)
877
0
       return TPM_RC_RANGE;
878
3
   exponent = RSA_DEFAULT_PUBLIC_EXPONENT;
879
3
   *counter = 0;
880
   // _cpri_GenerateKeyRSA can return CRYPT_CANCEL or CRYPT_FAIL
881
3
   retVal = _cpri__GenerateKeyRSA(&publicArea->unique.rsa.b,
882
3
                                  &sensitive->sensitive.rsa.b,
883
3
                                  publicArea->parameters.rsaDetail.keyBits,
884
3
                                  exponent,
885
3
                                  hashAlg,
886
3
                                  &seed->b,
887
3
                                  "RSA key by vendor",
888
3
                                  &name->b,
889
3
                                  counter);
890
   // CRYPT_CANCEL -> TPM_RC_CANCELLED; CRYPT_FAIL -> TPM_RC_VALUE
891
3
   return TranslateCryptErrors(retVal);
892
3
}
893
//
894
//
895
//      10.2.5.4    CryptLoadPrivateRSA()
896
//
897
//      This function is called to generate the private exponent of an RSA key. It uses CryptTestKeyRSA().
898
//
899
//      Error Returns                     Meaning
900
//
901
//      TPM_RC_BINDING                    public and private parts of rsaKey are not matched
902
//
903
TPM_RC
904
CryptLoadPrivateRSA(
905
   OBJECT              *rsaKey               // IN: the RSA key object
906
   )
907
32
{
908
32
   TPM_RC               result;
909
32
   TPMT_PUBLIC         *publicArea = &rsaKey->publicArea;
910
32
   TPMT_SENSITIVE      *sensitive = &rsaKey->sensitive;
911
   // Load key by computing the private exponent
912
   // TPM_RC_BINDING
913
32
   result = CryptTestKeyRSA(&(rsaKey->privateExponent.b),
914
32
                            publicArea->parameters.rsaDetail.exponent,
915
32
                            &(publicArea->unique.rsa.b),
916
32
                            &(sensitive->sensitive.rsa.b),
917
32
                            NULL);
918
32
   if(result == TPM_RC_SUCCESS)
919
1
       rsaKey->attributes.privateExp = SET;
920
32
   return result;
921
32
}
922
//
923
//
924
//      10.2.5.5    CryptSelectRSAScheme()
925
//
926
//      This function is used by TPM2_RSA_Decrypt() and TPM2_RSA_Encrypt(). It sets up the rules to select a
927
//      scheme between input and object default. This function assume the RSA object is loaded. If a default
928
//      scheme is defined in object, the default scheme should be chosen, otherwise, the input scheme should
929
//      be chosen. In the case that both the object and scheme are not TPM_ALG_NULL, then if the schemes
930
//
931
//
932
//      are the same, the input scheme will be chosen. if the scheme are not compatible, a NULL pointer will be
933
//      returned.
934
//      The return pointer may point to a TPM_ALG_NULL scheme.
935
//
936
TPMT_RSA_DECRYPT*
937
CryptSelectRSAScheme(
938
   TPMI_DH_OBJECT             rsaHandle,         // IN: handle of sign key
939
   TPMT_RSA_DECRYPT          *scheme             // IN: a sign or decrypt scheme
940
   )
941
0
{
942
0
   OBJECT                    *rsaObject;
943
0
   TPMT_ASYM_SCHEME          *keyScheme;
944
0
   TPMT_RSA_DECRYPT          *retVal = NULL;
945
   // Get sign object pointer
946
0
   rsaObject = ObjectGet(rsaHandle);
947
0
   keyScheme = &rsaObject->publicArea.parameters.asymDetail.scheme;
948
   // if the default scheme of the object is TPM_ALG_NULL, then select the
949
   // input scheme
950
0
   if(keyScheme->scheme == TPM_ALG_NULL)
951
0
   {
952
0
       retVal = scheme;
953
0
   }
954
   // if the object scheme is not TPM_ALG_NULL and the input scheme is
955
   // TPM_ALG_NULL, then select the default scheme of the object.
956
0
   else if(scheme->scheme == TPM_ALG_NULL)
957
0
   {
958
       // if input scheme is NULL
959
0
       retVal = (TPMT_RSA_DECRYPT *)keyScheme;
960
0
   }
961
   // get here if both the object scheme and the input scheme are
962
   // not TPM_ALG_NULL. Need to insure that they are the same.
963
   // The hash algorithm match has to be verified for OAEP.
964
   // IMPLEMENTATION NOTE: This could cause problems if future versions have
965
   // schemes that have more values than just a hash algorithm. A new function
966
   // (IsSchemeSame()) might be needed then.
967
0
   else if (keyScheme->scheme == scheme->scheme
968
0
            && ((keyScheme->scheme != TPM_ALG_OAEP) ||
969
0
                (keyScheme->details.anySig.hashAlg == scheme->details.anySig.hashAlg)))
970
0
   {
971
0
       retVal = scheme;
972
0
   }
973
   // two different, incompatible schemes specified will return NULL
974
0
   return retVal;
975
0
}
976
//
977
//
978
//      10.2.5.6    CryptDecryptRSA()
979
//
980
//      This function is the interface to _cpri__DecryptRSA(). It handles the return codes from that function and
981
//      converts them from CRYPT_RESULT to TPM_RC values. The rsaKey parameter must reference an RSA
982
//      decryption key
983
//
984
//      Error Returns                   Meaning
985
//
986
//      TPM_RC_BINDING                  Public and private parts of the key are not cryptographically bound.
987
//      TPM_RC_SIZE                     Size of data to decrypt is not the same as the key size.
988
//      TPM_RC_VALUE                    Numeric value of the encrypted data is greater than the public
989
//                                      exponent, or output buffer is too small for the decrypted message.
990
//
991
TPM_RC
992
CryptDecryptRSA(
993
   UINT16                    *dataOutSize,       // OUT: size of plain text in byte
994
   BYTE                    *dataOut,        //   OUT: plain text
995
   OBJECT                  *rsaKey,         //   IN: internal RSA key
996
   TPMT_RSA_DECRYPT        *scheme,         //   IN: selects the padding scheme
997
   UINT16                   cipherInSize,   //   IN: size of cipher text in byte
998
   BYTE                    *cipherIn,       //   IN: cipher text
999
   const char              *label           //   IN: a label, when needed
1000
   )
1001
0
{
1002
0
   RSA_KEY            key;
1003
0
   CRYPT_RESULT       retVal = CRYPT_SUCCESS;
1004
0
   UINT32             dSize;                   //   Place to put temporary value for the
1005
                                               //   returned data size
1006
0
   TPMI_ALG_HASH      hashAlg = TPM_ALG_NULL; //    hash algorithm in the selected
1007
                                               //   padding scheme
1008
0
   TPM_RC             result = TPM_RC_SUCCESS;
1009
   // pointer checks
1010
0
   pAssert(    (dataOutSize != NULL) && (dataOut != NULL)
1011
0
           && (rsaKey != NULL) && (cipherIn != NULL));
1012
   // The public type is a RSA decrypt key
1013
0
   pAssert(    (rsaKey->publicArea.type == TPM_ALG_RSA
1014
0
           && rsaKey->publicArea.objectAttributes.decrypt == SET));
1015
   // Must have the private portion loaded. This check is made before this
1016
   // function is called.
1017
0
   pAssert(rsaKey->attributes.publicOnly == CLEAR);
1018
   // decryption requires that the private modulus be present
1019
0
   if(rsaKey->attributes.privateExp == CLEAR)
1020
0
   {
1021
        // Load key by computing the private exponent
1022
        // CryptLoadPrivateRSA may return TPM_RC_BINDING
1023
0
        result = CryptLoadPrivateRSA(rsaKey);
1024
0
   }
1025
   // the input buffer must be the size of the key
1026
0
   if(result == TPM_RC_SUCCESS)
1027
0
   {
1028
0
       if(cipherInSize != rsaKey->publicArea.unique.rsa.t.size)
1029
0
            result = TPM_RC_SIZE;
1030
0
       else
1031
0
       {
1032
0
            BuildRSA(rsaKey, &key);
1033
             // Initialize the dOutSize parameter
1034
0
             dSize = *dataOutSize;
1035
             // For OAEP scheme, initialize the hash algorithm for padding
1036
0
             if(scheme->scheme == TPM_ALG_OAEP)
1037
0
             {
1038
0
                 hashAlg = scheme->details.oaep.hashAlg;
1039
0
                 TEST_HASH(hashAlg);
1040
0
             }
1041
             // See if the padding mode needs to be tested
1042
0
             TEST(scheme->scheme);
1043
             // _cpri__DecryptRSA may return CRYPT_PARAMETER CRYPT_FAIL CRYPT_SCHEME
1044
0
             retVal = _cpri__DecryptRSA(&dSize, dataOut, &key, scheme->scheme,
1045
0
                                        cipherInSize, cipherIn, hashAlg, label);
1046
             // Scheme must have been validated when the key was loaded/imported
1047
0
             pAssert(retVal != CRYPT_SCHEME);
1048
             // Set the return size
1049
0
               pAssert(dSize <= UINT16_MAX);
1050
0
               *dataOutSize = (UINT16)dSize;
1051
               // CRYPT_PARAMETER -> TPM_RC_VALUE, CRYPT_FAIL -> TPM_RC_VALUE
1052
0
               result = TranslateCryptErrors(retVal);
1053
0
       }
1054
0
   }
1055
0
   return result;
1056
0
}
1057
//
1058
//
1059
//      10.2.5.7   CryptEncryptRSA()
1060
//
1061
//      This function provides the interface to _cpri__EncryptRSA(). The object referenced by rsaKey is required
1062
//      to be an RSA decryption key.
1063
//
1064
//      Error Returns                   Meaning
1065
//
1066
//      TPM_RC_SCHEME                   scheme is not supported
1067
//      TPM_RC_VALUE                    numeric value of dataIn is greater than the key modulus
1068
//
1069
TPM_RC
1070
CryptEncryptRSA(
1071
   UINT16                    *cipherOutSize,    //   OUT: size of cipher text in byte
1072
   BYTE                      *cipherOut,        //   OUT: cipher text
1073
   OBJECT                    *rsaKey,           //   IN: internal RSA key
1074
   TPMT_RSA_DECRYPT          *scheme,           //   IN: selects the padding scheme
1075
   UINT16                     dataInSize,       //   IN: size of plain text in byte
1076
   BYTE                      *dataIn,           //   IN: plain text
1077
   const char                *label             //   IN: an optional label
1078
   )
1079
0
{
1080
0
   RSA_KEY                    key;
1081
0
   CRYPT_RESULT               retVal;
1082
0
   UINT32                     cOutSize;                         // Conversion variable
1083
0
   TPMI_ALG_HASH              hashAlg = TPM_ALG_NULL;           // hash algorithm in selected
1084
                                                                // padding scheme
1085
   // must have a pointer to a key and some data to encrypt
1086
0
   pAssert(rsaKey != NULL && dataIn != NULL);
1087
   // The public type is a RSA decryption key
1088
0
   pAssert(   rsaKey->publicArea.type == TPM_ALG_RSA
1089
0
           && rsaKey->publicArea.objectAttributes.decrypt == SET);
1090
   // If the cipher buffer must be provided and it must be large enough
1091
   // for the result
1092
0
   pAssert(   cipherOut != NULL
1093
0
           && cipherOutSize != NULL
1094
0
           && *cipherOutSize >= rsaKey->publicArea.unique.rsa.t.size);
1095
   // Only need the public key and exponent for encryption
1096
0
   BuildRSA(rsaKey, &key);
1097
   // Copy the size to the conversion buffer
1098
0
   cOutSize = *cipherOutSize;
1099
   // For OAEP scheme, initialize the hash algorithm for padding
1100
0
   if(scheme->scheme == TPM_ALG_OAEP)
1101
0
   {
1102
0
       hashAlg = scheme->details.oaep.hashAlg;
1103
0
       TEST_HASH(hashAlg);
1104
0
   }
1105
   // This is a public key operation and does not require that the private key
1106
   // be loaded. To verify this, need to do the full algorithm
1107
0
   TEST(scheme->scheme);
1108
   // Encrypt the data with the public exponent
1109
   // _cpri__EncryptRSA may return CRYPT_PARAMETER or CRYPT_SCHEME
1110
0
   retVal = _cpri__EncryptRSA(&cOutSize,cipherOut, &key, scheme->scheme,
1111
0
                              dataInSize, dataIn, hashAlg, label);
1112
0
   pAssert (cOutSize <= UINT16_MAX);
1113
0
   *cipherOutSize = (UINT16)cOutSize;
1114
   // CRYPT_PARAMETER -> TPM_RC_VALUE, CRYPT_SCHEME -> TPM_RC_SCHEME
1115
0
   return TranslateCryptErrors(retVal);
1116
0
}
1117
//
1118
//
1119
//      10.2.5.8     CryptSignRSA()
1120
//
1121
//      This function is used to sign a digest with an RSA signing key.
1122
//
1123
//      Error Returns                     Meaning
1124
//
1125
//      TPM_RC_BINDING                    public and private part of signKey are not properly bound
1126
//      TPM_RC_SCHEME                     scheme is not supported
1127
//      TPM_RC_VALUE                      hashData is larger than the modulus of signKey, or the size of
1128
//                                        hashData does not match hash algorithm in scheme
1129
//
1130
static TPM_RC
1131
CryptSignRSA(
1132
   OBJECT                   *signKey,              //   IN: RSA key signs the hash
1133
   TPMT_SIG_SCHEME          *scheme,               //   IN: sign scheme
1134
   TPM2B_DIGEST             *hashData,             //   IN: hash to be signed
1135
   TPMT_SIGNATURE           *sig                   //   OUT: signature
1136
   )
1137
0
{
1138
0
   UINT32                     signSize;
1139
0
   RSA_KEY                    key;
1140
0
   CRYPT_RESULT               retVal;
1141
0
   TPM_RC                     result = TPM_RC_SUCCESS;
1142
0
   pAssert(       (signKey != NULL) && (scheme != NULL)
1143
0
                  && (hashData != NULL) && (sig != NULL));
1144
   // assume that the key has private part loaded and that it is a signing key.
1145
0
   pAssert(   (signKey->attributes.publicOnly == CLEAR)
1146
0
           && (signKey->publicArea.objectAttributes.sign == SET));
1147
   // check if the private exponent has been computed
1148
0
   if(signKey->attributes.privateExp == CLEAR)
1149
       // May return TPM_RC_BINDING
1150
0
       result = CryptLoadPrivateRSA(signKey);
1151
0
   if(result == TPM_RC_SUCCESS)
1152
0
   {
1153
0
       BuildRSA(signKey, &key);
1154
          // Make sure that the hash is tested
1155
0
          TEST_HASH(sig->signature.any.hashAlg);
1156
          // Run a test of the RSA sign
1157
0
          TEST(scheme->scheme);
1158
          // _crypi__SignRSA can return CRYPT_SCHEME and CRYPT_PARAMETER
1159
0
          retVal = _cpri__SignRSA(&signSize,
1160
0
                                  sig->signature.rsassa.sig.t.buffer,
1161
0
                                  &key,
1162
0
                                  sig->sigAlg,
1163
0
                                  sig->signature.any.hashAlg,
1164
0
                                  hashData->t.size, hashData->t.buffer);
1165
0
          pAssert(signSize <= UINT16_MAX);
1166
0
          sig->signature.rsassa.sig.t.size = (UINT16)signSize;
1167
          // CRYPT_SCHEME -> TPM_RC_SCHEME; CRYPT_PARAMTER -> TPM_RC_VALUE
1168
0
          result = TranslateCryptErrors(retVal);
1169
0
   }
1170
0
   return result;
1171
0
}
1172
//
1173
//
1174
//      10.2.5.9    CryptRSAVerifySignature()
1175
//
1176
//      This function is used to verify signature signed by a RSA key.
1177
//
1178
//      Error Returns                   Meaning
1179
//
1180
//      TPM_RC_SIGNATURE                if signature is not genuine
1181
//      TPM_RC_SCHEME                   signature scheme not supported
1182
//
1183
static TPM_RC
1184
CryptRSAVerifySignature(
1185
   OBJECT              *signKey,            // IN: RSA key signed the hash
1186
   TPM2B_DIGEST        *digestData,         // IN: digest being signed
1187
   TPMT_SIGNATURE      *sig                 // IN: signature to be verified
1188
   )
1189
0
{
1190
0
   RSA_KEY                   key;
1191
0
   CRYPT_RESULT              retVal;
1192
0
   TPM_RC                    result;
1193
   // Validate parameter assumptions
1194
0
   pAssert((signKey != NULL) && (digestData != NULL) && (sig != NULL));
1195
0
   TEST_HASH(sig->signature.any.hashAlg);
1196
0
   TEST(sig->sigAlg);
1197
   // This is a public-key-only operation
1198
0
   BuildRSA(signKey, &key);
1199
   // Call crypto engine to verify signature
1200
   // _cpri_ValidateSignaturRSA may return CRYPT_FAIL or CRYPT_SCHEME
1201
0
   retVal = _cpri__ValidateSignatureRSA(&key,
1202
0
                                        sig->sigAlg,
1203
0
                                        sig->signature.any.hashAlg,
1204
0
                                        digestData->t.size,
1205
0
                                        digestData->t.buffer,
1206
0
                                        sig->signature.rsassa.sig.t.size,
1207
0
                                        sig->signature.rsassa.sig.t.buffer,
1208
0
                                        0);
1209
   // _cpri__ValidateSignatureRSA can return CRYPT_SUCCESS, CRYPT_FAIL, or
1210
   // CRYPT_SCHEME. Translate CRYPT_FAIL to TPM_RC_SIGNATURE
1211
0
   if(retVal == CRYPT_FAIL)
1212
0
       result = TPM_RC_SIGNATURE;
1213
0
   else
1214
       // CRYPT_SCHEME -> TPM_RC_SCHEME
1215
0
       result = TranslateCryptErrors(retVal);
1216
0
   return result;
1217
0
}
1218
//
1219
#endif //TPM_ALG_RSA             //% 2
1220
//
1221
//
1222
//      10.2.6     ECC Functions
1223
//
1224
//      10.2.6.1    CryptEccGetCurveDataPointer()
1225
//
1226
//      This function returns a pointer to an ECC_CURVE_VALUES structure that contains the parameters for
1227
//      the key size and schemes for a given curve.
1228
//
1229
#ifdef TPM_ALG_ECC //% 3
1230
static const ECC_CURVE    *
1231
CryptEccGetCurveDataPointer(
1232
    TPM_ECC_CURVE        curveID             // IN: id of the curve
1233
    )
1234
19
{
1235
19
    return _cpri__EccGetParametersByCurveId(curveID);
1236
19
}
1237
//
1238
//
1239
//      10.2.6.2    CryptEccGetKeySizeInBits()
1240
//
1241
//      This function returns the size in bits of the key associated with a curve.
1242
//
1243
UINT16
1244
CryptEccGetKeySizeInBits(
1245
    TPM_ECC_CURVE        curveID             // IN: id of the curve
1246
    )
1247
13
{
1248
13
    const ECC_CURVE               *curve = CryptEccGetCurveDataPointer(curveID);
1249
13
    UINT16                         keySizeInBits = 0;
1250
13
    if(curve != NULL)
1251
13
        keySizeInBits = curve->keySizeBits;
1252
13
    return keySizeInBits;
1253
13
}
1254
//
1255
//
1256
//      10.2.6.4    CryptEccGetParameter()
1257
//
1258
//      This function returns a pointer to an ECC curve parameter. The parameter is selected by a single
1259
//      character designator from the set of {pnabxyh}.
1260
//
1261
LIB_EXPORT const TPM2B *
1262
CryptEccGetParameter(
1263
    char                 p,                  // IN: the parameter selector
1264
    TPM_ECC_CURVE        curveId             // IN: the curve id
1265
    )
1266
0
{
1267
0
    const ECC_CURVE          *curve = _cpri__EccGetParametersByCurveId(curveId);
1268
0
    const TPM2B              *parameter = NULL;
1269
0
    if(curve != NULL)
1270
0
    {
1271
0
          switch (p)
1272
0
          {
1273
0
          case 'p':
1274
0
              parameter    = curve->curveData->p;
1275
0
              break;
1276
0
          case 'n':
1277
0
              parameter    =   curve->curveData->n;
1278
0
              break;
1279
0
          case 'a':
1280
0
              parameter    =   curve->curveData->a;
1281
0
              break;
1282
0
          case 'b':
1283
0
              parameter    =   curve->curveData->b;
1284
0
              break;
1285
0
          case 'x':
1286
0
              parameter    =   curve->curveData->x;
1287
0
              break;
1288
0
          case 'y':
1289
0
              parameter    =   curve->curveData->y;
1290
0
              break;
1291
0
          case 'h':
1292
0
              parameter    =   curve->curveData->h;
1293
0
              break;
1294
0
          default:
1295
0
              break;
1296
0
          }
1297
0
    }
1298
0
    return parameter;
1299
0
}
1300
//
1301
//
1302
//       10.2.6.5    CryptGetCurveSignScheme()
1303
//
1304
//       This function will return a pointer to the scheme of the curve.
1305
//
1306
const TPMT_ECC_SCHEME *
1307
CryptGetCurveSignScheme(
1308
    TPM_ECC_CURVE         curveId            // IN: The curve selector
1309
    )
1310
7
{
1311
7
    const ECC_CURVE               *curve = _cpri__EccGetParametersByCurveId(curveId);
1312
7
    const TPMT_ECC_SCHEME         *scheme = NULL;
1313
7
    if(curve != NULL)
1314
7
        scheme = &(curve->sign);
1315
7
    return scheme;
1316
7
}
1317
//
1318
//
1319
//       10.2.6.6    CryptEccIsPointOnCurve()
1320
//
1321
//       This function will validate that an ECC point is on the curve of given curveID.
1322
//
1323
//       Return Value                     Meaning
1324
//
1325
//       TRUE                             if the point is on curve
1326
//       FALSE                            if the point is not on curve
1327
//
1328
BOOL
1329
CryptEccIsPointOnCurve(
1330
    TPM_ECC_CURVE        curveID,            // IN: ECC curve ID
1331
    TPMS_ECC_POINT      *Q                   // IN: ECC point
1332
    )
1333
7
{
1334
   // Make sure that point multiply is working
1335
7
   TEST(TPM_ALG_ECC);
1336
   // Check point on curve logic by seeing if the test key is on the curve
1337
   // Call crypto engine function to check if a ECC public point is on the
1338
   // given curve
1339
7
   if(_cpri__EccIsPointOnCurve(curveID, Q))
1340
6
       return TRUE;
1341
1
   else
1342
1
       return FALSE;
1343
7
}
1344
//
1345
//
1346
//       10.2.6.7    CryptNewEccKey()
1347
//
1348
//       This function creates a random ECC key that is not derived from other parameters as is a Primary Key.
1349
//
1350
TPM_RC
1351
CryptNewEccKey(
1352
   TPM_ECC_CURVE                    curveID,               // IN: ECC curve
1353
   TPMS_ECC_POINT                  *publicPoint,           // OUT: public point
1354
   TPM2B_ECC_PARAMETER             *sensitive              // OUT: private area
1355
   )
1356
0
{
1357
0
   TPM_RC               result = TPM_RC_SUCCESS;
1358
   // _cpri__GetEphemeralECC may return CRYPT_PARAMETER
1359
0
   if(_cpri__GetEphemeralEcc(publicPoint, sensitive, curveID) != CRYPT_SUCCESS)
1360
       // Something is wrong with the key.
1361
0
       result = TPM_RC_KEY;
1362
0
   return result;
1363
0
}
1364
//
1365
//
1366
//       10.2.6.8    CryptEccPointMultiply()
1367
//
1368
//       This function is used to perform a point multiply R = [d]Q. If Q is not provided, the multiplication is
1369
//       performed using the generator point of the curve.
1370
//
1371
//       Error Returns                     Meaning
1372
//
1373
//       TPM_RC_ECC_POINT                  invalid optional ECC point pIn
1374
//       TPM_RC_NO_RESULT                  multiplication resulted in a point at infinity
1375
//       TPM_RC_CANCELED                   if a self-test was done, it might have been aborted
1376
//
1377
TPM_RC
1378
CryptEccPointMultiply(
1379
   TPMS_ECC_POINT                  *pOut,                  //   OUT: output point
1380
   TPM_ECC_CURVE                    curveId,               //   IN: curve selector
1381
   TPM2B_ECC_PARAMETER             *dIn,                   //   IN: public scalar
1382
   TPMS_ECC_POINT                  *pIn                    //   IN: optional point
1383
   )
1384
3
{
1385
3
   TPM2B_ECC_PARAMETER             *n = NULL;
1386
3
   CRYPT_RESULT                    retVal;
1387
3
   pAssert(pOut != NULL && dIn != NULL);
1388
3
   if(pIn != NULL)
1389
0
   {
1390
0
       n = dIn;
1391
0
       dIn = NULL;
1392
0
   }
1393
   // Do a test of point multiply
1394
3
   TEST(TPM_ALG_ECC);
1395
   // _cpri__EccPointMultiply may return CRYPT_POINT or CRYPT_NO_RESULT
1396
3
   retVal = _cpri__EccPointMultiply(pOut, curveId, dIn, pIn, n);
1397
   // CRYPT_POINT->TPM_RC_ECC_POINT and CRYPT_NO_RESULT->TPM_RC_NO_RESULT
1398
3
   return TranslateCryptErrors(retVal);
1399
3
}
1400
//
1401
//
1402
//       10.2.6.9    CryptGenerateKeyECC()
1403
//
1404
//       This function generates an ECC key from a seed value.
1405
//       The method here may not work for objects that have an order (G) that with a different size than a private
1406
//       key.
1407
//
1408
//       Error Returns                   Meaning
1409
//
1410
//       TPM_RC_VALUE                    hash algorithm is not supported
1411
//
1412
static TPM_RC
1413
CryptGenerateKeyECC(
1414
   TPMT_PUBLIC         *publicArea,        //   IN/OUT: The public area template for the new
1415
                                           //       key.
1416
   TPMT_SENSITIVE      *sensitive,         //   IN/OUT: the sensitive area
1417
   TPM_ALG_ID           hashAlg,           //   IN: algorithm for the KDF
1418
   TPM2B_SEED          *seed,              //   IN: the seed value
1419
   TPM2B_NAME          *name,              //   IN: the name of the object
1420
   UINT32              *counter            //   OUT: the iteration counter
1421
   )
1422
0
{
1423
0
   CRYPT_RESULT              retVal;
1424
0
   TEST_HASH(hashAlg);
1425
0
   TEST(ALG_ECDSA_VALUE); // ECDSA is used to verify each key
1426
   // The iteration counter has no meaning for ECC key generation. The parameter
1427
   // will be overloaded for those implementations that have a requirement for
1428
   // doing pair-wise consistency checks on signing keys. If the counter parameter
1429
   // is 0 or NULL, then no consistency check is done. If it is other than 0, then
1430
   // a consistency check is run. This modification allow this code to work with
1431
   // the existing versions of the CrytpoEngine and with FIPS-compliant versions
1432
   // as well.
1433
0
   *counter = (UINT32)(publicArea->objectAttributes.sign == SET);
1434
   // _cpri__GenerateKeyEcc only has one error return (CRYPT_PARAMETER) which means
1435
   // that the hash algorithm is not supported. This should not be possible
1436
0
   retVal = _cpri__GenerateKeyEcc(&publicArea->unique.ecc,
1437
0
                                  &sensitive->sensitive.ecc,
1438
0
                                  publicArea->parameters.eccDetail.curveID,
1439
0
                                  hashAlg, &seed->b, "ECC key by vendor",
1440
0
                                  &name->b, counter);
1441
   // This will only be useful if _cpri__GenerateKeyEcc return CRYPT_CANCEL
1442
0
   return TranslateCryptErrors(retVal);
1443
0
}
1444
//
1445
//
1446
//       10.2.6.10 CryptSignECC()
1447
//
1448
//       This function is used for ECC signing operations. If the signing scheme is a split scheme, and the signing
1449
//       operation is successful, the commit value is retired.
1450
//
1451
//
1452
//       Error Returns                     Meaning
1453
//
1454
//       TPM_RC_SCHEME                     unsupported scheme
1455
//       TPM_RC_VALUE                      invalid commit status (in case of a split scheme) or failed to generate
1456
//                                         r value.
1457
//
1458
static TPM_RC
1459
CryptSignECC(
1460
   OBJECT                   *signKey,                //   IN: ECC key to sign the hash
1461
   TPMT_SIG_SCHEME          *scheme,                 //   IN: sign scheme
1462
   TPM2B_DIGEST             *hashData,               //   IN: hash to be signed
1463
   TPMT_SIGNATURE           *signature               //   OUT: signature
1464
   )
1465
0
{
1466
0
   TPM2B_ECC_PARAMETER              r;
1467
0
   TPM2B_ECC_PARAMETER             *pr = NULL;
1468
0
   CRYPT_RESULT                     retVal;
1469
   // Run a test of the ECC sign and verify if it has not already been run
1470
0
   TEST_HASH(scheme->details.any.hashAlg);
1471
0
   TEST(scheme->scheme);
1472
0
   if(CryptIsSplitSign(scheme->scheme))
1473
0
   {
1474
       // When this code was written, the only split scheme was ECDAA
1475
       // (which can also be used for U-Prove).
1476
0
       if(!CryptGenerateR(&r,
1477
0
                          &scheme->details.ecdaa.count,
1478
0
                          signKey->publicArea.parameters.eccDetail.curveID,
1479
0
                          &signKey->name))
1480
0
           return TPM_RC_VALUE;
1481
0
       pr = &r;
1482
0
   }
1483
   // Call crypto engine function to sign
1484
   // _cpri__SignEcc may return CRYPT_SCHEME
1485
0
   retVal = _cpri__SignEcc(&signature->signature.ecdsa.signatureR,
1486
0
                           &signature->signature.ecdsa.signatureS,
1487
0
                           scheme->scheme,
1488
0
                           scheme->details.any.hashAlg,
1489
0
                           signKey->publicArea.parameters.eccDetail.curveID,
1490
0
                           &signKey->sensitive.sensitive.ecc,
1491
0
                           &hashData->b,
1492
0
                           pr
1493
0
                           );
1494
0
   if(CryptIsSplitSign(scheme->scheme) && retVal == CRYPT_SUCCESS)
1495
0
       CryptEndCommit(scheme->details.ecdaa.count);
1496
   // CRYPT_SCHEME->TPM_RC_SCHEME
1497
0
   return TranslateCryptErrors(retVal);
1498
0
}
1499
//
1500
//
1501
//       10.2.6.11 CryptECCVerifySignature()
1502
//
1503
//       This function is used to verify a signature created with an ECC key.
1504
//
1505
//       Error Returns                     Meaning
1506
//
1507
//       TPM_RC_SIGNATURE                  if signature is not valid
1508
//       TPM_RC_SCHEME                     the signing scheme or hashAlg is not supported
1509
//
1510
static TPM_RC
1511
CryptECCVerifySignature(
1512
   OBJECT              *signKey,               // IN: ECC key signed the hash
1513
   TPM2B_DIGEST        *digestData,       // IN: digest being signed
1514
   TPMT_SIGNATURE      *signature         // IN: signature to be verified
1515
   )
1516
0
{
1517
0
   CRYPT_RESULT              retVal;
1518
0
   TEST_HASH(signature->signature.any.hashAlg);
1519
0
   TEST(signature->sigAlg);
1520
   // This implementation uses the fact that all the defined ECC signing
1521
   // schemes have the hash as the first parameter.
1522
   // _cpriValidateSignatureEcc may return CRYPT_FAIL or CRYP_SCHEME
1523
0
   retVal = _cpri__ValidateSignatureEcc(&signature->signature.ecdsa.signatureR,
1524
0
                                  &signature->signature.ecdsa.signatureS,
1525
0
                                  signature->sigAlg,
1526
0
                                  signature->signature.any.hashAlg,
1527
0
                                  signKey->publicArea.parameters.eccDetail.curveID,
1528
0
                                  &signKey->publicArea.unique.ecc,
1529
0
                                  &digestData->b);
1530
0
   if(retVal == CRYPT_FAIL)
1531
0
       return TPM_RC_SIGNATURE;
1532
   // CRYPT_SCHEME->TPM_RC_SCHEME
1533
0
   return TranslateCryptErrors(retVal);
1534
0
}
1535
//
1536
//
1537
//       10.2.6.12 CryptGenerateR()
1538
//
1539
//       This function computes the commit random value for a split signing scheme.
1540
//       If c is NULL, it indicates that r is being generated for TPM2_Commit(). If c is not NULL, the TPM will
1541
//       validate that the gr.commitArray bit associated with the input value of c is SET. If not, the TPM returns
1542
//       FALSE and no r value is generated.
1543
//
1544
//       Return Value                    Meaning
1545
//
1546
//       TRUE                            r value computed
1547
//       FALSE                           no r value computed
1548
//
1549
BOOL
1550
CryptGenerateR(
1551
   TPM2B_ECC_PARAMETER           *r,                 //   OUT: the generated random value
1552
   UINT16                        *c,                 //   IN/OUT: count value.
1553
   TPMI_ECC_CURVE                 curveID,           //   IN: the curve for the value
1554
   TPM2B_NAME                    *name               //   IN: optional name of a key to
1555
                                                     //       associate with 'r'
1556
   )
1557
0
{
1558
   // This holds the marshaled g_commitCounter.
1559
0
   TPM2B_TYPE(8B, 8);
1560
0
   TPM2B_8B                cntr = {.b.size = 8};
1561
0
   UINT32                   iterations;
1562
0
   const TPM2B             *n;
1563
0
   UINT64                   currentCount = gr.commitCounter;
1564
   // This is just to suppress a compiler warning about a conditional expression
1565
   // being a constant. This is because of the macro expansion of ryptKDFa
1566
0
   TPMI_ALG_HASH            hashAlg = CONTEXT_INTEGRITY_HASH_ALG;
1567
0
   n = CryptEccGetParameter('n', curveID);
1568
0
   pAssert(r != NULL && n != NULL);
1569
   // If this is the commit phase, use the current value of the commit counter
1570
0
   if(c != NULL)
1571
//
1572
0
   {
1573
0
        UINT16      t1;
1574
        // if the array bit is not set, can't use the value.
1575
0
        if(!BitIsSet((*c & COMMIT_INDEX_MASK), gr.commitArray,
1576
0
                     sizeof(gr.commitArray)))
1577
0
            return FALSE;
1578
        //   If it is the sign phase, figure out what the counter value was
1579
        //   when the commitment was made.
1580
        //
1581
        //   When gr.commitArray has less than 64K bits, the extra
1582
        //   bits of 'c' are used as a check to make sure that the
1583
        //   signing operation is not using an out of range count value
1584
0
        t1   = (UINT16)currentCount;
1585
        // If the lower bits of c are greater or equal to the lower bits of t1
1586
        // then the upper bits of t1 must be one more than the upper bits
1587
        // of c
1588
0
        if((*c & COMMIT_INDEX_MASK) >= (t1 & COMMIT_INDEX_MASK))
1589
            // Since the counter is behind, reduce the current count
1590
0
            currentCount = currentCount - (COMMIT_INDEX_MASK + 1);
1591
0
        t1 = (UINT16)currentCount;
1592
0
        if((t1 & ~COMMIT_INDEX_MASK) != (*c & ~COMMIT_INDEX_MASK))
1593
0
            return FALSE;
1594
        // set the counter to the value that was
1595
        // present when the commitment was made
1596
0
        currentCount = (currentCount & 0xffffffffffff0000) | *c;
1597
0
   }
1598
   // Marshal the count value to a TPM2B buffer for the KDF
1599
0
   cntr.t.size = sizeof(currentCount);
1600
0
   UINT64_TO_BYTE_ARRAY(currentCount, cntr.t.buffer);
1601
   //   Now can do the KDF to create the random value for the signing operation
1602
   //   During the creation process, we may generate an r that does not meet the
1603
   //   requirements of the random value.
1604
   //   want to generate a new r.
1605
0
   r->t.size = n->size;
1606
   // Arbitrary upper limit on the number of times that we can look for
1607
   // a suitable random value. The normally number of tries will be 1.
1608
0
   for(iterations = 1; iterations < 1000000;)
1609
0
   {
1610
0
       BYTE    *pr = &r->b.buffer[0];
1611
0
       int     i;
1612
0
       CryptKDFa(hashAlg, &gr.commitNonce.b, "ECDAA Commit",
1613
0
                 name, &cntr.b, n->size * 8, r->t.buffer, &iterations);
1614
        // random value must be less than the prime
1615
0
        if(CryptCompare(r->b.size, r->b.buffer, n->size, n->buffer) >= 0)
1616
0
            continue;
1617
        // in this implementation it is required that at least bit
1618
        // in the upper half of the number be set
1619
0
        for(i = n->size/2; i > 0; i--)
1620
0
            if(*pr++ != 0)
1621
0
                return TRUE;
1622
0
   }
1623
0
   return FALSE;
1624
0
}
1625
//
1626
//
1627
//
1628
//       10.2.6.13 CryptCommit()
1629
//
1630
//       This function is called when the count value is committed. The gr.commitArray value associated with the
1631
//       current count value is SET and g_commitCounter is incremented. The low-order 16 bits of old value of the
1632
//       counter is returned.
1633
//
1634
UINT16
1635
CryptCommit(
1636
   void
1637
   )
1638
0
{
1639
0
   UINT16      oldCount = (UINT16)gr.commitCounter;
1640
0
   gr.commitCounter++;
1641
0
   BitSet(oldCount & COMMIT_INDEX_MASK, gr.commitArray, sizeof(gr.commitArray));
1642
0
   return oldCount;
1643
0
}
1644
//
1645
//
1646
//       10.2.6.14 CryptEndCommit()
1647
//
1648
//       This function is called when the signing operation using the committed value is completed. It clears the
1649
//       gr.commitArray bit associated with the count value so that it can't be used again.
1650
//
1651
void
1652
CryptEndCommit(
1653
   UINT16               c                    // IN: the counter value of the commitment
1654
   )
1655
0
{
1656
0
   BitClear((c & COMMIT_INDEX_MASK), gr.commitArray, sizeof(gr.commitArray));
1657
0
}
1658
//
1659
//
1660
//       10.2.6.15 CryptCommitCompute()
1661
//
1662
//       This function performs the computations for the TPM2_Commit() command. This could be a macro.
1663
//
1664
//       Error Returns                   Meaning
1665
//
1666
//       TPM_RC_NO_RESULT                K, L, or E is the point at infinity
1667
//       TPM_RC_CANCELLED                command was canceled
1668
//
1669
TPM_RC
1670
CryptCommitCompute(
1671
   TPMS_ECC_POINT                *K,                     //   OUT: [d]B
1672
   TPMS_ECC_POINT                *L,                     //   OUT: [r]B
1673
   TPMS_ECC_POINT                *E,                     //   OUT: [r]M
1674
   TPM_ECC_CURVE                  curveID,               //   IN: The curve for the computation
1675
   TPMS_ECC_POINT                *M,                     //   IN: M (P1)
1676
   TPMS_ECC_POINT                *B,                     //   IN: B (x2, y2)
1677
   TPM2B_ECC_PARAMETER           *d,                     //   IN: the private scalar
1678
   TPM2B_ECC_PARAMETER           *r                      //   IN: the computed r value
1679
   )
1680
0
{
1681
0
   TEST(ALG_ECDH_VALUE);
1682
   // CRYPT_NO_RESULT->TPM_RC_NO_RESULT CRYPT_CANCEL->TPM_RC_CANCELLED
1683
0
   return TranslateCryptErrors(
1684
0
              _cpri__EccCommitCompute(K, L , E, curveID, M, B, d, r));
1685
0
}
1686
//
1687
//
1688
//
1689
//       10.2.6.16 CryptEccGetParameters()
1690
//
1691
//       This function returns the ECC parameter details of the given curve
1692
//
1693
//       Return Value                      Meaning
1694
//
1695
//       TRUE                              Get parameters success
1696
//       FALSE                             Unsupported ECC curve ID
1697
//
1698
BOOL
1699
CryptEccGetParameters(
1700
   TPM_ECC_CURVE                        curveId,            // IN: ECC curve ID
1701
   TPMS_ALGORITHM_DETAIL_ECC           *parameters          // OUT: ECC parameter
1702
   )
1703
0
{
1704
0
   const ECC_CURVE                     *curve = _cpri__EccGetParametersByCurveId(curveId);
1705
0
   const ECC_CURVE_DATA                *data;
1706
0
   BOOL                                 found = curve != NULL;
1707
0
   if(found)
1708
0
   {
1709
0
        data = curve->curveData;
1710
0
        parameters->curveID = curve->curveId;
1711
        // Key size in bit
1712
0
        parameters->keySize = curve->keySizeBits;
1713
        // KDF
1714
0
        parameters->kdf = curve->kdf;
1715
        // Sign
1716
0
        parameters->sign = curve->sign;
1717
        // Copy p value
1718
0
        MemoryCopy2B(&parameters->p.b, data->p, sizeof(parameters->p.t.buffer));
1719
        // Copy a value
1720
0
        MemoryCopy2B(&parameters->a.b, data->a, sizeof(parameters->a.t.buffer));
1721
        // Copy b value
1722
0
        MemoryCopy2B(&parameters->b.b, data->b, sizeof(parameters->b.t.buffer));
1723
        // Copy Gx value
1724
0
        MemoryCopy2B(&parameters->gX.b, data->x, sizeof(parameters->gX.t.buffer));
1725
        // Copy Gy value
1726
0
        MemoryCopy2B(&parameters->gY.b, data->y, sizeof(parameters->gY.t.buffer));
1727
        // Copy n value
1728
0
        MemoryCopy2B(&parameters->n.b, data->n, sizeof(parameters->n.t.buffer));
1729
        // Copy h value
1730
0
        MemoryCopy2B(&parameters->h.b, data->h, sizeof(parameters->h.t.buffer));
1731
0
   }
1732
0
   return found;
1733
0
}
1734
#if IS_CC_ENABLED(ZGen_2Phase)
1735
//
1736
//       CryptEcc2PhaseKeyExchange() This is the interface to the key exchange function.
1737
//
1738
TPM_RC
1739
CryptEcc2PhaseKeyExchange(
1740
   TPMS_ECC_POINT                *outZ1,            //   OUT: the computed point
1741
   TPMS_ECC_POINT                *outZ2,            //   OUT: optional second point
1742
   TPM_ALG_ID                     scheme,           //   IN: the key exchange scheme
1743
   TPM_ECC_CURVE                  curveId,          //   IN: the curve for the computation
1744
   TPM2B_ECC_PARAMETER           *dsA,              //   IN: static private TPM key
1745
   TPM2B_ECC_PARAMETER           *deA,              //   IN: ephemeral private TPM key
1746
   TPMS_ECC_POINT                *QsB,              //   IN: static public party B key
1747
   TPMS_ECC_POINT                *QeB               //   IN: ephemeral public party B key
1748
   )
1749
{
1750
   return (TranslateCryptErrors(_cpri__C_2_2_KeyExchange(outZ1,
1751
                                                         outZ2,
1752
                                                         scheme,
1753
                                                         curveId,
1754
                                                         dsA,
1755
                                                         deA,
1756
                                                         QsB,
1757
                                                         QeB)));
1758
}
1759
#endif // CC_ZGen_2Phase
1760
#endif //TPM_ALG_ECC //% 3
1761
//
1762
//
1763
//       10.2.6.17 CryptIsSchemeAnonymous()
1764
//
1765
//       This function is used to test a scheme to see if it is an anonymous scheme The only anonymous scheme
1766
//       is ECDAA. ECDAA can be used to do things like U-Prove.
1767
//
1768
BOOL
1769
CryptIsSchemeAnonymous(
1770
   TPM_ALG_ID           scheme            // IN: the scheme algorithm to test
1771
   )
1772
0
{
1773
0
#ifdef TPM_ALG_ECDAA
1774
0
   return (scheme == TPM_ALG_ECDAA);
1775
#else
1776
   UNREFERENCED(scheme);
1777
   return 0;
1778
#endif
1779
0
}
1780
//
1781
//
1782
//       10.2.7     Symmetric Functions
1783
//
1784
//       10.2.7.1    ParmDecryptSym()
1785
//
1786
//       This function performs parameter decryption using symmetric block cipher.
1787
//
1788
void
1789
ParmDecryptSym(
1790
   TPM_ALG_ID          symAlg,            //   IN: the symmetric algorithm
1791
   TPM_ALG_ID          hash,              //   IN: hash algorithm for KDFa
1792
   UINT16              keySizeInBits,     //   IN: key key size in bit
1793
   TPM2B              *key,               //   IN: KDF HMAC key
1794
   TPM2B              *nonceCaller,       //   IN: nonce caller
1795
   TPM2B              *nonceTpm,          //   IN: nonce TPM
1796
   UINT32              dataSize,          //   IN: size of parameter buffer
1797
   BYTE               *data               //   OUT: buffer to be decrypted
1798
   )
1799
0
{
1800
   // KDF output buffer
1801
   // It contains parameters for the CFB encryption
1802
   // From MSB to LSB, they are the key and iv
1803
0
   BYTE             symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE];
1804
   // Symmetric key size in byte
1805
0
   UINT16           keySize = (keySizeInBits + 7) / 8;
1806
0
   TPM2B_IV         iv;
1807
0
   iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits);
1808
   // If there is decryption to do...
1809
0
   if(iv.t.size > 0)
1810
0
   {
1811
       // Generate key and iv
1812
0
       CryptKDFa(hash, key, "CFB", nonceCaller, nonceTpm,
1813
0
                 keySizeInBits + (iv.t.size * 8), symParmString, NULL);
1814
0
       MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size,
1815
0
                  sizeof(iv.t.buffer));
1816
0
          CryptSymmetricDecrypt(data, symAlg, keySizeInBits, TPM_ALG_CFB,
1817
0
                                symParmString, &iv, dataSize, data);
1818
0
   }
1819
0
   return;
1820
0
}
1821
//
1822
//
1823
//       10.2.7.2     ParmEncryptSym()
1824
//
1825
//       This function performs parameter encryption using symmetric block cipher.
1826
//
1827
void
1828
ParmEncryptSym(
1829
   TPM_ALG_ID          symAlg,            //   IN: symmetric algorithm
1830
   TPM_ALG_ID          hash,              //   IN: hash algorithm for KDFa
1831
   UINT16              keySizeInBits,     //   IN: AES key size in bit
1832
   TPM2B              *key,               //   IN: KDF HMAC key
1833
   TPM2B              *nonceCaller,       //   IN: nonce caller
1834
   TPM2B              *nonceTpm,          //   IN: nonce TPM
1835
   UINT32              dataSize,          //   IN: size of parameter buffer
1836
   BYTE               *data               //   OUT: buffer to be encrypted
1837
   )
1838
0
{
1839
   // KDF output buffer
1840
   // It contains parameters for the CFB encryption
1841
0
   BYTE             symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE];
1842
   // Symmetric key size in bytes
1843
0
   UINT16           keySize = (keySizeInBits + 7) / 8;
1844
0
   TPM2B_IV             iv;
1845
0
   iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits);
1846
   // See if there is any encryption to do
1847
0
   if(iv.t.size > 0)
1848
0
   {
1849
       // Generate key and iv
1850
0
       CryptKDFa(hash, key, "CFB", nonceTpm, nonceCaller,
1851
0
                 keySizeInBits + (iv.t.size * 8), symParmString, NULL);
1852
0
          MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size,
1853
0
                     sizeof(iv.t.buffer));
1854
0
          CryptSymmetricEncrypt(data, symAlg, keySizeInBits, TPM_ALG_CFB,
1855
0
                                symParmString, &iv, dataSize, data);
1856
0
   }
1857
0
   return;
1858
0
}
1859
//
1860
//
1861
//
1862
//       10.2.7.3     CryptGenerateNewSymmetric()
1863
//
1864
//       This function creates the sensitive symmetric values for an HMAC or symmetric key. If the sensitive area
1865
//       is zero, then the sensitive creation key data is copied. If it is not zero, then the TPM will generate a
1866
//       random value of the selected size.
1867
//
1868
void
1869
CryptGenerateNewSymmetric(
1870
   TPMS_SENSITIVE_CREATE        *sensitiveCreate,       //   IN: sensitive creation data
1871
   TPMT_SENSITIVE               *sensitive,             //   OUT: sensitive area
1872
   TPM_ALG_ID                    hashAlg,               //   IN: hash algorithm for the KDF
1873
   TPM2B_SEED                   *seed,                  //   IN: seed used in creation
1874
   TPM2B_NAME                   *name                   //   IN: name of the object
1875
   )
1876
0
{
1877
   // This function is called to create a key and obfuscation value for a
1878
   // symmetric key that can either be a block cipher or an XOR key. The buffer
1879
   // in sensitive->sensitive will hold either. When we call the function
1880
   // to copy the input value or generated value to the sensitive->sensitive
1881
   // buffer we will need to have a size for the output buffer. This define
1882
   // computes the maximum that it might need to be and uses that. It will always
1883
   // be smaller than the largest value that will fit.
1884
0
   #define MAX_SENSITIVE_SIZE                                                   \
1885
0
       (MAX(sizeof(sensitive->sensitive.bits.t.buffer),                         \
1886
0
           sizeof(sensitive->sensitive.sym.t.buffer)))
1887
   // set the size of the obfuscation value
1888
0
   sensitive->seedValue.t.size = CryptGetHashDigestSize(hashAlg);
1889
   // If the input sensitive size is zero, then create both the sensitive data
1890
   // and the obfuscation value
1891
0
   if(sensitiveCreate->data.t.size == 0)
1892
0
   {
1893
0
       BYTE                     symValues[MAX(MAX_DIGEST_SIZE, MAX_SYM_KEY_BYTES)
1894
0
                                          + MAX_DIGEST_SIZE];
1895
0
       UINT16                  requestSize;
1896
          // Set the size of the request to be the size of the key and the
1897
          // obfuscation value
1898
0
          requestSize =   sensitive->sensitive.sym.t.size
1899
0
                        + sensitive->seedValue.t.size;
1900
0
          pAssert(requestSize <= sizeof(symValues));
1901
0
          requestSize = _cpri__GenerateSeededRandom(requestSize, symValues, hashAlg,
1902
0
                                                    &seed->b,
1903
0
                                                    "symmetric sensitive", &name->b,
1904
0
                                                    NULL);
1905
0
          pAssert(requestSize != 0);
1906
          // Copy the new key
1907
0
          MemoryCopy(sensitive->sensitive.sym.t.buffer,
1908
0
                     symValues, sensitive->sensitive.sym.t.size,
1909
0
                     MAX_SENSITIVE_SIZE);
1910
          // copy the obfuscation value
1911
0
          MemoryCopy(sensitive->seedValue.t.buffer,
1912
0
                     &symValues[sensitive->sensitive.sym.t.size],
1913
0
                     sensitive->seedValue.t.size,
1914
0
                     sizeof(sensitive->seedValue.t.buffer));
1915
0
   }
1916
0
   else
1917
0
   {
1918
       // Copy input symmetric key to sensitive area as long as it will fit
1919
0
       MemoryCopy2B(&sensitive->sensitive.sym.b, &sensitiveCreate->data.b,
1920
0
                    MAX_SENSITIVE_SIZE);
1921
          // Create the obfuscation value
1922
0
          _cpri__GenerateSeededRandom(sensitive->seedValue.t.size,
1923
0
                                      sensitive->seedValue.t.buffer,
1924
0
                                      hashAlg, &seed->b,
1925
0
                                      "symmetric obfuscation", &name->b, NULL);
1926
0
   }
1927
0
   return;
1928
0
}
1929
//
1930
//
1931
//       10.2.7.4    CryptGenerateKeySymmetric()
1932
//
1933
//       This function derives a symmetric cipher key from the provided seed.
1934
//
1935
//       Error Returns                     Meaning
1936
//
1937
//       TPM_RC_KEY_SIZE                   key size in the public area does not match the size in the sensitive
1938
//                                         creation area
1939
//       TPM_RC_VALUE                      the publicArea nameAlg is invalid
1940
//
1941
static TPM_RC
1942
CryptGenerateKeySymmetric(
1943
   TPMT_PUBLIC                    *publicArea,               //   IN/OUT: The public area template
1944
                                                             //       for the new key.
1945
   TPMS_SENSITIVE_CREATE          *sensitiveCreate,          //   IN: sensitive creation data
1946
   TPMT_SENSITIVE                 *sensitive,                //   OUT: sensitive area
1947
   TPM_ALG_ID                      hashAlg,                  //   IN: hash algorithm for the KDF
1948
   TPM2B_SEED                     *seed,                     //   IN: seed used in creation
1949
   TPM2B_NAME                     *name                      //   IN: name of the object
1950
   )
1951
0
{
1952
   // Check parameter values
1953
0
   if(publicArea->nameAlg == TPM_ALG_NULL)
1954
0
   {
1955
0
       return TPM_RC_VALUE;
1956
0
   }
1957
   // If this is not a new key, then the provided key data must be the right size
1958
0
   if(publicArea->objectAttributes.sensitiveDataOrigin == CLEAR)
1959
0
   {
1960
0
       if(     (sensitiveCreate->data.t.size * 8)
1961
0
           != publicArea->parameters.symDetail.sym.keyBits.sym)
1962
0
           return TPM_RC_KEY_SIZE;
1963
       // Make sure that the key size is OK.
1964
       // This implementation only supports symmetric key sizes that are
1965
       // multiples of 8
1966
0
       if(publicArea->parameters.symDetail.sym.keyBits.sym % 8 != 0)
1967
0
           return TPM_RC_KEY_SIZE;
1968
0
   }
1969
0
   else
1970
0
   {
1971
       // TPM is going to generate the key so set the size
1972
0
       sensitive->sensitive.sym.t.size
1973
0
           = publicArea->parameters.symDetail.sym.keyBits.sym / 8;
1974
0
       sensitiveCreate->data.t.size = 0;
1975
0
   }
1976
   // Fill in the sensitive area
1977
0
   CryptGenerateNewSymmetric(sensitiveCreate, sensitive, hashAlg,
1978
0
                             seed, name);
1979
   // Create unique area in public
1980
0
   CryptComputeSymmetricUnique(publicArea->nameAlg,
1981
0
                               sensitive, &publicArea->unique.sym);
1982
0
   return TPM_RC_SUCCESS;
1983
0
}
1984
//
1985
//
1986
//
1987
//       10.2.7.5     CryptXORObfuscation()
1988
//
1989
//       This function implements XOR obfuscation. It should not be called if the hash algorithm is not
1990
//       implemented. The only return value from this function is TPM_RC_SUCCESS.
1991
//
1992
#ifdef TPM_ALG_KEYEDHASH //% 5
1993
void
1994
CryptXORObfuscation(
1995
   TPM_ALG_ID             hash,                  //   IN: hash algorithm for KDF
1996
   TPM2B                 *key,                   //   IN: KDF key
1997
   TPM2B                 *contextU,              //   IN: contextU
1998
   TPM2B                 *contextV,              //   IN: contextV
1999
   UINT32                 dataSize,              //   IN: size of data buffer
2000
   BYTE                  *data                   //   IN/OUT: data to be XORed in place
2001
   )
2002
0
{
2003
0
   BYTE                   mask[MAX_DIGEST_SIZE]; // Allocate a digest sized buffer
2004
0
   BYTE                  *pm;
2005
0
   UINT32                 i;
2006
0
   UINT32                 counter = 0;
2007
0
   UINT16                 hLen = CryptGetHashDigestSize(hash);
2008
0
   UINT32                 requestSize = dataSize * 8;
2009
0
   INT32                  remainBytes = (INT32) dataSize;
2010
0
   pAssert((key != NULL) && (data != NULL) && (hLen != 0));
2011
   // Call KDFa to generate XOR mask
2012
0
   for(; remainBytes > 0; remainBytes -= hLen)
2013
0
   {
2014
       // Make a call to KDFa to get next iteration
2015
0
       CryptKDFaOnce(hash, key, "XOR", contextU, contextV,
2016
0
                     requestSize, mask, &counter);
2017
          // XOR next piece of the data
2018
0
          pm = mask;
2019
0
          for(i = hLen < remainBytes ? hLen : remainBytes; i > 0; i--)
2020
0
              *data++ ^= *pm++;
2021
0
   }
2022
0
   return;
2023
0
}
2024
#endif //TPM_ALG_KEYED_HASH //%5
2025
//
2026
//
2027
//       10.2.8     Initialization and shut down
2028
//
2029
//       10.2.8.1     CryptInitUnits()
2030
//
2031
//       This function is called when the TPM receives a _TPM_Init() indication. After function returns, the hash
2032
//       algorithms should be available.
2033
//
2034
//       NOTE:           The hash algorithms do not have to be tested, they just need to be available. They have to be tested before the
2035
//                       TPM can accept HMAC authorization or return any result that relies on a hash algorithm.
2036
//
2037
void
2038
CryptInitUnits(
2039
   void
2040
   )
2041
231
{
2042
   // Initialize the vector of implemented algorithms
2043
231
   AlgorithmGetImplementedVector(&g_implementedAlgorithms);
2044
   // Indicate that all test are necessary
2045
231
   CryptInitializeToTest();
2046
//
2047
   // Call crypto engine unit initialization
2048
   // It is assumed that crypt engine initialization should always succeed.
2049
   // Otherwise, TPM should go to failure mode.
2050
231
   if(_cpri__InitCryptoUnits(&TpmFail) != CRYPT_SUCCESS)
2051
0
       FAIL(FATAL_ERROR_INTERNAL);
2052
231
   return;
2053
231
}
2054
//
2055
//
2056
//       10.2.8.2    CryptStopUnits()
2057
//
2058
//       This function is only used in a simulated environment. There should be no reason to shut down the
2059
//       cryptography on an actual TPM other than loss of power. After receiving TPM2_Startup(), the TPM should
2060
//       be able to accept commands until it loses power and, unless the TPM is in Failure Mode, the
2061
//       cryptographic algorithms should be available.
2062
//
2063
void
2064
CryptStopUnits(
2065
   void
2066
   )
2067
0
{
2068
   // Call crypto engine unit stopping
2069
0
   _cpri__StopCryptoUnits();
2070
0
   return;
2071
0
}
2072
//
2073
//
2074
//       10.2.8.3    CryptUtilStartup()
2075
//
2076
//       This function is called by TPM2_Startup() to initialize the functions in this crypto library and in the
2077
//       provided CryptoEngine(). In this implementation, the only initialization required in this library is
2078
//       initialization of the Commit nonce on TPM Reset.
2079
//       This function returns false if some problem prevents the functions from starting correctly. The TPM should
2080
//       go into failure mode.
2081
//
2082
BOOL
2083
CryptUtilStartup(
2084
   STARTUP_TYPE         type               // IN: the startup type
2085
   )
2086
231
{
2087
   // Make sure that the crypto library functions are ready.
2088
   // NOTE: need to initialize the crypto before loading
2089
   // the RND state may trigger a self-test which
2090
   // uses the
2091
231
   if( !_cpri__Startup())
2092
0
       return FALSE;
2093
   // Initialize the state of the RNG.
2094
231
   CryptDrbgGetPutState(PUT_STATE);
2095
231
   if(type == SU_RESET)
2096
231
   {
2097
231
#ifdef TPM_ALG_ECC
2098
       // Get a new random commit nonce
2099
231
       gr.commitNonce.t.size = sizeof(gr.commitNonce.t.buffer);
2100
231
       _cpri__GenerateRandom(gr.commitNonce.t.size, gr.commitNonce.t.buffer);
2101
       // Reset the counter and commit array
2102
231
       gr.commitCounter = 0;
2103
231
       MemorySet(gr.commitArray, 0, sizeof(gr.commitArray));
2104
231
#endif // TPM_ALG_ECC
2105
231
   }
2106
    // If the shutdown was orderly, then the values recovered from NV will
2107
    // be OK to use. If the shutdown was not orderly, then a TPM Reset was required
2108
    // and we would have initialized in the code above.
2109
231
    return TRUE;
2110
231
}
2111
//
2112
//
2113
//       10.2.9     Algorithm-Independent Functions
2114
//
2115
//       10.2.9.1    Introduction
2116
//
2117
//       These functions are used generically when a function of a general type (e.g., symmetric encryption) is
2118
//       required. The functions will modify the parameters as required to interface to the indicated algorithms.
2119
//
2120
//       10.2.9.2    CryptIsAsymAlgorithm()
2121
//
2122
//       This function indicates if an algorithm is an asymmetric algorithm.
2123
//
2124
//       Return Value                      Meaning
2125
//
2126
//       TRUE                              if it is an asymmetric algorithm
2127
//       FALSE                             if it is not an asymmetric algorithm
2128
//
2129
BOOL
2130
CryptIsAsymAlgorithm(
2131
    TPM_ALG_ID           algID                // IN: algorithm ID
2132
    )
2133
44
{
2134
44
   return (
2135
44
#ifdef TPM_ALG_RSA
2136
44
            algID == TPM_ALG_RSA
2137
44
#endif
2138
44
#if defined TPM_ALG_RSA && defined TPM_ALG_ECC
2139
44
            ||
2140
44
#endif
2141
44
#ifdef TPM_ALG_ECC
2142
44
            algID == TPM_ALG_ECC
2143
44
#endif
2144
44
          );
2145
44
}
2146
//
2147
//
2148
//       10.2.9.3    CryptGetSymmetricBlockSize()
2149
//
2150
//       This function returns the size in octets of the symmetric encryption block used by an algorithm and key
2151
//       size combination.
2152
//
2153
INT16
2154
CryptGetSymmetricBlockSize(
2155
    TPMI_ALG_SYM         algorithm,           // IN: symmetric algorithm
2156
    UINT16               keySize              // IN: key size in bit
2157
    )
2158
0
{
2159
0
    return _cpri__GetSymmetricBlockSize(algorithm, keySize);
2160
0
}
2161
//
2162
//
2163
//
2164
//       10.2.9.4    CryptSymmetricEncrypt()
2165
//
2166
//       This function does in-place encryption of a buffer using the indicated symmetric algorithm, key, IV, and
2167
//       mode. If the symmetric algorithm and mode are not defined, the TPM will fail.
2168
//
2169
void
2170
CryptSymmetricEncrypt(
2171
   BYTE                    *encrypted,         //   OUT: the encrypted data
2172
   TPM_ALG_ID               algorithm,         //   IN: algorithm for encryption
2173
   UINT16                   keySizeInBits,     //   IN: key size in bit
2174
   TPMI_ALG_SYM_MODE        mode,              //   IN: symmetric encryption mode
2175
   BYTE                    *key,               //   IN: encryption key
2176
   TPM2B_IV                *ivIn,              //   IN/OUT: Input IV and output chaining
2177
                                               //       value for the next block
2178
   UINT32                   dataSize,          //   IN: data size in byte
2179
   BYTE                    *data               //   IN/OUT: data buffer
2180
   )
2181
0
{
2182
0
   TPM2B_IV                 defaultIv = {};
2183
0
   TPM2B_IV                *iv = (ivIn != NULL) ? ivIn : &defaultIv;
2184
0
   TEST(algorithm);
2185
0
   pAssert(encrypted != NULL && key != NULL);
2186
   // this check can pass but the case below can fail. ALG_xx_VALUE values are
2187
   // defined for all algorithms but the TPM_ALG_xx might not be.
2188
0
   if(algorithm == ALG_AES_VALUE || algorithm == ALG_SM4_VALUE)
2189
0
   {
2190
0
       if(mode != TPM_ALG_ECB)
2191
0
           defaultIv.t.size = 16;
2192
       // A provided IV has to be the right size
2193
0
       pAssert(mode == TPM_ALG_ECB || iv->t.size == 16);
2194
0
   }
2195
0
   switch(algorithm)
2196
0
   {
2197
0
#ifdef TPM_ALG_AES
2198
0
       case TPM_ALG_AES:
2199
0
       {
2200
0
           switch (mode)
2201
0
           {
2202
0
               case TPM_ALG_CTR:
2203
0
                   _cpri__AESEncryptCTR(encrypted, keySizeInBits, key,
2204
0
                                        iv->t.buffer, dataSize, data);
2205
0
                   break;
2206
0
               case TPM_ALG_OFB:
2207
0
                   _cpri__AESEncryptOFB(encrypted, keySizeInBits, key,
2208
0
                                        iv->t.buffer, dataSize, data);
2209
0
                   break;
2210
0
               case TPM_ALG_CBC:
2211
0
                   _cpri__AESEncryptCBC(encrypted, keySizeInBits, key,
2212
0
                                        iv->t.buffer, dataSize, data);
2213
0
                   break;
2214
0
               case TPM_ALG_CFB:
2215
0
                   _cpri__AESEncryptCFB(encrypted, keySizeInBits, key,
2216
0
                                        iv->t.buffer, dataSize, data);
2217
0
                   break;
2218
0
               case TPM_ALG_ECB:
2219
0
                   _cpri__AESEncryptECB(encrypted, keySizeInBits, key,
2220
0
                                        dataSize, data);
2221
0
                   break;
2222
0
               default:
2223
0
                   pAssert(0);
2224
0
           }
2225
0
          }
2226
0
          break;
2227
0
#endif
2228
#ifdef TPM_ALG_SM4
2229
       case TPM_ALG_SM4:
2230
       {
2231
           switch (mode)
2232
           {
2233
               case TPM_ALG_CTR:
2234
                   _cpri__SM4EncryptCTR(encrypted, keySizeInBits, key,
2235
                                        iv->t.buffer, dataSize, data);
2236
                   break;
2237
               case TPM_ALG_OFB:
2238
                   _cpri__SM4EncryptOFB(encrypted, keySizeInBits, key,
2239
                                        iv->t.buffer, dataSize, data);
2240
                   break;
2241
               case TPM_ALG_CBC:
2242
                   _cpri__SM4EncryptCBC(encrypted, keySizeInBits, key,
2243
                                        iv->t.buffer, dataSize, data);
2244
                   break;
2245
                   case TPM_ALG_CFB:
2246
                       _cpri__SM4EncryptCFB(encrypted, keySizeInBits, key,
2247
                                            iv->t.buffer, dataSize, data);
2248
                       break;
2249
                   case TPM_ALG_ECB:
2250
                       _cpri__SM4EncryptECB(encrypted, keySizeInBits, key,
2251
                                            dataSize, data);
2252
                       break;
2253
                   default:
2254
                       pAssert(0);
2255
              }
2256
          }
2257
          break;
2258
#endif
2259
0
          default:
2260
0
              pAssert(FALSE);
2261
0
              break;
2262
0
   }
2263
0
   return;
2264
0
}
2265
//
2266
//
2267
//       10.2.9.5    CryptSymmetricDecrypt()
2268
//
2269
//       This function does in-place decryption of a buffer using the indicated symmetric algorithm, key, IV, and
2270
//       mode. If the symmetric algorithm and mode are not defined, the TPM will fail.
2271
//
2272
void
2273
CryptSymmetricDecrypt(
2274
   BYTE                      *decrypted,
2275
   TPM_ALG_ID                 algorithm,       //   IN: algorithm for encryption
2276
   UINT16                     keySizeInBits,   //   IN: key size in bit
2277
   TPMI_ALG_SYM_MODE          mode,            //   IN: symmetric encryption mode
2278
   BYTE                      *key,             //   IN: encryption key
2279
   TPM2B_IV                  *ivIn,            //   IN/OUT: IV for next block
2280
   UINT32                     dataSize,        //   IN: data size in byte
2281
   BYTE                      *data             //   IN/OUT: data buffer
2282
   )
2283
0
{
2284
0
   BYTE                      *iv = NULL;
2285
0
   BYTE                       defaultIV[sizeof(TPMT_HA)];
2286
0
   TEST(algorithm);
2287
0
   if(
2288
0
#ifdef TPM_ALG_AES
2289
0
         algorithm == TPM_ALG_AES
2290
0
#endif
2291
#if defined TPM_ALG_AES && defined TPM_ALG_SM4
2292
      ||
2293
#endif
2294
#ifdef TPM_ALG_SM4
2295
         algorithm == TPM_ALG_SM4
2296
#endif
2297
0
     )
2298
0
   {
2299
       // Both SM4 and AES have block size of 128 bits
2300
       // If the iv is not provided, create a default of 0
2301
0
       if(ivIn == NULL)
2302
0
       {
2303
            // Initialize the default IV
2304
0
            iv = defaultIV;
2305
0
            MemorySet(defaultIV, 0, 16);
2306
0
       }
2307
0
       else
2308
0
       {
2309
            // A provided IV has to be the right size
2310
0
            pAssert(mode == TPM_ALG_ECB || ivIn->t.size == 16);
2311
0
            iv = &(ivIn->t.buffer[0]);
2312
0
       }
2313
0
   }
2314
0
   switch(algorithm)
2315
0
   {
2316
0
#ifdef TPM_ALG_AES
2317
0
   case TPM_ALG_AES:
2318
0
   {
2319
0
        switch (mode)
2320
0
        {
2321
0
            case TPM_ALG_CTR:
2322
0
                _cpri__AESDecryptCTR(decrypted, keySizeInBits,   key, iv,
2323
0
                                     dataSize, data);
2324
0
                break;
2325
0
            case TPM_ALG_OFB:
2326
0
                _cpri__AESDecryptOFB(decrypted, keySizeInBits,   key, iv,
2327
0
                                     dataSize, data);
2328
0
                break;
2329
0
            case TPM_ALG_CBC:
2330
0
                _cpri__AESDecryptCBC(decrypted, keySizeInBits,   key, iv,
2331
0
                                     dataSize, data);
2332
0
                break;
2333
0
            case TPM_ALG_CFB:
2334
0
                _cpri__AESDecryptCFB(decrypted, keySizeInBits,   key, iv,
2335
0
                                     dataSize, data);
2336
0
                break;
2337
0
            case TPM_ALG_ECB:
2338
0
                _cpri__AESDecryptECB(decrypted, keySizeInBits,   key,
2339
0
                                     dataSize, data);
2340
0
                break;
2341
0
            default:
2342
0
                pAssert(0);
2343
0
        }
2344
0
        break;
2345
0
   }
2346
0
#endif //TPM_ALG_AES
2347
#ifdef TPM_ALG_SM4
2348
   case TPM_ALG_SM4 :
2349
       switch (mode)
2350
       {
2351
           case TPM_ALG_CTR:
2352
               _cpri__SM4DecryptCTR(decrypted, keySizeInBits,                       key, iv,
2353
                                    dataSize, data);
2354
               break;
2355
           case TPM_ALG_OFB:
2356
               _cpri__SM4DecryptOFB(decrypted, keySizeInBits,                       key, iv,
2357
                                    dataSize, data);
2358
               break;
2359
           case TPM_ALG_CBC:
2360
               _cpri__SM4DecryptCBC(decrypted, keySizeInBits,                       key, iv,
2361
                                    dataSize, data);
2362
               break;
2363
           case TPM_ALG_CFB:
2364
               _cpri__SM4DecryptCFB(decrypted, keySizeInBits,                       key, iv,
2365
                                    dataSize, data);
2366
               break;
2367
           case TPM_ALG_ECB:
2368
               _cpri__SM4DecryptECB(decrypted, keySizeInBits,                       key,
2369
                                    dataSize, data);
2370
               break;
2371
           default:
2372
               pAssert(0);
2373
       }
2374
       break;
2375
#endif //TPM_ALG_SM4
2376
0
   default:
2377
0
       pAssert(FALSE);
2378
0
       break;
2379
0
   }
2380
0
   return;
2381
0
}
2382
//
2383
//
2384
//       10.2.9.6    CryptSecretEncrypt()
2385
//
2386
//       This function creates a secret value and its associated secret structure using an asymmetric algorithm.
2387
//       This function is used by TPM2_Rewrap() TPM2_MakeCredential(), and TPM2_Duplicate().
2388
//
2389
//       Error Returns                   Meaning
2390
//
2391
//       TPM_RC_ATTRIBUTES               keyHandle does not reference a valid decryption key
2392
//       TPM_RC_KEY                      invalid ECC key (public point is not on the curve)
2393
//       TPM_RC_SCHEME                   RSA key with an unsupported padding scheme
2394
//       TPM_RC_VALUE                    numeric value of the data to be decrypted is greater than the RSA
2395
//                                       key modulus
2396
//
2397
TPM_RC
2398
CryptSecretEncrypt(
2399
   TPMI_DH_OBJECT                 keyHandle,           //   IN: encryption key handle
2400
   const char                    *label,               //   IN: a null-terminated string as L
2401
   TPM2B_DATA                    *data,                //   OUT: secret value
2402
   TPM2B_ENCRYPTED_SECRET        *secret               //   OUT: secret structure
2403
   )
2404
0
{
2405
0
   TPM_RC          result = TPM_RC_SUCCESS;
2406
0
   OBJECT         *encryptKey = ObjectGet(keyHandle);              // TPM key used for encrypt
2407
0
   pAssert(data != NULL && secret != NULL);
2408
   // The output secret value has the size of the digest produced by the nameAlg.
2409
0
   data->t.size = CryptGetHashDigestSize(encryptKey->publicArea.nameAlg);
2410
0
   pAssert(encryptKey->publicArea.objectAttributes.decrypt == SET);
2411
0
   switch(encryptKey->publicArea.type)
2412
0
   {
2413
0
#ifdef TPM_ALG_RSA
2414
0
       case TPM_ALG_RSA:
2415
0
       {
2416
0
           TPMT_RSA_DECRYPT            scheme;
2417
             // Use OAEP scheme
2418
0
             scheme.scheme = TPM_ALG_OAEP;
2419
0
             scheme.details.oaep.hashAlg = encryptKey->publicArea.nameAlg;
2420
             // Create secret data from RNG
2421
0
             CryptGenerateRandom(data->t.size, data->t.buffer);
2422
             // Encrypt the data by RSA OAEP into encrypted secret
2423
0
             result = CryptEncryptRSA(&secret->t.size, secret->t.secret,
2424
0
                                      encryptKey, &scheme,
2425
0
                                      data->t.size, data->t.buffer, label);
2426
0
       }
2427
0
       break;
2428
0
#endif //TPM_ALG_RSA
2429
0
#ifdef TPM_ALG_ECC
2430
0
       case TPM_ALG_ECC:
2431
0
       {
2432
0
           TPMS_ECC_POINT         eccPublic;
2433
0
           TPM2B_ECC_PARAMETER    eccPrivate;
2434
0
           TPMS_ECC_POINT         eccSecret;
2435
0
           BYTE                   *buffer = secret->t.secret;
2436
0
           INT32                  bufferSize = sizeof(TPMS_ECC_POINT);
2437
             // Need to make sure that the public point of the key is on the
2438
             // curve defined by the key.
2439
0
             if(!_cpri__EccIsPointOnCurve(
2440
0
                         encryptKey->publicArea.parameters.eccDetail.curveID,
2441
0
                         &encryptKey->publicArea.unique.ecc))
2442
0
                 result = TPM_RC_KEY;
2443
0
             else
2444
0
             {
2445
                  // Call crypto engine to create an auxiliary ECC key
2446
                  // We assume crypt engine initialization should always success.
2447
                  // Otherwise, TPM should go to failure mode.
2448
0
                  CryptNewEccKey(encryptKey->publicArea.parameters.eccDetail.curveID,
2449
0
                                 &eccPublic, &eccPrivate);
2450
                  // Marshal ECC public to secret structure. This will be used by the
2451
                  // recipient to decrypt the secret with their private key.
2452
0
                  secret->t.size = TPMS_ECC_POINT_Marshal(&eccPublic, &buffer, &bufferSize);
2453
                  // Compute ECDH shared secret which is R = [d]Q where d is the
2454
                  // private part of the ephemeral key and Q is the public part of a
2455
                  // TPM key. TPM_RC_KEY error return from CryptComputeECDHSecret
2456
                  // because the auxiliary ECC key is just created according to the
2457
                  // parameters of input ECC encrypt key.
2458
0
                  if(     CryptEccPointMultiply(&eccSecret,
2459
0
                                  encryptKey->publicArea.parameters.eccDetail.curveID,
2460
0
                                  &eccPrivate,
2461
0
                                  &encryptKey->publicArea.unique.ecc)
2462
0
                      != CRYPT_SUCCESS)
2463
0
                       result = TPM_RC_KEY;
2464
0
                  else
2465
                      //     The secret value is computed from Z using KDFe as:
2466
                      //     secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits)
2467
                      //     Where:
2468
                      //      HashID the nameAlg of the decrypt key
2469
                      //      Z    the x coordinate (Px) of the product (P) of the point
2470
                      //           (Q) of the secret and the private x coordinate (de,V)
2471
                      //           of the decryption key
2472
                      //      Use a null-terminated string containing "SECRET"
2473
                      //      PartyUInfo the x coordinate of the point in the secret
2474
                      //                   (Qe,U )
2475
                      //      PartyVInfo the x coordinate of the public key (Qs,V )
2476
                      //      bits     the number of bits in the digest of HashID
2477
                      //     Retrieve seed from KDFe
2478
0
                      CryptKDFe(encryptKey->publicArea.nameAlg, &eccSecret.x.b,
2479
0
                                label, &eccPublic.x.b,
2480
0
                                &encryptKey->publicArea.unique.ecc.x.b,
2481
0
                                data->t.size * 8, data->t.buffer);
2482
0
           }
2483
0
       }
2484
0
       break;
2485
0
#endif //TPM_ALG_ECC
2486
0
   default:
2487
0
       FAIL(FATAL_ERROR_INTERNAL);
2488
0
       break;
2489
0
   }
2490
0
   return result;
2491
0
}
2492
//
2493
//
2494
//       10.2.9.7   CryptSecretDecrypt()
2495
//
2496
//       Decrypt a secret value by asymmetric (or symmetric) algorithm This function is used for
2497
//       ActivateCredential() and Import for asymmetric decryption, and StartAuthSession() for both asymmetric
2498
//       and symmetric decryption process
2499
//
2500
//       Error Returns                    Meaning
2501
//
2502
//       TPM_RC_ATTRIBUTES                RSA key is not a decryption key
2503
//       TPM_RC_BINDING                   Invalid RSA key (public and private parts are not cryptographically
2504
//                                        bound.
2505
//       TPM_RC_ECC_POINT                 ECC point in the secret is not on the curve
2506
//       TPM_RC_INSUFFICIENT              failed to retrieve ECC point from the secret
2507
//       TPM_RC_NO_RESULT                 multiplication resulted in ECC point at infinity
2508
//       TPM_RC_SIZE                      data to decrypt is not of the same size as RSA key
2509
//       TPM_RC_VALUE                     For RSA key, numeric value of the encrypted data is greater than the
2510
//                                        modulus, or the recovered data is larger than the output buffer. For
2511
//                                        keyedHash or symmetric key, the secret is larger than the size of the
2512
//                                        digest produced by the name algorithm.
2513
//       TPM_RC_FAILURE                   internal error
2514
//
2515
TPM_RC
2516
CryptSecretDecrypt(
2517
   TPM_HANDLE                      tpmKey,               // IN: decrypt key
2518
   TPM2B_NONCE                    *nonceCaller,          // IN: nonceCaller. It is needed for
2519
                                                         //     symmetric decryption. For
2520
                                                   //     asymmetric decryption, this
2521
                                                   //     parameter is NULL
2522
   const char                    *label,           // IN: a null-terminated string as L
2523
   TPM2B_ENCRYPTED_SECRET        *secret,          // IN: input secret
2524
   TPM2B_DATA                    *data             // OUT: decrypted secret value
2525
   )
2526
0
{
2527
0
   TPM_RC         result = TPM_RC_SUCCESS;
2528
0
   OBJECT         *decryptKey = ObjectGet(tpmKey);          //TPM key used for decrypting
2529
   // Decryption for secret
2530
0
   switch(decryptKey->publicArea.type)
2531
0
   {
2532
0
#ifdef TPM_ALG_RSA
2533
0
       case TPM_ALG_RSA:
2534
0
       {
2535
0
           TPMT_RSA_DECRYPT             scheme;
2536
             // Use OAEP scheme
2537
0
             scheme.scheme = TPM_ALG_OAEP;
2538
0
             scheme.details.oaep.hashAlg = decryptKey->publicArea.nameAlg;
2539
             // Set the output buffer capacity
2540
0
             data->t.size = sizeof(data->t.buffer);
2541
             // Decrypt seed by RSA OAEP
2542
0
             result = CryptDecryptRSA(&data->t.size, data->t.buffer, decryptKey,
2543
0
                                       &scheme,
2544
0
                                       secret->t.size, secret->t.secret,label);
2545
0
             if(    (result == TPM_RC_SUCCESS)
2546
0
                 && (data->t.size
2547
0
                      > CryptGetHashDigestSize(decryptKey->publicArea.nameAlg)))
2548
0
                  result = TPM_RC_VALUE;
2549
0
       }
2550
0
       break;
2551
0
#endif //TPM_ALG_RSA
2552
0
#ifdef TPM_ALG_ECC
2553
0
       case TPM_ALG_ECC:
2554
0
       {
2555
0
           TPMS_ECC_POINT            eccPublic;
2556
0
           TPMS_ECC_POINT            eccSecret;
2557
0
           BYTE                     *buffer = secret->t.secret;
2558
0
           INT32                     size = secret->t.size;
2559
             // Retrieve ECC point from secret buffer
2560
0
             result = TPMS_ECC_POINT_Unmarshal(&eccPublic, &buffer, &size);
2561
0
             if(result == TPM_RC_SUCCESS)
2562
0
             {
2563
0
                 result = CryptEccPointMultiply(&eccSecret,
2564
0
                                decryptKey->publicArea.parameters.eccDetail.curveID,
2565
0
                                &decryptKey->sensitive.sensitive.ecc,
2566
0
                                &eccPublic);
2567
0
                  if(result == TPM_RC_SUCCESS)
2568
0
                  {
2569
                      // Set the size of the "recovered" secret value to be the size
2570
                      // of the digest produced by the nameAlg.
2571
0
                      data->t.size =
2572
0
                              CryptGetHashDigestSize(decryptKey->publicArea.nameAlg);
2573
                      // The secret value is computed from Z using KDFe as:
2574
                      // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits)
2575
                      // Where:
2576
                      // HashID -- the nameAlg of the decrypt key
2577
                      // Z -- the x coordinate (Px) of the product (P) of the point
2578
                      //        (Q) of the secret and the private x coordinate (de,V)
2579
                      //        of the decryption key
2580
                      // Use -- a null-terminated string containing "SECRET"
2581
                      // PartyUInfo -- the x coordinate of the point in the secret
2582
                      //              (Qe,U )
2583
                      // PartyVInfo -- the x coordinate of the public key (Qs,V )
2584
                      // bits -- the number of bits in the digest of HashID
2585
                      // Retrieve seed from KDFe
2586
0
                      CryptKDFe(decryptKey->publicArea.nameAlg, &eccSecret.x.b, label,
2587
0
                                &eccPublic.x.b,
2588
0
                                &decryptKey->publicArea.unique.ecc.x.b,
2589
0
                                data->t.size * 8, data->t.buffer);
2590
0
                  }
2591
0
              }
2592
0
       }
2593
0
       break;
2594
0
#endif //TPM_ALG_ECC
2595
0
        case TPM_ALG_KEYEDHASH:
2596
            // The seed size can not be bigger than the digest size of nameAlg
2597
0
            if(secret->t.size >
2598
0
                    CryptGetHashDigestSize(decryptKey->publicArea.nameAlg))
2599
0
                result = TPM_RC_VALUE;
2600
0
            else
2601
0
            {
2602
                // Retrieve seed by XOR Obfuscation:
2603
                //    seed = XOR(secret, hash, key, nonceCaller, nullNonce)
2604
                //    where:
2605
                //    secret the secret parameter from the TPM2_StartAuthHMAC
2606
                //             command
2607
                //             which contains the seed value
2608
                //    hash     nameAlg of tpmKey
2609
                //    key      the key or data value in the object referenced by
2610
                //             entityHandle in the TPM2_StartAuthHMAC command
2611
                //    nonceCaller the parameter from the TPM2_StartAuthHMAC command
2612
                //    nullNonce    a zero-length nonce
2613
                // XOR Obfuscation in place
2614
0
                CryptXORObfuscation(decryptKey->publicArea.nameAlg,
2615
0
                                     &decryptKey->sensitive.sensitive.bits.b,
2616
0
                                     &nonceCaller->b, NULL,
2617
0
                                     secret->t.size, secret->t.secret);
2618
                // Copy decrypted seed
2619
0
                MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer));
2620
0
            }
2621
0
            break;
2622
0
        case TPM_ALG_SYMCIPHER:
2623
0
            {
2624
0
                TPM2B_IV                 iv = {};
2625
0
                TPMT_SYM_DEF_OBJECT      *symDef;
2626
                // The seed size can not be bigger than the digest size of nameAlg
2627
0
                if(secret->t.size >
2628
0
                         CryptGetHashDigestSize(decryptKey->publicArea.nameAlg))
2629
0
                    result = TPM_RC_VALUE;
2630
0
                else
2631
0
                {
2632
0
                    symDef = &decryptKey->publicArea.parameters.symDetail.sym;
2633
0
                    iv.t.size = CryptGetSymmetricBlockSize(symDef->algorithm,
2634
0
                                                             symDef->keyBits.sym);
2635
0
                    pAssert(iv.t.size != 0);
2636
0
                    if(nonceCaller->t.size >= iv.t.size)
2637
0
                         MemoryCopy(iv.t.buffer, nonceCaller->t.buffer, iv.t.size,
2638
0
                                     sizeof(iv.t.buffer));
2639
0
                    else
2640
0
                         MemoryCopy(iv.b.buffer, nonceCaller->t.buffer,
2641
0
                                      nonceCaller->t.size, sizeof(iv.t.buffer));
2642
                       // CFB decrypt in place, using nonceCaller as iv
2643
0
                       CryptSymmetricDecrypt(secret->t.secret, symDef->algorithm,
2644
0
                                          symDef->keyBits.sym, TPM_ALG_CFB,
2645
0
                                          decryptKey->sensitive.sensitive.sym.t.buffer,
2646
0
                                          &iv, secret->t.size, secret->t.secret);
2647
                       // Copy decrypted seed
2648
0
                       MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer));
2649
0
                   }
2650
0
              }
2651
0
              break;
2652
0
          default:
2653
0
              pAssert(0);
2654
0
              break;
2655
0
   }
2656
0
   return result;
2657
0
}
2658
//
2659
//
2660
//       10.2.9.8    CryptParameterEncryption()
2661
//
2662
//       This function does in-place encryption of a response parameter.
2663
//
2664
void
2665
CryptParameterEncryption(
2666
   TPM_HANDLE           handle,            // IN: encrypt session handle
2667
   TPM2B               *nonceCaller,       // IN: nonce caller
2668
   UINT32               bufferSize,        // IN: size of parameter buffer
2669
   UINT16               leadingSizeInByte, // IN: the size of the leading size field in
2670
                                           //     byte
2671
   TPM2B_AUTH          *extraKey,          // IN: additional key material other than
2672
                                           //     session auth
2673
   BYTE                *buffer             // IN/OUT: parameter buffer to be encrypted
2674
   )
2675
0
{
2676
0
   SESSION     *session = SessionGet(handle); // encrypt session
2677
0
   TPM2B_TYPE(SYM_KEY, ( sizeof(extraKey->t.buffer)
2678
0
                        + sizeof(session->sessionKey.t.buffer)));
2679
0
   TPM2B_SYM_KEY        key;               // encryption key
2680
0
   UINT32               cipherSize = 0;    // size of cipher text
2681
0
   pAssert(session->sessionKey.t.size + extraKey->t.size <= sizeof(key.t.buffer));
2682
2683
0
    if (bufferSize < leadingSizeInByte)
2684
0
        return;
2685
   // Retrieve encrypted data size.
2686
0
   if(leadingSizeInByte == 2)
2687
0
   {
2688
       // Extract the first two bytes as the size field as the data size
2689
       // encrypt
2690
0
       cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer);
2691
       // advance the buffer
2692
0
       buffer = &buffer[2];
2693
0
       bufferSize -= 2;
2694
0
   }
2695
#ifdef      TPM4B
2696
   else if(leadingSizeInByte == 4)
2697
   {
2698
       // use the first four bytes to indicate the number of bytes to encrypt
2699
       cipherSize = BYTE_ARRAY_TO_UINT32(buffer);
2700
       //advance pointer
2701
       buffer = &buffer[4];
2702
       bufferSize -= 4;
2703
   }
2704
#endif
2705
0
   else
2706
0
   {
2707
0
       pAssert(FALSE);
2708
0
   }
2709
0
   if (cipherSize > bufferSize)
2710
0
       cipherSize = bufferSize;
2711
//
2712
   // Compute encryption key by concatenating sessionAuth with extra key
2713
0
   MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
2714
0
   MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer));
2715
0
   if (session->symmetric.algorithm == TPM_ALG_XOR)
2716
       // XOR parameter encryption formulation:
2717
       //    XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder)
2718
0
       CryptXORObfuscation(session->authHashAlg, &(key.b),
2719
0
                                  &(session->nonceTPM.b),
2720
0
                                  nonceCaller, cipherSize, buffer);
2721
0
   else
2722
0
       ParmEncryptSym(session->symmetric.algorithm, session->authHashAlg,
2723
0
                             session->symmetric.keyBits.aes, &(key.b),
2724
0
                             nonceCaller, &(session->nonceTPM.b),
2725
0
                             cipherSize, buffer);
2726
0
   return;
2727
0
}
2728
//
2729
//
2730
//       10.2.9.9   CryptParameterDecryption()
2731
//
2732
//       This function does in-place decryption of a command parameter.
2733
//
2734
//       Error Returns                  Meaning
2735
//
2736
//       TPM_RC_SIZE                    The number of bytes in the input buffer is less than the number of
2737
//                                      bytes to be decrypted.
2738
//
2739
TPM_RC
2740
CryptParameterDecryption(
2741
   TPM_HANDLE          handle,                 //   IN: encrypted session handle
2742
   TPM2B              *nonceCaller,            //   IN: nonce caller
2743
   UINT32              bufferSize,             //   IN: size of parameter buffer
2744
   UINT16              leadingSizeInByte,      //   IN: the size of the leading size field in
2745
                                               //       byte
2746
   TPM2B_AUTH         *extraKey,               //   IN: the authValue
2747
   BYTE               *buffer                  //   IN/OUT: parameter buffer to be decrypted
2748
   )
2749
0
{
2750
0
   SESSION         *session = SessionGet(handle); // encrypt session
2751
   // The HMAC key is going to be the concatenation of the session key and any
2752
   // additional key material (like the authValue). The size of both of these
2753
   // is the size of the buffer which can contain a TPMT_HA.
2754
0
   TPM2B_TYPE(HMAC_KEY, ( sizeof(extraKey->t.buffer)
2755
0
                         + sizeof(session->sessionKey.t.buffer)));
2756
0
   TPM2B_HMAC_KEY          key;            // decryption key
2757
0
   UINT32                  cipherSize = 0; // size of cipher text
2758
0
   pAssert(session->sessionKey.t.size + extraKey->t.size <= sizeof(key.t.buffer));
2759
2760
0
   if (bufferSize < leadingSizeInByte)
2761
0
       return TPM_RC_INSUFFICIENT;
2762
2763
   // Retrieve encrypted data size.
2764
0
   if(leadingSizeInByte == 2)
2765
0
   {
2766
       // The first two bytes of the buffer are the size of the
2767
       // data to be decrypted
2768
0
       cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer);
2769
0
       buffer = &buffer[2];    // advance the buffer
2770
0
       bufferSize -= 2;
2771
0
   }
2772
#ifdef TPM4B
2773
   else if(leadingSizeInByte == 4)
2774
   {
2775
       // the leading size is four bytes so get the four byte size field
2776
       cipherSize = BYTE_ARRAY_TO_UINT32(buffer);
2777
       buffer = &buffer[4];    //advance pointer
2778
       bufferSize -= 4;
2779
   }
2780
#endif
2781
0
   else
2782
0
   {
2783
0
       pAssert(FALSE);
2784
0
   }
2785
0
   if(cipherSize > bufferSize)
2786
0
       return TPM_RC_SIZE;
2787
   // Compute decryption key by concatenating sessionAuth with extra input key
2788
0
   MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
2789
0
   MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer));
2790
0
   if(session->symmetric.algorithm == TPM_ALG_XOR)
2791
       // XOR parameter decryption formulation:
2792
       //    XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder)
2793
       // Call XOR obfuscation function
2794
0
       CryptXORObfuscation(session->authHashAlg, &key.b, nonceCaller,
2795
0
                                  &(session->nonceTPM.b), cipherSize, buffer);
2796
0
   else
2797
       // Assume that it is one of the symmetric block ciphers.
2798
0
       ParmDecryptSym(session->symmetric.algorithm, session->authHashAlg,
2799
0
                             session->symmetric.keyBits.sym,
2800
0
                             &key.b, nonceCaller, &session->nonceTPM.b,
2801
0
                             cipherSize, buffer);
2802
0
   return TPM_RC_SUCCESS;
2803
0
}
2804
//
2805
//
2806
//       10.2.9.10 CryptComputeSymmetricUnique()
2807
//
2808
//       This function computes the unique field in public area for symmetric objects.
2809
//
2810
void
2811
CryptComputeSymmetricUnique(
2812
   TPMI_ALG_HASH        nameAlg,           // IN: object name algorithm
2813
   TPMT_SENSITIVE      *sensitive,         // IN: sensitive area
2814
   TPM2B_DIGEST        *unique             // OUT: unique buffer
2815
   )
2816
0
{
2817
0
   HASH_STATE     hashState;
2818
0
   pAssert(sensitive != NULL && unique != NULL);
2819
   // Compute the public value as the hash of sensitive.symkey || unique.buffer
2820
0
   unique->t.size = CryptGetHashDigestSize(nameAlg);
2821
0
   CryptStartHash(nameAlg, &hashState);
2822
   // Add obfuscation value
2823
0
   CryptUpdateDigest2B(&hashState, &sensitive->seedValue.b);
2824
   // Add sensitive value
2825
0
   CryptUpdateDigest2B(&hashState, &sensitive->sensitive.any.b);
2826
0
   CryptCompleteHash2B(&hashState, &unique->b);
2827
0
   return;
2828
0
}
2829
#if 0 //%
2830
//
2831
//
2832
//
2833
//       10.2.9.11 CryptComputeSymValue()
2834
//
2835
//       This function computes the seedValue field in asymmetric sensitive areas.
2836
//
2837
void
2838
CryptComputeSymValue(
2839
    TPM_HANDLE            parentHandle,      //   IN: parent handle of the object to be created
2840
    TPMT_PUBLIC          *publicArea,        //   IN/OUT: the public area template
2841
    TPMT_SENSITIVE       *sensitive,         //   IN: sensitive area
2842
    TPM2B_SEED           *seed,              //   IN: the seed
2843
    TPMI_ALG_HASH         hashAlg,           //   IN: hash algorithm for KDFa
2844
    TPM2B_NAME           *name               //   IN: object name
2845
    )
2846
{
2847
    TPM2B_AUTH       *proof = NULL;
2848
    if(CryptIsAsymAlgorithm(publicArea->type))
2849
    {
2850
        // Generate seedValue only when an asymmetric key is a storage key
2851
        if(publicArea->objectAttributes.decrypt == SET
2852
                  && publicArea->objectAttributes.restricted == SET)
2853
        {
2854
             // If this is a primary object in the endorsement hierarchy, use
2855
             // ehProof in the creation of the symmetric seed so that child
2856
             // objects in the endorsement hierarchy are voided on TPM2_Clear()
2857
             // or TPM2_ChangeEPS()
2858
             if(    parentHandle == TPM_RH_ENDORSEMENT
2859
                 && publicArea->objectAttributes.fixedTPM == SET)
2860
                  proof = &gp.ehProof;
2861
        }
2862
        else
2863
        {
2864
             sensitive->seedValue.t.size = 0;
2865
             return;
2866
        }
2867
    }
2868
    // For all object types, the size of seedValue is the digest size of nameAlg
2869
    sensitive->seedValue.t.size = CryptGetHashDigestSize(publicArea->nameAlg);
2870
    // Compute seedValue using implementation-dependent method
2871
    _cpri__GenerateSeededRandom(sensitive->seedValue.t.size,
2872
                                sensitive->seedValue.t.buffer,
2873
                                hashAlg,
2874
                                &seed->b,
2875
                                "seedValue",
2876
                                &name->b,
2877
                                (TPM2B *)proof);
2878
    return;
2879
}
2880
#endif //%
2881
//
2882
//
2883
//       10.2.9.12 CryptCreateObject()
2884
//
2885
//       This function creates an object. It:
2886
//       a) fills in the created key in public and sensitive area;
2887
//       b) creates a random number in sensitive area for symmetric keys; and
2888
//       c) compute the unique id in public area for symmetric keys.
2889
//
2890
//
2891
//
2892
//
2893
//       Error Returns                     Meaning
2894
//
2895
//       TPM_RC_KEY_SIZE                   key size in the public area does not match the size in the sensitive
2896
//                                         creation area for a symmetric key
2897
//       TPM_RC_RANGE                      for an RSA key, the exponent is not supported
2898
//       TPM_RC_SIZE                       sensitive data size is larger than allowed for the scheme for a keyed
2899
//                                         hash object
2900
//       TPM_RC_VALUE                      exponent is not prime or could not find a prime using the provided
2901
//                                         parameters for an RSA key; unsupported name algorithm for an ECC
2902
//                                         key; unsupported name algorithm for symmetric algorithms
2903
//
2904
TPM_RC
2905
CryptCreateObject(
2906
   TPM_HANDLE                       parentHandle,            //   IN/OUT: indication of the seed
2907
                                                             //       source
2908
   TPMT_PUBLIC                    *publicArea,               //   IN/OUT: public area
2909
   TPMS_SENSITIVE_CREATE          *sensitiveCreate,          //   IN: sensitive creation
2910
   TPMT_SENSITIVE                 *sensitive                 //   OUT: sensitive area
2911
   )
2912
3
{
2913
   // Next value is a placeholder for a random seed that is used in
2914
   // key creation when the parent is not a primary seed. It has the same
2915
   // size as the primary seed.
2916
3
   TPM2B_SEED          localSeed;            // data to seed key creation if this
2917
                                             // is not a primary seed
2918
3
   TPM2B_SEED         *seed = NULL;
2919
3
   TPM_RC              result = TPM_RC_SUCCESS;
2920
3
   TPM2B_NAME          name;
2921
3
   TPM_ALG_ID          hashAlg = CONTEXT_INTEGRITY_HASH_ALG;
2922
3
   OBJECT             *parent;
2923
3
   UINT32              counter;
2924
   // Set the sensitive type for the object
2925
3
   sensitive->sensitiveType = publicArea->type;
2926
3
   ObjectComputeName(publicArea, &name);
2927
   // For all objects, copy the initial auth data
2928
3
   sensitive->authValue = sensitiveCreate->userAuth;
2929
   // If this is a permanent handle assume that it is a hierarchy
2930
3
   if(HandleGetType(parentHandle) == TPM_HT_PERMANENT)
2931
3
   {
2932
3
       seed = HierarchyGetPrimarySeed(parentHandle);
2933
3
   }
2934
0
   else
2935
0
   {
2936
       // If not hierarchy handle, get parent
2937
0
       parent = ObjectGet(parentHandle);
2938
0
       hashAlg = parent->publicArea.nameAlg;
2939
        // Use random value as seed for non-primary objects
2940
0
        localSeed.t.size = PRIMARY_SEED_SIZE;
2941
0
        CryptGenerateRandom(PRIMARY_SEED_SIZE, localSeed.t.buffer);
2942
0
        seed = &localSeed;
2943
0
   }
2944
3
   switch(publicArea->type)
2945
3
   {
2946
0
#ifdef TPM_ALG_RSA
2947
       // Create RSA key
2948
3
   case TPM_ALG_RSA:
2949
3
       result = CryptGenerateKeyRSA(publicArea, sensitive,
2950
3
                                    hashAlg, seed, &name, &counter);
2951
3
       break;
2952
0
#endif // TPM_ALG_RSA
2953
0
#ifdef TPM_ALG_ECC
2954
       // Create ECC key
2955
0
   case TPM_ALG_ECC:
2956
0
       result = CryptGenerateKeyECC(publicArea, sensitive,
2957
0
                                        hashAlg, seed, &name, &counter);
2958
0
       break;
2959
0
#endif // TPM_ALG_ECC
2960
       // Collect symmetric key information
2961
0
   case TPM_ALG_SYMCIPHER:
2962
0
       return CryptGenerateKeySymmetric(publicArea, sensitiveCreate,
2963
0
                                        sensitive, hashAlg, seed, &name);
2964
0
       break;
2965
0
   case TPM_ALG_KEYEDHASH:
2966
0
       return CryptGenerateKeyedHash(publicArea, sensitiveCreate,
2967
0
                                     sensitive, hashAlg, seed, &name);
2968
0
       break;
2969
0
   default:
2970
0
       pAssert(0);
2971
0
       break;
2972
3
   }
2973
3
   if(result == TPM_RC_SUCCESS)
2974
3
   {
2975
3
       TPM2B_AUTH          *proof = NULL;
2976
3
        if(publicArea->objectAttributes.decrypt == SET
2977
3
                 && publicArea->objectAttributes.restricted == SET)
2978
0
        {
2979
            // If this is a primary object in the endorsement hierarchy, use
2980
            // ehProof in the creation of the symmetric seed so that child
2981
            // objects in the endorsement hierarchy are voided on TPM2_Clear()
2982
            // or TPM2_ChangeEPS()
2983
0
            if(    parentHandle == TPM_RH_ENDORSEMENT
2984
0
                && publicArea->objectAttributes.fixedTPM == SET)
2985
0
                 proof = &gp.ehProof;
2986
              // For all object types, the size of seedValue is the digest size
2987
              // of its nameAlg
2988
0
              sensitive->seedValue.t.size
2989
0
                  = CryptGetHashDigestSize(publicArea->nameAlg);
2990
              // Compute seedValue using implementation-dependent method
2991
0
              _cpri__GenerateSeededRandom(sensitive->seedValue.t.size,
2992
0
                                          sensitive->seedValue.t.buffer,
2993
0
                                          hashAlg,
2994
0
                                          &seed->b,
2995
0
                                          "seedValuea",
2996
0
                                          &name.b,
2997
0
                                          (TPM2B *)proof);
2998
0
        }
2999
3
        else
3000
3
        {
3001
3
              sensitive->seedValue.t.size = 0;
3002
3
        }
3003
3
   }
3004
3
   return result;
3005
3
}
3006
//
3007
//       10.2.9.13 CryptObjectIsPublicConsistent()
3008
//
3009
//       This function checks that the key sizes in the public area are consistent. For an asymmetric key, the size
3010
//       of the public key must match the size indicated by the public->parameters.
3011
//       Checks for the algorithm types matching the key type are handled by the unmarshaling operation.
3012
//
3013
//       Return Value                      Meaning
3014
//
3015
//       TRUE                              sizes are consistent
3016
//       FALSE                             sizes are not consistent
3017
//
3018
BOOL
3019
CryptObjectIsPublicConsistent(
3020
   TPMT_PUBLIC         *publicArea           // IN: public area
3021
   )
3022
40
{
3023
40
   BOOL                  OK = TRUE;
3024
40
   switch (publicArea->type)
3025
40
   {
3026
0
#ifdef TPM_ALG_RSA
3027
33
       case TPM_ALG_RSA:
3028
33
           OK = CryptAreKeySizesConsistent(publicArea);
3029
33
           break;
3030
0
#endif //TPM_ALG_RSA
3031
0
#ifdef TPM_ALG_ECC
3032
7
       case TPM_ALG_ECC:
3033
7
           {
3034
7
               const ECC_CURVE                              *curveValue;
3035
                  // Check that the public point is on the indicated curve.
3036
7
                  OK = CryptEccIsPointOnCurve(
3037
7
                                  publicArea->parameters.eccDetail.curveID,
3038
7
                                  &publicArea->unique.ecc);
3039
7
                  if(OK)
3040
6
                  {
3041
6
                      curveValue = CryptEccGetCurveDataPointer(
3042
6
                                           publicArea->parameters.eccDetail.curveID);
3043
6
                      pAssert(curveValue != NULL);
3044
                       // The input ECC curve must be a supported curve
3045
                       // IF a scheme is defined for the curve, then that scheme must
3046
                       // be used.
3047
6
                       OK =    (curveValue->sign.scheme == TPM_ALG_NULL
3048
6
                            || (   publicArea->parameters.eccDetail.scheme.scheme
3049
0
                                == curveValue->sign.scheme));
3050
6
                       OK = OK && CryptAreKeySizesConsistent(publicArea);
3051
6
               }
3052
7
           }
3053
7
           break;
3054
0
#endif //TPM_ALG_ECC
3055
0
        default:
3056
            // Symmetric object common checks
3057
            // There is noting to check with a symmetric key that is public only.
3058
            // Also not sure that there is anything useful to be done with it
3059
            // either.
3060
0
            break;
3061
40
   }
3062
40
   return OK;
3063
40
}
3064
//
3065
//
3066
//
3067
//       10.2.9.14 CryptObjectPublicPrivateMatch()
3068
//
3069
//       This function checks the cryptographic binding between the public and sensitive areas.
3070
//
3071
//       Error Returns                   Meaning
3072
//
3073
//       TPM_RC_TYPE                     the type of the public and private areas are not the same
3074
//       TPM_RC_FAILURE                  crypto error
3075
//       TPM_RC_BINDING                  the public and private areas are not cryptographically matched.
3076
//
3077
TPM_RC
3078
CryptObjectPublicPrivateMatch(
3079
   OBJECT              *object                // IN: the object to check
3080
   )
3081
39
{
3082
39
   TPMT_PUBLIC               *publicArea;
3083
39
   TPMT_SENSITIVE            *sensitive;
3084
39
   TPM_RC                     result = TPM_RC_SUCCESS;
3085
39
   BOOL                       isAsymmetric = FALSE;
3086
39
   pAssert(object != NULL);
3087
39
   publicArea = &object->publicArea;
3088
39
   sensitive = &object->sensitive;
3089
39
   if(publicArea->type != sensitive->sensitiveType)
3090
0
       return TPM_RC_TYPE;
3091
39
   switch(publicArea->type)
3092
39
   {
3093
0
#ifdef TPM_ALG_RSA
3094
33
   case TPM_ALG_RSA:
3095
33
       isAsymmetric = TRUE;
3096
       // The public and private key sizes need to be consistent
3097
33
       if(sensitive->sensitive.rsa.t.size != publicArea->unique.rsa.t.size/2)
3098
1
            result = TPM_RC_BINDING;
3099
32
       else
3100
       // Load key by computing the private exponent
3101
32
            result = CryptLoadPrivateRSA(object);
3102
33
       break;
3103
0
#endif
3104
0
#ifdef TPM_ALG_ECC
3105
       // This function is called from ObjectLoad() which has already checked to
3106
       // see that the public point is on the curve so no need to repeat that
3107
       // check.
3108
6
   case TPM_ALG_ECC:
3109
6
       isAsymmetric = TRUE;
3110
6
       if(    publicArea->unique.ecc.x.t.size
3111
6
                 != sensitive->sensitive.ecc.t.size)
3112
3
            result = TPM_RC_BINDING;
3113
3
       else if(publicArea->nameAlg != TPM_ALG_NULL)
3114
3
       {
3115
3
            TPMS_ECC_POINT           publicToCompare;
3116
            // Compute ECC public key
3117
3
            CryptEccPointMultiply(&publicToCompare,
3118
3
                                   publicArea->parameters.eccDetail.curveID,
3119
3
                                   &sensitive->sensitive.ecc, NULL);
3120
            // Compare ECC public key
3121
3
            if(    (!Memory2BEqual(&publicArea->unique.ecc.x.b,
3122
3
                                   &publicToCompare.x.b))
3123
3
                || (!Memory2BEqual(&publicArea->unique.ecc.y.b,
3124
0
                                   &publicToCompare.y.b)))
3125
3
                 result = TPM_RC_BINDING;
3126
3
       }
3127
6
       break;
3128
//
3129
0
#endif
3130
0
   case TPM_ALG_KEYEDHASH:
3131
0
       break;
3132
0
   case TPM_ALG_SYMCIPHER:
3133
0
       if(    (publicArea->parameters.symDetail.sym.keyBits.sym + 7)/8
3134
0
           != sensitive->sensitive.sym.t.size)
3135
0
            result = TPM_RC_BINDING;
3136
0
       break;
3137
0
   default:
3138
       // The choice here is an assert or a return of a bad type for the object
3139
0
       pAssert(0);
3140
0
       break;
3141
39
   }
3142
   // For asymmetric keys, the algorithm for validating the linkage between
3143
   // the public and private areas is algorithm dependent. For symmetric keys
3144
   // the linkage is based on hashing the symKey and obfuscation values.
3145
39
   if(   result == TPM_RC_SUCCESS && !isAsymmetric
3146
39
      && publicArea->nameAlg != TPM_ALG_NULL)
3147
0
   {
3148
0
       TPM2B_DIGEST    uniqueToCompare;
3149
        // Compute unique for symmetric key
3150
0
        CryptComputeSymmetricUnique(publicArea->nameAlg, sensitive,
3151
0
                                     &uniqueToCompare);
3152
        // Compare unique
3153
0
        if(!Memory2BEqual(&publicArea->unique.sym.b,
3154
0
                          &uniqueToCompare.b))
3155
0
            result = TPM_RC_BINDING;
3156
0
   }
3157
39
   return result;
3158
39
}
3159
//
3160
//
3161
//       10.2.9.15 CryptGetSignHashAlg()
3162
//
3163
//       Get the hash algorithm of signature from a TPMT_SIGNATURE structure. It assumes the signature is not
3164
//       NULL This is a function for easy access
3165
//
3166
TPMI_ALG_HASH
3167
CryptGetSignHashAlg(
3168
   TPMT_SIGNATURE     *auth             // IN: signature
3169
   )
3170
0
{
3171
0
   pAssert(auth->sigAlg != TPM_ALG_NULL);
3172
   // Get authHash algorithm based on signing scheme
3173
0
   switch(auth->sigAlg)
3174
0
   {
3175
0
#ifdef   TPM_ALG_RSA
3176
0
        case TPM_ALG_RSASSA:
3177
0
            return auth->signature.rsassa.hash;
3178
0
        case TPM_ALG_RSAPSS:
3179
0
            return auth->signature.rsapss.hash;
3180
0
   #endif //TPM_ALG_RSA
3181
0
   #ifdef TPM_ALG_ECC
3182
0
       case TPM_ALG_ECDSA:
3183
0
           return auth->signature.ecdsa.hash;
3184
0
   #endif //TPM_ALG_ECC
3185
0
            case TPM_ALG_HMAC:
3186
0
                return auth->signature.hmac.hashAlg;
3187
0
            default:
3188
0
                return TPM_ALG_NULL;
3189
0
    }
3190
0
}
3191
//
3192
//
3193
//       10.2.9.16 CryptIsSplitSign()
3194
//
3195
//       This function us used to determine if the signing operation is a split signing operation that required a
3196
//       TPM2_Commit().
3197
//
3198
BOOL
3199
CryptIsSplitSign(
3200
    TPM_ALG_ID           scheme             // IN: the algorithm selector
3201
    )
3202
0
{
3203
0
    if(   0
3204
0
#    ifdef   TPM_ALG_ECDAA
3205
0
       || scheme == TPM_ALG_ECDAA
3206
0
#    endif   // TPM_ALG_ECDAA
3207
0
        )
3208
0
        return TRUE;
3209
0
    return FALSE;
3210
0
}
3211
//
3212
//
3213
//       10.2.9.17 CryptIsSignScheme()
3214
//
3215
//       This function indicates if a scheme algorithm is a sign algorithm.
3216
//
3217
BOOL
3218
CryptIsSignScheme(
3219
    TPMI_ALG_ASYM_SCHEME           scheme
3220
    )
3221
15
{
3222
15
    BOOL                isSignScheme = FALSE;
3223
15
   switch(scheme)
3224
15
   {
3225
0
#ifdef TPM_ALG_RSA
3226
       // If RSA is implemented, then both signing schemes are required
3227
4
   case TPM_ALG_RSASSA:
3228
11
   case TPM_ALG_RSAPSS:
3229
11
       isSignScheme = TRUE;
3230
11
       break;
3231
0
#endif //TPM_ALG_RSA
3232
0
#ifdef TPM_ALG_ECC
3233
       // If ECC is implemented ECDSA is required
3234
2
   case TPM_ALG_ECDSA:
3235
2
#ifdef TPM_ALG_ECDAA
3236
       // ECDAA is optional
3237
2
   case TPM_ALG_ECDAA:
3238
2
#endif
3239
2
#ifdef   TPM_ALG_ECSCHNORR
3240
       // Schnorr is also optional
3241
4
   case TPM_ALG_ECSCHNORR:
3242
4
#endif
3243
4
#ifdef TPM_ALG_SM2
3244
4
   case TPM_ALG_SM2:
3245
4
#endif
3246
4
       isSignScheme = TRUE;
3247
4
       break;
3248
0
#endif //TPM_ALG_ECC
3249
0
   default:
3250
0
       break;
3251
15
   }
3252
15
   return isSignScheme;
3253
15
}
3254
//
3255
//
3256
//       10.2.9.18 CryptIsDecryptScheme()
3257
//
3258
//       This function indicate if a scheme algorithm is a decrypt algorithm.
3259
//
3260
BOOL
3261
CryptIsDecryptScheme(
3262
    TPMI_ALG_ASYM_SCHEME           scheme
3263
    )
3264
8
{
3265
8
    BOOL           isDecryptScheme = FALSE;
3266
8
   switch(scheme)
3267
8
   {
3268
0
#ifdef TPM_ALG_RSA
3269
       // If RSA is implemented, then both decrypt schemes are required
3270
0
   case TPM_ALG_RSAES:
3271
7
   case TPM_ALG_OAEP:
3272
7
        isDecryptScheme = TRUE;
3273
7
       break;
3274
0
#endif //TPM_ALG_RSA
3275
0
#ifdef TPM_ALG_ECC
3276
       // If ECC is implemented ECDH is required
3277
1
   case TPM_ALG_ECDH:
3278
1
#ifdef TPM_ALG_SM2
3279
1
   case TPM_ALG_SM2:
3280
1
#endif
3281
#ifdef TPM_ALG_ECMQV
3282
   case TPM_ALG_ECMQV:
3283
#endif
3284
1
       isDecryptScheme = TRUE;
3285
1
       break;
3286
0
#endif //TPM_ALG_ECC
3287
0
   default:
3288
0
       break;
3289
8
   }
3290
8
   return isDecryptScheme;
3291
8
}
3292
//
3293
//
3294
//       10.2.9.19 CryptSelectSignScheme()
3295
//
3296
//       This function is used by the attestation and signing commands. It implements the rules for selecting the
3297
//       signature scheme to use in signing. This function requires that the signing key either be TPM_RH_NULL
3298
//       or be loaded.
3299
//       If a default scheme is defined in object, the default scheme should be chosen, otherwise, the input
3300
//       scheme should be chosen. In the case that both object and input scheme has a non-NULL scheme
3301
//       algorithm, if the schemes are compatible, the input scheme will be chosen.
3302
//
3303
//
3304
//
3305
//
3306
//       Error Returns                   Meaning
3307
//
3308
//       TPM_RC_KEY                      key referenced by signHandle is not a signing key
3309
//       TPM_RC_SCHEME                   both scheme and key's default scheme are empty; or scheme is
3310
//                                       empty while key's default scheme requires explicit input scheme (split
3311
//                                       signing); or non-empty default key scheme differs from scheme
3312
//
3313
TPM_RC
3314
CryptSelectSignScheme(
3315
   TPMI_DH_OBJECT             signHandle,        // IN: handle of signing key
3316
   TPMT_SIG_SCHEME           *scheme             // IN/OUT: signing scheme
3317
   )
3318
0
{
3319
0
   OBJECT                    *signObject;
3320
0
   TPMT_SIG_SCHEME           *objectScheme;
3321
0
   TPMT_PUBLIC               *publicArea;
3322
0
   TPM_RC                     result = TPM_RC_SUCCESS;
3323
   // If the signHandle is TPM_RH_NULL, then the NULL scheme is used, regardless
3324
   // of the setting of scheme
3325
0
   if(signHandle == TPM_RH_NULL)
3326
0
   {
3327
0
       scheme->scheme = TPM_ALG_NULL;
3328
0
       scheme->details.any.hashAlg = TPM_ALG_NULL;
3329
0
   }
3330
0
   else
3331
0
   {
3332
       // sign handle is not NULL so...
3333
       // Get sign object pointer
3334
0
       signObject = ObjectGet(signHandle);
3335
0
       publicArea = &signObject->publicArea;
3336
        // is this a signing key?
3337
0
        if(!publicArea->objectAttributes.sign)
3338
0
             result = TPM_RC_KEY;
3339
0
        else
3340
0
        {
3341
             // "parms" defined to avoid long code lines.
3342
0
             TPMU_PUBLIC_PARMS    *parms = &publicArea->parameters;
3343
0
             if (CryptIsAsymAlgorithm(publicArea->type)) {
3344
0
               objectScheme = (TPMT_SIG_SCHEME *)&parms->asymDetail.scheme;
3345
0
             } else if (publicArea->type == TPM_ALG_KEYEDHASH) {
3346
0
               objectScheme = (TPMT_SIG_SCHEME *)&parms->keyedHashDetail.scheme;
3347
0
             } else {
3348
0
               return TPM_RC_SCHEME;
3349
0
             }
3350
               // If the object doesn't have a default scheme, then use the
3351
               // input scheme.
3352
0
               if(objectScheme->scheme == TPM_ALG_NULL)
3353
0
               {
3354
                   // Input and default can't both be NULL
3355
0
                   if(scheme->scheme == TPM_ALG_NULL)
3356
0
                       result = TPM_RC_SCHEME;
3357
                   // Assume that the scheme is compatible with the key. If not,
3358
                   // we will generate an error in the signing operation.
3359
0
               }
3360
0
               else if(scheme->scheme == TPM_ALG_NULL)
3361
0
               {
3362
                   // input scheme is NULL so use default
3363
                   // First, check to see if the default requires that the caller
3364
                   // provided scheme data
3365
0
                   if(CryptIsSplitSign(objectScheme->scheme))
3366
0
                       result = TPM_RC_SCHEME;
3367
0
                   else
3368
0
                   {
3369
0
                       scheme->scheme = objectScheme->scheme;
3370
0
                       scheme->details.any.hashAlg
3371
0
                                   = objectScheme->details.any.hashAlg;
3372
0
                   }
3373
0
               }
3374
0
               else
3375
0
               {
3376
                   // Both input and object have scheme selectors
3377
                   // If the scheme and the hash are not the same then...
3378
0
                   if(    objectScheme->scheme != scheme->scheme
3379
0
                       || (   objectScheme->details.any.hashAlg
3380
0
                           != scheme->details.any.hashAlg))
3381
0
                        result = TPM_RC_SCHEME;
3382
0
               }
3383
0
        }
3384
0
   }
3385
0
   return result;
3386
0
}
3387
//
3388
//
3389
//       10.2.9.20 CryptSign()
3390
//
3391
//       Sign a digest with asymmetric key or HMAC. This function is called by attestation commands and the
3392
//       generic TPM2_Sign() command. This function checks the key scheme and digest size. It does not check
3393
//       if the sign operation is allowed for restricted key. It should be checked before the function is called. The
3394
//       function will assert if the key is not a signing key.
3395
//
3396
//       Error Returns                     Meaning
3397
//
3398
//       TPM_RC_SCHEME                     signScheme is not compatible with the signing key type
3399
//       TPM_RC_VALUE                      digest value is greater than the modulus of signHandle or size of
3400
//                                         hashData does not match hash algorithm insignScheme (for an RSA
3401
//                                         key); invalid commit status or failed to generate r value (for an ECC
3402
//                                         key)
3403
//
3404
TPM_RC
3405
CryptSign(
3406
   TPMI_DH_OBJECT            signHandle,          //   IN: The handle of sign key
3407
   TPMT_SIG_SCHEME          *signScheme,          //   IN: sign scheme.
3408
   TPM2B_DIGEST             *digest,              //   IN: The digest being signed
3409
   TPMT_SIGNATURE           *signature            //   OUT: signature
3410
   )
3411
0
{
3412
0
   OBJECT                   *signKey = ObjectGet(signHandle);
3413
0
   TPM_RC                    result = TPM_RC_SCHEME;
3414
   // check if input handle is a sign key
3415
0
   pAssert(signKey->publicArea.objectAttributes.sign == SET);
3416
   // Must have the private portion loaded. This check is made during
3417
   // authorization.
3418
0
   pAssert(signKey->attributes.publicOnly == CLEAR);
3419
   // Initialize signature scheme
3420
0
   signature->sigAlg = signScheme->scheme;
3421
   // If the signature algorithm is TPM_ALG_NULL, then we are done
3422
0
   if(signature->sigAlg == TPM_ALG_NULL)
3423
0
       return TPM_RC_SUCCESS;
3424
   // All the schemes other than TPM_ALG_NULL have a hash algorithm
3425
0
    TEST_HASH(signScheme->details.any.hashAlg);
3426
    // Initialize signature hash
3427
    // Note: need to do the check for alg null first because the null scheme
3428
    // doesn't have a hashAlg member.
3429
0
    signature->signature.any.hashAlg = signScheme->details.any.hashAlg;
3430
    // perform sign operation based on different key type
3431
0
    switch (signKey->publicArea.type)
3432
0
    {
3433
0
#ifdef TPM_ALG_RSA
3434
0
       case TPM_ALG_RSA:
3435
0
           result = CryptSignRSA(signKey, signScheme, digest, signature);
3436
0
           break;
3437
0
#endif //TPM_ALG_RSA
3438
0
#ifdef TPM_ALG_ECC
3439
0
       case TPM_ALG_ECC:
3440
0
           result = CryptSignECC(signKey, signScheme, digest, signature);
3441
0
           break;
3442
0
#endif //TPM_ALG_ECC
3443
0
       case TPM_ALG_KEYEDHASH:
3444
0
           result = CryptSignHMAC(signKey, signScheme, digest, signature);
3445
0
           break;
3446
0
       default:
3447
0
           break;
3448
0
   }
3449
0
    return result;
3450
0
}
3451
//
3452
//
3453
//       10.2.9.21 CryptVerifySignature()
3454
//
3455
//       This function is used to verify a signature.               It is called by TPM2_VerifySignature() and
3456
//       TPM2_PolicySigned().
3457
//       Since this operation only requires use of a public key, no consistency checks are necessary for the key to
3458
//       signature type because a caller can load any public key that they like with any scheme that they like. This
3459
//       routine simply makes sure that the signature is correct, whatever the type.
3460
//       This function requires that auth is not a NULL pointer.
3461
//
3462
//       Error Returns                    Meaning
3463
//
3464
//       TPM_RC_SIGNATURE                 the signature is not genuine
3465
//       TPM_RC_SCHEME                    the scheme is not supported
3466
//       TPM_RC_HANDLE                    an HMAC key was selected but the private part of the key is not
3467
//                                        loaded
3468
//
3469
TPM_RC
3470
CryptVerifySignature(
3471
    TPMI_DH_OBJECT       keyHandle,         // IN: The handle of sign key
3472
    TPM2B_DIGEST        *digest,            // IN: The digest being validated
3473
    TPMT_SIGNATURE      *signature          // IN: signature
3474
    )
3475
0
{
3476
    // NOTE: ObjectGet will either return a pointer to a loaded object or
3477
    // will assert. It will never return a non-valid value. This makes it save
3478
    // to initialize 'publicArea' with the return value from ObjectGet() without
3479
    // checking it first.
3480
0
    OBJECT              *authObject = ObjectGet(keyHandle);
3481
0
    TPMT_PUBLIC         *publicArea = &authObject->publicArea;
3482
0
    TPM_RC                    result = TPM_RC_SCHEME;
3483
    // The input unmarshaling should prevent any input signature from being
3484
    // a NULL signature, but just in case
3485
0
    if(signature->sigAlg == TPM_ALG_NULL)
3486
0
        return TPM_RC_SIGNATURE;
3487
0
    switch (publicArea->type)
3488
0
    {
3489
0
#ifdef TPM_ALG_RSA
3490
0
   case TPM_ALG_RSA:
3491
0
       result = CryptRSAVerifySignature(authObject, digest, signature);
3492
0
       break;
3493
0
#endif //TPM_ALG_RSA
3494
0
#ifdef TPM_ALG_ECC
3495
0
   case TPM_ALG_ECC:
3496
0
       result = CryptECCVerifySignature(authObject, digest, signature);
3497
0
       break;
3498
0
#endif // TPM_ALG_ECC
3499
0
    case TPM_ALG_KEYEDHASH:
3500
0
        if(authObject->attributes.publicOnly)
3501
0
             result = TPM_RC_HANDLE;
3502
0
        else
3503
0
             result = CryptHMACVerifySignature(authObject, digest, signature);
3504
0
        break;
3505
0
    default:
3506
0
        break;
3507
0
    }
3508
0
    return result;
3509
0
}
3510
//
3511
//
3512
//       10.2.10 Math functions
3513
//
3514
//       10.2.10.1 CryptDivide()
3515
//
3516
//       This function interfaces to the math library for large number divide.
3517
//
3518
//       Error Returns                     Meaning
3519
//
3520
//       TPM_RC_SIZE                       quotient or remainder is too small to receive the result
3521
//
3522
TPM_RC
3523
CryptDivide(
3524
    TPM2B               *numerator,           //   IN: numerator
3525
    TPM2B               *denominator,         //   IN: denominator
3526
    TPM2B               *quotient,            //   OUT: quotient = numerator / denominator.
3527
    TPM2B               *remainder            //   OUT: numerator mod denominator.
3528
    )
3529
0
{
3530
0
    pAssert(   numerator != NULL         && denominator!= NULL
3531
0
            && (quotient != NULL         || remainder != NULL)
3532
0
           );
3533
    // assume denominator is not         0
3534
0
    pAssert(denominator->size !=         0);
3535
0
    return TranslateCryptErrors(_math__Div(numerator,
3536
0
                                           denominator,
3537
0
                                                              quotient,
3538
0
                                                              remainder)
3539
0
                                           );
3540
0
}
3541
//
3542
//
3543
//       10.2.10.2 CryptCompare()
3544
//
3545
//       This function interfaces to the math library for large number, unsigned compare.
3546
//
3547
//       Return Value                         Meaning
3548
//
3549
//       1                                    if a > b
3550
//       0                                    if a = b
3551
//       -1                                   if a < b
3552
//
3553
LIB_EXPORT int
3554
CryptCompare(
3555
    const   UINT32         aSize,                  //   IN:   size of a
3556
    const   BYTE          *a,                      //   IN:   a buffer
3557
    const   UINT32         bSize,                  //   IN:   size of b
3558
    const   BYTE          *b                       //   IN:   b buffer
3559
    )
3560
0
{
3561
0
    return _math__uComp(aSize, a, bSize, b);
3562
0
}
3563
//
3564
//
3565
//       10.2.10.3 CryptCompareSigned()
3566
//
3567
//       This function interfaces to the math library for large number, signed compare.
3568
//
3569
//       Return Value                         Meaning
3570
//
3571
//       1                                    if a > b
3572
//       0                                    if a = b
3573
//       -1                                   if a < b
3574
//
3575
int
3576
CryptCompareSigned(
3577
    UINT32                 aSize,                  //   IN:   size of a
3578
    BYTE                  *a,                      //   IN:   a buffer
3579
    UINT32                 bSize,                  //   IN:   size of b
3580
    BYTE                  *b                       //   IN:   b buffer
3581
    )
3582
0
{
3583
0
    return _math__Comp(aSize, a, bSize, b);
3584
0
}
3585
//
3586
//
3587
//       10.2.10.4 CryptGetTestResult
3588
//
3589
//       This function returns the results of a self-test function.
3590
//
3591
//       NOTE:            the behavior in this function is NOT the correct behavior for a real TPM implementation. An artificial behavior is
3592
//                        placed here due to the limitation of a software simulation environment. For the correct behavior, consult the
3593
//                        part 3 specification for TPM2_GetTestResult().
3594
//
3595
TPM_RC
3596
CryptGetTestResult(
3597
    TPM2B_MAX_BUFFER            *outData                 // OUT: test result data
3598
     )
3599
0
{
3600
0
     outData->t.size = 0;
3601
0
     return TPM_RC_SUCCESS;
3602
0
}
3603
//
3604
//
3605
//       10.2.11 Capability Support
3606
//
3607
//       10.2.11.1 CryptCapGetECCCurve()
3608
//
3609
//       This function returns the list of implemented ECC curves.
3610
//
3611
//       Return Value                      Meaning
3612
//
3613
//       YES                               if no more ECC curve is available
3614
//       NO                                if there are more ECC curves not reported
3615
//
3616
#ifdef TPM_ALG_ECC //% 5
3617
TPMI_YES_NO
3618
CryptCapGetECCCurve(
3619
     TPM_ECC_CURVE      curveID,             // IN: the starting ECC curve
3620
     UINT32             maxCount,            // IN: count of returned curve
3621
     TPML_ECC_CURVE    *curveList            // OUT: ECC curve list
3622
     )
3623
0
{
3624
0
     TPMI_YES_NO         more = NO;
3625
0
     UINT16              i;
3626
0
     UINT32              count = _cpri__EccGetCurveCount();
3627
0
     TPM_ECC_CURVE       curve;
3628
     // Initialize output property list
3629
0
     curveList->count = 0;
3630
     // The maximum count of curves we may return is MAX_ECC_CURVES
3631
0
     if(maxCount > MAX_ECC_CURVES) maxCount = MAX_ECC_CURVES;
3632
     // Scan the eccCurveValues array
3633
0
     for(i = 0; i < count; i++)
3634
0
     {
3635
0
         curve = _cpri__GetCurveIdByIndex(i);
3636
         // If curveID is less than the starting curveID, skip it
3637
0
         if(curve < curveID)
3638
0
             continue;
3639
0
         if(curveList->count < maxCount)
3640
0
         {
3641
              // If we have not filled up the return list, add more curves to
3642
              // it
3643
0
              curveList->eccCurves[curveList->count] = curve;
3644
0
              curveList->count++;
3645
0
         }
3646
0
         else
3647
0
         {
3648
              // If the return list is full but we still have curves
3649
              // available, report this and stop iterating
3650
0
              more = YES;
3651
0
              break;
3652
0
         }
3653
0
     }
3654
0
     return more;
3655
0
}
3656
//
3657
//
3658
//       10.2.11.2 CryptCapGetEccCurveNumber()
3659
//
3660
//       This function returns the number of ECC curves supported by the TPM.
3661
//
3662
UINT32
3663
CryptCapGetEccCurveNumber(
3664
   void
3665
   )
3666
0
{
3667
   // There is an array that holds the curve data. Its size divided by the
3668
   // size of an entry is the number of values in the table.
3669
0
   return _cpri__EccGetCurveCount();
3670
0
}
3671
#endif //TPM_ALG_ECC //% 5
3672
//
3673
//
3674
//       10.2.11.3 CryptAreKeySizesConsistent()
3675
//
3676
//       This function validates that the public key size values are consistent for an asymmetric key.
3677
//
3678
//       NOTE:           This is not a comprehensive test of the public key.
3679
//
3680
//
3681
//       Return Value                        Meaning
3682
//
3683
//       TRUE                                sizes are consistent
3684
//       FALSE                               sizes are not consistent
3685
//
3686
BOOL
3687
CryptAreKeySizesConsistent(
3688
   TPMT_PUBLIC           *publicArea              // IN: the public area to check
3689
   )
3690
80
{
3691
80
   BOOL                  consistent = FALSE;
3692
80
   switch (publicArea->type)
3693
80
   {
3694
0
#ifdef TPM_ALG_RSA
3695
67
       case TPM_ALG_RSA:
3696
           // The key size in bits is filtered by the unmarshaling
3697
67
           consistent = (     ((publicArea->parameters.rsaDetail.keyBits+7)/8)
3698
67
                           == publicArea->unique.rsa.t.size);
3699
67
           break;
3700
0
#endif //TPM_ALG_RSA
3701
0
#ifdef TPM_ALG_ECC
3702
13
       case TPM_ALG_ECC:
3703
13
           {
3704
13
               UINT16                        keySizeInBytes;
3705
13
               TPM_ECC_CURVE                 curveId = publicArea->parameters.eccDetail.curveID;
3706
13
                   keySizeInBytes = CryptEccGetKeySizeInBytes(curveId);
3707
13
                   consistent =         keySizeInBytes > 0
3708
13
                                     && publicArea->unique.ecc.x.t.size <= keySizeInBytes
3709
13
                                     && publicArea->unique.ecc.y.t.size <= keySizeInBytes;
3710
13
           }
3711
13
           break;
3712
0
#endif //TPM_ALG_ECC
3713
0
       default:
3714
0
           break;
3715
80
      }
3716
80
      return consistent;
3717
80
}
3718
//
3719
//
3720
//       10.2.11.4 CryptAlgSetImplemented()
3721
//
3722
//       This function initializes the bit vector with one bit for each implemented algorithm. This function is called
3723
//       from _TPM_Init(). The vector of implemented algorithms should be generated by the part 2 parser so that
3724
//       the g_implementedAlgorithms vector can be a const. That's not how it is now
3725
//
3726
void
3727
CryptAlgsSetImplemented(
3728
      void
3729
      )
3730
0
{
3731
0
      AlgorithmGetImplementedVector(&g_implementedAlgorithms);
3732
0
}