Skip to content

Commit afecb9a

Browse files
authored
Merge pull request RIOT-OS#12562 from kaspar030/pr/suit_v4_nanocbor
sys/suit/v4: switch to nanocbor
2 parents 1c624e4 + 4ccb4e5 commit afecb9a

File tree

5 files changed

+173
-197
lines changed

5 files changed

+173
-197
lines changed

Makefile.dep

+1-1
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ ifneq (,$(filter suit_v4_%,$(USEMODULE)))
937937
endif
938938

939939
ifneq (,$(filter suit_v4,$(USEMODULE)))
940-
USEPKG += tinycbor
940+
USEPKG += nanocbor
941941
USEPKG += libcose
942942
USEMODULE += libcose_crypt_c25519
943943
USEMODULE += suit_conditions

sys/include/suit/v4/handlers.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
#include "suit/v4/suit.h"
3131
#include "uuid.h"
32-
#include "cbor.h"
32+
#include "nanocbor/nanocbor.h"
3333

3434
#ifdef __cplusplus
3535
extern "C" {
@@ -39,12 +39,12 @@ extern "C" {
3939
* @brief suit handler prototype
4040
*
4141
* @param manifest SUIT v4 manifest context
42-
* @param it CborValue iterator to the content the handler must handle
42+
* @param it nanocbor_value_t iterator to the content the handler must handle
4343
*
4444
* @return 1 on success
4545
* @return negative on error
4646
*/
47-
typedef int (*suit_manifest_handler_t)(suit_v4_manifest_t *manifest, int key, CborValue *it);
47+
typedef int (*suit_manifest_handler_t)(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it);
4848

4949
/**
5050
* @brief Get suit manifest handler for given integer key

sys/include/suit/v4/suit.h

+14-20
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include <stdint.h>
2727

2828
#include "cose/sign.h"
29-
#include "cbor.h"
29+
#include "nanocbor/nanocbor.h"
3030
#include "uuid.h"
3131
#include "riotboot/flashwrite.h"
3232

@@ -73,11 +73,6 @@ typedef enum {
7373
SUIT_ERR_SIGNATURE = -6, /**< Unable to verify signature */
7474
} suit_v4_error_t;
7575

76-
/**
77-
* @brief TinyCBOR validation mode to use
78-
*/
79-
#define SUIT_TINYCBOR_VALIDATION_MODE CborValidateStrictMode
80-
8176
/**
8277
* @brief SUIT payload digest algorithms
8378
*
@@ -121,9 +116,9 @@ enum {
121116
*/
122117
typedef struct {
123118
uint32_t size; /**< Size */
124-
CborValue identifier; /**< Identifier*/
125-
CborValue url; /**< Url */
126-
CborValue digest; /**< Digest */
119+
nanocbor_value_t identifier; /**< Identifier*/
120+
nanocbor_value_t url; /**< Url */
121+
nanocbor_value_t digest; /**< Digest */
127122
} suit_v4_component_t;
128123

129124
/**
@@ -139,7 +134,7 @@ typedef struct {
139134
/** List of components in the manifest */
140135
suit_v4_component_t components[SUIT_V4_COMPONENT_MAX];
141136
unsigned components_len; /**< Current number of components */
142-
int component_current; /**< Current component index */
137+
int32_t component_current; /**< Current component index */
143138
riotboot_flashwrite_t *writer; /**< Pointer to the riotboot flash writer */
144139
/** Manifest validation buffer */
145140
uint8_t validation_buf[SUIT_COSE_BUF_SIZE];
@@ -191,7 +186,7 @@ int suit_v4_policy_check(suit_v4_manifest_t *manifest);
191186
* @return SUIT_OK when initialization is successful
192187
* @return SUIT_ERR_INVALID_MANIFEST if the manifest is not a cbor container
193188
*/
194-
int suit_cbor_map_iterate_init(CborValue *map, CborValue *it);
189+
int suit_cbor_map_iterate_init(nanocbor_value_t *map, nanocbor_value_t *it);
195190

196191
/**
197192
* @brief Iterate over a cbor map container
@@ -203,18 +198,18 @@ int suit_cbor_map_iterate_init(CborValue *map, CborValue *it);
203198
* @return 0 when the iterator is already at the end of the container
204199
* @return the number of returned (key, value) pair, e.g. 1
205200
*/
206-
int suit_cbor_map_iterate(CborValue *it, CborValue *key, CborValue *value);
201+
int suit_cbor_map_iterate(nanocbor_value_t *it, nanocbor_value_t *key, nanocbor_value_t *value);
207202

208203
/**
209-
* @brief Get cbor value as int
204+
* @brief Get cbor value as int32_t
210205
*
211206
* @param[in] it cbor container iterator
212207
* @param[out] out address of the returned integer
213208
*
214209
* @return SUIT_OK on success
215210
* @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit in an int
216211
*/
217-
int suit_cbor_get_int(const CborValue *it, int *out);
212+
int suit_cbor_get_int32(nanocbor_value_t *it, int32_t *out);
218213

219214
/**
220215
* @brief Get cbor value as unsigned
@@ -226,7 +221,7 @@ int suit_cbor_get_int(const CborValue *it, int *out);
226221
* @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit or cannot
227222
* be converted to unsigned
228223
*/
229-
int suit_cbor_get_uint(const CborValue *it, unsigned *out);
224+
int suit_cbor_get_uint(nanocbor_value_t *it, unsigned *out);
230225

231226
/**
232227
* @brief Get cbor value as unsigned long
@@ -238,7 +233,7 @@ int suit_cbor_get_uint(const CborValue *it, unsigned *out);
238233
* @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit or cannot
239234
* be converted to unsigned long
240235
*/
241-
int suit_cbor_get_uint32(const CborValue *it, uint32_t *out);
236+
int suit_cbor_get_uint32(nanocbor_value_t *it, uint32_t *out);
242237

243238
/**
244239
* @brief Get cbor value as string
@@ -250,20 +245,19 @@ int suit_cbor_get_uint32(const CborValue *it, uint32_t *out);
250245
* @return SUIT_OK on success
251246
* @return SUIT_ERR_INVALID_MANIFEST if value is not a valid string
252247
*/
253-
int suit_cbor_get_string(const CborValue *it, const uint8_t **buf, size_t *len);
248+
int suit_cbor_get_string(nanocbor_value_t *it, const uint8_t **buf, size_t *len);
254249

255250
/**
256251
* @brief Parser a cbor subsequence
257252
*
258-
* @param[in] parser ptr to cbor subparser
259-
* @param[out] bseq subsequence value
253+
* @param[in] bseq subsequence value
260254
* @param[out] it cbor iterator
261255
*
262256
* @return 0 on success
263257
* @return -1 if bseq is not a cbor string
264258
* @return CborError code on other cbor parser errors
265259
*/
266-
int suit_cbor_subparse(CborParser *parser, CborValue *bseq, CborValue *it);
260+
int suit_cbor_subparse(nanocbor_value_t *bseq, nanocbor_value_t *it);
267261

268262
/**
269263
* @brief Helper function for writing bytes on flash a specified offset

sys/suit/v4/cbor.c

+58-74
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "suit/v4/handlers.h"
2727
#include "suit/v4/suit.h"
2828
#include "suit/v4/policy.h"
29-
#include "cbor.h"
29+
#include "nanocbor/nanocbor.h"
3030
#include "cose/sign.h"
3131

3232
#include "public_key.h"
@@ -40,135 +40,116 @@
4040
static suit_manifest_handler_t _manifest_get_auth_wrapper_handler(int key);
4141
typedef suit_manifest_handler_t (*suit_manifest_handler_getter_t)(int key);
4242

43-
int suit_cbor_map_iterate_init(CborValue *map, CborValue *it)
43+
int suit_cbor_map_iterate_init(nanocbor_value_t *map, nanocbor_value_t *it)
4444
{
45-
if (!cbor_value_is_map(map)) {
45+
if (nanocbor_get_type(map) != NANOCBOR_TYPE_MAP) {
4646
LOG_INFO("suit_v4_parse(): manifest not a map\n)");
4747
return SUIT_ERR_INVALID_MANIFEST;
4848
}
4949

50-
cbor_value_enter_container(map, it);
50+
nanocbor_enter_map(map, it);
5151

5252
return SUIT_OK;
5353
}
5454

55-
int suit_cbor_map_iterate(CborValue *it, CborValue *key, CborValue *value)
55+
int suit_cbor_map_iterate(nanocbor_value_t *it, nanocbor_value_t *key,
56+
nanocbor_value_t *value)
5657
{
57-
if (cbor_value_at_end(it)) {
58+
if (nanocbor_at_end(it)) {
5859
return 0;
5960
}
6061

6162
*key = *it;
62-
cbor_value_advance(it);
63+
nanocbor_skip(it);
6364

6465
*value = *it;
65-
cbor_value_advance(it);
66+
nanocbor_skip(it);
6667

6768
return 1;
6869
}
6970

70-
int suit_cbor_get_int(const CborValue *it, int *out)
71+
int suit_cbor_get_int32(nanocbor_value_t *it, int32_t *out)
7172
{
72-
if (!cbor_value_is_integer(it)) {
73-
LOG_DEBUG("expected integer type, got %u\n", cbor_value_get_type(it));
74-
return SUIT_ERR_INVALID_MANIFEST;
75-
}
73+
int res = nanocbor_get_int32(it, out);
7674

77-
/* This check tests whether the integer fits into "int", thus the check
78-
* is platform dependent. This is for lack of specification of actually
79-
* allowed values, to be made explicit at some point. */
80-
if (cbor_value_get_int_checked(it, out) == CborErrorDataTooLarge) {
81-
LOG_DEBUG("integer doesn't fit into int type\n");
75+
if (res < NANOCBOR_OK) {
76+
LOG_DEBUG("suit_cbor_get_int32() error %u\n", res);
8277
return SUIT_ERR_INVALID_MANIFEST;
8378
}
8479

8580
return SUIT_OK;
8681
}
8782

88-
int suit_cbor_get_string(const CborValue *it, const uint8_t **buf, size_t *len)
83+
int suit_cbor_get_string(nanocbor_value_t *it, const uint8_t **buf, size_t *len)
8984
{
90-
if (!(cbor_value_is_text_string(it) || cbor_value_is_byte_string(it) || cbor_value_is_length_known(it))) {
85+
if (nanocbor_get_type(it) == NANOCBOR_TYPE_TSTR) {
86+
if (nanocbor_get_tstr(it, buf, len) < 0) {
87+
return SUIT_ERR_INVALID_MANIFEST;
88+
}
89+
return SUIT_OK;
90+
}
91+
else if (nanocbor_get_type(it) == NANOCBOR_TYPE_BSTR) {
92+
if (nanocbor_get_bstr(it, buf, len) < 0) {
93+
return SUIT_ERR_INVALID_MANIFEST;
94+
}
95+
return SUIT_OK;
96+
}
97+
else {
98+
LOG_DEBUG("suit_cbor_get_string(): unexpected type: %i\n",
99+
nanocbor_get_type(it));
91100
return SUIT_ERR_INVALID_MANIFEST;
92101
}
93-
CborValue next = *it;
94-
cbor_value_get_string_length(it, len);
95-
cbor_value_advance(&next);
96-
*buf = next.ptr - *len;
97-
return SUIT_OK;
98102
}
99103

100-
int suit_cbor_get_uint32(const CborValue *it, uint32_t *out)
104+
int suit_cbor_get_uint32(nanocbor_value_t *it, uint32_t *out)
101105
{
102-
int res;
103-
int64_t val;
104-
if (!cbor_value_is_unsigned_integer(it)) {
105-
return CborErrorIllegalType;
106-
}
107-
if ((res = cbor_value_get_int64_checked(it, &val))) {
108-
return res;
109-
}
110-
if (val > 0xFFFFFFFF) {
111-
return CborErrorDataTooLarge;
106+
if (nanocbor_get_uint32(it, out) < 0) {
107+
return SUIT_ERR_INVALID_MANIFEST;
112108
}
113-
*out = (val & 0xFFFFFFFF);
114-
115-
return CborNoError;
109+
return SUIT_OK;
116110
}
117111

118-
int suit_cbor_get_uint(const CborValue *it, unsigned *out)
112+
int suit_cbor_get_uint(nanocbor_value_t *it, unsigned *out)
119113
{
120114
return suit_cbor_get_uint32(it, (uint32_t *)out);
121115
}
122116

123-
int suit_cbor_subparse(CborParser *parser, CborValue *bseq, CborValue *it)
117+
int suit_cbor_subparse(nanocbor_value_t *bseq, nanocbor_value_t *it)
124118
{
125119
const uint8_t *bytes;
126120
size_t bytes_len = 0;
127-
128-
if (!cbor_value_is_byte_string(bseq)) {
129-
LOG_DEBUG("suit_cbor_subparse(): bseq not a byte string\n");
130-
return -1;
121+
int res = suit_cbor_get_string(bseq, &bytes, &bytes_len);
122+
if (res != SUIT_OK) {
123+
return res;
131124
}
132-
133-
suit_cbor_get_string(bseq, &bytes, &bytes_len);
134-
135-
return cbor_parser_init(bytes, bytes_len, SUIT_TINYCBOR_VALIDATION_MODE, parser,
136-
it);
125+
nanocbor_decoder_init(it, bytes, bytes_len);
126+
return SUIT_OK;
137127
}
138128

139129
static int _v4_parse(suit_v4_manifest_t *manifest, const uint8_t *buf,
140-
size_t len, suit_manifest_handler_getter_t getter)
130+
size_t len, suit_manifest_handler_getter_t getter)
141131
{
132+
nanocbor_value_t it, map, key, value;
142133

143-
CborParser parser;
144-
CborValue it, map, key, value;
145-
CborError err = cbor_parser_init(buf, len, SUIT_TINYCBOR_VALIDATION_MODE,
146-
&parser, &it);
147-
148-
if (err != 0) {
149-
return SUIT_ERR_INVALID_MANIFEST;
150-
}
134+
nanocbor_decoder_init(&it, buf, len);
151135

152136
map = it;
153137

154138
if (suit_cbor_map_iterate_init(&map, &it) != SUIT_OK) {
155-
LOG_DEBUG("manifest not a map!\n");
139+
LOG_DEBUG("suit _v4_parse(): manifest not a map!\n");
156140
return SUIT_ERR_INVALID_MANIFEST;
157141
}
158142

159-
LOG_DEBUG("jumping into map\n)");
160-
161143
while (suit_cbor_map_iterate(&it, &key, &value)) {
162-
int integer_key;
163-
if (suit_cbor_get_int(&key, &integer_key) != SUIT_OK){
144+
int32_t integer_key;
145+
if (suit_cbor_get_int32(&key, &integer_key) != SUIT_OK) {
164146
return SUIT_ERR_INVALID_MANIFEST;
165147
}
166-
LOG_DEBUG("got key val=%i\n", integer_key);
148+
LOG_DEBUG("got key val=%" PRIi32 "\n", integer_key);
167149
suit_manifest_handler_t handler = getter(integer_key);
168150

169151
if (handler) {
170152
int res = handler(manifest, integer_key, &value);
171-
LOG_DEBUG("handler res=%i\n", res);
172153
if (res < 0) {
173154
LOG_INFO("handler returned <0\n)");
174155
return SUIT_ERR_INVALID_MANIFEST;
@@ -179,20 +160,21 @@ static int _v4_parse(suit_v4_manifest_t *manifest, const uint8_t *buf,
179160
}
180161
}
181162

182-
cbor_value_leave_container(&map, &it);
163+
nanocbor_leave_container(&map, &it);
183164

184165
return SUIT_OK;
185166
}
186167

187168
int suit_v4_parse(suit_v4_manifest_t *manifest, const uint8_t *buf,
188-
size_t len)
169+
size_t len)
189170
{
190171
manifest->buf = buf;
191172
manifest->len = len;
192173
return _v4_parse(manifest, buf, len, _manifest_get_auth_wrapper_handler);
193174
}
194175

195-
static int _auth_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
176+
static int _auth_handler(suit_v4_manifest_t *manifest, int key,
177+
nanocbor_value_t *it)
196178
{
197179
(void)key;
198180
const uint8_t *cose_buf;
@@ -211,7 +193,8 @@ static int _auth_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
211193
return 0;
212194
}
213195

214-
static int _manifest_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
196+
static int _manifest_handler(suit_v4_manifest_t *manifest, int key,
197+
nanocbor_value_t *it)
215198
{
216199
(void)key;
217200
const uint8_t *manifest_buf;
@@ -238,19 +221,20 @@ static int _manifest_handler(suit_v4_manifest_t *manifest, int key, CborValue *i
238221

239222
LOG_INFO("suit: verifying manifest signature...\n");
240223
int verification = cose_sign_verify(&manifest->verify, &signature,
241-
&pkey, manifest->validation_buf, SUIT_COSE_BUF_SIZE);
224+
&pkey, manifest->validation_buf,
225+
SUIT_COSE_BUF_SIZE);
242226
if (verification != 0) {
243227
LOG_INFO("Unable to validate signature\n");
244228
return SUIT_ERR_SIGNATURE;
245229
}
246230

247231
return _v4_parse(manifest, manifest_buf,
248-
manifest_len, suit_manifest_get_manifest_handler);
232+
manifest_len, suit_manifest_get_manifest_handler);
249233
}
250234

251235
static suit_manifest_handler_t _suit_manifest_get_handler(int key,
252-
const suit_manifest_handler_t *handlers,
253-
size_t len)
236+
const suit_manifest_handler_t *handlers,
237+
size_t len)
254238
{
255239
if (key < 0 || (size_t)key >= len) {
256240
return NULL;

0 commit comments

Comments
 (0)