blob: afb4d325c394d8a746cc59fabbc49085276e9ce6 [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
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.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PSA_CRYPTO_C)
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +030029/*
30 * In case MBEDTLS_PSA_CRYPTO_SPM is defined the code is built for SPM (Secure
31 * Partition Manager) integration which separate the code into two parts
32 * NSPE (Non-Secure Process Environment) and SPE (Secure Process Environment).
33 * In this mode an additional header file should be included.
34 */
mohammad160327010052018-07-03 13:16:15 +030035#if defined(MBEDTLS_PSA_CRYPTO_SPM)
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +030036/*
37 * PSA_CRYPTO_SECURE means that this file is compiled to the SPE side.
38 * some headers will be affected by this flag.
39 */
mohammad160327010052018-07-03 13:16:15 +030040#define PSA_CRYPTO_SECURE 1
41#include "crypto_spe.h"
42#endif
43
Gilles Peskinee59236f2018-01-27 23:32:46 +010044#include "psa/crypto.h"
45
Gilles Peskine5e769522018-11-20 21:59:56 +010046#include "psa_crypto_invasive.h"
Gilles Peskine961849f2018-11-30 18:54:54 +010047#include "psa_crypto_slot_management.h"
Darryl Greend49a4992018-06-18 17:27:26 +010048/* Include internal declarations that are useful for implementing persistently
49 * stored keys. */
50#include "psa_crypto_storage.h"
51
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010052#include <stdlib.h>
53#include <string.h>
54#if defined(MBEDTLS_PLATFORM_C)
55#include "mbedtls/platform.h"
56#else
57#define mbedtls_calloc calloc
58#define mbedtls_free free
59#endif
60
Gilles Peskinea5905292018-02-07 20:59:33 +010061#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020062#include "mbedtls/asn1.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020063#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010064#include "mbedtls/blowfish.h"
65#include "mbedtls/camellia.h"
66#include "mbedtls/cipher.h"
67#include "mbedtls/ccm.h"
68#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010069#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010070#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020071#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010072#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010073#include "mbedtls/entropy.h"
Netanel Gonen2bcd3122018-11-19 11:53:02 +020074#include "mbedtls/entropy_poll.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010075#include "mbedtls/error.h"
76#include "mbedtls/gcm.h"
77#include "mbedtls/md2.h"
78#include "mbedtls/md4.h"
79#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010080#include "mbedtls/md.h"
81#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010082#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010083#include "mbedtls/pk_internal.h"
Gilles Peskine3f108122018-12-07 18:14:53 +010084#include "mbedtls/platform_util.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010085#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010086#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010087#include "mbedtls/sha1.h"
88#include "mbedtls/sha256.h"
89#include "mbedtls/sha512.h"
90#include "mbedtls/xtea.h"
91
Netanel Gonen2bcd3122018-11-19 11:53:02 +020092#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
93#include "psa_prot_internal_storage.h"
94#endif
Gilles Peskinee59236f2018-01-27 23:32:46 +010095
Gilles Peskine996deb12018-08-01 15:45:45 +020096#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
97
Gilles Peskine9ef733f2018-02-07 21:05:37 +010098/* constant-time buffer comparison */
99static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
100{
101 size_t i;
102 unsigned char diff = 0;
103
104 for( i = 0; i < n; i++ )
105 diff |= a[i] ^ b[i];
106
107 return( diff );
108}
109
110
111
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100112/****************************************************************/
113/* Global data, support functions and library management */
114/****************************************************************/
115
Gilles Peskine2d277862018-06-18 15:41:12 +0200116typedef struct
117{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100118 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300119 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200120 psa_key_lifetime_t lifetime;
Gilles Peskine69f976b2018-11-30 18:46:56 +0100121 psa_key_id_t persistent_storage_id;
Gilles Peskine961849f2018-11-30 18:54:54 +0100122 unsigned allocated : 1;
Gilles Peskine2d277862018-06-18 15:41:12 +0200123 union
124 {
125 struct raw_data
126 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100127 uint8_t *data;
128 size_t bytes;
129 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100130#if defined(MBEDTLS_RSA_C)
131 mbedtls_rsa_context *rsa;
132#endif /* MBEDTLS_RSA_C */
133#if defined(MBEDTLS_ECP_C)
134 mbedtls_ecp_keypair *ecp;
135#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100136 } data;
Gilles Peskine2f060a82018-12-04 17:12:32 +0100137} psa_key_slot_t;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100138
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200139static int key_type_is_raw_bytes( psa_key_type_t type )
140{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200141 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200142}
143
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100144/* Values for psa_global_data_t::rng_state */
145#define RNG_NOT_INITIALIZED 0
146#define RNG_INITIALIZED 1
147#define RNG_SEEDED 2
Gilles Peskinec6b69072018-11-20 21:42:52 +0100148
Gilles Peskine2d277862018-06-18 15:41:12 +0200149typedef struct
150{
Gilles Peskine5e769522018-11-20 21:59:56 +0100151 void (* entropy_init )( mbedtls_entropy_context *ctx );
152 void (* entropy_free )( mbedtls_entropy_context *ctx );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100153 mbedtls_entropy_context entropy;
154 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine2f060a82018-12-04 17:12:32 +0100155 psa_key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinec6b69072018-11-20 21:42:52 +0100156 unsigned initialized : 1;
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100157 unsigned rng_state : 2;
Gilles Peskinec6b69072018-11-20 21:42:52 +0100158 unsigned key_slots_initialized : 1;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100159} psa_global_data_t;
160
161static psa_global_data_t global_data;
162
itayzafrir0adf0fc2018-09-06 16:24:41 +0300163#define GUARD_MODULE_INITIALIZED \
164 if( global_data.initialized == 0 ) \
165 return( PSA_ERROR_BAD_STATE );
166
Gilles Peskinee59236f2018-01-27 23:32:46 +0100167static psa_status_t mbedtls_to_psa_error( int ret )
168{
Gilles Peskinea5905292018-02-07 20:59:33 +0100169 /* If there's both a high-level code and low-level code, dispatch on
170 * the high-level code. */
171 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100172 {
173 case 0:
174 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100175
176 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
177 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
178 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
179 return( PSA_ERROR_NOT_SUPPORTED );
180 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
181 return( PSA_ERROR_HARDWARE_FAILURE );
182
183 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
Gilles Peskine9a944802018-06-21 09:35:35 +0200186 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
187 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
188 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
189 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
190 case MBEDTLS_ERR_ASN1_INVALID_DATA:
191 return( PSA_ERROR_INVALID_ARGUMENT );
192 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
193 return( PSA_ERROR_INSUFFICIENT_MEMORY );
194 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
195 return( PSA_ERROR_BUFFER_TOO_SMALL );
196
Gilles Peskinea5905292018-02-07 20:59:33 +0100197 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
198 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
199 return( PSA_ERROR_NOT_SUPPORTED );
200 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
201 return( PSA_ERROR_HARDWARE_FAILURE );
202
203 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
204 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
205 return( PSA_ERROR_NOT_SUPPORTED );
206 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
207 return( PSA_ERROR_HARDWARE_FAILURE );
208
209 case MBEDTLS_ERR_CCM_BAD_INPUT:
210 return( PSA_ERROR_INVALID_ARGUMENT );
211 case MBEDTLS_ERR_CCM_AUTH_FAILED:
212 return( PSA_ERROR_INVALID_SIGNATURE );
213 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
214 return( PSA_ERROR_HARDWARE_FAILURE );
215
216 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
217 return( PSA_ERROR_NOT_SUPPORTED );
218 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
219 return( PSA_ERROR_INVALID_ARGUMENT );
220 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
221 return( PSA_ERROR_INSUFFICIENT_MEMORY );
222 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
223 return( PSA_ERROR_INVALID_PADDING );
224 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
225 return( PSA_ERROR_BAD_STATE );
226 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
227 return( PSA_ERROR_INVALID_SIGNATURE );
228 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
229 return( PSA_ERROR_TAMPERING_DETECTED );
230 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
231 return( PSA_ERROR_HARDWARE_FAILURE );
232
233 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
234 return( PSA_ERROR_HARDWARE_FAILURE );
235
236 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
237 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
238 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
239 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
240 return( PSA_ERROR_NOT_SUPPORTED );
241 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
242 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
243
244 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
245 return( PSA_ERROR_NOT_SUPPORTED );
246 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
247 return( PSA_ERROR_HARDWARE_FAILURE );
248
Gilles Peskinee59236f2018-01-27 23:32:46 +0100249 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
250 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
251 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
252 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100253
254 case MBEDTLS_ERR_GCM_AUTH_FAILED:
255 return( PSA_ERROR_INVALID_SIGNATURE );
256 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200257 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100258 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
259 return( PSA_ERROR_HARDWARE_FAILURE );
260
261 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
262 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
263 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
264 return( PSA_ERROR_HARDWARE_FAILURE );
265
266 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
267 return( PSA_ERROR_NOT_SUPPORTED );
268 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
269 return( PSA_ERROR_INVALID_ARGUMENT );
270 case MBEDTLS_ERR_MD_ALLOC_FAILED:
271 return( PSA_ERROR_INSUFFICIENT_MEMORY );
272 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
273 return( PSA_ERROR_STORAGE_FAILURE );
274 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
275 return( PSA_ERROR_HARDWARE_FAILURE );
276
Gilles Peskinef76aa772018-10-29 19:24:33 +0100277 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
278 return( PSA_ERROR_STORAGE_FAILURE );
279 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
280 return( PSA_ERROR_INVALID_ARGUMENT );
281 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
282 return( PSA_ERROR_INVALID_ARGUMENT );
283 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
284 return( PSA_ERROR_BUFFER_TOO_SMALL );
285 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
286 return( PSA_ERROR_INVALID_ARGUMENT );
287 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
288 return( PSA_ERROR_INVALID_ARGUMENT );
289 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
290 return( PSA_ERROR_INVALID_ARGUMENT );
291 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
292 return( PSA_ERROR_INSUFFICIENT_MEMORY );
293
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100294 case MBEDTLS_ERR_PK_ALLOC_FAILED:
295 return( PSA_ERROR_INSUFFICIENT_MEMORY );
296 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
297 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
298 return( PSA_ERROR_INVALID_ARGUMENT );
299 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100300 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100301 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
302 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
303 return( PSA_ERROR_INVALID_ARGUMENT );
304 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
305 return( PSA_ERROR_NOT_SUPPORTED );
306 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
307 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
308 return( PSA_ERROR_NOT_PERMITTED );
309 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
310 return( PSA_ERROR_INVALID_ARGUMENT );
311 case MBEDTLS_ERR_PK_INVALID_ALG:
312 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
313 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
314 return( PSA_ERROR_NOT_SUPPORTED );
315 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
316 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100317 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
318 return( PSA_ERROR_HARDWARE_FAILURE );
319
320 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
321 return( PSA_ERROR_HARDWARE_FAILURE );
322
323 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
324 return( PSA_ERROR_INVALID_ARGUMENT );
325 case MBEDTLS_ERR_RSA_INVALID_PADDING:
326 return( PSA_ERROR_INVALID_PADDING );
327 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
328 return( PSA_ERROR_HARDWARE_FAILURE );
329 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
330 return( PSA_ERROR_INVALID_ARGUMENT );
331 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
332 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
333 return( PSA_ERROR_TAMPERING_DETECTED );
334 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
335 return( PSA_ERROR_INVALID_SIGNATURE );
336 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
337 return( PSA_ERROR_BUFFER_TOO_SMALL );
338 case MBEDTLS_ERR_RSA_RNG_FAILED:
339 return( PSA_ERROR_INSUFFICIENT_MEMORY );
340 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
341 return( PSA_ERROR_NOT_SUPPORTED );
342 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
343 return( PSA_ERROR_HARDWARE_FAILURE );
344
345 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
346 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
347 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
348 return( PSA_ERROR_HARDWARE_FAILURE );
349
350 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
351 return( PSA_ERROR_INVALID_ARGUMENT );
352 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
353 return( PSA_ERROR_HARDWARE_FAILURE );
354
itayzafrir5c753392018-05-08 11:18:38 +0300355 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300356 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300357 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300358 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
359 return( PSA_ERROR_BUFFER_TOO_SMALL );
360 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
361 return( PSA_ERROR_NOT_SUPPORTED );
362 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
363 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
364 return( PSA_ERROR_INVALID_SIGNATURE );
365 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
366 return( PSA_ERROR_INSUFFICIENT_MEMORY );
367 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
368 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300369
Gilles Peskinee59236f2018-01-27 23:32:46 +0100370 default:
371 return( PSA_ERROR_UNKNOWN_ERROR );
372 }
373}
374
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200375
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200376
377
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100378/****************************************************************/
379/* Key management */
380/****************************************************************/
381
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100382#if defined(MBEDTLS_ECP_C)
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200383static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
384{
385 switch( grpid )
386 {
387 case MBEDTLS_ECP_DP_SECP192R1:
388 return( PSA_ECC_CURVE_SECP192R1 );
389 case MBEDTLS_ECP_DP_SECP224R1:
390 return( PSA_ECC_CURVE_SECP224R1 );
391 case MBEDTLS_ECP_DP_SECP256R1:
392 return( PSA_ECC_CURVE_SECP256R1 );
393 case MBEDTLS_ECP_DP_SECP384R1:
394 return( PSA_ECC_CURVE_SECP384R1 );
395 case MBEDTLS_ECP_DP_SECP521R1:
396 return( PSA_ECC_CURVE_SECP521R1 );
397 case MBEDTLS_ECP_DP_BP256R1:
398 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
399 case MBEDTLS_ECP_DP_BP384R1:
400 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
401 case MBEDTLS_ECP_DP_BP512R1:
402 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
403 case MBEDTLS_ECP_DP_CURVE25519:
404 return( PSA_ECC_CURVE_CURVE25519 );
405 case MBEDTLS_ECP_DP_SECP192K1:
406 return( PSA_ECC_CURVE_SECP192K1 );
407 case MBEDTLS_ECP_DP_SECP224K1:
408 return( PSA_ECC_CURVE_SECP224K1 );
409 case MBEDTLS_ECP_DP_SECP256K1:
410 return( PSA_ECC_CURVE_SECP256K1 );
411 case MBEDTLS_ECP_DP_CURVE448:
412 return( PSA_ECC_CURVE_CURVE448 );
413 default:
414 return( 0 );
415 }
416}
417
Gilles Peskine12313cd2018-06-20 00:20:32 +0200418static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
419{
420 switch( curve )
421 {
422 case PSA_ECC_CURVE_SECP192R1:
423 return( MBEDTLS_ECP_DP_SECP192R1 );
424 case PSA_ECC_CURVE_SECP224R1:
425 return( MBEDTLS_ECP_DP_SECP224R1 );
426 case PSA_ECC_CURVE_SECP256R1:
427 return( MBEDTLS_ECP_DP_SECP256R1 );
428 case PSA_ECC_CURVE_SECP384R1:
429 return( MBEDTLS_ECP_DP_SECP384R1 );
430 case PSA_ECC_CURVE_SECP521R1:
431 return( MBEDTLS_ECP_DP_SECP521R1 );
432 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
433 return( MBEDTLS_ECP_DP_BP256R1 );
434 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
435 return( MBEDTLS_ECP_DP_BP384R1 );
436 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
437 return( MBEDTLS_ECP_DP_BP512R1 );
438 case PSA_ECC_CURVE_CURVE25519:
439 return( MBEDTLS_ECP_DP_CURVE25519 );
440 case PSA_ECC_CURVE_SECP192K1:
441 return( MBEDTLS_ECP_DP_SECP192K1 );
442 case PSA_ECC_CURVE_SECP224K1:
443 return( MBEDTLS_ECP_DP_SECP224K1 );
444 case PSA_ECC_CURVE_SECP256K1:
445 return( MBEDTLS_ECP_DP_SECP256K1 );
446 case PSA_ECC_CURVE_CURVE448:
447 return( MBEDTLS_ECP_DP_CURVE448 );
448 default:
449 return( MBEDTLS_ECP_DP_NONE );
450 }
451}
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100452#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200453
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200454static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
455 size_t bits,
456 struct raw_data *raw )
457{
458 /* Check that the bit size is acceptable for the key type */
459 switch( type )
460 {
461 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200462 if( bits == 0 )
463 {
464 raw->bytes = 0;
465 raw->data = NULL;
466 return( PSA_SUCCESS );
467 }
468 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200469#if defined(MBEDTLS_MD_C)
470 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200471#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200472 case PSA_KEY_TYPE_DERIVE:
473 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200474#if defined(MBEDTLS_AES_C)
475 case PSA_KEY_TYPE_AES:
476 if( bits != 128 && bits != 192 && bits != 256 )
477 return( PSA_ERROR_INVALID_ARGUMENT );
478 break;
479#endif
480#if defined(MBEDTLS_CAMELLIA_C)
481 case PSA_KEY_TYPE_CAMELLIA:
482 if( bits != 128 && bits != 192 && bits != 256 )
483 return( PSA_ERROR_INVALID_ARGUMENT );
484 break;
485#endif
486#if defined(MBEDTLS_DES_C)
487 case PSA_KEY_TYPE_DES:
488 if( bits != 64 && bits != 128 && bits != 192 )
489 return( PSA_ERROR_INVALID_ARGUMENT );
490 break;
491#endif
492#if defined(MBEDTLS_ARC4_C)
493 case PSA_KEY_TYPE_ARC4:
494 if( bits < 8 || bits > 2048 )
495 return( PSA_ERROR_INVALID_ARGUMENT );
496 break;
497#endif
498 default:
499 return( PSA_ERROR_NOT_SUPPORTED );
500 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200501 if( bits % 8 != 0 )
502 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200503
504 /* Allocate memory for the key */
505 raw->bytes = PSA_BITS_TO_BYTES( bits );
506 raw->data = mbedtls_calloc( 1, raw->bytes );
507 if( raw->data == NULL )
508 {
509 raw->bytes = 0;
510 return( PSA_ERROR_INSUFFICIENT_MEMORY );
511 }
512 return( PSA_SUCCESS );
513}
514
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200515#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine86a440b2018-11-12 18:39:40 +0100516/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
517 * that are not a multiple of 8) well. For example, there is only
518 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
519 * way to return the exact bit size of a key.
520 * To keep things simple, reject non-byte-aligned key sizes. */
521static psa_status_t psa_check_rsa_key_byte_aligned(
522 const mbedtls_rsa_context *rsa )
523{
524 mbedtls_mpi n;
525 psa_status_t status;
526 mbedtls_mpi_init( &n );
527 status = mbedtls_to_psa_error(
528 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
529 if( status == PSA_SUCCESS )
530 {
531 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
532 status = PSA_ERROR_NOT_SUPPORTED;
533 }
534 mbedtls_mpi_free( &n );
535 return( status );
536}
537
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200538static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
539 mbedtls_rsa_context **p_rsa )
540{
541 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_RSA )
542 return( PSA_ERROR_INVALID_ARGUMENT );
543 else
544 {
545 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *pk );
Gilles Peskineaac64a22018-11-12 18:37:42 +0100546 /* The size of an RSA key doesn't have to be a multiple of 8.
547 * Mbed TLS supports non-byte-aligned key sizes, but not well.
548 * For example, mbedtls_rsa_get_len() returns the key size in
549 * bytes, not in bits. */
550 size_t bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100551 psa_status_t status;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200552 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
553 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100554 status = psa_check_rsa_key_byte_aligned( rsa );
555 if( status != PSA_SUCCESS )
556 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200557 *p_rsa = rsa;
558 return( PSA_SUCCESS );
559 }
560}
561#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
562
563#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinef76aa772018-10-29 19:24:33 +0100564/* Import an elliptic curve parsed by the mbedtls pk module. */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200565static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
566 mbedtls_pk_context *pk,
567 mbedtls_ecp_keypair **p_ecp )
568{
569 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
570 return( PSA_ERROR_INVALID_ARGUMENT );
571 else
572 {
573 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
574 psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
575 if( actual_curve != expected_curve )
576 return( PSA_ERROR_INVALID_ARGUMENT );
577 *p_ecp = ecp;
578 return( PSA_SUCCESS );
579 }
580}
581#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
582
Gilles Peskinef76aa772018-10-29 19:24:33 +0100583#if defined(MBEDTLS_ECP_C)
584/* Import a private key given as a byte string which is the private value
585 * in big-endian order. */
586static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
587 const uint8_t *data,
588 size_t data_length,
589 mbedtls_ecp_keypair **p_ecp )
590{
591 psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
592 mbedtls_ecp_keypair *ecp = NULL;
593 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
594
595 *p_ecp = NULL;
596 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
597 if( ecp == NULL )
598 return( PSA_ERROR_INSUFFICIENT_MEMORY );
599
600 /* Load the group. */
601 status = mbedtls_to_psa_error(
602 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
603 if( status != PSA_SUCCESS )
604 goto exit;
605 /* Load the secret value. */
606 status = mbedtls_to_psa_error(
607 mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
608 if( status != PSA_SUCCESS )
609 goto exit;
610 /* Validate the private key. */
611 status = mbedtls_to_psa_error(
612 mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
613 if( status != PSA_SUCCESS )
614 goto exit;
615 /* Calculate the public key from the private key. */
616 status = mbedtls_to_psa_error(
617 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
618 mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
619 if( status != PSA_SUCCESS )
620 goto exit;
621
622 *p_ecp = ecp;
623 return( PSA_SUCCESS );
624
625exit:
626 if( ecp != NULL )
627 {
628 mbedtls_ecp_keypair_free( ecp );
629 mbedtls_free( ecp );
630 }
631 return( status );
632}
633#endif /* defined(MBEDTLS_ECP_C) */
634
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100635/** Import key data into a slot. `slot->type` must have been set
636 * previously. This function assumes that the slot does not contain
637 * any key material yet. On failure, the slot content is unchanged. */
Gilles Peskine2f060a82018-12-04 17:12:32 +0100638static psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
Darryl Green940d72c2018-07-13 13:18:51 +0100639 const uint8_t *data,
640 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100641{
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200642 psa_status_t status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100643
Darryl Green940d72c2018-07-13 13:18:51 +0100644 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100645 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100646 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100647 if( data_length > SIZE_MAX / 8 )
648 return( PSA_ERROR_NOT_SUPPORTED );
Darryl Green940d72c2018-07-13 13:18:51 +0100649 status = prepare_raw_data_slot( slot->type,
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200650 PSA_BYTES_TO_BITS( data_length ),
651 &slot->data.raw );
652 if( status != PSA_SUCCESS )
653 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200654 if( data_length != 0 )
655 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100656 }
657 else
Gilles Peskinef76aa772018-10-29 19:24:33 +0100658#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100659 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100660 {
Darryl Green940d72c2018-07-13 13:18:51 +0100661 status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskinef76aa772018-10-29 19:24:33 +0100662 data, data_length,
663 &slot->data.ecp );
664 if( status != PSA_SUCCESS )
665 return( status );
666 }
667 else
668#endif /* MBEDTLS_ECP_C */
Gilles Peskine969ac722018-01-28 18:16:59 +0100669#if defined(MBEDTLS_PK_PARSE_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100670 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
671 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100672 {
673 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100674 mbedtls_pk_context pk;
675 mbedtls_pk_init( &pk );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200676
677 /* Parse the data. */
Darryl Green940d72c2018-07-13 13:18:51 +0100678 if( PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100679 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
680 else
681 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100682 if( ret != 0 )
683 return( mbedtls_to_psa_error( ret ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200684
685 /* We have something that the pkparse module recognizes.
686 * If it has the expected type and passes any type-specific
687 * checks, store it. */
Gilles Peskine969ac722018-01-28 18:16:59 +0100688#if defined(MBEDTLS_RSA_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100689 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200690 status = psa_import_rsa_key( &pk, &slot->data.rsa );
691 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100692#endif /* MBEDTLS_RSA_C */
693#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100694 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
695 status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200696 &pk, &slot->data.ecp );
697 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100698#endif /* MBEDTLS_ECP_C */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200699 {
700 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinec648d692018-06-28 08:46:13 +0200701 }
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200702
Gilles Peskinec648d692018-06-28 08:46:13 +0200703 /* Free the content of the pk object only on error. On success,
704 * the content of the object has been stored in the slot. */
705 if( status != PSA_SUCCESS )
706 {
707 mbedtls_pk_free( &pk );
708 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100709 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100710 }
711 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100712#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100713 {
714 return( PSA_ERROR_NOT_SUPPORTED );
715 }
Darryl Green940d72c2018-07-13 13:18:51 +0100716 return( PSA_SUCCESS );
717}
718
Darryl Greend49a4992018-06-18 17:27:26 +0100719#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine2f060a82018-12-04 17:12:32 +0100720static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *p_slot )
Darryl Greend49a4992018-06-18 17:27:26 +0100721{
722 psa_status_t status = PSA_SUCCESS;
723 uint8_t *key_data = NULL;
724 size_t key_data_length = 0;
725
Gilles Peskine69f976b2018-11-30 18:46:56 +0100726 status = psa_load_persistent_key( p_slot->persistent_storage_id,
727 &( p_slot )->type,
Darryl Greend49a4992018-06-18 17:27:26 +0100728 &( p_slot )->policy, &key_data,
729 &key_data_length );
730 if( status != PSA_SUCCESS )
731 goto exit;
732 status = psa_import_key_into_slot( p_slot,
733 key_data, key_data_length );
734exit:
735 psa_free_persistent_key_data( key_data, key_data_length );
736 return( status );
737}
738#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
739
Gilles Peskinec5487a82018-12-03 18:08:14 +0100740/* Access a key slot at the given handle. The handle of a key slot is
741 * the index of the slot in the global slot array, plus one so that handles
742 * start at 1 and not 0. */
743static psa_status_t psa_get_key_slot( psa_key_handle_t handle,
Gilles Peskine2f060a82018-12-04 17:12:32 +0100744 psa_key_slot_t **p_slot )
Darryl Green06fd18d2018-07-16 11:21:11 +0100745{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100746 psa_key_slot_t *slot = NULL;
Gilles Peskine961849f2018-11-30 18:54:54 +0100747
Darryl Green06fd18d2018-07-16 11:21:11 +0100748 GUARD_MODULE_INITIALIZED;
749
Gilles Peskinec5487a82018-12-03 18:08:14 +0100750 /* 0 is not a valid handle under any circumstance. This
Darryl Green06fd18d2018-07-16 11:21:11 +0100751 * implementation provides slots number 1 to N where N is the
752 * number of available slots. */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100753 if( handle == 0 || handle > ARRAY_LENGTH( global_data.key_slots ) )
754 return( PSA_ERROR_INVALID_HANDLE );
755 slot = &global_data.key_slots[handle - 1];
Darryl Green06fd18d2018-07-16 11:21:11 +0100756
Gilles Peskinec5487a82018-12-03 18:08:14 +0100757 /* If the slot hasn't been allocated, the handle is invalid. */
758 if( ! slot->allocated )
759 return( PSA_ERROR_INVALID_HANDLE );
Darryl Greend49a4992018-06-18 17:27:26 +0100760
Gilles Peskinec5487a82018-12-03 18:08:14 +0100761 *p_slot = slot;
Darryl Green06fd18d2018-07-16 11:21:11 +0100762 return( PSA_SUCCESS );
763}
764
765/* Retrieve an empty key slot (slot with no key data, but possibly
766 * with some metadata such as a policy). */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100767static psa_status_t psa_get_empty_key_slot( psa_key_handle_t handle,
Gilles Peskine2f060a82018-12-04 17:12:32 +0100768 psa_key_slot_t **p_slot )
Darryl Green06fd18d2018-07-16 11:21:11 +0100769{
770 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +0100771 psa_key_slot_t *slot = NULL;
Darryl Green06fd18d2018-07-16 11:21:11 +0100772
773 *p_slot = NULL;
774
Gilles Peskinec5487a82018-12-03 18:08:14 +0100775 status = psa_get_key_slot( handle, &slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100776 if( status != PSA_SUCCESS )
777 return( status );
778
779 if( slot->type != PSA_KEY_TYPE_NONE )
780 return( PSA_ERROR_OCCUPIED_SLOT );
781
782 *p_slot = slot;
783 return( status );
784}
785
786/** Retrieve a slot which must contain a key. The key must have allow all the
787 * usage flags set in \p usage. If \p alg is nonzero, the key must allow
788 * operations with this algorithm. */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100789static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle,
Gilles Peskine2f060a82018-12-04 17:12:32 +0100790 psa_key_slot_t **p_slot,
Darryl Green06fd18d2018-07-16 11:21:11 +0100791 psa_key_usage_t usage,
792 psa_algorithm_t alg )
793{
794 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +0100795 psa_key_slot_t *slot = NULL;
Darryl Green06fd18d2018-07-16 11:21:11 +0100796
797 *p_slot = NULL;
798
Gilles Peskinec5487a82018-12-03 18:08:14 +0100799 status = psa_get_key_slot( handle, &slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100800 if( status != PSA_SUCCESS )
801 return( status );
802 if( slot->type == PSA_KEY_TYPE_NONE )
803 return( PSA_ERROR_EMPTY_SLOT );
804
805 /* Enforce that usage policy for the key slot contains all the flags
806 * required by the usage parameter. There is one exception: public
807 * keys can always be exported, so we treat public key objects as
808 * if they had the export flag. */
809 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
810 usage &= ~PSA_KEY_USAGE_EXPORT;
811 if( ( slot->policy.usage & usage ) != usage )
812 return( PSA_ERROR_NOT_PERMITTED );
813 if( alg != 0 && ( alg != slot->policy.alg ) )
814 return( PSA_ERROR_NOT_PERMITTED );
815
816 *p_slot = slot;
817 return( PSA_SUCCESS );
818}
Darryl Green940d72c2018-07-13 13:18:51 +0100819
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100820/** Wipe key data from a slot. Preserve metadata such as the policy. */
Gilles Peskine2f060a82018-12-04 17:12:32 +0100821static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
Darryl Green40225ba2018-11-15 14:48:15 +0000822{
823 if( slot->type == PSA_KEY_TYPE_NONE )
824 {
825 /* No key material to clean. */
826 }
827 else if( key_type_is_raw_bytes( slot->type ) )
828 {
829 mbedtls_free( slot->data.raw.data );
830 }
831 else
832#if defined(MBEDTLS_RSA_C)
833 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
834 {
835 mbedtls_rsa_free( slot->data.rsa );
836 mbedtls_free( slot->data.rsa );
837 }
838 else
839#endif /* defined(MBEDTLS_RSA_C) */
840#if defined(MBEDTLS_ECP_C)
841 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
842 {
843 mbedtls_ecp_keypair_free( slot->data.ecp );
844 mbedtls_free( slot->data.ecp );
845 }
846 else
847#endif /* defined(MBEDTLS_ECP_C) */
848 {
849 /* Shouldn't happen: the key type is not any type that we
850 * put in. */
851 return( PSA_ERROR_TAMPERING_DETECTED );
852 }
853
854 return( PSA_SUCCESS );
855}
856
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100857/** Completely wipe a slot in memory, including its policy.
858 * Persistent storage is not affected. */
Gilles Peskine2f060a82018-12-04 17:12:32 +0100859static psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot )
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100860{
861 psa_status_t status = psa_remove_key_data_from_memory( slot );
862 /* At this point, key material and other type-specific content has
863 * been wiped. Clear remaining metadata. We can call memset and not
864 * zeroize because the metadata is not particularly sensitive. */
865 memset( slot, 0, sizeof( *slot ) );
866 return( status );
867}
868
Gilles Peskine961849f2018-11-30 18:54:54 +0100869psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle )
870{
Gilles Peskinec5487a82018-12-03 18:08:14 +0100871 for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) )
Gilles Peskine961849f2018-11-30 18:54:54 +0100872 {
Gilles Peskine2f060a82018-12-04 17:12:32 +0100873 psa_key_slot_t *slot = &global_data.key_slots[*handle - 1];
Gilles Peskinec5487a82018-12-03 18:08:14 +0100874 if( ! slot->allocated )
Gilles Peskine961849f2018-11-30 18:54:54 +0100875 {
876 slot->allocated = 1;
Gilles Peskine961849f2018-11-30 18:54:54 +0100877 return( PSA_SUCCESS );
878 }
879 }
880 return( PSA_ERROR_INSUFFICIENT_MEMORY );
881}
882
883psa_status_t psa_internal_make_key_persistent( psa_key_handle_t handle,
884 psa_key_id_t id )
885{
Gilles Peskine4a044732018-12-03 18:19:39 +0100886#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine2f060a82018-12-04 17:12:32 +0100887 psa_key_slot_t *slot;
Gilles Peskine961849f2018-11-30 18:54:54 +0100888 psa_status_t status;
889
890 /* Reject id=0 because by general library conventions, 0 is an invalid
891 * value wherever possible. */
892 if( id == 0 )
893 return( PSA_ERROR_INVALID_ARGUMENT );
894 /* Reject high values because the file names are reserved for the
895 * library's internal use. */
896 if( id >= 0xffff0000 )
897 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine961849f2018-11-30 18:54:54 +0100898
899 status = psa_get_key_slot( handle, &slot );
900 if( status != PSA_SUCCESS )
901 return( status );
902
903 slot->lifetime = PSA_KEY_LIFETIME_PERSISTENT;
904 slot->persistent_storage_id = id;
905 status = psa_load_persistent_key_into_slot( slot );
906
907 return( status );
Gilles Peskine4a044732018-12-03 18:19:39 +0100908
909#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
910 (void) handle;
911 (void) id;
912 return( PSA_ERROR_NOT_SUPPORTED );
913#endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine961849f2018-11-30 18:54:54 +0100914}
915
916psa_status_t psa_internal_release_key_slot( psa_key_handle_t handle )
917{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100918 psa_key_slot_t *slot;
Gilles Peskinec5487a82018-12-03 18:08:14 +0100919 psa_status_t status;
920
921 status = psa_get_key_slot( handle, &slot );
922 if( status != PSA_SUCCESS )
923 return( status );
Gilles Peskine961849f2018-11-30 18:54:54 +0100924 if( ! slot->allocated )
925 return( PSA_ERROR_INVALID_HANDLE );
Gilles Peskinec5487a82018-12-03 18:08:14 +0100926
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100927 return( psa_wipe_key_slot( slot ) );
Gilles Peskine961849f2018-11-30 18:54:54 +0100928}
929
Gilles Peskinec5487a82018-12-03 18:08:14 +0100930psa_status_t psa_import_key( psa_key_handle_t handle,
Darryl Green940d72c2018-07-13 13:18:51 +0100931 psa_key_type_t type,
932 const uint8_t *data,
933 size_t data_length )
934{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100935 psa_key_slot_t *slot;
Darryl Green940d72c2018-07-13 13:18:51 +0100936 psa_status_t status;
937
Gilles Peskinec5487a82018-12-03 18:08:14 +0100938 status = psa_get_empty_key_slot( handle, &slot );
Darryl Green940d72c2018-07-13 13:18:51 +0100939 if( status != PSA_SUCCESS )
940 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100941
942 slot->type = type;
Darryl Green940d72c2018-07-13 13:18:51 +0100943
944 status = psa_import_key_into_slot( slot, data, data_length );
945 if( status != PSA_SUCCESS )
946 {
947 slot->type = PSA_KEY_TYPE_NONE;
948 return( status );
949 }
950
Darryl Greend49a4992018-06-18 17:27:26 +0100951#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
952 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
953 {
954 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +0100955 status = psa_save_persistent_key( slot->persistent_storage_id,
956 slot->type, &slot->policy, data,
Darryl Greend49a4992018-06-18 17:27:26 +0100957 data_length );
958 if( status != PSA_SUCCESS )
959 {
960 (void) psa_remove_key_data_from_memory( slot );
961 slot->type = PSA_KEY_TYPE_NONE;
962 }
963 }
964#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
965
966 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100967}
968
Gilles Peskinec5487a82018-12-03 18:08:14 +0100969psa_status_t psa_destroy_key( psa_key_handle_t handle )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100970{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100971 psa_key_slot_t *slot;
Darryl Greend49a4992018-06-18 17:27:26 +0100972 psa_status_t status = PSA_SUCCESS;
973 psa_status_t storage_status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100974
Gilles Peskinec5487a82018-12-03 18:08:14 +0100975 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200976 if( status != PSA_SUCCESS )
977 return( status );
Darryl Greend49a4992018-06-18 17:27:26 +0100978#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
979 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
980 {
Gilles Peskine69f976b2018-11-30 18:46:56 +0100981 storage_status =
982 psa_destroy_persistent_key( slot->persistent_storage_id );
Darryl Greend49a4992018-06-18 17:27:26 +0100983 }
984#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100985 status = psa_wipe_key_slot( slot );
Darryl Greend49a4992018-06-18 17:27:26 +0100986 if( status != PSA_SUCCESS )
987 return( status );
988 return( storage_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100989}
990
Gilles Peskineb870b182018-07-06 16:02:09 +0200991/* Return the size of the key in the given slot, in bits. */
Gilles Peskine2f060a82018-12-04 17:12:32 +0100992static size_t psa_get_key_bits( const psa_key_slot_t *slot )
Gilles Peskineb870b182018-07-06 16:02:09 +0200993{
994 if( key_type_is_raw_bytes( slot->type ) )
995 return( slot->data.raw.bytes * 8 );
996#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200997 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaac64a22018-11-12 18:37:42 +0100998 return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
Gilles Peskineb870b182018-07-06 16:02:09 +0200999#endif /* defined(MBEDTLS_RSA_C) */
1000#if defined(MBEDTLS_ECP_C)
1001 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1002 return( slot->data.ecp->grp.pbits );
1003#endif /* defined(MBEDTLS_ECP_C) */
1004 /* Shouldn't happen except on an empty slot. */
1005 return( 0 );
1006}
1007
Gilles Peskinec5487a82018-12-03 18:08:14 +01001008psa_status_t psa_get_key_information( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001009 psa_key_type_t *type,
1010 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001011{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001012 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001013 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001014
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001015 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001016 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001017 if( bits != NULL )
1018 *bits = 0;
Gilles Peskinec5487a82018-12-03 18:08:14 +01001019 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001020 if( status != PSA_SUCCESS )
1021 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +02001022
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001023 if( slot->type == PSA_KEY_TYPE_NONE )
1024 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001025 if( type != NULL )
1026 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +02001027 if( bits != NULL )
1028 *bits = psa_get_key_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001029 return( PSA_SUCCESS );
1030}
1031
Gilles Peskine2f060a82018-12-04 17:12:32 +01001032static psa_status_t psa_internal_export_key( psa_key_slot_t *slot,
Gilles Peskine2d277862018-06-18 15:41:12 +02001033 uint8_t *data,
1034 size_t data_size,
1035 size_t *data_length,
1036 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001037{
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001038 *data_length = 0;
1039
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001040 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001041 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +03001042
Gilles Peskine48c0ea12018-06-21 14:15:31 +02001043 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001044 {
1045 if( slot->data.raw.bytes > data_size )
1046 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine52b90182018-10-29 19:26:27 +01001047 if( data_size != 0 )
1048 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001049 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine52b90182018-10-29 19:26:27 +01001050 memset( data + slot->data.raw.bytes, 0,
1051 data_size - slot->data.raw.bytes );
1052 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001053 *data_length = slot->data.raw.bytes;
1054 return( PSA_SUCCESS );
1055 }
Gilles Peskine188c71e2018-10-29 19:26:02 +01001056#if defined(MBEDTLS_ECP_C)
1057 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) && !export_public_key )
1058 {
Darryl Greendd8fb772018-11-07 16:00:44 +00001059 psa_status_t status;
1060
Gilles Peskine188c71e2018-10-29 19:26:02 +01001061 size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( slot ) );
1062 if( bytes > data_size )
1063 return( PSA_ERROR_BUFFER_TOO_SMALL );
1064 status = mbedtls_to_psa_error(
1065 mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
1066 if( status != PSA_SUCCESS )
1067 return( status );
1068 memset( data + bytes, 0, data_size - bytes );
1069 *data_length = bytes;
1070 return( PSA_SUCCESS );
1071 }
1072#endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001073 else
Moran Peker17e36e12018-05-02 12:55:20 +03001074 {
Gilles Peskine969ac722018-01-28 18:16:59 +01001075#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02001076 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
Moran Pekera998bc62018-04-16 18:16:20 +03001077 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +01001078 {
Moran Pekera998bc62018-04-16 18:16:20 +03001079 mbedtls_pk_context pk;
1080 int ret;
Gilles Peskined8008d62018-06-29 19:51:51 +02001081 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001082 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001083#if defined(MBEDTLS_RSA_C)
1084 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001085 pk.pk_info = &mbedtls_rsa_info;
1086 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001087#else
1088 return( PSA_ERROR_NOT_SUPPORTED );
1089#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001090 }
1091 else
1092 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001093#if defined(MBEDTLS_ECP_C)
1094 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001095 pk.pk_info = &mbedtls_eckey_info;
1096 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001097#else
1098 return( PSA_ERROR_NOT_SUPPORTED );
1099#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001100 }
Moran Pekerd7326592018-05-29 16:56:39 +03001101 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001102 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +03001103 else
1104 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +03001105 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001106 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001107 /* If data_size is 0 then data may be NULL and then the
1108 * call to memset would have undefined behavior. */
1109 if( data_size != 0 )
1110 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +03001111 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001112 }
Gilles Peskine0e231582018-06-20 00:11:07 +02001113 /* The mbedtls_pk_xxx functions write to the end of the buffer.
1114 * Move the data to the beginning and erase remaining data
1115 * at the original location. */
1116 if( 2 * (size_t) ret <= data_size )
1117 {
1118 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001119 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001120 }
1121 else if( (size_t) ret < data_size )
1122 {
1123 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001124 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001125 }
Moran Pekera998bc62018-04-16 18:16:20 +03001126 *data_length = ret;
1127 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +01001128 }
1129 else
Gilles Peskine6d912132018-03-07 16:41:37 +01001130#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +03001131 {
1132 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +02001133 it is valid for a special-purpose implementation to omit
1134 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +03001135 return( PSA_ERROR_NOT_SUPPORTED );
1136 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001137 }
1138}
1139
Gilles Peskinec5487a82018-12-03 18:08:14 +01001140psa_status_t psa_export_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001141 uint8_t *data,
1142 size_t data_size,
1143 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001144{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001145 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001146 psa_status_t status;
1147
1148 /* Set the key to empty now, so that even when there are errors, we always
1149 * set data_length to a value between 0 and data_size. On error, setting
1150 * the key to empty is a good choice because an empty key representation is
1151 * unlikely to be accepted anywhere. */
1152 *data_length = 0;
1153
1154 /* Export requires the EXPORT flag. There is an exception for public keys,
1155 * which don't require any flag, but psa_get_key_from_slot takes
1156 * care of this. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001157 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_EXPORT, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001158 if( status != PSA_SUCCESS )
1159 return( status );
1160 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001161 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001162}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001163
Gilles Peskinec5487a82018-12-03 18:08:14 +01001164psa_status_t psa_export_public_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001165 uint8_t *data,
1166 size_t data_size,
1167 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001168{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001169 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001170 psa_status_t status;
1171
1172 /* Set the key to empty now, so that even when there are errors, we always
1173 * set data_length to a value between 0 and data_size. On error, setting
1174 * the key to empty is a good choice because an empty key representation is
1175 * unlikely to be accepted anywhere. */
1176 *data_length = 0;
1177
1178 /* Exporting a public key doesn't require a usage flag. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001179 status = psa_get_key_from_slot( handle, &slot, 0, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001180 if( status != PSA_SUCCESS )
1181 return( status );
1182 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001183 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001184}
1185
Darryl Green0c6575a2018-11-07 16:05:30 +00001186#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine2f060a82018-12-04 17:12:32 +01001187static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t *slot,
Darryl Green0c6575a2018-11-07 16:05:30 +00001188 size_t bits )
1189{
1190 psa_status_t status;
1191 uint8_t *data;
1192 size_t key_length;
1193 size_t data_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type, bits );
1194 data = mbedtls_calloc( 1, data_size );
itayzafrir910c76b2018-11-21 16:03:21 +02001195 if( data == NULL )
1196 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Darryl Green0c6575a2018-11-07 16:05:30 +00001197 /* Get key data in export format */
1198 status = psa_internal_export_key( slot, data, data_size, &key_length, 0 );
1199 if( status != PSA_SUCCESS )
1200 {
1201 slot->type = PSA_KEY_TYPE_NONE;
1202 goto exit;
1203 }
1204 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +01001205 status = psa_save_persistent_key( slot->persistent_storage_id,
1206 slot->type, &slot->policy,
Darryl Green0c6575a2018-11-07 16:05:30 +00001207 data, key_length );
1208 if( status != PSA_SUCCESS )
1209 {
1210 slot->type = PSA_KEY_TYPE_NONE;
1211 }
1212exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01001213 mbedtls_platform_zeroize( data, key_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00001214 mbedtls_free( data );
1215 return( status );
1216}
1217#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1218
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001219
1220
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001221/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01001222/* Message digests */
1223/****************************************************************/
1224
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001225static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01001226{
1227 switch( alg )
1228 {
1229#if defined(MBEDTLS_MD2_C)
1230 case PSA_ALG_MD2:
1231 return( &mbedtls_md2_info );
1232#endif
1233#if defined(MBEDTLS_MD4_C)
1234 case PSA_ALG_MD4:
1235 return( &mbedtls_md4_info );
1236#endif
1237#if defined(MBEDTLS_MD5_C)
1238 case PSA_ALG_MD5:
1239 return( &mbedtls_md5_info );
1240#endif
1241#if defined(MBEDTLS_RIPEMD160_C)
1242 case PSA_ALG_RIPEMD160:
1243 return( &mbedtls_ripemd160_info );
1244#endif
1245#if defined(MBEDTLS_SHA1_C)
1246 case PSA_ALG_SHA_1:
1247 return( &mbedtls_sha1_info );
1248#endif
1249#if defined(MBEDTLS_SHA256_C)
1250 case PSA_ALG_SHA_224:
1251 return( &mbedtls_sha224_info );
1252 case PSA_ALG_SHA_256:
1253 return( &mbedtls_sha256_info );
1254#endif
1255#if defined(MBEDTLS_SHA512_C)
1256 case PSA_ALG_SHA_384:
1257 return( &mbedtls_sha384_info );
1258 case PSA_ALG_SHA_512:
1259 return( &mbedtls_sha512_info );
1260#endif
1261 default:
1262 return( NULL );
1263 }
1264}
1265
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001266psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
1267{
1268 switch( operation->alg )
1269 {
Gilles Peskine81736312018-06-26 15:04:31 +02001270 case 0:
1271 /* The object has (apparently) been initialized but it is not
1272 * in use. It's ok to call abort on such an object, and there's
1273 * nothing to do. */
1274 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001275#if defined(MBEDTLS_MD2_C)
1276 case PSA_ALG_MD2:
1277 mbedtls_md2_free( &operation->ctx.md2 );
1278 break;
1279#endif
1280#if defined(MBEDTLS_MD4_C)
1281 case PSA_ALG_MD4:
1282 mbedtls_md4_free( &operation->ctx.md4 );
1283 break;
1284#endif
1285#if defined(MBEDTLS_MD5_C)
1286 case PSA_ALG_MD5:
1287 mbedtls_md5_free( &operation->ctx.md5 );
1288 break;
1289#endif
1290#if defined(MBEDTLS_RIPEMD160_C)
1291 case PSA_ALG_RIPEMD160:
1292 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
1293 break;
1294#endif
1295#if defined(MBEDTLS_SHA1_C)
1296 case PSA_ALG_SHA_1:
1297 mbedtls_sha1_free( &operation->ctx.sha1 );
1298 break;
1299#endif
1300#if defined(MBEDTLS_SHA256_C)
1301 case PSA_ALG_SHA_224:
1302 case PSA_ALG_SHA_256:
1303 mbedtls_sha256_free( &operation->ctx.sha256 );
1304 break;
1305#endif
1306#if defined(MBEDTLS_SHA512_C)
1307 case PSA_ALG_SHA_384:
1308 case PSA_ALG_SHA_512:
1309 mbedtls_sha512_free( &operation->ctx.sha512 );
1310 break;
1311#endif
1312 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001313 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001314 }
1315 operation->alg = 0;
1316 return( PSA_SUCCESS );
1317}
1318
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02001319psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001320 psa_algorithm_t alg )
1321{
1322 int ret;
1323 operation->alg = 0;
1324 switch( alg )
1325 {
1326#if defined(MBEDTLS_MD2_C)
1327 case PSA_ALG_MD2:
1328 mbedtls_md2_init( &operation->ctx.md2 );
1329 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
1330 break;
1331#endif
1332#if defined(MBEDTLS_MD4_C)
1333 case PSA_ALG_MD4:
1334 mbedtls_md4_init( &operation->ctx.md4 );
1335 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
1336 break;
1337#endif
1338#if defined(MBEDTLS_MD5_C)
1339 case PSA_ALG_MD5:
1340 mbedtls_md5_init( &operation->ctx.md5 );
1341 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
1342 break;
1343#endif
1344#if defined(MBEDTLS_RIPEMD160_C)
1345 case PSA_ALG_RIPEMD160:
1346 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
1347 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
1348 break;
1349#endif
1350#if defined(MBEDTLS_SHA1_C)
1351 case PSA_ALG_SHA_1:
1352 mbedtls_sha1_init( &operation->ctx.sha1 );
1353 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
1354 break;
1355#endif
1356#if defined(MBEDTLS_SHA256_C)
1357 case PSA_ALG_SHA_224:
1358 mbedtls_sha256_init( &operation->ctx.sha256 );
1359 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
1360 break;
1361 case PSA_ALG_SHA_256:
1362 mbedtls_sha256_init( &operation->ctx.sha256 );
1363 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
1364 break;
1365#endif
1366#if defined(MBEDTLS_SHA512_C)
1367 case PSA_ALG_SHA_384:
1368 mbedtls_sha512_init( &operation->ctx.sha512 );
1369 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
1370 break;
1371 case PSA_ALG_SHA_512:
1372 mbedtls_sha512_init( &operation->ctx.sha512 );
1373 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1374 break;
1375#endif
1376 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001377 return( PSA_ALG_IS_HASH( alg ) ?
1378 PSA_ERROR_NOT_SUPPORTED :
1379 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001380 }
1381 if( ret == 0 )
1382 operation->alg = alg;
1383 else
1384 psa_hash_abort( operation );
1385 return( mbedtls_to_psa_error( ret ) );
1386}
1387
1388psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1389 const uint8_t *input,
1390 size_t input_length )
1391{
1392 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001393
1394 /* Don't require hash implementations to behave correctly on a
1395 * zero-length input, which may have an invalid pointer. */
1396 if( input_length == 0 )
1397 return( PSA_SUCCESS );
1398
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001399 switch( operation->alg )
1400 {
1401#if defined(MBEDTLS_MD2_C)
1402 case PSA_ALG_MD2:
1403 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1404 input, input_length );
1405 break;
1406#endif
1407#if defined(MBEDTLS_MD4_C)
1408 case PSA_ALG_MD4:
1409 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1410 input, input_length );
1411 break;
1412#endif
1413#if defined(MBEDTLS_MD5_C)
1414 case PSA_ALG_MD5:
1415 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1416 input, input_length );
1417 break;
1418#endif
1419#if defined(MBEDTLS_RIPEMD160_C)
1420 case PSA_ALG_RIPEMD160:
1421 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1422 input, input_length );
1423 break;
1424#endif
1425#if defined(MBEDTLS_SHA1_C)
1426 case PSA_ALG_SHA_1:
1427 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1428 input, input_length );
1429 break;
1430#endif
1431#if defined(MBEDTLS_SHA256_C)
1432 case PSA_ALG_SHA_224:
1433 case PSA_ALG_SHA_256:
1434 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1435 input, input_length );
1436 break;
1437#endif
1438#if defined(MBEDTLS_SHA512_C)
1439 case PSA_ALG_SHA_384:
1440 case PSA_ALG_SHA_512:
1441 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1442 input, input_length );
1443 break;
1444#endif
1445 default:
1446 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1447 break;
1448 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001449
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001450 if( ret != 0 )
1451 psa_hash_abort( operation );
1452 return( mbedtls_to_psa_error( ret ) );
1453}
1454
1455psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1456 uint8_t *hash,
1457 size_t hash_size,
1458 size_t *hash_length )
1459{
itayzafrir40835d42018-08-02 13:14:17 +03001460 psa_status_t status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001461 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001462 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001463
1464 /* Fill the output buffer with something that isn't a valid hash
1465 * (barring an attack on the hash and deliberately-crafted input),
1466 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001467 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001468 /* If hash_size is 0 then hash may be NULL and then the
1469 * call to memset would have undefined behavior. */
1470 if( hash_size != 0 )
1471 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001472
1473 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03001474 {
1475 status = PSA_ERROR_BUFFER_TOO_SMALL;
1476 goto exit;
1477 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001478
1479 switch( operation->alg )
1480 {
1481#if defined(MBEDTLS_MD2_C)
1482 case PSA_ALG_MD2:
1483 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1484 break;
1485#endif
1486#if defined(MBEDTLS_MD4_C)
1487 case PSA_ALG_MD4:
1488 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1489 break;
1490#endif
1491#if defined(MBEDTLS_MD5_C)
1492 case PSA_ALG_MD5:
1493 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1494 break;
1495#endif
1496#if defined(MBEDTLS_RIPEMD160_C)
1497 case PSA_ALG_RIPEMD160:
1498 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1499 break;
1500#endif
1501#if defined(MBEDTLS_SHA1_C)
1502 case PSA_ALG_SHA_1:
1503 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1504 break;
1505#endif
1506#if defined(MBEDTLS_SHA256_C)
1507 case PSA_ALG_SHA_224:
1508 case PSA_ALG_SHA_256:
1509 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1510 break;
1511#endif
1512#if defined(MBEDTLS_SHA512_C)
1513 case PSA_ALG_SHA_384:
1514 case PSA_ALG_SHA_512:
1515 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1516 break;
1517#endif
1518 default:
1519 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1520 break;
1521 }
itayzafrir40835d42018-08-02 13:14:17 +03001522 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001523
itayzafrir40835d42018-08-02 13:14:17 +03001524exit:
1525 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001526 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001527 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001528 return( psa_hash_abort( operation ) );
1529 }
1530 else
1531 {
1532 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03001533 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001534 }
1535}
1536
Gilles Peskine2d277862018-06-18 15:41:12 +02001537psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1538 const uint8_t *hash,
1539 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001540{
1541 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1542 size_t actual_hash_length;
1543 psa_status_t status = psa_hash_finish( operation,
1544 actual_hash, sizeof( actual_hash ),
1545 &actual_hash_length );
1546 if( status != PSA_SUCCESS )
1547 return( status );
1548 if( actual_hash_length != hash_length )
1549 return( PSA_ERROR_INVALID_SIGNATURE );
1550 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1551 return( PSA_ERROR_INVALID_SIGNATURE );
1552 return( PSA_SUCCESS );
1553}
1554
1555
1556
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001557/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001558/* MAC */
1559/****************************************************************/
1560
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001561static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001562 psa_algorithm_t alg,
1563 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001564 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001565 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001566{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001567 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001568 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001569
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001570 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001571 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001572
Gilles Peskine8c9def32018-02-08 10:02:12 +01001573 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1574 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001575 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001576 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001577 case PSA_ALG_ARC4:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001578 mode = MBEDTLS_MODE_STREAM;
1579 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001580 case PSA_ALG_CTR:
1581 mode = MBEDTLS_MODE_CTR;
1582 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001583 case PSA_ALG_CFB:
1584 mode = MBEDTLS_MODE_CFB;
1585 break;
1586 case PSA_ALG_OFB:
1587 mode = MBEDTLS_MODE_OFB;
1588 break;
1589 case PSA_ALG_CBC_NO_PADDING:
1590 mode = MBEDTLS_MODE_CBC;
1591 break;
1592 case PSA_ALG_CBC_PKCS7:
1593 mode = MBEDTLS_MODE_CBC;
1594 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001595 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001596 mode = MBEDTLS_MODE_CCM;
1597 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001598 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001599 mode = MBEDTLS_MODE_GCM;
1600 break;
1601 default:
1602 return( NULL );
1603 }
1604 }
1605 else if( alg == PSA_ALG_CMAC )
1606 mode = MBEDTLS_MODE_ECB;
1607 else if( alg == PSA_ALG_GMAC )
1608 mode = MBEDTLS_MODE_GCM;
1609 else
1610 return( NULL );
1611
1612 switch( key_type )
1613 {
1614 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001615 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001616 break;
1617 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001618 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1619 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001620 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001621 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001622 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001623 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001624 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1625 * but two-key Triple-DES is functionally three-key Triple-DES
1626 * with K1=K3, so that's how we present it to mbedtls. */
1627 if( key_bits == 128 )
1628 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001629 break;
1630 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001631 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001632 break;
1633 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001634 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001635 break;
1636 default:
1637 return( NULL );
1638 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001639 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001640 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001641
Jaeden Amero23bbb752018-06-26 14:16:54 +01001642 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1643 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001644}
1645
Gilles Peskinea05219c2018-11-16 16:02:56 +01001646#if defined(MBEDTLS_MD_C)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001647static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001648{
Gilles Peskine2d277862018-06-18 15:41:12 +02001649 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001650 {
1651 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001652 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001653 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001654 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001655 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001656 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001657 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001658 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001659 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001660 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001661 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001662 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001663 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001664 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001665 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001666 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001667 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001668 return( 128 );
1669 default:
1670 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001671 }
1672}
Gilles Peskinea05219c2018-11-16 16:02:56 +01001673#endif /* MBEDTLS_MD_C */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001674
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001675/* Initialize the MAC operation structure. Once this function has been
1676 * called, psa_mac_abort can run and will do the right thing. */
1677static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1678 psa_algorithm_t alg )
1679{
1680 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1681
1682 operation->alg = alg;
1683 operation->key_set = 0;
1684 operation->iv_set = 0;
1685 operation->iv_required = 0;
1686 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001687 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001688
1689#if defined(MBEDTLS_CMAC_C)
1690 if( alg == PSA_ALG_CMAC )
1691 {
1692 operation->iv_required = 0;
1693 mbedtls_cipher_init( &operation->ctx.cmac );
1694 status = PSA_SUCCESS;
1695 }
1696 else
1697#endif /* MBEDTLS_CMAC_C */
1698#if defined(MBEDTLS_MD_C)
1699 if( PSA_ALG_IS_HMAC( operation->alg ) )
1700 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02001701 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
1702 operation->ctx.hmac.hash_ctx.alg = 0;
1703 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001704 }
1705 else
1706#endif /* MBEDTLS_MD_C */
1707 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001708 if( ! PSA_ALG_IS_MAC( alg ) )
1709 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001710 }
1711
1712 if( status != PSA_SUCCESS )
1713 memset( operation, 0, sizeof( *operation ) );
1714 return( status );
1715}
1716
Gilles Peskine01126fa2018-07-12 17:04:55 +02001717#if defined(MBEDTLS_MD_C)
1718static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
1719{
Gilles Peskine3f108122018-12-07 18:14:53 +01001720 mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001721 return( psa_hash_abort( &hmac->hash_ctx ) );
1722}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01001723
1724static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
1725{
1726 /* Instances of psa_hash_operation_s can be initialized by zeroization. */
1727 memset( hmac, 0, sizeof( *hmac ) );
1728}
Gilles Peskine01126fa2018-07-12 17:04:55 +02001729#endif /* MBEDTLS_MD_C */
1730
Gilles Peskine8c9def32018-02-08 10:02:12 +01001731psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1732{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001733 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001734 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001735 /* The object has (apparently) been initialized but it is not
1736 * in use. It's ok to call abort on such an object, and there's
1737 * nothing to do. */
1738 return( PSA_SUCCESS );
1739 }
1740 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001741#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001742 if( operation->alg == PSA_ALG_CMAC )
1743 {
1744 mbedtls_cipher_free( &operation->ctx.cmac );
1745 }
1746 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001747#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001748#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001749 if( PSA_ALG_IS_HMAC( operation->alg ) )
1750 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001751 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001752 }
1753 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001754#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001755 {
1756 /* Sanity check (shouldn't happen: operation->alg should
1757 * always have been initialized to a valid value). */
1758 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001759 }
Moran Peker41deec42018-04-04 15:43:05 +03001760
Gilles Peskine8c9def32018-02-08 10:02:12 +01001761 operation->alg = 0;
1762 operation->key_set = 0;
1763 operation->iv_set = 0;
1764 operation->iv_required = 0;
1765 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001766 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001767
Gilles Peskine8c9def32018-02-08 10:02:12 +01001768 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001769
1770bad_state:
1771 /* If abort is called on an uninitialized object, we can't trust
1772 * anything. Wipe the object in case it contains confidential data.
1773 * This may result in a memory leak if a pointer gets overwritten,
1774 * but it's too late to do anything about this. */
1775 memset( operation, 0, sizeof( *operation ) );
1776 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001777}
1778
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001779#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02001780static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001781 size_t key_bits,
Gilles Peskine2f060a82018-12-04 17:12:32 +01001782 psa_key_slot_t *slot,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001783 const mbedtls_cipher_info_t *cipher_info )
1784{
1785 int ret;
1786
1787 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001788
1789 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1790 if( ret != 0 )
1791 return( ret );
1792
1793 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1794 slot->data.raw.data,
1795 key_bits );
1796 return( ret );
1797}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001798#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001799
Gilles Peskine248051a2018-06-20 16:09:38 +02001800#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02001801static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
1802 const uint8_t *key,
1803 size_t key_length,
1804 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001805{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001806 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001807 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001808 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001809 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001810 psa_status_t status;
1811
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001812 /* Sanity checks on block_size, to guarantee that there won't be a buffer
1813 * overflow below. This should never trigger if the hash algorithm
1814 * is implemented correctly. */
1815 /* The size checks against the ipad and opad buffers cannot be written
1816 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
1817 * because that triggers -Wlogical-op on GCC 7.3. */
1818 if( block_size > sizeof( ipad ) )
1819 return( PSA_ERROR_NOT_SUPPORTED );
1820 if( block_size > sizeof( hmac->opad ) )
1821 return( PSA_ERROR_NOT_SUPPORTED );
1822 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001823 return( PSA_ERROR_NOT_SUPPORTED );
1824
Gilles Peskined223b522018-06-11 18:12:58 +02001825 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001826 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001827 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001828 if( status != PSA_SUCCESS )
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001829 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001830 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001831 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001832 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001833 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001834 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001835 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001836 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001837 }
Gilles Peskine96889972018-07-12 17:07:03 +02001838 /* A 0-length key is not commonly used in HMAC when used as a MAC,
1839 * but it is permitted. It is common when HMAC is used in HKDF, for
1840 * example. Don't call `memcpy` in the 0-length because `key` could be
1841 * an invalid pointer which would make the behavior undefined. */
1842 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001843 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001844
Gilles Peskined223b522018-06-11 18:12:58 +02001845 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1846 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001847 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001848 ipad[i] ^= 0x36;
1849 memset( ipad + key_length, 0x36, block_size - key_length );
1850
1851 /* Copy the key material from ipad to opad, flipping the requisite bits,
1852 * and filling the rest of opad with the requisite constant. */
1853 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001854 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1855 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001856
Gilles Peskine01126fa2018-07-12 17:04:55 +02001857 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001858 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001859 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001860
Gilles Peskine01126fa2018-07-12 17:04:55 +02001861 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001862
1863cleanup:
Gilles Peskine3f108122018-12-07 18:14:53 +01001864 mbedtls_platform_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001865
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001866 return( status );
1867}
Gilles Peskine248051a2018-06-20 16:09:38 +02001868#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001869
Gilles Peskine89167cb2018-07-08 20:12:23 +02001870static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001871 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001872 psa_algorithm_t alg,
1873 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001874{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001875 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001876 psa_key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001877 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001878 psa_key_usage_t usage =
1879 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskined911eb72018-08-14 15:18:45 +02001880 unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02001881 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001882
Gilles Peskined911eb72018-08-14 15:18:45 +02001883 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001884 if( status != PSA_SUCCESS )
1885 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001886 if( is_sign )
1887 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001888
Gilles Peskinec5487a82018-12-03 18:08:14 +01001889 status = psa_get_key_from_slot( handle, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001890 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001891 goto exit;
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02001892 key_bits = psa_get_key_bits( slot );
1893
Gilles Peskine8c9def32018-02-08 10:02:12 +01001894#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001895 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001896 {
1897 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02001898 mbedtls_cipher_info_from_psa( full_length_alg,
1899 slot->type, key_bits, NULL );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001900 int ret;
1901 if( cipher_info == NULL )
1902 {
1903 status = PSA_ERROR_NOT_SUPPORTED;
1904 goto exit;
1905 }
1906 operation->mac_size = cipher_info->block_size;
1907 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
1908 status = mbedtls_to_psa_error( ret );
1909 }
1910 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001911#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001912#if defined(MBEDTLS_MD_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001913 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001914 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02001915 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001916 if( hash_alg == 0 )
1917 {
1918 status = PSA_ERROR_NOT_SUPPORTED;
1919 goto exit;
1920 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001921
1922 operation->mac_size = PSA_HASH_SIZE( hash_alg );
1923 /* Sanity check. This shouldn't fail on a valid configuration. */
1924 if( operation->mac_size == 0 ||
1925 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
1926 {
1927 status = PSA_ERROR_NOT_SUPPORTED;
1928 goto exit;
1929 }
1930
Gilles Peskine01126fa2018-07-12 17:04:55 +02001931 if( slot->type != PSA_KEY_TYPE_HMAC )
1932 {
1933 status = PSA_ERROR_INVALID_ARGUMENT;
1934 goto exit;
1935 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001936
Gilles Peskine01126fa2018-07-12 17:04:55 +02001937 status = psa_hmac_setup_internal( &operation->ctx.hmac,
1938 slot->data.raw.data,
1939 slot->data.raw.bytes,
1940 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001941 }
1942 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001943#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001944 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00001945 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02001946 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001947 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001948
Gilles Peskined911eb72018-08-14 15:18:45 +02001949 if( truncated == 0 )
1950 {
1951 /* The "normal" case: untruncated algorithm. Nothing to do. */
1952 }
1953 else if( truncated < 4 )
1954 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02001955 /* A very short MAC is too short for security since it can be
1956 * brute-forced. Ancient protocols with 32-bit MACs do exist,
1957 * so we make this our minimum, even though 32 bits is still
1958 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02001959 status = PSA_ERROR_NOT_SUPPORTED;
1960 }
1961 else if( truncated > operation->mac_size )
1962 {
1963 /* It's impossible to "truncate" to a larger length. */
1964 status = PSA_ERROR_INVALID_ARGUMENT;
1965 }
1966 else
1967 operation->mac_size = truncated;
1968
Gilles Peskinefbfac682018-07-08 20:51:54 +02001969exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001970 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001971 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001972 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001973 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001974 else
1975 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001976 operation->key_set = 1;
1977 }
1978 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001979}
1980
Gilles Peskine89167cb2018-07-08 20:12:23 +02001981psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001982 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001983 psa_algorithm_t alg )
1984{
Gilles Peskinec5487a82018-12-03 18:08:14 +01001985 return( psa_mac_setup( operation, handle, alg, 1 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001986}
1987
1988psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001989 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001990 psa_algorithm_t alg )
1991{
Gilles Peskinec5487a82018-12-03 18:08:14 +01001992 return( psa_mac_setup( operation, handle, alg, 0 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001993}
1994
Gilles Peskine8c9def32018-02-08 10:02:12 +01001995psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1996 const uint8_t *input,
1997 size_t input_length )
1998{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001999 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002000 if( ! operation->key_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002001 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002002 if( operation->iv_required && ! operation->iv_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002003 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002004 operation->has_input = 1;
2005
Gilles Peskine8c9def32018-02-08 10:02:12 +01002006#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002007 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03002008 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02002009 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
2010 input, input_length );
2011 status = mbedtls_to_psa_error( ret );
2012 }
2013 else
2014#endif /* MBEDTLS_CMAC_C */
2015#if defined(MBEDTLS_MD_C)
2016 if( PSA_ALG_IS_HMAC( operation->alg ) )
2017 {
2018 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
2019 input_length );
2020 }
2021 else
2022#endif /* MBEDTLS_MD_C */
2023 {
2024 /* This shouldn't happen if `operation` was initialized by
2025 * a setup function. */
2026 status = PSA_ERROR_BAD_STATE;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03002027 }
2028
Gilles Peskinefbfac682018-07-08 20:51:54 +02002029cleanup:
2030 if( status != PSA_SUCCESS )
2031 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002032 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002033}
2034
Gilles Peskine01126fa2018-07-12 17:04:55 +02002035#if defined(MBEDTLS_MD_C)
2036static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
2037 uint8_t *mac,
2038 size_t mac_size )
2039{
2040 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
2041 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
2042 size_t hash_size = 0;
2043 size_t block_size = psa_get_hash_block_size( hash_alg );
2044 psa_status_t status;
2045
Gilles Peskine01126fa2018-07-12 17:04:55 +02002046 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
2047 if( status != PSA_SUCCESS )
2048 return( status );
2049 /* From here on, tmp needs to be wiped. */
2050
2051 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
2052 if( status != PSA_SUCCESS )
2053 goto exit;
2054
2055 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
2056 if( status != PSA_SUCCESS )
2057 goto exit;
2058
2059 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
2060 if( status != PSA_SUCCESS )
2061 goto exit;
2062
Gilles Peskined911eb72018-08-14 15:18:45 +02002063 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
2064 if( status != PSA_SUCCESS )
2065 goto exit;
2066
2067 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002068
2069exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01002070 mbedtls_platform_zeroize( tmp, hash_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002071 return( status );
2072}
2073#endif /* MBEDTLS_MD_C */
2074
mohammad16036df908f2018-04-02 08:34:15 -07002075static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02002076 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002077 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002078{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02002079 if( ! operation->key_set )
2080 return( PSA_ERROR_BAD_STATE );
2081 if( operation->iv_required && ! operation->iv_set )
2082 return( PSA_ERROR_BAD_STATE );
2083
Gilles Peskine8c9def32018-02-08 10:02:12 +01002084 if( mac_size < operation->mac_size )
2085 return( PSA_ERROR_BUFFER_TOO_SMALL );
2086
Gilles Peskine8c9def32018-02-08 10:02:12 +01002087#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002088 if( operation->alg == PSA_ALG_CMAC )
2089 {
Gilles Peskined911eb72018-08-14 15:18:45 +02002090 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
2091 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
2092 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02002093 memcpy( mac, tmp, operation->mac_size );
Gilles Peskine3f108122018-12-07 18:14:53 +01002094 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002095 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002096 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02002097 else
2098#endif /* MBEDTLS_CMAC_C */
2099#if defined(MBEDTLS_MD_C)
2100 if( PSA_ALG_IS_HMAC( operation->alg ) )
2101 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002102 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02002103 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002104 }
2105 else
2106#endif /* MBEDTLS_MD_C */
2107 {
2108 /* This shouldn't happen if `operation` was initialized by
2109 * a setup function. */
2110 return( PSA_ERROR_BAD_STATE );
2111 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01002112}
2113
Gilles Peskineacd4be32018-07-08 19:56:25 +02002114psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
2115 uint8_t *mac,
2116 size_t mac_size,
2117 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07002118{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002119 psa_status_t status;
2120
2121 /* Fill the output buffer with something that isn't a valid mac
2122 * (barring an attack on the mac and deliberately-crafted input),
2123 * in case the caller doesn't check the return status properly. */
2124 *mac_length = mac_size;
2125 /* If mac_size is 0 then mac may be NULL and then the
2126 * call to memset would have undefined behavior. */
2127 if( mac_size != 0 )
2128 memset( mac, '!', mac_size );
2129
Gilles Peskine89167cb2018-07-08 20:12:23 +02002130 if( ! operation->is_sign )
2131 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002132 status = PSA_ERROR_BAD_STATE;
2133 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002134 }
mohammad16036df908f2018-04-02 08:34:15 -07002135
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002136 status = psa_mac_finish_internal( operation, mac, mac_size );
2137
2138cleanup:
2139 if( status == PSA_SUCCESS )
2140 {
2141 status = psa_mac_abort( operation );
2142 if( status == PSA_SUCCESS )
2143 *mac_length = operation->mac_size;
2144 else
2145 memset( mac, '!', mac_size );
2146 }
2147 else
2148 psa_mac_abort( operation );
2149 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07002150}
2151
Gilles Peskineacd4be32018-07-08 19:56:25 +02002152psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
2153 const uint8_t *mac,
2154 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002155{
Gilles Peskine828ed142018-06-18 23:25:51 +02002156 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07002157 psa_status_t status;
2158
Gilles Peskine89167cb2018-07-08 20:12:23 +02002159 if( operation->is_sign )
2160 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002161 status = PSA_ERROR_BAD_STATE;
2162 goto cleanup;
2163 }
2164 if( operation->mac_size != mac_length )
2165 {
2166 status = PSA_ERROR_INVALID_SIGNATURE;
2167 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002168 }
mohammad16036df908f2018-04-02 08:34:15 -07002169
2170 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002171 actual_mac, sizeof( actual_mac ) );
2172
2173 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
2174 status = PSA_ERROR_INVALID_SIGNATURE;
2175
2176cleanup:
2177 if( status == PSA_SUCCESS )
2178 status = psa_mac_abort( operation );
2179 else
2180 psa_mac_abort( operation );
2181
Gilles Peskine3f108122018-12-07 18:14:53 +01002182 mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02002183
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002184 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002185}
2186
2187
Gilles Peskine20035e32018-02-03 22:44:14 +01002188
Gilles Peskine20035e32018-02-03 22:44:14 +01002189/****************************************************************/
2190/* Asymmetric cryptography */
2191/****************************************************************/
2192
Gilles Peskine2b450e32018-06-27 15:42:46 +02002193#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002194/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002195 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002196static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
2197 size_t hash_length,
2198 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002199{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02002200 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002201 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002202 *md_alg = mbedtls_md_get_type( md_info );
2203
2204 /* The Mbed TLS RSA module uses an unsigned int for hash length
2205 * parameters. Validate that it fits so that we don't risk an
2206 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002207#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002208 if( hash_length > UINT_MAX )
2209 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002210#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002211
2212#if defined(MBEDTLS_PKCS1_V15)
2213 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
2214 * must be correct. */
2215 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
2216 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002217 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002218 if( md_info == NULL )
2219 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002220 if( mbedtls_md_get_size( md_info ) != hash_length )
2221 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002222 }
2223#endif /* MBEDTLS_PKCS1_V15 */
2224
2225#if defined(MBEDTLS_PKCS1_V21)
2226 /* PSS requires a hash internally. */
2227 if( PSA_ALG_IS_RSA_PSS( alg ) )
2228 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002229 if( md_info == NULL )
2230 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002231 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002232#endif /* MBEDTLS_PKCS1_V21 */
2233
Gilles Peskine61b91d42018-06-08 16:09:36 +02002234 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002235}
2236
Gilles Peskine2b450e32018-06-27 15:42:46 +02002237static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
2238 psa_algorithm_t alg,
2239 const uint8_t *hash,
2240 size_t hash_length,
2241 uint8_t *signature,
2242 size_t signature_size,
2243 size_t *signature_length )
2244{
2245 psa_status_t status;
2246 int ret;
2247 mbedtls_md_type_t md_alg;
2248
2249 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2250 if( status != PSA_SUCCESS )
2251 return( status );
2252
Gilles Peskine630a18a2018-06-29 17:49:35 +02002253 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002254 return( PSA_ERROR_BUFFER_TOO_SMALL );
2255
2256#if defined(MBEDTLS_PKCS1_V15)
2257 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2258 {
2259 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2260 MBEDTLS_MD_NONE );
2261 ret = mbedtls_rsa_pkcs1_sign( rsa,
2262 mbedtls_ctr_drbg_random,
2263 &global_data.ctr_drbg,
2264 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002265 md_alg,
2266 (unsigned int) hash_length,
2267 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002268 signature );
2269 }
2270 else
2271#endif /* MBEDTLS_PKCS1_V15 */
2272#if defined(MBEDTLS_PKCS1_V21)
2273 if( PSA_ALG_IS_RSA_PSS( alg ) )
2274 {
2275 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2276 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
2277 mbedtls_ctr_drbg_random,
2278 &global_data.ctr_drbg,
2279 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002280 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002281 (unsigned int) hash_length,
2282 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002283 signature );
2284 }
2285 else
2286#endif /* MBEDTLS_PKCS1_V21 */
2287 {
2288 return( PSA_ERROR_INVALID_ARGUMENT );
2289 }
2290
2291 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002292 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002293 return( mbedtls_to_psa_error( ret ) );
2294}
2295
2296static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
2297 psa_algorithm_t alg,
2298 const uint8_t *hash,
2299 size_t hash_length,
2300 const uint8_t *signature,
2301 size_t signature_length )
2302{
2303 psa_status_t status;
2304 int ret;
2305 mbedtls_md_type_t md_alg;
2306
2307 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2308 if( status != PSA_SUCCESS )
2309 return( status );
2310
Gilles Peskine630a18a2018-06-29 17:49:35 +02002311 if( signature_length < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002312 return( PSA_ERROR_BUFFER_TOO_SMALL );
2313
2314#if defined(MBEDTLS_PKCS1_V15)
2315 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2316 {
2317 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2318 MBEDTLS_MD_NONE );
2319 ret = mbedtls_rsa_pkcs1_verify( rsa,
2320 mbedtls_ctr_drbg_random,
2321 &global_data.ctr_drbg,
2322 MBEDTLS_RSA_PUBLIC,
2323 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002324 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002325 hash,
2326 signature );
2327 }
2328 else
2329#endif /* MBEDTLS_PKCS1_V15 */
2330#if defined(MBEDTLS_PKCS1_V21)
2331 if( PSA_ALG_IS_RSA_PSS( alg ) )
2332 {
2333 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2334 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
2335 mbedtls_ctr_drbg_random,
2336 &global_data.ctr_drbg,
2337 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002338 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002339 (unsigned int) hash_length,
2340 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002341 signature );
2342 }
2343 else
2344#endif /* MBEDTLS_PKCS1_V21 */
2345 {
2346 return( PSA_ERROR_INVALID_ARGUMENT );
2347 }
Gilles Peskineef12c632018-09-13 20:37:48 +02002348
2349 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
2350 * the rest of the signature is invalid". This has little use in
2351 * practice and PSA doesn't report this distinction. */
2352 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
2353 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002354 return( mbedtls_to_psa_error( ret ) );
2355}
2356#endif /* MBEDTLS_RSA_C */
2357
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002358#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002359/* `ecp` cannot be const because `ecp->grp` needs to be non-const
2360 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
2361 * (even though these functions don't modify it). */
2362static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
2363 psa_algorithm_t alg,
2364 const uint8_t *hash,
2365 size_t hash_length,
2366 uint8_t *signature,
2367 size_t signature_size,
2368 size_t *signature_length )
2369{
2370 int ret;
2371 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002372 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002373 mbedtls_mpi_init( &r );
2374 mbedtls_mpi_init( &s );
2375
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002376 if( signature_size < 2 * curve_bytes )
2377 {
2378 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
2379 goto cleanup;
2380 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002381
Gilles Peskinea05219c2018-11-16 16:02:56 +01002382#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002383 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
2384 {
2385 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
2386 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2387 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2388 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
2389 hash, hash_length,
2390 md_alg ) );
2391 }
2392 else
Gilles Peskinea05219c2018-11-16 16:02:56 +01002393#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002394 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01002395 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002396 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
2397 hash, hash_length,
2398 mbedtls_ctr_drbg_random,
2399 &global_data.ctr_drbg ) );
2400 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002401
2402 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
2403 signature,
2404 curve_bytes ) );
2405 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
2406 signature + curve_bytes,
2407 curve_bytes ) );
2408
2409cleanup:
2410 mbedtls_mpi_free( &r );
2411 mbedtls_mpi_free( &s );
2412 if( ret == 0 )
2413 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002414 return( mbedtls_to_psa_error( ret ) );
2415}
2416
2417static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
2418 const uint8_t *hash,
2419 size_t hash_length,
2420 const uint8_t *signature,
2421 size_t signature_length )
2422{
2423 int ret;
2424 mbedtls_mpi r, s;
2425 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
2426 mbedtls_mpi_init( &r );
2427 mbedtls_mpi_init( &s );
2428
2429 if( signature_length != 2 * curve_bytes )
2430 return( PSA_ERROR_INVALID_SIGNATURE );
2431
2432 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2433 signature,
2434 curve_bytes ) );
2435 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2436 signature + curve_bytes,
2437 curve_bytes ) );
2438
2439 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2440 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002441
2442cleanup:
2443 mbedtls_mpi_free( &r );
2444 mbedtls_mpi_free( &s );
2445 return( mbedtls_to_psa_error( ret ) );
2446}
2447#endif /* MBEDTLS_ECDSA_C */
2448
Gilles Peskinec5487a82018-12-03 18:08:14 +01002449psa_status_t psa_asymmetric_sign( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002450 psa_algorithm_t alg,
2451 const uint8_t *hash,
2452 size_t hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002453 uint8_t *signature,
2454 size_t signature_size,
2455 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002456{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002457 psa_key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002458 psa_status_t status;
2459
2460 *signature_length = signature_size;
2461
Gilles Peskinec5487a82018-12-03 18:08:14 +01002462 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002463 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002464 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002465 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002466 {
2467 status = PSA_ERROR_INVALID_ARGUMENT;
2468 goto exit;
2469 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002470
Gilles Peskine20035e32018-02-03 22:44:14 +01002471#if defined(MBEDTLS_RSA_C)
2472 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2473 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002474 status = psa_rsa_sign( slot->data.rsa,
2475 alg,
2476 hash, hash_length,
2477 signature, signature_size,
2478 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002479 }
2480 else
2481#endif /* defined(MBEDTLS_RSA_C) */
2482#if defined(MBEDTLS_ECP_C)
2483 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2484 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002485#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea05219c2018-11-16 16:02:56 +01002486 if(
2487#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
2488 PSA_ALG_IS_ECDSA( alg )
2489#else
2490 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
2491#endif
2492 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002493 status = psa_ecdsa_sign( slot->data.ecp,
2494 alg,
2495 hash, hash_length,
2496 signature, signature_size,
2497 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002498 else
2499#endif /* defined(MBEDTLS_ECDSA_C) */
2500 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002501 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002502 }
itayzafrir5c753392018-05-08 11:18:38 +03002503 }
2504 else
2505#endif /* defined(MBEDTLS_ECP_C) */
2506 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002507 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002508 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002509
2510exit:
2511 /* Fill the unused part of the output buffer (the whole buffer on error,
2512 * the trailing part on success) with something that isn't a valid mac
2513 * (barring an attack on the mac and deliberately-crafted input),
2514 * in case the caller doesn't check the return status properly. */
2515 if( status == PSA_SUCCESS )
2516 memset( signature + *signature_length, '!',
2517 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002518 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002519 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002520 /* If signature_size is 0 then we have nothing to do. We must not call
2521 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002522 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002523}
2524
Gilles Peskinec5487a82018-12-03 18:08:14 +01002525psa_status_t psa_asymmetric_verify( psa_key_handle_t handle,
itayzafrir5c753392018-05-08 11:18:38 +03002526 psa_algorithm_t alg,
2527 const uint8_t *hash,
2528 size_t hash_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002529 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002530 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002531{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002532 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002533 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002534
Gilles Peskinec5487a82018-12-03 18:08:14 +01002535 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002536 if( status != PSA_SUCCESS )
2537 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002538
Gilles Peskine61b91d42018-06-08 16:09:36 +02002539#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002540 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002541 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002542 return( psa_rsa_verify( slot->data.rsa,
2543 alg,
2544 hash, hash_length,
2545 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002546 }
2547 else
2548#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002549#if defined(MBEDTLS_ECP_C)
2550 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2551 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002552#if defined(MBEDTLS_ECDSA_C)
2553 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002554 return( psa_ecdsa_verify( slot->data.ecp,
2555 hash, hash_length,
2556 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002557 else
2558#endif /* defined(MBEDTLS_ECDSA_C) */
2559 {
2560 return( PSA_ERROR_INVALID_ARGUMENT );
2561 }
itayzafrir5c753392018-05-08 11:18:38 +03002562 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002563 else
2564#endif /* defined(MBEDTLS_ECP_C) */
2565 {
2566 return( PSA_ERROR_NOT_SUPPORTED );
2567 }
2568}
2569
Gilles Peskine072ac562018-06-30 00:21:29 +02002570#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
2571static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
2572 mbedtls_rsa_context *rsa )
2573{
2574 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
2575 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2576 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2577 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2578}
2579#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
2580
Gilles Peskinec5487a82018-12-03 18:08:14 +01002581psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002582 psa_algorithm_t alg,
2583 const uint8_t *input,
2584 size_t input_length,
2585 const uint8_t *salt,
2586 size_t salt_length,
2587 uint8_t *output,
2588 size_t output_size,
2589 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002590{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002591 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002592 psa_status_t status;
2593
Darryl Green5cc689a2018-07-24 15:34:10 +01002594 (void) input;
2595 (void) input_length;
2596 (void) salt;
2597 (void) output;
2598 (void) output_size;
2599
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002600 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002601
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002602 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2603 return( PSA_ERROR_INVALID_ARGUMENT );
2604
Gilles Peskinec5487a82018-12-03 18:08:14 +01002605 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002606 if( status != PSA_SUCCESS )
2607 return( status );
Gilles Peskine35da9a22018-06-29 19:17:49 +02002608 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
2609 PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002610 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002611
2612#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002613 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002614 {
2615 mbedtls_rsa_context *rsa = slot->data.rsa;
2616 int ret;
Gilles Peskine630a18a2018-06-29 17:49:35 +02002617 if( output_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002618 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002619#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002620 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002621 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002622 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2623 mbedtls_ctr_drbg_random,
2624 &global_data.ctr_drbg,
2625 MBEDTLS_RSA_PUBLIC,
2626 input_length,
2627 input,
2628 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002629 }
2630 else
2631#endif /* MBEDTLS_PKCS1_V15 */
2632#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002633 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002634 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002635 psa_rsa_oaep_set_padding_mode( alg, rsa );
2636 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
2637 mbedtls_ctr_drbg_random,
2638 &global_data.ctr_drbg,
2639 MBEDTLS_RSA_PUBLIC,
2640 salt, salt_length,
2641 input_length,
2642 input,
2643 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002644 }
2645 else
2646#endif /* MBEDTLS_PKCS1_V21 */
2647 {
2648 return( PSA_ERROR_INVALID_ARGUMENT );
2649 }
2650 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002651 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002652 return( mbedtls_to_psa_error( ret ) );
2653 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002654 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002655#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002656 {
2657 return( PSA_ERROR_NOT_SUPPORTED );
2658 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002659}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002660
Gilles Peskinec5487a82018-12-03 18:08:14 +01002661psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002662 psa_algorithm_t alg,
2663 const uint8_t *input,
2664 size_t input_length,
2665 const uint8_t *salt,
2666 size_t salt_length,
2667 uint8_t *output,
2668 size_t output_size,
2669 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002670{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002671 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002672 psa_status_t status;
2673
Darryl Green5cc689a2018-07-24 15:34:10 +01002674 (void) input;
2675 (void) input_length;
2676 (void) salt;
2677 (void) output;
2678 (void) output_size;
2679
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002680 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002681
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002682 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2683 return( PSA_ERROR_INVALID_ARGUMENT );
2684
Gilles Peskinec5487a82018-12-03 18:08:14 +01002685 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002686 if( status != PSA_SUCCESS )
2687 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002688 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2689 return( PSA_ERROR_INVALID_ARGUMENT );
2690
2691#if defined(MBEDTLS_RSA_C)
2692 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2693 {
2694 mbedtls_rsa_context *rsa = slot->data.rsa;
2695 int ret;
2696
Gilles Peskine630a18a2018-06-29 17:49:35 +02002697 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002698 return( PSA_ERROR_INVALID_ARGUMENT );
2699
2700#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002701 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002702 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002703 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2704 mbedtls_ctr_drbg_random,
2705 &global_data.ctr_drbg,
2706 MBEDTLS_RSA_PRIVATE,
2707 output_length,
2708 input,
2709 output,
2710 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002711 }
2712 else
2713#endif /* MBEDTLS_PKCS1_V15 */
2714#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002715 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002716 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002717 psa_rsa_oaep_set_padding_mode( alg, rsa );
2718 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
2719 mbedtls_ctr_drbg_random,
2720 &global_data.ctr_drbg,
2721 MBEDTLS_RSA_PRIVATE,
2722 salt, salt_length,
2723 output_length,
2724 input,
2725 output,
2726 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002727 }
2728 else
2729#endif /* MBEDTLS_PKCS1_V21 */
2730 {
2731 return( PSA_ERROR_INVALID_ARGUMENT );
2732 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002733
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002734 return( mbedtls_to_psa_error( ret ) );
2735 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002736 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002737#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002738 {
2739 return( PSA_ERROR_NOT_SUPPORTED );
2740 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002741}
Gilles Peskine20035e32018-02-03 22:44:14 +01002742
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002743
2744
mohammad1603503973b2018-03-12 15:59:30 +02002745/****************************************************************/
2746/* Symmetric cryptography */
2747/****************************************************************/
2748
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002749/* Initialize the cipher operation structure. Once this function has been
2750 * called, psa_cipher_abort can run and will do the right thing. */
2751static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2752 psa_algorithm_t alg )
2753{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002754 if( ! PSA_ALG_IS_CIPHER( alg ) )
2755 {
2756 memset( operation, 0, sizeof( *operation ) );
2757 return( PSA_ERROR_INVALID_ARGUMENT );
2758 }
2759
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002760 operation->alg = alg;
2761 operation->key_set = 0;
2762 operation->iv_set = 0;
2763 operation->iv_required = 1;
2764 operation->iv_size = 0;
2765 operation->block_size = 0;
2766 mbedtls_cipher_init( &operation->ctx.cipher );
2767 return( PSA_SUCCESS );
2768}
2769
Gilles Peskinee553c652018-06-04 16:22:46 +02002770static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002771 psa_key_handle_t handle,
Gilles Peskine7e928852018-06-04 16:23:10 +02002772 psa_algorithm_t alg,
2773 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002774{
2775 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2776 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +01002777 psa_key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02002778 size_t key_bits;
2779 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002780 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
2781 PSA_KEY_USAGE_ENCRYPT :
2782 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02002783
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002784 status = psa_cipher_init( operation, alg );
2785 if( status != PSA_SUCCESS )
2786 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002787
Gilles Peskinec5487a82018-12-03 18:08:14 +01002788 status = psa_get_key_from_slot( handle, &slot, usage, alg);
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002789 if( status != PSA_SUCCESS )
2790 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002791 key_bits = psa_get_key_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02002792
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002793 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002794 if( cipher_info == NULL )
2795 return( PSA_ERROR_NOT_SUPPORTED );
2796
mohammad1603503973b2018-03-12 15:59:30 +02002797 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002798 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002799 {
2800 psa_cipher_abort( operation );
2801 return( mbedtls_to_psa_error( ret ) );
2802 }
2803
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002804#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002805 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002806 {
2807 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2808 unsigned char keys[24];
2809 memcpy( keys, slot->data.raw.data, 16 );
2810 memcpy( keys + 16, slot->data.raw.data, 8 );
2811 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2812 keys,
2813 192, cipher_operation );
2814 }
2815 else
2816#endif
2817 {
2818 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2819 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002820 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002821 }
Moran Peker41deec42018-04-04 15:43:05 +03002822 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002823 {
2824 psa_cipher_abort( operation );
2825 return( mbedtls_to_psa_error( ret ) );
2826 }
2827
mohammad16038481e742018-03-18 13:57:31 +02002828#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002829 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02002830 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002831 case PSA_ALG_CBC_NO_PADDING:
2832 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2833 MBEDTLS_PADDING_NONE );
2834 break;
2835 case PSA_ALG_CBC_PKCS7:
2836 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2837 MBEDTLS_PADDING_PKCS7 );
2838 break;
2839 default:
2840 /* The algorithm doesn't involve padding. */
2841 ret = 0;
2842 break;
2843 }
2844 if( ret != 0 )
2845 {
2846 psa_cipher_abort( operation );
2847 return( mbedtls_to_psa_error( ret ) );
mohammad16038481e742018-03-18 13:57:31 +02002848 }
2849#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2850
mohammad1603503973b2018-03-12 15:59:30 +02002851 operation->key_set = 1;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002852 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
2853 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
2854 if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
mohammad16038481e742018-03-18 13:57:31 +02002855 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002856 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02002857 }
mohammad1603503973b2018-03-12 15:59:30 +02002858
Moran Peker395db872018-05-31 14:07:14 +03002859 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002860}
2861
Gilles Peskinefe119512018-07-08 21:39:34 +02002862psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002863 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02002864 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002865{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002866 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002867}
2868
Gilles Peskinefe119512018-07-08 21:39:34 +02002869psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002870 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02002871 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002872{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002873 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002874}
2875
Gilles Peskinefe119512018-07-08 21:39:34 +02002876psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
2877 unsigned char *iv,
2878 size_t iv_size,
2879 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002880{
itayzafrir534bd7c2018-08-02 13:56:32 +03002881 psa_status_t status;
2882 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002883 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002884 {
2885 status = PSA_ERROR_BAD_STATE;
2886 goto exit;
2887 }
Moran Peker41deec42018-04-04 15:43:05 +03002888 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002889 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002890 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03002891 goto exit;
2892 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002893 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2894 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002895 if( ret != 0 )
2896 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002897 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002898 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002899 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002900
mohammad16038481e742018-03-18 13:57:31 +02002901 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03002902 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002903
Moran Peker395db872018-05-31 14:07:14 +03002904exit:
itayzafrir534bd7c2018-08-02 13:56:32 +03002905 if( status != PSA_SUCCESS )
Moran Peker395db872018-05-31 14:07:14 +03002906 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002907 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002908}
2909
Gilles Peskinefe119512018-07-08 21:39:34 +02002910psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
2911 const unsigned char *iv,
2912 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002913{
itayzafrir534bd7c2018-08-02 13:56:32 +03002914 psa_status_t status;
2915 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002916 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002917 {
2918 status = PSA_ERROR_BAD_STATE;
2919 goto exit;
2920 }
Moran Pekera28258c2018-05-29 16:25:04 +03002921 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002922 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002923 status = PSA_ERROR_INVALID_ARGUMENT;
2924 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03002925 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002926 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
2927 status = mbedtls_to_psa_error( ret );
2928exit:
2929 if( status == PSA_SUCCESS )
2930 operation->iv_set = 1;
2931 else
mohammad1603503973b2018-03-12 15:59:30 +02002932 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002933 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002934}
2935
Gilles Peskinee553c652018-06-04 16:22:46 +02002936psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2937 const uint8_t *input,
2938 size_t input_length,
2939 unsigned char *output,
2940 size_t output_size,
2941 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002942{
itayzafrir534bd7c2018-08-02 13:56:32 +03002943 psa_status_t status;
2944 int ret;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002945 size_t expected_output_size;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002946 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002947 {
2948 /* Take the unprocessed partial block left over from previous
2949 * update calls, if any, plus the input to this call. Remove
2950 * the last partial block, if any. You get the data that will be
2951 * output in this call. */
2952 expected_output_size =
2953 ( operation->ctx.cipher.unprocessed_len + input_length )
2954 / operation->block_size * operation->block_size;
2955 }
2956 else
2957 {
2958 expected_output_size = input_length;
2959 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002960
Gilles Peskine89d789c2018-06-04 17:17:16 +02002961 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03002962 {
2963 status = PSA_ERROR_BUFFER_TOO_SMALL;
2964 goto exit;
2965 }
mohammad160382759612018-03-12 18:16:40 +02002966
mohammad1603503973b2018-03-12 15:59:30 +02002967 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002968 input_length, output, output_length );
itayzafrir534bd7c2018-08-02 13:56:32 +03002969 status = mbedtls_to_psa_error( ret );
2970exit:
2971 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02002972 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002973 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002974}
2975
Gilles Peskinee553c652018-06-04 16:22:46 +02002976psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2977 uint8_t *output,
2978 size_t output_size,
2979 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002980{
Janos Follath315b51c2018-07-09 16:04:51 +01002981 psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
2982 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002983 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002984
mohammad1603503973b2018-03-12 15:59:30 +02002985 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002986 {
Janos Follath315b51c2018-07-09 16:04:51 +01002987 status = PSA_ERROR_BAD_STATE;
2988 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002989 }
2990 if( operation->iv_required && ! operation->iv_set )
2991 {
Janos Follath315b51c2018-07-09 16:04:51 +01002992 status = PSA_ERROR_BAD_STATE;
2993 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002994 }
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002995
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002996 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002997 operation->alg == PSA_ALG_CBC_NO_PADDING &&
2998 operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03002999 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003000 status = PSA_ERROR_INVALID_ARGUMENT;
Janos Follath315b51c2018-07-09 16:04:51 +01003001 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03003002 }
3003
Janos Follath315b51c2018-07-09 16:04:51 +01003004 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
3005 temp_output_buffer,
3006 output_length );
3007 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02003008 {
Janos Follath315b51c2018-07-09 16:04:51 +01003009 status = mbedtls_to_psa_error( cipher_ret );
3010 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02003011 }
Janos Follath315b51c2018-07-09 16:04:51 +01003012
Gilles Peskine46f1fd72018-06-28 19:31:31 +02003013 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01003014 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02003015 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03003016 memcpy( output, temp_output_buffer, *output_length );
3017 else
3018 {
Janos Follath315b51c2018-07-09 16:04:51 +01003019 status = PSA_ERROR_BUFFER_TOO_SMALL;
3020 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03003021 }
mohammad1603503973b2018-03-12 15:59:30 +02003022
Gilles Peskine3f108122018-12-07 18:14:53 +01003023 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01003024 status = psa_cipher_abort( operation );
3025
3026 return( status );
3027
3028error:
3029
3030 *output_length = 0;
3031
Gilles Peskine3f108122018-12-07 18:14:53 +01003032 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01003033 (void) psa_cipher_abort( operation );
3034
3035 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003036}
3037
Gilles Peskinee553c652018-06-04 16:22:46 +02003038psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
3039{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003040 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02003041 {
3042 /* The object has (apparently) been initialized but it is not
3043 * in use. It's ok to call abort on such an object, and there's
3044 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003045 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02003046 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003047
Gilles Peskinef9c2c092018-06-21 16:57:07 +02003048 /* Sanity check (shouldn't happen: operation->alg should
3049 * always have been initialized to a valid value). */
3050 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
3051 return( PSA_ERROR_BAD_STATE );
3052
mohammad1603503973b2018-03-12 15:59:30 +02003053 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02003054
Moran Peker41deec42018-04-04 15:43:05 +03003055 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03003056 operation->key_set = 0;
3057 operation->iv_set = 0;
3058 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03003059 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03003060 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03003061
Moran Peker395db872018-05-31 14:07:14 +03003062 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02003063}
3064
Gilles Peskinea0655c32018-04-30 17:06:50 +02003065
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003066
mohammad16038cc1cee2018-03-28 01:21:33 +03003067/****************************************************************/
3068/* Key Policy */
3069/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003070
mohammad160327010052018-07-03 13:16:15 +03003071#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02003072void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003073{
Gilles Peskine803ce742018-06-18 16:07:14 +02003074 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03003075}
3076
Gilles Peskine2d277862018-06-18 15:41:12 +02003077void psa_key_policy_set_usage( psa_key_policy_t *policy,
3078 psa_key_usage_t usage,
3079 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03003080{
mohammad16034eed7572018-03-28 05:14:59 -07003081 policy->usage = usage;
3082 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03003083}
3084
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003085psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003086{
mohammad16036df908f2018-04-02 08:34:15 -07003087 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03003088}
3089
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003090psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003091{
mohammad16036df908f2018-04-02 08:34:15 -07003092 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03003093}
mohammad160327010052018-07-03 13:16:15 +03003094#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003095
Gilles Peskinec5487a82018-12-03 18:08:14 +01003096psa_status_t psa_set_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003097 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003098{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003099 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003100 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003101
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003102 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003103 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003104
Gilles Peskinec5487a82018-12-03 18:08:14 +01003105 status = psa_get_empty_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003106 if( status != PSA_SUCCESS )
3107 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03003108
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003109 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
3110 PSA_KEY_USAGE_ENCRYPT |
3111 PSA_KEY_USAGE_DECRYPT |
3112 PSA_KEY_USAGE_SIGN |
Gilles Peskineea0fb492018-07-12 17:17:20 +02003113 PSA_KEY_USAGE_VERIFY |
3114 PSA_KEY_USAGE_DERIVE ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07003115 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03003116
mohammad16036df908f2018-04-02 08:34:15 -07003117 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003118
3119 return( PSA_SUCCESS );
3120}
3121
Gilles Peskinec5487a82018-12-03 18:08:14 +01003122psa_status_t psa_get_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003123 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003124{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003125 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003126 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003127
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003128 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003129 return( PSA_ERROR_INVALID_ARGUMENT );
3130
Gilles Peskinec5487a82018-12-03 18:08:14 +01003131 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003132 if( status != PSA_SUCCESS )
3133 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003134
mohammad16036df908f2018-04-02 08:34:15 -07003135 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003136
3137 return( PSA_SUCCESS );
3138}
Gilles Peskine20035e32018-02-03 22:44:14 +01003139
Gilles Peskinea0655c32018-04-30 17:06:50 +02003140
3141
mohammad1603804cd712018-03-20 22:44:08 +02003142/****************************************************************/
3143/* Key Lifetime */
3144/****************************************************************/
3145
Gilles Peskinec5487a82018-12-03 18:08:14 +01003146psa_status_t psa_get_key_lifetime( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003147 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003148{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003149 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003150 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003151
Gilles Peskinec5487a82018-12-03 18:08:14 +01003152 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003153 if( status != PSA_SUCCESS )
3154 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003155
mohammad1603804cd712018-03-20 22:44:08 +02003156 *lifetime = slot->lifetime;
3157
3158 return( PSA_SUCCESS );
3159}
3160
Gilles Peskine20035e32018-02-03 22:44:14 +01003161
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003162
mohammad16035955c982018-04-26 00:53:03 +03003163/****************************************************************/
3164/* AEAD */
3165/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003166
Gilles Peskineedf9a652018-08-17 18:11:56 +02003167typedef struct
3168{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003169 psa_key_slot_t *slot;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003170 const mbedtls_cipher_info_t *cipher_info;
3171 union
3172 {
3173#if defined(MBEDTLS_CCM_C)
3174 mbedtls_ccm_context ccm;
3175#endif /* MBEDTLS_CCM_C */
3176#if defined(MBEDTLS_GCM_C)
3177 mbedtls_gcm_context gcm;
3178#endif /* MBEDTLS_GCM_C */
3179 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003180 psa_algorithm_t core_alg;
3181 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003182 uint8_t tag_length;
3183} aead_operation_t;
3184
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003185static void psa_aead_abort( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003186{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003187 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003188 {
3189#if defined(MBEDTLS_CCM_C)
3190 case PSA_ALG_CCM:
3191 mbedtls_ccm_free( &operation->ctx.ccm );
3192 break;
3193#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003194#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02003195 case PSA_ALG_GCM:
3196 mbedtls_gcm_free( &operation->ctx.gcm );
3197 break;
3198#endif /* MBEDTLS_GCM_C */
3199 }
3200}
3201
3202static psa_status_t psa_aead_setup( aead_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003203 psa_key_handle_t handle,
Gilles Peskineedf9a652018-08-17 18:11:56 +02003204 psa_key_usage_t usage,
3205 psa_algorithm_t alg )
3206{
3207 psa_status_t status;
3208 size_t key_bits;
3209 mbedtls_cipher_id_t cipher_id;
3210
Gilles Peskinec5487a82018-12-03 18:08:14 +01003211 status = psa_get_key_from_slot( handle, &operation->slot, usage, alg );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003212 if( status != PSA_SUCCESS )
3213 return( status );
3214
3215 key_bits = psa_get_key_bits( operation->slot );
3216
3217 operation->cipher_info =
3218 mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
3219 &cipher_id );
3220 if( operation->cipher_info == NULL )
3221 return( PSA_ERROR_NOT_SUPPORTED );
3222
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003223 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003224 {
3225#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003226 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
3227 operation->core_alg = PSA_ALG_CCM;
3228 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003229 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3230 return( PSA_ERROR_INVALID_ARGUMENT );
3231 mbedtls_ccm_init( &operation->ctx.ccm );
3232 status = mbedtls_to_psa_error(
3233 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
3234 operation->slot->data.raw.data,
3235 (unsigned int) key_bits ) );
3236 if( status != 0 )
3237 goto cleanup;
3238 break;
3239#endif /* MBEDTLS_CCM_C */
3240
3241#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003242 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
3243 operation->core_alg = PSA_ALG_GCM;
3244 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003245 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3246 return( PSA_ERROR_INVALID_ARGUMENT );
3247 mbedtls_gcm_init( &operation->ctx.gcm );
3248 status = mbedtls_to_psa_error(
3249 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
3250 operation->slot->data.raw.data,
3251 (unsigned int) key_bits ) );
3252 break;
3253#endif /* MBEDTLS_GCM_C */
3254
3255 default:
3256 return( PSA_ERROR_NOT_SUPPORTED );
3257 }
3258
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003259 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
3260 {
3261 status = PSA_ERROR_INVALID_ARGUMENT;
3262 goto cleanup;
3263 }
3264 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
3265 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
3266 * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
3267 * In both cases, mbedtls_xxx will validate the tag length below. */
3268
Gilles Peskineedf9a652018-08-17 18:11:56 +02003269 return( PSA_SUCCESS );
3270
3271cleanup:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003272 psa_aead_abort( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003273 return( status );
3274}
3275
Gilles Peskinec5487a82018-12-03 18:08:14 +01003276psa_status_t psa_aead_encrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003277 psa_algorithm_t alg,
3278 const uint8_t *nonce,
3279 size_t nonce_length,
3280 const uint8_t *additional_data,
3281 size_t additional_data_length,
3282 const uint8_t *plaintext,
3283 size_t plaintext_length,
3284 uint8_t *ciphertext,
3285 size_t ciphertext_size,
3286 size_t *ciphertext_length )
3287{
mohammad16035955c982018-04-26 00:53:03 +03003288 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003289 aead_operation_t operation;
mohammad160315223a82018-06-03 17:19:55 +03003290 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02003291
mohammad1603f08a5502018-06-03 15:05:47 +03003292 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07003293
Gilles Peskinec5487a82018-12-03 18:08:14 +01003294 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003295 if( status != PSA_SUCCESS )
3296 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003297
Gilles Peskineedf9a652018-08-17 18:11:56 +02003298 /* For all currently supported modes, the tag is at the end of the
3299 * ciphertext. */
3300 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
3301 {
3302 status = PSA_ERROR_BUFFER_TOO_SMALL;
3303 goto exit;
3304 }
3305 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03003306
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003307#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003308 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003309 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003310 status = mbedtls_to_psa_error(
3311 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
3312 MBEDTLS_GCM_ENCRYPT,
3313 plaintext_length,
3314 nonce, nonce_length,
3315 additional_data, additional_data_length,
3316 plaintext, ciphertext,
3317 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03003318 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003319 else
3320#endif /* MBEDTLS_GCM_C */
3321#if defined(MBEDTLS_CCM_C)
3322 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003323 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003324 status = mbedtls_to_psa_error(
3325 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
3326 plaintext_length,
3327 nonce, nonce_length,
3328 additional_data,
3329 additional_data_length,
3330 plaintext, ciphertext,
3331 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003332 }
mohammad16035c8845f2018-05-09 05:40:09 -07003333 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003334#endif /* MBEDTLS_CCM_C */
mohammad16035c8845f2018-05-09 05:40:09 -07003335 {
mohammad1603554faad2018-06-03 15:07:38 +03003336 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07003337 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003338
Gilles Peskineedf9a652018-08-17 18:11:56 +02003339 if( status != PSA_SUCCESS && ciphertext_size != 0 )
3340 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003341
Gilles Peskineedf9a652018-08-17 18:11:56 +02003342exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003343 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003344 if( status == PSA_SUCCESS )
3345 *ciphertext_length = plaintext_length + operation.tag_length;
3346 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003347}
3348
Gilles Peskineee652a32018-06-01 19:23:52 +02003349/* Locate the tag in a ciphertext buffer containing the encrypted data
3350 * followed by the tag. Return the length of the part preceding the tag in
3351 * *plaintext_length. This is the size of the plaintext in modes where
3352 * the encrypted data has the same size as the plaintext, such as
3353 * CCM and GCM. */
3354static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
3355 const uint8_t *ciphertext,
3356 size_t ciphertext_length,
3357 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02003358 const uint8_t **p_tag )
3359{
3360 size_t payload_length;
3361 if( tag_length > ciphertext_length )
3362 return( PSA_ERROR_INVALID_ARGUMENT );
3363 payload_length = ciphertext_length - tag_length;
3364 if( payload_length > plaintext_size )
3365 return( PSA_ERROR_BUFFER_TOO_SMALL );
3366 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02003367 return( PSA_SUCCESS );
3368}
3369
Gilles Peskinec5487a82018-12-03 18:08:14 +01003370psa_status_t psa_aead_decrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003371 psa_algorithm_t alg,
3372 const uint8_t *nonce,
3373 size_t nonce_length,
3374 const uint8_t *additional_data,
3375 size_t additional_data_length,
3376 const uint8_t *ciphertext,
3377 size_t ciphertext_length,
3378 uint8_t *plaintext,
3379 size_t plaintext_size,
3380 size_t *plaintext_length )
3381{
mohammad16035955c982018-04-26 00:53:03 +03003382 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003383 aead_operation_t operation;
3384 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02003385
Gilles Peskineee652a32018-06-01 19:23:52 +02003386 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03003387
Gilles Peskinec5487a82018-12-03 18:08:14 +01003388 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003389 if( status != PSA_SUCCESS )
3390 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003391
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003392#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003393 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003394 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003395 status = psa_aead_unpadded_locate_tag( operation.tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003396 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003397 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02003398 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003399 goto exit;
Gilles Peskineee652a32018-06-01 19:23:52 +02003400
Gilles Peskineedf9a652018-08-17 18:11:56 +02003401 status = mbedtls_to_psa_error(
3402 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
3403 ciphertext_length - operation.tag_length,
3404 nonce, nonce_length,
3405 additional_data,
3406 additional_data_length,
3407 tag, operation.tag_length,
3408 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03003409 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003410 else
3411#endif /* MBEDTLS_GCM_C */
3412#if defined(MBEDTLS_CCM_C)
3413 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003414 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003415 status = psa_aead_unpadded_locate_tag( operation.tag_length,
mohammad16039375f842018-06-03 14:28:24 +03003416 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003417 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03003418 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003419 goto exit;
mohammad16039375f842018-06-03 14:28:24 +03003420
Gilles Peskineedf9a652018-08-17 18:11:56 +02003421 status = mbedtls_to_psa_error(
3422 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
3423 ciphertext_length - operation.tag_length,
3424 nonce, nonce_length,
3425 additional_data,
3426 additional_data_length,
3427 ciphertext, plaintext,
3428 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003429 }
mohammad160339574652018-06-01 04:39:53 -07003430 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003431#endif /* MBEDTLS_CCM_C */
mohammad160339574652018-06-01 04:39:53 -07003432 {
mohammad1603554faad2018-06-03 15:07:38 +03003433 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07003434 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02003435
Gilles Peskineedf9a652018-08-17 18:11:56 +02003436 if( status != PSA_SUCCESS && plaintext_size != 0 )
3437 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03003438
Gilles Peskineedf9a652018-08-17 18:11:56 +02003439exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003440 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003441 if( status == PSA_SUCCESS )
3442 *plaintext_length = ciphertext_length - operation.tag_length;
3443 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003444}
3445
Gilles Peskinea0655c32018-04-30 17:06:50 +02003446
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003447
Gilles Peskine20035e32018-02-03 22:44:14 +01003448/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003449/* Generators */
3450/****************************************************************/
3451
3452psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
3453{
3454 psa_status_t status = PSA_SUCCESS;
3455 if( generator->alg == 0 )
3456 {
3457 /* The object has (apparently) been initialized but it is not
3458 * in use. It's ok to call abort on such an object, and there's
3459 * nothing to do. */
3460 }
3461 else
Gilles Peskine751d9652018-09-18 12:05:44 +02003462 if( generator->alg == PSA_ALG_SELECT_RAW )
3463 {
3464 if( generator->ctx.buffer.data != NULL )
3465 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003466 mbedtls_platform_zeroize( generator->ctx.buffer.data,
Gilles Peskine751d9652018-09-18 12:05:44 +02003467 generator->ctx.buffer.size );
3468 mbedtls_free( generator->ctx.buffer.data );
3469 }
3470 }
3471 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003472#if defined(MBEDTLS_MD_C)
3473 if( PSA_ALG_IS_HKDF( generator->alg ) )
3474 {
3475 mbedtls_free( generator->ctx.hkdf.info );
3476 status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
3477 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003478 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3479 /* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
3480 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003481 {
3482 if( generator->ctx.tls12_prf.key != NULL )
3483 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003484 mbedtls_platform_zeroize( generator->ctx.tls12_prf.key,
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003485 generator->ctx.tls12_prf.key_len );
3486 mbedtls_free( generator->ctx.tls12_prf.key );
3487 }
Hanno Becker580fba12018-11-13 20:50:45 +00003488
3489 if( generator->ctx.tls12_prf.Ai_with_seed != NULL )
3490 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003491 mbedtls_platform_zeroize( generator->ctx.tls12_prf.Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003492 generator->ctx.tls12_prf.Ai_with_seed_len );
3493 mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed );
3494 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003495 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003496 else
3497#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003498 {
3499 status = PSA_ERROR_BAD_STATE;
3500 }
3501 memset( generator, 0, sizeof( *generator ) );
3502 return( status );
3503}
3504
3505
3506psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3507 size_t *capacity)
3508{
3509 *capacity = generator->capacity;
3510 return( PSA_SUCCESS );
3511}
3512
Gilles Peskinebef7f142018-07-12 17:22:21 +02003513#if defined(MBEDTLS_MD_C)
3514/* Read some bytes from an HKDF-based generator. This performs a chunk
3515 * of the expand phase of the HKDF algorithm. */
3516static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
3517 psa_algorithm_t hash_alg,
3518 uint8_t *output,
3519 size_t output_length )
3520{
3521 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3522 psa_status_t status;
3523
3524 while( output_length != 0 )
3525 {
3526 /* Copy what remains of the current block */
3527 uint8_t n = hash_length - hkdf->offset_in_block;
3528 if( n > output_length )
3529 n = (uint8_t) output_length;
3530 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
3531 output += n;
3532 output_length -= n;
3533 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02003534 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003535 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003536 /* We can't be wanting more output after block 0xff, otherwise
3537 * the capacity check in psa_generator_read() would have
3538 * prevented this call. It could happen only if the generator
3539 * object was corrupted or if this function is called directly
3540 * inside the library. */
3541 if( hkdf->block_number == 0xff )
3542 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003543
3544 /* We need a new block */
3545 ++hkdf->block_number;
3546 hkdf->offset_in_block = 0;
3547 status = psa_hmac_setup_internal( &hkdf->hmac,
3548 hkdf->prk, hash_length,
3549 hash_alg );
3550 if( status != PSA_SUCCESS )
3551 return( status );
3552 if( hkdf->block_number != 1 )
3553 {
3554 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3555 hkdf->output_block,
3556 hash_length );
3557 if( status != PSA_SUCCESS )
3558 return( status );
3559 }
3560 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3561 hkdf->info,
3562 hkdf->info_length );
3563 if( status != PSA_SUCCESS )
3564 return( status );
3565 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3566 &hkdf->block_number, 1 );
3567 if( status != PSA_SUCCESS )
3568 return( status );
3569 status = psa_hmac_finish_internal( &hkdf->hmac,
3570 hkdf->output_block,
3571 sizeof( hkdf->output_block ) );
3572 if( status != PSA_SUCCESS )
3573 return( status );
3574 }
3575
3576 return( PSA_SUCCESS );
3577}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003578
3579static psa_status_t psa_generator_tls12_prf_generate_next_block(
3580 psa_tls12_prf_generator_t *tls12_prf,
3581 psa_algorithm_t alg )
3582{
3583 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3584 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3585 psa_hmac_internal_data hmac;
3586 psa_status_t status, cleanup_status;
3587
Hanno Becker3b339e22018-11-13 20:56:14 +00003588 unsigned char *Ai;
3589 size_t Ai_len;
3590
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003591 /* We can't be wanting more output after block 0xff, otherwise
3592 * the capacity check in psa_generator_read() would have
3593 * prevented this call. It could happen only if the generator
3594 * object was corrupted or if this function is called directly
3595 * inside the library. */
3596 if( tls12_prf->block_number == 0xff )
3597 return( PSA_ERROR_BAD_STATE );
3598
3599 /* We need a new block */
3600 ++tls12_prf->block_number;
3601 tls12_prf->offset_in_block = 0;
3602
3603 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
3604 *
3605 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
3606 *
3607 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
3608 * HMAC_hash(secret, A(2) + seed) +
3609 * HMAC_hash(secret, A(3) + seed) + ...
3610 *
3611 * A(0) = seed
3612 * A(i) = HMAC_hash( secret, A(i-1) )
3613 *
3614 * The `psa_tls12_prf_generator` structures saves the block
3615 * `HMAC_hash(secret, A(i) + seed)` from which the output
3616 * is currently extracted as `output_block`, while
3617 * `A(i) + seed` is stored in `Ai_with_seed`.
3618 *
3619 * Generating a new block means recalculating `Ai_with_seed`
3620 * from the A(i)-part of it, and afterwards recalculating
3621 * `output_block`.
3622 *
3623 * A(0) is computed at setup time.
3624 *
3625 */
3626
3627 psa_hmac_init_internal( &hmac );
3628
3629 /* We must distinguish the calculation of A(1) from those
3630 * of A(2) and higher, because A(0)=seed has a different
3631 * length than the other A(i). */
3632 if( tls12_prf->block_number == 1 )
3633 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003634 Ai = tls12_prf->Ai_with_seed + hash_length;
3635 Ai_len = tls12_prf->Ai_with_seed_len - hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003636 }
3637 else
3638 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003639 Ai = tls12_prf->Ai_with_seed;
3640 Ai_len = hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003641 }
3642
Hanno Becker3b339e22018-11-13 20:56:14 +00003643 /* Compute A(i+1) = HMAC_hash(secret, A(i)) */
3644 status = psa_hmac_setup_internal( &hmac,
3645 tls12_prf->key,
3646 tls12_prf->key_len,
3647 hash_alg );
3648 if( status != PSA_SUCCESS )
3649 goto cleanup;
3650
3651 status = psa_hash_update( &hmac.hash_ctx,
3652 Ai, Ai_len );
3653 if( status != PSA_SUCCESS )
3654 goto cleanup;
3655
3656 status = psa_hmac_finish_internal( &hmac,
3657 tls12_prf->Ai_with_seed,
3658 hash_length );
3659 if( status != PSA_SUCCESS )
3660 goto cleanup;
3661
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003662 /* Compute the next block `HMAC_hash(secret, A(i+1) + seed)`. */
3663 status = psa_hmac_setup_internal( &hmac,
3664 tls12_prf->key,
3665 tls12_prf->key_len,
3666 hash_alg );
3667 if( status != PSA_SUCCESS )
3668 goto cleanup;
3669
3670 status = psa_hash_update( &hmac.hash_ctx,
3671 tls12_prf->Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003672 tls12_prf->Ai_with_seed_len );
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003673 if( status != PSA_SUCCESS )
3674 goto cleanup;
3675
3676 status = psa_hmac_finish_internal( &hmac,
3677 tls12_prf->output_block,
3678 hash_length );
3679 if( status != PSA_SUCCESS )
3680 goto cleanup;
3681
3682cleanup:
3683
3684 cleanup_status = psa_hmac_abort_internal( &hmac );
3685 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
3686 status = cleanup_status;
3687
3688 return( status );
3689}
3690
3691/* Read some bytes from an TLS-1.2-PRF-based generator.
3692 * See Section 5 of RFC 5246. */
3693static psa_status_t psa_generator_tls12_prf_read(
3694 psa_tls12_prf_generator_t *tls12_prf,
3695 psa_algorithm_t alg,
3696 uint8_t *output,
3697 size_t output_length )
3698{
3699 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3700 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3701 psa_status_t status;
3702
3703 while( output_length != 0 )
3704 {
3705 /* Copy what remains of the current block */
3706 uint8_t n = hash_length - tls12_prf->offset_in_block;
3707
3708 /* Check if we have fully processed the current block. */
3709 if( n == 0 )
3710 {
3711 status = psa_generator_tls12_prf_generate_next_block( tls12_prf,
3712 alg );
3713 if( status != PSA_SUCCESS )
3714 return( status );
3715
3716 continue;
3717 }
3718
3719 if( n > output_length )
3720 n = (uint8_t) output_length;
3721 memcpy( output, tls12_prf->output_block + tls12_prf->offset_in_block,
3722 n );
3723 output += n;
3724 output_length -= n;
3725 tls12_prf->offset_in_block += n;
3726 }
3727
3728 return( PSA_SUCCESS );
3729}
Gilles Peskinebef7f142018-07-12 17:22:21 +02003730#endif /* MBEDTLS_MD_C */
3731
Gilles Peskineeab56e42018-07-12 17:12:33 +02003732psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
3733 uint8_t *output,
3734 size_t output_length )
3735{
3736 psa_status_t status;
3737
3738 if( output_length > generator->capacity )
3739 {
3740 generator->capacity = 0;
3741 /* Go through the error path to wipe all confidential data now
3742 * that the generator object is useless. */
3743 status = PSA_ERROR_INSUFFICIENT_CAPACITY;
3744 goto exit;
3745 }
3746 if( output_length == 0 &&
3747 generator->capacity == 0 && generator->alg == 0 )
3748 {
3749 /* Edge case: this is a blank or finished generator, and 0
3750 * bytes were requested. The right error in this case could
3751 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3752 * INSUFFICIENT_CAPACITY, which is right for a finished
3753 * generator, for consistency with the case when
3754 * output_length > 0. */
3755 return( PSA_ERROR_INSUFFICIENT_CAPACITY );
3756 }
3757 generator->capacity -= output_length;
3758
Gilles Peskine751d9652018-09-18 12:05:44 +02003759 if( generator->alg == PSA_ALG_SELECT_RAW )
3760 {
Gilles Peskine211a4362018-10-25 22:22:31 +02003761 /* Initially, the capacity of a selection generator is always
3762 * the size of the buffer, i.e. `generator->ctx.buffer.size`,
3763 * abbreviated in this comment as `size`. When the remaining
3764 * capacity is `c`, the next bytes to serve start `c` bytes
3765 * from the end of the buffer, i.e. `size - c` from the
3766 * beginning of the buffer. Since `generator->capacity` was just
3767 * decremented above, we need to serve the bytes from
3768 * `size - generator->capacity - output_length` to
3769 * `size - generator->capacity`. */
Gilles Peskine751d9652018-09-18 12:05:44 +02003770 size_t offset =
3771 generator->ctx.buffer.size - generator->capacity - output_length;
3772 memcpy( output, generator->ctx.buffer.data + offset, output_length );
3773 status = PSA_SUCCESS;
3774 }
3775 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003776#if defined(MBEDTLS_MD_C)
3777 if( PSA_ALG_IS_HKDF( generator->alg ) )
3778 {
3779 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
3780 status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
3781 output, output_length );
3782 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003783 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3784 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003785 {
3786 status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
3787 generator->alg, output,
3788 output_length );
3789 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003790 else
3791#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003792 {
3793 return( PSA_ERROR_BAD_STATE );
3794 }
3795
3796exit:
3797 if( status != PSA_SUCCESS )
3798 {
3799 psa_generator_abort( generator );
3800 memset( output, '!', output_length );
3801 }
3802 return( status );
3803}
3804
Gilles Peskine08542d82018-07-19 17:05:42 +02003805#if defined(MBEDTLS_DES_C)
3806static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
3807{
3808 if( data_size >= 8 )
3809 mbedtls_des_key_set_parity( data );
3810 if( data_size >= 16 )
3811 mbedtls_des_key_set_parity( data + 8 );
3812 if( data_size >= 24 )
3813 mbedtls_des_key_set_parity( data + 16 );
3814}
3815#endif /* MBEDTLS_DES_C */
3816
Gilles Peskinec5487a82018-12-03 18:08:14 +01003817psa_status_t psa_generator_import_key( psa_key_handle_t handle,
Gilles Peskineeab56e42018-07-12 17:12:33 +02003818 psa_key_type_t type,
3819 size_t bits,
3820 psa_crypto_generator_t *generator )
3821{
3822 uint8_t *data = NULL;
3823 size_t bytes = PSA_BITS_TO_BYTES( bits );
3824 psa_status_t status;
3825
3826 if( ! key_type_is_raw_bytes( type ) )
3827 return( PSA_ERROR_INVALID_ARGUMENT );
3828 if( bits % 8 != 0 )
3829 return( PSA_ERROR_INVALID_ARGUMENT );
3830 data = mbedtls_calloc( 1, bytes );
3831 if( data == NULL )
3832 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3833
3834 status = psa_generator_read( generator, data, bytes );
3835 if( status != PSA_SUCCESS )
3836 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02003837#if defined(MBEDTLS_DES_C)
3838 if( type == PSA_KEY_TYPE_DES )
3839 psa_des_set_key_parity( data, bytes );
3840#endif /* MBEDTLS_DES_C */
Gilles Peskinec5487a82018-12-03 18:08:14 +01003841 status = psa_import_key( handle, type, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02003842
3843exit:
3844 mbedtls_free( data );
3845 return( status );
3846}
3847
3848
3849
3850/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003851/* Key derivation */
3852/****************************************************************/
3853
Gilles Peskinea05219c2018-11-16 16:02:56 +01003854#if defined(MBEDTLS_MD_C)
Gilles Peskinebef7f142018-07-12 17:22:21 +02003855/* Set up an HKDF-based generator. This is exactly the extract phase
Gilles Peskine346797d2018-11-16 16:05:06 +01003856 * of the HKDF algorithm.
3857 *
3858 * Note that if this function fails, you must call psa_generator_abort()
3859 * to potentially free embedded data structures and wipe confidential data.
3860 */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003861static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003862 const uint8_t *secret,
3863 size_t secret_length,
Gilles Peskinebef7f142018-07-12 17:22:21 +02003864 psa_algorithm_t hash_alg,
3865 const uint8_t *salt,
3866 size_t salt_length,
3867 const uint8_t *label,
3868 size_t label_length )
3869{
3870 psa_status_t status;
3871 status = psa_hmac_setup_internal( &hkdf->hmac,
3872 salt, salt_length,
Gilles Peskine00709fa2018-08-22 18:25:41 +02003873 PSA_ALG_HMAC_GET_HASH( hash_alg ) );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003874 if( status != PSA_SUCCESS )
3875 return( status );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003876 status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003877 if( status != PSA_SUCCESS )
3878 return( status );
3879 status = psa_hmac_finish_internal( &hkdf->hmac,
3880 hkdf->prk,
3881 sizeof( hkdf->prk ) );
3882 if( status != PSA_SUCCESS )
3883 return( status );
3884 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
3885 hkdf->block_number = 0;
3886 hkdf->info_length = label_length;
3887 if( label_length != 0 )
3888 {
3889 hkdf->info = mbedtls_calloc( 1, label_length );
3890 if( hkdf->info == NULL )
3891 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3892 memcpy( hkdf->info, label, label_length );
3893 }
3894 return( PSA_SUCCESS );
3895}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003896#endif /* MBEDTLS_MD_C */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003897
Gilles Peskinea05219c2018-11-16 16:02:56 +01003898#if defined(MBEDTLS_MD_C)
Gilles Peskine346797d2018-11-16 16:05:06 +01003899/* Set up a TLS-1.2-prf-based generator (see RFC 5246, Section 5).
3900 *
3901 * Note that if this function fails, you must call psa_generator_abort()
3902 * to potentially free embedded data structures and wipe confidential data.
3903 */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003904static psa_status_t psa_generator_tls12_prf_setup(
3905 psa_tls12_prf_generator_t *tls12_prf,
3906 const unsigned char *key,
3907 size_t key_len,
3908 psa_algorithm_t hash_alg,
3909 const uint8_t *salt,
3910 size_t salt_length,
3911 const uint8_t *label,
3912 size_t label_length )
3913{
3914 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Hanno Becker580fba12018-11-13 20:50:45 +00003915 size_t Ai_with_seed_len = hash_length + salt_length + label_length;
3916 int overflow;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003917
3918 tls12_prf->key = mbedtls_calloc( 1, key_len );
3919 if( tls12_prf->key == NULL )
3920 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3921 tls12_prf->key_len = key_len;
3922 memcpy( tls12_prf->key, key, key_len );
3923
Hanno Becker580fba12018-11-13 20:50:45 +00003924 overflow = ( salt_length + label_length < salt_length ) ||
3925 ( salt_length + label_length + hash_length < hash_length );
3926 if( overflow )
3927 return( PSA_ERROR_INVALID_ARGUMENT );
3928
3929 tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len );
3930 if( tls12_prf->Ai_with_seed == NULL )
3931 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3932 tls12_prf->Ai_with_seed_len = Ai_with_seed_len;
3933
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003934 /* Write `label + seed' at the end of the `A(i) + seed` buffer,
3935 * leaving the initial `hash_length` bytes unspecified for now. */
Hanno Becker353e4532018-11-15 09:53:57 +00003936 if( label_length != 0 )
3937 {
3938 memcpy( tls12_prf->Ai_with_seed + hash_length,
3939 label, label_length );
3940 }
3941
3942 if( salt_length != 0 )
3943 {
3944 memcpy( tls12_prf->Ai_with_seed + hash_length + label_length,
3945 salt, salt_length );
3946 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003947
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003948 /* The first block gets generated when
3949 * psa_generator_read() is called. */
3950 tls12_prf->block_number = 0;
3951 tls12_prf->offset_in_block = hash_length;
3952
3953 return( PSA_SUCCESS );
3954}
Hanno Becker1aaedc02018-11-16 11:35:34 +00003955
3956/* Set up a TLS-1.2-PSK-to-MS-based generator. */
3957static psa_status_t psa_generator_tls12_psk_to_ms_setup(
3958 psa_tls12_prf_generator_t *tls12_prf,
3959 const unsigned char *psk,
3960 size_t psk_len,
3961 psa_algorithm_t hash_alg,
3962 const uint8_t *salt,
3963 size_t salt_length,
3964 const uint8_t *label,
3965 size_t label_length )
3966{
3967 psa_status_t status;
3968 unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
3969
3970 if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
3971 return( PSA_ERROR_INVALID_ARGUMENT );
3972
3973 /* Quoting RFC 4279, Section 2:
3974 *
3975 * The premaster secret is formed as follows: if the PSK is N octets
3976 * long, concatenate a uint16 with the value N, N zero octets, a second
3977 * uint16 with the value N, and the PSK itself.
3978 */
3979
3980 pms[0] = ( psk_len >> 8 ) & 0xff;
3981 pms[1] = ( psk_len >> 0 ) & 0xff;
3982 memset( pms + 2, 0, psk_len );
3983 pms[2 + psk_len + 0] = pms[0];
3984 pms[2 + psk_len + 1] = pms[1];
3985 memcpy( pms + 4 + psk_len, psk, psk_len );
3986
3987 status = psa_generator_tls12_prf_setup( tls12_prf,
3988 pms, 4 + 2 * psk_len,
3989 hash_alg,
3990 salt, salt_length,
3991 label, label_length );
3992
Gilles Peskine3f108122018-12-07 18:14:53 +01003993 mbedtls_platform_zeroize( pms, sizeof( pms ) );
Hanno Becker1aaedc02018-11-16 11:35:34 +00003994 return( status );
3995}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003996#endif /* MBEDTLS_MD_C */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003997
Gilles Peskine346797d2018-11-16 16:05:06 +01003998/* Note that if this function fails, you must call psa_generator_abort()
3999 * to potentially free embedded data structures and wipe confidential data.
4000 */
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004001static psa_status_t psa_key_derivation_internal(
4002 psa_crypto_generator_t *generator,
4003 const uint8_t *secret, size_t secret_length,
4004 psa_algorithm_t alg,
4005 const uint8_t *salt, size_t salt_length,
4006 const uint8_t *label, size_t label_length,
4007 size_t capacity )
4008{
4009 psa_status_t status;
4010 size_t max_capacity;
4011
4012 /* Set generator->alg even on failure so that abort knows what to do. */
4013 generator->alg = alg;
4014
Gilles Peskine751d9652018-09-18 12:05:44 +02004015 if( alg == PSA_ALG_SELECT_RAW )
4016 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01004017 (void) salt;
Gilles Peskine751d9652018-09-18 12:05:44 +02004018 if( salt_length != 0 )
4019 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea05219c2018-11-16 16:02:56 +01004020 (void) label;
Gilles Peskine751d9652018-09-18 12:05:44 +02004021 if( label_length != 0 )
4022 return( PSA_ERROR_INVALID_ARGUMENT );
4023 generator->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
4024 if( generator->ctx.buffer.data == NULL )
4025 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4026 memcpy( generator->ctx.buffer.data, secret, secret_length );
4027 generator->ctx.buffer.size = secret_length;
4028 max_capacity = secret_length;
4029 status = PSA_SUCCESS;
4030 }
4031 else
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004032#if defined(MBEDTLS_MD_C)
4033 if( PSA_ALG_IS_HKDF( alg ) )
4034 {
4035 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
4036 size_t hash_size = PSA_HASH_SIZE( hash_alg );
4037 if( hash_size == 0 )
4038 return( PSA_ERROR_NOT_SUPPORTED );
4039 max_capacity = 255 * hash_size;
4040 status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
4041 secret, secret_length,
4042 hash_alg,
4043 salt, salt_length,
4044 label, label_length );
4045 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00004046 /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
4047 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
4048 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004049 {
4050 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
4051 size_t hash_size = PSA_HASH_SIZE( hash_alg );
4052
4053 /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */
4054 if( hash_alg != PSA_ALG_SHA_256 &&
4055 hash_alg != PSA_ALG_SHA_384 )
4056 {
4057 return( PSA_ERROR_NOT_SUPPORTED );
4058 }
4059
4060 max_capacity = 255 * hash_size;
Hanno Becker1aaedc02018-11-16 11:35:34 +00004061
4062 if( PSA_ALG_IS_TLS12_PRF( alg ) )
4063 {
4064 status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
4065 secret, secret_length,
4066 hash_alg, salt, salt_length,
4067 label, label_length );
4068 }
4069 else
4070 {
4071 status = psa_generator_tls12_psk_to_ms_setup(
4072 &generator->ctx.tls12_prf,
4073 secret, secret_length,
4074 hash_alg, salt, salt_length,
4075 label, label_length );
4076 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004077 }
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004078 else
4079#endif
4080 {
4081 return( PSA_ERROR_NOT_SUPPORTED );
4082 }
4083
4084 if( status != PSA_SUCCESS )
4085 return( status );
4086
4087 if( capacity <= max_capacity )
4088 generator->capacity = capacity;
Gilles Peskine8feb3a82018-09-18 12:06:11 +02004089 else if( capacity == PSA_GENERATOR_UNBRIDLED_CAPACITY )
4090 generator->capacity = max_capacity;
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004091 else
4092 return( PSA_ERROR_INVALID_ARGUMENT );
4093
4094 return( PSA_SUCCESS );
4095}
4096
Gilles Peskineea0fb492018-07-12 17:17:20 +02004097psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
Gilles Peskinec5487a82018-12-03 18:08:14 +01004098 psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02004099 psa_algorithm_t alg,
4100 const uint8_t *salt,
4101 size_t salt_length,
4102 const uint8_t *label,
4103 size_t label_length,
4104 size_t capacity )
4105{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004106 psa_key_slot_t *slot;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004107 psa_status_t status;
4108
4109 if( generator->alg != 0 )
4110 return( PSA_ERROR_BAD_STATE );
4111
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004112 /* Make sure that alg is a key derivation algorithm. This prevents
4113 * key selection algorithms, which psa_key_derivation_internal
4114 * accepts for the sake of key agreement. */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004115 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
4116 return( PSA_ERROR_INVALID_ARGUMENT );
4117
Gilles Peskinec5487a82018-12-03 18:08:14 +01004118 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004119 if( status != PSA_SUCCESS )
4120 return( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004121
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004122 if( slot->type != PSA_KEY_TYPE_DERIVE )
4123 return( PSA_ERROR_INVALID_ARGUMENT );
4124
4125 status = psa_key_derivation_internal( generator,
4126 slot->data.raw.data,
4127 slot->data.raw.bytes,
4128 alg,
4129 salt, salt_length,
4130 label, label_length,
4131 capacity );
4132 if( status != PSA_SUCCESS )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004133 psa_generator_abort( generator );
4134 return( status );
4135}
4136
4137
4138
4139/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02004140/* Key agreement */
4141/****************************************************************/
4142
Gilles Peskinea05219c2018-11-16 16:02:56 +01004143#if defined(MBEDTLS_ECDH_C)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004144static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
4145 size_t peer_key_length,
4146 const mbedtls_ecp_keypair *our_key,
4147 uint8_t *shared_secret,
4148 size_t shared_secret_size,
4149 size_t *shared_secret_length )
4150{
4151 mbedtls_pk_context pk;
4152 mbedtls_ecp_keypair *their_key = NULL;
4153 mbedtls_ecdh_context ecdh;
4154 int ret;
4155 mbedtls_ecdh_init( &ecdh );
4156 mbedtls_pk_init( &pk );
4157
4158 ret = mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length );
4159 if( ret != 0 )
4160 goto exit;
Gilles Peskine88714d72018-10-25 23:07:25 +02004161 switch( mbedtls_pk_get_type( &pk ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004162 {
Gilles Peskine88714d72018-10-25 23:07:25 +02004163 case MBEDTLS_PK_ECKEY:
4164 case MBEDTLS_PK_ECKEY_DH:
4165 break;
4166 default:
4167 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4168 goto exit;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004169 }
4170 their_key = mbedtls_pk_ec( pk );
Gilles Peskineb4086612018-11-14 20:51:23 +01004171 if( their_key->grp.id != our_key->grp.id )
4172 {
4173 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4174 goto exit;
4175 }
4176
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004177 ret = mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS );
4178 if( ret != 0 )
4179 goto exit;
4180 ret = mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS );
4181 if( ret != 0 )
4182 goto exit;
4183
4184 ret = mbedtls_ecdh_calc_secret( &ecdh,
4185 shared_secret_length,
4186 shared_secret, shared_secret_size,
4187 mbedtls_ctr_drbg_random,
4188 &global_data.ctr_drbg );
4189
4190exit:
4191 mbedtls_pk_free( &pk );
4192 mbedtls_ecdh_free( &ecdh );
4193 return( mbedtls_to_psa_error( ret ) );
4194}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004195#endif /* MBEDTLS_ECDH_C */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004196
Gilles Peskine01d718c2018-09-18 12:01:02 +02004197#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
4198
Gilles Peskine346797d2018-11-16 16:05:06 +01004199/* Note that if this function fails, you must call psa_generator_abort()
4200 * to potentially free embedded data structures and wipe confidential data.
4201 */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004202static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
Gilles Peskine2f060a82018-12-04 17:12:32 +01004203 psa_key_slot_t *private_key,
Gilles Peskine01d718c2018-09-18 12:01:02 +02004204 const uint8_t *peer_key,
4205 size_t peer_key_length,
4206 psa_algorithm_t alg )
4207{
4208 psa_status_t status;
4209 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
4210 size_t shared_secret_length = 0;
4211
4212 /* Step 1: run the secret agreement algorithm to generate the shared
4213 * secret. */
4214 switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
4215 {
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004216#if defined(MBEDTLS_ECDH_C)
4217 case PSA_ALG_ECDH_BASE:
4218 if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
4219 return( PSA_ERROR_INVALID_ARGUMENT );
4220 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
4221 private_key->data.ecp,
4222 shared_secret,
4223 sizeof( shared_secret ),
4224 &shared_secret_length );
4225 break;
4226#endif /* MBEDTLS_ECDH_C */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004227 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01004228 (void) private_key;
4229 (void) peer_key;
4230 (void) peer_key_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004231 return( PSA_ERROR_NOT_SUPPORTED );
4232 }
4233 if( status != PSA_SUCCESS )
4234 goto exit;
4235
4236 /* Step 2: set up the key derivation to generate key material from
4237 * the shared secret. */
4238 status = psa_key_derivation_internal( generator,
4239 shared_secret, shared_secret_length,
4240 PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ),
4241 NULL, 0, NULL, 0,
4242 PSA_GENERATOR_UNBRIDLED_CAPACITY );
4243exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01004244 mbedtls_platform_zeroize( shared_secret, shared_secret_length );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004245 return( status );
4246}
4247
4248psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
Gilles Peskinec5487a82018-12-03 18:08:14 +01004249 psa_key_handle_t private_key,
Gilles Peskine01d718c2018-09-18 12:01:02 +02004250 const uint8_t *peer_key,
4251 size_t peer_key_length,
4252 psa_algorithm_t alg )
4253{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004254 psa_key_slot_t *slot;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004255 psa_status_t status;
4256 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
4257 return( PSA_ERROR_INVALID_ARGUMENT );
4258 status = psa_get_key_from_slot( private_key, &slot,
4259 PSA_KEY_USAGE_DERIVE, alg );
4260 if( status != PSA_SUCCESS )
4261 return( status );
Gilles Peskine346797d2018-11-16 16:05:06 +01004262 status = psa_key_agreement_internal( generator,
4263 slot,
4264 peer_key, peer_key_length,
4265 alg );
4266 if( status != PSA_SUCCESS )
4267 psa_generator_abort( generator );
4268 return( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004269}
4270
4271
4272
4273/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004274/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02004275/****************************************************************/
4276
4277psa_status_t psa_generate_random( uint8_t *output,
4278 size_t output_size )
4279{
itayzafrir0adf0fc2018-09-06 16:24:41 +03004280 int ret;
4281 GUARD_MODULE_INITIALIZED;
4282
4283 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
Gilles Peskine05d69892018-06-19 22:00:52 +02004284 return( mbedtls_to_psa_error( ret ) );
4285}
4286
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004287#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
avolinski13beb102018-11-20 16:51:49 +02004288
4289/* Support function for error conversion between psa_its error codes to psa crypto */
4290static psa_status_t its_to_psa_error( psa_its_status_t ret )
4291{
4292 switch( ret )
4293 {
4294 case PSA_ITS_SUCCESS:
4295 return( PSA_SUCCESS );
4296
4297 case PSA_ITS_ERROR_KEY_NOT_FOUND:
4298 return( PSA_ERROR_EMPTY_SLOT );
4299
4300 case PSA_ITS_ERROR_STORAGE_FAILURE:
4301 return( PSA_ERROR_STORAGE_FAILURE );
4302
4303 case PSA_ITS_ERROR_INSUFFICIENT_SPACE:
4304 return( PSA_ERROR_INSUFFICIENT_STORAGE );
4305
4306 case PSA_ITS_ERROR_INVALID_KEY:
4307 case PSA_PS_ERROR_OFFSET_INVALID:
4308 case PSA_ITS_ERROR_INCORRECT_SIZE:
4309 case PSA_ITS_ERROR_BAD_POINTER:
4310 return( PSA_ERROR_INVALID_ARGUMENT );
4311
4312 case PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED:
4313 return( PSA_ERROR_NOT_SUPPORTED );
4314
4315 case PSA_ITS_ERROR_WRITE_ONCE:
4316 return( PSA_ERROR_OCCUPIED_SLOT );
4317
4318 default:
4319 return( PSA_ERROR_UNKNOWN_ERROR );
4320 }
4321}
4322
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004323psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
4324 size_t seed_size )
4325{
4326 psa_status_t status;
avolinski13beb102018-11-20 16:51:49 +02004327 psa_its_status_t its_status;
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004328 struct psa_its_info_t p_info;
4329 if( global_data.initialized )
4330 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02004331
4332 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
4333 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
4334 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
4335 return( PSA_ERROR_INVALID_ARGUMENT );
4336
avolinski0d2c2662018-11-21 17:31:07 +02004337 its_status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
avolinski13beb102018-11-20 16:51:49 +02004338 status = its_to_psa_error( its_status );
4339
4340 if( PSA_ITS_ERROR_KEY_NOT_FOUND == its_status ) /* No seed exists */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004341 {
avolinski0d2c2662018-11-21 17:31:07 +02004342 its_status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
avolinski13beb102018-11-20 16:51:49 +02004343 status = its_to_psa_error( its_status );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004344 }
avolinski13beb102018-11-20 16:51:49 +02004345 else if( PSA_ITS_SUCCESS == its_status )
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004346 {
4347 /* You should not be here. Seed needs to be injected only once */
4348 status = PSA_ERROR_NOT_PERMITTED;
4349 }
4350 return( status );
4351}
4352#endif
4353
Gilles Peskinec5487a82018-12-03 18:08:14 +01004354psa_status_t psa_generate_key( psa_key_handle_t handle,
Gilles Peskine05d69892018-06-19 22:00:52 +02004355 psa_key_type_t type,
4356 size_t bits,
Gilles Peskine53d991e2018-07-12 01:14:59 +02004357 const void *extra,
4358 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02004359{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004360 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004361 psa_status_t status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004362
Gilles Peskine53d991e2018-07-12 01:14:59 +02004363 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004364 return( PSA_ERROR_INVALID_ARGUMENT );
4365
Gilles Peskinec5487a82018-12-03 18:08:14 +01004366 status = psa_get_empty_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004367 if( status != PSA_SUCCESS )
4368 return( status );
4369
Gilles Peskine48c0ea12018-06-21 14:15:31 +02004370 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004371 {
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004372 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004373 if( status != PSA_SUCCESS )
4374 return( status );
4375 status = psa_generate_random( slot->data.raw.data,
4376 slot->data.raw.bytes );
4377 if( status != PSA_SUCCESS )
4378 {
4379 mbedtls_free( slot->data.raw.data );
4380 return( status );
4381 }
4382#if defined(MBEDTLS_DES_C)
4383 if( type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02004384 psa_des_set_key_parity( slot->data.raw.data,
4385 slot->data.raw.bytes );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004386#endif /* MBEDTLS_DES_C */
4387 }
4388 else
4389
4390#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
4391 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
4392 {
4393 mbedtls_rsa_context *rsa;
4394 int ret;
4395 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02004396 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
4397 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +01004398 /* Accept only byte-aligned keys, for the same reasons as
4399 * in psa_import_rsa_key(). */
4400 if( bits % 8 != 0 )
4401 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02004402 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004403 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02004404 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004405 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004406 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02004407#if INT_MAX < 0xffffffff
4408 /* Check that the uint32_t value passed by the caller fits
4409 * in the range supported by this implementation. */
4410 if( p->e > INT_MAX )
4411 return( PSA_ERROR_NOT_SUPPORTED );
4412#endif
4413 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004414 }
4415 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
4416 if( rsa == NULL )
4417 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4418 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
4419 ret = mbedtls_rsa_gen_key( rsa,
4420 mbedtls_ctr_drbg_random,
4421 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004422 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02004423 exponent );
4424 if( ret != 0 )
4425 {
4426 mbedtls_rsa_free( rsa );
4427 mbedtls_free( rsa );
4428 return( mbedtls_to_psa_error( ret ) );
4429 }
4430 slot->data.rsa = rsa;
4431 }
4432 else
4433#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
4434
4435#if defined(MBEDTLS_ECP_C)
4436 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
4437 {
4438 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
4439 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
4440 const mbedtls_ecp_curve_info *curve_info =
4441 mbedtls_ecp_curve_info_from_grp_id( grp_id );
4442 mbedtls_ecp_keypair *ecp;
4443 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004444 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004445 return( PSA_ERROR_NOT_SUPPORTED );
4446 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
4447 return( PSA_ERROR_NOT_SUPPORTED );
4448 if( curve_info->bit_size != bits )
4449 return( PSA_ERROR_INVALID_ARGUMENT );
4450 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
4451 if( ecp == NULL )
4452 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4453 mbedtls_ecp_keypair_init( ecp );
4454 ret = mbedtls_ecp_gen_key( grp_id, ecp,
4455 mbedtls_ctr_drbg_random,
4456 &global_data.ctr_drbg );
4457 if( ret != 0 )
4458 {
4459 mbedtls_ecp_keypair_free( ecp );
4460 mbedtls_free( ecp );
4461 return( mbedtls_to_psa_error( ret ) );
4462 }
4463 slot->data.ecp = ecp;
4464 }
4465 else
4466#endif /* MBEDTLS_ECP_C */
4467
4468 return( PSA_ERROR_NOT_SUPPORTED );
4469
4470 slot->type = type;
Darryl Green0c6575a2018-11-07 16:05:30 +00004471
4472#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
4473 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
4474 {
Gilles Peskine69f976b2018-11-30 18:46:56 +01004475 return( psa_save_generated_persistent_key( slot, bits ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004476 }
4477#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
4478
4479 return( status );
Gilles Peskine05d69892018-06-19 22:00:52 +02004480}
4481
4482
4483/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01004484/* Module setup */
4485/****************************************************************/
4486
Gilles Peskine5e769522018-11-20 21:59:56 +01004487psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
4488 void (* entropy_init )( mbedtls_entropy_context *ctx ),
4489 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
4490{
4491 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4492 return( PSA_ERROR_BAD_STATE );
4493 global_data.entropy_init = entropy_init;
4494 global_data.entropy_free = entropy_free;
4495 return( PSA_SUCCESS );
4496}
4497
Gilles Peskinee59236f2018-01-27 23:32:46 +01004498void mbedtls_psa_crypto_free( void )
4499{
Gilles Peskinec6b69072018-11-20 21:42:52 +01004500 if( global_data.key_slots_initialized )
Darryl Green40225ba2018-11-15 14:48:15 +00004501 {
Gilles Peskinec5487a82018-12-03 18:08:14 +01004502 psa_key_handle_t key;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004503 for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ )
4504 {
Gilles Peskine2f060a82018-12-04 17:12:32 +01004505 psa_key_slot_t *slot = &global_data.key_slots[key - 1];
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01004506 (void) psa_wipe_key_slot( slot );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004507 }
Darryl Green40225ba2018-11-15 14:48:15 +00004508 }
Gilles Peskinec6b69072018-11-20 21:42:52 +01004509 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4510 {
4511 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
Gilles Peskine5e769522018-11-20 21:59:56 +01004512 global_data.entropy_free( &global_data.entropy );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004513 }
4514 /* Wipe all remaining data, including configuration.
4515 * In particular, this sets all state indicator to the value
4516 * indicating "uninitialized". */
Gilles Peskine3f108122018-12-07 18:14:53 +01004517 mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004518}
4519
4520psa_status_t psa_crypto_init( void )
4521{
4522 int ret;
4523 const unsigned char drbg_seed[] = "PSA";
4524
Gilles Peskinec6b69072018-11-20 21:42:52 +01004525 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004526 if( global_data.initialized != 0 )
4527 return( PSA_SUCCESS );
4528
Gilles Peskine5e769522018-11-20 21:59:56 +01004529 /* Set default configuration if
4530 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
4531 if( global_data.entropy_init == NULL )
4532 global_data.entropy_init = mbedtls_entropy_init;
4533 if( global_data.entropy_free == NULL )
4534 global_data.entropy_free = mbedtls_entropy_free;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004535
Gilles Peskinec6b69072018-11-20 21:42:52 +01004536 /* Initialize the random generator. */
Gilles Peskine5e769522018-11-20 21:59:56 +01004537 global_data.entropy_init( &global_data.entropy );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004538 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004539 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004540 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
4541 mbedtls_entropy_func,
4542 &global_data.entropy,
4543 drbg_seed, sizeof( drbg_seed ) - 1 );
4544 if( ret != 0 )
4545 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004546 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004547
Gilles Peskinec6b69072018-11-20 21:42:52 +01004548 /* Initialize the key slots. Zero-initialization has made all key
Gilles Peskinefe9756b2018-12-07 18:12:28 +01004549 * slots empty, so there is nothing to do. */
Gilles Peskinec6b69072018-11-20 21:42:52 +01004550 global_data.key_slots_initialized = 1;
4551
4552 /* All done. */
Gilles Peskinee4ebc122018-03-07 14:16:44 +01004553 global_data.initialized = 1;
4554
Gilles Peskinee59236f2018-01-27 23:32:46 +01004555exit:
4556 if( ret != 0 )
4557 mbedtls_psa_crypto_free( );
4558 return( mbedtls_to_psa_error( ret ) );
4559}
4560
4561#endif /* MBEDTLS_PSA_CRYPTO_C */