blob: d2ff1efab4864ec697f7bdbf14e63b82b285821b [file] [log] [blame]
John Wedig2098dab2021-09-14 13:56:28 -07001
2#include "estoraged.hpp"
3
John Edward Broadbent59dffa62022-01-13 17:41:32 -08004#include "cryptErase.hpp"
John Wedigb810c922021-11-17 16:38:03 -08005#include "cryptsetupInterface.hpp"
John Edward Broadbent7f2ab642021-11-11 21:00:38 -08006#include "pattern.hpp"
John Edward Broadbent605085a2021-11-05 13:45:45 -07007#include "sanitize.hpp"
John Edward Broadbente6ffe702021-10-14 14:03:11 -07008#include "verifyDriveGeometry.hpp"
John Edward Broadbent4bc8a102021-12-30 16:11:49 -08009#include "zero.hpp"
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -080010
John Wedigb810c922021-11-17 16:38:03 -080011#include <libcryptsetup.h>
12#include <openssl/rand.h>
John Wedigb810c922021-11-17 16:38:03 -080013
14#include <phosphor-logging/lg2.hpp>
John Wedig67a47442022-04-05 17:21:29 -070015#include <sdbusplus/asio/object_server.hpp>
John Wedig972c3fa2021-12-29 17:30:41 -080016#include <xyz/openbmc_project/Common/error.hpp>
John Wedigb810c922021-11-17 16:38:03 -080017
Ed Tanous82897c32022-02-21 14:11:59 -080018#include <cstdlib>
John Wedigb810c922021-11-17 16:38:03 -080019#include <filesystem>
John Wedig2098dab2021-09-14 13:56:28 -070020#include <iostream>
John Wedig67a47442022-04-05 17:21:29 -070021#include <string>
John Wedigb810c922021-11-17 16:38:03 -080022#include <string_view>
John Wedig67a47442022-04-05 17:21:29 -070023#include <utility>
John Wedig2098dab2021-09-14 13:56:28 -070024#include <vector>
25
26namespace estoraged
27{
28
John Wedig6c0d8ce2022-04-22 14:00:43 -070029using Association = std::tuple<std::string, std::string, std::string>;
John Wedig972c3fa2021-12-29 17:30:41 -080030using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
John Wedig972c3fa2021-12-29 17:30:41 -080031using sdbusplus::xyz::openbmc_project::Common::Error::UnsupportedRequest;
John Edward Broadbent91c1ec12022-05-20 16:51:43 -070032using sdbusplus::xyz::openbmc_project::Inventory::Item::server::Drive;
John Wedig67a47442022-04-05 17:21:29 -070033using sdbusplus::xyz::openbmc_project::Inventory::Item::server::Volume;
John Wedigb810c922021-11-17 16:38:03 -080034
John Wedig67a47442022-04-05 17:21:29 -070035EStoraged::EStoraged(sdbusplus::asio::object_server& server,
John Wedig6c0d8ce2022-04-22 14:00:43 -070036 const std::string& configPath, const std::string& devPath,
37 const std::string& luksName, uint64_t size,
John Wedigb4838302022-07-22 13:51:16 -070038 uint8_t lifeTime, const std::string& partNumber,
39 const std::string& serialNumber,
Tom Tung043af592023-11-24 13:37:05 +080040 const std::string& locationCode, uint64_t eraseMaxGeometry,
John Wedigd7be42b2024-01-19 16:07:19 -080041 uint64_t eraseMinGeometry, const std::string& driveType,
John Wedig67a47442022-04-05 17:21:29 -070042 std::unique_ptr<CryptsetupInterface> cryptInterface,
43 std::unique_ptr<FilesystemInterface> fsInterface) :
44 devPath(devPath),
45 containerName(luksName), mountPoint("/mnt/" + luksName + "_fs"),
Tom Tung043af592023-11-24 13:37:05 +080046 eraseMaxGeometry(eraseMaxGeometry), eraseMinGeometry(eraseMinGeometry),
John Edward Broadbent6771c692022-06-22 19:49:27 -070047 cryptIface(std::move(cryptInterface)), fsIface(std::move(fsInterface)),
John Wedig2443a022023-03-17 13:42:32 -070048 cryptDevicePath(cryptIface->cryptGetDir() + "/" + luksName),
John Edward Broadbent6771c692022-06-22 19:49:27 -070049 objectServer(server)
John Wedig67a47442022-04-05 17:21:29 -070050{
51 /* Get the filename of the device (without "/dev/"). */
52 std::string deviceName = std::filesystem::path(devPath).filename().string();
53 /* DBus object path */
Patrick Williams04c28fa2023-05-10 07:51:24 -050054 std::string objectPath = "/xyz/openbmc_project/inventory/storage/" +
55 deviceName;
John Wedig67a47442022-04-05 17:21:29 -070056
57 /* Add Volume interface. */
58 volumeInterface = objectServer.add_interface(
John Wedig6c0d8ce2022-04-22 14:00:43 -070059 objectPath, "xyz.openbmc_project.Inventory.Item.Volume");
John Wedig67a47442022-04-05 17:21:29 -070060 volumeInterface->register_method(
61 "FormatLuks", [this](const std::vector<uint8_t>& password,
62 Volume::FilesystemType type) {
Patrick Williamsff1b64f2023-10-20 11:19:56 -050063 this->formatLuks(password, type);
Patrick Williams04c28fa2023-05-10 07:51:24 -050064 });
Patrick Williamsff1b64f2023-10-20 11:19:56 -050065 volumeInterface->register_method(
66 "Erase",
67 [this](Volume::EraseMethod eraseType) { this->erase(eraseType); });
John Wedig67a47442022-04-05 17:21:29 -070068 volumeInterface->register_method("Lock", [this]() { this->lock(); });
Patrick Williamsff1b64f2023-10-20 11:19:56 -050069 volumeInterface->register_method(
70 "Unlock",
71 [this](std::vector<uint8_t>& password) { this->unlock(password); });
John Wedig67a47442022-04-05 17:21:29 -070072 volumeInterface->register_method(
73 "ChangePassword", [this](const std::vector<uint8_t>& oldPassword,
74 const std::vector<uint8_t>& newPassword) {
Patrick Williamsff1b64f2023-10-20 11:19:56 -050075 this->changePassword(oldPassword, newPassword);
76 });
John Wedig67a47442022-04-05 17:21:29 -070077 volumeInterface->register_property_r(
78 "Locked", lockedProperty, sdbusplus::vtable::property_::emits_change,
79 [this](bool& value) {
Patrick Williams04c28fa2023-05-10 07:51:24 -050080 value = this->isLocked();
81 return value;
Patrick Williamsff1b64f2023-10-20 11:19:56 -050082 });
John Wedig67a47442022-04-05 17:21:29 -070083
84 /* Add Drive interface. */
85 driveInterface = objectServer.add_interface(
John Wedig6c0d8ce2022-04-22 14:00:43 -070086 objectPath, "xyz.openbmc_project.Inventory.Item.Drive");
John Wedig67a47442022-04-05 17:21:29 -070087 driveInterface->register_property("Capacity", size);
John Edward Broadbent5d799bb2022-03-22 16:14:24 -070088 driveInterface->register_property("PredictedMediaLifeLeftPercent",
89 lifeTime);
John Wedigd7be42b2024-01-19 16:07:19 -080090 driveInterface->register_property(
91 "Type",
92 "xyz.openbmc_project.Inventory.Item.Drive.DriveType." + driveType);
John Edward Broadbent14aee772022-04-20 13:46:48 -070093 /* This registers the Locked property for the Drives interface.
94 * Now it is the same as the volume Locked property */
95 driveInterface->register_property_r(
96 "Locked", lockedProperty, sdbusplus::vtable::property_::emits_change,
97 [this](bool& value) {
Patrick Williams04c28fa2023-05-10 07:51:24 -050098 value = this->isLocked();
99 return value;
Patrick Williamsff1b64f2023-10-20 11:19:56 -0500100 });
John Wedig67a47442022-04-05 17:21:29 -0700101
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700102 driveInterface->register_property_r(
103 "EncryptionStatus", encryptionStatus,
104 sdbusplus::vtable::property_::emits_change,
105 [this](Drive::DriveEncryptionState& value) {
Patrick Williams04c28fa2023-05-10 07:51:24 -0500106 value = this->findEncryptionStatus();
107 return value;
Patrick Williamsff1b64f2023-10-20 11:19:56 -0500108 });
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700109
John Edward Broadbent49796412022-06-22 18:31:52 -0700110 embeddedLocationInterface = objectServer.add_interface(
111 objectPath, "xyz.openbmc_project.Inventory.Connector.Embedded");
John Edward Broadbent740e94b2022-06-10 19:42:30 -0700112
Rahul Kapoor19825052023-05-27 01:52:23 +0000113 if (!locationCode.empty())
114 {
115 locationCodeInterface = objectServer.add_interface(
116 objectPath, "xyz.openbmc_project.Inventory.Decorator.LocationCode");
117 locationCodeInterface->register_property("LocationCode", locationCode);
118 locationCodeInterface->initialize();
119 }
120
John Wedigb4838302022-07-22 13:51:16 -0700121 /* Add Asset interface. */
122 assetInterface = objectServer.add_interface(
123 objectPath, "xyz.openbmc_project.Inventory.Decorator.Asset");
124 assetInterface->register_property("PartNumber", partNumber);
125 assetInterface->register_property("SerialNumber", serialNumber);
126
John Wedig67a47442022-04-05 17:21:29 -0700127 volumeInterface->initialize();
128 driveInterface->initialize();
John Edward Broadbent49796412022-06-22 18:31:52 -0700129 embeddedLocationInterface->initialize();
John Wedigb4838302022-07-22 13:51:16 -0700130 assetInterface->initialize();
John Wedig6c0d8ce2022-04-22 14:00:43 -0700131
132 /* Set up the association between chassis and drive. */
133 association = objectServer.add_interface(
134 objectPath, "xyz.openbmc_project.Association.Definitions");
135
136 std::vector<Association> associations;
137 associations.emplace_back("chassis", "drive",
138 std::filesystem::path(configPath).parent_path());
139 association->register_property("Associations", associations);
140 association->initialize();
John Wedig67a47442022-04-05 17:21:29 -0700141}
142
143EStoraged::~EStoraged()
144{
145 objectServer.remove_interface(volumeInterface);
146 objectServer.remove_interface(driveInterface);
John Edward Broadbent49796412022-06-22 18:31:52 -0700147 objectServer.remove_interface(embeddedLocationInterface);
John Wedigb4838302022-07-22 13:51:16 -0700148 objectServer.remove_interface(assetInterface);
John Wedig6c0d8ce2022-04-22 14:00:43 -0700149 objectServer.remove_interface(association);
Rahul Kapoor19825052023-05-27 01:52:23 +0000150
151 if (locationCodeInterface != nullptr)
152 {
153 objectServer.remove_interface(locationCodeInterface);
154 }
John Wedig67a47442022-04-05 17:21:29 -0700155}
156
157void EStoraged::formatLuks(const std::vector<uint8_t>& password,
158 Volume::FilesystemType type)
John Wedig2098dab2021-09-14 13:56:28 -0700159{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800160 std::string msg = "OpenBMC.0.1.DriveFormat";
161 lg2::info("Starting format", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800162
John Wedig67a47442022-04-05 17:21:29 -0700163 if (type != Volume::FilesystemType::ext4)
John Wedig972c3fa2021-12-29 17:30:41 -0800164 {
165 lg2::error("Only ext4 filesystems are supported currently",
166 "REDFISH_MESSAGE_ID", std::string("OpenBMC.0.1.FormatFail"));
167 throw UnsupportedRequest();
168 }
169
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700170 formatLuksDev(password);
171 activateLuksDev(password);
John Wedigb810c922021-11-17 16:38:03 -0800172
173 createFilesystem();
174 mountFilesystem();
John Wedig2098dab2021-09-14 13:56:28 -0700175}
176
John Wedig67a47442022-04-05 17:21:29 -0700177void EStoraged::erase(Volume::EraseMethod inEraseMethod)
John Wedig2098dab2021-09-14 13:56:28 -0700178{
179 std::cerr << "Erasing encrypted eMMC" << std::endl;
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700180 lg2::info("Starting erase", "REDFISH_MESSAGE_ID",
181 std::string("OpenBMC.0.1.DriveErase"));
182 switch (inEraseMethod)
183 {
John Wedig67a47442022-04-05 17:21:29 -0700184 case Volume::EraseMethod::CryptoErase:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700185 {
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800186 CryptErase myCryptErase(devPath);
187 myCryptErase.doErase();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700188 break;
189 }
John Wedig67a47442022-04-05 17:21:29 -0700190 case Volume::EraseMethod::VerifyGeometry:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700191 {
192 VerifyDriveGeometry myVerifyGeometry(devPath);
Tom Tung043af592023-11-24 13:37:05 +0800193 myVerifyGeometry.geometryOkay(eraseMaxGeometry, eraseMinGeometry);
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700194 break;
195 }
John Wedig67a47442022-04-05 17:21:29 -0700196 case Volume::EraseMethod::LogicalOverWrite:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700197 {
John Edward Broadbent7f2ab642021-11-11 21:00:38 -0800198 Pattern myErasePattern(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700199 myErasePattern.writePattern();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700200 break;
201 }
John Wedig67a47442022-04-05 17:21:29 -0700202 case Volume::EraseMethod::LogicalVerify:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700203 {
John Edward Broadbent7f2ab642021-11-11 21:00:38 -0800204 Pattern myErasePattern(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700205 myErasePattern.verifyPattern();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700206 break;
207 }
John Wedig67a47442022-04-05 17:21:29 -0700208 case Volume::EraseMethod::VendorSanitize:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700209 {
John Edward Broadbent605085a2021-11-05 13:45:45 -0700210 Sanitize mySanitize(devPath);
211 mySanitize.doSanitize();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700212 break;
213 }
John Wedig67a47442022-04-05 17:21:29 -0700214 case Volume::EraseMethod::ZeroOverWrite:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700215 {
John Edward Broadbent4bc8a102021-12-30 16:11:49 -0800216 Zero myZero(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700217 myZero.writeZero();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700218 break;
219 }
John Wedig67a47442022-04-05 17:21:29 -0700220 case Volume::EraseMethod::ZeroVerify:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700221 {
John Edward Broadbent4bc8a102021-12-30 16:11:49 -0800222 Zero myZero(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700223 myZero.verifyZero();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700224 break;
225 }
John Wedig67a47442022-04-05 17:21:29 -0700226 case Volume::EraseMethod::SecuredLocked:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700227 {
John Wedig47cd7992022-10-05 15:45:11 -0700228 if (!isLocked())
John Edward Broadbentf59b7292022-02-15 15:07:15 -0800229 {
230 lock();
231 }
232 // TODO: implement hardware locking
233 // Until that is done, we can lock using eStoraged::lock()
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700234 break;
235 }
236 }
John Wedig2098dab2021-09-14 13:56:28 -0700237}
238
Ed Tanous82897c32022-02-21 14:11:59 -0800239void EStoraged::lock()
John Wedig2098dab2021-09-14 13:56:28 -0700240{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800241 std::string msg = "OpenBMC.0.1.DriveLock";
242 lg2::info("Starting lock", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800243
244 unmountFilesystem();
245 deactivateLuksDev();
John Wedig2098dab2021-09-14 13:56:28 -0700246}
247
Ed Tanous82897c32022-02-21 14:11:59 -0800248void EStoraged::unlock(std::vector<uint8_t> password)
John Wedig2098dab2021-09-14 13:56:28 -0700249{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800250 std::string msg = "OpenBMC.0.1.DriveUnlock";
251 lg2::info("Starting unlock", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800252
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700253 activateLuksDev(std::move(password));
John Wedigb810c922021-11-17 16:38:03 -0800254 mountFilesystem();
John Wedig2098dab2021-09-14 13:56:28 -0700255}
256
John Wedig8d5a3a02022-09-29 15:25:58 -0700257void EStoraged::changePassword(const std::vector<uint8_t>& oldPassword,
258 const std::vector<uint8_t>& newPassword)
John Wedig2098dab2021-09-14 13:56:28 -0700259{
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700260 lg2::info("Starting change password", "REDFISH_MESSAGE_ID",
261 std::string("OpenBMC.0.1.DrivePasswordChanged"));
John Wedig8d5a3a02022-09-29 15:25:58 -0700262
263 CryptHandle cryptHandle = loadLuksHeader();
264
265 int retval = cryptIface->cryptKeyslotChangeByPassphrase(
266 cryptHandle.get(), CRYPT_ANY_SLOT, CRYPT_ANY_SLOT,
267 reinterpret_cast<const char*>(oldPassword.data()), oldPassword.size(),
268 reinterpret_cast<const char*>(newPassword.data()), newPassword.size());
269 if (retval < 0)
270 {
271 lg2::error("Failed to change password", "REDFISH_MESSAGE_ID",
272 std::string("OpenBMC.0.1.DrivePasswordChangeFail"));
273 throw InternalFailure();
274 }
275
276 lg2::info("Successfully changed password for {DEV}", "DEV", devPath,
277 "REDFISH_MESSAGE_ID",
278 std::string("OpenBMC.0.1.DrivePasswordChangeSuccess"));
John Wedig2098dab2021-09-14 13:56:28 -0700279}
280
Ed Tanous82897c32022-02-21 14:11:59 -0800281bool EStoraged::isLocked() const
John Wedigb810c922021-11-17 16:38:03 -0800282{
John Wedig2443a022023-03-17 13:42:32 -0700283 /*
284 * Check if the mapped virtual device exists. If it exists, the LUKS volume
285 * is unlocked.
286 */
287 try
288 {
289 std::filesystem::path mappedDevicePath(cryptDevicePath);
290 return (std::filesystem::exists(mappedDevicePath) == false);
291 }
292 catch (const std::exception& e)
293 {
294 lg2::error("Failed to query locked status: {EXCEPT}", "EXCEPT",
295 e.what(), "REDFISH_MESSAGE_ID",
296 std::string("OpenBMC.0.1.IsLockedFail"));
297 /* If we couldn't query the filesystem path, assume unlocked. */
298 return false;
299 }
John Wedigb810c922021-11-17 16:38:03 -0800300}
301
Ed Tanous82897c32022-02-21 14:11:59 -0800302std::string_view EStoraged::getMountPoint() const
John Wedigb810c922021-11-17 16:38:03 -0800303{
304 return mountPoint;
305}
306
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700307void EStoraged::formatLuksDev(std::vector<uint8_t> password)
John Wedigb810c922021-11-17 16:38:03 -0800308{
309 lg2::info("Formatting device {DEV}", "DEV", devPath, "REDFISH_MESSAGE_ID",
310 std::string("OpenBMC.0.1.FormatLuksDev"));
311
312 /* Generate the volume key. */
313 const std::size_t keySize = 64;
314 std::vector<uint8_t> volumeKey(keySize);
315 if (RAND_bytes(volumeKey.data(), keySize) != 1)
316 {
317 lg2::error("Failed to create volume key", "REDFISH_MESSAGE_ID",
318 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800319 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800320 }
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700321
322 /* Create the handle. */
323 CryptHandle cryptHandle(devPath);
324
John Wedigb810c922021-11-17 16:38:03 -0800325 /* Format the LUKS encrypted device. */
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700326 int retval = cryptIface->cryptFormat(
327 cryptHandle.get(), CRYPT_LUKS2, "aes", "xts-plain64", nullptr,
328 reinterpret_cast<const char*>(volumeKey.data()), volumeKey.size(),
329 nullptr);
John Wedigb810c922021-11-17 16:38:03 -0800330 if (retval < 0)
331 {
332 lg2::error("Failed to format encrypted device: {RETVAL}", "RETVAL",
333 retval, "REDFISH_MESSAGE_ID",
334 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800335 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800336 }
337
John Wedigb810c922021-11-17 16:38:03 -0800338 /* Set the password. */
339 retval = cryptIface->cryptKeyslotAddByVolumeKey(
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700340 cryptHandle.get(), CRYPT_ANY_SLOT, nullptr, 0,
John Wedigb810c922021-11-17 16:38:03 -0800341 reinterpret_cast<const char*>(password.data()), password.size());
342
343 if (retval < 0)
344 {
345 lg2::error("Failed to set encryption password", "REDFISH_MESSAGE_ID",
346 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800347 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800348 }
349
350 lg2::info("Encrypted device {DEV} successfully formatted", "DEV", devPath,
351 "REDFISH_MESSAGE_ID",
352 std::string("OpenBMC.0.1.FormatLuksDevSuccess"));
353}
354
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700355CryptHandle EStoraged::loadLuksHeader()
John Wedigb810c922021-11-17 16:38:03 -0800356{
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700357 CryptHandle cryptHandle(devPath);
358
359 int retval = cryptIface->cryptLoad(cryptHandle.get(), CRYPT_LUKS2, nullptr);
John Wedigb810c922021-11-17 16:38:03 -0800360 if (retval < 0)
361 {
362 lg2::error("Failed to load LUKS header: {RETVAL}", "RETVAL", retval,
363 "REDFISH_MESSAGE_ID",
364 std::string("OpenBMC.0.1.ActivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800365 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800366 }
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700367 return cryptHandle;
368}
John Wedigb810c922021-11-17 16:38:03 -0800369
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700370Drive::DriveEncryptionState EStoraged::findEncryptionStatus()
371{
372 try
373 {
374 loadLuksHeader();
375 return Drive::DriveEncryptionState::Encrypted;
376 }
377 catch (...)
378 {
379 return Drive::DriveEncryptionState::Unknown;
380 }
381}
382
383void EStoraged::activateLuksDev(std::vector<uint8_t> password)
384{
385 lg2::info("Activating LUKS dev {DEV}", "DEV", devPath, "REDFISH_MESSAGE_ID",
386 std::string("OpenBMC.0.1.ActivateLuksDev"));
387
388 /* Create the handle. */
389 CryptHandle cryptHandle = loadLuksHeader();
390
391 int retval = cryptIface->cryptActivateByPassphrase(
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700392 cryptHandle.get(), containerName.c_str(), CRYPT_ANY_SLOT,
John Wedigb810c922021-11-17 16:38:03 -0800393 reinterpret_cast<const char*>(password.data()), password.size(), 0);
394
395 if (retval < 0)
396 {
397 lg2::error("Failed to activate LUKS dev: {RETVAL}", "RETVAL", retval,
398 "REDFISH_MESSAGE_ID",
399 std::string("OpenBMC.0.1.ActivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800400 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800401 }
402
John Wedigb810c922021-11-17 16:38:03 -0800403 lg2::info("Successfully activated LUKS dev {DEV}", "DEV", devPath,
404 "REDFISH_MESSAGE_ID",
405 std::string("OpenBMC.0.1.ActivateLuksDevSuccess"));
406}
407
Ed Tanous82897c32022-02-21 14:11:59 -0800408void EStoraged::createFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800409{
410 /* Run the command to create the filesystem. */
John Wedig2443a022023-03-17 13:42:32 -0700411 int retval = fsIface->runMkfs(cryptDevicePath);
Ed Tanous82897c32022-02-21 14:11:59 -0800412 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800413 {
414 lg2::error("Failed to create filesystem: {RETVAL}", "RETVAL", retval,
415 "REDFISH_MESSAGE_ID",
416 std::string("OpenBMC.0.1.CreateFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800417 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800418 }
John Wedig2443a022023-03-17 13:42:32 -0700419 lg2::info("Successfully created filesystem for {CONTAINER}", "CONTAINER",
420 cryptDevicePath, "REDFISH_MESSAGE_ID",
John Wedigb810c922021-11-17 16:38:03 -0800421 std::string("OpenBMC.0.1.CreateFilesystemSuccess"));
422}
423
Ed Tanous82897c32022-02-21 14:11:59 -0800424void EStoraged::mountFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800425{
John Wedigb17f8252022-01-12 14:24:26 -0800426 /*
427 * Create directory for the filesystem, if it's not already present. It
428 * might already exist if, for example, the BMC reboots after creating the
429 * directory.
430 */
431 if (!fsIface->directoryExists(std::filesystem::path(mountPoint)))
John Wedigb810c922021-11-17 16:38:03 -0800432 {
John Wedigb17f8252022-01-12 14:24:26 -0800433 bool success =
434 fsIface->createDirectory(std::filesystem::path(mountPoint));
435 if (!success)
436 {
437 lg2::error("Failed to create mount point: {DIR}", "DIR", mountPoint,
438 "REDFISH_MESSAGE_ID",
439 std::string("OpenBMC.0.1.MountFilesystemFail"));
440 throw InternalFailure();
441 }
John Wedigb810c922021-11-17 16:38:03 -0800442 }
443
444 /* Run the command to mount the filesystem. */
John Wedig2443a022023-03-17 13:42:32 -0700445 int retval = fsIface->doMount(cryptDevicePath.c_str(), mountPoint.c_str(),
John Wedigb810c922021-11-17 16:38:03 -0800446 "ext4", 0, nullptr);
Ed Tanous82897c32022-02-21 14:11:59 -0800447 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800448 {
449 lg2::error("Failed to mount filesystem: {RETVAL}", "RETVAL", retval,
450 "REDFISH_MESSAGE_ID",
451 std::string("OpenBMC.0.1.MountFilesystemFail"));
452 bool removeSuccess =
453 fsIface->removeDirectory(std::filesystem::path(mountPoint));
454 if (!removeSuccess)
455 {
456 lg2::error("Failed to remove mount point: {DIR}", "DIR", mountPoint,
457 "REDFISH_MESSAGE_ID",
458 std::string("OpenBMC.0.1.MountFilesystemFail"));
459 }
John Wedig972c3fa2021-12-29 17:30:41 -0800460 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800461 }
462
463 lg2::info("Successfully mounted filesystem at {DIR}", "DIR", mountPoint,
464 "REDFISH_MESSAGE_ID",
465 std::string("OpenBMC.0.1.MountFilesystemSuccess"));
466}
467
Ed Tanous82897c32022-02-21 14:11:59 -0800468void EStoraged::unmountFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800469{
470 int retval = fsIface->doUnmount(mountPoint.c_str());
Ed Tanous82897c32022-02-21 14:11:59 -0800471 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800472 {
473 lg2::error("Failed to unmount filesystem: {RETVAL}", "RETVAL", retval,
474 "REDFISH_MESSAGE_ID",
475 std::string("OpenBMC.0.1.UnmountFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800476 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800477 }
478
479 /* Remove the mount point. */
480 bool success = fsIface->removeDirectory(std::filesystem::path(mountPoint));
481 if (!success)
482 {
483 lg2::error("Failed to remove mount point {DIR}", "DIR", mountPoint,
484 "REDFISH_MESSAGE_ID",
485 std::string("OpenBMC.0.1.UnmountFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800486 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800487 }
488
489 lg2::info("Successfully unmounted filesystem at {DIR}", "DIR", mountPoint,
490 "REDFISH_MESSAGE_ID",
491 std::string("OpenBMC.0.1.MountFilesystemSuccess"));
492}
493
Ed Tanous82897c32022-02-21 14:11:59 -0800494void EStoraged::deactivateLuksDev()
John Wedigb810c922021-11-17 16:38:03 -0800495{
496 lg2::info("Deactivating LUKS device {DEV}", "DEV", devPath,
497 "REDFISH_MESSAGE_ID",
498 std::string("OpenBMC.0.1.DeactivateLuksDev"));
499
500 int retval = cryptIface->cryptDeactivate(nullptr, containerName.c_str());
501 if (retval < 0)
502 {
503 lg2::error("Failed to deactivate crypt device: {RETVAL}", "RETVAL",
504 retval, "REDFISH_MESSAGE_ID",
505 std::string("OpenBMC.0.1.DeactivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800506 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800507 }
508
John Wedigb810c922021-11-17 16:38:03 -0800509 lg2::info("Successfully deactivated LUKS device {DEV}", "DEV", devPath,
510 "REDFISH_MESSAGE_ID",
511 std::string("OpenBMC.0.1.DeactivateLuksDevSuccess"));
512}
513
John Wedig2443a022023-03-17 13:42:32 -0700514std::string_view EStoraged::getCryptDevicePath() const
John Wedig67a47442022-04-05 17:21:29 -0700515{
John Wedig2443a022023-03-17 13:42:32 -0700516 return cryptDevicePath;
John Wedig67a47442022-04-05 17:21:29 -0700517}
518
John Wedig2098dab2021-09-14 13:56:28 -0700519} // namespace estoraged