Initial commit
Initial commit.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef __BOOT_SERIAL_H__
|
||||
#define __BOOT_SERIAL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Function pointers to read/write data from uart.
|
||||
* read returns the number of bytes read, str points to buffer to fill,
|
||||
* cnt is the number of bytes to fill within buffer, *newline will be
|
||||
* set if newline is the last character.
|
||||
* write takes as it's arguments pointer to data to write, and the count
|
||||
* of bytes.
|
||||
*/
|
||||
struct boot_uart_funcs {
|
||||
int (*read)(char *str, int cnt, int *newline);
|
||||
void (*write)(const char *ptr, int cnt);
|
||||
};
|
||||
|
||||
/**
|
||||
* Start processing newtmgr commands for uploading image0 over serial.
|
||||
* Assumes serial port is open and waits for download command.
|
||||
*/
|
||||
void boot_serial_start(const struct boot_uart_funcs *f);
|
||||
|
||||
/**
|
||||
* Start processing newtmgr commands for uploading image0 over serial.
|
||||
* Assumes serial port is open and waits for download command.
|
||||
* This function will return if there is no mcumgr command received within
|
||||
* the given timeout. If a command is received within this timeout, the
|
||||
* function is similar to boot_serial_start
|
||||
*/
|
||||
void boot_serial_check_start(const struct boot_uart_funcs *f, int timeout_in_ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BOOT_SERIAL_H__ */
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*/
|
||||
|
||||
#ifndef H_BOOT_SERIAL_ENCRYPTION_
|
||||
#define H_BOOT_SERIAL_ENCRYPTION_
|
||||
#include "bootutil/fault_injection_hardening.h"
|
||||
|
||||
/**
|
||||
* Validate hash of a primary boot image doing on the fly decryption as well
|
||||
*
|
||||
* @param[in] fa_p flash area pointer
|
||||
* @param[in] hdr boot image header pointer
|
||||
* @param[in] buf buffer which is used for validating data
|
||||
* @param[in] buf_size size of input buffer
|
||||
*
|
||||
* @return FIH_SUCCESS on success, error code otherwise
|
||||
*/
|
||||
fih_ret
|
||||
boot_image_validate_encrypted(const struct flash_area *fa_p,
|
||||
struct image_header *hdr, uint8_t *buf,
|
||||
uint16_t buf_size);
|
||||
|
||||
/**
|
||||
* Handle an encrypted firmware in the main flash.
|
||||
* This will decrypt the image inplace
|
||||
*/
|
||||
int boot_handle_enc_fw(const struct flash_area *flash_area);
|
||||
|
||||
#endif
|
||||
38
bootloader/mcuboot/boot/boot_serial/pkg.yml
Normal file
38
bootloader/mcuboot/boot/boot_serial/pkg.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
pkg.name: boot/boot_serial
|
||||
pkg.description: The boot_serial library is used when downloading image over serial port.
|
||||
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
|
||||
pkg.homepage: "http://mynewt.apache.org/"
|
||||
pkg.keywords:
|
||||
- boot
|
||||
- bootloader
|
||||
|
||||
pkg.deps:
|
||||
- "@apache-mynewt-core/hw/hal"
|
||||
- "@apache-mynewt-core/kernel/os"
|
||||
- "@apache-mynewt-core/encoding/base64"
|
||||
- "@mcuboot/boot/mynewt/flash_map_backend"
|
||||
- "@mcuboot/boot/mynewt/boot_uart"
|
||||
- "@mcuboot/boot/zcbor"
|
||||
- "@apache-mynewt-core/util/crc"
|
||||
|
||||
pkg.req_apis:
|
||||
- bootloader
|
||||
1498
bootloader/mcuboot/boot/boot_serial/src/boot_serial.c
Normal file
1498
bootloader/mcuboot/boot/boot_serial/src/boot_serial.c
Normal file
File diff suppressed because it is too large
Load Diff
308
bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c
Normal file
308
bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2020-2023 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2020 Arm Limited
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "bootutil/image.h"
|
||||
#include <../src/bootutil_priv.h>
|
||||
#include "bootutil/bootutil_log.h"
|
||||
#include "bootutil/bootutil_public.h"
|
||||
#include "bootutil/fault_injection_hardening.h"
|
||||
#include "bootutil/enc_key.h"
|
||||
|
||||
#include "mcuboot_config/mcuboot_config.h"
|
||||
|
||||
#ifdef MCUBOOT_ENC_IMAGES
|
||||
|
||||
BOOT_LOG_MODULE_DECLARE(serial_encryption);
|
||||
|
||||
fih_ret
|
||||
boot_image_validate_encrypted(const struct flash_area *fa_p,
|
||||
struct image_header *hdr, uint8_t *buf,
|
||||
uint16_t buf_size)
|
||||
{
|
||||
FIH_DECLARE(fih_rc, FIH_FAILURE);
|
||||
|
||||
struct boot_loader_state boot_data;
|
||||
struct boot_loader_state *state = &boot_data;
|
||||
struct boot_status _bs;
|
||||
struct boot_status *bs = &_bs;
|
||||
uint8_t image_index;
|
||||
int rc;
|
||||
|
||||
memset(&boot_data, 0, sizeof(struct boot_loader_state));
|
||||
image_index = BOOT_CURR_IMG(state);
|
||||
if(IS_ENCRYPTED(hdr)) {
|
||||
rc = boot_enc_load(BOOT_CURR_ENC(state), 1, hdr, fa_p, bs);
|
||||
if (rc < 0) {
|
||||
FIH_RET(fih_rc);
|
||||
}
|
||||
rc = boot_enc_set_key(BOOT_CURR_ENC(state), 1, bs);
|
||||
if (rc < 0) {
|
||||
FIH_RET(fih_rc);
|
||||
}
|
||||
}
|
||||
FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), image_index,
|
||||
hdr, fa_p, buf, buf_size, NULL, 0, NULL);
|
||||
|
||||
FIH_RET(fih_rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the total size of the given image. Includes the size of
|
||||
* the TLVs.
|
||||
*/
|
||||
static int
|
||||
read_image_size(const struct flash_area *fa_p,
|
||||
struct image_header *hdr,
|
||||
uint32_t *size)
|
||||
{
|
||||
struct image_tlv_info info;
|
||||
uint32_t off;
|
||||
uint32_t protect_tlv_size;
|
||||
int rc;
|
||||
|
||||
off = BOOT_TLV_OFF(hdr);
|
||||
|
||||
if (flash_area_read(fa_p, off, &info, sizeof(info))) {
|
||||
rc = BOOT_EFLASH;
|
||||
goto done;
|
||||
}
|
||||
|
||||
protect_tlv_size = hdr->ih_protect_tlv_size;
|
||||
if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) {
|
||||
if (protect_tlv_size != info.it_tlv_tot) {
|
||||
rc = BOOT_EBADIMAGE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (flash_area_read(fa_p, off + info.it_tlv_tot, &info, sizeof(info))) {
|
||||
rc = BOOT_EFLASH;
|
||||
goto done;
|
||||
}
|
||||
} else if (protect_tlv_size != 0) {
|
||||
rc = BOOT_EBADIMAGE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
|
||||
rc = BOOT_EBADIMAGE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
*size = off + protect_tlv_size + info.it_tlv_tot;
|
||||
rc = 0;
|
||||
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* reads, decrypts in RAM & write back the decrypted image in the same region
|
||||
* This function is NOT power failsafe since the image is decrypted in the RAM
|
||||
* buffer.
|
||||
*
|
||||
* @param flash_area The ID of the source flash area.
|
||||
* @param off_src The offset within the flash area to
|
||||
* copy from.
|
||||
* @param sz The number of bytes to copy. should match erase sector
|
||||
*
|
||||
* @return 0 on success; nonzero on failure.
|
||||
*/
|
||||
static int
|
||||
decrypt_region_inplace(struct boot_loader_state *state,
|
||||
const struct flash_area *fap,
|
||||
struct image_header *hdr,
|
||||
uint32_t off, uint32_t sz)
|
||||
{
|
||||
uint32_t bytes_copied;
|
||||
int chunk_sz;
|
||||
int rc;
|
||||
uint32_t tlv_off;
|
||||
size_t blk_off;
|
||||
uint16_t idx;
|
||||
uint32_t blk_sz;
|
||||
int slot = flash_area_id_to_multi_image_slot(BOOT_CURR_IMG(state),
|
||||
flash_area_get_id(fap));
|
||||
uint8_t buf[sz] __attribute__((aligned));
|
||||
assert(sz <= sizeof buf);
|
||||
assert(slot >= 0);
|
||||
|
||||
bytes_copied = 0;
|
||||
while (bytes_copied < sz) {
|
||||
if (sz - bytes_copied > sizeof buf) {
|
||||
chunk_sz = sizeof buf;
|
||||
} else {
|
||||
chunk_sz = sz - bytes_copied;
|
||||
}
|
||||
|
||||
rc = flash_area_read(fap, off + bytes_copied, buf, chunk_sz);
|
||||
if (rc != 0) {
|
||||
return BOOT_EFLASH;
|
||||
}
|
||||
|
||||
if (IS_ENCRYPTED(hdr)) {
|
||||
blk_sz = chunk_sz;
|
||||
idx = 0;
|
||||
if (off + bytes_copied < hdr->ih_hdr_size) {
|
||||
/* do not decrypt header */
|
||||
if (hdr->ih_hdr_size > (off + bytes_copied + chunk_sz)) {
|
||||
/* all bytes in header, skip decryption */
|
||||
blk_sz = 0;
|
||||
}
|
||||
else {
|
||||
blk_sz = off + bytes_copied + chunk_sz - hdr->ih_hdr_size;
|
||||
}
|
||||
|
||||
blk_off = 0;
|
||||
idx = hdr->ih_hdr_size;
|
||||
} else {
|
||||
blk_off = ((off + bytes_copied) - hdr->ih_hdr_size) & 0xf;
|
||||
}
|
||||
tlv_off = BOOT_TLV_OFF(hdr);
|
||||
if (off + bytes_copied + chunk_sz > tlv_off) {
|
||||
/* do not decrypt TLVs */
|
||||
if (off + bytes_copied >= tlv_off) {
|
||||
blk_sz = 0;
|
||||
} else {
|
||||
blk_sz = tlv_off - (off + bytes_copied);
|
||||
}
|
||||
}
|
||||
boot_enc_decrypt(BOOT_CURR_ENC(state), slot,
|
||||
(off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
|
||||
blk_off, &buf[idx]);
|
||||
}
|
||||
rc = flash_area_erase(fap, off + bytes_copied, chunk_sz);
|
||||
if (rc != 0) {
|
||||
return BOOT_EFLASH;
|
||||
}
|
||||
rc = flash_area_write(fap, off + bytes_copied, buf, chunk_sz);
|
||||
if (rc != 0) {
|
||||
return BOOT_EFLASH;
|
||||
}
|
||||
|
||||
bytes_copied += chunk_sz;
|
||||
|
||||
MCUBOOT_WATCHDOG_FEED();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a image was encrypted into the first slot, and decrypt it
|
||||
* in place. this operation is not power failsafe.
|
||||
*
|
||||
* The operation is done by checking the last flash sector, and using it as a
|
||||
* temporarely scratch partition. The
|
||||
*
|
||||
* @param[in] fa_p flash area pointer
|
||||
* @param[in] hdr boot image header pointer
|
||||
*
|
||||
* @return FIH_SUCCESS on success, error code otherwise
|
||||
*/
|
||||
inline static fih_ret
|
||||
decrypt_image_inplace(const struct flash_area *fa_p,
|
||||
struct image_header *hdr)
|
||||
{
|
||||
FIH_DECLARE(fih_rc, FIH_FAILURE);
|
||||
int rc;
|
||||
struct boot_loader_state boot_data;
|
||||
struct boot_loader_state *state = &boot_data;
|
||||
struct boot_status _bs;
|
||||
struct boot_status *bs = &_bs;
|
||||
size_t size;
|
||||
size_t sect_size;
|
||||
size_t sect_count;
|
||||
size_t sect;
|
||||
struct flash_sector sector;
|
||||
|
||||
memset(&boot_data, 0, sizeof(struct boot_loader_state));
|
||||
memset(&_bs, 0, sizeof(struct boot_status));
|
||||
|
||||
/* Get size from last sector to know page/sector erase size */
|
||||
rc = flash_area_get_sector(fa_p, boot_status_off(fa_p), §or);
|
||||
|
||||
|
||||
if(IS_ENCRYPTED(hdr)) {
|
||||
#if 0 //Skip this step?, the image will just not boot if it's not decrypted properly
|
||||
static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
|
||||
/* First check if the encrypted image is a good image before decrypting */
|
||||
FIH_CALL(boot_image_validate_encrypted,fih_rc,fa_p,&_hdr,tmpbuf,BOOT_TMPBUF_SZ);
|
||||
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
|
||||
FIH_RET(fih_rc);
|
||||
}
|
||||
#endif
|
||||
memset(&boot_data, 0, sizeof(struct boot_loader_state));
|
||||
/* Load the encryption keys into cache */
|
||||
rc = boot_enc_load(BOOT_CURR_ENC(state), 0, hdr, fa_p, bs);
|
||||
if (rc < 0) {
|
||||
FIH_RET(fih_rc);
|
||||
}
|
||||
if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 0, bs)) {
|
||||
FIH_RET(fih_rc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Expected encrypted image! */
|
||||
FIH_RET(fih_rc);
|
||||
}
|
||||
|
||||
uint32_t src_size = 0;
|
||||
rc = read_image_size(fa_p,hdr, &src_size);
|
||||
if (rc != 0) {
|
||||
FIH_RET(fih_rc);
|
||||
}
|
||||
|
||||
/* TODO: This assumes every sector has an equal size, should instead use
|
||||
* flash_area_get_sectors() to get the size of each sector and iterate
|
||||
* over it.
|
||||
*/
|
||||
sect_size = sector.fs_size;
|
||||
sect_count = fa_p->fa_size / sect_size;
|
||||
for (sect = 0, size = 0; size < src_size && sect < sect_count; sect++) {
|
||||
rc = decrypt_region_inplace(state, fa_p,hdr, size, sect_size);
|
||||
if (rc != 0) {
|
||||
FIH_RET(fih_rc);
|
||||
}
|
||||
size += sect_size;
|
||||
}
|
||||
|
||||
fih_rc = FIH_SUCCESS;
|
||||
FIH_RET(fih_rc);
|
||||
}
|
||||
|
||||
int
|
||||
boot_handle_enc_fw(const struct flash_area *flash_area)
|
||||
{
|
||||
int rc = -1;
|
||||
struct image_header _hdr = { 0 };
|
||||
FIH_DECLARE(fih_rc, FIH_FAILURE);
|
||||
|
||||
rc = boot_image_load_header(flash_area, &_hdr);
|
||||
if (rc != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (IS_ENCRYPTED(&_hdr)) {
|
||||
//encrypted, we need to decrypt in place
|
||||
FIH_CALL(decrypt_image_inplace,fih_rc,flash_area,&_hdr);
|
||||
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
106
bootloader/mcuboot/boot/boot_serial/src/boot_serial_priv.h
Normal file
106
bootloader/mcuboot/boot/boot_serial/src/boot_serial_priv.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef __BOOTUTIL_SERIAL_PRIV_H__
|
||||
#define __BOOTUTIL_SERIAL_PRIV_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* From shell.h
|
||||
*/
|
||||
#define SHELL_NLIP_PKT_START1 6
|
||||
#define SHELL_NLIP_PKT_START2 9
|
||||
|
||||
#define SHELL_NLIP_DATA_START1 4
|
||||
#define SHELL_NLIP_DATA_START2 20
|
||||
|
||||
/*
|
||||
* From newtmgr.h
|
||||
*/
|
||||
#define MGMT_ERR_OK 0
|
||||
#define MGMT_ERR_EUNKNOWN 1
|
||||
#define MGMT_ERR_ENOMEM 2
|
||||
#define MGMT_ERR_EINVAL 3
|
||||
#define MGMT_ERR_ENOENT 5
|
||||
#define MGMT_ERR_ENOTSUP 8
|
||||
#define MGMT_ERR_EBUSY 10
|
||||
|
||||
#define NMGR_OP_READ 0
|
||||
#define NMGR_OP_WRITE 2
|
||||
|
||||
#define MGMT_GROUP_ID_DEFAULT 0
|
||||
#define MGMT_GROUP_ID_IMAGE 1
|
||||
#define MGMT_GROUP_ID_PERUSER 64
|
||||
|
||||
#define NMGR_ID_ECHO 0
|
||||
#define NMGR_ID_CONS_ECHO_CTRL 1
|
||||
#define NMGR_ID_RESET 5
|
||||
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
struct nmgr_hdr {
|
||||
#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
uint8_t _res1:3;
|
||||
uint8_t nh_version:2;
|
||||
uint8_t nh_op:3; /* NMGR_OP_XXX */
|
||||
#else
|
||||
uint8_t nh_op:3; /* NMGR_OP_XXX */
|
||||
uint8_t nh_version:2;
|
||||
uint8_t _res1:3;
|
||||
#endif
|
||||
uint8_t nh_flags;
|
||||
uint16_t nh_len; /* length of the payload */
|
||||
uint16_t nh_group; /* NMGR_GROUP_XXX */
|
||||
uint8_t nh_seq; /* sequence number */
|
||||
uint8_t nh_id; /* message ID within group */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* From imgmgr.h
|
||||
*/
|
||||
#define IMGMGR_NMGR_ID_STATE 0
|
||||
#define IMGMGR_NMGR_ID_UPLOAD 1
|
||||
#define IMGMGR_NMGR_ID_SLOT_INFO 6
|
||||
|
||||
void boot_serial_input(char *buf, int len);
|
||||
extern const struct boot_uart_funcs *boot_uf;
|
||||
|
||||
/**
|
||||
* @brief Selects direct image to upload according to the "image"
|
||||
* parameter of the mcumgr update frame.
|
||||
*
|
||||
* @param[in] image_id the value of the "image" parameter of the
|
||||
* mcumgr update frame to be translated.
|
||||
*
|
||||
* @return flash area ID for the image if defined;
|
||||
* -EINVAL when flash area for given image number has not been
|
||||
* defined.
|
||||
*/
|
||||
extern int flash_area_id_from_direct_image(int image_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BOOTUTIL_SERIAL_PRIV_H__ */
|
||||
69
bootloader/mcuboot/boot/boot_serial/src/zcbor_bulk.c
Normal file
69
bootloader/mcuboot/boot/boot_serial/src/zcbor_bulk.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "zcbor_bulk.h"
|
||||
|
||||
int zcbor_map_decode_bulk(zcbor_state_t *zsd, struct zcbor_map_decode_key_val *map,
|
||||
size_t map_size, size_t *matched)
|
||||
{
|
||||
bool ok;
|
||||
struct zcbor_map_decode_key_val *dptr = map;
|
||||
|
||||
if (!zcbor_map_start_decode(zsd)) {
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
*matched = 0;
|
||||
ok = true;
|
||||
|
||||
do {
|
||||
struct zcbor_string key;
|
||||
bool found = false;
|
||||
size_t map_count = 0;
|
||||
|
||||
ok = zcbor_tstr_decode(zsd, &key);
|
||||
|
||||
while (ok && map_count < map_size) {
|
||||
if (dptr >= (map + map_size)) {
|
||||
dptr = map;
|
||||
}
|
||||
|
||||
if (key.len == dptr->key.len &&
|
||||
memcmp(key.value, dptr->key.value, key.len) == 0) {
|
||||
|
||||
if (dptr->found) {
|
||||
return -EADDRINUSE;
|
||||
}
|
||||
if (!dptr->decoder(zsd, dptr->value_ptr)) {
|
||||
/* Failure to decode value matched to key
|
||||
* means that either decoder has been
|
||||
* incorrectly assigned or SMP payload
|
||||
* is broken anyway.
|
||||
*/
|
||||
return -ENOMSG;
|
||||
}
|
||||
|
||||
dptr->found = true;
|
||||
found = true;
|
||||
++dptr;
|
||||
++(*matched);
|
||||
break;
|
||||
}
|
||||
|
||||
++dptr;
|
||||
++map_count;
|
||||
}
|
||||
|
||||
if (!found && ok) {
|
||||
ok = zcbor_any_skip(zsd, NULL);
|
||||
}
|
||||
} while (ok);
|
||||
|
||||
return zcbor_map_end_decode(zsd) ? 0 : -EBADMSG;
|
||||
}
|
||||
116
bootloader/mcuboot/boot/boot_serial/src/zcbor_bulk.h
Normal file
116
bootloader/mcuboot/boot/boot_serial/src/zcbor_bulk.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef H_ZCBOR_BULK_PRIV_
|
||||
#define H_ZCBOR_BULK_PRIV_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __ZEPHYR__
|
||||
#include <zcbor_common.h>
|
||||
#include <zcbor_decode.h>
|
||||
#else
|
||||
#include "zcbor_common.h"
|
||||
#include "zcbor_decode.h"
|
||||
#endif
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
|
||||
struct zcbor_map_decode_key_val {
|
||||
struct zcbor_string key; /* Map key string */
|
||||
zcbor_decoder_t *decoder; /* Key corresponding decoder */
|
||||
void *value_ptr;
|
||||
bool found;
|
||||
};
|
||||
|
||||
/** @brief Define single key-decoder mapping
|
||||
*
|
||||
* The macro creates a single zcbor_map_decode_key_val type object.
|
||||
*
|
||||
* @param k key is "" enclosed string representing key;
|
||||
* @param dec decoder function; this should be zcbor_decoder_t
|
||||
* type function from zcbor or a user provided implementation
|
||||
* compatible with the type.
|
||||
* @param vp non-NULL pointer for result of decoding; should correspond
|
||||
* to type served by decoder function for the mapping.
|
||||
*/
|
||||
#define ZCBOR_MAP_DECODE_KEY_DECODER(k, dec, vp) \
|
||||
{ \
|
||||
{ \
|
||||
.value = (uint8_t *)k, \
|
||||
.len = sizeof(k) - 1, \
|
||||
}, \
|
||||
.decoder = (zcbor_decoder_t *)dec, \
|
||||
.value_ptr = vp, \
|
||||
}
|
||||
|
||||
/** @brief Define single key-value decode mapping
|
||||
*
|
||||
* ZCBOR_MAP_DECODE_KEY_DECODER should be used instead of this macro as,
|
||||
* this macro does not allow keys with whitespaces embeeded, which CBOR
|
||||
* does allow.
|
||||
*
|
||||
* The macro creates a single zcbor_map_decode_key_val type object.
|
||||
*
|
||||
* @param k key; the @p k will be stringified so should be given
|
||||
* without "";
|
||||
* @param dec decoder function; this should be zcbor_decoder_t
|
||||
* type function from zcbor or a user provided implementation
|
||||
* compatible with the type.
|
||||
* @param vp non-NULL pointer for result of decoding; should correspond
|
||||
* to type served by decoder function for the mapping.
|
||||
*/
|
||||
#define ZCBOR_MAP_DECODE_KEY_VAL(k, dec, vp) \
|
||||
ZCBOR_MAP_DECODE_KEY_DECODER(STRINGIFY(k), dec, vp)
|
||||
|
||||
/** @brief Decodes single level map according to a provided key-decode map.
|
||||
*
|
||||
* The function takes @p map of key to decoder array defined as:
|
||||
*
|
||||
* struct zcbor_map_decode_key_val map[] = {
|
||||
* ZCBOR_MAP_DECODE_KEY_DECODER("key0", decode_fun0, val_ptr0),
|
||||
* ZCBOR_MAP_DECODE_KEY_DECODER("key1", decode_fun1, val_ptr1),
|
||||
* ...
|
||||
* };
|
||||
*
|
||||
* where "key?" is string representing key; the decode_fun? is
|
||||
* zcbor_decoder_t compatible function, either from zcbor or defined by
|
||||
* user; val_ptr? are pointers to variables where decoder function for
|
||||
* a given key will place a decoded value - they have to agree in type
|
||||
* with decoder function.
|
||||
*
|
||||
* Failure to decode any of values will cause the function to return
|
||||
* negative error, and leave the map open: map is broken anyway or key-decoder
|
||||
* mapping is broken, and we can not really decode the map.
|
||||
*
|
||||
* Note that the function opens map by itself and will fail if map
|
||||
* is already opened.
|
||||
*
|
||||
* @param zsd zcbor decoder state;
|
||||
* @param map key-decoder mapping list;
|
||||
* @param map_size size of maps, both maps have to have the same size;
|
||||
* @param matched pointer to the counter of matched keys, zeroed upon
|
||||
* successful map entry and incremented only for successful
|
||||
* decoded fields.
|
||||
* @return 0 when the whole map has been parsed, there have been
|
||||
* no decoding errors, and map has been closed successfully;
|
||||
* -ENOMSG when given decoder function failed to decode
|
||||
* value;
|
||||
* -EADDRINUSE when key appears twice within map, map is then
|
||||
* parsed up to they key that has appeared twice;
|
||||
* -EBADMSG when failed to close map.
|
||||
*/
|
||||
int zcbor_map_decode_bulk(zcbor_state_t *zsd, struct zcbor_map_decode_key_val *map,
|
||||
size_t map_size, size_t *matched);
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_ZCBOR_BULK_PRIV_ */
|
||||
96
bootloader/mcuboot/boot/boot_serial/syscfg.yml
Normal file
96
bootloader/mcuboot/boot/boot_serial/syscfg.yml
Normal file
@@ -0,0 +1,96 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
syscfg.defs:
|
||||
BOOT_SERIAL_DETECT_PIN:
|
||||
description: >
|
||||
Start the serial boot loader if this pin is asserted at boot time.
|
||||
value: '-1'
|
||||
restrictions:
|
||||
- '(BOOT_SERIAL_DETECT_PIN != -1) ||
|
||||
(BOOT_SERIAL_DETECT_TIMEOUT != 0) ||
|
||||
(BOOT_SERIAL_NVREG_INDEX != -1)'
|
||||
|
||||
BOOT_SERIAL_DETECT_PIN_CFG:
|
||||
description: >
|
||||
GPIO configuration for the serial boot loader detect pin.
|
||||
value: 'HAL_GPIO_PULL_UP'
|
||||
|
||||
BOOT_SERIAL_DETECT_PIN_VAL:
|
||||
description: >
|
||||
The value the detect pin must be set to for the serial boot loader
|
||||
to start.
|
||||
value: 0
|
||||
|
||||
BOOT_SERIAL_DETECT_TIMEOUT:
|
||||
description: >
|
||||
The duration, in milliseconds, to listen on the UART for the
|
||||
management string (BOOT_SERIAL_DETECT_STRING). If the management
|
||||
string is detected during this period, the serial boot loader is
|
||||
started. If the period expires without the management string being
|
||||
received, the boot loader runs in the normal (non-serial) mode.
|
||||
Specify 0 to disable listening on the UART for the management
|
||||
string.
|
||||
value: 0
|
||||
restrictions:
|
||||
- '(BOOT_SERIAL_DETECT_PIN != -1) ||
|
||||
(BOOT_SERIAL_DETECT_TIMEOUT != 0) ||
|
||||
(BOOT_SERIAL_NVREG_INDEX != -1)'
|
||||
|
||||
BOOT_SERIAL_DETECT_STRING:
|
||||
description: >
|
||||
The string to listen for on the UART. If this management string is
|
||||
detected during the timeout period, the serial boot loader is
|
||||
started. If the period expires without this string being received,
|
||||
the boot loader runs in the normal (non-serial) mode. This setting
|
||||
has no effect if BOOT_SERIAL_DETECT_TIMEOUT is set to 0.
|
||||
value: '"nmgr"'
|
||||
|
||||
BOOT_SERIAL_REPORT_PIN:
|
||||
description: >
|
||||
The GPIO to toggle while the serial boot loader is running. Set to
|
||||
-1 to disable reporting.
|
||||
value: 'LED_BLINK_PIN'
|
||||
|
||||
BOOT_SERIAL_REPORT_FREQ:
|
||||
description: >
|
||||
The toggle rate, in Hz, of the serial boot loader report pin.
|
||||
value: 4
|
||||
|
||||
BOOT_SERIAL_NVREG_MAGIC:
|
||||
description: >
|
||||
Magic number, to be saved in a retained (reset-surviving) register.
|
||||
If the value in the register matches, the serial bootloader will
|
||||
load. Value must not be 0.
|
||||
value: 0xB7
|
||||
restrictions:
|
||||
- '(BOOT_SERIAL_NVREG_MAGIC != 0)'
|
||||
|
||||
BOOT_SERIAL_NVREG_INDEX:
|
||||
description: >
|
||||
Index of retained register to use (using hal_nvreg_read) for reading
|
||||
magic value.
|
||||
value: -1
|
||||
restrictions:
|
||||
- '(BOOT_SERIAL_DETECT_PIN != -1) ||
|
||||
(BOOT_SERIAL_DETECT_TIMEOUT != 0) ||
|
||||
(BOOT_SERIAL_NVREG_INDEX != -1)'
|
||||
|
||||
BOOT_SERIAL_MGMT_ECHO:
|
||||
description: If enabled, support for the mcumgr echo command is being added.
|
||||
value: 0
|
||||
35
bootloader/mcuboot/boot/boot_serial/test/pkg.yml
Normal file
35
bootloader/mcuboot/boot/boot_serial/test/pkg.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
pkg.name: boot/boot_serial/test
|
||||
pkg.type: unittest
|
||||
pkg.description: "Boot serial unit tests."
|
||||
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
|
||||
pkg.homepage: "http://mynewt.apache.org/"
|
||||
pkg.keywords:
|
||||
|
||||
pkg.deps:
|
||||
- "@mcuboot/boot/boot_serial"
|
||||
- "@mcuboot/boot/bootutil"
|
||||
- "@apache-mynewt-core/sys/log/stub"
|
||||
- "@apache-mynewt-core/test/testutil"
|
||||
|
||||
pkg.deps.SELFTEST:
|
||||
- "@apache-mynewt-core/sys/console/stub"
|
||||
|
||||
pkg.cflags:
|
||||
- '-DMCUBOOT_MYNEWT=1'
|
||||
85
bootloader/mcuboot/boot/boot_serial/test/src/boot_test.c
Normal file
85
bootloader/mcuboot/boot/boot_serial/test/src/boot_test.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "sysflash/sysflash.h"
|
||||
#include "os/endian.h"
|
||||
#include "base64/base64.h"
|
||||
#include "crc/crc16.h"
|
||||
#include "testutil/testutil.h"
|
||||
#include "hal/hal_flash.h"
|
||||
#include "flash_map_backend/flash_map_backend.h"
|
||||
|
||||
#include "boot_serial/boot_serial.h"
|
||||
#include "boot_serial_priv.h"
|
||||
|
||||
TEST_CASE_DECL(boot_serial_setup)
|
||||
TEST_CASE_DECL(boot_serial_empty_msg)
|
||||
TEST_CASE_DECL(boot_serial_empty_img_msg)
|
||||
TEST_CASE_DECL(boot_serial_img_msg)
|
||||
TEST_CASE_DECL(boot_serial_upload_bigger_image)
|
||||
|
||||
static void
|
||||
test_uart_write(const char *str, int len)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct boot_uart_funcs test_uart = {
|
||||
.write = test_uart_write
|
||||
};
|
||||
|
||||
void
|
||||
tx_msg(void *src, int len)
|
||||
{
|
||||
boot_serial_input(src, len);
|
||||
}
|
||||
|
||||
TEST_SUITE(boot_serial_suite)
|
||||
{
|
||||
boot_serial_setup();
|
||||
boot_serial_empty_msg();
|
||||
boot_serial_empty_img_msg();
|
||||
boot_serial_img_msg();
|
||||
boot_serial_upload_bigger_image();
|
||||
}
|
||||
|
||||
int
|
||||
boot_serial_test(void)
|
||||
{
|
||||
boot_uf = &test_uart;
|
||||
boot_serial_suite();
|
||||
return tu_any_failed;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(SELFTEST)
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
sysinit();
|
||||
|
||||
boot_serial_test();
|
||||
|
||||
return tu_any_failed;
|
||||
}
|
||||
#endif
|
||||
50
bootloader/mcuboot/boot/boot_serial/test/src/boot_test.h
Normal file
50
bootloader/mcuboot/boot/boot_serial/test/src/boot_test.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#ifndef _BOOT_TEST_H
|
||||
#define _BOOT_TEST_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "sysflash/sysflash.h"
|
||||
#include "os/endian.h"
|
||||
#include "base64/base64.h"
|
||||
#include "crc/crc16.h"
|
||||
#include "testutil/testutil.h"
|
||||
#include "hal/hal_flash.h"
|
||||
#include "flash_map_backend/flash_map_backend.h"
|
||||
#include "bootutil/bootutil.h"
|
||||
|
||||
#include "boot_serial_priv.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void tx_msg(void *src, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BOOT_TEST_H */
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#include "boot_test.h"
|
||||
|
||||
TEST_CASE(boot_serial_empty_img_msg)
|
||||
{
|
||||
char buf[sizeof(struct nmgr_hdr) + 32];
|
||||
struct nmgr_hdr *hdr;
|
||||
|
||||
hdr = (struct nmgr_hdr *)buf;
|
||||
memset(hdr, 0, sizeof(*hdr));
|
||||
hdr->nh_op = NMGR_OP_WRITE;
|
||||
hdr->nh_group = htons(MGMT_GROUP_ID_IMAGE);
|
||||
hdr->nh_id = IMGMGR_NMGR_ID_UPLOAD;
|
||||
hdr->nh_len = htons(2);
|
||||
strcpy((char *)(hdr + 1), "{}");
|
||||
|
||||
tx_msg(buf, sizeof(*hdr) + 2);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#include "boot_test.h"
|
||||
|
||||
TEST_CASE(boot_serial_empty_msg)
|
||||
{
|
||||
char buf[4];
|
||||
struct nmgr_hdr hdr;
|
||||
|
||||
tx_msg(buf, 0);
|
||||
|
||||
strcpy(buf, "--");
|
||||
tx_msg(buf, 2);
|
||||
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
tx_msg(&hdr, sizeof(hdr));
|
||||
|
||||
hdr.nh_op = NMGR_OP_WRITE;
|
||||
|
||||
tx_msg(&hdr, sizeof(hdr));
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "boot_test.h"
|
||||
|
||||
TEST_CASE(boot_serial_img_msg)
|
||||
{
|
||||
char img[16];
|
||||
char enc_img[BASE64_ENCODE_SIZE(sizeof(img)) + 1];
|
||||
char buf[sizeof(struct nmgr_hdr) + sizeof(enc_img) + 32];
|
||||
int len;
|
||||
int rc;
|
||||
struct nmgr_hdr *hdr;
|
||||
const struct flash_area *fap;
|
||||
|
||||
/* 00000000 a3 64 64 61 74 61 58 10 |.ddataX.|
|
||||
* 00000008 a5 a5 a5 a5 a5 a5 a5 a5 |........|
|
||||
* 00000010 a5 a5 a5 a5 a5 a5 a5 a5 |........|
|
||||
* 00000018 63 6c 65 6e 1a 00 01 14 |clen....|
|
||||
* 00000020 e8 63 6f 66 66 00 |.coff.|
|
||||
*/
|
||||
static const uint8_t payload[] = {
|
||||
0xa3, 0x64, 0x64, 0x61, 0x74, 0x61, 0x58, 0x10,
|
||||
/* 16 bytes of image data starts here. */
|
||||
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
|
||||
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
|
||||
0x63, 0x6c, 0x65, 0x6e, 0x1a, 0x00, 0x01, 0x14,
|
||||
0xe8, 0x63, 0x6f, 0x66, 0x66, 0x00,
|
||||
};
|
||||
|
||||
memset(img, 0xa5, sizeof(img));
|
||||
|
||||
hdr = (struct nmgr_hdr *)buf;
|
||||
memset(hdr, 0, sizeof(*hdr));
|
||||
hdr->nh_op = NMGR_OP_WRITE;
|
||||
hdr->nh_group = htons(MGMT_GROUP_ID_IMAGE);
|
||||
hdr->nh_id = IMGMGR_NMGR_ID_UPLOAD;
|
||||
|
||||
memcpy(hdr + 1, payload, sizeof payload);
|
||||
hdr->nh_len = htons(sizeof payload);
|
||||
|
||||
len = sizeof(*hdr) + sizeof payload;
|
||||
tx_msg(buf, len);
|
||||
|
||||
/*
|
||||
* Validate contents inside the primary slot
|
||||
*/
|
||||
rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &fap);
|
||||
assert(rc == 0);
|
||||
|
||||
rc = flash_area_read(fap, 0, enc_img, sizeof(img));
|
||||
assert(rc == 0);
|
||||
assert(!memcmp(enc_img, img, sizeof(img)));
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#include "boot_test.h"
|
||||
|
||||
TEST_CASE(boot_serial_setup)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <flash_map_backend/flash_map_backend.h>
|
||||
|
||||
#include "boot_test.h"
|
||||
#include "zcbor_common.h"
|
||||
|
||||
TEST_CASE(boot_serial_upload_bigger_image)
|
||||
{
|
||||
char img[256];
|
||||
char enc_img[64];
|
||||
char buf[sizeof(struct nmgr_hdr) + 128];
|
||||
int len;
|
||||
int off;
|
||||
int rc;
|
||||
struct nmgr_hdr *hdr;
|
||||
const struct flash_area *fap;
|
||||
int i;
|
||||
|
||||
const int payload_off = sizeof *hdr;
|
||||
const int img_data_off = payload_off + 8;
|
||||
|
||||
/* 00000000 a3 64 64 61 74 61 58 20 |.ddataX.|
|
||||
* 00000008 00 00 00 00 00 00 00 00 |........|
|
||||
* 00000010 00 00 00 00 00 00 00 00 |........|
|
||||
* 00000018 00 00 00 00 00 00 00 00 |........|
|
||||
* 00000020 00 00 00 00 00 00 00 00 |........|
|
||||
* 00000028 63 6c 65 6e 1a 00 01 14 |clen....|
|
||||
* 00000030 e8 63 6f 66 66 00 |.coff.|
|
||||
*/
|
||||
static const uint8_t payload_first[] = {
|
||||
0xa3, 0x64, 0x64, 0x61, 0x74, 0x61, 0x58, 0x20,
|
||||
/* 32 bytes of image data starts here. */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x63, 0x6c, 0x65, 0x6e, 0x1a, 0x00, 0x01, 0x14,
|
||||
0xe8, 0x63, 0x6f, 0x66, 0x66, 0x00,
|
||||
};
|
||||
|
||||
/* 00000000 a3 64 64 61 74 61 58 20 |.ddataX.|
|
||||
* 00000008 00 00 00 00 00 00 00 00 |........|
|
||||
* 00000010 00 00 00 00 00 00 00 00 |........|
|
||||
* 00000018 00 00 00 00 00 00 00 00 |........|
|
||||
* 00000020 00 00 00 00 00 00 00 00 |........|
|
||||
* 00000028 63 6f 66 66 00 00 |coff..|
|
||||
*/
|
||||
static const uint8_t payload_next[] = {
|
||||
0xa2, 0x64, 0x64, 0x61, 0x74, 0x61, 0x58, 0x20,
|
||||
/* 32 bytes of image data starts here. */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x63, 0x6f, 0x66, 0x66,
|
||||
/* 2 bytes of offset value starts here. */
|
||||
0x00, 0x00
|
||||
};
|
||||
|
||||
for (i = 0; i < sizeof(img); i++) {
|
||||
img[i] = i;
|
||||
}
|
||||
|
||||
for (off = 0; off < sizeof(img); off += 32) {
|
||||
hdr = (struct nmgr_hdr *)buf;
|
||||
memset(hdr, 0, sizeof(*hdr));
|
||||
hdr->nh_op = NMGR_OP_WRITE;
|
||||
hdr->nh_group = htons(MGMT_GROUP_ID_IMAGE);
|
||||
hdr->nh_id = IMGMGR_NMGR_ID_UPLOAD;
|
||||
|
||||
if (off) {
|
||||
memcpy(buf + payload_off, payload_next, sizeof payload_next);
|
||||
len = sizeof payload_next;
|
||||
buf[payload_off + len - 2] = ZCBOR_VALUE_IS_1_BYTE;
|
||||
buf[payload_off + len - 1] = off;
|
||||
} else {
|
||||
memcpy(buf + payload_off, payload_first, sizeof payload_first);
|
||||
len = sizeof payload_first;
|
||||
}
|
||||
memcpy(buf + img_data_off, img + off, 32);
|
||||
hdr->nh_len = htons(len);
|
||||
|
||||
len = sizeof(*hdr) + len;
|
||||
|
||||
tx_msg(buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate contents inside the primary slot
|
||||
*/
|
||||
rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &fap);
|
||||
assert(rc == 0);
|
||||
|
||||
for (off = 0; off < sizeof(img); off += sizeof(enc_img)) {
|
||||
rc = flash_area_read(fap, off, enc_img, sizeof(enc_img));
|
||||
assert(rc == 0);
|
||||
assert(!memcmp(enc_img, &img[off], sizeof(enc_img)));
|
||||
}
|
||||
}
|
||||
23
bootloader/mcuboot/boot/boot_serial/test/syscfg.yml
Normal file
23
bootloader/mcuboot/boot/boot_serial/test/syscfg.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
# Package: boot/boot_serial/test
|
||||
|
||||
syscfg.vals:
|
||||
# This is here to work around the $notnull syscfg restriction.
|
||||
BOOT_SERIAL_DETECT_PIN: 0
|
||||
Reference in New Issue
Block a user