blob: 6c26e5a93ee326b131ce4e99a231129100a4c6d6 [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 Wedigc0d66eb2024-02-26 15:54:47 -080042 const std::string& driveProtocol,
John Wedig67a47442022-04-05 17:21:29 -070043 std::unique_ptr<CryptsetupInterface> cryptInterface,
44 std::unique_ptr<FilesystemInterface> fsInterface) :
45 devPath(devPath),
46 containerName(luksName), mountPoint("/mnt/" + luksName + "_fs"),
Tom Tung043af592023-11-24 13:37:05 +080047 eraseMaxGeometry(eraseMaxGeometry), eraseMinGeometry(eraseMinGeometry),
John Edward Broadbent6771c692022-06-22 19:49:27 -070048 cryptIface(std::move(cryptInterface)), 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 Williams04c28fa2023-05-10 07:51:24 -050055 std::string objectPath = "/xyz/openbmc_project/inventory/storage/" +
56 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 Williamsff1b64f2023-10-20 11:19:56 -050064 this->formatLuks(password, type);
Patrick Williams04c28fa2023-05-10 07:51:24 -050065 });
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 Williamsff1b64f2023-10-20 11:19:56 -050076 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 Williams04c28fa2023-05-10 07:51:24 -050081 value = this->isLocked();
82 return value;
Patrick Williamsff1b64f2023-10-20 11:19:56 -050083 });
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 Edward Broadbent5d799bb2022-03-22 16:14:24 -070089 driveInterface->register_property("PredictedMediaLifeLeftPercent",
90 lifeTime);
John Wedigd7be42b2024-01-19 16:07:19 -080091 driveInterface->register_property(
92 "Type",
93 "xyz.openbmc_project.Inventory.Item.Drive.DriveType." + driveType);
John Wedigc0d66eb2024-02-26 15:54:47 -080094 driveInterface->register_property(
95 "Protocol", "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol." +
96 driveProtocol);
John Edward Broadbent14aee772022-04-20 13:46:48 -070097 /* This registers the Locked property for the Drives interface.
98 * Now it is the same as the volume Locked property */
99 driveInterface->register_property_r(
100 "Locked", lockedProperty, sdbusplus::vtable::property_::emits_change,
101 [this](bool& value) {
Patrick Williams04c28fa2023-05-10 07:51:24 -0500102 value = this->isLocked();
103 return value;
Patrick Williamsff1b64f2023-10-20 11:19:56 -0500104 });
John Wedig67a47442022-04-05 17:21:29 -0700105
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700106 driveInterface->register_property_r(
107 "EncryptionStatus", encryptionStatus,
108 sdbusplus::vtable::property_::emits_change,
109 [this](Drive::DriveEncryptionState& value) {
Patrick Williams04c28fa2023-05-10 07:51:24 -0500110 value = this->findEncryptionStatus();
111 return value;
Patrick Williamsff1b64f2023-10-20 11:19:56 -0500112 });
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700113
John Edward Broadbent49796412022-06-22 18:31:52 -0700114 embeddedLocationInterface = objectServer.add_interface(
115 objectPath, "xyz.openbmc_project.Inventory.Connector.Embedded");
John Edward Broadbent740e94b2022-06-10 19:42:30 -0700116
Rahul Kapoor19825052023-05-27 01:52:23 +0000117 if (!locationCode.empty())
118 {
119 locationCodeInterface = objectServer.add_interface(
120 objectPath, "xyz.openbmc_project.Inventory.Decorator.LocationCode");
121 locationCodeInterface->register_property("LocationCode", locationCode);
122 locationCodeInterface->initialize();
123 }
124
John Wedigb4838302022-07-22 13:51:16 -0700125 /* Add Asset interface. */
126 assetInterface = objectServer.add_interface(
127 objectPath, "xyz.openbmc_project.Inventory.Decorator.Asset");
128 assetInterface->register_property("PartNumber", partNumber);
129 assetInterface->register_property("SerialNumber", serialNumber);
130
John Wedig67a47442022-04-05 17:21:29 -0700131 volumeInterface->initialize();
132 driveInterface->initialize();
John Edward Broadbent49796412022-06-22 18:31:52 -0700133 embeddedLocationInterface->initialize();
John Wedigb4838302022-07-22 13:51:16 -0700134 assetInterface->initialize();
John Wedig6c0d8ce2022-04-22 14:00:43 -0700135
136 /* Set up the association between chassis and drive. */
137 association = objectServer.add_interface(
138 objectPath, "xyz.openbmc_project.Association.Definitions");
139
140 std::vector<Association> associations;
141 associations.emplace_back("chassis", "drive",
142 std::filesystem::path(configPath).parent_path());
143 association->register_property("Associations", associations);
144 association->initialize();
John Wedig67a47442022-04-05 17:21:29 -0700145}
146
147EStoraged::~EStoraged()
148{
149 objectServer.remove_interface(volumeInterface);
150 objectServer.remove_interface(driveInterface);
John Edward Broadbent49796412022-06-22 18:31:52 -0700151 objectServer.remove_interface(embeddedLocationInterface);
John Wedigb4838302022-07-22 13:51:16 -0700152 objectServer.remove_interface(assetInterface);
John Wedig6c0d8ce2022-04-22 14:00:43 -0700153 objectServer.remove_interface(association);
Rahul Kapoor19825052023-05-27 01:52:23 +0000154
155 if (locationCodeInterface != nullptr)
156 {
157 objectServer.remove_interface(locationCodeInterface);
158 }
John Wedig67a47442022-04-05 17:21:29 -0700159}
160
161void EStoraged::formatLuks(const std::vector<uint8_t>& password,
162 Volume::FilesystemType type)
John Wedig2098dab2021-09-14 13:56:28 -0700163{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800164 std::string msg = "OpenBMC.0.1.DriveFormat";
165 lg2::info("Starting format", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800166
John Wedig67a47442022-04-05 17:21:29 -0700167 if (type != Volume::FilesystemType::ext4)
John Wedig972c3fa2021-12-29 17:30:41 -0800168 {
169 lg2::error("Only ext4 filesystems are supported currently",
170 "REDFISH_MESSAGE_ID", std::string("OpenBMC.0.1.FormatFail"));
171 throw UnsupportedRequest();
172 }
173
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700174 formatLuksDev(password);
175 activateLuksDev(password);
John Wedigb810c922021-11-17 16:38:03 -0800176
177 createFilesystem();
178 mountFilesystem();
John Wedig2098dab2021-09-14 13:56:28 -0700179}
180
John Wedig67a47442022-04-05 17:21:29 -0700181void EStoraged::erase(Volume::EraseMethod inEraseMethod)
John Wedig2098dab2021-09-14 13:56:28 -0700182{
183 std::cerr << "Erasing encrypted eMMC" << std::endl;
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700184 lg2::info("Starting erase", "REDFISH_MESSAGE_ID",
185 std::string("OpenBMC.0.1.DriveErase"));
186 switch (inEraseMethod)
187 {
John Wedig67a47442022-04-05 17:21:29 -0700188 case Volume::EraseMethod::CryptoErase:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700189 {
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800190 CryptErase myCryptErase(devPath);
191 myCryptErase.doErase();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700192 break;
193 }
John Wedig67a47442022-04-05 17:21:29 -0700194 case Volume::EraseMethod::VerifyGeometry:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700195 {
196 VerifyDriveGeometry myVerifyGeometry(devPath);
Tom Tung043af592023-11-24 13:37:05 +0800197 myVerifyGeometry.geometryOkay(eraseMaxGeometry, eraseMinGeometry);
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700198 break;
199 }
John Wedig67a47442022-04-05 17:21:29 -0700200 case Volume::EraseMethod::LogicalOverWrite:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700201 {
John Edward Broadbent7f2ab642021-11-11 21:00:38 -0800202 Pattern myErasePattern(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700203 myErasePattern.writePattern();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700204 break;
205 }
John Wedig67a47442022-04-05 17:21:29 -0700206 case Volume::EraseMethod::LogicalVerify:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700207 {
John Edward Broadbent7f2ab642021-11-11 21:00:38 -0800208 Pattern myErasePattern(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700209 myErasePattern.verifyPattern();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700210 break;
211 }
John Wedig67a47442022-04-05 17:21:29 -0700212 case Volume::EraseMethod::VendorSanitize:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700213 {
John Edward Broadbent605085a2021-11-05 13:45:45 -0700214 Sanitize mySanitize(devPath);
215 mySanitize.doSanitize();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700216 break;
217 }
John Wedig67a47442022-04-05 17:21:29 -0700218 case Volume::EraseMethod::ZeroOverWrite:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700219 {
John Edward Broadbent4bc8a102021-12-30 16:11:49 -0800220 Zero myZero(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700221 myZero.writeZero();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700222 break;
223 }
John Wedig67a47442022-04-05 17:21:29 -0700224 case Volume::EraseMethod::ZeroVerify:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700225 {
John Edward Broadbent4bc8a102021-12-30 16:11:49 -0800226 Zero myZero(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700227 myZero.verifyZero();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700228 break;
229 }
John Wedig67a47442022-04-05 17:21:29 -0700230 case Volume::EraseMethod::SecuredLocked:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700231 {
John Wedig47cd7992022-10-05 15:45:11 -0700232 if (!isLocked())
John Edward Broadbentf59b7292022-02-15 15:07:15 -0800233 {
234 lock();
235 }
236 // TODO: implement hardware locking
237 // Until that is done, we can lock using eStoraged::lock()
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700238 break;
239 }
240 }
John Wedig2098dab2021-09-14 13:56:28 -0700241}
242
Ed Tanous82897c32022-02-21 14:11:59 -0800243void EStoraged::lock()
John Wedig2098dab2021-09-14 13:56:28 -0700244{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800245 std::string msg = "OpenBMC.0.1.DriveLock";
246 lg2::info("Starting lock", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800247
248 unmountFilesystem();
249 deactivateLuksDev();
John Wedig2098dab2021-09-14 13:56:28 -0700250}
251
Ed Tanous82897c32022-02-21 14:11:59 -0800252void EStoraged::unlock(std::vector<uint8_t> password)
John Wedig2098dab2021-09-14 13:56:28 -0700253{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800254 std::string msg = "OpenBMC.0.1.DriveUnlock";
255 lg2::info("Starting unlock", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800256
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700257 activateLuksDev(std::move(password));
John Wedigb810c922021-11-17 16:38:03 -0800258 mountFilesystem();
John Wedig2098dab2021-09-14 13:56:28 -0700259}
260
John Wedig8d5a3a02022-09-29 15:25:58 -0700261void EStoraged::changePassword(const std::vector<uint8_t>& oldPassword,
262 const std::vector<uint8_t>& newPassword)
John Wedig2098dab2021-09-14 13:56:28 -0700263{
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700264 lg2::info("Starting change password", "REDFISH_MESSAGE_ID",
265 std::string("OpenBMC.0.1.DrivePasswordChanged"));
John Wedig8d5a3a02022-09-29 15:25:58 -0700266
267 CryptHandle cryptHandle = loadLuksHeader();
268
269 int retval = cryptIface->cryptKeyslotChangeByPassphrase(
270 cryptHandle.get(), CRYPT_ANY_SLOT, CRYPT_ANY_SLOT,
271 reinterpret_cast<const char*>(oldPassword.data()), oldPassword.size(),
272 reinterpret_cast<const char*>(newPassword.data()), newPassword.size());
273 if (retval < 0)
274 {
275 lg2::error("Failed to change password", "REDFISH_MESSAGE_ID",
276 std::string("OpenBMC.0.1.DrivePasswordChangeFail"));
277 throw InternalFailure();
278 }
279
280 lg2::info("Successfully changed password for {DEV}", "DEV", devPath,
281 "REDFISH_MESSAGE_ID",
282 std::string("OpenBMC.0.1.DrivePasswordChangeSuccess"));
John Wedig2098dab2021-09-14 13:56:28 -0700283}
284
Ed Tanous82897c32022-02-21 14:11:59 -0800285bool EStoraged::isLocked() const
John Wedigb810c922021-11-17 16:38:03 -0800286{
John Wedig2443a022023-03-17 13:42:32 -0700287 /*
288 * Check if the mapped virtual device exists. If it exists, the LUKS volume
289 * is unlocked.
290 */
291 try
292 {
293 std::filesystem::path mappedDevicePath(cryptDevicePath);
294 return (std::filesystem::exists(mappedDevicePath) == false);
295 }
296 catch (const std::exception& e)
297 {
298 lg2::error("Failed to query locked status: {EXCEPT}", "EXCEPT",
299 e.what(), "REDFISH_MESSAGE_ID",
300 std::string("OpenBMC.0.1.IsLockedFail"));
301 /* If we couldn't query the filesystem path, assume unlocked. */
302 return false;
303 }
John Wedigb810c922021-11-17 16:38:03 -0800304}
305
Ed Tanous82897c32022-02-21 14:11:59 -0800306std::string_view EStoraged::getMountPoint() const
John Wedigb810c922021-11-17 16:38:03 -0800307{
308 return mountPoint;
309}
310
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700311void EStoraged::formatLuksDev(std::vector<uint8_t> password)
John Wedigb810c922021-11-17 16:38:03 -0800312{
313 lg2::info("Formatting device {DEV}", "DEV", devPath, "REDFISH_MESSAGE_ID",
314 std::string("OpenBMC.0.1.FormatLuksDev"));
315
316 /* Generate the volume key. */
317 const std::size_t keySize = 64;
318 std::vector<uint8_t> volumeKey(keySize);
319 if (RAND_bytes(volumeKey.data(), keySize) != 1)
320 {
321 lg2::error("Failed to create volume key", "REDFISH_MESSAGE_ID",
322 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800323 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800324 }
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700325
326 /* Create the handle. */
327 CryptHandle cryptHandle(devPath);
328
John Wedigb810c922021-11-17 16:38:03 -0800329 /* Format the LUKS encrypted device. */
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700330 int retval = cryptIface->cryptFormat(
331 cryptHandle.get(), CRYPT_LUKS2, "aes", "xts-plain64", nullptr,
332 reinterpret_cast<const char*>(volumeKey.data()), volumeKey.size(),
333 nullptr);
John Wedigb810c922021-11-17 16:38:03 -0800334 if (retval < 0)
335 {
336 lg2::error("Failed to format encrypted device: {RETVAL}", "RETVAL",
337 retval, "REDFISH_MESSAGE_ID",
338 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800339 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800340 }
341
John Wedigb810c922021-11-17 16:38:03 -0800342 /* Set the password. */
343 retval = cryptIface->cryptKeyslotAddByVolumeKey(
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700344 cryptHandle.get(), CRYPT_ANY_SLOT, nullptr, 0,
John Wedigb810c922021-11-17 16:38:03 -0800345 reinterpret_cast<const char*>(password.data()), password.size());
346
347 if (retval < 0)
348 {
349 lg2::error("Failed to set encryption password", "REDFISH_MESSAGE_ID",
350 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800351 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800352 }
353
354 lg2::info("Encrypted device {DEV} successfully formatted", "DEV", devPath,
355 "REDFISH_MESSAGE_ID",
356 std::string("OpenBMC.0.1.FormatLuksDevSuccess"));
357}
358
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700359CryptHandle EStoraged::loadLuksHeader()
John Wedigb810c922021-11-17 16:38:03 -0800360{
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700361 CryptHandle cryptHandle(devPath);
362
363 int retval = cryptIface->cryptLoad(cryptHandle.get(), CRYPT_LUKS2, nullptr);
John Wedigb810c922021-11-17 16:38:03 -0800364 if (retval < 0)
365 {
366 lg2::error("Failed to load LUKS header: {RETVAL}", "RETVAL", retval,
367 "REDFISH_MESSAGE_ID",
368 std::string("OpenBMC.0.1.ActivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800369 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800370 }
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700371 return cryptHandle;
372}
John Wedigb810c922021-11-17 16:38:03 -0800373
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700374Drive::DriveEncryptionState EStoraged::findEncryptionStatus()
375{
376 try
377 {
378 loadLuksHeader();
379 return Drive::DriveEncryptionState::Encrypted;
380 }
381 catch (...)
382 {
Hao Zhou0cec4282024-03-12 22:16:16 +0000383 return Drive::DriveEncryptionState::Unencrypted;
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700384 }
385}
386
387void EStoraged::activateLuksDev(std::vector<uint8_t> password)
388{
389 lg2::info("Activating LUKS dev {DEV}", "DEV", devPath, "REDFISH_MESSAGE_ID",
390 std::string("OpenBMC.0.1.ActivateLuksDev"));
391
392 /* Create the handle. */
393 CryptHandle cryptHandle = loadLuksHeader();
394
395 int retval = cryptIface->cryptActivateByPassphrase(
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700396 cryptHandle.get(), containerName.c_str(), CRYPT_ANY_SLOT,
John Wedigb810c922021-11-17 16:38:03 -0800397 reinterpret_cast<const char*>(password.data()), password.size(), 0);
398
399 if (retval < 0)
400 {
401 lg2::error("Failed to activate LUKS dev: {RETVAL}", "RETVAL", retval,
402 "REDFISH_MESSAGE_ID",
403 std::string("OpenBMC.0.1.ActivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800404 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800405 }
406
John Wedigb810c922021-11-17 16:38:03 -0800407 lg2::info("Successfully activated LUKS dev {DEV}", "DEV", devPath,
408 "REDFISH_MESSAGE_ID",
409 std::string("OpenBMC.0.1.ActivateLuksDevSuccess"));
410}
411
Ed Tanous82897c32022-02-21 14:11:59 -0800412void EStoraged::createFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800413{
414 /* Run the command to create the filesystem. */
John Wedig2443a022023-03-17 13:42:32 -0700415 int retval = fsIface->runMkfs(cryptDevicePath);
Ed Tanous82897c32022-02-21 14:11:59 -0800416 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800417 {
418 lg2::error("Failed to create filesystem: {RETVAL}", "RETVAL", retval,
419 "REDFISH_MESSAGE_ID",
420 std::string("OpenBMC.0.1.CreateFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800421 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800422 }
John Wedig2443a022023-03-17 13:42:32 -0700423 lg2::info("Successfully created filesystem for {CONTAINER}", "CONTAINER",
424 cryptDevicePath, "REDFISH_MESSAGE_ID",
John Wedigb810c922021-11-17 16:38:03 -0800425 std::string("OpenBMC.0.1.CreateFilesystemSuccess"));
426}
427
Ed Tanous82897c32022-02-21 14:11:59 -0800428void EStoraged::mountFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800429{
John Wedigb17f8252022-01-12 14:24:26 -0800430 /*
431 * Create directory for the filesystem, if it's not already present. It
432 * might already exist if, for example, the BMC reboots after creating the
433 * directory.
434 */
435 if (!fsIface->directoryExists(std::filesystem::path(mountPoint)))
John Wedigb810c922021-11-17 16:38:03 -0800436 {
John Wedigb17f8252022-01-12 14:24:26 -0800437 bool success =
438 fsIface->createDirectory(std::filesystem::path(mountPoint));
439 if (!success)
440 {
441 lg2::error("Failed to create mount point: {DIR}", "DIR", mountPoint,
442 "REDFISH_MESSAGE_ID",
443 std::string("OpenBMC.0.1.MountFilesystemFail"));
444 throw InternalFailure();
445 }
John Wedigb810c922021-11-17 16:38:03 -0800446 }
447
448 /* Run the command to mount the filesystem. */
John Wedig2443a022023-03-17 13:42:32 -0700449 int retval = fsIface->doMount(cryptDevicePath.c_str(), mountPoint.c_str(),
John Wedigb810c922021-11-17 16:38:03 -0800450 "ext4", 0, nullptr);
Ed Tanous82897c32022-02-21 14:11:59 -0800451 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800452 {
453 lg2::error("Failed to mount filesystem: {RETVAL}", "RETVAL", retval,
454 "REDFISH_MESSAGE_ID",
455 std::string("OpenBMC.0.1.MountFilesystemFail"));
456 bool removeSuccess =
457 fsIface->removeDirectory(std::filesystem::path(mountPoint));
458 if (!removeSuccess)
459 {
460 lg2::error("Failed to remove mount point: {DIR}", "DIR", mountPoint,
461 "REDFISH_MESSAGE_ID",
462 std::string("OpenBMC.0.1.MountFilesystemFail"));
463 }
John Wedig972c3fa2021-12-29 17:30:41 -0800464 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800465 }
466
467 lg2::info("Successfully mounted filesystem at {DIR}", "DIR", mountPoint,
468 "REDFISH_MESSAGE_ID",
469 std::string("OpenBMC.0.1.MountFilesystemSuccess"));
470}
471
Ed Tanous82897c32022-02-21 14:11:59 -0800472void EStoraged::unmountFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800473{
474 int retval = fsIface->doUnmount(mountPoint.c_str());
Ed Tanous82897c32022-02-21 14:11:59 -0800475 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800476 {
477 lg2::error("Failed to unmount filesystem: {RETVAL}", "RETVAL", retval,
478 "REDFISH_MESSAGE_ID",
479 std::string("OpenBMC.0.1.UnmountFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800480 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800481 }
482
483 /* Remove the mount point. */
484 bool success = fsIface->removeDirectory(std::filesystem::path(mountPoint));
485 if (!success)
486 {
487 lg2::error("Failed to remove mount point {DIR}", "DIR", mountPoint,
488 "REDFISH_MESSAGE_ID",
489 std::string("OpenBMC.0.1.UnmountFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800490 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800491 }
492
493 lg2::info("Successfully unmounted filesystem at {DIR}", "DIR", mountPoint,
494 "REDFISH_MESSAGE_ID",
495 std::string("OpenBMC.0.1.MountFilesystemSuccess"));
496}
497
Ed Tanous82897c32022-02-21 14:11:59 -0800498void EStoraged::deactivateLuksDev()
John Wedigb810c922021-11-17 16:38:03 -0800499{
500 lg2::info("Deactivating LUKS device {DEV}", "DEV", devPath,
501 "REDFISH_MESSAGE_ID",
502 std::string("OpenBMC.0.1.DeactivateLuksDev"));
503
504 int retval = cryptIface->cryptDeactivate(nullptr, containerName.c_str());
505 if (retval < 0)
506 {
507 lg2::error("Failed to deactivate crypt device: {RETVAL}", "RETVAL",
508 retval, "REDFISH_MESSAGE_ID",
509 std::string("OpenBMC.0.1.DeactivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800510 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800511 }
512
John Wedigb810c922021-11-17 16:38:03 -0800513 lg2::info("Successfully deactivated LUKS device {DEV}", "DEV", devPath,
514 "REDFISH_MESSAGE_ID",
515 std::string("OpenBMC.0.1.DeactivateLuksDevSuccess"));
516}
517
John Wedig2443a022023-03-17 13:42:32 -0700518std::string_view EStoraged::getCryptDevicePath() const
John Wedig67a47442022-04-05 17:21:29 -0700519{
John Wedig2443a022023-03-17 13:42:32 -0700520 return cryptDevicePath;
John Wedig67a47442022-04-05 17:21:29 -0700521}
522
John Wedig2098dab2021-09-14 13:56:28 -0700523} // namespace estoraged