diff --git a/configs/config-psa-crypto.h b/configs/config-psa-crypto.h index a8e06348bc..4873c36247 100644 --- a/configs/config-psa-crypto.h +++ b/configs/config-psa-crypto.h @@ -1146,16 +1146,6 @@ */ //#define MBEDTLS_ENTROPY_NV_SEED -/** - * \def MBEDTLS_PSA_HAS_ITS_IO - * - * Enable the non-volatile secure storage usage. - * - * This is crucial on systems that do not have a HW TRNG support. - * - */ -//#define MBEDTLS_PSA_HAS_ITS_IO - /* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER * * In PSA key storage, encode the owner of the key. @@ -1242,14 +1232,17 @@ //#define MBEDTLS_PSA_CRYPTO_SPM /** - * \def MBEDTLS_PSA_HAS_ITS_IO + * \def MBEDTLS_PSA_INJECT_ENTROPY * - * Enable the non-volatile secure storage usage. + * Enable support for entropy injection at first boot. This feature is + * required on systems that do not have a built-in entropy source (TRNG). + * This feature is currently not supported on systems that have a built-in + * entropy source. * - * This is crucial on systems that do not have a HW TRNG support. + * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED * */ -//#define MBEDTLS_PSA_HAS_ITS_IO +//#define MBEDTLS_PSA_INJECT_ENTROPY /** * \def MBEDTLS_RSA_NO_CRT @@ -2719,38 +2712,23 @@ * * Module: library/psa_crypto_storage.c * - * Requires: MBEDTLS_PSA_CRYPTO_C and one of either - * MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C or MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C - * (but not both) - * + * Requires: MBEDTLS_PSA_CRYPTO_C, + * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of + * the PSA ITS interface */ #define MBEDTLS_PSA_CRYPTO_STORAGE_C /** - * \def MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C + * \def MBEDTLS_PSA_ITS_FILE_C * - * Enable persistent key storage over files for the - * Platform Security Architecture cryptography API. + * Enable the emulation of the Platform Security Architecture + * Internal Trusted Storage (PSA ITS) over files. * - * Module: library/psa_crypto_storage_file.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_FS_IO + * Module: library/psa_its_file.c * + * Requires: MBEDTLS_FS_IO */ -#define MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C - -/** - * \def MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C - * - * Enable persistent key storage over PSA ITS for the - * Platform Security Architecture cryptography API. - * - * Module: library/psa_crypto_storage_its.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_HAS_ITS_IO - * - */ -//#define MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C +#define MBEDTLS_PSA_ITS_FILE_C /** * \def MBEDTLS_RIPEMD160_C diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 962d3db87e..c1450dbdaa 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -525,26 +525,25 @@ #error "MBEDTLS_PSA_CRYPTO_SPM defined, but not all prerequisites" #endif -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C) && defined(MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C) -#error "Only one of MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C or MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C can be defined" -#endif - #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ - !( defined(MBEDTLS_PSA_CRYPTO_C) && \ - ( defined(MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C) || \ - defined(MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C) ) ) + ! defined(MBEDTLS_PSA_CRYPTO_C) #error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites" #endif -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C) && \ - !( defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ - defined(MBEDTLS_FS_IO) ) -#error "MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C defined, but not all prerequisites" +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + !( defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ + defined(MBEDTLS_ENTROPY_NV_SEED) ) +#error "MBEDTLS_PSA_INJECT_ENTROPY defined, but not all prerequisites" #endif -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C) && \ - ! defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) -#error "MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C defined, but not all prerequisites" +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) +#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with actual entropy sources" +#endif + +#if defined(MBEDTLS_PSA_ITS_FILE_C) && \ + !defined(MBEDTLS_FS_IO) +#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites" #endif #if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 7f96e50cf4..5621965f26 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1166,16 +1166,6 @@ */ //#define MBEDTLS_ENTROPY_NV_SEED -/** - * \def MBEDTLS_PSA_HAS_ITS_IO - * - * Enable the non-volatile secure storage usage. - * - * This is crucial on systems that do not have a HW TRNG support. - * - */ -//#define MBEDTLS_PSA_HAS_ITS_IO - /* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER * * In PSA key storage, encode the owner of the key. @@ -1262,14 +1252,17 @@ //#define MBEDTLS_PSA_CRYPTO_SPM /** - * \def MBEDTLS_PSA_HAS_ITS_IO + * \def MBEDTLS_PSA_INJECT_ENTROPY * - * Enable the non-volatile secure storage usage. + * Enable support for entropy injection at first boot. This feature is + * required on systems that do not have a built-in entropy source (TRNG). + * This feature is currently not supported on systems that have a built-in + * entropy source. * - * This is crucial on systems that do not have a HW TRNG support. + * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED * */ -//#define MBEDTLS_PSA_HAS_ITS_IO +//#define MBEDTLS_PSA_INJECT_ENTROPY /** * \def MBEDTLS_RSA_NO_CRT @@ -2761,38 +2754,23 @@ * * Module: library/psa_crypto_storage.c * - * Requires: MBEDTLS_PSA_CRYPTO_C and one of either - * MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C or MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C - * (but not both) - * + * Requires: MBEDTLS_PSA_CRYPTO_C, + * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of + * the PSA ITS interface */ #define MBEDTLS_PSA_CRYPTO_STORAGE_C /** - * \def MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C + * \def MBEDTLS_PSA_ITS_FILE_C * - * Enable persistent key storage over files for the - * Platform Security Architecture cryptography API. + * Enable the emulation of the Platform Security Architecture + * Internal Trusted Storage (PSA ITS) over files. * - * Module: library/psa_crypto_storage_file.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_FS_IO + * Module: library/psa_its_file.c * + * Requires: MBEDTLS_FS_IO */ -#define MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C - -/** - * \def MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C - * - * Enable persistent key storage over PSA ITS for the - * Platform Security Architecture cryptography API. - * - * Module: library/psa_crypto_storage_its.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_HAS_ITS_IO - * - */ -//#define MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C +#define MBEDTLS_PSA_ITS_FILE_C /** * \def MBEDTLS_RIPEMD160_C diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 5dd47899e5..c89c55df30 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -114,10 +114,9 @@ void mbedtls_psa_crypto_free( void ); * This is an Mbed TLS extension. * * \note This function is only available on the following platforms: - * * If the compile-time options MBEDTLS_ENTROPY_NV_SEED and - * MBEDTLS_PSA_HAS_ITS_IO are both enabled. Note that you - * must provide compatible implementations of mbedtls_nv_seed_read - * and mbedtls_nv_seed_write. + * * If the compile-time option MBEDTLS_PSA_INJECT_ENTROPY is enabled. + * Note that you must provide compatible implementations of + * mbedtls_nv_seed_read and mbedtls_nv_seed_write. * * In a client-server integration of PSA Cryptography, on the client side, * if the server supports this feature. * \param[in] seed Buffer containing the seed value to inject. diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index e9372be5be..72378da783 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -56,8 +56,7 @@ set(src_crypto psa_crypto.c psa_crypto_slot_management.c psa_crypto_storage.c - psa_crypto_storage_file.c - psa_crypto_storage_its.c + psa_its_file.c ripemd160.c rsa.c rsa_internal.c diff --git a/library/Makefile b/library/Makefile index 8533eaad05..6ed5e68613 100644 --- a/library/Makefile +++ b/library/Makefile @@ -85,8 +85,7 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \ psa_crypto.o \ psa_crypto_slot_management.o \ psa_crypto_storage.o \ - psa_crypto_storage_file.o \ - psa_crypto_storage_its.o \ + psa_its_file.o \ ripemd160.o rsa_internal.o rsa.o \ sha1.o sha256.o sha512.o \ threading.o timing.o version.o \ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index cd1499a380..3b9c78ffc7 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -60,7 +60,6 @@ #include "mbedtls/ecdh.h" #include "mbedtls/ecp.h" #include "mbedtls/entropy.h" -#include "mbedtls/entropy_poll.h" #include "mbedtls/error.h" #include "mbedtls/gcm.h" #include "mbedtls/md2.h" @@ -78,10 +77,6 @@ #include "mbedtls/sha512.h" #include "mbedtls/xtea.h" -#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) ) -#include "psa/internal_trusted_storage.h" -#endif - #define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) ) /* constant-time buffer comparison */ @@ -4423,13 +4418,12 @@ psa_status_t psa_generate_random( uint8_t *output, return( mbedtls_to_psa_error( ret ) ); } -#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) ) +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) +#include "mbedtls/entropy_poll.h" psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed, size_t seed_size ) { - psa_status_t status; - struct psa_storage_info_t p_info; if( global_data.initialized ) return( PSA_ERROR_NOT_PERMITTED ); @@ -4438,20 +4432,9 @@ psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed, ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info ); - - if( PSA_ERROR_DOES_NOT_EXIST == status ) /* No seed exists */ - { - status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 ); - } - else if( PSA_SUCCESS == status ) - { - /* You should not be here. Seed needs to be injected only once */ - status = PSA_ERROR_NOT_PERMITTED; - } - return( status ); + return( mbedtls_psa_storage_inject_entropy( seed, seed_size ) ); } -#endif +#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ psa_status_t psa_generate_key( psa_key_handle_t handle, psa_key_type_t type, diff --git a/library/psa_crypto_its.h b/library/psa_crypto_its.h new file mode 100644 index 0000000000..44d51982a4 --- /dev/null +++ b/library/psa_crypto_its.h @@ -0,0 +1,142 @@ +/** \file psa_crypto_its.h + * \brief Interface of trusted storage that crypto is built on. + */ +/* 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 PSA_CRYPTO_ITS_H +#define PSA_CRYPTO_ITS_H + +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \brief Flags used when creating a data entry + */ +typedef uint32_t psa_storage_create_flags_t; + +/** \brief A type for UIDs used for identifying data + */ +typedef uint64_t psa_storage_uid_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 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 **/ +}; + +/** 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_INVALID_SIGNATURE ((psa_status_t)-149) +#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152) + +#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 */ + +/** + * \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_ARGUMENT 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_INVALID_SIZE The operation failed because the data associated with provided uid is larger than `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. + * In addition, this can also happen if an invalid offset was provided. + */ +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); + +#endif /* PSA_CRYPTO_ITS_H */ diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c index 84a6ed5585..840f418c38 100644 --- a/library/psa_crypto_storage.c +++ b/library/psa_crypto_storage.c @@ -33,9 +33,15 @@ #include "psa_crypto_service_integration.h" #include "psa/crypto.h" #include "psa_crypto_storage.h" -#include "psa_crypto_storage_backend.h" #include "mbedtls/platform_util.h" +#if defined(MBEDTLS_PSA_ITS_FILE_C) +#include "psa_crypto_its.h" +#else /* Native ITS implementation */ +#include "psa/error.h" +#include "psa/internal_trusted_storage.h" +#endif + #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else @@ -44,6 +50,173 @@ #define mbedtls_free free #endif +/* 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 ) +{ +#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 +} + +/** + * \brief Load persistent data for the given key slot number. + * + * This function reads data from a storage backend and returns the data in a + * buffer. + * + * \param key Persistent identifier of the key to be loaded. This + * should be an occupied storage location. + * \param[out] data Buffer where the data is to be written. + * \param data_size Size of the \c data buffer in bytes. + * + * \retval PSA_SUCCESS + * \retval PSA_ERROR_STORAGE_FAILURE + * \retval PSA_ERROR_DOES_NOT_EXIST + */ +static 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_storage_uid_t data_identifier = psa_its_identifier_of_slot( key ); + struct psa_storage_info_t data_identifier_info; + + status = psa_its_get_info( data_identifier, &data_identifier_info ); + if( status != PSA_SUCCESS ) + return( status ); + + status = psa_its_get( data_identifier, 0, (uint32_t) data_size, data ); + + return( status ); +} + +int psa_is_key_present_in_storage( const psa_key_file_id_t key ) +{ + 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_ERROR_DOES_NOT_EXIST ) + return( 0 ); + return( 1 ); +} + +/** + * \brief Store persistent data for the given key slot number. + * + * This function stores the given data buffer to a persistent storage. + * + * \param key Persistent identifier of the key to be stored. This + * should be an unoccupied storage location. + * \param[in] data Buffer containing the data to be stored. + * \param data_length The number of bytes + * that make up the data. + * + * \retval PSA_SUCCESS + * \retval PSA_ERROR_INSUFFICIENT_STORAGE + * \retval PSA_ERROR_STORAGE_FAILURE + * \retval PSA_ERROR_ALREADY_EXISTS + */ +static psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key, + const uint8_t *data, + size_t data_length ) +{ + psa_status_t status; + 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_ALREADY_EXISTS ); + + status = psa_its_set( data_identifier, (uint32_t) data_length, data, 0 ); + if( status != PSA_SUCCESS ) + { + return( PSA_ERROR_STORAGE_FAILURE ); + } + + status = psa_its_get_info( data_identifier, &data_identifier_info ); + if( status != PSA_SUCCESS ) + { + goto exit; + } + + if( data_identifier_info.size != data_length ) + { + status = PSA_ERROR_STORAGE_FAILURE; + goto exit; + } + +exit: + if( status != PSA_SUCCESS ) + psa_its_remove( data_identifier ); + return( status ); +} + +psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key ) +{ + 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_ERROR_DOES_NOT_EXIST ) + return( PSA_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_ERROR_DOES_NOT_EXIST ) + return( PSA_ERROR_STORAGE_FAILURE ); + + return( PSA_SUCCESS ); +} + +/** + * \brief Get data length for given key slot number. + * + * \param key Persistent identifier whose stored data length + * is to be obtained. + * \param[out] data_length The number of bytes that make up the data. + * + * \retval PSA_SUCCESS + * \retval PSA_ERROR_STORAGE_FAILURE + */ +static 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_storage_uid_t data_identifier = psa_its_identifier_of_slot( key ); + struct psa_storage_info_t data_identifier_info; + + status = psa_its_get_info( data_identifier, &data_identifier_info ); + if( status != PSA_SUCCESS ) + return( status ); + + *data_length = (size_t) data_identifier_info.size; + + return( PSA_SUCCESS ); +} + /* * 32-bit integer manipulation macros (little endian) */ @@ -218,4 +391,26 @@ exit: return( status ); } +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) +psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed, + size_t seed_size ) +{ + psa_status_t status; + struct psa_storage_info_t p_info; + + status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info ); + + if( PSA_ERROR_DOES_NOT_EXIST == status ) /* No seed exists */ + { + status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 ); + } + else if( PSA_SUCCESS == status ) + { + /* You should not be here. Seed needs to be injected only once */ + status = PSA_ERROR_NOT_PERMITTED; + } + return( status ); +} +#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ + #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h index 7e5aae9f98..5434d0529a 100644 --- a/library/psa_crypto_storage.h +++ b/library/psa_crypto_storage.h @@ -61,6 +61,21 @@ extern "C" { */ #define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xfffeffff +/** + * \brief Checks if persistent data is stored for the given key slot number + * + * This function checks if any key data or metadata exists for the key slot in + * the persistent storage. + * + * \param key Persistent identifier to check. + * + * \retval 0 + * No persistent data present for slot number + * \retval 1 + * Persistent data present for slot number + */ +int psa_is_key_present_in_storage( const psa_key_file_id_t key ); + /** * \brief Format key data and metadata and save to a location for given key * slot. @@ -188,6 +203,22 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data, psa_key_type_t *type, psa_key_policy_t *policy ); +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) +/** Backend side of mbedtls_psa_inject_entropy(). + * + * This function stores the supplied data into the entropy seed file. + * + * \retval #PSA_SUCCESS + * Success + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_NOT_PERMITTED + * The entropy seed file already exists. + */ +psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed, + size_t seed_size ); +#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ + #ifdef __cplusplus } #endif diff --git a/library/psa_crypto_storage_backend.h b/library/psa_crypto_storage_backend.h deleted file mode 100644 index dd534d2ff1..0000000000 --- a/library/psa_crypto_storage_backend.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - * \file psa_crypto_storage_backend.h - * - * \brief PSA cryptography module: Mbed TLS key storage backend - */ -/* - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#ifndef PSA_CRYPTO_STORAGE_BACKEND_H -#define PSA_CRYPTO_STORAGE_BACKEND_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Include the Mbed TLS configuration file, the way Mbed TLS does it - * in each of its header files. */ -#if defined(MBEDTLS_CONFIG_FILE) -#include MBEDTLS_CONFIG_FILE -#else -#include "mbedtls/config.h" -#endif - -#include "psa/crypto.h" -#include "psa_crypto_storage.h" -#include - -/** - * \brief Load persistent data for the given key slot number. - * - * This function reads data from a storage backend and returns the data in a - * buffer. - * - * \param key Persistent identifier of the key to be loaded. This - * should be an occupied storage location. - * \param[out] data Buffer where the data is to be written. - * \param data_size Size of the \c data buffer in bytes. - * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_STORAGE_FAILURE - * \retval PSA_ERROR_DOES_NOT_EXIST - */ -psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key, uint8_t *data, - size_t data_size ); - -/** - * \brief Store persistent data for the given key slot number. - * - * This function stores the given data buffer to a persistent storage. - * - * \param key Persistent identifier of the key to be stored. This - * should be an unoccupied storage location. - * \param[in] data Buffer containing the data to be stored. - * \param data_length The number of bytes - * that make up the data. - * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_INSUFFICIENT_STORAGE - * \retval PSA_ERROR_STORAGE_FAILURE - * \retval PSA_ERROR_ALREADY_EXISTS - */ -psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key, - const uint8_t *data, - size_t data_length ); - -/** - * \brief Checks if persistent data is stored for the given key slot number - * - * This function checks if any key data or metadata exists for the key slot in - * the persistent storage. - * - * \param key Persistent identifier to check. - * - * \retval 0 - * No persistent data present for slot number - * \retval 1 - * Persistent data present for slot number - */ -int psa_is_key_present_in_storage( const psa_key_file_id_t key ); - -/** - * \brief Get data length for given key slot number. - * - * \param key Persistent identifier whose stored data length - * is to be obtained. - * \param[out] data_length The number of bytes that make up the data. - * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_STORAGE_FAILURE - */ -psa_status_t psa_crypto_storage_get_data_length( const psa_key_file_id_t key, - size_t *data_length ); - - -#ifdef __cplusplus -} -#endif - -#endif /* PSA_CRYPTO_STORAGE_H */ diff --git a/library/psa_crypto_storage_file.c b/library/psa_crypto_storage_file.c deleted file mode 100644 index c4a534fe36..0000000000 --- a/library/psa_crypto_storage_file.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * PSA file storage backend for persistent keys - */ -/* 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if defined(MBEDTLS_CONFIG_FILE) -#include MBEDTLS_CONFIG_FILE -#else -#include "mbedtls/config.h" -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C) - -#include - -#include "psa/crypto.h" -#include "psa_crypto_storage_backend.h" -#include "mbedtls/platform_util.h" - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_snprintf snprintf -#endif - -/* This option sets where files are to be stored. If this is left unset, - * the files by default will be stored in the same location as the program, - * which may not be desired or possible. */ -#if !defined(CRYPTO_STORAGE_FILE_LOCATION) -#define CRYPTO_STORAGE_FILE_LOCATION "" -#endif - -enum { MAX_LOCATION_LEN = sizeof(CRYPTO_STORAGE_FILE_LOCATION) + 40 }; - -static void key_id_to_location( const psa_key_file_id_t key, - char *location, - size_t location_size ) -{ - mbedtls_snprintf( location, location_size, - CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_%lu", - (unsigned long) key ); -} - -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; - FILE *file; - size_t num_read; - char slot_location[MAX_LOCATION_LEN]; - - key_id_to_location( key, slot_location, MAX_LOCATION_LEN ); - file = fopen( slot_location, "rb" ); - if( file == NULL ) - { - status = PSA_ERROR_STORAGE_FAILURE; - goto exit; - } - num_read = fread( data, 1, data_size, file ); - if( num_read != data_size ) - status = PSA_ERROR_STORAGE_FAILURE; - -exit: - if( file != NULL ) - fclose( file ); - return( status ); -} - -int psa_is_key_present_in_storage( const psa_key_file_id_t key ) -{ - char slot_location[MAX_LOCATION_LEN]; - FILE *file; - - key_id_to_location( key, slot_location, MAX_LOCATION_LEN ); - - file = fopen( slot_location, "r" ); - if( file == NULL ) - { - /* File doesn't exist */ - return( 0 ); - } - - fclose( file ); - return( 1 ); -} - -psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key, - const uint8_t *data, - size_t data_length ) -{ - psa_status_t status = PSA_SUCCESS; - int ret; - size_t num_written; - char slot_location[MAX_LOCATION_LEN]; - FILE *file; - /* The storage location corresponding to "key slot 0" is used as a - * temporary location in order to make the apparition of the actual slot - * file atomic. 0 is not a valid key slot number, so this should not - * affect actual keys. */ - const char *temp_location = CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_0"; - - key_id_to_location( key, slot_location, MAX_LOCATION_LEN ); - - if( psa_is_key_present_in_storage( key ) == 1 ) - return( PSA_ERROR_ALREADY_EXISTS ); - - file = fopen( temp_location, "wb" ); - if( file == NULL ) - { - status = PSA_ERROR_STORAGE_FAILURE; - goto exit; - } - - num_written = fwrite( data, 1, data_length, file ); - if( num_written != data_length ) - { - status = PSA_ERROR_STORAGE_FAILURE; - goto exit; - } - - ret = fclose( file ); - file = NULL; - if( ret != 0 ) - { - status = PSA_ERROR_STORAGE_FAILURE; - goto exit; - } - - if( rename( temp_location, slot_location ) != 0 ) - { - status = PSA_ERROR_STORAGE_FAILURE; - goto exit; - } - -exit: - if( file != NULL ) - fclose( file ); - remove( temp_location ); - return( status ); -} - -psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key ) -{ - FILE *file; - char slot_location[MAX_LOCATION_LEN]; - - key_id_to_location( key, slot_location, MAX_LOCATION_LEN ); - - /* Only try remove the file if it exists */ - file = fopen( slot_location, "rb" ); - if( file != NULL ) - { - fclose( file ); - - if( remove( slot_location ) != 0 ) - return( PSA_ERROR_STORAGE_FAILURE ); - } - return( PSA_SUCCESS ); -} - -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; - FILE *file; - long file_size; - char slot_location[MAX_LOCATION_LEN]; - - key_id_to_location( key, slot_location, MAX_LOCATION_LEN ); - - file = fopen( slot_location, "rb" ); - if( file == NULL ) - return( PSA_ERROR_DOES_NOT_EXIST ); - - if( fseek( file, 0, SEEK_END ) != 0 ) - { - status = PSA_ERROR_STORAGE_FAILURE; - goto exit; - } - - file_size = ftell( file ); - - if( file_size < 0 ) - { - status = PSA_ERROR_STORAGE_FAILURE; - goto exit; - } - -#if LONG_MAX > SIZE_MAX - if( (unsigned long) file_size > SIZE_MAX ) - { - status = PSA_ERROR_STORAGE_FAILURE; - goto exit; - } -#endif - *data_length = (size_t) file_size; - -exit: - fclose( file ); - return( status ); -} - -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C */ diff --git a/library/psa_crypto_storage_its.c b/library/psa_crypto_storage_its.c deleted file mode 100644 index 447c0aebb4..0000000000 --- a/library/psa_crypto_storage_its.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * PSA storage backend for persistent keys using psa_its APIs. - */ -/* 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if defined(MBEDTLS_CONFIG_FILE) -#include MBEDTLS_CONFIG_FILE -#else -#include "mbedtls/config.h" -#endif - -#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" - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#endif - -/* 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 ) -{ -#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 -} - -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_storage_uid_t data_identifier = psa_its_identifier_of_slot( key ); - struct psa_storage_info_t data_identifier_info; - - status = psa_its_get_info( data_identifier, &data_identifier_info ); - if( status != PSA_SUCCESS ) - return( status ); - - status = psa_its_get( data_identifier, 0, data_size, data ); - - return( status ); -} - -int psa_is_key_present_in_storage( const psa_key_file_id_t key ) -{ - 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_ERROR_DOES_NOT_EXIST ) - return( 0 ); - return( 1 ); -} - -psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key, - const uint8_t *data, - size_t data_length ) -{ - psa_status_t status; - 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_ALREADY_EXISTS ); - - status = psa_its_set( data_identifier, data_length, data, 0 ); - if( status != PSA_SUCCESS ) - { - return( PSA_ERROR_STORAGE_FAILURE ); - } - - status = psa_its_get_info( data_identifier, &data_identifier_info ); - if( status != PSA_SUCCESS ) - { - goto exit; - } - - if( data_identifier_info.size != data_length ) - { - status = PSA_ERROR_STORAGE_FAILURE; - goto exit; - } - -exit: - if( status != PSA_SUCCESS ) - psa_its_remove( data_identifier ); - return( status ); -} - -psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key ) -{ - 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_ERROR_DOES_NOT_EXIST ) - return( PSA_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_ERROR_DOES_NOT_EXIST ) - return( PSA_ERROR_STORAGE_FAILURE ); - - return( PSA_SUCCESS ); -} - -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_storage_uid_t data_identifier = psa_its_identifier_of_slot( key ); - struct psa_storage_info_t data_identifier_info; - - status = psa_its_get_info( data_identifier, &data_identifier_info ); - if( status != PSA_SUCCESS ) - return( status ); - - *data_length = (size_t) data_identifier_info.size; - - return( PSA_SUCCESS ); -} - -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C */ diff --git a/library/psa_its_file.c b/library/psa_its_file.c new file mode 100644 index 0000000000..de60ecfc95 --- /dev/null +++ b/library/psa_its_file.c @@ -0,0 +1,233 @@ +/* + * PSA ITS simulator over stdio files. + */ +/* 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. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if defined(MBEDTLS_CONFIG_FILE) +#include MBEDTLS_CONFIG_FILE +#else +#include "mbedtls/config.h" +#endif + +#if defined(MBEDTLS_PSA_ITS_FILE_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_snprintf snprintf +#endif + +#include "psa_crypto_its.h" + +#include +#include +#include +#include + +#define PSA_ITS_STORAGE_PREFIX "" + +#define PSA_ITS_STORAGE_FILENAME_PATTERN "%08lx%08lx" +#define PSA_ITS_STORAGE_SUFFIX ".psa_its" +#define PSA_ITS_STORAGE_FILENAME_LENGTH \ + ( sizeof( PSA_ITS_STORAGE_PREFIX ) - 1 + /*prefix without terminating 0*/ \ + 16 + /*UID (64-bit number in hex)*/ \ + sizeof( PSA_ITS_STORAGE_SUFFIX ) - 1 + /*suffix without terminating 0*/ \ + 1 /*terminating null byte*/ ) +#define PSA_ITS_STORAGE_TEMP \ + PSA_ITS_STORAGE_PREFIX "tempfile" PSA_ITS_STORAGE_SUFFIX + +/* The maximum value of psa_storage_info_t.size */ +#define PSA_ITS_MAX_SIZE 0xffffffff + +#define PSA_ITS_MAGIC_STRING "PSA\0ITS\0" +#define PSA_ITS_MAGIC_LENGTH 8 + +typedef struct +{ + uint8_t magic[PSA_ITS_MAGIC_LENGTH]; + uint8_t size[sizeof( uint32_t )]; + uint8_t flags[sizeof( psa_storage_create_flags_t )]; +} psa_its_file_header_t; + +static void psa_its_fill_filename( psa_storage_uid_t uid, char *filename ) +{ + /* Break up the UID into two 32-bit pieces so as not to rely on + * long long support in snprintf. */ + mbedtls_snprintf( filename, PSA_ITS_STORAGE_FILENAME_LENGTH, + "%s" PSA_ITS_STORAGE_FILENAME_PATTERN "%s", + PSA_ITS_STORAGE_PREFIX, + (unsigned long) ( uid >> 32 ), + (unsigned long) ( uid & 0xffffffff ), + PSA_ITS_STORAGE_SUFFIX ); +} + +static psa_status_t psa_its_read_file( psa_storage_uid_t uid, + struct psa_storage_info_t *p_info, + FILE **p_stream ) +{ + char filename[PSA_ITS_STORAGE_FILENAME_LENGTH]; + psa_its_file_header_t header; + size_t n; + + *p_stream = NULL; + psa_its_fill_filename( uid, filename ); + *p_stream = fopen( filename, "rb" ); + if( *p_stream == NULL ) + return( PSA_ERROR_DOES_NOT_EXIST ); + + n = fread( &header, 1, sizeof( header ), *p_stream ); + if( n != sizeof( header ) ) + return( PSA_ERROR_DATA_CORRUPT ); + if( memcmp( header.magic, PSA_ITS_MAGIC_STRING, + PSA_ITS_MAGIC_LENGTH ) != 0 ) + return( PSA_ERROR_DATA_CORRUPT ); + + p_info->size = ( header.size[0] | + header.size[1] << 8 | + header.size[2] << 16 | + header.size[3] << 24 ); + p_info->flags = ( header.flags[0] | + header.flags[1] << 8 | + header.flags[2] << 16 | + header.flags[3] << 24 ); + return( PSA_SUCCESS ); +} + +psa_status_t psa_its_get_info( psa_storage_uid_t uid, + struct psa_storage_info_t *p_info ) +{ + psa_status_t status; + FILE *stream = NULL; + status = psa_its_read_file( uid, p_info, &stream ); + if( stream != NULL ) + fclose( stream ); + return( status ); +} + +psa_status_t psa_its_get( psa_storage_uid_t uid, + uint32_t data_offset, + uint32_t data_length, + void *p_data ) +{ + psa_status_t status; + FILE *stream = NULL; + size_t n; + struct psa_storage_info_t info; + + status = psa_its_read_file( uid, &info, &stream ); + if( status != PSA_SUCCESS ) + goto exit; + status = PSA_ERROR_INVALID_ARGUMENT; + if( data_offset + data_length < data_offset ) + goto exit; +#if SIZE_MAX < 0xffffffff + if( data_offset + data_length > SIZE_MAX ) + goto exit; +#endif + if( data_offset + data_length > info.size ) + goto exit; + + status = PSA_ERROR_STORAGE_FAILURE; +#if LONG_MAX < 0xffffffff + while( data_offset > LONG_MAX ) + { + if( fseek( stream, LONG_MAX, SEEK_CUR ) != 0 ) + goto exit; + data_offset -= LONG_MAX; + } +#endif + if( fseek( stream, data_offset, SEEK_CUR ) != 0 ) + goto exit; + n = fread( p_data, 1, data_length, stream ); + if( n != data_length ) + goto exit; + status = PSA_SUCCESS; + +exit: + if( stream != NULL ) + fclose( stream ); + return( status ); +} + +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 ) +{ + psa_status_t status = PSA_ERROR_STORAGE_FAILURE; + char filename[PSA_ITS_STORAGE_FILENAME_LENGTH]; + FILE *stream = NULL; + psa_its_file_header_t header; + size_t n; + + memcpy( header.magic, PSA_ITS_MAGIC_STRING, PSA_ITS_MAGIC_LENGTH ); + header.size[0] = data_length & 0xff; + header.size[1] = ( data_length >> 8 ) & 0xff; + header.size[2] = ( data_length >> 16 ) & 0xff; + header.size[3] = ( data_length >> 24 ) & 0xff; + header.flags[0] = create_flags & 0xff; + header.flags[1] = ( create_flags >> 8 ) & 0xff; + header.flags[2] = ( create_flags >> 16 ) & 0xff; + header.flags[3] = ( create_flags >> 24 ) & 0xff; + + psa_its_fill_filename( uid, filename ); + stream = fopen( PSA_ITS_STORAGE_TEMP, "wb" ); + if( stream == NULL ) + goto exit; + + status = PSA_ERROR_INSUFFICIENT_STORAGE; + n = fwrite( &header, 1, sizeof( header ), stream ); + if( n != sizeof( header ) ) + goto exit; + n = fwrite( p_data, 1, data_length, stream ); + if( n != data_length ) + goto exit; + status = PSA_SUCCESS; + +exit: + if( stream != NULL ) + { + int ret = fclose( stream ); + if( status == PSA_SUCCESS && ret != 0 ) + status = PSA_ERROR_INSUFFICIENT_STORAGE; + } + if( status == PSA_SUCCESS ) + { + if( rename( PSA_ITS_STORAGE_TEMP, filename ) != 0 ) + status = PSA_ERROR_STORAGE_FAILURE; + } + remove( PSA_ITS_STORAGE_TEMP ); + return( status ); +} + +psa_status_t psa_its_remove( psa_storage_uid_t uid ) +{ + char filename[PSA_ITS_STORAGE_FILENAME_LENGTH]; + FILE *stream; + psa_its_fill_filename( uid, filename ); + stream = fopen( filename, "rb" ); + if( stream == NULL ) + return( PSA_ERROR_DOES_NOT_EXIST ); + fclose( stream ); + if( remove( filename ) != 0 ) + return( PSA_ERROR_STORAGE_FAILURE ); + return( PSA_SUCCESS ); +} + +#endif /* MBEDTLS_PSA_ITS_FILE_C */ diff --git a/library/version_features.c b/library/version_features.c index f01eacee45..00fd2e90d6 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -411,9 +411,6 @@ static const char *features[] = { #if defined(MBEDTLS_ENTROPY_NV_SEED) "MBEDTLS_ENTROPY_NV_SEED", #endif /* MBEDTLS_ENTROPY_NV_SEED */ -#if defined(MBEDTLS_PSA_HAS_ITS_IO) - "MBEDTLS_PSA_HAS_ITS_IO", -#endif /* MBEDTLS_PSA_HAS_ITS_IO */ #if defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER) "MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER", #endif /* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */ @@ -435,9 +432,9 @@ static const char *features[] = { #if defined(MBEDTLS_PSA_CRYPTO_SPM) "MBEDTLS_PSA_CRYPTO_SPM", #endif /* MBEDTLS_PSA_CRYPTO_SPM */ -#if defined(MBEDTLS_PSA_HAS_ITS_IO) - "MBEDTLS_PSA_HAS_ITS_IO", -#endif /* MBEDTLS_PSA_HAS_ITS_IO */ +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) + "MBEDTLS_PSA_INJECT_ENTROPY", +#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ #if defined(MBEDTLS_RSA_NO_CRT) "MBEDTLS_RSA_NO_CRT", #endif /* MBEDTLS_RSA_NO_CRT */ @@ -714,12 +711,9 @@ static const char *features[] = { #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) "MBEDTLS_PSA_CRYPTO_STORAGE_C", #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C) - "MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C", -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C */ -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C) - "MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C", -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C */ +#if defined(MBEDTLS_PSA_ITS_FILE_C) + "MBEDTLS_PSA_ITS_FILE_C", +#endif /* MBEDTLS_PSA_ITS_FILE_C */ #if defined(MBEDTLS_RIPEMD160_C) "MBEDTLS_RIPEMD160_C", #endif /* MBEDTLS_RIPEMD160_C */ diff --git a/programs/test/query_config.c b/programs/test/query_config.c index 345d1ecbf6..d940b0d17a 100644 --- a/programs/test/query_config.c +++ b/programs/test/query_config.c @@ -1138,14 +1138,6 @@ int query_config( const char *config ) } #endif /* MBEDTLS_ENTROPY_NV_SEED */ -#if defined(MBEDTLS_PSA_HAS_ITS_IO) - if( strcmp( "MBEDTLS_PSA_HAS_ITS_IO", config ) == 0 ) - { - MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_HAS_ITS_IO ); - return( 0 ); - } -#endif /* MBEDTLS_PSA_HAS_ITS_IO */ - #if defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER) if( strcmp( "MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER", config ) == 0 ) { @@ -1202,13 +1194,13 @@ int query_config( const char *config ) } #endif /* MBEDTLS_PSA_CRYPTO_SPM */ -#if defined(MBEDTLS_PSA_HAS_ITS_IO) - if( strcmp( "MBEDTLS_PSA_HAS_ITS_IO", config ) == 0 ) +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) + if( strcmp( "MBEDTLS_PSA_INJECT_ENTROPY", config ) == 0 ) { - MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_HAS_ITS_IO ); + MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_INJECT_ENTROPY ); return( 0 ); } -#endif /* MBEDTLS_PSA_HAS_ITS_IO */ +#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ #if defined(MBEDTLS_RSA_NO_CRT) if( strcmp( "MBEDTLS_RSA_NO_CRT", config ) == 0 ) @@ -1946,21 +1938,13 @@ int query_config( const char *config ) } #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C) - if( strcmp( "MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C", config ) == 0 ) +#if defined(MBEDTLS_PSA_ITS_FILE_C) + if( strcmp( "MBEDTLS_PSA_ITS_FILE_C", config ) == 0 ) { - MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C ); + MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_ITS_FILE_C ); return( 0 ); } -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C */ - -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C) - if( strcmp( "MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C", config ) == 0 ) - { - MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C ); - return( 0 ); - } -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C */ +#endif /* MBEDTLS_PSA_ITS_FILE_C */ #if defined(MBEDTLS_RIPEMD160_C) if( strcmp( "MBEDTLS_RIPEMD160_C", config ) == 0 ) diff --git a/scripts/config.pl b/scripts/config.pl index 624decaca7..6927c4b40e 100755 --- a/scripts/config.pl +++ b/scripts/config.pl @@ -101,9 +101,8 @@ MBEDTLS_PKCS11_C MBEDTLS_NO_UDBL_DIVISION MBEDTLS_NO_64BIT_MULTIPLICATION MBEDTLS_PSA_CRYPTO_SPM -MBEDTLS_PSA_HAS_ITS_IO MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER -MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C +MBEDTLS_PSA_INJECT_ENTROPY MBEDTLS_USE_PSA_CRYPTO _ALT\s*$ ); @@ -125,9 +124,8 @@ MBEDTLS_MEMORY_BUFFER_ALLOC_C MBEDTLS_PLATFORM_TIME_ALT MBEDTLS_PLATFORM_FPRINTF_ALT MBEDTLS_PSA_CRYPTO_STORAGE_C -MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C -MBEDTLS_PSA_HAS_ITS_IO +MBEDTLS_PSA_ITS_FILE_C ); # Things that should be enabled in "full" even if they match @excluded diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 76a4608e16..1b239a45db 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -141,7 +141,7 @@ add_test_suite(psa_crypto_init) add_test_suite(psa_crypto_metadata) add_test_suite(psa_crypto_persistent_key) add_test_suite(psa_crypto_slot_management) -add_test_suite(psa_crypto_storage_file) +add_test_suite(psa_its) add_test_suite(shax) add_test_suite(timing) add_test_suite(rsa) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 2806426c12..d995ba50ce 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -689,8 +689,9 @@ component_test_no_platform () { scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C + scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C + scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C # Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19, # to re-enable platform integration features otherwise disabled in C99 builds make CC=gcc CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -O0 -D_DEFAULT_SOURCE' lib programs @@ -870,7 +871,8 @@ component_build_arm_none_eabi_gcc () { scripts/config.pl unset MBEDTLS_NET_C scripts/config.pl unset MBEDTLS_TIMING_C scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C + scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C + scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY @@ -889,7 +891,8 @@ component_build_arm_none_eabi_gcc_no_udbl_division () { scripts/config.pl unset MBEDTLS_NET_C scripts/config.pl unset MBEDTLS_TIMING_C scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C + scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C + scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY @@ -911,7 +914,8 @@ component_build_arm_none_eabi_gcc_no_64bit_multiplication () { scripts/config.pl unset MBEDTLS_NET_C scripts/config.pl unset MBEDTLS_TIMING_C scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C + scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C + scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY @@ -933,7 +937,8 @@ component_build_armcc () { scripts/config.pl unset MBEDTLS_NET_C scripts/config.pl unset MBEDTLS_TIMING_C scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C + scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C + scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED scripts/config.pl unset MBEDTLS_HAVE_TIME diff --git a/tests/suites/test_suite_psa_crypto_entropy.function b/tests/suites/test_suite_psa_crypto_entropy.function index a14657e9f3..91e210e0e8 100644 --- a/tests/suites/test_suite_psa_crypto_entropy.function +++ b/tests/suites/test_suite_psa_crypto_entropy.function @@ -2,17 +2,38 @@ #include #include "psa/crypto.h" -#include "psa_prot_internal_storage.h" #include "mbedtls/entropy.h" #include "mbedtls/entropy_poll.h" +#if defined(MBEDTLS_PSA_ITS_FILE_C) +#include +#else +#include +#endif + /* Calculating the minimum allowed entropy size in bytes */ #define MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE) +/* Remove the entropy seed file. Since the library does not expose a way + * to do this (it would be a security risk if such a function was ever + * accessible in production), implement this functionality in a white-box + * manner. */ +psa_status_t remove_seed_file( void ) +{ +#if defined(MBEDTLS_PSA_ITS_FILE_C) + if( remove( "00000000ffffff52.psa_its" ) == 0 ) + return( PSA_SUCCESS ); + else + return( PSA_ERROR_DOES_NOT_EXIST ); +#else + return( psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ) ); +#endif +} + /* END_HEADER */ /* BEGIN_DEPENDENCIES - * depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PSA_HAS_ITS_IO:MBEDTLS_PSA_CRYPTO_C + * depends_on:MBEDTLS_PSA_INJECT_ENTROPY * END_DEPENDENCIES */ @@ -42,7 +63,7 @@ void validate_entropy_seed_injection( int seed_length_a, { seed[i] = i; } - status = psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ); + status = remove_seed_file( ); TEST_ASSERT( ( status == PSA_SUCCESS ) || ( status == PSA_ERROR_DOES_NOT_EXIST ) ); status = mbedtls_psa_inject_entropy( seed, seed_length_a ); @@ -55,7 +76,7 @@ void validate_entropy_seed_injection( int seed_length_a, TEST_ASSERT( memcmp( output, zeros, sizeof( output ) ) != 0 ); exit: mbedtls_free( seed ); - psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ); + remove_seed_file( ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -64,19 +85,19 @@ exit: void run_entropy_inject_with_crypto_init( ) { psa_status_t status; - int i; + size_t i; uint8_t seed[MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE] = { 0 }; /* fill seed with some data */ for( i = 0; i < sizeof( seed ); ++i ) { seed[i] = i; } - status = psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ); + status = remove_seed_file( ); TEST_ASSERT( ( status == PSA_SUCCESS ) || ( status == PSA_ERROR_DOES_NOT_EXIST ) ); status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) ); PSA_ASSERT( status ); - status = psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ); + status = remove_seed_file( ); TEST_EQUAL( status, PSA_SUCCESS ); status = psa_crypto_init( ); TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_ENTROPY ); @@ -89,7 +110,7 @@ void run_entropy_inject_with_crypto_init( ) status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) ); TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED ); exit: - psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ); + remove_seed_file( ); mbedtls_psa_crypto_free( ); } /* END_CASE */ diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data index 613968dd51..f97a5e0636 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.data +++ b/tests/suites/test_suite_psa_crypto_persistent_key.data @@ -18,7 +18,7 @@ parse_storage_data_check:"505341004b4559":"":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_US # Not specific to files, but only run this test in an environment where the maximum size could be reached. Save maximum size persistent raw key -depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C +depends_on:MBEDTLS_PSA_ITS_FILE_C save_large_persistent_key:0:PSA_SUCCESS Save larger than maximum size persistent raw key, should fail diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index 2fa307e208..90e10f66b6 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -2,7 +2,6 @@ #include #include "psa/crypto.h" #include "psa_crypto_storage.h" -#include "psa_crypto_storage_backend.h" #include "mbedtls/md.h" #define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY" diff --git a/tests/suites/test_suite_psa_crypto_storage_file.data b/tests/suites/test_suite_psa_crypto_storage_file.data deleted file mode 100644 index 4b068e1218..0000000000 --- a/tests/suites/test_suite_psa_crypto_storage_file.data +++ /dev/null @@ -1,43 +0,0 @@ -PSA Storage Load verify loaded file -depends_on:MBEDTLS_FS_IO -load_data_from_file:1:"deadbeef":1:4:PSA_SUCCESS - -PSA Storage Load check slots dont share state -depends_on:MBEDTLS_FS_IO -load_data_from_file:2:"deadbeef":1:4:PSA_ERROR_STORAGE_FAILURE - -PSA Storage Load zero length file -depends_on:MBEDTLS_FS_IO -load_data_from_file:1:"":1:1:PSA_SUCCESS - -PSA Storage Load less than capacity of data buffer -depends_on:MBEDTLS_FS_IO -load_data_from_file:1:"deadbeef":1:5:PSA_SUCCESS - -PSA Storage Load nonexistent file location, should fail -depends_on:MBEDTLS_FS_IO -load_data_from_file:1:"deadbeef":0:4:PSA_ERROR_STORAGE_FAILURE - -PSA Storage Store verify stored file -depends_on:MBEDTLS_FS_IO -write_data_to_file:"deadbeef":PSA_SUCCESS - -PSA Storage Store into preexisting location, should fail -depends_on:MBEDTLS_FS_IO -write_data_to_prexisting_file:"psa_key_slot_1":"deadbeef":PSA_ERROR_ALREADY_EXISTS - -PSA Storage Store, preexisting temp_location file, should succeed -depends_on:MBEDTLS_FS_IO -write_data_to_prexisting_file:"psa_key_slot_0":"deadbeef":PSA_SUCCESS - -PSA Storage Get data size verify data size -depends_on:MBEDTLS_FS_IO -get_file_size:"deadbeef":4:PSA_SUCCESS:1 - -PSA Storage Get data size verify data size zero length file -depends_on:MBEDTLS_FS_IO -get_file_size:"":0:PSA_SUCCESS:1 - -PSA Storage Get data size nonexistent file location, should fail -depends_on:MBEDTLS_FS_IO -get_file_size:"deadbeef":4:PSA_ERROR_DOES_NOT_EXIST:0 diff --git a/tests/suites/test_suite_psa_crypto_storage_file.function b/tests/suites/test_suite_psa_crypto_storage_file.function deleted file mode 100644 index e596be1d79..0000000000 --- a/tests/suites/test_suite_psa_crypto_storage_file.function +++ /dev/null @@ -1,157 +0,0 @@ -/* BEGIN_HEADER */ -#include -#include "psa/crypto.h" -#include "psa_crypto_storage_backend.h" - -/* END_HEADER */ - -/* BEGIN_DEPENDENCIES - * depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C - * END_DEPENDENCIES - */ - -/* BEGIN_CASE */ -void load_data_from_file( int id_to_load_arg, - data_t *data, int should_make_file, - int capacity_arg, int expected_status ) -{ - psa_key_id_t id_to_load = id_to_load_arg; - char slot_location[] = "psa_key_slot_1"; - psa_status_t status; - int ret; - size_t file_size = 0; - uint8_t *loaded_data = NULL; - size_t capacity = (size_t) capacity_arg; - - if( should_make_file == 1 ) - { - /* Create a file with data contents, with mask permissions. */ - FILE *file; - file = fopen( slot_location, "wb+" ); - TEST_ASSERT( file != NULL ); - file_size = fwrite( data->x, 1, data->len, file ); - TEST_EQUAL( file_size, data->len ); - ret = fclose( file ); - TEST_EQUAL( ret, 0 ); - } - - /* Read from the file with psa_crypto_storage_load. */ - ASSERT_ALLOC( loaded_data, capacity ); - status = psa_crypto_storage_load( id_to_load, loaded_data, file_size ); - - /* Check we get the expected status. */ - TEST_EQUAL( status, expected_status ); - if( status != PSA_SUCCESS ) - goto exit; - - /* Check that the file data and data length is what we expect. */ - ASSERT_COMPARE( data->x, data->len, loaded_data, file_size ); - -exit: - mbedtls_free( loaded_data ); - remove( slot_location ); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void write_data_to_file( data_t *data, int expected_status ) -{ - char slot_location[] = "psa_key_slot_1"; - psa_status_t status; - int ret; - FILE *file; - size_t file_size; - size_t num_read; - uint8_t *loaded_data = NULL; - - /* Write data to file. */ - status = psa_crypto_storage_store( 1, data->x, data->len ); - - /* Check that we got the expected status. */ - TEST_EQUAL( status, expected_status ); - if( status != PSA_SUCCESS ) - goto exit; - - /* Check that the file length is what we expect */ - file = fopen( slot_location, "rb" ); - TEST_ASSERT( file != NULL ); - fseek( file, 0, SEEK_END ); - file_size = (size_t) ftell( file ); - fseek( file, 0, SEEK_SET ); - TEST_EQUAL( file_size, data->len ); - - /* Check that the file contents are what we expect */ - ASSERT_ALLOC( loaded_data, data->len ); - - num_read = fread( loaded_data, 1, file_size, file ); - TEST_EQUAL( num_read, file_size ); - ASSERT_COMPARE( data->x, data->len, loaded_data, file_size ); - ret = fclose( file ); - TEST_EQUAL( ret, 0 ); - -exit: - mbedtls_free( loaded_data ); - remove( slot_location ); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void get_file_size( data_t *data, int expected_data_length, - int expected_status, int should_make_file ) -{ - char slot_location[] = "psa_key_slot_1"; - psa_status_t status; - int ret; - size_t file_size; - - if( should_make_file ) - { - /* Create a file with data contents, with mask permissions. */ - FILE *file; - file = fopen( slot_location, "wb+" ); - TEST_ASSERT( file != NULL ); - file_size = fwrite( data->x, 1, data->len, file ); - TEST_EQUAL( file_size, data->len ); - ret = fclose( file ); - TEST_EQUAL( ret, 0 ); - } - - /* Check get data size is what we expect */ - status = psa_crypto_storage_get_data_length( 1, &file_size ); - TEST_EQUAL( status, expected_status ); - if( expected_status == PSA_SUCCESS ) - TEST_EQUAL( file_size, (size_t)expected_data_length ); - -exit: - remove( slot_location ); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void write_data_to_prexisting_file( char *preexist_file_location, - data_t *data, int expected_status ) -{ - char slot_location[] = "psa_key_slot_1"; - psa_status_t status; - int ret; - FILE *file; - - /* Create file first */ - file = fopen( preexist_file_location, "wb" ); - TEST_ASSERT( file != NULL ); - ret = fclose( file ); - TEST_EQUAL( ret, 0 ); - - /* Write data to file. */ - status = psa_crypto_storage_store( 1, data->x, data->len ); - - /* Check that we got the expected status. */ - TEST_EQUAL( status, expected_status ); - if( status != PSA_SUCCESS ) - goto exit; - -exit: - remove( preexist_file_location ); - remove( slot_location ); -} -/* END_CASE */ diff --git a/tests/suites/test_suite_psa_its.data b/tests/suites/test_suite_psa_its.data new file mode 100644 index 0000000000..63ca1290d2 --- /dev/null +++ b/tests/suites/test_suite_psa_its.data @@ -0,0 +1,65 @@ +Set/get/remove 0 bytes +set_get_remove:0:0:"" + +Set/get/remove 42 bytes +set_get_remove:0:0:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829" + +Set/get/remove 1000 bytes +set_get_remove:0:0:"6a07ecfcc7c7bfe0129d56d2dcf2955a12845b9e6e0034b0ed7226764261c6222a07b9f654deb682130eb1cd07ed298324e60a46f9c76c8a5a0be000c69e93dd81054ca21fbc6190cef7745e9d5436f70e20e10cbf111d1d40c9ceb83be108775199d81abaf0fecfe30eaa08e7ed82517cba939de4449f7ac5c730fcbbf56e691640b0129db0e178045dd2034262de9138873d9bdca57685146a3d516ff13c29e6628a00097435a8e10fef7faff62d2963c303a93793e2211d8604556fec08cd59c0f5bd1f22eea64be13e88b3f454781e83fe6e771d3d81eb2fbe2021e276f42a93db5343d767d854115e74f5e129a8036b1e81aced9872709d515e00bcf2098ccdee23006b0e836b27dc8aaf30f53fe58a31a6408abb79b13098c22e262a98040f9b09809a3b43bd42eb01cf1d17bbc8b4dfe51fa6573d4d8741943e3ae71a649e194c1218f2e20556c7d8cfe8c64d8cc1aa94531fbf638768c7d19b3c079299cf4f26ed3f964efb8fd23d82b4157a51f46da11156c74e2d6e2fd788869ebb52429e12a82da2ba083e2e74565026162f29ca22582da72a2698e7c5d958b919bc2cdfe12f50364ccfed30efd5cd120a7d5f196b2bd7f911bb44d5871eb3dedcd70ece7faf464988f9fe361f23d7244b1e08bee921d0f28bdb4912675809d099876d4d15b7d13ece356e1f2a5dce64feb3d6749a07a4f2b7721190e17a9ab2966e48b6d25187070b81eb45b1c44608b2f0e175958ba57fcf1b2cd145eea5fd4de858d157ddac69dfbb5d5d6f0c1691b0fae5a143b6e58cdf5000f28d74b3322670ed11e740c828c7bfad4e2f392012da3ac931ea26ed15fd003e604071f5900c6e1329d021805d50da9f1e732a49bcc292d9f8e07737cfd59442e8d7aaa813b18183a68e22bf6b4519545dd7d2d519db3652be4131bad4f4b0625dbaa749e979f6ee8c1b97803cb50a2fa20dc883eac932a824b777b226e15294de6a80be3ddef41478fe18172d64407a004de6bae18bc60e90c902c1cbb0e1633395b42391f5011be0d480541987609b0cd8d902ea29f86f73e7362340119323eb0ea4f672b70d6e9a9df5235f9f1965f5cb0c2998c5a7f4754e83eeda5d95fefbbaaa0875fe37b7ca461e7281cc5479162627c5a709b45fd9ddcde4dfb40659e1d70fa7361d9fc7de24f9b8b13259423fdae4dbb98d691db687467a5a7eb027a4a0552a03e430ac8a32de0c30160ba60a036d6b9db2d6182193283337b92e7438dc5d6eb4fa00200d8efa9127f1c3a32ac8e202262773aaa5a965c6b8035b2e5706c32a55511560429ddf1df4ac34076b7eedd9cf94b6915a894fdd9084ffe3db0e7040f382c3cd04f0484595de95865c36b6bf20f46a78cdfb37228acbeb218de798b9586f6d99a0cbae47e80d" + +Set/get/remove with flags +set_get_remove:0:0x12345678:"abcdef" + +Overwrite 0 -> 3 +set_overwrite:0:0x12345678:"":0x01020304:"abcdef" + +Overwrite 3 -> 0 +set_overwrite:0:0x12345678:"abcdef":0x01020304:"" + +Overwrite 3 -> 3 +set_overwrite:0:0x12345678:"123456":0x01020304:"abcdef" + +Overwrite 3 -> 18 +set_overwrite:0:0x12345678:"abcdef":0x01020304:"404142434445464748494a4b4c4d4e4f5051" + +Overwrite 18 -> 3 +set_overwrite:0:0x12345678:"404142434445464748494a4b4c4d4e4f5051":0x01020304:"abcdef" + +Multiple files +set_multiple:0:5 + +Non-existent file +nonexistent:0:0 + +Removed file +nonexistent:0:1 + +Get 0 bytes of 10 at 10 +get_at:0:"40414243444546474849":10:0:PSA_SUCCESS + +Get 1 byte of 10 at 9 +get_at:0:"40414243444546474849":9:1:PSA_SUCCESS + +Get 0 bytes of 10 at 0 +get_at:0:"40414243444546474849":0:0:PSA_SUCCESS + +Get 1 byte of 10 at 0 +get_at:0:"40414243444546474849":0:1:PSA_SUCCESS + +Get 2 bytes of 10 at 1 +get_at:0:"40414243444546474849":1:2:PSA_SUCCESS + +Get 1 byte of 10 at 10: out of range +get_at:0:"40414243444546474849":10:1:PSA_ERROR_INVALID_ARGUMENT + +Get 1 byte of 10 at 11: out of range +get_at:0:"40414243444546474849":11:1:PSA_ERROR_INVALID_ARGUMENT + +Get 0 bytes of 10 at 11: out of range +get_at:0:"40414243444546474849":11:0:PSA_ERROR_INVALID_ARGUMENT + +Get -1 byte of 10 at 10: out of range +get_at:0:"40414243444546474849":10:-1:PSA_ERROR_INVALID_ARGUMENT + +Get 1 byte of 10 at -1: out of range +get_at:0:"40414243444546474849":-1:1:PSA_ERROR_INVALID_ARGUMENT diff --git a/tests/suites/test_suite_psa_its.function b/tests/suites/test_suite_psa_its.function new file mode 100644 index 0000000000..867f64f6b6 --- /dev/null +++ b/tests/suites/test_suite_psa_its.function @@ -0,0 +1,213 @@ +/* BEGIN_HEADER */ +#include "../library/psa_crypto_its.h" + +/* Internal definitions of the implementation, copied for the sake of + * some of the tests and of the cleanup code. */ +#define PSA_ITS_STORAGE_PREFIX "" +#define PSA_ITS_STORAGE_FILENAME_PATTERN "%08lx%08lx" +#define PSA_ITS_STORAGE_SUFFIX ".psa_its" +#define PSA_ITS_STORAGE_FILENAME_LENGTH \ + ( sizeof( PSA_ITS_STORAGE_PREFIX ) - 1 + /*prefix without terminating 0*/ \ + 16 + /*UID (64-bit number in hex)*/ \ + sizeof( PSA_ITS_STORAGE_SUFFIX ) - 1 + /*suffix without terminating 0*/ \ + 1 /*terminating null byte*/ ) +#define PSA_ITS_STORAGE_TEMP \ + PSA_ITS_STORAGE_PREFIX "tempfile" PSA_ITS_STORAGE_SUFFIX +static void psa_its_fill_filename( psa_storage_uid_t uid, char *filename ) +{ + /* Break up the UID into two 32-bit pieces so as not to rely on + * long long support in snprintf. */ + mbedtls_snprintf( filename, PSA_ITS_STORAGE_FILENAME_LENGTH, + "%s" PSA_ITS_STORAGE_FILENAME_PATTERN "%s", + PSA_ITS_STORAGE_PREFIX, + (unsigned long) ( uid >> 32 ), + (unsigned long) ( uid & 0xffffffff ), + PSA_ITS_STORAGE_SUFFIX ); +} + +/* Maximum uid used by the test, recorded so that cleanup() can delete + * all files. 0xffffffffffffffff is always cleaned up, so it does not + * need to and should not be taken into account for uid_max. */ +static psa_storage_uid_t uid_max = 0; + +static void cleanup( void ) +{ + char filename[PSA_ITS_STORAGE_FILENAME_LENGTH]; + psa_storage_uid_t uid; + for( uid = 0; uid < uid_max; uid++ ) + { + psa_its_fill_filename( uid, filename ); + remove( filename ); + } + psa_its_fill_filename( (psa_storage_uid_t)( -1 ), filename ); + remove( filename ); + remove( PSA_ITS_STORAGE_TEMP ); + uid_max = 0; +} + +static psa_status_t psa_its_set_wrap( psa_storage_uid_t uid, + uint32_t data_length, + const void *p_data, + psa_storage_create_flags_t create_flags ) +{ + if( uid_max != (psa_storage_uid_t)( -1 ) && uid_max < uid ) + uid_max = uid; + return( psa_its_set( uid, data_length, p_data, create_flags ) ); +} + +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_PSA_ITS_FILE_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ +void set_get_remove( int uid_arg, int flags_arg, data_t *data ) +{ + psa_storage_uid_t uid = uid_arg; + uint32_t flags = flags_arg; + struct psa_storage_info_t info; + unsigned char *buffer = NULL; + + ASSERT_ALLOC( buffer, data->len ); + + PSA_ASSERT( psa_its_set_wrap( uid, data->len, data->x, flags ) ); + + PSA_ASSERT( psa_its_get_info( uid, &info ) ); + TEST_ASSERT( info.size == data->len ); + TEST_ASSERT( info.flags == flags ); + PSA_ASSERT( psa_its_get( uid, 0, data->len, buffer ) ); + ASSERT_COMPARE( data->x, data->len, buffer, data->len ); + + PSA_ASSERT( psa_its_remove( uid ) ); + +exit: + mbedtls_free( buffer ); + cleanup( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void set_overwrite( int uid_arg, + int flags1_arg, data_t *data1, + int flags2_arg, data_t *data2 ) +{ + psa_storage_uid_t uid = uid_arg; + uint32_t flags1 = flags1_arg; + uint32_t flags2 = flags2_arg; + struct psa_storage_info_t info; + unsigned char *buffer = NULL; + + ASSERT_ALLOC( buffer, MAX( data1->len, data2->len ) ); + + PSA_ASSERT( psa_its_set_wrap( uid, data1->len, data1->x, flags1 ) ); + PSA_ASSERT( psa_its_get_info( uid, &info ) ); + TEST_ASSERT( info.size == data1->len ); + TEST_ASSERT( info.flags == flags1 ); + PSA_ASSERT( psa_its_get( uid, 0, data1->len, buffer ) ); + ASSERT_COMPARE( data1->x, data1->len, buffer, data1->len ); + + PSA_ASSERT( psa_its_set_wrap( uid, data2->len, data2->x, flags2 ) ); + PSA_ASSERT( psa_its_get_info( uid, &info ) ); + TEST_ASSERT( info.size == data2->len ); + TEST_ASSERT( info.flags == flags2 ); + PSA_ASSERT( psa_its_get( uid, 0, data2->len, buffer ) ); + ASSERT_COMPARE( data2->x, data2->len, buffer, data2->len ); + + PSA_ASSERT( psa_its_remove( uid ) ); + +exit: + mbedtls_free( buffer ); + cleanup( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void set_multiple( int first_id, int count ) +{ + psa_storage_uid_t uid0 = first_id; + psa_storage_uid_t uid; + char stored[40]; + char retrieved[40]; + + memset( stored, '.', sizeof( stored ) ); + for( uid = uid0; uid < uid0 + count; uid++ ) + { + mbedtls_snprintf( stored, sizeof( stored ), + "Content of file 0x%08lx", (unsigned long) uid ); + PSA_ASSERT( psa_its_set_wrap( uid, sizeof( stored ), stored, 0 ) ); + } + + for( uid = uid0; uid < uid0 + count; uid++ ) + { + mbedtls_snprintf( stored, sizeof( stored ), + "Content of file 0x%08lx", (unsigned long) uid ); + PSA_ASSERT( psa_its_get( uid, 0, sizeof( stored ), retrieved ) ); + ASSERT_COMPARE( retrieved, sizeof( stored ), + stored, sizeof( stored ) ); + PSA_ASSERT( psa_its_remove( uid ) ); + TEST_ASSERT( psa_its_get( uid, 0, 0, NULL ) == + PSA_ERROR_DOES_NOT_EXIST ); + } + +exit: + cleanup( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void nonexistent( int uid_arg, int create_and_remove ) +{ + psa_storage_uid_t uid = uid_arg; + struct psa_storage_info_t info; + + if( create_and_remove ) + { + PSA_ASSERT( psa_its_set_wrap( uid, 0, NULL, 0 ) ); + PSA_ASSERT( psa_its_remove( uid ) ); + } + + TEST_ASSERT( psa_its_remove( uid ) == PSA_ERROR_DOES_NOT_EXIST ); + TEST_ASSERT( psa_its_get_info( uid, &info ) == + PSA_ERROR_DOES_NOT_EXIST ); + TEST_ASSERT( psa_its_get( uid, 0, 0, NULL ) == + PSA_ERROR_DOES_NOT_EXIST ); + +exit: + cleanup( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void get_at( int uid_arg, data_t *data, + int offset, int length_arg, + int expected_status ) +{ + psa_storage_uid_t uid = uid_arg; + unsigned char *buffer = NULL; + psa_status_t status; + size_t length = length_arg >= 0 ? length_arg : 0; + unsigned char *trailer; + size_t i; + + ASSERT_ALLOC( buffer, length + 16 ); + trailer = buffer + length; + memset( trailer, '-', 16 ); + + PSA_ASSERT( psa_its_set_wrap( uid, data->len, data->x, 0 ) ); + + status = psa_its_get( uid, offset, length_arg, buffer ); + TEST_ASSERT( status == (psa_status_t) expected_status ); + if( status == PSA_SUCCESS ) + ASSERT_COMPARE( data->x + offset, length, + buffer, length ); + for( i = 0; i < 16; i++ ) + TEST_ASSERT( trailer[i] == '-' ); + PSA_ASSERT( psa_its_remove( uid ) ); + +exit: + mbedtls_free( buffer ); + cleanup( ); +} +/* END_CASE */ diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index bb92d8f8c6..c56e976a70 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -238,10 +238,10 @@ + - @@ -301,8 +301,7 @@ - - +