1
0
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:
Koen Zandberg 2020-09-28 23:14:16 +02:00
parent edeffdcd54
commit b72d510690
No known key found for this signature in database
GPG Key ID: 0895A893E6D2985B
3 changed files with 94 additions and 70 deletions

View 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 */
/** @} */

View File

@ -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, &param_size) == 0) ||
(nanocbor_get_uint32(&param_size, img_size) < 0)) {
return SUIT_ERR_INVALID_MANIFEST;
if ((suit_param_ref_to_cbor(manifest, &comp->param_size, &param_size) == 0)
|| (nanocbor_get_uint32(&param_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);

View File

@ -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;
}