15679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This file was extracted from the TCG Published
25679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Trusted Platform Module Library
35679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Part 3: Commands
45679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Family "2.0"
55679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Level 00 Revision 01.16
65679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// October 30, 2014
75679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
85679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "InternalRoutines.h"
95679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "Object_spt_fp.h"
105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "Create_fp.h"
115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Error Returns               Meaning
145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_ASYMMETRIC           non-duplicable storage key and its parent have different public
165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 parameters
175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_ATTRIBUTES           sensitiveDataOrigin is CLEAR when 'sensitive.data' is an Empty
185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 Buffer, or is SET when 'sensitive.data' is not empty; fixedTPM,
195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 fixedParent, or encryptedDuplication attributes are inconsistent
205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 between themselves or with those of the parent object; inconsistent
215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 restricted, decrypt and sign attributes; attempt to inject sensitive data
225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 for an asymmetric key; attempt to create a symmetric cipher key that
235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 is not a decryption key
245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_HASH                 non-duplicable storage key and its parent have different name
255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 algorithm
265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_KDF                  incorrect KDF specified for decrypting keyed hash object
275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_KEY                  invalid key size values in an asymmetric key public area
285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_KEY_SIZE             key size in public area for symmetric key differs from the size in the
295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 sensitive creation area; may also be returned if the TPM does not
305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 allow the key size to be used for a Storage Key
315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_RANGE                the exponent value of an RSA key is not supported.
325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_SCHEME               inconsistent attributes decrypt, sign, restricted and key's scheme ID;
335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 or hash algorithm is inconsistent with the scheme ID for keyed hash
345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 object
355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_SIZE                 size of public auth policy or sensitive auth value does not match
365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 digest size of the name algorithm sensitive data size for the keyed
375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 hash object is larger than is allowed for the scheme
385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_SYMMETRIC            a storage key with no symmetric algorithm specified; or non-storage
395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 key with symmetric algorithm different from TPM_ALG_NULL
405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_TYPE                 unknown object type; non-duplicable storage key and its parent have
415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 different types; parentHandle does not reference a restricted
425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 decryption key in the storage hierarchy with both public and sensitive
435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 portion loaded
445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_VALUE                exponent is not prime or could not find a prime using the provided
455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 parameters for an RSA key; unsupported name algorithm for an ECC
465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 key
475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_OBJECT_MEMORY        there is no free slot for the object. This implementation does not
485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                 return this error.
495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
505679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
515679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM2_Create(
525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   Create_In        *in,            // IN: input parameter list
535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   Create_Out       *out            // OUT: output parameter list
545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC                  result = TPM_RC_SUCCESS;
575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SENSITIVE          sensitive;
585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_NAME              name;
595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Input Validation
615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT       *parentObject;
635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   parentObject = ObjectGet(in->parentHandle);
655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Does parent have the proper attributes?
675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(!AreAttributesForParent(parentObject))
685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_TYPE + RC_Create_parentHandle;
695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The sensitiveDataOrigin attribute must be consistent with the setting of
715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // the size of the data object in inSensitive.
725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(   (in->inPublic.t.publicArea.objectAttributes.sensitiveDataOrigin == SET)
735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      != (in->inSensitive.t.sensitive.data.t.size == 0))
745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Mismatch between the object attributes and the parameter.
755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_ATTRIBUTES + RC_Create_inSensitive;
765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Check attributes in input public area. TPM_RC_ASYMMETRIC, TPM_RC_ATTRIBUTES,
785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // TPM_RC_HASH, TPM_RC_KDF, TPM_RC_SCHEME, TPM_RC_SIZE, TPM_RC_SYMMETRIC,
795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // or TPM_RC_TYPE error may be returned at this point.
805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   result = PublicAttributesValidation(FALSE, in->parentHandle,
815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                       &in->inPublic.t.publicArea);
825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(result != TPM_RC_SUCCESS)
835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return RcSafeAddToResult(result, RC_Create_inPublic);
845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Validate the sensitive area values
865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if( MemoryRemoveTrailingZeros(&in->inSensitive.t.sensitive.userAuth)
875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           > CryptGetHashDigestSize(in->inPublic.t.publicArea.nameAlg))
885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SIZE + RC_Create_inSensitive;
895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Command Output
915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Create object crypto data
935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   result = CryptCreateObject(in->parentHandle, &in->inPublic.t.publicArea,
945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                              &in->inSensitive.t.sensitive, &sensitive);
955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(result != TPM_RC_SUCCESS)
965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return result;
975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Fill in creation data
995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   FillInCreationData(in->parentHandle, in->inPublic.t.publicArea.nameAlg,
1005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      &in->creationPCR, &in->outsideInfo,
1015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      &out->creationData, &out->creationHash);
1025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Copy public area from input to output
1045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   out->outPublic.t.publicArea = in->inPublic.t.publicArea;
1055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Compute name from public area
1075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   ObjectComputeName(&(out->outPublic.t.publicArea), &name);
1085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Compute creation ticket
1105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TicketComputeCreation(EntityGetHierarchy(in->parentHandle), &name,
1115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                         &out->creationHash, &out->creationTicket);
1125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Prepare output private data from sensitive
1145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SensitiveToPrivate(&sensitive, &name, in->parentHandle,
1155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      out->outPublic.t.publicArea.nameAlg,
1165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      &out->outPrivate);
1175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
1195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
120