1 /* Microsoft Reference Implementation for TPM 2.0
2 *
3 * The copyright in this software is being made available under the BSD License,
4 * included below. This software may be subject to other third party and
5 * contributor rights, including patent rights, and no such rights are granted
6 * under this license.
7 *
8 * Copyright (c) Microsoft Corporation
9 *
10 * All rights reserved.
11 *
12 * BSD License
13 *
14 * Redistribution and use in source and binary forms, with or without modification,
15 * are permitted provided that the following conditions are met:
16 *
17 * Redistributions of source code must retain the above copyright notice, this list
18 * of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright notice, this
21 * list of conditions and the following disclaimer in the documentation and/or
22 * other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 #include "Tpm.h"
36 #include "Object_spt_fp.h"
37 #include "Create_fp.h"
38
39 #if CC_Create // Conditional expansion of this file
40
41 /*(See part 3 specification)
42 // Create a regular object
43 */
44 // Return Type: TPM_RC
45 // TPM_RC_ATTRIBUTES 'sensitiveDataOrigin' is CLEAR when 'sensitive.data'
46 // is an Empty Buffer, or is SET when 'sensitive.data' is
47 // not empty;
48 // 'fixedTPM', 'fixedParent', or 'encryptedDuplication'
49 // attributes are inconsistent between themselves or with
50 // those of the parent object;
51 // inconsistent 'restricted', 'decrypt' and 'sign'
52 // attributes;
53 // attempt to inject sensitive data for an asymmetric
54 // key;
55 // TPM_RC_HASH non-duplicable storage key and its parent have
56 // different name algorithm
57 // TPM_RC_KDF incorrect KDF specified for decrypting keyed hash
58 // object
59 // TPM_RC_KEY invalid key size values in an asymmetric key public
60 // area or a provided symmetric key has a value that is
61 // not allowed
62 // TPM_RC_KEY_SIZE key size in public area for symmetric key differs from
63 // the size in the sensitive creation area; may also be
64 // returned if the TPM does not allow the key size to be
65 // used for a Storage Key
66 // TPM_RC_OBJECT_MEMORY a free slot is not available as scratch memory for
67 // object creation
68 // TPM_RC_RANGE the exponent value of an RSA key is not supported.
69 // TPM_RC_SCHEME inconsistent attributes 'decrypt', 'sign', or
70 // 'restricted' and key's scheme ID; or hash algorithm is
71 // inconsistent with the scheme ID for keyed hash object
72 // TPM_RC_SIZE size of public authPolicy or sensitive authValue does
73 // not match digest size of the name algorithm
74 // sensitive data size for the keyed hash object is
75 // larger than is allowed for the scheme
76 // TPM_RC_SYMMETRIC a storage key with no symmetric algorithm specified;
77 // or non-storage key with symmetric algorithm different
78 // from ALG_NULL
79 // TPM_RC_TYPE unknown object type;
80 // 'parentHandle' does not reference a restricted
81 // decryption key in the storage hierarchy with both
82 // public and sensitive portion loaded
83 // TPM_RC_VALUE exponent is not prime or could not find a prime using
84 // the provided parameters for an RSA key;
85 // unsupported name algorithm for an ECC key
86 // TPM_RC_OBJECT_MEMORY there is no free slot for the object
87 TPM_RC
TPM2_Create(Create_In * in,Create_Out * out)88 TPM2_Create(
89 Create_In *in, // IN: input parameter list
90 Create_Out *out // OUT: output parameter list
91 )
92 {
93 TPM_RC result = TPM_RC_SUCCESS;
94 OBJECT *parentObject;
95 OBJECT *newObject;
96 TPMT_PUBLIC *publicArea;
97
98 // Input Validation
99 parentObject = HandleToObject(in->parentHandle);
100 pAssert(parentObject != NULL);
101
102 // Does parent have the proper attributes?
103 if(!ObjectIsParent(parentObject))
104 return TPM_RCS_TYPE + RC_Create_parentHandle;
105
106 // Get a slot for the creation
107 newObject = FindEmptyObjectSlot(NULL);
108 if(newObject == NULL)
109 return TPM_RC_OBJECT_MEMORY;
110 // If the TPM2B_PUBLIC was passed as a structure, marshal it into is canonical
111 // form for processing
112
113 // to save typing.
114 publicArea = &newObject->publicArea;
115
116 // Copy the input structure to the allocated structure
117 *publicArea = in->inPublic.publicArea;
118
119 // Check attributes in input public area. CreateChecks() checks the things that
120 // are unique to creation and then validates the attributes and values that are
121 // common to create and load.
122 result = CreateChecks(parentObject, publicArea,
123 in->inSensitive.sensitive.data.t.size);
124 if(result != TPM_RC_SUCCESS)
125 return RcSafeAddToResult(result, RC_Create_inPublic);
126 // Clean up the authValue if necessary
127 if(!AdjustAuthSize(&in->inSensitive.sensitive.userAuth, publicArea->nameAlg))
128 return TPM_RCS_SIZE + RC_Create_inSensitive;
129
130 // Command Output
131 // Create the object using the default TPM random-number generator
132 result = CryptCreateObject(newObject, &in->inSensitive.sensitive, NULL);
133 if(result != TPM_RC_SUCCESS)
134 return result;
135 // Fill in creation data
136 FillInCreationData(in->parentHandle, publicArea->nameAlg,
137 &in->creationPCR, &in->outsideInfo,
138 &out->creationData, &out->creationHash);
139
140 // Compute creation ticket
141 TicketComputeCreation(EntityGetHierarchy(in->parentHandle), &newObject->name,
142 &out->creationHash, &out->creationTicket);
143
144 // Prepare output private data from sensitive
145 SensitiveToPrivate(&newObject->sensitive, &newObject->name, parentObject,
146 publicArea->nameAlg,
147 &out->outPrivate);
148
149 // Finish by copying the remaining return values
150 out->outPublic.publicArea = newObject->publicArea;
151
152 return TPM_RC_SUCCESS;
153 }
154
155 #endif // CC_Create