1
2
3#  t_cose
4
5t_cose implements enough of COSE to support [CBOR Web Token, RFC 8392](https://tools.ietf.org/html/rfc8392)
6and [Entity Attestation Token (EAT)](https://tools.ietf.org/html/draft-ietf-rats-eat-01).
7This is the COSE_Sign1 part of [COSE, RFC 8152](https://tools.ietf.org/html/rfc8152).
8
9## Characteristics
10
11**Implemented in C with minimal dependency** – There are three main
12dependencies: 1) [QCBOR](https://github.com/laurencelundblade/QCBOR), 2) A
13cryptographic library for ECDSA and SHA-2, 3)  C99, <stdint.h>, <stddef.h>,
14<stdbool.h> and <string.h>.  It is intended to be highly portable to different HW, OS's and
15cryptographic libraries. No #ifdefs or compiler options  need to be set for it to run correctly.
16
17**Crypto Library Integration Layer** – t_cose can work with different cryptographic
18libraries via a simple integration layer. The integration layer is kept small and simple,
19just enough for the use cases, so that integration is simpler. An integration layer for
20Openssl is included (not complete yet).
21
22**Secure coding style** – Uses a construct called UsefulBuf / q_useful_buf as a
23discipline for very safe coding and handling of binary data.
24
25**Small simple memory model** – Malloc is not needed. The signing
26context is less than 100 bytes. Stack use is light and
27there is no recursion. The caller supplies the memory to hold the
28completed COSE_Sign1 and encode/decode contexts so caller has full control
29of memory usage making it good for embedded implementations that
30have to run in small fixed memory.
31
32## Code Status
33
34As of December 2019, the code is in reasonable working order and the public interface is
35fairly stable. There is a crypto adaptaion layer for [OpenSSL](https://www.openssl.org)
36and for [Arm MBed Crypto](https://github.com/ARMmbed/mbedTLS).
37
38### The to-do list:
39* Add some more tests, particular test vectors from C_COSE or such
40* General documentation clean up, spelling checks and formatting.
41
42## Building and Dependencies
43
44Except for the crypto library set up, t_cose is very portable and
45should largely just work in any environment. It needs a few standard
46libraries and [QCBOR](https://github.com/laurencelundblade/QCBOR)
47(which is also very portable). Hence the rest of this section is about
48crypto library set up.
49
50### Currently Supported Libraries
51
52Here's three crypto library configurations that are supported. Others
53can be added with relative ease over time.
54
55#### Test Crypto -- Makefile.test
56
57This configuration should work instantly on any device and is useful
58to do quite a large amount of testing with, but can't be put to full
59commercial use. What it lacks is any integration with an ECDSA
60implementation so it can't produce real ECDSA signatures. It does
61however produce some fake signatures called "short-circuit
62signatures" that are very useful for testing. See header
63documentation for details on short-circuit sigs.
64
65This configuration (and only this configuration) uses an bundled
66SHA-256 implementation (SHA-256 is simple and easy to bundle, ECDSA is
67not).
68
69To use this, edit the makefile for the location of QCBOR and then just
70do
71
72    make -f Makefile.test
73
74#### OpenSSL Crypto -- Makefile.ossl
75
76This OpenSSL integration supports SHA-256, SHA-384 and SHA-512 with
77ECDSA to support the COSE algorithms ES256, ES384 and ES512. It is a
78full and tested integration with OpenSSL crypto.
79
80To use this, edit the makefile for the location of QCBOR and OpenSSL
81and do:
82
83    make -f Makefile.ossl
84
85The specific things that Makefile.ossl does is:
86* Links the crypto_adapters/t_cose_openssl_crypto.o into libt_cose.a
87* Links test/test/t_cose_make_openssl_test_key.o into the test binary
88* `#define T_COSE_USE_OPENSSL_CRYPTO`
89
90Note that the internally supplied b_con_hash is not used in this case
91by virtue of the Makefile not linking to it.
92
93#### PSA Crypto -- Makefile.psa
94
95This build configuration works for Arm PSA Crypto compatible libraries
96like the MBed Crypto Library.
97
98This integration supports SHA-256, SHA-384 and SHA-512 with ECDSA to support
99the COSE algorithms ES256, ES384 and ES512. It is a full implementation but
100needs on-target testing.
101
102To use this, edit the makefile for the location of CBOR and your
103PSA-compatible cryptographic library and do:
104
105    make -f Makefile.psa
106
107The specific things that Makefile.psa does is:
108    * Links the crypto_adapters/t_cose_psa_crypto.o into libt_cose.a
109    * Links test/test/t_cose_make_psa_test_key.o into the test binary
110    * `#define T_COSE_USE_PSA_CRYPTO`
111
112Note that the internally supplied b_con_hash is not used in this case
113by virtue of the Makefile not linking to it.
114
115Following are some notes on things discovered doing this integration.
116
117PSA Crypto is an API that Arm is standardizing. As of December 2019
118it is close to complete after some years of development. It seems
119the 1.0 version is soon to be released. The API has
120evolved over these years and some of the earlier versions are not
121compatible with the current ones. There are commercial implementations
122using earlier APIs so this variation must be handled by the crypto
123adpatation layer here. There are no official mechanisms, like a
124#define to help handle variations in these older versions.
125
126The MBed Crypto Library is an implementation of the PSA Crypto API and
127is versions separately. Presumably there are or will be implementations of
128the PSA Crypto API that are not the MBed Crypto Library.
129
130t_cose has been made to work against the released 1.1.0 version of
131MBed released in June 2019 and the 2.0.0 version released in September
1322019. Also, it works against the 1.1 version that is in TF-M which has
133different internals than the 1.1.0 version on the public GitHub.
134
135The PSA Crypto API in MBed 1.1.0 is different from that in MBed 2.0.0.
136t_cose has one configuration that covers both which hinges off a
137#define that happens to occur in 1.1.0 and not in 2.0.0. It can auto-detect
138which is which so you shouldn't have to worry about it. To overide
139the auto-detect `#define T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11`
140or `#define T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO20`.
141
142Presumably, this will soon become less messy with the release of
143PSA Crypto 1.0. Presumably the older implementations like MBed
144Crypto 1.1 will stop being used. Also, PSA Crypto 1.0 has
145official #defines to manage API versions.
146
147### General Crypto Library Strategy
148
149The functions that t_cose needs from the crypto library are all
150defined in src/t_cose_crypto.h.  This is a porting or adaption
151layer. There are no #ifdefs in the main t_cose code for different
152crypto libraries. When it needs a crypto function it just calls the
153interface defined in t_cose_crypto.h.
154
155When integrating t_cose with a new cryptographic library, what is
156necessary is to write some code, an "adaptor", that implements
157t_cose_crypto.h using the new target cryptographic library. This can
158be done without changes to any t_cose code for many cryptographic
159libraries. See the interface documentation in t_cose_crypto.h for what
160needs to be implemented.
161
162That said, there is one case where t_cose source code needs to be
163modified. This is for hash algorithm implementations that are linked
164into and run inline with t_cose and that have a context structure. In
165this case t_cose_crypto.h should be modified to use that context
166structure. Use the OpenSSL configuration as an example.
167
168To complete the set up for a new cryptographic library and test it, a
169new test adaptation file is also needed. This file makes public key
170pairs of the correct type for use with testing.  This file is usually
171named test/t_cose_make_xxxx_test_key.c and is linked in with the test
172app. The keys it makes are passed through t_cose untouched, through
173the t_cose_crypto.h interface into the underlying crypto.
174
175## Memory Usage
176
177### Code
178
179These are approximate numbers for 64-bit x86 code optimized for size
180
181* Common to signing and verifying:  515
182* Signing: 920 (742)
183* Verify: 1596
184* OpenSSL adaptor layer: 609
185* Total: 3710
186* Signing only total: 1813
187* Verify only total: 2509
188
189### Heap and stack
190Malloc is not used.
191
192Stack usage is less than 1KB for signing and for encryption.
193
194The design is such that only one copy of the COSE_Sign1 need be in memory. It makes
195use of special features in QCBOR to accomplish this.
196
197The payload to sign must be in one contiguous buffer and be passed in. It can be allocated
198however the caller wishes, even in ROM, since it is only read.
199
200A buffer to hold the signed COSE result must be passed in. It must be about 100 bytes
201larger than the combined size of the payload and key id for ECDSA 256. It can be
202allocated however the caller wishes.
203
204### Crypto library memory usage
205In addition to the above memory usage, the crypto library will use some stack and / or
206heap memory. This will vary quite a bit by crypto library. Some may use malloc. Some may
207not.
208
209So far no support for RSA is available, but since the keys and signatures are much bigger,
210it will up the memory usage a lot and may require use of malloc.
211
212The OpenSSL library does use malloc, even with ECDSA. Another implementation of ECDSA
213might not use malloc, as the keys are small enough.
214
215### Mixed code style
216QCBOR uses camelCase and t_cose follows
217[Arm's coding guidelines](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/tree/docs/contributing/coding_guide.rst)
218resulting in code with mixed styles. For better or worse, an Arm-style version of UsefulBuf
219is created and used and so there is a duplicate of UsefulBuf. The two are identical. They
220just have different names.
221
222## Limitations
223* The payload input and output and the signed structure input and output must be in
224contiguous memory.
225* Doesn't handle COSE string algorithm IDs. Only COSE integer algorithm IDs are handled.
226Thus far no string algorithm IDs have been assigned by IANA.
227* No way to add custom headers when creating signed messages or process them during
228verification.
229* Only ECDSA is supported so far (facilities are available to add others).
230* Does not handle CBOR indefinite length strings (indefinite length maps and arrays are handled).
231* Counter signatures are not supported.
232
233## Credit
234
235* Tamas Ban for lots code review comments, design ideas and porting to ARM PSA.
236* Rob Coombs, Shebu Varghese Kuriakose and other ARM folks for sponsorship.
237
238## Copyright and License
239
240t_cose is available under the 3-Clause BSD License.
241