diff --git a/Makefile.dep b/Makefile.dep index 8b0c36cc93..c3301ba5a3 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -937,7 +937,7 @@ ifneq (,$(filter suit_v4_%,$(USEMODULE))) endif ifneq (,$(filter suit_v4,$(USEMODULE))) - USEPKG += tinycbor + USEPKG += nanocbor USEPKG += libcose USEMODULE += libcose_crypt_c25519 USEMODULE += suit_conditions diff --git a/sys/include/suit/v4/handlers.h b/sys/include/suit/v4/handlers.h index c12b8bba60..9012dd8171 100644 --- a/sys/include/suit/v4/handlers.h +++ b/sys/include/suit/v4/handlers.h @@ -29,7 +29,7 @@ #include "suit/v4/suit.h" #include "uuid.h" -#include "cbor.h" +#include "nanocbor/nanocbor.h" #ifdef __cplusplus extern "C" { @@ -39,12 +39,12 @@ extern "C" { * @brief suit handler prototype * * @param manifest SUIT v4 manifest context - * @param it CborValue iterator to the content the handler must handle + * @param it nanocbor_value_t iterator to the content the handler must handle * * @return 1 on success * @return negative on error */ -typedef int (*suit_manifest_handler_t)(suit_v4_manifest_t *manifest, int key, CborValue *it); +typedef int (*suit_manifest_handler_t)(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it); /** * @brief Get suit manifest handler for given integer key diff --git a/sys/include/suit/v4/suit.h b/sys/include/suit/v4/suit.h index 5b3d3227bd..889e934be4 100644 --- a/sys/include/suit/v4/suit.h +++ b/sys/include/suit/v4/suit.h @@ -26,7 +26,7 @@ #include #include "cose/sign.h" -#include "cbor.h" +#include "nanocbor/nanocbor.h" #include "uuid.h" #include "riotboot/flashwrite.h" @@ -73,11 +73,6 @@ typedef enum { SUIT_ERR_SIGNATURE = -6, /**< Unable to verify signature */ } suit_v4_error_t; -/** - * @brief TinyCBOR validation mode to use - */ -#define SUIT_TINYCBOR_VALIDATION_MODE CborValidateStrictMode - /** * @brief SUIT payload digest algorithms * @@ -121,9 +116,9 @@ enum { */ typedef struct { uint32_t size; /**< Size */ - CborValue identifier; /**< Identifier*/ - CborValue url; /**< Url */ - CborValue digest; /**< Digest */ + nanocbor_value_t identifier; /**< Identifier*/ + nanocbor_value_t url; /**< Url */ + nanocbor_value_t digest; /**< Digest */ } suit_v4_component_t; /** @@ -139,7 +134,7 @@ typedef struct { /** List of components in the manifest */ suit_v4_component_t components[SUIT_V4_COMPONENT_MAX]; unsigned components_len; /**< Current number of components */ - int component_current; /**< Current component index */ + int32_t component_current; /**< Current component index */ riotboot_flashwrite_t *writer; /**< Pointer to the riotboot flash writer */ /** Manifest validation buffer */ uint8_t validation_buf[SUIT_COSE_BUF_SIZE]; @@ -191,7 +186,7 @@ int suit_v4_policy_check(suit_v4_manifest_t *manifest); * @return SUIT_OK when initialization is successful * @return SUIT_ERR_INVALID_MANIFEST if the manifest is not a cbor container */ -int suit_cbor_map_iterate_init(CborValue *map, CborValue *it); +int suit_cbor_map_iterate_init(nanocbor_value_t *map, nanocbor_value_t *it); /** * @brief Iterate over a cbor map container @@ -203,10 +198,10 @@ int suit_cbor_map_iterate_init(CborValue *map, CborValue *it); * @return 0 when the iterator is already at the end of the container * @return the number of returned (key, value) pair, e.g. 1 */ -int suit_cbor_map_iterate(CborValue *it, CborValue *key, CborValue *value); +int suit_cbor_map_iterate(nanocbor_value_t *it, nanocbor_value_t *key, nanocbor_value_t *value); /** - * @brief Get cbor value as int + * @brief Get cbor value as int32_t * * @param[in] it cbor container iterator * @param[out] out address of the returned integer @@ -214,7 +209,7 @@ int suit_cbor_map_iterate(CborValue *it, CborValue *key, CborValue *value); * @return SUIT_OK on success * @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit in an int */ -int suit_cbor_get_int(const CborValue *it, int *out); +int suit_cbor_get_int32(nanocbor_value_t *it, int32_t *out); /** * @brief Get cbor value as unsigned @@ -226,7 +221,7 @@ int suit_cbor_get_int(const CborValue *it, int *out); * @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit or cannot * be converted to unsigned */ -int suit_cbor_get_uint(const CborValue *it, unsigned *out); +int suit_cbor_get_uint(nanocbor_value_t *it, unsigned *out); /** * @brief Get cbor value as unsigned long @@ -238,7 +233,7 @@ int suit_cbor_get_uint(const CborValue *it, unsigned *out); * @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit or cannot * be converted to unsigned long */ -int suit_cbor_get_uint32(const CborValue *it, uint32_t *out); +int suit_cbor_get_uint32(nanocbor_value_t *it, uint32_t *out); /** * @brief Get cbor value as string @@ -250,20 +245,19 @@ int suit_cbor_get_uint32(const CborValue *it, uint32_t *out); * @return SUIT_OK on success * @return SUIT_ERR_INVALID_MANIFEST if value is not a valid string */ -int suit_cbor_get_string(const CborValue *it, const uint8_t **buf, size_t *len); +int suit_cbor_get_string(nanocbor_value_t *it, const uint8_t **buf, size_t *len); /** * @brief Parser a cbor subsequence * - * @param[in] parser ptr to cbor subparser - * @param[out] bseq subsequence value + * @param[in] bseq subsequence value * @param[out] it cbor iterator * * @return 0 on success * @return -1 if bseq is not a cbor string * @return CborError code on other cbor parser errors */ -int suit_cbor_subparse(CborParser *parser, CborValue *bseq, CborValue *it); +int suit_cbor_subparse(nanocbor_value_t *bseq, nanocbor_value_t *it); /** * @brief Helper function for writing bytes on flash a specified offset diff --git a/sys/suit/v4/cbor.c b/sys/suit/v4/cbor.c index 2bc00851e6..d000697f93 100644 --- a/sys/suit/v4/cbor.c +++ b/sys/suit/v4/cbor.c @@ -26,7 +26,7 @@ #include "suit/v4/handlers.h" #include "suit/v4/suit.h" #include "suit/v4/policy.h" -#include "cbor.h" +#include "nanocbor/nanocbor.h" #include "cose/sign.h" #include "public_key.h" @@ -40,135 +40,116 @@ static suit_manifest_handler_t _manifest_get_auth_wrapper_handler(int key); typedef suit_manifest_handler_t (*suit_manifest_handler_getter_t)(int key); -int suit_cbor_map_iterate_init(CborValue *map, CborValue *it) +int suit_cbor_map_iterate_init(nanocbor_value_t *map, nanocbor_value_t *it) { - if (!cbor_value_is_map(map)) { + if (nanocbor_get_type(map) != NANOCBOR_TYPE_MAP) { LOG_INFO("suit_v4_parse(): manifest not a map\n)"); return SUIT_ERR_INVALID_MANIFEST; } - cbor_value_enter_container(map, it); + nanocbor_enter_map(map, it); return SUIT_OK; } -int suit_cbor_map_iterate(CborValue *it, CborValue *key, CborValue *value) +int suit_cbor_map_iterate(nanocbor_value_t *it, nanocbor_value_t *key, + nanocbor_value_t *value) { - if (cbor_value_at_end(it)) { + if (nanocbor_at_end(it)) { return 0; } *key = *it; - cbor_value_advance(it); + nanocbor_skip(it); *value = *it; - cbor_value_advance(it); + nanocbor_skip(it); return 1; } -int suit_cbor_get_int(const CborValue *it, int *out) +int suit_cbor_get_int32(nanocbor_value_t *it, int32_t *out) { - if (!cbor_value_is_integer(it)) { - LOG_DEBUG("expected integer type, got %u\n", cbor_value_get_type(it)); - return SUIT_ERR_INVALID_MANIFEST; - } + int res = nanocbor_get_int32(it, out); - /* This check tests whether the integer fits into "int", thus the check - * is platform dependent. This is for lack of specification of actually - * allowed values, to be made explicit at some point. */ - if (cbor_value_get_int_checked(it, out) == CborErrorDataTooLarge) { - LOG_DEBUG("integer doesn't fit into int type\n"); + if (res < NANOCBOR_OK) { + LOG_DEBUG("suit_cbor_get_int32() error %u\n", res); return SUIT_ERR_INVALID_MANIFEST; } return SUIT_OK; } -int suit_cbor_get_string(const CborValue *it, const uint8_t **buf, size_t *len) +int suit_cbor_get_string(nanocbor_value_t *it, const uint8_t **buf, size_t *len) { - if (!(cbor_value_is_text_string(it) || cbor_value_is_byte_string(it) || cbor_value_is_length_known(it))) { + if (nanocbor_get_type(it) == NANOCBOR_TYPE_TSTR) { + if (nanocbor_get_tstr(it, buf, len) < 0) { + return SUIT_ERR_INVALID_MANIFEST; + } + return SUIT_OK; + } + else if (nanocbor_get_type(it) == NANOCBOR_TYPE_BSTR) { + if (nanocbor_get_bstr(it, buf, len) < 0) { + return SUIT_ERR_INVALID_MANIFEST; + } + return SUIT_OK; + } + else { + LOG_DEBUG("suit_cbor_get_string(): unexpected type: %i\n", + nanocbor_get_type(it)); + return SUIT_ERR_INVALID_MANIFEST; + } +} + +int suit_cbor_get_uint32(nanocbor_value_t *it, uint32_t *out) +{ + if (nanocbor_get_uint32(it, out) < 0) { return SUIT_ERR_INVALID_MANIFEST; } - CborValue next = *it; - cbor_value_get_string_length(it, len); - cbor_value_advance(&next); - *buf = next.ptr - *len; return SUIT_OK; } -int suit_cbor_get_uint32(const CborValue *it, uint32_t *out) -{ - int res; - int64_t val; - if (!cbor_value_is_unsigned_integer(it)) { - return CborErrorIllegalType; - } - if ((res = cbor_value_get_int64_checked(it, &val))) { - return res; - } - if (val > 0xFFFFFFFF) { - return CborErrorDataTooLarge; - } - *out = (val & 0xFFFFFFFF); - - return CborNoError; -} - -int suit_cbor_get_uint(const CborValue *it, unsigned *out) +int suit_cbor_get_uint(nanocbor_value_t *it, unsigned *out) { return suit_cbor_get_uint32(it, (uint32_t *)out); } -int suit_cbor_subparse(CborParser *parser, CborValue *bseq, CborValue *it) +int suit_cbor_subparse(nanocbor_value_t *bseq, nanocbor_value_t *it) { const uint8_t *bytes; size_t bytes_len = 0; - - if (!cbor_value_is_byte_string(bseq)) { - LOG_DEBUG("suit_cbor_subparse(): bseq not a byte string\n"); - return -1; + int res = suit_cbor_get_string(bseq, &bytes, &bytes_len); + if (res != SUIT_OK) { + return res; } - - suit_cbor_get_string(bseq, &bytes, &bytes_len); - - return cbor_parser_init(bytes, bytes_len, SUIT_TINYCBOR_VALIDATION_MODE, parser, - it); + nanocbor_decoder_init(it, bytes, bytes_len); + return SUIT_OK; } static int _v4_parse(suit_v4_manifest_t *manifest, const uint8_t *buf, - size_t len, suit_manifest_handler_getter_t getter) + size_t len, suit_manifest_handler_getter_t getter) { + nanocbor_value_t it, map, key, value; - CborParser parser; - CborValue it, map, key, value; - CborError err = cbor_parser_init(buf, len, SUIT_TINYCBOR_VALIDATION_MODE, - &parser, &it); - - if (err != 0) { - return SUIT_ERR_INVALID_MANIFEST; - } + nanocbor_decoder_init(&it, buf, len); map = it; if (suit_cbor_map_iterate_init(&map, &it) != SUIT_OK) { - LOG_DEBUG("manifest not a map!\n"); + LOG_DEBUG("suit _v4_parse(): manifest not a map!\n"); return SUIT_ERR_INVALID_MANIFEST; } - LOG_DEBUG("jumping into map\n)"); - while (suit_cbor_map_iterate(&it, &key, &value)) { - int integer_key; - if (suit_cbor_get_int(&key, &integer_key) != SUIT_OK){ + int32_t integer_key; + if (suit_cbor_get_int32(&key, &integer_key) != SUIT_OK) { return SUIT_ERR_INVALID_MANIFEST; } - LOG_DEBUG("got key val=%i\n", integer_key); + LOG_DEBUG("got key val=%" PRIi32 "\n", integer_key); suit_manifest_handler_t handler = getter(integer_key); if (handler) { int res = handler(manifest, integer_key, &value); - LOG_DEBUG("handler res=%i\n", res); if (res < 0) { LOG_INFO("handler returned <0\n)"); return SUIT_ERR_INVALID_MANIFEST; @@ -179,20 +160,21 @@ static int _v4_parse(suit_v4_manifest_t *manifest, const uint8_t *buf, } } - cbor_value_leave_container(&map, &it); + nanocbor_leave_container(&map, &it); return SUIT_OK; } int suit_v4_parse(suit_v4_manifest_t *manifest, const uint8_t *buf, - size_t len) + size_t len) { manifest->buf = buf; manifest->len = len; return _v4_parse(manifest, buf, len, _manifest_get_auth_wrapper_handler); } -static int _auth_handler(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _auth_handler(suit_v4_manifest_t *manifest, int key, + nanocbor_value_t *it) { (void)key; const uint8_t *cose_buf; @@ -211,7 +193,8 @@ static int _auth_handler(suit_v4_manifest_t *manifest, int key, CborValue *it) return 0; } -static int _manifest_handler(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _manifest_handler(suit_v4_manifest_t *manifest, int key, + nanocbor_value_t *it) { (void)key; const uint8_t *manifest_buf; @@ -238,19 +221,20 @@ static int _manifest_handler(suit_v4_manifest_t *manifest, int key, CborValue *i LOG_INFO("suit: verifying manifest signature...\n"); int verification = cose_sign_verify(&manifest->verify, &signature, - &pkey, manifest->validation_buf, SUIT_COSE_BUF_SIZE); + &pkey, manifest->validation_buf, + SUIT_COSE_BUF_SIZE); if (verification != 0) { LOG_INFO("Unable to validate signature\n"); return SUIT_ERR_SIGNATURE; } return _v4_parse(manifest, manifest_buf, - manifest_len, suit_manifest_get_manifest_handler); + manifest_len, suit_manifest_get_manifest_handler); } static suit_manifest_handler_t _suit_manifest_get_handler(int key, - const suit_manifest_handler_t *handlers, - size_t len) + const suit_manifest_handler_t *handlers, + size_t len) { if (key < 0 || (size_t)key >= len) { return NULL; diff --git a/sys/suit/v4/handlers.c b/sys/suit/v4/handlers.c index 30dde7a3f6..09c3077491 100644 --- a/sys/suit/v4/handlers.c +++ b/sys/suit/v4/handlers.c @@ -27,50 +27,52 @@ #include "suit/v4/suit.h" #include "riotboot/hdr.h" #include "riotboot/slot.h" -#include "cbor.h" +#include #include "log.h" #define HELLO_HANDLER_MAX_STRLEN 32 -static int _handle_command_sequence(suit_v4_manifest_t *manifest, CborValue *it, +static int _handle_command_sequence(suit_v4_manifest_t *manifest, nanocbor_value_t *it, suit_manifest_handler_t handler); -static int _common_handler(suit_v4_manifest_t *manifest, int key, CborValue *it); -static int _common_sequence_handler(suit_v4_manifest_t *manifest, int key, CborValue *it); +static int _common_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it); +static int _common_sequence_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it); -static int _hello_handler(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _hello_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it) { (void)manifest; (void)key; - if (cbor_value_is_text_string(it)) { + if (nanocbor_get_type(it) == NANOCBOR_TYPE_TSTR) { size_t len = HELLO_HANDLER_MAX_STRLEN; char buf[HELLO_HANDLER_MAX_STRLEN]; - cbor_value_copy_text_string(it, buf, &len, NULL); + nanocbor_get_tstr(it, ((const uint8_t **) &buf), &len); return SUIT_OK; } else { - LOG_DEBUG("_hello_handler(): unexpected value type: %u\n", cbor_value_get_type( - it)); + LOG_DEBUG("_hello_handler(): unexpected value type: %u\n", nanocbor_get_type(it)); return -1; } } -static int _validate_uuid(suit_v4_manifest_t *manifest, CborValue *it, uuid_t *uuid) +static int _validate_uuid(suit_v4_manifest_t *manifest, nanocbor_value_t *it, uuid_t *uuid) { (void)manifest; - uuid_t uuid_manifest; + const uint8_t *uuid_manifest_ptr; + size_t len = sizeof(uuid_t); char uuid_str[UUID_STR_LEN + 1]; char uuid_str2[UUID_STR_LEN + 1]; - size_t len = sizeof(uuid_t); - cbor_value_copy_byte_string(it, (uint8_t*)&uuid_manifest, &len, NULL); - uuid_to_string(&uuid_manifest, uuid_str); + if (suit_cbor_get_string(it, &uuid_manifest_ptr, &len) != SUIT_OK) { + return SUIT_ERR_INVALID_MANIFEST; + } + + uuid_to_string((uuid_t *)uuid_manifest_ptr, uuid_str); uuid_to_string(uuid, uuid_str2); LOG_INFO("Comparing %s to %s from manifest\n", uuid_str2, uuid_str); - return uuid_equal(uuid, &uuid_manifest) ? 0 : -1; + return uuid_equal(uuid, (uuid_t *)uuid_manifest_ptr) ? 0 : -1; } -static int _cond_vendor_handler(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _cond_vendor_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it) { (void)key; LOG_INFO("validating vendor ID\n"); @@ -82,7 +84,7 @@ static int _cond_vendor_handler(suit_v4_manifest_t *manifest, int key, CborValue return rc; } -static int _cond_class_handler(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _cond_class_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it) { (void)key; LOG_INFO("validating class id\n"); @@ -94,7 +96,7 @@ static int _cond_class_handler(suit_v4_manifest_t *manifest, int key, CborValue return rc; } -static int _cond_comp_offset(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _cond_comp_offset(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it) { (void)manifest; (void)key; @@ -107,21 +109,22 @@ static int _cond_comp_offset(suit_v4_manifest_t *manifest, int key, CborValue *i return other_offset == offset ? 0 : -1; } -static int _dtv_set_comp_idx(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _dtv_set_comp_idx(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it) { (void)key; - if (cbor_value_is_boolean(it)) { - LOG_DEBUG("_dtv_set_comp_idx() ignoring boolean\n)"); + if (nanocbor_get_type(it) == NANOCBOR_TYPE_FLOAT) { + LOG_DEBUG("_dtv_set_comp_idx() ignoring boolean and floats\n)"); + nanocbor_skip(it); return 0; } - int res = suit_cbor_get_int(it, &manifest->component_current); + int res = suit_cbor_get_int32(it, &manifest->component_current); if (!res) { - LOG_DEBUG("Setting component index to %d\n", manifest->component_current); + LOG_DEBUG("Setting component index to %d\n", (int)manifest->component_current); } return res; } -static int _dtv_run_seq_cond(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _dtv_run_seq_cond(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it) { (void)key; LOG_DEBUG("Starting conditional sequence handler\n"); @@ -129,20 +132,20 @@ static int _dtv_run_seq_cond(suit_v4_manifest_t *manifest, int key, CborValue *i return 0; } -static int _param_get_uri_list(suit_v4_manifest_t *manifest, CborValue *it) +static int _param_get_uri_list(suit_v4_manifest_t *manifest, nanocbor_value_t *it) { LOG_DEBUG("got url list\n"); manifest->components[manifest->component_current].url = *it; return 0; } -static int _param_get_digest(suit_v4_manifest_t *manifest, CborValue *it) +static int _param_get_digest(suit_v4_manifest_t *manifest, nanocbor_value_t *it) { LOG_DEBUG("got digest\n"); manifest->components[manifest->component_current].digest = *it; return 0; } -static int _param_get_img_size(suit_v4_manifest_t *manifest, CborValue *it) +static int _param_get_img_size(suit_v4_manifest_t *manifest, nanocbor_value_t *it) { int res = suit_cbor_get_uint32(it, &manifest->components[0].size); if (res) { @@ -152,21 +155,20 @@ static int _param_get_img_size(suit_v4_manifest_t *manifest, CborValue *it) return res; } -static int _dtv_set_param(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _dtv_set_param(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it) { (void)key; /* `it` points to the entry of the map containing the type and value */ - CborValue map; + nanocbor_value_t map; - cbor_value_enter_container(it, &map); + nanocbor_enter_map(it, &map); - while (!cbor_value_at_end(&map)) { + while (!nanocbor_at_end(&map)) { /* map points to the key of the param */ - int param_key; - suit_cbor_get_int(&map, ¶m_key); - cbor_value_advance(&map); - LOG_DEBUG("Setting component index to %d\n", manifest->component_current); - LOG_DEBUG("param_key=%i\n", param_key); + int32_t param_key; + suit_cbor_get_int32(&map, ¶m_key); + LOG_DEBUG("Setting component index to %" PRIi32 "\n", manifest->component_current); + LOG_DEBUG("param_key=%" PRIi32 "\n", param_key); int res; switch (param_key) { case 6: /* SUIT URI LIST */ @@ -182,7 +184,7 @@ static int _dtv_set_param(suit_v4_manifest_t *manifest, int key, CborValue *it) res = -1; } - cbor_value_advance(&map); + nanocbor_skip(&map); if (res) { return res; @@ -191,7 +193,7 @@ static int _dtv_set_param(suit_v4_manifest_t *manifest, int key, CborValue *it) return SUIT_OK; } -static int _dtv_fetch(suit_v4_manifest_t *manifest, int key, CborValue *_it) +static int _dtv_fetch(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *_it) { (void)key; (void)_it; (void)manifest; LOG_DEBUG("_dtv_fetch() key=%i\n", key); @@ -205,39 +207,40 @@ static int _dtv_fetch(suit_v4_manifest_t *manifest, int key, CborValue *_it) * (priority, url) tuples (represented as array with length two) * */ - CborParser parser; - CborValue it; + nanocbor_value_t it; /* open sequence with cbor parser */ - int err = suit_cbor_subparse(&parser, &manifest->components[0].url, &it); + int err = suit_cbor_subparse(&manifest->components[0].url, &it); if (err < 0) { LOG_DEBUG("subparse failed\n)"); return err; } /* confirm the document contains an array */ - if (!cbor_value_is_array(&it)) { + if (nanocbor_get_type(&it) != NANOCBOR_TYPE_ARR) { LOG_DEBUG("url list no array\n)"); - LOG_DEBUG("type: %u\n", cbor_value_get_type(&it)); + LOG_DEBUG("type: %u\n", nanocbor_get_type(&it)); } /* enter container, confirm it is an array, too */ - CborValue url_it; - cbor_value_enter_container(&it, &url_it); - if (!cbor_value_is_array(&url_it)) { + nanocbor_value_t url_it; + nanocbor_enter_array(&it, &url_it); + if (nanocbor_get_type(&url_it) != NANOCBOR_TYPE_ARR) { LOG_DEBUG("url entry no array\n)"); } /* expect two entries: priority as int, url as byte string. bail out if not. */ - CborValue url_value_it; - cbor_value_enter_container(&url_it, &url_value_it); + nanocbor_value_t url_value_it; + nanocbor_enter_array(&url_it, &url_value_it); - /* check that first array entry is an int (the priority of the url) */ - if (cbor_value_get_type(&url_value_it) != CborIntegerType) { + /* check that first array entry is an int (the priotity of the url) */ + if (nanocbor_get_type(&url_value_it) != NANOCBOR_TYPE_UINT) { + LOG_DEBUG("expected URL priority (int), got %d\n", nanocbor_get_type(&url_value_it)); return -1; } - cbor_value_advance(&url_value_it); + /* skip URL priority (currently unused) */ + nanocbor_skip(&url_value_it); int res = suit_cbor_get_string(&url_value_it, &url, &url_len); if (res) { @@ -251,8 +254,8 @@ static int _dtv_fetch(suit_v4_manifest_t *manifest, int key, CborValue *_it) memcpy(manifest->urlbuf, url, url_len); manifest->urlbuf[url_len] = '\0'; - cbor_value_leave_container(&url_it, &url_value_it); - cbor_value_leave_container(&it, &url_it); + nanocbor_leave_container(&url_it, &url_value_it); + nanocbor_leave_container(&it, &url_it); } LOG_DEBUG("_dtv_fetch() fetching \"%s\" (url_len=%u)\n", manifest->urlbuf, (unsigned)url_len); @@ -291,14 +294,14 @@ static int _dtv_fetch(suit_v4_manifest_t *manifest, int key, CborValue *_it) } static int _version_handler(suit_v4_manifest_t *manifest, int key, - CborValue *it) + nanocbor_value_t *it) { (void)manifest; (void)key; /* Validate manifest version */ - int version = -1; - if (cbor_value_is_integer(it) && - (cbor_value_get_int(it, &version) == CborNoError)) { + int32_t version = -1; + if ((nanocbor_get_type(it) == NANOCBOR_TYPE_UINT) && + (nanocbor_get_int32(it, &version) >= 0)) { if (version == SUIT_VERSION) { manifest->validated |= SUIT_VALIDATED_VERSION; LOG_INFO("suit: validated manifest version\n)"); @@ -311,32 +314,31 @@ static int _version_handler(suit_v4_manifest_t *manifest, int key, return -1; } -static int _seq_no_handler(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _seq_no_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it) { (void)manifest; (void)key; (void)it; - int64_t seq_nr; - if (cbor_value_is_unsigned_integer(it) && - (cbor_value_get_int64_checked(it, &seq_nr) == CborNoError)) { + int32_t seq_nr; + if ((nanocbor_get_type(it) == NANOCBOR_TYPE_UINT)) { + nanocbor_get_int32(it, &seq_nr); const riotboot_hdr_t *hdr = riotboot_slot_get_hdr(riotboot_slot_current()); - if (seq_nr <= (int64_t)hdr->version) { - LOG_INFO("%"PRIu64" <= %"PRIu32"\n", seq_nr, hdr->version); + if (seq_nr <= (int32_t)hdr->version) { + LOG_INFO("%"PRId32" <= %"PRId32"\n", seq_nr, hdr->version); LOG_INFO("seq_nr <= running image\n)"); return -1; } hdr = riotboot_slot_get_hdr(riotboot_slot_other()); if (riotboot_hdr_validate(hdr) == 0) { - if (seq_nr <= (int64_t)hdr->version) { - LOG_INFO("%"PRIu64" <= %"PRIu32"\n", seq_nr, hdr->version); + if (seq_nr<= (int32_t)hdr->version) { + LOG_INFO("%"PRIu32" <= %"PRIu32"\n", seq_nr, hdr->version); LOG_INFO("seq_nr <= other image\n)"); return -1; } } - LOG_INFO("suit: validated sequence number\n)"); manifest->validated |= SUIT_VALIDATED_SEQ_NR; return 0; @@ -346,7 +348,7 @@ static int _seq_no_handler(suit_v4_manifest_t *manifest, int key, CborValue *it) } static int _dependencies_handler(suit_v4_manifest_t *manifest, int key, - CborValue *it) + nanocbor_value_t *it) { (void)manifest; (void)key; @@ -356,23 +358,23 @@ static int _dependencies_handler(suit_v4_manifest_t *manifest, int key, } static int _component_handler(suit_v4_manifest_t *manifest, int key, - CborValue *it) + nanocbor_value_t *it) { (void)manifest; (void)key; - CborValue arr; + nanocbor_value_t arr; LOG_DEBUG("storing components\n)"); - if (!cbor_value_is_array(it)) { + if (nanocbor_get_type(it) != NANOCBOR_TYPE_ARR) { LOG_DEBUG("components field not an array\n"); return -1; } - cbor_value_enter_container(it, &arr); + nanocbor_enter_array(it, &arr); unsigned n = 0; - while (!cbor_value_at_end(&arr)) { - CborValue map, key, value; + while (!nanocbor_at_end(&arr)) { + nanocbor_value_t map, key, value; if (n < SUIT_V4_COMPONENT_MAX) { manifest->components_len += 1; } @@ -387,8 +389,8 @@ static int _component_handler(suit_v4_manifest_t *manifest, int key, while (suit_cbor_map_iterate(&map, &key, &value)) { /* handle key, value */ - int integer_key; - if (suit_cbor_get_int(&key, &integer_key)) { + int32_t integer_key; + if (suit_cbor_get_int32(&key, &integer_key)) { return SUIT_ERR_INVALID_MANIFEST; } @@ -403,20 +405,21 @@ static int _component_handler(suit_v4_manifest_t *manifest, int key, current->digest = value; break; default: - LOG_DEBUG("ignoring unexpected component data (nr. %i)\n", integer_key); + LOG_DEBUG("ignoring unexpected component data (nr. %" PRIi32 ")\n", integer_key); } LOG_DEBUG("component %u parsed\n", n); } - - cbor_value_advance(&arr); + nanocbor_leave_container(&arr, &map); n++; } manifest->state |= SUIT_MANIFEST_HAVE_COMPONENTS; - cbor_value_leave_container(it, &arr); + + nanocbor_leave_container(it, &arr); LOG_DEBUG("storing components done\n)"); + return 0; } @@ -470,7 +473,7 @@ suit_manifest_handler_t suit_manifest_get_manifest_handler(int key) global_handlers_len); } -static int _common_sequence_handler(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _common_sequence_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it) { suit_manifest_handler_t handler = _suit_manifest_get_handler(key, _sequence_handlers, _sequence_handlers_len); @@ -484,52 +487,47 @@ static int _common_sequence_handler(suit_v4_manifest_t *manifest, int key, CborV } } -static int _common_handler(suit_v4_manifest_t *manifest, int key, CborValue *it) +static int _common_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it) { (void)key; return _handle_command_sequence(manifest, it, _common_sequence_handler); } -int _handle_command_sequence(suit_v4_manifest_t *manifest, CborValue *bseq, +int _handle_command_sequence(suit_v4_manifest_t *manifest, nanocbor_value_t *bseq, suit_manifest_handler_t handler) { LOG_DEBUG("Handling command sequence\n"); - CborParser parser; - CborValue it, arr; + nanocbor_value_t it, arr; - int err = suit_cbor_subparse(&parser, bseq, &it); + int err = suit_cbor_subparse(bseq, &it); if (err < 0) { return err; } - if (!cbor_value_is_array(&it)) { - LOG_DEBUG("Not a byte array\n"); + if (nanocbor_get_type(&it) != NANOCBOR_TYPE_ARR) { return -1; } - cbor_value_enter_container(&it, &arr); + nanocbor_enter_array(&it, &arr); - while (!cbor_value_at_end(&arr)) { - CborValue map; - if (!cbor_value_is_map(&arr)) { + while (!nanocbor_at_end(&arr)) { + nanocbor_value_t map; + if (nanocbor_get_type(&arr) != NANOCBOR_TYPE_MAP) { return SUIT_ERR_INVALID_MANIFEST; } - cbor_value_enter_container(&arr, &map); - int integer_key; - if (suit_cbor_get_int(&map, &integer_key)) { + nanocbor_enter_map(&arr, &map); + int32_t integer_key; + if (suit_cbor_get_int32(&map, &integer_key)) { return SUIT_ERR_INVALID_MANIFEST; } - - cbor_value_advance(&map); int res = handler(manifest, integer_key, &map); if (res < 0) { LOG_DEBUG("Sequence handler error\n"); return res; } - cbor_value_advance(&map); - cbor_value_leave_container(&arr, &map); + nanocbor_leave_container(&arr, &map); } - cbor_value_leave_container(&it, &arr); + nanocbor_leave_container(&it, &arr); return 0; }