diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2015-05-20 10:32:25 -0700 |
---|---|---|
committer | Vadim Bendebury <vbendeb@chromium.org> | 2015-05-20 22:32:05 -0700 |
commit | 5679752bf24c21135884e987c4077e2f71848971 (patch) | |
tree | 3e680dd91a7af84c45ea1170ee88225bd4ad32c8 /Import.c | |
download | tpm2-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.c | 186 |
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; +} |