blob: 3a0233ad5f43568ae619c279246fe412d132b2ac [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// 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//
50TPM_RC
51TPM2_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}