Mbed OS Reference
Loading...
Searching...
No Matches
t_cose_sign1_sign.h
Go to the documentation of this file.
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.h"
17#include "t_cose_common.h"
18
19
20/**
21 * \file t_cose_sign1_sign.h
22 *
23 * \brief Create a \c COSE_Sign1, usually for EAT or CWT Token.
24 *
25 * This creates a \c COSE_Sign1 in compliance with [COSE (RFC 8152)]
26 * (https://tools.ietf.org/html/rfc8152). A \c COSE_Sign1 is a CBOR
27 * encoded binary blob that contains headers, a payload and a
28 * signature. Usually the signature is made with an EC signing
29 * algorithm like ECDSA.
30 *
31 * This implementation is intended to be small and portable to
32 * different OS's and platforms. Its dependencies are:
33 * - QCBOR
34 * - <stdint.h>, <string.h>, <stddef.h>
35 * - Hash functions like SHA-256
36 * - Signing functions like ECDSA
37 *
38 * There is a cryptographic adaptation layer defined in
39 * t_cose_crypto.h. An implementation can be made of the functions in
40 * it for different platforms or OS's. This means that different
41 * platforms and OS's may support only signing with a particular set
42 * of algorithms.
43 *
44 * This \c COSE_Sign1 implementations is optimized for creating EAT
45 * tokens.
46 *
47 * It should work for CWT and others use cases too. The main point of
48 * the optimization is that only one output buffer is needed. There is
49 * no need for one buffer to hold the payload and another to hold the
50 * end result \c COSE_Sign1. The payload is encoded right into its final
51 * place in the end result \c COSE_Sign1.
52 */
53
54
55/**
56 * This is the context for creating a \c COSE_Sign1 structure. The caller
57 * should allocate it and pass it to the functions here. This is
58 * about 32 bytes so it fits easily on the stack.
59 */
61 /* Private data structure */
62 uint8_t buffer_for_protected_headers[
63 T_COSE_SIGN1_MAX_PROT_HEADER];
64 struct useful_buf_c protected_headers;
65 int32_t cose_algorithm_id;
66 int32_t key_select;
67 bool short_circuit_sign;
68 QCBOREncodeContext *cbor_encode_ctx;
69};
70
71
72/**
73 * \brief Initialize to start creating a \c COSE_Sign1.
74 *
75 * \param[in] me The t_cose signing context.
76 * \param[in] short_circuit_sign \c true to select special test mode.
77 * \param[in] cose_algorithm_id The algorithm to sign with. The IDs are
78 * defined in [COSE (RFC 8152)]
79 * (https://tools.ietf.org/html/rfc8152) or
80 * in the [IANA COSE Registry]
81 * (https://www.iana.org/assignments/cose/cose.xhtml).
82 * \param[in] key_select Which signing key to use.
83 * \param[in] cbor_encode_ctx The CBOR encoder context to output to.
84 *
85 * \return This returns one of the error codes defined by \ref t_cose_err_t.
86 *
87 * It is possible to use this to compute the exact size of the
88 * resulting token so the exact sized buffer can be allocated. To do
89 * this initialize the \c cbor_encode_ctx with \c UsefulBufC that has
90 * a \c NULL pointer and large length like \c UINT32_MAX. Then run the
91 * normal token creation. The result will have a NULL pointer and the
92 * length of the token that would have been created. When this is run
93 * like this, the cryptographic functions will not actually run, but
94 * the size of their output will be taken into account.
95 *
96 * The key selection depends on the platform / OS.
97 *
98 * Which signing algorithms are supported depends on the platform/OS.
99 * The header file t_cose_defines.h contains defined constants for
100 * some of them. A typical example is \ref COSE_ALGORITHM_ES256 which
101 * indicates ECDSA with the NIST P-256 curve and SHA-256.
102 *
103 * To use this, create a \c QCBOREncodeContext and initialize it with
104 * an output buffer big enough to hold the payload and the COSE Sign 1
105 * overhead. This overhead is about 30 bytes plus the size of the
106 * signature and the size of the key ID.
107 *
108 * After the \c QCBOREncodeContext is initialized, call
109 * t_cose_sign1_init() on it.
110 *
111 * Next call \c QCBOREncode_BstrWrap() to indicate the start of the
112 * payload.
113 *
114 * Next call various \c QCBOREncode_Addxxxx() methods to create the
115 * payload.
116 *
117 * Next call \c QCBOREncode_CloseBstrWrap() to indicate the end of the
118 * payload. This will also return a pointer and length of the payload
119 * that gets hashed.
120 *
121 * Next call t_cose_sign1_finish() with the pointer and length of the
122 * payload. This will do all the cryptography and complete the COSE
123 * Sign1.
124 *
125 * Finally, call \c QCBOREncode_Finish() to get the pointer and length
126 * of the complete token.
127 *
128 * This implements a special signing test mode called _short_
129 * _circuit_ _signing_. This mode is useful when there is no signing
130 * key available, perhaps because it has not been provisioned or
131 * configured for the particular device. It may also be because the
132 * public key cryptographic functions have not been connected up in
133 * the cryptographic adaptation layer.
134 *
135 * It has no value for security at all. Data signed this way should
136 * not be trusted as anyone can sign like this.
137 *
138 * In this mode the signature is the hash of that would normally be
139 * signed by the public key algorithm. To make the signature the
140 * correct size for the particular algorithm instances of the hash are
141 * concatenated to pad it out.
142 *
143 * This mode is very useful for testing because all the code except
144 * the actual signing algorithm is run exactly as it would if a proper
145 * signing algorithm was run.
146 *
147 * The kid (Key ID) put in the unprotected headers is created as
148 * follows. The EC public key is CBOR encoded as a \c COSE_Key as
149 * defined in the COSE standard. That encoded CBOR is then
150 * hashed with SHA-256. This is similar to key IDs defined in IETF
151 * PKIX, but is based on COSE and CBOR rather than ASN.1.
152 */
154 bool short_circuit_sign,
155 int32_t cose_algorithm_id,
156 int32_t key_select,
157 QCBOREncodeContext *cbor_encode_ctx);
158
159
160/**
161 * \brief Finish creation of the \c COSE_Sign1.
162 *
163 * \param[in] me The t_cose signing context.
164 * \param[in] payload The pointer and length of the payload.
165 *
166 * \return This returns one of the error codes defined by \ref t_cose_err_t.
167 *
168 * Call this to complete creation of a signed token started with
169 * t_cose_sign1_init().
170 *
171 * This is when the signature algorithm is run.
172 *
173 * The payload parameter is used only to compute the hash for
174 * signing. The completed \c COSE_Sign1 is retrieved from the \c
175 * cbor_encode_ctx by calling \c QCBOREncode_Finish()
176 */
178 struct useful_buf_c payload);
179
180
181#endif /* __T_COSE_SIGN1_H__ */
Q C B O R E n c o d e / D e c o d e.
This is the context for creating a COSE_Sign1 structure.
UsefulBufC and UsefulBuf are simple data structures to hold a pointer and length for a binary data.
Definition: UsefulBuf.h:149
Defines common to all public t_cose interfaces.
t_cose_err_t
Error codes return by t_cose.
Definition: t_cose_common.h:44
enum t_cose_err_t t_cose_sign1_finish(struct t_cose_sign1_ctx *me, struct useful_buf_c payload)
Finish creation of the COSE_Sign1.
enum t_cose_err_t t_cose_sign1_init(struct t_cose_sign1_ctx *me, bool short_circuit_sign, int32_t cose_algorithm_id, int32_t key_select, QCBOREncodeContext *cbor_encode_ctx)
Initialize to start creating a COSE_Sign1.