#include "pattern.hpp" #include "erase.hpp" #include #include #include #include #include #include #include #include #include #include namespace estoraged { constexpr uint32_t seed = 0x6a656272; constexpr size_t blockSize = 4096; constexpr size_t blockSizeUsing32 = blockSize / sizeof(uint32_t); using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; using stdplus::fd::ManagedFd; void Pattern::writePattern(const uint64_t driveSize) { // static seed defines a fixed prng sequnce so it can be verified later, // and validated for entropy uint64_t currentIndex = 0; // random number generator seeded with a constant value will // generate a predictable sequence of values NOLINTNEXTLINE std::minstd_rand0 generator(seed); std::array randArr{}; ManagedFd fd = stdplus::fd::open(devPath, stdplus::fd::OpenAccess::WriteOnly); while (currentIndex < driveSize) { // generate a 4k block of prng std::array* randArrFill = reinterpret_cast*>(&randArr); for (uint32_t i = 0; i < blockSizeUsing32; i++) { (*randArrFill)[i] = generator(); } // if we can write all 4k bytes do that, else write the remainder size_t writeSize = currentIndex + blockSize < driveSize ? blockSize : driveSize - currentIndex; if (fd.write({randArr.data(), writeSize}).size() != writeSize) { lg2::error("Estoraged erase pattern unable to write sizeof(long)", "REDFISH_MESSAGE_ID", std::string("eStorageD.1.0.EraseFailure"), "REDFISH_MESSAGE_ARGS", std::to_string(fd.get())); throw InternalFailure(); } currentIndex = currentIndex + writeSize; } } void Pattern::verifyPattern(const uint64_t driveSize) { uint64_t currentIndex = 0; // random number generator seeded with a constant value will // generate a predictable sequence of values NOLINTNEXTLINE std::minstd_rand0 generator(seed); std::array randArr{}; std::array readArr{}; ManagedFd fd = stdplus::fd::open(devPath, stdplus::fd::OpenAccess::ReadOnly); while (currentIndex < driveSize) { size_t readSize = currentIndex + blockSize < driveSize ? blockSize : driveSize - currentIndex; try { std::array* randArrFill = reinterpret_cast*>( &randArr); for (uint32_t i = 0; i < blockSizeUsing32; i++) { (*randArrFill)[i] = generator(); } fd.read({readArr.data(), readSize}); } catch (...) { lg2::error("Estoraged erase pattern unable to read", "REDFISH_MESSAGE_ID", std::string("eStorageD.1.0.EraseFailure"), "REDFISH_MESSAGE_ARGS", std::to_string(fd.get())); throw InternalFailure(); } if (!std::equal(randArr.begin(), randArr.begin() + readSize, readArr.begin(), readArr.begin() + readSize)) { lg2::error("Estoraged erase pattern does not match", "REDFISH_MESSAGE_ID", std::string("eStorageD.1.0.EraseFailure")); throw InternalFailure(); } currentIndex = currentIndex + readSize; } } } // namespace estoraged