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 "LoadExternal_fp.h"
10 #include "Object_spt_fp.h"
11 //
12 //
13 //     Error Returns                     Meaning
14 //
15 //     TPM_RC_ATTRIBUTES                 'fixedParent" and fixedTPM must be CLEAR on on an external key if
16 //                                       both public and sensitive portions are loaded
17 //     TPM_RC_BINDING                    the inPublic and inPrivate structures are not cryptographically bound.
18 //     TPM_RC_HASH                       incorrect hash selection for signing key
19 //     TPM_RC_HIERARCHY                  hierarchy is turned off, or only NULL hierarchy is allowed when
20 //                                       loading public and private parts of an object
21 //     TPM_RC_KDF                        incorrect KDF selection for decrypting keyedHash object
22 //     TPM_RC_KEY                        the size of the object's unique field is not consistent with the indicated
23 //                                       size in the object's parameters
24 //     TPM_RC_OBJECT_MEMORY              if there is no free slot for an object
25 //     TPM_RC_SCHEME                     the signing scheme is not valid for the key
26 //     TPM_RC_SIZE                       authPolicy is not zero and is not the size of a digest produced by the
27 //                                       object's nameAlg TPM_RH_NULL hierarchy
28 //     TPM_RC_SYMMETRIC                  symmetric algorithm not provided when required
29 //     TPM_RC_TYPE                       inPublic and inPrivate are not the same type
30 //
31 TPM_RC
TPM2_LoadExternal(LoadExternal_In * in,LoadExternal_Out * out)32 TPM2_LoadExternal(
33    LoadExternal_In       *in,                   // IN: input parameter list
34    LoadExternal_Out      *out                   // OUT: output parameter list
35    )
36 {
37    TPM_RC                 result;
38    TPMT_SENSITIVE        *sensitive;
39    BOOL                   skipChecks;
40 
41 // Input Validation
42 
43    // If the target hierarchy is turned off, the object can not be loaded.
44    if(!HierarchyIsEnabled(in->hierarchy))
45        return TPM_RC_HIERARCHY + RC_LoadExternal_hierarchy;
46 
47    // the size of authPolicy is either 0 or the digest size of nameAlg
48    if(in->inPublic.t.publicArea.authPolicy.t.size != 0
49            && in->inPublic.t.publicArea.authPolicy.t.size !=
50            CryptGetHashDigestSize(in->inPublic.t.publicArea.nameAlg))
51        return TPM_RC_SIZE + RC_LoadExternal_inPublic;
52 
53    // For loading an object with both public and sensitive
54    if(in->inPrivate.t.size != 0)
55    {
56        // An external object can only be loaded at TPM_RH_NULL hierarchy
57        if(in->hierarchy != TPM_RH_NULL)
58            return TPM_RC_HIERARCHY + RC_LoadExternal_hierarchy;
59        // An external object with a sensitive area must have fixedTPM == CLEAR
60        // fixedParent == CLEAR, and must have restrict CLEAR so that it does not
61        // appear to be a key that was created by this TPM.
62          if(   in->inPublic.t.publicArea.objectAttributes.fixedTPM != CLEAR
63             || in->inPublic.t.publicArea.objectAttributes.fixedParent != CLEAR
64             || in->inPublic.t.publicArea.objectAttributes.restricted != CLEAR
65            )
66              return TPM_RC_ATTRIBUTES + RC_LoadExternal_inPublic;
67    }
68 
69    // Validate the scheme parameters
70    result = SchemeChecks(TRUE, TPM_RH_NULL, &in->inPublic.t.publicArea);
71    if(result != TPM_RC_SUCCESS)
72            return RcSafeAddToResult(result, RC_LoadExternal_inPublic);
73 
74 // Internal Data Update
75    // Need the name to compute the qualified name
76    ObjectComputeName(&in->inPublic.t.publicArea, &out->name);
77    skipChecks = (in->inPublic.t.publicArea.nameAlg == TPM_ALG_NULL);
78 
79    // If a sensitive area was provided, load it
80    if(in->inPrivate.t.size != 0)
81        sensitive = &in->inPrivate.t.sensitiveArea;
82    else
83        sensitive = NULL;
84 
85    // Create external object. A TPM_RC_BINDING, TPM_RC_KEY, TPM_RC_OBJECT_MEMORY
86    // or TPM_RC_TYPE error may be returned by ObjectLoad()
87    result = ObjectLoad(in->hierarchy, &in->inPublic.t.publicArea,
88                        sensitive, &out->name, TPM_RH_NULL, skipChecks,
89                        &out->objectHandle);
90    return result;
91 }
92