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//
17TPM_RC
18TPM2_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