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 "EvictControl_fp.h"
10//
11//
12//     Error Returns                     Meaning
13//
14//     TPM_RC_ATTRIBUTES                 an object with temporary, stClear or publicOnly attribute SET cannot
15//                                       be made persistent
16//     TPM_RC_HIERARCHY                  auth cannot authorize the operation in the hierarchy of evictObject
17//     TPM_RC_HANDLE                     evictHandle of the persistent object to be evicted is not the same as
18//                                       the persistentHandle argument
19//     TPM_RC_NV_HANDLE                  persistentHandle is unavailable
20//     TPM_RC_NV_SPACE                   no space in NV to make evictHandle persistent
21//     TPM_RC_RANGE                      persistentHandle is not in the range corresponding to the hierarchy of
22//                                       evictObject
23//
24TPM_RC
25TPM2_EvictControl(
26   EvictControl_In       *in                   // IN: input parameter list
27   )
28{
29   TPM_RC       result;
30   OBJECT       *evictObject;
31
32   // The command needs NV update. Check if NV is available.
33   // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
34   // this point
35   result = NvIsAvailable();
36   if(result != TPM_RC_SUCCESS) return result;
37
38// Input Validation
39
40   // Get internal object pointer
41   evictObject = ObjectGet(in->objectHandle);
42
43   // Temporary, stClear or public only objects can not be made persistent
44   if(   evictObject->attributes.temporary == SET
45      || evictObject->attributes.stClear == SET
46      || evictObject->attributes.publicOnly == SET
47     )
48       return TPM_RC_ATTRIBUTES + RC_EvictControl_objectHandle;
49
50   // If objectHandle refers to a persistent object, it should be the same as
51   // input persistentHandle
52   if(   evictObject->attributes.evict == SET
53      && evictObject->evictHandle != in->persistentHandle
54     )
55       return TPM_RC_HANDLE + RC_EvictControl_objectHandle;
56
57   // Additional auth validation
58   if(in->auth == TPM_RH_PLATFORM)
59   {
60       // To make persistent
61       if(evictObject->attributes.evict == CLEAR)
62       {
63           // Platform auth can not set evict object in storage or endorsement
64           // hierarchy
65          if(evictObject->attributes.ppsHierarchy == CLEAR)
66              return TPM_RC_HIERARCHY + RC_EvictControl_objectHandle;
67
68          // Platform cannot use a handle outside of platform persistent range.
69          if(!NvIsPlatformPersistentHandle(in->persistentHandle))
70              return TPM_RC_RANGE + RC_EvictControl_persistentHandle;
71      }
72      // Platform auth can delete any persistent object
73  }
74  else if(in->auth == TPM_RH_OWNER)
75  {
76      // Owner auth can not set or clear evict object in platform hierarchy
77      if(evictObject->attributes.ppsHierarchy == SET)
78          return TPM_RC_HIERARCHY + RC_EvictControl_objectHandle;
79
80      // Owner cannot use a handle outside of owner persistent range.
81      if(   evictObject->attributes.evict == CLEAR
82         && !NvIsOwnerPersistentHandle(in->persistentHandle)
83        )
84          return TPM_RC_RANGE + RC_EvictControl_persistentHandle;
85  }
86  else
87  {
88      // Other auth is not allowed in this command and should be filtered out
89      // at unmarshal process
90      pAssert(FALSE);
91  }
92
93// Internal Data Update
94
95  // Change evict state
96  if(evictObject->attributes.evict == CLEAR)
97  {
98      // Make object persistent
99      // A TPM_RC_NV_HANDLE or TPM_RC_NV_SPACE error may be returned at this
100      // point
101      result = NvAddEvictObject(in->persistentHandle, evictObject);
102      if(result != TPM_RC_SUCCESS) return result;
103  }
104  else
105  {
106      // Delete the persistent object in NV
107      NvDeleteEntity(evictObject->evictHandle);
108  }
109
110  return TPM_RC_SUCCESS;
111
112}
113