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 //
10 //
11 //       10.3.3       Functions
12 //
13 //       10.3.3.1       TicketIsSafe()
14 //
15 //       This function indicates if producing a ticket is safe. It checks if the leading bytes of an input buffer is
16 //       TPM_GENERATED_VALUE or its substring of canonical form. If so, it is not safe to produce ticket for an
17 //       input buffer claiming to be TPM generated buffer
18 //
19 //       Return Value                      Meaning
20 //
21 //       TRUE                              It is safe to produce ticket
22 //       FALSE                             It is not safe to produce ticket
23 //
24 BOOL
TicketIsSafe(TPM2B * buffer)25 TicketIsSafe(
26       TPM2B                *buffer
27       )
28 {
29       TPM_GENERATED        valueToCompare = TPM_GENERATED_VALUE;
30       BYTE                 bufferToCompare[sizeof(valueToCompare)];
31       BYTE                 *marshalBuffer;
32       INT32                bufferSize;
33       // If the buffer size is less than the size of TPM_GENERATED_VALUE, assume
34       // it is not safe to generate a ticket
35       if(buffer->size < sizeof(valueToCompare))
36           return FALSE;
37       marshalBuffer = bufferToCompare;
38       bufferSize = sizeof(TPM_GENERATED);
39    TPM_GENERATED_Marshal(&valueToCompare, &marshalBuffer, &bufferSize);
40    if(MemoryEqual(buffer->buffer, bufferToCompare, sizeof(valueToCompare)))
41        return FALSE;
42    else
43        return TRUE;
44 }
45 //
46 //
47 //     10.3.3.2   TicketComputeVerified()
48 //
49 //     This function creates a TPMT_TK_VERIFIED ticket.
50 //
51 void
TicketComputeVerified(TPMI_RH_HIERARCHY hierarchy,TPM2B_DIGEST * digest,TPM2B_NAME * keyName,TPMT_TK_VERIFIED * ticket)52 TicketComputeVerified(
53    TPMI_RH_HIERARCHY          hierarchy,       //   IN: hierarchy constant for ticket
54    TPM2B_DIGEST              *digest,          //   IN: digest
55    TPM2B_NAME                *keyName,         //   IN: name of key that signed the value
56    TPMT_TK_VERIFIED          *ticket           //   OUT: verified ticket
57    )
58 {
59    TPM2B_AUTH                *proof;
60    HMAC_STATE                 hmacState;
61    // Fill in ticket fields
62    ticket->tag = TPM_ST_VERIFIED;
63    ticket->hierarchy = hierarchy;
64    // Use the proof value of the hierarchy
65    proof = HierarchyGetProof(hierarchy);
66    // Start HMAC
67    ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
68                                             &proof->b, &hmacState);
69    // add TPM_ST_VERIFIED
70    CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag);
71    // add digest
72    CryptUpdateDigest2B(&hmacState, &digest->b);
73    // add key name
74    CryptUpdateDigest2B(&hmacState, &keyName->b);
75    // complete HMAC
76    CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
77    return;
78 }
79 //
80 //
81 //     10.3.3.3   TicketComputeAuth()
82 //
83 //     This function creates a TPMT_TK_AUTH ticket.
84 //
85 void
TicketComputeAuth(TPM_ST type,TPMI_RH_HIERARCHY hierarchy,UINT64 timeout,TPM2B_DIGEST * cpHashA,TPM2B_NONCE * policyRef,TPM2B_NAME * entityName,TPMT_TK_AUTH * ticket)86 TicketComputeAuth(
87    TPM_ST                     type,            //   IN: the type of ticket.
88    TPMI_RH_HIERARCHY          hierarchy,       //   IN: hierarchy constant for ticket
89    UINT64                     timeout,         //   IN: timeout
90    TPM2B_DIGEST              *cpHashA,         //   IN: input cpHashA
91    TPM2B_NONCE               *policyRef,       //   IN: input policyRef
92    TPM2B_NAME                *entityName,      //   IN: name of entity
93    TPMT_TK_AUTH              *ticket           //   OUT: Created ticket
94    )
95 {
96    TPM2B_AUTH              *proof;
97    HMAC_STATE               hmacState;
98    // Get proper proof
99    proof = HierarchyGetProof(hierarchy);
100    // Fill in ticket fields
101    ticket->tag = type;
102    ticket->hierarchy = hierarchy;
103    // Start HMAC
104    ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
105                                             &proof->b, &hmacState);
106    // Adding TPM_ST_AUTH
107    CryptUpdateDigestInt(&hmacState, sizeof(UINT16), &ticket->tag);
108    // Adding timeout
109    CryptUpdateDigestInt(&hmacState, sizeof(UINT64), &timeout);
110    // Adding cpHash
111    CryptUpdateDigest2B(&hmacState, &cpHashA->b);
112    // Adding policyRef
113    CryptUpdateDigest2B(&hmacState, &policyRef->b);
114    // Adding keyName
115    CryptUpdateDigest2B(&hmacState, &entityName->b);
116    // Compute HMAC
117    CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
118    return;
119 }
120 //
121 //
122 //      10.3.3.4   TicketComputeHashCheck()
123 //
124 //      This function creates a TPMT_TK_HASHCHECK ticket.
125 //
126 void
TicketComputeHashCheck(TPMI_RH_HIERARCHY hierarchy,TPM_ALG_ID hashAlg,TPM2B_DIGEST * digest,TPMT_TK_HASHCHECK * ticket)127 TicketComputeHashCheck(
128    TPMI_RH_HIERARCHY        hierarchy,      //   IN: hierarchy constant for ticket
129    TPM_ALG_ID               hashAlg,        //   IN: the hash algorithm used to create
130                                             //       'digest'
131    TPM2B_DIGEST            *digest,         //   IN: input digest
132    TPMT_TK_HASHCHECK       *ticket          //   OUT: Created ticket
133    )
134 {
135    TPM2B_AUTH              *proof;
136    HMAC_STATE               hmacState;
137    // Get proper proof
138    proof = HierarchyGetProof(hierarchy);
139    // Fill in ticket fields
140    ticket->tag = TPM_ST_HASHCHECK;
141    ticket->hierarchy = hierarchy;
142    ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
143                                             &proof->b, &hmacState);
144    // Add TPM_ST_HASHCHECK
145    CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag);
146 //
147       // Add hash algorithm
148       CryptUpdateDigestInt(&hmacState, sizeof(hashAlg), &hashAlg);
149       // Add digest
150       CryptUpdateDigest2B(&hmacState, &digest->b);
151       // Compute HMAC
152       CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
153       return;
154 }
155 //
156 //
157 //      10.3.3.5     TicketComputeCreation()
158 //
159 //      This function creates a TPMT_TK_CREATION ticket.
160 //
161 void
TicketComputeCreation(TPMI_RH_HIERARCHY hierarchy,TPM2B_NAME * name,TPM2B_DIGEST * creation,TPMT_TK_CREATION * ticket)162 TicketComputeCreation(
163       TPMI_RH_HIERARCHY       hierarchy,        //   IN: hierarchy for ticket
164       TPM2B_NAME             *name,             //   IN: object name
165       TPM2B_DIGEST           *creation,         //   IN: creation hash
166       TPMT_TK_CREATION       *ticket            //   OUT: created ticket
167       )
168 {
169       TPM2B_AUTH             *proof;
170       HMAC_STATE              hmacState;
171       // Get proper proof
172       proof = HierarchyGetProof(hierarchy);
173       // Fill in ticket fields
174       ticket->tag = TPM_ST_CREATION;
175       ticket->hierarchy = hierarchy;
176       ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
177                                                &proof->b, &hmacState);
178       // Add TPM_ST_CREATION
179       CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag);
180       // Add name
181       CryptUpdateDigest2B(&hmacState, &name->b);
182       // Add creation hash
183       CryptUpdateDigest2B(&hmacState, &creation->b);
184       // Compute HMAC
185       CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
186       return;
187 }
188