Coverage Report

Created: 2025-08-26 06:27

/src/tpm2/ContextLoad.c
Line
Count
Source (jump to first uncovered line)
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 "ContextLoad_fp.h"
10
#include "Context_spt_fp.h"
11
//
12
//
13
//     Error Returns                 Meaning
14
//
15
//     TPM_RC_CONTEXT_GAP            there is only one available slot and this is not the oldest saved
16
//                                   session context
17
//     TPM_RC_HANDLE                 'context. savedHandle' does not reference a saved session
18
//     TPM_RC_HIERARCHY              'context.hierarchy' is disabled
19
//     TPM_RC_INTEGRITY              context integrity check fail
20
//     TPM_RC_OBJECT_MEMORY          no free slot for an object
21
//     TPM_RC_SESSION_MEMORY         no free session slots
22
//     TPM_RC_SIZE                   incorrect context blob size
23
//
24
TPM_RC
25
TPM2_ContextLoad(
26
   ContextLoad_In     *in,                  // IN: input parameter list
27
   ContextLoad_Out    *out                  // OUT: output parameter list
28
   )
29
5
{
30
// Local Variables
31
5
   TPM_RC      result = TPM_RC_SUCCESS;
32
33
5
   TPM2B_DIGEST       integrityToCompare;
34
5
   TPM2B_DIGEST       integrity;
35
5
   UINT16             integritySize;
36
5
   UINT64             fingerprint;
37
5
   BYTE               *buffer;
38
5
   INT32              size;
39
40
5
   TPM_HT             handleType;
41
5
   TPM2B_SYM_KEY      symKey;
42
5
   TPM2B_IV           iv;
43
44
// Input Validation
45
46
   // Check context blob size
47
5
   handleType = HandleGetType(in->context.savedHandle);
48
49
   // Check integrity
50
   // In this implementation, the same routine is used for both sessions
51
   // and objects.
52
5
   integritySize = CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
53
54
   // Get integrity from context blob
55
5
   buffer = in->context.contextBlob.t.buffer;
56
5
   size = (INT32) in->context.contextBlob.t.size;
57
5
   result = TPM2B_DIGEST_Unmarshal(&integrity, &buffer, &size);
58
5
   if(result != TPM_RC_SUCCESS)
59
0
       return result;
60
5
   if(integrity.t.size != integritySize)
61
5
       return TPM_RC_SIZE;
62
63
0
   integritySize += sizeof(integrity.t.size);
64
//
65
66
   // Compute context integrity
67
0
   ComputeContextIntegrity(&in->context, &integrityToCompare);
68
69
   // Compare integrity
70
0
   if(!Memory2BEqual(&integrity.b, &integrityToCompare.b))
71
0
       return TPM_RC_INTEGRITY + RC_ContextLoad_context;
72
73
   // Compute context encryption key
74
0
   ComputeContextProtectionKey(&in->context, &symKey, &iv);
75
76
   // Decrypt context data in place
77
0
   CryptSymmetricDecrypt(in->context.contextBlob.t.buffer + integritySize,
78
0
                         CONTEXT_ENCRYPT_ALG, CONTEXT_ENCRYPT_KEY_BITS,
79
0
                         TPM_ALG_CFB, symKey.t.buffer, &iv,
80
0
                         in->context.contextBlob.t.size - integritySize,
81
0
                         in->context.contextBlob.t.buffer + integritySize);
82
83
   // Read the fingerprint value, skip the leading integrity size
84
0
   MemoryCopy(&fingerprint, in->context.contextBlob.t.buffer + integritySize,
85
0
              sizeof(fingerprint), sizeof(fingerprint));
86
   // Check fingerprint. If the check fails, TPM should be put to failure mode
87
0
   if(fingerprint != in->context.sequence)
88
0
       FAIL(FATAL_ERROR_INTERNAL);
89
90
   // Perform object or session specific input check
91
0
   switch(handleType)
92
0
   {
93
0
   case TPM_HT_TRANSIENT:
94
0
   {
95
       // Get a pointer to the object in the context blob
96
0
       OBJECT      *outObject = (OBJECT *)(in->context.contextBlob.t.buffer
97
0
                               + integritySize + sizeof(fingerprint));
98
99
       // Discard any changes to the handle that the TRM might have made
100
0
       in->context.savedHandle = TRANSIENT_FIRST;
101
102
       // If hierarchy is disabled, no object context can be loaded in this
103
       // hierarchy
104
0
       if(!HierarchyIsEnabled(in->context.hierarchy))
105
0
           return TPM_RC_HIERARCHY + RC_ContextLoad_context;
106
107
       // Restore object. A TPM_RC_OBJECT_MEMORY error may be returned at
108
       // this point
109
0
       result = ObjectContextLoad(outObject, &out->loadedHandle);
110
0
       if(result != TPM_RC_SUCCESS)
111
0
           return result;
112
113
       // If this is a sequence object, the crypto library may need to
114
       // reformat the data into an internal format
115
0
       if(ObjectIsSequence(outObject))
116
0
           SequenceDataImportExport(ObjectGet(out->loadedHandle),
117
0
                                    outObject, IMPORT_STATE);
118
119
0
       break;
120
0
   }
121
0
   case TPM_HT_POLICY_SESSION:
122
0
   case TPM_HT_HMAC_SESSION:
123
0
   {
124
125
0
       SESSION      *session = (SESSION *)(in->context.contextBlob.t.buffer
126
0
                                        + integritySize + sizeof(fingerprint));
127
128
       // This command may cause the orderlyState to be cleared due to
129
       // the update of state reset data. If this is the case, check if NV is
130
       // available first
131
0
      if(gp.orderlyState != SHUTDOWN_NONE)
132
0
      {
133
          // The command needs NV update. Check if NV is available.
134
          // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned
135
          // at this point
136
0
          result = NvIsAvailable();
137
0
          if(result != TPM_RC_SUCCESS)
138
0
              return result;
139
0
      }
140
141
      // Check if input handle points to a valid saved session
142
0
      if(!SessionIsSaved(in->context.savedHandle))
143
0
          return TPM_RC_HANDLE + RC_ContextLoad_context;
144
145
      // Restore session. A TPM_RC_SESSION_MEMORY, TPM_RC_CONTEXT_GAP error
146
      // may be returned at this point
147
0
      result = SessionContextLoad(session, &in->context.savedHandle);
148
0
      if(result != TPM_RC_SUCCESS)
149
0
          return result;
150
151
0
      out->loadedHandle = in->context.savedHandle;
152
153
      // orderly state should be cleared because of the update of state
154
      // reset and state clear data
155
0
      g_clearOrderly = TRUE;
156
157
0
      break;
158
0
  }
159
0
  default:
160
      // Context blob may only have an object handle or a session handle.
161
      // All the other handle type should be filtered out at unmarshal
162
0
      pAssert(FALSE);
163
0
      break;
164
0
  }
165
166
0
   return TPM_RC_SUCCESS;
167
0
}