estoraged.cpp (4e13b0a103353b48fac1c592dda0582cc6df26f7) | estoraged.cpp (b810c926021976665707f90d460aec0300f5ccf1) |
---|---|
1 2#include "estoraged.hpp" 3 | 1 2#include "estoraged.hpp" 3 |
4#include "cryptsetupInterface.hpp" 5 6#include <libcryptsetup.h> 7#include <openssl/rand.h> 8#include <stdlib.h> 9 |
|
4#include <phosphor-logging/lg2.hpp> | 10#include <phosphor-logging/lg2.hpp> |
11#include <xyz/openbmc_project/eStoraged/error.hpp> |
|
5 | 12 |
13#include <filesystem> |
|
6#include <iostream> | 14#include <iostream> |
15#include <string_view> |
|
7#include <vector> 8 9namespace estoraged 10{ 11 | 16#include <vector> 17 18namespace estoraged 19{ 20 |
12void eStoraged::format(std::vector<uint8_t>) | 21using sdbusplus::xyz::openbmc_project::eStoraged::Error::EncryptionError; 22using sdbusplus::xyz::openbmc_project::eStoraged::Error::FilesystemError; 23 24void eStoraged::format(std::vector<uint8_t> password) |
13{ | 25{ |
14 std::cerr << "Formatting encrypted eMMC" << std::endl; | |
15 std::string msg = "OpenBMC.0.1.DriveFormat"; 16 lg2::info("Starting format", "REDFISH_MESSAGE_ID", msg); | 26 std::string msg = "OpenBMC.0.1.DriveFormat"; 27 lg2::info("Starting format", "REDFISH_MESSAGE_ID", msg); |
28 29 struct crypt_device* cryptDev; 30 CryptHandle cryptHandle(&cryptDev, devPath.c_str()); 31 if (*cryptHandle.handle == nullptr) 32 { 33 lg2::error("Failed to initialize crypt device", "REDFISH_MESSAGE_ID", 34 std::string("OpenBMC.0.1.FormatFail")); 35 throw EncryptionError(); 36 } 37 38 formatLuksDev(cryptDev, password); 39 activateLuksDev(cryptDev, password); 40 41 createFilesystem(); 42 mountFilesystem(); |
|
17} 18 19void eStoraged::erase(std::vector<uint8_t>, EraseMethod) 20{ 21 std::cerr << "Erasing encrypted eMMC" << std::endl; 22 std::string msg = "OpenBMC.0.1.DriveErase"; 23 lg2::info("Starting erase", "REDFISH_MESSAGE_ID", msg); 24} 25 26void eStoraged::lock(std::vector<uint8_t>) 27{ | 43} 44 45void eStoraged::erase(std::vector<uint8_t>, EraseMethod) 46{ 47 std::cerr << "Erasing encrypted eMMC" << std::endl; 48 std::string msg = "OpenBMC.0.1.DriveErase"; 49 lg2::info("Starting erase", "REDFISH_MESSAGE_ID", msg); 50} 51 52void eStoraged::lock(std::vector<uint8_t>) 53{ |
28 std::cerr << "Locking encrypted eMMC" << std::endl; | |
29 std::string msg = "OpenBMC.0.1.DriveLock"; 30 lg2::info("Starting lock", "REDFISH_MESSAGE_ID", msg); | 54 std::string msg = "OpenBMC.0.1.DriveLock"; 55 lg2::info("Starting lock", "REDFISH_MESSAGE_ID", msg); |
56 57 unmountFilesystem(); 58 deactivateLuksDev(); |
|
31} 32 | 59} 60 |
33void eStoraged::unlock(std::vector<uint8_t>) | 61void eStoraged::unlock(std::vector<uint8_t> password) |
34{ | 62{ |
35 std::cerr << "Unlocking encrypted eMMC" << std::endl; | |
36 std::string msg = "OpenBMC.0.1.DriveUnlock"; 37 lg2::info("Starting unlock", "REDFISH_MESSAGE_ID", msg); | 63 std::string msg = "OpenBMC.0.1.DriveUnlock"; 64 lg2::info("Starting unlock", "REDFISH_MESSAGE_ID", msg); |
65 66 struct crypt_device* cryptDev; 67 CryptHandle cryptHandle(&cryptDev, devPath.c_str()); 68 if (*cryptHandle.handle == nullptr) 69 { 70 lg2::error("Failed to initialize crypt device", "REDFISH_MESSAGE_ID", 71 std::string("OpenBMC.0.1.UnlockFail")); 72 throw EncryptionError(); 73 } 74 75 activateLuksDev(cryptDev, password); 76 mountFilesystem(); |
|
38} 39 40void eStoraged::changePassword(std::vector<uint8_t>, std::vector<uint8_t>) 41{ 42 std::cerr << "Changing password for encrypted eMMC" << std::endl; 43 std::string msg = "OpenBMC.0.1.DrivePasswordChanged"; 44 lg2::info("Starting change password", "REDFISH_MESSAGE_ID", msg); 45} 46 | 77} 78 79void eStoraged::changePassword(std::vector<uint8_t>, std::vector<uint8_t>) 80{ 81 std::cerr << "Changing password for encrypted eMMC" << std::endl; 82 std::string msg = "OpenBMC.0.1.DrivePasswordChanged"; 83 lg2::info("Starting change password", "REDFISH_MESSAGE_ID", msg); 84} 85 |
86bool eStoraged::isLocked() const 87{ 88 return locked(); 89} 90 91std::string_view eStoraged::getMountPoint() const 92{ 93 return mountPoint; 94} 95 96void eStoraged::formatLuksDev(struct crypt_device* cd, 97 std::vector<uint8_t> password) 98{ 99 lg2::info("Formatting device {DEV}", "DEV", devPath, "REDFISH_MESSAGE_ID", 100 std::string("OpenBMC.0.1.FormatLuksDev")); 101 102 /* Generate the volume key. */ 103 const std::size_t keySize = 64; 104 std::vector<uint8_t> volumeKey(keySize); 105 if (RAND_bytes(volumeKey.data(), keySize) != 1) 106 { 107 lg2::error("Failed to create volume key", "REDFISH_MESSAGE_ID", 108 std::string("OpenBMC.0.1.FormatLuksDevFail")); 109 throw EncryptionError(); 110 } 111 /* Format the LUKS encrypted device. */ 112 int retval = 113 cryptIface->cryptFormat(cd, CRYPT_LUKS2, "aes", "xts-plain64", nullptr, 114 reinterpret_cast<const char*>(volumeKey.data()), 115 volumeKey.size(), nullptr); 116 if (retval < 0) 117 { 118 lg2::error("Failed to format encrypted device: {RETVAL}", "RETVAL", 119 retval, "REDFISH_MESSAGE_ID", 120 std::string("OpenBMC.0.1.FormatLuksDevFail")); 121 throw EncryptionError(); 122 } 123 124 /* Device is now encrypted. */ 125 locked(true); 126 127 /* Set the password. */ 128 retval = cryptIface->cryptKeyslotAddByVolumeKey( 129 cd, CRYPT_ANY_SLOT, nullptr, 0, 130 reinterpret_cast<const char*>(password.data()), password.size()); 131 132 if (retval < 0) 133 { 134 lg2::error("Failed to set encryption password", "REDFISH_MESSAGE_ID", 135 std::string("OpenBMC.0.1.FormatLuksDevFail")); 136 throw EncryptionError(); 137 } 138 139 lg2::info("Encrypted device {DEV} successfully formatted", "DEV", devPath, 140 "REDFISH_MESSAGE_ID", 141 std::string("OpenBMC.0.1.FormatLuksDevSuccess")); 142} 143 144void eStoraged::activateLuksDev(struct crypt_device* cd, 145 std::vector<uint8_t> password) 146{ 147 lg2::info("Activating LUKS dev {DEV}", "DEV", devPath, "REDFISH_MESSAGE_ID", 148 std::string("OpenBMC.0.1.ActivateLuksDev")); 149 150 int retval = cryptIface->cryptLoad(cd, CRYPT_LUKS2, nullptr); 151 if (retval < 0) 152 { 153 lg2::error("Failed to load LUKS header: {RETVAL}", "RETVAL", retval, 154 "REDFISH_MESSAGE_ID", 155 std::string("OpenBMC.0.1.ActivateLuksDevFail")); 156 throw EncryptionError(); 157 } 158 159 retval = cryptIface->cryptActivateByPassphrase( 160 cd, containerName.c_str(), CRYPT_ANY_SLOT, 161 reinterpret_cast<const char*>(password.data()), password.size(), 0); 162 163 if (retval < 0) 164 { 165 lg2::error("Failed to activate LUKS dev: {RETVAL}", "RETVAL", retval, 166 "REDFISH_MESSAGE_ID", 167 std::string("OpenBMC.0.1.ActivateLuksDevFail")); 168 throw EncryptionError(); 169 } 170 171 /* Device is now unlocked. */ 172 locked(false); 173 174 lg2::info("Successfully activated LUKS dev {DEV}", "DEV", devPath, 175 "REDFISH_MESSAGE_ID", 176 std::string("OpenBMC.0.1.ActivateLuksDevSuccess")); 177} 178 179void eStoraged::createFilesystem() 180{ 181 /* Run the command to create the filesystem. */ 182 int retval = fsIface->runMkfs(containerName); 183 if (retval) 184 { 185 lg2::error("Failed to create filesystem: {RETVAL}", "RETVAL", retval, 186 "REDFISH_MESSAGE_ID", 187 std::string("OpenBMC.0.1.CreateFilesystemFail")); 188 throw FilesystemError(); 189 } 190 lg2::info("Successfully created filesystem for /dev/mapper/{CONTAINER}", 191 "CONTAINER", containerName, "REDFISH_MESSAGE_ID", 192 std::string("OpenBMC.0.1.CreateFilesystemSuccess")); 193} 194 195void eStoraged::mountFilesystem() 196{ 197 /* Create directory for the filesystem. */ 198 bool success = fsIface->createDirectory(std::filesystem::path(mountPoint)); 199 if (!success) 200 { 201 lg2::error("Failed to create mount point: {DIR}", "DIR", mountPoint, 202 "REDFISH_MESSAGE_ID", 203 std::string("OpenBMC.0.1.MountFilesystemFail")); 204 throw FilesystemError(); 205 } 206 207 /* Run the command to mount the filesystem. */ 208 std::string luksContainer("/dev/mapper/" + containerName); 209 int retval = fsIface->doMount(luksContainer.c_str(), mountPoint.c_str(), 210 "ext4", 0, nullptr); 211 if (retval) 212 { 213 lg2::error("Failed to mount filesystem: {RETVAL}", "RETVAL", retval, 214 "REDFISH_MESSAGE_ID", 215 std::string("OpenBMC.0.1.MountFilesystemFail")); 216 bool removeSuccess = 217 fsIface->removeDirectory(std::filesystem::path(mountPoint)); 218 if (!removeSuccess) 219 { 220 lg2::error("Failed to remove mount point: {DIR}", "DIR", mountPoint, 221 "REDFISH_MESSAGE_ID", 222 std::string("OpenBMC.0.1.MountFilesystemFail")); 223 } 224 throw FilesystemError(); 225 } 226 227 lg2::info("Successfully mounted filesystem at {DIR}", "DIR", mountPoint, 228 "REDFISH_MESSAGE_ID", 229 std::string("OpenBMC.0.1.MountFilesystemSuccess")); 230} 231 232void eStoraged::unmountFilesystem() 233{ 234 int retval = fsIface->doUnmount(mountPoint.c_str()); 235 if (retval) 236 { 237 lg2::error("Failed to unmount filesystem: {RETVAL}", "RETVAL", retval, 238 "REDFISH_MESSAGE_ID", 239 std::string("OpenBMC.0.1.UnmountFilesystemFail")); 240 throw FilesystemError(); 241 } 242 243 /* Remove the mount point. */ 244 bool success = fsIface->removeDirectory(std::filesystem::path(mountPoint)); 245 if (!success) 246 { 247 lg2::error("Failed to remove mount point {DIR}", "DIR", mountPoint, 248 "REDFISH_MESSAGE_ID", 249 std::string("OpenBMC.0.1.UnmountFilesystemFail")); 250 throw FilesystemError(); 251 } 252 253 lg2::info("Successfully unmounted filesystem at {DIR}", "DIR", mountPoint, 254 "REDFISH_MESSAGE_ID", 255 std::string("OpenBMC.0.1.MountFilesystemSuccess")); 256} 257 258void eStoraged::deactivateLuksDev() 259{ 260 lg2::info("Deactivating LUKS device {DEV}", "DEV", devPath, 261 "REDFISH_MESSAGE_ID", 262 std::string("OpenBMC.0.1.DeactivateLuksDev")); 263 264 int retval = cryptIface->cryptDeactivate(nullptr, containerName.c_str()); 265 if (retval < 0) 266 { 267 lg2::error("Failed to deactivate crypt device: {RETVAL}", "RETVAL", 268 retval, "REDFISH_MESSAGE_ID", 269 std::string("OpenBMC.0.1.DeactivateLuksDevFail")); 270 throw EncryptionError(); 271 } 272 273 /* Device is now locked. */ 274 locked(true); 275 276 lg2::info("Successfully deactivated LUKS device {DEV}", "DEV", devPath, 277 "REDFISH_MESSAGE_ID", 278 std::string("OpenBMC.0.1.DeactivateLuksDevSuccess")); 279} 280 |
|
47} // namespace estoraged | 281} // namespace estoraged |