blob: 649bd37bcee4249377204f750044534f5c1fa8ea [file] [log] [blame]
John Edward Broadbent7f2ab642021-11-11 21:00:38 -08001#include "pattern.hpp"
2
3#include "erase.hpp"
4
5#include <unistd.h>
6
7#include <phosphor-logging/lg2.hpp>
8#include <stdplus/fd/create.hpp>
9#include <stdplus/fd/managed.hpp>
10#include <xyz/openbmc_project/Common/error.hpp>
11
12#include <array>
13#include <iostream>
14#include <random>
15#include <span>
16#include <string>
17
18constexpr uint32_t seed = 0x6a656272;
19constexpr size_t blockSize = 4096;
20constexpr size_t blockSizeUsing32 = blockSize / sizeof(uint32_t);
21
22using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
23using stdplus::fd::ManagedFd;
24
25void Pattern::writePattern(const uint64_t driveSize, ManagedFd& fd)
26{
27 // static seed defines a fixed prng sequnce so it can be verified later,
28 // and validated for entropy
29 uint64_t currentIndex = 0;
30 std::minstd_rand0 generator(seed);
31 std::array<std::byte, blockSize> randArr;
32 while (currentIndex < driveSize)
33 {
34 // generate a 4k block of prng
35 std::array<uint32_t, blockSizeUsing32>* randArrFill =
36 reinterpret_cast<std::array<uint32_t, blockSizeUsing32>*>(&randArr);
37 for (uint32_t i = 0; i < blockSizeUsing32; i++)
38 {
39 (*randArrFill)[i] = generator();
40 }
41 // if we can write all 4k bytes do that, else write the remainder
42 size_t writeSize = currentIndex + blockSize < driveSize
43 ? blockSize
44 : driveSize - currentIndex;
45 if (fd.write({randArr.data(), writeSize}).size() != writeSize)
46 {
47 lg2::error("Estoraged erase pattern unable to write sizeof(long)",
48 "REDFISH_MESSAGE_ID",
49 std::string("eStorageD.1.0.EraseFailure"),
50 "REDFISH_MESSAGE_ARGS", std::to_string(fd.get()));
51 throw InternalFailure();
52 }
53 currentIndex = currentIndex + writeSize;
54 }
55}
56
57void Pattern::verifyPattern(const uint64_t driveSize, ManagedFd& fd)
58{
59
60 uint64_t currentIndex = 0;
61 std::minstd_rand0 generator(seed);
62 std::array<std::byte, blockSize> randArr;
63 std::array<std::byte, blockSize> readArr;
64 while (currentIndex < driveSize)
65 {
66 size_t readSize = currentIndex + blockSize < driveSize
67 ? blockSize
68 : driveSize - currentIndex;
69 try
70 {
71 std::array<uint32_t, blockSizeUsing32>* randArrFill =
72 reinterpret_cast<std::array<uint32_t, blockSizeUsing32>*>(
73 &randArr);
74 for (uint32_t i = 0; i < blockSizeUsing32; i++)
75 {
76 (*randArrFill)[i] = generator();
77 }
78 fd.read({readArr.data(), readSize});
79 }
80 catch (...)
81 {
82 lg2::error("Estoraged erase pattern unable to read",
83 "REDFISH_MESSAGE_ID",
84 std::string("eStorageD.1.0.EraseFailure"),
85 "REDFISH_MESSAGE_ARGS", std::to_string(fd.get()));
86 throw InternalFailure();
87 }
88
89 if (!std::equal(randArr.begin(), randArr.begin() + readSize,
90 readArr.begin(), readArr.begin() + readSize))
91 {
92 lg2::error("Estoraged erase pattern does not match",
93 "REDFISH_MESSAGE_ID",
94 std::string("eStorageD.1.0.EraseFailure"));
95 throw InternalFailure();
96 }
97 currentIndex = currentIndex + readSize;
98 }
99}