aboutsummaryrefslogtreecommitdiff
path: root/Context_spt.c
blob: 8ed14af29d68716eaa36c65e5514e04056095fa7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#include "InternalRoutines.h"
#include "Context_spt_fp.h"
//
//
//            Functions
//
//              ComputeContextProtectionKey()
//
//      This function retrieves the symmetric protection key for context encryption It is used by
//      TPM2_ConextSave() and TPM2_ContextLoad() to create the symmetric encryption key and iv
//
void
ComputeContextProtectionKey(
     TPMS_CONTEXT      *contextBlob,    // IN: context blob
     TPM2B_SYM_KEY     *symKey,         // OUT: the symmetric key
     TPM2B_IV          *iv              // OUT: the IV.
     )
{
     UINT16             symKeyBits;     // number of bits in the parent's
                                        //   symmetric key
     TPM2B_AUTH        *proof = NULL;   // the proof value to use. Is null for
                                        //   everything but a primary object in
                                        //   the Endorsement Hierarchy
     BYTE               kdfResult[sizeof(TPMU_HA) * 2];// Value produced by the KDF
     TPM2B_DATA         sequence2B, handle2B;
     // Get proof value
     proof = HierarchyGetProof(contextBlob->hierarchy);
     // Get sequence value in 2B format
     sequence2B.t.size = sizeof(contextBlob->sequence);
     MemoryCopy(sequence2B.t.buffer, &contextBlob->sequence,
                sizeof(contextBlob->sequence),
                sizeof(sequence2B.t.buffer));
     // Get handle value in 2B format
     handle2B.t.size = sizeof(contextBlob->savedHandle);
     MemoryCopy(handle2B.t.buffer, &contextBlob->savedHandle,
                sizeof(contextBlob->savedHandle),
                sizeof(handle2B.t.buffer));
     // Get the symmetric encryption key size
     symKey->t.size = CONTEXT_ENCRYPT_KEY_BYTES;
//
   symKeyBits = CONTEXT_ENCRYPT_KEY_BITS;
   // Get the size of the IV for the algorithm
   iv->t.size = CryptGetSymmetricBlockSize(CONTEXT_ENCRYPT_ALG, symKeyBits);
   // KDFa to generate symmetric key and IV value
   KDFa(CONTEXT_INTEGRITY_HASH_ALG, &proof->b, "CONTEXT", &sequence2B.b,
        &handle2B.b, (symKey->t.size + iv->t.size) * 8, kdfResult, NULL);
   // Copy part of the returned value as the key
   MemoryCopy(symKey->t.buffer, kdfResult, symKey->t.size,
              sizeof(symKey->t.buffer));
   // Copy the rest as the IV
   MemoryCopy(iv->t.buffer, &kdfResult[symKey->t.size], iv->t.size,
              sizeof(iv->t.buffer));
   return;
}
//
//
//         ComputeContextIntegrity()
//
//     Generate the integrity hash for a context It is used by TPM2_ContextSave() to create an integrity hash
//     and by TPM2_ContextLoad() to compare an integrity hash
//
void
ComputeContextIntegrity(
   TPMS_CONTEXT       *contextBlob,      // IN: context blob
   TPM2B_DIGEST       *integrity         // OUT: integrity
   )
{
   HMAC_STATE              hmacState;
   TPM2B_AUTH              *proof;
   UINT16                  integritySize;
   // Get proof value
   proof = HierarchyGetProof(contextBlob->hierarchy);
   // Start HMAC
   integrity->t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
                                        &proof->b, &hmacState);
   // Compute integrity size at the beginning of context blob
   integritySize = sizeof(integrity->t.size) + integrity->t.size;
   // Adding total reset counter so that the context cannot be
   // used after a TPM Reset
   CryptUpdateDigestInt(&hmacState, sizeof(gp.totalResetCount),
                        &gp.totalResetCount);
   // If this is a ST_CLEAR object, add the clear count
   // so that this contest cannot be loaded after a TPM Restart
   if(contextBlob->savedHandle == 0x80000002)
       CryptUpdateDigestInt(&hmacState, sizeof(gr.clearCount), &gr.clearCount);
   // Adding sequence number to the HMAC to make sure that it doesn't
   // get changed
   CryptUpdateDigestInt(&hmacState, sizeof(contextBlob->sequence),
                        &contextBlob->sequence);
   // Protect the handle
   CryptUpdateDigestInt(&hmacState, sizeof(contextBlob->savedHandle),
                         &contextBlob->savedHandle);
   // Adding sensitive contextData, skip the leading integrity area
     CryptUpdateDigest(&hmacState, contextBlob->contextBlob.t.size - integritySize,
                       contextBlob->contextBlob.t.buffer + integritySize);
     // Complete HMAC
     CryptCompleteHMAC2B(&hmacState, &integrity->b);
     return;
}
//
//
//           SequenceDataImportExport()
//
//      This function is used scan through the sequence object and either modify the hash state data for
//      LIB_EXPORT or to import it into the internal format
//
void
SequenceDataImportExport(
     OBJECT           *object,          // IN: the object containing the sequence data
     OBJECT           *exportObject,    // IN/OUT: the object structure that will get
                                        //     the exported hash state
     IMPORT_EXPORT     direction
     )
{
     int                      count = 1;
     HASH_OBJECT             *internalFmt = (HASH_OBJECT *)object;
     HASH_OBJECT             *externalFmt = (HASH_OBJECT *)exportObject;
     if(object->attributes.eventSeq)
         count = HASH_COUNT;
     for(; count; count--)
         CryptHashStateImportExport(&internalFmt->state.hashState[count - 1],
                              externalFmt->state.hashState, direction);
}