1 
2 #include "cryptErase.hpp"
3 #include "cryptsetupInterface.hpp"
4 #include "estoraged.hpp"
5 #include "estoraged_test.hpp"
6 
7 #include <unistd.h>
8 
9 #include <xyz/openbmc_project/Common/error.hpp>
10 
11 #include <exception>
12 #include <filesystem>
13 #include <fstream>
14 #include <string>
15 
16 #include <gmock/gmock.h>
17 #include <gtest/gtest.h>
18 
19 namespace estoraged_test
20 {
21 
22 using estoraged::CryptErase;
23 using estoraged::Cryptsetup;
24 using estoraged::CryptsetupInterface;
25 using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
26 using sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound;
27 using sdbusplus::xyz::openbmc_project::Inventory::Item::server::Volume;
28 using ::testing::_;
29 using ::testing::Return;
30 using ::testing::StrEq;
31 
32 class cryptoEraseTest : public testing::Test
33 {
34   public:
35     static constexpr char testFileName[] = "testfile";
36     std::ofstream testFile;
37 
38     void SetUp() override
39     {
40         /* Create an empty file that we'll pretend is a 'storage device'. */
41         testFile.open(testFileName,
42                       std::ios::out | std::ios::binary | std::ios::trunc);
43         testFile.close();
44         if (testFile.fail())
45         {
46             throw std::runtime_error("Failed to open test file");
47         }
48         testFile.close();
49     }
50 };
51 
52 TEST_F(cryptoEraseTest, EraseCryptPass)
53 {
54     std::unique_ptr<MockCryptsetupInterface> mockCryptIface =
55         std::make_unique<MockCryptsetupInterface>();
56 
57     EXPECT_CALL(*mockCryptIface, cryptLoad(_, StrEq(CRYPT_LUKS2), nullptr))
58         .WillOnce(Return(0));
59 
60     EXPECT_CALL(*mockCryptIface, cryptKeySlotMax(StrEq(CRYPT_LUKS2)))
61         .WillOnce(Return(1));
62 
63     EXPECT_CALL(*mockCryptIface, cryptKeySlotStatus(_, 0))
64         .WillOnce(Return(CRYPT_SLOT_ACTIVE_LAST));
65 
66     EXPECT_CALL(*mockCryptIface, cryptKeyslotDestroy(_, 0)).Times(1);
67 
68     CryptErase myCryptErase =
69         CryptErase(testFileName, std::move(mockCryptIface));
70     EXPECT_NO_THROW(myCryptErase.doErase());
71 }
72 
73 TEST_F(cryptoEraseTest, EraseCrypMaxSlotFails)
74 {
75     std::unique_ptr<MockCryptsetupInterface> mockCryptIface =
76         std::make_unique<MockCryptsetupInterface>();
77 
78     EXPECT_CALL(*mockCryptIface, cryptLoad(_, StrEq(CRYPT_LUKS2), nullptr))
79         .WillOnce(Return(0));
80 
81     EXPECT_CALL(*mockCryptIface, cryptKeySlotMax(StrEq(CRYPT_LUKS2)))
82         .WillOnce(Return(-1));
83 
84     CryptErase myCryptErase =
85         CryptErase(testFileName, std::move(mockCryptIface));
86     EXPECT_THROW(myCryptErase.doErase(), ResourceNotFound);
87 }
88 
89 TEST_F(cryptoEraseTest, EraseCrypMaxSlotZero)
90 {
91     std::unique_ptr<MockCryptsetupInterface> mockCryptIface =
92         std::make_unique<MockCryptsetupInterface>();
93 
94     EXPECT_CALL(*mockCryptIface, cryptLoad(_, StrEq(CRYPT_LUKS2), nullptr))
95         .WillOnce(Return(0));
96 
97     EXPECT_CALL(*mockCryptIface, cryptKeySlotMax(StrEq(CRYPT_LUKS2)))
98         .WillOnce(Return(0));
99 
100     CryptErase myCryptErase =
101         CryptErase(testFileName, std::move(mockCryptIface));
102     EXPECT_THROW(myCryptErase.doErase(), ResourceNotFound);
103 }
104 
105 TEST_F(cryptoEraseTest, EraseCrypOnlyInvalid)
106 {
107     std::unique_ptr<MockCryptsetupInterface> mockCryptIface =
108         std::make_unique<MockCryptsetupInterface>();
109 
110     EXPECT_CALL(*mockCryptIface, cryptLoad(_, StrEq(CRYPT_LUKS2), nullptr))
111         .WillOnce(Return(0));
112 
113     EXPECT_CALL(*mockCryptIface, cryptKeySlotMax(StrEq(CRYPT_LUKS2)))
114         .WillOnce(Return(32));
115 
116     EXPECT_CALL(*mockCryptIface, cryptKeySlotStatus(_, _))
117         .WillRepeatedly(Return(CRYPT_SLOT_INVALID));
118 
119     CryptErase myCryptErase =
120         CryptErase(testFileName, std::move(mockCryptIface));
121     EXPECT_NO_THROW(myCryptErase.doErase());
122 }
123 
124 TEST_F(cryptoEraseTest, EraseCrypDestoryFails)
125 {
126     std::unique_ptr<MockCryptsetupInterface> mockCryptIface =
127         std::make_unique<MockCryptsetupInterface>();
128 
129     EXPECT_CALL(*mockCryptIface, cryptLoad(_, StrEq(CRYPT_LUKS2), nullptr))
130         .WillOnce(Return(0));
131 
132     EXPECT_CALL(*mockCryptIface, cryptKeySlotMax(StrEq(CRYPT_LUKS2)))
133         .WillOnce(Return(1));
134 
135     EXPECT_CALL(*mockCryptIface, cryptKeySlotStatus(_, 0))
136         .WillOnce(Return(CRYPT_SLOT_ACTIVE));
137 
138     EXPECT_CALL(*mockCryptIface, cryptKeyslotDestroy(_, 0))
139         .WillOnce(Return(-1));
140 
141     CryptErase myCryptErase =
142         CryptErase(testFileName, std::move(mockCryptIface));
143     EXPECT_THROW(myCryptErase.doErase(), InternalFailure);
144 }
145 
146 } // namespace estoraged_test
147