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