Coverage Report

Created: 2025-10-12 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tpm2/Import.c
Line
Count
Source
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 "Import_fp.h"
10
#include "Object_spt_fp.h"
11
//
12
//
13
//    Error Returns                     Meaning
14
//
15
//    TPM_RC_ASYMMETRIC                 non-duplicable storage key represented by objectPublic and its
16
//                                      parent referenced by parentHandle have different public parameters
17
//    TPM_RC_ATTRIBUTES                 attributes FixedTPM and fixedParent of objectPublic are not both
18
//                                      CLEAR; or inSymSeed is nonempty and parentHandle does not
19
//                                      reference a decryption key; or objectPublic and parentHandle have
20
//                                      incompatible or inconsistent attributes; or encrytpedDuplication is
21
//                                      SET in objectPublic but the inner or outer wrapper is missing.
22
//
23
//    NOTE:           if the TPM provides parameter values, the parameter number will indicate symmetricKey (missing
24
//                    inner wrapper) or inSymSeed (missing outer wrapper).
25
//
26
//
27
//    TPM_RC_BINDING                    duplicate and objectPublic are not cryptographically
28
//                                      bound
29
//
30
//    TPM_RC_ECC_POINT                  inSymSeed is nonempty and ECC point in inSymSeed is not on the
31
//                                      curve
32
//    TPM_RC_HASH                       non-duplicable storage key represented by objectPublic and its
33
//                                      parent referenced by parentHandle have different name algorithm
34
//    TPM_RC_INSUFFICIENT               inSymSeed is nonempty and failed to retrieve ECC point from the
35
//                                      secret; or unmarshaling sensitive value from duplicate failed the
36
//                                      result of inSymSeed decryption
37
//    TPM_RC_INTEGRITY                  duplicate integrity is broken
38
//    TPM_RC_KDF                        objectPublic representing decrypting keyed hash object specifies
39
//                                      invalid KDF
40
//    TPM_RC_KEY                        inconsistent parameters of objectPublic; or inSymSeed is nonempty
41
//                                      and parentHandle does not reference a key of supported type; or
42
//                                      invalid key size in objectPublic representing an asymmetric key
43
//    TPM_RC_NO_RESULT                  inSymSeed is nonempty and multiplication resulted in ECC point at
44
//                                      infinity
45
//    TPM_RC_OBJECT_MEMORY              no available object slot
46
//    TPM_RC_SCHEME                     inconsistent attributes decrypt, sign, restricted and key's scheme ID
47
//                                      in objectPublic; or hash algorithm is inconsistent with the scheme ID
48
//                                      for keyed hash object
49
//    TPM_RC_SIZE                       authPolicy size does not match digest size of the name algorithm in
50
//                                      objectPublic; or symmetricAlg and encryptionKey have different
51
//                                      sizes; or inSymSeed is nonempty and it size is not consistent with the
52
//                                      type of parentHandle; or unmarshaling sensitive value from duplicate
53
//                                      failed
54
//    TPM_RC_SYMMETRIC                  objectPublic is either a storage key with no symmetric algorithm or a
55
//                                      non-storage key with symmetric algorithm different from
56
//                                      TPM_ALG_NULL
57
//    TPM_RC_TYPE                       unsupported type of objectPublic; or non-duplicable storage key
58
//                                      represented by objectPublic and its parent referenced by
59
//                                      parentHandle are of different types; or parentHandle is not a storage
60
//                                      key; or only the public portion of parentHandle is loaded; or
61
//                                  objectPublic and duplicate are of different types
62
//     TPM_RC_VALUE                 nonempty inSymSeed and its numeric value is greater than the
63
//                                  modulus of the key referenced by parentHandle or inSymSeed is
64
//                                  larger than the size of the digest produced by the name algorithm of
65
//                                  the symmetric key referenced by parentHandle
66
//
67
TPM_RC
68
TPM2_Import(
69
   Import_In         *in,            // IN: input parameter list
70
   Import_Out        *out            // OUT: output parameter list
71
   )
72
0
{
73
74
0
   TPM_RC                   result = TPM_RC_SUCCESS;
75
0
   OBJECT                   *parentObject;
76
0
   TPM2B_DATA               data;                   // symmetric key
77
0
   TPMT_SENSITIVE           sensitive;
78
0
   TPM2B_NAME               name;
79
80
0
   UINT16                   innerKeySize = 0;             // encrypt key size for inner
81
                                                          // wrapper
82
83
// Input Validation
84
85
   // FixedTPM and fixedParent must be CLEAR
86
0
   if(   in->objectPublic.t.publicArea.objectAttributes.fixedTPM == SET
87
0
      || in->objectPublic.t.publicArea.objectAttributes.fixedParent == SET)
88
0
       return TPM_RC_ATTRIBUTES + RC_Import_objectPublic;
89
90
   // Get parent pointer
91
0
   parentObject = ObjectGet(in->parentHandle);
92
93
0
   if(!AreAttributesForParent(parentObject))
94
0
       return TPM_RC_TYPE + RC_Import_parentHandle;
95
96
0
   if(in->symmetricAlg.algorithm != TPM_ALG_NULL)
97
0
   {
98
       // Get inner wrap key size
99
0
       innerKeySize = in->symmetricAlg.keyBits.sym;
100
       // Input symmetric key must match the size of algorithm.
101
0
       if(in->encryptionKey.t.size != (innerKeySize + 7) / 8)
102
0
           return TPM_RC_SIZE + RC_Import_encryptionKey;
103
0
   }
104
0
   else
105
0
   {
106
       // If input symmetric algorithm is NULL, input symmetric key size must
107
       // be 0 as well
108
0
       if(in->encryptionKey.t.size != 0)
109
0
           return TPM_RC_SIZE + RC_Import_encryptionKey;
110
       // If encryptedDuplication is SET, then the object must have an inner
111
       // wrapper
112
0
       if(in->objectPublic.t.publicArea.objectAttributes.encryptedDuplication)
113
0
           return TPM_RC_ATTRIBUTES + RC_Import_encryptionKey;
114
0
   }
115
116
   // See if there is an outer wrapper
117
0
   if(in->inSymSeed.t.size != 0)
118
0
   {
119
       // Decrypt input secret data via asymmetric decryption. TPM_RC_ATTRIBUTES,
120
       // TPM_RC_ECC_POINT, TPM_RC_INSUFFICIENT, TPM_RC_KEY, TPM_RC_NO_RESULT,
121
       // TPM_RC_SIZE, TPM_RC_VALUE may be returned at this point
122
0
       result = CryptSecretDecrypt(in->parentHandle, NULL, "DUPLICATE",
123
0
                                   &in->inSymSeed, &data);
124
0
       pAssert(result != TPM_RC_BINDING);
125
//
126
0
       if(result != TPM_RC_SUCCESS)
127
0
           return RcSafeAddToResult(result, RC_Import_inSymSeed);
128
0
   }
129
0
   else
130
0
   {
131
       // If encrytpedDuplication is set, then the object must have an outer
132
       // wrapper
133
0
       if(in->objectPublic.t.publicArea.objectAttributes.encryptedDuplication)
134
0
           return TPM_RC_ATTRIBUTES + RC_Import_inSymSeed;
135
0
       data.t.size = 0;
136
0
   }
137
138
   // Compute name of object
139
0
   ObjectComputeName(&(in->objectPublic.t.publicArea), &name);
140
141
   // Retrieve sensitive from private.
142
   // TPM_RC_INSUFFICIENT, TPM_RC_INTEGRITY, TPM_RC_SIZE may be returned here.
143
0
   result = DuplicateToSensitive(&in->duplicate, &name, in->parentHandle,
144
0
                                 in->objectPublic.t.publicArea.nameAlg,
145
0
                                 (TPM2B_SEED *) &data, &in->symmetricAlg,
146
0
                                 &in->encryptionKey, &sensitive);
147
0
   if(result != TPM_RC_SUCCESS)
148
0
       return RcSafeAddToResult(result, RC_Import_duplicate);
149
150
   // If the parent of this object has fixedTPM SET, then fully validate this
151
   // object so that validation can be skipped when it is loaded
152
0
   if(parentObject->publicArea.objectAttributes.fixedTPM == SET)
153
0
   {
154
0
       TPM_HANDLE       objectHandle;
155
156
       // Perform self check on input public area. A TPM_RC_SIZE, TPM_RC_SCHEME,
157
       // TPM_RC_VALUE, TPM_RC_SYMMETRIC, TPM_RC_TYPE, TPM_RC_HASH,
158
       // TPM_RC_ASYMMETRIC, TPM_RC_ATTRIBUTES or TPM_RC_KDF error may be returned
159
       // at this point
160
0
       result = PublicAttributesValidation(TRUE, in->parentHandle,
161
0
                                           &in->objectPublic.t.publicArea);
162
0
       if(result != TPM_RC_SUCCESS)
163
0
           return RcSafeAddToResult(result, RC_Import_objectPublic);
164
165
       // Create internal object. A TPM_RC_KEY_SIZE, TPM_RC_KEY or
166
       // TPM_RC_OBJECT_MEMORY error may be returned at this point
167
0
       result = ObjectLoad(TPM_RH_NULL, &in->objectPublic.t.publicArea,
168
0
                           &sensitive, NULL, in->parentHandle, FALSE,
169
0
                           &objectHandle);
170
0
       if(result != TPM_RC_SUCCESS)
171
0
           return result;
172
173
       // Don't need the object, just needed the checks to be performed so
174
       // flush the object
175
0
       ObjectFlush(objectHandle);
176
0
   }
177
178
// Command output
179
180
   // Prepare output private data from sensitive
181
0
   SensitiveToPrivate(&sensitive, &name, in->parentHandle,
182
0
                      in->objectPublic.t.publicArea.nameAlg,
183
0
                      &out->outPrivate);
184
185
0
   return TPM_RC_SUCCESS;
186
0
}