blob: 4897c9e97165c9a1b4cc664eaee841c3b50993df [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,
75 /** Something is wrong with the COSE signing structure, missing
76 headers or such. */
77 ATTEST_TOKEN_ERR_COSE_SIGN1_FORMAT,
78 /** COSE signature is invalid, data is corrupted. */
79 ATTEST_TOKEN_ERR_COSE_SIGN1_VALIDATION,
80 /** The signing algorithm is not supported. */
81 ATTEST_TOKEN_ERR_UNSUPPORTED_SIG_ALG,
82 /** Out of memory. */
83 ATTEST_TOKEN_ERR_INSUFFICIENT_MEMORY,
84 /** Tampering detected in cryptographic function. */
85 ATTEST_TOKEN_ERR_TAMPERING_DETECTED,
Tamas Ban95e56472020-01-10 13:46:47 +000086 /** Signing key is not found or of wrong type. */
87 ATTEST_TOKEN_ERR_SIGNING_KEY,
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080088 /** Verification key is not found or of wrong type. */
Laurence Lundbladee1610ad2019-02-20 13:53:20 -080089 ATTEST_TOKEN_ERR_VERIFICATION_KEY,
Laurence Lundbladedada1232019-03-01 09:13:14 -080090 /** No token was given or validated */
91 ATTEST_TOKEN_ERR_NO_VALID_TOKEN,
92 /** Data item with label wasn't found. */
93 ATTEST_TOKEN_ERR_NOT_FOUND,
Tamas Ban95e56472020-01-10 13:46:47 +000094 /** SW Components absence not correctly indicated. */
Laurence Lundbladedada1232019-03-01 09:13:14 -080095 ATTEST_TOKEN_ERR_SW_COMPONENTS_MISSING
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -080096};
97
98
99
100/**
101 * Request that the claims internally generated not be added to the
102 * token. This is a test mode that results in a static token that
103 * never changes. Only the nonce is included. The nonce is under
104 * the callers control unlike the other claims.
105 */
106#define TOKEN_OPT_OMIT_CLAIMS 0x40000000
107
108
109/**
110 * A special test mode where a proper signature is not produced. In
111 * its place there is a concatenation of hashes of the payload to be
112 * the same size as the signature. This works and can be used to
113 * verify all of the SW stack except the public signature part. The
114 * token has no security value in this mode because anyone can
115 * replicate it. */
116#define TOKEN_OPT_SHORT_CIRCUIT_SIGN 0x80000000
117
118
119/**
120 * The context for creating an attestation token. The caller of
121 * attest_token must create one of these and pass it to the functions
122 * here. It is small enough that it can go on the stack. It is most of
123 * the memory needed to create a token except the output buffer and
124 * any memory requirements for the cryptographic operations.
125 *
126 * The structure is opaque for the caller.
127 *
128 * This is roughly 148 + 8 + 32 = 188 bytes
129 */
130struct attest_token_ctx {
131 /* Private data structure */
Tamas Ban95e56472020-01-10 13:46:47 +0000132 QCBOREncodeContext cbor_enc_ctx;
133 uint32_t opt_flags;
134 int32_t key_select;
David Hu5bd5bae2020-01-20 18:01:13 +0800135#ifdef SYMMETRIC_INITIAL_ATTESTATION
136 struct t_cose_mac0_sign_ctx mac_ctx;
137#else
Tamas Ban95e56472020-01-10 13:46:47 +0000138 struct t_cose_sign1_sign_ctx signer_ctx;
David Hu5bd5bae2020-01-20 18:01:13 +0800139#endif
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800140};
141
142
143/**
144 * \brief Initialize a token creation context.
145 *
146 * \param[in] me The token creation context to be initialized.
147 * \param[in] opt_flags Flags to select different custom options,
148 for example \ref TOKEN_OPT_OMIT_CLAIMS.
149 * \param[in] key_select Selects which attestation key to sign with.
150 * \param[in] cose_alg_id The algorithm to sign with. The IDs are
151 * defined in [COSE (RFC 8152)]
152 * (https://tools.ietf.org/html/rfc8152) or
153 * in the [IANA COSE Registry]
154 * (https://www.iana.org/assignments/cose/cose.xhtml).
155 * \param[out] out_buffer The output buffer to write the encoded token into.
156 *
157 * \return one of the \ref attest_token_err_t errors.
158 *
159 * The size of the buffer in \c out_buffer->len
160 * determines the size of the token that can be created. It must be
161 * able to hold the final encoded and signed token. The data encoding
162 * overhead is just that of CBOR. The signing overhead depends on the
163 * signing key size. It is about 150 bytes for 256-bit ECDSA.
164 *
165 * If \c out_buffer->ptr is \c NULL and \c out_buffer_ptr->len is
166 * large like \c UINT32_MAX no token will be created but the length of
167 * the token that would be created will be in \c completed_token as
168 * returned by attest_token_finish(). None of the cryptographic
169 * functions run during this, but the sizes of what they would output
170 * is taken into account.
171 */
172enum attest_token_err_t
173attest_token_start(struct attest_token_ctx *me,
174 uint32_t opt_flags,
175 int32_t key_select,
176 int32_t cose_alg_id,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800177 const struct q_useful_buf *out_buffer);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800178
179
180
181/**
182 * \brief Get a copy of the CBOR encoding context
183 *
184 * \param[in] me Token creation context.
185 *
186 * \return The CBOR encoding context
187 *
188 * Allows the caller to encode CBOR right into the output buffer using
189 * any of the \c QCBOREncode_AddXXXX() methods. Anything added here
190 * will be part of the payload that gets hashed. This can be used to
191 * make complex CBOR structures. All open arrays and maps must be
192 * close before calling any other \c attest_token methods. \c
193 * QCBOREncode_Finish() should not be closed on this context.
194 */
195QCBOREncodeContext *attest_token_borrow_cbor_cntxt(struct attest_token_ctx *me);
196
197/**
198 * \brief Add a 64-bit signed integer claim
199 *
200 * \param[in] me Token creation context.
201 * \param[in] label Integer label for claim.
202 * \param[in] value The integer claim data.
203 */
204void attest_token_add_integer(struct attest_token_ctx *me,
205 int32_t label,
206 int64_t value);
207
208/**
209 * \brief Add a binary string claim
210 *
211 * \param[in] me Token creation context.
212 * \param[in] label Integer label for claim.
213 * \param[in] value The binary claim data.
214 */
215void attest_token_add_bstr(struct attest_token_ctx *me,
216 int32_t label,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800217 const struct q_useful_buf_c *value);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800218
219/**
220 * \brief Add a text string claim
221 *
222 * \param[in] me Token creation context.
223 * \param[in] label Integer label for claim.
224 * \param[in] value The text claim data.
225 */
226void attest_token_add_tstr(struct attest_token_ctx *me,
227 int32_t label,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800228 const struct q_useful_buf_c *value);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800229
230/**
231 * \brief Add some already-encoded CBOR to payload
232 *
233 * \param[in] me Token creation context.
234 * \param[in] label Integer label for claim.
235 * \param[in] encoded The already-encoded CBOR.
236 *
237 * Encoded CBOR must be a full map or full array or a non-aggregate
238 * type. It cannot be a partial map or array. It can be nested maps
239 * and arrays, but they must all be complete.
240 */
241void attest_token_add_encoded(struct attest_token_ctx *me,
242 int32_t label,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800243 const struct q_useful_buf_c *encoded);
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800244
245
246/**
247 * \brief Finish the token, complete the signing and get the result
248 *
249 * \param[in] me Token Creation Context.
250 * \param[out] completed_token Pointer and length to completed token.
251 *
252 * \return one of the \ref attest_token_err_t errors.
253 *
254 * This completes the token after the payload has been added. When
255 * this is called the signing algorithm is run and the final
256 * formatting of the token is completed.
257 */
258enum attest_token_err_t
259attest_token_finish(struct attest_token_ctx *me,
Laurence Lundbladee1610ad2019-02-20 13:53:20 -0800260 struct q_useful_buf_c *completed_token);
261
262#ifdef __cplusplus
263}
264#endif
Laurence Lundbladeaffd65a2018-12-18 10:50:48 -0800265
266#endif /* __ATTEST_TOKEN_H__ */