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