mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #12385 from tymoteuszblochmobica/rot
DeviceKey Root of Trust generation refactored.pull/12520/head
						commit
						67e950296d
					
				| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @}*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue