1 #pragma once 2 3 #include "cryptsetupInterface.hpp" 4 #include "filesystemInterface.hpp" 5 #include "util.hpp" 6 7 #include <libcryptsetup.h> 8 9 #include <sdbusplus/asio/object_server.hpp> 10 #include <sdbusplus/bus.hpp> 11 #include <sdbusplus/exception.hpp> 12 #include <sdbusplus/server/object.hpp> 13 #include <util.hpp> 14 #include <xyz/openbmc_project/Inventory/Item/Drive/server.hpp> 15 #include <xyz/openbmc_project/Inventory/Item/Volume/server.hpp> 16 17 #include <filesystem> 18 #include <memory> 19 #include <string> 20 #include <string_view> 21 #include <vector> 22 23 namespace estoraged 24 { 25 using estoraged::Cryptsetup; 26 using estoraged::Filesystem; 27 using sdbusplus::xyz::openbmc_project::Inventory::Item::server::Drive; 28 using sdbusplus::xyz::openbmc_project::Inventory::Item::server::Volume; 29 30 /** @class eStoraged 31 * @brief eStoraged object to manage a LUKS encrypted storage device. 32 */ 33 class EStoraged 34 { 35 public: 36 /** @brief Constructor for eStoraged 37 * 38 * @param[in] server - sdbusplus asio object server 39 * @param[in] configPath - path of the config object from Entity Manager 40 * @param[in] devPath - path to device file, e.g. /dev/mmcblk0 41 * @param[in] luksName - name for the LUKS container 42 * @param[in] size - size of the drive in bytes 43 * @param[in] lifeTime - percent of lifetime remaining for a drive 44 * @param[in] partNumber - part number for the storage device 45 * @param[in] serialNumber - serial number for the storage device 46 * @param[in] locationCode - location code for the storage device 47 * @param[in] eraseMaxGeometry - max geometry to erase if it's specified 48 * @param[in] eraseMinGeometry - min geometry to erase if it's specified 49 * @param[in] driveType - type of drive, e.g. HDD vs SSD 50 * @param[in] driveProtocol - protocol used to communicate with drive 51 * @param[in] cryptInterface - (optional) pointer to CryptsetupInterface 52 * object 53 * @param[in] fsInterface - (optional) pointer to FilesystemInterface 54 * object 55 */ 56 EStoraged(sdbusplus::asio::object_server& server, 57 const std::string& configPath, const std::string& devPath, 58 const std::string& luksName, uint64_t size, uint8_t lifeTime, 59 const std::string& partNumber, const std::string& serialNumber, 60 const std::string& locationCode, uint64_t eraseMaxGeometry, 61 uint64_t eraseMinGeometry, const std::string& driveType, 62 const std::string& driveProtocol, 63 std::unique_ptr<CryptsetupInterface> cryptInterface = 64 std::make_unique<Cryptsetup>(), 65 std::unique_ptr<FilesystemInterface> fsInterface = 66 std::make_unique<Filesystem>()); 67 68 /** @brief Destructor for eStoraged. */ 69 ~EStoraged(); 70 71 EStoraged& operator=(const EStoraged&) = delete; 72 EStoraged(const EStoraged&) = delete; 73 EStoraged(EStoraged&&) = default; 74 EStoraged& operator=(EStoraged&&) = delete; 75 76 /** @brief Format the LUKS encrypted device and create empty filesystem. 77 * 78 * @param[in] password - password to set for the LUKS device. 79 * @param[in] type - filesystem type, e.g. ext4 80 */ 81 void formatLuks(const std::vector<uint8_t>& password, 82 Volume::FilesystemType type); 83 84 /** @brief Erase the contents of the storage device. 85 * 86 * @param[in] eraseType - type of erase operation. 87 */ 88 void erase(Volume::EraseMethod eraseType); 89 90 /** @brief Unmount filesystem and lock the LUKS device. 91 */ 92 void lock(); 93 94 /** @brief Unlock device and mount the filesystem. 95 * 96 * @param[in] password - password for the LUKS device. 97 */ 98 void unlock(std::vector<uint8_t> password); 99 100 /** @brief Change the password for the LUKS device. 101 * 102 * @param[in] oldPassword - old password for the LUKS device. 103 * @param[in] newPassword - new password for the LUKS device. 104 */ 105 void changePassword(const std::vector<uint8_t>& oldPassword, 106 const std::vector<uint8_t>& newPassword); 107 108 /** @brief Check if the LUKS device is currently locked. */ 109 bool isLocked() const; 110 111 /** @brief Get the mount point for the filesystem on the LUKS device. */ 112 std::string_view getMountPoint() const; 113 114 /** @brief Get the path to the mapped crypt device. */ 115 std::string_view getCryptDevicePath() const; 116 117 private: 118 /** @brief Full path of the device file, e.g. /dev/mmcblk0. */ 119 std::string devPath; 120 121 /** @brief Name of the LUKS container. */ 122 std::string containerName; 123 124 /** @brief Mount point for the filesystem. */ 125 std::string mountPoint; 126 127 /** @brief Max geometry to erase. */ 128 uint64_t eraseMaxGeometry; 129 130 /** @brief Min geometry to erase. */ 131 uint64_t eraseMinGeometry; 132 133 /** @brief Indicates whether the LUKS device is currently locked. */ 134 bool lockedProperty{false}; 135 136 /** @brief Pointer to cryptsetup interface object. 137 * @details This is used to mock out the cryptsetup functions. 138 */ 139 std::unique_ptr<CryptsetupInterface> cryptIface; 140 141 /** @brief Pointer to filesystem interface object. 142 * @details This is used to mock out filesystem operations. 143 */ 144 std::unique_ptr<FilesystemInterface> fsIface; 145 146 /** @brief Path where the mapped crypt device gets created. */ 147 const std::string cryptDevicePath; 148 149 /** @brief D-Bus object server. */ 150 sdbusplus::asio::object_server& objectServer; 151 152 /** @brief D-Bus interface for the logical volume. */ 153 std::shared_ptr<sdbusplus::asio::dbus_interface> volumeInterface; 154 155 /** @brief D-Bus interface for the physical drive. */ 156 std::shared_ptr<sdbusplus::asio::dbus_interface> driveInterface; 157 158 /** @brief D-Bus interface for the location type of the drive. */ 159 std::shared_ptr<sdbusplus::asio::dbus_interface> embeddedLocationInterface; 160 161 /** @brief D-Bus interface for the location code of the drive. */ 162 std::shared_ptr<sdbusplus::asio::dbus_interface> locationCodeInterface; 163 164 /** @brief D-Bus interface for the asset information. */ 165 std::shared_ptr<sdbusplus::asio::dbus_interface> assetInterface; 166 167 /** @brief Association between chassis and drive. */ 168 std::shared_ptr<sdbusplus::asio::dbus_interface> association; 169 170 /** @brief Indicates whether the LUKS header is on the disk. */ 171 Drive::DriveEncryptionState encryptionStatus{ 172 Drive::DriveEncryptionState::Unknown}; 173 174 /** @brief Format LUKS encrypted device. 175 * 176 * @param[in] password - password to set for the LUKS device. 177 */ 178 void formatLuksDev(std::vector<uint8_t> password); 179 180 /** @brief check the LUKS header, for devPath 181 * 182 * @returns a CryptHandle to the LUKS drive 183 */ 184 CryptHandle loadLuksHeader(); 185 186 /** @brief Unlock the device. 187 * 188 * @param[in] password - password to activate the LUKS device. 189 */ 190 191 Drive::DriveEncryptionState findEncryptionStatus(); 192 193 void activateLuksDev(std::vector<uint8_t> password); 194 195 /** @brief Create the filesystem on the LUKS device. 196 * @details The LUKS device should already be activated, i.e. unlocked. 197 */ 198 void createFilesystem(); 199 200 /** @brief Deactivate the LUKS device. 201 * @details The filesystem is assumed to be unmounted already. 202 */ 203 void deactivateLuksDev(); 204 205 /** @brief Mount the filesystem. 206 * @details The filesystem should already exist and the LUKS device should 207 * be unlocked already. 208 */ 209 void mountFilesystem(); 210 211 /** @brief Unmount the filesystem. */ 212 void unmountFilesystem(); 213 }; 214 215 } // namespace estoraged 216