Merge pull request #9708 from davidsaada/david_protected_storage

Implement PSA protected storage & restructure PSA storage implementation
pull/9666/head
Cruz Monrreal 2019-02-21 17:30:56 -06:00 committed by GitHub
commit 870bd05904
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 2131 additions and 1441 deletions

View File

@ -350,7 +350,7 @@ void test_crypto_key_handles(void)
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_destroy_key(key_handle));
key_handle = 0;
TEST_ASSERT_EQUAL(PSA_ERROR_EMPTY_SLOT, psa_open_key(PSA_KEY_LIFETIME_PERSISTENT, id, &key_handle));
TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, psa_open_key(PSA_KEY_LIFETIME_PERSISTENT, id, &key_handle));
}
void test_crypto_hash_clone(void)

View File

@ -70,7 +70,6 @@ void validate_entropy_seed_injection(int seed_length_a,
void run_entropy_inject_with_crypto_init()
{
psa_its_status_t its_status;
psa_status_t status;
status = psa_crypto_init();
TEST_ASSERT_EQUAL_INT(PSA_ERROR_INSUFFICIENT_ENTROPY, status);
@ -158,7 +157,7 @@ utest::v1::status_t case_teardown_handler(const Case *const source, const size_t
{
psa_status_t status;
status = mbed_psa_reboot_and_request_new_security_state(PSA_LIFECYCLE_ASSEMBLY_AND_TEST);
TEST_ASSERT_EQUAL(PSA_ITS_SUCCESS, status);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
mbedtls_psa_crypto_free();
return greentea_case_teardown_handler(source, passed, failed, reason);
}
@ -167,7 +166,7 @@ utest::v1::status_t case_setup_handler(const Case *const source, const size_t in
{
psa_status_t status;
status = mbed_psa_reboot_and_request_new_security_state(PSA_LIFECYCLE_ASSEMBLY_AND_TEST);
TEST_ASSERT_EQUAL(PSA_ITS_SUCCESS, status);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
return greentea_case_setup_handler(source, index_of_case);
}

View File

@ -1,146 +0,0 @@
/*
* 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 TARGET_PSA
#error [NOT_SUPPORTED] ITS tests can run only on PSA-enabled targets.
#endif // TARGET_PSA
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest/utest.h"
#include "psa/internal_trusted_storage.h"
#include "psa/lifecycle.h"
using namespace utest::v1;
#define TEST_BUFF_SIZE 16
static void pits_test()
{
psa_its_status_t status = PSA_ITS_SUCCESS;
uint8_t write_buff[TEST_BUFF_SIZE] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
uint8_t read_buff[TEST_BUFF_SIZE] = {0};
struct psa_its_info_t info = {0, PSA_ITS_FLAG_WRITE_ONCE};
memset(read_buff, 0, TEST_BUFF_SIZE);
status = psa_its_get_info(5, &info);
TEST_ASSERT_EQUAL(PSA_ITS_ERROR_UID_NOT_FOUND, status);
status = psa_its_set(5, TEST_BUFF_SIZE, write_buff, 0);
TEST_ASSERT_EQUAL(PSA_ITS_SUCCESS, status);
status = psa_its_get_info(5, &info);
TEST_ASSERT_EQUAL(PSA_ITS_SUCCESS, status);
TEST_ASSERT_EQUAL(TEST_BUFF_SIZE, info.size);
TEST_ASSERT_EQUAL(0, info.flags);
status = psa_its_get(5, 0, TEST_BUFF_SIZE, read_buff);
TEST_ASSERT_EQUAL(PSA_ITS_SUCCESS, status);
TEST_ASSERT_EQUAL_MEMORY(write_buff, read_buff, TEST_BUFF_SIZE);
memset(read_buff, 0, TEST_BUFF_SIZE);
status = psa_its_get(5, 1, TEST_BUFF_SIZE, read_buff);
TEST_ASSERT_NOT_EQUAL(PSA_ITS_SUCCESS, status);
status = psa_its_get(5, 1, TEST_BUFF_SIZE - 1, read_buff);
TEST_ASSERT_EQUAL(PSA_ITS_SUCCESS, status);
TEST_ASSERT_EQUAL_MEMORY(write_buff + 1, read_buff, TEST_BUFF_SIZE - 1);
status = psa_its_remove(5);
TEST_ASSERT_EQUAL(PSA_ITS_SUCCESS, status);
status = psa_its_get_info(5, &info);
TEST_ASSERT_EQUAL(PSA_ITS_ERROR_UID_NOT_FOUND, status);
}
static void pits_write_once_test()
{
psa_its_status_t status = PSA_ITS_SUCCESS;
uint8_t write_buff[TEST_BUFF_SIZE] = {0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
uint8_t read_buff[TEST_BUFF_SIZE] = {0};
struct psa_its_info_t info = {0, 0};
status = psa_its_get_info(5, &info);
TEST_ASSERT_EQUAL(PSA_ITS_ERROR_UID_NOT_FOUND, status);
status = psa_its_set(5, TEST_BUFF_SIZE, write_buff, PSA_ITS_FLAG_WRITE_ONCE);
TEST_ASSERT_EQUAL(PSA_ITS_SUCCESS, status);
info.size = 0;
info.flags = PSA_ITS_FLAG_NONE;
status = psa_its_get_info(5, &info);
TEST_ASSERT_EQUAL(PSA_ITS_SUCCESS, status);
TEST_ASSERT_EQUAL(TEST_BUFF_SIZE, info.size);
TEST_ASSERT_EQUAL(PSA_ITS_FLAG_WRITE_ONCE, info.flags);
status = psa_its_get(5, 0, TEST_BUFF_SIZE, read_buff);
TEST_ASSERT_EQUAL(PSA_ITS_SUCCESS, status);
TEST_ASSERT_EQUAL_MEMORY(write_buff, read_buff, TEST_BUFF_SIZE);
status = psa_its_set(5, TEST_BUFF_SIZE, write_buff, PSA_ITS_FLAG_WRITE_ONCE);
TEST_ASSERT_NOT_EQUAL(PSA_ITS_SUCCESS, status);
status = psa_its_set(5, TEST_BUFF_SIZE, write_buff, 0);
TEST_ASSERT_NOT_EQUAL(PSA_ITS_SUCCESS, status);
status = psa_its_remove(5);
TEST_ASSERT_NOT_EQUAL(PSA_ITS_SUCCESS, status);
info.size = 0;
info.flags = PSA_ITS_FLAG_NONE;
status = psa_its_get_info(5, &info);
TEST_ASSERT_EQUAL(PSA_ITS_SUCCESS, status);
TEST_ASSERT_EQUAL(TEST_BUFF_SIZE, info.size);
TEST_ASSERT_EQUAL(PSA_ITS_FLAG_WRITE_ONCE, info.flags);
}
utest::v1::status_t case_teardown_handler(const Case *const source, const size_t passed, const size_t failed, const failure_t reason)
{
psa_status_t status;
status = mbed_psa_reboot_and_request_new_security_state(PSA_LIFECYCLE_ASSEMBLY_AND_TEST);
TEST_ASSERT_EQUAL(PSA_LIFECYCLE_SUCCESS, status);
return greentea_case_teardown_handler(source, passed, failed, reason);
}
utest::v1::status_t case_setup_handler(const Case *const source, const size_t index_of_case)
{
psa_status_t status;
status = mbed_psa_reboot_and_request_new_security_state(PSA_LIFECYCLE_ASSEMBLY_AND_TEST);
TEST_ASSERT_EQUAL(PSA_LIFECYCLE_SUCCESS, status);
return greentea_case_setup_handler(source, index_of_case);
}
Case cases[] = {
Case("PSA prot internal storage - Basic", case_setup_handler, pits_test, case_teardown_handler),
Case("PSA prot internal storage - Write-once", case_setup_handler, pits_write_once_test, case_teardown_handler)
};
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
{
#ifndef NO_GREENTEA
GREENTEA_SETUP(60, "default_auto");
#endif
return greentea_test_setup_handler(number_of_cases);
}
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
int main()
{
return !Harness::run(specification);
}

198
TESTS/psa/its_ps/main.cpp Normal file
View File

@ -0,0 +1,198 @@
/*
* Copyright (c) 2019 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 TARGET_PSA
#error [NOT_SUPPORTED] ITS/PS tests can run only on PSA-enabled targets.
#endif // TARGET_PSA
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest/utest.h"
#include "psa/error.h"
#include "psa/storage_common.h"
#include "psa/internal_trusted_storage.h"
#include "psa/protected_storage.h"
#include "psa/lifecycle.h"
using namespace utest::v1;
#define TEST_BUFF_SIZE 16
typedef enum {
its,
ps
} storage_type_t;
extern "C" psa_status_t psa_ps_reset();
static psa_status_t set_func(storage_type_t stype, psa_storage_uid_t uid, uint32_t data_length,
const void *p_data, psa_storage_create_flags_t create_flags)
{
return (stype == its) ?
psa_its_set(uid, data_length, p_data, create_flags) :
psa_ps_set(uid, data_length, p_data, create_flags);
}
static psa_status_t get_func(storage_type_t stype, psa_storage_uid_t uid, uint32_t data_offset,
uint32_t data_length, void *p_data)
{
return (stype == its) ?
psa_its_get(uid, data_offset, data_length, p_data) :
psa_ps_get(uid, data_offset, data_length, p_data);
}
static psa_status_t get_info_func(storage_type_t stype, psa_storage_uid_t uid,
struct psa_storage_info_t *p_info)
{
return (stype == its) ?
psa_its_get_info(uid, p_info) :
psa_ps_get_info(uid, p_info);
}
static psa_status_t remove_func(storage_type_t stype, psa_storage_uid_t uid)
{
return (stype == its) ?
psa_its_remove(uid) :
psa_ps_remove(uid);
}
template <storage_type_t stype>
void pits_ps_test()
{
psa_status_t status = PSA_SUCCESS;
uint8_t write_buff[TEST_BUFF_SIZE] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
uint8_t read_buff[TEST_BUFF_SIZE] = {0};
struct psa_storage_info_t info = {0, PSA_STORAGE_FLAG_WRITE_ONCE};
memset(read_buff, 0, TEST_BUFF_SIZE);
status = get_info_func(stype, 5, &info);
TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, status);
status = set_func(stype, 5, TEST_BUFF_SIZE, write_buff, 0);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = get_info_func(stype, 5, &info);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL(TEST_BUFF_SIZE, info.size);
TEST_ASSERT_EQUAL(0, info.flags);
status = get_func(stype, 5, 0, TEST_BUFF_SIZE, read_buff);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL_MEMORY(write_buff, read_buff, TEST_BUFF_SIZE);
memset(read_buff, 0, TEST_BUFF_SIZE);
status = get_func(stype, 5, 1, TEST_BUFF_SIZE, read_buff);
TEST_ASSERT_NOT_EQUAL(PSA_SUCCESS, status);
status = get_func(stype, 5, 1, TEST_BUFF_SIZE - 1, read_buff);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL_MEMORY(write_buff + 1, read_buff, TEST_BUFF_SIZE - 1);
status = remove_func(stype, 5);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
status = get_info_func(stype, 5, &info);
TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, status);
}
template <storage_type_t stype>
void pits_ps_write_once_test()
{
psa_status_t status = PSA_SUCCESS;
uint8_t write_buff[TEST_BUFF_SIZE] = {0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
uint8_t read_buff[TEST_BUFF_SIZE] = {0};
struct psa_storage_info_t info = {0, 0};
status = get_info_func(stype, 5, &info);
TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, status);
status = set_func(stype, 5, TEST_BUFF_SIZE, write_buff, PSA_STORAGE_FLAG_WRITE_ONCE);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
info.size = 0;
info.flags = PSA_STORAGE_FLAG_WRITE_ONCE;
status = get_info_func(stype, 5, &info);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL(TEST_BUFF_SIZE, info.size);
TEST_ASSERT_EQUAL(PSA_STORAGE_FLAG_WRITE_ONCE, info.flags);
status = get_func(stype, 5, 0, TEST_BUFF_SIZE, read_buff);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL_MEMORY(write_buff, read_buff, TEST_BUFF_SIZE);
status = set_func(stype, 5, TEST_BUFF_SIZE, write_buff, PSA_STORAGE_FLAG_WRITE_ONCE);
TEST_ASSERT_EQUAL(PSA_ERROR_NOT_PERMITTED, status);
status = set_func(stype, 5, TEST_BUFF_SIZE, write_buff, 0);
TEST_ASSERT_EQUAL(PSA_ERROR_NOT_PERMITTED, status);
status = remove_func(stype, 5);
TEST_ASSERT_EQUAL(PSA_ERROR_NOT_PERMITTED, status);
info.size = 0;
info.flags = PSA_STORAGE_FLAG_WRITE_ONCE;
status = get_info_func(stype, 5, &info);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL(TEST_BUFF_SIZE, info.size);
TEST_ASSERT_EQUAL(PSA_STORAGE_FLAG_WRITE_ONCE, info.flags);
}
utest::v1::status_t case_its_teardown_handler(const Case *const source, const size_t passed, const size_t failed, const failure_t reason)
{
psa_status_t status;
status = mbed_psa_reboot_and_request_new_security_state(PSA_LIFECYCLE_ASSEMBLY_AND_TEST);
TEST_ASSERT_EQUAL(PSA_LIFECYCLE_SUCCESS, status);
return greentea_case_teardown_handler(source, passed, failed, reason);
}
template <storage_type_t stype>
utest::v1::status_t case_its_setup_handler(const Case *const source, const size_t index_of_case)
{
psa_status_t status;
if (stype == its) {
status = mbed_psa_reboot_and_request_new_security_state(PSA_LIFECYCLE_ASSEMBLY_AND_TEST);
TEST_ASSERT_EQUAL(PSA_LIFECYCLE_SUCCESS, status);
} else {
status = psa_ps_reset();
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
}
return greentea_case_setup_handler(source, index_of_case);
}
Case cases[] = {
Case("PSA prot internal storage - Basic", case_its_setup_handler<its>, pits_ps_test<its>, case_its_teardown_handler),
Case("PSA prot internal storage - Write-once", case_its_setup_handler<its>, pits_ps_write_once_test<its>, case_its_teardown_handler),
Case("PSA protected storage - Basic", case_its_setup_handler<ps>, pits_ps_test<ps>),
Case("PSA protected storage - Write-once", case_its_setup_handler<ps>, pits_ps_write_once_test<ps>)
};
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
{
#ifndef NO_GREENTEA
GREENTEA_SETUP(60, "default_auto");
#endif
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

@ -26,6 +26,7 @@
#include <stdint.h>
#include <stdlib.h>
#include "psa/error.h"
/* --------------------------------- extern "C" wrapper ------------------------------ */
@ -60,7 +61,6 @@ extern "C" {
#define PSA_DOORBELL (0x00000008UL) /**< Mask for PSA_DOORBELL signal.*/
#define PSA_SUCCESS (0L) /**< A general result code for calls to psa_call() indicating success.*/
#define PSA_IPC_CONNECT (1) /**< The IPC message type that indicates a new connection.*/
#define PSA_IPC_CALL (2) /**< The IPC message type that indicates a client request.*/
#define PSA_IPC_DISCONNECT (3) /**< The IPC message type that indicates the end of a connection.*/
@ -75,7 +75,6 @@ extern "C" {
/* -------------------------------------- Typedefs ----------------------------------- */
typedef uint32_t psa_signal_t;
typedef int32_t psa_status_t;
typedef int32_t psa_handle_t;
typedef psa_status_t error_t;

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2019 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.
*/
/* psa/error.h
Standard error codes for the SPM and RoT Services
As defined in PSA Firmware Framework v1.0
*/
#ifndef __PSA_ERROR__
#define __PSA_ERROR__
#include <stddef.h>
#include <stdint.h>
typedef int32_t psa_status_t;
#define PSA_SUCCESS ((psa_status_t)0)
#define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t)-129)
#define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t)-130)
#define PSA_ERROR_CONNECTION_BUSY ((psa_status_t)-131)
#define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132)
#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133)
#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134)
#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135)
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
#define PSA_ERROR_BAD_STATE ((psa_status_t)-137)
#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138)
#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139)
#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140)
#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141)
#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142)
#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t)-144)
#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145)
#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146)
#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147)
#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149)
#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152)
#endif // __PSA_ERROR__

View File

@ -0,0 +1,200 @@
/* Copyright (C) 2019, 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.
*/
/** @file
@brief This file describes the PSA Protected Storage API
*/
#ifndef __PSA_PROTECTED_STORAGE_H__
#define __PSA_PROTECTED_STORAGE_H__
#include <stddef.h>
#include <stdint.h>
#include "psa/error.h"
#include "psa/storage_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PSA_PS_API_VERSION_MAJOR 1 /**< The major version number of the PSA PS API. It will be incremented on significant updates that may include breaking changes */
#define PSA_PS_API_VERSION_MINOR 1 /**< The minor version number of the PSA PS API. It will be incremented in small updates that are unlikely to include breaking changes */
/**
* \brief create a new or modify an existing key/value pair
*
* \param[in] uid the identifier for the data
* \param[in] data_length The size in bytes of the data in `p_data`
* \param[in] p_data A buffer containing the data
* \param[in] create_flags The flags indicating the properties of the data
*
* \return A status indicating the success/failure of the operation
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_NOT_PERMITTED The operation failed because the provided uid value was already created with PSA_STORAGE_WRITE_ONCE_FLAG
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one or more of the given arguments were invalid.
* \retval PSA_ERROR_NOT_SUPPORTED The operation failed because one or more of the flags provided in `create_flags` is not supported or is not valid
* \retval PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because there was insufficient space on the storage medium
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
* \retval PSA_ERROR_GENERIC_ERROR The operation failed because of an unspecified internal failure
*/
psa_status_t psa_ps_set(psa_storage_uid_t uid,
uint32_t data_length,
const void *p_data,
psa_storage_create_flags_t create_flags);
/**
* \brief Retrieve the value for a provided uid
*
* \param[in] uid The identifier for the data
* \param[in] data_offset The offset within the data associated with the `uid` to start retrieving data
* \param[in] data_length The amount of data to read (and the minimum allocated size of the `p_data` buffer)
* \param[out] p_data The buffer where the data will be placed upon successful completion
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one or more of the given arguments were invalid (null pointer, wrong flags etc.)
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided uid value was not found in the storage
* \retval PSA_ERROR_BUFFER_TOO_SMALL The operation failed because the data associated with provided uid is not the same size as `data_size`
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
* \retval PSA_ERROR_GENERIC_ERROR The operation failed because of an unspecified internal failure
* \retval PSA_ERROR_DATA_CORRUPT The operation failed because of an authentication failure when attempting to get the key
* \retval PSA_ERROR_INVALID_SIGNATURE The operation failed because the data associated with the UID failed authentication
*/
psa_status_t psa_ps_get(psa_storage_uid_t uid,
uint32_t data_offset,
uint32_t data_length,
void *p_data);
/**
* \brief Retrieve the metadata about the provided uid
*
* \param[in] uid The identifier for the data
* \param[out] p_info A pointer to the `psa_storage_info_t` struct that will be populated with the metadata
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one or more of the given arguments were invalid (null pointer, wrong flags etc.)
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided uid value was not found in the storage
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
* \retval PSA_ERROR_GENERIC_ERROR The operation failed because of an unspecified internal failure
* \retval PSA_ERROR_DATA_CORRUPT The operation failed because of an authentication failure when attempting to get the key
* \retval PSA_ERROR_INVALID_SIGNATURE The operation failed because the data associated with the UID failed authentication
*/
psa_status_t psa_ps_get_info(psa_storage_uid_t uid, struct psa_storage_info_t *p_info);
/**
* \brief Remove the provided uid and its associated data from the storage
*
* \param[in] uid The identifier for the data to be removed
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one or more of the given arguments were invalid (null pointer, wrong flags etc.)
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided uid value was not found in the storage
* \retval PSA_ERROR_NOT_PERMITTED The operation failed because the provided uid value was created with psa_eps_WRITE_ONCE_FLAG
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
* \retval PSA_ERROR_GENERIC_ERROR The operation failed because of an unspecified internal failure
*/
psa_status_t psa_ps_remove(psa_storage_uid_t uid);
/**
* Creates an asset based on the given identifier, the maximum size and
* creation flags. This create allocates the space in the secure storage
* area without setting any data in the asset.
*
* It is only necessary to call this function for items that will be written
* with the \ref psa_ps_set_extended function. If only the \ref psa_ps_set function
* is needed, calls to this function are redundant.
*
* If the \ref PSA_STORAGE_FLAG_WRITE_ONCE flag is passed, implementations should
* return \ref PSA_ERROR_NOT_SUPPORTED.
*
* This function is optional. Not all PSA Protected Storage Implementations
* will implement this function. Consult the documentation of your chosen
* platform to determine if it is present.
*
* \param[in] uid A unique identifier for the asset.
* \param[in] size The maximum size in bytes of the asset.
* \param[in] create_flags Create flags \ref psa_storage_create_flags_t.
*
* \retval PSA_SUCCESS The assest does not exist and the input parameters are correct or
* the asset already exists, the input parameters are the same that
* have been used to create the asset and the owner is the same and the current asset content is kept
* TDB: "Owner is the same" doesn't really make sense from a PSA perspective, as each partition
* has its own UID space, making other partitions' data unadressable
* \retval PSA_ERROR_STORAGE_FAILURE The create action has a physical storage error
* \retval PSA_ERROR_INSUFFICIENT_STORAGE The maximum size is bigger of the current available space
* \retval PSA_ERROR_NOT_SUPPORTED One or more create_flags are not valid or supported
* \retval PSA_ERROR_INVALID_ARGUMENT The asset exists and the input paramters are not the same as the existing asset
* \retval PSA_ERROR_NOT_SUPPORTED The implementation of the API does not support this function
* \retval PSA_ERROR_GENERIC_ERROR The operation has failed due to an unspecified error
*/
psa_status_t psa_ps_create(psa_storage_uid_t uid,
uint32_t size,
psa_storage_create_flags_t create_flags);
/**
* Sets partial data into an asset based on the given identifier, data_offset,
* data length and p_data.
*
* Before calling this function, the asset must have been created with a call
* to \ref psa_ps_create.
*
* This function is optional. Not all PSA Protected Storage Implementations
* will implement this function. Consult the documentation of your chosen
* platform to determine if it is present.
*
* \param[in] uid The unique identifier for the asset.
* \param[in] data_offset Offset within the asset to start the write.
* \param[in] data_length The size in bytes of the data in p_data to write.
* \param[in] p_data Pointer to a buffer which contains the data to write.
*
* \retval PSA_SUCCESS If the asset exists, the input parameters are correct and the data
* is correctly written in the physical storage
* \retval PSA_ERROR_STORAGE_FAILURE If the data is not written correctly in the physical storage
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one or more of the given arguments were invalid (null pointer, wrong flags, etc)
* \retval PSA_ERROR_DOES_NOT_EXIST The specified UID was not found
* \retval PSA_ERROR_NOT_SUPPORTED The implementation of the API does not support this function
* \retval PSA_ERROR_GENERIC_ERROR The operation failed due to an unspecified error
* \retval PSA_ERROR_DATA_CORRUPT The operation failed because the existing data has been corrupted
* \retval PSA_ERROR_INVALID_SIGNATURE The operation failed because the existing data failed authentication (MAC check failed)
*/
psa_status_t psa_ps_set_extended(psa_storage_uid_t uid,
uint32_t data_offset,
uint32_t data_length,
const void *p_data);
/**
* Returns a bitmask with flags set for all of the optional features supported
* by the implementation.
*
* Currently defined flags are limited to:
* - \ref PSA_STORAGE_SUPPORT_SET_EXTENDED
*/
uint32_t psa_ps_get_support(void);
#ifdef __cplusplus
}
#endif
#endif // __PSA_PROTECTED_STORAGE_H__

View File

@ -0,0 +1,61 @@
/* Copyright (C) 2019, 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.
*/
/** @file
@brief This file includes common definitions for PSA storage
*/
#ifndef __PSA_STORAGE_COMMON_H__
#define __PSA_STORAGE_COMMON_H__
#include <stddef.h>
#include <stdint.h>
#include "psa/error.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \brief Flags used when creating a data entry
*/
typedef uint32_t psa_storage_create_flags_t;
#define PSA_STORAGE_FLAG_NONE 0 /**< No flags to pass */
#define PSA_STORAGE_FLAG_WRITE_ONCE (1 << 0) /**< The data associated with the uid will not be able to be modified or deleted. Intended to be used to set bits in `psa_storage_create_flags_t`*/
/** \brief A type for UIDs used for identifying data
*/
typedef uint64_t psa_storage_uid_t;
/**
* \brief A container for metadata associated with a specific uid
*/
struct psa_storage_info_t {
uint32_t size; /**< The size of the data associated with a uid **/
psa_storage_create_flags_t flags; /**< The flags set when the uid was created **/
};
/** \brief Flag indicating that \ref psa_storage_create and \ref psa_storage_set_extended are supported */
#define PSA_STORAGE_SUPPORT_SET_EXTENDED (1 << 0)
/** \brief PSA storage specific error codes */
#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152)
#ifdef __cplusplus
}
#endif
#endif // __PSA_STORAGE_COMMON_H__

View File

@ -43,10 +43,6 @@ psa_status_t psa_crypto_init(void)
err_call = psa_call(handle, NULL, 0, NULL, 0);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -71,10 +67,6 @@ psa_status_t psa_mac_abort(psa_mac_operation_t *operation)
psa_close(operation->handle);
operation->handle = PSA_NULL_HANDLE;
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -99,9 +91,6 @@ static psa_status_t psa_mac_setup(psa_mac_operation_t *operation,
}
err = psa_call(operation->handle, &in_vec, 1, NULL, 0);
if (err < 0) {
err = PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err);
}
@ -140,13 +129,10 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation,
};
if (operation->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err = psa_call(operation->handle, in_vec, 2, NULL, 0);
if (err < 0) {
err = PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err);
}
@ -167,17 +153,13 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,
psa_outvec out_vec[2] = { { mac, mac_size }, { mac_length, sizeof(*mac_length) } };
if (operation->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err_call = psa_call(operation->handle, in_vec, 2, out_vec, 2);
psa_close(operation->handle);
operation->handle = PSA_NULL_HANDLE;
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -196,17 +178,13 @@ psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
};
if (operation->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err_call = psa_call(operation->handle, in_vec, 3, NULL, 0);
psa_close(operation->handle);
operation->handle = PSA_NULL_HANDLE;
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -232,10 +210,6 @@ psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
psa_close(operation->handle);
operation->handle = PSA_NULL_HANDLE;
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -256,9 +230,6 @@ psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
}
err = psa_call(operation->handle, &in_vec, 1, NULL, 0);
if (err < 0) {
err = PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err);
}
@ -277,13 +248,10 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation,
};
if (operation->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err = psa_call(operation->handle, in_vec, 2, NULL, 0);
if (err < 0) {
err = PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err);
}
@ -306,17 +274,13 @@ psa_status_t psa_hash_finish(psa_hash_operation_t *operation,
};
if (operation->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err_call = psa_call(operation->handle, in_vec, 2, out_vec, 2);
psa_close(operation->handle);
operation->handle = PSA_NULL_HANDLE;
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -335,17 +299,13 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
};
if (operation->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err_call = psa_call(operation->handle, in_vec, 3, NULL, 0);
psa_close(operation->handle);
operation->handle = PSA_NULL_HANDLE;
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -373,18 +333,12 @@ psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
psa_crypto_ipc.func = PSA_HASH_CLONE_BEGIN;
err_call = psa_call(source_operation->handle, in_vec, 1, &out_vec, 1);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
if (err_call != 0) {
goto exit;
}
psa_crypto_ipc.func = PSA_HASH_CLONE_END;
err_call = psa_call(target_operation->handle, in_vec, 2, NULL, 0);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
exit:
if (err_call != 0) {
@ -463,9 +417,6 @@ psa_status_t psa_aead_encrypt(psa_key_handle_t key_handle,
psa_close(handle);
if (call_error < 0) {
call_error = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t)call_error);
}
@ -535,9 +486,6 @@ psa_status_t psa_aead_decrypt(psa_key_handle_t key_handle,
psa_close(handle);
if (call_error < 0) {
call_error = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t)call_error);
}
@ -586,9 +534,6 @@ psa_status_t psa_asymmetric_sign(psa_key_handle_t key_handle,
psa_close(handle);
if (call_error < 0) {
call_error = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t)call_error);
}
@ -625,9 +570,6 @@ psa_status_t psa_asymmetric_verify(psa_key_handle_t key_handle,
call_error = psa_call(handle, in_vec, 3, NULL, 0);
psa_close(handle);
if (call_error < 0) {
call_error = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t)call_error);
}
@ -686,9 +628,6 @@ static psa_status_t psa_asymmetric_operation(psa_sec_function_t func,
psa_close(handle);
if (call_error < 0) {
call_error = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t)call_error);
}
@ -754,9 +693,6 @@ psa_status_t psa_allocate_key(psa_key_handle_t *key_handle)
err_call = psa_call(handle, in_vec, 1, out_vec, 1);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -787,9 +723,6 @@ psa_status_t psa_create_key(psa_key_lifetime_t lifetime,
err_call = psa_call(handle, in_vec, 2, out_vec, 1);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -820,9 +753,6 @@ psa_status_t psa_open_key(psa_key_lifetime_t lifetime,
err_call = psa_call(handle, in_vec, 2, out_vec, 1);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -845,9 +775,6 @@ psa_status_t psa_close_key(psa_key_handle_t key_handle)
err_call = psa_call(handle, in_vec, 1, NULL, 0);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -876,9 +803,6 @@ psa_status_t psa_get_key_lifetime(psa_key_handle_t key_handle,
err_call = psa_call(handle, in_vec, 1, out_vec, 1);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -921,9 +845,6 @@ psa_status_t psa_set_key_policy(psa_key_handle_t key_handle,
err_call = psa_call(handle, in_vec, 2, NULL, 0);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -954,9 +875,6 @@ psa_status_t psa_get_key_policy(psa_key_handle_t key_handle,
err_call = psa_call(handle, in_vec, 1, out_vec, 1);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -984,9 +902,6 @@ psa_status_t psa_import_key(psa_key_handle_t key_handle,
err_call = psa_call(handle, in_vec, 2, NULL, 0);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1009,9 +924,6 @@ psa_status_t psa_destroy_key(psa_key_handle_t key_handle)
err_call = psa_call(handle, in_vec, 1, NULL, 0);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1047,9 +959,6 @@ psa_status_t psa_get_key_information(psa_key_handle_t key_handle,
err_call = psa_call(handle, in_vec, 1, out_vec, 2);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1078,9 +987,6 @@ static psa_status_t psa_export_key_common(psa_key_handle_t key_handle,
err_call = psa_call(handle, in_vec, 1, out_vec, 2);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1138,9 +1044,6 @@ psa_status_t psa_generate_key(psa_key_handle_t key_handle,
err_call = psa_call(handle, in_vec, 3, NULL, 0);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1163,9 +1066,6 @@ psa_status_t psa_generate_random(uint8_t *output,
err_call = psa_call(handle, NULL, 0, out_vec, 1);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1187,9 +1087,6 @@ psa_status_t mbedtls_psa_inject_entropy(const unsigned char *seed,
err_call = psa_call(handle, &in_vec, 1, NULL, 0);
psa_close(handle);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1206,14 +1103,11 @@ psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
psa_outvec out_vec = { capacity, sizeof(*capacity) };
if (generator->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err_call = psa_call(generator->handle, &in_vec, 1, &out_vec, 1);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1228,14 +1122,11 @@ psa_status_t psa_generator_read(psa_crypto_generator_t *generator,
psa_outvec out_vec = { output, output_length };
if (generator->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err_call = psa_call(generator->handle, &in_vec, 1, &out_vec, 1);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1254,14 +1145,11 @@ psa_status_t psa_generator_import_key(psa_key_handle_t key_handle,
};
if (generator->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err_call = psa_call(generator->handle, in_vec, 3, NULL, 0);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1293,11 +1181,7 @@ psa_status_t psa_key_derivation(psa_crypto_generator_t *generator,
err_call = psa_call(generator->handle, in_vec, 3, NULL, 0);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
psa_status_t psa_key_agreement(psa_crypto_generator_t *generator,
@ -1323,9 +1207,6 @@ psa_status_t psa_key_agreement(psa_crypto_generator_t *generator,
err_call = psa_call(generator->handle, in_vec, 2, NULL, 0);
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1340,9 +1221,6 @@ psa_status_t psa_generator_abort(psa_crypto_generator_t *generator)
psa_close(generator->handle);
generator->handle = PSA_NULL_HANDLE;
}
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
@ -1373,9 +1251,7 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
}
err = psa_call(operation->handle, &in_vec, 1, NULL, 0);
if (err < 0) {
err = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err);
}
@ -1402,9 +1278,7 @@ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
}
err = psa_call(operation->handle, &in_vec, 1, NULL, 0);
if (err < 0) {
err = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err);
}
@ -1432,13 +1306,11 @@ psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
};
if (operation->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err = psa_call(operation->handle, &in_vec, 1, out_vec, 2);
if (err < 0) {
err = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err);
}
@ -1460,13 +1332,11 @@ psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
};
if (operation->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err = psa_call(operation->handle, in_vec, 2, NULL, 0);
if (err < 0) {
err = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err);
}
@ -1500,13 +1370,11 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
};
if (operation->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err = psa_call(operation->handle, in_vec, 2, out_vec, 2);
if (err < 0) {
err = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err);
}
@ -1535,15 +1403,13 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
};
if (operation->handle <= 0) {
return (PSA_ERROR_BAD_STATE);
return (PSA_ERROR_INVALID_ARGUMENT);
}
err_call = psa_call(operation->handle, &in_vec, 1, out_vec, 2);
psa_close(operation->handle);
operation->handle = PSA_NULL_HANDLE;
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}
@ -1566,9 +1432,7 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
err_call = psa_call(operation->handle, &in_vec, 1, NULL, 0);
psa_close(operation->handle);
operation->handle = PSA_NULL_HANDLE;
if (err_call < 0) {
err_call = (psa_status_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
return ((psa_status_t) err_call);
}

View File

@ -31,7 +31,7 @@ psa_status_t psa_platfrom_lifecycle_get_impl(uint32_t *lc_state)
return PSA_LIFECYCLE_SUCCESS;
}
psa_its_status_t psa_its_reset();
psa_status_t psa_its_reset();
psa_status_t psa_platfrom_lifecycle_change_request_impl(uint32_t state)
{

View File

@ -37,7 +37,7 @@ static psa_status_t lifecycle_get(psa_msg_t *msg)
return PSA_DROP_CONNECTION;
}
psa_its_status_t status = psa_platfrom_lifecycle_get_impl(&lc_state);
psa_status_t status = psa_platfrom_lifecycle_get_impl(&lc_state);
if (status == PSA_SUCCESS) {
psa_write(msg->handle, 0, &lc_state, sizeof(lc_state));
}

View File

@ -1,41 +0,0 @@
/* Copyright (c) 2019 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 __PITS_VER_IMPL_H__
#define __PITS_VER_IMPL_H__
#include "psa/internal_trusted_storage.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define ITS_VERSION_KEY "PSA_ITS_VERSION" // ITS version entry identifier in TDBStore
typedef struct its_version {
uint32_t major;
uint32_t minor;
} its_version_t;
psa_its_status_t its_version_migrate(void *storage, const its_version_t *version);
#ifdef __cplusplus
}
#endif
#endif // __PITS_VER_IMPL_H__

View File

@ -1,154 +0,0 @@
/* Copyright (C) 2019, 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.
*/
/** @file
@brief This file describes the PSA Internal Trusted Storage API
*/
#ifndef __INTERNAL_TRUSTED_STORAGE_H__
#define __INTERNAL_TRUSTED_STORAGE_H__
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PSA_ITS_API_VERSION_MAJOR 1 /**< The major version number of the PSA ITS API. It will be incremented on significant updates that may include breaking changes */
#define PSA_ITS_API_VERSION_MINOR 0 /**< The minor version number of the PSA ITS API. It will be incremented in small updates that are unlikely to include breaking changes */
/** \brief Flags used when creating a key
*/
typedef uint32_t psa_its_create_flags_t;
/** \brief A type for UIDs used for identifying data
*/
typedef uint64_t psa_its_uid_t;
#define PSA_ITS_FLAG_NONE 0 /**< No flags to pass */
#define PSA_ITS_FLAG_WRITE_ONCE ( 1 << 0 ) /**< The data associated with the key will not be able to be modified or deleted. Intended to be used to set bits in `psa_its_create_flags_t` */
/** Mask for all of the ITS Flags
*/
#define PSA_ITS_FLAGS_MSK ( \
PSA_ITS_FLAG_NONE | \
PSA_ITS_FLAG_WRITE_ONCE \
)
/**
* \brief A container for metadata associated with a specific key
*/
struct psa_its_info_t {
uint32_t size; /**< The size of the data associated with a key **/
psa_its_create_flags_t flags; /**< The flags set when the key was created **/
};
/**
* \brief The return status type for the PSA Trusted Storage functions
*/
typedef uint32_t psa_its_status_t;
#define PSA_ITS_SUCCESS 0 /**< The operation completed successfully */
#define PSA_ITS_ERROR_WRITE_ONCE 1 /**< The operation failed because the provided key value was already created with PSA_ITS_WRITE_ONCE_FLAG */
#define PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED 2 /**< The operation failed because one or more of the flags provided in `create_flags` is not supported or is not valid */
#define PSA_ITS_ERROR_INSUFFICIENT_SPACE 3 /**< The operation failed because there was insufficient space on the storage medium */
#define PSA_ITS_ERROR_STORAGE_FAILURE 4 /**< The operation failed because the physical storage has failed (Fatal error) */
#define PSA_ITS_ERROR_INVALID_ARGUMENTS 5 /**< The operation failed because one of the provided pointers is invalid, for example is `NULL` or references memory the caller cannot access */
#define PSA_ITS_ERROR_UID_NOT_FOUND 6 /**< The operation failed because the provided key value was not found in the storage */
#define PSA_ITS_ERROR_INCORRECT_SIZE 7 /**< The operation failed because the data associated with provided key is not the same size as `data_size`, or `offset+data_size` is too large for the data, but `offset` is less than the size */
#define PSA_ITS_ERROR_OFFSET_INVALID 8 /**< The operation failed because an offset was supplied that is invalid for the existing data associated with the uid. For example, offset is greater that the size of the data */
/**
* \brief create a new or modify an existing uid/value pair
*
* \param[in] uid the identifier for the data
* \param[in] data_length The size in bytes of the data in `p_data`
* \param[in] p_data A buffer containing the data
* \param[in] create_flags The flags that the data will be stored with
*
* \return A status indicating the success/failure of the operation
* \retval PSA_ITS_SUCCESS The operation completed successfully
* \retval PSA_ITS_ERROR_WRITE_ONCE The operation failed because the provided `uid` value was already created with PSA_ITS_WRITE_ONCE_FLAG
* \retval PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED The operation failed because one or more of the flags provided in `create_flags` is not supported or is not valid
* \retval PSA_ITS_ERROR_INSUFFICIENT_SPACE The operation failed because there was insufficient space on the storage medium
* \retval PSA_ITS_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
* \retval PSA_ITS_ERROR_INVALID_ARGUMENTS The operation failed because one of the provided pointers(`p_data`)
* is invalid, for example is `NULL` or references memory the caller cannot access
*/
psa_its_status_t psa_its_set(psa_its_uid_t uid,
uint32_t data_length,
const void *p_data,
psa_its_create_flags_t create_flags);
/**
* \brief Retrieve the value associated with a provided uid
*
* \param[in] uid The uid value
* \param[in] data_offset The starting offset of the data requested
* \param[in] data_length the amount of data requested (and the minimum allocated size of the `p_data` buffer)
* \param[out] p_data The buffer where the data will be placed upon successful completion
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_ITS_SUCCESS The operation completed successfully
* \retval PSA_ITS_ERROR_UID_NOT_FOUND The operation failed because the provided `uid` value was not found in the storage
* \retval PSA_ITS_ERROR_INCORRECT_SIZE The operation failed because the data associated with provided `uid` is not the same size as `data_size`
* \retval PSA_ITS_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
* \retval PSA_ITS_ERROR_INVALID_ARGUMENTS The operation failed because one of the provided pointers(`p_data`, `p_data_length`)
* is invalid. For example is `NULL` or references memory the caller cannot access
* \retval PSA_ITS_ERROR_OFFSET_INVALID The operation failed because an offset was supplied that is invalid for the existing data associated with the
* uid. For example, offset + size is invalid
*/
psa_its_status_t psa_its_get(psa_its_uid_t uid,
uint32_t data_offset,
uint32_t data_length,
void *p_data);
/**
* \brief Retrieve the metadata about the provided uid
*
* \param[in] uid The uid value
* \param[out] p_info A pointer to the `psa_its_info_t` struct that will be populated with the metadata
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_ITS_SUCCESS The operation completed successfully
* \retval PSA_ITS_ERROR_UID_NOT_FOUND The operation failed because the provided uid value was not found in the storage
* \retval PSA_ITS_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
* \retval PSA_ITS_ERROR_INVALID_ARGUMENTS The operation failed because one of the provided pointers(`p_info`)
* is invalid, for example is `NULL` or references memory the caller cannot access
*/
psa_its_status_t psa_its_get_info(psa_its_uid_t uid,
struct psa_its_info_t *p_info);
/**
* \brief Remove the provided key and its associated data from the storage
*
* \param[in] uid The uid value
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_ITS_SUCCESS The operation completed successfully
* \retval PSA_ITS_ERROR_UID_NOT_FOUND The operation failed because the provided key value was not found in the storage
* \retval PSA_ITS_ERROR_WRITE_ONCE The operation failed because the provided key value was created with psa_its_WRITE_ONCE_FLAG
* \retval PSA_ITS_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
*/
psa_its_status_t psa_its_remove(psa_its_uid_t uid);
#ifdef __cplusplus
}
#endif
#endif // __INTERNAL_TRUSTED_STORAGE_H__

View File

@ -16,43 +16,26 @@
*/
#include <cstring>
#include "KVStore.h"
#include "TDBStore.h"
#include "psa/internal_trusted_storage.h"
#include "pits_impl.h"
#include "pits_version_impl.h"
#include "psa_storage_common_impl.h"
#include "mbed_error.h"
#include "mbed_assert.h"
#include "mbed_toolchain.h"
#if defined(TARGET_TFM)
using namespace mbed;
KVStore *get_its_kvstore_instance(void);
#else
#include "KVMap.h"
using namespace mbed;
/*
* \brief Get default KVStore instance for internal flesh storage
*
* \return valid pointer to KVStore
*/
KVStore *get_its_kvstore_instance(void)
#ifdef __cplusplus
extern "C"
{
KVMap &kv_map = KVMap::get_instance();
return kv_map.get_internal_kv_instance(STR_EXPAND(MBED_CONF_STORAGE_DEFAULT_KV));
}
#endif // defined(TARGET_TFM)
#endif
// Maximum length of filename we use for kvstore API.
// pid: 6; delimiter: 1; uid: 11; str terminator: 1
#define PSA_ITS_FILENAME_MAX_LEN 19
#define PSA_STORAGE_FILE_NAME_MAX 19
#define FLAGS_MSK PSA_STORAGE_FLAG_WRITE_ONCE
#define STR_EXPAND(tok) #tok
const uint8_t base64_coding_table[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
@ -65,65 +48,41 @@ const uint8_t base64_coding_table[] = {
'4', '5', '6', '7', '8', '9', '+', '-'
};
static KVStore *kvstore = NULL;
MBED_WEAK psa_its_status_t its_version_migrate(void *storage, const its_version_t *version)
void psa_storage_handle_version(KVStore *kvstore, const char *version_key, const psa_storage_version_t *curr_version,
migrate_func_t migrate_func)
{
(void)storage;
(void)version;
return PSA_ITS_SUCCESS;
}
static void its_init(void)
{
kvstore = get_its_kvstore_instance();
if (!kvstore) {
// Can only happen due to system misconfiguration.
// Thus considered as unrecoverable error for runtime.
error("Failed getting kvstore instance\n");
}
its_version_t version = { 0, 0 };
psa_storage_version_t read_version = {0, 0};
size_t actual_size = 0;
KVStore::info_t kv_info;
bool write_version = false;
int status = kvstore->get_info(ITS_VERSION_KEY, &kv_info);
if (status != MBED_SUCCESS) {
version.major = PSA_ITS_API_VERSION_MAJOR;
version.minor = PSA_ITS_API_VERSION_MINOR;
int status = kvstore->get(version_key, &read_version, sizeof(read_version), &actual_size, 0);
if (status == MBED_SUCCESS) {
if (actual_size != sizeof(read_version)) {
error("PSA storage version data is corrupt");
}
} else if (status == MBED_ERROR_ITEM_NOT_FOUND) {
write_version = true;
} else {
if (kv_info.size != sizeof(version)) {
error("ITS version data is corrupt");
error("Could not read PSA storage version data");
}
status = kvstore->get(ITS_VERSION_KEY, &version, sizeof(version), &actual_size, 0);
if ((status != MBED_SUCCESS) ||
((status == MBED_SUCCESS) && (actual_size != sizeof(version)))) {
error("Could not read ITS version data");
}
if ((read_version.major > curr_version->major) ||
((read_version.major == curr_version->major) && (read_version.minor > curr_version->minor))) {
error("Downgrading PSA storage version is not allowed");
}
if ((version.major > PSA_ITS_API_VERSION_MAJOR) ||
((version.major == PSA_ITS_API_VERSION_MAJOR) && (version.minor > PSA_ITS_API_VERSION_MINOR))) {
error("Downgrading ITS version is not allowed");
if ((read_version.major < curr_version->major) ||
((read_version.major == curr_version->major) && (read_version.minor < curr_version->minor))) {
psa_status_t migration_status = migrate_func(kvstore, &read_version, curr_version);
if (migration_status != PSA_SUCCESS) {
error("PSA storage migration failed");
}
if ((version.major < PSA_ITS_API_VERSION_MAJOR) ||
((version.major == PSA_ITS_API_VERSION_MAJOR) && (version.minor < PSA_ITS_API_VERSION_MINOR))) {
psa_its_status_t migration_status = its_version_migrate(kvstore, &version);
if (migration_status != PSA_ITS_SUCCESS) {
error("ITS migration failed");
}
version.major = PSA_ITS_API_VERSION_MAJOR;
version.minor = PSA_ITS_API_VERSION_MINOR;
write_version = true;
}
if (write_version) {
if (kvstore->set(ITS_VERSION_KEY, &version, sizeof(version), 0) != MBED_SUCCESS) {
error("Could not write PSA ITS version");
if (kvstore->set(version_key, curr_version, sizeof(psa_storage_version_t), 0) != MBED_SUCCESS) {
error("Could not write PSA storage version");
}
}
}
@ -134,19 +93,29 @@ static void its_init(void)
* \param[in] status - KVStore status code
* \return PSA internal storage status code
*/
static psa_its_status_t convert_status(int status)
static psa_status_t convert_status(int status)
{
switch (status) {
case MBED_SUCCESS:
return PSA_ITS_SUCCESS;
return PSA_SUCCESS;
case MBED_ERROR_WRITE_PROTECTED:
return PSA_ITS_ERROR_WRITE_ONCE;
return PSA_ERROR_NOT_PERMITTED;
case MBED_ERROR_MEDIA_FULL:
return PSA_ITS_ERROR_INSUFFICIENT_SPACE;
return PSA_ERROR_INSUFFICIENT_STORAGE;
case MBED_ERROR_ITEM_NOT_FOUND:
return PSA_ITS_ERROR_UID_NOT_FOUND;
return PSA_ERROR_DOES_NOT_EXIST;
case MBED_ERROR_INVALID_DATA_DETECTED:
return PSA_ERROR_DATA_CORRUPT;
case MBED_ERROR_INVALID_ARGUMENT:
return PSA_ERROR_INVALID_ARGUMENT;
case MBED_ERROR_READ_FAILED: // fallthrough
case MBED_ERROR_WRITE_FAILED:
return PSA_ERROR_STORAGE_FAILURE;
case MBED_ERROR_AUTHENTICATION_FAILED: // fallthrough
case MBED_ERROR_RBP_AUTHENTICATION_FAILED:
return PSA_ERROR_INVALID_SIGNATURE;
default:
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_GENERIC_ERROR;
}
}
@ -187,10 +156,10 @@ MBED_FORCEINLINE uint64_t lsr64(uint64_t x, uint32_t n)
* \param[in] uid - PSA internal storage unique ID
* \param[in] pid - owner PSA partition ID
*/
static void generate_fn(char *tdb_filename, uint32_t tdb_filename_size, psa_its_uid_t uid, int32_t pid)
static void generate_fn(char *tdb_filename, uint32_t tdb_filename_size, psa_storage_uid_t uid, int32_t pid)
{
MBED_ASSERT(tdb_filename != NULL);
MBED_ASSERT(tdb_filename_size == PSA_ITS_FILENAME_MAX_LEN);
MBED_ASSERT(tdb_filename_size == PSA_STORAGE_FILE_NAME_MAX);
uint8_t filename_idx = 0;
uint32_t unsigned_pid = (uint32_t)pid; // binary only representation for bitwise operations
@ -211,25 +180,23 @@ static void generate_fn(char *tdb_filename, uint32_t tdb_filename_size, psa_its_
} while (uid != 0);
tdb_filename[filename_idx++] = '\0';
MBED_ASSERT(filename_idx <= PSA_ITS_FILENAME_MAX_LEN);
MBED_ASSERT(filename_idx <= PSA_STORAGE_FILE_NAME_MAX);
}
psa_its_status_t psa_its_set_impl(int32_t pid, psa_its_uid_t uid, uint32_t data_length, const void *p_data, psa_its_create_flags_t create_flags)
psa_status_t psa_storage_set_impl(KVStore *kvstore, int32_t pid, psa_storage_uid_t uid,
uint32_t data_length, const void *p_data,
psa_storage_create_flags_t create_flags)
{
if (!kvstore) {
its_init();
}
if ((create_flags & (~PSA_ITS_FLAGS_MSK)) != 0) {
return PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED;
if ((create_flags & (~FLAGS_MSK)) != 0) {
return PSA_ERROR_NOT_SUPPORTED;
}
// Generate KVStore key
char kv_key[PSA_ITS_FILENAME_MAX_LEN] = {'\0'};
generate_fn(kv_key, PSA_ITS_FILENAME_MAX_LEN, uid, pid);
char kv_key[PSA_STORAGE_FILE_NAME_MAX] = {'\0'};
generate_fn(kv_key, PSA_STORAGE_FILE_NAME_MAX, uid, pid);
uint32_t kv_create_flags = 0;
if (create_flags & PSA_ITS_FLAG_WRITE_ONCE) {
if (create_flags & PSA_STORAGE_FLAG_WRITE_ONCE) {
kv_create_flags = KVStore::WRITE_ONCE_FLAG;
}
@ -238,55 +205,46 @@ psa_its_status_t psa_its_set_impl(int32_t pid, psa_its_uid_t uid, uint32_t data_
return convert_status(status);
}
psa_its_status_t psa_its_get_impl(int32_t pid, psa_its_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data)
psa_status_t psa_storage_get_impl(KVStore *kvstore, int32_t pid, psa_storage_uid_t uid,
uint32_t data_offset, uint32_t data_length, void *p_data)
{
if (!kvstore) {
its_init();
}
// Generate KVStore key
char kv_key[PSA_ITS_FILENAME_MAX_LEN] = {'\0'};
generate_fn(kv_key, PSA_ITS_FILENAME_MAX_LEN, uid, pid);
char kv_key[PSA_STORAGE_FILE_NAME_MAX] = {'\0'};
generate_fn(kv_key, PSA_STORAGE_FILE_NAME_MAX, uid, pid);
KVStore::info_t kv_info;
int status = kvstore->get_info(kv_key, &kv_info);
if (status == MBED_SUCCESS) {
if (data_offset > kv_info.size) {
return PSA_ITS_ERROR_OFFSET_INVALID;
return PSA_ERROR_INVALID_ARGUMENT;
}
// Verify (size + offset) does not wrap around
if (data_length + data_offset < data_length) {
return PSA_ITS_ERROR_INCORRECT_SIZE;
return PSA_ERROR_INVALID_ARGUMENT;
}
if (data_offset + data_length > kv_info.size) {
return PSA_ITS_ERROR_INCORRECT_SIZE;
return PSA_ERROR_BUFFER_TOO_SMALL;
}
size_t actual_size = 0;
status = kvstore->get(kv_key, p_data, data_length, &actual_size, data_offset);
if (status == MBED_SUCCESS) {
if (actual_size < data_length) {
status = PSA_ITS_ERROR_INCORRECT_SIZE;
}
if ((status == MBED_SUCCESS) && (actual_size < data_length)) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
}
return convert_status(status);
}
psa_its_status_t psa_its_get_info_impl(int32_t pid, psa_its_uid_t uid, struct psa_its_info_t *p_info)
psa_status_t psa_storage_get_info_impl(KVStore *kvstore, int32_t pid, psa_storage_uid_t uid,
struct psa_storage_info_t *p_info)
{
if (!kvstore) {
its_init();
}
// Generate KVStore key
char kv_key[PSA_ITS_FILENAME_MAX_LEN] = {'\0'};
generate_fn(kv_key, PSA_ITS_FILENAME_MAX_LEN, uid, pid);
char kv_key[PSA_STORAGE_FILE_NAME_MAX] = {'\0'};
generate_fn(kv_key, PSA_STORAGE_FILE_NAME_MAX, uid, pid);
KVStore::info_t kv_info;
int status = kvstore->get_info(kv_key, &kv_info);
@ -294,7 +252,7 @@ psa_its_status_t psa_its_get_info_impl(int32_t pid, psa_its_uid_t uid, struct ps
if (status == MBED_SUCCESS) {
p_info->flags = 0;
if (kv_info.flags & KVStore::WRITE_ONCE_FLAG) {
p_info->flags |= PSA_ITS_FLAG_WRITE_ONCE;
p_info->flags |= PSA_STORAGE_FLAG_WRITE_ONCE;
}
p_info->size = (uint32_t)(kv_info.size); // kv_info.size is of type size_t
}
@ -302,27 +260,23 @@ psa_its_status_t psa_its_get_info_impl(int32_t pid, psa_its_uid_t uid, struct ps
return convert_status(status);
}
psa_its_status_t psa_its_remove_impl(int32_t pid, psa_its_uid_t uid)
psa_status_t psa_storage_remove_impl(KVStore *kvstore, int32_t pid, psa_storage_uid_t uid)
{
if (!kvstore) {
its_init();
}
// Generate KVStore key
char kv_key[PSA_ITS_FILENAME_MAX_LEN] = {'\0'};
generate_fn(kv_key, PSA_ITS_FILENAME_MAX_LEN, uid, pid);
char kv_key[PSA_STORAGE_FILE_NAME_MAX] = {'\0'};
generate_fn(kv_key, PSA_STORAGE_FILE_NAME_MAX, uid, pid);
int status = kvstore->remove(kv_key);
return convert_status(status);
}
psa_its_status_t psa_its_reset_impl()
psa_status_t psa_storage_reset_impl(KVStore *kvstore)
{
if (!kvstore) {
its_init();
}
int status = kvstore->reset();
return convert_status(status);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,50 @@
/* Copyright (c) 2019 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 __PSA_STORAGE_COMMON_IMPL_H__
#define __PSA_STORAGE_COMMON_IMPL_H__
#include "psa/error.h"
#include "psa/storage_common.h"
#include "KVStore.h"
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct {
uint32_t major;
uint32_t minor;
} psa_storage_version_t;
typedef psa_status_t (*migrate_func_t)(mbed::KVStore *kvstore, const psa_storage_version_t *old_version, const psa_storage_version_t *new_version);
void psa_storage_handle_version(mbed::KVStore *kvstore, const char *version_key, const psa_storage_version_t *version,
migrate_func_t migrate_func);
psa_status_t psa_storage_set_impl(mbed::KVStore *kvstore, int32_t pid, psa_storage_uid_t uid, uint32_t data_length, const void *p_data, psa_storage_create_flags_t create_flags);
psa_status_t psa_storage_get_impl(mbed::KVStore *kvstore, int32_t pid, psa_storage_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data);
psa_status_t psa_storage_get_info_impl(mbed::KVStore *kvstore, int32_t pid, psa_storage_uid_t uid, struct psa_storage_info_t *p_info);
psa_status_t psa_storage_remove_impl(mbed::KVStore *kvstore, int32_t pid, psa_storage_uid_t uid);
psa_status_t psa_storage_reset_impl(mbed::KVStore *kvstore);
#ifdef __cplusplus
}
#endif
#endif // __PSA_STORAGE_COMMON_IMPL_H__

View File

@ -19,6 +19,7 @@
#include <string.h>
#include "psa/internal_trusted_storage.h"
#include "psa/storage_common.h"
#include "pits_impl.h"
#include "kv_config.h"
#include "mbed_error.h"
@ -27,10 +28,10 @@
// So here we set a global pid value to be used for when calling IMPL functions
#define PSA_ITS_EMUL_PID 1
psa_its_status_t psa_its_set(psa_its_uid_t uid, uint32_t data_length, const void *p_data, psa_its_create_flags_t create_flags)
psa_status_t psa_its_set(psa_storage_uid_t uid, uint32_t data_length, const void *p_data, psa_storage_create_flags_t create_flags)
{
if (!p_data && data_length) {
return PSA_ITS_ERROR_INVALID_ARGUMENTS;
return PSA_ERROR_INVALID_ARGUMENT;
}
// KVStore initiation:
@ -38,18 +39,18 @@ psa_its_status_t psa_its_set(psa_its_uid_t uid, uint32_t data_length, const void
// - Repeating calls has no effect
int kv_status = kv_init_storage_config();
if (kv_status != MBED_SUCCESS) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
psa_its_status_t res = psa_its_set_impl(PSA_ITS_EMUL_PID, uid, data_length, p_data, create_flags);
psa_status_t res = psa_its_set_impl(PSA_ITS_EMUL_PID, uid, data_length, p_data, create_flags);
return res;
}
psa_its_status_t psa_its_get(psa_its_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data)
psa_status_t psa_its_get(psa_storage_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data)
{
if (!p_data && data_length) {
return PSA_ITS_ERROR_INVALID_ARGUMENTS;
return PSA_ERROR_INVALID_ARGUMENT;
}
// KVStore initiation:
@ -57,16 +58,16 @@ psa_its_status_t psa_its_get(psa_its_uid_t uid, uint32_t data_offset, uint32_t d
// - Repeating calls has no effect
int kv_status = kv_init_storage_config();
if (kv_status != MBED_SUCCESS) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
return psa_its_get_impl(PSA_ITS_EMUL_PID, uid, data_offset, data_length, p_data);
}
psa_its_status_t psa_its_get_info(psa_its_uid_t uid, struct psa_its_info_t *p_info)
psa_status_t psa_its_get_info(psa_storage_uid_t uid, struct psa_storage_info_t *p_info)
{
if (!p_info) {
return PSA_ITS_ERROR_INVALID_ARGUMENTS;
return PSA_ERROR_INVALID_ARGUMENT;
}
// KVStore initiation:
@ -74,33 +75,33 @@ psa_its_status_t psa_its_get_info(psa_its_uid_t uid, struct psa_its_info_t *p_in
// - Repeating calls has no effect
int kv_status = kv_init_storage_config();
if (kv_status != MBED_SUCCESS) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
return psa_its_get_info_impl(PSA_ITS_EMUL_PID, uid, p_info);
}
psa_its_status_t psa_its_remove(psa_its_uid_t uid)
psa_status_t psa_its_remove(psa_storage_uid_t uid)
{
// KVStore initiation:
// - In EMUL (non-secure single core) we do it here since we don't have another context to do it inside.
// - Repeating calls has no effect
int kv_status = kv_init_storage_config();
if (kv_status != MBED_SUCCESS) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
return psa_its_remove_impl(PSA_ITS_EMUL_PID, uid);
}
extern "C" psa_its_status_t psa_its_reset()
extern "C" psa_status_t psa_its_reset()
{
// KVStore initiation:
// - In EMUL (non-secure single core) we do it here since we don't have another context to do it inside.
// - Repeating calls has no effect
int kv_status = kv_init_storage_config();
if (kv_status != MBED_SUCCESS) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
return psa_its_reset_impl();

View File

@ -142,8 +142,7 @@ KVStore *get_its_kvstore_instance(void)
{
return internal_store;
}
int kv_init_storage_config()
extern "C" int kv_init_storage_config()
{
int ret = MBED_SUCCESS;

View File

@ -0,0 +1,140 @@
/* Copyright (c) 2019 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.
*/
#include <cstring>
#include "KVStore.h"
#include "TDBStore.h"
#include "psa/internal_trusted_storage.h"
#include "psa_storage_common_impl.h"
#include "pits_impl.h"
#include "mbed_error.h"
#include "mbed_toolchain.h"
using namespace mbed;
#if defined(TARGET_TFM)
KVStore *get_its_kvstore_instance(void);
#else
#include "KVMap.h"
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#define STR_EXPAND(tok) #tok
#define ITS_VERSION_KEY "PSA_ITS_VERSION" // ITS version entry identifier in TDBStore
static KVStore *kvstore = NULL;
MBED_WEAK psa_status_t its_version_migrate(KVStore *kvstore,
const psa_storage_version_t *old_version, const psa_storage_version_t *new_version)
{
(void)kvstore;
(void)old_version;
(void)new_version;
return PSA_SUCCESS;
}
static void its_init(void)
{
#if defined(TARGET_TFM)
kvstore = get_its_kvstore_instance();
#else
KVMap &kv_map = KVMap::get_instance();
kvstore = kv_map.get_internal_kv_instance(STR_EXPAND(MBED_CONF_STORAGE_DEFAULT_KV));
#endif
psa_storage_version_t version = {PSA_ITS_API_VERSION_MAJOR, PSA_ITS_API_VERSION_MINOR};
if (!kvstore) {
// Can only happen due to system misconfiguration.
// Thus considered as unrecoverable error for runtime.
error("Failed getting kvstore instance\n");
}
psa_storage_handle_version(kvstore, ITS_VERSION_KEY, &version, its_version_migrate);
}
// used from test only
void its_deinit(void)
{
kvstore = NULL;
}
psa_status_t psa_its_set_impl(int32_t pid, psa_storage_uid_t uid, uint32_t data_length, const void *p_data, psa_storage_create_flags_t create_flags)
{
if (!kvstore) {
its_init();
}
return psa_storage_set_impl(kvstore, pid, uid, data_length, p_data, create_flags);
}
psa_status_t psa_its_get_impl(int32_t pid, psa_storage_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data)
{
if (!kvstore) {
its_init();
}
return psa_storage_get_impl(kvstore, pid, uid, data_offset, data_length, p_data);
}
psa_status_t psa_its_get_info_impl(int32_t pid, psa_storage_uid_t uid, struct psa_storage_info_t *p_info)
{
if (!kvstore) {
its_init();
}
return psa_storage_get_info_impl(kvstore, pid, uid, p_info);
}
psa_status_t psa_its_remove_impl(int32_t pid, psa_storage_uid_t uid)
{
if (!kvstore) {
its_init();
}
return psa_storage_remove_impl(kvstore, pid, uid);
}
psa_status_t psa_its_reset_impl()
{
// Do not call its_init here to avoid version check before reset
#if defined(TARGET_TFM)
kvstore = get_its_kvstore_instance();
#else
KVMap &kv_map = KVMap::get_instance();
kvstore = kv_map.get_internal_kv_instance(STR_EXPAND(MBED_CONF_STORAGE_DEFAULT_KV));
#endif
if (!kvstore) {
// Can only happen due to system misconfiguration.
// Thus considered as unrecoverable error for runtime.
error("Failed getting kvstore instance\n");
}
return psa_storage_reset_impl(kvstore);
}
#ifdef __cplusplus
}
#endif

View File

@ -18,26 +18,19 @@
#ifndef __PITS_IMPL_H__
#define __PITS_IMPL_H__
#include "psa/internal_trusted_storage.h"
#include "psa/error.h"
#include "psa/storage_common.h"
#ifdef __cplusplus
extern "C"
{
#endif
#if defined(TARGET_TFM) && defined(COMPONENT_SPE)
extern int kv_init_storage_config();
#endif
#define PITS_DATA_PTR_AT_OFFSET(ptr, offset) ((void *)(((uintptr_t)ptr) + ((uintptr_t)offset)))
#define STR_EXPAND(tok) #tok
psa_its_status_t psa_its_set_impl(int32_t pid, psa_its_uid_t uid, uint32_t data_length, const void *p_data, psa_its_create_flags_t create_flags);
psa_its_status_t psa_its_get_impl(int32_t pid, psa_its_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data);
psa_its_status_t psa_its_get_info_impl(int32_t pid, psa_its_uid_t uid, struct psa_its_info_t *p_info);
psa_its_status_t psa_its_remove_impl(int32_t pid, psa_its_uid_t uid);
psa_its_status_t psa_its_reset_impl();
psa_its_status_t psa_its_reset_impl(void);
psa_status_t psa_its_set_impl(int32_t pid, psa_storage_uid_t uid, uint32_t data_length, const void *p_data, psa_storage_create_flags_t create_flags);
psa_status_t psa_its_get_impl(int32_t pid, psa_storage_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data);
psa_status_t psa_its_get_info_impl(int32_t pid, psa_storage_uid_t uid, struct psa_storage_info_t *p_info);
psa_status_t psa_its_remove_impl(int32_t pid, psa_storage_uid_t uid);
psa_status_t psa_its_reset_impl();
#ifdef __cplusplus
}

View File

@ -16,13 +16,14 @@
*/
#include "psa/client.h"
#include "psa/storage_common.h"
#include "psa/internal_trusted_storage.h"
#include "psa_its_ifs.h"
psa_its_status_t psa_its_set(psa_its_uid_t uid, uint32_t data_length, const void *p_data, psa_its_create_flags_t create_flags)
psa_status_t psa_its_set(psa_storage_uid_t uid, uint32_t data_length, const void *p_data, psa_storage_create_flags_t create_flags)
{
if (!p_data && data_length) {
return PSA_ITS_ERROR_INVALID_ARGUMENTS;
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_invec msg[3] = {
@ -33,22 +34,22 @@ psa_its_status_t psa_its_set(psa_its_uid_t uid, uint32_t data_length, const void
psa_handle_t conn = psa_connect(PSA_ITS_SET, 1);
if (conn <= PSA_NULL_HANDLE) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
psa_status_t status = psa_call(conn, msg, 3, NULL, 0);
if (status == PSA_DROP_CONNECTION) {
status = PSA_ITS_ERROR_STORAGE_FAILURE;
status = PSA_ERROR_STORAGE_FAILURE;
}
psa_close(conn);
return status;
}
psa_its_status_t psa_its_get(psa_its_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data)
psa_status_t psa_its_get(psa_storage_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data)
{
if (!p_data && data_length) {
return PSA_ITS_ERROR_INVALID_ARGUMENTS;
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_invec msg[2] = {
@ -59,31 +60,31 @@ psa_its_status_t psa_its_get(psa_its_uid_t uid, uint32_t data_offset, uint32_t d
psa_handle_t conn = psa_connect(PSA_ITS_GET, 1);
if (conn <= PSA_NULL_HANDLE) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
psa_status_t status = psa_call(conn, msg, 2, &resp, 1);
if (status == PSA_DROP_CONNECTION) {
status = PSA_ITS_ERROR_STORAGE_FAILURE;
status = PSA_ERROR_STORAGE_FAILURE;
}
psa_close(conn);
return status;
}
psa_its_status_t psa_its_get_info(psa_its_uid_t uid, struct psa_its_info_t *p_info)
psa_status_t psa_its_get_info(psa_storage_uid_t uid, struct psa_storage_info_t *p_info)
{
if (!p_info) {
return PSA_ITS_ERROR_INVALID_ARGUMENTS;
return PSA_ERROR_INVALID_ARGUMENT;
}
struct psa_its_info_t info = { 0, PSA_ITS_FLAG_NONE };
struct psa_storage_info_t info = { 0, PSA_STORAGE_FLAG_NONE };
psa_invec msg = { &uid, sizeof(uid) };
psa_outvec resp = { &info, sizeof(info) };
psa_handle_t conn = psa_connect(PSA_ITS_INFO, 1);
if (conn <= PSA_NULL_HANDLE) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
psa_status_t status = psa_call(conn, &msg, 1, &resp, 1);
@ -91,40 +92,40 @@ psa_its_status_t psa_its_get_info(psa_its_uid_t uid, struct psa_its_info_t *p_in
*p_info = info;
if (status == PSA_DROP_CONNECTION) {
status = PSA_ITS_ERROR_STORAGE_FAILURE;
status = PSA_ERROR_STORAGE_FAILURE;
}
psa_close(conn);
return status;
}
psa_its_status_t psa_its_remove(psa_its_uid_t uid)
psa_status_t psa_its_remove(psa_storage_uid_t uid)
{
psa_invec msg = { &uid, sizeof(uid) };
psa_handle_t conn = psa_connect(PSA_ITS_REMOVE, 1);
if (conn <= PSA_NULL_HANDLE) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
psa_status_t status = psa_call(conn, &msg, 1, NULL, 0);
if (status == PSA_DROP_CONNECTION) {
status = PSA_ITS_ERROR_STORAGE_FAILURE;
status = PSA_ERROR_STORAGE_FAILURE;
}
psa_close(conn);
return status;
}
psa_its_status_t psa_its_reset()
psa_status_t psa_its_reset()
{
psa_handle_t conn = psa_connect(PSA_ITS_RESET, 1);
if (conn <= PSA_NULL_HANDLE) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
psa_status_t status = psa_call(conn, NULL, 0, NULL, 0);
if (status == PSA_DROP_CONNECTION) {
status = PSA_ITS_ERROR_STORAGE_FAILURE;
status = PSA_ERROR_STORAGE_FAILURE;
}
psa_close(conn);

View File

@ -44,10 +44,10 @@ typedef psa_status_t (*SignalHandler)(psa_msg_t *);
static psa_status_t storage_set(psa_msg_t *msg)
{
psa_its_uid_t key = 0;
psa_storage_uid_t key = 0;
void *data = NULL;
uint32_t alloc_size = msg->in_size[1];
psa_its_create_flags_t flags = 0;
psa_storage_create_flags_t flags = 0;
if ((msg->in_size[0] != sizeof(key)) || (msg->in_size[2] != sizeof(flags))) {
return PSA_DROP_CONNECTION;
@ -63,17 +63,17 @@ static psa_status_t storage_set(psa_msg_t *msg)
data = malloc(alloc_size);
if (data == NULL) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
if (psa_read(msg->handle, 1, data, msg->in_size[1]) != msg->in_size[1]) {
free(data);
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
#if defined(TARGET_MBED_SPM)
psa_its_status_t status = psa_its_set_impl(psa_identity(msg->handle), key, alloc_size, data, flags);
psa_status_t status = psa_its_set_impl(psa_identity(msg->handle), key, alloc_size, data, flags);
#else
psa_its_status_t status = psa_its_set_impl(msg->client_id, key, alloc_size, data, flags);
psa_status_t status = psa_its_set_impl(msg->client_id, key, alloc_size, data, flags);
#endif
memset(data, 0, alloc_size);
free(data);
@ -82,7 +82,7 @@ static psa_status_t storage_set(psa_msg_t *msg)
static psa_status_t storage_get(psa_msg_t *msg)
{
psa_its_uid_t key = 0;
psa_storage_uid_t key = 0;
uint32_t offset = 0;
if ((msg->in_size[0] != sizeof(key)) || (msg->in_size[1] != sizeof(offset))) {
@ -99,16 +99,16 @@ static psa_status_t storage_get(psa_msg_t *msg)
uint8_t *data = (uint8_t *)malloc(msg->out_size[0]);
if (data == NULL) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
return PSA_ERROR_STORAGE_FAILURE;
}
#if defined(TARGET_MBED_SPM)
psa_its_status_t status = psa_its_get_impl(psa_identity(msg->handle), key, offset, msg->out_size[0], data);
psa_status_t status = psa_its_get_impl(psa_identity(msg->handle), key, offset, msg->out_size[0], data);
#else
psa_its_status_t status = psa_its_get_impl(msg->client_id, key, offset, msg->out_size[0], data);
psa_status_t status = psa_its_get_impl(msg->client_id, key, offset, msg->out_size[0], data);
#endif
if (status == PSA_ITS_SUCCESS) {
if (status == PSA_SUCCESS) {
psa_write(msg->handle, 0, data, msg->out_size[0]);
}
@ -119,8 +119,8 @@ static psa_status_t storage_get(psa_msg_t *msg)
static psa_status_t storage_info(psa_msg_t *msg)
{
struct psa_its_info_t info = { 0 };
psa_its_uid_t key = 0;
struct psa_storage_info_t info = { 0 };
psa_storage_uid_t key = 0;
if ((msg->in_size[0] != sizeof(key)) || (msg->out_size[0] != sizeof(info))) {
return PSA_DROP_CONNECTION;
@ -131,12 +131,12 @@ static psa_status_t storage_info(psa_msg_t *msg)
}
#if defined(TARGET_MBED_SPM)
psa_its_status_t status = psa_its_get_info_impl(psa_identity(msg->handle), key, &info);
psa_status_t status = psa_its_get_info_impl(psa_identity(msg->handle), key, &info);
#else
psa_its_status_t status = psa_its_get_info_impl(msg->client_id, key, &info);
psa_status_t status = psa_its_get_info_impl(msg->client_id, key, &info);
#endif
if (status == PSA_ITS_SUCCESS) {
if (status == PSA_SUCCESS) {
psa_write(msg->handle, 0, &info, msg->out_size[0]);
}
@ -145,7 +145,7 @@ static psa_status_t storage_info(psa_msg_t *msg)
static psa_status_t storage_remove(psa_msg_t *msg)
{
psa_its_uid_t key = 0;
psa_storage_uid_t key = 0;
if (msg->in_size[0] != sizeof(key)) {
return PSA_DROP_CONNECTION;

View File

@ -0,0 +1,145 @@
/* Copyright (C) 2019, 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.
*/
/** @file
@brief This file describes the PSA Internal Trusted Storage API
*/
#ifndef __PSA_INTERNAL_TRUSTED_STORAGE_H__
#define __PSA_INTERNAL_TRUSTED_STORAGE_H__
#include <stddef.h>
#include <stdint.h>
#include "psa/error.h"
#include "psa/storage_common.h"
#include "mbed_toolchain.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PSA_ITS_API_VERSION_MAJOR 1 /**< The major version number of the PSA ITS API. It will be incremented on significant updates that may include breaking changes */
#define PSA_ITS_API_VERSION_MINOR 1 /**< The minor version number of the PSA ITS API. It will be incremented in small updates that are unlikely to include breaking changes */
// These deprecated types are still used by our PSA compliance test tools
MBED_DEPRECATED("ITS specific types should not be used")
typedef psa_status_t psa_its_status_t;
MBED_DEPRECATED("ITS specific types should not be used")
typedef psa_storage_create_flags_t psa_its_create_flags_t;
MBED_DEPRECATED("ITS specific types should not be used")
typedef psa_storage_uid_t psa_its_uid_t;
MBED_DEPRECATED("ITS specific types should not be used")
struct psa_its_info_t {
uint32_t size;
psa_its_create_flags_t flags;
};
// These defines should also be deprecated
#define PSA_ITS_SUCCESS PSA_SUCCESS
#define PSA_ITS_ERROR_UID_NOT_FOUND PSA_ERROR_DOES_NOT_EXIST
#define PSA_ITS_ERROR_STORAGE_FAILURE PSA_ERROR_STORAGE_FAILURE
#define PSA_ITS_ERROR_INSUFFICIENT_SPACE PSA_ERROR_INSUFFICIENT_STORAGE
#define PSA_ITS_ERROR_OFFSET_INVALID PSA_ERROR_INVALID_ARGUMENT
#define PSA_ITS_ERROR_INCORRECT_SIZE PSA_ERROR_INVALID_ARGUMENT
#define PSA_ITS_ERROR_INVALID_ARGUMENTS PSA_ERROR_INVALID_ARGUMENT
#define PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED PSA_ERROR_NOT_SUPPORTED
#define PSA_ITS_ERROR_WRITE_ONCE PSA_ERROR_ALREADY_EXISTS
/**
* \brief create a new or modify an existing uid/value pair
*
* \param[in] uid the identifier for the data
* \param[in] data_length The size in bytes of the data in `p_data`
* \param[in] p_data A buffer containing the data
* \param[in] create_flags The flags that the data will be stored with
*
* \return A status indicating the success/failure of the operation
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_NOT_PERMITTED The operation failed because the provided `uid` value was already created with PSA_STORAGE_WRITE_ONCE_FLAG
* \retval PSA_ERROR_NOT_SUPPORTED The operation failed because one or more of the flags provided in `create_flags` is not supported or is not valid
* \retval PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because there was insufficient space on the storage medium
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
* \retval PSA_ERROR_INVALID_ARGUMENTS The operation failed because one of the provided pointers(`p_data`)
* is invalid, for example is `NULL` or references memory the caller cannot access
*/
psa_status_t psa_its_set(psa_storage_uid_t uid,
uint32_t data_length,
const void *p_data,
psa_storage_create_flags_t create_flags);
/**
* \brief Retrieve the value associated with a provided uid
*
* \param[in] uid The uid value
* \param[in] data_offset The starting offset of the data requested
* \param[in] data_length the amount of data requested (and the minimum allocated size of the `p_data` buffer)
* \param[out] p_data The buffer where the data will be placed upon successful completion
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided `uid` value was not found in the storage
* \retval PSA_ERROR_BUFFER_TOO_SMALL The operation failed because the data associated with provided `uid` is not the same size as `data_size`
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`, `p_data_length`)
* is invalid. For example is `NULL` or references memory the caller cannot access
*/
psa_status_t psa_its_get(psa_storage_uid_t uid,
uint32_t data_offset,
uint32_t data_length,
void *p_data);
/**
* \brief Retrieve the metadata about the provided uid
*
* \param[in] uid The uid value
* \param[out] p_info A pointer to the `psa_storage_info_t` struct that will be populated with the metadata
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided uid value was not found in the storage
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_info`)
* is invalid, for example is `NULL` or references memory the caller cannot access
*/
psa_status_t psa_its_get_info(psa_storage_uid_t uid,
struct psa_storage_info_t *p_info);
/**
* \brief Remove the provided key and its associated data from the storage
*
* \param[in] uid The uid value
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided key value was not found in the storage
* \retval PSA_ERROR_NOT_PERMITTED The operation failed because the provided key value was created with PSA_STORAGE_WRITE_ONCE_FLAG
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
*/
psa_status_t psa_its_remove(psa_storage_uid_t uid);
#ifdef __cplusplus
}
#endif
#endif // __PSA_INTERNAL_TRUSTED_STORAGE_H__

View File

@ -0,0 +1,139 @@
/* Copyright (c) 2019 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.
*/
#include <cstring>
#include "KVMap.h"
#include "KVStore.h"
#include "kv_config.h"
#include "TDBStore.h"
#include "psa/protected_storage.h"
#include "psa_storage_common_impl.h"
#include "mbed_error.h"
#include "mbed_toolchain.h"
using namespace mbed;
#ifdef __cplusplus
extern "C"
{
#endif
#define STR_EXPAND(tok) #tok
#define PS_VERSION_KEY "PSA_PS_VERSION" // PS version entry identifier in TDBStore
// Global PID for protected storage, used when calling IMPL functions
#define PSA_PS_GLOBAL_PID 1
static KVStore *kvstore = NULL;
MBED_WEAK psa_status_t ps_version_migrate(KVStore *kvstore,
const psa_storage_version_t *old_version, const psa_storage_version_t *new_version)
{
(void)kvstore;
(void)old_version;
(void)new_version;
return PSA_SUCCESS;
}
static void ps_init(void)
{
int ret = kv_init_storage_config();
if (ret) {
// Can only happen due to system misconfiguration.
// Thus considered as unrecoverable error for runtime.
error("Failed initializing kvstore configuration\n");
}
KVMap &kv_map = KVMap::get_instance();
psa_storage_version_t version = {PSA_PS_API_VERSION_MAJOR, PSA_PS_API_VERSION_MINOR};
kvstore = kv_map.get_main_kv_instance(STR_EXPAND(MBED_CONF_STORAGE_DEFAULT_KV));
if (!kvstore) {
// Can only happen due to system misconfiguration.
// Thus considered as unrecoverable error for runtime.
error("Failed getting kvstore instance\n");
}
psa_storage_handle_version(kvstore, PS_VERSION_KEY, &version, ps_version_migrate);
}
// used from test only
void ps_deinit(void)
{
kvstore = NULL;
}
psa_status_t psa_ps_set(psa_storage_uid_t uid, uint32_t data_length, const void *p_data, psa_storage_create_flags_t create_flags)
{
if (!kvstore) {
ps_init();
}
return psa_storage_set_impl(kvstore, PSA_PS_GLOBAL_PID, uid, data_length, p_data, create_flags);
}
psa_status_t psa_ps_get(psa_storage_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data)
{
if (!kvstore) {
ps_init();
}
return psa_storage_get_impl(kvstore, PSA_PS_GLOBAL_PID, uid, data_offset, data_length, p_data);
}
psa_status_t psa_ps_get_info(psa_storage_uid_t uid, struct psa_storage_info_t *p_info)
{
if (!kvstore) {
ps_init();
}
return psa_storage_get_info_impl(kvstore, PSA_PS_GLOBAL_PID, uid, p_info);
}
psa_status_t psa_ps_remove(psa_storage_uid_t uid)
{
if (!kvstore) {
ps_init();
}
return psa_storage_remove_impl(kvstore, PSA_PS_GLOBAL_PID, uid);
}
extern "C" psa_status_t psa_ps_reset()
{
// Do not call its_init here to avoid version check before reset
int ret = kv_init_storage_config();
if (ret) {
// Can only happen due to system misconfiguration.
// Thus considered as unrecoverable error for runtime.
error("Failed initializing kvstore configuration\n");
}
KVMap &kv_map = KVMap::get_instance();
kvstore = kv_map.get_main_kv_instance(STR_EXPAND(MBED_CONF_STORAGE_DEFAULT_KV));
if (!kvstore) {
// Can only happen due to system misconfiguration.
// Thus considered as unrecoverable error for runtime.
error("Failed getting kvstore instance\n");
}
return psa_storage_reset_impl(kvstore);
}
#ifdef __cplusplus
}
#endif

View File

@ -1 +1 @@
mbedcrypto-1.0.0d2
mbedcrypto-1.0.0d4

View File

@ -29,7 +29,7 @@
# Set the Mbed Crypto release to import (this can/should be edited before
# import)
CRYPTO_RELEASE ?= mbedcrypto-1.0.0d2
CRYPTO_RELEASE ?= mbedcrypto-1.0.0d4
CRYPTO_REPO_URL ?= git@github.com:ARMmbed/mbed-crypto.git
# Translate between Mbed Crypto namespace and Mbed OS namespace

File diff suppressed because it is too large Load Diff

View File

@ -111,7 +111,6 @@ void mbedtls_psa_crypto_free( void );
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p seed_size is out of range.
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval `PSA_ITS_ERROR_XXX`
* There was a failure reading or writing from storage.
* \retval #PSA_ERROR_NOT_PERMITTED
* The library has already been initialized. It is no longer

View File

@ -49,4 +49,53 @@
/* Integral type representing a key handle. */
typedef uint16_t psa_key_handle_t;
/* This implementation distinguishes *application key identifiers*, which
* are the key identifiers specified by the application, from
* *key file identifiers*, which are the key identifiers that the library
* sees internally. The two types can be different if there is a remote
* call layer between the application and the library which supports
* multiple client applications that do not have access to each others'
* keys. The point of having different types is that the key file
* identifier may encode not only the key identifier specified by the
* application, but also the the identity of the application.
*
* Note that this is an internal concept of the library and the remote
* call layer. The application itself never sees anything other than
* #psa_app_key_id_t with its standard definition.
*/
/* The application key identifier is always what the application sees as
* #psa_key_id_t. */
typedef uint32_t psa_app_key_id_t;
#if defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER)
#if defined(PSA_CRYPTO_SECURE)
/* Building for the PSA Crypto service on a PSA platform. */
/* A key owner is a PSA partition identifier. */
typedef int32_t psa_key_owner_id_t;
#endif
typedef struct
{
uint32_t key_id;
psa_key_owner_id_t owner;
} psa_key_file_id_t;
#define PSA_KEY_FILE_GET_KEY_ID( file_id ) ( ( file_id ).key_id )
/* Since crypto.h is used as part of the PSA Cryptography API specification,
* it must use standard types for things like the argument of psa_open_key().
* If it wasn't for that constraint, psa_open_key() would take a
* `psa_key_file_id_t` argument. As a workaround, make `psa_key_id_t` an
* alias for `psa_key_file_id_t` when building for a multi-client service. */
typedef psa_key_file_id_t psa_key_id_t;
#else /* !MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */
/* By default, a key file identifier is just the application key identifier. */
typedef psa_app_key_id_t psa_key_file_id_t;
#define PSA_KEY_FILE_GET_KEY_ID( id ) ( id )
#endif /* !MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */
#endif /* PSA_CRYPTO_PLATFORM_H */

View File

@ -754,7 +754,7 @@ typedef psa_status_t (*psa_drv_destroy_key_t)(psa_key_slot_t key);
* that make up the key data.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_EMPTY_SLOT
* \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_COMMUNICATION_FAILURE

View File

@ -294,7 +294,7 @@
#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \
(PSA_ALG_IS_RSA_OAEP(alg) ? \
2 * PSA_HASH_FINAL_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \
2 * PSA_HASH_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \
11 /*PKCS#1v1.5*/)
/**

View File

@ -47,8 +47,13 @@
* This is either #PSA_SUCCESS (which is zero), indicating success,
* or a nonzero value indicating that an error occurred. Errors are
* encoded as one of the \c PSA_ERROR_xxx values defined here.
* If #PSA_SUCCESS is already defined, it means that #psa_status_t
* is also defined in an external header, so prevent its multiple
* definition.
*/
#ifndef PSA_SUCCESS
typedef int32_t psa_status_t;
#endif
/**@}*/
@ -85,7 +90,14 @@ typedef uint32_t psa_key_lifetime_t;
/** Encoding of identifiers of persistent keys.
*/
/* Implementation-specific quirk: The Mbed Crypto library can be built as
* part of a multi-client service that exposes the PSA Crypto API in each
* client and encodes the client identity in the key id argument of functions
* such as psa_open_key(). In this build configuration, we define
* psa_key_id_t in crypto_platform.h instead of here. */
#if !defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER)
typedef uint32_t psa_key_id_t;
#endif
/**@}*/

View File

@ -40,25 +40,17 @@
* @{
*/
#if !defined(PSA_SUCCESS)
/* If PSA_SUCCESS is defined, assume that PSA crypto is being used
* together with PSA IPC, which also defines the identifier
* PSA_SUCCESS. We must not define PSA_SUCCESS ourselves in that case;
* the other error code names don't clash. This is a temporary hack
* until we unify error reporting in PSA IPC and PSA crypto.
*
* Note that psa_defs.h must be included before this header!
*/
/* PSA error codes */
/** The action was completed successfully. */
#define PSA_SUCCESS ((psa_status_t)0)
#endif /* !defined(PSA_SUCCESS) */
/** An error occurred that does not correspond to any defined
* failure cause.
*
* Implementations may use this error code if none of the other standard
* error codes are applicable. */
#define PSA_ERROR_UNKNOWN_ERROR ((psa_status_t)1)
#define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132)
/** The requested operation or a parameter is not supported
* by this implementation.
@ -67,7 +59,7 @@
* parameter such as a key type, algorithm, etc. is not recognized.
* If a combination of parameters is recognized and identified as
* not valid, return #PSA_ERROR_INVALID_ARGUMENT instead. */
#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)2)
#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134)
/** The requested action is denied by a policy.
*
@ -80,7 +72,7 @@
* not valid or not supported, it is unspecified whether the function
* returns #PSA_ERROR_NOT_PERMITTED, #PSA_ERROR_NOT_SUPPORTED or
* #PSA_ERROR_INVALID_ARGUMENT. */
#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)3)
#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133)
/** An output buffer is too small.
*
@ -92,23 +84,19 @@
* buffer would succeed. However implementations may return this
* error if a function has invalid or unsupported parameters in addition
* to the parameters that determine the necessary output buffer size. */
#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)4)
#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138)
/** A slot is occupied, but must be empty to carry out the
* requested action.
/** Asking for an item that already exists
*
* If a handle is invalid, it does not designate an occupied slot.
* The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE.
*/
#define PSA_ERROR_OCCUPIED_SLOT ((psa_status_t)5)
* Implementations should return this error, when attempting
* to write an item (like a key) that already exists. */
#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139)
/** A slot is empty, but must be occupied to carry out the
* requested action.
/** Asking for an item that doesn't exist
*
* If a handle is invalid, it does not designate an empty slot.
* The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE.
*/
#define PSA_ERROR_EMPTY_SLOT ((psa_status_t)6)
* Implementations should return this error, if a requested item (like
* a key) does not exist. */
#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140)
/** The requested action cannot be performed in the current state.
*
@ -118,9 +106,9 @@
*
* Implementations shall not return this error code to indicate
* that a key slot is occupied when it needs to be free or vice versa,
* but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT
* but shall return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
* as applicable. */
#define PSA_ERROR_BAD_STATE ((psa_status_t)7)
#define PSA_ERROR_BAD_STATE ((psa_status_t)-137)
/** The parameters passed to the function are invalid.
*
@ -129,20 +117,20 @@
*
* Implementations shall not return this error code to indicate
* that a key slot is occupied when it needs to be free or vice versa,
* but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT
* but shall return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
* as applicable.
*
* Implementation shall not return this error code to indicate that a
* key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
* instead.
*/
#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)8)
#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135)
/** There is not enough runtime memory.
*
* If the action is carried out across multiple security realms, this
* error can refer to available memory in any of the security realms. */
#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)9)
#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141)
/** There is not enough persistent storage.
*
@ -151,7 +139,7 @@
* many functions that do not otherwise access storage may return this
* error code if the implementation requires a mandatory log entry for
* the requested action and the log storage space is full. */
#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)10)
#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142)
/** There was a communication failure inside the implementation.
*
@ -168,7 +156,7 @@
* cryptoprocessor but there was a breakdown of communication before
* the cryptoprocessor could report the status to the application.
*/
#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)11)
#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145)
/** There was a storage failure that may have led to data loss.
*
@ -193,13 +181,13 @@
* permanent storage corruption. However application writers should
* keep in mind that transient errors while reading the storage may be
* reported using this error code. */
#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)12)
#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146)
/** A hardware failure was detected.
*
* A hardware failure may be transient or permanent depending on the
* cause. */
#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)13)
#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147)
/** A tampering attempt was detected.
*
@ -230,7 +218,7 @@
* This error indicates an attack against the application. Implementations
* shall not return this error code as a consequence of the behavior of
* the application itself. */
#define PSA_ERROR_TAMPERING_DETECTED ((psa_status_t)14)
#define PSA_ERROR_TAMPERING_DETECTED ((psa_status_t)-151)
/** There is not enough entropy to generate random data needed
* for the requested action.
@ -249,7 +237,7 @@
* secure pseudorandom generator (PRNG). However implementations may return
* this error at any time if a policy requires the PRNG to be reseeded
* during normal operation. */
#define PSA_ERROR_INSUFFICIENT_ENTROPY ((psa_status_t)15)
#define PSA_ERROR_INSUFFICIENT_ENTROPY ((psa_status_t)-148)
/** The signature, MAC or hash is incorrect.
*
@ -259,7 +247,7 @@
*
* If the value to verify has an invalid size, implementations may return
* either #PSA_ERROR_INVALID_ARGUMENT or #PSA_ERROR_INVALID_SIGNATURE. */
#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)16)
#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149)
/** The decrypted padding is incorrect.
*
@ -275,17 +263,15 @@
* as close as possible to indistinguishable to an external observer.
* In particular, the timing of a decryption operation should not
* depend on the validity of the padding. */
#define PSA_ERROR_INVALID_PADDING ((psa_status_t)17)
#define PSA_ERROR_INVALID_PADDING ((psa_status_t)-150)
/** The generator has insufficient capacity left.
*
* Once a function returns this error, attempts to read from the
* generator will always return this error. */
#define PSA_ERROR_INSUFFICIENT_CAPACITY ((psa_status_t)18)
/** Return this error when there's insufficient data when attempting
* to read from a resource. */
#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
/** The key handle is not valid.
*/
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)19)
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
/**@}*/
@ -766,7 +752,7 @@
* algorithm is considered identical to the untruncated algorithm
* for policy comparison purposes.
*
* \param alg A MAC algorithm identifier (value of type
* \param mac_alg A MAC algorithm identifier (value of type
* #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg)
* is true). This may be a truncated or untruncated
* MAC algorithm.
@ -782,14 +768,14 @@
* MAC algorithm or if \p mac_length is too small or
* too large for the specified MAC algorithm.
*/
#define PSA_ALG_TRUNCATED_MAC(alg, mac_length) \
(((alg) & ~PSA_ALG_MAC_TRUNCATION_MASK) | \
#define PSA_ALG_TRUNCATED_MAC(mac_alg, mac_length) \
(((mac_alg) & ~PSA_ALG_MAC_TRUNCATION_MASK) | \
((mac_length) << PSA_MAC_TRUNCATION_OFFSET & PSA_ALG_MAC_TRUNCATION_MASK))
/** Macro to build the base MAC algorithm corresponding to a truncated
* MAC algorithm.
*
* \param alg A MAC algorithm identifier (value of type
* \param mac_alg A MAC algorithm identifier (value of type
* #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg)
* is true). This may be a truncated or untruncated
* MAC algorithm.
@ -798,12 +784,12 @@
* \return Unspecified if \p alg is not a supported
* MAC algorithm.
*/
#define PSA_ALG_FULL_LENGTH_MAC(alg) \
((alg) & ~PSA_ALG_MAC_TRUNCATION_MASK)
#define PSA_ALG_FULL_LENGTH_MAC(mac_alg) \
((mac_alg) & ~PSA_ALG_MAC_TRUNCATION_MASK)
/** Length to which a MAC algorithm is truncated.
*
* \param alg A MAC algorithm identifier (value of type
* \param mac_alg A MAC algorithm identifier (value of type
* #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg)
* is true).
*
@ -812,8 +798,8 @@
* \return Unspecified if \p alg is not a supported
* MAC algorithm.
*/
#define PSA_MAC_TRUNCATED_LENGTH(alg) \
(((alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET)
#define PSA_MAC_TRUNCATED_LENGTH(mac_alg) \
(((mac_alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET)
#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x02c00000)
#define PSA_ALG_CBC_MAC ((psa_algorithm_t)0x02c00001)
@ -910,7 +896,7 @@
* Depending on the algorithm, the tag length may affect the calculation
* of the ciphertext.
*
* \param alg A AEAD algorithm identifier (value of type
* \param aead_alg An AEAD algorithm identifier (value of type
* #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p alg)
* is true).
* \param tag_length Desired length of the authentication tag in bytes.
@ -921,26 +907,26 @@
* AEAD algorithm or if \p tag_length is not valid
* for the specified AEAD algorithm.
*/
#define PSA_ALG_AEAD_WITH_TAG_LENGTH(alg, tag_length) \
(((alg) & ~PSA_ALG_AEAD_TAG_LENGTH_MASK) | \
#define PSA_ALG_AEAD_WITH_TAG_LENGTH(aead_alg, tag_length) \
(((aead_alg) & ~PSA_ALG_AEAD_TAG_LENGTH_MASK) | \
((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET & \
PSA_ALG_AEAD_TAG_LENGTH_MASK))
/** Calculate the corresponding AEAD algorithm with the default tag length.
*
* \param alg An AEAD algorithm (\c PSA_ALG_XXX value such that
* \param aead_alg An AEAD algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
*
* \return The corresponding AEAD algorithm with the default tag length
* for that algorithm.
* \return The corresponding AEAD algorithm with the default
* tag length for that algorithm.
*/
#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) \
#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(aead_alg) \
( \
PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, PSA_ALG_CCM) \
PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, PSA_ALG_GCM) \
PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, PSA_ALG_CCM) \
PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, PSA_ALG_GCM) \
0)
#define PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, ref) \
PSA_ALG_AEAD_WITH_TAG_LENGTH(alg, 0) == \
#define PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, ref) \
PSA_ALG_AEAD_WITH_TAG_LENGTH(aead_alg, 0) == \
PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ? \
ref :

View File

@ -26,22 +26,8 @@
#endif
#if defined(MBEDTLS_PSA_CRYPTO_C)
/*
* When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is being built for SPM
* (Secure Partition Manager) integration which separates the code into two
* parts: NSPE (Non-Secure Processing Environment) and SPE (Secure Processing
* Environment). When building for the SPE, an additional header file should be
* included.
*/
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
/*
* PSA_CRYPTO_SECURE means that this file is compiled for the SPE.
* Some headers will be affected by this flag.
*/
#define PSA_CRYPTO_SECURE 1
#include "crypto_spe.h"
#endif
#include "psa_crypto_service_integration.h"
#include "psa/crypto.h"
#include "psa_crypto_core.h"
@ -172,13 +158,21 @@ static psa_status_t mbedtls_to_psa_error( int ret )
case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
return( PSA_ERROR_BUFFER_TOO_SMALL );
#if defined(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA)
case MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA:
#elif defined(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH)
case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
#endif
case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
return( PSA_ERROR_NOT_SUPPORTED );
case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
return( PSA_ERROR_HARDWARE_FAILURE );
#if defined(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA:
#elif defined(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH)
case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
#endif
case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
return( PSA_ERROR_NOT_SUPPORTED );
case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
@ -346,7 +340,7 @@ static psa_status_t mbedtls_to_psa_error( int ret )
return( PSA_ERROR_HARDWARE_FAILURE );
default:
return( PSA_ERROR_UNKNOWN_ERROR );
return( PSA_ERROR_GENERIC_ERROR );
}
}
@ -742,12 +736,38 @@ static psa_status_t psa_get_empty_key_slot( psa_key_handle_t handle,
return( status );
if( slot->type != PSA_KEY_TYPE_NONE )
return( PSA_ERROR_OCCUPIED_SLOT );
return( PSA_ERROR_ALREADY_EXISTS );
*p_slot = slot;
return( status );
}
/** Calculate the intersection of two algorithm usage policies.
*
* Return 0 (which allows no operation) on incompatibility.
*/
static psa_algorithm_t psa_key_policy_algorithm_intersection(
psa_algorithm_t alg1,
psa_algorithm_t alg2 )
{
/* Common case: the policy only allows alg. */
if( alg1 == alg2 )
return( alg1 );
/* If the policies are from the same hash-and-sign family, check
* if one is a wildcard. If so the other has the specific algorithm. */
if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) &&
PSA_ALG_IS_HASH_AND_SIGN( alg2 ) &&
( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
{
if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
return( alg2 );
if( PSA_ALG_SIGN_GET_HASH( alg2 ) == PSA_ALG_ANY_HASH )
return( alg1 );
}
/* If the policies are incompatible, allow nothing. */
return( 0 );
}
/** Test whether a policy permits an algorithm.
*
* The caller must test usage flags separately.
@ -771,6 +791,31 @@ static int psa_key_policy_permits( const psa_key_policy_t *policy,
return( 0 );
}
/** Restrict a key policy based on a constraint.
*
* \param[in,out] policy The policy to restrict.
* \param[in] constraint The policy constraint to apply.
*
* \retval #PSA_SUCCESS
* \c *policy contains the intersection of the original value of
* \c *policy and \c *constraint.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \c *policy and \c *constraint are incompatible.
* \c *policy is unchanged.
*/
static psa_status_t psa_restrict_key_policy(
psa_key_policy_t *policy,
const psa_key_policy_t *constraint )
{
psa_algorithm_t intersection_alg =
psa_key_policy_algorithm_intersection( policy->alg, constraint->alg );
if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 )
return( PSA_ERROR_INVALID_ARGUMENT );
policy->usage &= constraint->usage;
policy->alg = intersection_alg;
return( PSA_SUCCESS );
}
/** Retrieve a slot which must contain a key. The key must have allow all the
* usage flags set in \p usage. If \p alg is nonzero, the key must allow
* operations with this algorithm. */
@ -788,7 +833,7 @@ static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle,
if( status != PSA_SUCCESS )
return( status );
if( slot->type == PSA_KEY_TYPE_NONE )
return( PSA_ERROR_EMPTY_SLOT );
return( PSA_ERROR_DOES_NOT_EXIST );
/* Enforce that usage policy for the key slot contains all the flags
* required by the usage parameter. There is one exception: public
@ -950,7 +995,7 @@ psa_status_t psa_get_key_information( psa_key_handle_t handle,
return( status );
if( slot->type == PSA_KEY_TYPE_NONE )
return( PSA_ERROR_EMPTY_SLOT );
return( PSA_ERROR_DOES_NOT_EXIST );
if( type != NULL )
*type = slot->type;
if( bits != NULL )
@ -974,7 +1019,7 @@ static int pk_write_pubkey_simple( mbedtls_pk_context *key,
}
#endif /* defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C) */
static psa_status_t psa_internal_export_key( psa_key_slot_t *slot,
static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot,
uint8_t *data,
size_t data_size,
size_t *data_length,
@ -1165,6 +1210,65 @@ exit:
}
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
psa_key_handle_t target )
{
psa_status_t status;
uint8_t *buffer = NULL;
size_t buffer_size = 0;
size_t length;
buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->type,
psa_get_key_bits( source ) );
buffer = mbedtls_calloc( 1, buffer_size );
if( buffer == NULL && buffer_size != 0 )
return( PSA_ERROR_INSUFFICIENT_MEMORY );
status = psa_internal_export_key( source, buffer, buffer_size, &length, 0 );
if( status != PSA_SUCCESS )
goto exit;
status = psa_import_key( target, source->type, buffer, length );
exit:
if( buffer_size != 0 )
mbedtls_platform_zeroize( buffer, buffer_size );
mbedtls_free( buffer );
return( status );
}
psa_status_t psa_copy_key(psa_key_handle_t source_handle,
psa_key_handle_t target_handle,
const psa_key_policy_t *constraint)
{
psa_key_slot_t *source_slot = NULL;
psa_key_slot_t *target_slot = NULL;
psa_key_policy_t new_policy;
psa_status_t status;
status = psa_get_key_from_slot( source_handle, &source_slot, 0, 0 );
if( status != PSA_SUCCESS )
return( status );
status = psa_get_empty_key_slot( target_handle, &target_slot );
if( status != PSA_SUCCESS )
return( status );
new_policy = target_slot->policy;
status = psa_restrict_key_policy( &new_policy, &source_slot->policy );
if( status != PSA_SUCCESS )
return( status );
if( constraint != NULL )
{
status = psa_restrict_key_policy( &new_policy, constraint );
if( status != PSA_SUCCESS )
return( status );
}
status = psa_copy_key_material( source_slot, target_handle );
if( status != PSA_SUCCESS )
return( status );
target_slot->policy = new_policy;
return( PSA_SUCCESS );
}
/****************************************************************/
@ -2988,7 +3092,7 @@ psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
size_t output_size,
size_t *output_length )
{
psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
@ -3511,6 +3615,12 @@ psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
size_t *capacity)
{
if( generator->alg == 0 )
{
/* This is a blank generator. */
return PSA_ERROR_BAD_STATE;
}
*capacity = generator->capacity;
return( PSA_SUCCESS );
}
@ -3740,24 +3850,29 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
{
psa_status_t status;
if( generator->alg == 0 )
{
/* This is a blank generator. */
return PSA_ERROR_BAD_STATE;
}
if( output_length > generator->capacity )
{
generator->capacity = 0;
/* Go through the error path to wipe all confidential data now
* that the generator object is useless. */
status = PSA_ERROR_INSUFFICIENT_CAPACITY;
status = PSA_ERROR_INSUFFICIENT_DATA;
goto exit;
}
if( output_length == 0 &&
generator->capacity == 0 && generator->alg == 0 )
if( output_length == 0 && generator->capacity == 0 )
{
/* Edge case: this is a blank or finished generator, and 0
* bytes were requested. The right error in this case could
/* Edge case: this is a finished generator, and 0 bytes
* were requested. The right error in this case could
* be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
* INSUFFICIENT_CAPACITY, which is right for a finished
* generator, for consistency with the case when
* output_length > 0. */
return( PSA_ERROR_INSUFFICIENT_CAPACITY );
return( PSA_ERROR_INSUFFICIENT_DATA );
}
generator->capacity -= output_length;
@ -3801,7 +3916,13 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
exit:
if( status != PSA_SUCCESS )
{
/* Preserve the algorithm upon errors, but clear all sensitive state.
* This allows us to differentiate between exhausted generators and
* blank generators, so we can return PSA_ERROR_BAD_STATE on blank
* generators. */
psa_algorithm_t alg = generator->alg;
psa_generator_abort( generator );
generator->alg = alg;
memset( output, '!', output_length );
}
return( status );
@ -4281,45 +4402,11 @@ psa_status_t psa_generate_random( uint8_t *output,
#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
/* Support function for error conversion between psa_its error codes to psa crypto */
static psa_status_t its_to_psa_error( psa_its_status_t ret )
{
switch( ret )
{
case PSA_ITS_SUCCESS:
return( PSA_SUCCESS );
case PSA_ITS_ERROR_UID_NOT_FOUND:
return( PSA_ERROR_EMPTY_SLOT );
case PSA_ITS_ERROR_STORAGE_FAILURE:
return( PSA_ERROR_STORAGE_FAILURE );
case PSA_ITS_ERROR_INSUFFICIENT_SPACE:
return( PSA_ERROR_INSUFFICIENT_STORAGE );
case PSA_ITS_ERROR_OFFSET_INVALID:
case PSA_ITS_ERROR_INCORRECT_SIZE:
case PSA_ITS_ERROR_INVALID_ARGUMENTS:
return( PSA_ERROR_INVALID_ARGUMENT );
case PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED:
return( PSA_ERROR_NOT_SUPPORTED );
case PSA_ITS_ERROR_WRITE_ONCE:
return( PSA_ERROR_OCCUPIED_SLOT );
default:
return( PSA_ERROR_UNKNOWN_ERROR );
}
}
psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
size_t seed_size )
{
psa_status_t status;
psa_its_status_t its_status;
struct psa_its_info_t p_info;
struct psa_storage_info_t p_info;
if( global_data.initialized )
return( PSA_ERROR_NOT_PERMITTED );
@ -4328,15 +4415,13 @@ psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
return( PSA_ERROR_INVALID_ARGUMENT );
its_status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
status = its_to_psa_error( its_status );
status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
if( PSA_ITS_ERROR_UID_NOT_FOUND == its_status ) /* No seed exists */
if( PSA_ERROR_DOES_NOT_EXIST == status ) /* No seed exists */
{
its_status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
status = its_to_psa_error( its_status );
status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
}
else if( PSA_ITS_SUCCESS == its_status )
else if( PSA_SUCCESS == status )
{
/* You should not be here. Seed needs to be injected only once */
status = PSA_ERROR_NOT_PERMITTED;

View File

@ -41,7 +41,7 @@ typedef struct
psa_key_type_t type;
psa_key_policy_t policy;
psa_key_lifetime_t lifetime;
psa_key_id_t persistent_storage_id;
psa_key_file_id_t persistent_storage_id;
unsigned allocated : 1;
union
{

View File

@ -0,0 +1,40 @@
/* Copyright (C) 2019, 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.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef PSA_CRYPTO_SERVICE_INTEGRATION_H
#define PSA_CRYPTO_SERVICE_INTEGRATION_H
/*
* When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is being built for SPM
* (Secure Partition Manager) integration which separates the code into two
* parts: NSPE (Non-Secure Processing Environment) and SPE (Secure Processing
* Environment). When building for the SPE, an additional header file should be
* included.
*/
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
/*
* PSA_CRYPTO_SECURE means that the file which included this file is being
* compiled for SPE. The files crypto_structs.h and crypto_types.h have
* different implementations for NSPE and SPE and are compiled according to this
* flag.
*/
#define PSA_CRYPTO_SECURE 1
#include "crypto_spe.h"
#endif // MBEDTLS_PSA_CRYPTO_SPM
#endif // PSA_CRYPTO_SERVICE_INTEGRATION_H

View File

@ -26,22 +26,8 @@
#endif
#if defined(MBEDTLS_PSA_CRYPTO_C)
/*
* When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is being built for SPM
* (Secure Partition Manager) integration which separates the code into two
* parts: NSPE (Non-Secure Processing Environment) and SPE (Secure Processing
* Environment). When building for the SPE, an additional header file should be
* included.
*/
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
/*
* PSA_CRYPTO_SECURE means that this file is compiled for the SPE.
* Some headers will be affected by this flag.
*/
#define PSA_CRYPTO_SECURE 1
#include "crypto_spe.h"
#endif
#include "psa_crypto_service_integration.h"
#include "psa/crypto.h"
#include "psa_crypto_core.h"
@ -182,6 +168,30 @@ exit:
psa_free_persistent_key_data( key_data, key_data_length );
return( status );
}
/** Check whether a key identifier is acceptable.
*
* For backward compatibility, key identifiers that were valid in a
* past released version must remain valid, unless a migration path
* is provided.
*
* \param file_id The key identifier to check.
*
* \return 1 if \p file_id is acceptable, otherwise 0.
*/
static int psa_is_key_id_valid( psa_key_file_id_t file_id )
{
psa_app_key_id_t key_id = PSA_KEY_FILE_GET_KEY_ID( file_id );
/* Reject id=0 because by general library conventions, 0 is an invalid
* value wherever possible. */
if( key_id == 0 )
return( 0 );
/* Reject high values because the file names are reserved for the
* library's internal use. */
if( key_id > PSA_MAX_PERSISTENT_KEY_IDENTIFIER )
return( 0 );
return( 1 );
}
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
/** Declare a slot as persistent and load it from storage.
@ -194,7 +204,7 @@ exit:
*
* \retval #PSA_SUCCESS
* The slot content was loaded successfully.
* \retval #PSA_ERROR_EMPTY_SLOT
* \retval #PSA_ERROR_DOES_NOT_EXIST
* There is no content for this slot in persistent storage.
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_INVALID_ARGUMENT
@ -203,19 +213,13 @@ exit:
* \retval #PSA_ERROR_STORAGE_FAILURE
*/
static psa_status_t psa_internal_make_key_persistent( psa_key_handle_t handle,
psa_key_id_t id )
psa_key_file_id_t id )
{
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
psa_key_slot_t *slot;
psa_status_t status;
/* Reject id=0 because by general library conventions, 0 is an invalid
* value wherever possible. */
if( id == 0 )
return( PSA_ERROR_INVALID_ARGUMENT );
/* Reject high values because the file names are reserved for the
* library's internal use. */
if( id >= PSA_MAX_PERSISTENT_KEY_IDENTIFIER )
if( ! psa_is_key_id_valid( id ) )
return( PSA_ERROR_INVALID_ARGUMENT );
status = psa_get_key_slot( handle, &slot );
@ -236,7 +240,7 @@ static psa_status_t psa_internal_make_key_persistent( psa_key_handle_t handle,
}
static psa_status_t persistent_key_setup( psa_key_lifetime_t lifetime,
psa_key_id_t id,
psa_key_file_id_t id,
psa_key_handle_t *handle,
psa_status_t wanted_load_status )
{
@ -261,24 +265,24 @@ static psa_status_t persistent_key_setup( psa_key_lifetime_t lifetime,
}
psa_status_t psa_open_key( psa_key_lifetime_t lifetime,
psa_key_id_t id,
psa_key_file_id_t id,
psa_key_handle_t *handle )
{
return( persistent_key_setup( lifetime, id, handle, PSA_SUCCESS ) );
}
psa_status_t psa_create_key( psa_key_lifetime_t lifetime,
psa_key_id_t id,
psa_key_file_id_t id,
psa_key_handle_t *handle )
{
psa_status_t status;
status = persistent_key_setup( lifetime, id, handle,
PSA_ERROR_EMPTY_SLOT );
PSA_ERROR_DOES_NOT_EXIST );
switch( status )
{
case PSA_SUCCESS: return( PSA_ERROR_OCCUPIED_SLOT );
case PSA_ERROR_EMPTY_SLOT: return( PSA_SUCCESS );
case PSA_SUCCESS: return( PSA_ERROR_ALREADY_EXISTS );
case PSA_ERROR_DOES_NOT_EXIST: return( PSA_SUCCESS );
default: return( status );
}
}

View File

@ -30,6 +30,7 @@
#include <stdlib.h>
#include <string.h>
#include "psa_crypto_service_integration.h"
#include "psa/crypto.h"
#include "psa_crypto_storage.h"
#include "psa_crypto_storage_backend.h"
@ -38,6 +39,7 @@
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
@ -147,7 +149,7 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
return( PSA_SUCCESS );
}
psa_status_t psa_save_persistent_key( const psa_key_id_t key,
psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
const psa_key_type_t type,
const psa_key_policy_t *policy,
const uint8_t *data,
@ -185,7 +187,7 @@ void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length )
mbedtls_free( key_data );
}
psa_status_t psa_load_persistent_key( psa_key_id_t key,
psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
psa_key_type_t *type,
psa_key_policy_t *policy,
uint8_t **data,

View File

@ -59,7 +59,7 @@ extern "C" {
* This limitation will probably become moot when we implement client
* separation for key storage.
*/
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xffff0000
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xfffeffff
/**
* \brief Format key data and metadata and save to a location for given key
@ -84,9 +84,9 @@ extern "C" {
* \retval PSA_ERROR_INSUFFICIENT_MEMORY
* \retval PSA_ERROR_INSUFFICIENT_STORAGE
* \retval PSA_ERROR_STORAGE_FAILURE
* \retval PSA_ERROR_OCCUPIED_SLOT
* \retval PSA_ERROR_ALREADY_EXISTS
*/
psa_status_t psa_save_persistent_key( const psa_key_id_t key,
psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
const psa_key_type_t type,
const psa_key_policy_t *policy,
const uint8_t *data,
@ -115,9 +115,9 @@ psa_status_t psa_save_persistent_key( const psa_key_id_t key,
* \retval PSA_SUCCESS
* \retval PSA_ERROR_INSUFFICIENT_MEMORY
* \retval PSA_ERROR_STORAGE_FAILURE
* \retval PSA_ERROR_EMPTY_SLOT
* \retval PSA_ERROR_DOES_NOT_EXIST
*/
psa_status_t psa_load_persistent_key( psa_key_id_t key,
psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
psa_key_type_t *type,
psa_key_policy_t *policy,
uint8_t **data,
@ -134,7 +134,7 @@ psa_status_t psa_load_persistent_key( psa_key_id_t key,
* or the key did not exist.
* \retval PSA_ERROR_STORAGE_FAILURE
*/
psa_status_t psa_destroy_persistent_key( const psa_key_id_t key );
psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key );
/**
* \brief Free the temporary buffer allocated by psa_load_persistent_key().

View File

@ -54,9 +54,9 @@ extern "C" {
*
* \retval PSA_SUCCESS
* \retval PSA_ERROR_STORAGE_FAILURE
* \retval PSA_ERROR_EMPTY_SLOT
* \retval PSA_ERROR_DOES_NOT_EXIST
*/
psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key, uint8_t *data,
size_t data_size );
/**
@ -73,9 +73,9 @@ psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
* \retval PSA_SUCCESS
* \retval PSA_ERROR_INSUFFICIENT_STORAGE
* \retval PSA_ERROR_STORAGE_FAILURE
* \retval PSA_ERROR_OCCUPIED_SLOT
* \retval PSA_ERROR_ALREADY_EXISTS
*/
psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key,
const uint8_t *data,
size_t data_length );
@ -92,7 +92,7 @@ psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
* \retval 1
* Persistent data present for slot number
*/
int psa_is_key_present_in_storage( const psa_key_id_t key );
int psa_is_key_present_in_storage( const psa_key_file_id_t key );
/**
* \brief Get data length for given key slot number.
@ -104,7 +104,7 @@ int psa_is_key_present_in_storage( const psa_key_id_t key );
* \retval PSA_SUCCESS
* \retval PSA_ERROR_STORAGE_FAILURE
*/
psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key,
psa_status_t psa_crypto_storage_get_data_length( const psa_key_file_id_t key,
size_t *data_length );

View File

@ -36,6 +36,7 @@
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_snprintf snprintf
#endif
@ -48,7 +49,7 @@
enum { MAX_LOCATION_LEN = sizeof(CRYPTO_STORAGE_FILE_LOCATION) + 40 };
static void key_id_to_location( const psa_key_id_t key,
static void key_id_to_location( const psa_key_file_id_t key,
char *location,
size_t location_size )
{
@ -57,7 +58,7 @@ static void key_id_to_location( const psa_key_id_t key,
(unsigned long) key );
}
psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key, uint8_t *data,
size_t data_size )
{
psa_status_t status = PSA_SUCCESS;
@ -82,7 +83,7 @@ exit:
return( status );
}
int psa_is_key_present_in_storage( const psa_key_id_t key )
int psa_is_key_present_in_storage( const psa_key_file_id_t key )
{
char slot_location[MAX_LOCATION_LEN];
FILE *file;
@ -100,7 +101,7 @@ int psa_is_key_present_in_storage( const psa_key_id_t key )
return( 1 );
}
psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key,
const uint8_t *data,
size_t data_length )
{
@ -118,7 +119,7 @@ psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
key_id_to_location( key, slot_location, MAX_LOCATION_LEN );
if( psa_is_key_present_in_storage( key ) == 1 )
return( PSA_ERROR_OCCUPIED_SLOT );
return( PSA_ERROR_ALREADY_EXISTS );
file = fopen( temp_location, "wb" );
if( file == NULL )
@ -155,7 +156,7 @@ exit:
return( status );
}
psa_status_t psa_destroy_persistent_key( const psa_key_id_t key )
psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key )
{
FILE *file;
char slot_location[MAX_LOCATION_LEN];
@ -174,7 +175,7 @@ psa_status_t psa_destroy_persistent_key( const psa_key_id_t key )
return( PSA_SUCCESS );
}
psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key,
psa_status_t psa_crypto_storage_get_data_length( const psa_key_file_id_t key,
size_t *data_length )
{
psa_status_t status = PSA_SUCCESS;
@ -186,7 +187,7 @@ psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key,
file = fopen( slot_location, "rb" );
if( file == NULL )
return( PSA_ERROR_EMPTY_SLOT );
return( PSA_ERROR_DOES_NOT_EXIST );
if( fseek( file, 0, SEEK_END ) != 0 )
{

View File

@ -27,6 +27,8 @@
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C)
#include "psa/error.h"
#include "psa_crypto_service_integration.h"
#include "psa/crypto.h"
#include "psa_crypto_storage_backend.h"
#include "psa/internal_trusted_storage.h"
@ -35,96 +37,77 @@
#include "mbedtls/platform.h"
#endif
static psa_status_t its_to_psa_error( psa_its_status_t ret )
/* Determine a file name (ITS file identifier) for the given key file
* identifier. The file name must be distinct from any file that is used
* for a purpose other than storing a key. Currently, the only such file
* is the random seed file whose name is PSA_CRYPTO_ITS_RANDOM_SEED_UID
* and whose value is 0xFFFFFF52. */
static psa_storage_uid_t psa_its_identifier_of_slot( psa_key_file_id_t file_id )
{
switch( ret )
{
case PSA_ITS_SUCCESS:
return( PSA_SUCCESS );
case PSA_ITS_ERROR_UID_NOT_FOUND:
return( PSA_ERROR_EMPTY_SLOT );
case PSA_ITS_ERROR_STORAGE_FAILURE:
return( PSA_ERROR_STORAGE_FAILURE );
case PSA_ITS_ERROR_INSUFFICIENT_SPACE:
return( PSA_ERROR_INSUFFICIENT_STORAGE );
case PSA_ITS_ERROR_OFFSET_INVALID:
case PSA_ITS_ERROR_INCORRECT_SIZE:
case PSA_ITS_ERROR_INVALID_ARGUMENTS:
return( PSA_ERROR_INVALID_ARGUMENT );
case PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED:
return( PSA_ERROR_NOT_SUPPORTED );
case PSA_ITS_ERROR_WRITE_ONCE:
return( PSA_ERROR_OCCUPIED_SLOT );
default:
return( PSA_ERROR_UNKNOWN_ERROR );
}
#if defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER) && \
defined(PSA_CRYPTO_SECURE)
/* Encode the owner in the upper 32 bits. This means that if
* owner values are nonzero (as they are on a PSA platform),
* no key file will ever have a value less than 0x100000000, so
* the whole range 0..0xffffffff is available for non-key files. */
uint32_t unsigned_owner = (uint32_t) file_id.owner;
return( (uint64_t) unsigned_owner << 32 | file_id.key_id );
#else
/* Use the key id directly as a file name.
* psa_is_key_file_id_valid() in psa_crypto_slot_management.c
* is responsible for ensuring that key identifiers do not have a
* value that is reserved for non-key files. */
return( file_id );
#endif
}
static psa_its_uid_t psa_its_identifier_of_slot( psa_key_id_t key )
{
return( key );
}
psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key, uint8_t *data,
size_t data_size )
{
psa_its_status_t ret;
psa_status_t status;
psa_its_uid_t data_identifier = psa_its_identifier_of_slot( key );
struct psa_its_info_t data_identifier_info;
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
struct psa_storage_info_t data_identifier_info;
ret = psa_its_get_info( data_identifier, &data_identifier_info );
status = its_to_psa_error( ret );
status = psa_its_get_info( data_identifier, &data_identifier_info );
if( status != PSA_SUCCESS )
return( status );
ret = psa_its_get( data_identifier, 0, data_size, data );
status = its_to_psa_error( ret );
status = psa_its_get( data_identifier, 0, data_size, data );
return( status );
}
int psa_is_key_present_in_storage( const psa_key_id_t key )
int psa_is_key_present_in_storage( const psa_key_file_id_t key )
{
psa_its_status_t ret;
psa_its_uid_t data_identifier = psa_its_identifier_of_slot( key );
struct psa_its_info_t data_identifier_info;
psa_status_t ret;
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
struct psa_storage_info_t data_identifier_info;
ret = psa_its_get_info( data_identifier, &data_identifier_info );
if( ret == PSA_ITS_ERROR_UID_NOT_FOUND )
if( ret == PSA_ERROR_DOES_NOT_EXIST )
return( 0 );
return( 1 );
}
psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key,
const uint8_t *data,
size_t data_length )
{
psa_its_status_t ret;
psa_status_t status;
psa_its_uid_t data_identifier = psa_its_identifier_of_slot( key );
struct psa_its_info_t data_identifier_info;
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
struct psa_storage_info_t data_identifier_info;
if( psa_is_key_present_in_storage( key ) == 1 )
return( PSA_ERROR_OCCUPIED_SLOT );
return( PSA_ERROR_ALREADY_EXISTS );
ret = psa_its_set( data_identifier, data_length, data, 0 );
status = its_to_psa_error( ret );
status = psa_its_set( data_identifier, data_length, data, 0 );
if( status != PSA_SUCCESS )
{
return( PSA_ERROR_STORAGE_FAILURE );
}
ret = psa_its_get_info( data_identifier, &data_identifier_info );
status = its_to_psa_error( ret );
status = psa_its_get_info( data_identifier, &data_identifier_info );
if( status != PSA_SUCCESS )
{
goto exit;
@ -142,36 +125,34 @@ exit:
return( status );
}
psa_status_t psa_destroy_persistent_key( const psa_key_id_t key )
psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key )
{
psa_its_status_t ret;
psa_its_uid_t data_identifier = psa_its_identifier_of_slot( key );
struct psa_its_info_t data_identifier_info;
psa_status_t ret;
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
struct psa_storage_info_t data_identifier_info;
ret = psa_its_get_info( data_identifier, &data_identifier_info );
if( ret == PSA_ITS_ERROR_UID_NOT_FOUND )
if( ret == PSA_ERROR_DOES_NOT_EXIST )
return( PSA_SUCCESS );
if( psa_its_remove( data_identifier ) != PSA_ITS_SUCCESS )
if( psa_its_remove( data_identifier ) != PSA_SUCCESS )
return( PSA_ERROR_STORAGE_FAILURE );
ret = psa_its_get_info( data_identifier, &data_identifier_info );
if( ret != PSA_ITS_ERROR_UID_NOT_FOUND )
if( ret != PSA_ERROR_DOES_NOT_EXIST )
return( PSA_ERROR_STORAGE_FAILURE );
return( PSA_SUCCESS );
}
psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key,
psa_status_t psa_crypto_storage_get_data_length( const psa_key_file_id_t key,
size_t *data_length )
{
psa_its_status_t ret;
psa_status_t status;
psa_its_uid_t data_identifier = psa_its_identifier_of_slot( key );
struct psa_its_info_t data_identifier_info;
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
struct psa_storage_info_t data_identifier_info;
ret = psa_its_get_info( data_identifier, &data_identifier_info );
status = its_to_psa_error( ret );
status = psa_its_get_info( data_identifier, &data_identifier_info );
if( status != PSA_SUCCESS )
return( status );

View File

@ -5,21 +5,13 @@
int mbed_default_seed_read(unsigned char *buf, size_t buf_len)
{
/* Make sure that in case of an error the value will be negative
* return (-1 * rc);
* Mbed TLS errors are negative values
*/
psa_its_status_t rc = psa_its_get(PSA_CRYPTO_ITS_RANDOM_SEED_UID, 0, buf_len, buf);
return ( -1 * rc );
psa_status_t rc = psa_its_get(PSA_CRYPTO_ITS_RANDOM_SEED_UID, 0, buf_len, buf);
return ( rc );
}
int mbed_default_seed_write(unsigned char *buf, size_t buf_len)
{
psa_its_status_t rc = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID, buf_len, buf, 0);
/* Make sure that in case of an error the value will be negative
* return (-1 * rc);
* Mbed TLS errors are negative values
*/
return ( -1 * rc );
psa_status_t rc = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID, buf_len, buf, 0);
return ( rc );
}

View File

@ -8083,7 +8083,7 @@
"inherits": ["NSPE_Target", "FUTURE_SEQUANA"],
"extra_labels_add": ["PSA", "MBED_SPM"],
"extra_labels_remove": ["CORDIO"],
"components_add": ["SPM_MAILBOX"],
"components_add": ["SPM_MAILBOX", "FLASHIAP"],
"macros_add": ["PSOC6_DYNSRM_DISABLE=1", "MBEDTLS_PSA_CRYPTO_C"],
"hex_filename": "psa_release_1.0.hex",
"overrides": {

View File

@ -34,7 +34,7 @@ TEMPLATES_LIST_FILE = path_join(SCRIPT_DIR, 'tfm', 'tfm_generated_file_list.json
SERVICES_DIR = os.path.join(MBED_OS_ROOT, "components", "TARGET_PSA", "services")
SERVICES_MANIFESTS = [
path_join(SERVICES_DIR, 'psa_prot_internal_storage', 'pits_psa.json'),
path_join(SERVICES_DIR, 'storage', 'its', 'pits_psa.json'),
path_join(SERVICES_DIR, 'platform', 'platform_psa.json'),
path_join(SERVICES_DIR, 'crypto', 'crypto_partition_psa.json')
]