Mbed OS Reference
Loading...
Searching...
No Matches
t_cose_sign1_sign.h File Reference

Create a COSE_Sign1, usually for EAT or CWT Token. More...

#include <stdint.h>
#include <stdbool.h>
#include "qcbor.h"
#include "t_cose_common.h"

Go to the source code of this file.

Data Structures

struct  t_cose_sign1_ctx
 This is the context for creating a COSE_Sign1 structure. More...
 

Functions

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. More...
 
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. More...
 

Detailed Description

Create a COSE_Sign1, usually for EAT or CWT Token.

This creates a COSE_Sign1 in compliance with [COSE (RFC 8152)] (https://tools.ietf.org/html/rfc8152). A COSE_Sign1 is a CBOR encoded binary blob that contains headers, a payload and a signature. Usually the signature is made with an EC signing algorithm like ECDSA.

This implementation is intended to be small and portable to different OS's and platforms. Its dependencies are:

  • QCBOR
  • <stdint.h>, <string.h>, <stddef.h>
  • Hash functions like SHA-256
  • Signing functions like ECDSA

There is a cryptographic adaptation layer defined in t_cose_crypto.h. An implementation can be made of the functions in it for different platforms or OS's. This means that different platforms and OS's may support only signing with a particular set of algorithms.

This COSE_Sign1 implementations is optimized for creating EAT tokens.

It should work for CWT and others use cases too. The main point of the optimization is that only one output buffer is needed. There is no need for one buffer to hold the payload and another to hold the end result COSE_Sign1. The payload is encoded right into its final place in the end result COSE_Sign1.

Definition in file t_cose_sign1_sign.h.

Function Documentation

◆ t_cose_sign1_init()

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.

Parameters
[in]meThe t_cose signing context.
[in]short_circuit_signtrue to select special test mode.
[in]cose_algorithm_idThe algorithm to sign with. The IDs are defined in [COSE (RFC 8152)] (https://tools.ietf.org/html/rfc8152) or in the [IANA COSE Registry] (https://www.iana.org/assignments/cose/cose.xhtml).
[in]key_selectWhich signing key to use.
[in]cbor_encode_ctxThe CBOR encoder context to output to.
Returns
This returns one of the error codes defined by t_cose_err_t.

It is possible to use this to compute the exact size of the resulting token so the exact sized buffer can be allocated. To do this initialize the cbor_encode_ctx with UsefulBufC that has a NULL pointer and large length like UINT32_MAX. Then run the normal token creation. The result will have a NULL pointer and the length of the token that would have been created. When this is run like this, the cryptographic functions will not actually run, but the size of their output will be taken into account.

The key selection depends on the platform / OS.

Which signing algorithms are supported depends on the platform/OS. The header file t_cose_defines.h contains defined constants for some of them. A typical example is COSE_ALGORITHM_ES256 which indicates ECDSA with the NIST P-256 curve and SHA-256.

To use this, create a QCBOREncodeContext and initialize it with an output buffer big enough to hold the payload and the COSE Sign 1 overhead. This overhead is about 30 bytes plus the size of the signature and the size of the key ID.

After the QCBOREncodeContext is initialized, call t_cose_sign1_init() on it.

Next call QCBOREncode_BstrWrap() to indicate the start of the payload.

Next call various QCBOREncode_Addxxxx() methods to create the payload.

Next call QCBOREncode_CloseBstrWrap() to indicate the end of the payload. This will also return a pointer and length of the payload that gets hashed.

Next call t_cose_sign1_finish() with the pointer and length of the payload. This will do all the cryptography and complete the COSE Sign1.

Finally, call QCBOREncode_Finish() to get the pointer and length of the complete token.

This implements a special signing test mode called short circuit signing. This mode is useful when there is no signing key available, perhaps because it has not been provisioned or configured for the particular device. It may also be because the public key cryptographic functions have not been connected up in the cryptographic adaptation layer.

It has no value for security at all. Data signed this way should not be trusted as anyone can sign like this.

In this mode the signature is the hash of that would normally be signed by the public key algorithm. To make the signature the correct size for the particular algorithm instances of the hash are concatenated to pad it out.

This mode is very useful for testing because all the code except the actual signing algorithm is run exactly as it would if a proper signing algorithm was run.

The kid (Key ID) put in the unprotected headers is created as follows. The EC public key is CBOR encoded as a COSE_Key as defined in the COSE standard. That encoded CBOR is then hashed with SHA-256. This is similar to key IDs defined in IETF PKIX, but is based on COSE and CBOR rather than ASN.1.

◆ t_cose_sign1_finish()

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.

Parameters
[in]meThe t_cose signing context.
[in]payloadThe pointer and length of the payload.
Returns
This returns one of the error codes defined by t_cose_err_t.

Call this to complete creation of a signed token started with t_cose_sign1_init().

This is when the signature algorithm is run.

The payload parameter is used only to compute the hash for signing. The completed COSE_Sign1 is retrieved from the cbor_encode_ctx by calling QCBOREncode_Finish()