xref: /optee_os/ta/pkcs11/src/attributes.h (revision f6e2b9e2d1a270542c6f6f5e36ed4e36abe18256)
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 
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  * Return PKCS11_CKR_OK on success, or a PKCS11 return code.
220  */
221 bool attributes_match_reference(struct obj_attrs *ref,
222 				struct obj_attrs *candidate);
223 
224 /*
225  * get_class() - Get class ID of an object
226  * @head:	Pointer to serialized attributes
227  *
228  * Returns the class ID of an object on succes or returns
229  * PKCS11_CKO_UNDEFINED_ID on error.
230  */
231 static inline enum pkcs11_class_id get_class(struct obj_attrs *head)
232 {
233 	uint32_t class = 0;
234 	uint32_t size = sizeof(class);
235 
236 	if (get_attribute(head, PKCS11_CKA_CLASS, &class, &size))
237 		return PKCS11_CKO_UNDEFINED_ID;
238 
239 	return class;
240 }
241 
242 /*
243  * get_key_type() - Get the key type of an object
244  * @head:	Pointer to serialized attributes
245  *
246  * Returns the key type of an object on success or returns
247  * PKCS11_CKK_UNDEFINED_ID on error.
248  */
249 static inline enum pkcs11_key_type get_key_type(struct obj_attrs *head)
250 {
251 	uint32_t type = 0;
252 	uint32_t size = sizeof(type);
253 
254 	if (get_attribute(head, PKCS11_CKA_KEY_TYPE, &type, &size))
255 		return PKCS11_CKK_UNDEFINED_ID;
256 
257 	return type;
258 }
259 
260 /*
261  * get_mechanism_type() - Get the mechanism type of an object
262  * @head:	Pointer to serialized attributes
263  *
264  * Returns the mechanism type of an object on success or returns
265  * PKCS11_CKM_UNDEFINED_ID on error.
266  */
267 static inline enum pkcs11_mechanism_id get_mechanism_type(struct obj_attrs *head)
268 {
269 	uint32_t type = 0;
270 	uint32_t size = sizeof(type);
271 
272 	if (get_attribute(head, PKCS11_CKA_MECHANISM_TYPE, &type, &size))
273 		return PKCS11_CKM_UNDEFINED_ID;
274 
275 	return type;
276 }
277 
278 /*
279  * get_bool() - Get the bool value of an attribute
280  * @head:	Pointer to serialized attributes
281  * @attribute:	Attribute ID to look for
282  *
283  * May assert if attribute ID isn't of the boolean type.
284  *
285  * Returns the bool value of the supplied attribute ID on success if found
286  * else false.
287  */
288 bool get_bool(struct obj_attrs *head, uint32_t attribute);
289 
290 #if CFG_TEE_TA_LOG_LEVEL > 0
291 /* Debug: dump object attributes to IMSG() trace console */
292 void trace_attributes(const char *prefix, void *ref);
293 #else
294 static inline void trace_attributes(const char *prefix __unused,
295 				    void *ref __unused)
296 {
297 }
298 #endif /*CFG_TEE_TA_LOG_LEVEL*/
299 #endif /*PKCS11_TA_ATTRIBUTES_H*/
300