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