xref: /optee_os/ta/pkcs11/src/pkcs11_token.c (revision 11fa71b9ddb429088f325cfda430183003ccd1db)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2017-2020, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <confine_array_index.h>
8 #include <pkcs11_ta.h>
9 #include <string.h>
10 #include <string_ext.h>
11 #include <sys/queue.h>
12 #include <tee_api_types.h>
13 #include <tee_internal_api_extensions.h>
14 #include <util.h>
15 
16 #include "pkcs11_helpers.h"
17 #include "pkcs11_token.h"
18 #include "serializer.h"
19 
20 /* Provide 3 slots/tokens, ID is token index */
21 #ifndef CFG_PKCS11_TA_TOKEN_COUNT
22 #define TOKEN_COUNT		3
23 #else
24 #define TOKEN_COUNT		CFG_PKCS11_TA_TOKEN_COUNT
25 #endif
26 
27 /*
28  * Structure tracking client applications
29  *
30  * @link - chained list of registered client applications
31  * @sessions - list of the PKCS11 sessions opened by the client application
32  */
33 struct pkcs11_client {
34 	TAILQ_ENTRY(pkcs11_client) link;
35 	struct session_list session_list;
36 	struct handle_db session_handle_db;
37 };
38 
39 /* Static allocation of tokens runtime instances (reset to 0 at load) */
40 struct ck_token ck_token[TOKEN_COUNT];
41 
42 static struct client_list pkcs11_client_list =
43 	TAILQ_HEAD_INITIALIZER(pkcs11_client_list);
44 
45 static void close_ck_session(struct pkcs11_session *session);
46 
47 struct ck_token *get_token(unsigned int token_id)
48 {
49 	if (token_id < TOKEN_COUNT)
50 		return &ck_token[confine_array_index(token_id, TOKEN_COUNT)];
51 
52 	return NULL;
53 }
54 
55 unsigned int get_token_id(struct ck_token *token)
56 {
57 	ptrdiff_t id = token - ck_token;
58 
59 	assert(id >= 0 && id < TOKEN_COUNT);
60 	return id;
61 }
62 
63 struct pkcs11_client *tee_session2client(void *tee_session)
64 {
65 	struct pkcs11_client *client = NULL;
66 
67 	TAILQ_FOREACH(client, &pkcs11_client_list, link)
68 		if (client == tee_session)
69 			break;
70 
71 	return client;
72 }
73 
74 struct pkcs11_session *pkcs11_handle2session(uint32_t handle,
75 					     struct pkcs11_client *client)
76 {
77 	return handle_lookup(&client->session_handle_db, handle);
78 }
79 
80 struct pkcs11_client *register_client(void)
81 {
82 	struct pkcs11_client *client = NULL;
83 
84 	client = TEE_Malloc(sizeof(*client), TEE_MALLOC_FILL_ZERO);
85 	if (!client)
86 		return NULL;
87 
88 	TAILQ_INSERT_HEAD(&pkcs11_client_list, client, link);
89 	TAILQ_INIT(&client->session_list);
90 	handle_db_init(&client->session_handle_db);
91 
92 	return client;
93 }
94 
95 void unregister_client(struct pkcs11_client *client)
96 {
97 	struct pkcs11_session *session = NULL;
98 	struct pkcs11_session *next = NULL;
99 
100 	if (!client) {
101 		EMSG("Invalid TEE session handle");
102 		return;
103 	}
104 
105 	TAILQ_FOREACH_SAFE(session, &client->session_list, link, next)
106 		close_ck_session(session);
107 
108 	TAILQ_REMOVE(&pkcs11_client_list, client, link);
109 	handle_db_destroy(&client->session_handle_db);
110 	TEE_Free(client);
111 }
112 
113 static TEE_Result pkcs11_token_init(unsigned int id)
114 {
115 	struct ck_token *token = init_persistent_db(id);
116 
117 	if (!token)
118 		return TEE_ERROR_SECURITY;
119 
120 	if (token->state == PKCS11_TOKEN_RESET) {
121 		/* As per PKCS#11 spec, token resets to read/write state */
122 		token->state = PKCS11_TOKEN_READ_WRITE;
123 		token->session_count = 0;
124 		token->rw_session_count = 0;
125 	}
126 
127 	return TEE_SUCCESS;
128 }
129 
130 TEE_Result pkcs11_init(void)
131 {
132 	unsigned int id = 0;
133 	TEE_Result ret = TEE_ERROR_GENERIC;
134 
135 	for (id = 0; id < TOKEN_COUNT; id++) {
136 		ret = pkcs11_token_init(id);
137 		if (ret)
138 			break;
139 	}
140 
141 	return ret;
142 }
143 
144 void pkcs11_deinit(void)
145 {
146 	unsigned int id = 0;
147 
148 	for (id = 0; id < TOKEN_COUNT; id++)
149 		close_persistent_db(get_token(id));
150 }
151 
152 uint32_t entry_ck_slot_list(uint32_t ptypes, TEE_Param *params)
153 {
154 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
155 						TEE_PARAM_TYPE_NONE,
156 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
157 						TEE_PARAM_TYPE_NONE);
158 	TEE_Param *out = &params[2];
159 	uint32_t token_id = 0;
160 	const size_t out_size = sizeof(token_id) * TOKEN_COUNT;
161 	uint8_t *id = NULL;
162 
163 	if (ptypes != exp_pt ||
164 	    params[0].memref.size != TEE_PARAM0_SIZE_MIN)
165 		return PKCS11_CKR_ARGUMENTS_BAD;
166 
167 	if (out->memref.size < out_size) {
168 		out->memref.size = out_size;
169 
170 		if (out->memref.buffer)
171 			return PKCS11_CKR_BUFFER_TOO_SMALL;
172 		else
173 			return PKCS11_CKR_OK;
174 	}
175 
176 	for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT;
177 	     token_id++, id += sizeof(token_id))
178 		TEE_MemMove(id, &token_id, sizeof(token_id));
179 
180 	out->memref.size = out_size;
181 
182 	return PKCS11_CKR_OK;
183 }
184 
185 static void pad_str(uint8_t *str, size_t size)
186 {
187 	int n = strnlen((char *)str, size);
188 
189 	TEE_MemFill(str + n, ' ', size - n);
190 }
191 
192 uint32_t entry_ck_slot_info(uint32_t ptypes, TEE_Param *params)
193 {
194 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
195 						TEE_PARAM_TYPE_NONE,
196 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
197 						TEE_PARAM_TYPE_NONE);
198 	TEE_Param *ctrl = &params[0];
199 	TEE_Param *out = &params[2];
200 	uint32_t rv = 0;
201 	struct serialargs ctrlargs = { };
202 	uint32_t token_id = 0;
203 	struct ck_token *token = NULL;
204 	struct pkcs11_slot_info info = {
205 		.slot_description = PKCS11_SLOT_DESCRIPTION,
206 		.manufacturer_id = PKCS11_SLOT_MANUFACTURER,
207 		.flags = PKCS11_CKFS_TOKEN_PRESENT,
208 		.hardware_version = PKCS11_SLOT_HW_VERSION,
209 		.firmware_version = PKCS11_SLOT_FW_VERSION,
210 	};
211 
212 	COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <=
213 			    sizeof(info.slot_description));
214 	COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <=
215 			    sizeof(info.manufacturer_id));
216 
217 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
218 		return PKCS11_CKR_ARGUMENTS_BAD;
219 
220 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
221 
222 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
223 	if (rv)
224 		return rv;
225 
226 	if (serialargs_remaining_bytes(&ctrlargs))
227 		return PKCS11_CKR_ARGUMENTS_BAD;
228 
229 	token = get_token(token_id);
230 	if (!token)
231 		return PKCS11_CKR_SLOT_ID_INVALID;
232 
233 	pad_str(info.slot_description, sizeof(info.slot_description));
234 	pad_str(info.manufacturer_id, sizeof(info.manufacturer_id));
235 
236 	out->memref.size = sizeof(info);
237 	TEE_MemMove(out->memref.buffer, &info, out->memref.size);
238 
239 	return PKCS11_CKR_OK;
240 }
241 
242 uint32_t entry_ck_token_info(uint32_t ptypes, TEE_Param *params)
243 {
244 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
245 						TEE_PARAM_TYPE_NONE,
246 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
247 						TEE_PARAM_TYPE_NONE);
248 	TEE_Param *ctrl = &params[0];
249 	TEE_Param *out = &params[2];
250 	uint32_t rv = 0;
251 	struct serialargs ctrlargs = { };
252 	uint32_t token_id = 0;
253 	struct ck_token *token = NULL;
254 	struct pkcs11_token_info info = {
255 		.manufacturer_id = PKCS11_TOKEN_MANUFACTURER,
256 		.model = PKCS11_TOKEN_MODEL,
257 		.serial_number = PKCS11_TOKEN_SERIAL_NUMBER,
258 		.max_session_count = UINT32_MAX,
259 		.max_rw_session_count = UINT32_MAX,
260 		.max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX,
261 		.min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN,
262 		.total_public_memory = UINT32_MAX,
263 		.free_public_memory = UINT32_MAX,
264 		.total_private_memory = UINT32_MAX,
265 		.free_private_memory = UINT32_MAX,
266 		.hardware_version = PKCS11_TOKEN_HW_VERSION,
267 		.firmware_version = PKCS11_TOKEN_FW_VERSION,
268 	};
269 
270 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
271 		return PKCS11_CKR_ARGUMENTS_BAD;
272 
273 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
274 
275 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
276 	if (rv)
277 		return rv;
278 
279 	if (serialargs_remaining_bytes(&ctrlargs))
280 		return PKCS11_CKR_ARGUMENTS_BAD;
281 
282 	token = get_token(token_id);
283 	if (!token)
284 		return PKCS11_CKR_SLOT_ID_INVALID;
285 
286 	pad_str(info.manufacturer_id, sizeof(info.manufacturer_id));
287 	pad_str(info.model, sizeof(info.model));
288 	pad_str(info.serial_number, sizeof(info.serial_number));
289 
290 	TEE_MemMove(info.label, token->db_main->label, sizeof(info.label));
291 
292 	info.flags = token->db_main->flags;
293 	info.session_count = token->session_count;
294 	info.rw_session_count = token->rw_session_count;
295 
296 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
297 
298 	return PKCS11_CKR_OK;
299 }
300 
301 static void dmsg_print_supported_mechanism(unsigned int token_id __maybe_unused,
302 					   uint32_t *array __maybe_unused,
303 					   size_t count __maybe_unused)
304 {
305 	size_t __maybe_unused n = 0;
306 
307 	if (TRACE_LEVEL < TRACE_DEBUG)
308 		return;
309 
310 	for (n = 0; n < count; n++)
311 		DMSG("PKCS11 token %"PRIu32": mechanism 0x%04"PRIx32": %s",
312 		     token_id, array[n], id2str_mechanism(array[n]));
313 }
314 
315 uint32_t entry_ck_token_mecha_ids(uint32_t ptypes, TEE_Param *params)
316 {
317 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
318 						TEE_PARAM_TYPE_NONE,
319 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
320 						TEE_PARAM_TYPE_NONE);
321 	TEE_Param *ctrl = &params[0];
322 	TEE_Param *out = &params[2];
323 	uint32_t rv = 0;
324 	struct serialargs ctrlargs = { };
325 	uint32_t token_id = 0;
326 	struct ck_token __maybe_unused *token = NULL;
327 	size_t count = 0;
328 	uint32_t *array = NULL;
329 
330 	if (ptypes != exp_pt)
331 		return PKCS11_CKR_ARGUMENTS_BAD;
332 
333 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
334 
335 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
336 	if (rv)
337 		return rv;
338 
339 	if (serialargs_remaining_bytes(&ctrlargs))
340 		return PKCS11_CKR_ARGUMENTS_BAD;
341 
342 	token = get_token(token_id);
343 	if (!token)
344 		return PKCS11_CKR_SLOT_ID_INVALID;
345 
346 	count = out->memref.size / sizeof(*array);
347 	array = tee_malloc_mechanism_list(&count);
348 
349 	if (out->memref.size < count * sizeof(*array)) {
350 		assert(!array);
351 		out->memref.size = count * sizeof(*array);
352 		if (out->memref.buffer)
353 			return PKCS11_CKR_BUFFER_TOO_SMALL;
354 		else
355 			return PKCS11_CKR_OK;
356 	}
357 
358 	if (!array)
359 		return PKCS11_CKR_DEVICE_MEMORY;
360 
361 	dmsg_print_supported_mechanism(token_id, array, count);
362 
363 	out->memref.size = count * sizeof(*array);
364 	TEE_MemMove(out->memref.buffer, array, out->memref.size);
365 
366 	TEE_Free(array);
367 
368 	return rv;
369 }
370 
371 static void supported_mechanism_key_size(uint32_t proc_id,
372 					 uint32_t *max_key_size,
373 					 uint32_t *min_key_size)
374 {
375 	switch (proc_id) {
376 	/* Will be filled once TA supports mechanisms */
377 	default:
378 		*min_key_size = 0;
379 		*max_key_size = 0;
380 		break;
381 	}
382 }
383 
384 uint32_t entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params)
385 {
386 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
387 						TEE_PARAM_TYPE_NONE,
388 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
389 						TEE_PARAM_TYPE_NONE);
390 	TEE_Param *ctrl = &params[0];
391 	TEE_Param *out = &params[2];
392 	uint32_t rv = 0;
393 	struct serialargs ctrlargs = { };
394 	uint32_t token_id = 0;
395 	uint32_t type = 0;
396 	struct ck_token *token = NULL;
397 	struct pkcs11_mechanism_info info = { };
398 
399 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
400 		return PKCS11_CKR_ARGUMENTS_BAD;
401 
402 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
403 
404 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
405 	if (rv)
406 		return rv;
407 
408 	rv = serialargs_get(&ctrlargs, &type, sizeof(uint32_t));
409 	if (rv)
410 		return rv;
411 
412 	if (serialargs_remaining_bytes(&ctrlargs))
413 		return PKCS11_CKR_ARGUMENTS_BAD;
414 
415 	token = get_token(token_id);
416 	if (!token)
417 		return PKCS11_CKR_SLOT_ID_INVALID;
418 
419 	if (!mechanism_is_valid(type))
420 		return PKCS11_CKR_MECHANISM_INVALID;
421 
422 	info.flags = mechanism_supported_flags(type);
423 
424 	supported_mechanism_key_size(type, &info.min_key_size,
425 				     &info.max_key_size);
426 
427 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
428 
429 	DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info",
430 	     token_id, type);
431 
432 	return PKCS11_CKR_OK;
433 }
434 
435 /* Select the ReadOnly or ReadWrite state for session login state */
436 static void set_session_state(struct pkcs11_client *client,
437 			      struct pkcs11_session *session, bool readonly)
438 {
439 	struct pkcs11_session *sess = NULL;
440 	enum pkcs11_session_state state = PKCS11_CKS_RO_PUBLIC_SESSION;
441 
442 	/* Default to public session if no session already registered */
443 	if (readonly)
444 		state = PKCS11_CKS_RO_PUBLIC_SESSION;
445 	else
446 		state = PKCS11_CKS_RW_PUBLIC_SESSION;
447 
448 	/*
449 	 * No need to check all client sessions, the first found in
450 	 * target token gives client login configuration.
451 	 */
452 	TAILQ_FOREACH(sess, &client->session_list, link) {
453 		assert(sess != session);
454 
455 		if (sess->token == session->token) {
456 			switch (sess->state) {
457 			case PKCS11_CKS_RW_PUBLIC_SESSION:
458 			case PKCS11_CKS_RO_PUBLIC_SESSION:
459 				if (readonly)
460 					state = PKCS11_CKS_RO_PUBLIC_SESSION;
461 				else
462 					state = PKCS11_CKS_RW_PUBLIC_SESSION;
463 				break;
464 			case PKCS11_CKS_RO_USER_FUNCTIONS:
465 			case PKCS11_CKS_RW_USER_FUNCTIONS:
466 				if (readonly)
467 					state = PKCS11_CKS_RO_USER_FUNCTIONS;
468 				else
469 					state = PKCS11_CKS_RW_USER_FUNCTIONS;
470 				break;
471 			case PKCS11_CKS_RW_SO_FUNCTIONS:
472 				if (readonly)
473 					TEE_Panic(0);
474 				else
475 					state = PKCS11_CKS_RW_SO_FUNCTIONS;
476 				break;
477 			default:
478 				TEE_Panic(0);
479 			}
480 			break;
481 		}
482 	}
483 
484 	session->state = state;
485 }
486 
487 uint32_t entry_ck_open_session(struct pkcs11_client *client,
488 			       uint32_t ptypes, TEE_Param *params)
489 {
490 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
491 						TEE_PARAM_TYPE_NONE,
492 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
493 						TEE_PARAM_TYPE_NONE);
494 	TEE_Param *ctrl = &params[0];
495 	TEE_Param *out = &params[2];
496 	uint32_t rv = 0;
497 	struct serialargs ctrlargs = { };
498 	uint32_t token_id = 0;
499 	uint32_t flags = 0;
500 	struct ck_token *token = NULL;
501 	struct pkcs11_session *session = NULL;
502 	bool readonly = false;
503 
504 	if (!client || ptypes != exp_pt ||
505 	    out->memref.size != sizeof(session->handle))
506 		return PKCS11_CKR_ARGUMENTS_BAD;
507 
508 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
509 
510 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
511 	if (rv)
512 		return rv;
513 
514 	rv = serialargs_get(&ctrlargs, &flags, sizeof(flags));
515 	if (rv)
516 		return rv;
517 
518 	if (serialargs_remaining_bytes(&ctrlargs))
519 		return PKCS11_CKR_ARGUMENTS_BAD;
520 
521 	token = get_token(token_id);
522 	if (!token)
523 		return PKCS11_CKR_SLOT_ID_INVALID;
524 
525 	/* Sanitize session flags */
526 	if (!(flags & PKCS11_CKFSS_SERIAL_SESSION) ||
527 	    (flags & ~(PKCS11_CKFSS_RW_SESSION |
528 		       PKCS11_CKFSS_SERIAL_SESSION)))
529 		return PKCS11_CKR_ARGUMENTS_BAD;
530 
531 	readonly = !(flags & PKCS11_CKFSS_RW_SESSION);
532 
533 	if (!readonly && token->state == PKCS11_TOKEN_READ_ONLY)
534 		return PKCS11_CKR_TOKEN_WRITE_PROTECTED;
535 
536 	if (readonly) {
537 		/* Specifically reject read-only session under SO login */
538 		TAILQ_FOREACH(session, &client->session_list, link)
539 			if (pkcs11_session_is_so(session))
540 				return PKCS11_CKR_SESSION_READ_WRITE_SO_EXISTS;
541 	}
542 
543 	session = TEE_Malloc(sizeof(*session), TEE_MALLOC_FILL_ZERO);
544 	if (!session)
545 		return PKCS11_CKR_DEVICE_MEMORY;
546 
547 	session->handle = handle_get(&client->session_handle_db, session);
548 	if (!session->handle) {
549 		TEE_Free(session);
550 		return PKCS11_CKR_DEVICE_MEMORY;
551 	}
552 
553 	session->token = token;
554 	session->client = client;
555 
556 	set_session_state(client, session, readonly);
557 
558 	TAILQ_INSERT_HEAD(&client->session_list, session, link);
559 
560 	session->token->session_count++;
561 	if (!readonly)
562 		session->token->rw_session_count++;
563 
564 	TEE_MemMove(out->memref.buffer, &session->handle,
565 		    sizeof(session->handle));
566 
567 	DMSG("Open PKCS11 session %"PRIu32, session->handle);
568 
569 	return PKCS11_CKR_OK;
570 }
571 
572 static void close_ck_session(struct pkcs11_session *session)
573 {
574 	TAILQ_REMOVE(&session->client->session_list, session, link);
575 	handle_put(&session->client->session_handle_db, session->handle);
576 
577 	session->token->session_count--;
578 	if (pkcs11_session_is_read_write(session))
579 		session->token->rw_session_count--;
580 
581 	TEE_Free(session);
582 
583 	DMSG("Close PKCS11 session %"PRIu32, session->handle);
584 }
585 
586 uint32_t entry_ck_close_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_NONE,
592 						TEE_PARAM_TYPE_NONE);
593 	TEE_Param *ctrl = &params[0];
594 	uint32_t rv = 0;
595 	struct serialargs ctrlargs = { };
596 	uint32_t session_handle = 0;
597 	struct pkcs11_session *session = NULL;
598 
599 	if (!client || ptypes != exp_pt)
600 		return PKCS11_CKR_ARGUMENTS_BAD;
601 
602 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
603 
604 	rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
605 	if (rv)
606 		return rv;
607 
608 	if (serialargs_remaining_bytes(&ctrlargs))
609 		return PKCS11_CKR_ARGUMENTS_BAD;
610 
611 	session = pkcs11_handle2session(session_handle, client);
612 	if (!session)
613 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
614 
615 	close_ck_session(session);
616 
617 	return PKCS11_CKR_OK;
618 }
619 
620 uint32_t entry_ck_close_all_sessions(struct pkcs11_client *client,
621 				     uint32_t ptypes, TEE_Param *params)
622 {
623 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
624 						TEE_PARAM_TYPE_NONE,
625 						TEE_PARAM_TYPE_NONE,
626 						TEE_PARAM_TYPE_NONE);
627 	TEE_Param *ctrl = &params[0];
628 	uint32_t rv = 0;
629 	struct serialargs ctrlargs = { };
630 	uint32_t token_id = 0;
631 	struct ck_token *token = NULL;
632 	struct pkcs11_session *session = NULL;
633 	struct pkcs11_session *next = NULL;
634 
635 	if (!client || ptypes != exp_pt)
636 		return PKCS11_CKR_ARGUMENTS_BAD;
637 
638 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
639 
640 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
641 	if (rv)
642 		return rv;
643 
644 	if (serialargs_remaining_bytes(&ctrlargs))
645 		return PKCS11_CKR_ARGUMENTS_BAD;
646 
647 	token = get_token(token_id);
648 	if (!token)
649 		return PKCS11_CKR_SLOT_ID_INVALID;
650 
651 	DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id);
652 
653 	TAILQ_FOREACH_SAFE(session, &client->session_list, link, next)
654 		if (session->token == token)
655 			close_ck_session(session);
656 
657 	return PKCS11_CKR_OK;
658 }
659 
660 uint32_t entry_ck_session_info(struct pkcs11_client *client,
661 			       uint32_t ptypes, TEE_Param *params)
662 {
663 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
664 						TEE_PARAM_TYPE_NONE,
665 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
666 						TEE_PARAM_TYPE_NONE);
667 	TEE_Param *ctrl = &params[0];
668 	TEE_Param *out = &params[2];
669 	uint32_t rv = 0;
670 	struct serialargs ctrlargs = { };
671 	uint32_t session_handle = 0;
672 	struct pkcs11_session *session = NULL;
673 	struct pkcs11_session_info info = {
674 		.flags = PKCS11_CKFSS_SERIAL_SESSION,
675 	};
676 
677 	if (!client || ptypes != exp_pt || out->memref.size != sizeof(info))
678 		return PKCS11_CKR_ARGUMENTS_BAD;
679 
680 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
681 
682 	rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
683 	if (rv)
684 		return rv;
685 
686 	if (serialargs_remaining_bytes(&ctrlargs))
687 		return PKCS11_CKR_ARGUMENTS_BAD;
688 
689 	session = pkcs11_handle2session(session_handle, client);
690 	if (!session)
691 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
692 
693 	info.slot_id = get_token_id(session->token);
694 	info.state = session->state;
695 	if (pkcs11_session_is_read_write(session))
696 		info.flags |= PKCS11_CKFSS_RW_SESSION;
697 
698 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
699 
700 	DMSG("Get find on PKCS11 session %"PRIu32, session->handle);
701 
702 	return PKCS11_CKR_OK;
703 }
704 
705 uint32_t entry_ck_token_initialize(uint32_t ptypes, TEE_Param *params)
706 {
707 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
708 						TEE_PARAM_TYPE_NONE,
709 						TEE_PARAM_TYPE_NONE,
710 						TEE_PARAM_TYPE_NONE);
711 	char label[PKCS11_TOKEN_LABEL_SIZE] = { 0 };
712 	struct pkcs11_client *client = NULL;
713 	struct pkcs11_session *sess = NULL;
714 	enum pkcs11_rc rc = PKCS11_CKR_OK;
715 	struct serialargs ctrlargs = { };
716 	struct ck_token *token = NULL;
717 	TEE_Param *ctrl = params;
718 	uint32_t token_id = 0;
719 	uint32_t pin_size = 0;
720 	void *pin = NULL;
721 
722 	if (ptypes != exp_pt)
723 		return PKCS11_CKR_ARGUMENTS_BAD;
724 
725 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
726 
727 	rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
728 	if (rc)
729 		return rc;
730 
731 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
732 	if (rc)
733 		return rc;
734 
735 	rc = serialargs_get(&ctrlargs, &label, PKCS11_TOKEN_LABEL_SIZE);
736 	if (rc)
737 		return rc;
738 
739 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
740 	if (rc)
741 		return rc;
742 
743 	if (serialargs_remaining_bytes(&ctrlargs))
744 		return PKCS11_CKR_ARGUMENTS_BAD;
745 
746 	token = get_token(token_id);
747 	if (!token)
748 		return PKCS11_CKR_SLOT_ID_INVALID;
749 
750 	if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) {
751 		IMSG("Token %"PRIu32": SO PIN locked", token_id);
752 		return PKCS11_CKR_PIN_LOCKED;
753 	}
754 
755 	/* Check there's no open session on this token */
756 	TAILQ_FOREACH(client, &pkcs11_client_list, link)
757 		TAILQ_FOREACH(sess, &client->session_list, link)
758 			if (sess->token == token)
759 				return PKCS11_CKR_SESSION_EXISTS;
760 
761 	if (!token->db_main->so_pin_salt) {
762 		/*
763 		 * The spec doesn't permit returning
764 		 * PKCS11_CKR_PIN_LEN_RANGE for this function, take another
765 		 * error code.
766 		 */
767 		if (pin_size < PKCS11_TOKEN_PIN_SIZE_MIN ||
768 		    pin_size > PKCS11_TOKEN_PIN_SIZE_MAX)
769 			return PKCS11_CKR_ARGUMENTS_BAD;
770 
771 		rc = hash_pin(PKCS11_CKU_SO, pin, pin_size,
772 			      &token->db_main->so_pin_salt,
773 			      token->db_main->so_pin_hash);
774 		if (rc)
775 			return rc;
776 
777 		update_persistent_db(token);
778 
779 		goto inited;
780 	}
781 
782 	rc = verify_pin(PKCS11_CKU_SO, pin, pin_size,
783 			token->db_main->so_pin_salt,
784 			token->db_main->so_pin_hash);
785 	if (rc) {
786 		unsigned int pin_count = 0;
787 
788 		if (rc != PKCS11_CKR_PIN_INCORRECT)
789 			return rc;
790 
791 		token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW;
792 		token->db_main->so_pin_count++;
793 
794 		pin_count = token->db_main->so_pin_count;
795 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1)
796 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY;
797 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX)
798 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED;
799 
800 		update_persistent_db(token);
801 
802 		return PKCS11_CKR_PIN_INCORRECT;
803 	}
804 
805 	token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW |
806 				   PKCS11_CKFT_SO_PIN_FINAL_TRY);
807 	token->db_main->so_pin_count = 0;
808 
809 inited:
810 	TEE_MemMove(token->db_main->label, label, PKCS11_TOKEN_LABEL_SIZE);
811 	token->db_main->flags |= PKCS11_CKFT_TOKEN_INITIALIZED;
812 	/* Reset user PIN */
813 	token->db_main->user_pin_salt = 0;
814 	token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_INITIALIZED |
815 				   PKCS11_CKFT_USER_PIN_COUNT_LOW |
816 				   PKCS11_CKFT_USER_PIN_FINAL_TRY |
817 				   PKCS11_CKFT_USER_PIN_LOCKED |
818 				   PKCS11_CKFT_USER_PIN_TO_BE_CHANGED);
819 
820 	update_persistent_db(token);
821 
822 	IMSG("PKCS11 token %"PRIu32": initialized", token_id);
823 
824 	return PKCS11_CKR_OK;
825 }
826 
827 static enum pkcs11_rc set_pin(struct pkcs11_session *session,
828 			      uint8_t *new_pin, size_t new_pin_size,
829 			      enum pkcs11_user_type user_type)
830 {
831 	enum pkcs11_rc rc = PKCS11_CKR_OK;
832 	uint32_t flags_clear = 0;
833 	uint32_t flags_set = 0;
834 
835 	if (session->token->db_main->flags & PKCS11_CKFT_WRITE_PROTECTED)
836 		return PKCS11_CKR_TOKEN_WRITE_PROTECTED;
837 
838 	if (!pkcs11_session_is_read_write(session))
839 		return PKCS11_CKR_SESSION_READ_ONLY;
840 
841 	if (new_pin_size < PKCS11_TOKEN_PIN_SIZE_MIN ||
842 	    new_pin_size > PKCS11_TOKEN_PIN_SIZE_MAX)
843 		return PKCS11_CKR_PIN_LEN_RANGE;
844 
845 	switch (user_type) {
846 	case PKCS11_CKU_SO:
847 		rc = hash_pin(user_type, new_pin, new_pin_size,
848 			      &session->token->db_main->so_pin_salt,
849 			      session->token->db_main->so_pin_hash);
850 		if (rc)
851 			return rc;
852 		session->token->db_main->so_pin_count = 0;
853 		flags_clear = PKCS11_CKFT_SO_PIN_COUNT_LOW |
854 			      PKCS11_CKFT_SO_PIN_FINAL_TRY |
855 			      PKCS11_CKFT_SO_PIN_LOCKED |
856 			      PKCS11_CKFT_SO_PIN_TO_BE_CHANGED;
857 		break;
858 	case PKCS11_CKU_USER:
859 		rc = hash_pin(user_type, new_pin, new_pin_size,
860 			      &session->token->db_main->user_pin_salt,
861 			      session->token->db_main->user_pin_hash);
862 		if (rc)
863 			return rc;
864 		session->token->db_main->user_pin_count = 0;
865 		flags_clear = PKCS11_CKFT_USER_PIN_COUNT_LOW |
866 			      PKCS11_CKFT_USER_PIN_FINAL_TRY |
867 			      PKCS11_CKFT_USER_PIN_LOCKED |
868 			      PKCS11_CKFT_USER_PIN_TO_BE_CHANGED;
869 		flags_set = PKCS11_CKFT_USER_PIN_INITIALIZED;
870 		break;
871 	default:
872 		return PKCS11_CKR_FUNCTION_FAILED;
873 	}
874 
875 	session->token->db_main->flags &= ~flags_clear;
876 	session->token->db_main->flags |= flags_set;
877 
878 	update_persistent_db(session->token);
879 
880 	return PKCS11_CKR_OK;
881 }
882 
883 uint32_t entry_ck_init_pin(struct pkcs11_client *client,
884 			   uint32_t ptypes, TEE_Param *params)
885 {
886 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
887 						TEE_PARAM_TYPE_NONE,
888 						TEE_PARAM_TYPE_NONE,
889 						TEE_PARAM_TYPE_NONE);
890 	struct pkcs11_session *session = NULL;
891 	enum pkcs11_rc rc = PKCS11_CKR_OK;
892 	struct serialargs ctrlargs = { };
893 	uint32_t session_handle = 0;
894 	TEE_Param *ctrl = params;
895 	uint32_t pin_size = 0;
896 	void *pin = NULL;
897 
898 	if (!client || ptypes != exp_pt)
899 		return PKCS11_CKR_ARGUMENTS_BAD;
900 
901 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
902 
903 	rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
904 	if (rc)
905 		return rc;
906 
907 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
908 	if (rc)
909 		return rc;
910 
911 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
912 	if (rc)
913 		return rc;
914 
915 	if (serialargs_remaining_bytes(&ctrlargs))
916 		return PKCS11_CKR_ARGUMENTS_BAD;
917 
918 	session = pkcs11_handle2session(session_handle, client);
919 	if (!session)
920 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
921 
922 	if (!pkcs11_session_is_so(session))
923 		return PKCS11_CKR_USER_NOT_LOGGED_IN;
924 
925 	assert(session->token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED);
926 
927 	IMSG("PKCS11 session %"PRIu32": init PIN", session_handle);
928 
929 	return set_pin(session, pin, pin_size, PKCS11_CKU_USER);
930 }
931 
932 static uint32_t check_so_pin(struct pkcs11_session *session,
933 			     uint8_t *pin, size_t pin_size)
934 {
935 	struct ck_token *token = session->token;
936 	enum pkcs11_rc rc = PKCS11_CKR_OK;
937 
938 	assert(token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED);
939 
940 	if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED)
941 		return PKCS11_CKR_PIN_LOCKED;
942 
943 	rc = verify_pin(PKCS11_CKU_SO, pin, pin_size,
944 			token->db_main->so_pin_salt,
945 			token->db_main->so_pin_hash);
946 	if (rc) {
947 		unsigned int pin_count = 0;
948 
949 		if (rc != PKCS11_CKR_PIN_INCORRECT)
950 			return rc;
951 
952 		token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW;
953 		token->db_main->so_pin_count++;
954 
955 		pin_count = token->db_main->so_pin_count;
956 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1)
957 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY;
958 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX)
959 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED;
960 
961 		update_persistent_db(token);
962 
963 		if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED)
964 			return PKCS11_CKR_PIN_LOCKED;
965 
966 		return PKCS11_CKR_PIN_INCORRECT;
967 	}
968 
969 	if (token->db_main->so_pin_count) {
970 		token->db_main->so_pin_count = 0;
971 
972 		update_persistent_db(token);
973 	}
974 
975 	if (token->db_main->flags & (PKCS11_CKFT_SO_PIN_COUNT_LOW |
976 				     PKCS11_CKFT_SO_PIN_FINAL_TRY)) {
977 		token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW |
978 					   PKCS11_CKFT_SO_PIN_FINAL_TRY);
979 
980 		update_persistent_db(token);
981 	}
982 
983 	return PKCS11_CKR_OK;
984 }
985 
986 static uint32_t check_user_pin(struct pkcs11_session *session,
987 			       uint8_t *pin, size_t pin_size)
988 {
989 	struct ck_token *token = session->token;
990 	enum pkcs11_rc rc = PKCS11_CKR_OK;
991 
992 	if (!token->db_main->user_pin_salt)
993 		return PKCS11_CKR_USER_PIN_NOT_INITIALIZED;
994 
995 	if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED)
996 		return PKCS11_CKR_PIN_LOCKED;
997 
998 	rc = verify_pin(PKCS11_CKU_USER, pin, pin_size,
999 			token->db_main->user_pin_salt,
1000 			token->db_main->user_pin_hash);
1001 	if (rc) {
1002 		unsigned int pin_count = 0;
1003 
1004 		if (rc != PKCS11_CKR_PIN_INCORRECT)
1005 			return rc;
1006 
1007 		token->db_main->flags |= PKCS11_CKFT_USER_PIN_COUNT_LOW;
1008 		token->db_main->user_pin_count++;
1009 
1010 		pin_count = token->db_main->user_pin_count;
1011 		if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX - 1)
1012 			token->db_main->flags |= PKCS11_CKFT_USER_PIN_FINAL_TRY;
1013 		if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX)
1014 			token->db_main->flags |= PKCS11_CKFT_USER_PIN_LOCKED;
1015 
1016 		update_persistent_db(token);
1017 
1018 		if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED)
1019 			return PKCS11_CKR_PIN_LOCKED;
1020 
1021 		return PKCS11_CKR_PIN_INCORRECT;
1022 	}
1023 
1024 	if (token->db_main->user_pin_count) {
1025 		token->db_main->user_pin_count = 0;
1026 
1027 		update_persistent_db(token);
1028 	}
1029 
1030 	if (token->db_main->flags & (PKCS11_CKFT_USER_PIN_COUNT_LOW |
1031 				     PKCS11_CKFT_USER_PIN_FINAL_TRY)) {
1032 		token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_COUNT_LOW |
1033 					   PKCS11_CKFT_USER_PIN_FINAL_TRY);
1034 
1035 		update_persistent_db(token);
1036 	}
1037 
1038 	return PKCS11_CKR_OK;
1039 }
1040 
1041 uint32_t entry_ck_set_pin(struct pkcs11_client *client,
1042 			  uint32_t ptypes, TEE_Param *params)
1043 {
1044 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1045 						TEE_PARAM_TYPE_NONE,
1046 						TEE_PARAM_TYPE_NONE,
1047 						TEE_PARAM_TYPE_NONE);
1048 	struct pkcs11_session *session = NULL;
1049 	enum pkcs11_rc rc = PKCS11_CKR_OK;
1050 	struct serialargs ctrlargs = { };
1051 	uint32_t session_handle = 0;
1052 	uint32_t old_pin_size = 0;
1053 	TEE_Param *ctrl = params;
1054 	uint32_t pin_size = 0;
1055 	void *old_pin = NULL;
1056 	void *pin = NULL;
1057 
1058 	if (!client || ptypes != exp_pt)
1059 		return PKCS11_CKR_ARGUMENTS_BAD;
1060 
1061 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1062 
1063 	rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
1064 	if (rc)
1065 		return rc;
1066 
1067 	rc = serialargs_get(&ctrlargs, &old_pin_size, sizeof(uint32_t));
1068 	if (rc)
1069 		return rc;
1070 
1071 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
1072 	if (rc)
1073 		return rc;
1074 
1075 	rc = serialargs_get_ptr(&ctrlargs, &old_pin, old_pin_size);
1076 	if (rc)
1077 		return rc;
1078 
1079 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
1080 	if (rc)
1081 		return rc;
1082 
1083 	if (serialargs_remaining_bytes(&ctrlargs))
1084 		return PKCS11_CKR_ARGUMENTS_BAD;
1085 
1086 	session = pkcs11_handle2session(session_handle, client);
1087 	if (!session)
1088 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
1089 
1090 	if (!pkcs11_session_is_read_write(session))
1091 		return PKCS11_CKR_SESSION_READ_ONLY;
1092 
1093 	if (pkcs11_session_is_so(session)) {
1094 		if (!(session->token->db_main->flags &
1095 		      PKCS11_CKFT_TOKEN_INITIALIZED))
1096 			return PKCS11_CKR_GENERAL_ERROR;
1097 
1098 		rc = check_so_pin(session, old_pin, old_pin_size);
1099 		if (rc)
1100 			return rc;
1101 
1102 		IMSG("PKCS11 session %"PRIu32": set PIN", session_handle);
1103 
1104 		return set_pin(session, pin, pin_size, PKCS11_CKU_SO);
1105 	}
1106 
1107 	if (!(session->token->db_main->flags &
1108 	      PKCS11_CKFT_USER_PIN_INITIALIZED))
1109 		return PKCS11_CKR_GENERAL_ERROR;
1110 
1111 	rc = check_user_pin(session, old_pin, old_pin_size);
1112 	if (rc)
1113 		return rc;
1114 
1115 	IMSG("PKCS11 session %"PRIu32": set PIN", session_handle);
1116 
1117 	return set_pin(session, pin, pin_size, PKCS11_CKU_USER);
1118 }
1119 
1120 static void session_login_user(struct pkcs11_session *session)
1121 {
1122 	struct pkcs11_client *client = session->client;
1123 	struct pkcs11_session *sess = NULL;
1124 
1125 	TAILQ_FOREACH(sess, &client->session_list, link) {
1126 		if (sess->token != session->token)
1127 			continue;
1128 
1129 		if (pkcs11_session_is_read_write(sess))
1130 			sess->state = PKCS11_CKS_RW_USER_FUNCTIONS;
1131 		else
1132 			sess->state = PKCS11_CKS_RO_USER_FUNCTIONS;
1133 	}
1134 }
1135 
1136 static void session_login_so(struct pkcs11_session *session)
1137 {
1138 	struct pkcs11_client *client = session->client;
1139 	struct pkcs11_session *sess = NULL;
1140 
1141 	TAILQ_FOREACH(sess, &client->session_list, link) {
1142 		if (sess->token != session->token)
1143 			continue;
1144 
1145 		if (pkcs11_session_is_read_write(sess))
1146 			sess->state = PKCS11_CKS_RW_SO_FUNCTIONS;
1147 		else
1148 			TEE_Panic(0);
1149 	}
1150 }
1151 
1152 static void session_logout(struct pkcs11_session *session)
1153 {
1154 	struct pkcs11_client *client = session->client;
1155 	struct pkcs11_session *sess = NULL;
1156 
1157 	TAILQ_FOREACH(sess, &client->session_list, link) {
1158 		if (sess->token != session->token)
1159 			continue;
1160 
1161 		if (pkcs11_session_is_read_write(sess))
1162 			sess->state = PKCS11_CKS_RW_PUBLIC_SESSION;
1163 		else
1164 			sess->state = PKCS11_CKS_RO_PUBLIC_SESSION;
1165 	}
1166 }
1167 
1168 uint32_t entry_ck_login(struct pkcs11_client *client,
1169 			uint32_t ptypes, TEE_Param *params)
1170 {
1171 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1172 						TEE_PARAM_TYPE_NONE,
1173 						TEE_PARAM_TYPE_NONE,
1174 						TEE_PARAM_TYPE_NONE);
1175 	struct pkcs11_session *session = NULL;
1176 	struct pkcs11_session *sess = NULL;
1177 	enum pkcs11_rc rc = PKCS11_CKR_OK;
1178 	struct serialargs ctrlargs = { };
1179 	uint32_t session_handle = 0;
1180 	TEE_Param *ctrl = params;
1181 	uint32_t user_type = 0;
1182 	uint32_t pin_size = 0;
1183 	void *pin = NULL;
1184 
1185 	if (!client || ptypes != exp_pt)
1186 		return PKCS11_CKR_ARGUMENTS_BAD;
1187 
1188 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1189 
1190 	rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
1191 	if (rc)
1192 		return rc;
1193 
1194 	rc = serialargs_get(&ctrlargs, &user_type, sizeof(uint32_t));
1195 	if (rc)
1196 		return rc;
1197 
1198 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
1199 	if (rc)
1200 		return rc;
1201 
1202 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
1203 	if (rc)
1204 		return rc;
1205 
1206 	if (serialargs_remaining_bytes(&ctrlargs))
1207 		return PKCS11_CKR_ARGUMENTS_BAD;
1208 
1209 	session = pkcs11_handle2session(session_handle, client);
1210 	if (!session)
1211 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
1212 
1213 	switch (user_type) {
1214 	case PKCS11_CKU_SO:
1215 		if (pkcs11_session_is_so(session))
1216 			return PKCS11_CKR_USER_ALREADY_LOGGED_IN;
1217 
1218 		if (pkcs11_session_is_user(session))
1219 			return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
1220 
1221 		TAILQ_FOREACH(sess, &client->session_list, link)
1222 			if (sess->token == session->token &&
1223 			    !pkcs11_session_is_read_write(sess))
1224 				return PKCS11_CKR_SESSION_READ_ONLY_EXISTS;
1225 
1226 		/*
1227 		 * This is the point where we could check if another client
1228 		 * has another user or SO logged in.
1229 		 *
1230 		 * The spec says:
1231 		 * CKR_USER_TOO_MANY_TYPES: An attempt was made to have
1232 		 * more distinct users simultaneously logged into the token
1233 		 * than the token and/or library permits. For example, if
1234 		 * some application has an open SO session, and another
1235 		 * application attempts to log the normal user into a
1236 		 * session, the attempt may return this error. It is not
1237 		 * required to, however. Only if the simultaneous distinct
1238 		 * users cannot be supported does C_Login have to return
1239 		 * this value. Note that this error code generalizes to
1240 		 * true multi-user tokens.
1241 		 *
1242 		 * So it's permitted to have another user or SO logged in
1243 		 * from another client.
1244 		 */
1245 
1246 		rc = check_so_pin(session, pin, pin_size);
1247 		if (!rc)
1248 			session_login_so(session);
1249 
1250 		break;
1251 
1252 	case PKCS11_CKU_USER:
1253 		if (pkcs11_session_is_so(session))
1254 			return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
1255 
1256 		if (pkcs11_session_is_user(session))
1257 			return PKCS11_CKR_USER_ALREADY_LOGGED_IN;
1258 
1259 		/*
1260 		 * This is the point where we could check if another client
1261 		 * has another user or SO logged in.
1262 		 * See comment on CKR_USER_TOO_MANY_TYPES above.
1263 		 */
1264 
1265 		rc = check_user_pin(session, pin, pin_size);
1266 		if (!rc)
1267 			session_login_user(session);
1268 
1269 		break;
1270 
1271 	case PKCS11_CKU_CONTEXT_SPECIFIC:
1272 		return PKCS11_CKR_OPERATION_NOT_INITIALIZED;
1273 
1274 	default:
1275 		return PKCS11_CKR_USER_TYPE_INVALID;
1276 	}
1277 
1278 	if (!rc)
1279 		IMSG("PKCS11 session %"PRIu32": login", session_handle);
1280 
1281 	return rc;
1282 }
1283 
1284 uint32_t entry_ck_logout(struct pkcs11_client *client,
1285 			 uint32_t ptypes, TEE_Param *params)
1286 {
1287 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1288 						TEE_PARAM_TYPE_NONE,
1289 						TEE_PARAM_TYPE_NONE,
1290 						TEE_PARAM_TYPE_NONE);
1291 	struct pkcs11_session *session = NULL;
1292 	enum pkcs11_rc rc = PKCS11_CKR_OK;
1293 	struct serialargs ctrlargs = { };
1294 	uint32_t session_handle = 0;
1295 	TEE_Param *ctrl = params;
1296 
1297 	if (!client || ptypes != exp_pt)
1298 		return PKCS11_CKR_ARGUMENTS_BAD;
1299 
1300 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1301 
1302 	rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
1303 	if (rc)
1304 		return rc;
1305 
1306 	if (serialargs_remaining_bytes(&ctrlargs))
1307 		return PKCS11_CKR_ARGUMENTS_BAD;
1308 
1309 	session = pkcs11_handle2session(session_handle, client);
1310 	if (!session)
1311 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
1312 
1313 	if (pkcs11_session_is_public(session))
1314 		return PKCS11_CKR_USER_NOT_LOGGED_IN;
1315 
1316 	session_logout(session);
1317 
1318 	IMSG("PKCS11 session %"PRIu32": logout", session_handle);
1319 
1320 	return PKCS11_CKR_OK;
1321 }
1322