blob: 12e3ee4c9499f5927e2f1b9d69d9da613cc7d4b8 [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright Laurence Lundblade.
4 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
5 */
6
7/*
8 * This file is derived from:
9 * trusted-firmware-m/secure_fw/partitions/initial_attestation/attest_token.h
10 */
11
12#ifndef ATTESTATION_TOKEN_H
13#define ATTESTATION_TOKEN_H
14
15#include <measurement.h>
Mate Toth-Palc08e0112023-06-27 13:08:31 +020016#ifndef CBMC
Soby Mathewb4c6df42022-11-09 11:13:29 +000017#include <qcbor/qcbor.h>
Mate Toth-Palc08e0112023-06-27 13:08:31 +020018#endif /* CBMC */
19#include <stddef.h>
20#include <stdint.h>
21#ifndef CBMC
Soby Mathewb4c6df42022-11-09 11:13:29 +000022#include <t_cose/q_useful_buf.h>
Mate Toth-Palfda673a2023-06-13 12:25:43 +020023#include <t_cose/t_cose_sign_sign.h>
24#include <t_cose/t_cose_signature_sign_restart.h>
Soby Mathew9ca57552024-10-03 12:21:36 +010025#include <t_cose_el3_token_sign.h>
Mate Toth-Palc69951d2023-03-17 17:30:50 +010026#include <t_cose_psa_crypto.h>
Mate Toth-Palc08e0112023-06-27 13:08:31 +020027#endif /* CBMC */
28
Soby Mathewf3622132024-07-19 07:31:40 +010029/* The state of the CCA token generation */
Mate Toth-Palc08e0112023-06-27 13:08:31 +020030enum attest_token_gen_state_t {
Soby Mathewf3622132024-07-19 07:31:40 +010031 ATTEST_TOKEN_NOT_STARTED, /* Initial phase */
32 ATTEST_TOKEN_INIT, /* Initialized */
33 ATTEST_TOKEN_SIGN, /* Realm token sign */
34 ATTEST_TOKEN_CREATE, /* CCA Token create */
Mate Toth-Palc08e0112023-06-27 13:08:31 +020035};
36
37#ifndef CBMC
Soby Mathewb4c6df42022-11-09 11:13:29 +000038
39#define ATTEST_TOKEN_BUFFER_SIZE GRANULE_SIZE
40
41enum attest_token_err_t {
42 /* Success */
43 ATTEST_TOKEN_ERR_SUCCESS = 0,
Soby Mathewf3622132024-07-19 07:31:40 +010044 /* The Attest token context state is incorrect */
45 ATTEST_TOKEN_ERR_INVALID_STATE,
Soby Mathewb4c6df42022-11-09 11:13:29 +000046 /* The buffer passed in to receive the output is too small. */
47 ATTEST_TOKEN_ERR_TOO_SMALL,
48 /*
49 * Something went wrong formatting the CBOR, most likely the
50 * payload has maps or arrays that are not closed.
51 */
52 ATTEST_TOKEN_ERR_CBOR_FORMATTING,
53 /* Signing key is not found or of wrong type. */
54 ATTEST_TOKEN_ERR_SIGNING_KEY,
55 ATTEST_TOKEN_ERR_COSE_ERROR,
Mate Toth-Palc08e0112023-06-27 13:08:31 +020056 /*
57 * Signing is in progress, function should be called with the same
Soby Mathewb4c6df42022-11-09 11:13:29 +000058 * parameters again.
59 */
Juan Pablo Conde79ca2562024-08-12 17:05:41 -050060 ATTEST_TOKEN_ERR_COSE_SIGN_IN_PROGRESS,
61 /*
62 * Error code to return when CCA token creation fails.
63 */
64 ATTEST_TOKEN_ERR_CCA_TOKEN_CREATE
Soby Mathewb4c6df42022-11-09 11:13:29 +000065};
66
Soby Mathewb4c6df42022-11-09 11:13:29 +000067/*
68 * The context for creating an attestation token. The caller of
69 * attest_token_encode must create one of these and pass it to the functions
70 * here. It is small enough that it can go on the stack. It is most of
71 * the memory needed to create a token except the output buffer and
72 * any memory requirements for the cryptographic operations.
73 *
74 * The structure is opaque for the caller.
75 *
76 * This is roughly 148 + 8 + 32 = 188 bytes
77 */
78
79struct attest_token_encode_ctx {
80 /* Private data structure */
Mate Toth-Palc69951d2023-03-17 17:30:50 +010081 QCBOREncodeContext cbor_enc_ctx;
82 uint32_t opt_flags;
83 int32_t key_select;
Mate Toth-Palfda673a2023-06-13 12:25:43 +020084 struct q_useful_buf_c signed_payload;
85 struct t_cose_sign_sign_ctx sign_ctx;
86 struct t_cose_signature_sign_restart restartable_signer_ctx;
Soby Mathew9ca57552024-10-03 12:21:36 +010087#if ATTEST_EL3_TOKEN_SIGN
88 struct t_cose_el3_token_sign_ctx crypto_ctx;
89#else
Mate Toth-Palc69951d2023-03-17 17:30:50 +010090 struct t_cose_psa_crypto_context crypto_ctx;
Soby Mathew9ca57552024-10-03 12:21:36 +010091#endif
Soby Mathewb4c6df42022-11-09 11:13:29 +000092};
93
94#define ATTEST_CHALLENGE_SIZE (64)
95
96/*
97 * The context for signing an attestation token. Each REC contains one context
98 * that is passed to the attestation library during attestation token creation
99 * to keep track of the signing state.
100 */
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100101struct token_sign_cntxt {
Soby Mathewb4c6df42022-11-09 11:13:29 +0000102 /*
103 * 'state' is used to implement a state machine
104 * to track the current state of signing.
105 */
106 enum attest_token_gen_state_t state;
107 struct attest_token_encode_ctx ctx;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000108};
109
Mate Toth-Palc08e0112023-06-27 13:08:31 +0200110#else /* CBMC */
111
112#define ATTEST_TOKEN_BUFFER_SIZE GRANULE_SIZE
113
114enum attest_token_err_t {
115 /* Success */
116 ATTEST_TOKEN_ERR_SUCCESS = 0,
117 /*
118 * Signing is in progress, function should be called with the same
119 * parameters again.
120 */
121 ATTEST_TOKEN_ERR_COSE_SIGN_IN_PROGRESS
122};
123
124struct attest_token_encode_ctx {
125 uint32_t unused;
126};
127
128struct token_sign_cntxt {
129 enum attest_token_gen_state_t state;
130};
131
132#define ATTEST_CHALLENGE_SIZE (1)
133
134#endif /* CBMC */
135
Soby Mathewb4c6df42022-11-09 11:13:29 +0000136/*
137 * Sign the realm token and complete the CBOR encoding.
138 * This function returns ATTEST_TOKEN_ERR_COSE_SIGN_IN_PROGRESS
139 * if signing is not complete and this function needs to be
140 * invoked again. ATTEST_TOKEN_ERR_SUCCESS is returned if
141 * signing is complete and `completed_token` is valid.
142 * Else returns one of the attest_token_err_t errors on
143 * any other error.
144 *
Soby Mathewf3622132024-07-19 07:31:40 +0100145 * me Token Sign Context.
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200146 * completed_token_len Length of the completed token.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000147 *
148 * This completes the token after the payload has been added. When
149 * this is called the signing algorithm is run and the final
150 * formatting of the token is completed.
151 */
152enum attest_token_err_t
Soby Mathewf3622132024-07-19 07:31:40 +0100153attest_realm_token_sign(struct token_sign_cntxt *me,
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200154 size_t *completed_token_len);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000155
156/*
157 * Combine realm token and platform token to top-level cca token
158 *
Soby Mathewf3622132024-07-19 07:31:40 +0100159 * me Token Sign Context.
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200160 * attest_token_buf Pointer to the buffer where the token will be
AlexeiFedorov47165422023-09-13 11:47:57 +0100161 * written.
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200162 * attest_token_buf_size Size of the buffer where the token will be
AlexeiFedorov47165422023-09-13 11:47:57 +0100163 * written.
Juan Pablo Conde79ca2562024-08-12 17:05:41 -0500164 * realm_token_buf Pointer to the realm token.
165 * realm_token_len Length of the realm token.
166 * cca_token_len Returns the length of top-level CCA token
Soby Mathewb4c6df42022-11-09 11:13:29 +0000167 *
Juan Pablo Conde79ca2562024-08-12 17:05:41 -0500168 * Returns ATTEST_TOKEN_ERR_SUCCESS (0) if CCA top-level token is
169 * created. Otherwise, returns the proper error value.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000170 */
Juan Pablo Conde79ca2562024-08-12 17:05:41 -0500171enum attest_token_err_t
172attest_cca_token_create(struct token_sign_cntxt *me,
Soby Mathewf3622132024-07-19 07:31:40 +0100173 void *attest_token_buf,
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200174 size_t attest_token_buf_size,
175 const void *realm_token_buf,
Juan Pablo Conde79ca2562024-08-12 17:05:41 -0500176 size_t realm_token_len,
177 size_t *cca_token_len);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000178
179/*
180 * Assemble the Realm token in the buffer provided in realm_token_buf,
181 * except the signature.
182 *
183 * Arguments:
184 * Algorithm - Algorithm used during measurement.
185 * Measurement - Array of buffers containing all the measurements.
186 * num_measurements - Number of measurements to add to the token.
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200187 * rpv_buf - Pointer to the Realm Personalization value
188 * rpv_len - Length of the Realm Personalization value
Soby Mathewb4c6df42022-11-09 11:13:29 +0000189 * ctx - Token sign context, used for signing.
190 * realm_token_buf - Buffer where to assemble the attestation token.
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200191 * realm_token_buf_size - size of the buffer where to assemble the attestation
192 * token.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000193 *
194 * Returns ATTEST_TOKEN_ERR_SUCCESS (0) on success or a negative error code
195 * otherwise.
196 */
197int attest_realm_token_create(enum hash_algo algorithm,
198 unsigned char measurements[][MAX_MEASUREMENT_SIZE],
199 unsigned int num_measurements,
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200200 const void *rpv_buf,
201 size_t rpv_len,
Mate Toth-Pal4feff402024-08-30 10:53:32 +0200202 const void *challenge_buf,
203 size_t challenge_len,
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100204 struct token_sign_cntxt *ctx,
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200205 void *realm_token_buf,
206 size_t realm_token_buf_size);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000207
Soby Mathewf3622132024-07-19 07:31:40 +0100208/*
209 * Initialize the token sign context and also the heap buffer used for the crypto.
210 * It is assumed that the heap alloc context has already been assigned to this
211 * CPU. If the token sign context has already been initialized, this API will
212 * not initialize again as an optimization.
213 *
214 * Arguments:
215 * token_ctx - Token sign context.
216 * heap_buf - Buffer to use as heap.
217 * heap_buf_len - Size of the buffer to use as heap.
Soby Mathew9ca57552024-10-03 12:21:36 +0100218 * cookie - Unique cookie to associate with the context (ex rec granule PA)
Soby Mathewf3622132024-07-19 07:31:40 +0100219 *
Soby Mathew376ffa42024-10-04 14:01:59 +0100220 * Return code:
221 * ATTEST_TOKEN_ERR_SUCCESS (0) - Success.
222 * ATTEST_TOKEN_ERR_INVALID_STATE - Failed possibly due to invalid state.
Soby Mathewf3622132024-07-19 07:31:40 +0100223 */
224int attest_token_ctx_init(struct token_sign_cntxt *token_ctx,
225 unsigned char *heap_buf,
Soby Mathew9ca57552024-10-03 12:21:36 +0100226 unsigned int heap_buf_len,
227 uintptr_t cookie);
228
229/*
230 * Pull the response from EL3 into the per cpu response buffer. The function
231 * returns the cookie associated with the response. The response could correspond
232 * to current REC or another REC which had requested the EL3 service.
233 *
234 * Arguments:
235 * cookie - Pointer to storage of cookie to return the value from
236 * response.
237 *
238 * Return code:
239 * 0 - Success
240 * -EAGAIN - Response not ready. Call this API again.
241 * -ENOTSUP - Other error including EL3_TOKEN_SIGN not supported in
242 * EL3 firmware.
243 */
244int attest_el3_token_sign_pull_response_from_el3(uintptr_t *cookie);
245
246/*
247 * Write the response from EL3 to the context. The response is written only if the context
248 * is valid and the response is for the right request. If the function returns an error
249 * the caller must treat it as a fatal error. The cookie is checked against the per cpu
250 * response buffer to ensure that the response is for the right request.
251 * The caller must ensure that the REC granule lock is held so that it cannot be deleted
252 * while the response is being written.
253 *
254 * Arguments:
255 * ctx - Pointer to token_sign_cntxt
256 * cookie - Pointer to storage of cookie to return the value from
257 * response.
258 *
259 * Returns 0 on success or a negative error code otherwise.
260 */
261int attest_el3_token_write_response_to_ctx(struct token_sign_cntxt *sign_ctx, uintptr_t cookie);
Soby Mathewf3622132024-07-19 07:31:40 +0100262
Soby Mathewb4c6df42022-11-09 11:13:29 +0000263#endif /* ATTESTATION_TOKEN_H */