aboutsummaryrefslogtreecommitdiff
path: root/components/service/attestation/claims/sources/instance_id/instance_id_claim_source.c
blob: a1222eef11298e63f065d010ee7c59c18db1e327 (plain)
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);
}