/src/tpm2/PolicyFidoSigned.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2019 The Chromium OS Authors. All rights reserved. |
3 | | * Use of this source code is governed by a BSD-style license that can be |
4 | | * found in the LICENSE file. |
5 | | */ |
6 | | #include "InternalRoutines.h" |
7 | | #include "PolicyFidoSigned_fp.h" |
8 | | |
9 | | /* |
10 | | * PolicyFidoContextUpdate |
11 | | * |
12 | | * @param commandCode IN: TPM Ext command code |
13 | | * @param name IN: name of entity |
14 | | * @param in IN: input buffer of the command |
15 | | * @param policyTimeout IN: policy timeout |
16 | | * @param session IN/OUT: policy session to be updated |
17 | | * @return none |
18 | | */ |
19 | | static void PolicyFidoContextUpdate(TPM_CC commandCode, |
20 | | TPM2B_NAME *entityName, |
21 | | PolicyFidoSigned_In *in, |
22 | | SESSION *session) |
23 | 0 | { |
24 | 0 | HASH_STATE hashState; |
25 | 0 | UINT16 policyDigestSize; |
26 | 0 | int i; |
27 | | |
28 | | /* Start hash */ |
29 | 0 | policyDigestSize = CryptStartHash(session->authHashAlg, &hashState); |
30 | | |
31 | | /* |
32 | | * policyDigest size should always be the digest size of session hash |
33 | | * algorithm. |
34 | | */ |
35 | 0 | pAssert(session->u2.policyDigest.t.size == policyDigestSize); |
36 | | |
37 | | /* add old digest */ |
38 | 0 | CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b); |
39 | | |
40 | | /* add commandCode */ |
41 | 0 | CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode); |
42 | | |
43 | | /* add name if applicable */ |
44 | 0 | if (entityName != NULL) |
45 | 0 | CryptUpdateDigest2B(&hashState, &entityName->b); |
46 | | |
47 | | /* Complete the digest and get the results */ |
48 | 0 | CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b); |
49 | | |
50 | | /* Start second hash computation */ |
51 | 0 | CryptStartHash(session->authHashAlg, &hashState); |
52 | | |
53 | | /* add policy digest */ |
54 | 0 | CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b); |
55 | | |
56 | | /* add authDataDescr */ |
57 | 0 | CryptUpdateDigest(&hashState, |
58 | 0 | in->authDataDescrCount * sizeof(DATA_OFFSET), |
59 | 0 | (BYTE *)in->authDataDescr); |
60 | | |
61 | | /* add authData[authDataDescr] */ |
62 | 0 | for (i = 0; i < in->authDataDescrCount; i++) { |
63 | 0 | CryptUpdateDigest(&hashState, |
64 | 0 | in->authDataDescr[i].size, |
65 | 0 | &(in->authData.t.buffer[in->authDataDescr[i].offset])); |
66 | 0 | } |
67 | | |
68 | | /* Complete second digest */ |
69 | 0 | CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b); |
70 | |
|
71 | 0 | return; |
72 | 0 | } |
73 | | |
74 | | TPM_RC TPM2_PolicyFidoSigned(PolicyFidoSigned_In *in, |
75 | | PolicyFidoSigned_Out *out) |
76 | 0 | { |
77 | 0 | TPM_RC result = TPM_RC_SUCCESS; |
78 | 0 | SESSION *session; |
79 | 0 | TPM2B_NAME entityName; |
80 | |
|
81 | 0 | session = SessionGet(in->policySession); |
82 | | |
83 | | /* Only do input validation if this is not a trial policy session */ |
84 | 0 | if (session->attributes.isTrialPolicy == CLEAR) { |
85 | 0 | TPM2B_DIGEST authHash; |
86 | 0 | HASH_STATE hashState; |
87 | | |
88 | | /* |
89 | | * Re-compute the digest being signed: |
90 | | * |
91 | | * aHash := hash (authenticatorData[] || nonceTPM) |
92 | | * |
93 | | * Start hash |
94 | | */ |
95 | 0 | authHash.t.size = CryptStartHash(CryptGetSignHashAlg(&in->auth), |
96 | 0 | &hashState); |
97 | | |
98 | | /* add authData */ |
99 | 0 | CryptUpdateDigest(&hashState, |
100 | 0 | in->authData.t.size, |
101 | 0 | (BYTE *)in->authData.t.buffer); |
102 | | |
103 | | /* Add the sesson nonce */ |
104 | 0 | CryptUpdateDigest2B(&hashState, &session->nonceTPM.b); |
105 | | |
106 | | /* Complete digest */ |
107 | 0 | CryptCompleteHash2B(&hashState, &authHash.b); |
108 | | |
109 | | /* |
110 | | * Validate Signature. A TPM_RC_SCHEME, TPM_RC_HANDLE or |
111 | | * TPM_RC_SIGNATURE error may be returned at this point. |
112 | | */ |
113 | 0 | result = CryptVerifySignature(in->authObject, &authHash, &in->auth); |
114 | 0 | if (result != TPM_RC_SUCCESS) |
115 | 0 | return RcSafeAddToResult(result, RC_PolicySigned_auth); |
116 | 0 | } |
117 | | |
118 | | /* Internal Data Update */ |
119 | | |
120 | | /* Need the Name of the signing entity */ |
121 | 0 | entityName.t.size = EntityGetName(in->authObject, &entityName.t.name); |
122 | | |
123 | | /* |
124 | | * Update policy with input policyRef and name of auth key |
125 | | * These values are updated even if the session is a trial session |
126 | | */ |
127 | 0 | PolicyFidoContextUpdate(TPM_CCE_PolicyFidoSigned, |
128 | 0 | &entityName, |
129 | 0 | in, |
130 | 0 | session); |
131 | | |
132 | | /* |
133 | | * Command Output |
134 | | * |
135 | | * No output to generate. |
136 | | */ |
137 | |
|
138 | 0 | return TPM_RC_SUCCESS; |
139 | 0 | } |