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 * get_u32_attribute() - Copy out the 32-bit attribute value of a given ID 163 * @head: Pointer to serialized attributes 164 * @attribute: Attribute ID 165 * @attr: holds the retrieved 32-bit attribute value 166 * 167 * If attribute is not found, return PKCS11_RV_NOT_FOUND. 168 * If the retreived attribute doesn't have a 4 byte sized value 169 * PKCS11_CKR_GENERAL_ERROR is returned. 170 * 171 * Return PKCS11_CKR_OK or PKCS11_RV_NOT_FOUND on success, or a PKCS11 return 172 * code. 173 */ 174 175 static inline enum pkcs11_rc get_u32_attribute(struct obj_attrs *head, 176 uint32_t attribute, 177 uint32_t *attr) 178 { 179 uint32_t size = sizeof(uint32_t); 180 enum pkcs11_rc rc = get_attribute(head, attribute, attr, &size); 181 182 if (!rc && size != sizeof(uint32_t)) 183 return PKCS11_CKR_GENERAL_ERROR; 184 185 return rc; 186 } 187 188 /* 189 * Return true if all attributes from the reference are found and match value 190 * in the candidate attribute list. 191 * 192 * Return PKCS11_CKR_OK on success, or a PKCS11 return code. 193 */ 194 bool attributes_match_reference(struct obj_attrs *ref, 195 struct obj_attrs *candidate); 196 197 /* 198 * get_class() - Get class ID of an object 199 * @head: Pointer to serialized attributes 200 * 201 * Returns the class ID of an object on succes or returns 202 * PKCS11_CKO_UNDEFINED_ID on error. 203 */ 204 static inline enum pkcs11_class_id get_class(struct obj_attrs *head) 205 { 206 uint32_t class = 0; 207 uint32_t size = sizeof(class); 208 209 if (get_attribute(head, PKCS11_CKA_CLASS, &class, &size)) 210 return PKCS11_CKO_UNDEFINED_ID; 211 212 return class; 213 } 214 215 /* 216 * get_key_type() - Get the key type of an object 217 * @head: Pointer to serialized attributes 218 * 219 * Returns the key type of an object on success or returns 220 * PKCS11_CKK_UNDEFINED_ID on error. 221 */ 222 static inline enum pkcs11_key_type get_key_type(struct obj_attrs *head) 223 { 224 uint32_t type = 0; 225 uint32_t size = sizeof(type); 226 227 if (get_attribute(head, PKCS11_CKA_KEY_TYPE, &type, &size)) 228 return PKCS11_CKK_UNDEFINED_ID; 229 230 return type; 231 } 232 233 /* 234 * get_mechanism_type() - Get the mechanism type of an object 235 * @head: Pointer to serialized attributes 236 * 237 * Returns the mechanism type of an object on success or returns 238 * PKCS11_CKM_UNDEFINED_ID on error. 239 */ 240 static inline enum pkcs11_mechanism_id get_mechanism_type(struct obj_attrs *head) 241 { 242 uint32_t type = 0; 243 uint32_t size = sizeof(type); 244 245 if (get_attribute(head, PKCS11_CKA_MECHANISM_TYPE, &type, &size)) 246 return PKCS11_CKM_UNDEFINED_ID; 247 248 return type; 249 } 250 251 /* 252 * get_bool() - Get the bool value of an attribute 253 * @head: Pointer to serialized attributes 254 * @attribute: Attribute ID to look for 255 * 256 * May assert if attribute ID isn't of the boolean type. 257 * 258 * Returns the bool value of the supplied attribute ID on success if found 259 * else false. 260 */ 261 bool get_bool(struct obj_attrs *head, uint32_t attribute); 262 263 #if CFG_TEE_TA_LOG_LEVEL > 0 264 /* Debug: dump object attributes to IMSG() trace console */ 265 void trace_attributes(const char *prefix, void *ref); 266 #else 267 static inline void trace_attributes(const char *prefix __unused, 268 void *ref __unused) 269 { 270 } 271 #endif /*CFG_TEE_TA_LOG_LEVEL*/ 272 #endif /*PKCS11_TA_ATTRIBUTES_H*/ 273