Skip to content

DeviceKey Root of Trust generation refactored. #12385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions TESTS/psa/its_ps/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
#include "KVStore.h"
#include "kv_config.h"
#include "psa_storage_common_impl.h"
#include "DeviceKey.h"

using namespace utest::v1;
using namespace mbed;

#define TEST_BUFF_SIZE 16
#define STR_EXPAND(tok) #tok
Expand Down Expand Up @@ -217,6 +219,9 @@ utest::v1::status_t case_its_setup_handler(const Case *const source, const size_
status = psa_ps_reset();
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
}
#if DEVICEKEY_ENABLED
DeviceKey::get_instance().generate_root_of_trust();
#endif
return greentea_case_setup_handler(source, index_of_case);
}

Expand Down
35 changes: 28 additions & 7 deletions features/device_key/TESTS/device_key/functionality/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ void generate_derived_key_consistency_16_byte_key_long_consistency_test(char *ke
int ret = inner_store->reset();
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

ret = inject_dummy_rot_key();
ret = DeviceKey::get_instance().generate_root_of_trust();
if (ret != DEVICEKEY_SUCCESS) {
ret = inject_dummy_rot_key();
}
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

memset(output1, 0, sizeof(output1));
Expand Down Expand Up @@ -165,7 +168,10 @@ void generate_derived_key_consistency_32_byte_key_long_consistency_test(char *ke
int ret = inner_store->reset();
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

ret = inject_dummy_rot_key();
ret = DeviceKey::get_instance().generate_root_of_trust();
if (ret != DEVICEKEY_SUCCESS) {
ret = inject_dummy_rot_key();
}
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

memset(output1, 0, sizeof(output1));
Expand Down Expand Up @@ -318,7 +324,10 @@ void generate_derived_key_consistency_16_byte_key_test()
int ret = inner_store->reset();
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

ret = inject_dummy_rot_key();
ret = DeviceKey::get_instance().generate_root_of_trust();
if (ret != DEVICEKEY_SUCCESS) {
ret = inject_dummy_rot_key();
}
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

size_t salt_size = sizeof(salt);
Expand Down Expand Up @@ -355,7 +364,10 @@ void generate_derived_key_consistency_32_byte_key_test()
int ret = inner_store->reset();
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

ret = inject_dummy_rot_key();
ret = DeviceKey::get_instance().generate_root_of_trust();
if (ret != DEVICEKEY_SUCCESS) {
ret = inject_dummy_rot_key();
}
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

size_t salt_size = sizeof(salt);
Expand Down Expand Up @@ -392,7 +404,10 @@ void generate_derived_key_key_type_16_test()
int ret = inner_store->reset();
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

ret = inject_dummy_rot_key();
ret = DeviceKey::get_instance().generate_root_of_trust();
if (ret != DEVICEKEY_SUCCESS) {
ret = inject_dummy_rot_key();
}
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

memset(output, 0, DEVICE_KEY_16BYTE * 2);
Expand Down Expand Up @@ -425,7 +440,10 @@ void generate_derived_key_key_type_32_test()
int ret = inner_store->reset();
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

ret = inject_dummy_rot_key();
ret = DeviceKey::get_instance().generate_root_of_trust();
if (ret != DEVICEKEY_SUCCESS) {
ret = inject_dummy_rot_key();
}
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

memset(output, 0, DEVICE_KEY_32BYTE * 2);
Expand Down Expand Up @@ -456,7 +474,10 @@ void generate_derived_key_wrong_key_type_test()
int ret = inner_store->reset();
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

ret = inject_dummy_rot_key();
ret = DeviceKey::get_instance().generate_root_of_trust();
if (ret != DEVICEKEY_SUCCESS) {
ret = inject_dummy_rot_key();
}
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);

memset(output, 0, DEVICE_KEY_16BYTE);
Expand Down
31 changes: 9 additions & 22 deletions features/device_key/source/DeviceKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,23 +94,10 @@ int DeviceKey::generate_derived_key(const unsigned char *salt, size_t isalt_size

//First try to read the key from KVStore
int ret = read_key_from_kvstore(key_buff, actual_size);
if (DEVICEKEY_SUCCESS != ret && DEVICEKEY_NOT_FOUND != ret) {
if (DEVICEKEY_SUCCESS != ret) {
return ret;
}

//If the key was not found in KVStore we will create it by using random generation and then save it to KVStore
if (DEVICEKEY_NOT_FOUND == ret) {
ret = generate_key_by_random(key_buff, actual_size);
if (DEVICEKEY_SUCCESS != ret) {
return ret;
}

ret = device_inject_root_of_trust(key_buff, actual_size);
if (DEVICEKEY_SUCCESS != ret) {
return ret;
}
}

ret = get_derived_key(key_buff, actual_size, salt, isalt_size, output, ikey_type);
return ret;
}
Expand Down Expand Up @@ -259,22 +246,22 @@ int DeviceKey::get_derived_key(uint32_t *ikey_buff, size_t ikey_size, const unsi
return DEVICEKEY_SUCCESS;
}

int DeviceKey::generate_key_by_random(uint32_t *output, size_t size)
int DeviceKey::generate_root_of_trust()
{
int ret = DEVICEKEY_GENERATE_RANDOM_ERROR;
uint32_t key_buff[DEVICE_KEY_32BYTE / sizeof(uint32_t)];
size_t actual_size = DEVICE_KEY_32BYTE;

if (DEVICE_KEY_16BYTE > size) {
return DEVICEKEY_BUFFER_TOO_SMALL;
} else if (DEVICE_KEY_16BYTE != size && DEVICE_KEY_32BYTE != size) {
return DEVICEKEY_INVALID_PARAM;
if (read_key_from_kvstore(key_buff, actual_size) == DEVICEKEY_SUCCESS) {
return DEVICEKEY_ALREADY_EXIST;
}

#if defined(DEVICE_TRNG) || defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
mbedtls_entropy_context *entropy = new mbedtls_entropy_context;
mbedtls_entropy_init(entropy);
memset(output, 0, size);
memset(key_buff, 0, actual_size);

ret = mbedtls_entropy_func(entropy, (unsigned char *)output, size);
ret = mbedtls_entropy_func(entropy, (unsigned char *)key_buff, actual_size);
if (ret != MBED_SUCCESS) {
ret = DEVICEKEY_GENERATE_RANDOM_ERROR;
} else {
Expand All @@ -283,7 +270,7 @@ int DeviceKey::generate_key_by_random(uint32_t *output, size_t size)

mbedtls_entropy_free(entropy);
delete entropy;

ret = device_inject_root_of_trust(key_buff, actual_size);
#endif

return ret;
Expand Down
21 changes: 10 additions & 11 deletions features/device_key/source/DeviceKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ class DeviceKey : private mbed::NonCopyable<DeviceKey> {
* @return 0 on success, negative error code on failure
*/
int device_inject_root_of_trust(uint32_t *value, size_t isize);
/** Generate Root of Trust.
* Uses TRNG or various other entropy sources to generate random device key and
* inject it into device's KVStore. Device Key can only be generated once.
*
* \return DEVICEKEY_SUCCESS, when device key successfully generated and injected.
* \return DEVICEKEY_ALREADY_EXIST, if the key has already been written.
* \return DEVICEKEY_GENERATE_RANDOM_ERROR if this device does not contain entropy sources and cannot generate a key.
* \return error codes on other failures.
*/
int generate_root_of_trust();

private:
// Private constructor, as class is a singleton
Expand Down Expand Up @@ -139,17 +149,6 @@ class DeviceKey : private mbed::NonCopyable<DeviceKey> {
int get_derived_key(uint32_t *ikey_buff, size_t ikey_size, const unsigned char *isalt, size_t isalt_size,
unsigned char *output, uint32_t ikey_type);

/** Generate a random ROT key by using entropy
* @param output Output buffer for the generated key.
* @param size Input: The size of the buffer. If size is less
* than 16 bytes, the method generates an
* error. 16-31 bytes creates a 16-byte key.
* 32 or higher generates a 32-byte key
* Output: The actual written size to the buffer
* @return 0 on success, negative error code on failure
*/
int generate_key_by_random(uint32_t *output, size_t size);

};

/** @}*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "unity/unity.h"
#include "utest/utest.h"
#include "FileSystemStore.h"
#include "DeviceKey.h"

using namespace utest::v1;
using namespace mbed;
Expand Down Expand Up @@ -901,7 +902,9 @@ int main()
total_num_cases++;
}
}

#if DEVICEKEY_ENABLED
DeviceKey::get_instance().generate_root_of_trust();
#endif
Specification specification(greentea_test_setup, cases, total_num_cases,
greentea_test_teardown_handler, default_handler);

Expand Down
4 changes: 4 additions & 0 deletions features/storage/TESTS/kvstore/general_tests_phase_2/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "unity/unity.h"
#include "utest/utest.h"
#include "FileSystemStore.h"
#include "DeviceKey.h"

using namespace utest::v1;
using namespace mbed;
Expand Down Expand Up @@ -884,6 +885,9 @@ int main()
}
}

#if DEVICEKEY_ENABLED
DeviceKey::get_instance().generate_root_of_trust();
#endif
Specification specification(greentea_test_setup, cases, total_num_cases,
greentea_test_teardown_handler, default_handler);

Expand Down
4 changes: 4 additions & 0 deletions features/storage/TESTS/kvstore/securestore_whitebox/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include "DeviceKey.h"

#if (!defined(TARGET_K64F) && !defined(TARGET_ARM_FM)) && !defined(TARGET_MCU_PSOC6) || !SECURESTORE_ENABLED
#error [NOT_SUPPORTED] Kvstore API tests run only on K64F devices, Fastmodels, and PSoC 6. KVStore & SecureStore need to be enabled for this test
Expand Down Expand Up @@ -145,6 +146,9 @@ static void white_box_test()
timer.reset();
result = sec_kv->reset();
TEST_ASSERT_EQUAL_ERROR_CODE(MBED_SUCCESS, result);
#if DEVICEKEY_ENABLED
DeviceKey::get_instance().generate_root_of_trust();
#endif
elapsed = timer.read_ms();
printf("Elapsed time for reset is %d ms\n", elapsed);

Expand Down
11 changes: 10 additions & 1 deletion features/storage/TESTS/kvstore/static_tests/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "unity/unity.h"
#include "utest/utest.h"
#include "kvstore_global_api.h"

#include "DeviceKey.h"
#include <cstring>

using namespace utest::v1;
Expand Down Expand Up @@ -85,6 +85,9 @@ static void kvstore_init()
init_res = kv_reset(def_kv);
TEST_SKIP_UNLESS_MESSAGE(init_res != MBED_ERROR_UNSUPPORTED, "Unsupported configuration. Test skipped.");
TEST_ASSERT_EQUAL_ERROR_CODE(MBED_SUCCESS, init_res);
#if DEVICEKEY_ENABLED
DeviceKey::get_instance().generate_root_of_trust();
#endif
}

/*----------------set()------------------*/
Expand Down Expand Up @@ -207,6 +210,9 @@ static void set_write_once_flag_try_remove()

res = kv_reset(def_kv);
TEST_ASSERT_EQUAL_ERROR_CODE(MBED_SUCCESS, res);
#if DEVICEKEY_ENABLED
DeviceKey::get_instance().generate_root_of_trust();
#endif
}

//set key value one byte size
Expand Down Expand Up @@ -622,6 +628,9 @@ static void get_info_existed_key()

res = kv_reset(def_kv);
TEST_ASSERT_EQUAL_ERROR_CODE(MBED_SUCCESS, res);
#if DEVICEKEY_ENABLED
DeviceKey::get_instance().generate_root_of_trust();
#endif
}

//get_info of overwritten key
Expand Down