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 "Object_spt_fp.h" 10 #include "Create_fp.h" 11 // 12 // 13 // Error Returns Meaning 14 // 15 // TPM_RC_ASYMMETRIC non-duplicable storage key and its parent have different public 16 // parameters 17 // TPM_RC_ATTRIBUTES sensitiveDataOrigin is CLEAR when 'sensitive.data' is an Empty 18 // Buffer, or is SET when 'sensitive.data' is not empty; fixedTPM, 19 // fixedParent, or encryptedDuplication attributes are inconsistent 20 // between themselves or with those of the parent object; inconsistent 21 // restricted, decrypt and sign attributes; attempt to inject sensitive data 22 // for an asymmetric key; attempt to create a symmetric cipher key that 23 // is not a decryption key 24 // TPM_RC_HASH non-duplicable storage key and its parent have different name 25 // algorithm 26 // TPM_RC_KDF incorrect KDF specified for decrypting keyed hash object 27 // TPM_RC_KEY invalid key size values in an asymmetric key public area 28 // TPM_RC_KEY_SIZE key size in public area for symmetric key differs from the size in the 29 // sensitive creation area; may also be returned if the TPM does not 30 // allow the key size to be used for a Storage Key 31 // TPM_RC_RANGE the exponent value of an RSA key is not supported. 32 // TPM_RC_SCHEME inconsistent attributes decrypt, sign, restricted and key's scheme ID; 33 // or hash algorithm is inconsistent with the scheme ID for keyed hash 34 // object 35 // TPM_RC_SIZE size of public auth policy or sensitive auth value does not match 36 // digest size of the name algorithm sensitive data size for the keyed 37 // hash object is larger than is allowed for the scheme 38 // TPM_RC_SYMMETRIC a storage key with no symmetric algorithm specified; or non-storage 39 // key with symmetric algorithm different from TPM_ALG_NULL 40 // TPM_RC_TYPE unknown object type; non-duplicable storage key and its parent have 41 // different types; parentHandle does not reference a restricted 42 // decryption key in the storage hierarchy with both public and sensitive 43 // portion loaded 44 // TPM_RC_VALUE exponent is not prime or could not find a prime using the provided 45 // parameters for an RSA key; unsupported name algorithm for an ECC 46 // key 47 // TPM_RC_OBJECT_MEMORY there is no free slot for the object. This implementation does not 48 // return this error. 49 // 50 TPM_RC 51 TPM2_Create( 52 Create_In *in, // IN: input parameter list 53 Create_Out *out // OUT: output parameter list 54 ) 55 { 56 TPM_RC result = TPM_RC_SUCCESS; 57 TPMT_SENSITIVE sensitive; 58 TPM2B_NAME name; 59 60 // Input Validation 61 62 OBJECT *parentObject; 63 64 parentObject = ObjectGet(in->parentHandle); 65 66 // Does parent have the proper attributes? 67 if(!AreAttributesForParent(parentObject)) 68 return TPM_RC_TYPE + RC_Create_parentHandle; 69 70 // The sensitiveDataOrigin attribute must be consistent with the setting of 71 // the size of the data object in inSensitive. 72 if( (in->inPublic.t.publicArea.objectAttributes.sensitiveDataOrigin == SET) 73 != (in->inSensitive.t.sensitive.data.t.size == 0)) 74 // Mismatch between the object attributes and the parameter. 75 return TPM_RC_ATTRIBUTES + RC_Create_inSensitive; 76 77 // Check attributes in input public area. TPM_RC_ASYMMETRIC, TPM_RC_ATTRIBUTES, 78 // TPM_RC_HASH, TPM_RC_KDF, TPM_RC_SCHEME, TPM_RC_SIZE, TPM_RC_SYMMETRIC, 79 // or TPM_RC_TYPE error may be returned at this point. 80 result = PublicAttributesValidation(FALSE, in->parentHandle, 81 &in->inPublic.t.publicArea); 82 if(result != TPM_RC_SUCCESS) 83 return RcSafeAddToResult(result, RC_Create_inPublic); 84 85 // Validate the sensitive area values 86 if( MemoryRemoveTrailingZeros(&in->inSensitive.t.sensitive.userAuth) 87 > CryptGetHashDigestSize(in->inPublic.t.publicArea.nameAlg)) 88 return TPM_RC_SIZE + RC_Create_inSensitive; 89 90 // Command Output 91 92 // Create object crypto data 93 result = CryptCreateObject(in->parentHandle, &in->inPublic.t.publicArea, 94 &in->inSensitive.t.sensitive, &sensitive); 95 if(result != TPM_RC_SUCCESS) 96 return result; 97 98 // Fill in creation data 99 FillInCreationData(in->parentHandle, in->inPublic.t.publicArea.nameAlg, 100 &in->creationPCR, &in->outsideInfo, 101 &out->creationData, &out->creationHash); 102 103 // Copy public area from input to output 104 out->outPublic.t.publicArea = in->inPublic.t.publicArea; 105 106 // Compute name from public area 107 ObjectComputeName(&(out->outPublic.t.publicArea), &name); 108 109 // Compute creation ticket 110 TicketComputeCreation(EntityGetHierarchy(in->parentHandle), &name, 111 &out->creationHash, &out->creationTicket); 112 113 // Prepare output private data from sensitive 114 SensitiveToPrivate(&sensitive, &name, in->parentHandle, 115 out->outPublic.t.publicArea.nameAlg, 116 &out->outPrivate); 117 118 return TPM_RC_SUCCESS; 119 } 120