1 /* Microsoft Reference Implementation for TPM 2.0
2 *
3 * The copyright in this software is being made available under the BSD License,
4 * included below. This software may be subject to other third party and
5 * contributor rights, including patent rights, and no such rights are granted
6 * under this license.
7 *
8 * Copyright (c) Microsoft Corporation
9 *
10 * All rights reserved.
11 *
12 * BSD License
13 *
14 * Redistribution and use in source and binary forms, with or without modification,
15 * are permitted provided that the following conditions are met:
16 *
17 * Redistributions of source code must retain the above copyright notice, this list
18 * of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright notice, this
21 * list of conditions and the following disclaimer in the documentation and/or
22 * other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 #include "Tpm.h"
36 #include "PolicyAuthorize_fp.h"
37
38 #if CC_PolicyAuthorize // Conditional expansion of this file
39
40 #include "Policy_spt_fp.h"
41
42 /*(See part 3 specification)
43 // Change policy by a signature from authority
44 */
45 // Return Type: TPM_RC
46 // TPM_RC_HASH hash algorithm in 'keyName' is not supported
47 // TPM_RC_SIZE 'keyName' is not the correct size for its hash algorithm
48 // TPM_RC_VALUE the current policyDigest of 'policySession' does not
49 // match 'approvedPolicy'; or 'checkTicket' doesn't match
50 // the provided values
51 TPM_RC
TPM2_PolicyAuthorize(PolicyAuthorize_In * in)52 TPM2_PolicyAuthorize(
53 PolicyAuthorize_In *in // IN: input parameter list
54 )
55 {
56 SESSION *session;
57 TPM2B_DIGEST authHash;
58 HASH_STATE hashState;
59 TPMT_TK_VERIFIED ticket;
60 TPM_ALG_ID hashAlg;
61 UINT16 digestSize;
62
63 // Input Validation
64
65 // Get pointer to the session structure
66 session = SessionGet(in->policySession);
67
68 // Extract from the Name of the key, the algorithm used to compute it's Name
69 hashAlg = BYTE_ARRAY_TO_UINT16(in->keySign.t.name);
70
71 // 'keySign' parameter needs to use a supported hash algorithm, otherwise
72 // can't tell how large the digest should be
73 if(!CryptHashIsValidAlg(hashAlg, FALSE))
74 return TPM_RCS_HASH + RC_PolicyAuthorize_keySign;
75
76 digestSize = CryptHashGetDigestSize(hashAlg);
77 if(digestSize != (in->keySign.t.size - 2))
78 return TPM_RCS_SIZE + RC_PolicyAuthorize_keySign;
79
80 //If this is a trial policy, skip all validations
81 if(session->attributes.isTrialPolicy == CLEAR)
82 {
83 // Check that "approvedPolicy" matches the current value of the
84 // policyDigest in policy session
85 if(!MemoryEqual2B(&session->u2.policyDigest.b,
86 &in->approvedPolicy.b))
87 return TPM_RCS_VALUE + RC_PolicyAuthorize_approvedPolicy;
88
89 // Validate ticket TPMT_TK_VERIFIED
90 // Compute aHash. The authorizing object sign a digest
91 // aHash := hash(approvedPolicy || policyRef).
92 // Start hash
93 authHash.t.size = CryptHashStart(&hashState, hashAlg);
94
95 // add approvedPolicy
96 CryptDigestUpdate2B(&hashState, &in->approvedPolicy.b);
97
98 // add policyRef
99 CryptDigestUpdate2B(&hashState, &in->policyRef.b);
100
101 // complete hash
102 CryptHashEnd2B(&hashState, &authHash.b);
103
104 // re-compute TPMT_TK_VERIFIED
105 TicketComputeVerified(in->checkTicket.hierarchy, &authHash,
106 &in->keySign, &ticket);
107
108 // Compare ticket digest. If not match, return error
109 if(!MemoryEqual2B(&in->checkTicket.digest.b, &ticket.digest.b))
110 return TPM_RCS_VALUE + RC_PolicyAuthorize_checkTicket;
111 }
112
113 // Internal Data Update
114
115 // Set policyDigest to zero digest
116 PolicyDigestClear(session);
117
118 // Update policyDigest
119 PolicyContextUpdate(TPM_CC_PolicyAuthorize, &in->keySign, &in->policyRef,
120 NULL, 0, session);
121
122 return TPM_RC_SUCCESS;
123 }
124
125 #endif // CC_PolicyAuthorize