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