1*900bf7c6SYuichi Sugiyama // SPDX-License-Identifier: BSD-2-Clause
2*900bf7c6SYuichi Sugiyama /*
3*900bf7c6SYuichi Sugiyama * Copyright (C) 2024, Institute of Information Security (IISEC)
4*900bf7c6SYuichi Sugiyama */
5*900bf7c6SYuichi Sugiyama
6*900bf7c6SYuichi Sugiyama #include <base64.h>
7*900bf7c6SYuichi Sugiyama #include <kernel/pseudo_ta.h>
8*900bf7c6SYuichi Sugiyama #include <mempool.h>
9*900bf7c6SYuichi Sugiyama #include <pta_veraison_attestation.h>
10*900bf7c6SYuichi Sugiyama #include <stdlib.h>
11*900bf7c6SYuichi Sugiyama #include <string.h>
12*900bf7c6SYuichi Sugiyama
13*900bf7c6SYuichi Sugiyama #include "cbor.h"
14*900bf7c6SYuichi Sugiyama #include "hash.h"
15*900bf7c6SYuichi Sugiyama
16*900bf7c6SYuichi Sugiyama #define PTA_NAME "veraison_attestation.pta"
17*900bf7c6SYuichi Sugiyama
18*900bf7c6SYuichi Sugiyama #define MAX_KEY_SIZE 4096
19*900bf7c6SYuichi Sugiyama #define MAX_NONCE_SIZE 64
20*900bf7c6SYuichi Sugiyama #define TEE_SHA256_HASH_SIZE 32
21*900bf7c6SYuichi Sugiyama
22*900bf7c6SYuichi Sugiyama #define EAT_PROFILE "http://arm.com/psa/2.0.0"
23*900bf7c6SYuichi Sugiyama #define CLIENT_ID 1
24*900bf7c6SYuichi Sugiyama #define LIFECYCLE 12288
25*900bf7c6SYuichi Sugiyama #define MEASURMENT_TYPE "PRoT"
26*900bf7c6SYuichi Sugiyama #define SIGNER_ID_LEN 32
27*900bf7c6SYuichi Sugiyama #define INSTANCE_ID_LEN 33
28*900bf7c6SYuichi Sugiyama
29*900bf7c6SYuichi Sugiyama /* clang-format off */
30*900bf7c6SYuichi Sugiyama #define SIGNER_ID { \
31*900bf7c6SYuichi Sugiyama 0xac, 0xbb, 0x11, 0xc7, 0xe4, 0xda, 0x21, 0x72, \
32*900bf7c6SYuichi Sugiyama 0x05, 0x52, 0x3c, 0xe4, 0xce, 0x1a, 0x24, 0x5a, \
33*900bf7c6SYuichi Sugiyama 0xe1, 0xa2, 0x39, 0xae, 0x3c, 0x6b, 0xfd, 0x9e, \
34*900bf7c6SYuichi Sugiyama 0x78, 0x71, 0xf7, 0xe5, 0xd8, 0xba, 0xe8, 0x6b \
35*900bf7c6SYuichi Sugiyama }
36*900bf7c6SYuichi Sugiyama #define INSTANCE_ID { \
37*900bf7c6SYuichi Sugiyama 0x01, 0xce, 0xeb, 0xae, 0x7b, 0x89, 0x27, 0xa3, \
38*900bf7c6SYuichi Sugiyama 0x22, 0x7e, 0x53, 0x03, 0xcf, 0x5e, 0x0f, 0x1f, \
39*900bf7c6SYuichi Sugiyama 0x7b, 0x34, 0xbb, 0x54, 0x2a, 0xd7, 0x25, 0x0a, \
40*900bf7c6SYuichi Sugiyama 0xc0, 0x3f, 0xbc, 0xde, 0x36, 0xec, 0x2f, 0x15, \
41*900bf7c6SYuichi Sugiyama 0x08 \
42*900bf7c6SYuichi Sugiyama }
43*900bf7c6SYuichi Sugiyama /* clang-format on */
44*900bf7c6SYuichi Sugiyama
cmd_get_cbor_evidence(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])45*900bf7c6SYuichi Sugiyama static TEE_Result cmd_get_cbor_evidence(uint32_t param_types,
46*900bf7c6SYuichi Sugiyama TEE_Param params[TEE_NUM_PARAMS])
47*900bf7c6SYuichi Sugiyama {
48*900bf7c6SYuichi Sugiyama const uint8_t *nonce = params[0].memref.buffer;
49*900bf7c6SYuichi Sugiyama const size_t nonce_sz = params[0].memref.size;
50*900bf7c6SYuichi Sugiyama uint8_t *output_buffer = params[1].memref.buffer;
51*900bf7c6SYuichi Sugiyama size_t *output_buffer_len = ¶ms[1].memref.size;
52*900bf7c6SYuichi Sugiyama const uint8_t *psa_implementation_id = params[2].memref.buffer;
53*900bf7c6SYuichi Sugiyama const size_t psa_implementation_id_len = params[2].memref.size;
54*900bf7c6SYuichi Sugiyama TEE_Result status = TEE_SUCCESS;
55*900bf7c6SYuichi Sugiyama
56*900bf7c6SYuichi Sugiyama const char eat_profile[] = EAT_PROFILE;
57*900bf7c6SYuichi Sugiyama const int psa_client_id = CLIENT_ID;
58*900bf7c6SYuichi Sugiyama const int psa_security_lifecycle = LIFECYCLE;
59*900bf7c6SYuichi Sugiyama const char measurement_type[] = MEASURMENT_TYPE;
60*900bf7c6SYuichi Sugiyama const uint8_t signer_id[SIGNER_ID_LEN] = SIGNER_ID;
61*900bf7c6SYuichi Sugiyama const uint8_t psa_instance_id[INSTANCE_ID_LEN] = INSTANCE_ID;
62*900bf7c6SYuichi Sugiyama
63*900bf7c6SYuichi Sugiyama uint8_t measurement_value[TEE_SHA256_HASH_SIZE] = { 0 };
64*900bf7c6SYuichi Sugiyama size_t b64_measurement_value_len = TEE_SHA256_HASH_SIZE * 2;
65*900bf7c6SYuichi Sugiyama char b64_measurement_value[TEE_SHA256_HASH_SIZE * 2] = { 0 };
66*900bf7c6SYuichi Sugiyama
67*900bf7c6SYuichi Sugiyama UsefulBufC ubc_cbor_evidence = { NULL, 0 };
68*900bf7c6SYuichi Sugiyama UsefulBufC ubc_cose_evidence = { NULL, 0 };
69*900bf7c6SYuichi Sugiyama
70*900bf7c6SYuichi Sugiyama if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
71*900bf7c6SYuichi Sugiyama TEE_PARAM_TYPE_MEMREF_OUTPUT,
72*900bf7c6SYuichi Sugiyama TEE_PARAM_TYPE_MEMREF_INPUT,
73*900bf7c6SYuichi Sugiyama TEE_PARAM_TYPE_NONE))
74*900bf7c6SYuichi Sugiyama return TEE_ERROR_BAD_PARAMETERS;
75*900bf7c6SYuichi Sugiyama
76*900bf7c6SYuichi Sugiyama if (!nonce || !nonce_sz)
77*900bf7c6SYuichi Sugiyama return TEE_ERROR_BAD_PARAMETERS;
78*900bf7c6SYuichi Sugiyama
79*900bf7c6SYuichi Sugiyama if (!output_buffer && *output_buffer_len)
80*900bf7c6SYuichi Sugiyama return TEE_ERROR_BAD_PARAMETERS;
81*900bf7c6SYuichi Sugiyama
82*900bf7c6SYuichi Sugiyama /* Calculate measurement hash of memory */
83*900bf7c6SYuichi Sugiyama status = get_hash_ta_memory(measurement_value);
84*900bf7c6SYuichi Sugiyama if (status != TEE_SUCCESS)
85*900bf7c6SYuichi Sugiyama return status;
86*900bf7c6SYuichi Sugiyama
87*900bf7c6SYuichi Sugiyama /* Encode measurement_value to base64 */
88*900bf7c6SYuichi Sugiyama if (!base64_enc(measurement_value, TEE_SHA256_HASH_SIZE,
89*900bf7c6SYuichi Sugiyama b64_measurement_value,
90*900bf7c6SYuichi Sugiyama &b64_measurement_value_len)) {
91*900bf7c6SYuichi Sugiyama DMSG("Failed to encode measurement_value to base64");
92*900bf7c6SYuichi Sugiyama return TEE_ERROR_GENERIC;
93*900bf7c6SYuichi Sugiyama }
94*900bf7c6SYuichi Sugiyama DMSG("b64_measurement_value: %s", b64_measurement_value);
95*900bf7c6SYuichi Sugiyama
96*900bf7c6SYuichi Sugiyama /* Encode evidence to CBOR */
97*900bf7c6SYuichi Sugiyama ubc_cbor_evidence = generate_cbor_evidence(eat_profile,
98*900bf7c6SYuichi Sugiyama psa_client_id,
99*900bf7c6SYuichi Sugiyama psa_security_lifecycle,
100*900bf7c6SYuichi Sugiyama psa_implementation_id,
101*900bf7c6SYuichi Sugiyama psa_implementation_id_len,
102*900bf7c6SYuichi Sugiyama measurement_type,
103*900bf7c6SYuichi Sugiyama signer_id,
104*900bf7c6SYuichi Sugiyama SIGNER_ID_LEN,
105*900bf7c6SYuichi Sugiyama psa_instance_id,
106*900bf7c6SYuichi Sugiyama INSTANCE_ID_LEN,
107*900bf7c6SYuichi Sugiyama nonce,
108*900bf7c6SYuichi Sugiyama nonce_sz,
109*900bf7c6SYuichi Sugiyama measurement_value,
110*900bf7c6SYuichi Sugiyama TEE_SHA256_HASH_SIZE);
111*900bf7c6SYuichi Sugiyama if (UsefulBuf_IsNULLC(ubc_cbor_evidence)) {
112*900bf7c6SYuichi Sugiyama DMSG("Failed to encode evidence to CBOR");
113*900bf7c6SYuichi Sugiyama return TEE_ERROR_GENERIC;
114*900bf7c6SYuichi Sugiyama }
115*900bf7c6SYuichi Sugiyama
116*900bf7c6SYuichi Sugiyama /* Sign the CBOR and generate a COSE evidence */
117*900bf7c6SYuichi Sugiyama ubc_cose_evidence = generate_cose_evidence(ubc_cbor_evidence);
118*900bf7c6SYuichi Sugiyama if (UsefulBuf_IsNULLC(ubc_cose_evidence)) {
119*900bf7c6SYuichi Sugiyama DMSG("Failed to encode CBOR to COSE");
120*900bf7c6SYuichi Sugiyama status = TEE_ERROR_GENERIC;
121*900bf7c6SYuichi Sugiyama goto free_ubc_cbor_evidence;
122*900bf7c6SYuichi Sugiyama }
123*900bf7c6SYuichi Sugiyama
124*900bf7c6SYuichi Sugiyama /* Copy COSE evidence for return buffer */
125*900bf7c6SYuichi Sugiyama if (ubc_cose_evidence.len > *output_buffer_len) {
126*900bf7c6SYuichi Sugiyama *output_buffer_len = ubc_cose_evidence.len;
127*900bf7c6SYuichi Sugiyama status = TEE_ERROR_SHORT_BUFFER;
128*900bf7c6SYuichi Sugiyama goto free_ubc_cose_evidence;
129*900bf7c6SYuichi Sugiyama }
130*900bf7c6SYuichi Sugiyama memcpy(output_buffer, ubc_cose_evidence.ptr, ubc_cose_evidence.len);
131*900bf7c6SYuichi Sugiyama *output_buffer_len = ubc_cose_evidence.len;
132*900bf7c6SYuichi Sugiyama
133*900bf7c6SYuichi Sugiyama /* Free mempool allocation before returning to the caller */
134*900bf7c6SYuichi Sugiyama free_ubc_cose_evidence:
135*900bf7c6SYuichi Sugiyama mempool_free(mempool_default, (void *)ubc_cose_evidence.ptr);
136*900bf7c6SYuichi Sugiyama free_ubc_cbor_evidence:
137*900bf7c6SYuichi Sugiyama mempool_free(mempool_default, (void *)ubc_cbor_evidence.ptr);
138*900bf7c6SYuichi Sugiyama
139*900bf7c6SYuichi Sugiyama return status;
140*900bf7c6SYuichi Sugiyama }
141*900bf7c6SYuichi Sugiyama
invoke_command(void * sess_ctx __unused,uint32_t cmd_id,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])142*900bf7c6SYuichi Sugiyama static TEE_Result invoke_command(void *sess_ctx __unused, uint32_t cmd_id,
143*900bf7c6SYuichi Sugiyama uint32_t param_types,
144*900bf7c6SYuichi Sugiyama TEE_Param params[TEE_NUM_PARAMS])
145*900bf7c6SYuichi Sugiyama {
146*900bf7c6SYuichi Sugiyama switch (cmd_id) {
147*900bf7c6SYuichi Sugiyama case PTA_VERAISON_ATTESTATION_GET_CBOR_EVIDENCE:
148*900bf7c6SYuichi Sugiyama return cmd_get_cbor_evidence(param_types, params);
149*900bf7c6SYuichi Sugiyama default:
150*900bf7c6SYuichi Sugiyama break;
151*900bf7c6SYuichi Sugiyama }
152*900bf7c6SYuichi Sugiyama return TEE_ERROR_NOT_IMPLEMENTED;
153*900bf7c6SYuichi Sugiyama }
154*900bf7c6SYuichi Sugiyama
155*900bf7c6SYuichi Sugiyama pseudo_ta_register(.uuid = PTA_VERAISON_ATTESTATION_UUID, .name = PTA_NAME,
156*900bf7c6SYuichi Sugiyama .flags = PTA_DEFAULT_FLAGS,
157*900bf7c6SYuichi Sugiyama .invoke_command_entry_point = invoke_command);
158