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 "PolicyCpHash_fp.h"
10 //
11 //
12 //     Error Returns                     Meaning
13 //
14 //     TPM_RC_CPHASH                     cpHash of policySession has previously been set to a different value
15 //     TPM_RC_SIZE                       cpHashA is not the size of a digest produced by the hash algorithm
16 //                                       associated with policySession
17 //
18 TPM_RC
TPM2_PolicyCpHash(PolicyCpHash_In * in)19 TPM2_PolicyCpHash(
20    PolicyCpHash_In       *in                   // IN: input parameter list
21    )
22 {
23    SESSION      *session;
24    TPM_CC       commandCode = TPM_CC_PolicyCpHash;
25    HASH_STATE   hashState;
26 
27 // Input Validation
28 
29    // Get pointer to the session structure
30    session = SessionGet(in->policySession);
31 
32    // A new cpHash is given in input parameter, but cpHash in session context
33    // is not empty, or is not the same as the new cpHash
34    if(    in->cpHashA.t.size != 0
35        && session->u1.cpHash.t.size != 0
36        && !Memory2BEqual(&in->cpHashA.b, &session->u1.cpHash.b)
37       )
38        return TPM_RC_CPHASH;
39 
40    // A valid cpHash must have the same size as session hash digest
41    if(in->cpHashA.t.size != CryptGetHashDigestSize(session->authHashAlg))
42        return TPM_RC_SIZE + RC_PolicyCpHash_cpHashA;
43 
44 // Internal Data Update
45 
46    // Update policy hash
47    // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyCpHash || cpHashA)
48    // Start hash
49    CryptStartHash(session->authHashAlg, &hashState);
50 
51    // add old digest
52    CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
53 
54    // add commandCode
55    CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode);
56 
57    // add cpHashA
58    CryptUpdateDigest2B(&hashState, &in->cpHashA.b);
59 
60    // complete the digest and get the results
61    CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
62 
63    // update cpHash in session context
64    session->u1.cpHash = in->cpHashA;
65    session->attributes.iscpHashDefined = SET;
66 
67    return TPM_RC_SUCCESS;
68 }
69