Commit e863ebaa authored by Brendan Moran's avatar Brendan Moran
Browse files

Refactor parser for more efficient code utilisation

This is a large refactor that makes the code flow much simpler. The parser still needs better debugging infrastructure.

* Unimplemented variables are no longer used
* Tags are now handled
* bstr wrappers are now handled implicitly where necessary
* Added a new k/v pair handler that processes a key with a type in one shot.
* Added distinct handling for arrays (a sequence of identical types) and lists (a sequence of different types)
* Integrated COSE signature handling
* Added a const array initializer helper macro so that parser element counts are calculated at compile-time.
* Added an image verification handler that consumes SUIT_Digests and handles the algorithm correctly
* Verify manifest against authenticated hash before processing
parent 9b058fba
......@@ -29,6 +29,26 @@
#include "mbed_application.h"
#include "suit_bootloader.h"
const uint8_t vendor_id[16] = {
0xfa, 0x6b, 0x4a, 0x53, 0xd5, 0xad, 0x5f, 0xdf,
0xbe, 0x9d, 0xe6, 0x63, 0xe4, 0xd4, 0x1f, 0xfe
};
const uint8_t class_id[16] = {
0x14, 0x92, 0xaf, 0x14, 0x25, 0x69, 0x5e, 0x48,
0xbf, 0x42, 0x9b, 0x2d, 0x51, 0xf2, 0xab, 0x45
};
const uint8_t public_key[] = {
0x84, 0x96, 0x81, 0x1a, 0xae, 0x0b, 0xaa, 0xab,
0xd2, 0x61, 0x57, 0x18, 0x9e, 0xec, 0xda, 0x26,
0xbe, 0xaa, 0x8b, 0xf1, 0x1b, 0x6f, 0x3f, 0xe6,
0xe2, 0xb5, 0x65, 0x9c, 0x85, 0xdb, 0xc0, 0xad,
0x3b, 0x1f, 0x2a, 0x4b, 0x6c, 0x09, 0x81, 0x31,
0xc0, 0xa3, 0x6d, 0xac, 0xd1, 0xd7, 0x8b, 0xd3,
0x81, 0xdc, 0xdf, 0xb0, 0x9c, 0x05, 0x2d, 0xb3,
0x39, 0x91, 0xdb, 0x73, 0x38, 0xb4, 0xa8, 0x96,
};
const entrypoint_t entrypoints[] = {
{
SUIT_BOOTLOADER_SLOT_A_OFFSET + SUIT_BOOTLOADER_HEADER_SIZE,
......
......@@ -26,27 +26,7 @@
#include <stdio.h>
#include <string.h>
const uint8_t vendor_id[16] = {
0xfa, 0x6b, 0x4a, 0x53, 0xd5, 0xad, 0x5f, 0xdf,
0xbe, 0x9d, 0xe6, 0x63, 0xe4, 0xd4, 0x1f, 0xfe
};
const uint8_t class_id[16] = {
0x14, 0x92, 0xaf, 0x14, 0x25, 0x69, 0x5e, 0x48,
0xbf, 0x42, 0x9b, 0x2d, 0x51, 0xf2, 0xab, 0x45
};
const uint8_t COSE_Sign1_context[] = "\x84\x6ASignature1";
const uint8_t public_key[] = {
0x84, 0x96, 0x81, 0x1a, 0xae, 0x0b, 0xaa, 0xab,
0xd2, 0x61, 0x57, 0x18, 0x9e, 0xec, 0xda, 0x26,
0xbe, 0xaa, 0x8b, 0xf1, 0x1b, 0x6f, 0x3f, 0xe6,
0xe2, 0xb5, 0x65, 0x9c, 0x85, 0xdb, 0xc0, 0xad,
0x3b, 0x1f, 0x2a, 0x4b, 0x6c, 0x09, 0x81, 0x31,
0xc0, 0xa3, 0x6d, 0xac, 0xd1, 0xd7, 0x8b, 0xd3,
0x81, 0xdc, 0xdf, 0xb0, 0x9c, 0x05, 0x2d, 0xb3,
0x39, 0x91, 0xdb, 0x73, 0x38, 0xb4, 0xa8, 0x96,
};
size_t bl_slot_index;
......@@ -72,6 +52,15 @@ int suit_platform_get_image_ref(
return 0;
}
void compute_sha256(uint8_t *hash, const uint8_t *msg, size_t msg_len) {
mbedtls_sha256_context ctx;
mbedtls_sha256_init (&ctx);
mbedtls_sha256_starts_ret (&ctx, 0);
mbedtls_sha256_update_ret(&ctx, msg, msg_len);
mbedtls_sha256_finish_ret(&ctx, hash);
mbedtls_sha256_free(&ctx);
}
int suit_platform_verify_image(
const uint8_t *component_id,
int digest_type,
......@@ -83,15 +72,8 @@ int suit_platform_verify_image(
}
const uint8_t *image = (const uint8_t *)((uintptr_t)entrypoints[bl_slot_index].app_offset);
mbedtls_sha256_context ctx;
uint8_t hash[32];
mbedtls_sha256_init (&ctx);
mbedtls_sha256_starts_ret (&ctx, 0);
mbedtls_sha256_update_ret(&ctx, image, image_size);
mbedtls_sha256_finish_ret(&ctx, hash);
mbedtls_sha256_free(&ctx);
compute_sha256(hash, image, image_size);
// no secret information in this hash, so memcmp is fine
return memcmp(hash, expected_digest, sizeof(hash));
......@@ -102,127 +84,63 @@ int suit_platform_verify_sha256(
const uint8_t *data,
size_t data_len)
{
mbedtls_sha256_context ctx;
uint8_t hash[32];
mbedtls_sha256_init (&ctx);
mbedtls_sha256_starts_ret (&ctx, 0);
mbedtls_sha256_update_ret(&ctx, data, data_len);
mbedtls_sha256_finish_ret(&ctx, hash);
mbedtls_sha256_free(&ctx);
compute_sha256(hash, data, data_len);
if (0==memcmp(hash, expected_digest, sizeof(hash))) {
return CBOR_ERR_NONE;
}
else {
return SUIT_ERROR_DIGEST_MISMATCH;
RETURN_ERROR( SUIT_ERROR_DIGEST_MISMATCH);
}
}
int do_cose_auth(
const uint8_t *auth_buffer,
const uint8_t *data, size_t data_size)
int suit_platform_verify_digest(int alg, const uint8_t *exp, size_t exp_len, const uint8_t *data, size_t data_len)
{
const uint8_t* p = auth_buffer;
cbor_value_t auth_bstr;
int rc = cbor_check_type_extract_ref(&p, p + 9, &auth_bstr, CBOR_TYPE_BSTR);
if (rc) return rc;
p = auth_bstr.ref.ptr;
const uint8_t *auth_end = p + auth_bstr.ref.length;
// The auth container is a list.
// Only support single authorisation/signature
// TODO: Multiple authorisations
if (p[0] != 0x81) {
RETURN_ERROR(1);
switch (alg) {
// TODO: expected digest length.
case SUIT_DIGEST_TYPE_SHA256:
return suit_platform_verify_sha256(exp, data, data_len);
}
p += 1;
// A COSE_Sign1_tagged must begin with 0xD2 0x84
if (p[0] != 0xD2 || p[1] != 0x84) {
RETURN_ERROR(1);
}
p += 2;
// COSE_Sign1 = [
// protected : bstr .cbor header_map / bstr .size 0,
// unprotected : header_map,
// payload : bstr / nil,
// signature : bstr
// ]
cbor_value_t values[4];
const uint8_t COSE_Sign1_types[] = {
CBOR_TYPE_BSTR,
CBOR_TYPE_MAP,
CBOR_TYPE_BSTR,
CBOR_TYPE_BSTR
};
for (size_t i = 0; i < 4; i++) {
const uint8_t* cbor_start = p;
rc = cbor_check_type_extract_ref(&p, auth_end, &values[i], COSE_Sign1_types[i]);
if (rc) return rc;
if (COSE_Sign1_types[i] == CBOR_TYPE_BSTR) {
p = values[i].ref.ptr + values[i].ref.length;
} else {
p = cbor_start;
rc = cbor_skip(&p, auth_end);
if(rc) return rc;
}
}
// Check that body_protected is recognised
if (values[0].ref.length != 3) {
RETURN_ERROR(2);
}
if (memcmp(values[0].ref.ptr, "\xA1\x01\x26", 3) != 0) {
RETURN_ERROR(3);
}
// Digest the signed object:
// Sig_structure = [
// context : "Signature" ; Const
// body_protected : empty_or_serialized_map, ; Included in auth buffer
// external_aad : bstr, ; NULL
// payload : bstr ; Included in manifest
// ]
// body_protected is a digest between 224 and 512 bits
// There should be an array wrapper (1B) and a type identifier (1B)
RETURN_ERROR(SUIT_ERROR_DIGEST_MISMATCH);
}
size_t struct_len =
sizeof(COSE_Sign1_context) - 1 +
(values[0].ref.length + values[0].ref.ptr - values[0].cbor_start) +
1 +
(values[2].ref.length + values[2].ref.ptr - values[2].cbor_start);
uint8_t bstr_start[1+sizeof(size_t)];
int ES256_verify(
const uint8_t *msg, size_t msg_len,
const uint8_t *sig, size_t sig_len,
const uint8_t *kid, size_t kid_len)
{
//TODO: SHA
uint8_t hash[32] = {0};
compute_sha256(hash, msg, msg_len);
size_t byte_size = sizeof(size_t) - __builtin_clz(struct_len)/8;
size_t byte_size_log = sizeof(size_t)*8 - __builtin_clz(byte_size);
bstr_start[0] = CBOR_TYPE_BSTR + byte_size_log + 23;
for (size_t n = byte_size; n; n--) {
bstr_start[byte_size - (n - 1)] = (struct_len >> ((n - 1)<<3));
//TODO: Lookup public key by key-id
if (uECC_verify(public_key, hash, sig)) {
return CBOR_ERR_NONE;
}
mbedtls_sha256_context ctx;
uint8_t hash[32];
mbedtls_sha256_init (&ctx);
mbedtls_sha256_starts_ret (&ctx, 0);
mbedtls_sha256_update_ret(&ctx, bstr_start, 1 + byte_size);
mbedtls_sha256_update_ret(&ctx, COSE_Sign1_context, sizeof(COSE_Sign1_context) - 1);
mbedtls_sha256_update_ret(&ctx, values[0].cbor_start, values[0].ref.length + values[0].ref.ptr - values[0].cbor_start);
mbedtls_sha256_update_ret(&ctx, (uint8_t *)"\x40", 1);
mbedtls_sha256_update_ret(&ctx, values[2].cbor_start, (values[2].ref.length + values[2].ref.ptr - values[2].cbor_start));
mbedtls_sha256_finish_ret(&ctx, hash);
mbedtls_sha256_free(&ctx);
rc = uECC_verify(public_key, hash, values[3].ref.ptr);
if (!rc) {
return SUIT_ERR_SIG;
else {
RETURN_ERROR(SUIT_ERR_SIG);
}
}
// Verify the manifest
// Extract the signed digest of the manifest
rc = verify_suit_digest(
values[2].ref.ptr,
values[2].ref.ptr + 1 + 8 + 2, //TODO: Fix length handling
data,
data_size);
if (rc != CBOR_ERR_NONE) {
rc = SUIT_ERR_SIG;
int COSEAuthVerify(
const uint8_t *msg, size_t msg_len,
const uint8_t *sig, size_t sig_len,
const uint8_t *kid, size_t kid_len,
int alg)
{
int rc;
switch (alg) {
case COSE_ES256:
rc = ES256_verify(
msg, msg_len,
sig, sig_len,
kid, kid_len);
break;
default:
SET_ERROR(rc, CBOR_ERR_UNIMPLEMENTED);
break;
}
return rc;
}
......
......@@ -32,6 +32,9 @@ typedef struct entrypoint_s {
const uintptr_t manifest;
} entrypoint_t;
extern const uint8_t public_key[];
extern const uint8_t class_id[16];
extern const uint8_t vendor_id[16];
extern const entrypoint_t entrypoints [];
extern const size_t n_entrypoints;
int suit_bootloader();
......
This diff is collapsed.
......@@ -31,7 +31,7 @@
#define CBOR_TYPE_MAP (5 << 5)
#define CBOR_TYPE_TAG (6 << 5)
#define CBOR_TYPE_SIMPLE (7 << 5)
#define CBOR_TYPE_MAX (7 << 5)
#define CBOR_TYPE_MASK (7 << 5)
#define CBOR_FALSE (CBOR_TYPE_SIMPLE | 20)
#define CBOR_TRUE (CBOR_TYPE_SIMPLE | 21)
......@@ -39,6 +39,64 @@
#define SUIT_SUPPORTED_VERSION 1
#define SIGNATURE1 "Signature1"
// Signature1 is never more than 256 bytes long.
#define SUIT_SIGNATURE1_BSTR_START_MAX (1+1)
// Signature1 is always 4 elements
#define SUIT_SIGNATURE1_ARRAY_START_LEN 1
// Signature1 context length
#define SUIT_SIGNATURE1_CONTEXT_LEN (sizeof(SIGNATURE1)-1)
// There are fewer than 23 header fields, so only 1 byte for header map
#define SUIT_SIGNATURE1_HDRMAP_START_LEN 1
// Each header field consists of 1 integer field identifier with a value
// below 23 and one field with a size dependent on the field.
// Typically, only the algorithm is defined in protected headers.
#define SUIT_SIGNATURE1_HDR_ALG_LEN (2)
#define SUIT_BODYPROTECTED_MAX_LEN (\
SUIT_SIGNATURE1_BSTR_START_MAX +\
SUIT_SIGNATURE1_HDRMAP_START_LEN +\
SUIT_SIGNATURE1_HDR_ALG_LEN \
)
// AAD is not used in SUIT
#define SUIT_SIGNATURE1_AAD_LEN 1
// The payload contains a BSTR-encoded SUIT Digest
// Since a digest itself is always at least 28 bytes (SHA224) and never
// more than 64 bytes (SHA512), the bstr header is always 2 bytes
#define SUIT_DIGEST_BSTR_START_MAX SUIT_SIGNATURE1_BSTR_START_MAX
// The array is always fewer than 24 elements, so the array is 1 byte
#define SUIT_DIGEST_ARRAY_START_LEN SUIT_SIGNATURE1_ARRAY_START_LEN
// The type identifier of the digest should always be 1 byte
#define SUIT_DIGEST_TYPE_MAX_LEN 1
#ifndef SUIT_DIGEST_SIZE
// The longest digest supported is SHA512 (64 bytes)
#define SUIT_DIGEST_SIZE 64
#endif
#define SUIT_SIGNATURE1_PAYLOAD_LEN (\
SUIT_DIGEST_BSTR_START_MAX +\
SUIT_DIGEST_ARRAY_START_LEN +\
SUIT_DIGEST_TYPE_MAX_LEN +\
SUIT_DIGEST_BSTR_START_MAX +\
SUIT_DIGEST_SIZE \
)
#define SUIT_SIGNATURE1_MAX_LEN (\
SUIT_SIGNATURE1_BSTR_START_MAX +\
SUIT_SIGNATURE1_ARRAY_START_LEN +\
SUIT_SIGNATURE1_CONTEXT_LEN +\
SUIT_BODYPROTECTED_MAX_LEN +\
SUIT_SIGNATURE1_AAD_LEN +\
SUIT_SIGNATURE1_PAYLOAD_LEN \
)
#define UUID_SIZE (128/8)
#define COSE_SIGN1_TAG (18)
#define COSE_HDR_ALG (1)
#define COSE_HDR_KID (4)
#define COSE_ES256 (-7)
#define PRINT_ON_ERROR 0
......@@ -57,8 +115,8 @@
#define ARRAY_SIZE(X) (sizeof(X)/sizeof((X)[0]))
#define SUIT_OUTER_AUTH 2
#define SUIT_OUTER_MANIFEST 3
#define SUIT_ENVELOPE_AUTH 2
#define SUIT_ENVELOPE_MANIFEST 3
#define SUIT_MANIFEST_VERSION 1
#define SUIT_MANIFEST_SEQUCENCE_NUMBER 2
......@@ -82,36 +140,102 @@
#define SUIT_DIRECTIVE_FETCH 21
#define SUIT_DIRECTIVE_INVOKE 23
#define SUIT_PARAMETER_VENDOR_ID 3
#define SUIT_PARAMETER_CLASS_ID 4
#define SUIT_PARAMETER_URI 6
#define SUIT_PARAMETER_SOURCE_COMPONENT 10
#define SUIT_PARAMETER_IMAGE_DIGEST 11
#define SUIT_PARAMETER_IMAGE_SIZE 12
#define SUIT_PARAMETER_VENDOR_ID 1
#define SUIT_PARAMETER_CLASS_ID 2
#define SUIT_PARAMETER_IMAGE_DIGEST 3
#define SUIT_PARAMETER_IMAGE_SIZE 14
#define SUIT_PARAMETER_URI 21
#define SUIT_PARAMETER_SOURCE_COMPONENT 22
#define SUIT_DIGEST_TYPE_SHA224 1
#define SUIT_DIGEST_TYPE_SHA256 2
#define SUIT_DIGEST_TYPE_SHA384 3
#define SUIT_SUPPORT_VAR(VAR) (1L <<((VAR)-1))
#define SUIT_SUPPORTED_VARS ( \
SUIT_SUPPORT_VAR(SUIT_PARAMETER_VENDOR_ID) | \
SUIT_SUPPORT_VAR(SUIT_PARAMETER_CLASS_ID) | \
SUIT_SUPPORT_VAR(SUIT_PARAMETER_IMAGE_DIGEST) | \
SUIT_SUPPORT_VAR(SUIT_PARAMETER_IMAGE_SIZE) | \
SUIT_SUPPORT_VAR(SUIT_PARAMETER_URI) | \
SUIT_SUPPORT_VAR(SUIT_PARAMETER_SOURCE_COMPONENT) | \
0)
#define COUNT_BITS_2(X) ((X) - (((X)>>1) & 0x55555555))
#define COUNT_BITS_4(X) (((COUNT_BITS_2(X) >> 2) & 0x33333333UL) + ((COUNT_BITS_2(X)) & 0x33333333UL))
#define COUNT_BITS_8(X) (((COUNT_BITS_4(X) >> 4) + COUNT_BITS_4(X)) & 0x0F0F0F0F)
#define COUNT_BITS_16(X) ((COUNT_BITS_8(X) >> 8) + COUNT_BITS_8(X))
#define COUNT_BITS_32(X) (((COUNT_BITS_16(X) >> 16) + COUNT_BITS_16(X)) & 0x3F)
#define SUIT_VAR_COUNT (COUNT_BITS_32(SUIT_SUPPORTED_VARS))
#ifdef PARSER_DEBUG
#define CBOR_KPARSE_ELEMENT_C_BWRAP_KV(KEY, TYPE, CHILDREN, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, .is_kv = 1, .bstr_wrap = 1, 0, 0, 0, .ptr = (CHILDREN), .desc=(DESC)}
#define CBOR_KPARSE_ELEMENT_C_BWRAP(KEY, TYPE, CHILDREN, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, .bstr_wrap = 1, 0, 0, 0, .ptr = (CHILDREN), .desc=(DESC)}
#define CBOR_KPARSE_ELEMENT_A_BWRAP(KEY, TYPE, CHILDREN, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, .bstr_wrap = 1, .is_array = 1, 0, 0, .ptr = (CHILDREN), .desc=(DESC)}
#define CBOR_KPARSE_ELEMENT_C(KEY, TYPE, CHILDREN, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, 0, 0, 0, 0, .ptr = (CHILDREN), .desc=(DESC)}
#define CBOR_KPARSE_ELEMENT_H(KEY, TYPE, HANDLER, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, .has_handler = 1, 0, 0, 0, 0, .ptr = (HANDLER), .desc=(DESC)}
#define CBOR_KPARSE_ELEMENT_H_BWRAP(KEY, TYPE, HANDLER, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, .has_handler = 1, .bstr_wrap = 1, 0, 0, 0, .ptr = (HANDLER), .desc=(DESC)}
#define CBOR_KPARSE_ELEMENT(KEY, TYPE, HANDLER, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, 0, 0, .handler=(HANDLER), .desc=(DESC)}
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, 0, 0, .ptr=(HANDLER), .desc=(DESC)}
#define CBOR_KPARSE_ELEMENT_NULL(KEY, TYPE, HANDLER, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, 0, .null_opt = 1, .handler=(HANDLER), .desc=(DESC)}
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, 0, .null_opt = 1, .ptr=(HANDLER), .desc=(DESC)}
#define CBOR_KPARSE_ELEMENT_CHOICE(KEY, TYPE, HANDLER, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, .choice = 1, 0, .handler=(HANDLER), .desc=(DESC)}
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, .choice = 1, 0, .ptr=(HANDLER), .desc=(DESC)}
#define PD_PRINTF(...)\
printf(__VA_ARGS__)
#else
#define CBOR_KPARSE_ELEMENT_C_BWRAP_KV(KEY, TYPE, CHILDREN, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, .is_kv = 1, .bstr_wrap = 1, 0, 0, 0, .ptr = (CHILDREN)}
#define CBOR_KPARSE_ELEMENT_C_BWRAP(KEY, TYPE, CHILDREN, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, .bstr_wrap = 1, 0, 0, 0, .ptr = (CHILDREN)}
#define CBOR_KPARSE_ELEMENT_A_BWRAP(KEY, TYPE, CHILDREN, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, .bstr_wrap = 1, .is_array = 1, 0, 0, .ptr = (CHILDREN)}
#define CBOR_KPARSE_ELEMENT_C(KEY, TYPE, CHILDREN, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, 0, 0, 0, 0, .ptr = (CHILDREN)}
#define CBOR_KPARSE_ELEMENT_H(KEY, TYPE, HANDLER, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, .has_handler = 1, 0, 0, 0, 0, .ptr = (HANDLER)}
#define CBOR_KPARSE_ELEMENT_H_BWRAP(KEY, TYPE, HANDLER, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, .has_handler = 1, .bstr_wrap = 1, 0, 0, 0, .ptr = (HANDLER)}
#define CBOR_KPARSE_ELEMENT(KEY, TYPE, HANDLER, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, 0, 0, .handler=(HANDLER)}
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, 0, 0, .ptr = (HANDLER)}
#define CBOR_KPARSE_ELEMENT_NULL(KEY, TYPE, HANDLER, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, 0, .null_opt = 1, .handler=(HANDLER)}
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, 0, .null_opt = 1, .ptr = (HANDLER)}
#define CBOR_KPARSE_ELEMENT_CHOICE(KEY, TYPE, HANDLER, DESC)\
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, .choice = 1, 0, .handler=(HANDLER)}
{.key = (KEY), 0, .type = (TYPE) >> 5, 0, .choice = 1, 0, .ptr = (HANDLER)}
#define PD_PRINTF(...)
#endif
#define FLEXARRAY_HELPER(STRUCT_TYPE, TYPE, NAME, TMPNAME, ...)\
const TYPE TMPNAME [] = { \
__VA_ARGS__\
};\
const struct {\
STRUCT_TYPE elements;\
TYPE elements_raw [ARRAY_SIZE(TMPNAME)];\
} NAME = {{.count = ARRAY_SIZE(TMPNAME)}, { \
__VA_ARGS__\
}}
#define FLEXARRAY(STRUCT_TYPE, TYPE, NAME, ...) FLEXARRAY_HELPER(STRUCT_TYPE, TYPE, NAME, _flexarray_ ## NAME ## _tmp, __VA_ARGS__)
#define CBOR_KPARSE_ELEMENT_LIST(NAME, ...) \
FLEXARRAY(cbor_keyed_parse_elements_t, cbor_keyed_parse_element_t, NAME, __VA_ARGS__)
// int key:16;
// unsigned int resvd:8;
// unsigned int type:3;
// unsigned int has_handler:1;
// unsigned int bstr_wrap:1;
// unsigned int repeat:1;
// unsigned int choice:1;
// unsigned int null_opt:1;
#define PARSE_HANDLER(N)\
int N( \
const uint8_t **p, \
......@@ -159,56 +283,66 @@ typedef struct cbor_value_s {
int64_t i64;
struct {
const uint8_t *ptr;
uint64_t length;
uint64_t uival;
} ref;
uint8_t primitive;
};
} cbor_value_t;
typedef struct suit_vars_s {
const uint8_t *vendor_id;
const uint8_t *class_id;
const uint8_t *device_id;
const uint8_t *uri;
const uint8_t *encryption_info;
const uint8_t *compression_info;
const uint8_t *unpack_info;
const uint8_t *source_component;
const uint8_t *image_digest;
const uint8_t *image_size;
const uint8_t LAST[0];
} suit_vars_t;
typedef struct suit_reference_t {
const uint8_t *ptr;
const uint8_t *end;
} suit_reference_t;
typedef suit_reference_t suit_vars_t[SUIT_VAR_COUNT];
typedef struct suit_parse_context_s {
int64_t search_key;
suit_vars_t vars[MAX_COMPONENTS];
const uint8_t* outer;
const uint8_t* auth;
const uint8_t* inner;
const uint8_t* common;
const uint8_t* search_result;
uint16_t outer_size;
uint16_t common_size;
suit_reference_t envelope;
uint8_t manifest_suit_digest[SUIT_SIGNATURE1_PAYLOAD_LEN];
union {
struct {
int64_t search_key;
suit_reference_t search_result;
suit_vars_t vars[MAX_COMPONENTS];
suit_reference_t manifest;
suit_reference_t common;
size_t current_component;
};
struct {
uint8_t Signature1[SUIT_SIGNATURE1_MAX_LEN];
size_t offset;
int alg;
suit_reference_t kid;
} Sign1;
};
} suit_parse_context_t;
typedef PARSE_HANDLER((*suit_handler_t));
struct cbor_keyed_parse_elements_s;
typedef struct cbor_keyed_parse_element_s {
int key:16;
unsigned int resvd0:8;
int key:16;
unsigned int resvd:6;
unsigned int type:3;
unsigned int resvd1:2;
unsigned int repeat:1;
unsigned int is_kv:1;
unsigned int has_handler:1;
unsigned int bstr_wrap:1;
unsigned int is_array:1; // array of like items. If 0, list.
unsigned int choice:1;
unsigned int null_opt:1;
// Defined by cbor_type
// int (*extractor)(void* ctx, const uint8_t **p, cbor_value_t *val, const uint8_t *end);
suit_handler_t handler;
const void* ptr;
#ifdef PARSER_DEBUG
const char* desc;
#endif
} cbor_keyed_parse_element_t;
typedef struct cbor_keyed_parse_elements_s {
size_t count;
cbor_keyed_parse_element_t elements[];
} cbor_keyed_parse_elements_t;
int suit_do_process_manifest(const uint8_t *manifest, size_t manifest_size);
int suit_platform_do_run();
int suit_platform_verify_image(
......@@ -243,6 +377,14 @@ int verify_suit_digest(
size_t data_len);
int cbor_skip(const uint8_t **p, const uint8_t *end);
int COSEAuthVerify(
const uint8_t *msg, size_t msg_len,
const uint8_t *sig, size_t sig_len,
const uint8_t *kid, size_t kid_len,
int alg);
int suit_platform_verify_digest(int alg, const uint8_t *exp, size_t exp_len, const uint8_t *data, size_t data_len);
#ifdef __cplusplus
}
#endif
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment