1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * Copyright (c) 2017-2020, Linaro Limited
4 */
5
6 #ifndef PKCS11_TA_ATTRIBUTES_H
7 #define PKCS11_TA_ATTRIBUTES_H
8
9 #include <stdbool.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 #include <util.h>
13
14 #include "pkcs11_helpers.h"
15
16 /*
17 * Boolean property attributes (BPA): bit position in a 64 bit mask
18 * for boolean properties object can mandate as attribute, depending
19 * on the object. These attributes are often accessed and it is
20 * quicker to get them from a 64 bit field in the object instance
21 * rather than searching into the object attributes.
22 */
23 #define PKCS11_BOOLPROPS_BASE 0
24 #define PKCS11_BOOLPROPS_MAX_COUNT 64
25
26 enum boolprop_attr {
27 BPA_TOKEN = 0,
28 BPA_PRIVATE,
29 BPA_TRUSTED,
30 BPA_SENSITIVE,
31 BPA_ENCRYPT,
32 BPA_DECRYPT,
33 BPA_WRAP,
34 BPA_UNWRAP,
35 BPA_SIGN,
36 BPA_SIGN_RECOVER,
37 BPA_VERIFY,
38 BPA_VERIFY_RECOVER,
39 BPA_DERIVE,
40 BPA_EXTRACTABLE,
41 BPA_LOCAL,
42 BPA_NEVER_EXTRACTABLE,
43 BPA_ALWAYS_SENSITIVE,
44 BPA_MODIFIABLE,
45 BPA_COPYABLE,
46 BPA_DESTROYABLE,
47 BPA_ALWAYS_AUTHENTICATE,
48 BPA_WRAP_WITH_TRUSTED,
49 };
50
51 /*
52 * Header of a serialized memory object inside PKCS11 TA.
53 *
54 * @attrs_size: byte size of the serialized data
55 * @attrs_count: number of items in the blob
56 * @attrs: then starts the blob binary data
57 */
58 struct obj_attrs {
59 uint32_t attrs_size;
60 uint32_t attrs_count;
61 uint8_t attrs[];
62 };
63
64 /*
65 * init_attributes_head() - Allocate a reference for serialized attributes
66 * @head: *@head holds the retrieved pointer
67 *
68 * Retrieved pointer can be freed from a simple TEE_Free(reference).
69 *
70 * Return PKCS11_CKR_OK on success or a PKCS11 return code.
71 */
72 enum pkcs11_rc init_attributes_head(struct obj_attrs **head);
73
74 /*
75 * add_attribute() - Update serialized attributes to add an entry.
76 *
77 * @head: *@head points to serialized attributes,
78 * can be reallocated as attributes are added
79 * @attribute: Attribute ID to add
80 * @data: Opaque data of attribute
81 * @size: Size of data
82 *
83 * Return PKCS11_CKR_OK on success or a PKCS11 return code.
84 */
85 enum pkcs11_rc add_attribute(struct obj_attrs **head, uint32_t attribute,
86 void *data, size_t size);
87
88 /*
89 * Update serialized attributes to remove an empty entry. Can relocate the
90 * attribute list buffer. Only 1 instance of the entry is expected.
91 *
92 * Return PKCS11_CKR_OK on success or a PKCS11 return code.
93 */
94 enum pkcs11_rc remove_empty_attribute(struct obj_attrs **head, uint32_t attrib);
95
96 /*
97 * get_attribute_ptrs() - Get pointers to attributes with a given ID
98 * @head: Pointer to serialized attributes
99 * @attribute: Attribute ID to look for
100 * @attr: Array of pointers to the data inside @head
101 * @attr_size: Array of uint32_t holding the sizes of each value pointed to
102 * by @attr
103 * @count: Number of elements in the arrays above
104 *
105 * If *count == 0, count and return in *count the number of attributes matching
106 * the input attribute ID.
107 *
108 * If *count != 0, return the address and size of the attributes found, up to
109 * the occurrence number *count. attr and attr_size are expected large
110 * enough. attr is the output array of the values found. attr_size is the
111 * output array of the size of each value found.
112 *
113 * If attr_size != NULL, return in *attr_size attribute value size.
114 * If attr != NULL return in *attr the address of the attribute value.
115 */
116 void get_attribute_ptrs(struct obj_attrs *head, uint32_t attribute,
117 void **attr, uint32_t *attr_size, size_t *count);
118
119 /*
120 * get_attribute_ptrs() - Get pointer to the attribute of a given ID
121 * @head: Pointer to serialized attributes
122 * @attribute: Attribute ID
123 * @attr: *@attr holds the retrieved pointer to the attribute value
124 * @attr_size: Size of the attribute value
125 *
126 * If no matching attributes is found return PKCS11_RV_NOT_FOUND.
127 * If attr_size != NULL, return in *attr_size attribute value size.
128 * If attr != NULL, return in *attr the address of the attribute value.
129 *
130 * Return PKCS11_CKR_OK or PKCS11_RV_NOT_FOUND on success, or a PKCS11 return
131 * code.
132 */
133 enum pkcs11_rc get_attribute_ptr(struct obj_attrs *head, uint32_t attribute,
134 void **attr_ptr, uint32_t *attr_size);
135
136 /*
137 * get_attribute() - Copy out the attribute of a given ID
138 * @head: Pointer to serialized attributes
139 * @attribute: Attribute ID to look for
140 * @attr: holds the retrieved attribute value
141 * @attr_size: Size of the attribute value
142 *
143 * If attribute is not found, return PKCS11_RV_NOT_FOUND.
144 *
145 * If attr_size != NULL, check that attr has enough room for value (compare
146 * against *attr_size), copy attribute value to attr and finally return actual
147 * value size in *attr_size.
148 *
149 * If there is not enough room return PKCS11_CKR_BUFFER_TOO_SMALL with expected
150 * size in *attr_size.
151 *
152 * If attr is NULL and attr_size != NULL return expected buffer size in
153 * *attr_size.
154 *
155 * Return PKCS11_CKR_OK or PKCS11_RV_NOT_FOUND on success, or a PKCS11 return
156 * code.
157 */
158 enum pkcs11_rc get_attribute(struct obj_attrs *head, uint32_t attribute,
159 void *attr, uint32_t *attr_size);
160
161 /*
162 * set_attribute() - Set the attribute of a given ID with value
163 * @head: Pointer to serialized attributes where attribute is to be set,
164 * can be relocated as attributes are modified/added
165 * @attribute: Attribute ID to look for
166 * @data: Holds the attribute value to be set
167 * @size: Size of the attribute value
168 *
169 * Return PKCS11_CKR_OK on success or a PKCS11 return code.
170 */
171 enum pkcs11_rc set_attribute(struct obj_attrs **head, uint32_t attribute,
172 void *data, size_t size);
173
174 /*
175 * modify_attributes_list() - Modify the value of attributes in destination
176 * attribute list (serialized attributes) based on the value of attributes in
177 * the source attribute list
178 * @dst: Pointer to serialized attrbutes where attributes are to be
179 * modified, can be relocated as attributes are modified
180 * @head: Serialized attributes containing attributes which need to be
181 * modified in the destination attribute list
182 *
183 * Return PKCS11_CKR_OK on success
184 */
185 enum pkcs11_rc modify_attributes_list(struct obj_attrs **dst,
186 struct obj_attrs *head);
187
188 /*
189 * get_u32_attribute() - Copy out the 32-bit attribute value of a given ID
190 * @head: Pointer to serialized attributes
191 * @attribute: Attribute ID
192 * @attr: holds the retrieved 32-bit attribute value
193 *
194 * If attribute is not found, return PKCS11_RV_NOT_FOUND.
195 * If the retreived attribute doesn't have a 4 byte sized value
196 * PKCS11_CKR_GENERAL_ERROR is returned.
197 *
198 * Return PKCS11_CKR_OK or PKCS11_RV_NOT_FOUND on success, or a PKCS11 return
199 * code.
200 */
201
get_u32_attribute(struct obj_attrs * head,uint32_t attribute,uint32_t * attr)202 static inline enum pkcs11_rc get_u32_attribute(struct obj_attrs *head,
203 uint32_t attribute,
204 uint32_t *attr)
205 {
206 uint32_t size = sizeof(uint32_t);
207 enum pkcs11_rc rc = get_attribute(head, attribute, attr, &size);
208
209 if (!rc && size != sizeof(uint32_t))
210 return PKCS11_CKR_GENERAL_ERROR;
211
212 return rc;
213 }
214
215 /*
216 * Return true if all attributes from the reference are found and match value
217 * in the candidate attribute list.
218 */
219 bool attributes_match_reference(struct obj_attrs *ref,
220 struct obj_attrs *candidate);
221
222 /*
223 * Check attributes from @ref are all found or added in @head
224 *
225 * Return PKCS11_CKR_OK on success, or a PKCS11 return code.
226 */
227 enum pkcs11_rc attributes_match_add_reference(struct obj_attrs **head,
228 struct obj_attrs *ref);
229 /*
230 * get_class() - Get class ID of an object
231 * @head: Pointer to serialized attributes
232 *
233 * Returns the class ID of an object on succes or returns
234 * PKCS11_CKO_UNDEFINED_ID on error.
235 */
get_class(struct obj_attrs * head)236 static inline enum pkcs11_class_id get_class(struct obj_attrs *head)
237 {
238 uint32_t class = 0;
239 uint32_t size = sizeof(class);
240
241 if (get_attribute(head, PKCS11_CKA_CLASS, &class, &size))
242 return PKCS11_CKO_UNDEFINED_ID;
243
244 return class;
245 }
246
247 /*
248 * get_key_type() - Get the key type of an object
249 * @head: Pointer to serialized attributes
250 *
251 * Returns the key type of an object on success or returns
252 * PKCS11_CKK_UNDEFINED_ID on error.
253 */
get_key_type(struct obj_attrs * head)254 static inline enum pkcs11_key_type get_key_type(struct obj_attrs *head)
255 {
256 uint32_t type = 0;
257 uint32_t size = sizeof(type);
258
259 if (get_attribute(head, PKCS11_CKA_KEY_TYPE, &type, &size))
260 return PKCS11_CKK_UNDEFINED_ID;
261
262 return type;
263 }
264
265 /*
266 * get_certificate_type() - Get the certificate type of an object
267 * @head: Pointer to serialized attributes
268 *
269 * Returns the certificate type of an object on success or returns
270 * PKCS11_CKC_UNDEFINED_ID on error.
271 */
272 static inline
get_certificate_type(struct obj_attrs * head)273 enum pkcs11_certificate_type get_certificate_type(struct obj_attrs *head)
274 {
275 uint32_t type = 0;
276
277 if (get_u32_attribute(head, PKCS11_CKA_CERTIFICATE_TYPE, &type))
278 return PKCS11_CKC_UNDEFINED_ID;
279
280 return type;
281 }
282
283 /*
284 * get_mechanism_type() - Get the mechanism type of an object
285 * @head: Pointer to serialized attributes
286 *
287 * Returns the mechanism type of an object on success or returns
288 * PKCS11_CKM_UNDEFINED_ID on error.
289 */
get_mechanism_type(struct obj_attrs * head)290 static inline enum pkcs11_mechanism_id get_mechanism_type(struct obj_attrs *head)
291 {
292 uint32_t type = 0;
293 uint32_t size = sizeof(type);
294
295 if (get_attribute(head, PKCS11_CKA_MECHANISM_TYPE, &type, &size))
296 return PKCS11_CKM_UNDEFINED_ID;
297
298 return type;
299 }
300
301 /*
302 * get_bool() - Get the bool value of an attribute
303 * @head: Pointer to serialized attributes
304 * @attribute: Attribute ID to look for
305 *
306 * May assert if attribute ID isn't of the boolean type.
307 *
308 * Returns the bool value of the supplied attribute ID on success if found
309 * else false.
310 */
311 bool get_bool(struct obj_attrs *head, uint32_t attribute);
312
313 #if CFG_TEE_TA_LOG_LEVEL > 0
314 /* Debug: dump object attributes to IMSG() trace console */
315 void trace_attributes(const char *prefix, void *ref);
316 #else
trace_attributes(const char * prefix __unused,void * ref __unused)317 static inline void trace_attributes(const char *prefix __unused,
318 void *ref __unused)
319 {
320 }
321 #endif /*CFG_TEE_TA_LOG_LEVEL*/
322 #endif /*PKCS11_TA_ATTRIBUTES_H*/
323