1 /*
2 * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <psa/crypto.h>
10 #include <service/attestation/claims/claim.h>
11 #include <service/attestation/key_mngr/attest_key_mngr.h>
12 #include "instance_id_claim_source.h"
13
14 static bool instance_id_claim_source_get_claim(void *context, struct claim *claim);
15 static bool prepare_instance_id(struct instance_id_claim_source *instance);
16 static bool cal_iak_hash(struct instance_id_claim_source *instance,
17 const uint8_t *key_buf, size_t key_len);
18
instance_id_claim_source_init(struct instance_id_claim_source * instance)19 struct claim_source *instance_id_claim_source_init(struct instance_id_claim_source *instance)
20 {
21 instance->base.get_claim = instance_id_claim_source_get_claim;
22 instance->base.context = instance;
23
24 instance->is_known = false;
25
26 return &instance->base;
27 }
28
instance_id_claim_source_get_claim(void * context,struct claim * claim)29 static bool instance_id_claim_source_get_claim(void *context, struct claim *claim)
30 {
31 struct instance_id_claim_source *instance = (struct instance_id_claim_source*)context;
32
33 if (!instance->is_known)
34 instance->is_known = prepare_instance_id(instance);
35
36 if (instance->is_known) {
37
38 claim->category = CLAIM_CATEGORY_DEVICE;
39 claim->subject_id = CLAIM_SUBJECT_ID_INSTANCE_ID;
40 claim->variant_id = CLAIM_VARIANT_ID_BYTE_STRING;
41 claim->raw_data = NULL;
42
43 claim->variant.byte_string.bytes = instance->instance_id;
44 claim->variant.byte_string.len = sizeof(instance->instance_id);
45 }
46
47 return instance->is_known;
48 }
49
prepare_instance_id(struct instance_id_claim_source * instance)50 static bool prepare_instance_id(struct instance_id_claim_source *instance)
51 {
52 bool success = false;
53 size_t key_buf_size = attest_key_mngr_max_iak_export_size();
54 uint8_t *key_buf = malloc(key_buf_size);
55
56 if (key_buf) {
57
58 size_t key_len;
59 int status;
60
61 status = attest_key_mngr_export_iak_public_key(key_buf, key_buf_size, &key_len);
62
63 if (status == PSA_SUCCESS) {
64
65 success = cal_iak_hash(instance, key_buf, key_len);
66
67 /* Add the UEID type */
68 instance->instance_id[0] = 0x01;
69 }
70
71 free(key_buf);
72 }
73
74 return success;
75 }
76
cal_iak_hash(struct instance_id_claim_source * instance,const uint8_t * key_buf,size_t key_len)77 static bool cal_iak_hash(struct instance_id_claim_source *instance,
78 const uint8_t *key_buf, size_t key_len)
79 {
80 int status;
81 size_t hash_len;
82
83 psa_hash_operation_t op = psa_hash_operation_init();
84
85 status = psa_hash_setup(&op, PSA_ALG_SHA_256);
86 if (status != PSA_SUCCESS) return false;
87
88 status = psa_hash_update(&op, key_buf, key_len);
89 if (status != PSA_SUCCESS) return false;
90
91 status = psa_hash_finish(&op,
92 &instance->instance_id[1],
93 INSTANCE_ID_HASH_LEN,
94 &hash_len);
95
96 return (status == PSA_SUCCESS) && (hash_len == INSTANCE_ID_HASH_LEN);
97 }
98