xref: /optee_os/ta/pkcs11/src/pkcs11_token.c (revision d38f96356bdf7996620f902a2652f69190d98d56)
1c84ccd0aSEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause
2c84ccd0aSEtienne Carriere /*
3c84ccd0aSEtienne Carriere  * Copyright (c) 2017-2020, Linaro Limited
4c84ccd0aSEtienne Carriere  */
5c84ccd0aSEtienne Carriere 
6c84ccd0aSEtienne Carriere #include <assert.h>
7*d38f9635SEtienne Carriere #include <confine_array_index.h>
8c84ccd0aSEtienne Carriere #include <pkcs11_ta.h>
9c84ccd0aSEtienne Carriere #include <string.h>
10c84ccd0aSEtienne Carriere #include <string_ext.h>
11c84ccd0aSEtienne Carriere #include <sys/queue.h>
12c84ccd0aSEtienne Carriere #include <tee_api_types.h>
13c84ccd0aSEtienne Carriere #include <tee_internal_api_extensions.h>
14c84ccd0aSEtienne Carriere #include <util.h>
15c84ccd0aSEtienne Carriere 
16c84ccd0aSEtienne Carriere #include "pkcs11_token.h"
17c84ccd0aSEtienne Carriere #include "pkcs11_helpers.h"
1822ac6984SEtienne Carriere #include "serializer.h"
19c84ccd0aSEtienne Carriere 
20c84ccd0aSEtienne Carriere /* Provide 3 slots/tokens, ID is token index */
21c84ccd0aSEtienne Carriere #ifndef CFG_PKCS11_TA_TOKEN_COUNT
22c84ccd0aSEtienne Carriere #define TOKEN_COUNT		3
23c84ccd0aSEtienne Carriere #else
24c84ccd0aSEtienne Carriere #define TOKEN_COUNT		CFG_PKCS11_TA_TOKEN_COUNT
25c84ccd0aSEtienne Carriere #endif
26c84ccd0aSEtienne Carriere 
27c84ccd0aSEtienne Carriere /* Static allocation of tokens runtime instances (reset to 0 at load) */
28c84ccd0aSEtienne Carriere struct ck_token ck_token[TOKEN_COUNT];
29c84ccd0aSEtienne Carriere 
30c84ccd0aSEtienne Carriere struct ck_token *get_token(unsigned int token_id)
31c84ccd0aSEtienne Carriere {
32*d38f9635SEtienne Carriere 	if (token_id < TOKEN_COUNT)
33*d38f9635SEtienne Carriere 		return &ck_token[confine_array_index(token_id, TOKEN_COUNT)];
34c84ccd0aSEtienne Carriere 
35*d38f9635SEtienne Carriere 	return NULL;
36c84ccd0aSEtienne Carriere }
37c84ccd0aSEtienne Carriere 
38c84ccd0aSEtienne Carriere unsigned int get_token_id(struct ck_token *token)
39c84ccd0aSEtienne Carriere {
40c84ccd0aSEtienne Carriere 	ptrdiff_t id = token - ck_token;
41c84ccd0aSEtienne Carriere 
42c84ccd0aSEtienne Carriere 	assert(id >= 0 && id < TOKEN_COUNT);
43c84ccd0aSEtienne Carriere 	return id;
44c84ccd0aSEtienne Carriere }
45c84ccd0aSEtienne Carriere 
46c84ccd0aSEtienne Carriere static TEE_Result pkcs11_token_init(unsigned int id)
47c84ccd0aSEtienne Carriere {
48c84ccd0aSEtienne Carriere 	struct ck_token *token = init_persistent_db(id);
49c84ccd0aSEtienne Carriere 
50c84ccd0aSEtienne Carriere 	if (!token)
51c84ccd0aSEtienne Carriere 		return TEE_ERROR_SECURITY;
52c84ccd0aSEtienne Carriere 
53c84ccd0aSEtienne Carriere 	if (token->state == PKCS11_TOKEN_RESET) {
54c84ccd0aSEtienne Carriere 		/* As per PKCS#11 spec, token resets to read/write state */
55c84ccd0aSEtienne Carriere 		token->state = PKCS11_TOKEN_READ_WRITE;
56c84ccd0aSEtienne Carriere 		token->session_count = 0;
57c84ccd0aSEtienne Carriere 		token->rw_session_count = 0;
58c84ccd0aSEtienne Carriere 	}
59c84ccd0aSEtienne Carriere 
60c84ccd0aSEtienne Carriere 	return TEE_SUCCESS;
61c84ccd0aSEtienne Carriere }
62c84ccd0aSEtienne Carriere 
63c84ccd0aSEtienne Carriere TEE_Result pkcs11_init(void)
64c84ccd0aSEtienne Carriere {
65c84ccd0aSEtienne Carriere 	unsigned int id = 0;
66c84ccd0aSEtienne Carriere 	TEE_Result ret = TEE_ERROR_GENERIC;
67c84ccd0aSEtienne Carriere 
68c84ccd0aSEtienne Carriere 	for (id = 0; id < TOKEN_COUNT; id++) {
69c84ccd0aSEtienne Carriere 		ret = pkcs11_token_init(id);
70c84ccd0aSEtienne Carriere 		if (ret)
71c84ccd0aSEtienne Carriere 			return ret;
72c84ccd0aSEtienne Carriere 	}
73c84ccd0aSEtienne Carriere 
74c84ccd0aSEtienne Carriere 	return ret;
75c84ccd0aSEtienne Carriere }
76c84ccd0aSEtienne Carriere 
77c84ccd0aSEtienne Carriere void pkcs11_deinit(void)
78c84ccd0aSEtienne Carriere {
79c84ccd0aSEtienne Carriere 	unsigned int id = 0;
80c84ccd0aSEtienne Carriere 
81c84ccd0aSEtienne Carriere 	for (id = 0; id < TOKEN_COUNT; id++)
82c84ccd0aSEtienne Carriere 		close_persistent_db(get_token(id));
83c84ccd0aSEtienne Carriere }
8422ac6984SEtienne Carriere 
8522ac6984SEtienne Carriere uint32_t entry_ck_slot_list(uint32_t ptypes, TEE_Param *params)
8622ac6984SEtienne Carriere {
8722ac6984SEtienne Carriere 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
8822ac6984SEtienne Carriere 						TEE_PARAM_TYPE_NONE,
8922ac6984SEtienne Carriere 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
9022ac6984SEtienne Carriere 						TEE_PARAM_TYPE_NONE);
9122ac6984SEtienne Carriere 	TEE_Param *out = &params[2];
9222ac6984SEtienne Carriere 	uint32_t token_id = 0;
9322ac6984SEtienne Carriere 	const size_t out_size = sizeof(token_id) * TOKEN_COUNT;
9422ac6984SEtienne Carriere 	uint8_t *id = NULL;
9522ac6984SEtienne Carriere 
9622ac6984SEtienne Carriere 	if (ptypes != exp_pt ||
9722ac6984SEtienne Carriere 	    params[0].memref.size != TEE_PARAM0_SIZE_MIN)
9822ac6984SEtienne Carriere 		return PKCS11_CKR_ARGUMENTS_BAD;
9922ac6984SEtienne Carriere 
10022ac6984SEtienne Carriere 	if (out->memref.size < out_size) {
10122ac6984SEtienne Carriere 		out->memref.size = out_size;
10222ac6984SEtienne Carriere 
10322ac6984SEtienne Carriere 		if (out->memref.buffer)
10422ac6984SEtienne Carriere 			return PKCS11_CKR_BUFFER_TOO_SMALL;
10522ac6984SEtienne Carriere 		else
10622ac6984SEtienne Carriere 			return PKCS11_CKR_OK;
10722ac6984SEtienne Carriere 	}
10822ac6984SEtienne Carriere 
10922ac6984SEtienne Carriere 	for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT;
11022ac6984SEtienne Carriere 	     token_id++, id += sizeof(token_id))
11122ac6984SEtienne Carriere 		TEE_MemMove(id, &token_id, sizeof(token_id));
11222ac6984SEtienne Carriere 
11322ac6984SEtienne Carriere 	out->memref.size = out_size;
11422ac6984SEtienne Carriere 
11522ac6984SEtienne Carriere 	return PKCS11_CKR_OK;
11622ac6984SEtienne Carriere }
117