blob: d969d25e5a86eebcde29502487f4f24074ef3d91 [file] [log] [blame]
Namyoon Woof4428142019-10-30 19:02:58 -07001/*
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 */
19static void PolicyFidoContextUpdate(TPM_CC commandCode,
20 TPM2B_NAME *entityName,
21 PolicyFidoSigned_In *in,
22 SESSION *session)
23{
24 HASH_STATE hashState;
25 UINT16 policyDigestSize;
26 int i;
27
28 /* Start hash */
29 policyDigestSize = CryptStartHash(session->authHashAlg, &hashState);
30
31 /*
32 * policyDigest size should always be the digest size of session hash
33 * algorithm.
34 */
35 pAssert(session->u2.policyDigest.t.size == policyDigestSize);
36
37 /* add old digest */
38 CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
39
40 /* add commandCode */
41 CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode);
42
43 /* add name if applicable */
44 if (entityName != NULL)
45 CryptUpdateDigest2B(&hashState, &entityName->b);
46
47 /* Complete the digest and get the results */
48 CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
49
50 /* Start second hash computation */
51 CryptStartHash(session->authHashAlg, &hashState);
52
53 /* add policy digest */
54 CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
55
56 /* add authDataDescr */
57 CryptUpdateDigest(&hashState,
58 in->authDataDescrCount * sizeof(DATA_OFFSET),
59 (BYTE *)in->authDataDescr);
60
61 /* add authData[authDataDescr] */
62 for (i = 0; i < in->authDataDescrCount; i++) {
63 CryptUpdateDigest(&hashState,
64 in->authDataDescr[i].size,
65 &(in->authData.t.buffer[in->authDataDescr[i].offset]));
66 }
67
68 /* Complete second digest */
69 CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
70
71 return;
72}
73
74TPM_RC TPM2_PolicyFidoSigned(PolicyFidoSigned_In *in,
75 PolicyFidoSigned_Out *out)
76{
77 TPM_RC result = TPM_RC_SUCCESS;
78 SESSION *session;
79 TPM2B_NAME entityName;
80
81 session = SessionGet(in->policySession);
82
83 /* Only do input validation if this is not a trial policy session */
84 if (session->attributes.isTrialPolicy == CLEAR) {
85 TPM2B_DIGEST authHash;
86 HASH_STATE hashState;
87
88 /*
89 * Re-compute the digest being signed:
90 *
91 * aHash := hash (authenticatorData[] || nonceTPM)
92 *
93 * Start hash
94 */
95 authHash.t.size = CryptStartHash(CryptGetSignHashAlg(&in->auth),
96 &hashState);
97
98 /* add authData */
99 CryptUpdateDigest(&hashState,
100 in->authData.t.size,
101 (BYTE *)in->authData.t.buffer);
102
103 /* Add the sesson nonce */
104 CryptUpdateDigest2B(&hashState, &session->nonceTPM.b);
105
106 /* Complete digest */
107 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 result = CryptVerifySignature(in->authObject, &authHash, &in->auth);
114 if (result != TPM_RC_SUCCESS)
115 return RcSafeAddToResult(result, RC_PolicySigned_auth);
116 }
117
118 /* Internal Data Update */
119
120 /* Need the Name of the signing entity */
121 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 PolicyFidoContextUpdate(TPM_CCE_PolicyFidoSigned,
128 &entityName,
129 in,
130 session);
131
132 /*
133 * Command Output
134 *
135 * No output to generate.
136 */
137
138 return TPM_RC_SUCCESS;
139}