blob: e41e5128705fc666acc7e5247bbf7271197ed229 [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)
29
30#include "psa/crypto.h"
31
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010032#include <stdlib.h>
33#include <string.h>
34#if defined(MBEDTLS_PLATFORM_C)
35#include "mbedtls/platform.h"
36#else
37#define mbedtls_calloc calloc
38#define mbedtls_free free
39#endif
40
Gilles Peskinea5905292018-02-07 20:59:33 +010041#include "mbedtls/arc4.h"
42#include "mbedtls/blowfish.h"
43#include "mbedtls/camellia.h"
44#include "mbedtls/cipher.h"
45#include "mbedtls/ccm.h"
46#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010047#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010048#include "mbedtls/des.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010049#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010050#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010051#include "mbedtls/error.h"
52#include "mbedtls/gcm.h"
53#include "mbedtls/md2.h"
54#include "mbedtls/md4.h"
55#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010056#include "mbedtls/md.h"
57#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010058#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010059#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010060#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010061#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010062#include "mbedtls/sha1.h"
63#include "mbedtls/sha256.h"
64#include "mbedtls/sha512.h"
65#include "mbedtls/xtea.h"
66
Gilles Peskinee59236f2018-01-27 23:32:46 +010067
68
69/* Implementation that should never be optimized out by the compiler */
70static void mbedtls_zeroize( void *v, size_t n )
71{
72 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
73}
74
Gilles Peskine9ef733f2018-02-07 21:05:37 +010075/* constant-time buffer comparison */
76static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
77{
78 size_t i;
79 unsigned char diff = 0;
80
81 for( i = 0; i < n; i++ )
82 diff |= a[i] ^ b[i];
83
84 return( diff );
85}
86
87
88
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010089/****************************************************************/
90/* Global data, support functions and library management */
91/****************************************************************/
92
93/* Number of key slots (plus one because 0 is not used).
94 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +020095#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010096
Gilles Peskine2d277862018-06-18 15:41:12 +020097typedef struct
98{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010099 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300100 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200101 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200102 union
103 {
104 struct raw_data
105 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100106 uint8_t *data;
107 size_t bytes;
108 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100109#if defined(MBEDTLS_RSA_C)
110 mbedtls_rsa_context *rsa;
111#endif /* MBEDTLS_RSA_C */
112#if defined(MBEDTLS_ECP_C)
113 mbedtls_ecp_keypair *ecp;
114#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100115 } data;
116} key_slot_t;
117
Gilles Peskine2d277862018-06-18 15:41:12 +0200118typedef struct
119{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100120 int initialized;
121 mbedtls_entropy_context entropy;
122 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200123 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100124} psa_global_data_t;
125
126static psa_global_data_t global_data;
127
128static psa_status_t mbedtls_to_psa_error( int ret )
129{
Gilles Peskinea5905292018-02-07 20:59:33 +0100130 /* If there's both a high-level code and low-level code, dispatch on
131 * the high-level code. */
132 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100133 {
134 case 0:
135 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100136
137 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
138 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
139 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
140 return( PSA_ERROR_NOT_SUPPORTED );
141 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
142 return( PSA_ERROR_HARDWARE_FAILURE );
143
144 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
145 return( PSA_ERROR_HARDWARE_FAILURE );
146
147 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
148 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
149 return( PSA_ERROR_NOT_SUPPORTED );
150 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
151 return( PSA_ERROR_HARDWARE_FAILURE );
152
153 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
154 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
155 return( PSA_ERROR_NOT_SUPPORTED );
156 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
157 return( PSA_ERROR_HARDWARE_FAILURE );
158
159 case MBEDTLS_ERR_CCM_BAD_INPUT:
160 return( PSA_ERROR_INVALID_ARGUMENT );
161 case MBEDTLS_ERR_CCM_AUTH_FAILED:
162 return( PSA_ERROR_INVALID_SIGNATURE );
163 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
164 return( PSA_ERROR_HARDWARE_FAILURE );
165
166 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
167 return( PSA_ERROR_NOT_SUPPORTED );
168 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
169 return( PSA_ERROR_INVALID_ARGUMENT );
170 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
171 return( PSA_ERROR_INSUFFICIENT_MEMORY );
172 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
173 return( PSA_ERROR_INVALID_PADDING );
174 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
175 return( PSA_ERROR_BAD_STATE );
176 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
177 return( PSA_ERROR_INVALID_SIGNATURE );
178 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
179 return( PSA_ERROR_TAMPERING_DETECTED );
180 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
181 return( PSA_ERROR_HARDWARE_FAILURE );
182
183 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
186 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
187 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
188 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
189 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
190 return( PSA_ERROR_NOT_SUPPORTED );
191 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
192 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
193
194 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
195 return( PSA_ERROR_NOT_SUPPORTED );
196 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
197 return( PSA_ERROR_HARDWARE_FAILURE );
198
Gilles Peskinee59236f2018-01-27 23:32:46 +0100199 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
200 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
201 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
202 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100203
204 case MBEDTLS_ERR_GCM_AUTH_FAILED:
205 return( PSA_ERROR_INVALID_SIGNATURE );
206 case MBEDTLS_ERR_GCM_BAD_INPUT:
207 return( PSA_ERROR_NOT_SUPPORTED );
208 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
209 return( PSA_ERROR_HARDWARE_FAILURE );
210
211 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
212 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
213 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
214 return( PSA_ERROR_HARDWARE_FAILURE );
215
216 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
217 return( PSA_ERROR_NOT_SUPPORTED );
218 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
219 return( PSA_ERROR_INVALID_ARGUMENT );
220 case MBEDTLS_ERR_MD_ALLOC_FAILED:
221 return( PSA_ERROR_INSUFFICIENT_MEMORY );
222 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
223 return( PSA_ERROR_STORAGE_FAILURE );
224 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
225 return( PSA_ERROR_HARDWARE_FAILURE );
226
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100227 case MBEDTLS_ERR_PK_ALLOC_FAILED:
228 return( PSA_ERROR_INSUFFICIENT_MEMORY );
229 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
230 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
231 return( PSA_ERROR_INVALID_ARGUMENT );
232 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100233 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100234 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
235 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
236 return( PSA_ERROR_INVALID_ARGUMENT );
237 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
238 return( PSA_ERROR_NOT_SUPPORTED );
239 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
240 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
241 return( PSA_ERROR_NOT_PERMITTED );
242 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
243 return( PSA_ERROR_INVALID_ARGUMENT );
244 case MBEDTLS_ERR_PK_INVALID_ALG:
245 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
246 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
247 return( PSA_ERROR_NOT_SUPPORTED );
248 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
249 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100250 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
251 return( PSA_ERROR_HARDWARE_FAILURE );
252
253 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
254 return( PSA_ERROR_HARDWARE_FAILURE );
255
256 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
257 return( PSA_ERROR_INVALID_ARGUMENT );
258 case MBEDTLS_ERR_RSA_INVALID_PADDING:
259 return( PSA_ERROR_INVALID_PADDING );
260 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
261 return( PSA_ERROR_HARDWARE_FAILURE );
262 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
263 return( PSA_ERROR_INVALID_ARGUMENT );
264 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
265 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
266 return( PSA_ERROR_TAMPERING_DETECTED );
267 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
268 return( PSA_ERROR_INVALID_SIGNATURE );
269 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
270 return( PSA_ERROR_BUFFER_TOO_SMALL );
271 case MBEDTLS_ERR_RSA_RNG_FAILED:
272 return( PSA_ERROR_INSUFFICIENT_MEMORY );
273 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
274 return( PSA_ERROR_NOT_SUPPORTED );
275 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
276 return( PSA_ERROR_HARDWARE_FAILURE );
277
278 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
279 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
280 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
281 return( PSA_ERROR_HARDWARE_FAILURE );
282
283 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
284 return( PSA_ERROR_INVALID_ARGUMENT );
285 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
286 return( PSA_ERROR_HARDWARE_FAILURE );
287
itayzafrir5c753392018-05-08 11:18:38 +0300288 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300289 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300290 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300291 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
292 return( PSA_ERROR_BUFFER_TOO_SMALL );
293 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
294 return( PSA_ERROR_NOT_SUPPORTED );
295 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
296 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
297 return( PSA_ERROR_INVALID_SIGNATURE );
298 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
299 return( PSA_ERROR_INSUFFICIENT_MEMORY );
300 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
301 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300302
Gilles Peskinee59236f2018-01-27 23:32:46 +0100303 default:
304 return( PSA_ERROR_UNKNOWN_ERROR );
305 }
306}
307
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200308
309
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100310/****************************************************************/
311/* Key management */
312/****************************************************************/
313
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200314static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
315{
316 switch( grpid )
317 {
318 case MBEDTLS_ECP_DP_SECP192R1:
319 return( PSA_ECC_CURVE_SECP192R1 );
320 case MBEDTLS_ECP_DP_SECP224R1:
321 return( PSA_ECC_CURVE_SECP224R1 );
322 case MBEDTLS_ECP_DP_SECP256R1:
323 return( PSA_ECC_CURVE_SECP256R1 );
324 case MBEDTLS_ECP_DP_SECP384R1:
325 return( PSA_ECC_CURVE_SECP384R1 );
326 case MBEDTLS_ECP_DP_SECP521R1:
327 return( PSA_ECC_CURVE_SECP521R1 );
328 case MBEDTLS_ECP_DP_BP256R1:
329 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
330 case MBEDTLS_ECP_DP_BP384R1:
331 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
332 case MBEDTLS_ECP_DP_BP512R1:
333 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
334 case MBEDTLS_ECP_DP_CURVE25519:
335 return( PSA_ECC_CURVE_CURVE25519 );
336 case MBEDTLS_ECP_DP_SECP192K1:
337 return( PSA_ECC_CURVE_SECP192K1 );
338 case MBEDTLS_ECP_DP_SECP224K1:
339 return( PSA_ECC_CURVE_SECP224K1 );
340 case MBEDTLS_ECP_DP_SECP256K1:
341 return( PSA_ECC_CURVE_SECP256K1 );
342 case MBEDTLS_ECP_DP_CURVE448:
343 return( PSA_ECC_CURVE_CURVE448 );
344 default:
345 return( 0 );
346 }
347}
348
Gilles Peskine2d277862018-06-18 15:41:12 +0200349psa_status_t psa_import_key( psa_key_slot_t key,
350 psa_key_type_t type,
351 const uint8_t *data,
352 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100353{
354 key_slot_t *slot;
355
Gilles Peskine828ed142018-06-18 23:25:51 +0200356 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100357 return( PSA_ERROR_INVALID_ARGUMENT );
358 slot = &global_data.key_slots[key];
359 if( slot->type != PSA_KEY_TYPE_NONE )
360 return( PSA_ERROR_OCCUPIED_SLOT );
361
Gilles Peskine8c9def32018-02-08 10:02:12 +0100362 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100363 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100364 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100365 if( data_length > SIZE_MAX / 8 )
366 return( PSA_ERROR_NOT_SUPPORTED );
367 slot->data.raw.data = mbedtls_calloc( 1, data_length );
368 if( slot->data.raw.data == NULL )
369 return( PSA_ERROR_INSUFFICIENT_MEMORY );
370 memcpy( slot->data.raw.data, data, data_length );
371 slot->data.raw.bytes = data_length;
372 }
373 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100374#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100375 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
376 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
377 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100378 {
379 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100380 mbedtls_pk_context pk;
381 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100382 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
383 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
384 else
385 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100386 if( ret != 0 )
387 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100388 switch( mbedtls_pk_get_type( &pk ) )
389 {
390#if defined(MBEDTLS_RSA_C)
391 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100392 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
393 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200394 slot->data.rsa = mbedtls_pk_rsa( pk );
Gilles Peskine969ac722018-01-28 18:16:59 +0100395 else
396 return( PSA_ERROR_INVALID_ARGUMENT );
397 break;
398#endif /* MBEDTLS_RSA_C */
399#if defined(MBEDTLS_ECP_C)
400 case MBEDTLS_PK_ECKEY:
401 if( PSA_KEY_TYPE_IS_ECC( type ) )
402 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200403 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
404 psa_ecc_curve_t actual_curve =
405 mbedtls_ecc_group_to_psa( ecp->grp.id );
406 psa_ecc_curve_t expected_curve =
407 PSA_KEY_TYPE_GET_CURVE( type );
408 if( actual_curve != expected_curve )
409 return( PSA_ERROR_INVALID_ARGUMENT );
410 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100411 }
412 else
413 return( PSA_ERROR_INVALID_ARGUMENT );
414 break;
415#endif /* MBEDTLS_ECP_C */
416 default:
417 return( PSA_ERROR_INVALID_ARGUMENT );
418 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100419 }
420 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100421#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100422 {
423 return( PSA_ERROR_NOT_SUPPORTED );
424 }
425
426 slot->type = type;
427 return( PSA_SUCCESS );
428}
429
Gilles Peskine2d277862018-06-18 15:41:12 +0200430psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100431{
432 key_slot_t *slot;
433
Gilles Peskine828ed142018-06-18 23:25:51 +0200434 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100435 return( PSA_ERROR_INVALID_ARGUMENT );
436 slot = &global_data.key_slots[key];
437 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200438 {
439 /* No key material to clean, but do zeroize the slot below to wipe
440 * metadata such as policies. */
441 }
442 else if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100443 {
444 mbedtls_free( slot->data.raw.data );
445 }
446 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100447#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100448 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
449 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100450 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100451 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100452 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100453 }
454 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100455#endif /* defined(MBEDTLS_RSA_C) */
456#if defined(MBEDTLS_ECP_C)
457 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
458 {
459 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100460 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100461 }
462 else
463#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100464 {
465 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100466 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100467 return( PSA_ERROR_TAMPERING_DETECTED );
468 }
469
470 mbedtls_zeroize( slot, sizeof( *slot ) );
471 return( PSA_SUCCESS );
472}
473
Gilles Peskine2d277862018-06-18 15:41:12 +0200474psa_status_t psa_get_key_information( psa_key_slot_t key,
475 psa_key_type_t *type,
476 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100477{
478 key_slot_t *slot;
479
Gilles Peskine828ed142018-06-18 23:25:51 +0200480 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100481 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100482 slot = &global_data.key_slots[key];
483 if( type != NULL )
484 *type = slot->type;
485 if( bits != NULL )
486 *bits = 0;
487 if( slot->type == PSA_KEY_TYPE_NONE )
488 return( PSA_ERROR_EMPTY_SLOT );
489
Gilles Peskine8c9def32018-02-08 10:02:12 +0100490 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100491 {
492 if( bits != NULL )
493 *bits = slot->data.raw.bytes * 8;
494 }
495 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100496#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100497 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
498 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100499 {
500 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100501 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100502 }
503 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100504#endif /* defined(MBEDTLS_RSA_C) */
505#if defined(MBEDTLS_ECP_C)
506 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
507 {
508 if( bits != NULL )
509 *bits = slot->data.ecp->grp.pbits;
510 }
511 else
512#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100513 {
514 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100515 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100516 return( PSA_ERROR_TAMPERING_DETECTED );
517 }
518
519 return( PSA_SUCCESS );
520}
521
Gilles Peskine2d277862018-06-18 15:41:12 +0200522static psa_status_t psa_internal_export_key( psa_key_slot_t key,
523 uint8_t *data,
524 size_t data_size,
525 size_t *data_length,
526 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100527{
528 key_slot_t *slot;
529
Gilles Peskine828ed142018-06-18 23:25:51 +0200530 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100531 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100532 slot = &global_data.key_slots[key];
533 if( slot->type == PSA_KEY_TYPE_NONE )
534 return( PSA_ERROR_EMPTY_SLOT );
535
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200536 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300537 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300538
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200539 if( ! export_public_key &&
540 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
541 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300542 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200543
Gilles Peskine8c9def32018-02-08 10:02:12 +0100544 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100545 {
546 if( slot->data.raw.bytes > data_size )
547 return( PSA_ERROR_BUFFER_TOO_SMALL );
548 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
549 *data_length = slot->data.raw.bytes;
550 return( PSA_SUCCESS );
551 }
552 else
Moran Peker17e36e12018-05-02 12:55:20 +0300553 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100554#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100555 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300556 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
557 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100558 {
Moran Pekera998bc62018-04-16 18:16:20 +0300559 mbedtls_pk_context pk;
560 int ret;
561 mbedtls_pk_init( &pk );
562 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
563 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
564 {
565 pk.pk_info = &mbedtls_rsa_info;
566 pk.pk_ctx = slot->data.rsa;
567 }
568 else
569 {
570 pk.pk_info = &mbedtls_eckey_info;
571 pk.pk_ctx = slot->data.ecp;
572 }
Moran Pekerd7326592018-05-29 16:56:39 +0300573 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300574 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300575 else
576 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300577 if( ret < 0 )
Moran Pekera998bc62018-04-16 18:16:20 +0300578 return( mbedtls_to_psa_error( ret ) );
579 *data_length = ret;
580 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100581 }
582 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100583#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300584 {
585 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200586 it is valid for a special-purpose implementation to omit
587 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300588 return( PSA_ERROR_NOT_SUPPORTED );
589 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100590 }
591}
592
Gilles Peskine2d277862018-06-18 15:41:12 +0200593psa_status_t psa_export_key( psa_key_slot_t key,
594 uint8_t *data,
595 size_t data_size,
596 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300597{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200598 return( psa_internal_export_key( key, data, data_size,
599 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100600}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100601
Gilles Peskine2d277862018-06-18 15:41:12 +0200602psa_status_t psa_export_public_key( psa_key_slot_t key,
603 uint8_t *data,
604 size_t data_size,
605 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300606{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200607 return( psa_internal_export_key( key, data, data_size,
608 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300609}
610
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200611
612
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100613/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100614/* Message digests */
615/****************************************************************/
616
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100617static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100618{
619 switch( alg )
620 {
621#if defined(MBEDTLS_MD2_C)
622 case PSA_ALG_MD2:
623 return( &mbedtls_md2_info );
624#endif
625#if defined(MBEDTLS_MD4_C)
626 case PSA_ALG_MD4:
627 return( &mbedtls_md4_info );
628#endif
629#if defined(MBEDTLS_MD5_C)
630 case PSA_ALG_MD5:
631 return( &mbedtls_md5_info );
632#endif
633#if defined(MBEDTLS_RIPEMD160_C)
634 case PSA_ALG_RIPEMD160:
635 return( &mbedtls_ripemd160_info );
636#endif
637#if defined(MBEDTLS_SHA1_C)
638 case PSA_ALG_SHA_1:
639 return( &mbedtls_sha1_info );
640#endif
641#if defined(MBEDTLS_SHA256_C)
642 case PSA_ALG_SHA_224:
643 return( &mbedtls_sha224_info );
644 case PSA_ALG_SHA_256:
645 return( &mbedtls_sha256_info );
646#endif
647#if defined(MBEDTLS_SHA512_C)
648 case PSA_ALG_SHA_384:
649 return( &mbedtls_sha384_info );
650 case PSA_ALG_SHA_512:
651 return( &mbedtls_sha512_info );
652#endif
653 default:
654 return( NULL );
655 }
656}
657
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100658psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
659{
660 switch( operation->alg )
661 {
662#if defined(MBEDTLS_MD2_C)
663 case PSA_ALG_MD2:
664 mbedtls_md2_free( &operation->ctx.md2 );
665 break;
666#endif
667#if defined(MBEDTLS_MD4_C)
668 case PSA_ALG_MD4:
669 mbedtls_md4_free( &operation->ctx.md4 );
670 break;
671#endif
672#if defined(MBEDTLS_MD5_C)
673 case PSA_ALG_MD5:
674 mbedtls_md5_free( &operation->ctx.md5 );
675 break;
676#endif
677#if defined(MBEDTLS_RIPEMD160_C)
678 case PSA_ALG_RIPEMD160:
679 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
680 break;
681#endif
682#if defined(MBEDTLS_SHA1_C)
683 case PSA_ALG_SHA_1:
684 mbedtls_sha1_free( &operation->ctx.sha1 );
685 break;
686#endif
687#if defined(MBEDTLS_SHA256_C)
688 case PSA_ALG_SHA_224:
689 case PSA_ALG_SHA_256:
690 mbedtls_sha256_free( &operation->ctx.sha256 );
691 break;
692#endif
693#if defined(MBEDTLS_SHA512_C)
694 case PSA_ALG_SHA_384:
695 case PSA_ALG_SHA_512:
696 mbedtls_sha512_free( &operation->ctx.sha512 );
697 break;
698#endif
699 default:
700 return( PSA_ERROR_NOT_SUPPORTED );
701 }
702 operation->alg = 0;
703 return( PSA_SUCCESS );
704}
705
706psa_status_t psa_hash_start( psa_hash_operation_t *operation,
707 psa_algorithm_t alg )
708{
709 int ret;
710 operation->alg = 0;
711 switch( alg )
712 {
713#if defined(MBEDTLS_MD2_C)
714 case PSA_ALG_MD2:
715 mbedtls_md2_init( &operation->ctx.md2 );
716 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
717 break;
718#endif
719#if defined(MBEDTLS_MD4_C)
720 case PSA_ALG_MD4:
721 mbedtls_md4_init( &operation->ctx.md4 );
722 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
723 break;
724#endif
725#if defined(MBEDTLS_MD5_C)
726 case PSA_ALG_MD5:
727 mbedtls_md5_init( &operation->ctx.md5 );
728 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
729 break;
730#endif
731#if defined(MBEDTLS_RIPEMD160_C)
732 case PSA_ALG_RIPEMD160:
733 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
734 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
735 break;
736#endif
737#if defined(MBEDTLS_SHA1_C)
738 case PSA_ALG_SHA_1:
739 mbedtls_sha1_init( &operation->ctx.sha1 );
740 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
741 break;
742#endif
743#if defined(MBEDTLS_SHA256_C)
744 case PSA_ALG_SHA_224:
745 mbedtls_sha256_init( &operation->ctx.sha256 );
746 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
747 break;
748 case PSA_ALG_SHA_256:
749 mbedtls_sha256_init( &operation->ctx.sha256 );
750 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
751 break;
752#endif
753#if defined(MBEDTLS_SHA512_C)
754 case PSA_ALG_SHA_384:
755 mbedtls_sha512_init( &operation->ctx.sha512 );
756 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
757 break;
758 case PSA_ALG_SHA_512:
759 mbedtls_sha512_init( &operation->ctx.sha512 );
760 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
761 break;
762#endif
763 default:
764 return( PSA_ERROR_NOT_SUPPORTED );
765 }
766 if( ret == 0 )
767 operation->alg = alg;
768 else
769 psa_hash_abort( operation );
770 return( mbedtls_to_psa_error( ret ) );
771}
772
773psa_status_t psa_hash_update( psa_hash_operation_t *operation,
774 const uint8_t *input,
775 size_t input_length )
776{
777 int ret;
778 switch( operation->alg )
779 {
780#if defined(MBEDTLS_MD2_C)
781 case PSA_ALG_MD2:
782 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
783 input, input_length );
784 break;
785#endif
786#if defined(MBEDTLS_MD4_C)
787 case PSA_ALG_MD4:
788 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
789 input, input_length );
790 break;
791#endif
792#if defined(MBEDTLS_MD5_C)
793 case PSA_ALG_MD5:
794 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
795 input, input_length );
796 break;
797#endif
798#if defined(MBEDTLS_RIPEMD160_C)
799 case PSA_ALG_RIPEMD160:
800 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
801 input, input_length );
802 break;
803#endif
804#if defined(MBEDTLS_SHA1_C)
805 case PSA_ALG_SHA_1:
806 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
807 input, input_length );
808 break;
809#endif
810#if defined(MBEDTLS_SHA256_C)
811 case PSA_ALG_SHA_224:
812 case PSA_ALG_SHA_256:
813 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
814 input, input_length );
815 break;
816#endif
817#if defined(MBEDTLS_SHA512_C)
818 case PSA_ALG_SHA_384:
819 case PSA_ALG_SHA_512:
820 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
821 input, input_length );
822 break;
823#endif
824 default:
825 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
826 break;
827 }
828 if( ret != 0 )
829 psa_hash_abort( operation );
830 return( mbedtls_to_psa_error( ret ) );
831}
832
833psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
834 uint8_t *hash,
835 size_t hash_size,
836 size_t *hash_length )
837{
838 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200839 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100840
841 /* Fill the output buffer with something that isn't a valid hash
842 * (barring an attack on the hash and deliberately-crafted input),
843 * in case the caller doesn't check the return status properly. */
844 *hash_length = actual_hash_length;
845 memset( hash, '!', hash_size );
846
847 if( hash_size < actual_hash_length )
848 return( PSA_ERROR_BUFFER_TOO_SMALL );
849
850 switch( operation->alg )
851 {
852#if defined(MBEDTLS_MD2_C)
853 case PSA_ALG_MD2:
854 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
855 break;
856#endif
857#if defined(MBEDTLS_MD4_C)
858 case PSA_ALG_MD4:
859 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
860 break;
861#endif
862#if defined(MBEDTLS_MD5_C)
863 case PSA_ALG_MD5:
864 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
865 break;
866#endif
867#if defined(MBEDTLS_RIPEMD160_C)
868 case PSA_ALG_RIPEMD160:
869 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
870 break;
871#endif
872#if defined(MBEDTLS_SHA1_C)
873 case PSA_ALG_SHA_1:
874 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
875 break;
876#endif
877#if defined(MBEDTLS_SHA256_C)
878 case PSA_ALG_SHA_224:
879 case PSA_ALG_SHA_256:
880 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
881 break;
882#endif
883#if defined(MBEDTLS_SHA512_C)
884 case PSA_ALG_SHA_384:
885 case PSA_ALG_SHA_512:
886 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
887 break;
888#endif
889 default:
890 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
891 break;
892 }
893
894 if( ret == 0 )
895 {
896 return( psa_hash_abort( operation ) );
897 }
898 else
899 {
900 psa_hash_abort( operation );
901 return( mbedtls_to_psa_error( ret ) );
902 }
903}
904
Gilles Peskine2d277862018-06-18 15:41:12 +0200905psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
906 const uint8_t *hash,
907 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100908{
909 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
910 size_t actual_hash_length;
911 psa_status_t status = psa_hash_finish( operation,
912 actual_hash, sizeof( actual_hash ),
913 &actual_hash_length );
914 if( status != PSA_SUCCESS )
915 return( status );
916 if( actual_hash_length != hash_length )
917 return( PSA_ERROR_INVALID_SIGNATURE );
918 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
919 return( PSA_ERROR_INVALID_SIGNATURE );
920 return( PSA_SUCCESS );
921}
922
923
924
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100925/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +0100926/* MAC */
927/****************************************************************/
928
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100929static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +0100930 psa_algorithm_t alg,
931 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +0200932 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +0300933 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100934{
Gilles Peskine8c9def32018-02-08 10:02:12 +0100935 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +0300936 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100937
938 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
939 {
940 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +0200941 {
942 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
943 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +0200944
Nir Sonnenscheine9664c32018-06-17 14:41:30 +0300945 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100946 {
947 case PSA_ALG_STREAM_CIPHER:
948 mode = MBEDTLS_MODE_STREAM;
949 break;
950 case PSA_ALG_CBC_BASE:
951 mode = MBEDTLS_MODE_CBC;
952 break;
953 case PSA_ALG_CFB_BASE:
954 mode = MBEDTLS_MODE_CFB;
955 break;
956 case PSA_ALG_OFB_BASE:
957 mode = MBEDTLS_MODE_OFB;
958 break;
959 case PSA_ALG_CTR:
960 mode = MBEDTLS_MODE_CTR;
961 break;
962 case PSA_ALG_CCM:
963 mode = MBEDTLS_MODE_CCM;
964 break;
965 case PSA_ALG_GCM:
966 mode = MBEDTLS_MODE_GCM;
967 break;
968 default:
969 return( NULL );
970 }
971 }
972 else if( alg == PSA_ALG_CMAC )
973 mode = MBEDTLS_MODE_ECB;
974 else if( alg == PSA_ALG_GMAC )
975 mode = MBEDTLS_MODE_GCM;
976 else
977 return( NULL );
978
979 switch( key_type )
980 {
981 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +0300982 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100983 break;
984 case PSA_KEY_TYPE_DES:
985 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +0300986 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100987 else
mohammad1603f4f0d612018-06-03 15:04:51 +0300988 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100989 break;
990 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +0300991 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100992 break;
993 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +0300994 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100995 break;
996 default:
997 return( NULL );
998 }
mohammad1603f4f0d612018-06-03 15:04:51 +0300999 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001000 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001001
mohammad1603f4f0d612018-06-03 15:04:51 +03001002 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001003}
1004
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001005static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001006{
Gilles Peskine2d277862018-06-18 15:41:12 +02001007 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001008 {
1009 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001010 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001011 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001012 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001013 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001014 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001015 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001016 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001017 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001018 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001019 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001020 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001021 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001022 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001023 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001024 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001025 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001026 return( 128 );
1027 default:
1028 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001029 }
1030}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001031
Gilles Peskine8c9def32018-02-08 10:02:12 +01001032psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1033{
1034 switch( operation->alg )
1035 {
1036#if defined(MBEDTLS_CMAC_C)
1037 case PSA_ALG_CMAC:
1038 mbedtls_cipher_free( &operation->ctx.cmac );
1039 break;
1040#endif /* MBEDTLS_CMAC_C */
1041 default:
1042#if defined(MBEDTLS_MD_C)
1043 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001044 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001045 unsigned int block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001046 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001047
Gilles Peskine99bc6492018-06-11 17:13:00 +02001048 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001049 return( PSA_ERROR_NOT_SUPPORTED );
1050
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001051 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001052 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001053 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001054 else
1055#endif /* MBEDTLS_MD_C */
1056 return( PSA_ERROR_NOT_SUPPORTED );
1057 }
Moran Peker41deec42018-04-04 15:43:05 +03001058
Gilles Peskine8c9def32018-02-08 10:02:12 +01001059 operation->alg = 0;
1060 operation->key_set = 0;
1061 operation->iv_set = 0;
1062 operation->iv_required = 0;
1063 operation->has_input = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001064
Gilles Peskine8c9def32018-02-08 10:02:12 +01001065 return( PSA_SUCCESS );
1066}
1067
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001068#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001069static int psa_cmac_start( psa_mac_operation_t *operation,
1070 size_t key_bits,
1071 key_slot_t *slot,
1072 const mbedtls_cipher_info_t *cipher_info )
1073{
1074 int ret;
1075
1076 operation->mac_size = cipher_info->block_size;
1077 operation->iv_required = 0;
1078 mbedtls_cipher_init( &operation->ctx.cmac );
1079
1080 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1081 if( ret != 0 )
1082 return( ret );
1083
1084 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1085 slot->data.raw.data,
1086 key_bits );
1087 return( ret );
1088}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001089#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001090
1091static int psa_hmac_start( psa_mac_operation_t *operation,
1092 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001093 key_slot_t *slot,
1094 psa_algorithm_t alg )
1095{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001096 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001097 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001098 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001099 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001100 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001101 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001102 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001103 size_t key_length = slot->data.raw.bytes;
1104 psa_status_t status;
1105
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001106 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001107 return( PSA_ERROR_NOT_SUPPORTED );
1108
1109 if( key_type != PSA_KEY_TYPE_HMAC )
1110 return( PSA_ERROR_INVALID_ARGUMENT );
1111
1112 operation->iv_required = 0;
1113 operation->mac_size = digest_size;
1114
1115 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1116 PSA_ALG_HMAC_HASH( alg ) );
1117 if( status != PSA_SUCCESS )
1118 return( status );
1119
Gilles Peskined223b522018-06-11 18:12:58 +02001120 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001121 {
1122 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001123 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001124 if( status != PSA_SUCCESS )
1125 return( status );
1126 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001127 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001128 if( status != PSA_SUCCESS )
1129 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001130 }
Gilles Peskined223b522018-06-11 18:12:58 +02001131 else
1132 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001133
Gilles Peskined223b522018-06-11 18:12:58 +02001134 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1135 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001136 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001137 ipad[i] ^= 0x36;
1138 memset( ipad + key_length, 0x36, block_size - key_length );
1139
1140 /* Copy the key material from ipad to opad, flipping the requisite bits,
1141 * and filling the rest of opad with the requisite constant. */
1142 for( i = 0; i < key_length; i++ )
1143 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1144 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001145
1146 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1147 PSA_ALG_HMAC_HASH( alg ) );
1148 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001149 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001150
1151 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1152 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001153
1154cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001155 mbedtls_zeroize( ipad, key_length );
1156 /* opad is in the context. It needs to stay in memory if this function
1157 * succeeds, and it will be wiped by psa_mac_abort() called from
1158 * psa_mac_start in the error case. */
1159
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001160 return( status );
1161}
1162
Gilles Peskine8c9def32018-02-08 10:02:12 +01001163psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1164 psa_key_slot_t key,
1165 psa_algorithm_t alg )
1166{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001167 psa_status_t status;
1168 key_slot_t *slot;
1169 psa_key_type_t key_type;
1170 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001171 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001172
1173 operation->alg = 0;
1174 operation->key_set = 0;
1175 operation->iv_set = 0;
1176 operation->iv_required = 1;
1177 operation->has_input = 0;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001178 operation->key_usage_sign = 0;
1179 operation->key_usage_verify = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001180
1181 status = psa_get_key_information( key, &key_type, &key_bits );
1182 if( status != PSA_SUCCESS )
1183 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001184
Gilles Peskine8c9def32018-02-08 10:02:12 +01001185 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001186 if( slot->type == PSA_KEY_TYPE_NONE )
1187 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001188
Moran Pekerd7326592018-05-29 16:56:39 +03001189 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001190 operation->key_usage_sign = 1;
1191
Moran Pekerd7326592018-05-29 16:56:39 +03001192 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001193 operation->key_usage_verify = 1;
1194
Gilles Peskine8c9def32018-02-08 10:02:12 +01001195 if( ! PSA_ALG_IS_HMAC( alg ) )
1196 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001197 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001198 if( cipher_info == NULL )
1199 return( PSA_ERROR_NOT_SUPPORTED );
1200 operation->mac_size = cipher_info->block_size;
1201 }
1202 switch( alg )
1203 {
1204#if defined(MBEDTLS_CMAC_C)
1205 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001206 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1207 key_bits,
1208 slot,
1209 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001210 break;
1211#endif /* MBEDTLS_CMAC_C */
1212 default:
1213#if defined(MBEDTLS_MD_C)
1214 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001215 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001216 else
1217#endif /* MBEDTLS_MD_C */
1218 return( PSA_ERROR_NOT_SUPPORTED );
1219 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001220
Gilles Peskine8c9def32018-02-08 10:02:12 +01001221 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001222
1223 * context may contain data that needs to be wiped on error. */
1224 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001225 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001226 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001227 }
Gilles Peskine99bc6492018-06-11 17:13:00 +02001228
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001229 else
1230 {
1231 operation->alg = alg;
1232 operation->key_set = 1;
1233 }
1234 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001235}
1236
1237psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1238 const uint8_t *input,
1239 size_t input_length )
1240{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001241 int ret = 0 ;
1242 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001243 if( ! operation->key_set )
1244 return( PSA_ERROR_BAD_STATE );
1245 if( operation->iv_required && ! operation->iv_set )
1246 return( PSA_ERROR_BAD_STATE );
1247 operation->has_input = 1;
1248
1249 switch( operation->alg )
1250 {
1251#if defined(MBEDTLS_CMAC_C)
1252 case PSA_ALG_CMAC:
1253 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1254 input, input_length );
1255 break;
1256#endif /* MBEDTLS_CMAC_C */
1257 default:
1258#if defined(MBEDTLS_MD_C)
1259 if( PSA_ALG_IS_HMAC( operation->alg ) )
1260 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001261 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001262 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001263 }
1264 else
1265#endif /* MBEDTLS_MD_C */
1266 {
1267 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1268 }
1269 break;
1270 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001271 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001272 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001273 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001274 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001275 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001276 }
1277
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001278 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001279}
1280
mohammad16036df908f2018-04-02 08:34:15 -07001281static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001282 uint8_t *mac,
1283 size_t mac_size,
1284 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001285{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001286 int ret = 0;
1287 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001288 if( ! operation->key_set )
1289 return( PSA_ERROR_BAD_STATE );
1290 if( operation->iv_required && ! operation->iv_set )
1291 return( PSA_ERROR_BAD_STATE );
1292
1293 /* Fill the output buffer with something that isn't a valid mac
1294 * (barring an attack on the mac and deliberately-crafted input),
1295 * in case the caller doesn't check the return status properly. */
1296 *mac_length = operation->mac_size;
1297 memset( mac, '!', mac_size );
1298
1299 if( mac_size < operation->mac_size )
1300 return( PSA_ERROR_BUFFER_TOO_SMALL );
1301
1302 switch( operation->alg )
1303 {
1304#if defined(MBEDTLS_CMAC_C)
1305 case PSA_ALG_CMAC:
1306 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1307 break;
1308#endif /* MBEDTLS_CMAC_C */
1309 default:
1310#if defined(MBEDTLS_MD_C)
1311 if( PSA_ALG_IS_HMAC( operation->alg ) )
1312 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001313 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001314 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001315 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001316 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001317 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001318
Gilles Peskine99bc6492018-06-11 17:13:00 +02001319 if( block_size == 0 )
1320 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001321
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001322 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001323 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001324 if( status != PSA_SUCCESS )
1325 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001326 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001327
1328 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1329 PSA_ALG_HMAC_HASH( operation->alg ) );
1330 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001331 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001332
1333 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001334 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001335 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001336 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001337
1338 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001339 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001340 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001341 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001342
1343 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1344 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001345 hmac_cleanup:
1346 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001347 }
1348 else
1349#endif /* MBEDTLS_MD_C */
1350 {
1351 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1352 }
1353 break;
1354 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001355cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001356
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001357 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001358 {
1359 return( psa_mac_abort( operation ) );
1360 }
1361 else
1362 {
1363 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001364 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001365 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001366
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001367 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001368 }
1369}
1370
mohammad16036df908f2018-04-02 08:34:15 -07001371psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1372 uint8_t *mac,
1373 size_t mac_size,
1374 size_t *mac_length )
1375{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001376 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001377 return( PSA_ERROR_NOT_PERMITTED );
1378
Gilles Peskine99bc6492018-06-11 17:13:00 +02001379 return( psa_mac_finish_internal( operation, mac,
1380 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001381}
1382
Gilles Peskine828ed142018-06-18 23:25:51 +02001383#define PSA_MAC_MAX_SIZE \
Gilles Peskine2d277862018-06-18 15:41:12 +02001384 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1385 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001386 MBEDTLS_MAX_BLOCK_LENGTH )
1387psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1388 const uint8_t *mac,
1389 size_t mac_length )
1390{
Gilles Peskine828ed142018-06-18 23:25:51 +02001391 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001392 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001393 psa_status_t status;
1394
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001395 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001396 return( PSA_ERROR_NOT_PERMITTED );
1397
1398 status = psa_mac_finish_internal( operation,
1399 actual_mac, sizeof( actual_mac ),
1400 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001401 if( status != PSA_SUCCESS )
1402 return( status );
1403 if( actual_mac_length != mac_length )
1404 return( PSA_ERROR_INVALID_SIGNATURE );
1405 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1406 return( PSA_ERROR_INVALID_SIGNATURE );
1407 return( PSA_SUCCESS );
1408}
1409
1410
Gilles Peskine20035e32018-02-03 22:44:14 +01001411
Gilles Peskine20035e32018-02-03 22:44:14 +01001412/****************************************************************/
1413/* Asymmetric cryptography */
1414/****************************************************************/
1415
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001416/* Decode the hash algorithm from alg and store the mbedtls encoding in
1417 * md_alg. Verify that the hash length is consistent. */
1418static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1419 size_t hash_length,
1420 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001421{
Gilles Peskine61b91d42018-06-08 16:09:36 +02001422 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
1423 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1424 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1425 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001426 {
1427#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001428 if( hash_length > UINT_MAX )
1429 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001430#endif
1431 }
1432 else
1433 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001434 if( mbedtls_md_get_size( md_info ) != hash_length )
1435 return( PSA_ERROR_INVALID_ARGUMENT );
1436 if( md_info == NULL )
1437 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001438 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001439 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001440}
1441
Gilles Peskine61b91d42018-06-08 16:09:36 +02001442psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1443 psa_algorithm_t alg,
1444 const uint8_t *hash,
1445 size_t hash_length,
1446 const uint8_t *salt,
1447 size_t salt_length,
1448 uint8_t *signature,
1449 size_t signature_size,
1450 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001451{
1452 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001453 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001454 *signature_length = 0;
1455 (void) salt;
1456 (void) salt_length;
1457
Gilles Peskine828ed142018-06-18 23:25:51 +02001458 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine20035e32018-02-03 22:44:14 +01001459 return( PSA_ERROR_EMPTY_SLOT );
1460 slot = &global_data.key_slots[key];
1461 if( slot->type == PSA_KEY_TYPE_NONE )
1462 return( PSA_ERROR_EMPTY_SLOT );
1463 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1464 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001465 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001466 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001467
Gilles Peskine20035e32018-02-03 22:44:14 +01001468#if defined(MBEDTLS_RSA_C)
1469 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1470 {
1471 mbedtls_rsa_context *rsa = slot->data.rsa;
1472 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001473 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001474 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001475 if( status != PSA_SUCCESS )
1476 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001477
Gilles Peskine20035e32018-02-03 22:44:14 +01001478 if( signature_size < rsa->len )
1479 return( PSA_ERROR_BUFFER_TOO_SMALL );
1480#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001481 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001482 {
1483 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1484 MBEDTLS_MD_NONE );
1485 ret = mbedtls_rsa_pkcs1_sign( rsa,
1486 mbedtls_ctr_drbg_random,
1487 &global_data.ctr_drbg,
1488 MBEDTLS_RSA_PRIVATE,
1489 md_alg, hash_length, hash,
1490 signature );
1491 }
1492 else
1493#endif /* MBEDTLS_PKCS1_V15 */
1494#if defined(MBEDTLS_PKCS1_V21)
1495 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1496 {
1497 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1498 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1499 mbedtls_ctr_drbg_random,
1500 &global_data.ctr_drbg,
1501 MBEDTLS_RSA_PRIVATE,
1502 md_alg, hash_length, hash,
1503 signature );
1504 }
1505 else
1506#endif /* MBEDTLS_PKCS1_V21 */
1507 {
1508 return( PSA_ERROR_INVALID_ARGUMENT );
1509 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001510 if( ret == 0 )
1511 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001512 return( mbedtls_to_psa_error( ret ) );
1513 }
1514 else
1515#endif /* defined(MBEDTLS_RSA_C) */
1516#if defined(MBEDTLS_ECP_C)
1517 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1518 {
itayzafrir5c753392018-05-08 11:18:38 +03001519 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1520 int ret;
1521 const mbedtls_md_info_t *md_info;
1522 mbedtls_md_type_t md_alg;
1523 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1524 return( PSA_ERROR_BUFFER_TOO_SMALL );
1525 md_info = mbedtls_md_info_from_psa( alg );
1526 md_alg = mbedtls_md_get_type( md_info );
1527 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001528 signature, signature_length,
1529 mbedtls_ctr_drbg_random,
1530 &global_data.ctr_drbg );
itayzafrir5c753392018-05-08 11:18:38 +03001531 return( mbedtls_to_psa_error( ret ) );
1532 }
1533 else
1534#endif /* defined(MBEDTLS_ECP_C) */
1535 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001536 return( PSA_ERROR_NOT_SUPPORTED );
1537 }
itayzafrir5c753392018-05-08 11:18:38 +03001538}
1539
1540psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1541 psa_algorithm_t alg,
1542 const uint8_t *hash,
1543 size_t hash_length,
1544 const uint8_t *salt,
1545 size_t salt_length,
1546 uint8_t *signature,
1547 size_t signature_size )
1548{
1549 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001550 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001551 (void) salt;
1552 (void) salt_length;
1553
Gilles Peskine828ed142018-06-18 23:25:51 +02001554 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001555 return( PSA_ERROR_INVALID_ARGUMENT );
1556 slot = &global_data.key_slots[key];
1557 if( slot->type == PSA_KEY_TYPE_NONE )
1558 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001559 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001560 return( PSA_ERROR_NOT_PERMITTED );
1561
Gilles Peskine61b91d42018-06-08 16:09:36 +02001562#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001563 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1564 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001565 {
1566 mbedtls_rsa_context *rsa = slot->data.rsa;
1567 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001568 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001569 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001570 if( status != PSA_SUCCESS )
1571 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001572
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001573 if( signature_size < rsa->len )
1574 return( PSA_ERROR_BUFFER_TOO_SMALL );
1575#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001576 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001577 {
1578 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1579 MBEDTLS_MD_NONE );
1580
1581 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001582 mbedtls_ctr_drbg_random,
1583 &global_data.ctr_drbg,
1584 MBEDTLS_RSA_PUBLIC,
1585 md_alg,
1586 hash_length,
1587 hash,
1588 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001589
1590 }
1591 else
1592#endif /* MBEDTLS_PKCS1_V15 */
1593#if defined(MBEDTLS_PKCS1_V21)
1594 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1595 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001596 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1597 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1598 mbedtls_ctr_drbg_random,
1599 &global_data.ctr_drbg,
1600 MBEDTLS_RSA_PUBLIC,
1601 md_alg, hash_length, hash,
1602 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001603 }
1604 else
1605#endif /* MBEDTLS_PKCS1_V21 */
1606 {
1607 return( PSA_ERROR_INVALID_ARGUMENT );
1608 }
1609 return( mbedtls_to_psa_error( ret ) );
1610 }
1611 else
1612#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001613#if defined(MBEDTLS_ECP_C)
1614 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1615 {
1616 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1617 int ret;
Gilles Peskine2d277862018-06-18 15:41:12 +02001618 (void) alg;
Gilles Peskine61b91d42018-06-08 16:09:36 +02001619 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length,
1620 signature, signature_size );
itayzafrir5c753392018-05-08 11:18:38 +03001621 return( mbedtls_to_psa_error( ret ) );
1622 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001623 else
1624#endif /* defined(MBEDTLS_ECP_C) */
1625 {
1626 return( PSA_ERROR_NOT_SUPPORTED );
1627 }
1628}
1629
Gilles Peskine61b91d42018-06-08 16:09:36 +02001630psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1631 psa_algorithm_t alg,
1632 const uint8_t *input,
1633 size_t input_length,
1634 const uint8_t *salt,
1635 size_t salt_length,
1636 uint8_t *output,
1637 size_t output_size,
1638 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001639{
1640 key_slot_t *slot;
1641 (void) salt;
1642 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001643 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001644
Gilles Peskine828ed142018-06-18 23:25:51 +02001645 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001646 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001647 slot = &global_data.key_slots[key];
1648 if( slot->type == PSA_KEY_TYPE_NONE )
1649 return( PSA_ERROR_EMPTY_SLOT );
1650 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1651 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001652 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1653 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001654
1655#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001656 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1657 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001658 {
1659 mbedtls_rsa_context *rsa = slot->data.rsa;
1660 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001661 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001662 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001663#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001664 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001665 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001666 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1667 mbedtls_ctr_drbg_random,
1668 &global_data.ctr_drbg,
1669 MBEDTLS_RSA_PUBLIC,
1670 input_length,
1671 input,
1672 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001673 }
1674 else
1675#endif /* MBEDTLS_PKCS1_V15 */
1676#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001677 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001678 {
1679 return( PSA_ERROR_NOT_SUPPORTED );
1680 }
1681 else
1682#endif /* MBEDTLS_PKCS1_V21 */
1683 {
1684 return( PSA_ERROR_INVALID_ARGUMENT );
1685 }
1686 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001687 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001688 return( mbedtls_to_psa_error( ret ) );
1689 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001690 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001691#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001692 {
1693 return( PSA_ERROR_NOT_SUPPORTED );
1694 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001695}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001696
Gilles Peskine61b91d42018-06-08 16:09:36 +02001697psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1698 psa_algorithm_t alg,
1699 const uint8_t *input,
1700 size_t input_length,
1701 const uint8_t *salt,
1702 size_t salt_length,
1703 uint8_t *output,
1704 size_t output_size,
1705 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001706{
1707 key_slot_t *slot;
1708 (void) salt;
1709 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001710 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001711
Gilles Peskine828ed142018-06-18 23:25:51 +02001712 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001713 return( PSA_ERROR_EMPTY_SLOT );
1714 slot = &global_data.key_slots[key];
1715 if( slot->type == PSA_KEY_TYPE_NONE )
1716 return( PSA_ERROR_EMPTY_SLOT );
1717 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1718 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001719 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1720 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001721
1722#if defined(MBEDTLS_RSA_C)
1723 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1724 {
1725 mbedtls_rsa_context *rsa = slot->data.rsa;
1726 int ret;
1727
Gilles Peskinec4def2f2018-06-08 17:53:48 +02001728 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001729 return( PSA_ERROR_INVALID_ARGUMENT );
1730
1731#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001732 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001733 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001734 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
1735 mbedtls_ctr_drbg_random,
1736 &global_data.ctr_drbg,
1737 MBEDTLS_RSA_PRIVATE,
1738 output_length,
1739 input,
1740 output,
1741 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001742 }
1743 else
1744#endif /* MBEDTLS_PKCS1_V15 */
1745#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001746 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001747 {
1748 return( PSA_ERROR_NOT_SUPPORTED );
1749 }
1750 else
1751#endif /* MBEDTLS_PKCS1_V21 */
1752 {
1753 return( PSA_ERROR_INVALID_ARGUMENT );
1754 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001755
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001756 return( mbedtls_to_psa_error( ret ) );
1757 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001758 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001759#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001760 {
1761 return( PSA_ERROR_NOT_SUPPORTED );
1762 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001763}
Gilles Peskine20035e32018-02-03 22:44:14 +01001764
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001765
1766
mohammad1603503973b2018-03-12 15:59:30 +02001767/****************************************************************/
1768/* Symmetric cryptography */
1769/****************************************************************/
1770
Gilles Peskinee553c652018-06-04 16:22:46 +02001771static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1772 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001773 psa_algorithm_t alg,
1774 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001775{
1776 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1777 psa_status_t status;
1778 key_slot_t *slot;
1779 psa_key_type_t key_type;
1780 size_t key_bits;
1781 const mbedtls_cipher_info_t *cipher_info = NULL;
1782
Moran Peker41deec42018-04-04 15:43:05 +03001783 operation->alg = alg;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001784 operation->key_set = 0;
1785 operation->iv_set = 0;
1786 operation->iv_required = 1;
1787 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001788 operation->block_size = 0;
mohammad1603503973b2018-03-12 15:59:30 +02001789
1790 status = psa_get_key_information( key, &key_type, &key_bits );
1791 if( status != PSA_SUCCESS )
1792 return( status );
1793 slot = &global_data.key_slots[key];
1794
Gilles Peskinebb1072f2018-06-08 18:46:05 +02001795 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02001796 if( cipher_info == NULL )
1797 return( PSA_ERROR_NOT_SUPPORTED );
1798
mohammad1603503973b2018-03-12 15:59:30 +02001799 mbedtls_cipher_init( &operation->ctx.cipher );
1800 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03001801 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001802 {
1803 psa_cipher_abort( operation );
1804 return( mbedtls_to_psa_error( ret ) );
1805 }
1806
1807 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
Gilles Peskinee553c652018-06-04 16:22:46 +02001808 key_bits, cipher_operation );
Moran Peker41deec42018-04-04 15:43:05 +03001809 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001810 {
1811 psa_cipher_abort( operation );
1812 return( mbedtls_to_psa_error( ret ) );
1813 }
1814
mohammad16038481e742018-03-18 13:57:31 +02001815#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03001816 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02001817 {
Gilles Peskine53514202018-06-06 15:11:46 +02001818 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1819 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02001820
Moran Pekera28258c2018-05-29 16:25:04 +03001821 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02001822 {
1823 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
1824 mode = MBEDTLS_PADDING_PKCS7;
1825 break;
1826 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
1827 mode = MBEDTLS_PADDING_NONE;
1828 break;
1829 default:
Moran Pekerae382792018-05-31 14:06:17 +03001830 psa_cipher_abort( operation );
1831 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02001832 }
1833 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03001834 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03001835 {
1836 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02001837 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03001838 }
mohammad16038481e742018-03-18 13:57:31 +02001839 }
1840#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
1841
mohammad1603503973b2018-03-12 15:59:30 +02001842 operation->key_set = 1;
1843 operation->alg = alg;
Gilles Peskine7e928852018-06-04 16:23:10 +02001844 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
1845 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
1846 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001847 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02001848 {
mohammad160389e0f462018-04-12 08:48:45 +03001849 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02001850 }
mohammad1603503973b2018-03-12 15:59:30 +02001851
Moran Peker395db872018-05-31 14:07:14 +03001852 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001853}
1854
Gilles Peskinee553c652018-06-04 16:22:46 +02001855psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
1856 psa_key_slot_t key,
1857 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001858{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001859 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001860}
1861
Gilles Peskinee553c652018-06-04 16:22:46 +02001862psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
1863 psa_key_slot_t key,
1864 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001865{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001866 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001867}
1868
Gilles Peskinee553c652018-06-04 16:22:46 +02001869psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
1870 unsigned char *iv,
1871 size_t iv_size,
1872 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001873{
Moran Peker41deec42018-04-04 15:43:05 +03001874 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001875 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001876 return( PSA_ERROR_BAD_STATE );
1877 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02001878 {
Moran Peker41deec42018-04-04 15:43:05 +03001879 ret = PSA_ERROR_BUFFER_TOO_SMALL;
1880 goto exit;
1881 }
Gilles Peskine7e928852018-06-04 16:23:10 +02001882 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
1883 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03001884 if( ret != 0 )
1885 {
1886 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02001887 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02001888 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001889
mohammad16038481e742018-03-18 13:57:31 +02001890 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03001891 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001892
Moran Peker395db872018-05-31 14:07:14 +03001893exit:
1894 if( ret != PSA_SUCCESS )
1895 psa_cipher_abort( operation );
1896 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02001897}
1898
Gilles Peskinee553c652018-06-04 16:22:46 +02001899psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
1900 const unsigned char *iv,
1901 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001902{
Moran Peker41deec42018-04-04 15:43:05 +03001903 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001904 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001905 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03001906 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03001907 {
Moran Pekerae382792018-05-31 14:06:17 +03001908 psa_cipher_abort( operation );
1909 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03001910 }
mohammad1603503973b2018-03-12 15:59:30 +02001911 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001912 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001913 {
1914 psa_cipher_abort( operation );
1915 return( mbedtls_to_psa_error( ret ) );
1916 }
1917
1918 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02001919
Moran Peker395db872018-05-31 14:07:14 +03001920 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001921}
1922
Gilles Peskinee553c652018-06-04 16:22:46 +02001923psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
1924 const uint8_t *input,
1925 size_t input_length,
1926 unsigned char *output,
1927 size_t output_size,
1928 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001929{
1930 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02001931 size_t expected_output_size;
1932 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
1933 {
1934 /* Take the unprocessed partial block left over from previous
1935 * update calls, if any, plus the input to this call. Remove
1936 * the last partial block, if any. You get the data that will be
1937 * output in this call. */
1938 expected_output_size =
1939 ( operation->ctx.cipher.unprocessed_len + input_length )
1940 / operation->block_size * operation->block_size;
1941 }
1942 else
1943 {
1944 expected_output_size = input_length;
1945 }
1946 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03001947 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02001948
mohammad1603503973b2018-03-12 15:59:30 +02001949 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02001950 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03001951 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001952 {
1953 psa_cipher_abort( operation );
1954 return( mbedtls_to_psa_error( ret ) );
1955 }
1956
Moran Peker395db872018-05-31 14:07:14 +03001957 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001958}
1959
Gilles Peskinee553c652018-06-04 16:22:46 +02001960psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
1961 uint8_t *output,
1962 size_t output_size,
1963 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001964{
1965 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02001966 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03001967
mohammad1603503973b2018-03-12 15:59:30 +02001968 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001969 {
Moran Peker7cb22b82018-06-05 11:40:02 +03001970 psa_cipher_abort( operation );
1971 return( PSA_ERROR_BAD_STATE );
1972 }
1973 if( operation->iv_required && ! operation->iv_set )
1974 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001975 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001976 return( PSA_ERROR_BAD_STATE );
1977 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001978 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
1979 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03001980 {
Gilles Peskine53514202018-06-06 15:11:46 +02001981 psa_algorithm_t padding_mode =
1982 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03001983 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02001984 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001985 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001986 return( PSA_ERROR_TAMPERING_DETECTED );
1987 }
Gilles Peskine53514202018-06-06 15:11:46 +02001988 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03001989 {
1990 if( operation->ctx.cipher.unprocessed_len != 0 )
1991 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001992 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001993 return( PSA_ERROR_INVALID_ARGUMENT );
1994 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02001995 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001996 }
1997
1998 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02001999 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002000 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002001 {
2002 psa_cipher_abort( operation );
2003 return( mbedtls_to_psa_error( ret ) );
2004 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002005 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002006 memcpy( output, temp_output_buffer, *output_length );
2007 else
2008 {
2009 psa_cipher_abort( operation );
2010 return( PSA_ERROR_BUFFER_TOO_SMALL );
2011 }
mohammad1603503973b2018-03-12 15:59:30 +02002012
Moran Peker4c80d832018-04-22 20:15:31 +03002013 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002014}
2015
Gilles Peskinee553c652018-06-04 16:22:46 +02002016psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2017{
mohammad1603503973b2018-03-12 15:59:30 +02002018 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002019
Moran Peker41deec42018-04-04 15:43:05 +03002020 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002021 operation->key_set = 0;
2022 operation->iv_set = 0;
2023 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002024 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002025 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002026
Moran Peker395db872018-05-31 14:07:14 +03002027 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002028}
2029
Gilles Peskinea0655c32018-04-30 17:06:50 +02002030
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002031
mohammad16038cc1cee2018-03-28 01:21:33 +03002032/****************************************************************/
2033/* Key Policy */
2034/****************************************************************/
2035
Gilles Peskine2d277862018-06-18 15:41:12 +02002036void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002037{
Gilles Peskine803ce742018-06-18 16:07:14 +02002038 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002039}
2040
Gilles Peskine2d277862018-06-18 15:41:12 +02002041void psa_key_policy_set_usage( psa_key_policy_t *policy,
2042 psa_key_usage_t usage,
2043 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002044{
mohammad16034eed7572018-03-28 05:14:59 -07002045 policy->usage = usage;
2046 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002047}
2048
Gilles Peskine2d277862018-06-18 15:41:12 +02002049psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002050{
mohammad16036df908f2018-04-02 08:34:15 -07002051 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002052}
2053
Gilles Peskine2d277862018-06-18 15:41:12 +02002054psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002055{
mohammad16036df908f2018-04-02 08:34:15 -07002056 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002057}
2058
Gilles Peskine2d277862018-06-18 15:41:12 +02002059psa_status_t psa_set_key_policy( psa_key_slot_t key,
2060 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002061{
2062 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002063
Gilles Peskine828ed142018-06-18 23:25:51 +02002064 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002065 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002066
mohammad16038cc1cee2018-03-28 01:21:33 +03002067 slot = &global_data.key_slots[key];
2068 if( slot->type != PSA_KEY_TYPE_NONE )
2069 return( PSA_ERROR_OCCUPIED_SLOT );
2070
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002071 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2072 PSA_KEY_USAGE_ENCRYPT |
2073 PSA_KEY_USAGE_DECRYPT |
2074 PSA_KEY_USAGE_SIGN |
2075 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002076 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002077
mohammad16036df908f2018-04-02 08:34:15 -07002078 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002079
2080 return( PSA_SUCCESS );
2081}
2082
Gilles Peskine2d277862018-06-18 15:41:12 +02002083psa_status_t psa_get_key_policy( psa_key_slot_t key,
2084 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002085{
2086 key_slot_t *slot;
2087
Gilles Peskine828ed142018-06-18 23:25:51 +02002088 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002089 return( PSA_ERROR_INVALID_ARGUMENT );
2090
2091 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002092
mohammad16036df908f2018-04-02 08:34:15 -07002093 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002094
2095 return( PSA_SUCCESS );
2096}
Gilles Peskine20035e32018-02-03 22:44:14 +01002097
Gilles Peskinea0655c32018-04-30 17:06:50 +02002098
2099
mohammad1603804cd712018-03-20 22:44:08 +02002100/****************************************************************/
2101/* Key Lifetime */
2102/****************************************************************/
2103
Gilles Peskine2d277862018-06-18 15:41:12 +02002104psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2105 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002106{
2107 key_slot_t *slot;
2108
Gilles Peskine828ed142018-06-18 23:25:51 +02002109 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002110 return( PSA_ERROR_INVALID_ARGUMENT );
2111
2112 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002113
mohammad1603804cd712018-03-20 22:44:08 +02002114 *lifetime = slot->lifetime;
2115
2116 return( PSA_SUCCESS );
2117}
2118
Gilles Peskine2d277862018-06-18 15:41:12 +02002119psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2120 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002121{
2122 key_slot_t *slot;
2123
Gilles Peskine828ed142018-06-18 23:25:51 +02002124 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002125 return( PSA_ERROR_INVALID_ARGUMENT );
2126
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002127 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2128 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002129 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2130 return( PSA_ERROR_INVALID_ARGUMENT );
2131
mohammad1603804cd712018-03-20 22:44:08 +02002132 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002133 if( slot->type != PSA_KEY_TYPE_NONE )
2134 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002135
Moran Pekerd7326592018-05-29 16:56:39 +03002136 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002137 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002138
mohammad1603060ad8a2018-03-20 14:28:38 -07002139 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002140
2141 return( PSA_SUCCESS );
2142}
2143
Gilles Peskine20035e32018-02-03 22:44:14 +01002144
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002145
mohammad16035955c982018-04-26 00:53:03 +03002146/****************************************************************/
2147/* AEAD */
2148/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002149
mohammad16035955c982018-04-26 00:53:03 +03002150psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2151 psa_algorithm_t alg,
2152 const uint8_t *nonce,
2153 size_t nonce_length,
2154 const uint8_t *additional_data,
2155 size_t additional_data_length,
2156 const uint8_t *plaintext,
2157 size_t plaintext_length,
2158 uint8_t *ciphertext,
2159 size_t ciphertext_size,
2160 size_t *ciphertext_length )
2161{
2162 int ret;
2163 psa_status_t status;
2164 key_slot_t *slot;
2165 psa_key_type_t key_type;
2166 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002167 uint8_t *tag;
2168 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002169 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002170 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002171
mohammad1603f08a5502018-06-03 15:05:47 +03002172 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002173
mohammad16035955c982018-04-26 00:53:03 +03002174 status = psa_get_key_information( key, &key_type, &key_bits );
2175 if( status != PSA_SUCCESS )
2176 return( status );
2177 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002178 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002179 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002180
mohammad16035ed06212018-06-06 13:09:34 +03002181 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2182 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002183 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002184 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002185
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002186 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002187 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002188
Gilles Peskine2d277862018-06-18 15:41:12 +02002189 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2190 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002191 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002192
mohammad16035955c982018-04-26 00:53:03 +03002193 if( alg == PSA_ALG_GCM )
2194 {
2195 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002196 tag_length = 16;
2197
mohammad160396910d82018-06-04 14:33:00 +03002198 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2199 return( PSA_ERROR_INVALID_ARGUMENT );
2200
mohammad160315223a82018-06-03 17:19:55 +03002201 //make sure we have place to hold the tag in the ciphertext buffer
2202 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002203 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002204
2205 //update the tag pointer to point to the end of the ciphertext_length
2206 tag = ciphertext + plaintext_length;
2207
mohammad16035955c982018-04-26 00:53:03 +03002208 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002209 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002210 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002211 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002212 if( ret != 0 )
2213 {
2214 mbedtls_gcm_free( &gcm );
2215 return( mbedtls_to_psa_error( ret ) );
2216 }
2217 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002218 plaintext_length, nonce,
2219 nonce_length, additional_data,
2220 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002221 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002222 mbedtls_gcm_free( &gcm );
2223 }
2224 else if( alg == PSA_ALG_CCM )
2225 {
2226 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002227 tag_length = 16;
2228
mohammad160396910d82018-06-04 14:33:00 +03002229 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2230 return( PSA_ERROR_INVALID_ARGUMENT );
2231
mohammad160347ddf3d2018-04-26 01:11:21 +03002232 if( nonce_length < 7 || nonce_length > 13 )
2233 return( PSA_ERROR_INVALID_ARGUMENT );
2234
mohammad160315223a82018-06-03 17:19:55 +03002235 //make sure we have place to hold the tag in the ciphertext buffer
2236 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002237 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002238
2239 //update the tag pointer to point to the end of the ciphertext_length
2240 tag = ciphertext + plaintext_length;
2241
mohammad16035955c982018-04-26 00:53:03 +03002242 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002243 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002244 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002245 if( ret != 0 )
2246 {
2247 mbedtls_ccm_free( &ccm );
2248 return( mbedtls_to_psa_error( ret ) );
2249 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002250 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002251 nonce, nonce_length,
2252 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002253 additional_data_length,
2254 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002255 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002256 mbedtls_ccm_free( &ccm );
2257 }
mohammad16035c8845f2018-05-09 05:40:09 -07002258 else
2259 {
mohammad1603554faad2018-06-03 15:07:38 +03002260 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002261 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002262
mohammad160315223a82018-06-03 17:19:55 +03002263 if( ret != 0 )
2264 {
2265 memset( ciphertext, 0, ciphertext_size );
2266 return( mbedtls_to_psa_error( ret ) );
2267 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002268
mohammad160315223a82018-06-03 17:19:55 +03002269 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002270 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002271}
2272
Gilles Peskineee652a32018-06-01 19:23:52 +02002273/* Locate the tag in a ciphertext buffer containing the encrypted data
2274 * followed by the tag. Return the length of the part preceding the tag in
2275 * *plaintext_length. This is the size of the plaintext in modes where
2276 * the encrypted data has the same size as the plaintext, such as
2277 * CCM and GCM. */
2278static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2279 const uint8_t *ciphertext,
2280 size_t ciphertext_length,
2281 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002282 const uint8_t **p_tag )
2283{
2284 size_t payload_length;
2285 if( tag_length > ciphertext_length )
2286 return( PSA_ERROR_INVALID_ARGUMENT );
2287 payload_length = ciphertext_length - tag_length;
2288 if( payload_length > plaintext_size )
2289 return( PSA_ERROR_BUFFER_TOO_SMALL );
2290 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002291 return( PSA_SUCCESS );
2292}
2293
mohammad16035955c982018-04-26 00:53:03 +03002294psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2295 psa_algorithm_t alg,
2296 const uint8_t *nonce,
2297 size_t nonce_length,
2298 const uint8_t *additional_data,
2299 size_t additional_data_length,
2300 const uint8_t *ciphertext,
2301 size_t ciphertext_length,
2302 uint8_t *plaintext,
2303 size_t plaintext_size,
2304 size_t *plaintext_length )
2305{
2306 int ret;
2307 psa_status_t status;
2308 key_slot_t *slot;
2309 psa_key_type_t key_type;
2310 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002311 const uint8_t *tag;
2312 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002313 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002314 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002315
Gilles Peskineee652a32018-06-01 19:23:52 +02002316 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002317
mohammad16035955c982018-04-26 00:53:03 +03002318 status = psa_get_key_information( key, &key_type, &key_bits );
2319 if( status != PSA_SUCCESS )
2320 return( status );
2321 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002322 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002323 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002324
mohammad16035ed06212018-06-06 13:09:34 +03002325 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2326 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002327 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002328 return( PSA_ERROR_NOT_SUPPORTED );
2329
mohammad1603f14394b2018-06-04 14:33:19 +03002330 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2331 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002332
Gilles Peskine2d277862018-06-18 15:41:12 +02002333 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2334 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002335 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002336
mohammad16035955c982018-04-26 00:53:03 +03002337 if( alg == PSA_ALG_GCM )
2338 {
2339 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002340
Gilles Peskineee652a32018-06-01 19:23:52 +02002341 tag_length = 16;
2342 status = psa_aead_unpadded_locate_tag( tag_length,
2343 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002344 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002345 if( status != PSA_SUCCESS )
2346 return( status );
2347
mohammad16035955c982018-04-26 00:53:03 +03002348 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002349 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002350 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002351 if( ret != 0 )
2352 {
2353 mbedtls_gcm_free( &gcm );
2354 return( mbedtls_to_psa_error( ret ) );
2355 }
mohammad16035955c982018-04-26 00:53:03 +03002356
Gilles Peskineee652a32018-06-01 19:23:52 +02002357 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002358 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002359 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002360 additional_data,
2361 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002362 tag, tag_length,
2363 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002364 mbedtls_gcm_free( &gcm );
2365 }
2366 else if( alg == PSA_ALG_CCM )
2367 {
2368 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002369
mohammad160347ddf3d2018-04-26 01:11:21 +03002370 if( nonce_length < 7 || nonce_length > 13 )
2371 return( PSA_ERROR_INVALID_ARGUMENT );
2372
mohammad16039375f842018-06-03 14:28:24 +03002373 tag_length = 16;
2374 status = psa_aead_unpadded_locate_tag( tag_length,
2375 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002376 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002377 if( status != PSA_SUCCESS )
2378 return( status );
2379
mohammad16035955c982018-04-26 00:53:03 +03002380 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002381 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002382 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002383 if( ret != 0 )
2384 {
2385 mbedtls_ccm_free( &ccm );
2386 return( mbedtls_to_psa_error( ret ) );
2387 }
mohammad160360a64d02018-06-03 17:20:42 +03002388 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002389 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002390 additional_data,
2391 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002392 ciphertext, plaintext,
2393 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002394 mbedtls_ccm_free( &ccm );
2395 }
mohammad160339574652018-06-01 04:39:53 -07002396 else
2397 {
mohammad1603554faad2018-06-03 15:07:38 +03002398 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002399 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002400
Gilles Peskineee652a32018-06-01 19:23:52 +02002401 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002402 memset( plaintext, 0, plaintext_size );
2403 else
2404 *plaintext_length = ciphertext_length - tag_length;
2405
Gilles Peskineee652a32018-06-01 19:23:52 +02002406 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002407}
2408
Gilles Peskinea0655c32018-04-30 17:06:50 +02002409
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002410
Gilles Peskine20035e32018-02-03 22:44:14 +01002411/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002412/* Module setup */
2413/****************************************************************/
2414
Gilles Peskinee59236f2018-01-27 23:32:46 +01002415void mbedtls_psa_crypto_free( void )
2416{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002417 size_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02002418 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002419 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002420 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2421 mbedtls_entropy_free( &global_data.entropy );
2422 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2423}
2424
2425psa_status_t psa_crypto_init( void )
2426{
2427 int ret;
2428 const unsigned char drbg_seed[] = "PSA";
2429
2430 if( global_data.initialized != 0 )
2431 return( PSA_SUCCESS );
2432
2433 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2434 mbedtls_entropy_init( &global_data.entropy );
2435 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2436
2437 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2438 mbedtls_entropy_func,
2439 &global_data.entropy,
2440 drbg_seed, sizeof( drbg_seed ) - 1 );
2441 if( ret != 0 )
2442 goto exit;
2443
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002444 global_data.initialized = 1;
2445
Gilles Peskinee59236f2018-01-27 23:32:46 +01002446exit:
2447 if( ret != 0 )
2448 mbedtls_psa_crypto_free( );
2449 return( mbedtls_to_psa_error( ret ) );
2450}
2451
2452#endif /* MBEDTLS_PSA_CRYPTO_C */