mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
suit/transport/mock: Use common storage backend
This commit is contained in:
parent
edeffdcd54
commit
b72d510690
61
sys/include/suit/transport/mock.h
Normal file
61
sys/include/suit/transport/mock.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Koen Zandberg
|
||||
* 2020 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
/**
|
||||
* @defgroup sys_suit_transport_mock SUIT secure firmware OTA mock transport
|
||||
* @ingroup sys_suit
|
||||
* @brief SUIT firmware mock transport
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @brief Mock transport backend definitions for SUIT manifests
|
||||
* @author Koen Zandberg <koen@bergzand.net>
|
||||
*
|
||||
* The mock transport is a noop transport. Payloads are preloaded in flash and
|
||||
* provided as an array of @ref suit_transport_mock_payload_t to the module.
|
||||
*
|
||||
* Both the array of payloads named `payloads` and the size with name
|
||||
* `num_payloads` must be provided.
|
||||
*/
|
||||
|
||||
#ifndef SUIT_TRANSPORT_MOCK_H
|
||||
#define SUIT_TRANSPORT_MOCK_H
|
||||
|
||||
#include "suit.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Mock payload.
|
||||
*/
|
||||
typedef struct {
|
||||
const uint8_t *buf; /**< Ptr to the memory space containing the payload */
|
||||
size_t len; /**< Length of the payload in bytes */
|
||||
} suit_transport_mock_payload_t;
|
||||
|
||||
/**
|
||||
* @brief 'fetch' a payload
|
||||
*
|
||||
* The payload fetched from the payloads array is indicated by the @ref
|
||||
* suit_manifest_t::component_current member
|
||||
*
|
||||
* @param[in] manifest suit manifest context
|
||||
*
|
||||
* @returns SUIT_OK if valid
|
||||
* @returns negative otherwise
|
||||
*/
|
||||
int suit_transport_mock_fetch(const suit_manifest_t *manifest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SUIT_TRANSPORT_MOCK_H */
|
||||
/** @} */
|
@ -47,9 +47,9 @@ static int _get_component_size(suit_manifest_t *manifest,
|
||||
uint32_t *img_size)
|
||||
{
|
||||
nanocbor_value_t param_size;
|
||||
if ((suit_param_ref_to_cbor(manifest, &comp->param_size, ¶m_size) == 0) ||
|
||||
(nanocbor_get_uint32(¶m_size, img_size) < 0)) {
|
||||
return SUIT_ERR_INVALID_MANIFEST;
|
||||
if ((suit_param_ref_to_cbor(manifest, &comp->param_size, ¶m_size) == 0)
|
||||
|| (nanocbor_get_uint32(¶m_size, img_size) < 0)) { return
|
||||
SUIT_ERR_INVALID_MANIFEST;
|
||||
}
|
||||
return SUIT_OK;
|
||||
}
|
||||
@ -201,8 +201,7 @@ static int _dtv_run_seq_cond(suit_manifest_t *manifest,
|
||||
(void)key;
|
||||
LOG_DEBUG("Starting conditional sequence handler\n");
|
||||
return suit_handle_manifest_structure_bstr(manifest, it,
|
||||
suit_command_sequence_handlers,
|
||||
suit_command_sequence_handlers_len);
|
||||
suit_command_sequence_handlers, suit_command_sequence_handlers_len);
|
||||
}
|
||||
|
||||
static int _dtv_try_each(suit_manifest_t *manifest,
|
||||
@ -223,8 +222,8 @@ static int _dtv_try_each(suit_manifest_t *manifest,
|
||||
/* `_container` should be CBOR _bstr wrapped according to the spec, but
|
||||
* it is not */
|
||||
res = suit_handle_manifest_structure_bstr(manifest, &_container,
|
||||
suit_command_sequence_handlers,
|
||||
suit_command_sequence_handlers_len);
|
||||
suit_command_sequence_handlers,
|
||||
suit_command_sequence_handlers_len);
|
||||
|
||||
nanocbor_skip(&container);
|
||||
|
||||
@ -366,7 +365,7 @@ static int _dtv_fetch(suit_manifest_t *manifest, int key,
|
||||
#endif
|
||||
#ifdef MODULE_SUIT_TRANSPORT_MOCK
|
||||
else if (strncmp(manifest->urlbuf, "test://", 7) == 0) {
|
||||
res = SUIT_OK;
|
||||
res = suit_transport_mock_fetch(manifest);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
@ -379,7 +378,7 @@ static int _dtv_fetch(suit_manifest_t *manifest, int key,
|
||||
if (res) {
|
||||
suit_component_set_flag(comp, SUIT_COMPONENT_STATE_FETCH_FAILED);
|
||||
/* TODO: The leftover data from a failed fetch should be purged. It
|
||||
* could contain potential malicous data from an attacker */
|
||||
* could contain potential malicious data from an attacker */
|
||||
LOG_INFO("image download failed with code %i\n", res);
|
||||
return res;
|
||||
}
|
||||
@ -388,7 +387,8 @@ static int _dtv_fetch(suit_manifest_t *manifest, int key,
|
||||
return SUIT_OK;
|
||||
}
|
||||
|
||||
static int _get_digest(nanocbor_value_t *bstr, const uint8_t **digest, size_t *digest_len)
|
||||
static int _get_digest(nanocbor_value_t *bstr, const uint8_t **digest, size_t
|
||||
*digest_len)
|
||||
{
|
||||
/* Bstr is a byte string with a cbor array containing the type and the
|
||||
* digest */
|
||||
@ -407,7 +407,8 @@ static int _get_digest(nanocbor_value_t *bstr, const uint8_t **digest, size_t *d
|
||||
return nanocbor_get_bstr(&arr_it, digest, digest_len);
|
||||
}
|
||||
|
||||
static int _validate_payload(suit_component_t *component, const uint8_t *digest, size_t payload_size)
|
||||
static int _validate_payload(suit_component_t *component, const uint8_t *digest,
|
||||
size_t payload_size)
|
||||
{
|
||||
uint8_t payload_digest[SHA256_DIGEST_LENGTH];
|
||||
suit_storage_t *storage = component->storage_backend;
|
||||
@ -446,7 +447,6 @@ static int _validate_payload(suit_component_t *component, const uint8_t *digest,
|
||||
SUIT_OK : SUIT_ERR_DIGEST_MISMATCH;
|
||||
}
|
||||
|
||||
|
||||
static int _dtv_verify_image_match(suit_manifest_t *manifest, int key,
|
||||
nanocbor_value_t *_it)
|
||||
{
|
||||
@ -463,7 +463,8 @@ static int _dtv_verify_image_match(suit_manifest_t *manifest, int key,
|
||||
|
||||
/* Only check the component if it is fetched, but not failed */
|
||||
if (!suit_component_check_flag(comp, SUIT_COMPONENT_STATE_FETCHED) ||
|
||||
suit_component_check_flag(comp, SUIT_COMPONENT_STATE_FETCH_FAILED)) {
|
||||
suit_component_check_flag(comp,
|
||||
SUIT_COMPONENT_STATE_FETCH_FAILED)) {
|
||||
LOG_ERROR("Fetch failed, or nothing fetched, nothing to check: %u\n",
|
||||
comp->state);
|
||||
return SUIT_ERR_INVALID_MANIFEST;
|
||||
@ -513,4 +514,5 @@ const suit_manifest_handler_t suit_command_sequence_handlers[] = {
|
||||
};
|
||||
/* end{code-style-ignore} */
|
||||
|
||||
const size_t suit_command_sequence_handlers_len = ARRAY_SIZE(suit_command_sequence_handlers);
|
||||
const size_t suit_command_sequence_handlers_len =
|
||||
ARRAY_SIZE(suit_command_sequence_handlers);
|
||||
|
@ -11,71 +11,32 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "kernel_defines.h"
|
||||
#include "cpu_conf.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "riotboot/flashwrite.h"
|
||||
#include "riotboot/hdr.h"
|
||||
#include "suit.h"
|
||||
#include "suit/storage.h"
|
||||
#include "suit/transport/mock.h"
|
||||
|
||||
#define SLOT0_OFFSET 0x1000
|
||||
#define SLOT1_OFFSET 0x2000
|
||||
/* Must be defined by the test */
|
||||
extern const suit_transport_mock_payload_t payloads[];
|
||||
extern const size_t num_payloads;
|
||||
|
||||
static riotboot_hdr_t _riotboot_slots[] = {
|
||||
{ .magic_number = RIOTBOOT_MAGIC,
|
||||
.version = 1,
|
||||
.start_addr=0x100000,
|
||||
},
|
||||
{ .magic_number = RIOTBOOT_MAGIC,
|
||||
.version = 2,
|
||||
.start_addr=0x200000,
|
||||
},
|
||||
};
|
||||
|
||||
const riotboot_hdr_t * const riotboot_slots[] = {
|
||||
&_riotboot_slots[0],
|
||||
&_riotboot_slots[1],
|
||||
};
|
||||
|
||||
const unsigned riotboot_slot_numof = ARRAY_SIZE(riotboot_slots);
|
||||
|
||||
static int _current_slot;
|
||||
|
||||
int riotboot_slot_current(void)
|
||||
static const suit_component_t *_get_component(const suit_manifest_t *manifest)
|
||||
{
|
||||
return _current_slot;
|
||||
assert(manifest->component_current < CONFIG_SUIT_COMPONENT_MAX);
|
||||
return &manifest->components[manifest->component_current];
|
||||
}
|
||||
|
||||
int riotboot_slot_other(void)
|
||||
int suit_transport_mock_fetch(const suit_manifest_t *manifest)
|
||||
{
|
||||
return (_current_slot == 0) ? 1 : 0;
|
||||
}
|
||||
size_t file = manifest->component_current;
|
||||
const suit_component_t *comp = _get_component(manifest);
|
||||
|
||||
const riotboot_hdr_t *riotboot_slot_get_hdr(unsigned slot)
|
||||
{
|
||||
assert(slot < riotboot_slot_numof);
|
||||
assert(file < num_payloads);
|
||||
|
||||
return riotboot_slots[slot];
|
||||
}
|
||||
LOG_INFO("Mock writing payload %d\n", (unsigned)file);
|
||||
|
||||
size_t riotboot_slot_offset(unsigned slot)
|
||||
{
|
||||
return (slot == 0) ? SLOT0_OFFSET : SLOT1_OFFSET;
|
||||
}
|
||||
|
||||
int riotboot_flashwrite_init_raw(riotboot_flashwrite_t *state, int target_slot,
|
||||
size_t offset)
|
||||
{
|
||||
(void)state;
|
||||
(void)target_slot;
|
||||
(void)offset;
|
||||
puts("riotboot_flashwrite_init_raw() empty mock");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int riotboot_flashwrite_verify_sha256(const uint8_t *sha256_digest,
|
||||
size_t img_size, int target_slot)
|
||||
{
|
||||
(void)sha256_digest;
|
||||
(void)img_size;
|
||||
(void)target_slot;
|
||||
suit_storage_write(comp->storage_backend, manifest, payloads[file].buf, 0,
|
||||
payloads[file].len);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user