• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stefanberger / libtpms / #2001

10 Jun 2025 05:34PM UTC coverage: 76.734% (-0.5%) from 77.211%
#2001

push

travis-ci

web-flow
Merge 953b57ed4 into 9d6d76cc6

26 of 29 new or added lines in 2 files covered. (89.66%)

2807 existing lines in 74 files now uncovered.

33291 of 43385 relevant lines covered (76.73%)

61752.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.05
/src/tpm2/ObjectCommands.c
1
/********************************************************************************/
2
/*                                                                                */
3
/*                             Object Commands                                        */
4
/*                             Written by Ken Goldman                                */
5
/*                       IBM Thomas J. Watson Research Center                        */
6
/*            $Id: ObjectCommands.c 1259 2018-07-10 19:11:09Z kgoldman $        */
7
/*                                                                                */
8
/*  Licenses and Notices                                                        */
9
/*                                                                                */
10
/*  1. Copyright Licenses:                                                        */
11
/*                                                                                */
12
/*  - Trusted Computing Group (TCG) grants to the user of the source code in        */
13
/*    this specification (the "Source Code") a worldwide, irrevocable,                 */
14
/*    nonexclusive, royalty free, copyright license to reproduce, create         */
15
/*    derivative works, distribute, display and perform the Source Code and        */
16
/*    derivative works thereof, and to grant others the rights granted herein.        */
17
/*                                                                                */
18
/*  - The TCG grants to the user of the other parts of the specification         */
19
/*    (other than the Source Code) the rights to reproduce, distribute,         */
20
/*    display, and perform the specification solely for the purpose of                 */
21
/*    developing products based on such documents.                                */
22
/*                                                                                */
23
/*  2. Source Code Distribution Conditions:                                        */
24
/*                                                                                */
25
/*  - Redistributions of Source Code must retain the above copyright licenses,         */
26
/*    this list of conditions and the following disclaimers.                        */
27
/*                                                                                */
28
/*  - Redistributions in binary form must reproduce the above copyright         */
29
/*    licenses, this list of conditions        and the following disclaimers in the         */
30
/*    documentation and/or other materials provided with the distribution.        */
31
/*                                                                                */
32
/*  3. Disclaimers:                                                                */
33
/*                                                                                */
34
/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF        */
35
/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH        */
36
/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)        */
37
/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.                */
38
/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for                 */
39
/*  information on specification licensing rights available through TCG         */
40
/*  membership agreements.                                                        */
41
/*                                                                                */
42
/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED         */
43
/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR         */
44
/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR                 */
45
/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY                 */
46
/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.                */
47
/*                                                                                */
48
/*  - Without limitation, TCG and its members and licensors disclaim all         */
49
/*    liability, including liability for infringement of any proprietary         */
50
/*    rights, relating to use of information in this specification and to the        */
51
/*    implementation of this specification, and TCG disclaims all liability for        */
52
/*    cost of procurement of substitute goods or services, lost profits, loss         */
53
/*    of use, loss of data or any incidental, consequential, direct, indirect,         */
54
/*    or special damages, whether under contract, tort, warranty or otherwise,         */
55
/*    arising in any way out of use or reliance upon this specification or any         */
56
/*    information herein.                                                        */
57
/*                                                                                */
58
/*  (c) Copyright IBM Corp. and others, 2016 - 2018                                */
59
/*                                                                                */
60
/********************************************************************************/
61

62
#include "Tpm.h"
63
#include "Object_spt_fp.h"
64
#include "Create_fp.h"
65
#if CC_Create  // Conditional expansion of this file
66
TPM_RC
67
TPM2_Create(
255✔
68
            Create_In       *in,            // IN: input parameter list
69
            Create_Out      *out            // OUT: output parameter list
70
            )
71
{
72
    TPM_RC                   result = TPM_RC_SUCCESS;
255✔
73
    OBJECT                  *parentObject;
255✔
74
    OBJECT                  *newObject;
255✔
75
    TPMT_PUBLIC             *publicArea;
255✔
76
    // Input Validation
77
    parentObject = HandleToObject(in->parentHandle);
255✔
78
    pAssert(parentObject != NULL);
255✔
79
    // Does parent have the proper attributes?
80
    if(!ObjectIsParent(parentObject))
255✔
81
        return TPM_RCS_TYPE + RC_Create_parentHandle;
82
    // Get a slot for the creation
83
    newObject = FindEmptyObjectSlot(NULL);
255✔
84
    if(newObject == NULL)
255✔
85
        return TPM_RC_OBJECT_MEMORY;
86
    // If the TPM2B_PUBLIC was passed as a structure, marshal it into is canonical
87
    // form for processing
88
    // to save typing.
89
    publicArea = &newObject->publicArea;
255✔
90
    // Copy the input structure to the allocated structure
91
    *publicArea = in->inPublic.publicArea;
255✔
92
    // Check attributes in input public area. CreateChecks() checks the things that
93
    // are unique to creation and then validates the attributes and values that are
94
    // common to create and load.
95
    result = CreateChecks(parentObject, publicArea,
510✔
96
                          in->inSensitive.sensitive.data.t.size);
255✔
97
    if(result != TPM_RC_SUCCESS)
255✔
UNCOV
98
        return RcSafeAddToResult(result, RC_Create_inPublic);
×
99
    // Clean up the authValue if necessary
100
    if(!AdjustAuthSize(&in->inSensitive.sensitive.userAuth, publicArea->nameAlg))
255✔
101
        return TPM_RCS_SIZE + RC_Create_inSensitive;
102
    // Command Output
103
    // Create the object using the default TPM random-number generator
104
    result = CryptCreateObject(newObject, &in->inSensitive.sensitive, NULL);
255✔
105
    if(result != TPM_RC_SUCCESS)
255✔
106
        return result;
107
    // Fill in creation data
108
    FillInCreationData(in->parentHandle, publicArea->nameAlg,
255✔
109
                       &in->creationPCR, &in->outsideInfo,
110
                       &out->creationData, &out->creationHash);
111
    // Compute creation ticket
112
    TicketComputeCreation(EntityGetHierarchy(in->parentHandle), &newObject->name,
255✔
113
                          &out->creationHash, &out->creationTicket);
114
    // Prepare output private data from sensitive
115
    SensitiveToPrivate(&newObject->sensitive, &newObject->name.b, parentObject,
255✔
116
                       publicArea->nameAlg,
255✔
117
                       &out->outPrivate);
118
    // Finish by copying the remaining return values
119
    out->outPublic.publicArea = newObject->publicArea;
255✔
120
    return TPM_RC_SUCCESS;
255✔
121
}
122
#endif // CC_Create
123
#include "Tpm.h"
124
#include "Load_fp.h"
125
#if CC_Load  // Conditional expansion of this file
126
#include "Object_spt_fp.h"
127
TPM_RC
128
TPM2_Load(
366✔
129
          Load_In         *in,            // IN: input parameter list
130
          Load_Out        *out            // OUT: output parameter list
131
          )
132
{
133
    TPM_RC                   result = TPM_RC_SUCCESS;
366✔
134
    TPMT_SENSITIVE           sensitive;
366✔
135
    OBJECT                  *parentObject;
366✔
136
    OBJECT                  *newObject;
366✔
137
    // Input Validation
138
    // Don't get invested in loading if there is no place to put it.
139
    newObject = FindEmptyObjectSlot(&out->objectHandle);
366✔
140
    if(newObject == NULL)
366✔
141
        return TPM_RC_OBJECT_MEMORY;
142
    if(in->inPrivate.t.size == 0)
366✔
143
        return TPM_RCS_SIZE + RC_Load_inPrivate;
144
    parentObject = HandleToObject(in->parentHandle);
366✔
145
    pAssert(parentObject != NULL);
366✔
146
    // Is the object that is being used as the parent actually a parent.
147
    if(!ObjectIsParent(parentObject))
366✔
148
        return TPM_RCS_TYPE + RC_Load_parentHandle;
149
    // Compute the name of object. If there isn't one, it is because the nameAlg is
150
    // not valid.
151
    PublicMarshalAndComputeName(&in->inPublic.publicArea, &out->name);
366✔
152
    if(out->name.t.size == 0)
366✔
153
        return TPM_RCS_HASH + RC_Load_inPublic;
154
    // Retrieve sensitive data.
155
    result = PrivateToSensitive(&in->inPrivate.b, &out->name.b, parentObject,
732✔
156
                                in->inPublic.publicArea.nameAlg,
366✔
157
                                &sensitive);
158
    if(result != TPM_RC_SUCCESS)
366✔
159
        return RcSafeAddToResult(result, RC_Load_inPrivate);
3✔
160
    // Internal Data Update
161
    // Load and validate object
162
    result = ObjectLoad(newObject, parentObject,
363✔
163
                        &in->inPublic.publicArea, &sensitive,
164
                        RC_Load_inPublic, RC_Load_inPrivate,
165
                        &out->name);
166
    if(result == TPM_RC_SUCCESS)
363✔
167
        {
168
            // Set the common OBJECT attributes for a loaded object.
169
            ObjectSetLoadedAttributes(newObject, in->parentHandle);
363✔
170
        }
171
    return result;
172
}
173
#endif // CC_Load
174
#include "Tpm.h"
175
#include "LoadExternal_fp.h"
176
#if CC_LoadExternal  // Conditional expansion of this file
177
#include "Object_spt_fp.h"
178
TPM_RC
179
TPM2_LoadExternal(
533✔
180
                  LoadExternal_In     *in,            // IN: input parameter list
181
                  LoadExternal_Out    *out            // OUT: output parameter list
182
                  )
183
{
184
    TPM_RC               result;
533✔
185
    OBJECT              *object;
533✔
186
    TPMT_SENSITIVE      *sensitive = NULL;
533✔
187
    // Input Validation
188
    // Don't get invested in loading if there is no place to put it.
189
    object = FindEmptyObjectSlot(&out->objectHandle);
533✔
190
    if(object == NULL)
533✔
191
        return TPM_RC_OBJECT_MEMORY;
192
    // If the hierarchy to be associated with this object is turned off, the object
193
    // cannot be loaded.
194
    if(!HierarchyIsEnabled(in->hierarchy))
533✔
195
        return TPM_RCS_HIERARCHY + RC_LoadExternal_hierarchy;
196
    // For loading an object with both public and sensitive
197
    if(in->inPrivate.size != 0)
533✔
198
        {
199
            // An external object with a sensitive area can only be loaded in the
200
            // NULL hierarchy
201
            if(in->hierarchy != TPM_RH_NULL)
376✔
202
                return TPM_RCS_HIERARCHY + RC_LoadExternal_hierarchy;
203
            // An external object with a sensitive area must have fixedTPM == CLEAR
204
            // fixedParent == CLEAR so that it does not appear to be a key created by
205
            // this TPM.
206
            if(IS_ATTRIBUTE(in->inPublic.publicArea.objectAttributes, TPMA_OBJECT, fixedTPM)
372✔
207
               || IS_ATTRIBUTE(in->inPublic.publicArea.objectAttributes, TPMA_OBJECT,
208
                               fixedParent)
209
               || IS_ATTRIBUTE(in->inPublic.publicArea.objectAttributes, TPMA_OBJECT,
372✔
210
                               restricted))
211
                return TPM_RCS_ATTRIBUTES + RC_LoadExternal_inPublic;
212
            // Have sensitive point to something other than NULL so that object
213
            // initialization will load the sensitive part too
214
            sensitive = &in->inPrivate.sensitiveArea;
368✔
215
        }
216
    // Need the name to initialize the object structure
217
    PublicMarshalAndComputeName(&in->inPublic.publicArea, &out->name);
525✔
218
    // Load and validate key
219
    result = ObjectLoad(object, NULL,
525✔
220
                        &in->inPublic.publicArea, sensitive,
221
                        RC_LoadExternal_inPublic, RC_LoadExternal_inPrivate,
222
                        &out->name);
223
    if(result == TPM_RC_SUCCESS)
525✔
224
        {
225
            object->attributes.external = SET;
133✔
226
            // Set the common OBJECT attributes for a loaded object.
227
            ObjectSetLoadedAttributes(object, in->hierarchy);
133✔
228
        }
229
    return result;
230
}
231
#endif // CC_LoadExternal
232
#include "Tpm.h"
233
#include "ReadPublic_fp.h"
234
#if CC_ReadPublic  // Conditional expansion of this file
235
TPM_RC
236
TPM2_ReadPublic(
100✔
237
                ReadPublic_In   *in,            // IN: input parameter list
238
                ReadPublic_Out  *out            // OUT: output parameter list
239
                )
240
{
241
    OBJECT                  *object = HandleToObject(in->objectHandle);
100✔
242
    // Input Validation
243
    // Can not read public area of a sequence object
244
    if(ObjectIsSequence(object))
100✔
245
        return TPM_RC_SEQUENCE;
246
    // Command Output
247
    out->outPublic.publicArea = object->publicArea;
100✔
248
    out->name = object->name;
100✔
249
    out->qualifiedName = object->qualifiedName;
100✔
250
    return TPM_RC_SUCCESS;
100✔
251
}
252
#endif // CC_ReadPublic
253
#include "Tpm.h"
254
#include "ActivateCredential_fp.h"
255
#if CC_ActivateCredential  // Conditional expansion of this file
256
#include "Object_spt_fp.h"
257
TPM_RC
258
TPM2_ActivateCredential(
1✔
259
                        ActivateCredential_In   *in,            // IN: input parameter list
260
                        ActivateCredential_Out  *out            // OUT: output parameter list
261
                        )
262
{
263
    TPM_RC                   result = TPM_RC_SUCCESS;
1✔
264
    OBJECT                  *object;            // decrypt key
1✔
265
    OBJECT                  *activateObject;    // key associated with credential
1✔
266
    TPM2B_DATA               data;          // credential data
1✔
267
    // Input Validation
268
    // Get decrypt key pointer
269
    object = HandleToObject(in->keyHandle);
1✔
270
    // Get certificated object pointer
271
    activateObject = HandleToObject(in->activateHandle);
1✔
272
    // input decrypt key must be an asymmetric, restricted decryption key
273
    if(!CryptIsAsymAlgorithm(object->publicArea.type)
1✔
274
       || !IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, decrypt)
275
       || !IS_ATTRIBUTE(object->publicArea.objectAttributes,
1✔
276
                        TPMA_OBJECT, restricted))
277
        return TPM_RCS_TYPE + RC_ActivateCredential_keyHandle;
278
    // Command output
279
    // Decrypt input credential data via asymmetric decryption.  A
280
    // TPM_RC_VALUE, TPM_RC_KEY or unmarshal errors may be returned at this
281
    // point
282
    result = CryptSecretDecrypt(object, NULL, IDENTITY_STRING, &in->secret, &data);
1✔
283
    if(result != TPM_RC_SUCCESS)
1✔
284
        {
UNCOV
285
            if(result == TPM_RC_KEY)
×
286
                return TPM_RC_FAILURE;
UNCOV
287
            return RcSafeAddToResult(result, RC_ActivateCredential_secret);
×
288
        }
289
    // Retrieve secret data.  A TPM_RC_INTEGRITY error or unmarshal
290
    // errors may be returned at this point
291
    result = CredentialToSecret(&in->credentialBlob.b,
1✔
292
                                &activateObject->name.b,
293
                                &data.b,
294
                                object,
295
                                &out->certInfo);
296
    if(result != TPM_RC_SUCCESS)
1✔
UNCOV
297
        return RcSafeAddToResult(result, RC_ActivateCredential_credentialBlob);
×
298
    return TPM_RC_SUCCESS;
299
}
300
#endif // CC_ActivateCredential
301
#include "Tpm.h"
302
#include "MakeCredential_fp.h"
303
#if CC_MakeCredential  // Conditional expansion of this file
304
#include "Object_spt_fp.h"
305
TPM_RC
306
TPM2_MakeCredential(
1✔
307
                    MakeCredential_In   *in,            // IN: input parameter list
308
                    MakeCredential_Out  *out            // OUT: output parameter list
309
                    )
310
{
311
    TPM_RC               result = TPM_RC_SUCCESS;
1✔
312
    OBJECT              *object;
1✔
313
    TPM2B_DATA           data;
1✔
314
    // Input Validation
315
    // Get object pointer
316
    object = HandleToObject(in->handle);
1✔
317
    // input key must be an asymmetric, restricted decryption key
318
    // NOTE: Needs to be restricted to have a symmetric value.
319
    if(!CryptIsAsymAlgorithm(object->publicArea.type)
1✔
320
       || !IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, decrypt)
321
       || !IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, restricted))
1✔
322
        return TPM_RCS_TYPE + RC_MakeCredential_handle;
323
    // The credential information may not be larger than the digest size used for
324
    // the Name of the key associated with handle.
325
    if(in->credential.t.size > CryptHashGetDigestSize(object->publicArea.nameAlg))
1✔
326
        return TPM_RCS_SIZE + RC_MakeCredential_credential;
327
    // Command Output
328
    // Make encrypt key and its associated secret structure.
329
    out->secret.t.size = sizeof(out->secret.t.secret);
1✔
330
    result = CryptSecretEncrypt(object, IDENTITY_STRING, &data, &out->secret);
1✔
331
    if(result != TPM_RC_SUCCESS)
1✔
332
        return result;
333
    // Prepare output credential data from secret
334
    SecretToCredential(&in->credential, &in->objectName.b, &data.b,
1✔
335
                       object, &out->credentialBlob);
336
    return TPM_RC_SUCCESS;
1✔
337
}
338
#endif // CC_MakeCredential
339
#include "Tpm.h"
340
#include "Unseal_fp.h"
341
#if CC_Unseal  // Conditional expansion of this file
342
TPM_RC
343
TPM2_Unseal(
22✔
344
            Unseal_In           *in,
345
            Unseal_Out          *out
346
            )
347
{
348
    OBJECT                  *object;
22✔
349
    // Input Validation
350
    // Get pointer to loaded object
351
    object = HandleToObject(in->itemHandle);
22✔
352
    // Input handle must be a data object
353
    if(object->publicArea.type != TPM_ALG_KEYEDHASH)
22✔
354
        return TPM_RCS_TYPE + RC_Unseal_itemHandle;
355
    if(IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, decrypt)
22✔
356
       || IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, sign)
357
       || IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, restricted))
22✔
358
        return TPM_RCS_ATTRIBUTES + RC_Unseal_itemHandle;
359
    // Command Output
360
    // Copy data
361
    out->outData = object->sensitive.sensitive.bits;
22✔
362
    return TPM_RC_SUCCESS;
22✔
363
}
364
#endif // CC_Unseal
365
#include "Tpm.h"
366
#include "ObjectChangeAuth_fp.h"
367
#if CC_ObjectChangeAuth  // Conditional expansion of this file
368
#include "Object_spt_fp.h"
369
TPM_RC
370
TPM2_ObjectChangeAuth(
5✔
371
                      ObjectChangeAuth_In     *in,            // IN: input parameter list
372
                      ObjectChangeAuth_Out    *out            // OUT: output parameter list
373
                      )
374
{
375
    TPMT_SENSITIVE           sensitive;
5✔
376
    OBJECT                  *object = HandleToObject(in->objectHandle);
5✔
377
    TPM2B_NAME               QNCompare;
5✔
378
    // Input Validation
379
    // Can not change authorization on sequence object
380
    if(ObjectIsSequence(object))
5✔
381
        return TPM_RCS_TYPE + RC_ObjectChangeAuth_objectHandle;
382
    // Make sure that the authorization value is consistent with the nameAlg
383
    if(!AdjustAuthSize(&in->newAuth, object->publicArea.nameAlg))
5✔
384
        return TPM_RCS_SIZE + RC_ObjectChangeAuth_newAuth;
385
    // Parent handle should be the parent of object handle.  In this
386
    // implementation we verify this by checking the QN of object.  Other
387
    // implementation may choose different method to verify this attribute.
388
    ComputeQualifiedName(in->parentHandle,
5✔
389
                         object->publicArea.nameAlg,
5✔
390
                         &object->name, &QNCompare);
391
    if(!MemoryEqual2B(&object->qualifiedName.b, &QNCompare.b))
5✔
392
        return TPM_RCS_TYPE + RC_ObjectChangeAuth_parentHandle;
393
    // Command Output
394
    // Prepare the sensitive area with the new authorization value
395
    sensitive = object->sensitive;
5✔
396
    sensitive.authValue = in->newAuth;
5✔
397
    // Protect the sensitive area
398
    SensitiveToPrivate(&sensitive, &object->name.b, HandleToObject(in->parentHandle),
10✔
399
                       object->publicArea.nameAlg,
5✔
400
                       &out->outPrivate);
401
    return TPM_RC_SUCCESS;
5✔
402
}
403
#endif // CC_ObjectChangeAuth
404
#include "Tpm.h"
405
#include "CreateLoaded_fp.h"
406
#if CC_CreateLoaded  // Conditional expansion of this file
407
TPM_RC
408
TPM2_CreateLoaded(
43✔
409
                  CreateLoaded_In    *in,            // IN: input parameter list
410
                  CreateLoaded_Out   *out            // OUT: output parameter list
411
                  )
412
{
413
    TPM_RC                       result = TPM_RC_SUCCESS;
43✔
414
    OBJECT                      *parent = HandleToObject(in->parentHandle);
43✔
415
    OBJECT                      *newObject;
43✔
416
    BOOL                         derivation;
43✔
417
    TPMT_PUBLIC                 *publicArea;
43✔
418
    RAND_STATE                   randState;
43✔
419
    RAND_STATE                  *rand = &randState;
43✔
420
    TPMS_DERIVE                  labelContext;
43✔
421
    // Input Validation
422
    // How the public area is unmarshaled is determined by the parent, so
423
    // see if parent is a derivation parent
424
    derivation = (parent != NULL && parent->attributes.derivation);
43✔
425
    // If the parent is an object, then make sure that it is either a parent or
426
    // derivation parent
427
    if(parent != NULL && !parent->attributes.isParent && !derivation)
43✔
428
        return TPM_RCS_TYPE + RC_CreateLoaded_parentHandle;
429
    // Get a spot in which to create the newObject
430
    newObject = FindEmptyObjectSlot(&out->objectHandle);
43✔
431
    if(newObject == NULL)
43✔
432
        return TPM_RC_OBJECT_MEMORY;
433
    // Do this to save typing
434
    publicArea = &newObject->publicArea;
43✔
435
    // Unmarshal the template into the object space. TPM2_Create() and
436
    // TPM2_CreatePrimary() have the publicArea unmarshaled by CommandDispatcher.
437
    // This command is different because of an unfortunate property of the
438
    // unique field of an ECC key. It is a structure rather than a single TPM2B. If
439
    // if had been a TPM2B, then the label and context could be within a TPM2B and
440
    // unmarshaled like other public areas. Since it is not, this command needs its
441
    // on template that is a TPM2B that is unmarshaled as a BYTE array with a
442
    // its own unmarshal function.
443
    result = UnmarshalToPublic(publicArea, &in->inPublic, derivation,
43✔
444
                               &labelContext);
445
    if(result != TPM_RC_SUCCESS)
43✔
UNCOV
446
        return result + RC_CreateLoaded_inPublic;
×
447
    // Validate that the authorization size is appropriate
448
    if(!AdjustAuthSize(&in->inSensitive.sensitive.userAuth, publicArea->nameAlg))
43✔
449
        return TPM_RCS_SIZE + RC_CreateLoaded_inSensitive;
450
    // Command output
451
    if(derivation)
43✔
452
        {
453
            TPMT_KEYEDHASH_SCHEME       *scheme;
10✔
454
            scheme = &parent->publicArea.parameters.keyedHashDetail.scheme;
10✔
455
            // SP800-108 is the only KDF supported by this implementation and there is
456
            // no default hash algorithm.
457
            pAssert(scheme->details.xorr.hashAlg != TPM_ALG_NULL
10✔
458
                    && scheme->details.xorr.kdf == TPM_ALG_KDF1_SP800_108);
10✔
459
            // Don't derive RSA keys
460
            if(publicArea->type == ALG_RSA_VALUE)
10✔
461
                return TPM_RCS_TYPE + RC_CreateLoaded_inPublic;
462
            // sensitiveDataOrigin has to be CLEAR in a derived object. Since this
463
            // is specific to a derived object, it is checked here.
464
            if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT,
10✔
465
                            sensitiveDataOrigin))
466
                return TPM_RCS_ATTRIBUTES;
467
            // Check the reset of the attributes
468
            result = PublicAttributesValidation(parent, publicArea);
10✔
469
            if(result != TPM_RC_SUCCESS)
10✔
UNCOV
470
                return RcSafeAddToResult(result, RC_CreateLoaded_inPublic);
×
471
            // Process the template and sensitive areas to get the actual 'label' and
472
            // 'context' values to be used for this derivation.
473
            result = SetLabelAndContext(&labelContext, &in->inSensitive.sensitive.data);
10✔
474
            if(result != TPM_RC_SUCCESS)
10✔
475
                return result;
476
            // Set up the KDF for object generation
477
            DRBG_InstantiateSeededKdf((KDF_STATE *)rand,
10✔
478
                                      scheme->details.xorr.hashAlg,
10✔
479
                                      scheme->details.xorr.kdf,
10✔
480
                                      &parent->sensitive.sensitive.bits.b,
481
                                      &labelContext.label.b,
482
                                      &labelContext.context.b,
483
                                      TPM_MAX_DERIVATION_BITS);
484
            // Clear the sensitive size so that the creation functions will not try
485
            // to use this value.
486
            in->inSensitive.sensitive.data.t.size = 0;
10✔
487
        }
488
    else
489
        {
490
            // Check attributes in input public area. CreateChecks() checks the things
491
            // that are unique to creation and then validates the attributes and values
492
            // that are common to create and load.
493
            result = CreateChecks(parent, publicArea,
66✔
494
                                  in->inSensitive.sensitive.data.t.size);
33✔
495
            if(result != TPM_RC_SUCCESS)
33✔
UNCOV
496
                return RcSafeAddToResult(result, RC_CreateLoaded_inPublic);
×
497
            // Creating a primary object
498
            if(parent == NULL)
33✔
499
                {
500
                    TPM2B_NAME              name;
31✔
501
                    newObject->attributes.primary = SET;
31✔
502
                    if(in->parentHandle == TPM_RH_ENDORSEMENT)
31✔
503
                        newObject->attributes.epsHierarchy = SET;
10✔
504
                    // If so, use the primary seed and the digest of the template
505
                    // to seed the DRBG
506
                    DRBG_InstantiateSeeded((DRBG_STATE *)rand,
93✔
507
                                           &HierarchyGetPrimarySeed(in->parentHandle)->b,
31✔
508
                                           PRIMARY_OBJECT_CREATION,
509
                                           (TPM2B *)PublicMarshalAndComputeName(publicArea,
31✔
510
                                                                                &name),
511
                                           &in->inSensitive.sensitive.data.b);
31✔
512
                }
513
            else
514
                // This is an ordinary object so use the normal random number generator
515
                rand = NULL;
516
        }
517
    // Internal data update
518
    // Create the object
519
    result = CryptCreateObject(newObject, &in->inSensitive.sensitive, rand);
43✔
520
    if(result != TPM_RC_SUCCESS)
43✔
521
        return result;
522
    // if this is not a Primary key and not a derived key, then return the sensitive
523
    // area
524
    if(parent != NULL && !derivation)
43✔
525
        // Prepare output private data from sensitive
526
        SensitiveToPrivate(&newObject->sensitive, &newObject->name.b,
2✔
527
                           parent, newObject->publicArea.nameAlg,
2✔
528
                           &out->outPrivate);
529
    else
530
        out->outPrivate.t.size = 0;
41✔
531
    // Set the remaining return values
532
    out->outPublic.publicArea = newObject->publicArea;
43✔
533
    out->name = newObject->name;
43✔
534
    // Set the remaining attributes for a loaded object
535
    ObjectSetLoadedAttributes(newObject, in->parentHandle);
43✔
536
    return result;
43✔
537
}
538
#endif // CC_CreateLoaded
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc