163f89caaSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 263f89caaSJens Wiklander /* 363f89caaSJens Wiklander * Copyright (c) 2017-2020, Linaro Limited 463f89caaSJens Wiklander */ 563f89caaSJens Wiklander 663f89caaSJens Wiklander #include <bitstring.h> 763f89caaSJens Wiklander #include <pkcs11_ta.h> 863f89caaSJens Wiklander #include <stdlib.h> 963f89caaSJens Wiklander #include <string.h> 1063f89caaSJens Wiklander #include <util.h> 1163f89caaSJens Wiklander #include <tee_internal_api.h> 1263f89caaSJens Wiklander #include <tee_internal_api_extensions.h> 1363f89caaSJens Wiklander #include <trace.h> 1463f89caaSJens Wiklander 1563f89caaSJens Wiklander #include "attributes.h" 1663f89caaSJens Wiklander #include "pkcs11_helpers.h" 1763f89caaSJens Wiklander #include "sanitize_object.h" 1863f89caaSJens Wiklander #include "serializer.h" 1963f89caaSJens Wiklander #include "token_capabilities.h" 2063f89caaSJens Wiklander 2163f89caaSJens Wiklander /* 2263f89caaSJens Wiklander * Functions to generate a serialized object. 2363f89caaSJens Wiklander * References are pointers to struct serializer. 2463f89caaSJens Wiklander */ 2563f89caaSJens Wiklander 2663f89caaSJens Wiklander bool sanitize_consistent_class_and_type(struct obj_attrs *attrs) 2763f89caaSJens Wiklander { 2863f89caaSJens Wiklander switch (get_class(attrs)) { 2963f89caaSJens Wiklander case PKCS11_CKO_DATA: 3063f89caaSJens Wiklander return true; 3163f89caaSJens Wiklander case PKCS11_CKO_SECRET_KEY: 3263f89caaSJens Wiklander return key_type_is_symm_key(get_key_type(attrs)); 3363f89caaSJens Wiklander case PKCS11_CKO_MECHANISM: 3463f89caaSJens Wiklander return mechanism_is_valid(get_mechanism_type(attrs)); 3563f89caaSJens Wiklander case PKCS11_CKO_PUBLIC_KEY: 3663f89caaSJens Wiklander case PKCS11_CKO_PRIVATE_KEY: 3763f89caaSJens Wiklander return key_type_is_asymm_key(get_key_type(attrs)); 3863f89caaSJens Wiklander case PKCS11_CKO_OTP_KEY: 3963f89caaSJens Wiklander case PKCS11_CKO_CERTIFICATE: 4063f89caaSJens Wiklander case PKCS11_CKO_DOMAIN_PARAMETERS: 4163f89caaSJens Wiklander case PKCS11_CKO_HW_FEATURE: 4263f89caaSJens Wiklander default: 4363f89caaSJens Wiklander return false; 4463f89caaSJens Wiklander } 4563f89caaSJens Wiklander 4663f89caaSJens Wiklander return false; 4763f89caaSJens Wiklander } 4863f89caaSJens Wiklander 4963f89caaSJens Wiklander static enum pkcs11_rc read_attr_advance(void *buf, size_t blen, size_t *pos, 5063f89caaSJens Wiklander struct pkcs11_attribute_head *attr, 5163f89caaSJens Wiklander void **data) 5263f89caaSJens Wiklander { 5363f89caaSJens Wiklander uint8_t *b = buf; 5463f89caaSJens Wiklander size_t data_pos = 0; 5563f89caaSJens Wiklander size_t next_pos = 0; 5663f89caaSJens Wiklander 5763f89caaSJens Wiklander if (ADD_OVERFLOW(*pos, sizeof(*attr), &data_pos) || data_pos > blen) 5863f89caaSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 5963f89caaSJens Wiklander TEE_MemMove(attr, b + *pos, sizeof(*attr)); 6063f89caaSJens Wiklander 6163f89caaSJens Wiklander if (ADD_OVERFLOW(data_pos, attr->size, &next_pos) || next_pos > blen) 6263f89caaSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 6363f89caaSJens Wiklander 6463f89caaSJens Wiklander *data = b + data_pos; 6563f89caaSJens Wiklander *pos = next_pos; 6663f89caaSJens Wiklander 6763f89caaSJens Wiklander return PKCS11_CKR_OK; 6863f89caaSJens Wiklander } 6963f89caaSJens Wiklander 7063f89caaSJens Wiklander /* Sanitize class/type in a client attribute list */ 7163f89caaSJens Wiklander static enum pkcs11_rc sanitize_class_and_type(struct obj_attrs **dst, void *src, 72*dcad3409SRuchika Gupta size_t src_size, 73*dcad3409SRuchika Gupta uint32_t class_hint, 74*dcad3409SRuchika Gupta uint32_t type_hint) 7563f89caaSJens Wiklander { 7663f89caaSJens Wiklander uint32_t class_found = PKCS11_CKO_UNDEFINED_ID; 7763f89caaSJens Wiklander size_t pos = sizeof(struct pkcs11_object_head); 7863f89caaSJens Wiklander struct pkcs11_attribute_head cli_ref = { }; 7963f89caaSJens Wiklander uint32_t type_found = PKCS11_UNDEFINED_ID; 8063f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 8163f89caaSJens Wiklander void *data = NULL; 8263f89caaSJens Wiklander 8363f89caaSJens Wiklander while (pos != src_size) { 8463f89caaSJens Wiklander rc = read_attr_advance(src, src_size, &pos, &cli_ref, &data); 8563f89caaSJens Wiklander if (rc) 8663f89caaSJens Wiklander goto err; 8763f89caaSJens Wiklander 8863f89caaSJens Wiklander if (cli_ref.id == PKCS11_CKA_CLASS) { 8963f89caaSJens Wiklander uint32_t class = 0; 9063f89caaSJens Wiklander 9163f89caaSJens Wiklander if (cli_ref.size != sizeof(class)) { 9263f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 9363f89caaSJens Wiklander goto err; 9463f89caaSJens Wiklander } 9563f89caaSJens Wiklander 9663f89caaSJens Wiklander TEE_MemMove(&class, data, sizeof(class)); 9763f89caaSJens Wiklander 9863f89caaSJens Wiklander if (class_found != PKCS11_CKO_UNDEFINED_ID && 9963f89caaSJens Wiklander class_found != class) { 10063f89caaSJens Wiklander EMSG("Conflicting class value"); 10163f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 10263f89caaSJens Wiklander goto err; 10363f89caaSJens Wiklander } 10463f89caaSJens Wiklander 10563f89caaSJens Wiklander class_found = class; 10663f89caaSJens Wiklander continue; 10763f89caaSJens Wiklander } 10863f89caaSJens Wiklander 10963f89caaSJens Wiklander /* The attribute is a type-in-class */ 11063f89caaSJens Wiklander if (pkcs11_attr_is_type(cli_ref.id)) { 11163f89caaSJens Wiklander uint32_t type = 0; 11263f89caaSJens Wiklander 11363f89caaSJens Wiklander if (cli_ref.size != sizeof(type)) { 11463f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 11563f89caaSJens Wiklander goto err; 11663f89caaSJens Wiklander } 11763f89caaSJens Wiklander 11863f89caaSJens Wiklander TEE_MemMove(&type, data, sizeof(type)); 11963f89caaSJens Wiklander 12063f89caaSJens Wiklander if (type_found != PKCS11_CKK_UNDEFINED_ID && 12163f89caaSJens Wiklander type_found != type) { 12263f89caaSJens Wiklander EMSG("Conflicting type-in-class value"); 12363f89caaSJens Wiklander rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 12463f89caaSJens Wiklander goto err; 12563f89caaSJens Wiklander } 12663f89caaSJens Wiklander 12763f89caaSJens Wiklander type_found = type; 12863f89caaSJens Wiklander } 12963f89caaSJens Wiklander } 13063f89caaSJens Wiklander 13163f89caaSJens Wiklander if (class_found != PKCS11_CKO_UNDEFINED_ID) { 13263f89caaSJens Wiklander rc = add_attribute(dst, PKCS11_CKA_CLASS, 13363f89caaSJens Wiklander &class_found, sizeof(class_found)); 13463f89caaSJens Wiklander if (rc) 13563f89caaSJens Wiklander return rc; 136*dcad3409SRuchika Gupta } else { 137*dcad3409SRuchika Gupta if (class_hint != PKCS11_CKO_UNDEFINED_ID) { 138*dcad3409SRuchika Gupta rc = add_attribute(dst, PKCS11_CKA_CLASS, 139*dcad3409SRuchika Gupta &class_hint, sizeof(class_hint)); 140*dcad3409SRuchika Gupta if (rc) 141*dcad3409SRuchika Gupta return rc; 142*dcad3409SRuchika Gupta } 14363f89caaSJens Wiklander } 14463f89caaSJens Wiklander 14563f89caaSJens Wiklander if (type_found != PKCS11_UNDEFINED_ID) { 14663f89caaSJens Wiklander rc = add_attribute(dst, PKCS11_CKA_KEY_TYPE, 14763f89caaSJens Wiklander &type_found, sizeof(type_found)); 14863f89caaSJens Wiklander if (rc) 14963f89caaSJens Wiklander return rc; 150*dcad3409SRuchika Gupta } else { 151*dcad3409SRuchika Gupta if (type_hint != PKCS11_UNDEFINED_ID) { 152*dcad3409SRuchika Gupta rc = add_attribute(dst, PKCS11_CKA_KEY_TYPE, 153*dcad3409SRuchika Gupta &type_hint, sizeof(type_hint)); 154*dcad3409SRuchika Gupta if (rc) 155*dcad3409SRuchika Gupta return rc; 156*dcad3409SRuchika Gupta } 15763f89caaSJens Wiklander } 15863f89caaSJens Wiklander 15963f89caaSJens Wiklander return PKCS11_CKR_OK; 16063f89caaSJens Wiklander 16163f89caaSJens Wiklander err: 16263f89caaSJens Wiklander trace_attributes_from_api_head("bad-template", src, src_size); 16363f89caaSJens Wiklander 16463f89caaSJens Wiklander return rc; 16563f89caaSJens Wiklander } 16663f89caaSJens Wiklander 16763f89caaSJens Wiklander static enum pkcs11_rc sanitize_boolprops(struct obj_attrs **dst, void *src, 16863f89caaSJens Wiklander size_t src_size) 16963f89caaSJens Wiklander { 17063f89caaSJens Wiklander bitstr_t bit_decl(seen_attrs, PKCS11_BOOLPROPS_MAX_COUNT) = { 0 }; 17163f89caaSJens Wiklander bitstr_t bit_decl(boolprops, PKCS11_BOOLPROPS_MAX_COUNT) = { 0 }; 17263f89caaSJens Wiklander size_t pos = sizeof(struct pkcs11_object_head); 17363f89caaSJens Wiklander struct pkcs11_attribute_head cli_ref = { }; 17463f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 17563f89caaSJens Wiklander bool value = false; 17663f89caaSJens Wiklander void *data = NULL; 17763f89caaSJens Wiklander int idx = 0; 17863f89caaSJens Wiklander 17963f89caaSJens Wiklander /* 18063f89caaSJens Wiklander * We're keeping track of seen boolean attributes in the bitstring 18163f89caaSJens Wiklander * seen_attrs. The bitstring boolprops holds the recorded value 18263f89caaSJens Wiklander * once seen_attrs has been updated. 18363f89caaSJens Wiklander */ 18463f89caaSJens Wiklander 18563f89caaSJens Wiklander while (pos != src_size) { 18663f89caaSJens Wiklander rc = read_attr_advance(src, src_size, &pos, &cli_ref, &data); 18763f89caaSJens Wiklander if (rc) 18863f89caaSJens Wiklander return rc; 18963f89caaSJens Wiklander 19063f89caaSJens Wiklander idx = pkcs11_attr2boolprop_shift(cli_ref.id); 19163f89caaSJens Wiklander if (idx < 0) 19263f89caaSJens Wiklander continue; /* skipping non-boolean attributes */ 19363f89caaSJens Wiklander 19463f89caaSJens Wiklander if (idx >= PKCS11_BOOLPROPS_MAX_COUNT || 19563f89caaSJens Wiklander cli_ref.size != sizeof(uint8_t)) 19663f89caaSJens Wiklander return PKCS11_CKR_FUNCTION_FAILED; 19763f89caaSJens Wiklander 19863f89caaSJens Wiklander value = *(uint8_t *)data; 19963f89caaSJens Wiklander 20063f89caaSJens Wiklander /* 20163f89caaSJens Wiklander * If this attribute has already been seen, check that it 20263f89caaSJens Wiklander * still holds the same value as last time. 20363f89caaSJens Wiklander */ 20463f89caaSJens Wiklander if (bit_test(seen_attrs, idx) && 20563f89caaSJens Wiklander value != (bool)bit_test(boolprops, idx)) 20663f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 20763f89caaSJens Wiklander 20863f89caaSJens Wiklander if (value) 20963f89caaSJens Wiklander bit_set(boolprops, idx); 21063f89caaSJens Wiklander 21163f89caaSJens Wiklander if (!bit_test(seen_attrs, idx)) { 21263f89caaSJens Wiklander uint8_t pkcs11_bool = value; 21363f89caaSJens Wiklander 21463f89caaSJens Wiklander rc = add_attribute(dst, cli_ref.id, &pkcs11_bool, 21563f89caaSJens Wiklander sizeof(pkcs11_bool)); 21663f89caaSJens Wiklander if (rc) 21763f89caaSJens Wiklander return rc; 21863f89caaSJens Wiklander } 21963f89caaSJens Wiklander bit_set(seen_attrs, idx); 22063f89caaSJens Wiklander } 22163f89caaSJens Wiklander 22263f89caaSJens Wiklander return PKCS11_CKR_OK; 22363f89caaSJens Wiklander } 22463f89caaSJens Wiklander 22563f89caaSJens Wiklander static uint32_t sanitize_indirect_attr(struct obj_attrs **dst, 22663f89caaSJens Wiklander struct pkcs11_attribute_head *cli_ref, 22763f89caaSJens Wiklander char *data) 22863f89caaSJens Wiklander { 22963f89caaSJens Wiklander struct obj_attrs *obj2 = NULL; 23063f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 23163f89caaSJens Wiklander enum pkcs11_class_id class = get_class(*dst); 23263f89caaSJens Wiklander 23363f89caaSJens Wiklander /* 23463f89caaSJens Wiklander * Serialized attributes: current applicable only to the key 23563f89caaSJens Wiklander * templates which are tables of attributes. 23663f89caaSJens Wiklander */ 23763f89caaSJens Wiklander switch (cli_ref->id) { 23863f89caaSJens Wiklander case PKCS11_CKA_WRAP_TEMPLATE: 23963f89caaSJens Wiklander case PKCS11_CKA_UNWRAP_TEMPLATE: 24063f89caaSJens Wiklander case PKCS11_CKA_DERIVE_TEMPLATE: 24163f89caaSJens Wiklander break; 24263f89caaSJens Wiklander default: 24363f89caaSJens Wiklander return PKCS11_RV_NOT_FOUND; 24463f89caaSJens Wiklander } 2455440719dSRuchika Gupta 2465440719dSRuchika Gupta if (class == PKCS11_CKO_UNDEFINED_ID) { 2475440719dSRuchika Gupta DMSG("Template without CLASS not supported yet"); 2485440719dSRuchika Gupta return PKCS11_CKR_TEMPLATE_INCOMPLETE; 2495440719dSRuchika Gupta } 2505440719dSRuchika Gupta 25163f89caaSJens Wiklander /* Such attributes are expected only for keys (and vendor defined) */ 25263f89caaSJens Wiklander if (pkcs11_attr_class_is_key(class)) 25363f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 25463f89caaSJens Wiklander 25563f89caaSJens Wiklander rc = init_attributes_head(&obj2); 25663f89caaSJens Wiklander if (rc) 25763f89caaSJens Wiklander return rc; 25863f89caaSJens Wiklander 25963f89caaSJens Wiklander /* Build a new serial object while sanitizing the attributes list */ 260*dcad3409SRuchika Gupta rc = sanitize_client_object(&obj2, data, cli_ref->size, 261*dcad3409SRuchika Gupta PKCS11_CKO_UNDEFINED_ID, 262*dcad3409SRuchika Gupta PKCS11_UNDEFINED_ID); 26363f89caaSJens Wiklander if (rc) 26463f89caaSJens Wiklander goto out; 26563f89caaSJens Wiklander 26663f89caaSJens Wiklander rc = add_attribute(dst, cli_ref->id, obj2, 26763f89caaSJens Wiklander sizeof(*obj2) + obj2->attrs_size); 26863f89caaSJens Wiklander out: 26963f89caaSJens Wiklander TEE_Free(obj2); 27063f89caaSJens Wiklander return rc; 27163f89caaSJens Wiklander } 27263f89caaSJens Wiklander 27363f89caaSJens Wiklander enum pkcs11_rc sanitize_client_object(struct obj_attrs **dst, void *src, 274*dcad3409SRuchika Gupta size_t size, uint32_t class_hint, 275*dcad3409SRuchika Gupta uint32_t type_hint) 27663f89caaSJens Wiklander { 27763f89caaSJens Wiklander struct pkcs11_attribute_head cli_ref = { }; 27863f89caaSJens Wiklander struct pkcs11_object_head head = { }; 27963f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 28063f89caaSJens Wiklander size_t pos = sizeof(head); 28163f89caaSJens Wiklander size_t sz_from_hdr = 0; 28263f89caaSJens Wiklander void *data = NULL; 28363f89caaSJens Wiklander 28463f89caaSJens Wiklander if (size < sizeof(head)) 28563f89caaSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 28663f89caaSJens Wiklander 28763f89caaSJens Wiklander TEE_MemMove(&head, src, sizeof(head)); 28863f89caaSJens Wiklander 28963f89caaSJens Wiklander if (ADD_OVERFLOW(sizeof(head), head.attrs_size, &sz_from_hdr) || 29063f89caaSJens Wiklander size < sz_from_hdr) 29163f89caaSJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 29263f89caaSJens Wiklander 29363f89caaSJens Wiklander rc = init_attributes_head(dst); 29463f89caaSJens Wiklander if (rc) 29563f89caaSJens Wiklander return rc; 29663f89caaSJens Wiklander 297*dcad3409SRuchika Gupta rc = sanitize_class_and_type(dst, src, sz_from_hdr, class_hint, 298*dcad3409SRuchika Gupta type_hint); 29963f89caaSJens Wiklander if (rc) 30063f89caaSJens Wiklander return rc; 30163f89caaSJens Wiklander 30263f89caaSJens Wiklander rc = sanitize_boolprops(dst, src, sz_from_hdr); 30363f89caaSJens Wiklander if (rc) 30463f89caaSJens Wiklander return rc; 30563f89caaSJens Wiklander 30663f89caaSJens Wiklander while (pos != sz_from_hdr) { 30763f89caaSJens Wiklander rc = read_attr_advance(src, sz_from_hdr, &pos, &cli_ref, &data); 30863f89caaSJens Wiklander if (rc) 30963f89caaSJens Wiklander return rc; 31063f89caaSJens Wiklander 31163f89caaSJens Wiklander if (cli_ref.id == PKCS11_CKA_CLASS || 31263f89caaSJens Wiklander pkcs11_attr_is_type(cli_ref.id) || 31363f89caaSJens Wiklander pkcs11_attr_is_boolean(cli_ref.id)) 31463f89caaSJens Wiklander continue; 31563f89caaSJens Wiklander 31663f89caaSJens Wiklander rc = sanitize_indirect_attr(dst, &cli_ref, data); 31763f89caaSJens Wiklander if (rc == PKCS11_CKR_OK) 31863f89caaSJens Wiklander continue; 31963f89caaSJens Wiklander if (rc != PKCS11_RV_NOT_FOUND) 32063f89caaSJens Wiklander return rc; 32163f89caaSJens Wiklander 32263f89caaSJens Wiklander if (!valid_pkcs11_attribute_id(cli_ref.id, cli_ref.size)) { 32363f89caaSJens Wiklander EMSG("Invalid attribute id %#"PRIx32, cli_ref.id); 32463f89caaSJens Wiklander return PKCS11_CKR_TEMPLATE_INCONSISTENT; 32563f89caaSJens Wiklander } 32663f89caaSJens Wiklander 32763f89caaSJens Wiklander rc = add_attribute(dst, cli_ref.id, data, cli_ref.size); 32863f89caaSJens Wiklander if (rc) 32963f89caaSJens Wiklander return rc; 33063f89caaSJens Wiklander } 33163f89caaSJens Wiklander 33263f89caaSJens Wiklander return rc; 33363f89caaSJens Wiklander } 33463f89caaSJens Wiklander 33563f89caaSJens Wiklander /* 33663f89caaSJens Wiklander * Debug: dump object attribute array to output trace 33763f89caaSJens Wiklander */ 33863f89caaSJens Wiklander 33963f89caaSJens Wiklander static void __trace_attributes(char *prefix, void *src, void *end) 34063f89caaSJens Wiklander { 34163f89caaSJens Wiklander size_t next = 0; 34263f89caaSJens Wiklander char *prefix2 = NULL; 34363f89caaSJens Wiklander size_t prefix_len = strlen(prefix); 34463f89caaSJens Wiklander char *cur = src; 34563f89caaSJens Wiklander 34663f89caaSJens Wiklander /* append 4 spaces to the prefix plus terminal '\0' */ 34763f89caaSJens Wiklander prefix2 = TEE_Malloc(prefix_len + 1 + 4, TEE_MALLOC_FILL_ZERO); 34863f89caaSJens Wiklander if (!prefix2) 34963f89caaSJens Wiklander return; 35063f89caaSJens Wiklander 35163f89caaSJens Wiklander TEE_MemMove(prefix2, prefix, prefix_len + 1); 35263f89caaSJens Wiklander TEE_MemFill(prefix2 + prefix_len, ' ', 4); 35363f89caaSJens Wiklander *(prefix2 + prefix_len + 4) = '\0'; 35463f89caaSJens Wiklander 35563f89caaSJens Wiklander for (; cur < (char *)end; cur += next) { 35663f89caaSJens Wiklander struct pkcs11_attribute_head pkcs11_ref; 35763f89caaSJens Wiklander uint8_t data[4] = { 0 }; 35863f89caaSJens Wiklander uint32_t data_u32 = 0; 35963f89caaSJens Wiklander 36063f89caaSJens Wiklander TEE_MemMove(&pkcs11_ref, cur, sizeof(pkcs11_ref)); 36163f89caaSJens Wiklander TEE_MemMove(&data[0], cur + sizeof(pkcs11_ref), 36263f89caaSJens Wiklander MIN(pkcs11_ref.size, sizeof(data))); 36363f89caaSJens Wiklander TEE_MemMove(&data_u32, cur + sizeof(pkcs11_ref), 36463f89caaSJens Wiklander sizeof(data_u32)); 36563f89caaSJens Wiklander 36663f89caaSJens Wiklander next = sizeof(pkcs11_ref) + pkcs11_ref.size; 36763f89caaSJens Wiklander 36863f89caaSJens Wiklander DMSG_RAW("%s Attr %s / %s (%#04"PRIx32" %"PRIu32"-byte)", 36963f89caaSJens Wiklander prefix, id2str_attr(pkcs11_ref.id), 37063f89caaSJens Wiklander id2str_attr_value(pkcs11_ref.id, pkcs11_ref.size, 37163f89caaSJens Wiklander cur + sizeof(pkcs11_ref)), 37263f89caaSJens Wiklander pkcs11_ref.id, pkcs11_ref.size); 37363f89caaSJens Wiklander 37463f89caaSJens Wiklander switch (pkcs11_ref.size) { 37563f89caaSJens Wiklander case 0: 37663f89caaSJens Wiklander break; 37763f89caaSJens Wiklander case 1: 37863f89caaSJens Wiklander DMSG_RAW("%s Attr byte value: %02x", prefix, data[0]); 37963f89caaSJens Wiklander break; 38063f89caaSJens Wiklander case 2: 38163f89caaSJens Wiklander DMSG_RAW("%s Attr byte value: %02x %02x", 38263f89caaSJens Wiklander prefix, data[0], data[1]); 38363f89caaSJens Wiklander break; 38463f89caaSJens Wiklander case 3: 38563f89caaSJens Wiklander DMSG_RAW("%s Attr byte value: %02x %02x %02x", 38663f89caaSJens Wiklander prefix, data[0], data[1], data[2]); 38763f89caaSJens Wiklander break; 38863f89caaSJens Wiklander case 4: 38963f89caaSJens Wiklander DMSG_RAW("%s Attr byte value: %02x %02x %02x %02x", 39063f89caaSJens Wiklander prefix, data[0], data[1], data[2], data[3]); 39163f89caaSJens Wiklander break; 39263f89caaSJens Wiklander default: 39363f89caaSJens Wiklander DMSG_RAW("%s Attr byte value: %02x %02x %02x %02x ...", 39463f89caaSJens Wiklander prefix, data[0], data[1], data[2], data[3]); 39563f89caaSJens Wiklander break; 39663f89caaSJens Wiklander } 39763f89caaSJens Wiklander 39863f89caaSJens Wiklander switch (pkcs11_ref.id) { 39963f89caaSJens Wiklander case PKCS11_CKA_WRAP_TEMPLATE: 40063f89caaSJens Wiklander case PKCS11_CKA_UNWRAP_TEMPLATE: 40163f89caaSJens Wiklander case PKCS11_CKA_DERIVE_TEMPLATE: 40263f89caaSJens Wiklander trace_attributes_from_api_head(prefix2, 40363f89caaSJens Wiklander cur + sizeof(pkcs11_ref), 40463f89caaSJens Wiklander (char *)end - cur); 40563f89caaSJens Wiklander break; 40663f89caaSJens Wiklander default: 40763f89caaSJens Wiklander break; 40863f89caaSJens Wiklander } 40963f89caaSJens Wiklander } 41063f89caaSJens Wiklander 41163f89caaSJens Wiklander /* Sanity */ 41263f89caaSJens Wiklander if (cur != (char *)end) 41363f89caaSJens Wiklander EMSG("Warning: unexpected alignment issue"); 41463f89caaSJens Wiklander 41563f89caaSJens Wiklander TEE_Free(prefix2); 41663f89caaSJens Wiklander } 41763f89caaSJens Wiklander 41863f89caaSJens Wiklander void trace_attributes_from_api_head(const char *prefix, void *ref, size_t size) 41963f89caaSJens Wiklander { 42063f89caaSJens Wiklander struct pkcs11_object_head head = { }; 42163f89caaSJens Wiklander char *pre = NULL; 42263f89caaSJens Wiklander size_t offset = 0; 42363f89caaSJens Wiklander 42463f89caaSJens Wiklander TEE_MemMove(&head, ref, sizeof(head)); 42563f89caaSJens Wiklander 42663f89caaSJens Wiklander if (size > sizeof(head) + head.attrs_size) { 42763f89caaSJens Wiklander EMSG("template overflows client buffer (%zu/%zu)", 42863f89caaSJens Wiklander size, sizeof(head) + head.attrs_size); 42963f89caaSJens Wiklander return; 43063f89caaSJens Wiklander } 43163f89caaSJens Wiklander 43263f89caaSJens Wiklander pre = TEE_Malloc(prefix ? strlen(prefix) + 2 : 2, TEE_MALLOC_FILL_ZERO); 43363f89caaSJens Wiklander if (!pre) { 43463f89caaSJens Wiklander EMSG("%s: out of memory", prefix); 43563f89caaSJens Wiklander return; 43663f89caaSJens Wiklander } 43763f89caaSJens Wiklander if (prefix) 43863f89caaSJens Wiklander TEE_MemMove(pre, prefix, strlen(prefix)); 43963f89caaSJens Wiklander 44063f89caaSJens Wiklander DMSG_RAW("%s,--- (serial object) Attributes list --------", pre); 44163f89caaSJens Wiklander DMSG_RAW("%s| %"PRIu32" item(s) - %"PRIu32" bytes", 44263f89caaSJens Wiklander pre, head.attrs_count, head.attrs_size); 44363f89caaSJens Wiklander 44463f89caaSJens Wiklander offset = sizeof(head); 44563f89caaSJens Wiklander pre[prefix ? strlen(prefix) : 0] = '|'; 44663f89caaSJens Wiklander __trace_attributes(pre, (char *)ref + offset, 44763f89caaSJens Wiklander (char *)ref + offset + head.attrs_size); 44863f89caaSJens Wiklander 44963f89caaSJens Wiklander DMSG_RAW("%s`-----------------------", prefix ? prefix : ""); 45063f89caaSJens Wiklander 45163f89caaSJens Wiklander TEE_Free(pre); 45263f89caaSJens Wiklander } 453