Skip to content

Commit

Permalink
Adds unit tests for SGX HAL nvmem module
Browse files Browse the repository at this point in the history
  • Loading branch information
italo-sampaio committed Oct 1, 2024
1 parent ab02b5b commit b98c74e
Show file tree
Hide file tree
Showing 8 changed files with 557 additions and 0 deletions.
1 change: 1 addition & 0 deletions firmware/src/hal/sgx/test/common/assert_utils.h
33 changes: 33 additions & 0 deletions firmware/src/hal/sgx/test/common/common.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# The MIT License (MIT)
#
# Copyright (c) 2021 RSK Labs Ltd
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

SRCDIR = ../../src/trusted
COMMONDIR = ../../../../common/src
MOCKDIR = ../mock
HALINCDIR = ../../../../hal/include
THISCOMMONDIR = ../common
CFLAGS = -iquote $(COMMONDIR)
CFLAGS += -iquote $(SRCDIR) -iquote $(HALINCDIR)
CFLAGS += -iquote $(THISCOMMONDIR)
CFLAGS += -DHSM_PLATFORM_SGX

include ../../../../../coverage/coverage.mk
89 changes: 89 additions & 0 deletions firmware/src/hal/sgx/test/common/mock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2021 RSK Labs Ltd
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

// Mock functions for the secret store

/**
* @brief Initializes the mock secret store
*/
void mock_sest_init();

/**
* @brief Mock implementation of sest_exists
*
* @param key the key for the secret
*
* @returns whether the provided key corresponds to a secret in the store
*/
bool mock_sest_exists(char *key);

/**
* @brief Mock implementation of sest_write
*
* @param key the key for the secret
* @param secret the secret to write
* @param secret_length the length of the secret
*
* @returns Whether the write was successful.
*
* NOTE: This mock implementation will always return true unless the
* fail_next_write flag is set.
*/
bool mock_sest_write(char *key, uint8_t *secret, size_t secret_length);

/**
* @brief Mock implementation of sest_read
*
* @param key the key for the secret
* @param dest the destination buffer for the read secret
* @param dest_length the length of the destination buffer
*
* @returns the length of the secret read, or ZERO upon error.
*
* NOTE: This mock implementation will fail if the fail_next_read flag is set,
* regardless of the key provided.
*/
uint8_t mock_sest_read(char *key, uint8_t *dest, size_t dest_length);

/**
* @brief Resets the mock secret store to its initial state
*/
void mock_sest_reset();

/**
* @brief Sets the value of the fail_next_read flag
*
* @param fail whether the next call to sest_read should fail
*/
void mock_sest_fail_next_read(bool fail);

/**
* @brief Sets the value of the fail_next_write flag
*
* @param fail whether the next call to sest_write should fail
*/
void mock_sest_fail_next_write(bool fail);
99 changes: 99 additions & 0 deletions firmware/src/hal/sgx/test/mock/mock_secret_store.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "mock.h"

typedef struct mock_sest_register {
char *key;
uint8_t *secret;
uint8_t secret_length;
} mock_sest_register_t;

#define MOCK_SEST_MAX_REGISTERS 10
typedef struct mock_secret_store {
mock_sest_register_t registers[MOCK_SEST_MAX_REGISTERS];
size_t num_registers;
bool fail_next_read;
bool fail_next_write;
} mock_secret_store_t;

static mock_secret_store_t g_mock_secret_store;

bool mock_sest_exists(char *key) {
for (int i = 0; i < g_mock_secret_store.num_registers; i++) {
if (strcmp(g_mock_secret_store.registers[i].key, key) == 0) {
return true;
}
}
return false;
}

bool mock_sest_write(char *key, uint8_t *secret, size_t secret_length) {
if (g_mock_secret_store.fail_next_write) {
g_mock_secret_store.fail_next_write = false;
return false;
}
int register_index = -1;
for (int i = 0; i < g_mock_secret_store.num_registers; i++) {
if (strcmp(g_mock_secret_store.registers[i].key, key) == 0) {
register_index = i;
break;
}
}
if (register_index == -1) {
assert(g_mock_secret_store.num_registers < MOCK_SEST_MAX_REGISTERS);
register_index = g_mock_secret_store.num_registers;
}

mock_sest_register_t *new_register =
&g_mock_secret_store.registers[register_index];
new_register->key = malloc(strlen(key) + 1);
strcpy(new_register->key, key);
new_register->secret = malloc(secret_length);
memcpy(new_register->secret, secret, secret_length);
new_register->secret_length = secret_length;
g_mock_secret_store.num_registers++;

return true;
}

uint8_t mock_sest_read(char *key, uint8_t *dest, size_t dest_length) {
if (g_mock_secret_store.fail_next_read) {
g_mock_secret_store.fail_next_read = false;
return 0;
}
for (int i = 0; i < g_mock_secret_store.num_registers; i++) {
if (strcmp(g_mock_secret_store.registers[i].key, key) == 0) {
assert(dest_length >=
g_mock_secret_store.registers[i].secret_length);
memcpy(dest,
g_mock_secret_store.registers[i].secret,
g_mock_secret_store.registers[i].secret_length);
return g_mock_secret_store.registers[i].secret_length;
}
}
return 0;
}

void mock_sest_init() {
memset(&g_mock_secret_store, 0, sizeof(g_mock_secret_store));
}

void mock_sest_reset() {
for (int i = 0; i < g_mock_secret_store.num_registers; i++) {
free(g_mock_secret_store.registers[i].key);
free(g_mock_secret_store.registers[i].secret);
}
memset(&g_mock_secret_store, 0, sizeof(g_mock_secret_store));
}

void mock_sest_fail_next_read(bool fail) {
g_mock_secret_store.fail_next_read = fail;
}

void mock_sest_fail_next_write(bool fail) {
g_mock_secret_store.fail_next_write = fail;
}
48 changes: 48 additions & 0 deletions firmware/src/hal/sgx/test/nvmem/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# The MIT License (MIT)
#
# Copyright (c) 2021 RSK Labs Ltd
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

include ../common/common.mk

PROG = test.out
OBJS = nvmem.o test_nvmem.o mock_secret_store.o

all: $(PROG)

$(PROG): $(OBJS)
$(CC) $(COVFLAGS) -o $@ $^

test_nvmem.o: test_nvmem.c
$(CC) $(CFLAGS) -c -o $@ $^

nvmem.o: $(SRCDIR)/nvmem.c
$(CC) $(CFLAGS) $(COVFLAGS) -c -o $@ $^

mock_secret_store.o: $(MOCKDIR)/mock_secret_store.c
$(CC) $(CFLAGS) -c -o $@ $^

.PHONY: clean test

clean:
rm -f $(PROG) *.o $(COVFILES)

test: all
./$(PROG)
Loading

0 comments on commit b98c74e

Please sign in to comment.