blob: af30fa832027a65f54f45cd66218df7b9142a8f9 [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"
17#include "t_cose_sign1_sign.h"
18
Laurence Lundbladee1610ad2019-02-20 13:53:20 -080019#ifdef __cplusplus
20extern "C" {
21#endif
22
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080023
24/**
25 * \file attest_token.h
26 *
27 * \brief Attestation Token Creation Interface
28 *
29 * The context and functions here are the way to create an attestation
30 * token. The steps are roughly:
31 *
Laurence Lundbladee1610ad2019-02-20 13:53:20 -080032 * -# Create and initialize an attest_token_ctx indicating the
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080033 * options, key and such using attest_token_start().
34 *
35 * -# Use various add methods to fill in the payload with claims. The
36 * encoding context can also be borrowed for more rich payloads.
37 *
38 * -# Call attest_token_finish() to create the signature and finish
39 * formatting the COSE signed output.
40 */
41
42
43/**
44 Error codes returned from attestation token creation.
45 */
46enum attest_token_err_t {
47 /** Success */
48 ATTEST_TOKEN_ERR_SUCCESS = 0,
49 /** The buffer passed in to receive the output is too small. */
50 ATTEST_TOKEN_ERR_TOO_SMALL,
51 /** Something went wrong formatting the CBOR, most likely the
52 payload has maps or arrays that are not closed. */
53 ATTEST_TOKEN_ERR_CBOR_FORMATTING,
54 /** A general, unspecific error when creating or decoding the
55 token. */
56 ATTEST_TOKEN_ERR_GENERAL,
57 /** A hash function that is needed to make the token is not
58 available. */
59 ATTEST_TOKEN_ERR_HASH_UNAVAILABLE,
60 /** CBOR Syntax not well-formed -- a CBOR syntax error. */
61 ATTEST_TOKEN_ERR_CBOR_NOT_WELL_FORMED,
62 /** Bad CBOR structure, for example not a map when was is
63 required. */
64 ATTEST_TOKEN_ERR_CBOR_STRUCTURE,
65 /** Bad CBOR type, for example an not a text string, when a text
66 string is required. */
Alamy Liuf5d2fbf2020-03-24 16:37:06 -070067 ATTEST_TOKEN_ERR_CBOR_TYPE,
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080068 /** Integer too large, for example an \c int32_t is required, but
69 value only fits in \c int64_t */
70 ATTEST_TOKEN_ERR_INTEGER_VALUE,
71 /** Something is wrong with the COSE signing structure, missing
72 headers or such. */
73 ATTEST_TOKEN_ERR_COSE_SIGN1_FORMAT,
74 /** COSE signature is invalid, data is corrupted. */
75 ATTEST_TOKEN_ERR_COSE_SIGN1_VALIDATION,
76 /** The signing algorithm is not supported. */
77 ATTEST_TOKEN_ERR_UNSUPPORTED_SIG_ALG,
78 /** Out of memory. */
79 ATTEST_TOKEN_ERR_INSUFFICIENT_MEMORY,
80 /** Tampering detected in cryptographic function. */
81 ATTEST_TOKEN_ERR_TAMPERING_DETECTED,
Tamas Ban95e56472020-01-10 13:46:47 +000082 /** Signing key is not found or of wrong type. */
83 ATTEST_TOKEN_ERR_SIGNING_KEY,
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080084 /** Verification key is not found or of wrong type. */
Laurence Lundbladee1610ad2019-02-20 13:53:20 -080085 ATTEST_TOKEN_ERR_VERIFICATION_KEY,
Laurence Lundbladedada1232019-03-01 09:13:14 -080086 /** No token was given or validated */
87 ATTEST_TOKEN_ERR_NO_VALID_TOKEN,
88 /** Data item with label wasn't found. */
89 ATTEST_TOKEN_ERR_NOT_FOUND,
Tamas Ban95e56472020-01-10 13:46:47 +000090 /** SW Components absence not correctly indicated. */
Laurence Lundbladedada1232019-03-01 09:13:14 -080091 ATTEST_TOKEN_ERR_SW_COMPONENTS_MISSING
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080092};
93
94
95
96/**
97 * Request that the claims internally generated not be added to the
98 * token. This is a test mode that results in a static token that
99 * never changes. Only the nonce is included. The nonce is under
100 * the callers control unlike the other claims.
101 */
102#define TOKEN_OPT_OMIT_CLAIMS 0x40000000
103
104
105/**
106 * A special test mode where a proper signature is not produced. In
107 * its place there is a concatenation of hashes of the payload to be
108 * the same size as the signature. This works and can be used to
109 * verify all of the SW stack except the public signature part. The
110 * token has no security value in this mode because anyone can
111 * replicate it. */
112#define TOKEN_OPT_SHORT_CIRCUIT_SIGN 0x80000000
113
114
115/**
116 * The context for creating an attestation token. The caller of
117 * attest_token must create one of these and pass it to the functions
118 * here. It is small enough that it can go on the stack. It is most of
119 * the memory needed to create a token except the output buffer and
120 * any memory requirements for the cryptographic operations.
121 *
122 * The structure is opaque for the caller.
123 *
124 * This is roughly 148 + 8 + 32 = 188 bytes
125 */
126struct attest_token_ctx {
127 /* Private data structure */
Tamas Ban95e56472020-01-10 13:46:47 +0000128 QCBOREncodeContext cbor_enc_ctx;
129 uint32_t opt_flags;
130 int32_t key_select;
131 struct t_cose_sign1_sign_ctx signer_ctx;
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800132};
133
134
135/**
136 * \brief Initialize a token creation context.
137 *
138 * \param[in] me The token creation context to be initialized.
139 * \param[in] opt_flags Flags to select different custom options,
140 for example \ref TOKEN_OPT_OMIT_CLAIMS.
141 * \param[in] key_select Selects which attestation key to sign with.
142 * \param[in] cose_alg_id The algorithm to sign with. The IDs are
143 * defined in [COSE (RFC 8152)]
144 * (https://tools.ietf.org/html/rfc8152) or
145 * in the [IANA COSE Registry]
146 * (https://www.iana.org/assignments/cose/cose.xhtml).
147 * \param[out] out_buffer The output buffer to write the encoded token into.
148 *
149 * \return one of the \ref attest_token_err_t errors.
150 *
151 * The size of the buffer in \c out_buffer->len
152 * determines the size of the token that can be created. It must be
153 * able to hold the final encoded and signed token. The data encoding
154 * overhead is just that of CBOR. The signing overhead depends on the
155 * signing key size. It is about 150 bytes for 256-bit ECDSA.
156 *
157 * If \c out_buffer->ptr is \c NULL and \c out_buffer_ptr->len is
158 * large like \c UINT32_MAX no token will be created but the length of
159 * the token that would be created will be in \c completed_token as
160 * returned by attest_token_finish(). None of the cryptographic
161 * functions run during this, but the sizes of what they would output
162 * is taken into account.
163 */
164enum attest_token_err_t
165attest_token_start(struct attest_token_ctx *me,
166 uint32_t opt_flags,
167 int32_t key_select,
168 int32_t cose_alg_id,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800169 const struct q_useful_buf *out_buffer);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800170
171
172
173/**
174 * \brief Get a copy of the CBOR encoding context
175 *
176 * \param[in] me Token creation context.
177 *
178 * \return The CBOR encoding context
179 *
180 * Allows the caller to encode CBOR right into the output buffer using
181 * any of the \c QCBOREncode_AddXXXX() methods. Anything added here
182 * will be part of the payload that gets hashed. This can be used to
183 * make complex CBOR structures. All open arrays and maps must be
184 * close before calling any other \c attest_token methods. \c
185 * QCBOREncode_Finish() should not be closed on this context.
186 */
187QCBOREncodeContext *attest_token_borrow_cbor_cntxt(struct attest_token_ctx *me);
188
189/**
190 * \brief Add a 64-bit signed integer claim
191 *
192 * \param[in] me Token creation context.
193 * \param[in] label Integer label for claim.
194 * \param[in] value The integer claim data.
195 */
196void attest_token_add_integer(struct attest_token_ctx *me,
197 int32_t label,
198 int64_t value);
199
200/**
201 * \brief Add a binary string claim
202 *
203 * \param[in] me Token creation context.
204 * \param[in] label Integer label for claim.
205 * \param[in] value The binary claim data.
206 */
207void attest_token_add_bstr(struct attest_token_ctx *me,
208 int32_t label,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800209 const struct q_useful_buf_c *value);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800210
211/**
212 * \brief Add a text string claim
213 *
214 * \param[in] me Token creation context.
215 * \param[in] label Integer label for claim.
216 * \param[in] value The text claim data.
217 */
218void attest_token_add_tstr(struct attest_token_ctx *me,
219 int32_t label,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800220 const struct q_useful_buf_c *value);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800221
222/**
223 * \brief Add some already-encoded CBOR to payload
224 *
225 * \param[in] me Token creation context.
226 * \param[in] label Integer label for claim.
227 * \param[in] encoded The already-encoded CBOR.
228 *
229 * Encoded CBOR must be a full map or full array or a non-aggregate
230 * type. It cannot be a partial map or array. It can be nested maps
231 * and arrays, but they must all be complete.
232 */
233void attest_token_add_encoded(struct attest_token_ctx *me,
234 int32_t label,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800235 const struct q_useful_buf_c *encoded);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800236
237
238/**
239 * \brief Finish the token, complete the signing and get the result
240 *
241 * \param[in] me Token Creation Context.
242 * \param[out] completed_token Pointer and length to completed token.
243 *
244 * \return one of the \ref attest_token_err_t errors.
245 *
246 * This completes the token after the payload has been added. When
247 * this is called the signing algorithm is run and the final
248 * formatting of the token is completed.
249 */
250enum attest_token_err_t
251attest_token_finish(struct attest_token_ctx *me,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800252 struct q_useful_buf_c *completed_token);
253
254#ifdef __cplusplus
255}
256#endif
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800257
258#endif /* __ATTEST_TOKEN_H__ */