blob: 0a5805b62b45f7663d106fe380e38f15ac0582f6 [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
41#define mbedtls_calloc calloc
42#define mbedtls_free free
43#endif
44
45/*
46 * 32-bit integer manipulation macros (little endian)
47 */
48#ifndef GET_UINT32_LE
49#define GET_UINT32_LE(n,b,i) \
50{ \
51 (n) = ( (uint32_t) (b)[(i) ] ) \
52 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
53 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
54 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
55}
56#endif
57
58#ifndef PUT_UINT32_LE
59#define PUT_UINT32_LE(n,b,i) \
60{ \
61 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
62 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
63 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
64 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
65}
66#endif
67
Moran Peker96ebf9e2018-06-28 18:02:17 +030068/**
69 * Persistent key storage magic header.
70 */
71#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
72#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ( sizeof( PSA_KEY_STORAGE_MAGIC_HEADER ) )
73
Darryl Greendb2b8db2018-06-15 13:06:04 +010074typedef struct {
Moran Peker96ebf9e2018-06-28 18:02:17 +030075 uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
Darryl Greendb2b8db2018-06-15 13:06:04 +010076 uint8_t version[4];
77 uint8_t type[sizeof( psa_key_type_t )];
78 uint8_t policy[sizeof( psa_key_policy_t )];
79 uint8_t data_len[4];
80 uint8_t key_data[];
81} psa_persistent_key_storage_format;
82
83void psa_format_key_data_for_storage( const uint8_t *data,
84 const size_t data_length,
85 const psa_key_type_t type,
86 const psa_key_policy_t *policy,
87 uint8_t *storage_data )
88{
89 psa_persistent_key_storage_format *storage_format =
90 (psa_persistent_key_storage_format *) storage_data;
91
Moran Peker96ebf9e2018-06-28 18:02:17 +030092 memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH );
Darryl Greendb2b8db2018-06-15 13:06:04 +010093 PUT_UINT32_LE(0, storage_format->version, 0);
94 PUT_UINT32_LE(type, storage_format->type, 0);
95 PUT_UINT32_LE(policy->usage, storage_format->policy, 0);
96 PUT_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
97 PUT_UINT32_LE(data_length, storage_format->data_len, 0);
98 memcpy( storage_format->key_data, data, data_length );
99}
100
Moran Peker96ebf9e2018-06-28 18:02:17 +0300101static psa_status_t check_magic_header( const uint8_t *data )
102{
103 if( memcmp( data, PSA_KEY_STORAGE_MAGIC_HEADER,
104 PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ) != 0 )
105 return( PSA_ERROR_STORAGE_FAILURE );
106 return( PSA_SUCCESS );
107}
108
Darryl Greendb2b8db2018-06-15 13:06:04 +0100109psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
110 size_t storage_data_length,
111 uint8_t **key_data,
112 size_t *key_data_length,
113 psa_key_type_t *type,
114 psa_key_policy_t *policy )
115{
Moran Peker96ebf9e2018-06-28 18:02:17 +0300116 psa_status_t status;
Darryl Greendb2b8db2018-06-15 13:06:04 +0100117 const psa_persistent_key_storage_format *storage_format =
118 (const psa_persistent_key_storage_format *)storage_data;
119 uint32_t version;
120
Moran Peker96ebf9e2018-06-28 18:02:17 +0300121 if( storage_data_length < sizeof(*storage_format) )
122 return( PSA_ERROR_STORAGE_FAILURE );
123
124 status = check_magic_header( storage_data );
125 if( status != PSA_SUCCESS )
126 return( status );
127
Darryl Greendb2b8db2018-06-15 13:06:04 +0100128 GET_UINT32_LE(version, storage_format->version, 0);
129 if( version != 0 )
130 return( PSA_ERROR_STORAGE_FAILURE );
131
132 GET_UINT32_LE(*key_data_length, storage_format->data_len, 0);
133 if( *key_data_length > ( storage_data_length - sizeof(*storage_format) ) ||
134 *key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
135 return( PSA_ERROR_STORAGE_FAILURE );
136
137 *key_data = mbedtls_calloc( 1, *key_data_length );
138 if( *key_data == NULL )
139 return( PSA_ERROR_INSUFFICIENT_MEMORY );
140
141 GET_UINT32_LE(*type, storage_format->type, 0);
142 GET_UINT32_LE(policy->usage, storage_format->policy, 0);
143 GET_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
144
145 memcpy( *key_data, storage_format->key_data, *key_data_length );
146
147 return( PSA_SUCCESS );
148}
149
150psa_status_t psa_save_persistent_key( const psa_key_slot_t key,
151 const psa_key_type_t type,
152 const psa_key_policy_t *policy,
153 const uint8_t *data,
154 const size_t data_length )
155{
156 size_t storage_data_length;
157 uint8_t *storage_data;
158 psa_status_t status;
159
160 if( data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
161 return PSA_ERROR_INSUFFICIENT_STORAGE;
162 storage_data_length = data_length + sizeof( psa_persistent_key_storage_format );
163
164 storage_data = mbedtls_calloc( 1, storage_data_length );
165 if( storage_data == NULL )
166 return( PSA_ERROR_INSUFFICIENT_MEMORY );
167
168 psa_format_key_data_for_storage( data, data_length, type, policy,
169 storage_data );
170
171 status = psa_crypto_storage_store( key,
172 storage_data, storage_data_length );
173
174 mbedtls_free( storage_data );
175
176 return( status );
177}
178
179void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length )
180{
181 if( key_data != NULL )
182 {
183 mbedtls_platform_zeroize( key_data, key_data_length );
184 }
185 mbedtls_free( key_data );
186}
187
188psa_status_t psa_load_persistent_key( psa_key_slot_t key,
189 psa_key_type_t *type,
190 psa_key_policy_t *policy,
191 uint8_t **data,
192 size_t *data_length )
193{
194 psa_status_t status = PSA_SUCCESS;
195 uint8_t *loaded_data;
196 size_t storage_data_length = 0;
197
198 status = psa_crypto_storage_get_data_length( key, &storage_data_length );
199 if( status != PSA_SUCCESS )
200 return( status );
201
202 loaded_data = mbedtls_calloc( 1, storage_data_length );
203
204 if( loaded_data == NULL )
205 return( PSA_ERROR_INSUFFICIENT_MEMORY );
206
207 status = psa_crypto_storage_load( key, loaded_data, storage_data_length );
208 if( status != PSA_SUCCESS )
209 goto exit;
210
211 status = psa_parse_key_data_from_storage( loaded_data, storage_data_length,
212 data, data_length, type, policy );
213
214exit:
215 mbedtls_free( loaded_data );
216 return( status );
217}
218
219#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */