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//
20TPM_RC
21TPM2_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