blob: f9c69dc396ba60dd5cf380e739687a5a95e0e1dc [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,
41 uint64_t eraseMinGeometry,
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 Edward Broadbent14aee772022-04-20 13:46:48 -070090 /* This registers the Locked property for the Drives interface.
91 * Now it is the same as the volume Locked property */
92 driveInterface->register_property_r(
93 "Locked", lockedProperty, sdbusplus::vtable::property_::emits_change,
94 [this](bool& value) {
Patrick Williams04c28fa2023-05-10 07:51:24 -050095 value = this->isLocked();
96 return value;
Patrick Williamsff1b64f2023-10-20 11:19:56 -050097 });
John Wedig67a47442022-04-05 17:21:29 -070098
John Edward Broadbent91c1ec12022-05-20 16:51:43 -070099 driveInterface->register_property_r(
100 "EncryptionStatus", encryptionStatus,
101 sdbusplus::vtable::property_::emits_change,
102 [this](Drive::DriveEncryptionState& value) {
Patrick Williams04c28fa2023-05-10 07:51:24 -0500103 value = this->findEncryptionStatus();
104 return value;
Patrick Williamsff1b64f2023-10-20 11:19:56 -0500105 });
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700106
John Edward Broadbent49796412022-06-22 18:31:52 -0700107 embeddedLocationInterface = objectServer.add_interface(
108 objectPath, "xyz.openbmc_project.Inventory.Connector.Embedded");
John Edward Broadbent740e94b2022-06-10 19:42:30 -0700109
Rahul Kapoor19825052023-05-27 01:52:23 +0000110 if (!locationCode.empty())
111 {
112 locationCodeInterface = objectServer.add_interface(
113 objectPath, "xyz.openbmc_project.Inventory.Decorator.LocationCode");
114 locationCodeInterface->register_property("LocationCode", locationCode);
115 locationCodeInterface->initialize();
116 }
117
John Wedigb4838302022-07-22 13:51:16 -0700118 /* Add Asset interface. */
119 assetInterface = objectServer.add_interface(
120 objectPath, "xyz.openbmc_project.Inventory.Decorator.Asset");
121 assetInterface->register_property("PartNumber", partNumber);
122 assetInterface->register_property("SerialNumber", serialNumber);
123
John Wedig67a47442022-04-05 17:21:29 -0700124 volumeInterface->initialize();
125 driveInterface->initialize();
John Edward Broadbent49796412022-06-22 18:31:52 -0700126 embeddedLocationInterface->initialize();
John Wedigb4838302022-07-22 13:51:16 -0700127 assetInterface->initialize();
John Wedig6c0d8ce2022-04-22 14:00:43 -0700128
129 /* Set up the association between chassis and drive. */
130 association = objectServer.add_interface(
131 objectPath, "xyz.openbmc_project.Association.Definitions");
132
133 std::vector<Association> associations;
134 associations.emplace_back("chassis", "drive",
135 std::filesystem::path(configPath).parent_path());
136 association->register_property("Associations", associations);
137 association->initialize();
John Wedig67a47442022-04-05 17:21:29 -0700138}
139
140EStoraged::~EStoraged()
141{
142 objectServer.remove_interface(volumeInterface);
143 objectServer.remove_interface(driveInterface);
John Edward Broadbent49796412022-06-22 18:31:52 -0700144 objectServer.remove_interface(embeddedLocationInterface);
John Wedigb4838302022-07-22 13:51:16 -0700145 objectServer.remove_interface(assetInterface);
John Wedig6c0d8ce2022-04-22 14:00:43 -0700146 objectServer.remove_interface(association);
Rahul Kapoor19825052023-05-27 01:52:23 +0000147
148 if (locationCodeInterface != nullptr)
149 {
150 objectServer.remove_interface(locationCodeInterface);
151 }
John Wedig67a47442022-04-05 17:21:29 -0700152}
153
154void EStoraged::formatLuks(const std::vector<uint8_t>& password,
155 Volume::FilesystemType type)
John Wedig2098dab2021-09-14 13:56:28 -0700156{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800157 std::string msg = "OpenBMC.0.1.DriveFormat";
158 lg2::info("Starting format", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800159
John Wedig67a47442022-04-05 17:21:29 -0700160 if (type != Volume::FilesystemType::ext4)
John Wedig972c3fa2021-12-29 17:30:41 -0800161 {
162 lg2::error("Only ext4 filesystems are supported currently",
163 "REDFISH_MESSAGE_ID", std::string("OpenBMC.0.1.FormatFail"));
164 throw UnsupportedRequest();
165 }
166
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700167 formatLuksDev(password);
168 activateLuksDev(password);
John Wedigb810c922021-11-17 16:38:03 -0800169
170 createFilesystem();
171 mountFilesystem();
John Wedig2098dab2021-09-14 13:56:28 -0700172}
173
John Wedig67a47442022-04-05 17:21:29 -0700174void EStoraged::erase(Volume::EraseMethod inEraseMethod)
John Wedig2098dab2021-09-14 13:56:28 -0700175{
176 std::cerr << "Erasing encrypted eMMC" << std::endl;
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700177 lg2::info("Starting erase", "REDFISH_MESSAGE_ID",
178 std::string("OpenBMC.0.1.DriveErase"));
179 switch (inEraseMethod)
180 {
John Wedig67a47442022-04-05 17:21:29 -0700181 case Volume::EraseMethod::CryptoErase:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700182 {
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800183 CryptErase myCryptErase(devPath);
184 myCryptErase.doErase();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700185 break;
186 }
John Wedig67a47442022-04-05 17:21:29 -0700187 case Volume::EraseMethod::VerifyGeometry:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700188 {
189 VerifyDriveGeometry myVerifyGeometry(devPath);
Tom Tung043af592023-11-24 13:37:05 +0800190 myVerifyGeometry.geometryOkay(eraseMaxGeometry, eraseMinGeometry);
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700191 break;
192 }
John Wedig67a47442022-04-05 17:21:29 -0700193 case Volume::EraseMethod::LogicalOverWrite:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700194 {
John Edward Broadbent7f2ab642021-11-11 21:00:38 -0800195 Pattern myErasePattern(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700196 myErasePattern.writePattern();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700197 break;
198 }
John Wedig67a47442022-04-05 17:21:29 -0700199 case Volume::EraseMethod::LogicalVerify:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700200 {
John Edward Broadbent7f2ab642021-11-11 21:00:38 -0800201 Pattern myErasePattern(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700202 myErasePattern.verifyPattern();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700203 break;
204 }
John Wedig67a47442022-04-05 17:21:29 -0700205 case Volume::EraseMethod::VendorSanitize:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700206 {
John Edward Broadbent605085a2021-11-05 13:45:45 -0700207 Sanitize mySanitize(devPath);
208 mySanitize.doSanitize();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700209 break;
210 }
John Wedig67a47442022-04-05 17:21:29 -0700211 case Volume::EraseMethod::ZeroOverWrite:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700212 {
John Edward Broadbent4bc8a102021-12-30 16:11:49 -0800213 Zero myZero(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700214 myZero.writeZero();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700215 break;
216 }
John Wedig67a47442022-04-05 17:21:29 -0700217 case Volume::EraseMethod::ZeroVerify:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700218 {
John Edward Broadbent4bc8a102021-12-30 16:11:49 -0800219 Zero myZero(devPath);
John Edward Broadbenta6e3b992022-03-17 14:33:15 -0700220 myZero.verifyZero();
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700221 break;
222 }
John Wedig67a47442022-04-05 17:21:29 -0700223 case Volume::EraseMethod::SecuredLocked:
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700224 {
John Wedig47cd7992022-10-05 15:45:11 -0700225 if (!isLocked())
John Edward Broadbentf59b7292022-02-15 15:07:15 -0800226 {
227 lock();
228 }
229 // TODO: implement hardware locking
230 // Until that is done, we can lock using eStoraged::lock()
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700231 break;
232 }
233 }
John Wedig2098dab2021-09-14 13:56:28 -0700234}
235
Ed Tanous82897c32022-02-21 14:11:59 -0800236void EStoraged::lock()
John Wedig2098dab2021-09-14 13:56:28 -0700237{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800238 std::string msg = "OpenBMC.0.1.DriveLock";
239 lg2::info("Starting lock", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800240
241 unmountFilesystem();
242 deactivateLuksDev();
John Wedig2098dab2021-09-14 13:56:28 -0700243}
244
Ed Tanous82897c32022-02-21 14:11:59 -0800245void EStoraged::unlock(std::vector<uint8_t> password)
John Wedig2098dab2021-09-14 13:56:28 -0700246{
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -0800247 std::string msg = "OpenBMC.0.1.DriveUnlock";
248 lg2::info("Starting unlock", "REDFISH_MESSAGE_ID", msg);
John Wedigb810c922021-11-17 16:38:03 -0800249
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700250 activateLuksDev(std::move(password));
John Wedigb810c922021-11-17 16:38:03 -0800251 mountFilesystem();
John Wedig2098dab2021-09-14 13:56:28 -0700252}
253
John Wedig8d5a3a02022-09-29 15:25:58 -0700254void EStoraged::changePassword(const std::vector<uint8_t>& oldPassword,
255 const std::vector<uint8_t>& newPassword)
John Wedig2098dab2021-09-14 13:56:28 -0700256{
John Edward Broadbente6ffe702021-10-14 14:03:11 -0700257 lg2::info("Starting change password", "REDFISH_MESSAGE_ID",
258 std::string("OpenBMC.0.1.DrivePasswordChanged"));
John Wedig8d5a3a02022-09-29 15:25:58 -0700259
260 CryptHandle cryptHandle = loadLuksHeader();
261
262 int retval = cryptIface->cryptKeyslotChangeByPassphrase(
263 cryptHandle.get(), CRYPT_ANY_SLOT, CRYPT_ANY_SLOT,
264 reinterpret_cast<const char*>(oldPassword.data()), oldPassword.size(),
265 reinterpret_cast<const char*>(newPassword.data()), newPassword.size());
266 if (retval < 0)
267 {
268 lg2::error("Failed to change password", "REDFISH_MESSAGE_ID",
269 std::string("OpenBMC.0.1.DrivePasswordChangeFail"));
270 throw InternalFailure();
271 }
272
273 lg2::info("Successfully changed password for {DEV}", "DEV", devPath,
274 "REDFISH_MESSAGE_ID",
275 std::string("OpenBMC.0.1.DrivePasswordChangeSuccess"));
John Wedig2098dab2021-09-14 13:56:28 -0700276}
277
Ed Tanous82897c32022-02-21 14:11:59 -0800278bool EStoraged::isLocked() const
John Wedigb810c922021-11-17 16:38:03 -0800279{
John Wedig2443a022023-03-17 13:42:32 -0700280 /*
281 * Check if the mapped virtual device exists. If it exists, the LUKS volume
282 * is unlocked.
283 */
284 try
285 {
286 std::filesystem::path mappedDevicePath(cryptDevicePath);
287 return (std::filesystem::exists(mappedDevicePath) == false);
288 }
289 catch (const std::exception& e)
290 {
291 lg2::error("Failed to query locked status: {EXCEPT}", "EXCEPT",
292 e.what(), "REDFISH_MESSAGE_ID",
293 std::string("OpenBMC.0.1.IsLockedFail"));
294 /* If we couldn't query the filesystem path, assume unlocked. */
295 return false;
296 }
John Wedigb810c922021-11-17 16:38:03 -0800297}
298
Ed Tanous82897c32022-02-21 14:11:59 -0800299std::string_view EStoraged::getMountPoint() const
John Wedigb810c922021-11-17 16:38:03 -0800300{
301 return mountPoint;
302}
303
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700304void EStoraged::formatLuksDev(std::vector<uint8_t> password)
John Wedigb810c922021-11-17 16:38:03 -0800305{
306 lg2::info("Formatting device {DEV}", "DEV", devPath, "REDFISH_MESSAGE_ID",
307 std::string("OpenBMC.0.1.FormatLuksDev"));
308
309 /* Generate the volume key. */
310 const std::size_t keySize = 64;
311 std::vector<uint8_t> volumeKey(keySize);
312 if (RAND_bytes(volumeKey.data(), keySize) != 1)
313 {
314 lg2::error("Failed to create volume key", "REDFISH_MESSAGE_ID",
315 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800316 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800317 }
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700318
319 /* Create the handle. */
320 CryptHandle cryptHandle(devPath);
321
John Wedigb810c922021-11-17 16:38:03 -0800322 /* Format the LUKS encrypted device. */
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700323 int retval = cryptIface->cryptFormat(
324 cryptHandle.get(), CRYPT_LUKS2, "aes", "xts-plain64", nullptr,
325 reinterpret_cast<const char*>(volumeKey.data()), volumeKey.size(),
326 nullptr);
John Wedigb810c922021-11-17 16:38:03 -0800327 if (retval < 0)
328 {
329 lg2::error("Failed to format encrypted device: {RETVAL}", "RETVAL",
330 retval, "REDFISH_MESSAGE_ID",
331 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800332 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800333 }
334
John Wedigb810c922021-11-17 16:38:03 -0800335 /* Set the password. */
336 retval = cryptIface->cryptKeyslotAddByVolumeKey(
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700337 cryptHandle.get(), CRYPT_ANY_SLOT, nullptr, 0,
John Wedigb810c922021-11-17 16:38:03 -0800338 reinterpret_cast<const char*>(password.data()), password.size());
339
340 if (retval < 0)
341 {
342 lg2::error("Failed to set encryption password", "REDFISH_MESSAGE_ID",
343 std::string("OpenBMC.0.1.FormatLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800344 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800345 }
346
347 lg2::info("Encrypted device {DEV} successfully formatted", "DEV", devPath,
348 "REDFISH_MESSAGE_ID",
349 std::string("OpenBMC.0.1.FormatLuksDevSuccess"));
350}
351
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700352CryptHandle EStoraged::loadLuksHeader()
John Wedigb810c922021-11-17 16:38:03 -0800353{
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700354 CryptHandle cryptHandle(devPath);
355
356 int retval = cryptIface->cryptLoad(cryptHandle.get(), CRYPT_LUKS2, nullptr);
John Wedigb810c922021-11-17 16:38:03 -0800357 if (retval < 0)
358 {
359 lg2::error("Failed to load LUKS header: {RETVAL}", "RETVAL", retval,
360 "REDFISH_MESSAGE_ID",
361 std::string("OpenBMC.0.1.ActivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800362 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800363 }
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700364 return cryptHandle;
365}
John Wedigb810c922021-11-17 16:38:03 -0800366
John Edward Broadbent91c1ec12022-05-20 16:51:43 -0700367Drive::DriveEncryptionState EStoraged::findEncryptionStatus()
368{
369 try
370 {
371 loadLuksHeader();
372 return Drive::DriveEncryptionState::Encrypted;
373 }
374 catch (...)
375 {
376 return Drive::DriveEncryptionState::Unknown;
377 }
378}
379
380void EStoraged::activateLuksDev(std::vector<uint8_t> password)
381{
382 lg2::info("Activating LUKS dev {DEV}", "DEV", devPath, "REDFISH_MESSAGE_ID",
383 std::string("OpenBMC.0.1.ActivateLuksDev"));
384
385 /* Create the handle. */
386 CryptHandle cryptHandle = loadLuksHeader();
387
388 int retval = cryptIface->cryptActivateByPassphrase(
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700389 cryptHandle.get(), containerName.c_str(), CRYPT_ANY_SLOT,
John Wedigb810c922021-11-17 16:38:03 -0800390 reinterpret_cast<const char*>(password.data()), password.size(), 0);
391
392 if (retval < 0)
393 {
394 lg2::error("Failed to activate LUKS dev: {RETVAL}", "RETVAL", retval,
395 "REDFISH_MESSAGE_ID",
396 std::string("OpenBMC.0.1.ActivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800397 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800398 }
399
John Wedigb810c922021-11-17 16:38:03 -0800400 lg2::info("Successfully activated LUKS dev {DEV}", "DEV", devPath,
401 "REDFISH_MESSAGE_ID",
402 std::string("OpenBMC.0.1.ActivateLuksDevSuccess"));
403}
404
Ed Tanous82897c32022-02-21 14:11:59 -0800405void EStoraged::createFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800406{
407 /* Run the command to create the filesystem. */
John Wedig2443a022023-03-17 13:42:32 -0700408 int retval = fsIface->runMkfs(cryptDevicePath);
Ed Tanous82897c32022-02-21 14:11:59 -0800409 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800410 {
411 lg2::error("Failed to create filesystem: {RETVAL}", "RETVAL", retval,
412 "REDFISH_MESSAGE_ID",
413 std::string("OpenBMC.0.1.CreateFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800414 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800415 }
John Wedig2443a022023-03-17 13:42:32 -0700416 lg2::info("Successfully created filesystem for {CONTAINER}", "CONTAINER",
417 cryptDevicePath, "REDFISH_MESSAGE_ID",
John Wedigb810c922021-11-17 16:38:03 -0800418 std::string("OpenBMC.0.1.CreateFilesystemSuccess"));
419}
420
Ed Tanous82897c32022-02-21 14:11:59 -0800421void EStoraged::mountFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800422{
John Wedigb17f8252022-01-12 14:24:26 -0800423 /*
424 * Create directory for the filesystem, if it's not already present. It
425 * might already exist if, for example, the BMC reboots after creating the
426 * directory.
427 */
428 if (!fsIface->directoryExists(std::filesystem::path(mountPoint)))
John Wedigb810c922021-11-17 16:38:03 -0800429 {
John Wedigb17f8252022-01-12 14:24:26 -0800430 bool success =
431 fsIface->createDirectory(std::filesystem::path(mountPoint));
432 if (!success)
433 {
434 lg2::error("Failed to create mount point: {DIR}", "DIR", mountPoint,
435 "REDFISH_MESSAGE_ID",
436 std::string("OpenBMC.0.1.MountFilesystemFail"));
437 throw InternalFailure();
438 }
John Wedigb810c922021-11-17 16:38:03 -0800439 }
440
441 /* Run the command to mount the filesystem. */
John Wedig2443a022023-03-17 13:42:32 -0700442 int retval = fsIface->doMount(cryptDevicePath.c_str(), mountPoint.c_str(),
John Wedigb810c922021-11-17 16:38:03 -0800443 "ext4", 0, nullptr);
Ed Tanous82897c32022-02-21 14:11:59 -0800444 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800445 {
446 lg2::error("Failed to mount filesystem: {RETVAL}", "RETVAL", retval,
447 "REDFISH_MESSAGE_ID",
448 std::string("OpenBMC.0.1.MountFilesystemFail"));
449 bool removeSuccess =
450 fsIface->removeDirectory(std::filesystem::path(mountPoint));
451 if (!removeSuccess)
452 {
453 lg2::error("Failed to remove mount point: {DIR}", "DIR", mountPoint,
454 "REDFISH_MESSAGE_ID",
455 std::string("OpenBMC.0.1.MountFilesystemFail"));
456 }
John Wedig972c3fa2021-12-29 17:30:41 -0800457 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800458 }
459
460 lg2::info("Successfully mounted filesystem at {DIR}", "DIR", mountPoint,
461 "REDFISH_MESSAGE_ID",
462 std::string("OpenBMC.0.1.MountFilesystemSuccess"));
463}
464
Ed Tanous82897c32022-02-21 14:11:59 -0800465void EStoraged::unmountFilesystem()
John Wedigb810c922021-11-17 16:38:03 -0800466{
467 int retval = fsIface->doUnmount(mountPoint.c_str());
Ed Tanous82897c32022-02-21 14:11:59 -0800468 if (retval != 0)
John Wedigb810c922021-11-17 16:38:03 -0800469 {
470 lg2::error("Failed to unmount filesystem: {RETVAL}", "RETVAL", retval,
471 "REDFISH_MESSAGE_ID",
472 std::string("OpenBMC.0.1.UnmountFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800473 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800474 }
475
476 /* Remove the mount point. */
477 bool success = fsIface->removeDirectory(std::filesystem::path(mountPoint));
478 if (!success)
479 {
480 lg2::error("Failed to remove mount point {DIR}", "DIR", mountPoint,
481 "REDFISH_MESSAGE_ID",
482 std::string("OpenBMC.0.1.UnmountFilesystemFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800483 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800484 }
485
486 lg2::info("Successfully unmounted filesystem at {DIR}", "DIR", mountPoint,
487 "REDFISH_MESSAGE_ID",
488 std::string("OpenBMC.0.1.MountFilesystemSuccess"));
489}
490
Ed Tanous82897c32022-02-21 14:11:59 -0800491void EStoraged::deactivateLuksDev()
John Wedigb810c922021-11-17 16:38:03 -0800492{
493 lg2::info("Deactivating LUKS device {DEV}", "DEV", devPath,
494 "REDFISH_MESSAGE_ID",
495 std::string("OpenBMC.0.1.DeactivateLuksDev"));
496
497 int retval = cryptIface->cryptDeactivate(nullptr, containerName.c_str());
498 if (retval < 0)
499 {
500 lg2::error("Failed to deactivate crypt device: {RETVAL}", "RETVAL",
501 retval, "REDFISH_MESSAGE_ID",
502 std::string("OpenBMC.0.1.DeactivateLuksDevFail"));
John Wedig972c3fa2021-12-29 17:30:41 -0800503 throw InternalFailure();
John Wedigb810c922021-11-17 16:38:03 -0800504 }
505
John Wedigb810c922021-11-17 16:38:03 -0800506 lg2::info("Successfully deactivated LUKS device {DEV}", "DEV", devPath,
507 "REDFISH_MESSAGE_ID",
508 std::string("OpenBMC.0.1.DeactivateLuksDevSuccess"));
509}
510
John Wedig2443a022023-03-17 13:42:32 -0700511std::string_view EStoraged::getCryptDevicePath() const
John Wedig67a47442022-04-05 17:21:29 -0700512{
John Wedig2443a022023-03-17 13:42:32 -0700513 return cryptDevicePath;
John Wedig67a47442022-04-05 17:21:29 -0700514}
515
John Wedig2098dab2021-09-14 13:56:28 -0700516} // namespace estoraged