Home | History | Annotate | Download | only in tpm2
      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