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