Mistake on this page?
Report an issue in GitHub or email us
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  */
90 static 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  */
148 enum t_cose_err_t
149 t_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  */
206 enum t_cose_err_t
207 t_cose_crypto_pub_key_verify(int32_t cose_alg_id,
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  */
271 enum t_cose_err_t
272 t_cose_crypto_get_ec_pub_key(int32_t key_select,
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  */
343 enum 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  */
363 void t_cose_crypto_hash_update(struct t_cose_crypto_hash *hash_ctx,
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  */
392 enum 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  */
402 static 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__ */
This is a TF-M coding style version of UsefulBuf.
The context for use with the hash adaptation layer here.
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.
Defines common to all public t_cose interfaces.
The non-const UsefulBuf typically used for some allocated memory that is to be filled in...
Definition: UsefulBuf.h:160
static size_t t_cose_signature_size(int32_t cose_sig_alg_id)
Get the size in bytes of a particular signature type.
UsefulBufC and UsefulBuf are simple data structures to hold a pointer and length for a binary data...
Definition: UsefulBuf.h:149
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.
#define T_COSE_EC_P256_SIG_SIZE
Size of the signature output for the NIST P-256 Curve.
Definition: t_cose_crypto.h:67
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.
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.
#define COSE_ALGORITHM_ES256
Indicates ECDSA with SHA-256.
t_cose_err_t
Error codes return by t_cose.
Definition: t_cose_common.h:44
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_start(struct t_cose_crypto_hash *hash_ctx, int32_t cose_hash_alg_id)
Start cryptographic hash.
Constants from COSE standard and IANA registry.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.