Skip to content

Commit

Permalink
Merge branch '38-refactor-tests' into 'develop'
Browse files Browse the repository at this point in the history
Check comments, update code coverage

Closes #38

See merge request internal/sw-design/libtropic!46
  • Loading branch information
pavelpolach321 committed Oct 11, 2024
2 parents 1136796 + 5815ad5 commit 83fe88d
Show file tree
Hide file tree
Showing 46 changed files with 1,074 additions and 555 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- lt_handshake() function renamed to lt_start_session()
- TROPIC01 hw wallet example updated - compiles for 32 and 64 bit system
- Unit tests organization was updated
- Included lt_l2_api_structs.h and lt_l3_api_structs.h are automatically generated

### Added

Expand Down
10 changes: 7 additions & 3 deletions examples/hw_wallet/TROPIC01_hw_wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,13 +602,13 @@ static int session_H3(void)
LT_ASSERT(LT_OK, lt_ecc_eddsa_sign(&h, ECC_SLOT_0, msg, 4, rs, 64));

LOG_OUT_SESSION("%s", "lt_ecc_key_read() ");
uint8_t slot_1_pubkey[64];
uint8_t slot_0_pubkey[64];
lt_ecc_curve_type_t curve;
ecc_key_origin_t origin;
LT_ASSERT(LT_OK, lt_ecc_key_read(&h, ECC_SLOT_0, slot_1_pubkey, 64, &curve, &origin));
LT_ASSERT(LT_OK, lt_ecc_key_read(&h, ECC_SLOT_0, slot_0_pubkey, 64, &curve, &origin));

LOG_OUT_SESSION("%s", "lt_ecc_eddsa_sig_verify() ");
LT_ASSERT(LT_OK, lt_ecc_eddsa_sig_verify(msg, 4, slot_1_pubkey, rs));
LT_ASSERT(LT_OK, lt_ecc_eddsa_sig_verify(msg, 4, slot_0_pubkey, rs));

// TODO generate key
LOG_OUT_SESSION("%s", "lt_ecc_key_generate() in ECC_SLOT_8");
Expand All @@ -618,6 +618,10 @@ static int session_H3(void)
LOG_OUT_SESSION("%s", "lt_ecc_key_generate() in ECC_SLOT_24");
LT_ASSERT(LT_OK, lt_ecc_key_generate(&h, ECC_SLOT_24, CURVE_ED25519));

LOG_OUT_SESSION("%s", "lt_random_get() RANDOM_VALUE_GET_LEN_MAX == 255");
uint8_t buff[RANDOM_VALUE_GET_LEN_MAX];
LT_ASSERT(LT_OK, lt_random_get(&h, buff, RANDOM_VALUE_GET_LEN_MAX));

// TODO write r mem data
LOG_OUT_SESSION("%s", "lt_r_mem_data_erase() slot 0 ");
LT_ASSERT(LT_OK, lt_r_mem_data_erase(&h, 0));
Expand Down
8 changes: 4 additions & 4 deletions include/libtropic.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ lt_ret_t lt_r_mem_data_erase(lt_handle_t *h, const uint16_t udata_slot);

//--------------------------------------------------------------------------------------------------------------------//
/** @brief Maximum number of random bytes requested at once */
#define RANDOM_VALUE_GET_LEN_MAX L2_CHUNK_MAX_DATA_SIZE
#define RANDOM_VALUE_GET_LEN_MAX 255//L2_CHUNK_MAX_DATA_SIZE

/**
* @brief Get number of random bytes
Expand Down Expand Up @@ -439,13 +439,13 @@ lt_ret_t lt_ecc_key_erase(lt_handle_t *h, const ecc_slot_t slot);
*
* @param h Device's handle
* @param slot Slot containing a private key, ECC_SLOT_1 - ECC_SLOT_32
* @param msg_hash Buffer containing hash of a message
* @param msg_hash_len Length of hash's buffer should be 32B
* @param msg Buffer containing a message
* @param msg_len Length of msg's buffer
* @param rs Buffer for storing a signature in a form of R and S bytes
* @param rs_len Length of rs buffer should be 64B
* @return LT_OK if success, otherwise returns other error code.
*/
lt_ret_t lt_ecc_ecdsa_sign(lt_handle_t *h, const ecc_slot_t slot, const uint8_t *msg_hash, const uint16_t msg_hash_len, uint8_t *rs, const uint8_t rs_len);
lt_ret_t lt_ecc_ecdsa_sign(lt_handle_t *h, const ecc_slot_t slot, const uint8_t *msg, const uint16_t msg_len, uint8_t *rs, const uint8_t rs_len);

/**
* @brief EdDSA sign message with a private key stored in TROPIC01 device
Expand Down
2 changes: 2 additions & 0 deletions include/libtropic_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ typedef uint32_t u32;

/** Size of RES_SIZE field */
#define L3_RES_SIZE_SIZE sizeof(uint16_t)
/** Size of CMD_SIZE field */
#define L3_CMD_SIZE_SIZE sizeof(uint16_t)
/** Size of l3 CMD_ID field */
#define L3_CMD_ID_SIZE (1)
/** Maximal size of l3 RES/RSP DATA field */
Expand Down
1 change: 1 addition & 0 deletions project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
- ./src/**
- ./vendor/trezor_crypto/**
- ./hal/**
- ./hal/crypto/trezor_crypto/*
:support:
- tests/unit/support
:libraries: []
Expand Down
100 changes: 53 additions & 47 deletions src/libtropic.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ lt_ret_t lt_ping(lt_handle_t *h, const uint8_t *msg_out, uint8_t *msg_in, const
}

// Check incomming l3 length
if(len != (p_l3_res->res_size - 1))
if(len != (p_l3_res->res_size - LT_L3_PING_CMD_SIZE_MIN))
{
return LT_FAIL;
}
Expand Down Expand Up @@ -660,14 +660,54 @@ lt_ret_t lt_pairing_key_invalidate(lt_handle_t *h, const uint8_t slot)
return LT_OK;
}

static bool conf_obj_valid(enum CONFIGURATION_OBJECTS_REGS addr)
{
bool valid = false;

switch(addr) {
case CONFIGURATION_OBJECTS_CFG_START_UP_ADDR:
case CONFIGURATION_OBJECTS_CFG_SLEEP_MODE_ADDR:
case CONFIGURATION_OBJECTS_CFG_SENSORS_ADDR:
case CONFIGURATION_OBJECTS_CFG_DEBUG_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_PAIRING_KEY_WRITE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_PAIRING_KEY_READ_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_PAIRING_KEY_INVALIDATE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_R_CONFIG_WRITE_ERASE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_R_CONFIG_READ_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_I_CONFIG_WRITE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_I_CONFIG_READ_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_PING_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_R_MEM_DATA_WRITE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_R_MEM_DATA_READ_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_R_MEM_DATA_ERASE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_RANDOM_VALUE_GET_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_ECC_KEY_GENERATE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_ECC_KEY_STORE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_ECC_KEY_READ_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_ECC_KEY_ERASE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_ECDSA_SIGN_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_EDDSA_SIGN_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_MCOUNTER_INIT_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_MCOUNTER_GET_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_MCOUNTER_UPDATE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_MAC_AND_DESTROY_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_SERIAL_CODE_GET_ADDR:
valid = true;
}
return valid;
}

lt_ret_t lt_r_config_write(lt_handle_t *h, enum CONFIGURATION_OBJECTS_REGS addr, const uint32_t obj)
{
if( !h
|| !conf_obj_valid(addr)
// TODO how to check object?
) {
return LT_PARAM_ERR;
}
if(h->session != SESSION_ON) {
return LT_HOST_NO_SESSION;
}
if(!h) {
return LT_PARAM_ERR;
}

// Setup a pointer to l3 buffer, which is placed in handle
struct lt_l3_r_config_write_cmd_t* p_l3_cmd = (struct lt_l3_r_config_write_cmd_t*)&h->l3_buff;
Expand Down Expand Up @@ -695,12 +735,15 @@ lt_ret_t lt_r_config_write(lt_handle_t *h, enum CONFIGURATION_OBJECTS_REGS addr,

lt_ret_t lt_r_config_read(lt_handle_t *h, const enum CONFIGURATION_OBJECTS_REGS addr, uint32_t *obj)
{
if( !h
|| !conf_obj_valid(addr)
|| !obj
) {
return LT_PARAM_ERR;
}
if(h->session != SESSION_ON) {
return LT_HOST_NO_SESSION;
}
if(!h) {
return LT_PARAM_ERR;
}

// Setup a pointer to l3 buffer, which is placed in handle
struct lt_l3_r_config_read_cmd_t* p_l3_cmd = (struct lt_l3_r_config_read_cmd_t*)&h->l3_buff;
Expand Down Expand Up @@ -758,43 +801,6 @@ lt_ret_t lt_r_config_erase(lt_handle_t *h)
return LT_OK;
}

static bool conf_obj_valid(enum CONFIGURATION_OBJECTS_REGS addr)
{
bool valid = false;

switch(addr) {
case CONFIGURATION_OBJECTS_CFG_START_UP_ADDR:
case CONFIGURATION_OBJECTS_CFG_SLEEP_MODE_ADDR:
case CONFIGURATION_OBJECTS_CFG_SENSORS_ADDR:
case CONFIGURATION_OBJECTS_CFG_DEBUG_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_PAIRING_KEY_WRITE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_PAIRING_KEY_READ_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_PAIRING_KEY_INVALIDATE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_R_CONFIG_WRITE_ERASE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_R_CONFIG_READ_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_I_CONFIG_WRITE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_I_CONFIG_READ_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_PING_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_R_MEM_DATA_WRITE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_R_MEM_DATA_READ_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_R_MEM_DATA_ERASE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_RANDOM_VALUE_GET_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_ECC_KEY_GENERATE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_ECC_KEY_STORE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_ECC_KEY_READ_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_ECC_KEY_ERASE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_ECDSA_SIGN_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_EDDSA_SIGN_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_MCOUNTER_INIT_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_MCOUNTER_GET_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_MCOUNTER_UPDATE_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_MAC_AND_DESTROY_ADDR:
case CONFIGURATION_OBJECTS_CFG_UAP_SERIAL_CODE_GET_ADDR:
valid = true;
}
return valid;
}

lt_ret_t lt_i_config_write(lt_handle_t *h, const enum CONFIGURATION_OBJECTS_REGS addr, const uint8_t bit_index)
{
if( !h
Expand Down Expand Up @@ -898,7 +904,7 @@ lt_ret_t lt_r_mem_data_write(lt_handle_t *h, const uint16_t udata_slot, uint8_t
}

// Check incomming l3 length
if(1 != (p_l3_res->res_size)) {
if(LT_L3_R_MEM_DATA_WRITE_RES_SIZE != (p_l3_res->res_size)) {
return LT_FAIL;
}

Expand Down Expand Up @@ -1004,7 +1010,7 @@ lt_ret_t lt_random_get(lt_handle_t *h, uint8_t *buff, const uint16_t len)
}

// Check incomming l3 length
if(LT_L3_RANDOM_VALUE_GET_RES_SIZE_MIN + len != (p_l3_res->res_size - 3)) {
if(LT_L3_RANDOM_VALUE_GET_RES_SIZE_MIN + len != (p_l3_res->res_size)) {
return LT_FAIL;
}

Expand Down Expand Up @@ -1251,7 +1257,7 @@ lt_ret_t lt_ecc_eddsa_sign(lt_handle_t *h, const ecc_slot_t slot, const uint8_t
struct lt_l3_eddsa_sign_res_t* p_l3_res = (struct lt_l3_eddsa_sign_res_t*)&h->l3_buff;

// Fill l3 buffer
p_l3_cmd->cmd_size = LT_L3_EDDSA_SIGN_CMD_SIZE_MIN + msg_len;
p_l3_cmd->cmd_size = LT_L3_EDDSA_SIGN_CMD_SIZE_MIN + msg_len - 1; // -1 Because the LT_L3_EDDSA_SIGN_CMD_SIZE_MIN already includes minimal message size 1B
p_l3_cmd->cmd_id = LT_L3_EDDSA_SIGN_CMD_ID;
p_l3_cmd->slot = slot;
memcpy(p_l3_cmd->msg, msg, msg_len);
Expand Down
8 changes: 4 additions & 4 deletions src/lt_l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ lt_ret_t lt_l2_encrypted_cmd(lt_handle_t *h)

struct lt_l3_gen_frame_t * p_frame = (struct lt_l3_gen_frame_t*)h->l3_buff;
// Calculate number of chunks to send. At least one chunk needs to be sent, therefore + 1
uint16_t chunk_num = ((L3_RES_SIZE_SIZE + p_frame->cmd_size + L3_TAG_SIZE) / L2_CHUNK_MAX_DATA_SIZE) + 1;
uint16_t chunk_num = ((L3_CMD_SIZE_SIZE + p_frame->cmd_size + L3_TAG_SIZE) / L2_CHUNK_MAX_DATA_SIZE) + 1;
// Calculate the length of the last
uint16_t chunk_last_len = ((L3_RES_SIZE_SIZE + p_frame->cmd_size + L3_TAG_SIZE) % L2_CHUNK_MAX_DATA_SIZE);

Expand All @@ -110,7 +110,7 @@ lt_ret_t lt_l2_encrypted_cmd(lt_handle_t *h)
} else {
req->req_len = L2_CHUNK_MAX_DATA_SIZE;
}
memcpy(req->cmd_ciphertext, (uint8_t*)&h->l3_buff + i*L2_CHUNK_MAX_DATA_SIZE, req->req_len);
memcpy(req->l3_chunk, (uint8_t*)&h->l3_buff + i*L2_CHUNK_MAX_DATA_SIZE, req->req_len);

add_crc(req);

Expand Down Expand Up @@ -156,13 +156,13 @@ lt_ret_t lt_l2_encrypted_cmd(lt_handle_t *h)
switch (ret) {
case LT_L2_RES_CONT:
// Copy content of l2 into certain offset of l3 buffer
memcpy((uint8_t*)&h->l3_buff + offset, (struct l2_encrypted_rsp_t*)resp->res_ciphertext, resp->rsp_len);
memcpy((uint8_t*)&h->l3_buff + offset, (struct l2_encrypted_rsp_t*)resp->l3_chunk, resp->rsp_len);
offset += resp->rsp_len;
loops++;
break;
case LT_OK:
// This was last l2 frame of l3 packet, copy it and return
memcpy((uint8_t*)&h->l3_buff + offset, (struct l2_encrypted_rsp_t*)resp->res_ciphertext, resp->rsp_len);
memcpy((uint8_t*)&h->l3_buff + offset, (struct l2_encrypted_rsp_t*)resp->l3_chunk, resp->rsp_len);
return LT_OK;
default:
// Any other L2 packet's status is not expected
Expand Down
30 changes: 4 additions & 26 deletions src/lt_l2_api_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,21 +166,8 @@ struct lt_l2_handshake_rsp_t {
struct lt_l2_encrypted_cmd_req_t {
u8 req_id; /**< Request ID byte */
u8 req_len; /**< Length byte */
/**
* @brief
* The size of the CMD_CIPHERTEXT L3 Field in bytes.
*/
u16 cmd_size; /**< L3 Command size. */
/**
* @brief
* An encrypted L3 Command.
*/
u8 cmd_ciphertext[4096]; /**< L3 Command. */
/**
* @brief
* The L3 Command Authentication Tag.
*/
u8 cmd_tag[16]; /**< Authentication Tag. */
/** Contains a chunk of encrypted command */
uint8_t l3_chunk[255];
u8 crc[2]; /**< Checksum */
} __attribute__((__packed__));

Expand All @@ -196,17 +183,8 @@ struct lt_l2_encrypted_cmd_rsp_t {
* @brief
* The size of the RES_CIPHERTEXT L3 Field in bytes.
*/
u16 res_size; /**< L3 Result size. */
/**
* @brief
* An encrypted L3 Result.
*/
u8 res_ciphertext[4096]; /**< L3 Result */
/**
* @brief
* The L3 Result Authentication Tag.
*/
u8 res_tag[16]; /**< Authentication tag. */
/** Contains a chunk of encrypted command */
uint8_t l3_chunk[255];
u8 crc[2]; /**< Checksum */
} __attribute__((__packed__));

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_libtropic__lt_cert_verify_and_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

void setUp(void)
{
char buffer[100];
char buffer[100] = {0};
#ifdef RNG_SEED
srand(RNG_SEED);
#else
Expand Down
13 changes: 4 additions & 9 deletions tests/unit/test_libtropic__lt_deinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

void setUp(void)
{
char buffer[100];
char buffer[100] = {0};
#ifdef RNG_SEED
srand(RNG_SEED);
#else
Expand All @@ -54,8 +54,7 @@ void tearDown(void)
// Test if function returns LT_PARAM_ERR on invalid handle
void test__invalid_handle()
{
int ret = lt_deinit(NULL);
TEST_ASSERT_EQUAL(LT_PARAM_ERR, ret);
TEST_ASSERT_EQUAL(LT_PARAM_ERR, lt_deinit(NULL));
}

//---------------------------------------------------------------------------------------------------------//
Expand All @@ -68,9 +67,7 @@ void test__lt_l1_deinit_fail()
lt_handle_t h = {0};

lt_l1_deinit_ExpectAndReturn(&h, LT_FAIL);

lt_ret_t ret = lt_deinit(&h);
TEST_ASSERT_EQUAL(LT_FAIL, ret);
TEST_ASSERT_EQUAL(LT_FAIL, lt_deinit(&h));
}

//---------------------------------------------------------------------------------------------------------//
Expand All @@ -81,7 +78,5 @@ void test__correct()
lt_handle_t h = {0};

lt_l1_deinit_ExpectAndReturn(&h, LT_OK);

lt_ret_t ret = lt_deinit(&h);
TEST_ASSERT_EQUAL(LT_OK, ret);
TEST_ASSERT_EQUAL(LT_OK, lt_deinit(&h));
}
Loading

0 comments on commit 83fe88d

Please sign in to comment.