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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
// 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"
//
//
// 10.3.3 Functions
//
// 10.3.3.1 TicketIsSafe()
//
// This function indicates if producing a ticket is safe. It checks if the leading bytes of an input buffer is
// TPM_GENERATED_VALUE or its substring of canonical form. If so, it is not safe to produce ticket for an
// input buffer claiming to be TPM generated buffer
//
// Return Value Meaning
//
// TRUE It is safe to produce ticket
// FALSE It is not safe to produce ticket
//
BOOL
TicketIsSafe(
TPM2B *buffer
)
{
TPM_GENERATED valueToCompare = TPM_GENERATED_VALUE;
BYTE bufferToCompare[sizeof(valueToCompare)];
BYTE *marshalBuffer;
INT32 bufferSize;
// If the buffer size is less than the size of TPM_GENERATED_VALUE, assume
// it is not safe to generate a ticket
if(buffer->size < sizeof(valueToCompare))
return FALSE;
marshalBuffer = bufferToCompare;
bufferSize = sizeof(TPM_GENERATED);
TPM_GENERATED_Marshal(&valueToCompare, &marshalBuffer, &bufferSize);
if(MemoryEqual(buffer->buffer, bufferToCompare, sizeof(valueToCompare)))
return FALSE;
else
return TRUE;
}
//
//
// 10.3.3.2 TicketComputeVerified()
//
// This function creates a TPMT_TK_VERIFIED ticket.
//
void
TicketComputeVerified(
TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
TPM2B_DIGEST *digest, // IN: digest
TPM2B_NAME *keyName, // IN: name of key that signed the value
TPMT_TK_VERIFIED *ticket // OUT: verified ticket
)
{
TPM2B_AUTH *proof;
HMAC_STATE hmacState;
// Fill in ticket fields
ticket->tag = TPM_ST_VERIFIED;
ticket->hierarchy = hierarchy;
// Use the proof value of the hierarchy
proof = HierarchyGetProof(hierarchy);
// Start HMAC
ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
&proof->b, &hmacState);
// add TPM_ST_VERIFIED
CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag);
// add digest
CryptUpdateDigest2B(&hmacState, &digest->b);
// add key name
CryptUpdateDigest2B(&hmacState, &keyName->b);
// complete HMAC
CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
return;
}
//
//
// 10.3.3.3 TicketComputeAuth()
//
// This function creates a TPMT_TK_AUTH ticket.
//
void
TicketComputeAuth(
TPM_ST type, // IN: the type of ticket.
TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
UINT64 timeout, // IN: timeout
TPM2B_DIGEST *cpHashA, // IN: input cpHashA
TPM2B_NONCE *policyRef, // IN: input policyRef
TPM2B_NAME *entityName, // IN: name of entity
TPMT_TK_AUTH *ticket // OUT: Created ticket
)
{
TPM2B_AUTH *proof;
HMAC_STATE hmacState;
// Get proper proof
proof = HierarchyGetProof(hierarchy);
// Fill in ticket fields
ticket->tag = type;
ticket->hierarchy = hierarchy;
// Start HMAC
ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
&proof->b, &hmacState);
// Adding TPM_ST_AUTH
CryptUpdateDigestInt(&hmacState, sizeof(UINT16), &ticket->tag);
// Adding timeout
CryptUpdateDigestInt(&hmacState, sizeof(UINT64), &timeout);
// Adding cpHash
CryptUpdateDigest2B(&hmacState, &cpHashA->b);
// Adding policyRef
CryptUpdateDigest2B(&hmacState, &policyRef->b);
// Adding keyName
CryptUpdateDigest2B(&hmacState, &entityName->b);
// Compute HMAC
CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
return;
}
//
//
// 10.3.3.4 TicketComputeHashCheck()
//
// This function creates a TPMT_TK_HASHCHECK ticket.
//
void
TicketComputeHashCheck(
TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
TPM_ALG_ID hashAlg, // IN: the hash algorithm used to create
// 'digest'
TPM2B_DIGEST *digest, // IN: input digest
TPMT_TK_HASHCHECK *ticket // OUT: Created ticket
)
{
TPM2B_AUTH *proof;
HMAC_STATE hmacState;
// Get proper proof
proof = HierarchyGetProof(hierarchy);
// Fill in ticket fields
ticket->tag = TPM_ST_HASHCHECK;
ticket->hierarchy = hierarchy;
ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
&proof->b, &hmacState);
// Add TPM_ST_HASHCHECK
CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag);
//
// Add hash algorithm
CryptUpdateDigestInt(&hmacState, sizeof(hashAlg), &hashAlg);
// Add digest
CryptUpdateDigest2B(&hmacState, &digest->b);
// Compute HMAC
CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
return;
}
//
//
// 10.3.3.5 TicketComputeCreation()
//
// This function creates a TPMT_TK_CREATION ticket.
//
void
TicketComputeCreation(
TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy for ticket
TPM2B_NAME *name, // IN: object name
TPM2B_DIGEST *creation, // IN: creation hash
TPMT_TK_CREATION *ticket // OUT: created ticket
)
{
TPM2B_AUTH *proof;
HMAC_STATE hmacState;
// Get proper proof
proof = HierarchyGetProof(hierarchy);
// Fill in ticket fields
ticket->tag = TPM_ST_CREATION;
ticket->hierarchy = hierarchy;
ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
&proof->b, &hmacState);
// Add TPM_ST_CREATION
CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag);
// Add name
CryptUpdateDigest2B(&hmacState, &name->b);
// Add creation hash
CryptUpdateDigest2B(&hmacState, &creation->b);
// Compute HMAC
CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
return;
}
|