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 <assert.h>
763f89caaSJens Wiklander #include <compiler.h>
863f89caaSJens Wiklander #include <pkcs11_ta.h>
963f89caaSJens Wiklander #include <stddef.h>
1063f89caaSJens Wiklander #include <stdlib.h>
1163f89caaSJens Wiklander #include <string.h>
1263f89caaSJens Wiklander #include <string_ext.h>
1363f89caaSJens Wiklander #include <tee_internal_api.h>
1463f89caaSJens Wiklander #include <trace.h>
1563f89caaSJens Wiklander #include <util.h>
1663f89caaSJens Wiklander
1763f89caaSJens Wiklander #include "attributes.h"
1863f89caaSJens Wiklander #include "pkcs11_helpers.h"
1963f89caaSJens Wiklander #include "serializer.h"
2063f89caaSJens Wiklander
init_attributes_head(struct obj_attrs ** head)2163f89caaSJens Wiklander enum pkcs11_rc init_attributes_head(struct obj_attrs **head)
2263f89caaSJens Wiklander {
2363f89caaSJens Wiklander *head = TEE_Malloc(sizeof(**head), TEE_MALLOC_FILL_ZERO);
2463f89caaSJens Wiklander if (!*head)
2563f89caaSJens Wiklander return PKCS11_CKR_DEVICE_MEMORY;
2663f89caaSJens Wiklander
2763f89caaSJens Wiklander return PKCS11_CKR_OK;
2863f89caaSJens Wiklander }
2963f89caaSJens Wiklander
add_attribute(struct obj_attrs ** head,uint32_t attribute,void * data,size_t size)3063f89caaSJens Wiklander enum pkcs11_rc add_attribute(struct obj_attrs **head, uint32_t attribute,
3163f89caaSJens Wiklander void *data, size_t size)
3263f89caaSJens Wiklander {
3363f89caaSJens Wiklander size_t buf_len = sizeof(struct obj_attrs) + (*head)->attrs_size;
3463f89caaSJens Wiklander char **bstart = (void *)head;
3563f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
3663f89caaSJens Wiklander uint32_t data32 = 0;
3763f89caaSJens Wiklander
3863f89caaSJens Wiklander data32 = attribute;
3963f89caaSJens Wiklander rc = serialize(bstart, &buf_len, &data32, sizeof(uint32_t));
4063f89caaSJens Wiklander if (rc)
4163f89caaSJens Wiklander return rc;
4263f89caaSJens Wiklander
4363f89caaSJens Wiklander data32 = size;
4463f89caaSJens Wiklander rc = serialize(bstart, &buf_len, &data32, sizeof(uint32_t));
4563f89caaSJens Wiklander if (rc)
4663f89caaSJens Wiklander return rc;
4763f89caaSJens Wiklander
4863f89caaSJens Wiklander rc = serialize(bstart, &buf_len, data, size);
4963f89caaSJens Wiklander if (rc)
5063f89caaSJens Wiklander return rc;
5163f89caaSJens Wiklander
5263f89caaSJens Wiklander /* Alloced buffer is always well aligned */
5363f89caaSJens Wiklander head = (void *)bstart;
5463f89caaSJens Wiklander (*head)->attrs_size += 2 * sizeof(uint32_t) + size;
5563f89caaSJens Wiklander (*head)->attrs_count++;
5663f89caaSJens Wiklander
5763f89caaSJens Wiklander return rc;
5863f89caaSJens Wiklander }
5963f89caaSJens Wiklander
_remove_attribute(struct obj_attrs ** head,uint32_t attribute,bool empty)60fa247a2aSRuchika Gupta static enum pkcs11_rc _remove_attribute(struct obj_attrs **head,
61fa247a2aSRuchika Gupta uint32_t attribute, bool empty)
62fa247a2aSRuchika Gupta {
63fa247a2aSRuchika Gupta struct obj_attrs *h = *head;
64fa247a2aSRuchika Gupta char *cur = NULL;
65fa247a2aSRuchika Gupta char *end = NULL;
66fa247a2aSRuchika Gupta size_t next_off = 0;
67fa247a2aSRuchika Gupta
68fa247a2aSRuchika Gupta /* Let's find the target attribute */
69fa247a2aSRuchika Gupta cur = (char *)h + sizeof(struct obj_attrs);
70fa247a2aSRuchika Gupta end = cur + h->attrs_size;
71fa247a2aSRuchika Gupta for (; cur < end; cur += next_off) {
72fa247a2aSRuchika Gupta struct pkcs11_attribute_head pkcs11_ref = { };
73fa247a2aSRuchika Gupta
74fa247a2aSRuchika Gupta TEE_MemMove(&pkcs11_ref, cur, sizeof(pkcs11_ref));
75fa247a2aSRuchika Gupta next_off = sizeof(pkcs11_ref) + pkcs11_ref.size;
76fa247a2aSRuchika Gupta
77fa247a2aSRuchika Gupta if (pkcs11_ref.id != attribute)
78fa247a2aSRuchika Gupta continue;
79fa247a2aSRuchika Gupta
80fa247a2aSRuchika Gupta if (empty && pkcs11_ref.size)
81fa247a2aSRuchika Gupta return PKCS11_CKR_FUNCTION_FAILED;
82fa247a2aSRuchika Gupta
83fa247a2aSRuchika Gupta TEE_MemMove(cur, cur + next_off, end - (cur + next_off));
84fa247a2aSRuchika Gupta
85fa247a2aSRuchika Gupta h->attrs_count--;
86fa247a2aSRuchika Gupta h->attrs_size -= next_off;
87fa247a2aSRuchika Gupta end -= next_off;
88fa247a2aSRuchika Gupta next_off = 0;
89fa247a2aSRuchika Gupta
90fa247a2aSRuchika Gupta return PKCS11_CKR_OK;
91fa247a2aSRuchika Gupta }
92fa247a2aSRuchika Gupta
93fa247a2aSRuchika Gupta DMSG("Attribute %s (%#x) not found", id2str_attr(attribute), attribute);
94fa247a2aSRuchika Gupta return PKCS11_RV_NOT_FOUND;
95fa247a2aSRuchika Gupta }
96fa247a2aSRuchika Gupta
remove_empty_attribute(struct obj_attrs ** head,uint32_t attribute)97fa247a2aSRuchika Gupta enum pkcs11_rc remove_empty_attribute(struct obj_attrs **head,
98fa247a2aSRuchika Gupta uint32_t attribute)
99fa247a2aSRuchika Gupta {
100fa247a2aSRuchika Gupta return _remove_attribute(head, attribute, true /* empty */);
101fa247a2aSRuchika Gupta }
102fa247a2aSRuchika Gupta
get_attribute_ptrs(struct obj_attrs * head,uint32_t attribute,void ** attr,uint32_t * attr_size,size_t * count)10363f89caaSJens Wiklander void get_attribute_ptrs(struct obj_attrs *head, uint32_t attribute,
10463f89caaSJens Wiklander void **attr, uint32_t *attr_size, size_t *count)
10563f89caaSJens Wiklander {
10663f89caaSJens Wiklander char *cur = (char *)head + sizeof(struct obj_attrs);
10763f89caaSJens Wiklander char *end = cur + head->attrs_size;
10863f89caaSJens Wiklander size_t next_off = 0;
10963f89caaSJens Wiklander size_t max_found = *count;
11063f89caaSJens Wiklander size_t found = 0;
11163f89caaSJens Wiklander void **attr_ptr = attr;
11263f89caaSJens Wiklander uint32_t *attr_size_ptr = attr_size;
11363f89caaSJens Wiklander
11463f89caaSJens Wiklander for (; cur < end; cur += next_off) {
11563f89caaSJens Wiklander /* Structure aligned copy of the pkcs11_ref in the object */
11663f89caaSJens Wiklander struct pkcs11_attribute_head pkcs11_ref = { };
11763f89caaSJens Wiklander
11863f89caaSJens Wiklander TEE_MemMove(&pkcs11_ref, cur, sizeof(pkcs11_ref));
11963f89caaSJens Wiklander next_off = sizeof(pkcs11_ref) + pkcs11_ref.size;
12063f89caaSJens Wiklander
12163f89caaSJens Wiklander if (pkcs11_ref.id != attribute)
12263f89caaSJens Wiklander continue;
12363f89caaSJens Wiklander
12463f89caaSJens Wiklander found++;
12563f89caaSJens Wiklander
12663f89caaSJens Wiklander if (!max_found)
12763f89caaSJens Wiklander continue; /* only count matching attributes */
12863f89caaSJens Wiklander
1290b912584SEtienne Carriere if (attr) {
1300b912584SEtienne Carriere if (pkcs11_ref.size)
13163f89caaSJens Wiklander *attr_ptr++ = cur + sizeof(pkcs11_ref);
1320b912584SEtienne Carriere else
1330b912584SEtienne Carriere *attr_ptr++ = NULL;
1340b912584SEtienne Carriere }
13563f89caaSJens Wiklander
13663f89caaSJens Wiklander if (attr_size)
13763f89caaSJens Wiklander *attr_size_ptr++ = pkcs11_ref.size;
13863f89caaSJens Wiklander
13963f89caaSJens Wiklander if (found == max_found)
14063f89caaSJens Wiklander break;
14163f89caaSJens Wiklander }
14263f89caaSJens Wiklander
14363f89caaSJens Wiklander /* Sanity */
14463f89caaSJens Wiklander if (cur > end) {
14563f89caaSJens Wiklander DMSG("Exceeding serial object length");
14663f89caaSJens Wiklander TEE_Panic(0);
14763f89caaSJens Wiklander }
14863f89caaSJens Wiklander
14963f89caaSJens Wiklander *count = found;
15063f89caaSJens Wiklander }
15163f89caaSJens Wiklander
get_attribute_ptr(struct obj_attrs * head,uint32_t attribute,void ** attr_ptr,uint32_t * attr_size)15263f89caaSJens Wiklander enum pkcs11_rc get_attribute_ptr(struct obj_attrs *head, uint32_t attribute,
15363f89caaSJens Wiklander void **attr_ptr, uint32_t *attr_size)
15463f89caaSJens Wiklander {
15563f89caaSJens Wiklander size_t count = 1;
15663f89caaSJens Wiklander
15763f89caaSJens Wiklander get_attribute_ptrs(head, attribute, attr_ptr, attr_size, &count);
15863f89caaSJens Wiklander
15963f89caaSJens Wiklander if (!count)
16063f89caaSJens Wiklander return PKCS11_RV_NOT_FOUND;
16163f89caaSJens Wiklander
16263f89caaSJens Wiklander if (count != 1)
16363f89caaSJens Wiklander return PKCS11_CKR_GENERAL_ERROR;
16463f89caaSJens Wiklander
16563f89caaSJens Wiklander return PKCS11_CKR_OK;
16663f89caaSJens Wiklander }
16763f89caaSJens Wiklander
get_attribute(struct obj_attrs * head,uint32_t attribute,void * attr,uint32_t * attr_size)16863f89caaSJens Wiklander enum pkcs11_rc get_attribute(struct obj_attrs *head, uint32_t attribute,
16963f89caaSJens Wiklander void *attr, uint32_t *attr_size)
17063f89caaSJens Wiklander {
17163f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
17263f89caaSJens Wiklander void *attr_ptr = NULL;
17363f89caaSJens Wiklander uint32_t size = 0;
17463f89caaSJens Wiklander
17563f89caaSJens Wiklander rc = get_attribute_ptr(head, attribute, &attr_ptr, &size);
17663f89caaSJens Wiklander if (rc)
17763f89caaSJens Wiklander return rc;
17863f89caaSJens Wiklander
179d17c25d2SVesa Jääskeläinen if (attr_size && *attr_size < size) {
18063f89caaSJens Wiklander *attr_size = size;
18163f89caaSJens Wiklander /* This reuses buffer-to-small for any bad size matching */
18263f89caaSJens Wiklander return PKCS11_CKR_BUFFER_TOO_SMALL;
18363f89caaSJens Wiklander }
18463f89caaSJens Wiklander
18563f89caaSJens Wiklander if (attr)
18663f89caaSJens Wiklander TEE_MemMove(attr, attr_ptr, size);
18763f89caaSJens Wiklander
18863f89caaSJens Wiklander if (attr_size)
18963f89caaSJens Wiklander *attr_size = size;
19063f89caaSJens Wiklander
19163f89caaSJens Wiklander return PKCS11_CKR_OK;
19263f89caaSJens Wiklander }
19363f89caaSJens Wiklander
set_attribute(struct obj_attrs ** head,uint32_t attribute,void * data,size_t size)1942d25a9bcSRuchika Gupta enum pkcs11_rc set_attribute(struct obj_attrs **head, uint32_t attribute,
1952d25a9bcSRuchika Gupta void *data, size_t size)
1962d25a9bcSRuchika Gupta {
1972d25a9bcSRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK;
1982d25a9bcSRuchika Gupta
1992d25a9bcSRuchika Gupta rc = _remove_attribute(head, attribute, false);
2002d25a9bcSRuchika Gupta if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
2012d25a9bcSRuchika Gupta return rc;
2022d25a9bcSRuchika Gupta
2032d25a9bcSRuchika Gupta return add_attribute(head, attribute, data, size);
2042d25a9bcSRuchika Gupta }
2052d25a9bcSRuchika Gupta
modify_attributes_list(struct obj_attrs ** dst,struct obj_attrs * head)2062d25a9bcSRuchika Gupta enum pkcs11_rc modify_attributes_list(struct obj_attrs **dst,
2072d25a9bcSRuchika Gupta struct obj_attrs *head)
2082d25a9bcSRuchika Gupta {
2092d25a9bcSRuchika Gupta char *cur = (char *)head + sizeof(struct obj_attrs);
2102d25a9bcSRuchika Gupta char *end = cur + head->attrs_size;
2112d25a9bcSRuchika Gupta size_t len = 0;
2122d25a9bcSRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK;
2132d25a9bcSRuchika Gupta
2142d25a9bcSRuchika Gupta for (; cur < end; cur += len) {
2152d25a9bcSRuchika Gupta struct pkcs11_attribute_head *cli_ref = (void *)cur;
2162d25a9bcSRuchika Gupta /* Structure aligned copy of the pkcs11_ref in the object */
2172d25a9bcSRuchika Gupta struct pkcs11_attribute_head cli_head = { };
2182d25a9bcSRuchika Gupta
2192d25a9bcSRuchika Gupta TEE_MemMove(&cli_head, cur, sizeof(cli_head));
2202d25a9bcSRuchika Gupta len = sizeof(cli_head) + cli_head.size;
2212d25a9bcSRuchika Gupta
2222d25a9bcSRuchika Gupta rc = set_attribute(dst, cli_head.id,
2232d25a9bcSRuchika Gupta cli_head.size ? cli_ref->data : NULL,
2242d25a9bcSRuchika Gupta cli_head.size);
2252d25a9bcSRuchika Gupta if (rc)
2262d25a9bcSRuchika Gupta return rc;
2272d25a9bcSRuchika Gupta }
2282d25a9bcSRuchika Gupta
2292d25a9bcSRuchika Gupta return PKCS11_CKR_OK;
2302d25a9bcSRuchika Gupta }
2312d25a9bcSRuchika Gupta
get_bool(struct obj_attrs * head,uint32_t attribute)23263f89caaSJens Wiklander bool get_bool(struct obj_attrs *head, uint32_t attribute)
23363f89caaSJens Wiklander {
23463f89caaSJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK;
23563f89caaSJens Wiklander uint8_t bbool = 0;
23663f89caaSJens Wiklander uint32_t size = sizeof(bbool);
23763f89caaSJens Wiklander
23863f89caaSJens Wiklander rc = get_attribute(head, attribute, &bbool, &size);
23963f89caaSJens Wiklander
24063f89caaSJens Wiklander if (rc == PKCS11_RV_NOT_FOUND)
24163f89caaSJens Wiklander return false;
24263f89caaSJens Wiklander
24363f89caaSJens Wiklander assert(rc == PKCS11_CKR_OK);
24463f89caaSJens Wiklander return bbool;
24563f89caaSJens Wiklander }
24663f89caaSJens Wiklander
attributes_match_reference(struct obj_attrs * candidate,struct obj_attrs * ref)247dc99b202SRuchika Gupta bool attributes_match_reference(struct obj_attrs *candidate,
248dc99b202SRuchika Gupta struct obj_attrs *ref)
249dc99b202SRuchika Gupta {
250dc99b202SRuchika Gupta size_t count = ref->attrs_count;
251dc99b202SRuchika Gupta unsigned char *ref_attr = ref->attrs;
252dc99b202SRuchika Gupta uint32_t rc = PKCS11_CKR_GENERAL_ERROR;
253dc99b202SRuchika Gupta
254dc99b202SRuchika Gupta if (!ref->attrs_count) {
255fa1ac767SRobin van der Gracht DMSG("Empty reference match all");
256fa1ac767SRobin van der Gracht return true;
257dc99b202SRuchika Gupta }
258dc99b202SRuchika Gupta
259dc99b202SRuchika Gupta for (count = 0; count < ref->attrs_count; count++) {
260dc99b202SRuchika Gupta struct pkcs11_attribute_head pkcs11_ref = { };
261dc99b202SRuchika Gupta void *value = NULL;
262dc99b202SRuchika Gupta uint32_t size = 0;
263dc99b202SRuchika Gupta
264dc99b202SRuchika Gupta TEE_MemMove(&pkcs11_ref, ref_attr, sizeof(pkcs11_ref));
265dc99b202SRuchika Gupta
266*981966bcSVesa Jääskeläinen /* Hidden attributes cannot be matched */
267*981966bcSVesa Jääskeläinen if (attribute_is_hidden(&pkcs11_ref))
268*981966bcSVesa Jääskeläinen return false;
269*981966bcSVesa Jääskeläinen
270dc99b202SRuchika Gupta rc = get_attribute_ptr(candidate, pkcs11_ref.id, &value, &size);
271dc99b202SRuchika Gupta
272dc99b202SRuchika Gupta if (rc || !value || size != pkcs11_ref.size ||
273dc99b202SRuchika Gupta TEE_MemCompare(ref_attr + sizeof(pkcs11_ref), value, size))
274dc99b202SRuchika Gupta return false;
275dc99b202SRuchika Gupta
276dc99b202SRuchika Gupta ref_attr += sizeof(pkcs11_ref) + pkcs11_ref.size;
277dc99b202SRuchika Gupta }
278dc99b202SRuchika Gupta
279dc99b202SRuchika Gupta return true;
280dc99b202SRuchika Gupta }
281dc99b202SRuchika Gupta
attributes_match_add_reference(struct obj_attrs ** head,struct obj_attrs * ref)282e3f0cb56SRuchika Gupta enum pkcs11_rc attributes_match_add_reference(struct obj_attrs **head,
283e3f0cb56SRuchika Gupta struct obj_attrs *ref)
284e3f0cb56SRuchika Gupta {
285e3f0cb56SRuchika Gupta size_t count = ref->attrs_count;
286e3f0cb56SRuchika Gupta unsigned char *ref_attr = ref->attrs;
287e3f0cb56SRuchika Gupta enum pkcs11_rc rc = PKCS11_CKR_OK;
288e3f0cb56SRuchika Gupta
289e3f0cb56SRuchika Gupta if (!ref->attrs_count)
290e3f0cb56SRuchika Gupta return PKCS11_CKR_OK;
291e3f0cb56SRuchika Gupta
292e3f0cb56SRuchika Gupta for (count = 0; count < ref->attrs_count; count++) {
293e3f0cb56SRuchika Gupta struct pkcs11_attribute_head pkcs11_ref = { };
294e3f0cb56SRuchika Gupta void *value = NULL;
295e3f0cb56SRuchika Gupta uint32_t size = 0;
296e3f0cb56SRuchika Gupta
297e3f0cb56SRuchika Gupta TEE_MemMove(&pkcs11_ref, ref_attr, sizeof(pkcs11_ref));
298e3f0cb56SRuchika Gupta
299e3f0cb56SRuchika Gupta rc = get_attribute_ptr(*head, pkcs11_ref.id, &value, &size);
300e3f0cb56SRuchika Gupta if (rc == PKCS11_RV_NOT_FOUND) {
301e3f0cb56SRuchika Gupta rc = add_attribute(head, pkcs11_ref.id,
302e3f0cb56SRuchika Gupta ref_attr + sizeof(pkcs11_ref),
303e3f0cb56SRuchika Gupta pkcs11_ref.size);
304e3f0cb56SRuchika Gupta if (rc)
305e3f0cb56SRuchika Gupta return rc;
306e3f0cb56SRuchika Gupta } else {
307e3f0cb56SRuchika Gupta if (rc || !value || size != pkcs11_ref.size ||
308e3f0cb56SRuchika Gupta TEE_MemCompare(ref_attr + sizeof(pkcs11_ref), value,
309e3f0cb56SRuchika Gupta size))
310e3f0cb56SRuchika Gupta return PKCS11_CKR_TEMPLATE_INCONSISTENT;
311e3f0cb56SRuchika Gupta }
312e3f0cb56SRuchika Gupta
313e3f0cb56SRuchika Gupta ref_attr += sizeof(pkcs11_ref) + pkcs11_ref.size;
314e3f0cb56SRuchika Gupta }
315e3f0cb56SRuchika Gupta
316e3f0cb56SRuchika Gupta return PKCS11_CKR_OK;
317e3f0cb56SRuchika Gupta }
318e3f0cb56SRuchika Gupta
31963f89caaSJens Wiklander #if CFG_TEE_TA_LOG_LEVEL > 0
32063f89caaSJens Wiklander /*
32163f89caaSJens Wiklander * Debug: dump CK attribute array to output trace
32263f89caaSJens Wiklander */
32363f89caaSJens Wiklander #define ATTR_TRACE_FMT "%s attr %s / %s\t(0x%04"PRIx32" %"PRIu32"-byte"
32463f89caaSJens Wiklander #define ATTR_FMT_0BYTE ATTR_TRACE_FMT ")"
32563f89caaSJens Wiklander #define ATTR_FMT_1BYTE ATTR_TRACE_FMT ": %02x)"
32663f89caaSJens Wiklander #define ATTR_FMT_2BYTE ATTR_TRACE_FMT ": %02x %02x)"
32763f89caaSJens Wiklander #define ATTR_FMT_3BYTE ATTR_TRACE_FMT ": %02x %02x %02x)"
32863f89caaSJens Wiklander #define ATTR_FMT_4BYTE ATTR_TRACE_FMT ": %02x %02x %02x %02x)"
32963f89caaSJens Wiklander #define ATTR_FMT_ARRAY ATTR_TRACE_FMT ": %02x %02x %02x %02x ...)"
33063f89caaSJens Wiklander
__trace_attributes(char * prefix,void * src,void * end)33163f89caaSJens Wiklander static void __trace_attributes(char *prefix, void *src, void *end)
33263f89caaSJens Wiklander {
33363f89caaSJens Wiklander size_t next_off = 0;
33463f89caaSJens Wiklander char *prefix2 = NULL;
33563f89caaSJens Wiklander size_t prefix_len = strlen(prefix);
33663f89caaSJens Wiklander char *cur = src;
33763f89caaSJens Wiklander
33863f89caaSJens Wiklander /* append 4 spaces to the prefix plus terminal '\0' */
33963f89caaSJens Wiklander prefix2 = TEE_Malloc(prefix_len + 1 + 4, TEE_MALLOC_FILL_ZERO);
34063f89caaSJens Wiklander if (!prefix2)
34163f89caaSJens Wiklander return;
34263f89caaSJens Wiklander
34363f89caaSJens Wiklander TEE_MemMove(prefix2, prefix, prefix_len + 1);
34463f89caaSJens Wiklander TEE_MemFill(prefix2 + prefix_len, ' ', 4);
34563f89caaSJens Wiklander *(prefix2 + prefix_len + 4) = '\0';
34663f89caaSJens Wiklander
34763f89caaSJens Wiklander for (; cur < (char *)end; cur += next_off) {
34863f89caaSJens Wiklander struct pkcs11_attribute_head pkcs11_ref = { };
34963f89caaSJens Wiklander uint8_t data[4] = { 0 };
35063f89caaSJens Wiklander
35163f89caaSJens Wiklander TEE_MemMove(&pkcs11_ref, cur, sizeof(pkcs11_ref));
35263f89caaSJens Wiklander TEE_MemMove(&data[0], cur + sizeof(pkcs11_ref),
35363f89caaSJens Wiklander MIN(pkcs11_ref.size, sizeof(data)));
35463f89caaSJens Wiklander
35563f89caaSJens Wiklander next_off = sizeof(pkcs11_ref) + pkcs11_ref.size;
35663f89caaSJens Wiklander
35763f89caaSJens Wiklander switch (pkcs11_ref.size) {
35863f89caaSJens Wiklander case 0:
35963f89caaSJens Wiklander IMSG_RAW(ATTR_FMT_0BYTE,
36063f89caaSJens Wiklander prefix, id2str_attr(pkcs11_ref.id), "*",
36163f89caaSJens Wiklander pkcs11_ref.id, pkcs11_ref.size);
36263f89caaSJens Wiklander break;
36363f89caaSJens Wiklander case 1:
36463f89caaSJens Wiklander IMSG_RAW(ATTR_FMT_1BYTE,
36563f89caaSJens Wiklander prefix, id2str_attr(pkcs11_ref.id),
36663f89caaSJens Wiklander id2str_attr_value(pkcs11_ref.id,
36763f89caaSJens Wiklander pkcs11_ref.size,
36863f89caaSJens Wiklander cur + sizeof(pkcs11_ref)),
36963f89caaSJens Wiklander pkcs11_ref.id, pkcs11_ref.size, data[0]);
37063f89caaSJens Wiklander break;
37163f89caaSJens Wiklander case 2:
37263f89caaSJens Wiklander IMSG_RAW(ATTR_FMT_2BYTE,
37363f89caaSJens Wiklander prefix, id2str_attr(pkcs11_ref.id),
37463f89caaSJens Wiklander id2str_attr_value(pkcs11_ref.id,
37563f89caaSJens Wiklander pkcs11_ref.size,
37663f89caaSJens Wiklander cur + sizeof(pkcs11_ref)),
37763f89caaSJens Wiklander pkcs11_ref.id, pkcs11_ref.size, data[0],
37863f89caaSJens Wiklander data[1]);
37963f89caaSJens Wiklander break;
38063f89caaSJens Wiklander case 3:
38163f89caaSJens Wiklander IMSG_RAW(ATTR_FMT_3BYTE,
38263f89caaSJens Wiklander prefix, id2str_attr(pkcs11_ref.id),
38363f89caaSJens Wiklander id2str_attr_value(pkcs11_ref.id,
38463f89caaSJens Wiklander pkcs11_ref.size,
38563f89caaSJens Wiklander cur + sizeof(pkcs11_ref)),
38663f89caaSJens Wiklander pkcs11_ref.id, pkcs11_ref.size,
38763f89caaSJens Wiklander data[0], data[1], data[2]);
38863f89caaSJens Wiklander break;
38963f89caaSJens Wiklander case 4:
39063f89caaSJens Wiklander IMSG_RAW(ATTR_FMT_4BYTE,
39163f89caaSJens Wiklander prefix, id2str_attr(pkcs11_ref.id),
39263f89caaSJens Wiklander id2str_attr_value(pkcs11_ref.id,
39363f89caaSJens Wiklander pkcs11_ref.size,
39463f89caaSJens Wiklander cur + sizeof(pkcs11_ref)),
39563f89caaSJens Wiklander pkcs11_ref.id, pkcs11_ref.size,
39663f89caaSJens Wiklander data[0], data[1], data[2], data[3]);
39763f89caaSJens Wiklander break;
39863f89caaSJens Wiklander default:
39963f89caaSJens Wiklander IMSG_RAW(ATTR_FMT_ARRAY,
40063f89caaSJens Wiklander prefix, id2str_attr(pkcs11_ref.id),
40163f89caaSJens Wiklander id2str_attr_value(pkcs11_ref.id,
40263f89caaSJens Wiklander pkcs11_ref.size,
40363f89caaSJens Wiklander cur + sizeof(pkcs11_ref)),
40463f89caaSJens Wiklander pkcs11_ref.id, pkcs11_ref.size,
40563f89caaSJens Wiklander data[0], data[1], data[2], data[3]);
40663f89caaSJens Wiklander break;
40763f89caaSJens Wiklander }
40863f89caaSJens Wiklander
40963f89caaSJens Wiklander switch (pkcs11_ref.id) {
41063f89caaSJens Wiklander case PKCS11_CKA_WRAP_TEMPLATE:
41163f89caaSJens Wiklander case PKCS11_CKA_UNWRAP_TEMPLATE:
41263f89caaSJens Wiklander case PKCS11_CKA_DERIVE_TEMPLATE:
413ef5f7584SEtienne Carriere if (pkcs11_ref.size)
414ef5f7584SEtienne Carriere trace_attributes(prefix2,
415ef5f7584SEtienne Carriere cur + sizeof(pkcs11_ref));
41663f89caaSJens Wiklander break;
41763f89caaSJens Wiklander default:
41863f89caaSJens Wiklander break;
41963f89caaSJens Wiklander }
42063f89caaSJens Wiklander }
42163f89caaSJens Wiklander
42263f89caaSJens Wiklander /* Sanity */
42363f89caaSJens Wiklander if (cur != end)
42463f89caaSJens Wiklander EMSG("Warning: unexpected alignment in object attributes");
42563f89caaSJens Wiklander
42663f89caaSJens Wiklander TEE_Free(prefix2);
42763f89caaSJens Wiklander }
42863f89caaSJens Wiklander
trace_attributes(const char * prefix,void * ref)42963f89caaSJens Wiklander void trace_attributes(const char *prefix, void *ref)
43063f89caaSJens Wiklander {
431ef5f7584SEtienne Carriere struct obj_attrs head = { };
43263f89caaSJens Wiklander char *pre = NULL;
43363f89caaSJens Wiklander
43463f89caaSJens Wiklander TEE_MemMove(&head, ref, sizeof(head));
43563f89caaSJens Wiklander
436ef5f7584SEtienne Carriere if (!head.attrs_count)
437ef5f7584SEtienne Carriere return;
438ef5f7584SEtienne Carriere
43963f89caaSJens Wiklander pre = TEE_Malloc(prefix ? strlen(prefix) + 2 : 2, TEE_MALLOC_FILL_ZERO);
44063f89caaSJens Wiklander if (!pre) {
44163f89caaSJens Wiklander EMSG("%s: out of memory", prefix);
44263f89caaSJens Wiklander return;
44363f89caaSJens Wiklander }
44463f89caaSJens Wiklander
44563f89caaSJens Wiklander if (prefix)
44663f89caaSJens Wiklander TEE_MemMove(pre, prefix, strlen(prefix));
44763f89caaSJens Wiklander
44863f89caaSJens Wiklander IMSG_RAW("%s,--- (serial object) Attributes list --------", pre);
44963f89caaSJens Wiklander IMSG_RAW("%s| %"PRIu32" item(s) - %"PRIu32" bytes",
45063f89caaSJens Wiklander pre, head.attrs_count, head.attrs_size);
45163f89caaSJens Wiklander
45263f89caaSJens Wiklander pre[prefix ? strlen(prefix) : 0] = '|';
45363f89caaSJens Wiklander __trace_attributes(pre, (char *)ref + sizeof(head),
45463f89caaSJens Wiklander (char *)ref + sizeof(head) + head.attrs_size);
45563f89caaSJens Wiklander
45663f89caaSJens Wiklander IMSG_RAW("%s`-----------------------", prefix ? prefix : "");
45763f89caaSJens Wiklander
45863f89caaSJens Wiklander TEE_Free(pre);
45963f89caaSJens Wiklander }
46063f89caaSJens Wiklander #endif /*CFG_TEE_TA_LOG_LEVEL*/
461