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 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 */ 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 */ 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 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 */ 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 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