aboutsummaryrefslogtreecommitdiff
path: root/components/service/attestation/reporter/psa/psa_attest_report.c
blob: 3228f1ca29a014c07945b0cf0f2b7a41ad8bf0c4 (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

/**
 * An attestation reporter that creates PSA compliant attestation
 * reports.  The report content is specified by the PSA Attestation
 * specification.  Reports are serialized using CBOR and signed using
 * COSE.
 */

#include <stdlib.h>
#include <psa/error.h>
#include <service/attestation/reporter/attest_report.h>
#include <service/attestation/claims/claims_register.h>
#include "eat_serializer.h"
#include "eat_signer.h"

/* Local defines */
#define MAX_DEVICE_CLAIMS       (50)
#define MAX_SW_CLAIMS           (50)

static void add_auth_challenge_claim(struct claim_vector *v, const uint8_t *data, size_t len);
static void add_client_id_claim(struct claim_vector *v, int32_t client_id);
static void add_no_sw_claim(struct claim_vector *v);


int attest_report_create(psa_key_handle_t key_handle, int32_t client_id,
    const uint8_t *auth_challenge_data, size_t auth_challenge_len,
    const uint8_t **report, size_t *report_len)
{
    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
    struct claim_vector device_claims;
    struct claim_vector sw_claims;

    *report = NULL;
    *report_len = 0;

    claim_vector_init(&device_claims, MAX_DEVICE_CLAIMS);
    claim_vector_init(&sw_claims, MAX_SW_CLAIMS);

    /* Add claims related to the requester */
    add_auth_challenge_claim(&device_claims, auth_challenge_data, auth_challenge_len);
    add_client_id_claim(&device_claims, client_id);

    /* Collate all other claims to include in the report */
    claims_register_query_by_category(CLAIM_CATEGORY_DEVICE, &device_claims);
    claims_register_query_by_category(CLAIM_CATEGORY_VERIFICATION_SERVICE, &device_claims);
    claims_register_query_by_category(CLAIM_CATEGORY_BOOT_MEASUREMENT, &sw_claims);

    /* And if there aren't any sw claims, indicate in report */
    if (!sw_claims.size) add_no_sw_claim(&device_claims);

    /* Serialize and sign the collated claims to create the final EAT token */
    const uint8_t *unsigned_token = NULL;
    size_t unsigned_token_len = 0;
    status = eat_serialize(&device_claims, &sw_claims,
                    &unsigned_token, &unsigned_token_len);

    if (status == PSA_SUCCESS) {
        status = eat_sign(key_handle,
                    unsigned_token, unsigned_token_len,
                    report, report_len);
    }

    /* Free resource used */
    free((void*)unsigned_token);
    claim_vector_deinit(&device_claims);
    claim_vector_deinit(&sw_claims);

    return status;
}

void attest_report_destroy(const uint8_t *report)
{
    free((void*)report);
}

static void add_auth_challenge_claim(struct claim_vector *v, const uint8_t *data, size_t len)
{
    struct claim claim;

    claim.subject_id = CLAIM_SUBJECT_ID_AUTH_CHALLENGE;
    claim.variant_id = CLAIM_VARIANT_ID_BYTE_STRING;
    claim.raw_data = NULL;

    claim.variant.byte_string.bytes = data;
    claim.variant.byte_string.len = len;

    claim_vector_push_back(v, &claim);
}

static void add_client_id_claim(struct claim_vector *v, int32_t client_id)
{
    struct claim claim;

    claim.subject_id = CLAIM_SUBJECT_ID_CLIENT_ID;
    claim.variant_id = CLAIM_VARIANT_ID_INTEGER;
    claim.raw_data = NULL;

    claim.variant.integer.value = client_id;

    claim_vector_push_back(v, &claim);
}

static void add_no_sw_claim(struct claim_vector *v)
{
    struct claim claim;

    claim.subject_id = CLAIM_SUBJECT_ID_NO_SW_MEASUREMENTS;
    claim.variant_id = CLAIM_VARIANT_ID_INTEGER;
    claim.raw_data = NULL;

    claim.variant.integer.value = 1;

    claim_vector_push_back(v, &claim);
}