1 /*
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>
16 #include <qcbor/qcbor.h>
17 #include <t_cose/q_useful_buf.h>
18 #include <t_cose/t_cose_sign1_sign.h>
19 
20 #define ATTEST_TOKEN_BUFFER_SIZE		GRANULE_SIZE
21 
22 enum attest_token_err_t {
23 	/* Success */
24 	ATTEST_TOKEN_ERR_SUCCESS = 0,
25 	/* The buffer passed in to receive the output is too small. */
26 	ATTEST_TOKEN_ERR_TOO_SMALL,
27 	/*
28 	 * Something went wrong formatting the CBOR, most likely the
29 	 * payload has maps or arrays that are not closed.
30 	 */
31 	ATTEST_TOKEN_ERR_CBOR_FORMATTING,
32 	/* Signing key is not found or of wrong type. */
33 	ATTEST_TOKEN_ERR_SIGNING_KEY,
34 	ATTEST_TOKEN_ERR_COSE_ERROR,
35 	/* Signing is in progress, function should be called with the same
36 	 * parameters again.
37 	 */
38 	ATTEST_TOKEN_ERR_COSE_SIGN_IN_PROGRESS
39 };
40 
41 /* The state of the realm token generation */
42 enum attest_token_gen_state_t {
43 	ATTEST_SIGN_NOT_STARTED,
44 	ATTEST_SIGN_IN_PROGRESS,
45 	ATTEST_SIGN_TOKEN_WRITE_IN_PROGRESS,
46 };
47 
48 /*
49  * The context for creating an attestation token. The caller of
50  * attest_token_encode must create one of these and pass it to the functions
51  * here. It is small enough that it can go on the stack. It is most of
52  * the memory needed to create a token except the output buffer and
53  * any memory requirements for the cryptographic operations.
54  *
55  * The structure is opaque for the caller.
56  *
57  * This is roughly 148 + 8 + 32 = 188 bytes
58  */
59 
60 struct attest_token_encode_ctx {
61 	/* Private data structure */
62 	QCBOREncodeContext                   cbor_enc_ctx;
63 	uint32_t                             opt_flags;
64 	int32_t                              key_select;
65 	struct t_cose_sign1_sign_ctx         signer_ctx;
66 	struct t_cose_sign1_sign_restart_ctx signer_restart_ctx;
67 	struct t_cose_crypto_backend_ctx     crypto_ctx;
68 };
69 
70 #define ATTEST_CHALLENGE_SIZE			(64)
71 
72 /*
73  * The context for signing an attestation token. Each REC contains one context
74  * that is passed to the attestation library during attestation token creation
75  * to keep track of the signing state.
76  */
77 struct token_sign_ctx {
78 	/*
79 	 * 'state' is used to implement a state machine
80 	 * to track the current state of signing.
81 	 */
82 	enum attest_token_gen_state_t state;
83 	struct attest_token_encode_ctx ctx;
84 	/* Data saved in the first iteration */
85 	unsigned long token_ipa;
86 	unsigned char challenge[ATTEST_CHALLENGE_SIZE];
87 };
88 
89 /*
90  * Sign the realm token and complete the CBOR encoding.
91  * This function returns ATTEST_TOKEN_ERR_COSE_SIGN_IN_PROGRESS
92  * if signing is not complete and this function needs to be
93  * invoked again. ATTEST_TOKEN_ERR_SUCCESS is returned if
94  * signing is complete and `completed_token` is valid.
95  * Else returns one of the attest_token_err_t errors on
96  * any other error.
97  *
98  * me					Token Creation Context.
99  * completed_token		Pointer and length to completed token.
100  *
101  * This completes the token after the payload has been added. When
102  * this is called the signing algorithm is run and the final
103  * formatting of the token is completed.
104  */
105 enum attest_token_err_t
106 attest_realm_token_sign(struct attest_token_encode_ctx *me,
107 			struct q_useful_buf_c *completed_token);
108 
109 /*
110  * Combine realm token and platform token to top-level cca token
111  *
112  * attest_token_buf  Pointer and length to the buffer where the token will be
113  *                   written.
114  * realm_token       Pointer and length to the realm token.
115  *
116  * Return 0 in case of error, the length of the cca token otherwise.
117  */
118 size_t attest_cca_token_create(struct q_useful_buf         *attest_token_buf,
119 			       const struct q_useful_buf_c *realm_token);
120 
121 /*
122  * Assemble the Realm token in the buffer provided in realm_token_buf,
123  * except the signature.
124  *
125  * Arguments:
126  * Algorithm		- Algorithm used during measurement.
127  * Measurement		- Array of buffers containing all the measurements.
128  * num_measurements	- Number of measurements to add to the token.
129  * rpv                  - Realm Personalization value
130  * ctx			- Token sign context, used for signing.
131  * realm_token_buf	- Buffer where to assemble the attestation token.
132  *
133  * Returns ATTEST_TOKEN_ERR_SUCCESS (0) on success or a negative error code
134  * otherwise.
135  */
136 int attest_realm_token_create(enum hash_algo algorithm,
137 			     unsigned char measurements[][MAX_MEASUREMENT_SIZE],
138 			     unsigned int num_measurements,
139 			     struct q_useful_buf_c *rpv,
140 			     struct token_sign_ctx *ctx,
141 			     struct q_useful_buf *realm_token_buf);
142 
143 
144 #endif /* ATTESTATION_TOKEN_H */
145