Commit a7d34caa authored by Øyvind Rønningstad's avatar Øyvind Rønningstad Committed by David Brown
Browse files

boot_serial: Upgrade from cddl-gen 0.1.0 to zcbor 0.4.0



cddl-gen has been renamed to zcbor.
Update regenerate_serial_recovery_cbor.sh and regenerate/recopy all
files.

Remove the submodule in ext/ since it is no longer necessary when
the zcbor package is installed (only needed for regeneration, not
for building).

Signed-off-by: default avatarØyvind Rønningstad <oyvind.ronningstad@nordicsemi.no>
parent 35f61d30
...@@ -19,9 +19,6 @@ ...@@ -19,9 +19,6 @@
[submodule "boot/cypress/libs/cy-mbedtls-acceleration"] [submodule "boot/cypress/libs/cy-mbedtls-acceleration"]
path = boot/cypress/libs/cy-mbedtls-acceleration path = boot/cypress/libs/cy-mbedtls-acceleration
url = https://github.com/cypresssemiconductorco/cy-mbedtls-acceleration.git url = https://github.com/cypresssemiconductorco/cy-mbedtls-acceleration.git
[submodule "ext/cddl-gen"]
path = ext/cddl-gen
url = https://github.com/NordicSemiconductor/cddl-gen.git
[submodule "boot/espressif/hal/esp-idf"] [submodule "boot/espressif/hal/esp-idf"]
path = boot/espressif/hal/esp-idf path = boot/espressif/hal/esp-idf
url = https://github.com/espressif/esp-idf.git url = https://github.com/espressif/esp-idf.git
......
...@@ -11,7 +11,6 @@ samples/* ...@@ -11,7 +11,6 @@ samples/*
scripts/* scripts/*
sim/* sim/*
testplan/* testplan/*
ext/cddl_gen/*
ext/fiat/* ext/fiat/*
ext/mbedtls/* ext/mbedtls/*
ext/mbedtls-asn1/* ext/mbedtls-asn1/*
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "sysflash/sysflash.h" #include "sysflash/sysflash.h"
#include "bootutil/bootutil_log.h" #include "bootutil/bootutil_log.h"
#include "cbor_encode.h" #include "zcbor_encode.h"
#ifdef __ZEPHYR__ #ifdef __ZEPHYR__
#include <sys/reboot.h> #include <sys/reboot.h>
...@@ -99,17 +99,12 @@ static char bs_obuf[BOOT_SERIAL_OUT_MAX]; ...@@ -99,17 +99,12 @@ static char bs_obuf[BOOT_SERIAL_OUT_MAX];
static void boot_serial_output(void); static void boot_serial_output(void);
static cbor_state_backups_t dummy_backups; static zcbor_state_t cbor_state[2];
static cbor_state_t cbor_state = {
.backups = &dummy_backups
};
void reset_cbor_state(void) void reset_cbor_state(void)
{ {
cbor_state.payload_mut = (uint8_t *)bs_obuf; zcbor_new_encode_state(cbor_state, 2, (uint8_t *)bs_obuf,
cbor_state.payload_end = (const uint8_t *)bs_obuf (size_t)bs_obuf + sizeof(bs_obuf), 0);
+ sizeof(bs_obuf);
cbor_state.elem_count = 0;
} }
/** /**
...@@ -126,7 +121,7 @@ void reset_cbor_state(void) ...@@ -126,7 +121,7 @@ void reset_cbor_state(void)
*/ */
extern int bs_peruser_system_specific(const struct nmgr_hdr *hdr, extern int bs_peruser_system_specific(const struct nmgr_hdr *hdr,
const char *buffer, const char *buffer,
int len, cbor_state_t *cs); int len, zcbor_state_t *cs);
/* /*
* Convert version into string without use of snprintf(). * Convert version into string without use of snprintf().
...@@ -157,6 +152,9 @@ u32toa(char *tgt, uint32_t val) ...@@ -157,6 +152,9 @@ u32toa(char *tgt, uint32_t val)
return dst - tgt; return dst - tgt;
} }
#define zcbor_tstr_put_lit_cast(state, string) \
zcbor_tstr_encode_ptr(state, (uint8_t *)string, sizeof(string) - 1)
/* /*
* dst has to be able to fit "255.255.65535.4294967295" (25 characters). * dst has to be able to fit "255.255.65535.4294967295" (25 characters).
*/ */
...@@ -186,9 +184,9 @@ bs_list(char *buf, int len) ...@@ -186,9 +184,9 @@ bs_list(char *buf, int len)
const struct flash_area *fap; const struct flash_area *fap;
uint8_t image_index; uint8_t image_index;
map_start_encode(&cbor_state, 1); zcbor_map_start_encode(cbor_state, 1);
tstrx_put(&cbor_state, "images"); zcbor_tstr_put_lit_cast(cbor_state, "images");
list_start_encode(&cbor_state, 5); zcbor_list_start_encode(cbor_state, 5);
image_index = 0; image_index = 0;
IMAGES_ITER(image_index) { IMAGES_ITER(image_index) {
for (slot = 0; slot < 2; slot++) { for (slot = 0; slot < 2; slot++) {
...@@ -235,24 +233,24 @@ bs_list(char *buf, int len) ...@@ -235,24 +233,24 @@ bs_list(char *buf, int len)
continue; continue;
} }
map_start_encode(&cbor_state, 20); zcbor_map_start_encode(cbor_state, 20);
#if (BOOT_IMAGE_NUMBER > 1) #if (BOOT_IMAGE_NUMBER > 1)
tstrx_put(&cbor_state, "image"); zcbor_tstr_put_lit_cast(cbor_state, "image");
uintx32_put(&cbor_state, image_index); zcbor_uint32_put(cbor_state, image_index);
#endif #endif
tstrx_put(&cbor_state, "slot"); zcbor_tstr_put_lit_cast(cbor_state, "slot");
uintx32_put(&cbor_state, slot); zcbor_uint32_put(cbor_state, slot);
tstrx_put(&cbor_state, "version"); zcbor_tstr_put_lit_cast(cbor_state, "version");
bs_list_img_ver((char *)tmpbuf, sizeof(tmpbuf), &hdr.ih_ver); bs_list_img_ver((char *)tmpbuf, sizeof(tmpbuf), &hdr.ih_ver);
tstrx_put_term(&cbor_state, (char *)tmpbuf); zcbor_tstr_encode_ptr(cbor_state, tmpbuf, strlen((char *)tmpbuf));
map_end_encode(&cbor_state, 20); zcbor_map_end_encode(cbor_state, 20);
} }
} }
list_end_encode(&cbor_state, 5); zcbor_list_end_encode(cbor_state, 5);
map_end_encode(&cbor_state, 1); zcbor_map_end_encode(cbor_state, 1);
boot_serial_output(); boot_serial_output();
} }
...@@ -289,15 +287,15 @@ bs_upload(char *buf, int len) ...@@ -289,15 +287,15 @@ bs_upload(char *buf, int len)
*/ */
struct Upload upload; struct Upload upload;
uint32_t decoded_len; size_t decoded_len;
bool result = cbor_decode_Upload((const uint8_t *)buf, len, &upload, &decoded_len); uint_fast8_t result = cbor_decode_Upload((const uint8_t *)buf, len, &upload, &decoded_len);
if (!result || (len != decoded_len)) { if ((result != ZCBOR_SUCCESS) || (len != decoded_len)) {
goto out_invalid_data; goto out_invalid_data;
} }
for (int i = 0; i < upload._Upload_members_count; i++) { for (int i = 0; i < upload._Upload_members_count; i++) {
struct Member_ *member = &upload._Upload_members[i]; struct Member_ *member = &upload._Upload_members[i]._Upload_members;
switch(member->_Member_choice) { switch(member->_Member_choice) {
case _Member_image: case _Member_image:
img_num = member->_Member_image; img_num = member->_Member_image;
...@@ -458,14 +456,14 @@ bs_upload(char *buf, int len) ...@@ -458,14 +456,14 @@ bs_upload(char *buf, int len)
out: out:
BOOT_LOG_INF("RX: 0x%x", rc); BOOT_LOG_INF("RX: 0x%x", rc);
map_start_encode(&cbor_state, 10); zcbor_map_start_encode(cbor_state, 10);
tstrx_put(&cbor_state, "rc"); zcbor_tstr_put_lit_cast(cbor_state, "rc");
uintx32_put(&cbor_state, rc); zcbor_uint32_put(cbor_state, rc);
if (rc == 0) { if (rc == 0) {
tstrx_put(&cbor_state, "off"); zcbor_tstr_put_lit_cast(cbor_state, "off");
uintx32_put(&cbor_state, curr_off); zcbor_uint32_put(cbor_state, curr_off);
} }
map_end_encode(&cbor_state, 10); zcbor_map_end_encode(cbor_state, 10);
boot_serial_output(); boot_serial_output();
flash_area_close(fap); flash_area_close(fap);
...@@ -484,10 +482,10 @@ out: ...@@ -484,10 +482,10 @@ out:
static void static void
bs_rc_rsp(int rc_code) bs_rc_rsp(int rc_code)
{ {
map_start_encode(&cbor_state, 10); zcbor_map_start_encode(cbor_state, 10);
tstrx_put(&cbor_state, "rc"); zcbor_tstr_put_lit_cast(cbor_state, "rc");
uintx32_put(&cbor_state, rc_code); zcbor_uint32_put(cbor_state, rc_code);
map_end_encode(&cbor_state, 10); zcbor_map_end_encode(cbor_state, 10);
boot_serial_output(); boot_serial_output();
} }
...@@ -605,7 +603,7 @@ boot_serial_input(char *buf, int len) ...@@ -605,7 +603,7 @@ boot_serial_input(char *buf, int len)
break; break;
} }
} else if (MCUBOOT_PERUSER_MGMT_GROUP_ENABLED == 1) { } else if (MCUBOOT_PERUSER_MGMT_GROUP_ENABLED == 1) {
if (bs_peruser_system_specific(hdr, buf, len, &cbor_state) == 0) { if (bs_peruser_system_specific(hdr, buf, len, cbor_state) == 0) {
boot_serial_output(); boot_serial_output();
} }
} else { } else {
...@@ -628,7 +626,7 @@ boot_serial_output(void) ...@@ -628,7 +626,7 @@ boot_serial_output(void)
char encoded_buf[BASE64_ENCODE_SIZE(sizeof(buf))]; char encoded_buf[BASE64_ENCODE_SIZE(sizeof(buf))];
data = bs_obuf; data = bs_obuf;
len = (uint32_t)cbor_state.payload_mut - (uint32_t)bs_obuf; len = (uint32_t)cbor_state->payload_mut - (uint32_t)bs_obuf;
bs_hdr->nh_op++; bs_hdr->nh_op++;
bs_hdr->nh_flags = 0; bs_hdr->nh_flags = 0;
......
/*
* This file has been copied from the cddl-gen submodule.
* Commit 9f77837f9950da1633d22abf6181a830521a6688
*/
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "cbor_common.h"
_Static_assert((sizeof(size_t) == sizeof(void *)),
"This code needs size_t to be the same length as pointers.");
bool new_backup(cbor_state_t *state, uint32_t new_elem_count)
{
if ((state->backups->current_backup + 1)
>= state->backups->num_backups) {
FAIL();
}
uint32_t i = ++(state->backups->current_backup);
memcpy(&state->backups->backup_list[i], state,
sizeof(cbor_state_t));
state->elem_count = new_elem_count;
return true;
}
bool restore_backup(cbor_state_t *state, uint32_t flags,
uint32_t max_elem_count)
{
const uint8_t *payload = state->payload;
const uint32_t elem_count = state->elem_count;
if (state->backups->current_backup == 0) {
FAIL();
}
if (flags & FLAG_RESTORE) {
uint32_t i = state->backups->current_backup;
memcpy(state, &state->backups->backup_list[i],
sizeof(cbor_state_t));
}
if (flags & FLAG_DISCARD) {
state->backups->current_backup--;
}
if (elem_count > max_elem_count) {
cbor_print("elem_count: %d (expected max %d)\r\n",
elem_count, max_elem_count);
FAIL();
}
if (flags & FLAG_TRANSFER_PAYLOAD) {
state->payload = payload;
}
return true;
}
bool union_start_code(cbor_state_t *state)
{
if (!new_backup(state, state->elem_count)) {
FAIL();
}
return true;
}
bool union_elem_code(cbor_state_t *state)
{
if (!restore_backup(state, FLAG_RESTORE, state->elem_count)) {
FAIL();
}
return true;
}
bool union_end_code(cbor_state_t *state)
{
if (!restore_backup(state, FLAG_DISCARD, state->elem_count)) {
FAIL();
}
return true;
}
bool entry_function(const uint8_t *payload, uint32_t payload_len,
const void *struct_ptr, uint32_t *payload_len_out,
cbor_encoder_t func, uint32_t elem_count, uint32_t num_backups)
{
cbor_state_t state = {
.payload = payload,
.payload_end = payload + payload_len,
.elem_count = elem_count,
};
cbor_state_t state_backups[num_backups + 1];
cbor_state_backups_t backups = {
.backup_list = state_backups,
.current_backup = 0,
.num_backups = num_backups + 1,
};
state.backups = &backups;
bool result = func(&state, struct_ptr);
if (result && (payload_len_out != NULL)) {
*payload_len_out = MIN(payload_len,
(size_t)state.payload - (size_t)payload);
}
return result;
}
/*
* This file has been copied from the cddl-gen submodule.
* Commit 9f77837f9950da1633d22abf6181a830521a6688
*/
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef CBOR_COMMON_H__
#define CBOR_COMMON_H__
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/** Convenience type that allows pointing to strings directly inside the payload
* without the need to copy out.
*/
typedef struct
{
const uint8_t *value;
uint32_t len;
} cbor_string_type_t;
#ifdef CDDL_CBOR_VERBOSE
#include <sys/printk.h>
#define cbor_trace() (printk("bytes left: %d, byte: 0x%x, elem_count: 0x%zx, %s:%d\n",\
(uint32_t)state->payload_end - (uint32_t)state->payload, *state->payload, state->elem_count,\
__FILE__, __LINE__))
#define cbor_assert(expr, ...) \
do { \
if (!(expr)) { \
printk("ASSERTION \n \"" #expr \
"\"\nfailed at %s:%d with message:\n ", \
__FILE__, __LINE__); \
printk(__VA_ARGS__);\
return false; \
} \
} while(0)
#define cbor_print(...) printk(__VA_ARGS__)
#else
#define cbor_trace() ((void)state)
#define cbor_assert(...)
#define cbor_print(...)
#endif
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
struct cbor_state_backups_s;
typedef struct cbor_state_backups_s cbor_state_backups_t;
typedef struct{
union {
uint8_t *payload_mut;
uint8_t const *payload; /**< The current place in the payload. Will be
updated when an element is correctly
processed. */
};
uint8_t const *payload_bak; /**< Temporary backup of payload. */
uint32_t elem_count; /**< The current element is part of a LIST or a MAP,
and this keeps count of how many elements are
expected. This will be checked before processing
and decremented if the element is correctly
processed. */
uint8_t const *payload_end; /**< The end of the payload. This will be
checked against payload before
processing each element. */
cbor_state_backups_t *backups;
} cbor_state_t;
struct cbor_state_backups_s{
cbor_state_t *backup_list;
uint32_t current_backup;
uint32_t num_backups;
};
/** Function pointer type used with multi_decode.
*
* This type is compatible with all decoding functions here and in the generated
* code, except for multi_decode.
*/
typedef bool(cbor_encoder_t)(cbor_state_t *, const void *);
typedef bool(cbor_decoder_t)(cbor_state_t *, void *);
/** Enumeration representing the major types available in CBOR.
*
* The major type is represented in the 3 first bits of the header byte.
*/
typedef enum
{
CBOR_MAJOR_TYPE_PINT = 0, ///! Positive Integer
CBOR_MAJOR_TYPE_NINT = 1, ///! Negative Integer
CBOR_MAJOR_TYPE_BSTR = 2, ///! Byte String
CBOR_MAJOR_TYPE_TSTR = 3, ///! Text String
CBOR_MAJOR_TYPE_LIST = 4, ///! List
CBOR_MAJOR_TYPE_MAP = 5, ///! Map
CBOR_MAJOR_TYPE_TAG = 6, ///! Semantic Tag
CBOR_MAJOR_TYPE_PRIM = 7, ///! Primitive Type
} cbor_major_type_t;
/** Shorthand macro to check if a result is within min/max constraints.
*/
#define PTR_VALUE_IN_RANGE(type, res, min, max) \
(((min == NULL) || (*(type *)res >= *(type *)min)) \
&& ((max == NULL) || (*(type *)res <= *(type *)max)))
#define FAIL() \
do {\
cbor_trace(); \
return false; \
} while(0)
#define VALUE_IN_HEADER 23 /**! For values below this, the value is encoded
directly in the header. */
#define BOOL_TO_PRIM 20 ///! In CBOR, false/true have the values 20/21
#define FLAG_RESTORE 1UL
#define FLAG_DISCARD 2UL
#define FLAG_TRANSFER_PAYLOAD 4UL
bool new_backup(cbor_state_t *state, uint32_t new_elem_count);
bool restore_backup(cbor_state_t *state, uint32_t flags,
uint32_t max_elem_count);
bool union_start_code(cbor_state_t *state);
bool union_elem_code(cbor_state_t *state);
bool union_end_code(cbor_state_t *state);
bool entry_function(const uint8_t *payload, uint32_t payload_len,
const void *struct_ptr, uint32_t *payload_len_out,
cbor_encoder_t func, uint32_t elem_count, uint32_t num_backups);
#endif /* CBOR_COMMON_H__ */
/*
* This file has been copied from the cddl-gen submodule.
* Commit 9f77837f9950da1633d22abf6181a830521a6688
*/
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include "cbor_decode.h"
#include "cbor_common.h"
/** Return value length from additional value.
*/
static uint32_t additional_len(uint8_t additional)
{
if (24 <= additional && additional <= 27) {
/* 24 => 1
* 25 => 2
* 26 => 4
* 27 => 8
*/
return 1 << (additional - 24);
}
return 0;
}
/** Extract the major type, i.e. the first 3 bits of the header byte. */
#define MAJOR_TYPE(header_byte) (((header_byte) >> 5) & 0x7)
/** Extract the additional info, i.e. the last 5 bits of the header byte. */
#define ADDITIONAL(header_byte) ((header_byte) & 0x1F)
#define FAIL_AND_DECR_IF(expr) \
do {\
if (expr) { \
(state->payload)--; \
FAIL(); \
} \
} while(0)
#define FAIL_IF(expr) \
do {\
if (expr) { \
FAIL(); \
} \
} while(0)
#define FAIL_RESTORE() \
state->payload = state->payload_bak; \
state->elem_count++; \
FAIL()
/** Get a single value.
*
* @details @p ppayload must point to the header byte. This function will
* retrieve the value (either from within the additional info, or from
* the subsequent bytes) and return it in the result. The result can
* have arbitrary length.
*
* The function will also validate
* - Min/max constraints on the value.
* - That @p payload doesn't overrun past @p payload_end.
* - That @p elem_count has not been exhausted.
*
* @p ppayload and @p elem_count are updated if the function
* succeeds. If not, they are left unchanged.
*
* CBOR values are always big-endian, so this function converts from
* big to little-endian if necessary (@ref CONFIG_BIG_ENDIAN).
*/
static bool value_extract(cbor_state_t *state,
void *const result, uint32_t result_len)
{
cbor_trace();
cbor_assert(result_len != 0, "0-length result not supported.\n");
cbor_assert(result != NULL, NULL);
FAIL_IF((state->elem_count == 0) \
|| (state->payload >= state->payload_end));
uint8_t *u8_result = (uint8_t *)result;