Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers psa_crypto_storage.c Source File

psa_crypto_storage.c

00001 /*
00002  *  PSA persistent key storage
00003  */
00004 /*  Copyright (C) 2018, ARM Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of mbed TLS (https://tls.mbed.org)
00020  */
00021 
00022 #if defined(MBEDTLS_CONFIG_FILE)
00023 #include MBEDTLS_CONFIG_FILE
00024 #else
00025 #include "mbedtls/config.h"
00026 #endif
00027 
00028 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
00029 
00030 #include <stdlib.h>
00031 #include <string.h>
00032 
00033 #include "psa_crypto_service_integration.h"
00034 #include "psa/crypto.h"
00035 #include "psa_crypto_storage.h"
00036 #include "mbedtls/platform_util.h"
00037 
00038 #if defined(MBEDTLS_PSA_ITS_FILE_C)
00039 #include "psa_crypto_its.h"
00040 #else /* Native ITS implementation */
00041 #include "psa/error.h"
00042 #include "psa/internal_trusted_storage.h"
00043 #endif
00044 
00045 #if defined(MBEDTLS_PLATFORM_C)
00046 #include "mbedtls/platform.h"
00047 #else
00048 #include <stdlib.h>
00049 #define mbedtls_calloc   calloc
00050 #define mbedtls_free     free
00051 #endif
00052 
00053 
00054 
00055 /****************************************************************/
00056 /* Key storage */
00057 /****************************************************************/
00058 
00059 /* Determine a file name (ITS file identifier) for the given key file
00060  * identifier. The file name must be distinct from any file that is used
00061  * for a purpose other than storing a key. Currently, the only such file
00062  * is the random seed file whose name is PSA_CRYPTO_ITS_RANDOM_SEED_UID
00063  * and whose value is 0xFFFFFF52. */
00064 static psa_storage_uid_t psa_its_identifier_of_slot( psa_key_file_id_t file_id )
00065 {
00066 #if defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER) && \
00067     defined(PSA_CRYPTO_SECURE)
00068     /* Encode the owner in the upper 32 bits. This means that if
00069      * owner values are nonzero (as they are on a PSA platform),
00070      * no key file will ever have a value less than 0x100000000, so
00071      * the whole range 0..0xffffffff is available for non-key files. */
00072     uint32_t unsigned_owner = (uint32_t) file_id.owner;
00073     return( (uint64_t) unsigned_owner << 32 | file_id.key_id );
00074 #else
00075     /* Use the key id directly as a file name.
00076      * psa_is_key_file_id_valid() in psa_crypto_slot_management.c
00077      * is responsible for ensuring that key identifiers do not have a
00078      * value that is reserved for non-key files. */
00079     return( file_id );
00080 #endif
00081 }
00082 
00083 /**
00084  * \brief Load persistent data for the given key slot number.
00085  *
00086  * This function reads data from a storage backend and returns the data in a
00087  * buffer.
00088  *
00089  * \param key               Persistent identifier of the key to be loaded. This
00090  *                          should be an occupied storage location.
00091  * \param[out] data         Buffer where the data is to be written.
00092  * \param data_size         Size of the \c data buffer in bytes.
00093  *
00094  * \retval PSA_SUCCESS
00095  * \retval PSA_ERROR_STORAGE_FAILURE
00096  * \retval PSA_ERROR_DOES_NOT_EXIST
00097  */
00098 static psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key,
00099                                              uint8_t *data,
00100                                              size_t data_size )
00101 {
00102     psa_status_t status;
00103     psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
00104     struct psa_storage_info_t data_identifier_info;
00105     size_t data_length = 0;
00106 
00107     status = psa_its_get_info( data_identifier, &data_identifier_info );
00108     if( status  != PSA_SUCCESS )
00109         return( status );
00110 
00111     status = psa_its_get( data_identifier, 0, (uint32_t) data_size, data, &data_length );
00112     if( data_size  != data_length )
00113         return( PSA_ERROR_STORAGE_FAILURE );
00114 
00115     return( status );
00116 }
00117 
00118 int psa_is_key_present_in_storage( const psa_key_file_id_t key )
00119 {
00120     psa_status_t ret;
00121     psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
00122     struct psa_storage_info_t data_identifier_info;
00123 
00124     ret = psa_its_get_info( data_identifier, &data_identifier_info );
00125 
00126     if( ret == PSA_ERROR_DOES_NOT_EXIST )
00127         return( 0 );
00128     return( 1 );
00129 }
00130 
00131 /**
00132  * \brief Store persistent data for the given key slot number.
00133  *
00134  * This function stores the given data buffer to a persistent storage.
00135  *
00136  * \param key           Persistent identifier of the key to be stored. This
00137  *                      should be an unoccupied storage location.
00138  * \param[in] data      Buffer containing the data to be stored.
00139  * \param data_length   The number of bytes
00140  *                      that make up the data.
00141  *
00142  * \retval PSA_SUCCESS
00143  * \retval PSA_ERROR_INSUFFICIENT_STORAGE
00144  * \retval PSA_ERROR_STORAGE_FAILURE
00145  * \retval PSA_ERROR_ALREADY_EXISTS
00146  */
00147 static psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key,
00148                                               const uint8_t *data,
00149                                               size_t data_length )
00150 {
00151     psa_status_t status;
00152     psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
00153     struct psa_storage_info_t data_identifier_info;
00154 
00155     if( psa_is_key_present_in_storage( key ) == 1 )
00156         return( PSA_ERROR_ALREADY_EXISTS );
00157 
00158     status = psa_its_set( data_identifier, (uint32_t) data_length, data, 0 );
00159     if( status != PSA_SUCCESS )
00160     {
00161         return( PSA_ERROR_STORAGE_FAILURE );
00162     }
00163 
00164     status = psa_its_get_info( data_identifier, &data_identifier_info );
00165     if( status != PSA_SUCCESS )
00166     {
00167         goto exit;
00168     }
00169 
00170     if( data_identifier_info.size != data_length )
00171     {
00172         status = PSA_ERROR_STORAGE_FAILURE;
00173         goto exit;
00174     }
00175 
00176 exit:
00177     if( status != PSA_SUCCESS )
00178         psa_its_remove( data_identifier );
00179     return( status );
00180 }
00181 
00182 psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key )
00183 {
00184     psa_status_t ret;
00185     psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
00186     struct psa_storage_info_t data_identifier_info;
00187 
00188     ret = psa_its_get_info( data_identifier, &data_identifier_info );
00189     if( ret == PSA_ERROR_DOES_NOT_EXIST )
00190         return( PSA_SUCCESS );
00191 
00192     if( psa_its_remove( data_identifier ) != PSA_SUCCESS )
00193         return( PSA_ERROR_STORAGE_FAILURE );
00194 
00195     ret = psa_its_get_info( data_identifier, &data_identifier_info );
00196     if( ret != PSA_ERROR_DOES_NOT_EXIST )
00197         return( PSA_ERROR_STORAGE_FAILURE );
00198 
00199     return( PSA_SUCCESS );
00200 }
00201 
00202 /**
00203  * \brief Get data length for given key slot number.
00204  *
00205  * \param key               Persistent identifier whose stored data length
00206  *                          is to be obtained.
00207  * \param[out] data_length  The number of bytes that make up the data.
00208  *
00209  * \retval PSA_SUCCESS
00210  * \retval PSA_ERROR_STORAGE_FAILURE
00211  */
00212 static psa_status_t psa_crypto_storage_get_data_length(
00213     const psa_key_file_id_t key,
00214     size_t *data_length )
00215 {
00216     psa_status_t status;
00217     psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
00218     struct psa_storage_info_t data_identifier_info;
00219 
00220     status = psa_its_get_info( data_identifier, &data_identifier_info );
00221     if( status != PSA_SUCCESS )
00222         return( status );
00223 
00224     *data_length = (size_t) data_identifier_info.size;
00225 
00226     return( PSA_SUCCESS );
00227 }
00228 
00229 /*
00230  * 32-bit integer manipulation macros (little endian)
00231  */
00232 #ifndef GET_UINT32_LE
00233 #define GET_UINT32_LE( n, b, i )                        \
00234 {                                                       \
00235     (n) = ( (uint32_t) (b)[(i)    ]       )             \
00236         | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
00237         | ( (uint32_t) (b)[(i) + 2] << 16 )             \
00238         | ( (uint32_t) (b)[(i) + 3] << 24 );            \
00239 }
00240 #endif
00241 
00242 #ifndef PUT_UINT32_LE
00243 #define PUT_UINT32_LE( n, b, i )                                \
00244 {                                                               \
00245     (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
00246     (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
00247     (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
00248     (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
00249 }
00250 #endif
00251 
00252 /**
00253  * Persistent key storage magic header.
00254  */
00255 #define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
00256 #define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ( sizeof( PSA_KEY_STORAGE_MAGIC_HEADER ) )
00257 
00258 typedef struct {
00259     uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
00260     uint8_t version[4];
00261     uint8_t lifetime[sizeof( psa_key_lifetime_t )];
00262     uint8_t type[sizeof( psa_key_type_t )];
00263     uint8_t policy[sizeof( psa_key_policy_t )];
00264     uint8_t data_len[4];
00265     uint8_t key_data[];
00266 } psa_persistent_key_storage_format;
00267 
00268 void psa_format_key_data_for_storage( const uint8_t *data,
00269                                       const size_t data_length,
00270                                       const psa_core_key_attributes_t *attr,
00271                                       uint8_t *storage_data )
00272 {
00273     psa_persistent_key_storage_format *storage_format =
00274         (psa_persistent_key_storage_format *) storage_data;
00275 
00276     memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH );
00277     PUT_UINT32_LE( 0, storage_format->version, 0 );
00278     PUT_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
00279     PUT_UINT32_LE( attr->type, storage_format->type, 0 );
00280     PUT_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
00281     PUT_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
00282     PUT_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
00283     PUT_UINT32_LE( data_length, storage_format->data_len, 0 );
00284     memcpy( storage_format->key_data, data, data_length );
00285 }
00286 
00287 static psa_status_t check_magic_header( const uint8_t *data )
00288 {
00289     if( memcmp( data, PSA_KEY_STORAGE_MAGIC_HEADER,
00290                 PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ) != 0 )
00291         return( PSA_ERROR_STORAGE_FAILURE );
00292     return( PSA_SUCCESS );
00293 }
00294 
00295 psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
00296                                               size_t storage_data_length,
00297                                               uint8_t **key_data,
00298                                               size_t *key_data_length,
00299                                               psa_core_key_attributes_t *attr )
00300 {
00301     psa_status_t status;
00302     const psa_persistent_key_storage_format *storage_format =
00303         (const psa_persistent_key_storage_format *)storage_data;
00304     uint32_t version;
00305 
00306     if( storage_data_length < sizeof(*storage_format) )
00307         return( PSA_ERROR_STORAGE_FAILURE );
00308 
00309     status = check_magic_header( storage_data );
00310     if( status != PSA_SUCCESS )
00311         return( status );
00312 
00313     GET_UINT32_LE( version, storage_format->version, 0 );
00314     if( version != 0 )
00315         return( PSA_ERROR_STORAGE_FAILURE );
00316 
00317     GET_UINT32_LE( *key_data_length, storage_format->data_len, 0 );
00318     if( *key_data_length > ( storage_data_length - sizeof(*storage_format) ) ||
00319         *key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
00320         return( PSA_ERROR_STORAGE_FAILURE );
00321 
00322     if( *key_data_length == 0 )
00323     {
00324         *key_data = NULL;
00325     }
00326     else
00327     {
00328         *key_data = mbedtls_calloc( 1, *key_data_length );
00329         if( *key_data == NULL )
00330             return( PSA_ERROR_INSUFFICIENT_MEMORY );
00331         memcpy( *key_data, storage_format->key_data, *key_data_length );
00332     }
00333 
00334     GET_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
00335     GET_UINT32_LE( attr->type, storage_format->type, 0 );
00336     GET_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
00337     GET_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
00338     GET_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
00339 
00340     return( PSA_SUCCESS );
00341 }
00342 
00343 psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr,
00344                                       const uint8_t *data,
00345                                       const size_t data_length )
00346 {
00347     size_t storage_data_length;
00348     uint8_t *storage_data;
00349     psa_status_t status;
00350 
00351     if( data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
00352         return PSA_ERROR_INSUFFICIENT_STORAGE;
00353     storage_data_length = data_length + sizeof( psa_persistent_key_storage_format );
00354 
00355     storage_data = mbedtls_calloc( 1, storage_data_length );
00356     if( storage_data == NULL )
00357         return( PSA_ERROR_INSUFFICIENT_MEMORY );
00358 
00359     psa_format_key_data_for_storage( data, data_length, attr, storage_data );
00360 
00361     status = psa_crypto_storage_store( attr->id,
00362                                        storage_data, storage_data_length );
00363 
00364     mbedtls_free( storage_data );
00365 
00366     return( status );
00367 }
00368 
00369 void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length )
00370 {
00371     if( key_data != NULL )
00372     {
00373         mbedtls_platform_zeroize( key_data, key_data_length );
00374     }
00375     mbedtls_free( key_data );
00376 }
00377 
00378 psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr,
00379                                       uint8_t **data,
00380                                       size_t *data_length )
00381 {
00382     psa_status_t status = PSA_SUCCESS;
00383     uint8_t *loaded_data;
00384     size_t storage_data_length = 0;
00385     psa_key_id_t key = attr->id;
00386 
00387     status = psa_crypto_storage_get_data_length( key, &storage_data_length );
00388     if( status != PSA_SUCCESS )
00389         return( status );
00390 
00391     loaded_data = mbedtls_calloc( 1, storage_data_length );
00392 
00393     if( loaded_data == NULL )
00394         return( PSA_ERROR_INSUFFICIENT_MEMORY );
00395 
00396     status = psa_crypto_storage_load( key, loaded_data, storage_data_length );
00397     if( status != PSA_SUCCESS )
00398         goto exit;
00399 
00400     status = psa_parse_key_data_from_storage( loaded_data, storage_data_length,
00401                                               data, data_length, attr );
00402 
00403 exit:
00404     mbedtls_free( loaded_data );
00405     return( status );
00406 }
00407 
00408 
00409 
00410 /****************************************************************/
00411 /* Transactions */
00412 /****************************************************************/
00413 
00414 #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
00415 
00416 psa_crypto_transaction_t psa_crypto_transaction;
00417 
00418 psa_status_t psa_crypto_save_transaction( void )
00419 {
00420     struct psa_storage_info_t p_info;
00421     psa_status_t status;
00422     status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
00423     if( status == PSA_SUCCESS )
00424     {
00425         /* This shouldn't happen: we're trying to start a transaction while
00426          * there is still a transaction that hasn't been replayed. */
00427         return( PSA_ERROR_CORRUPTION_DETECTED );
00428     }
00429     else if( status != PSA_ERROR_DOES_NOT_EXIST )
00430         return( status );
00431     return( psa_its_set( PSA_CRYPTO_ITS_TRANSACTION_UID,
00432                          sizeof( psa_crypto_transaction ),
00433                          &psa_crypto_transaction,
00434                          0 ) );
00435 }
00436 
00437 psa_status_t psa_crypto_load_transaction( void )
00438 {
00439     psa_status_t status;
00440     size_t length;
00441     status = psa_its_get( PSA_CRYPTO_ITS_TRANSACTION_UID, 0,
00442                           sizeof( psa_crypto_transaction ),
00443                           &psa_crypto_transaction, &length );
00444     if( status != PSA_SUCCESS )
00445         return( status );
00446     if( length != sizeof( psa_crypto_transaction ) )
00447         return( PSA_ERROR_STORAGE_FAILURE );
00448     return( PSA_SUCCESS );
00449 }
00450 
00451 psa_status_t psa_crypto_stop_transaction( void )
00452 {
00453     psa_status_t status = psa_its_remove( PSA_CRYPTO_ITS_TRANSACTION_UID );
00454     /* Whether or not updating the storage succeeded, the transaction is
00455      * finished now. It's too late to go back, so zero out the in-memory
00456      * data. */
00457     memset( &psa_crypto_transaction, 0, sizeof( psa_crypto_transaction ) );
00458     return( status );
00459 }
00460 
00461 #endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
00462 
00463 
00464 
00465 /****************************************************************/
00466 /* Random generator state */
00467 /****************************************************************/
00468 
00469 #if defined(MBEDTLS_PSA_INJECT_ENTROPY)
00470 psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed,
00471                                                  size_t seed_size )
00472 {
00473     psa_status_t status;
00474     struct psa_storage_info_t p_info;
00475 
00476     status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
00477 
00478     if( PSA_ERROR_DOES_NOT_EXIST == status ) /* No seed exists */
00479     {
00480         status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
00481     }
00482     else if( PSA_SUCCESS == status )
00483     {
00484         /* You should not be here. Seed needs to be injected only once */
00485         status = PSA_ERROR_NOT_PERMITTED;
00486     }
00487     return( status );
00488 }
00489 #endif /* MBEDTLS_PSA_INJECT_ENTROPY */
00490 
00491 
00492 
00493 /****************************************************************/
00494 /* The end */
00495 /****************************************************************/
00496 
00497 #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */