1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <gtest/gtest.h>
17 #include <thread>
18 #include <unistd.h>
19
20 #include "file_ex.h"
21 #include "hks_api.h"
22 #include "hks_log.h"
23 #include "hks_mem.h"
24 #include "hks_param.h"
25 #include "hks_template.h"
26
27 #include "securec.h"
28
29 using namespace testing::ext;
30 namespace Unittest::HksThreeStageMultiThreadTest {
31 class HksThreeStageMultiThreadTest : public testing::Test {
32 public:
33 static void SetUpTestCase(void);
34
35 static void TearDownTestCase(void);
36
37 void SetUp();
38
39 void TearDown();
40 };
41
SetUpTestCase(void)42 void HksThreeStageMultiThreadTest::SetUpTestCase(void)
43 {
44 }
45
TearDownTestCase(void)46 void HksThreeStageMultiThreadTest::TearDownTestCase(void)
47 {
48 }
49
SetUp()50 void HksThreeStageMultiThreadTest::SetUp()
51 {
52 }
53
TearDown()54 void HksThreeStageMultiThreadTest::TearDown()
55 {
56 }
57
58 const uint32_t THREADS_NUM = 10;
59 static const uint32_t HKS_SM4_IV_SIZE = 16;
60
61 static uint8_t g_hksSm4TestIv[HKS_SM4_IV_SIZE] = {0};
62
63 static struct HksParam g_genParams[] = {
64 {
65 .tag = HKS_TAG_ALGORITHM,
66 .uint32Param = HKS_ALG_SM4
67 }, {
68 .tag = HKS_TAG_IV,
69 .blob = {
70 .size = HKS_SM4_IV_SIZE,
71 .data = static_cast<uint8_t *>(g_hksSm4TestIv)
72 }
73 }, {
74 .tag = HKS_TAG_PURPOSE,
75 .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT
76 }, {
77 .tag = HKS_TAG_PADDING,
78 .uint32Param = HKS_PADDING_PKCS7
79 }, {
80 .tag = HKS_TAG_KEY_SIZE,
81 .uint32Param = HKS_SM4_KEY_SIZE_128
82 }, {
83 .tag = HKS_TAG_BLOCK_MODE,
84 .uint32Param = HKS_MODE_CBC
85 },
86 };
87
InitParamSet(struct HksParamSet ** paramSet,const struct HksParam * params,uint32_t paramcount)88 static int32_t InitParamSet(struct HksParamSet **paramSet, const struct HksParam *params, uint32_t paramcount)
89 {
90 int32_t ret = HksInitParamSet(paramSet);
91 if (ret != HKS_SUCCESS) {
92 HKS_LOG_E("HksInitParamSet failed");
93 return ret;
94 }
95
96 ret = HksAddParams(*paramSet, params, paramcount);
97 if (ret != HKS_SUCCESS) {
98 HksFreeParamSet(paramSet);
99 HKS_LOG_E("HksAddParams failed");
100 return ret;
101 }
102
103 ret = HksBuildParamSet(paramSet);
104 if (ret != HKS_SUCCESS) {
105 HksFreeParamSet(paramSet);
106 HKS_LOG_E("HksBuildParamSet failed!");
107 return ret;
108 }
109
110 return ret;
111 }
112
GenerateKeyTest(const char * tmpKeyAlias)113 static int32_t GenerateKeyTest(const char *tmpKeyAlias)
114 {
115 struct HksBlob keyAlias = { strlen(tmpKeyAlias),
116 const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(tmpKeyAlias)) };
117
118 struct HksParamSet *genParamSet = nullptr;
119 int32_t ret = InitParamSet(&genParamSet, g_genParams, sizeof(g_genParams) / sizeof(HksParam));
120 EXPECT_EQ(ret, HKS_SUCCESS) << "InitParamSet(gen) failed.";
121
122 ret = HksGenerateKey(&keyAlias, genParamSet, nullptr);
123 EXPECT_EQ(ret, HKS_SUCCESS) << "GenerateKey failed.";
124
125 HksFreeParamSet(&genParamSet);
126 return ret;
127 }
128
DeleteKeyTest(const char * tmpKeyAlias)129 static int32_t DeleteKeyTest(const char *tmpKeyAlias)
130 {
131 struct HksBlob keyAlias = { strlen(tmpKeyAlias),
132 const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(tmpKeyAlias)) };
133 return HksDeleteKey(&keyAlias, nullptr);
134 }
135
136 static struct HksParam g_encryptParams[] = {
137 {
138 .tag = HKS_TAG_ALGORITHM,
139 .uint32Param = HKS_ALG_SM4
140 }, {
141 .tag = HKS_TAG_PURPOSE,
142 .uint32Param = HKS_KEY_PURPOSE_ENCRYPT
143 }, {
144 .tag = HKS_TAG_IV,
145 .blob = {
146 .size = HKS_SM4_IV_SIZE,
147 .data = static_cast<uint8_t *>(g_hksSm4TestIv)
148 }
149 }, {
150 .tag = HKS_TAG_PADDING,
151 .uint32Param = HKS_PADDING_PKCS7
152 }, {
153 .tag = HKS_TAG_KEY_SIZE,
154 .uint32Param = HKS_SM4_KEY_SIZE_128
155 }, {
156 .tag = HKS_TAG_BLOCK_MODE,
157 .uint32Param = HKS_MODE_CBC
158 },
159 };
160
InitSessionTest(const char * tmpKeyAlias,struct HksBlob * handle)161 static int32_t InitSessionTest(const char *tmpKeyAlias, struct HksBlob *handle)
162 {
163 struct HksBlob keyAlias = { strlen(tmpKeyAlias),
164 const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(tmpKeyAlias)) };
165 struct HksParamSet *encryptParamSet = nullptr;
166 int32_t ret = InitParamSet(&encryptParamSet, g_encryptParams, sizeof(g_encryptParams) / sizeof(HksParam));
167 EXPECT_EQ(ret, HKS_SUCCESS) << "InitParamSet(encrypt) failed.";
168 ret = HksInit(&keyAlias, encryptParamSet, handle, nullptr);
169 EXPECT_EQ(ret, HKS_SUCCESS) << "HksInit failed.";
170 HksFreeParamSet(&encryptParamSet);
171 return ret;
172 }
173
UpdateSessionTest(struct HksBlob * handle)174 static int32_t UpdateSessionTest(struct HksBlob *handle)
175 {
176 struct HksParamSet *encryptParamSet = nullptr;
177 int32_t ret = InitParamSet(&encryptParamSet, g_encryptParams, sizeof(g_encryptParams) / sizeof(HksParam));
178 EXPECT_EQ(ret, HKS_SUCCESS) << "InitParamSet(encrypt) failed.";
179
180 uint32_t indataSize = 8192;
181 uint32_t outdataSize = 8208;
182 uint8_t *indata = static_cast<uint8_t *>(HksMalloc(indataSize));
183 struct HksBlob indataBlob = { indataSize, indata };
184 uint8_t *outdata = static_cast<uint8_t *>(HksMalloc(outdataSize));
185 struct HksBlob outdataBlob = { outdataSize, outdata };
186 ret = HksUpdate(handle, encryptParamSet, &indataBlob, &outdataBlob);
187 HKS_IF_NOT_SUCC_LOGE(ret, "HksUpdate failed.")
188 HksFreeParamSet(&encryptParamSet);
189 HKS_FREE(indata);
190 HKS_FREE(outdata);
191 return ret;
192 }
193
FinishSessionTest(struct HksBlob * handle)194 static int32_t FinishSessionTest(struct HksBlob *handle)
195 {
196 struct HksParamSet *encryptParamSet = nullptr;
197 int32_t ret = InitParamSet(&encryptParamSet, g_encryptParams, sizeof(g_encryptParams) / sizeof(HksParam));
198 EXPECT_EQ(ret, HKS_SUCCESS) << "InitParamSet(encrypt) failed.";
199
200 uint32_t indataSize = 8192;
201 uint8_t *indata = static_cast<uint8_t *>(HksMalloc(indataSize));
202 struct HksBlob indataBlob = { indataSize, indata };
203 uint32_t outdataSize = 8208;
204 uint8_t *outdata = static_cast<uint8_t *>(HksMalloc(outdataSize));
205 struct HksBlob outdataBlob = { outdataSize, outdata };
206 ret = HksFinish(handle, encryptParamSet, &indataBlob, &outdataBlob);
207 HKS_IF_NOT_SUCC_LOGE(ret, "HksFinish failed.")
208 HksFreeParamSet(&encryptParamSet);
209 HKS_FREE(indata);
210 HKS_FREE(outdata);
211 return ret;
212 }
213
AbortSessionTest(struct HksBlob * handle)214 static int32_t AbortSessionTest(struct HksBlob *handle)
215 {
216 struct HksParamSet *encryptParamSet = nullptr;
217 int32_t ret = InitParamSet(&encryptParamSet, g_encryptParams, sizeof(g_encryptParams) / sizeof(HksParam));
218 EXPECT_EQ(ret, HKS_SUCCESS) << "InitParamSet(encrypt) failed.";
219 ret = HksAbort(handle, encryptParamSet);
220 HKS_IF_NOT_SUCC_LOGE(ret, "HksAbort failed.")
221 HksFreeParamSet(&encryptParamSet);
222 return ret;
223 }
224
ThreeStageTest(uint32_t testIndex)225 static void ThreeStageTest(uint32_t testIndex)
226 {
227 char alias[20];
228 (void)sprintf_s(alias, sizeof(alias), "%s%u", "test_three_stage", testIndex);
229 uint8_t handleE[sizeof(uint64_t)] = { 0 };
230 struct HksBlob handleBlob = { sizeof(uint64_t), handleE };
231 int32_t ret = GenerateKeyTest(alias);
232 EXPECT_EQ(ret, HKS_SUCCESS) << "GenerateKeyTest failed.";
233 ret = InitSessionTest(alias, &handleBlob);
234 EXPECT_EQ(ret, HKS_SUCCESS) << "InitSessionTest failed.";
235
236 std::vector<std::thread> threads;
237 srand(time(nullptr));
238 uint32_t finishPos = static_cast<uint32_t>(rand() / RAND_MAX) * THREADS_NUM;
239
240 for (uint32_t i = 0; i < THREADS_NUM; i++) {
241 if (finishPos == i) {
242 threads.emplace_back(std::thread(AbortSessionTest, &handleBlob));
243 } else {
244 threads.emplace_back(std::thread(UpdateSessionTest, &handleBlob));
245 }
246 }
247
248 for (auto &t : threads) {
249 t.join();
250 }
251
252 EXPECT_EQ(ret, HKS_SUCCESS) << "InitSessionTest failed.";
253
254 std::vector<std::thread> threads2;
255 ret = InitSessionTest(alias, &handleBlob);
256 threads2.emplace_back(std::thread(FinishSessionTest, &handleBlob));
257 threads2.emplace_back(std::thread(AbortSessionTest, &handleBlob));
258
259 for (auto &t : threads2) {
260 t.join();
261 }
262
263 ret = DeleteKeyTest(alias);
264 EXPECT_EQ(ret, HKS_SUCCESS) << "DeleteKeyTest failed.";
265 }
266
267 /**
268 * @tc.name: HksThreeStageMultiThreadTest.HksThreeStageMultiThreadTest001
269 * @tc.desc: test three stage multi thread test
270 * @tc.type: FUNC
271 */
272 HWTEST_F(HksThreeStageMultiThreadTest, HksThreeStageMultiThreadTest001, TestSize.Level0)
273 {
274 HKS_LOG_I("enter HksThreeStageMultiThreadTest001");
275 std::vector<std::thread> threads;
276
277 for (uint32_t i = 0; i < THREADS_NUM; i++) {
278 threads.emplace_back(std::thread(&ThreeStageTest, i));
279 }
280
281 for (auto &t : threads) {
282 t.join();
283 }
284 int32_t ret = HksInitialize();
285 ASSERT_TRUE(ret == HKS_SUCCESS);
286 }
287 }