1 // This file was extracted from the TCG Published
2 // Trusted Platform Module Library
3 // Part 3: Commands
4 // Family "2.0"
5 // Level 00 Revision 01.16
6 // October 30, 2014
7
8 #include "InternalRoutines.h"
9 #include "PolicyAuthorize_fp.h"
10 #include "Policy_spt_fp.h"
11 //
12 //
13 // Error Returns Meaning
14 //
15 // TPM_RC_HASH hash algorithm in keyName is not supported
16 // TPM_RC_SIZE keyName is not the correct size for its hash algorithm
17 // TPM_RC_VALUE the current policyDigest of policySession does not match
18 // approvedPolicy; or checkTicket doesn't match the provided values
19 //
20 TPM_RC
TPM2_PolicyAuthorize(PolicyAuthorize_In * in)21 TPM2_PolicyAuthorize(
22 PolicyAuthorize_In *in // IN: input parameter list
23 )
24 {
25 SESSION *session;
26 TPM2B_DIGEST authHash;
27 HASH_STATE hashState;
28 TPMT_TK_VERIFIED ticket;
29 TPM_ALG_ID hashAlg;
30 UINT16 digestSize;
31
32 // Input Validation
33
34 // Get pointer to the session structure
35 session = SessionGet(in->policySession);
36
37 // Extract from the Name of the key, the algorithm used to compute it's Name
38 hashAlg = BYTE_ARRAY_TO_UINT16(in->keySign.t.name);
39
40 // 'keySign' parameter needs to use a supported hash algorithm, otherwise
41 // can't tell how large the digest should be
42 digestSize = CryptGetHashDigestSize(hashAlg);
43 if(digestSize == 0)
44 return TPM_RC_HASH + RC_PolicyAuthorize_keySign;
45
46 if(digestSize != (in->keySign.t.size - 2))
47 return TPM_RC_SIZE + RC_PolicyAuthorize_keySign;
48
49 //If this is a trial policy, skip all validations
50 if(session->attributes.isTrialPolicy == CLEAR)
51 {
52 // Check that "approvedPolicy" matches the current value of the
53 // policyDigest in policy session
54 if(!Memory2BEqual(&session->u2.policyDigest.b,
55 &in->approvedPolicy.b))
56 return TPM_RC_VALUE + RC_PolicyAuthorize_approvedPolicy;
57
58 // Validate ticket TPMT_TK_VERIFIED
59 // Compute aHash. The authorizing object sign a digest
60 // aHash := hash(approvedPolicy || policyRef).
61 // Start hash
62 authHash.t.size = CryptStartHash(hashAlg, &hashState);
63
64 // add approvedPolicy
65 CryptUpdateDigest2B(&hashState, &in->approvedPolicy.b);
66
67 // add policyRef
68 CryptUpdateDigest2B(&hashState, &in->policyRef.b);
69
70 // complete hash
71 CryptCompleteHash2B(&hashState, &authHash.b);
72
73 // re-compute TPMT_TK_VERIFIED
74 TicketComputeVerified(in->checkTicket.hierarchy, &authHash,
75 &in->keySign, &ticket);
76
77 // Compare ticket digest. If not match, return error
78 if(!Memory2BEqual(&in->checkTicket.digest.b, &ticket.digest.b))
79 return TPM_RC_VALUE+ RC_PolicyAuthorize_checkTicket;
80 }
81
82 // Internal Data Update
83
84 // Set policyDigest to zero digest
85 MemorySet(session->u2.policyDigest.t.buffer, 0,
86 session->u2.policyDigest.t.size);
87
88 // Update policyDigest
89 PolicyContextUpdate(TPM_CC_PolicyAuthorize, &in->keySign, &in->policyRef,
90 NULL, 0, session);
91
92 return TPM_RC_SUCCESS;
93
94 }
95