1 /*
2  * t_cose_sign1_sign.h
3  *
4  * Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * See BSD-3-Clause license in README.md
9  */
10 
11 #ifndef __T_COSE_SIGN1_H__
12 #define __T_COSE_SIGN1_H__
13 
14 #include <stdint.h>
15 #include <stdbool.h>
16 #include "qcbor/qcbor.h"
17 #include "t_cose_common.h"
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 
24 /**
25  * \file t_cose_sign1_sign.h
26  *
27  * \brief Create a \c COSE_Sign1 message, usually for EAT or CWT Token.
28  *
29  * This creates a \c COSE_Sign1 message in compliance with
30  * [COSE (RFC 8152)](https://tools.ietf.org/html/rfc8152).
31  * A \c COSE_Sign1 message is a CBOR encoded binary blob that contains
32  * header parameters, a payload and a signature. Usually the signature is made
33  * with an EC signing algorithm like ECDSA.
34  *
35  * This implementation is intended to be small and portable to
36  * different OS's and platforms. Its dependencies are:
37  * - [QCBOR](https://github.com/laurencelundblade/QCBOR)
38  * - <stdint.h>, <string.h>, <stddef.h>
39  * - Hash functions like SHA-256
40  * - Signing functions like ECDSA
41  *
42  * There is a cryptographic adaptation layer defined in
43  * t_cose_crypto.h.  An implementation can be made of the functions in
44  * it for different cryptographic libraries. This means that different
45  * integrations with different cryptographic libraries may support
46  * only signing with a particular set of algorithms. Integration with
47  * [OpenSSL](https://www.openssl.org) is supported.  Key ID look up
48  * also varies by different cryptographic library integrations.
49  *
50  * This implementation has a mode where a CBOR-format payload can be
51  * output directly into the output buffer. This saves having two
52  * copies of the payload in memory. For this mode use
53  * t_cose_sign1_encode_parameters() and
54  * t_cose_sign1_encode_signature(). For a simpler API that just takes
55  * the payload as an input buffer use t_cose_sign1_sign().
56  *
57  * See t_cose_common.h for preprocessor defines to reduce object code
58  * and stack use by disabling features.
59  */
60 
61 
62 /**
63  * This is the context for creating a \c COSE_Sign1 structure. The
64  * caller should allocate it and pass it to the functions here.  This
65  * is about 100 bytes so it fits easily on the stack.
66  */
67 struct t_cose_sign1_sign_ctx {
68     /* Private data structure */
69     uint8_t               protected_parameters_buffer[T_COSE_SIGN1_MAX_SIZE_PROTECTED_PARAMETERS];
70     struct q_useful_buf_c protected_parameters; /* The encoded protected parameters */
71     int32_t               cose_algorithm_id;
72     struct t_cose_key     signing_key;
73     int32_t               option_flags;
74     struct q_useful_buf_c kid;
75 #ifndef T_COSE_DISABLE_CONTENT_TYPE
76     uint32_t              content_type_uint;
77     const char *          content_type_tstr;
78 #endif
79 };
80 
81 
82 /**
83  * This selects a signing test mode called _short_ _circuit_
84  * _signing_. This mode is useful when there is no signing key
85  * available, perhaps because it has not been provisioned or
86  * configured for the particular device. It may also be because the
87  * public key cryptographic functions have not been connected up in
88  * the cryptographic adaptation layer.
89  *
90  * It has no value for security at all. Data signed this way MUST NOT
91  * be trusted as anyone can sign like this.
92  *
93  * In this mode, the signature is the hash of that which would
94  * normally be signed by the public key algorithm. To make the
95  * signature the correct size for the particular algorithm, instances
96  * of the hash are concatenated to pad it out.
97  *
98  * This mode is very useful for testing because all the code except
99  * the actual signing algorithm is run exactly as it would if a proper
100  * signing algorithm was run. This can be used for end-end system
101  * testing all the way to a server or relying party, not just for
102  * testing device code as t_cose_sign1_verify() supports it too.
103  */
104 #define T_COSE_OPT_SHORT_CIRCUIT_SIG 0x00000001
105 
106 
107 
108 
109 /**
110  * \brief  Initialize to start creating a \c COSE_Sign1.
111  *
112  * \param[in] context            The t_cose signing context.
113  * \param[in] option_flags       One of \c T_COSE_OPT_XXXX.
114  * \param[in] cose_algorithm_id  The algorithm to sign with, for example
115  *                               \ref T_COSE_ALGORITHM_ES256.
116  *
117  * Initialize the \ref t_cose_sign1_ctx context. Typically, no
118  * \c option_flags are needed and 0 is passed. A \c cose_algorithm_id
119  * must always be given. See \ref T_COSE_OPT_SHORT_CIRCUIT_SIG and
120  * related for possible option flags.
121  *
122  * The algorithm ID space is from
123  * [COSE (RFC8152)](https://tools.ietf.org/html/rfc8152) and the
124  * [IANA COSE Registry](https://www.iana.org/assignments/cose/cose.xhtml).
125  * \ref T_COSE_ALGORITHM_ES256 and a few others are defined here for
126  * convenience. The signing algorithms supported depends on the
127  * cryptographic library that t_cose is integrated with.
128  *
129  * Errors such as the passing of an unsupported \c cose_algorithm_id
130  * are reported when t_cose_sign1_sign() or
131  * t_cose_sign1_encode_parameters() is called.
132  */
133 static void
134 t_cose_sign1_sign_init(struct t_cose_sign1_sign_ctx *context,
135                        int32_t                       option_flags,
136                        int32_t                       cose_algorithm_id);
137 
138 
139 /**
140  * \brief  Set the key and kid (key ID) for signing.
141  *
142  * \param[in] context      The t_cose signing context.
143  * \param[in] signing_key  The signing key to use or \ref T_COSE_NULL_KEY.
144  * \param[in] kid          COSE kid (key ID) parameter or \c NULL_Q_USEFUL_BUF_C.
145  *
146  * This needs to be called to set the signing key to use. The \c kid
147  * may be omitted by giving \c NULL_Q_USEFUL_BUF_C.
148  *
149  * If short-circuit signing is used,
150  * \ref T_COSE_OPT_SHORT_CIRCUIT_SIG, then this does not need to be
151  * called. If it is called the \c kid given will be used, but the \c
152  * signing_key is never used. When the \c kid is given with a
153  * short-circuit signature, the internally fixed kid for short circuit
154  * will not be used and this \c COSE_Sign1 message can not be verified
155  * by t_cose_sign1_verify().
156  */
157 static void
158 t_cose_sign1_set_signing_key(struct t_cose_sign1_sign_ctx *context,
159                              struct t_cose_key             signing_key,
160                              struct q_useful_buf_c         kid);
161 
162 
163 
164 #ifndef T_COSE_DISABLE_CONTENT_TYPE
165 /**
166  * \brief Set the payload content type using CoAP content types.
167  *
168  * \param[in] context      The t_cose signing context.
169  * \param[in] content_type The content type of the payload as defined
170  *                         in the IANA CoAP Content-Formats registry.
171  *
172  * It is not allowed to have both a CoAP and MIME content type. This
173  * error will show up when t_cose_sign1_sign() or
174  * t_cose_sign1_encode_parameters() is called as no error is returned by
175  * this function.
176  *
177  * The IANA CoAP Content-Formats registry is found
178  * [here](https://www.iana.org/assignments/core-parameters/core-parameters.xhtml#content-formats).
179  */
180 static inline void
181 t_cose_sign1_set_content_type_uint(struct t_cose_sign1_sign_ctx *context,
182                                    uint16_t                      content_type);
183 
184 /**
185  * \brief Set the payload content type using MIME content types.
186  *
187  * \param[in] context      The t_cose signing context.
188  * \param[in] content_type The content type of the payload as defined
189  *                         in the IANA Media Types registry.
190 
191  *
192  * It is not allowed to have both a CoAP and MIME content type. This
193  * error will show up when t_cose_sign1_sign() or
194  * t_cose_sign1_encode_parameters() is called.
195  *
196  * The IANA Media Types registry can be found
197  * [here](https://www.iana.org/assignments/media-types/media-types.xhtml).
198  * These have been known as MIME types in the past.
199  */
200 static inline void
201 t_cose_sign1_set_content_type_tstr(struct t_cose_sign1_sign_ctx *context,
202                                    const char                   *content_type);
203 #endif /* T_COSE_DISABLE_CONTENT_TYPE */
204 
205 
206 
207 /**
208  * \brief  Create and sign a \c COSE_Sign1 message with a payload.
209  *
210  * \param[in] context  The t_cose signing context.
211  * \param[in] payload  Pointer and length of payload to sign.
212  * \param[in] out_buf  Pointer and length of buffer to output to.
213  * \param[out] result  Pointer and length of the resulting \c COSE_Sign1.
214  *
215  * The \c context must have been initialized with
216  * t_cose_sign1_sign_init() and the key set with
217  * t_cose_sign1_set_signing_key() before this is called.
218  *
219  * This creates the COSE header parameter, hashes and signs the
220  * payload and creates the signature. \c out_buf gives the pointer and
221  * length memory into which the output is written. The pointer and
222  * length of the actual \c COSE_Sign1 is returned in \c result.
223  *
224  * Typically, the required size of \c out_buf is about 30 bytes plus
225  * the size of the signature and the size of the key ID. This is about
226  * 150 bytes for ECDSA 256 with a 32-byte key ID.
227  *
228  * To compute the size of the buffer needed before it is allocated
229  * call this with \c out_buf containing a \c NULL pointer and large
230  * length like \c UINT32_MAX.  The algorithm and key, kid and such
231  * must be set up just as if the real \c COSE_Sign1 were to be created
232  * as these values are needed to compute the size correctly.  The
233  * contents of \c result will be a \c NULL pointer and the length of
234  * the \c COSE_Sign1. When this is run like this, the cryptographic
235  * functions will not actually run, but the size of their output will
236  * be taken into account to give an exact size.
237  *
238  * This function requires the payload be complete and formatted in a
239  * contiguous buffer. The resulting \c COSE_Sign1 message also
240  * contains the payload preceded by the header parameters and followed
241  * by the signature, all CBOR formatted. This function thus requires
242  * two copies of the payload to be in memory.  Alternatively
243  * t_cose_sign1_encode_parameters() and
244  * t_cose_sign1_encode_signature() can be used. They are more complex
245  * to use, but avoid the two copies of the payload.
246  */
247 enum t_cose_err_t
248 t_cose_sign1_sign(struct t_cose_sign1_sign_ctx *context,
249                   struct q_useful_buf_c         payload,
250                   struct q_useful_buf           out_buf,
251                   struct q_useful_buf_c        *result);
252 
253 
254 /**
255  * \brief  Output first part and parameters for a \c COSE_Sign1 message.
256  *
257  * \param[in] context          The t_cose signing context.
258  * \param[in] cbor_encode_ctx  Encoding context to output to.
259  *
260  * This is the more complex and more memory efficient alternative to
261  * t_cose_sign1_sign(). Like t_cose_sign1_sign(),
262  * t_cose_sign1_sign_init() and t_cose_sign1_set_signing_key() must be
263  * called before calling this.
264  *
265  * When this is called, the opening parts of the \c COSE_Sign1 message
266  * are output to the \c cbor_encode_ctx.
267  *
268  * After this is called, the CBOR-formatted payload must be written to
269  * the \c cbor_encode_ctx by calling all the various
270  * \c QCBOREncode_AddXxx calls. It can be as simple or complex as needed.
271  *
272  * To complete the \c COSE_Sign1 call t_cose_sign1_encode_signature().
273  *
274  * The \c cbor_encode_ctx must have been initialized with an output
275  * buffer to hold the \c COSE_Sign1 header parameters, the payload and the
276  * signature.
277  *
278  * This and t_cose_sign1_encode_signature() can be used to calculate
279  * the size of the \c COSE_Sign1 in the way \c QCBOREncode is usually
280  * used to calculate sizes. In this case the \c t_cose_sign1_ctx must
281  * be initialized with the options, algorithm, key and kid just as
282  * normal as these are needed to calculate the size. Then set up the
283  * QCBOR encoder context with a \c NULL pointer and large length like
284  * \c UINT32_MAX.  Call t_cose_sign1_encode_parameters(), then format
285  * the payload into the encoder context, then call
286  * t_cose_sign1_encode_signature().  Finally call \c
287  * QCBOREncode_FinishGetSize() to get the length.
288  */
289 enum t_cose_err_t
290 t_cose_sign1_encode_parameters(struct t_cose_sign1_sign_ctx *context,
291                                QCBOREncodeContext           *cbor_encode_ctx);
292 
293 
294 /**
295  * \brief Finish a \c COSE_Sign1 message by outputting the signature.
296  *
297  * \param[in] context          The t_cose signing context.
298  * \param[in] cbor_encode_ctx  Encoding context to output to.
299  *
300  * \return This returns one of the error codes defined by \ref t_cose_err_t.
301  *
302  * Call this to complete creation of a signed \c COSE_Sign1 started
303  * with t_cose_sign1_encode_parameters().
304  *
305  * This is when the cryptographic signature algorithm is run.
306  *
307  * The completed \c COSE_Sign1 message is retrieved from the
308  * \c cbor_encode_ctx by calling \c QCBOREncode_Finish().
309  */
310 enum t_cose_err_t
311 t_cose_sign1_encode_signature(struct t_cose_sign1_sign_ctx *context,
312                               QCBOREncodeContext           *cbor_encode_ctx);
313 
314 
315 
316 
317 
318 
319 /* ------------------------------------------------------------------------
320  * Inline implementations of public functions defined above.
321  */
322 static inline void
t_cose_sign1_sign_init(struct t_cose_sign1_sign_ctx * me,int32_t option_flags,int32_t cose_algorithm_id)323 t_cose_sign1_sign_init(struct t_cose_sign1_sign_ctx *me,
324                        int32_t                       option_flags,
325                        int32_t                       cose_algorithm_id)
326 {
327     memset(me, 0, sizeof(*me));
328 #ifndef T_COSE_DISABLE_CONTENT_TYPE
329     /* Only member for which 0 is not the empty state */
330     me->content_type_uint = T_COSE_EMPTY_UINT_CONTENT_TYPE;
331 #endif
332 
333     me->cose_algorithm_id = cose_algorithm_id;
334     me->option_flags      = option_flags;
335 }
336 
337 
338 static inline void
t_cose_sign1_set_signing_key(struct t_cose_sign1_sign_ctx * me,struct t_cose_key signing_key,struct q_useful_buf_c kid)339 t_cose_sign1_set_signing_key(struct t_cose_sign1_sign_ctx *me,
340                              struct t_cose_key             signing_key,
341                              struct q_useful_buf_c         kid)
342 {
343     me->kid         = kid;
344     me->signing_key = signing_key;
345 }
346 
347 
348 #ifndef T_COSE_DISABLE_CONTENT_TYPE
349 static inline void
t_cose_sign1_set_content_type_uint(struct t_cose_sign1_sign_ctx * me,uint16_t content_type)350 t_cose_sign1_set_content_type_uint(struct t_cose_sign1_sign_ctx *me,
351                                    uint16_t                     content_type)
352 {
353     me->content_type_uint = content_type;
354 }
355 
356 
357 static inline void
t_cose_sign1_set_content_type_tstr(struct t_cose_sign1_sign_ctx * me,const char * content_type)358 t_cose_sign1_set_content_type_tstr(struct t_cose_sign1_sign_ctx *me,
359                                    const char                   *content_type)
360 {
361     me->content_type_tstr = content_type;
362 }
363 #endif
364 
365 #ifdef __cplusplus
366 }
367 #endif
368 
369 #endif /* __T_COSE_SIGN1_H__ */
370