blob: c7c7a08fe5a8366a80c451151ed30ab5e4daf582 [file] [log] [blame]
Etienne Carriere109c1d72019-01-09 11:02:02 +01001/*
2 * Copyright (c) 2018, Linaro Limited
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Etienne Carrierefa7e34f2020-02-04 15:34:16 +010014#include <ck_debug.h>
Etienne Carriere109c1d72019-01-09 11:02:02 +010015#include <inttypes.h>
Etienne Carriere109c1d72019-01-09 11:02:02 +010016#include <pkcs11.h>
Etienne Carrierefa7e34f2020-02-04 15:34:16 +010017#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
Etienne Carriere109c1d72019-01-09 11:02:02 +010020
21#include "xtest_test.h"
22#include "xtest_helpers.h"
23
Etienne Carriere3b5558a2020-03-12 09:55:26 +010024/*
25 * Util to find a slot on which to open a session
26 */
27static CK_RV close_lib(void)
28{
29 return C_Finalize(0);
30}
31
32static CK_RV init_lib_and_find_token_slot(CK_SLOT_ID *slot)
33{
34 CK_RV rv = CKR_GENERAL_ERROR;
35 CK_SLOT_ID_PTR slots = NULL;
36 CK_ULONG count = 0;
37
38 rv = C_Initialize(0);
39 if (rv)
40 return rv;
41
42 rv = C_GetSlotList(CK_TRUE, NULL, &count);
43 if (rv != CKR_OK)
44 goto bail;
45
46 if (count < 1) {
47 rv = CKR_GENERAL_ERROR;
48 goto bail;
49 }
50
51 slots = malloc(count * sizeof(CK_SLOT_ID));
52 if (!slots) {
53 rv = CKR_HOST_MEMORY;
54 goto bail;
55 }
56
57 rv = C_GetSlotList(CK_TRUE, slots, &count);
58 if (rv)
59 goto bail;
60
61 /* Use the last slot */
62 *slot = slots[count - 1];
63
64bail:
65 free(slots);
66 if (rv)
67 close_lib();
68
69 return rv;
70}
71
Etienne Carriere109c1d72019-01-09 11:02:02 +010072static void xtest_tee_test_1000(ADBG_Case_t *c)
73{
74 CK_RV rv;
75
76 rv = C_Initialize(NULL);
77 if (!ADBG_EXPECT_CK_OK(c, rv))
78 return;
79
80 rv = C_Finalize(NULL);
81 if (!ADBG_EXPECT_CK_OK(c, rv))
82 return;
83
84 rv = C_Initialize(NULL);
85 if (!ADBG_EXPECT_CK_OK(c, rv))
86 return;
87
88 rv = C_Initialize(NULL);
89 ADBG_EXPECT_CK_RESULT(c, CKR_CRYPTOKI_ALREADY_INITIALIZED, rv);
90
91 rv = C_Finalize(NULL);
92 ADBG_EXPECT_CK_OK(c, rv);
Etienne Carriere21f4e3c2020-02-05 15:40:24 +010093
94 rv = C_Finalize(NULL);
95 ADBG_EXPECT_CK_RESULT(c, CKR_CRYPTOKI_NOT_INITIALIZED, rv);
Etienne Carriere109c1d72019-01-09 11:02:02 +010096}
97
98ADBG_CASE_DEFINE(pkcs11, 1000, xtest_tee_test_1000,
99 "Initialize and close Cryptoki library");
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100100
101static void xtest_tee_test_1001(ADBG_Case_t *c)
102{
103 CK_RV rv = CKR_GENERAL_ERROR;
104 CK_SLOT_ID_PTR slot_ids = NULL;
105 CK_ULONG slot_count = 0;
106 CK_ULONG present_slot_count = 0;
107 CK_INFO lib_info = { };
108 CK_SLOT_INFO slot_info = { };
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100109 CK_TOKEN_INFO token_info = { };
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100110 CK_FUNCTION_LIST_PTR ckfunc_list = NULL;
111 size_t i = 0;
112 CK_SLOT_ID max_slot_id = 0;
Etienne Carriered3121292020-03-04 17:38:24 +0100113 CK_MECHANISM_TYPE_PTR mecha_types = NULL;
114 CK_ULONG mecha_count = 0;
115 CK_MECHANISM_INFO mecha_info = { };
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100116
117 rv = C_Initialize(NULL);
118 if (!ADBG_EXPECT_CK_OK(c, rv))
119 return;
120
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100121 Do_ADBG_BeginSubCase(c, "Test C_GetFunctionList()");
122
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100123 rv = C_GetFunctionList(&ckfunc_list);
124 if (!ADBG_EXPECT_CK_OK(c, rv))
125 goto out;
126
127 if (!ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetInfo) ||
128 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetSlotList) ||
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100129 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetSlotInfo) ||
Etienne Carriered3121292020-03-04 17:38:24 +0100130 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetTokenInfo) ||
131 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetMechanismList) ||
132 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetMechanismInfo))
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100133 goto out;
134
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100135 Do_ADBG_EndSubCase(c, "Test C_GetFunctionList()");
136 Do_ADBG_BeginSubCase(c, "Test C_GetInfo()");
137
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100138 rv = C_GetInfo(&lib_info);
139 if (!ADBG_EXPECT_CK_OK(c, rv))
140 goto out;
141
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100142 Do_ADBG_EndSubCase(c, "Test C_GetInfo()");
143 Do_ADBG_BeginSubCase(c, "Test C_GetSlotList()");
144
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100145 rv = C_GetSlotList(0, NULL, &slot_count);
146 if (!ADBG_EXPECT_CK_OK(c, rv))
147 goto out;
148
149 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, slot_count, !=, 0))
150 goto out;
151
Etienne Carrierede746332020-03-04 19:43:53 +0100152 if (slot_count > 1) {
153 /* Ensure case non-NULL-buffer and zero-count is tested */
154 CK_SLOT_ID id = 0;
155
156 slot_count = 0;
157 rv = C_GetSlotList(0, &id, &slot_count);
158 if (!ADBG_EXPECT_CK_RESULT(c, CKR_BUFFER_TOO_SMALL, rv))
159 goto out;
160 }
161
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100162 rv = C_GetSlotList(1, NULL, &present_slot_count);
163 if (!ADBG_EXPECT_CK_OK(c, rv))
164 goto out;
165
166 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, slot_count, ==,
167 present_slot_count))
168 goto out;
169
170 slot_ids = calloc(slot_count, sizeof(CK_SLOT_ID));
171 if (!ADBG_EXPECT_NOT_NULL(c, slot_ids))
172 goto out;
173
174 slot_count--;
175 rv = C_GetSlotList(1, slot_ids, &slot_count);
176 if (!ADBG_EXPECT_CK_RESULT(c, CKR_BUFFER_TOO_SMALL, rv))
177 goto out;
178
179 rv = C_GetSlotList(1, slot_ids, &slot_count);
180 if (!ADBG_EXPECT_CK_OK(c, rv))
181 goto out;
182
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100183 Do_ADBG_EndSubCase(c, "Test C_GetSlotList()");
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100184 Do_ADBG_BeginSubCase(c, "Test C_Get{Slot|Token}Info()");
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100185
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100186 for (i = 0; i < slot_count; i++) {
187 CK_SLOT_ID slot = slot_ids[i];
188
189 rv = C_GetSlotInfo(slot, &slot_info);
190 if (!ADBG_EXPECT_CK_OK(c, rv))
191 goto out;
192
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100193 rv = C_GetTokenInfo(slot, &token_info);
194 if (!ADBG_EXPECT_CK_OK(c, rv))
195 goto out;
196
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100197 if (max_slot_id < slot)
198 max_slot_id = slot;
199 }
200
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100201 Do_ADBG_EndSubCase(c, "Test C_Get{Slot|Token}Info()");
Etienne Carriered3121292020-03-04 17:38:24 +0100202 Do_ADBG_BeginSubCase(c, "Test C_GetMechanism{List|Info}()");
203
204 for (i = 0; i < slot_count; i++) {
205 CK_SLOT_ID slot = slot_ids[i];
206 size_t j = 0;
207
208 mecha_count = 0;
209 rv = C_GetMechanismList(slot, NULL, &mecha_count);
210 if (!ADBG_EXPECT_CK_OK(c, rv))
211 goto out;
212
213 if (mecha_count == 0)
214 continue;
215
216 free(mecha_types);
217 mecha_types = calloc(mecha_count, sizeof(*mecha_types));
218 if (!ADBG_EXPECT_NOT_NULL(c, mecha_types))
219 goto out;
220
221 /* Test specific case: valid buffer reference with 0 count */
222 mecha_count = 0;
223 rv = C_GetMechanismList(slot, mecha_types, &mecha_count);
224 if (!ADBG_EXPECT_CK_RESULT(c, CKR_BUFFER_TOO_SMALL, rv))
225 goto out;
226
227 rv = C_GetMechanismList(slot, mecha_types, &mecha_count);
228 if (!ADBG_EXPECT_CK_OK(c, rv))
229 goto out;
230
231 for (j = 0; j < mecha_count; j++) {
232 rv = C_GetMechanismInfo(slot, mecha_types[j],
233 &mecha_info);
234 if (!ADBG_EXPECT_CK_OK(c, rv))
235 goto out;
236 }
237 }
238
239 Do_ADBG_EndSubCase(c, "Test C_GetMechanism{List|Info}()");
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100240 Do_ADBG_BeginSubCase(c, "Test C_Get*Info() with invalid reference");
241
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100242 rv = C_GetSlotInfo(max_slot_id + 1, &slot_info);
243 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
244 goto out;
245
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100246 rv = C_GetTokenInfo(max_slot_id + 1, &token_info);
247 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
248 goto out;
249
Etienne Carriered3121292020-03-04 17:38:24 +0100250 mecha_count = 1;
251 if (!mecha_types)
252 mecha_types = malloc(sizeof(*mecha_types));
253 if (!ADBG_EXPECT_NOT_NULL(c, mecha_types))
254 goto out;
255
256 rv = C_GetMechanismList(max_slot_id + 1, mecha_types, &mecha_count);
257 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
258 goto out;
259
260 rv = C_GetMechanismInfo(max_slot_id + 1, CKM_AES_KEY_GEN, &mecha_info);
261 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
262 goto out;
263
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100264 rv = C_GetSlotInfo(ULONG_MAX, &slot_info);
265 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
266 goto out;
267
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100268 rv = C_GetTokenInfo(ULONG_MAX, &token_info);
269 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
270 goto out;
271
Etienne Carriered3121292020-03-04 17:38:24 +0100272 mecha_count = 1;
273 rv = C_GetMechanismList(ULONG_MAX, mecha_types, &mecha_count);
274 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
275 goto out;
276
277 rv = C_GetMechanismInfo(ULONG_MAX, CKM_AES_KEY_GEN, &mecha_info);
278 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
279 goto out;
280
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100281out:
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100282 Do_ADBG_EndSubCase(c, NULL);
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100283 free(slot_ids);
Etienne Carriered3121292020-03-04 17:38:24 +0100284 free(mecha_types);
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100285
286 rv = C_Finalize(NULL);
287 ADBG_EXPECT_CK_OK(c, rv);
288}
289
290ADBG_CASE_DEFINE(pkcs11, 1001, xtest_tee_test_1001,
291 "PKCS11: List PKCS#11 slots and get information from");
Etienne Carriere3b5558a2020-03-12 09:55:26 +0100292
293static void xtest_pkcs11_test_1002(ADBG_Case_t *c)
294{
295 CK_RV rv = CKR_GENERAL_ERROR;
296 CK_SLOT_ID slot = 0;
297 CK_SESSION_HANDLE session[3] = { 0 };
298 CK_FLAGS session_flags = 0;
299 CK_SESSION_INFO session_info = { };
300 CK_FUNCTION_LIST_PTR ckfunc_list = NULL;
301
302 rv = init_lib_and_find_token_slot(&slot);
303 if (!ADBG_EXPECT_CK_OK(c, rv))
304 return;
305
306 rv = C_GetFunctionList(&ckfunc_list);
307 if (!ADBG_EXPECT_CK_OK(c, rv) ||
308 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_OpenSession) ||
309 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_CloseSession) ||
310 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_CloseAllSessions) ||
311 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetSessionInfo))
312 goto bail;
313
314 Do_ADBG_BeginSubCase(c, "Test C_OpenSession()/C_GetSessionInfo()");
315
316 session_flags = CKF_RW_SESSION;
317
318 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[0]);
319 if (!ADBG_EXPECT_CK_RESULT(c, CKR_ARGUMENTS_BAD, rv))
320 goto bail;
321
322 session_flags = CKF_SERIAL_SESSION;
323
324 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[0]);
325 if (!ADBG_EXPECT_CK_OK(c, rv))
326 goto bail;
327
328 rv = C_GetSessionInfo(session[0], &session_info);
329 if (!ADBG_EXPECT_CK_OK(c, rv) ||
330 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.slotID, ==, slot) ||
331 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.flags, ==,
332 session_flags) ||
333 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.state, ==,
334 CKS_RO_PUBLIC_SESSION) ||
335 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.ulDeviceError, ==, 0))
336 goto bail;
337
338 session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
339
340 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[1]);
341 if (!ADBG_EXPECT_CK_OK(c, rv))
342 goto bail;
343
344 rv = C_GetSessionInfo(session[1], &session_info);
345 if (!ADBG_EXPECT_CK_OK(c, rv) ||
346 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.slotID, ==, slot) ||
347 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.flags, ==,
348 session_flags) ||
349 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.state, ==,
350 CKS_RW_PUBLIC_SESSION) ||
351 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.ulDeviceError, ==, 0))
352 goto bail;
353
354 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[2]);
355 if (!ADBG_EXPECT_CK_OK(c, rv))
356 goto bail;
357
358 rv = C_GetSessionInfo(session[2], &session_info);
359 if (!ADBG_EXPECT_CK_OK(c, rv) ||
360 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.slotID, ==, slot) ||
361 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.flags, ==,
362 session_flags) ||
363 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.state, ==,
364 CKS_RW_PUBLIC_SESSION) ||
365 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.ulDeviceError, ==, 0))
366 goto bail;
367
368 Do_ADBG_EndSubCase(c, "Test C_OpenSession()/C_GetSessionInfo()");
369 Do_ADBG_BeginSubCase(c, "Test C_CloseSession()");
370
371 /* Close 2 of them */
372 rv = C_CloseSession(session[0]);
373 if (!ADBG_EXPECT_CK_OK(c, rv))
374 goto bail;
375
376 rv = C_GetSessionInfo(session[0], &session_info);
377 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
378 goto bail;
379
380 rv = C_GetSessionInfo(session[1], &session_info);
381 if (!ADBG_EXPECT_CK_OK(c, rv))
382 goto bail;
383
384 rv = C_GetSessionInfo(session[2], &session_info);
385 if (!ADBG_EXPECT_CK_OK(c, rv))
386 goto bail;
387
388 /* Close all remaining sessions, later calls should failed on session */
389 rv = C_CloseAllSessions(slot);
390 if (!ADBG_EXPECT_CK_OK(c, rv))
391 goto bail;
392
393 rv = C_CloseSession(session[1]);
394 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
395 goto bail;
396
397 rv = C_CloseSession(session[2]);
398 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
399 goto bail;
400
401 rv = C_GetSessionInfo(session[1], &session_info);
402 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
403 goto bail;
404
405 rv = C_GetSessionInfo(session[2], &session_info);
406 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
407 goto bail;
408
409 /* Open a session, should be closed from library closure */
410 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[0]);
411 if (!ADBG_EXPECT_CK_OK(c, rv))
412 goto bail;
413
414bail:
415 Do_ADBG_EndSubCase(c, NULL);
416 rv = close_lib();
417 ADBG_EXPECT_CK_OK(c, rv);
418}
419
420ADBG_CASE_DEFINE(pkcs11, 1002, xtest_pkcs11_test_1002,
421 "PKCS11: Open and close PKCS#11 sessions");