blob: 28290c4d48d41d36553d77d1272e40b26c481d2c [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 Wedig1755d1b2025-07-21 22:26:30 +000030using sdbusplus::asio::PropertyPermission;
John Wedig972c3fa2021-12-29 17:30:41 -080031using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
John Wedig972c3fa2021-12-29 17:30:41 -080032using sdbusplus::xyz::openbmc_project::Common::Error::UnsupportedRequest;
John Edward Broadbent91c1ec12022-05-20 16:51:43 -070033using sdbusplus::xyz::openbmc_project::Inventory::Item::server::Drive;
John Wedig67a47442022-04-05 17:21:29 -070034using sdbusplus::xyz::openbmc_project::Inventory::Item::server::Volume;
John Wedigb810c922021-11-17 16:38:03 -080035
Patrick Williams15b63e12024-08-16 15:22:01 -040036EStoraged::EStoraged(
37 sdbusplus::asio::object_server& server, const std::string& configPath,
38 const std::string& devPath, const std::string& luksName, uint64_t size,
39 uint8_t lifeTime, const std::string& partNumber,
40 const std::string& serialNumber, const std::string& locationCode,
41 uint64_t eraseMaxGeometry, uint64_t eraseMinGeometry,
42 const std::string& driveType, const std::string& driveProtocol,
43 std::unique_ptr<CryptsetupInterface> cryptInterface,
44 std::unique_ptr<FilesystemInterface> fsInterface) :
45 devPath(devPath), containerName(luksName),
46 mountPoint("/mnt/" + luksName + "_fs"), eraseMaxGeometry(eraseMaxGeometry),
47 eraseMinGeometry(eraseMinGeometry), cryptIface(std::move(cryptInterface)),
48 fsIface(std::move(fsInterface)),
John Wedig2443a022023-03-17 13:42:32 -070049 cryptDevicePath(cryptIface->cryptGetDir() + "/" + luksName),
John Edward Broadbent6771c692022-06-22 19:49:27 -070050 objectServer(server)
John Wedig67a47442022-04-05 17:21:29 -070051{
52 /* Get the filename of the device (without "/dev/"). */
53 std::string deviceName = std::filesystem::path(devPath).filename().string();
54 /* DBus object path */
Patrick Williams15b63e12024-08-16 15:22:01 -040055 std::string objectPath =
56 "/xyz/openbmc_project/inventory/storage/" + deviceName;
John Wedig67a47442022-04-05 17:21:29 -070057
58 /* Add Volume interface. */
59 volumeInterface = objectServer.add_interface(
John Wedig6c0d8ce2022-04-22 14:00:43 -070060 objectPath, "xyz.openbmc_project.Inventory.Item.Volume");
John Wedig67a47442022-04-05 17:21:29 -070061 volumeInterface->register_method(
62 "FormatLuks", [this](const std::vector<uint8_t>& password,
63 Volume::FilesystemType type) {
Patrick Williams15b63e12024-08-16 15:22:01 -040064 this->formatLuks(password, type);
65 });
Patrick Williamsff1b64f2023-10-20 11:19:56 -050066 volumeInterface->register_method(
67 "Erase",
68 [this](Volume::EraseMethod eraseType) { this->erase(eraseType); });
John Wedig67a47442022-04-05 17:21:29 -070069 volumeInterface->register_method("Lock", [this]() { this->lock(); });
Patrick Williamsff1b64f2023-10-20 11:19:56 -050070 volumeInterface->register_method(
71 "Unlock",
72 [this](std::vector<uint8_t>& password) { this->unlock(password); });
John Wedig67a47442022-04-05 17:21:29 -070073 volumeInterface->register_method(
74 "ChangePassword", [this](const std::vector<uint8_t>& oldPassword,
75 const std::vector<uint8_t>& newPassword) {
Patrick Williams15b63e12024-08-16 15:22:01 -040076 this->changePassword(oldPassword, newPassword);
77 });
John Wedig67a47442022-04-05 17:21:29 -070078 volumeInterface->register_property_r(
79 "Locked", lockedProperty, sdbusplus::vtable::property_::emits_change,
80 [this](bool& value) {
Patrick Williams15b63e12024-08-16 15:22:01 -040081 value = this->isLocked();
82 return value;
83 });
John Wedig67a47442022-04-05 17:21:29 -070084
85 /* Add Drive interface. */
86 driveInterface = objectServer.add_interface(
John Wedig6c0d8ce2022-04-22 14:00:43 -070087 objectPath, "xyz.openbmc_project.Inventory.Item.Drive");
John Wedig67a47442022-04-05 17:21:29 -070088 driveInterface->register_property("Capacity", size);
John Wedig1755d1b2025-07-21 22:26:30 +000089 /* The lifetime property is read/write only for testing purposes. */
90 driveInterface->register_property("PredictedMediaLifeLeftPercent", lifeTime,
91 PropertyPermission::readWrite);
John Wedigd7be42b2024-01-19 16:07:19 -080092 driveInterface->register_property(
93 "Type",
94 "xyz.openbmc_project.Inventory.Item.Drive.DriveType." + driveType);
John Wedigc0d66eb2024-02-26 15:54:47 -080095 driveInterface->register_property(
96 "Protocol", "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol." +
97 driveProtocol);
John Edward Broadbent14aee772022-04-20 13:46:48 -070098 /* This registers the Locked property for the Drives interface.
99 * Now it is the same as the volume Locked property */
100 driveInterface->register_property_r(
101 "Locked", lockedProperty, sdbusplus::vtable::property_::emits_change,
102 [this](bool& value) {
Patrick Williams15b63e12024-08-16 15:22:01 -0400103 value = this->isLocked();
104 return value;
105 });
John Wedig67a47442022-04-05 17:21:29 -0700106
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700107 driveInterface->register_property_r(
108 "EncryptionStatus", encryptionStatus,
109 sdbusplus::vtable::property_::emits_change,
110 [this](Drive::DriveEncryptionState& value) {
Patrick Williams15b63e12024-08-16 15:22:01 -0400111 value = this->findEncryptionStatus();
112 return value;
113 });
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700114
John Edward Broadbent49796412022-06-22 18:31:52 -0700115 embeddedLocationInterface = objectServer.add_interface(
116 objectPath, "xyz.openbmc_project.Inventory.Connector.Embedded");
John Edward Broadbent740e94b2022-06-10 19:42:30 -0700117
Rahul Kapoor19825052023-05-27 01:52:23 +0000118 if (!locationCode.empty())
119 {
120 locationCodeInterface = objectServer.add_interface(
121 objectPath, "xyz.openbmc_project.Inventory.Decorator.LocationCode");
122 locationCodeInterface->register_property("LocationCode", locationCode);
123 locationCodeInterface->initialize();
124 }
125
John Wedigb4838302022-07-22 13:51:16 -0700126 /* Add Asset interface. */
127 assetInterface = objectServer.add_interface(
128 objectPath, "xyz.openbmc_project.Inventory.Decorator.Asset");
129 assetInterface->register_property("PartNumber", partNumber);
130 assetInterface->register_property("SerialNumber", serialNumber);
131
John Wedig67a47442022-04-05 17:21:29 -0700132 volumeInterface->initialize();
133 driveInterface->initialize();
John Edward Broadbent49796412022-06-22 18:31:52 -0700134 embeddedLocationInterface->initialize();
John Wedigb4838302022-07-22 13:51:16 -0700135 assetInterface->initialize();
John Wedig6c0d8ce2022-04-22 14:00:43 -0700136
137 /* Set up the association between chassis and drive. */
138 association = objectServer.add_interface(
139 objectPath, "xyz.openbmc_project.Association.Definitions");
140
141 std::vector<Association> associations;
142 associations.emplace_back("chassis", "drive",
143 std::filesystem::path(configPath).parent_path());
144 association->register_property("Associations", associations);
145 association->initialize();
John Wedig67a47442022-04-05 17:21:29 -0700146}
147
148EStoraged::~EStoraged()
149{
150 objectServer.remove_interface(volumeInterface);
151 objectServer.remove_interface(driveInterface);
John Edward Broadbent49796412022-06-22 18:31:52 -0700152 objectServer.remove_interface(embeddedLocationInterface);
John Wedigb4838302022-07-22 13:51:16 -0700153 objectServer.remove_interface(assetInterface);
John Wedig6c0d8ce2022-04-22 14:00:43 -0700154 objectServer.remove_interface(association);
Rahul Kapoor19825052023-05-27 01:52:23 +0000155
156 if (locationCodeInterface != nullptr)
157 {
158 objectServer.remove_interface(locationCodeInterface);
159 }
John Wedig67a47442022-04-05 17:21:29 -0700160}
161
162void EStoraged::formatLuks(const std::vector<uint8_t>& password,
163 Volume::FilesystemType type)
John Wedig2098dab2021-09-14 13:56:28 -0700164{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800165 std::string msg = "OpenBMC.0.1.DriveFormat";
166 lg2::info("Starting format", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800167
John Wedig67a47442022-04-05 17:21:29 -0700168 if (type != Volume::FilesystemType::ext4)
John Wedig972c3fa2021-12-29 17:30:41 -0800169 {
170 lg2::error("Only ext4 filesystems are supported currently",
171 "REDFISH_MESSAGE_ID", std::string("OpenBMC.0.1.FormatFail"));
172 throw UnsupportedRequest();
173 }
174
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700175 formatLuksDev(password);
176 activateLuksDev(password);
John Wedigb810c922021-11-17 16:38:03 -0800177
178 createFilesystem();
179 mountFilesystem();
John Wedig2098dab2021-09-14 13:56:28 -0700180}
181
John Wedig67a47442022-04-05 17:21:29 -0700182void EStoraged::erase(Volume::EraseMethod inEraseMethod)
John Wedig2098dab2021-09-14 13:56:28 -0700183{
184 std::cerr << "Erasing encrypted eMMC" << std::endl;
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700185 lg2::info("Starting erase", "REDFISH_MESSAGE_ID",
186 std::string("OpenBMC.0.1.DriveErase"));
187 switch (inEraseMethod)
188 {
John Wedig67a47442022-04-05 17:21:29 -0700189 case Volume::EraseMethod::CryptoErase:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700190 {
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800191 CryptErase myCryptErase(devPath);
192 myCryptErase.doErase();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700193 break;
194 }
John Wedig67a47442022-04-05 17:21:29 -0700195 case Volume::EraseMethod::VerifyGeometry:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700196 {
197 VerifyDriveGeometry myVerifyGeometry(devPath);
Tom Tung043af592023-11-24 13:37:05 +0800198 myVerifyGeometry.geometryOkay(eraseMaxGeometry, eraseMinGeometry);
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700199 break;
200 }
John Wedig67a47442022-04-05 17:21:29 -0700201 case Volume::EraseMethod::LogicalOverWrite:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700202 {
John Edward Broadbent7f2ab642021-11-11 21:00:38 -0800203 Pattern myErasePattern(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700204 myErasePattern.writePattern();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700205 break;
206 }
John Wedig67a47442022-04-05 17:21:29 -0700207 case Volume::EraseMethod::LogicalVerify:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700208 {
John Edward Broadbent7f2ab642021-11-11 21:00:38 -0800209 Pattern myErasePattern(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700210 myErasePattern.verifyPattern();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700211 break;
212 }
John Wedig67a47442022-04-05 17:21:29 -0700213 case Volume::EraseMethod::VendorSanitize:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700214 {
John Edward Broadbent605085a2021-11-05 13:45:45 -0700215 Sanitize mySanitize(devPath);
216 mySanitize.doSanitize();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700217 break;
218 }
John Wedig67a47442022-04-05 17:21:29 -0700219 case Volume::EraseMethod::ZeroOverWrite:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700220 {
John Edward Broadbent4bc8a102021-12-30 16:11:49 -0800221 Zero myZero(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700222 myZero.writeZero();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700223 break;
224 }
John Wedig67a47442022-04-05 17:21:29 -0700225 case Volume::EraseMethod::ZeroVerify:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700226 {
John Edward Broadbent4bc8a102021-12-30 16:11:49 -0800227 Zero myZero(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700228 myZero.verifyZero();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700229 break;
230 }
John Wedig67a47442022-04-05 17:21:29 -0700231 case Volume::EraseMethod::SecuredLocked:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700232 {
John Wedig47cd7992022-10-05 15:45:11 -0700233 if (!isLocked())
John Edward Broadbentf59b7292022-02-15 15:07:15 -0800234 {
235 lock();
236 }
237 // TODO: implement hardware locking
238 // Until that is done, we can lock using eStoraged::lock()
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700239 break;
240 }
241 }
John Wedig2098dab2021-09-14 13:56:28 -0700242}
243
Ed Tanous82897c32022-02-21 14:11:59 -0800244void EStoraged::lock()
John Wedig2098dab2021-09-14 13:56:28 -0700245{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800246 std::string msg = "OpenBMC.0.1.DriveLock";
247 lg2::info("Starting lock", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800248
249 unmountFilesystem();
250 deactivateLuksDev();
John Wedig2098dab2021-09-14 13:56:28 -0700251}
252
Ed Tanous82897c32022-02-21 14:11:59 -0800253void EStoraged::unlock(std::vector<uint8_t> password)
John Wedig2098dab2021-09-14 13:56:28 -0700254{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800255 std::string msg = "OpenBMC.0.1.DriveUnlock";
256 lg2::info("Starting unlock", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800257
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700258 activateLuksDev(std::move(password));
John Wedigb810c922021-11-17 16:38:03 -0800259 mountFilesystem();
John Wedig2098dab2021-09-14 13:56:28 -0700260}
261
John Wedig8d5a3a02022-09-29 15:25:58 -0700262void EStoraged::changePassword(const std::vector<uint8_t>& oldPassword,
263 const std::vector<uint8_t>& newPassword)
John Wedig2098dab2021-09-14 13:56:28 -0700264{
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700265 lg2::info("Starting change password", "REDFISH_MESSAGE_ID",
266 std::string("OpenBMC.0.1.DrivePasswordChanged"));
John Wedig8d5a3a02022-09-29 15:25:58 -0700267
268 CryptHandle cryptHandle = loadLuksHeader();
269
270 int retval = cryptIface->cryptKeyslotChangeByPassphrase(
271 cryptHandle.get(), CRYPT_ANY_SLOT, CRYPT_ANY_SLOT,
272 reinterpret_cast<const char*>(oldPassword.data()), oldPassword.size(),
273 reinterpret_cast<const char*>(newPassword.data()), newPassword.size());
274 if (retval < 0)
275 {
276 lg2::error("Failed to change password", "REDFISH_MESSAGE_ID",
277 std::string("OpenBMC.0.1.DrivePasswordChangeFail"));
278 throw InternalFailure();
279 }
280
281 lg2::info("Successfully changed password for {DEV}", "DEV", devPath,
282 "REDFISH_MESSAGE_ID",
283 std::string("OpenBMC.0.1.DrivePasswordChangeSuccess"));
John Wedig2098dab2021-09-14 13:56:28 -0700284}
285
Ed Tanous82897c32022-02-21 14:11:59 -0800286bool EStoraged::isLocked() const
John Wedigb810c922021-11-17 16:38:03 -0800287{
John Wedig2443a022023-03-17 13:42:32 -0700288 /*
289 * Check if the mapped virtual device exists. If it exists, the LUKS volume
290 * is unlocked.
291 */
292 try
293 {
294 std::filesystem::path mappedDevicePath(cryptDevicePath);
295 return (std::filesystem::exists(mappedDevicePath) == false);
296 }
297 catch (const std::exception& e)
298 {
299 lg2::error("Failed to query locked status: {EXCEPT}", "EXCEPT",
300 e.what(), "REDFISH_MESSAGE_ID",
301 std::string("OpenBMC.0.1.IsLockedFail"));
302 /* If we couldn't query the filesystem path, assume unlocked. */
303 return false;
304 }
John Wedigb810c922021-11-17 16:38:03 -0800305}
306
Ed Tanous82897c32022-02-21 14:11:59 -0800307std::string_view EStoraged::getMountPoint() const
John Wedigb810c922021-11-17 16:38:03 -0800308{
309 return mountPoint;
310}
311
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700312void EStoraged::formatLuksDev(std::vector<uint8_t> password)
John Wedigb810c922021-11-17 16:38:03 -0800313{
314 lg2::info("Formatting device {DEV}", "DEV", devPath, "REDFISH_MESSAGE_ID",
315 std::string("OpenBMC.0.1.FormatLuksDev"));
316
317 /* Generate the volume key. */
318 const std::size_t keySize = 64;
319 std::vector<uint8_t> volumeKey(keySize);
320 if (RAND_bytes(volumeKey.data(), keySize) != 1)
321 {
322 lg2::error("Failed to create volume key", "REDFISH_MESSAGE_ID",
323 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800324 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800325 }
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700326
327 /* Create the handle. */
328 CryptHandle cryptHandle(devPath);
329
John Wedigb810c922021-11-17 16:38:03 -0800330 /* Format the LUKS encrypted device. */
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700331 int retval = cryptIface->cryptFormat(
332 cryptHandle.get(), CRYPT_LUKS2, "aes", "xts-plain64", nullptr,
333 reinterpret_cast<const char*>(volumeKey.data()), volumeKey.size(),
334 nullptr);
John Wedigb810c922021-11-17 16:38:03 -0800335 if (retval < 0)
336 {
337 lg2::error("Failed to format encrypted device: {RETVAL}", "RETVAL",
338 retval, "REDFISH_MESSAGE_ID",
339 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800340 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800341 }
342
John Wedigb810c922021-11-17 16:38:03 -0800343 /* Set the password. */
344 retval = cryptIface->cryptKeyslotAddByVolumeKey(
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700345 cryptHandle.get(), CRYPT_ANY_SLOT, nullptr, 0,
John Wedigb810c922021-11-17 16:38:03 -0800346 reinterpret_cast<const char*>(password.data()), password.size());
347
348 if (retval < 0)
349 {
350 lg2::error("Failed to set encryption password", "REDFISH_MESSAGE_ID",
351 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800352 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800353 }
354
355 lg2::info("Encrypted device {DEV} successfully formatted", "DEV", devPath,
356 "REDFISH_MESSAGE_ID",
357 std::string("OpenBMC.0.1.FormatLuksDevSuccess"));
358}
359
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700360CryptHandle EStoraged::loadLuksHeader()
John Wedigb810c922021-11-17 16:38:03 -0800361{
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700362 CryptHandle cryptHandle(devPath);
363
364 int retval = cryptIface->cryptLoad(cryptHandle.get(), CRYPT_LUKS2, nullptr);
John Wedigb810c922021-11-17 16:38:03 -0800365 if (retval < 0)
366 {
367 lg2::error("Failed to load LUKS header: {RETVAL}", "RETVAL", retval,
368 "REDFISH_MESSAGE_ID",
369 std::string("OpenBMC.0.1.ActivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800370 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800371 }
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700372 return cryptHandle;
373}
John Wedigb810c922021-11-17 16:38:03 -0800374
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700375Drive::DriveEncryptionState EStoraged::findEncryptionStatus()
376{
377 try
378 {
379 loadLuksHeader();
380 return Drive::DriveEncryptionState::Encrypted;
381 }
382 catch (...)
383 {
Hao Zhou0cec4282024-03-12 22:16:16 +0000384 return Drive::DriveEncryptionState::Unencrypted;
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700385 }
386}
387
388void EStoraged::activateLuksDev(std::vector<uint8_t> password)
389{
390 lg2::info("Activating LUKS dev {DEV}", "DEV", devPath, "REDFISH_MESSAGE_ID",
391 std::string("OpenBMC.0.1.ActivateLuksDev"));
392
393 /* Create the handle. */
394 CryptHandle cryptHandle = loadLuksHeader();
395
396 int retval = cryptIface->cryptActivateByPassphrase(
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700397 cryptHandle.get(), containerName.c_str(), CRYPT_ANY_SLOT,
John Wedigb810c922021-11-17 16:38:03 -0800398 reinterpret_cast<const char*>(password.data()), password.size(), 0);
399
400 if (retval < 0)
401 {
402 lg2::error("Failed to activate LUKS dev: {RETVAL}", "RETVAL", retval,
403 "REDFISH_MESSAGE_ID",
404 std::string("OpenBMC.0.1.ActivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800405 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800406 }
407
John Wedigb810c922021-11-17 16:38:03 -0800408 lg2::info("Successfully activated LUKS dev {DEV}", "DEV", devPath,
409 "REDFISH_MESSAGE_ID",
410 std::string("OpenBMC.0.1.ActivateLuksDevSuccess"));
411}
412
Ed Tanous82897c32022-02-21 14:11:59 -0800413void EStoraged::createFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800414{
415 /* Run the command to create the filesystem. */
John Wedig2443a022023-03-17 13:42:32 -0700416 int retval = fsIface->runMkfs(cryptDevicePath);
Ed Tanous82897c32022-02-21 14:11:59 -0800417 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800418 {
419 lg2::error("Failed to create filesystem: {RETVAL}", "RETVAL", retval,
420 "REDFISH_MESSAGE_ID",
421 std::string("OpenBMC.0.1.CreateFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800422 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800423 }
John Wedig2443a022023-03-17 13:42:32 -0700424 lg2::info("Successfully created filesystem for {CONTAINER}", "CONTAINER",
425 cryptDevicePath, "REDFISH_MESSAGE_ID",
John Wedigb810c922021-11-17 16:38:03 -0800426 std::string("OpenBMC.0.1.CreateFilesystemSuccess"));
427}
428
Ed Tanous82897c32022-02-21 14:11:59 -0800429void EStoraged::mountFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800430{
John Wedigb17f8252022-01-12 14:24:26 -0800431 /*
432 * Create directory for the filesystem, if it's not already present. It
433 * might already exist if, for example, the BMC reboots after creating the
434 * directory.
435 */
436 if (!fsIface->directoryExists(std::filesystem::path(mountPoint)))
John Wedigb810c922021-11-17 16:38:03 -0800437 {
John Wedigb17f8252022-01-12 14:24:26 -0800438 bool success =
439 fsIface->createDirectory(std::filesystem::path(mountPoint));
440 if (!success)
441 {
442 lg2::error("Failed to create mount point: {DIR}", "DIR", mountPoint,
443 "REDFISH_MESSAGE_ID",
444 std::string("OpenBMC.0.1.MountFilesystemFail"));
445 throw InternalFailure();
446 }
John Wedigb810c922021-11-17 16:38:03 -0800447 }
448
449 /* Run the command to mount the filesystem. */
John Wedig2443a022023-03-17 13:42:32 -0700450 int retval = fsIface->doMount(cryptDevicePath.c_str(), mountPoint.c_str(),
John Wedigb810c922021-11-17 16:38:03 -0800451 "ext4", 0, nullptr);
Ed Tanous82897c32022-02-21 14:11:59 -0800452 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800453 {
454 lg2::error("Failed to mount filesystem: {RETVAL}", "RETVAL", retval,
455 "REDFISH_MESSAGE_ID",
456 std::string("OpenBMC.0.1.MountFilesystemFail"));
457 bool removeSuccess =
458 fsIface->removeDirectory(std::filesystem::path(mountPoint));
459 if (!removeSuccess)
460 {
461 lg2::error("Failed to remove mount point: {DIR}", "DIR", mountPoint,
462 "REDFISH_MESSAGE_ID",
463 std::string("OpenBMC.0.1.MountFilesystemFail"));
464 }
John Wedig972c3fa2021-12-29 17:30:41 -0800465 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800466 }
467
468 lg2::info("Successfully mounted filesystem at {DIR}", "DIR", mountPoint,
469 "REDFISH_MESSAGE_ID",
470 std::string("OpenBMC.0.1.MountFilesystemSuccess"));
471}
472
Ed Tanous82897c32022-02-21 14:11:59 -0800473void EStoraged::unmountFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800474{
475 int retval = fsIface->doUnmount(mountPoint.c_str());
Ed Tanous82897c32022-02-21 14:11:59 -0800476 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800477 {
478 lg2::error("Failed to unmount filesystem: {RETVAL}", "RETVAL", retval,
479 "REDFISH_MESSAGE_ID",
480 std::string("OpenBMC.0.1.UnmountFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800481 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800482 }
483
484 /* Remove the mount point. */
485 bool success = fsIface->removeDirectory(std::filesystem::path(mountPoint));
486 if (!success)
487 {
488 lg2::error("Failed to remove mount point {DIR}", "DIR", mountPoint,
489 "REDFISH_MESSAGE_ID",
490 std::string("OpenBMC.0.1.UnmountFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800491 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800492 }
493
494 lg2::info("Successfully unmounted filesystem at {DIR}", "DIR", mountPoint,
495 "REDFISH_MESSAGE_ID",
496 std::string("OpenBMC.0.1.MountFilesystemSuccess"));
497}
498
Ed Tanous82897c32022-02-21 14:11:59 -0800499void EStoraged::deactivateLuksDev()
John Wedigb810c922021-11-17 16:38:03 -0800500{
501 lg2::info("Deactivating LUKS device {DEV}", "DEV", devPath,
502 "REDFISH_MESSAGE_ID",
503 std::string("OpenBMC.0.1.DeactivateLuksDev"));
504
505 int retval = cryptIface->cryptDeactivate(nullptr, containerName.c_str());
506 if (retval < 0)
507 {
508 lg2::error("Failed to deactivate crypt device: {RETVAL}", "RETVAL",
509 retval, "REDFISH_MESSAGE_ID",
510 std::string("OpenBMC.0.1.DeactivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800511 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800512 }
513
John Wedigb810c922021-11-17 16:38:03 -0800514 lg2::info("Successfully deactivated LUKS device {DEV}", "DEV", devPath,
515 "REDFISH_MESSAGE_ID",
516 std::string("OpenBMC.0.1.DeactivateLuksDevSuccess"));
517}
518
John Wedig2443a022023-03-17 13:42:32 -0700519std::string_view EStoraged::getCryptDevicePath() const
John Wedig67a47442022-04-05 17:21:29 -0700520{
John Wedig2443a022023-03-17 13:42:32 -0700521 return cryptDevicePath;
John Wedig67a47442022-04-05 17:21:29 -0700522}
523
John Wedig2098dab2021-09-14 13:56:28 -0700524} // namespace estoraged