blob: b7bf58ae963322880dda5a2f36cfd254fb0989b0 [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 Lundbladeb1bfe102019-03-07 11:09:38 -080036 * -# Create and initialize an attest_token_encode_ctx indicating the
37 * options, key and such using attest_token_encode_start().
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080038 *
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 *
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -080042 * -# Call attest_token_encode_finish() to create the signature and finish
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080043 * 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
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800122 * attest_token_encode must create one of these and pass it to the functions
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800123 * 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 */
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800131struct attest_token_encode_ctx {
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800132 /* 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,
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800149 * for example \ref TOKEN_OPT_OMIT_CLAIMS.
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800150 * \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
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800169 * returned by attest_token_encode_finish(). None of the cryptographic
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800170 * functions run during this, but the sizes of what they would output
171 * is taken into account.
172 */
173enum attest_token_err_t
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800174attest_token_encode_start(struct attest_token_encode_ctx *me,
175 uint32_t opt_flags,
176 int32_t key_select,
177 int32_t cose_alg_id,
178 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
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800193 * close before calling any other \c attest_token_encode methods. \c
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800194 * QCBOREncode_Finish() should not be closed on this context.
195 */
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800196QCBOREncodeContext *
197attest_token_encode_borrow_cbor_cntxt(struct attest_token_encode_ctx *me);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800198
199/**
200 * \brief Add a 64-bit signed integer claim
201 *
202 * \param[in] me Token creation context.
203 * \param[in] label Integer label for claim.
204 * \param[in] value The integer claim data.
205 */
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800206void attest_token_encode_add_integer(struct attest_token_encode_ctx *me,
207 int32_t label,
208 int64_t value);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800209
210/**
211 * \brief Add a binary string claim
212 *
213 * \param[in] me Token creation context.
214 * \param[in] label Integer label for claim.
215 * \param[in] value The binary claim data.
216 */
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800217void attest_token_encode_add_bstr(struct attest_token_encode_ctx *me,
218 int32_t label,
219 const struct q_useful_buf_c *value);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800220
221/**
222 * \brief Add a text string claim
223 *
224 * \param[in] me Token creation context.
225 * \param[in] label Integer label for claim.
226 * \param[in] value The text claim data.
227 */
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800228void attest_token_encode_add_tstr(struct attest_token_encode_ctx *me,
229 int32_t label,
230 const struct q_useful_buf_c *value);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800231
232/**
233 * \brief Add some already-encoded CBOR to payload
234 *
235 * \param[in] me Token creation context.
236 * \param[in] label Integer label for claim.
237 * \param[in] encoded The already-encoded CBOR.
238 *
239 * Encoded CBOR must be a full map or full array or a non-aggregate
240 * type. It cannot be a partial map or array. It can be nested maps
241 * and arrays, but they must all be complete.
242 */
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800243void attest_token_encode_add_cbor(struct attest_token_encode_ctx *me,
244 int32_t label,
245 const struct q_useful_buf_c *encoded);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800246
247
248/**
249 * \brief Finish the token, complete the signing and get the result
250 *
251 * \param[in] me Token Creation Context.
252 * \param[out] completed_token Pointer and length to completed token.
253 *
254 * \return one of the \ref attest_token_err_t errors.
255 *
256 * This completes the token after the payload has been added. When
257 * this is called the signing algorithm is run and the final
258 * formatting of the token is completed.
259 */
260enum attest_token_err_t
Laurence Lundbladeb1bfe102019-03-07 11:09:38 -0800261attest_token_encode_finish(struct attest_token_encode_ctx *me,
262 struct q_useful_buf_c *completed_token);
263
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800264
265#ifdef __cplusplus
266}
267#endif
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800268
269#endif /* __ATTEST_TOKEN_H__ */