blob: 5285826ce6e3ea448e6c89178a843786430fdfe1 [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
68typedef struct {
69 uint8_t version[4];
70 uint8_t type[sizeof( psa_key_type_t )];
71 uint8_t policy[sizeof( psa_key_policy_t )];
72 uint8_t data_len[4];
73 uint8_t key_data[];
74} psa_persistent_key_storage_format;
75
76void psa_format_key_data_for_storage( const uint8_t *data,
77 const size_t data_length,
78 const psa_key_type_t type,
79 const psa_key_policy_t *policy,
80 uint8_t *storage_data )
81{
82 psa_persistent_key_storage_format *storage_format =
83 (psa_persistent_key_storage_format *) storage_data;
84
85 PUT_UINT32_LE(0, storage_format->version, 0);
86 PUT_UINT32_LE(type, storage_format->type, 0);
87 PUT_UINT32_LE(policy->usage, storage_format->policy, 0);
88 PUT_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
89 PUT_UINT32_LE(data_length, storage_format->data_len, 0);
90 memcpy( storage_format->key_data, data, data_length );
91}
92
93psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
94 size_t storage_data_length,
95 uint8_t **key_data,
96 size_t *key_data_length,
97 psa_key_type_t *type,
98 psa_key_policy_t *policy )
99{
100 const psa_persistent_key_storage_format *storage_format =
101 (const psa_persistent_key_storage_format *)storage_data;
102 uint32_t version;
103
104 GET_UINT32_LE(version, storage_format->version, 0);
105 if( version != 0 )
106 return( PSA_ERROR_STORAGE_FAILURE );
107
108 GET_UINT32_LE(*key_data_length, storage_format->data_len, 0);
109 if( *key_data_length > ( storage_data_length - sizeof(*storage_format) ) ||
110 *key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
111 return( PSA_ERROR_STORAGE_FAILURE );
112
113 *key_data = mbedtls_calloc( 1, *key_data_length );
114 if( *key_data == NULL )
115 return( PSA_ERROR_INSUFFICIENT_MEMORY );
116
117 GET_UINT32_LE(*type, storage_format->type, 0);
118 GET_UINT32_LE(policy->usage, storage_format->policy, 0);
119 GET_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
120
121 memcpy( *key_data, storage_format->key_data, *key_data_length );
122
123 return( PSA_SUCCESS );
124}
125
126psa_status_t psa_save_persistent_key( const psa_key_slot_t key,
127 const psa_key_type_t type,
128 const psa_key_policy_t *policy,
129 const uint8_t *data,
130 const size_t data_length )
131{
132 size_t storage_data_length;
133 uint8_t *storage_data;
134 psa_status_t status;
135
136 if( data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
137 return PSA_ERROR_INSUFFICIENT_STORAGE;
138 storage_data_length = data_length + sizeof( psa_persistent_key_storage_format );
139
140 storage_data = mbedtls_calloc( 1, storage_data_length );
141 if( storage_data == NULL )
142 return( PSA_ERROR_INSUFFICIENT_MEMORY );
143
144 psa_format_key_data_for_storage( data, data_length, type, policy,
145 storage_data );
146
147 status = psa_crypto_storage_store( key,
148 storage_data, storage_data_length );
149
150 mbedtls_free( storage_data );
151
152 return( status );
153}
154
155void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length )
156{
157 if( key_data != NULL )
158 {
159 mbedtls_platform_zeroize( key_data, key_data_length );
160 }
161 mbedtls_free( key_data );
162}
163
164psa_status_t psa_load_persistent_key( psa_key_slot_t key,
165 psa_key_type_t *type,
166 psa_key_policy_t *policy,
167 uint8_t **data,
168 size_t *data_length )
169{
170 psa_status_t status = PSA_SUCCESS;
171 uint8_t *loaded_data;
172 size_t storage_data_length = 0;
173
174 status = psa_crypto_storage_get_data_length( key, &storage_data_length );
175 if( status != PSA_SUCCESS )
176 return( status );
177
178 loaded_data = mbedtls_calloc( 1, storage_data_length );
179
180 if( loaded_data == NULL )
181 return( PSA_ERROR_INSUFFICIENT_MEMORY );
182
183 status = psa_crypto_storage_load( key, loaded_data, storage_data_length );
184 if( status != PSA_SUCCESS )
185 goto exit;
186
187 status = psa_parse_key_data_from_storage( loaded_data, storage_data_length,
188 data, data_length, type, policy );
189
190exit:
191 mbedtls_free( loaded_data );
192 return( status );
193}
194
195#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */