• 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 "InternalRoutines.h"
9 #include "Context_spt_fp.h"
10 //
11 //
12 //            Functions
13 //
14 //              ComputeContextProtectionKey()
15 //
16 //      This function retrieves the symmetric protection key for context encryption It is used by
17 //      TPM2_ConextSave() and TPM2_ContextLoad() to create the symmetric encryption key and iv
18 //
19 void
ComputeContextProtectionKey(TPMS_CONTEXT * contextBlob,TPM2B_SYM_KEY * symKey,TPM2B_IV * iv)20 ComputeContextProtectionKey(
21      TPMS_CONTEXT      *contextBlob,    // IN: context blob
22      TPM2B_SYM_KEY     *symKey,         // OUT: the symmetric key
23      TPM2B_IV          *iv              // OUT: the IV.
24      )
25 {
26      UINT16             symKeyBits;     // number of bits in the parent's
27                                         //   symmetric key
28      TPM2B_AUTH        *proof = NULL;   // the proof value to use. Is null for
29                                         //   everything but a primary object in
30                                         //   the Endorsement Hierarchy
31      BYTE               kdfResult[sizeof(TPMU_HA) * 2];// Value produced by the KDF
32      TPM2B_DATA         sequence2B, handle2B;
33      // Get proof value
34      proof = HierarchyGetProof(contextBlob->hierarchy);
35      // Get sequence value in 2B format
36      sequence2B.t.size = sizeof(contextBlob->sequence);
37      MemoryCopy(sequence2B.t.buffer, &contextBlob->sequence,
38                 sizeof(contextBlob->sequence),
39                 sizeof(sequence2B.t.buffer));
40      // Get handle value in 2B format
41      handle2B.t.size = sizeof(contextBlob->savedHandle);
42      MemoryCopy(handle2B.t.buffer, &contextBlob->savedHandle,
43                 sizeof(contextBlob->savedHandle),
44                 sizeof(handle2B.t.buffer));
45      // Get the symmetric encryption key size
46      symKey->t.size = CONTEXT_ENCRYPT_KEY_BYTES;
47 //
48    symKeyBits = CONTEXT_ENCRYPT_KEY_BITS;
49    // Get the size of the IV for the algorithm
50    iv->t.size = CryptGetSymmetricBlockSize(CONTEXT_ENCRYPT_ALG, symKeyBits);
51    // KDFa to generate symmetric key and IV value
52    KDFa(CONTEXT_INTEGRITY_HASH_ALG, &proof->b, "CONTEXT", &sequence2B.b,
53         &handle2B.b, (symKey->t.size + iv->t.size) * 8, kdfResult, NULL);
54    // Copy part of the returned value as the key
55    MemoryCopy(symKey->t.buffer, kdfResult, symKey->t.size,
56               sizeof(symKey->t.buffer));
57    // Copy the rest as the IV
58    MemoryCopy(iv->t.buffer, &kdfResult[symKey->t.size], iv->t.size,
59               sizeof(iv->t.buffer));
60    return;
61 }
62 //
63 //
64 //         ComputeContextIntegrity()
65 //
66 //     Generate the integrity hash for a context It is used by TPM2_ContextSave() to create an integrity hash
67 //     and by TPM2_ContextLoad() to compare an integrity hash
68 //
69 void
ComputeContextIntegrity(TPMS_CONTEXT * contextBlob,TPM2B_DIGEST * integrity)70 ComputeContextIntegrity(
71    TPMS_CONTEXT       *contextBlob,      // IN: context blob
72    TPM2B_DIGEST       *integrity         // OUT: integrity
73    )
74 {
75    HMAC_STATE              hmacState;
76    TPM2B_AUTH              *proof;
77    UINT16                  integritySize;
78    // Get proof value
79    proof = HierarchyGetProof(contextBlob->hierarchy);
80    // Start HMAC
81    integrity->t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
82                                         &proof->b, &hmacState);
83    // Compute integrity size at the beginning of context blob
84    integritySize = sizeof(integrity->t.size) + integrity->t.size;
85    // Adding total reset counter so that the context cannot be
86    // used after a TPM Reset
87    CryptUpdateDigestInt(&hmacState, sizeof(gp.totalResetCount),
88                         &gp.totalResetCount);
89    // If this is a ST_CLEAR object, add the clear count
90    // so that this contest cannot be loaded after a TPM Restart
91    if(contextBlob->savedHandle == 0x80000002)
92        CryptUpdateDigestInt(&hmacState, sizeof(gr.clearCount), &gr.clearCount);
93    // Adding sequence number to the HMAC to make sure that it doesn't
94    // get changed
95    CryptUpdateDigestInt(&hmacState, sizeof(contextBlob->sequence),
96                         &contextBlob->sequence);
97    // Protect the handle
98    CryptUpdateDigestInt(&hmacState, sizeof(contextBlob->savedHandle),
99                          &contextBlob->savedHandle);
100    // Adding sensitive contextData, skip the leading integrity area
101      CryptUpdateDigest(&hmacState, contextBlob->contextBlob.t.size - integritySize,
102                        contextBlob->contextBlob.t.buffer + integritySize);
103      // Complete HMAC
104      CryptCompleteHMAC2B(&hmacState, &integrity->b);
105      return;
106 }
107 //
108 //
109 //           SequenceDataImportExport()
110 //
111 //      This function is used scan through the sequence object and either modify the hash state data for
112 //      LIB_EXPORT or to import it into the internal format
113 //
114 void
SequenceDataImportExport(OBJECT * object,OBJECT * exportObject,IMPORT_EXPORT direction)115 SequenceDataImportExport(
116      OBJECT           *object,          // IN: the object containing the sequence data
117      OBJECT           *exportObject,    // IN/OUT: the object structure that will get
118                                         //     the exported hash state
119      IMPORT_EXPORT     direction
120      )
121 {
122      int                      count = 1;
123      HASH_OBJECT             *internalFmt = (HASH_OBJECT *)object;
124      HASH_OBJECT             *externalFmt = (HASH_OBJECT *)exportObject;
125      if(object->attributes.eventSeq)
126          count = HASH_COUNT;
127      for(; count; count--)
128          CryptHashStateImportExport(&internalFmt->state.hashState[count - 1],
129                               externalFmt->state.hashState, direction);
130 }
131