mirror of https://github.com/wolfSSL/wolfBoot.git
Refactoring of PKCS11 store module + unit tests
parent
002dc8d415
commit
6737d7e7ad
|
@ -843,3 +843,12 @@ endif
|
|||
ifeq ($(SIGN_ALG),ext_LMS)
|
||||
SIGN_ALG=LMS
|
||||
endif
|
||||
|
||||
ifneq ($(KEYVAULT_OBJ_SIZE),)
|
||||
CFLAGS+=-DKEYVAULT_OBJ_SIZE=$(KEYVAULT_OBJ_SIZE)
|
||||
endif
|
||||
|
||||
ifneq ($(KEYVAULT_MAX_ITEMS),)
|
||||
CFLAGS+=-DKEYVAULT_MAX_ITEMS=$(KEYVAULT_MAX_ITEMS)
|
||||
endif
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pkcs11_store.c
|
||||
*
|
||||
* Copyright (C) 2023 wolfSSL Inc.
|
||||
* Copyright (C) 2024 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
|
@ -20,7 +20,6 @@
|
|||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -34,14 +33,13 @@
|
|||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
|
||||
extern uint32_t *_flash_keyvault; /* From linker script: origin of vault flash */
|
||||
extern uint32_t *_flash_keyvault_size; /* From linker script: size of vault */
|
||||
#ifndef KEYVAULT_OBJ_SIZE
|
||||
#define KEYVAULT_OBJ_SIZE 0x1000 /* 4KB per object */
|
||||
#endif
|
||||
|
||||
extern unsigned int _start_heap; /* From linker script: heap memory */
|
||||
extern unsigned int _heap_size; /* From linker script: heap limit */
|
||||
|
||||
#define KEYVAULT_OBJ_SIZE 0x1000 /* 4KB per object */
|
||||
#define KEYVAULT_MAX_ITEMS 0x18 /* Total memory: 0x18000, 24 items */
|
||||
#ifndef KEYVAULT_MAX_ITEMS
|
||||
#define KEYVAULT_MAX_ITEMS 0x17 /* Total memory: 0x18000, 22 items + 2 sector overhead */
|
||||
#endif
|
||||
|
||||
/* Internal errors from wolfPKCS11 */
|
||||
#define PIN_INVALID_E -1
|
||||
|
@ -55,11 +53,16 @@ extern unsigned int _heap_size; /* From linker script: heap limit */
|
|||
#define LOGGED_IN_E -9
|
||||
#define OBJ_COUNT_E -10
|
||||
|
||||
|
||||
#ifndef UNIT_TEST
|
||||
extern uint32_t *_flash_keyvault; /* From linker script: origin of vault flash */
|
||||
static uint8_t *vault_base = (uint8_t *)&_flash_keyvault;
|
||||
static int vault_idx = -1;
|
||||
|
||||
/* Back-end for malloc, used by wolfPKCS11 */
|
||||
|
||||
extern unsigned int _start_heap; /* From linker script: heap memory */
|
||||
extern unsigned int _heap_size; /* From linker script: heap limit */
|
||||
|
||||
/* Back-end for malloc, used for token handling */
|
||||
void * _sbrk(unsigned int incr)
|
||||
{
|
||||
static unsigned char *heap = (unsigned char *)&_start_heap;
|
||||
|
@ -78,133 +81,452 @@ void * _sbrk(unsigned int incr)
|
|||
}
|
||||
return old_heap;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int vault_idx = -1;
|
||||
|
||||
struct obj_hdr
|
||||
{
|
||||
uint32_t token_id;
|
||||
uint32_t object_id;
|
||||
int type;
|
||||
uint32_t off;
|
||||
int32_t type;
|
||||
uint32_t pos;
|
||||
uint32_t size;
|
||||
uint32_t __pad[3];
|
||||
};
|
||||
#define STORE_PRIV_HDR_SIZE 16
|
||||
#define STORE_PRIV_HDR_SIZE 0x20
|
||||
#define STORE_PRIV_HDR_OFFSET 0x80
|
||||
#define PKCS11_INVALID_ID 0xFFFFFFFF
|
||||
|
||||
struct store_object
|
||||
#define BITMAP_OFFSET (4)
|
||||
#define BITMAP_SIZE (KEYVAULT_MAX_ITEMS / 8 + 1)
|
||||
|
||||
#if (BITMAP_SIZE > (STORE_PRIV_HDR_OFFSET - 4))
|
||||
#error Too many keyvault items
|
||||
#endif
|
||||
|
||||
/* This spells "PKCS" */
|
||||
#ifndef BIG_ENDIAN_ORDER
|
||||
#define VAULT_HEADER_MAGIC 0x53434B50
|
||||
#else
|
||||
#define VAULT_HEADER_MAGIC 0x504B4353
|
||||
#endif
|
||||
|
||||
#define MAX_OPEN_STORES 16
|
||||
|
||||
struct store_handle {
|
||||
uint32_t flags;
|
||||
uint32_t pos;
|
||||
void *buffer;
|
||||
struct obj_hdr *hdr;
|
||||
uint32_t in_buffer_offset;
|
||||
};
|
||||
|
||||
#define STORE_FLAGS_OPEN (1 << 0)
|
||||
#define STORE_FLAGS_READONLY (1 << 1)
|
||||
|
||||
static struct store_handle openstores_handles[MAX_OPEN_STORES] = {};
|
||||
|
||||
static uint8_t cached_sector[WOLFBOOT_SECTOR_SIZE];
|
||||
|
||||
static void bitmap_put(uint32_t pos, int val)
|
||||
{
|
||||
struct obj_hdr hdr;
|
||||
int vault_idx;
|
||||
int read;
|
||||
};
|
||||
uint32_t octet = pos / 8;
|
||||
uint32_t bit = pos % 8;
|
||||
uint8_t *bitmap = cached_sector + sizeof(uint32_t);
|
||||
|
||||
static struct store_object *vault_descriptors[KEYVAULT_MAX_ITEMS];
|
||||
if (val != 0) {
|
||||
bitmap[octet] |= (1 << bit);
|
||||
} else {
|
||||
bitmap[octet] &= ~(1 << bit);
|
||||
}
|
||||
}
|
||||
|
||||
static int bitmap_get(uint32_t pos)
|
||||
{
|
||||
uint32_t octet = pos / 8;
|
||||
uint32_t bit = pos % 8;
|
||||
uint8_t *bitmap = vault_base + sizeof(uint32_t);
|
||||
return (bitmap[octet] & (1 << bit)) >> bit;
|
||||
}
|
||||
|
||||
static int bitmap_find_free_pos(void)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < KEYVAULT_MAX_ITEMS; i++) {
|
||||
if (bitmap_get(i) == 0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* A table with nodes is stored at the beginning of the keyvault
|
||||
* - 4 B: Magic (spells "PKCS" when the vault is initialized)
|
||||
* - N B: bitmap (N = KEYVAULT_MAX_ITEMS / 8 + 1)
|
||||
*
|
||||
* At byte 0x80:
|
||||
* - Start of the obj hdr structures array
|
||||
*/
|
||||
|
||||
#define NODES_TABLE ( (struct obj_hdr *)(vault_base + STORE_PRIV_HDR_OFFSET) )
|
||||
|
||||
/* A backup sector immediately after the header sector */
|
||||
|
||||
#define BACKUP_SECTOR_ADDRESS (vault_base + WOLFBOOT_SECTOR_SIZE)
|
||||
|
||||
static void cache_commit(uint32_t offset)
|
||||
{
|
||||
hal_flash_unlock();
|
||||
|
||||
|
||||
/* Write backup sector first */
|
||||
hal_flash_erase((uint32_t)BACKUP_SECTOR_ADDRESS, WOLFBOOT_SECTOR_SIZE);
|
||||
hal_flash_write((uint32_t)BACKUP_SECTOR_ADDRESS, cached_sector, WOLFBOOT_SECTOR_SIZE);
|
||||
|
||||
/* Erase + write actual destination sector */
|
||||
hal_flash_erase((uint32_t)vault_base + offset, WOLFBOOT_SECTOR_SIZE);
|
||||
hal_flash_write((uint32_t)vault_base + offset, cached_sector, WOLFBOOT_SECTOR_SIZE);
|
||||
|
||||
hal_flash_lock();
|
||||
}
|
||||
|
||||
static void restore_backup(uint32_t offset)
|
||||
{
|
||||
hal_flash_unlock();
|
||||
/* Erase + copy from backup */
|
||||
hal_flash_erase((uint32_t)vault_base + offset, WOLFBOOT_SECTOR_SIZE);
|
||||
hal_flash_write((uint32_t)vault_base + offset, BACKUP_SECTOR_ADDRESS,
|
||||
WOLFBOOT_SECTOR_SIZE);
|
||||
hal_flash_lock();
|
||||
}
|
||||
|
||||
static void check_vault(void)
|
||||
{
|
||||
uint32_t *magic = (uint32_t *)vault_base;
|
||||
uint32_t total_vault_size = KEYVAULT_MAX_ITEMS * KEYVAULT_OBJ_SIZE;
|
||||
|
||||
if ((total_vault_size % WOLFBOOT_SECTOR_SIZE) != 0)
|
||||
total_vault_size = (total_vault_size / WOLFBOOT_SECTOR_SIZE) * WOLFBOOT_SECTOR_SIZE + WOLFBOOT_SECTOR_SIZE;
|
||||
|
||||
if (*magic != VAULT_HEADER_MAGIC) {
|
||||
uint32_t *magic = (uint32_t *)BACKUP_SECTOR_ADDRESS;
|
||||
if (*magic == VAULT_HEADER_MAGIC) {
|
||||
restore_backup(0);
|
||||
return;
|
||||
}
|
||||
memset(cached_sector, 0xFF, WOLFBOOT_SECTOR_SIZE);
|
||||
magic = (uint32_t *)cached_sector;
|
||||
*magic = VAULT_HEADER_MAGIC;
|
||||
memset(cached_sector + sizeof(uint32_t), 0x00, BITMAP_SIZE);
|
||||
cache_commit(0);
|
||||
hal_flash_unlock();
|
||||
hal_flash_erase((uint32_t)vault_base + WOLFBOOT_SECTOR_SIZE * 2, total_vault_size);
|
||||
hal_flash_lock();
|
||||
}
|
||||
}
|
||||
|
||||
static void delete_object(int32_t type, uint32_t tok_id, uint32_t obj_id)
|
||||
{
|
||||
struct obj_hdr *hdr = (struct obj_hdr *)cached_sector;
|
||||
check_vault();
|
||||
memcpy(cached_sector, vault_base, WOLFBOOT_SECTOR_SIZE);
|
||||
|
||||
while ((uintptr_t)hdr < ((uintptr_t)cached_sector + WOLFBOOT_SECTOR_SIZE)) {
|
||||
if ((hdr->token_id == tok_id) && (hdr->object_id == obj_id) &&
|
||||
(hdr->type == type)) {
|
||||
hdr->token_id = PKCS11_INVALID_ID;
|
||||
hdr->object_id = PKCS11_INVALID_ID;
|
||||
bitmap_put(hdr->pos, 0);
|
||||
cache_commit(0);
|
||||
return;
|
||||
}
|
||||
hdr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns a pointer to the selected object in flash.
|
||||
* NULL is OK here as error return value, even if the keystore
|
||||
* started at physical 0x0000 0000, the buffers are stored from sector
|
||||
* 2 onwards.
|
||||
*/
|
||||
static uint8_t *find_object_buffer(int32_t type, uint32_t tok_id, uint32_t obj_id)
|
||||
{
|
||||
struct obj_hdr *hdr = NODES_TABLE;
|
||||
uint32_t *tok_obj_stored = NULL;
|
||||
while ((uint32_t)hdr < ((uint32_t)NODES_TABLE + WOLFBOOT_SECTOR_SIZE)) {
|
||||
if ((hdr->token_id == tok_id) && (hdr->object_id == obj_id)
|
||||
&& (hdr->type == type)) {
|
||||
tok_obj_stored = (uint32_t *) (vault_base + (2 * WOLFBOOT_SECTOR_SIZE) + (hdr->pos * KEYVAULT_OBJ_SIZE));
|
||||
if ((tok_obj_stored[0] != tok_id) || (tok_obj_stored[1] != obj_id)) {
|
||||
/* Id's don't match. Try backup sector. */
|
||||
uint32_t in_sector_off = (hdr->pos * KEYVAULT_OBJ_SIZE) %
|
||||
WOLFBOOT_SECTOR_SIZE;
|
||||
uint32_t sector_base = hdr->pos * KEYVAULT_OBJ_SIZE +
|
||||
2 * WOLFBOOT_SECTOR_SIZE - in_sector_off;
|
||||
tok_obj_stored = (uint32_t *)((BACKUP_SECTOR_ADDRESS + in_sector_off));
|
||||
if ((tok_obj_stored[0] == tok_id) && (tok_obj_stored[1] == obj_id)) {
|
||||
/* Found backup! restoring... */
|
||||
restore_backup(sector_base);
|
||||
} else {
|
||||
delete_object(type, tok_id, obj_id);
|
||||
return NULL; /* Cannot recover object payload */
|
||||
}
|
||||
}
|
||||
/* Object is now OK */
|
||||
return vault_base + 2 * WOLFBOOT_SECTOR_SIZE + hdr->pos * KEYVAULT_OBJ_SIZE;
|
||||
}
|
||||
hdr++;
|
||||
}
|
||||
return NULL; /* object not found */
|
||||
}
|
||||
|
||||
static struct obj_hdr *find_object_header(int32_t type, uint32_t tok_id,
|
||||
uint32_t obj_id)
|
||||
{
|
||||
struct obj_hdr *hdr = NODES_TABLE;
|
||||
uint32_t *tok_obj_stored = NULL;
|
||||
while ((uint32_t)hdr < ((uint32_t)NODES_TABLE + WOLFBOOT_SECTOR_SIZE)) {
|
||||
if ((hdr->token_id == tok_id) && (hdr->object_id == obj_id)
|
||||
&& (hdr->type == type)) {
|
||||
return hdr;
|
||||
}
|
||||
hdr++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct obj_hdr *create_object(int32_t type, uint32_t tok_id, uint32_t obj_id)
|
||||
{
|
||||
struct obj_hdr *hdr = NULL;
|
||||
uint32_t *tok_obj_id;
|
||||
/* Refuse to create an object that's already in store */
|
||||
if (find_object_buffer(type, tok_id, obj_id) != NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Caching sector 0 */
|
||||
memcpy(cached_sector, vault_base , WOLFBOOT_SECTOR_SIZE);
|
||||
hdr = (struct obj_hdr *)(cached_sector + STORE_PRIV_HDR_OFFSET);
|
||||
while ((uint32_t)hdr < ((uint32_t)cached_sector + WOLFBOOT_SECTOR_SIZE)) {
|
||||
if (hdr->token_id == PKCS11_INVALID_ID) {
|
||||
uint32_t sector_base, in_sector_off;
|
||||
int pos = bitmap_find_free_pos();
|
||||
if (pos < 0) {
|
||||
return NULL;
|
||||
}
|
||||
hdr->pos = (unsigned)pos;
|
||||
in_sector_off = (hdr->pos * KEYVAULT_OBJ_SIZE) %
|
||||
WOLFBOOT_SECTOR_SIZE;
|
||||
sector_base = hdr->pos * KEYVAULT_OBJ_SIZE +
|
||||
2 * WOLFBOOT_SECTOR_SIZE - in_sector_off;
|
||||
/* Claim the spot in the table */
|
||||
hdr->token_id = tok_id;
|
||||
hdr->object_id = obj_id;
|
||||
hdr->type = type;
|
||||
/* Set vault initial size to eight bytes (this includes the
|
||||
* tok/obj id at the beginning of the buffer, before the
|
||||
* payload). When an object is opened, the initial 'in_buffer_offset'
|
||||
* is set to 8 as well.
|
||||
*/
|
||||
hdr->size = 2 * sizeof(uint32_t);
|
||||
/* Set the bit to claim the position in flash */
|
||||
bitmap_put(hdr->pos, 1);
|
||||
cache_commit(0);
|
||||
/* Mark the beginning of the object in the sector,
|
||||
* write the tok/obj ids
|
||||
*/
|
||||
memcpy(cached_sector, vault_base + sector_base,
|
||||
WOLFBOOT_SECTOR_SIZE);
|
||||
tok_obj_id = (uint32_t *)(cached_sector + in_sector_off);
|
||||
tok_obj_id[0] = tok_id;
|
||||
tok_obj_id[1] = obj_id;
|
||||
cache_commit(sector_base);
|
||||
/* Return the address of the header in flash */
|
||||
return (struct obj_hdr *)(vault_base + ((uint8_t *)hdr - (uint8_t *)cached_sector));
|
||||
}
|
||||
hdr++;
|
||||
}
|
||||
return NULL; /* No space left in the nodes table */
|
||||
}
|
||||
|
||||
static void update_store_size(struct obj_hdr *hdr, uint32_t size)
|
||||
{
|
||||
uint32_t off;
|
||||
struct obj_hdr *hdr_mem;
|
||||
if (((uint8_t *)hdr) < vault_base ||
|
||||
((uint8_t *)hdr > vault_base + WOLFBOOT_SECTOR_SIZE))
|
||||
return;
|
||||
check_vault();
|
||||
off = (uint32_t)hdr - (uint32_t)vault_base;
|
||||
memcpy(cached_sector, vault_base, WOLFBOOT_SECTOR_SIZE);
|
||||
hdr_mem = (struct obj_hdr *)(cached_sector + off);
|
||||
hdr_mem->size = size;
|
||||
cache_commit(0);
|
||||
}
|
||||
|
||||
/* Find a free handle in openstores_handles[] array
|
||||
* to manage the interaction with the API.
|
||||
*
|
||||
* A maximum of MAX_OPEN_STORES objects can be opened
|
||||
* at the same time.
|
||||
*/
|
||||
static struct store_handle *find_free_handle(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_OPEN_STORES; i++) {
|
||||
if ((openstores_handles[i].flags & STORE_FLAGS_OPEN) == 0)
|
||||
return &openstores_handles[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int wolfPKCS11_Store_Open(int type, CK_ULONG id1, CK_ULONG id2, int read,
|
||||
void** store)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int found = 0;
|
||||
struct obj_hdr *hdr;
|
||||
struct store_object *obj;
|
||||
struct store_handle *handle;
|
||||
uint8_t *buf;
|
||||
struct obj_hdr *hdr = NULL;
|
||||
|
||||
for (i = 1; i < KEYVAULT_MAX_ITEMS; i++) {
|
||||
hdr = (struct obj_hdr*)(vault_base + i * KEYVAULT_OBJ_SIZE);
|
||||
if ((type == hdr->type) && (id1 == hdr->token_id) &&
|
||||
(id2 == hdr->object_id)) {
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if there is one handle available to open the slot */
|
||||
handle = find_free_handle();
|
||||
if (!handle) {
|
||||
*store = NULL;
|
||||
return SESSION_COUNT_E;
|
||||
}
|
||||
if ((!found) && read) {
|
||||
|
||||
/* Check if the target object exists */
|
||||
check_vault();
|
||||
buf = find_object_buffer(type, id1, id2);
|
||||
if ((buf == NULL) && read) {
|
||||
*store = NULL;
|
||||
return NOT_AVAILABLE_E;
|
||||
} else if (found) {
|
||||
*store = vault_descriptors[found];
|
||||
obj = vault_descriptors[found];
|
||||
memcpy(&obj->hdr, vault_base + found * KEYVAULT_OBJ_SIZE, sizeof(struct obj_hdr));
|
||||
obj->vault_idx = found;
|
||||
obj->read = read;
|
||||
} else if ((!found) && (!read)) {
|
||||
if (vault_idx++ >= KEYVAULT_MAX_ITEMS) {
|
||||
vault_idx--;
|
||||
}
|
||||
|
||||
if ((buf == NULL) && (!read)) {
|
||||
handle->hdr = create_object(type, id1, id2);
|
||||
if (handle->hdr == NULL) {
|
||||
*store = NULL;
|
||||
return FIND_FULL_E;
|
||||
|
||||
}
|
||||
obj = XMALLOC(sizeof(struct store_object), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (!obj)
|
||||
buf = find_object_buffer(type, id1, id2);
|
||||
if (!buf) {
|
||||
*store = NULL;
|
||||
return NOT_AVAILABLE_E;
|
||||
vault_descriptors[vault_idx] = obj;
|
||||
hdr = (struct obj_hdr *)obj;
|
||||
obj->vault_idx = vault_idx;
|
||||
obj->hdr.type = type;
|
||||
obj->hdr.token_id = id1;
|
||||
obj->hdr.object_id = id2;
|
||||
obj->hdr.size = 0;
|
||||
obj->read = 0;
|
||||
hal_flash_unlock();
|
||||
hal_flash_erase((uint32_t)(vault_base + vault_idx * KEYVAULT_OBJ_SIZE),
|
||||
KEYVAULT_OBJ_SIZE);
|
||||
hal_flash_write((uint32_t)(vault_base + vault_idx * KEYVAULT_OBJ_SIZE), (void *)obj,
|
||||
sizeof(struct obj_hdr));
|
||||
hal_flash_lock();
|
||||
*store = obj;
|
||||
}
|
||||
} else { /* buf != NULL, readonly */
|
||||
handle->hdr = find_object_header(type, id1, id2);
|
||||
if (!handle->hdr) {
|
||||
*store = NULL;
|
||||
return NOT_AVAILABLE_E;
|
||||
}
|
||||
}
|
||||
hdr->off = 0;
|
||||
|
||||
/* Set the position of the buffer in the handle */
|
||||
handle->buffer = buf;
|
||||
handle->pos = (((uint32_t)buf) - (uint32_t)vault_base) / KEYVAULT_OBJ_SIZE;
|
||||
/* Set the 'open' flag */
|
||||
handle->flags |= STORE_FLAGS_OPEN;
|
||||
|
||||
/* Set the 'readonly' flag in this handle if open with 'r' */
|
||||
if (read)
|
||||
handle->flags |= STORE_FLAGS_READONLY;
|
||||
else {
|
||||
handle->flags &= ~STORE_FLAGS_READONLY;
|
||||
/* Truncate the slot when opening in write mode */
|
||||
update_store_size(handle->hdr, 2 * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
|
||||
/* Set start of the buffer after the tok/obj id fields */
|
||||
handle->in_buffer_offset = (2 * sizeof(uint32_t));
|
||||
*store = handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wolfPKCS11_Store_Close(void* store)
|
||||
{
|
||||
struct store_object *obj = store;
|
||||
vault_descriptors[obj->vault_idx] = NULL;
|
||||
XFREE(obj, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
struct store_handle *handle = store;
|
||||
/* This removes all flags (including STORE_FLAGS_OPEN) */
|
||||
handle->flags = 0;
|
||||
handle->hdr = NULL;
|
||||
}
|
||||
|
||||
int wolfPKCS11_Store_Read(void* store, unsigned char* buffer, int len)
|
||||
{
|
||||
struct store_object *obj = store;
|
||||
if ((uint32_t)len + obj->hdr.off > obj->hdr.size) {
|
||||
len = obj->hdr.size - obj->hdr.off;
|
||||
}
|
||||
struct store_handle *handle = store;
|
||||
uint32_t *tok_obj_id;
|
||||
uint32_t obj_size = 0;
|
||||
if ((handle == NULL) || (handle->hdr == NULL) || (handle->buffer == NULL))
|
||||
return -1;
|
||||
|
||||
tok_obj_id = (uint32_t *)handle->buffer;
|
||||
obj_size = handle->hdr->size;
|
||||
if (obj_size > KEYVAULT_OBJ_SIZE)
|
||||
return -1;
|
||||
|
||||
if (handle->in_buffer_offset >= obj_size)
|
||||
return 0; /* "EOF" */
|
||||
|
||||
/* Truncate len to actual available bytes */
|
||||
if (handle->in_buffer_offset + len > obj_size)
|
||||
len = (obj_size - handle->in_buffer_offset);
|
||||
|
||||
if (len > 0) {
|
||||
memcpy(buffer, vault_base + obj->vault_idx * KEYVAULT_OBJ_SIZE +
|
||||
STORE_PRIV_HDR_SIZE + obj->hdr.off, len);
|
||||
obj->hdr.off += len;
|
||||
memcpy(buffer, (uint8_t *)(handle->buffer) + handle->in_buffer_offset, len);
|
||||
handle->in_buffer_offset += len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int wolfPKCS11_Store_Write(void* store, unsigned char* buffer, int len)
|
||||
{
|
||||
struct store_object *obj = store;
|
||||
int pos = 0;
|
||||
if (len + obj->hdr.off > (KEYVAULT_OBJ_SIZE - STORE_PRIV_HDR_SIZE)) {
|
||||
return -1;
|
||||
}
|
||||
if (obj->read)
|
||||
return -1;
|
||||
if (obj->vault_idx > KEYVAULT_MAX_ITEMS)
|
||||
return -1;
|
||||
obj->hdr.size += len;
|
||||
hal_flash_unlock();
|
||||
if (obj->hdr.off == 0)
|
||||
hal_flash_erase((uint32_t)(vault_base + obj->vault_idx * KEYVAULT_OBJ_SIZE),
|
||||
KEYVAULT_OBJ_SIZE);
|
||||
struct store_handle *handle = store;
|
||||
uint32_t obj_size = 0;
|
||||
uint32_t in_sector_offset = 0;
|
||||
uint32_t in_sector_len = 0;
|
||||
uint32_t sector_base = 0;
|
||||
int written = 0;
|
||||
|
||||
hal_flash_write((uint32_t)(vault_base + obj->vault_idx * KEYVAULT_OBJ_SIZE),
|
||||
(void *)obj, sizeof(struct obj_hdr));
|
||||
while (pos < len) {
|
||||
uint32_t base = (uint32_t)(vault_base +
|
||||
obj->vault_idx * KEYVAULT_OBJ_SIZE);
|
||||
uint32_t sz = len;
|
||||
if (sz > WOLFBOOT_SECTOR_SIZE) {
|
||||
sz = WOLFBOOT_SECTOR_SIZE;
|
||||
}
|
||||
hal_flash_write(base + STORE_PRIV_HDR_SIZE + pos, buffer + pos + obj->hdr.off, sz);
|
||||
pos += sz;
|
||||
|
||||
if ((handle == NULL) || (handle->hdr == NULL) || (handle->buffer == NULL))
|
||||
return -1;
|
||||
if ((handle->flags & STORE_FLAGS_READONLY) != 0)
|
||||
return -1;
|
||||
|
||||
obj_size = handle->hdr->size;
|
||||
if (obj_size > KEYVAULT_OBJ_SIZE)
|
||||
return -1;
|
||||
|
||||
if (len + handle->in_buffer_offset > KEYVAULT_OBJ_SIZE)
|
||||
len = KEYVAULT_OBJ_SIZE - handle->in_buffer_offset;
|
||||
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
|
||||
while (written < len) {
|
||||
in_sector_offset = ((uint32_t)(handle->buffer) + handle->in_buffer_offset)
|
||||
% WOLFBOOT_SECTOR_SIZE;
|
||||
sector_base = (uint32_t)handle->buffer + handle->in_buffer_offset - in_sector_offset;
|
||||
in_sector_len = WOLFBOOT_SECTOR_SIZE - in_sector_offset;
|
||||
if (in_sector_len > (uint32_t)len)
|
||||
in_sector_len = len;
|
||||
|
||||
/* Cache the corresponding sector */
|
||||
memcpy(cached_sector, (void *)sector_base, WOLFBOOT_SECTOR_SIZE);
|
||||
/* Write content into cache */
|
||||
memcpy(cached_sector + in_sector_offset, buffer + written, in_sector_len);
|
||||
/* Adjust in_buffer position for the handle accordingly */
|
||||
handle->in_buffer_offset += in_sector_len;
|
||||
written += in_sector_len;
|
||||
/* Write sector to flash */
|
||||
cache_commit((uint32_t)sector_base - (uint32_t)vault_base);
|
||||
}
|
||||
hal_flash_lock();
|
||||
obj->hdr.off += len;
|
||||
obj_size += written;
|
||||
update_store_size(handle->hdr, obj_size);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,4 +102,7 @@ CONFIG_VARS:= ARCH TARGET SIGN HASH MCUXSDK MCUXPRESSO MCUXPRESSO_CPU MCUXPRESSO
|
|||
XMSS_PARAMS \
|
||||
ELF BIG_ENDIAN \
|
||||
NXP_CUSTOM_DCD NXP_CUSTOM_DCD_OBJS \
|
||||
FLASH_OTP_KEYSTORE
|
||||
FLASH_OTP_KEYSTORE \
|
||||
KEYVAULT_OBJ_SIZE \
|
||||
KEYVAULT_MAX_ITEMS
|
||||
|
||||
|
|
|
@ -13,13 +13,14 @@ CFLAGS+=--coverage
|
|||
LDFLAGS+=-fprofile-arcs
|
||||
LDFLAGS+=-ftest-coverage
|
||||
WOLFCRYPT=../../lib/wolfssl/
|
||||
WOLFPKCS11=../../lib/wolfPKCS11/
|
||||
|
||||
|
||||
|
||||
TESTS:=unit-parser unit-extflash unit-aes128 unit-aes256 unit-chacha20 unit-pci \
|
||||
unit-mock-state unit-sectorflags unit-image unit-nvm unit-nvm-flagshome \
|
||||
unit-enc-nvm unit-enc-nvm-flagshome unit-delta unit-update-flash \
|
||||
unit-update-ram
|
||||
unit-update-ram unit-pkcs11_store
|
||||
|
||||
all: $(TESTS)
|
||||
|
||||
|
@ -62,6 +63,7 @@ unit-update-flash:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH
|
|||
unit-update-ram:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
|
||||
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT \
|
||||
-DPART_SWAP_EXT -DPART_BOOT_EXT -DWOLFBOOT_DUALBOOT -DNO_XIP
|
||||
unit-pkcs11_store:CFLAGS+=-I$(WOLFPKCS11) -DMOCK_PARTITIONS -DMOCK_KEYVAULT -DSECURE_PKCS11
|
||||
|
||||
|
||||
|
||||
|
@ -124,6 +126,9 @@ unit-update-flash: ../../include/target.h unit-update-flash.c
|
|||
unit-update-ram: ../../include/target.h unit-update-ram.c
|
||||
gcc -o $@ unit-update-ram.c ../../src/image.c ../../lib/wolfssl/wolfcrypt/src/sha256.c $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
unit-pkcs11_store: ../../include/target.h unit-pkcs11_store.c
|
||||
gcc -o $@ $(WOLFCRYPT_SRC) unit-pkcs11_store.c $(CFLAGS) $(WOLFCRYPT_CFLAGS) $(LDFLAGS)
|
||||
|
||||
%.o:%.c
|
||||
gcc -c -o $@ $^ $(CFLAGS)
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#else
|
||||
#define WOLFBOOT_PARTITION_SIZE 0x8000
|
||||
#endif
|
||||
#define WOLFBOOT_KEYVAULT 0xCF000000
|
||||
#else
|
||||
|
||||
#ifdef WOLFBOOT_FIXED_PARTITIONS
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* txt_filler.h
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*
|
||||
* This file contains excerpts from "La Divina Commedia" by Dante Alighieri,
|
||||
* written in the early 14th century.
|
||||
* The text of "La Divina Commedia" is in the public domain worldwide.
|
||||
*
|
||||
* Public Domain Notice:
|
||||
* This work is free of known copyright restrictions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DANTE_FILLER
|
||||
#define DANTE_FILLER \
|
||||
"Nel mezzo del cammin di nostra vita " \
|
||||
"mi ritrovai per una selva oscura, " \
|
||||
"ché la diritta via era smarrita. " \
|
||||
" " \
|
||||
"Ahi quanto a dir qual era è cosa dura " \
|
||||
"esta selva selvaggia e aspra e forte " \
|
||||
"che nel pensier rinova la paura! " \
|
||||
" " \
|
||||
"Tant’ è amara che poco è più morte; " \
|
||||
"ma per trattar del ben ch’i’ vi trovai, " \
|
||||
"dirò de l’altre cose ch’i’ v’ho scorte. " \
|
||||
" " \
|
||||
"Io non so ben ridir com’ i’ v’intrai, " \
|
||||
"tant’ era pien di sonno a quel punto " \
|
||||
"che la verace via abbandonai. " \
|
||||
" " \
|
||||
"Ma poi ch’i’ fui al piè d’un colle giunto, " \
|
||||
"là dove terminava quella valle " \
|
||||
"che m’avea di paura il cor compunto, " \
|
||||
" " \
|
||||
"guardai in alto e vidi le sue spalle " \
|
||||
"vestite già de’ raggi del pianeta " \
|
||||
"che mena dritto altrui per ogne calle. " \
|
||||
" " \
|
||||
"Allor fu la paura un poco queta, " \
|
||||
"che nel lago del cor m’era durata " \
|
||||
"la notte ch’i’ passai con tanta pieta. " \
|
||||
" " \
|
||||
"E come quei che con lena affannata, " \
|
||||
"uscito fuor del pelago a la riva, " \
|
||||
"si volge a l’acqua perigliosa e guata, " \
|
||||
" " \
|
||||
"così l’animo mio, ch’ancor fuggiva, " \
|
||||
"si volse a retro a rimirar lo passo " \
|
||||
"che non lasciò già mai persona viva. " \
|
||||
" " \
|
||||
"Poi ch’èi posato un poco il corpo lasso, " \
|
||||
"ripresi via per la piaggia diserta, " \
|
||||
"sì che ’l piè fermo sempre era ’l più basso. " \
|
||||
" " \
|
||||
"Ed ecco, quasi al cominciar de l’erta, " \
|
||||
"una lonza leggera e presta molto, " \
|
||||
"che di pel macolato era coverta; " \
|
||||
" " \
|
||||
"e non mi si partia dinanzi al volto, " \
|
||||
"anzi ’mpediva tanto il mio cammino, " \
|
||||
"ch’i’ fui per ritornar più volte vòlto. " \
|
||||
" " \
|
||||
"Temp’ era dal principio del mattino, " \
|
||||
"e ’l sol montava ’n sù con quelle stelle " \
|
||||
"ch’eran con lui quando l’amor divino " \
|
||||
" " \
|
||||
"mosse di prima quelle cose belle; " \
|
||||
"sì ch’a bene sperar m’era cagione " \
|
||||
"di quella fiera a la gaetta pelle " \
|
||||
" " \
|
||||
"l’ora del tempo e la dolce stagione; " \
|
||||
"ma non sì che paura non mi desse " \
|
||||
"la vista che m’apparve d’un leone. " \
|
||||
" " \
|
||||
"Questi parea che contra me venisse " \
|
||||
"con la test’ alta e con rabbiosa fame, " \
|
||||
"sì che parea che l’aere ne tremesse. " \
|
||||
" " \
|
||||
"Ed una lupa, che di tutte brame " \
|
||||
"sembiava carca ne la sua magrezza, " \
|
||||
"e molte genti fé già viver grame, " \
|
||||
" " \
|
||||
"questa mi porse tanto di gravezza " \
|
||||
"con la paura ch’uscia di sua vista, " \
|
||||
"ch’io perdei la speranza de l’altezza. " \
|
||||
" " \
|
||||
"E qual è quei che volontieri acquista, " \
|
||||
"e giugne ’l tempo che perder lo face, " \
|
||||
"che ’n tutti suoi pensier piange e s’attrista" \
|
||||
" " \
|
||||
"tal mi fece la bestia sanza pace, " \
|
||||
"che, venendomi ’ncontro, a poco a poco " \
|
||||
"mi ripigneva là dove ’l sol tace. " \
|
||||
" " \
|
||||
"Mentre ch’i’ rovinava in basso loco, " \
|
||||
"dinanzi a li occhi mi si fu offerto " \
|
||||
"chi per lungo silenzio parea fioco. " \
|
||||
" " \
|
||||
"Quando vidi costui nel gran diserto, " \
|
||||
"«Miserere di me», gridai a lui, " \
|
||||
"«qual che tu sii, od ombra od omo certo!». "
|
||||
#endif
|
|
@ -97,6 +97,7 @@ int hal_flash_erase(haladdr_t address, int len)
|
|||
memset(address, 0xFF, len);
|
||||
#ifdef MOCK_KEYVAULT
|
||||
} else if ((address >= vault_base) && (address < vault_base + keyvault_size)) {
|
||||
printf("Erasing vault from %p : %p bytes\n", address, len);
|
||||
erased_vault++;
|
||||
memset(address, 0xFF, len);
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,294 @@
|
|||
/* unit-pkcs11_store.c
|
||||
*
|
||||
* Unit test for PKCS11 storage module
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2024 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
/* Option to enable sign tool debugging */
|
||||
/* Must also define DEBUG_WOLFSSL in user_settings.h */
|
||||
#define WOLFBOOT_HASH_SHA256
|
||||
#define EXT_FLASH
|
||||
#define PART_UPDATE_EXT
|
||||
#define NVM_FLASH_WRITEONCE
|
||||
|
||||
#if defined(ENCRYPT_WITH_AES256) || defined(ENCRYPT_WITH_AES128)
|
||||
#define WOLFSSL_AES_COUNTER
|
||||
#define WOLFSSL_AES_DIRECT
|
||||
#endif
|
||||
#if defined(ENCRYPT_WITH_AES256)
|
||||
#define WOLFSSL_AES_256
|
||||
#endif
|
||||
#if defined(ENCRYPT_WITH_CHACHA)
|
||||
#define HAVE_CHACHA
|
||||
#endif
|
||||
#define ECC_TIMING_RESISTANT
|
||||
|
||||
#define WOLFSSL_USER_SETTINGS
|
||||
#define UNIT_TEST
|
||||
#define WOLFBOOT_SIGN_ECC256
|
||||
#define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ECC256
|
||||
|
||||
#define __WOLFBOOT
|
||||
|
||||
#include <stdio.h>
|
||||
#include <check.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define XMALLOC_OVERRIDE
|
||||
#define XMALLOC(n,h,t) malloc(n)
|
||||
#define XFREE(p,h,t) free(p)
|
||||
|
||||
#include "user_settings.h"
|
||||
#include "wolfssl/wolfcrypt/sha.h"
|
||||
#include "wolfboot/wolfboot.h"
|
||||
#include "wolfpkcs11/pkcs11.h"
|
||||
#include "hal.h"
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define MOCK_ADDRESS 0xCF000000
|
||||
uint8_t *vault_base = (uint8_t *)MOCK_ADDRESS;
|
||||
#include "unit-keystore.c"
|
||||
#include "pkcs11_store.c"
|
||||
const uint32_t keyvault_size = KEYVAULT_OBJ_SIZE * KEYVAULT_MAX_ITEMS + 2 * WOLFBOOT_SECTOR_SIZE;
|
||||
#include "unit-mock-flash.c"
|
||||
|
||||
#include "txt_filler.h"
|
||||
|
||||
const char dante_filler[KEYVAULT_OBJ_SIZE] = DANTE_FILLER;
|
||||
|
||||
START_TEST (test_store_and_load_objs) {
|
||||
CK_ULONG id_tok, id_obj;
|
||||
int type;
|
||||
int ret, readonly;
|
||||
void *store = NULL;
|
||||
const char secret1[] = "Everyone gets Friday off.";
|
||||
const char secret2[] = "This is just a test string.";
|
||||
const char short_string[] = "Short string";
|
||||
char secret_rd[KEYVAULT_OBJ_SIZE];
|
||||
|
||||
type = DYNAMIC_TYPE_ECC;
|
||||
id_tok = 1;
|
||||
id_obj = 12;
|
||||
readonly = 0;
|
||||
ret = mmap_file("/tmp/wolfboot-unit-keyvault.bin", vault_base,
|
||||
keyvault_size, NULL);
|
||||
fail_if(ret != 0);
|
||||
memset(vault_base, 0xEE, keyvault_size);
|
||||
/* Open the vault, create the object */
|
||||
fprintf(stderr, "Opening the vault\n");
|
||||
printf("Flash Keyvault: %p\n", vault_base);
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_unless(ret == 0, "Failed to open the vault: %d", ret);
|
||||
fail_if(store == NULL, "Did not receive a store address");
|
||||
fprintf(stderr, "open successful\n");
|
||||
|
||||
/* Test two subsequent writes */
|
||||
ret = wolfPKCS11_Store_Write(store, secret1, strlen(secret1) + 1);
|
||||
ck_assert_int_eq(ret, strlen(secret1) + 1);
|
||||
ret = wolfPKCS11_Store_Write(store, secret2, strlen(secret2) + 1);
|
||||
ck_assert_int_eq(ret, strlen(secret2) + 1);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
printf("Closed vault. Reopening in RO mode\n");
|
||||
|
||||
/* Reopen for reading */
|
||||
readonly = 1;
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_if(ret != 0, "Failed to reopen the vault in read-only mode: %d", ret);
|
||||
|
||||
/* Read out the content */
|
||||
ret = wolfPKCS11_Store_Read(store, secret_rd, 128);
|
||||
fail_if(ret != strlen(secret1) + strlen(secret2) + 2);
|
||||
fail_if(strcmp(secret1, secret_rd) != 0);
|
||||
fail_if(strcmp(secret2, secret_rd + 1 + strlen(secret1)) != 0);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
|
||||
/* Create a second object with same Ids, different type*/
|
||||
type = DYNAMIC_TYPE_RSA;
|
||||
readonly = 0;
|
||||
fprintf(stderr, "Opening the second vault\n");
|
||||
printf("Flash Keyvault: %p\n", vault_base);
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_unless(ret == 0, "Failed to open the 2nd vault: %d", ret);
|
||||
fail_if(store == NULL, "Did not receive a store address for 2nd vault");
|
||||
fprintf(stderr, "open 2 successful\n");
|
||||
ret = wolfPKCS11_Store_Write(store, secret2, strlen(secret2) + 1);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
|
||||
/* Reopen for reading */
|
||||
readonly = 1;
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_if(ret != 0, "Failed to reopen the vault in read-only mode: %d", ret);
|
||||
/* Read out the content */
|
||||
ret = wolfPKCS11_Store_Read(store, secret_rd, 128);
|
||||
fail_if(ret != strlen(secret2) + 1);
|
||||
fail_if(strcmp(secret2, secret_rd) != 0);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
|
||||
/* Create more similar objects, different secret */
|
||||
type = DYNAMIC_TYPE_RSA;
|
||||
id_tok = 2;
|
||||
id_obj = 22;
|
||||
readonly = 0;
|
||||
fprintf(stderr, "Creating one more vault\n");
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_unless(ret == 0, "Failed to create vault: %d", ret);
|
||||
fail_if(store == NULL, "Did not receive a store address for vault");
|
||||
fprintf(stderr, "open 2 successful\n");
|
||||
ret = wolfPKCS11_Store_Write(store, secret1, strlen(secret1) + 1);
|
||||
|
||||
id_tok = 3;
|
||||
id_obj = 23;
|
||||
readonly = 0;
|
||||
fprintf(stderr, "Creating one more vault\n");
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_unless(ret == 0, "Failed to create vault: %d", ret);
|
||||
fail_if(store == NULL, "Did not receive a store address for vault");
|
||||
fprintf(stderr, "open 2 successful\n");
|
||||
ret = wolfPKCS11_Store_Write(store, secret1, strlen(secret1) + 1);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
|
||||
/* Reopen for reading */
|
||||
id_tok = 1;
|
||||
id_obj = 12;
|
||||
readonly = 1;
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_if(ret != 0, "Failed to reopen the vault in read-only mode: %d", ret);
|
||||
/* Read out the content */
|
||||
ret = wolfPKCS11_Store_Read(store, secret_rd, 128);
|
||||
fail_if(ret != strlen(secret2) + 1);
|
||||
fail_if(strcmp(secret2, secret_rd) != 0);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
|
||||
/* Open non-existing vaults */
|
||||
id_tok = 5;
|
||||
readonly = 1;
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_if(ret == 0, "Returned with success with invalid id_tok %d", id_tok);
|
||||
id_tok = 2;
|
||||
id_obj = 0;
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_if(ret == 0, "Returned with success with invalid id_obj %d", id_obj);
|
||||
type = 0xFF;
|
||||
id_tok = 2;
|
||||
id_obj = 23;
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_if(ret == 0, "Returned with success with invalid type %d", type);
|
||||
|
||||
/* Test backup recovery for allocation table */
|
||||
memset(vault_base, 0xEE, WOLFBOOT_SECTOR_SIZE);
|
||||
type = DYNAMIC_TYPE_RSA;
|
||||
id_tok = 1;
|
||||
id_obj = 12;
|
||||
readonly = 1;
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_if(ret != 0, "Failed to reopen the vault recovering from alloc table backup: %d", ret);
|
||||
/* Read out the content */
|
||||
ret = wolfPKCS11_Store_Read(store, secret_rd, 128);
|
||||
fail_if(ret != strlen(secret2) + 1);
|
||||
fail_if(strcmp(secret2, secret_rd) != 0);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
|
||||
/* Test backup recovery for object sector */
|
||||
printf("Test recovery sector...\n");
|
||||
memcpy(vault_base + WOLFBOOT_SECTOR_SIZE, vault_base + 0x1800,
|
||||
WOLFBOOT_SECTOR_SIZE);
|
||||
memset(vault_base + 0x1800, 0xEE, WOLFBOOT_SECTOR_SIZE);
|
||||
id_tok = 1;
|
||||
id_obj = 12;
|
||||
readonly = 1;
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_if(ret != 0, "Failed to reopen the vault recovering from object sector backup: %d", ret);
|
||||
/* Read out the content */
|
||||
ret = wolfPKCS11_Store_Read(store, secret_rd, 128);
|
||||
fail_if(ret != strlen(secret2) + 1);
|
||||
fail_if(strcmp(secret2, secret_rd) != 0);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
|
||||
/* Test with very large payload */
|
||||
type = DYNAMIC_TYPE_RSA;
|
||||
id_tok = 3;
|
||||
id_obj = 33;
|
||||
readonly = 0;
|
||||
fprintf(stderr, "Creating one BIG vault\n");
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_unless(ret == 0, "Failed to create vault: %d", ret);
|
||||
fail_if(store == NULL, "Did not receive a store address for vault");
|
||||
fprintf(stderr, "open 3.33 successful\n");
|
||||
ret = wolfPKCS11_Store_Write(store, dante_filler, strlen(dante_filler) + 1);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
|
||||
/* Reopen for reading */
|
||||
readonly = 1;
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_if(ret != 0, "Failed to reopen the vault in read-only mode: %d", ret);
|
||||
/* Read out the content */
|
||||
memset(secret_rd, 0, KEYVAULT_OBJ_SIZE);
|
||||
ret = wolfPKCS11_Store_Read(store, secret_rd, KEYVAULT_OBJ_SIZE);
|
||||
fail_if(ret != KEYVAULT_OBJ_SIZE - 8);
|
||||
fail_if(strncmp(dante_filler, secret_rd, KEYVAULT_OBJ_SIZE - 8) != 0);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
|
||||
/* Reopen for writing, test truncate */
|
||||
readonly = 0;
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_unless(ret == 0, "Failed to create vault: %d", ret);
|
||||
fail_if(store == NULL, "Did not receive a store address for vault");
|
||||
fprintf(stderr, "open 3.33 successful\n");
|
||||
ret = wolfPKCS11_Store_Write(store, short_string, strlen(short_string) + 1);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
|
||||
/* Reopen for reading */
|
||||
readonly = 1;
|
||||
ret = wolfPKCS11_Store_Open(type, id_tok, id_obj, readonly, &store);
|
||||
fail_if(ret != 0, "Failed to reopen the vault in read-only mode: %d", ret);
|
||||
/* Read out the content */
|
||||
memset(secret_rd, 0, KEYVAULT_OBJ_SIZE);
|
||||
ret = wolfPKCS11_Store_Read(store, secret_rd, KEYVAULT_OBJ_SIZE);
|
||||
fail_if(ret != strlen(short_string) + 1);
|
||||
fail_if(strcmp(short_string, secret_rd) != 0);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *wolfboot_suite(void)
|
||||
{
|
||||
/* Suite initialization */
|
||||
Suite *s = suite_create("wolfBoot-pkcs11-store");
|
||||
|
||||
TCase* tcase_store_and_load_objs = tcase_create("store_and_load_objs");
|
||||
tcase_add_test(tcase_store_and_load_objs, test_store_and_load_objs);
|
||||
suite_add_tcase(s, tcase_store_and_load_objs);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = wolfboot_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
Loading…
Reference in New Issue