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