Merge pull request #9215 from offirko/offir_bootloader_get-device-key

Direct access to device key
pull/9302/head
Cruz Monrreal 2019-01-10 00:14:14 -06:00 committed by GitHub
commit d6c014c20d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 681 additions and 0 deletions

View File

@ -0,0 +1,336 @@
/* Copyright (c) 2018 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef COMPONENT_FLASHIAP
#error [NOT_SUPPORTED] Target must have internal FlashIAP for this test
#endif
#include "mbed.h"
#include <stdio.h>
#include <string.h>
#include "DeviceKey.h"
#include "KVStore.h"
#include "KVMap.h"
#include "kv_config.h"
#include "TDBStore.h"
#include "FlashIAP.h"
#include "FlashIAPBlockDevice.h"
#include "DirectAccessDevicekey.h"
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"
#include <stdlib.h>
using namespace utest::v1;
using namespace mbed;
#define TEST_DEVICEKEY_LENGTH 32
static inline uint32_t align_up(uint64_t val, uint64_t size)
{
return (((val - 1) / size) + 1) * size;
}
static inline uint32_t align_down(uint64_t val, uint64_t size)
{
return (((val) / size)) * size;
}
int get_virtual_TDBStore_position(uint32_t conf_start_address, uint32_t conf_size, bool is_conf_tdb_internal,
uint32_t *tdb_start_address, uint32_t *tdb_end_address)
{
uint32_t bd_final_size = conf_size;;
uint32_t flash_end_address;
uint32_t flash_start_address;
uint32_t aligned_start_address;
FlashIAP flash;
int ret = flash.init();
if (ret != 0) {
return -1;
}
uint32_t flash_first_writable_sector_address = (uint32_t)(align_up(FLASHIAP_APP_ROM_END_ADDR,
flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR)));
//Get flash parameters before starting
flash_start_address = flash.get_flash_start();
flash_end_address = flash_start_address + flash.get_flash_size();
bool request_default = false;
if (conf_start_address == 0 && conf_size == 0) {
request_default = true;
}
if (!request_default) {
if (conf_start_address == 0) {
conf_start_address = flash_end_address - conf_size;
}
aligned_start_address = align_down(conf_start_address, flash.get_sector_size(conf_start_address));
if (conf_size == 0) {
bd_final_size = (flash_end_address - aligned_start_address);
}
if ((conf_size == 0) || (conf_start_address == 0)) {
if (aligned_start_address < flash_first_writable_sector_address) {
flash.deinit();
return -2;
}
}
} else {
if (is_conf_tdb_internal == true) {
aligned_start_address = flash_first_writable_sector_address;
bd_size_t spare_size_for_app = 0;
bd_addr_t curr_addr = aligned_start_address;
int spare_sectors_for_app = 2;
int min_sectors_for_storage = 2;
for (int i = 0; i < spare_sectors_for_app + min_sectors_for_storage - 1; i++) {
bd_size_t sector_size = flash.get_sector_size(curr_addr);
curr_addr += sector_size;
if (curr_addr >= flash_end_address) {
spare_size_for_app = 0;
break;
}
if (i < spare_sectors_for_app) {
spare_size_for_app += sector_size;
}
}
aligned_start_address += spare_size_for_app;
bd_final_size = (flash_end_address - aligned_start_address);
} else {
aligned_start_address = flash_end_address - (flash.get_sector_size(flash_end_address - 1) * 2);
if (aligned_start_address < flash_first_writable_sector_address) {
flash.deinit();
return -2;
}
bd_final_size = (flash_end_address - aligned_start_address);
}
}
(*tdb_start_address) = aligned_start_address;
(*tdb_end_address) = aligned_start_address + bd_final_size;
flash.deinit();
return 0;
}
void test_direct_access_to_devicekey_tdb_flashiap_remainder()
{
utest_printf("Test Direct Access To DeviceKey Test Entire FlashIAP Remainder\n");
uint32_t flash_bd_start_address;
uint32_t flash_bd_end_address;
int err = get_virtual_TDBStore_position(0, 0, true, &flash_bd_start_address, &flash_bd_end_address);
TEST_SKIP_UNLESS_MESSAGE(err != -2, "Test skipped. Not enough available space on Internal FlashIAP");
TEST_ASSERT_EQUAL(0, err);
uint32_t flash_bd_size = flash_bd_end_address - flash_bd_start_address;
FlashIAPBlockDevice *flash_bd = new FlashIAPBlockDevice((bd_addr_t)flash_bd_start_address, (bd_size_t)flash_bd_size);
TEST_ASSERT_NOT_EQUAL(NULL, flash_bd);
TDBStore *tdb = new TDBStore(flash_bd);
TEST_ASSERT_NOT_EQUAL(NULL, tdb);
// Start by Init and Reset to TDBStore
err = tdb->init();
TEST_ASSERT_EQUAL_ERROR_CODE(0, err);
err = tdb->reset();
TEST_ASSERT_EQUAL_ERROR_CODE(0, err);
// Assign a dummy DeviceKey, and set via tdb
uint8_t device_key_in[TEST_DEVICEKEY_LENGTH] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
err = tdb->reserved_data_set(device_key_in, TEST_DEVICEKEY_LENGTH);
TEST_ASSERT_EQUAL_ERROR_CODE(0, err);
err = tdb->deinit();
TEST_ASSERT_EQUAL(0, err);
delete tdb;
delete flash_bd;
// Now use Direct Access To DeviceKey to retrieve it
uint8_t device_key_out[TEST_DEVICEKEY_LENGTH] = {0};
size_t actual_data_size = 0;
err = direct_access_to_devicekey((uint32_t)flash_bd_start_address, (uint32_t)flash_bd_end_address, device_key_out,
TEST_DEVICEKEY_LENGTH,
&actual_data_size);
TEST_ASSERT_EQUAL_ERROR_CODE(0, err);
// Assert DeviceKey value and length
TEST_ASSERT_EQUAL(actual_data_size, TEST_DEVICEKEY_LENGTH);
for (int i_ind = 0; i_ind < TEST_DEVICEKEY_LENGTH; i_ind++) {
TEST_ASSERT_EQUAL(device_key_in[i_ind], device_key_out[i_ind]);
}
}
void test_direct_access_to_devicekey_tdb_last_two_sectors()
{
utest_printf("Test Direct Access To DeviceKey Test Entire FlashIAP Remainder\n");
uint32_t flash_bd_start_address;
uint32_t flash_bd_end_address;
int err = get_virtual_TDBStore_position(0, 0, false, &flash_bd_start_address, &flash_bd_end_address);
TEST_SKIP_UNLESS_MESSAGE(err != -2, "Test skipped. Not enough available space on Internal FlashIAP");
TEST_ASSERT_EQUAL(0, err);
uint32_t flash_bd_size = flash_bd_end_address - flash_bd_start_address;
FlashIAPBlockDevice *flash_bd = new FlashIAPBlockDevice((bd_addr_t)flash_bd_start_address, (bd_size_t)flash_bd_size);
TDBStore *tdb = new TDBStore(flash_bd);
// Start by Init and Reset to TDBStore
err = tdb->init();
TEST_ASSERT_EQUAL_ERROR_CODE(0, err);
err = tdb->reset();
TEST_ASSERT_EQUAL_ERROR_CODE(0, err);
// Assign a dummy DeviceKey, and set via tdb
uint8_t device_key_in[TEST_DEVICEKEY_LENGTH] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
err = tdb->reserved_data_set(device_key_in, TEST_DEVICEKEY_LENGTH);
TEST_ASSERT_EQUAL_ERROR_CODE(0, err);
err = tdb->deinit();
TEST_ASSERT_EQUAL(0, err);
delete tdb;
delete flash_bd;
// Now use Direct Access To DeviceKey to retrieve it
uint8_t device_key_out[TEST_DEVICEKEY_LENGTH] = {0};
size_t actual_data_size = 0;
err = direct_access_to_devicekey((uint32_t)flash_bd_start_address, (uint32_t)flash_bd_end_address, device_key_out,
TEST_DEVICEKEY_LENGTH,
&actual_data_size);
TEST_ASSERT_EQUAL_ERROR_CODE(0, err);
// Assert DeviceKey value and length
TEST_ASSERT_EQUAL(TEST_DEVICEKEY_LENGTH, actual_data_size);
for (int i_ind = 0; i_ind < TEST_DEVICEKEY_LENGTH; i_ind++) {
TEST_ASSERT_EQUAL(device_key_in[i_ind], device_key_out[i_ind]);
}
}
#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)
void test_direct_access_to_device_inject_root()
{
kv_init_storage_config();
DeviceKey &devkey = DeviceKey::get_instance();
uint32_t rkey[DEVICE_KEY_16BYTE / sizeof(uint32_t)];
uint32_t key[DEVICE_KEY_16BYTE / sizeof(uint32_t)];
KVMap &kv_map = KVMap::get_instance();
KVStore *inner_store = kv_map.get_internal_kv_instance(NULL);
TEST_ASSERT_NOT_EQUAL(NULL, inner_store);
BlockDevice *flash_bd = kv_map.get_internal_blockdevice_instance("");
TEST_ASSERT_NOT_EQUAL(NULL, flash_bd);
int ret = inner_store->reset();
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);
memcpy(key, "abcdefghabcdefgh", sizeof(key));
ret = devkey.device_inject_root_of_trust(key, DEVICE_KEY_16BYTE);
TEST_ASSERT_EQUAL_INT(DEVICEKEY_SUCCESS, ret);
// Now use Direct Access To DeviceKey to retrieve it */
uint32_t internal_start_address;
uint32_t internal_rbp_size;
bool is_conf_tdb_internal = false;
if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "FILESYSTEM") == 0) {
internal_start_address = MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS;
internal_rbp_size = MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE;
} else if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_EXTERNAL") == 0) {
internal_start_address = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS;
internal_rbp_size = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE;
} else if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_INTERNAL") == 0) {
internal_start_address = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS;
internal_rbp_size = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE;
is_conf_tdb_internal = true;
} else {
TEST_SKIP_UNLESS_MESSAGE(false, "Test skipped. No KVStore Internal");
}
uint32_t tdb_st_add = 0;
uint32_t tdb_end_add = 0;
ret = get_virtual_TDBStore_position(internal_start_address, internal_rbp_size, is_conf_tdb_internal, &tdb_st_add, &tdb_end_add);
TEST_SKIP_UNLESS_MESSAGE(ret != -2, "Test skipped. Not enough available space on Internal FlashIAP");
TEST_ASSERT_EQUAL(0, ret);
uint32_t expected_tdb_st_add = 0;
uint32_t expected_tdb_end_add = 0;
ret = get_expected_internal_TDBStore_position(&expected_tdb_st_add, &expected_tdb_end_add);
if (ret == MBED_SUCCESS) {
TEST_ASSERT_EQUAL(expected_tdb_st_add, tdb_st_add);
TEST_ASSERT_EQUAL(expected_tdb_end_add, tdb_end_add);
}
memset(rkey, 0, sizeof(rkey));
size_t actual_data_size = 0;
ret = ((TDBStore *)inner_store)->reserved_data_get(rkey, DEVICE_KEY_16BYTE, &actual_data_size);
TEST_ASSERT_EQUAL_ERROR_CODE(0, ret);
TEST_ASSERT_EQUAL(actual_data_size, DEVICE_KEY_16BYTE);
TEST_ASSERT_EQUAL_INT32_ARRAY(key, rkey, DEVICE_KEY_16BYTE / sizeof(uint32_t));
memset(rkey, 0, sizeof(rkey));
actual_data_size = 0;
ret = direct_access_to_devicekey(tdb_st_add, tdb_end_add, rkey, DEVICE_KEY_16BYTE, &actual_data_size);
TEST_ASSERT_EQUAL_ERROR_CODE(0, ret);
/* Assert DeviceKey value and length */
TEST_ASSERT_EQUAL(actual_data_size, DEVICE_KEY_16BYTE);
TEST_ASSERT_EQUAL_INT32_ARRAY(key, rkey, DEVICE_KEY_16BYTE / sizeof(uint32_t));
ret = inner_store->deinit();
TEST_ASSERT_EQUAL_ERROR_CODE(0, ret);
}
// Test setup
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
{
greentea_case_failure_abort_handler(source, reason);
return STATUS_CONTINUE;
}
Case cases[] = {
Case("Testing direct access to devicekey with tdb over flashiap remainder", test_direct_access_to_devicekey_tdb_flashiap_remainder, greentea_failure_handler),
Case("Testing direct access to devicekey with tdb over last two sectors", test_direct_access_to_devicekey_tdb_last_two_sectors, greentea_failure_handler),
Case("Testing direct access to injected devicekey ", test_direct_access_to_device_inject_root, greentea_failure_handler),
};
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(120, "default_auto");
return greentea_test_setup_handler(number_of_cases);
}
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
int main()
{
return !Harness::run(specification);
}

View File

@ -0,0 +1,283 @@
/*
* Copyright (c) 2018 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// ----------------------------------------------------------- Includes -----------------------------------------------------------
#if DEVICE_FLASH
#include "DirectAccessDevicekey.h"
#include <string.h>
#include <stdio.h>
#include "mbed_error.h"
#include "MbedCRC.h"
#include "mbed_trace.h"
#define TRACE_GROUP "DADK"
using namespace mbed;
// --------------------------------------------------------- Definitions ----------------------------------------------------------
typedef struct {
uint32_t address;
size_t size;
} tdbstore_area_data_t;
typedef struct {
uint16_t trailer_size;
uint16_t data_size;
uint32_t crc;
} reserved_trailer_t;
#define TDBSTORE_NUMBER_OF_AREAS 2
#define MAX_DEVICEKEY_DATA_SIZE 64
#define RESERVED_AREA_SIZE (MAX_DEVICEKEY_DATA_SIZE+sizeof(reserved_trailer_t)) /* DeviceKey Max Data size + metadata trailer */
#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)
// -------------------------------------------------- Local Functions Declaration ----------------------------------------------------
static int calc_area_params(FlashIAP *flash, uint32_t out_tdb_start_offset, uint32_t tdb_end_offset,
tdbstore_area_data_t *area_params);
static int reserved_data_get(FlashIAP *flash, tdbstore_area_data_t *area_params, void *reserved_data_buf,
size_t reserved_data_buf_size, size_t *actual_data_size_ptr);
static inline uint32_t align_up(uint64_t val, uint64_t size);
static inline uint32_t align_down(uint64_t val, uint64_t size);
static uint32_t calc_crc(uint32_t init_crc, uint32_t data_size, const void *data_buf);
// -------------------------------------------------- API Functions Implementation ----------------------------------------------------
int direct_access_to_devicekey(uint32_t tdb_start_offset, uint32_t tdb_end_offset, void *data_buf,
size_t data_buf_size, size_t *actual_data_size_ptr)
{
int status = MBED_ERROR_INVALID_ARGUMENT;
FlashIAP flash;
uint8_t active_area = 0;
tdbstore_area_data_t area_params[TDBSTORE_NUMBER_OF_AREAS];
memset(area_params, 0, sizeof(area_params));
bool is_flash_init = false;
if (NULL == data_buf) {
tr_error("Invalid Data Buf Argument");
goto exit_point;
}
status = flash.init();
if (status != 0) {
tr_error("FlashIAP init failed - err: %d", status);
status = MBED_ERROR_FAILED_OPERATION;
goto exit_point;
}
is_flash_init = true;
status = calc_area_params(&flash, tdb_start_offset, tdb_end_offset, area_params);
if (status != MBED_SUCCESS) {
tr_error("Couldn't calulate Area Params - err: %d", status);
goto exit_point;
}
/* DeviceKey data can be found either in first or second Flash Area */
/* Loop through Areas to find valid DeviceKey data */
for (active_area = 0; active_area < TDBSTORE_NUMBER_OF_AREAS; active_area++) {
status = reserved_data_get(&flash, &area_params[active_area], data_buf, data_buf_size, actual_data_size_ptr);
if (status == MBED_SUCCESS) {
break;
}
}
if (status != MBED_SUCCESS) {
status = MBED_ERROR_ITEM_NOT_FOUND;
tr_error("Couldn't find valid DeviceKey - err: %d", status);
}
exit_point:
if (true == is_flash_init) {
flash.deinit();
}
return status;
}
int get_expected_internal_TDBStore_position(uint32_t *out_tdb_start_offset, uint32_t *out_tdb_end_offset)
{
uint32_t flash_end_address;
uint32_t flash_start_address;
uint32_t aligned_start_address;
uint32_t aligned_end_address;
FlashIAP flash;
bool is_default_configuration = false;
uint32_t tdb_size;
if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "FILESYSTEM") == 0) {
*out_tdb_start_offset = MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS;
tdb_size = MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE;
} else if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_EXTERNAL") == 0) {
*out_tdb_start_offset = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS;
tdb_size = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE;
} else {
return MBED_ERROR_UNSUPPORTED;
}
*out_tdb_end_offset = (*out_tdb_start_offset) + tdb_size;
if ((*out_tdb_start_offset == 0) && (tdb_size == 0)) {
is_default_configuration = true;
} else if ((*out_tdb_start_offset == 0) || (tdb_size == 0)) {
return MBED_ERROR_UNSUPPORTED;
}
int ret = flash.init();
if (ret != 0) {
return MBED_ERROR_FAILED_OPERATION;
}
uint32_t flash_first_writable_sector_address = (uint32_t)(align_up(FLASHIAP_APP_ROM_END_ADDR,
flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR)));
//Get flash parameters before starting
flash_start_address = flash.get_flash_start();
flash_end_address = flash_start_address + flash.get_flash_size();
if (!is_default_configuration) {
aligned_start_address = align_down(*out_tdb_start_offset, flash.get_sector_size(*out_tdb_start_offset));
aligned_end_address = align_up(*out_tdb_end_offset, flash.get_sector_size(*out_tdb_end_offset - 1));
if ((*out_tdb_start_offset != aligned_start_address) || (*out_tdb_end_offset != aligned_end_address)
|| (*out_tdb_end_offset > flash_end_address)) {
flash.deinit();
return MBED_ERROR_INVALID_OPERATION;
}
} else {
aligned_start_address = flash_end_address - (flash.get_sector_size(flash_end_address - 1) * 2);
if (aligned_start_address < flash_first_writable_sector_address) {
flash.deinit();
return MBED_ERROR_INVALID_OPERATION;
}
*out_tdb_start_offset = aligned_start_address;
*out_tdb_end_offset = flash_end_address;
}
flash.deinit();
return MBED_SUCCESS;
}
// -------------------------------------------------- Local Functions Implementation ----------------------------------------------------
static int calc_area_params(FlashIAP *flash, uint32_t out_tdb_start_offset, uint32_t tdb_end_offset,
tdbstore_area_data_t *area_params)
{
uint32_t bd_size = 0;
uint32_t initial_erase_size = flash->get_sector_size(out_tdb_start_offset);
uint32_t erase_unit_size = initial_erase_size;
size_t cur_area_size = 0;
if ((tdb_end_offset < (out_tdb_start_offset + 2 * RESERVED_AREA_SIZE - 1)) ||
(tdb_end_offset > (flash->get_flash_start() + flash->get_flash_size()))) {
tr_error("calc_area_params failed - Invalid input addresses");
return MBED_ERROR_INVALID_ARGUMENT;
}
// Entire TDBStore can't exceed 32 bits
bd_size = (tdb_end_offset - out_tdb_start_offset + 1);
while (cur_area_size < bd_size / 2) {
erase_unit_size = flash->get_sector_size(out_tdb_start_offset + cur_area_size);
cur_area_size += erase_unit_size;
}
area_params[0].address = out_tdb_start_offset;
area_params[0].size = cur_area_size;
area_params[1].address = out_tdb_start_offset + cur_area_size;
area_params[1].size = bd_size - cur_area_size;
return MBED_SUCCESS;
}
static int reserved_data_get(FlashIAP *flash, tdbstore_area_data_t *area_params, void *reserved_data_buf,
size_t reserved_data_buf_size, size_t *actual_data_size_ptr)
{
int status = MBED_SUCCESS;
reserved_trailer_t trailer;
uint8_t *buf;
int ret = MBED_SUCCESS;
bool erased = true;
size_t actual_size = 0;
uint32_t initial_crc = 0xFFFFFFFF;
uint32_t crc = initial_crc;
uint8_t blank = flash->get_erase_value();
/* Read Into trailer deviceKey metadata */
ret = flash->read(&trailer, area_params->address + MAX_DEVICEKEY_DATA_SIZE, sizeof(trailer));
if (ret != MBED_SUCCESS) {
status = MBED_ERROR_READ_FAILED;
goto exit_point;
}
buf = reinterpret_cast <uint8_t *>(&trailer);
for (uint32_t i = 0; i < sizeof(trailer); i++) {
if (buf[i] != blank) {
erased = false;
break;
}
}
if (true == erased) {
/* Metadata is erased , DeviceKey Data is NOT in this Area */
status = MBED_ERROR_ITEM_NOT_FOUND;
goto exit_point;
}
actual_size = trailer.data_size;
if (actual_data_size_ptr != NULL) {
*actual_data_size_ptr = actual_size;
}
if (reserved_data_buf_size < actual_size) {
status = MBED_ERROR_INVALID_SIZE;
goto exit_point;
}
buf = reinterpret_cast <uint8_t *>(reserved_data_buf);
/* Read DeviceKey Data */
ret = flash->read(buf, area_params->address, (uint32_t)actual_size);
if (ret != MBED_SUCCESS) {
status = MBED_ERROR_READ_FAILED;
goto exit_point;
}
crc = calc_crc(crc, (uint32_t)actual_size, buf);
if (crc != trailer.crc) {
status = MBED_ERROR_INVALID_DATA_DETECTED;
}
exit_point:
return status;
}
static inline uint32_t align_up(uint64_t val, uint64_t size)
{
return (((val - 1) / size) + 1) * size;
}
static inline uint32_t align_down(uint64_t val, uint64_t size)
{
return (((val) / size)) * size;
}
static uint32_t calc_crc(uint32_t init_crc, uint32_t data_size, const void *data_buf)
{
uint32_t crc;
MbedCRC<POLY_32BIT_ANSI, 32> ct(init_crc, 0x0, true, false);
ct.compute(const_cast<void *>(data_buf), data_size, &crc);
return crc;
}
#endif // DEVICE_FLASH

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2018 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_DIRECT_ACCESS_DEVICEKEY_H
#define MBED_DIRECT_ACCESS_DEVICEKEY_H
#include "FlashIAP.h"
#include <stdio.h>
/**
* @brief Returns devicekey directly from internal FlashIAP by given tdb internal position
*
* @param[in] tdb_start_offset FlashIAP Start address offset of tdb store
* @param[in] tdb_end_offset FlashIAP End address offset of tdb store
* @param[in] data_buf Buffer to store devicekey data
* @param[in] data_buf_size Max expected size of buffer to store the devicekey data
* @param[out] actual_data_size_ptr Actual retrieved devicekey size
*
* @returns MBED_ERROR_INVALID_ARGUMENT Illegal argument given
* MBED_ERROR_INVALID_SIZE data_buf_size is too small for retrieving actual data size
* MBED_ERROR_INVALID_DATA_DETECTED devicekey data invalid crc
* MBED_ERROR_ITEM_NOT_FOUND devicekey data not found
* MBED_ERROR_FAILED_OPERATION internal flash failure
* MBED_ERROR_READ_FAILED internal flash read failed
* MBED_SUCCESS successful
*/
int direct_access_to_devicekey(uint32_t tdb_start_offset, uint32_t tdb_end_offset, void *data_buf,
size_t data_buf_size, size_t *actual_data_size_ptr);
/**
* @brief Returns the expected tdb internal position.
* Limitations:
* 1. supporting FILESYSTEM or TDB_EXTERNAL configuration only
* 2. supporting either both start_address and size are explicitly given (different than zero)
* or both of them are zero (default configuration)
*
* @param[out] out_tdb_start_offset Expected FlashIAP Start address offset of tdb store
* @param[out] out_tdb_end_offset Expected FlashIAP End address offset of tdb store
*
* @returns MBED_ERROR_FAILED_OPERATION internal flash failure
* MBED_ERROR_UNSUPPORTED kvstore configuration different than FILESYSTEM or TDB_EXTERNAL
* or start_address or size are different than 0 and the other isn't
* MBED_ERROR_INVALID_OPERATION tdb_start_offset or tdb_end_offset are not aligned or lower
* than end of code segment (when using default configuration)
* MBED_SUCCESS successful
*
*/
int get_expected_internal_TDBStore_position(uint32_t *out_tdb_start_offset, uint32_t *out_tdb_end_offset);
#endif /* MBED_DIRECT_ACCESS_DEVICEKEY_H */