blob: 7255aab57c10631c2fd4eed70895d4fa363f2888 [file] [log] [blame]
/* Microsoft Reference Implementation for TPM 2.0
*
* The copyright in this software is being made available under the BSD License,
* included below. This software may be subject to other third party and
* contributor rights, including patent rights, and no such rights are granted
* under this license.
*
* Copyright (c) Microsoft Corporation
*
* All rights reserved.
*
* BSD License
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Tpm.h"
#include "CreatePrimary_fp.h"
#ifdef TPM_CC_CreatePrimary // Conditional expansion of this file
/*(See part 3 specification)
// Creates a primary or temporary object from a primary seed.
*/
// return type: TPM_RC
// TPM_RC_ATTRIBUTES sensitiveDataOrigin is CLEAR when sensitive.data is an
// Empty Buffer 'fixedTPM', 'fixedParent', or
// 'encryptedDuplication' attributes are inconsistent
// between themselves or with those of the parent object;
// inconsistent 'restricted', 'decrypt' and 'sign'
// attributes
// attempt to inject sensitive data for an asymmetric key;
// TPM_RC_KDF incorrect KDF specified for decrypting keyed hash object
// TPM_RC_KEY a provided symmetric key value is not allowed
// TPM_RC_OBJECT_MEMORY there is no free slot for the object
// TPM_RC_SCHEME inconsistent attributes 'decrypt', 'sign', 'restricted'
// and key's scheme ID; or hash algorithm is inconsistent
// with the scheme ID for keyed hash object
// TPM_RC_SIZE size of public authorization policy or sensitive
// authorization value does not match digest size of the
// name algorithm; or sensitive data size for the keyed
// hash object is larger than is allowed for the scheme
// TPM_RC_SYMMETRIC a storage key with no symmetric algorithm specified; or
// non-storage key with symmetric algorithm different from
// TPM_ALG_NULL
// TPM_RC_TYPE unknown object type
TPM_RC
TPM2_CreatePrimary(
CreatePrimary_In *in, // IN: input parameter list
CreatePrimary_Out *out // OUT: output parameter list
)
{
// Local variables
TPM_RC result = TPM_RC_SUCCESS;
TPMT_PUBLIC *publicArea;
DRBG_STATE rand;
OBJECT *newObject;
TPM2B_NAME name;
// Input Validation
// Will need a place to put the result
newObject = FindEmptyObjectSlot(&out->objectHandle);
if(newObject == NULL)
return TPM_RC_OBJECT_MEMORY;
// Get the address of the public area in the new object
// (this is just to save typing)
publicArea = &newObject->publicArea;
*publicArea = in->inPublic.publicArea;
// Check attributes in input public area. CreateChecks() checks the things that
// are unique to creation and then validates the attributes and values that are
// common to create and load.
result = CreateChecks(NULL, publicArea,
in->inSensitive.sensitive.data.t.size);
if(result != TPM_RC_SUCCESS)
return RcSafeAddToResult(result, RC_CreatePrimary_inPublic);
// Validate the sensitive area values
if(!AdjustAuthSize(&in->inSensitive.sensitive.userAuth,
publicArea->nameAlg))
return TPM_RCS_SIZE + RC_CreatePrimary_inSensitive;
// Command output
// Compute the name using out->name as a scratch area (this is not the value
// that ultimately will be returned, then instantiate the state that will be
// used as a random number generator during the object creation.
// The caller does not know the seed values so the actual name does not have
// to be over the input, it can be over the unmarshaled structure.
DRBG_InstantiateSeeded(&rand,
&HierarchyGetPrimarySeed(in->primaryHandle)->b,
PRIMARY_OBJECT_CREATION,
(TPM2B *)PublicMarshalAndComputeName(publicArea, &name),
&in->inSensitive.sensitive.data.b);
newObject->attributes.primary = SET;
if(in->primaryHandle == TPM_RH_ENDORSEMENT)
newObject->attributes.epsHierarchy = SET;
// Create the primary object.
result = CryptCreateObject(newObject, &in->inSensitive.sensitive,
(RAND_STATE *)&rand);
if(result != TPM_RC_SUCCESS)
return result;
// Set the publicArea and name from the computed values
out->outPublic.publicArea = newObject->publicArea;
out->name = newObject->name;
// Fill in creation data
FillInCreationData(in->primaryHandle, publicArea->nameAlg,
&in->creationPCR, &in->outsideInfo, &out->creationData,
&out->creationHash);
// Compute creation ticket
TicketComputeCreation(EntityGetHierarchy(in->primaryHandle), &out->name,
&out->creationHash, &out->creationTicket);
// Set the remaining attributes for a loaded object
ObjectSetLoadedAttributes(newObject, in->primaryHandle);
return result;
}
#endif // CC_CreatePrimary