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
|
// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 3: Commands
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014
#include "InternalRoutines.h"
#include "Policy_spt_fp.h"
#include "PolicySigned_fp.h"
//
//
// Error Returns Meaning
//
// TPM_RC_CPHASH cpHash was previously set to a different value
// TPM_RC_EXPIRED expiration indicates a time in the past or expiration is non-zero but no
// nonceTPM is present
// TPM_RC_HANDLE authObject need to have sensitive portion loaded
// TPM_RC_KEY authObject is not a signing scheme
// TPM_RC_NONCE nonceTPM is not the nonce associated with the policySession
// TPM_RC_SCHEME the signing scheme of auth is not supported by the TPM
// TPM_RC_SIGNATURE the signature is not genuine
// TPM_RC_SIZE input cpHash has wrong size
// TPM_RC_VALUE input policyID or expiration does not match the internal data in policy
// session
//
TPM_RC
TPM2_PolicySigned(
PolicySigned_In *in, // IN: input parameter list
PolicySigned_Out *out // OUT: output parameter list
)
{
TPM_RC result = TPM_RC_SUCCESS;
SESSION *session;
TPM2B_NAME entityName;
TPM2B_DIGEST authHash;
HASH_STATE hashState;
UINT32 expiration = (in->expiration < 0)
? -(in->expiration) : in->expiration;
UINT64 authTimeout = 0;
// Input Validation
// Set up local pointers
session = SessionGet(in->policySession); // the session structure
// Only do input validation if this is not a trial policy session
if(session->attributes.isTrialPolicy == CLEAR)
{
if(expiration != 0)
authTimeout = expiration * 1000 + session->startTime;
result = PolicyParameterChecks(session, authTimeout,
&in->cpHashA, &in->nonceTPM,
RC_PolicySigned_nonceTPM,
RC_PolicySigned_cpHashA,
RC_PolicySigned_expiration);
if(result != TPM_RC_SUCCESS)
return result;
// Re-compute the digest being signed
/*(See part 3 specification)
// The digest is computed as:
// aHash := hash ( nonceTPM | expiration | cpHashA | policyRef)
// where:
// hash() the hash associated with the signed auth
// nonceTPM the nonceTPM value from the TPM2_StartAuthSession .
// response If the authorization is not limited to this
// session, the size of this value is zero.
// expiration time limit on authorization set by authorizing object.
// This 32-bit value is set to zero if the expiration
// time is not being set.
// cpHashA hash of the command parameters for the command being
// approved using the hash algorithm of the PSAP session.
// Set to NULLauth if the authorization is not limited
// to a specific command.
// policyRef hash of an opaque value determined by the authorizing
// object. Set to the NULLdigest if no hash is present.
*/
// Start hash
authHash.t.size = CryptStartHash(CryptGetSignHashAlg(&in->auth),
&hashState);
// add nonceTPM
CryptUpdateDigest2B(&hashState, &in->nonceTPM.b);
// add expiration
CryptUpdateDigestInt(&hashState, sizeof(UINT32), (BYTE*) &in->expiration);
// add cpHashA
CryptUpdateDigest2B(&hashState, &in->cpHashA.b);
// add policyRef
CryptUpdateDigest2B(&hashState, &in->policyRef.b);
// Complete digest
CryptCompleteHash2B(&hashState, &authHash.b);
// Validate Signature. A TPM_RC_SCHEME, TPM_RC_HANDLE or TPM_RC_SIGNATURE
// error may be returned at this point
result = CryptVerifySignature(in->authObject, &authHash, &in->auth);
if(result != TPM_RC_SUCCESS)
return RcSafeAddToResult(result, RC_PolicySigned_auth);
}
// Internal Data Update
// Need the Name of the signing entity
entityName.t.size = EntityGetName(in->authObject, &entityName.t.name);
// Update policy with input policyRef and name of auth key
// These values are updated even if the session is a trial session
PolicyContextUpdate(TPM_CC_PolicySigned, &entityName, &in->policyRef,
&in->cpHashA, authTimeout, session);
// Command Output
// Create ticket and timeout buffer if in->expiration < 0 and this is not
// a trial session.
// NOTE: PolicyParameterChecks() makes sure that nonceTPM is present
// when expiration is non-zero.
if( in->expiration < 0
&& session->attributes.isTrialPolicy == CLEAR
)
{
// Generate timeout buffer. The format of output timeout buffer is
// TPM-specific.
// Note: can't do a direct copy because the output buffer is a byte
// array and it may not be aligned to accept a 64-bit value. The method
// used has the side-effect of making the returned value a big-endian,
// 64-bit value that is byte aligned.
out->timeout.t.size = sizeof(UINT64);
UINT64_TO_BYTE_ARRAY(authTimeout, out->timeout.t.buffer);
// Compute policy ticket
TicketComputeAuth(TPM_ST_AUTH_SIGNED, EntityGetHierarchy(in->authObject),
authTimeout, &in->cpHashA, &in->policyRef, &entityName,
&out->policyTicket);
}
else
{
// Generate a null ticket.
// timeout buffer is null
out->timeout.t.size = 0;
// auth ticket is null
out->policyTicket.tag = TPM_ST_AUTH_SIGNED;
out->policyTicket.hierarchy = TPM_RH_NULL;
out->policyTicket.digest.t.size = 0;
}
return TPM_RC_SUCCESS;
}
|