Merge pull request #12385 from tymoteuszblochmobica/rot

DeviceKey Root of Trust generation refactored.
pull/12520/head
Martin Kojtal 2020-02-26 16:59:24 +00:00 committed by GitHub
commit 67e950296d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 74 additions and 42 deletions

View File

@ -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
@ -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);
}

View File

@ -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));
@ -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));
@ -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);
@ -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);
@ -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);
@ -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);
@ -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);

View File

@ -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;
}
@ -259,22 +246,22 @@ finish:
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 {
@ -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;

View File

@ -106,6 +106,16 @@ public:
* @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
@ -139,17 +149,6 @@ private:
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);
};
/** @}*/

View File

@ -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;
@ -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);

View File

@ -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;
@ -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);

View File

@ -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
@ -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);

View File

@ -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;
@ -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()------------------*/
@ -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
@ -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