aboutsummaryrefslogtreecommitdiff
path: root/Duplicate.c
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2015-05-20 10:32:25 -0700
committerVadim Bendebury <vbendeb@chromium.org>2015-05-20 22:32:05 -0700
commit5679752bf24c21135884e987c4077e2f71848971 (patch)
tree3e680dd91a7af84c45ea1170ee88225bd4ad32c8 /Duplicate.c
downloadtpm2-5679752bf24c21135884e987c4077e2f71848971.tar.gz
Initial commit to seed TPM2.0 source code directory
LICENSE file text copied from TCG library specification. README describes the procedure used to extract source code from parts 3 and 4 of the specification. The python scripts and part{34}.txt files will be removed in the following commits. Change-Id: Ie281e6e988481831f33483053455e8aff8f3f75f Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'Duplicate.c')
-rw-r--r--Duplicate.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/Duplicate.c b/Duplicate.c
new file mode 100644
index 0000000..1bf4d74
--- /dev/null
+++ b/Duplicate.c
@@ -0,0 +1,118 @@
+// This file was extracted from the TCG Published
+// Trusted Platform Module Library
+// Part 3: Commands
+// Family "2.0"
+// Level 00 Revision 01.16
+// October 30, 2014
+
+#include "InternalRoutines.h"
+#include "Duplicate_fp.h"
+#include "Object_spt_fp.h"
+//
+//
+// Error Returns Meaning
+//
+// TPM_RC_ATTRIBUTES key to duplicate has fixedParent SET
+// TPM_RC_HIERARCHY encryptedDuplication is SET and newParentHandle specifies Null
+// Hierarchy
+// TPM_RC_KEY newParentHandle references invalid ECC key (public point not on the
+// curve)
+// TPM_RC_SIZE input encryption key size does not match the size specified in
+// symmetric algorithm
+// TPM_RC_SYMMETRIC encryptedDuplication is SET but no symmetric algorithm is provided
+// TPM_RC_TYPE newParentHandle is neither a storage key nor TPM_RH_NULL; or
+// the object has a NULL nameAlg
+//
+TPM_RC
+TPM2_Duplicate(
+ Duplicate_In *in, // IN: input parameter list
+ Duplicate_Out *out // OUT: output parameter list
+ )
+{
+ TPM_RC result = TPM_RC_SUCCESS;
+ TPMT_SENSITIVE sensitive;
+
+ UINT16 innerKeySize = 0; // encrypt key size for inner wrap
+
+ OBJECT *object;
+ TPM2B_DATA data;
+
+// Input Validation
+
+ // Get duplicate object pointer
+ object = ObjectGet(in->objectHandle);
+
+ // duplicate key must have fixParent bit CLEAR.
+ if(object->publicArea.objectAttributes.fixedParent == SET)
+ return TPM_RC_ATTRIBUTES + RC_Duplicate_objectHandle;
+
+ // Do not duplicate object with NULL nameAlg
+ if(object->publicArea.nameAlg == TPM_ALG_NULL)
+ return TPM_RC_TYPE + RC_Duplicate_objectHandle;
+
+ // new parent key must be a storage object or TPM_RH_NULL
+ if(in->newParentHandle != TPM_RH_NULL
+ && !ObjectIsStorage(in->newParentHandle))
+ return TPM_RC_TYPE + RC_Duplicate_newParentHandle;
+
+ // If the duplicates object has encryptedDuplication SET, then there must be
+ // an inner wrapper and the new parent may not be TPM_RH_NULL
+ if(object->publicArea.objectAttributes.encryptedDuplication == SET)
+ {
+ if(in->symmetricAlg.algorithm == TPM_ALG_NULL)
+ return TPM_RC_SYMMETRIC + RC_Duplicate_symmetricAlg;
+ if(in->newParentHandle == TPM_RH_NULL)
+ return TPM_RC_HIERARCHY + RC_Duplicate_newParentHandle;
+ }
+
+ if(in->symmetricAlg.algorithm == TPM_ALG_NULL)
+ {
+ // if algorithm is TPM_ALG_NULL, input key size must be 0
+ if(in->encryptionKeyIn.t.size != 0)
+ return TPM_RC_SIZE + RC_Duplicate_encryptionKeyIn;
+ }
+ else
+ {
+ // Get inner wrap key size
+ innerKeySize = in->symmetricAlg.keyBits.sym;
+
+ // If provided the input symmetric key must match the size of the algorithm
+ if(in->encryptionKeyIn.t.size != 0
+ && in->encryptionKeyIn.t.size != (innerKeySize + 7) / 8)
+ return TPM_RC_SIZE + RC_Duplicate_encryptionKeyIn;
+ }
+
+// Command Output
+
+ if(in->newParentHandle != TPM_RH_NULL)
+ {
+
+ // Make encrypt key and its associated secret structure. A TPM_RC_KEY
+ // error may be returned at this point
+ out->outSymSeed.t.size = sizeof(out->outSymSeed.t.secret);
+ result = CryptSecretEncrypt(in->newParentHandle,
+ "DUPLICATE", &data, &out->outSymSeed);
+ pAssert(result != TPM_RC_VALUE);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ }
+ else
+ {
+ // Do not apply outer wrapper
+ data.t.size = 0;
+ out->outSymSeed.t.size = 0;
+ }
+
+ // Copy sensitive area
+ sensitive = object->sensitive;
+
+ // Prepare output private data from sensitive
+ SensitiveToDuplicate(&sensitive, &object->name, in->newParentHandle,
+ object->publicArea.nameAlg, (TPM2B_SEED *) &data,
+ &in->symmetricAlg, &in->encryptionKeyIn,
+ &out->duplicate);
+
+ out->encryptionKeyOut = in->encryptionKeyIn;
+
+ return TPM_RC_SUCCESS;
+}