1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef NVRAM_CORE_NVRAM_MANAGER_H_ 18 #define NVRAM_CORE_NVRAM_MANAGER_H_ 19 20 #include <nvram/messages/nvram_messages.h> 21 22 #include <nvram/core/persistence.h> 23 24 namespace nvram { 25 26 // |NvramManager| implements the core functionality of the access-controlled 27 // NVRAM HAL backend. It keeps track of the allocated spaces and their state, 28 // including the transient state that is held per boot. It provides operations 29 // for querying, creating, deleting, reading and writing spaces. It deals with 30 // persistent storage objects in the form of |NvramHeader| and |NvramSpace| 31 // objects and uses the persistence layer to read and write them from persistent 32 // storage. 33 class NvramManager { 34 public: 35 // Looks at |request| to determine the command to execute, extracts the 36 // request parameters and invokes the correct handler function. Stores status 37 // and output parameters in |response|. 38 void Dispatch(const Request& request, Response* response); 39 40 nvram_result_t GetInfo(const GetInfoRequest& request, 41 GetInfoResponse* response); 42 nvram_result_t CreateSpace(const CreateSpaceRequest& request, 43 CreateSpaceResponse* response); 44 nvram_result_t GetSpaceInfo(const GetSpaceInfoRequest& request, 45 GetSpaceInfoResponse* response); 46 nvram_result_t DeleteSpace(const DeleteSpaceRequest& request, 47 DeleteSpaceResponse* response); 48 nvram_result_t DisableCreate(const DisableCreateRequest& request, 49 DisableCreateResponse* response); 50 nvram_result_t WriteSpace(const WriteSpaceRequest& request, 51 WriteSpaceResponse* response); 52 nvram_result_t ReadSpace(const ReadSpaceRequest& request, 53 ReadSpaceResponse* response); 54 nvram_result_t LockSpaceWrite(const LockSpaceWriteRequest& request, 55 LockSpaceWriteResponse* response); 56 nvram_result_t LockSpaceRead(const LockSpaceReadRequest& request, 57 LockSpaceReadResponse* response); 58 59 // The wipe functions are meant for use by firmware after determining the 60 // device's mode of operation. These can be used to clear access-controlled 61 // NVRAM when a user invokes a full hardware reset. Note that in regular 62 // operation, the user *MUST BE PREVENTED* from wiping access-controlled 63 // NVRAM. 64 // 65 // If a full hardware reset can conveniently clear the access-controlled NVRAM 66 // storage area out of band, it's fine to do so. In this case, the 67 // wiping-related commands should not be exposed at all. Note that this is the 68 // default behavior - the reference implementation will ignore all wipe 69 // requests unless compiled with NVRAM_WIPE_STORAGE_SUPPORT=1. 70 // 71 // For devices where firmware doesn't have direct control over the storage 72 // area used by access-controlled NVRAM, the wiping commands are provided to 73 // facilitate clearing storage: 74 // 1. Determine boot mode. 75 // 2. If not in recovery mode, call DisableWipe(). All further wipe requests 76 // will be rejected. A reboot (or TEE restart for that matter) is 77 // required before a new decision can be made. 78 // 3. If operating in recovery mode, forgo calling DisableWipe(). The 79 // recovery process will then be able to invoke WipeStorage() later as 80 // needed. 81 nvram_result_t WipeStorage(const WipeStorageRequest& request, 82 WipeStorageResponse* response); 83 nvram_result_t DisableWipe(const DisableWipeRequest& request, 84 DisableWipeResponse* response); 85 86 private: 87 // Holds transient state corresponding to an allocated NVRAM space, i.e. meta 88 // data valid for a single boot. One instance of this struct is kept in memory 89 // in the |spaces_| array for each of the spaces that are currently allocated. 90 struct SpaceListEntry { 91 uint32_t index; 92 bool write_locked = false; 93 bool read_locked = false; 94 }; 95 96 // |SpaceRecord| holds all information known about a space. It includes both 97 // an index and pointer to the transient information held in the 98 // |SpaceListEntry| in the |spaces_| array and the persistent |NvramSpace| 99 // state held in permanent storage. We only load the persistent space data 100 // from storage when it is needed for an operation, such as reading and 101 // writing space contents. 102 struct SpaceRecord { 103 // Access control check for write access to the space. The 104 // |authorization_value| is only relevant if the space was configured to 105 // require authorization. Returns RESULT_SUCCESS if write access is 106 // permitted and a suitable result code to return to the client on failure. 107 nvram_result_t CheckWriteAccess(const Blob& authorization_value); 108 109 // Access control check for read access to the space. The 110 // |authorization_value| is only relevant if the space was configured to 111 // require authorization. Returns RESULT_SUCCESS if write access is 112 // permitted and a suitable result code to return the client on failure. 113 nvram_result_t CheckReadAccess(const Blob& authorization_value); 114 115 size_t array_index = 0; 116 SpaceListEntry* transient = nullptr; 117 NvramSpace persistent; 118 }; 119 120 // Initializes |header_| from storage if that hasn't happened already. Returns 121 // true if NvramManager object is initialized and ready to serve requests. May 122 // be called again after failure to attempt initialization again. 123 bool Initialize(); 124 125 // Finds the array index in |spaces_| that corresponds to |space_index|. 126 // Returns |kMaxSpaces| if there is no matching space. 127 size_t FindSpace(uint32_t space_index); 128 129 // Loads space data for |index|. Fills in |space_record| and returns true if 130 // successful. Returns false and sets |result| on error. 131 bool LoadSpaceRecord(uint32_t index, 132 SpaceRecord* space_record, 133 nvram_result_t* result); 134 135 // Writes the header to storage and returns a suitable status code. 136 nvram_result_t WriteHeader(Optional<uint32_t> provisional_index); 137 138 // Write |space| data for |index|. 139 nvram_result_t WriteSpace(uint32_t index, const NvramSpace& space); 140 141 // Maximum number of NVRAM spaces we're willing to allocate. 142 static constexpr size_t kMaxSpaces = 32; 143 144 bool initialized_ = false; 145 bool disable_create_ = false; 146 bool disable_wipe_ = false; 147 148 // Bookkeeping information for allocated spaces. 149 size_t num_spaces_ = 0; 150 SpaceListEntry spaces_[kMaxSpaces]; 151 }; 152 153 } // namespace nvram 154 155 #endif // NVRAM_CORE_NVRAM_MANAGER_H_ 156