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