blob: 84a6ed55853910038431c0695165582720847574 [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>
32
itayzafrir7723ab12019-02-14 10:28:02 +020033#include "psa_crypto_service_integration.h"
Darryl Greendb2b8db2018-06-15 13:06:04 +010034#include "psa/crypto.h"
35#include "psa_crypto_storage.h"
36#include "psa_crypto_storage_backend.h"
37#include "mbedtls/platform_util.h"
38
39#if defined(MBEDTLS_PLATFORM_C)
40#include "mbedtls/platform.h"
41#else
Jaeden Amerodb29ab52019-02-12 16:40:27 +000042#include <stdlib.h>
Darryl Greendb2b8db2018-06-15 13:06:04 +010043#define mbedtls_calloc calloc
44#define mbedtls_free free
45#endif
46
47/*
48 * 32-bit integer manipulation macros (little endian)
49 */
50#ifndef GET_UINT32_LE
51#define GET_UINT32_LE(n,b,i) \
52{ \
53 (n) = ( (uint32_t) (b)[(i) ] ) \
54 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
55 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
56 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
57}
58#endif
59
60#ifndef PUT_UINT32_LE
61#define PUT_UINT32_LE(n,b,i) \
62{ \
63 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
64 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
65 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
66 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
67}
68#endif
69
Moran Peker96ebf9e2018-06-28 18:02:17 +030070/**
71 * Persistent key storage magic header.
72 */
73#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
74#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ( sizeof( PSA_KEY_STORAGE_MAGIC_HEADER ) )
75
Darryl Greendb2b8db2018-06-15 13:06:04 +010076typedef struct {
Moran Peker96ebf9e2018-06-28 18:02:17 +030077 uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
Darryl Greendb2b8db2018-06-15 13:06:04 +010078 uint8_t version[4];
79 uint8_t type[sizeof( psa_key_type_t )];
80 uint8_t policy[sizeof( psa_key_policy_t )];
81 uint8_t data_len[4];
82 uint8_t key_data[];
83} psa_persistent_key_storage_format;
84
85void psa_format_key_data_for_storage( const uint8_t *data,
86 const size_t data_length,
87 const psa_key_type_t type,
88 const psa_key_policy_t *policy,
89 uint8_t *storage_data )
90{
91 psa_persistent_key_storage_format *storage_format =
92 (psa_persistent_key_storage_format *) storage_data;
93
Moran Peker96ebf9e2018-06-28 18:02:17 +030094 memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH );
Darryl Greendb2b8db2018-06-15 13:06:04 +010095 PUT_UINT32_LE(0, storage_format->version, 0);
96 PUT_UINT32_LE(type, storage_format->type, 0);
97 PUT_UINT32_LE(policy->usage, storage_format->policy, 0);
98 PUT_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
99 PUT_UINT32_LE(data_length, storage_format->data_len, 0);
100 memcpy( storage_format->key_data, data, data_length );
101}
102
Moran Peker96ebf9e2018-06-28 18:02:17 +0300103static psa_status_t check_magic_header( const uint8_t *data )
104{
105 if( memcmp( data, PSA_KEY_STORAGE_MAGIC_HEADER,
106 PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ) != 0 )
107 return( PSA_ERROR_STORAGE_FAILURE );
108 return( PSA_SUCCESS );
109}
110
Darryl Greendb2b8db2018-06-15 13:06:04 +0100111psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
112 size_t storage_data_length,
113 uint8_t **key_data,
114 size_t *key_data_length,
115 psa_key_type_t *type,
116 psa_key_policy_t *policy )
117{
Moran Peker96ebf9e2018-06-28 18:02:17 +0300118 psa_status_t status;
Darryl Greendb2b8db2018-06-15 13:06:04 +0100119 const psa_persistent_key_storage_format *storage_format =
120 (const psa_persistent_key_storage_format *)storage_data;
121 uint32_t version;
122
Moran Peker96ebf9e2018-06-28 18:02:17 +0300123 if( storage_data_length < sizeof(*storage_format) )
124 return( PSA_ERROR_STORAGE_FAILURE );
125
126 status = check_magic_header( storage_data );
127 if( status != PSA_SUCCESS )
128 return( status );
129
Darryl Greendb2b8db2018-06-15 13:06:04 +0100130 GET_UINT32_LE(version, storage_format->version, 0);
131 if( version != 0 )
132 return( PSA_ERROR_STORAGE_FAILURE );
133
134 GET_UINT32_LE(*key_data_length, storage_format->data_len, 0);
135 if( *key_data_length > ( storage_data_length - sizeof(*storage_format) ) ||
136 *key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
137 return( PSA_ERROR_STORAGE_FAILURE );
138
139 *key_data = mbedtls_calloc( 1, *key_data_length );
140 if( *key_data == NULL )
141 return( PSA_ERROR_INSUFFICIENT_MEMORY );
142
143 GET_UINT32_LE(*type, storage_format->type, 0);
144 GET_UINT32_LE(policy->usage, storage_format->policy, 0);
145 GET_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
146
147 memcpy( *key_data, storage_format->key_data, *key_data_length );
148
149 return( PSA_SUCCESS );
150}
151
Gilles Peskine5b229a02019-02-19 13:24:37 +0100152psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
Darryl Greendb2b8db2018-06-15 13:06:04 +0100153 const psa_key_type_t type,
154 const psa_key_policy_t *policy,
155 const uint8_t *data,
156 const size_t data_length )
157{
158 size_t storage_data_length;
159 uint8_t *storage_data;
160 psa_status_t status;
161
162 if( data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
163 return PSA_ERROR_INSUFFICIENT_STORAGE;
164 storage_data_length = data_length + sizeof( psa_persistent_key_storage_format );
165
166 storage_data = mbedtls_calloc( 1, storage_data_length );
167 if( storage_data == NULL )
168 return( PSA_ERROR_INSUFFICIENT_MEMORY );
169
170 psa_format_key_data_for_storage( data, data_length, type, policy,
171 storage_data );
172
173 status = psa_crypto_storage_store( key,
174 storage_data, storage_data_length );
175
176 mbedtls_free( storage_data );
177
178 return( status );
179}
180
181void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length )
182{
183 if( key_data != NULL )
184 {
185 mbedtls_platform_zeroize( key_data, key_data_length );
186 }
187 mbedtls_free( key_data );
188}
189
Gilles Peskine5b229a02019-02-19 13:24:37 +0100190psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
Darryl Greendb2b8db2018-06-15 13:06:04 +0100191 psa_key_type_t *type,
192 psa_key_policy_t *policy,
193 uint8_t **data,
194 size_t *data_length )
195{
196 psa_status_t status = PSA_SUCCESS;
197 uint8_t *loaded_data;
198 size_t storage_data_length = 0;
199
200 status = psa_crypto_storage_get_data_length( key, &storage_data_length );
201 if( status != PSA_SUCCESS )
202 return( status );
203
204 loaded_data = mbedtls_calloc( 1, storage_data_length );
205
206 if( loaded_data == NULL )
207 return( PSA_ERROR_INSUFFICIENT_MEMORY );
208
209 status = psa_crypto_storage_load( key, loaded_data, storage_data_length );
210 if( status != PSA_SUCCESS )
211 goto exit;
212
213 status = psa_parse_key_data_from_storage( loaded_data, storage_data_length,
214 data, data_length, type, policy );
215
216exit:
217 mbedtls_free( loaded_data );
218 return( status );
219}
220
221#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */