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 "PolicyDuplicationSelect_fp.h"
10 //
11 //
12 //     Error Returns                     Meaning
13 //
14 //     TPM_RC_COMMAND_CODE               commandCode of 'policySession; is not empty
15 //     TPM_RC_CPHASH                     cpHash of policySession is not empty
16 //
17 TPM_RC
TPM2_PolicyDuplicationSelect(PolicyDuplicationSelect_In * in)18 TPM2_PolicyDuplicationSelect(
19    PolicyDuplicationSelect_In       *in                 // IN: input parameter list
20    )
21 {
22    SESSION           *session;
23    HASH_STATE        hashState;
24    TPM_CC            commandCode = TPM_CC_PolicyDuplicationSelect;
25 
26 // Input Validation
27 
28    // Get pointer to the session structure
29    session = SessionGet(in->policySession);
30 
31    // cpHash in session context must be empty
32    if(session->u1.cpHash.t.size != 0)
33        return TPM_RC_CPHASH;
34 
35    // commandCode in session context must be empty
36    if(session->commandCode != 0)
37        return TPM_RC_COMMAND_CODE;
38 
39 // Internal Data Update
40 
41    // Update name hash
42    session->u1.cpHash.t.size = CryptStartHash(session->authHashAlg, &hashState);
43 
44    // add objectName
45    CryptUpdateDigest2B(&hashState, &in->objectName.b);
46 
47    // add new parent name
48    CryptUpdateDigest2B(&hashState, &in->newParentName.b);
49 
50    // complete hash
51    CryptCompleteHash2B(&hashState, &session->u1.cpHash.b);
52 
53    // update policy hash
54    // Old policyDigest size should be the same as the new policyDigest size since
55    // they are using the same hash algorithm
56    session->u2.policyDigest.t.size
57            = CryptStartHash(session->authHashAlg, &hashState);
58 
59    // add old policy
60    CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
61 
62    // add command code
63    CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode);
64 
65    // add objectName
66    if(in->includeObject == YES)
67        CryptUpdateDigest2B(&hashState, &in->objectName.b);
68 
69   // add new parent name
70   CryptUpdateDigest2B(&hashState, &in->newParentName.b);
71 
72   // add includeObject
73   CryptUpdateDigestInt(&hashState, sizeof(TPMI_YES_NO), &in->includeObject);
74 
75   // complete digest
76   CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
77 
78   // clear iscpHashDefined bit to indicate now this field contains a nameHash
79   session->attributes.iscpHashDefined = CLEAR;
80 
81   // set commandCode in session context
82   session->commandCode = TPM_CC_Duplicate;
83 
84    return TPM_RC_SUCCESS;
85 }
86