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