Mbed OS Reference
Loading...
Searching...
No Matches
t_cose_crypto.h
Go to the documentation of this file.
1/*
2 * t_cose_crypto.h
3 *
4 * Copyright 2019, Laurence Lundblade
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 *
8 * See BSD-3-Clause license in README.mdE.
9 */
10
11
12#ifndef __T_COSE_CRYPTO_H__
13#define __T_COSE_CRYPTO_H__
14
15#include "t_cose_common.h"
16#include "useful_buf.h"
17#include <stdint.h>
18#include "t_cose_defines.h"
19
20
21/**
22 * \file t_cose_crypto.h
23 *
24 * \brief This is the adaptation layer for cryptographic functions used by
25 * t_cose.
26 *
27 * This is small wrapper around the cryptographic functions to:
28 * - Map COSE algorithm IDs to TF-M algorithm IDs
29 * - Map crypto errors to \ref t_cose_err_t errors
30 * - Have inputs and outputs be \c struct \c useful_buf_c and
31 * \c struct \c useful_buf
32 * - Handle key selection
33 *
34 * The idea is that implementations can be made of these functions
35 * that adapt to various cryptographic libraries that are used on
36 * various platforms and OSs.
37 *
38 * This runs entirely off of COSE-style algorithm identifiers. They
39 * are simple integers and thus work nice as function parameters. An
40 * initial set is defined by [COSE (RFC 8152)]
41 * (https://tools.ietf.org/html/rfc8152). New ones can be registered
42 * in the [IANA COSE Registry]
43 * (https://www.iana.org/assignments/cose/cose.xhtml). Local use new
44 * ones can also be defined (\c \#define) if what is needed is not in
45 * the IANA registry.
46 *
47 * Binary data is returned to the caller using a \c struct \c
48 * useful_buf to pass the buffer to receive the data and its length in
49 * and a \c useful_buf_c to return the pointer and length of the
50 * returned data. The point of this is coding hygiene. The buffer
51 * passed in is not const as it is to be modified. The \c
52 * useful_buf_c returned is const.
53 *
54 * The pointer in the \c useful_buf_c will always point to the buffer
55 * passed in via the \c useful_buf so the lifetime of the data is
56 * under control of the caller.
57 *
58 * This is not intended as any sort of general cryptographic API. It
59 * is just the functions needed by t_cose in the form that is most
60 * useful for t_cose.
61 */
62
63
64/**
65 * Size of the signature output for the NIST P-256 Curve.
66 */
67#define T_COSE_EC_P256_SIG_SIZE 64
68
69/**
70 * Size of the largest signature of any of the algorithm types
71 * supported.
72 *
73 * This will have to be adjusted if support for other algorithms
74 * larger is added.
75 *
76 * This is a compile time constant so it can be used to define stack
77 * variable sizes.
78 */
79#define T_COSE_MAX_EC_SIG_SIZE T_COSE_EC_P256_SIG_SIZE
80
81
82/**
83 * \brief Get the size in bytes of a particular signature type.
84 *
85 * \param[in] cose_sig_alg_id The COSE algorithm ID.
86 *
87 * \return The size in bytes of the signature for a public-key signing
88 * algorithm.
89 */
90static inline size_t t_cose_signature_size(int32_t cose_sig_alg_id);
91
92
93/**
94 * \brief Perform public key signing. Part of the t_cose crypto
95 * adaptation layer.
96 *
97 * \param[in] cose_alg_id The algorithm to sign with. The IDs are
98 * defined in [COSE (RFC 8152)]
99 * (https://tools.ietf.org/html/rfc8152) or
100 * in the [IANA COSE Registry]
101 * (https://www.iana.org/assignments/cose/cose.xhtml).
102 * A proprietary ID can also be defined
103 * locally (\c \#define) if the needed
104 * one hasn't been registered.
105 * \param[in] key_select Indicates which key to use to sign.
106 * \param[in] hash_to_sign The bytes to sign. Typically, a hash of
107 * a payload.
108 * \param[in] signature_buffer Pointer and length of buffer into which
109 * the resulting signature is put.
110 * \param[in] signature Pointer and length of the signature
111 * returned.
112 *
113 * \retval T_COSE_SUCCESS
114 * Successfully created the signature.
115 * \retval T_COSE_ERR_SIG_BUFFER_SIZE
116 * The \c signature_buffer too small.
117 * \retval T_COSE_ERR_UNSUPPORTED_SIGNING_ALG
118 * The requested signing algorithm, \c cose_alg_id, is not
119 * supported.
120 * \retval T_COSE_ERR_UNKNOWN_KEY
121 * The key identified by \c key_select was not found.
122 * \retval T_COSE_ERR_WRONG_TYPE_OF_KEY
123 * The key was found, but it was the wrong type.
124 * \retval T_COSE_ERR_INVALID_ARGUMENT
125 * Some (unspecified) argument was not valid.
126 * \retval T_COSE_ERR_INSUFFICIENT_MEMORY
127 * Insufficient heap memory.
128 * \retval T_COSE_ERR_FAIL
129 * General unspecific failure.
130 * \retval T_COSE_ERR_TAMPERING_DETECTED
131 * Equivalent to \c PSA_ERROR_TAMPERING_DETECTED.
132 *
133 * This is called to do public key signing. The implementation will
134 * vary from one platform / OS to another but should conform to the
135 * description here.
136 *
137 * The key selection depends on the platform / OS.
138 *
139 * See the note in the Detailed Description (the \\file comment block)
140 * for details on how \c useful_buf and \c useful_buf_c are used to
141 * return the signature.
142 *
143 * To find out the size of the signature buffer needed, call this with
144 * \c signature_buffer->ptr \c NULL and \c signature_buffer->len a
145 * very large number like \c UINT32_MAX. The size will be returned in
146 * \c signature->len.
147 */
148enum t_cose_err_t
149t_cose_crypto_pub_key_sign(int32_t cose_alg_id,
150 int32_t key_select,
151 struct useful_buf_c hash_to_sign,
152 struct useful_buf signature_buffer,
153 struct useful_buf_c *signature);
154
155
156/**
157 * \brief perform public key signature verification. Part of the
158 * t_cose crypto adaptation layer.
159 *
160 * \param[in] cose_alg_id The algorithm to use for verification.
161 * The IDs are defined in [COSE (RFC 8152)]
162 * (https://tools.ietf.org/html/rfc8152)
163 * or in the [IANA COSE Registry]
164 * (https://www.iana.org/assignments/cose/cose.xhtml).
165 * A proprietary ID can also be defined
166 * locally (\c \#define) if the needed one
167 * hasn't been registered.
168 * \param[in] key_select Verification key selection.
169 * \param[in] key_id A key id or \c NULL_USEFUL_BUF_C.
170 * \param[in] hash_to_verify The data or hash that is to be verified.
171 * \param[in] signature The signature.
172 *
173 * This verifies that the \c signature passed in was over the \c
174 * hash_to_verify passed in.
175 *
176 * The public key used to verify the signature is selected by the \c
177 * key_id if it is not \c NULL_USEFUL_BUF_C or the \c key_select if it
178 * is.
179 *
180 * The key selected must be, or include, a public key of the correct
181 * type for \c cose_alg_id.
182 *
183 * \retval T_COSE_SUCCESS
184 * The signature is valid
185 * \retval T_COSE_ERR_SIG_VERIFY
186 * Signature verification failed. For example, the
187 * cryptographic operations completed successfully but hash
188 * wasn't as expected.
189 * \retval T_COSE_ERR_UNKNOWN_KEY
190 * The key identified by \c key_select or a \c kid was
191 * not found.
192 * \retval T_COSE_ERR_WRONG_TYPE_OF_KEY
193 * The key was found, but it was the wrong type
194 * for the operation.
195 * \retval T_COSE_ERR_UNSUPPORTED_SIGNING_ALG
196 * The requested signing algorithm is not supported.
197 * \retval T_COSE_ERR_INVALID_ARGUMENT
198 * Some (unspecified) argument was not valid.
199 * \retval T_COSE_ERR_INSUFFICIENT_MEMORY
200 * Out of heap memory.
201 * \retval T_COSE_ERR_FAIL
202 * General unspecific failure.
203 * \retval T_COSE_ERR_TAMPERING_DETECTED
204 * Equivalent to \c PSA_ERROR_TAMPERING_DETECTED.
205 */
206enum t_cose_err_t
208 int32_t key_select,
209 struct useful_buf_c key_id,
210 struct useful_buf_c hash_to_verify,
211 struct useful_buf_c signature);
212
213
214/**
215 * The size of X and Y coordinate in 2 parameter style EC public
216 * key. Format is as defined in [COSE (RFC 8152)]
217 * (https://tools.ietf.org/html/rfc8152) and [SEC 1: Elliptic Curve
218 * Cryptography](http://www.secg.org/sec1-v2.pdf).
219 *
220 * This size is well-known and documented in public standards.
221 */
222#define T_COSE_CRYPTO_EC_P256_COORD_SIZE 32
223
224
225/**
226 * \brief Get an elliptic curve public key. Part of the t_cose crypto
227 * adaptation layer.
228 *
229 * \param[in] key_select Used to look up the public
230 * key to return when \c kid is
231 * \c NULL_USEFUL_BUF_C.
232 * \param[in] kid A key ID to look up against. May be
233 * \c NULL_USEFUL_BUF_C. This is typically
234 * the kid from the COSE unprotected header.
235 * \param[out] cose_curve_id The curve ID of the key returned as
236 * defined by [COSE (RFC 8152)]
237 * (https://tools.ietf.org/html/rfc8152)
238 * or the IANA COSE registry.
239 * \param[in] buf_to_hold_x_coord Pointer and length into which the
240 * X coordinate is put.
241 * \param[in] buf_to_hold_y_coord Pointer and length into which the
242 * Y coordinate is put.
243 * \param[out] x_coord Pointer and length of the returned X
244 * coordinate.
245 * \param[out] y_coord Pointer and length of the returned Y
246 * coordinate.
247 *
248 * \retval T_COSE_SUCCESS
249 * The key was found and is returned.
250 * \retval T_COSE_ERR_UNKNOWN_KEY
251 * The key identified by \c key_select or a \c kid was not
252 * found.
253 * \retval T_COSE_ERR_WRONG_TYPE_OF_KEY
254 * The key was found, but it was the wrong type for the
255 * operation.
256 * \retval T_COSE_ERR_FAIL
257 * General unspecific failure.
258 * \retval T_COSE_ERR_KEY_BUFFER_SIZE
259 * Buffer to hold the output was too small.
260 *
261 * This finds and returns a public key. Where it looks for the key is
262 * dependent on the OS / platform.
263 *
264 * \ref T_COSE_CRYPTO_EC_P256_COORD_SIZE is the size of the X or Y
265 * coordinate for the NIST P-256 curve.
266 *
267 * See the note in the Detailed Description (the \\file comment block)
268 * for details on how \c useful_buf and \c useful_buf_c are used to
269 * return the X and Y coordinates.
270 */
271enum t_cose_err_t
273 struct useful_buf_c kid,
274 int32_t *cose_curve_id,
275 struct useful_buf buf_to_hold_x_coord,
276 struct useful_buf buf_to_hold_y_coord,
277 struct useful_buf_c *x_coord,
278 struct useful_buf_c *y_coord);
279
280
281/*
282 * No function to get private key because there is no need for it.
283 * The private signing key only needs to exist behind
284 * t_cose_crypto_pub_key_sign().
285 */
286
287
288
289
290/**
291 * The context for use with the hash adaptation layer here.
292 */
294 /* Can't put the actual size here without creating dependecy on
295 * actual hash implementation, so this is a fairly large and
296 * accommodating size.
297 */
298 uint8_t bytes[280];
299};
300
301
302/**
303 * The size of the output of SHA-256 in bytes.
304 *
305 * (It is safe to define this independently here as its size is
306 * well-known and fixed. There is no need to reference
307 * platform-specific headers and incur messy dependence.)
308 */
309#define T_COSE_CRYPTO_SHA256_SIZE 32
310
311
312/**
313 * \brief Start cryptographic hash. Part of the t_cose crypto
314 * adaptation layer.
315 *
316 * \param[in,out] hash_ctx Pointer to the hash context that
317 * will be initialized.
318 * \param[in] cose_hash_alg_id Algorithm ID that identifies the
319 * hash to use. This is from the
320 * [IANA COSE Registry]
321 * (https://www.iana.org/assignments/cose/cose.xhtml).
322 * As of the creation of this interface
323 * no identifiers of only a hash
324 * functions have been registered.
325 * Signature algorithms that include
326 * specification of the hash have been
327 * registered, but they are not to be
328 * used here. Until hash functions only
329 * have been officially registered, some
330 * IDs are defined in the proprietary
331 * space in t_cose_common.h.
332 *
333 * \retval T_COSE_ERR_UNSUPPORTED_HASH
334 * The requested algorithm is unknown or unsupported.
335 *
336 * \retval T_COSE_ERR_HASH_GENERAL_FAIL
337 * Some general failure of the hash function
338 *
339 * This initializes the hash context for the particular algorithm. It
340 * must be called first. A \c hash_ctx can be reused if it is
341 * reinitialized.
342 */
343enum t_cose_err_t
345 int32_t cose_hash_alg_id);
346
347
348/**
349 * \brief Feed data into a cryptographic hash. Part of the t_cose
350 * crypto adaptation layer.
351 *
352 * \param[in,out] hash_ctx Pointer to the hash context in which
353 * accumulate the hash.
354 * \param[in] data_to_hash Pointer and length of data to feed into
355 * hash. The pointer may by \c NULL in which
356 * case no hashing is performed.
357 *
358 * There is no return value. If an error occurs it is remembered in \c
359 * hash_ctx and returned when t_cose_crypto_hash_finish() is called.
360 * Once in the error state, this function may be called, but it will
361 * not do anything.
362 */
364 struct useful_buf_c data_to_hash);
365
366
367/**
368 * \brief Finish a cryptographic hash. Part of the t_cose crypto
369 * adaptation layer.
370 *
371 * \param[in,out] hash_ctx Pointer to the hash context.
372 * \param[in] buffer_to_hold_result Pointer and length into which
373 * the resulting hash is put.
374 * \param[out] hash_result Pointer and length of the
375 * resulting hash.
376 *
377 * \retval T_COSE_ERR_HASH_GENERAL_FAIL
378 * Some general failure of the hash function.
379 * \retval T_COSE_ERR_HASH_BUFFER_SIZE
380 * The size of the buffer to hold the hash result was
381 * too small.
382 *
383 * Call this to complete the hashing operation. If the everything
384 * completed correctly, the resulting hash is returned. Note that any
385 * errors that occurred during t_cose_crypto_hash_update() are
386 * returned here.
387 *
388 * See the note in the Detailed Description (the \\file comment block)
389 * for details on how \c useful_buf and \c useful_buf_c are used to
390 * return the hash.
391 */
392enum t_cose_err_t
394 struct useful_buf buffer_to_hold_result,
395 struct useful_buf_c *hash_result);
396
397
398
399/*
400 * Public inline function. See documentation above.
401 */
402static inline size_t t_cose_signature_size(int32_t cose_sig_alg_id)
403{
404 switch(cose_sig_alg_id) {
407 default:
409 }
410}
411
412
413#endif /* __T_COSE_CRYPTO_H__ */
The context for use with the hash adaptation layer here.
UsefulBufC and UsefulBuf are simple data structures to hold a pointer and length for a binary data.
Definition: UsefulBuf.h:149
The non-const UsefulBuf typically used for some allocated memory that is to be filled in.
Definition: UsefulBuf.h:160
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_crypto_pub_key_sign(int32_t cose_alg_id, int32_t key_select, struct useful_buf_c hash_to_sign, struct useful_buf signature_buffer, struct useful_buf_c *signature)
Perform public key signing.
enum t_cose_err_t t_cose_crypto_pub_key_verify(int32_t cose_alg_id, int32_t key_select, struct useful_buf_c key_id, struct useful_buf_c hash_to_verify, struct useful_buf_c signature)
perform public key signature verification.
void t_cose_crypto_hash_update(struct t_cose_crypto_hash *hash_ctx, struct useful_buf_c data_to_hash)
Feed data into a cryptographic hash.
enum t_cose_err_t t_cose_crypto_get_ec_pub_key(int32_t key_select, struct useful_buf_c kid, int32_t *cose_curve_id, struct useful_buf buf_to_hold_x_coord, struct useful_buf buf_to_hold_y_coord, struct useful_buf_c *x_coord, struct useful_buf_c *y_coord)
Get an elliptic curve public key.
enum t_cose_err_t t_cose_crypto_hash_finish(struct t_cose_crypto_hash *hash_ctx, struct useful_buf buffer_to_hold_result, struct useful_buf_c *hash_result)
Finish a cryptographic hash.
enum t_cose_err_t t_cose_crypto_hash_start(struct t_cose_crypto_hash *hash_ctx, int32_t cose_hash_alg_id)
Start cryptographic hash.
#define T_COSE_EC_P256_SIG_SIZE
Size of the signature output for the NIST P-256 Curve.
Definition: t_cose_crypto.h:67
Constants from COSE standard and IANA registry.
#define COSE_ALGORITHM_ES256
Indicates ECDSA with SHA-256.
This is a TF-M coding style version of UsefulBuf.