aboutsummaryrefslogtreecommitdiff
path: root/Import.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 /Import.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 'Import.c')
-rw-r--r--Import.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/Import.c b/Import.c
new file mode 100644
index 0000000..a5e80a1
--- /dev/null
+++ b/Import.c
@@ -0,0 +1,186 @@
+// 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 "Import_fp.h"
+#include "Object_spt_fp.h"
+//
+//
+// Error Returns Meaning
+//
+// TPM_RC_ASYMMETRIC non-duplicable storage key represented by objectPublic and its
+// parent referenced by parentHandle have different public parameters
+// TPM_RC_ATTRIBUTES attributes FixedTPM and fixedParent of objectPublic are not both
+// CLEAR; or inSymSeed is nonempty and parentHandle does not
+// reference a decryption key; or objectPublic and parentHandle have
+// incompatible or inconsistent attributes; or encrytpedDuplication is
+// SET in objectPublic but the inner or outer wrapper is missing.
+//
+// NOTE: if the TPM provides parameter values, the parameter number will indicate symmetricKey (missing
+// inner wrapper) or inSymSeed (missing outer wrapper).
+//
+//
+// TPM_RC_BINDING duplicate and objectPublic are not cryptographically
+// bound
+//
+// TPM_RC_ECC_POINT inSymSeed is nonempty and ECC point in inSymSeed is not on the
+// curve
+// TPM_RC_HASH non-duplicable storage key represented by objectPublic and its
+// parent referenced by parentHandle have different name algorithm
+// TPM_RC_INSUFFICIENT inSymSeed is nonempty and failed to retrieve ECC point from the
+// secret; or unmarshaling sensitive value from duplicate failed the
+// result of inSymSeed decryption
+// TPM_RC_INTEGRITY duplicate integrity is broken
+// TPM_RC_KDF objectPublic representing decrypting keyed hash object specifies
+// invalid KDF
+// TPM_RC_KEY inconsistent parameters of objectPublic; or inSymSeed is nonempty
+// and parentHandle does not reference a key of supported type; or
+// invalid key size in objectPublic representing an asymmetric key
+// TPM_RC_NO_RESULT inSymSeed is nonempty and multiplication resulted in ECC point at
+// infinity
+// TPM_RC_OBJECT_MEMORY no available object slot
+// TPM_RC_SCHEME inconsistent attributes decrypt, sign, restricted and key's scheme ID
+// in objectPublic; or hash algorithm is inconsistent with the scheme ID
+// for keyed hash object
+// TPM_RC_SIZE authPolicy size does not match digest size of the name algorithm in
+// objectPublic; or symmetricAlg and encryptionKey have different
+// sizes; or inSymSeed is nonempty and it size is not consistent with the
+// type of parentHandle; or unmarshaling sensitive value from duplicate
+// failed
+// TPM_RC_SYMMETRIC objectPublic is either a storage key with no symmetric algorithm or a
+// non-storage key with symmetric algorithm different from
+// TPM_ALG_NULL
+// TPM_RC_TYPE unsupported type of objectPublic; or non-duplicable storage key
+// represented by objectPublic and its parent referenced by
+// parentHandle are of different types; or parentHandle is not a storage
+// key; or only the public portion of parentHandle is loaded; or
+// objectPublic and duplicate are of different types
+// TPM_RC_VALUE nonempty inSymSeed and its numeric value is greater than the
+// modulus of the key referenced by parentHandle or inSymSeed is
+// larger than the size of the digest produced by the name algorithm of
+// the symmetric key referenced by parentHandle
+//
+TPM_RC
+TPM2_Import(
+ Import_In *in, // IN: input parameter list
+ Import_Out *out // OUT: output parameter list
+ )
+{
+
+ TPM_RC result = TPM_RC_SUCCESS;
+ OBJECT *parentObject;
+ TPM2B_DATA data; // symmetric key
+ TPMT_SENSITIVE sensitive;
+ TPM2B_NAME name;
+
+ UINT16 innerKeySize = 0; // encrypt key size for inner
+ // wrapper
+
+// Input Validation
+
+ // FixedTPM and fixedParent must be CLEAR
+ if( in->objectPublic.t.publicArea.objectAttributes.fixedTPM == SET
+ || in->objectPublic.t.publicArea.objectAttributes.fixedParent == SET)
+ return TPM_RC_ATTRIBUTES + RC_Import_objectPublic;
+
+ // Get parent pointer
+ parentObject = ObjectGet(in->parentHandle);
+
+ if(!AreAttributesForParent(parentObject))
+ return TPM_RC_TYPE + RC_Import_parentHandle;
+
+ if(in->symmetricAlg.algorithm != TPM_ALG_NULL)
+ {
+ // Get inner wrap key size
+ innerKeySize = in->symmetricAlg.keyBits.sym;
+ // Input symmetric key must match the size of algorithm.
+ if(in->encryptionKey.t.size != (innerKeySize + 7) / 8)
+ return TPM_RC_SIZE + RC_Import_encryptionKey;
+ }
+ else
+ {
+ // If input symmetric algorithm is NULL, input symmetric key size must
+ // be 0 as well
+ if(in->encryptionKey.t.size != 0)
+ return TPM_RCS_SIZE + RC_Import_encryptionKey;
+ // If encryptedDuplication is SET, then the object must have an inner
+ // wrapper
+ if(in->objectPublic.t.publicArea.objectAttributes.encryptedDuplication)
+ return TPM_RCS_ATTRIBUTES + RC_Import_encryptionKey;
+ }
+
+ // See if there is an outer wrapper
+ if(in->inSymSeed.t.size != 0)
+ {
+ // Decrypt input secret data via asymmetric decryption. TPM_RC_ATTRIBUTES,
+ // TPM_RC_ECC_POINT, TPM_RC_INSUFFICIENT, TPM_RC_KEY, TPM_RC_NO_RESULT,
+ // TPM_RC_SIZE, TPM_RC_VALUE may be returned at this point
+ result = CryptSecretDecrypt(in->parentHandle, NULL, "DUPLICATE",
+ &in->inSymSeed, &data);
+ pAssert(result != TPM_RC_BINDING);
+//
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_Import_inSymSeed);
+ }
+ else
+ {
+ // If encrytpedDuplication is set, then the object must have an outer
+ // wrapper
+ if(in->objectPublic.t.publicArea.objectAttributes.encryptedDuplication)
+ return TPM_RCS_ATTRIBUTES + RC_Import_inSymSeed;
+ data.t.size = 0;
+ }
+
+ // Compute name of object
+ ObjectComputeName(&(in->objectPublic.t.publicArea), &name);
+
+ // Retrieve sensitive from private.
+ // TPM_RC_INSUFFICIENT, TPM_RC_INTEGRITY, TPM_RC_SIZE may be returned here.
+ result = DuplicateToSensitive(&in->duplicate, &name, in->parentHandle,
+ in->objectPublic.t.publicArea.nameAlg,
+ (TPM2B_SEED *) &data, &in->symmetricAlg,
+ &in->encryptionKey, &sensitive);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_Import_duplicate);
+
+ // If the parent of this object has fixedTPM SET, then fully validate this
+ // object so that validation can be skipped when it is loaded
+ if(parentObject->publicArea.objectAttributes.fixedTPM == SET)
+ {
+ TPM_HANDLE objectHandle;
+
+ // Perform self check on input public area. A TPM_RC_SIZE, TPM_RC_SCHEME,
+ // TPM_RC_VALUE, TPM_RC_SYMMETRIC, TPM_RC_TYPE, TPM_RC_HASH,
+ // TPM_RC_ASYMMETRIC, TPM_RC_ATTRIBUTES or TPM_RC_KDF error may be returned
+ // at this point
+ result = PublicAttributesValidation(TRUE, in->parentHandle,
+ &in->objectPublic.t.publicArea);
+ if(result != TPM_RC_SUCCESS)
+ return RcSafeAddToResult(result, RC_Import_objectPublic);
+
+ // Create internal object. A TPM_RC_KEY_SIZE, TPM_RC_KEY or
+ // TPM_RC_OBJECT_MEMORY error may be returned at this point
+ result = ObjectLoad(TPM_RH_NULL, &in->objectPublic.t.publicArea,
+ &sensitive, NULL, in->parentHandle, FALSE,
+ &objectHandle);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+
+ // Don't need the object, just needed the checks to be performed so
+ // flush the object
+ ObjectFlush(objectHandle);
+ }
+
+// Command output
+
+ // Prepare output private data from sensitive
+ SensitiveToPrivate(&sensitive, &name, in->parentHandle,
+ in->objectPublic.t.publicArea.nameAlg,
+ &out->outPrivate);
+
+ return TPM_RC_SUCCESS;
+}