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 "CreatePrimary_fp.h"
10 #include "Object_spt_fp.h"
11 #include "Platform.h"
12 //
13 //
14 //     Error Returns                  Meaning
15 //
16 //     TPM_RC_ATTRIBUTES              sensitiveDataOrigin is CLEAR when 'sensitive.data' is an Empty
17 //                                    Buffer, or is SET when 'sensitive.data' is not empty; fixedTPM,
18 //                                    fixedParent, or encryptedDuplication attributes are inconsistent
19 //                                    between themselves or with those of the parent object; inconsistent
20 //                                    restricted, decrypt and sign attributes; attempt to inject sensitive data
21 //                                    for an asymmetric key; attempt to create a symmetric cipher key that
22 //                                    is not a decryption key
23 //     TPM_RC_KDF                     incorrect KDF specified for decrypting keyed hash object
24 //     TPM_RC_OBJECT_MEMORY           there is no free slot for the object
25 //     TPM_RC_SCHEME                  inconsistent attributes decrypt, sign, restricted and key's scheme ID;
26 //                                    or hash algorithm is inconsistent with the scheme ID for keyed hash
27 //                                    object
28 //     TPM_RC_SIZE                    size of public auth policy or sensitive auth value does not match
29 //                                    digest size of the name algorithm sensitive data size for the keyed
30 //                                    hash object is larger than is allowed for the scheme
31 //     TPM_RC_SYMMETRIC               a storage key with no symmetric algorithm specified; or non-storage
32 //                                    key with symmetric algorithm different from TPM_ALG_NULL
33 //     TPM_RC_TYPE                    unknown object type;
34 //
35 TPM_RC
TPM2_CreatePrimary(CreatePrimary_In * in,CreatePrimary_Out * out)36 TPM2_CreatePrimary(
37    CreatePrimary_In    *in,                  // IN: input parameter list
38    CreatePrimary_Out   *out                  // OUT: output parameter list
39    )
40 {
41 // Local variables
42    TPM_RC              result = TPM_RC_SUCCESS;
43    TPMT_SENSITIVE      sensitive;
44 
45 // Input Validation
46    // The sensitiveDataOrigin attribute must be consistent with the setting of
47    // the size of the data object in inSensitive.
48    if(   (in->inPublic.t.publicArea.objectAttributes.sensitiveDataOrigin == SET)
49       != (in->inSensitive.t.sensitive.data.t.size == 0 ))
50        // Mismatch between the object attributes and the parameter.
51        return TPM_RC_ATTRIBUTES + RC_CreatePrimary_inSensitive;
52 
53    // Check attributes in input public area. TPM_RC_ATTRIBUTES, TPM_RC_KDF,
54    // TPM_RC_SCHEME, TPM_RC_SIZE, TPM_RC_SYMMETRIC, or TPM_RC_TYPE error may
55    // be returned at this point.
56    result = PublicAttributesValidation(FALSE, in->primaryHandle,
57                                        &in->inPublic.t.publicArea);
58    if(result != TPM_RC_SUCCESS)
59        return RcSafeAddToResult(result, RC_CreatePrimary_inPublic);
60 
61    // Validate the sensitive area values
62    if( MemoryRemoveTrailingZeros(&in->inSensitive.t.sensitive.userAuth)
63            > CryptGetHashDigestSize(in->inPublic.t.publicArea.nameAlg))
64 //
65        return TPM_RC_SIZE + RC_CreatePrimary_inSensitive;
66 
67 // Command output
68 
69    // Generate Primary Object
70    // The primary key generation process uses the Name of the input public
71    // template to compute the key. The keys are generated from the template
72    // before anything in the template is allowed to be changed.
73    // A TPM_RC_KDF, TPM_RC_SIZE error may be returned at this point
74    result = CryptCreateObject(in->primaryHandle, &in->inPublic.t.publicArea,
75                               &in->inSensitive.t.sensitive,&sensitive);
76    if(result != TPM_RC_SUCCESS)
77        return result;
78 
79    // Fill in creation data
80    FillInCreationData(in->primaryHandle, in->inPublic.t.publicArea.nameAlg,
81                       &in->creationPCR, &in->outsideInfo, &out->creationData,
82                       &out->creationHash);
83 
84    // Copy public area
85    out->outPublic = in->inPublic;
86 
87    // Fill in private area for output
88    ObjectComputeName(&(out->outPublic.t.publicArea), &out->name);
89 
90    // Compute creation ticket
91    TicketComputeCreation(EntityGetHierarchy(in->primaryHandle), &out->name,
92                          &out->creationHash, &out->creationTicket);
93 
94    // Create a internal object. A TPM_RC_OBJECT_MEMORY error may be returned
95    // at this point.
96    result = ObjectLoad(in->primaryHandle, &in->inPublic.t.publicArea, &sensitive,
97                        &out->name, in->primaryHandle, TRUE, &out->objectHandle);
98 
99    return result;
100 }
101