blob: 33c935408cd142d152975221be84c5d326f63811 [file] [log] [blame]
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -08001/*
2 * attest_token.h
3 *
Laurence Lundbladedada1232019-03-01 09:13:14 -08004 * Copyright (c) 2018-2019, Laurence Lundblade.
Tamas Ban95e56472020-01-10 13:46:47 +00005 * Copyright (c) 2020, Arm Limited.
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -08006 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 * See BSD-3-Clause license in README.md
10 */
11
12#ifndef __ATTEST_TOKEN_H__
13#define __ATTEST_TOKEN_H__
14
15#include <stdint.h>
16#include "qcbor.h"
David Hu5bd5bae2020-01-20 18:01:13 +080017#ifdef SYMMETRIC_INITIAL_ATTESTATION
18#include "t_cose_mac0_sign.h"
19#else
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080020#include "t_cose_sign1_sign.h"
David Hu5bd5bae2020-01-20 18:01:13 +080021#endif
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080022
Laurence Lundbladee1610ad2019-02-20 13:53:20 -080023#ifdef __cplusplus
24extern "C" {
25#endif
26
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080027
28/**
29 * \file attest_token.h
30 *
31 * \brief Attestation Token Creation Interface
32 *
33 * The context and functions here are the way to create an attestation
34 * token. The steps are roughly:
35 *
Laurence Lundbladee1610ad2019-02-20 13:53:20 -080036 * -# Create and initialize an attest_token_ctx indicating the
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080037 * options, key and such using attest_token_start().
38 *
39 * -# Use various add methods to fill in the payload with claims. The
40 * encoding context can also be borrowed for more rich payloads.
41 *
42 * -# Call attest_token_finish() to create the signature and finish
43 * formatting the COSE signed output.
44 */
45
46
47/**
48 Error codes returned from attestation token creation.
49 */
50enum attest_token_err_t {
51 /** Success */
52 ATTEST_TOKEN_ERR_SUCCESS = 0,
53 /** The buffer passed in to receive the output is too small. */
54 ATTEST_TOKEN_ERR_TOO_SMALL,
55 /** Something went wrong formatting the CBOR, most likely the
56 payload has maps or arrays that are not closed. */
57 ATTEST_TOKEN_ERR_CBOR_FORMATTING,
58 /** A general, unspecific error when creating or decoding the
59 token. */
60 ATTEST_TOKEN_ERR_GENERAL,
61 /** A hash function that is needed to make the token is not
62 available. */
63 ATTEST_TOKEN_ERR_HASH_UNAVAILABLE,
64 /** CBOR Syntax not well-formed -- a CBOR syntax error. */
65 ATTEST_TOKEN_ERR_CBOR_NOT_WELL_FORMED,
66 /** Bad CBOR structure, for example not a map when was is
67 required. */
68 ATTEST_TOKEN_ERR_CBOR_STRUCTURE,
69 /** Bad CBOR type, for example an not a text string, when a text
70 string is required. */
Alamy Liuf5d2fbf2020-03-24 16:37:06 -070071 ATTEST_TOKEN_ERR_CBOR_TYPE,
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080072 /** Integer too large, for example an \c int32_t is required, but
73 value only fits in \c int64_t */
74 ATTEST_TOKEN_ERR_INTEGER_VALUE,
David Hub835f4d2020-01-26 15:28:51 +080075 /** Something is wrong with the COSE message structure, missing
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080076 headers or such. */
David Hub835f4d2020-01-26 15:28:51 +080077 ATTEST_TOKEN_ERR_COSE_FORMAT,
78 /** COSE signature or authentication tag is invalid, data
79 is corrupted. */
80 ATTEST_TOKEN_ERR_COSE_VALIDATION,
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080081 /** The signing algorithm is not supported. */
82 ATTEST_TOKEN_ERR_UNSUPPORTED_SIG_ALG,
83 /** Out of memory. */
84 ATTEST_TOKEN_ERR_INSUFFICIENT_MEMORY,
85 /** Tampering detected in cryptographic function. */
86 ATTEST_TOKEN_ERR_TAMPERING_DETECTED,
Tamas Ban95e56472020-01-10 13:46:47 +000087 /** Signing key is not found or of wrong type. */
88 ATTEST_TOKEN_ERR_SIGNING_KEY,
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080089 /** Verification key is not found or of wrong type. */
Laurence Lundbladee1610ad2019-02-20 13:53:20 -080090 ATTEST_TOKEN_ERR_VERIFICATION_KEY,
Laurence Lundbladedada1232019-03-01 09:13:14 -080091 /** No token was given or validated */
92 ATTEST_TOKEN_ERR_NO_VALID_TOKEN,
93 /** Data item with label wasn't found. */
94 ATTEST_TOKEN_ERR_NOT_FOUND,
Tamas Ban95e56472020-01-10 13:46:47 +000095 /** SW Components absence not correctly indicated. */
Laurence Lundbladedada1232019-03-01 09:13:14 -080096 ATTEST_TOKEN_ERR_SW_COMPONENTS_MISSING
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080097};
98
99
100
101/**
102 * Request that the claims internally generated not be added to the
103 * token. This is a test mode that results in a static token that
104 * never changes. Only the nonce is included. The nonce is under
105 * the callers control unlike the other claims.
106 */
107#define TOKEN_OPT_OMIT_CLAIMS 0x40000000
108
109
110/**
111 * A special test mode where a proper signature is not produced. In
112 * its place there is a concatenation of hashes of the payload to be
113 * the same size as the signature. This works and can be used to
114 * verify all of the SW stack except the public signature part. The
115 * token has no security value in this mode because anyone can
116 * replicate it. */
117#define TOKEN_OPT_SHORT_CIRCUIT_SIGN 0x80000000
118
119
120/**
121 * The context for creating an attestation token. The caller of
122 * attest_token must create one of these and pass it to the functions
123 * here. It is small enough that it can go on the stack. It is most of
124 * the memory needed to create a token except the output buffer and
125 * any memory requirements for the cryptographic operations.
126 *
127 * The structure is opaque for the caller.
128 *
129 * This is roughly 148 + 8 + 32 = 188 bytes
130 */
131struct attest_token_ctx {
132 /* Private data structure */
Tamas Ban95e56472020-01-10 13:46:47 +0000133 QCBOREncodeContext cbor_enc_ctx;
134 uint32_t opt_flags;
135 int32_t key_select;
David Hu5bd5bae2020-01-20 18:01:13 +0800136#ifdef SYMMETRIC_INITIAL_ATTESTATION
137 struct t_cose_mac0_sign_ctx mac_ctx;
138#else
Tamas Ban95e56472020-01-10 13:46:47 +0000139 struct t_cose_sign1_sign_ctx signer_ctx;
David Hu5bd5bae2020-01-20 18:01:13 +0800140#endif
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800141};
142
143
144/**
145 * \brief Initialize a token creation context.
146 *
147 * \param[in] me The token creation context to be initialized.
148 * \param[in] opt_flags Flags to select different custom options,
149 for example \ref TOKEN_OPT_OMIT_CLAIMS.
150 * \param[in] key_select Selects which attestation key to sign with.
151 * \param[in] cose_alg_id The algorithm to sign with. The IDs are
152 * defined in [COSE (RFC 8152)]
153 * (https://tools.ietf.org/html/rfc8152) or
154 * in the [IANA COSE Registry]
155 * (https://www.iana.org/assignments/cose/cose.xhtml).
156 * \param[out] out_buffer The output buffer to write the encoded token into.
157 *
158 * \return one of the \ref attest_token_err_t errors.
159 *
160 * The size of the buffer in \c out_buffer->len
161 * determines the size of the token that can be created. It must be
162 * able to hold the final encoded and signed token. The data encoding
163 * overhead is just that of CBOR. The signing overhead depends on the
164 * signing key size. It is about 150 bytes for 256-bit ECDSA.
165 *
166 * If \c out_buffer->ptr is \c NULL and \c out_buffer_ptr->len is
167 * large like \c UINT32_MAX no token will be created but the length of
168 * the token that would be created will be in \c completed_token as
169 * returned by attest_token_finish(). None of the cryptographic
170 * functions run during this, but the sizes of what they would output
171 * is taken into account.
172 */
173enum attest_token_err_t
174attest_token_start(struct attest_token_ctx *me,
175 uint32_t opt_flags,
176 int32_t key_select,
177 int32_t cose_alg_id,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800178 const struct q_useful_buf *out_buffer);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800179
180
181
182/**
183 * \brief Get a copy of the CBOR encoding context
184 *
185 * \param[in] me Token creation context.
186 *
187 * \return The CBOR encoding context
188 *
189 * Allows the caller to encode CBOR right into the output buffer using
190 * any of the \c QCBOREncode_AddXXXX() methods. Anything added here
191 * will be part of the payload that gets hashed. This can be used to
192 * make complex CBOR structures. All open arrays and maps must be
193 * close before calling any other \c attest_token methods. \c
194 * QCBOREncode_Finish() should not be closed on this context.
195 */
196QCBOREncodeContext *attest_token_borrow_cbor_cntxt(struct attest_token_ctx *me);
197
198/**
199 * \brief Add a 64-bit signed integer claim
200 *
201 * \param[in] me Token creation context.
202 * \param[in] label Integer label for claim.
203 * \param[in] value The integer claim data.
204 */
205void attest_token_add_integer(struct attest_token_ctx *me,
206 int32_t label,
207 int64_t value);
208
209/**
210 * \brief Add a binary string claim
211 *
212 * \param[in] me Token creation context.
213 * \param[in] label Integer label for claim.
214 * \param[in] value The binary claim data.
215 */
216void attest_token_add_bstr(struct attest_token_ctx *me,
217 int32_t label,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800218 const struct q_useful_buf_c *value);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800219
220/**
221 * \brief Add a text string claim
222 *
223 * \param[in] me Token creation context.
224 * \param[in] label Integer label for claim.
225 * \param[in] value The text claim data.
226 */
227void attest_token_add_tstr(struct attest_token_ctx *me,
228 int32_t label,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800229 const struct q_useful_buf_c *value);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800230
231/**
232 * \brief Add some already-encoded CBOR to payload
233 *
234 * \param[in] me Token creation context.
235 * \param[in] label Integer label for claim.
236 * \param[in] encoded The already-encoded CBOR.
237 *
238 * Encoded CBOR must be a full map or full array or a non-aggregate
239 * type. It cannot be a partial map or array. It can be nested maps
240 * and arrays, but they must all be complete.
241 */
242void attest_token_add_encoded(struct attest_token_ctx *me,
243 int32_t label,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800244 const struct q_useful_buf_c *encoded);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800245
246
247/**
248 * \brief Finish the token, complete the signing and get the result
249 *
250 * \param[in] me Token Creation Context.
251 * \param[out] completed_token Pointer and length to completed token.
252 *
253 * \return one of the \ref attest_token_err_t errors.
254 *
255 * This completes the token after the payload has been added. When
256 * this is called the signing algorithm is run and the final
257 * formatting of the token is completed.
258 */
259enum attest_token_err_t
260attest_token_finish(struct attest_token_ctx *me,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800261 struct q_useful_buf_c *completed_token);
262
263#ifdef __cplusplus
264}
265#endif
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800266
267#endif /* __ATTEST_TOKEN_H__ */