xref: /optee_os/ta/pkcs11/src/token_capabilities.c (revision 10b907910d58334cc5b1486cb2f91a08f764566e)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2017-2020, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <pkcs11_ta.h>
8 #include <string.h>
9 #include <util.h>
10 #include <tee_api.h>
11 #include <tee_internal_api_extensions.h>
12 
13 #include "pkcs11_helpers.h"
14 #include "token_capabilities.h"
15 
16 #define ALLOWED_PKCS11_CKFM	\
17 	(PKCS11_CKFM_ENCRYPT | PKCS11_CKFM_DECRYPT |		\
18 	 PKCS11_CKFM_DERIVE | PKCS11_CKFM_DIGEST |		\
19 	 PKCS11_CKFM_SIGN | PKCS11_CKFM_SIGN_RECOVER |		\
20 	 PKCS11_CKFM_VERIFY | PKCS11_CKFM_VERIFY_RECOVER |	\
21 	 PKCS11_CKFM_GENERATE |	PKCS11_CKFM_GENERATE_KEY_PAIR |	\
22 	 PKCS11_CKFM_WRAP | PKCS11_CKFM_UNWRAP)
23 
24 /*
25  * Definition of supported processings for a PKCS#11 mechanisms
26  * @id: Mechanism ID
27  * @flags: Valid PKCS11_CKFM_* for a mechanism as per PKCS#11
28  * @one_shot: true of mechanism can be used for a one-short processing
29  * @string: Helper string of the mechanism ID for debug purpose
30  */
31 struct pkcs11_mechachism_modes {
32 	uint32_t id;
33 	uint32_t flags;
34 	bool one_shot;
35 #if CFG_TEE_TA_LOG_LEVEL > 0
36 	const char *string;
37 #endif
38 };
39 
40 #if CFG_TEE_TA_LOG_LEVEL > 0
41 #define MECHANISM(_label, _flags, _single_part)	\
42 	{					\
43 		.id = _label,			\
44 		.one_shot = (_single_part),	\
45 		.flags = (_flags),		\
46 		.string = #_label,		\
47 	}
48 #else
49 #define MECHANISM(_label, _flags, _single_part)	\
50 	{					\
51 		.id = _label,			\
52 		.one_shot = (_single_part),	\
53 		.flags = (_flags),		\
54 	}
55 #endif
56 
57 #define SINGLE_PART_ONLY	true
58 #define ANY_PART		false
59 
60 /* PKCS#11 specificies permitted operation for each mechanism  */
61 static const struct pkcs11_mechachism_modes pkcs11_modes[] = {
62 	MECHANISM(PKCS11_CKM_AES_ECB,
63 		  PKCS11_CKFM_ENCRYPT | PKCS11_CKFM_DECRYPT |
64 		  PKCS11_CKFM_DERIVE |
65 		  PKCS11_CKFM_WRAP | PKCS11_CKFM_UNWRAP,
66 		  ANY_PART),
67 };
68 
69 #if CFG_TEE_TA_LOG_LEVEL > 0
70 const char *mechanism_string_id(enum pkcs11_mechanism_id id)
71 {
72 	const size_t offset = sizeof("PKCS11_CKM_") - 1;
73 	size_t n = 0;
74 
75 	for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++)
76 		if (pkcs11_modes[n].id == id)
77 			return pkcs11_modes[n].string + offset;
78 
79 	return "Unknown ID";
80 }
81 #endif /*CFG_TEE_TA_LOG_LEVEL*/
82 
83 /*
84  * Return true if @id is a valid mechanism ID
85  */
86 bool mechanism_is_valid(enum pkcs11_mechanism_id id)
87 {
88 	size_t n = 0;
89 
90 	for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++)
91 		if (id == pkcs11_modes[n].id)
92 			return true;
93 
94 	return false;
95 }
96 
97 /*
98  * Return true if mechanism ID is valid and flags matches PKCS#11 compliancy
99  */
100 bool __maybe_unused mechanism_flags_complies_pkcs11(uint32_t mechanism_type,
101 						    uint32_t flags)
102 {
103 	size_t n = 0;
104 
105 	assert((flags & ~ALLOWED_PKCS11_CKFM) == 0);
106 
107 	for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++) {
108 		if (pkcs11_modes[n].id == mechanism_type) {
109 			if (flags & ~pkcs11_modes[n].flags)
110 				EMSG("%s flags: 0x%"PRIx32" vs 0x%"PRIx32,
111 				     id2str_mechanism(mechanism_type),
112 				     flags, pkcs11_modes[n].flags);
113 
114 			return (flags & ~pkcs11_modes[n].flags) == 0;
115 		}
116 	}
117 
118 	/* Mechanism ID unexpectedly not found */
119 	return false;
120 }
121 
122 /*
123  * Arrays that centralizes the IDs and processing flags for mechanisms
124  * supported by each embedded token. Currently none.
125  */
126 const struct pkcs11_mechachism_modes token_mechanism[] = {
127 	MECHANISM(PKCS11_CKM_AES_ECB, 0, 0),
128 };
129 
130 /*
131  * tee_malloc_mechanism_array - Allocate and fill array of supported mechanisms
132  * @count: [in] [out] Pointer to number of mechanism IDs in client resource
133  * Return allocated array of the supported mechanism IDs
134  *
135  * Allocates array with 32bit cells mechanism IDs for the supported ones only
136  * if *@count covers number mechanism IDs exposed.
137  */
138 uint32_t *tee_malloc_mechanism_list(size_t *out_count)
139 {
140 	size_t n = 0;
141 	size_t count = 0;
142 	uint32_t *array = NULL;
143 
144 	for (n = 0; n < ARRAY_SIZE(token_mechanism); n++)
145 		if (token_mechanism[n].flags)
146 			count++;
147 
148 	if (*out_count >= count)
149 		array = TEE_Malloc(count * sizeof(*array),
150 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
151 
152 	*out_count = count;
153 
154 	if (!array)
155 		return NULL;
156 
157 	for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) {
158 		if (token_mechanism[n].flags) {
159 			count--;
160 			array[count] = token_mechanism[n].id;
161 		}
162 	}
163 	assert(!count);
164 
165 	return array;
166 }
167 
168 uint32_t mechanism_supported_flags(enum pkcs11_mechanism_id id)
169 {
170 	size_t n = 0;
171 
172 	for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) {
173 		if (id == token_mechanism[n].id) {
174 			uint32_t flags = token_mechanism[n].flags;
175 
176 			assert(mechanism_flags_complies_pkcs11(id, flags));
177 			return flags;
178 		}
179 	}
180 
181 	return 0;
182 }
183