1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2017-2020, Linaro Limited
4 */
5
6 #include <assert.h>
7 #include <config.h>
8 #include <confine_array_index.h>
9 #include <pkcs11_ta.h>
10 #include <printk.h>
11 #include <pta_system.h>
12 #include <string.h>
13 #include <string_ext.h>
14 #include <sys/queue.h>
15 #include <tee_api_types.h>
16 #include <tee_internal_api_extensions.h>
17 #include <util.h>
18
19 #include "attributes.h"
20 #include "handle.h"
21 #include "pkcs11_helpers.h"
22 #include "pkcs11_token.h"
23 #include "processing.h"
24 #include "serializer.h"
25 #include "token_capabilities.h"
26
27 /* Number of tokens implemented by the TA. Token ID is the token index */
28 #define TOKEN_COUNT CFG_PKCS11_TA_TOKEN_COUNT
29
30 /* RNG chunk size used to split RNG generation to smaller sizes */
31 #define RNG_CHUNK_SIZE 512U
32
33 /*
34 * Structure tracking client applications
35 *
36 * @link - chained list of registered client applications
37 * @sessions - list of the PKCS11 sessions opened by the client application
38 * @object_handle_db - Database for object handles in name space of client
39 */
40 struct pkcs11_client {
41 TAILQ_ENTRY(pkcs11_client) link;
42 struct session_list session_list;
43 struct handle_db session_handle_db;
44 struct handle_db object_handle_db;
45 };
46
47 /* Static allocation of tokens runtime instances (reset to 0 at load) */
48 struct ck_token ck_token[TOKEN_COUNT];
49
50 static struct client_list pkcs11_client_list =
51 TAILQ_HEAD_INITIALIZER(pkcs11_client_list);
52
53 static void close_ck_session(struct pkcs11_session *session);
54
get_token(unsigned int token_id)55 struct ck_token *get_token(unsigned int token_id)
56 {
57 if (token_id < TOKEN_COUNT)
58 return &ck_token[confine_array_index(token_id, TOKEN_COUNT)];
59
60 return NULL;
61 }
62
get_token_id(struct ck_token * token)63 unsigned int get_token_id(struct ck_token *token)
64 {
65 ptrdiff_t id = token - ck_token;
66
67 assert(id >= 0 && id < TOKEN_COUNT);
68 return id;
69 }
70
get_object_handle_db(struct pkcs11_session * session)71 struct handle_db *get_object_handle_db(struct pkcs11_session *session)
72 {
73 return &session->client->object_handle_db;
74 }
75
get_session_list(struct pkcs11_session * session)76 struct session_list *get_session_list(struct pkcs11_session *session)
77 {
78 return &session->client->session_list;
79 }
80
tee_session2client(void * tee_session)81 struct pkcs11_client *tee_session2client(void *tee_session)
82 {
83 struct pkcs11_client *client = NULL;
84
85 TAILQ_FOREACH(client, &pkcs11_client_list, link)
86 if (client == tee_session)
87 break;
88
89 return client;
90 }
91
pkcs11_handle2session(uint32_t handle,struct pkcs11_client * client)92 struct pkcs11_session *pkcs11_handle2session(uint32_t handle,
93 struct pkcs11_client *client)
94 {
95 return handle_lookup(&client->session_handle_db, handle);
96 }
97
token_invalidate_object_handles(struct pkcs11_object * obj)98 void token_invalidate_object_handles(struct pkcs11_object *obj)
99 {
100 struct pkcs11_client *client = NULL;
101 uint32_t handle = 0;
102
103 TAILQ_FOREACH(client, &pkcs11_client_list, link) {
104 handle = handle_lookup_handle(&client->object_handle_db, obj);
105 if (handle)
106 handle_invalidate(&client->object_handle_db, handle);
107 }
108 }
109
register_client(void)110 struct pkcs11_client *register_client(void)
111 {
112 struct pkcs11_client *client = NULL;
113
114 client = TEE_Malloc(sizeof(*client), TEE_MALLOC_FILL_ZERO);
115 if (!client)
116 return NULL;
117
118 TAILQ_INSERT_HEAD(&pkcs11_client_list, client, link);
119 TAILQ_INIT(&client->session_list);
120 handle_db_init(&client->session_handle_db);
121 handle_db_init(&client->object_handle_db);
122
123 return client;
124 }
125
unregister_client(struct pkcs11_client * client)126 void unregister_client(struct pkcs11_client *client)
127 {
128 struct pkcs11_session *session = NULL;
129 struct pkcs11_session *next = NULL;
130
131 if (!client) {
132 EMSG("Invalid TEE session handle");
133 return;
134 }
135
136 TAILQ_FOREACH_SAFE(session, &client->session_list, link, next)
137 close_ck_session(session);
138
139 TAILQ_REMOVE(&pkcs11_client_list, client, link);
140 handle_db_destroy(&client->object_handle_db);
141 handle_db_destroy(&client->session_handle_db);
142 TEE_Free(client);
143 }
144
pkcs11_token_init(unsigned int id)145 static TEE_Result pkcs11_token_init(unsigned int id)
146 {
147 struct ck_token *token = init_persistent_db(id);
148
149 if (!token)
150 return TEE_ERROR_SECURITY;
151
152 if (token->state == PKCS11_TOKEN_RESET) {
153 /* As per PKCS#11 spec, token resets to read/write state */
154 token->state = PKCS11_TOKEN_READ_WRITE;
155 token->session_count = 0;
156 token->rw_session_count = 0;
157 }
158
159 return TEE_SUCCESS;
160 }
161
pkcs11_init(void)162 TEE_Result pkcs11_init(void)
163 {
164 unsigned int id = 0;
165 TEE_Result ret = TEE_ERROR_GENERIC;
166
167 for (id = 0; id < TOKEN_COUNT; id++) {
168 ret = pkcs11_token_init(id);
169 if (ret)
170 break;
171 }
172
173 return ret;
174 }
175
pkcs11_deinit(void)176 void pkcs11_deinit(void)
177 {
178 unsigned int id = 0;
179
180 for (id = 0; id < TOKEN_COUNT; id++)
181 close_persistent_db(get_token(id));
182 }
183
184 /*
185 * Currently no support for dual operations.
186 */
set_processing_state(struct pkcs11_session * session,enum processing_func function,struct pkcs11_object * obj1,struct pkcs11_object * obj2)187 enum pkcs11_rc set_processing_state(struct pkcs11_session *session,
188 enum processing_func function,
189 struct pkcs11_object *obj1,
190 struct pkcs11_object *obj2)
191 {
192 enum pkcs11_proc_state state = PKCS11_SESSION_READY;
193 struct active_processing *proc = NULL;
194
195 if (session->processing)
196 return PKCS11_CKR_OPERATION_ACTIVE;
197
198 switch (function) {
199 case PKCS11_FUNCTION_ENCRYPT:
200 state = PKCS11_SESSION_ENCRYPTING;
201 break;
202 case PKCS11_FUNCTION_DECRYPT:
203 state = PKCS11_SESSION_DECRYPTING;
204 break;
205 case PKCS11_FUNCTION_SIGN:
206 state = PKCS11_SESSION_SIGNING;
207 break;
208 case PKCS11_FUNCTION_VERIFY:
209 state = PKCS11_SESSION_VERIFYING;
210 break;
211 case PKCS11_FUNCTION_DIGEST:
212 state = PKCS11_SESSION_DIGESTING;
213 break;
214 case PKCS11_FUNCTION_DERIVE:
215 case PKCS11_FUNCTION_WRAP:
216 case PKCS11_FUNCTION_UNWRAP:
217 state = PKCS11_SESSION_BUSY;
218 break;
219 default:
220 TEE_Panic(function);
221 return -1;
222 }
223
224 proc = TEE_Malloc(sizeof(*proc), TEE_MALLOC_FILL_ZERO);
225 if (!proc)
226 return PKCS11_CKR_DEVICE_MEMORY;
227
228 /* Boolean are default to false and pointers to NULL */
229 proc->state = state;
230 proc->step = PKCS11_FUNC_STEP_INIT;
231 proc->tee_op_handle = TEE_HANDLE_NULL;
232 proc->tee_hash_algo = 0;
233 proc->tee_op_handle2 = TEE_HANDLE_NULL;
234
235 if (obj1 && get_bool(obj1->attributes, PKCS11_CKA_ALWAYS_AUTHENTICATE))
236 proc->always_authen = true;
237
238 if (obj2 && get_bool(obj2->attributes, PKCS11_CKA_ALWAYS_AUTHENTICATE))
239 proc->always_authen = true;
240
241 session->processing = proc;
242
243 return PKCS11_CKR_OK;
244 }
245
entry_ck_slot_list(uint32_t ptypes,TEE_Param * params)246 enum pkcs11_rc entry_ck_slot_list(uint32_t ptypes, TEE_Param *params)
247 {
248 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
249 TEE_PARAM_TYPE_NONE,
250 TEE_PARAM_TYPE_MEMREF_OUTPUT,
251 TEE_PARAM_TYPE_NONE);
252 TEE_Param *out = params + 2;
253 uint32_t token_id = 0;
254 const size_t out_size = sizeof(token_id) * TOKEN_COUNT;
255 uint8_t *id = NULL;
256
257 if (ptypes != exp_pt ||
258 params[0].memref.size != TEE_PARAM0_SIZE_MIN)
259 return PKCS11_CKR_ARGUMENTS_BAD;
260
261 if (out->memref.size < out_size) {
262 out->memref.size = out_size;
263
264 if (out->memref.buffer)
265 return PKCS11_CKR_BUFFER_TOO_SMALL;
266 else
267 return PKCS11_CKR_OK;
268 }
269
270 for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT;
271 token_id++, id += sizeof(token_id))
272 TEE_MemMove(id, &token_id, sizeof(token_id));
273
274 out->memref.size = out_size;
275
276 return PKCS11_CKR_OK;
277 }
278
pad_str(uint8_t * str,size_t size)279 static void pad_str(uint8_t *str, size_t size)
280 {
281 int n = strnlen((char *)str, size);
282
283 TEE_MemFill(str + n, ' ', size - n);
284 }
285
set_token_description(struct pkcs11_slot_info * info)286 static void set_token_description(struct pkcs11_slot_info *info)
287 {
288 char desc[sizeof(info->slot_description) + 1] = { 0 };
289 TEE_UUID dev_id = { };
290 TEE_Result res = TEE_ERROR_GENERIC;
291 int n = 0;
292
293 res = TEE_GetPropertyAsUUID(TEE_PROPSET_TEE_IMPLEMENTATION,
294 "gpd.tee.deviceID", &dev_id);
295 if (res == TEE_SUCCESS) {
296 n = snprintk(desc, sizeof(desc), PKCS11_SLOT_DESCRIPTION
297 " - TEE UUID %pUl", (void *)&dev_id);
298 } else {
299 n = snprintf(desc, sizeof(desc), PKCS11_SLOT_DESCRIPTION
300 " - No TEE UUID");
301 }
302 if (n < 0 || n >= (int)sizeof(desc))
303 TEE_Panic(0);
304
305 TEE_MemMove(info->slot_description, desc, n);
306 pad_str(info->slot_description, sizeof(info->slot_description));
307 }
308
entry_ck_slot_info(uint32_t ptypes,TEE_Param * params)309 enum pkcs11_rc entry_ck_slot_info(uint32_t ptypes, TEE_Param *params)
310 {
311 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
312 TEE_PARAM_TYPE_NONE,
313 TEE_PARAM_TYPE_MEMREF_OUTPUT,
314 TEE_PARAM_TYPE_NONE);
315 TEE_Param *ctrl = params;
316 TEE_Param *out = params + 2;
317 enum pkcs11_rc rc = PKCS11_CKR_OK;
318 struct serialargs ctrlargs = { };
319 uint32_t token_id = 0;
320 struct pkcs11_slot_info info = {
321 .slot_description = PKCS11_SLOT_DESCRIPTION,
322 .manufacturer_id = PKCS11_SLOT_MANUFACTURER,
323 .flags = PKCS11_CKFS_TOKEN_PRESENT,
324 .hardware_version = PKCS11_SLOT_HW_VERSION,
325 .firmware_version = PKCS11_SLOT_FW_VERSION,
326 };
327
328 COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <=
329 sizeof(info.slot_description));
330 COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <=
331 sizeof(info.manufacturer_id));
332
333 if (ptypes != exp_pt || out->memref.size != sizeof(info))
334 return PKCS11_CKR_ARGUMENTS_BAD;
335
336 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
337
338 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
339 if (rc)
340 return rc;
341
342 if (serialargs_remaining_bytes(&ctrlargs))
343 return PKCS11_CKR_ARGUMENTS_BAD;
344
345 if (!get_token(token_id))
346 return PKCS11_CKR_SLOT_ID_INVALID;
347
348 set_token_description(&info);
349
350 pad_str(info.manufacturer_id, sizeof(info.manufacturer_id));
351
352 out->memref.size = sizeof(info);
353 TEE_MemMove(out->memref.buffer, &info, out->memref.size);
354
355 return PKCS11_CKR_OK;
356 }
357
entry_ck_token_info(uint32_t ptypes,TEE_Param * params)358 enum pkcs11_rc entry_ck_token_info(uint32_t ptypes, TEE_Param *params)
359 {
360 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
361 TEE_PARAM_TYPE_NONE,
362 TEE_PARAM_TYPE_MEMREF_OUTPUT,
363 TEE_PARAM_TYPE_NONE);
364 TEE_Param *ctrl = params;
365 TEE_Param *out = params + 2;
366 enum pkcs11_rc rc = PKCS11_CKR_OK;
367 struct serialargs ctrlargs = { };
368 uint32_t token_id = 0;
369 struct ck_token *token = NULL;
370 struct pkcs11_token_info info = {
371 .manufacturer_id = PKCS11_TOKEN_MANUFACTURER,
372 .model = PKCS11_TOKEN_MODEL,
373 .max_session_count = UINT32_MAX,
374 .max_rw_session_count = UINT32_MAX,
375 .max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX,
376 .min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN,
377 .total_public_memory = UINT32_MAX,
378 .free_public_memory = UINT32_MAX,
379 .total_private_memory = UINT32_MAX,
380 .free_private_memory = UINT32_MAX,
381 .hardware_version = PKCS11_TOKEN_HW_VERSION,
382 .firmware_version = PKCS11_TOKEN_FW_VERSION,
383 };
384 char sn[sizeof(info.serial_number) + 1] = { 0 };
385 int n = 0;
386
387 if (ptypes != exp_pt || out->memref.size != sizeof(info))
388 return PKCS11_CKR_ARGUMENTS_BAD;
389
390 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
391
392 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
393 if (rc)
394 return rc;
395
396 if (serialargs_remaining_bytes(&ctrlargs))
397 return PKCS11_CKR_ARGUMENTS_BAD;
398
399 token = get_token(token_id);
400 if (!token)
401 return PKCS11_CKR_SLOT_ID_INVALID;
402
403 pad_str(info.manufacturer_id, sizeof(info.manufacturer_id));
404 pad_str(info.model, sizeof(info.model));
405
406 n = snprintf(sn, sizeof(sn), "%0*"PRIu32,
407 (int)sizeof(info.serial_number), token_id);
408 if (n != (int)sizeof(info.serial_number))
409 TEE_Panic(0);
410
411 TEE_MemMove(info.serial_number, sn, sizeof(info.serial_number));
412 pad_str(info.serial_number, sizeof(info.serial_number));
413
414 TEE_MemMove(info.label, token->db_main->label, sizeof(info.label));
415
416 info.flags = token->db_main->flags;
417 info.session_count = token->session_count;
418 info.rw_session_count = token->rw_session_count;
419
420 TEE_MemMove(out->memref.buffer, &info, sizeof(info));
421
422 return PKCS11_CKR_OK;
423 }
424
dmsg_print_supported_mechanism(unsigned int token_id __maybe_unused,uint32_t * array __maybe_unused,size_t count __maybe_unused)425 static void dmsg_print_supported_mechanism(unsigned int token_id __maybe_unused,
426 uint32_t *array __maybe_unused,
427 size_t count __maybe_unused)
428 {
429 size_t __maybe_unused n = 0;
430
431 if (TRACE_LEVEL < TRACE_DEBUG)
432 return;
433
434 for (n = 0; n < count; n++)
435 DMSG("PKCS11 token %"PRIu32": mechanism 0x%04"PRIx32": %s",
436 token_id, array[n], id2str_mechanism(array[n]));
437 }
438
entry_ck_token_mecha_ids(uint32_t ptypes,TEE_Param * params)439 enum pkcs11_rc entry_ck_token_mecha_ids(uint32_t ptypes, TEE_Param *params)
440 {
441 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
442 TEE_PARAM_TYPE_NONE,
443 TEE_PARAM_TYPE_MEMREF_OUTPUT,
444 TEE_PARAM_TYPE_NONE);
445 TEE_Param *ctrl = params;
446 TEE_Param *out = params + 2;
447 enum pkcs11_rc rc = PKCS11_CKR_OK;
448 struct serialargs ctrlargs = { };
449 uint32_t token_id = 0;
450 struct ck_token __maybe_unused *token = NULL;
451 size_t count = 0;
452 uint32_t *array = NULL;
453
454 if (ptypes != exp_pt)
455 return PKCS11_CKR_ARGUMENTS_BAD;
456
457 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
458
459 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
460 if (rc)
461 return rc;
462
463 if (serialargs_remaining_bytes(&ctrlargs))
464 return PKCS11_CKR_ARGUMENTS_BAD;
465
466 token = get_token(token_id);
467 if (!token)
468 return PKCS11_CKR_SLOT_ID_INVALID;
469
470 count = out->memref.size / sizeof(*array);
471 array = tee_malloc_mechanism_list(&count);
472
473 if (out->memref.size < count * sizeof(*array)) {
474 assert(!array);
475 out->memref.size = count * sizeof(*array);
476 if (out->memref.buffer)
477 return PKCS11_CKR_BUFFER_TOO_SMALL;
478 else
479 return PKCS11_CKR_OK;
480 }
481
482 if (!array)
483 return PKCS11_CKR_DEVICE_MEMORY;
484
485 dmsg_print_supported_mechanism(token_id, array, count);
486
487 out->memref.size = count * sizeof(*array);
488 TEE_MemMove(out->memref.buffer, array, out->memref.size);
489
490 TEE_Free(array);
491
492 return rc;
493 }
494
entry_ck_token_mecha_info(uint32_t ptypes,TEE_Param * params)495 enum pkcs11_rc entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params)
496 {
497 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
498 TEE_PARAM_TYPE_NONE,
499 TEE_PARAM_TYPE_MEMREF_OUTPUT,
500 TEE_PARAM_TYPE_NONE);
501 TEE_Param *ctrl = params;
502 TEE_Param *out = params + 2;
503 enum pkcs11_rc rc = PKCS11_CKR_OK;
504 struct serialargs ctrlargs = { };
505 uint32_t token_id = 0;
506 uint32_t type = 0;
507 struct ck_token *token = NULL;
508 struct pkcs11_mechanism_info info = { };
509
510 if (ptypes != exp_pt || out->memref.size != sizeof(info))
511 return PKCS11_CKR_ARGUMENTS_BAD;
512
513 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
514
515 rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
516 if (rc)
517 return rc;
518
519 rc = serialargs_get(&ctrlargs, &type, sizeof(uint32_t));
520 if (rc)
521 return rc;
522
523 if (serialargs_remaining_bytes(&ctrlargs))
524 return PKCS11_CKR_ARGUMENTS_BAD;
525
526 token = get_token(token_id);
527 if (!token)
528 return PKCS11_CKR_SLOT_ID_INVALID;
529
530 if (!mechanism_is_valid(type))
531 return PKCS11_CKR_MECHANISM_INVALID;
532
533 info.flags = mechanism_supported_flags(type);
534
535 pkcs11_mechanism_supported_key_sizes(type, &info.min_key_size,
536 &info.max_key_size);
537
538 TEE_MemMove(out->memref.buffer, &info, sizeof(info));
539
540 DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info",
541 token_id, type);
542
543 return PKCS11_CKR_OK;
544 }
545
546 /* Select the ReadOnly or ReadWrite state for session login state */
set_session_state(struct pkcs11_client * client,struct pkcs11_session * session,bool readonly)547 static void set_session_state(struct pkcs11_client *client,
548 struct pkcs11_session *session, bool readonly)
549 {
550 struct pkcs11_session *sess = NULL;
551 enum pkcs11_session_state state = PKCS11_CKS_RO_PUBLIC_SESSION;
552
553 /* Default to public session if no session already registered */
554 if (readonly)
555 state = PKCS11_CKS_RO_PUBLIC_SESSION;
556 else
557 state = PKCS11_CKS_RW_PUBLIC_SESSION;
558
559 /*
560 * No need to check all client sessions, the first found in
561 * target token gives client login configuration.
562 */
563 TAILQ_FOREACH(sess, &client->session_list, link) {
564 assert(sess != session);
565
566 if (sess->token == session->token) {
567 switch (sess->state) {
568 case PKCS11_CKS_RW_PUBLIC_SESSION:
569 case PKCS11_CKS_RO_PUBLIC_SESSION:
570 if (readonly)
571 state = PKCS11_CKS_RO_PUBLIC_SESSION;
572 else
573 state = PKCS11_CKS_RW_PUBLIC_SESSION;
574 break;
575 case PKCS11_CKS_RO_USER_FUNCTIONS:
576 case PKCS11_CKS_RW_USER_FUNCTIONS:
577 if (readonly)
578 state = PKCS11_CKS_RO_USER_FUNCTIONS;
579 else
580 state = PKCS11_CKS_RW_USER_FUNCTIONS;
581 break;
582 case PKCS11_CKS_RW_SO_FUNCTIONS:
583 if (readonly)
584 TEE_Panic(0);
585 else
586 state = PKCS11_CKS_RW_SO_FUNCTIONS;
587 break;
588 default:
589 TEE_Panic(0);
590 }
591 break;
592 }
593 }
594
595 session->state = state;
596 }
597
entry_ck_open_session(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)598 enum pkcs11_rc entry_ck_open_session(struct pkcs11_client *client,
599 uint32_t ptypes, TEE_Param *params)
600 {
601 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
602 TEE_PARAM_TYPE_NONE,
603 TEE_PARAM_TYPE_MEMREF_OUTPUT,
604 TEE_PARAM_TYPE_NONE);
605 TEE_Param *ctrl = params;
606 TEE_Param *out = params + 2;
607 enum pkcs11_rc rc = PKCS11_CKR_OK;
608 struct serialargs ctrlargs = { };
609 uint32_t token_id = 0;
610 uint32_t flags = 0;
611 struct ck_token *token = NULL;
612 struct pkcs11_session *session = NULL;
613 bool readonly = false;
614
615 if (!client || ptypes != exp_pt ||
616 out->memref.size != sizeof(session->handle))
617 return PKCS11_CKR_ARGUMENTS_BAD;
618
619 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
620
621 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
622 if (rc)
623 return rc;
624
625 rc = serialargs_get(&ctrlargs, &flags, sizeof(flags));
626 if (rc)
627 return rc;
628
629 if (serialargs_remaining_bytes(&ctrlargs))
630 return PKCS11_CKR_ARGUMENTS_BAD;
631
632 token = get_token(token_id);
633 if (!token)
634 return PKCS11_CKR_SLOT_ID_INVALID;
635
636 /* Sanitize session flags */
637 if (!(flags & PKCS11_CKFSS_SERIAL_SESSION))
638 return PKCS11_CKR_SESSION_PARALLEL_NOT_SUPPORTED;
639
640 if (flags & ~(PKCS11_CKFSS_RW_SESSION | PKCS11_CKFSS_SERIAL_SESSION))
641 return PKCS11_CKR_ARGUMENTS_BAD;
642
643 readonly = !(flags & PKCS11_CKFSS_RW_SESSION);
644
645 if (!readonly && token->state == PKCS11_TOKEN_READ_ONLY)
646 return PKCS11_CKR_TOKEN_WRITE_PROTECTED;
647
648 if (readonly) {
649 /* Specifically reject read-only session under SO login */
650 TAILQ_FOREACH(session, &client->session_list, link)
651 if (pkcs11_session_is_so(session))
652 return PKCS11_CKR_SESSION_READ_WRITE_SO_EXISTS;
653 }
654
655 session = TEE_Malloc(sizeof(*session), TEE_MALLOC_FILL_ZERO);
656 if (!session)
657 return PKCS11_CKR_DEVICE_MEMORY;
658
659 session->handle = handle_get(&client->session_handle_db, session);
660 if (!session->handle) {
661 TEE_Free(session);
662 return PKCS11_CKR_DEVICE_MEMORY;
663 }
664
665 session->token = token;
666 session->client = client;
667
668 LIST_INIT(&session->object_list);
669
670 set_session_state(client, session, readonly);
671
672 TAILQ_INSERT_HEAD(&client->session_list, session, link);
673
674 session->token->session_count++;
675 if (!readonly)
676 session->token->rw_session_count++;
677
678 TEE_MemMove(out->memref.buffer, &session->handle,
679 sizeof(session->handle));
680
681 DMSG("Open PKCS11 session %"PRIu32, session->handle);
682
683 return PKCS11_CKR_OK;
684 }
685
close_ck_session(struct pkcs11_session * session)686 static void close_ck_session(struct pkcs11_session *session)
687 {
688 release_active_processing(session);
689 release_session_find_obj_context(session);
690
691 /* Release all session objects */
692 while (!LIST_EMPTY(&session->object_list))
693 destroy_object(session,
694 LIST_FIRST(&session->object_list), true);
695
696 TAILQ_REMOVE(&session->client->session_list, session, link);
697 handle_put(&session->client->session_handle_db, session->handle);
698
699 session->token->session_count--;
700 if (pkcs11_session_is_read_write(session))
701 session->token->rw_session_count--;
702
703 DMSG("Close PKCS11 session %"PRIu32, session->handle);
704
705 TEE_Free(session);
706 }
707
entry_ck_close_session(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)708 enum pkcs11_rc entry_ck_close_session(struct pkcs11_client *client,
709 uint32_t ptypes, TEE_Param *params)
710 {
711 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
712 TEE_PARAM_TYPE_NONE,
713 TEE_PARAM_TYPE_NONE,
714 TEE_PARAM_TYPE_NONE);
715 TEE_Param *ctrl = params;
716 enum pkcs11_rc rc = PKCS11_CKR_OK;
717 struct serialargs ctrlargs = { };
718 struct pkcs11_session *session = NULL;
719
720 if (!client || ptypes != exp_pt)
721 return PKCS11_CKR_ARGUMENTS_BAD;
722
723 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
724
725 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
726 if (rc)
727 return rc;
728
729 if (serialargs_remaining_bytes(&ctrlargs))
730 return PKCS11_CKR_ARGUMENTS_BAD;
731
732 close_ck_session(session);
733
734 return PKCS11_CKR_OK;
735 }
736
entry_ck_close_all_sessions(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)737 enum pkcs11_rc entry_ck_close_all_sessions(struct pkcs11_client *client,
738 uint32_t ptypes, TEE_Param *params)
739 {
740 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
741 TEE_PARAM_TYPE_NONE,
742 TEE_PARAM_TYPE_NONE,
743 TEE_PARAM_TYPE_NONE);
744 TEE_Param *ctrl = params;
745 enum pkcs11_rc rc = PKCS11_CKR_OK;
746 struct serialargs ctrlargs = { };
747 uint32_t token_id = 0;
748 struct ck_token *token = NULL;
749 struct pkcs11_session *session = NULL;
750 struct pkcs11_session *next = NULL;
751
752 if (!client || ptypes != exp_pt)
753 return PKCS11_CKR_ARGUMENTS_BAD;
754
755 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
756
757 rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
758 if (rc)
759 return rc;
760
761 if (serialargs_remaining_bytes(&ctrlargs))
762 return PKCS11_CKR_ARGUMENTS_BAD;
763
764 token = get_token(token_id);
765 if (!token)
766 return PKCS11_CKR_SLOT_ID_INVALID;
767
768 DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id);
769
770 TAILQ_FOREACH_SAFE(session, &client->session_list, link, next)
771 if (session->token == token)
772 close_ck_session(session);
773
774 return PKCS11_CKR_OK;
775 }
776
entry_ck_session_info(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)777 enum pkcs11_rc entry_ck_session_info(struct pkcs11_client *client,
778 uint32_t ptypes, TEE_Param *params)
779 {
780 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
781 TEE_PARAM_TYPE_NONE,
782 TEE_PARAM_TYPE_MEMREF_OUTPUT,
783 TEE_PARAM_TYPE_NONE);
784 TEE_Param *ctrl = params;
785 TEE_Param *out = params + 2;
786 enum pkcs11_rc rc = PKCS11_CKR_OK;
787 struct serialargs ctrlargs = { };
788 struct pkcs11_session *session = NULL;
789 struct pkcs11_session_info info = {
790 .flags = PKCS11_CKFSS_SERIAL_SESSION,
791 };
792
793 if (!client || ptypes != exp_pt || out->memref.size != sizeof(info))
794 return PKCS11_CKR_ARGUMENTS_BAD;
795
796 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
797
798 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
799 if (rc)
800 return rc;
801
802 if (serialargs_remaining_bytes(&ctrlargs))
803 return PKCS11_CKR_ARGUMENTS_BAD;
804
805 info.slot_id = get_token_id(session->token);
806 info.state = session->state;
807 if (pkcs11_session_is_read_write(session))
808 info.flags |= PKCS11_CKFSS_RW_SESSION;
809
810 TEE_MemMove(out->memref.buffer, &info, sizeof(info));
811
812 DMSG("Get find on PKCS11 session %"PRIu32, session->handle);
813
814 return PKCS11_CKR_OK;
815 }
816
entry_ck_token_initialize(uint32_t ptypes,TEE_Param * params)817 enum pkcs11_rc entry_ck_token_initialize(uint32_t ptypes, TEE_Param *params)
818 {
819 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
820 TEE_PARAM_TYPE_NONE,
821 TEE_PARAM_TYPE_NONE,
822 TEE_PARAM_TYPE_NONE);
823 char label[PKCS11_TOKEN_LABEL_SIZE] = { 0 };
824 struct pkcs11_client *client = NULL;
825 struct pkcs11_session *sess = NULL;
826 enum pkcs11_rc rc = PKCS11_CKR_OK;
827 struct serialargs ctrlargs = { };
828 struct ck_token *token = NULL;
829 TEE_Param *ctrl = params;
830 uint32_t token_id = 0;
831 uint32_t pin_size = 0;
832 void *pin = NULL;
833 struct pkcs11_object *obj = NULL;
834
835 if (ptypes != exp_pt)
836 return PKCS11_CKR_ARGUMENTS_BAD;
837
838 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
839
840 rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
841 if (rc)
842 return rc;
843
844 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
845 if (rc)
846 return rc;
847
848 rc = serialargs_get(&ctrlargs, &label, PKCS11_TOKEN_LABEL_SIZE);
849 if (rc)
850 return rc;
851
852 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
853 if (rc)
854 return rc;
855
856 if (serialargs_remaining_bytes(&ctrlargs))
857 return PKCS11_CKR_ARGUMENTS_BAD;
858
859 token = get_token(token_id);
860 if (!token)
861 return PKCS11_CKR_SLOT_ID_INVALID;
862
863 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) {
864 IMSG("Token %"PRIu32": SO PIN locked", token_id);
865 return PKCS11_CKR_PIN_LOCKED;
866 }
867
868 /* Check there's no open session on this token */
869 TAILQ_FOREACH(client, &pkcs11_client_list, link)
870 TAILQ_FOREACH(sess, &client->session_list, link)
871 if (sess->token == token)
872 return PKCS11_CKR_SESSION_EXISTS;
873
874 /* Verify authentication if token is already initialized */
875 if (token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED) {
876 unsigned int pin_count = 0;
877
878 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) &&
879 (token->db_main->flags &
880 PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH)) {
881 /* Check TEE Identity based authentication if enabled */
882 rc = verify_identity_auth(token, PKCS11_CKU_SO);
883 if (rc)
884 return rc;
885
886 goto inited;
887 }
888
889 /* Check PIN based authentication */
890 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size,
891 token->db_main->so_pin_salt,
892 token->db_main->so_pin_hash);
893 if (!rc)
894 goto inited;
895
896 if (rc != PKCS11_CKR_PIN_INCORRECT)
897 return rc;
898
899 token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW;
900 token->db_main->so_pin_count++;
901
902 pin_count = token->db_main->so_pin_count;
903 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1)
904 token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY;
905 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX)
906 token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED;
907
908 update_persistent_db(token);
909
910 return PKCS11_CKR_PIN_INCORRECT;
911 }
912
913 /* Initialize SO's authentication */
914 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) && !pin) {
915 rc = setup_so_identity_auth_from_client(token);
916 if (rc)
917 return rc;
918 } else {
919 /*
920 * The spec doesn't permit returning
921 * PKCS11_CKR_PIN_LEN_RANGE for this function, take another
922 * error code.
923 */
924 if (pin_size < PKCS11_TOKEN_PIN_SIZE_MIN ||
925 pin_size > PKCS11_TOKEN_PIN_SIZE_MAX)
926 return PKCS11_CKR_ARGUMENTS_BAD;
927
928 rc = hash_pin(PKCS11_CKU_SO, pin, pin_size,
929 &token->db_main->so_pin_salt,
930 token->db_main->so_pin_hash);
931 if (rc)
932 return rc;
933 }
934
935 inited:
936 /* Make sure SO PIN counters are zeroed */
937 token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW |
938 PKCS11_CKFT_SO_PIN_FINAL_TRY |
939 PKCS11_CKFT_SO_PIN_LOCKED |
940 PKCS11_CKFT_SO_PIN_TO_BE_CHANGED);
941 token->db_main->so_pin_count = 0;
942
943 TEE_MemMove(token->db_main->label, label, PKCS11_TOKEN_LABEL_SIZE);
944 token->db_main->flags |= PKCS11_CKFT_TOKEN_INITIALIZED;
945 /* Reset user PIN */
946 token->db_main->user_pin_salt = 0;
947 token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_INITIALIZED |
948 PKCS11_CKFT_USER_PIN_COUNT_LOW |
949 PKCS11_CKFT_USER_PIN_FINAL_TRY |
950 PKCS11_CKFT_USER_PIN_LOCKED |
951 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED);
952
953 update_persistent_db(token);
954
955 /* Remove all persistent objects */
956 while (!LIST_EMPTY(&token->object_list)) {
957 obj = LIST_FIRST(&token->object_list);
958
959 /* Try twice otherwise panic! */
960 if (unregister_persistent_object(token, obj->uuid) &&
961 unregister_persistent_object(token, obj->uuid))
962 TEE_Panic(0);
963
964 cleanup_persistent_object(obj, token);
965 }
966
967 IMSG("PKCS11 token %"PRIu32": initialized", token_id);
968
969 return PKCS11_CKR_OK;
970 }
971
set_pin(struct pkcs11_session * session,uint8_t * new_pin,size_t new_pin_size,enum pkcs11_user_type user_type)972 static enum pkcs11_rc set_pin(struct pkcs11_session *session,
973 uint8_t *new_pin, size_t new_pin_size,
974 enum pkcs11_user_type user_type)
975 {
976 struct ck_token *token = session->token;
977 enum pkcs11_rc rc = PKCS11_CKR_OK;
978 uint32_t flags_clear = 0;
979 uint32_t flags_set = 0;
980
981 if (token->db_main->flags & PKCS11_CKFT_WRITE_PROTECTED)
982 return PKCS11_CKR_TOKEN_WRITE_PROTECTED;
983
984 if (!pkcs11_session_is_read_write(session))
985 return PKCS11_CKR_SESSION_READ_ONLY;
986
987 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) &&
988 (token->db_main->flags &
989 PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH)) {
990 rc = setup_identity_auth_from_pin(token, user_type,
991 new_pin, new_pin_size);
992 if (rc == PKCS11_CKR_OK) {
993 goto update_db;
994 } else if (rc == PKCS11_CKR_PIN_INVALID &&
995 !(token->db_main->flags &
996 PKCS11_CKFT_USER_PIN_INITIALIZED)) {
997 /*
998 * PIN was not compatible with TEE Identity
999 * Authentication syntax so let's assume it might be a
1000 * new SO PIN to switch the authentication mode.
1001 */
1002
1003 /* Update mode flag if all PIN checks pass */
1004 flags_clear |=
1005 PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH;
1006 } else {
1007 return rc;
1008 }
1009 } else if ((user_type == PKCS11_CKU_SO) && !new_pin &&
1010 IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) &&
1011 !(token->db_main->flags &
1012 PKCS11_CKFT_USER_PIN_INITIALIZED)) {
1013 /*
1014 * Allow changing of token authentication mode before user pin
1015 * has been initialized.
1016 */
1017
1018 /*
1019 * Set protected authentication path temporary until
1020 * finalized.
1021 */
1022 token->db_main->flags |=
1023 PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH;
1024
1025 /*
1026 * Setup authentication from currently active TEE Client
1027 * Identity.
1028 */
1029 rc = setup_identity_auth_from_pin(token, PKCS11_CKU_SO,
1030 NULL, 0);
1031 if (rc) {
1032 /*
1033 * Failed to setup protected authentication path so
1034 * clear the temporary flag.
1035 */
1036 token->db_main->flags &=
1037 ~PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH;
1038 return rc;
1039 }
1040
1041 goto update_db;
1042 }
1043
1044 if (new_pin_size < PKCS11_TOKEN_PIN_SIZE_MIN ||
1045 new_pin_size > PKCS11_TOKEN_PIN_SIZE_MAX)
1046 return PKCS11_CKR_PIN_LEN_RANGE;
1047
1048 switch (user_type) {
1049 case PKCS11_CKU_SO:
1050 rc = hash_pin(user_type, new_pin, new_pin_size,
1051 &token->db_main->so_pin_salt,
1052 token->db_main->so_pin_hash);
1053 if (rc)
1054 return rc;
1055 token->db_main->so_pin_count = 0;
1056 flags_clear |= PKCS11_CKFT_SO_PIN_COUNT_LOW |
1057 PKCS11_CKFT_SO_PIN_FINAL_TRY |
1058 PKCS11_CKFT_SO_PIN_LOCKED |
1059 PKCS11_CKFT_SO_PIN_TO_BE_CHANGED;
1060 break;
1061 case PKCS11_CKU_USER:
1062 rc = hash_pin(user_type, new_pin, new_pin_size,
1063 &token->db_main->user_pin_salt,
1064 token->db_main->user_pin_hash);
1065 if (rc)
1066 return rc;
1067 token->db_main->user_pin_count = 0;
1068 flags_clear |= PKCS11_CKFT_USER_PIN_COUNT_LOW |
1069 PKCS11_CKFT_USER_PIN_FINAL_TRY |
1070 PKCS11_CKFT_USER_PIN_LOCKED |
1071 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED;
1072 flags_set |= PKCS11_CKFT_USER_PIN_INITIALIZED;
1073 break;
1074 default:
1075 return PKCS11_CKR_FUNCTION_FAILED;
1076 }
1077
1078 update_db:
1079 token->db_main->flags &= ~flags_clear;
1080 token->db_main->flags |= flags_set;
1081
1082 update_persistent_db(token);
1083
1084 return PKCS11_CKR_OK;
1085 }
1086
entry_ck_init_pin(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)1087 enum pkcs11_rc entry_ck_init_pin(struct pkcs11_client *client,
1088 uint32_t ptypes, TEE_Param *params)
1089 {
1090 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1091 TEE_PARAM_TYPE_NONE,
1092 TEE_PARAM_TYPE_NONE,
1093 TEE_PARAM_TYPE_NONE);
1094 struct pkcs11_session *session = NULL;
1095 enum pkcs11_rc rc = PKCS11_CKR_OK;
1096 struct serialargs ctrlargs = { };
1097 TEE_Param *ctrl = params;
1098 uint32_t pin_size = 0;
1099 void *pin = NULL;
1100
1101 if (!client || ptypes != exp_pt)
1102 return PKCS11_CKR_ARGUMENTS_BAD;
1103
1104 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1105
1106 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
1107 if (rc)
1108 return rc;
1109
1110 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
1111 if (rc)
1112 return rc;
1113
1114 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
1115 if (rc)
1116 return rc;
1117
1118 if (serialargs_remaining_bytes(&ctrlargs))
1119 return PKCS11_CKR_ARGUMENTS_BAD;
1120
1121 if (!pkcs11_session_is_so(session))
1122 return PKCS11_CKR_USER_NOT_LOGGED_IN;
1123
1124 assert(session->token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED);
1125
1126 IMSG("PKCS11 session %"PRIu32": init PIN", session->handle);
1127
1128 return set_pin(session, pin, pin_size, PKCS11_CKU_USER);
1129 }
1130
check_so_pin(struct pkcs11_session * session,uint8_t * pin,size_t pin_size)1131 static enum pkcs11_rc check_so_pin(struct pkcs11_session *session,
1132 uint8_t *pin, size_t pin_size)
1133 {
1134 struct ck_token *token = session->token;
1135 struct token_persistent_main *db = token->db_main;
1136 enum pkcs11_rc rc = PKCS11_CKR_OK;
1137
1138 assert(db->flags & PKCS11_CKFT_TOKEN_INITIALIZED);
1139
1140 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) &&
1141 db->flags & PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH)
1142 return verify_identity_auth(token, PKCS11_CKU_SO);
1143
1144 if (db->flags & PKCS11_CKFT_SO_PIN_LOCKED)
1145 return PKCS11_CKR_PIN_LOCKED;
1146
1147 /*
1148 * Preset the counter and flags conservatively in the database so that
1149 * the tentative is saved whatever happens next.
1150 */
1151 db->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW;
1152 db->so_pin_count++;
1153
1154 if (db->so_pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1)
1155 db->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY;
1156 else if (db->so_pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX)
1157 db->flags |= PKCS11_CKFT_SO_PIN_LOCKED;
1158
1159 update_persistent_db(token);
1160
1161 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size,
1162 db->so_pin_salt,
1163 db->so_pin_hash);
1164 if (rc == PKCS11_CKR_PIN_INCORRECT) {
1165 if (db->flags & PKCS11_CKFT_SO_PIN_LOCKED)
1166 return PKCS11_CKR_PIN_LOCKED;
1167
1168 return PKCS11_CKR_PIN_INCORRECT;
1169 }
1170
1171 if (rc)
1172 db->so_pin_count--;
1173 else
1174 db->so_pin_count = 0;
1175
1176 db->flags &= ~PKCS11_CKFT_SO_PIN_LOCKED;
1177 if (db->so_pin_count < PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1) {
1178 db->flags &= ~PKCS11_CKFT_SO_PIN_FINAL_TRY;
1179 if (!db->so_pin_count)
1180 db->flags &= ~PKCS11_CKFT_SO_PIN_COUNT_LOW;
1181 }
1182
1183 update_persistent_db(token);
1184
1185 return rc;
1186 }
1187
check_user_pin(struct pkcs11_session * session,uint8_t * pin,size_t pin_size)1188 static enum pkcs11_rc check_user_pin(struct pkcs11_session *session,
1189 uint8_t *pin, size_t pin_size)
1190 {
1191 struct ck_token *token = session->token;
1192 struct token_persistent_main *db = token->db_main;
1193 enum pkcs11_rc rc = PKCS11_CKR_OK;
1194
1195 if (!(db->flags & PKCS11_CKFT_USER_PIN_INITIALIZED))
1196 return PKCS11_CKR_USER_PIN_NOT_INITIALIZED;
1197
1198 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) &&
1199 db->flags & PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH)
1200 return verify_identity_auth(token, PKCS11_CKU_USER);
1201
1202 assert(db->user_pin_salt);
1203
1204 if (db->flags & PKCS11_CKFT_USER_PIN_LOCKED)
1205 return PKCS11_CKR_PIN_LOCKED;
1206
1207 /*
1208 * Preset the counter and flags conservatively in the database so that
1209 * the tentative is saved whatever happens next.
1210 */
1211 db->flags |= PKCS11_CKFT_USER_PIN_COUNT_LOW;
1212 db->user_pin_count++;
1213
1214 if (db->user_pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX - 1)
1215 db->flags |= PKCS11_CKFT_USER_PIN_FINAL_TRY;
1216 else if (db->user_pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX)
1217 db->flags |= PKCS11_CKFT_USER_PIN_LOCKED;
1218
1219 update_persistent_db(token);
1220
1221 rc = verify_pin(PKCS11_CKU_USER, pin, pin_size,
1222 db->user_pin_salt,
1223 db->user_pin_hash);
1224 if (rc == PKCS11_CKR_PIN_INCORRECT) {
1225 if (db->flags & PKCS11_CKFT_USER_PIN_LOCKED)
1226 return PKCS11_CKR_PIN_LOCKED;
1227
1228 return PKCS11_CKR_PIN_INCORRECT;
1229 }
1230
1231 if (rc)
1232 db->user_pin_count--;
1233 else
1234 db->user_pin_count = 0;
1235
1236 db->flags &= ~PKCS11_CKFT_USER_PIN_LOCKED;
1237 if (db->user_pin_count < PKCS11_TOKEN_USER_PIN_COUNT_MAX - 1) {
1238 db->flags &= ~PKCS11_CKFT_USER_PIN_FINAL_TRY;
1239 if (!db->user_pin_count)
1240 db->flags &= ~PKCS11_CKFT_USER_PIN_COUNT_LOW;
1241 }
1242
1243 update_persistent_db(token);
1244
1245 return rc;
1246 }
1247
entry_ck_set_pin(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)1248 enum pkcs11_rc entry_ck_set_pin(struct pkcs11_client *client,
1249 uint32_t ptypes, TEE_Param *params)
1250 {
1251 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1252 TEE_PARAM_TYPE_NONE,
1253 TEE_PARAM_TYPE_NONE,
1254 TEE_PARAM_TYPE_NONE);
1255 struct pkcs11_session *session = NULL;
1256 enum pkcs11_rc rc = PKCS11_CKR_OK;
1257 struct serialargs ctrlargs = { };
1258 uint32_t old_pin_size = 0;
1259 TEE_Param *ctrl = params;
1260 uint32_t pin_size = 0;
1261 void *old_pin = NULL;
1262 void *pin = NULL;
1263
1264 if (!client || ptypes != exp_pt)
1265 return PKCS11_CKR_ARGUMENTS_BAD;
1266
1267 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1268
1269 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
1270 if (rc)
1271 return rc;
1272
1273 rc = serialargs_get(&ctrlargs, &old_pin_size, sizeof(uint32_t));
1274 if (rc)
1275 return rc;
1276
1277 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
1278 if (rc)
1279 return rc;
1280
1281 rc = serialargs_get_ptr(&ctrlargs, &old_pin, old_pin_size);
1282 if (rc)
1283 return rc;
1284
1285 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
1286 if (rc)
1287 return rc;
1288
1289 if (serialargs_remaining_bytes(&ctrlargs))
1290 return PKCS11_CKR_ARGUMENTS_BAD;
1291
1292 if (!pkcs11_session_is_read_write(session))
1293 return PKCS11_CKR_SESSION_READ_ONLY;
1294
1295 if (pkcs11_session_is_so(session)) {
1296 if (!(session->token->db_main->flags &
1297 PKCS11_CKFT_TOKEN_INITIALIZED))
1298 return PKCS11_CKR_GENERAL_ERROR;
1299
1300 rc = check_so_pin(session, old_pin, old_pin_size);
1301 if (rc)
1302 return rc;
1303
1304 IMSG("PKCS11 session %"PRIu32": set PIN", session->handle);
1305
1306 return set_pin(session, pin, pin_size, PKCS11_CKU_SO);
1307 }
1308
1309 if (!(session->token->db_main->flags &
1310 PKCS11_CKFT_USER_PIN_INITIALIZED))
1311 return PKCS11_CKR_GENERAL_ERROR;
1312
1313 rc = check_user_pin(session, old_pin, old_pin_size);
1314 if (rc)
1315 return rc;
1316
1317 IMSG("PKCS11 session %"PRIu32": set PIN", session->handle);
1318
1319 return set_pin(session, pin, pin_size, PKCS11_CKU_USER);
1320 }
1321
session_login_user(struct pkcs11_session * session)1322 static void session_login_user(struct pkcs11_session *session)
1323 {
1324 struct pkcs11_client *client = session->client;
1325 struct pkcs11_session *sess = NULL;
1326
1327 TAILQ_FOREACH(sess, &client->session_list, link) {
1328 if (sess->token != session->token)
1329 continue;
1330
1331 if (pkcs11_session_is_read_write(sess))
1332 sess->state = PKCS11_CKS_RW_USER_FUNCTIONS;
1333 else
1334 sess->state = PKCS11_CKS_RO_USER_FUNCTIONS;
1335 }
1336 }
1337
session_login_so(struct pkcs11_session * session)1338 static void session_login_so(struct pkcs11_session *session)
1339 {
1340 struct pkcs11_client *client = session->client;
1341 struct pkcs11_session *sess = NULL;
1342
1343 TAILQ_FOREACH(sess, &client->session_list, link) {
1344 if (sess->token != session->token)
1345 continue;
1346
1347 if (pkcs11_session_is_read_write(sess))
1348 sess->state = PKCS11_CKS_RW_SO_FUNCTIONS;
1349 else
1350 TEE_Panic(0);
1351 }
1352 }
1353
session_logout(struct pkcs11_session * session)1354 static void session_logout(struct pkcs11_session *session)
1355 {
1356 struct pkcs11_client *client = session->client;
1357 struct pkcs11_session *sess = NULL;
1358
1359 TAILQ_FOREACH(sess, &client->session_list, link) {
1360 struct pkcs11_object *obj = NULL;
1361 struct pkcs11_object *tobj = NULL;
1362 uint32_t handle = 0;
1363
1364 if (sess->token != session->token)
1365 continue;
1366
1367 release_active_processing(session);
1368
1369 /* Destroy private session objects */
1370 LIST_FOREACH_SAFE(obj, &sess->object_list, link, tobj) {
1371 if (object_is_private(obj->attributes))
1372 destroy_object(sess, obj, true);
1373 }
1374
1375 /*
1376 * Remove handle of token private objects from
1377 * sessions object_handle_db
1378 */
1379 LIST_FOREACH(obj, &session->token->object_list, link) {
1380 handle = pkcs11_object2handle(obj, session);
1381
1382 if (handle && object_is_private(obj->attributes))
1383 handle_put(get_object_handle_db(sess), handle);
1384 }
1385
1386 release_session_find_obj_context(session);
1387
1388 if (pkcs11_session_is_read_write(sess))
1389 sess->state = PKCS11_CKS_RW_PUBLIC_SESSION;
1390 else
1391 sess->state = PKCS11_CKS_RO_PUBLIC_SESSION;
1392 }
1393 }
1394
entry_ck_login(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)1395 enum pkcs11_rc entry_ck_login(struct pkcs11_client *client,
1396 uint32_t ptypes, TEE_Param *params)
1397 {
1398 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1399 TEE_PARAM_TYPE_NONE,
1400 TEE_PARAM_TYPE_NONE,
1401 TEE_PARAM_TYPE_NONE);
1402 struct pkcs11_session *session = NULL;
1403 struct pkcs11_session *sess = NULL;
1404 enum pkcs11_rc rc = PKCS11_CKR_OK;
1405 struct serialargs ctrlargs = { };
1406 TEE_Param *ctrl = params;
1407 uint32_t user_type = 0;
1408 uint32_t pin_size = 0;
1409 void *pin = NULL;
1410
1411 if (!client || ptypes != exp_pt)
1412 return PKCS11_CKR_ARGUMENTS_BAD;
1413
1414 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1415
1416 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
1417 if (rc)
1418 return rc;
1419
1420 rc = serialargs_get(&ctrlargs, &user_type, sizeof(uint32_t));
1421 if (rc)
1422 return rc;
1423
1424 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
1425 if (rc)
1426 return rc;
1427
1428 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
1429 if (rc)
1430 return rc;
1431
1432 if (serialargs_remaining_bytes(&ctrlargs))
1433 return PKCS11_CKR_ARGUMENTS_BAD;
1434
1435 switch (user_type) {
1436 case PKCS11_CKU_SO:
1437 if (pkcs11_session_is_so(session))
1438 return PKCS11_CKR_USER_ALREADY_LOGGED_IN;
1439
1440 if (pkcs11_session_is_user(session))
1441 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
1442
1443 TAILQ_FOREACH(sess, &client->session_list, link)
1444 if (sess->token == session->token &&
1445 !pkcs11_session_is_read_write(sess))
1446 return PKCS11_CKR_SESSION_READ_ONLY_EXISTS;
1447
1448 /*
1449 * This is the point where we could check if another client
1450 * has another user or SO logged in.
1451 *
1452 * The spec says:
1453 * CKR_USER_TOO_MANY_TYPES: An attempt was made to have
1454 * more distinct users simultaneously logged into the token
1455 * than the token and/or library permits. For example, if
1456 * some application has an open SO session, and another
1457 * application attempts to log the normal user into a
1458 * session, the attempt may return this error. It is not
1459 * required to, however. Only if the simultaneous distinct
1460 * users cannot be supported does C_Login have to return
1461 * this value. Note that this error code generalizes to
1462 * true multi-user tokens.
1463 *
1464 * So it's permitted to have another user or SO logged in
1465 * from another client.
1466 */
1467
1468 rc = check_so_pin(session, pin, pin_size);
1469 if (!rc)
1470 session_login_so(session);
1471
1472 break;
1473
1474 case PKCS11_CKU_USER:
1475 if (pkcs11_session_is_so(session))
1476 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
1477
1478 if (pkcs11_session_is_user(session))
1479 return PKCS11_CKR_USER_ALREADY_LOGGED_IN;
1480
1481 /*
1482 * This is the point where we could check if another client
1483 * has another user or SO logged in.
1484 * See comment on CKR_USER_TOO_MANY_TYPES above.
1485 */
1486
1487 rc = check_user_pin(session, pin, pin_size);
1488 if (!rc)
1489 session_login_user(session);
1490
1491 break;
1492
1493 case PKCS11_CKU_CONTEXT_SPECIFIC:
1494 return PKCS11_CKR_OPERATION_NOT_INITIALIZED;
1495
1496 default:
1497 return PKCS11_CKR_USER_TYPE_INVALID;
1498 }
1499
1500 if (!rc)
1501 IMSG("PKCS11 session %"PRIu32": login", session->handle);
1502
1503 return rc;
1504 }
1505
entry_ck_logout(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)1506 enum pkcs11_rc entry_ck_logout(struct pkcs11_client *client,
1507 uint32_t ptypes, TEE_Param *params)
1508 {
1509 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1510 TEE_PARAM_TYPE_NONE,
1511 TEE_PARAM_TYPE_NONE,
1512 TEE_PARAM_TYPE_NONE);
1513 struct pkcs11_session *session = NULL;
1514 enum pkcs11_rc rc = PKCS11_CKR_OK;
1515 struct serialargs ctrlargs = { };
1516 TEE_Param *ctrl = params;
1517
1518 if (!client || ptypes != exp_pt)
1519 return PKCS11_CKR_ARGUMENTS_BAD;
1520
1521 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1522
1523 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
1524 if (rc)
1525 return rc;
1526
1527 if (serialargs_remaining_bytes(&ctrlargs))
1528 return PKCS11_CKR_ARGUMENTS_BAD;
1529
1530 if (pkcs11_session_is_public(session))
1531 return PKCS11_CKR_USER_NOT_LOGGED_IN;
1532
1533 session_logout(session);
1534
1535 IMSG("PKCS11 session %"PRIu32": logout", session->handle);
1536
1537 return PKCS11_CKR_OK;
1538 }
1539
seed_rng_pool(void * seed,size_t length)1540 static TEE_Result seed_rng_pool(void *seed, size_t length)
1541 {
1542 static const TEE_UUID system_uuid = PTA_SYSTEM_UUID;
1543 uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1544 TEE_PARAM_TYPE_NONE,
1545 TEE_PARAM_TYPE_NONE,
1546 TEE_PARAM_TYPE_NONE);
1547 TEE_Param params[TEE_NUM_PARAMS] = { };
1548 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
1549 TEE_Result res = TEE_ERROR_GENERIC;
1550 uint32_t ret_orig = 0;
1551
1552 params[0].memref.buffer = seed;
1553 params[0].memref.size = (uint32_t)length;
1554
1555 res = TEE_OpenTASession(&system_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
1556 &sess, &ret_orig);
1557 if (res != TEE_SUCCESS) {
1558 EMSG("Can't open session to system PTA");
1559 return res;
1560 }
1561
1562 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1563 PTA_SYSTEM_ADD_RNG_ENTROPY,
1564 param_types, params, &ret_orig);
1565 if (res != TEE_SUCCESS)
1566 EMSG("Can't invoke system PTA");
1567
1568 TEE_CloseTASession(sess);
1569 return res;
1570 }
1571
entry_ck_seed_random(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)1572 enum pkcs11_rc entry_ck_seed_random(struct pkcs11_client *client,
1573 uint32_t ptypes, TEE_Param *params)
1574 {
1575 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1576 TEE_PARAM_TYPE_MEMREF_INPUT,
1577 TEE_PARAM_TYPE_NONE,
1578 TEE_PARAM_TYPE_NONE);
1579 TEE_Param *ctrl = params;
1580 TEE_Param *in = params + 1;
1581 enum pkcs11_rc rc = PKCS11_CKR_OK;
1582 struct serialargs ctrlargs = { };
1583 struct pkcs11_session *session = NULL;
1584 TEE_Result res = TEE_SUCCESS;
1585
1586 if (!client || ptypes != exp_pt)
1587 return PKCS11_CKR_ARGUMENTS_BAD;
1588
1589 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1590
1591 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
1592 if (rc)
1593 return rc;
1594
1595 if (serialargs_remaining_bytes(&ctrlargs))
1596 return PKCS11_CKR_ARGUMENTS_BAD;
1597
1598 if (in->memref.size && !in->memref.buffer)
1599 return PKCS11_CKR_ARGUMENTS_BAD;
1600
1601 if (!in->memref.size)
1602 return PKCS11_CKR_OK;
1603
1604 res = seed_rng_pool(in->memref.buffer, in->memref.size);
1605 if (res != TEE_SUCCESS)
1606 return PKCS11_CKR_FUNCTION_FAILED;
1607
1608 DMSG("PKCS11 session %"PRIu32": seed random", session->handle);
1609
1610 return PKCS11_CKR_OK;
1611 }
1612
entry_ck_generate_random(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)1613 enum pkcs11_rc entry_ck_generate_random(struct pkcs11_client *client,
1614 uint32_t ptypes, TEE_Param *params)
1615 {
1616 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1617 TEE_PARAM_TYPE_NONE,
1618 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1619 TEE_PARAM_TYPE_NONE);
1620 TEE_Param *ctrl = params;
1621 TEE_Param *out = params + 2;
1622 enum pkcs11_rc rc = PKCS11_CKR_OK;
1623 struct serialargs ctrlargs = { };
1624 struct pkcs11_session *session = NULL;
1625 void *buffer = NULL;
1626 size_t buffer_size = 0;
1627 uint8_t *data = NULL;
1628 size_t left = 0;
1629
1630 if (!client || ptypes != exp_pt)
1631 return PKCS11_CKR_ARGUMENTS_BAD;
1632
1633 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1634
1635 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
1636 if (rc)
1637 return rc;
1638
1639 if (serialargs_remaining_bytes(&ctrlargs))
1640 return PKCS11_CKR_ARGUMENTS_BAD;
1641
1642 if (out->memref.size && !out->memref.buffer)
1643 return PKCS11_CKR_ARGUMENTS_BAD;
1644
1645 if (!out->memref.size)
1646 return PKCS11_CKR_OK;
1647
1648 buffer_size = MIN(out->memref.size, RNG_CHUNK_SIZE);
1649 buffer = TEE_Malloc(buffer_size, TEE_MALLOC_FILL_ZERO);
1650 if (!buffer)
1651 return PKCS11_CKR_DEVICE_MEMORY;
1652
1653 data = out->memref.buffer;
1654 left = out->memref.size;
1655
1656 while (left) {
1657 size_t count = MIN(left, buffer_size);
1658
1659 TEE_GenerateRandom(buffer, count);
1660 TEE_MemMove(data, buffer, count);
1661
1662 data += count;
1663 left -= count;
1664 }
1665
1666 DMSG("PKCS11 session %"PRIu32": generate random", session->handle);
1667
1668 TEE_Free(buffer);
1669
1670 return PKCS11_CKR_OK;
1671 }
1672