blob: 296ed34aeb00874b94048591f3f5ee3a1a25f8aa [file] [log] [blame]
Darryl Greendb2b8db2018-06-15 13:06:04 +01001/*
2 * PSA persistent key storage
3 */
4/* Copyright (C) 2018, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if defined(MBEDTLS_CONFIG_FILE)
23#include MBEDTLS_CONFIG_FILE
24#else
25#include "mbedtls/config.h"
26#endif
27
28#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
29
30#include <stdlib.h>
31#include <string.h>
itayzafrir7132dd92019-01-29 14:23:52 +020032/*
33 * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is being built for SPM
34 * (Secure Partition Manager) integration which separates the code into two
35 * parts: NSPE (Non-Secure Processing Environment) and SPE (Secure Processing
36 * Environment). When building for the SPE, an additional header file should be
37 * included.
38 */
39#if defined(MBEDTLS_PSA_CRYPTO_SPM)
40/*
41 * PSA_CRYPTO_SECURE means that this file is compiled for the SPE.
42 * Some headers will be affected by this flag.
43 */
44#define PSA_CRYPTO_SECURE 1
45#endif
Darryl Greendb2b8db2018-06-15 13:06:04 +010046
47#include "psa/crypto.h"
48#include "psa_crypto_storage.h"
49#include "psa_crypto_storage_backend.h"
50#include "mbedtls/platform_util.h"
51
52#if defined(MBEDTLS_PLATFORM_C)
53#include "mbedtls/platform.h"
54#else
Jaeden Amerodb29ab52019-02-12 16:40:27 +000055#include <stdlib.h>
Darryl Greendb2b8db2018-06-15 13:06:04 +010056#define mbedtls_calloc calloc
57#define mbedtls_free free
58#endif
59
60/*
61 * 32-bit integer manipulation macros (little endian)
62 */
63#ifndef GET_UINT32_LE
64#define GET_UINT32_LE(n,b,i) \
65{ \
66 (n) = ( (uint32_t) (b)[(i) ] ) \
67 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
68 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
69 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
70}
71#endif
72
73#ifndef PUT_UINT32_LE
74#define PUT_UINT32_LE(n,b,i) \
75{ \
76 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
77 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
78 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
79 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
80}
81#endif
82
Moran Peker96ebf9e2018-06-28 18:02:17 +030083/**
84 * Persistent key storage magic header.
85 */
86#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
87#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ( sizeof( PSA_KEY_STORAGE_MAGIC_HEADER ) )
88
Darryl Greendb2b8db2018-06-15 13:06:04 +010089typedef struct {
Moran Peker96ebf9e2018-06-28 18:02:17 +030090 uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
Darryl Greendb2b8db2018-06-15 13:06:04 +010091 uint8_t version[4];
92 uint8_t type[sizeof( psa_key_type_t )];
93 uint8_t policy[sizeof( psa_key_policy_t )];
94 uint8_t data_len[4];
95 uint8_t key_data[];
96} psa_persistent_key_storage_format;
97
98void psa_format_key_data_for_storage( const uint8_t *data,
99 const size_t data_length,
100 const psa_key_type_t type,
101 const psa_key_policy_t *policy,
102 uint8_t *storage_data )
103{
104 psa_persistent_key_storage_format *storage_format =
105 (psa_persistent_key_storage_format *) storage_data;
106
Moran Peker96ebf9e2018-06-28 18:02:17 +0300107 memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH );
Darryl Greendb2b8db2018-06-15 13:06:04 +0100108 PUT_UINT32_LE(0, storage_format->version, 0);
109 PUT_UINT32_LE(type, storage_format->type, 0);
110 PUT_UINT32_LE(policy->usage, storage_format->policy, 0);
111 PUT_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
112 PUT_UINT32_LE(data_length, storage_format->data_len, 0);
113 memcpy( storage_format->key_data, data, data_length );
114}
115
Moran Peker96ebf9e2018-06-28 18:02:17 +0300116static psa_status_t check_magic_header( const uint8_t *data )
117{
118 if( memcmp( data, PSA_KEY_STORAGE_MAGIC_HEADER,
119 PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ) != 0 )
120 return( PSA_ERROR_STORAGE_FAILURE );
121 return( PSA_SUCCESS );
122}
123
Darryl Greendb2b8db2018-06-15 13:06:04 +0100124psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
125 size_t storage_data_length,
126 uint8_t **key_data,
127 size_t *key_data_length,
128 psa_key_type_t *type,
129 psa_key_policy_t *policy )
130{
Moran Peker96ebf9e2018-06-28 18:02:17 +0300131 psa_status_t status;
Darryl Greendb2b8db2018-06-15 13:06:04 +0100132 const psa_persistent_key_storage_format *storage_format =
133 (const psa_persistent_key_storage_format *)storage_data;
134 uint32_t version;
135
Moran Peker96ebf9e2018-06-28 18:02:17 +0300136 if( storage_data_length < sizeof(*storage_format) )
137 return( PSA_ERROR_STORAGE_FAILURE );
138
139 status = check_magic_header( storage_data );
140 if( status != PSA_SUCCESS )
141 return( status );
142
Darryl Greendb2b8db2018-06-15 13:06:04 +0100143 GET_UINT32_LE(version, storage_format->version, 0);
144 if( version != 0 )
145 return( PSA_ERROR_STORAGE_FAILURE );
146
147 GET_UINT32_LE(*key_data_length, storage_format->data_len, 0);
148 if( *key_data_length > ( storage_data_length - sizeof(*storage_format) ) ||
149 *key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
150 return( PSA_ERROR_STORAGE_FAILURE );
151
152 *key_data = mbedtls_calloc( 1, *key_data_length );
153 if( *key_data == NULL )
154 return( PSA_ERROR_INSUFFICIENT_MEMORY );
155
156 GET_UINT32_LE(*type, storage_format->type, 0);
157 GET_UINT32_LE(policy->usage, storage_format->policy, 0);
158 GET_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
159
160 memcpy( *key_data, storage_format->key_data, *key_data_length );
161
162 return( PSA_SUCCESS );
163}
164
Gilles Peskine8d4919b2018-12-03 16:48:09 +0100165psa_status_t psa_save_persistent_key( const psa_key_id_t key,
Darryl Greendb2b8db2018-06-15 13:06:04 +0100166 const psa_key_type_t type,
167 const psa_key_policy_t *policy,
168 const uint8_t *data,
169 const size_t data_length )
170{
171 size_t storage_data_length;
172 uint8_t *storage_data;
173 psa_status_t status;
174
175 if( data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
176 return PSA_ERROR_INSUFFICIENT_STORAGE;
177 storage_data_length = data_length + sizeof( psa_persistent_key_storage_format );
178
179 storage_data = mbedtls_calloc( 1, storage_data_length );
180 if( storage_data == NULL )
181 return( PSA_ERROR_INSUFFICIENT_MEMORY );
182
183 psa_format_key_data_for_storage( data, data_length, type, policy,
184 storage_data );
185
186 status = psa_crypto_storage_store( key,
187 storage_data, storage_data_length );
188
189 mbedtls_free( storage_data );
190
191 return( status );
192}
193
194void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length )
195{
196 if( key_data != NULL )
197 {
198 mbedtls_platform_zeroize( key_data, key_data_length );
199 }
200 mbedtls_free( key_data );
201}
202
Gilles Peskine8d4919b2018-12-03 16:48:09 +0100203psa_status_t psa_load_persistent_key( psa_key_id_t key,
Darryl Greendb2b8db2018-06-15 13:06:04 +0100204 psa_key_type_t *type,
205 psa_key_policy_t *policy,
206 uint8_t **data,
207 size_t *data_length )
208{
209 psa_status_t status = PSA_SUCCESS;
210 uint8_t *loaded_data;
211 size_t storage_data_length = 0;
212
213 status = psa_crypto_storage_get_data_length( key, &storage_data_length );
214 if( status != PSA_SUCCESS )
215 return( status );
216
217 loaded_data = mbedtls_calloc( 1, storage_data_length );
218
219 if( loaded_data == NULL )
220 return( PSA_ERROR_INSUFFICIENT_MEMORY );
221
222 status = psa_crypto_storage_load( key, loaded_data, storage_data_length );
223 if( status != PSA_SUCCESS )
224 goto exit;
225
226 status = psa_parse_key_data_from_storage( loaded_data, storage_data_length,
227 data, data_length, type, policy );
228
229exit:
230 mbedtls_free( loaded_data );
231 return( status );
232}
233
234#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */