blob: 5609f42837e46189888b2f080229d6c070ab6038 [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 Peskine0ff4b0f2018-06-19 21:31:50 +0200349static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
350 size_t bits,
351 struct raw_data *raw )
352{
353 /* Check that the bit size is acceptable for the key type */
354 switch( type )
355 {
356 case PSA_KEY_TYPE_RAW_DATA:
357#if defined(MBEDTLS_MD_C)
358 case PSA_KEY_TYPE_HMAC:
359#endif
360 break;
361#if defined(MBEDTLS_AES_C)
362 case PSA_KEY_TYPE_AES:
363 if( bits != 128 && bits != 192 && bits != 256 )
364 return( PSA_ERROR_INVALID_ARGUMENT );
365 break;
366#endif
367#if defined(MBEDTLS_CAMELLIA_C)
368 case PSA_KEY_TYPE_CAMELLIA:
369 if( bits != 128 && bits != 192 && bits != 256 )
370 return( PSA_ERROR_INVALID_ARGUMENT );
371 break;
372#endif
373#if defined(MBEDTLS_DES_C)
374 case PSA_KEY_TYPE_DES:
375 if( bits != 64 && bits != 128 && bits != 192 )
376 return( PSA_ERROR_INVALID_ARGUMENT );
377 break;
378#endif
379#if defined(MBEDTLS_ARC4_C)
380 case PSA_KEY_TYPE_ARC4:
381 if( bits < 8 || bits > 2048 )
382 return( PSA_ERROR_INVALID_ARGUMENT );
383 break;
384#endif
385 default:
386 return( PSA_ERROR_NOT_SUPPORTED );
387 }
388
389 /* Allocate memory for the key */
390 raw->bytes = PSA_BITS_TO_BYTES( bits );
391 raw->data = mbedtls_calloc( 1, raw->bytes );
392 if( raw->data == NULL )
393 {
394 raw->bytes = 0;
395 return( PSA_ERROR_INSUFFICIENT_MEMORY );
396 }
397 return( PSA_SUCCESS );
398}
399
Gilles Peskine2d277862018-06-18 15:41:12 +0200400psa_status_t psa_import_key( psa_key_slot_t key,
401 psa_key_type_t type,
402 const uint8_t *data,
403 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100404{
405 key_slot_t *slot;
406
Gilles Peskine828ed142018-06-18 23:25:51 +0200407 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100408 return( PSA_ERROR_INVALID_ARGUMENT );
409 slot = &global_data.key_slots[key];
410 if( slot->type != PSA_KEY_TYPE_NONE )
411 return( PSA_ERROR_OCCUPIED_SLOT );
412
Gilles Peskine8c9def32018-02-08 10:02:12 +0100413 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100414 {
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200415 psa_status_t status;
Gilles Peskine6d912132018-03-07 16:41:37 +0100416 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100417 if( data_length > SIZE_MAX / 8 )
418 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200419 status = prepare_raw_data_slot( type,
420 PSA_BYTES_TO_BITS( data_length ),
421 &slot->data.raw );
422 if( status != PSA_SUCCESS )
423 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100424 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100425 }
426 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100427#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100428 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
429 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
430 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100431 {
432 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100433 mbedtls_pk_context pk;
434 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100435 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
436 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
437 else
438 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100439 if( ret != 0 )
440 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100441 switch( mbedtls_pk_get_type( &pk ) )
442 {
443#if defined(MBEDTLS_RSA_C)
444 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100445 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
446 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200447 slot->data.rsa = mbedtls_pk_rsa( pk );
Gilles Peskine969ac722018-01-28 18:16:59 +0100448 else
449 return( PSA_ERROR_INVALID_ARGUMENT );
450 break;
451#endif /* MBEDTLS_RSA_C */
452#if defined(MBEDTLS_ECP_C)
453 case MBEDTLS_PK_ECKEY:
454 if( PSA_KEY_TYPE_IS_ECC( type ) )
455 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200456 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
457 psa_ecc_curve_t actual_curve =
458 mbedtls_ecc_group_to_psa( ecp->grp.id );
459 psa_ecc_curve_t expected_curve =
460 PSA_KEY_TYPE_GET_CURVE( type );
461 if( actual_curve != expected_curve )
462 return( PSA_ERROR_INVALID_ARGUMENT );
463 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100464 }
465 else
466 return( PSA_ERROR_INVALID_ARGUMENT );
467 break;
468#endif /* MBEDTLS_ECP_C */
469 default:
470 return( PSA_ERROR_INVALID_ARGUMENT );
471 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100472 }
473 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100474#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100475 {
476 return( PSA_ERROR_NOT_SUPPORTED );
477 }
478
479 slot->type = type;
480 return( PSA_SUCCESS );
481}
482
Gilles Peskine2d277862018-06-18 15:41:12 +0200483psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100484{
485 key_slot_t *slot;
486
Gilles Peskine828ed142018-06-18 23:25:51 +0200487 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100488 return( PSA_ERROR_INVALID_ARGUMENT );
489 slot = &global_data.key_slots[key];
490 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200491 {
492 /* No key material to clean, but do zeroize the slot below to wipe
493 * metadata such as policies. */
494 }
495 else if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100496 {
497 mbedtls_free( slot->data.raw.data );
498 }
499 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100500#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100501 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
502 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100503 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100504 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100505 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100506 }
507 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100508#endif /* defined(MBEDTLS_RSA_C) */
509#if defined(MBEDTLS_ECP_C)
510 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
511 {
512 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100513 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100514 }
515 else
516#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100517 {
518 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100519 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100520 return( PSA_ERROR_TAMPERING_DETECTED );
521 }
522
523 mbedtls_zeroize( slot, sizeof( *slot ) );
524 return( PSA_SUCCESS );
525}
526
Gilles Peskine2d277862018-06-18 15:41:12 +0200527psa_status_t psa_get_key_information( psa_key_slot_t key,
528 psa_key_type_t *type,
529 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100530{
531 key_slot_t *slot;
532
Gilles Peskine828ed142018-06-18 23:25:51 +0200533 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100534 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100535 slot = &global_data.key_slots[key];
536 if( type != NULL )
537 *type = slot->type;
538 if( bits != NULL )
539 *bits = 0;
540 if( slot->type == PSA_KEY_TYPE_NONE )
541 return( PSA_ERROR_EMPTY_SLOT );
542
Gilles Peskine8c9def32018-02-08 10:02:12 +0100543 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100544 {
545 if( bits != NULL )
546 *bits = slot->data.raw.bytes * 8;
547 }
548 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100549#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100550 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
551 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100552 {
553 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100554 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100555 }
556 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100557#endif /* defined(MBEDTLS_RSA_C) */
558#if defined(MBEDTLS_ECP_C)
559 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
560 {
561 if( bits != NULL )
562 *bits = slot->data.ecp->grp.pbits;
563 }
564 else
565#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100566 {
567 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100568 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100569 return( PSA_ERROR_TAMPERING_DETECTED );
570 }
571
572 return( PSA_SUCCESS );
573}
574
Gilles Peskine2d277862018-06-18 15:41:12 +0200575static psa_status_t psa_internal_export_key( psa_key_slot_t key,
576 uint8_t *data,
577 size_t data_size,
578 size_t *data_length,
579 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100580{
581 key_slot_t *slot;
582
Gilles Peskine828ed142018-06-18 23:25:51 +0200583 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100584 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100585 slot = &global_data.key_slots[key];
586 if( slot->type == PSA_KEY_TYPE_NONE )
587 return( PSA_ERROR_EMPTY_SLOT );
588
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200589 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300590 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300591
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200592 if( ! export_public_key &&
593 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
594 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300595 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200596
Gilles Peskine8c9def32018-02-08 10:02:12 +0100597 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100598 {
599 if( slot->data.raw.bytes > data_size )
600 return( PSA_ERROR_BUFFER_TOO_SMALL );
601 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
602 *data_length = slot->data.raw.bytes;
603 return( PSA_SUCCESS );
604 }
605 else
Moran Peker17e36e12018-05-02 12:55:20 +0300606 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100607#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100608 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300609 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
610 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100611 {
Moran Pekera998bc62018-04-16 18:16:20 +0300612 mbedtls_pk_context pk;
613 int ret;
614 mbedtls_pk_init( &pk );
615 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
616 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
617 {
618 pk.pk_info = &mbedtls_rsa_info;
619 pk.pk_ctx = slot->data.rsa;
620 }
621 else
622 {
623 pk.pk_info = &mbedtls_eckey_info;
624 pk.pk_ctx = slot->data.ecp;
625 }
Moran Pekerd7326592018-05-29 16:56:39 +0300626 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300627 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300628 else
629 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300630 if( ret < 0 )
Moran Pekera998bc62018-04-16 18:16:20 +0300631 return( mbedtls_to_psa_error( ret ) );
632 *data_length = ret;
633 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100634 }
635 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100636#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300637 {
638 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200639 it is valid for a special-purpose implementation to omit
640 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300641 return( PSA_ERROR_NOT_SUPPORTED );
642 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100643 }
644}
645
Gilles Peskine2d277862018-06-18 15:41:12 +0200646psa_status_t psa_export_key( psa_key_slot_t key,
647 uint8_t *data,
648 size_t data_size,
649 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300650{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200651 return( psa_internal_export_key( key, data, data_size,
652 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100653}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100654
Gilles Peskine2d277862018-06-18 15:41:12 +0200655psa_status_t psa_export_public_key( psa_key_slot_t key,
656 uint8_t *data,
657 size_t data_size,
658 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300659{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200660 return( psa_internal_export_key( key, data, data_size,
661 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300662}
663
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200664
665
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100666/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100667/* Message digests */
668/****************************************************************/
669
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100670static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100671{
672 switch( alg )
673 {
674#if defined(MBEDTLS_MD2_C)
675 case PSA_ALG_MD2:
676 return( &mbedtls_md2_info );
677#endif
678#if defined(MBEDTLS_MD4_C)
679 case PSA_ALG_MD4:
680 return( &mbedtls_md4_info );
681#endif
682#if defined(MBEDTLS_MD5_C)
683 case PSA_ALG_MD5:
684 return( &mbedtls_md5_info );
685#endif
686#if defined(MBEDTLS_RIPEMD160_C)
687 case PSA_ALG_RIPEMD160:
688 return( &mbedtls_ripemd160_info );
689#endif
690#if defined(MBEDTLS_SHA1_C)
691 case PSA_ALG_SHA_1:
692 return( &mbedtls_sha1_info );
693#endif
694#if defined(MBEDTLS_SHA256_C)
695 case PSA_ALG_SHA_224:
696 return( &mbedtls_sha224_info );
697 case PSA_ALG_SHA_256:
698 return( &mbedtls_sha256_info );
699#endif
700#if defined(MBEDTLS_SHA512_C)
701 case PSA_ALG_SHA_384:
702 return( &mbedtls_sha384_info );
703 case PSA_ALG_SHA_512:
704 return( &mbedtls_sha512_info );
705#endif
706 default:
707 return( NULL );
708 }
709}
710
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100711psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
712{
713 switch( operation->alg )
714 {
715#if defined(MBEDTLS_MD2_C)
716 case PSA_ALG_MD2:
717 mbedtls_md2_free( &operation->ctx.md2 );
718 break;
719#endif
720#if defined(MBEDTLS_MD4_C)
721 case PSA_ALG_MD4:
722 mbedtls_md4_free( &operation->ctx.md4 );
723 break;
724#endif
725#if defined(MBEDTLS_MD5_C)
726 case PSA_ALG_MD5:
727 mbedtls_md5_free( &operation->ctx.md5 );
728 break;
729#endif
730#if defined(MBEDTLS_RIPEMD160_C)
731 case PSA_ALG_RIPEMD160:
732 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
733 break;
734#endif
735#if defined(MBEDTLS_SHA1_C)
736 case PSA_ALG_SHA_1:
737 mbedtls_sha1_free( &operation->ctx.sha1 );
738 break;
739#endif
740#if defined(MBEDTLS_SHA256_C)
741 case PSA_ALG_SHA_224:
742 case PSA_ALG_SHA_256:
743 mbedtls_sha256_free( &operation->ctx.sha256 );
744 break;
745#endif
746#if defined(MBEDTLS_SHA512_C)
747 case PSA_ALG_SHA_384:
748 case PSA_ALG_SHA_512:
749 mbedtls_sha512_free( &operation->ctx.sha512 );
750 break;
751#endif
752 default:
753 return( PSA_ERROR_NOT_SUPPORTED );
754 }
755 operation->alg = 0;
756 return( PSA_SUCCESS );
757}
758
759psa_status_t psa_hash_start( psa_hash_operation_t *operation,
760 psa_algorithm_t alg )
761{
762 int ret;
763 operation->alg = 0;
764 switch( alg )
765 {
766#if defined(MBEDTLS_MD2_C)
767 case PSA_ALG_MD2:
768 mbedtls_md2_init( &operation->ctx.md2 );
769 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
770 break;
771#endif
772#if defined(MBEDTLS_MD4_C)
773 case PSA_ALG_MD4:
774 mbedtls_md4_init( &operation->ctx.md4 );
775 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
776 break;
777#endif
778#if defined(MBEDTLS_MD5_C)
779 case PSA_ALG_MD5:
780 mbedtls_md5_init( &operation->ctx.md5 );
781 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
782 break;
783#endif
784#if defined(MBEDTLS_RIPEMD160_C)
785 case PSA_ALG_RIPEMD160:
786 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
787 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
788 break;
789#endif
790#if defined(MBEDTLS_SHA1_C)
791 case PSA_ALG_SHA_1:
792 mbedtls_sha1_init( &operation->ctx.sha1 );
793 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
794 break;
795#endif
796#if defined(MBEDTLS_SHA256_C)
797 case PSA_ALG_SHA_224:
798 mbedtls_sha256_init( &operation->ctx.sha256 );
799 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
800 break;
801 case PSA_ALG_SHA_256:
802 mbedtls_sha256_init( &operation->ctx.sha256 );
803 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
804 break;
805#endif
806#if defined(MBEDTLS_SHA512_C)
807 case PSA_ALG_SHA_384:
808 mbedtls_sha512_init( &operation->ctx.sha512 );
809 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
810 break;
811 case PSA_ALG_SHA_512:
812 mbedtls_sha512_init( &operation->ctx.sha512 );
813 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
814 break;
815#endif
816 default:
817 return( PSA_ERROR_NOT_SUPPORTED );
818 }
819 if( ret == 0 )
820 operation->alg = alg;
821 else
822 psa_hash_abort( operation );
823 return( mbedtls_to_psa_error( ret ) );
824}
825
826psa_status_t psa_hash_update( psa_hash_operation_t *operation,
827 const uint8_t *input,
828 size_t input_length )
829{
830 int ret;
831 switch( operation->alg )
832 {
833#if defined(MBEDTLS_MD2_C)
834 case PSA_ALG_MD2:
835 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
836 input, input_length );
837 break;
838#endif
839#if defined(MBEDTLS_MD4_C)
840 case PSA_ALG_MD4:
841 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
842 input, input_length );
843 break;
844#endif
845#if defined(MBEDTLS_MD5_C)
846 case PSA_ALG_MD5:
847 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
848 input, input_length );
849 break;
850#endif
851#if defined(MBEDTLS_RIPEMD160_C)
852 case PSA_ALG_RIPEMD160:
853 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
854 input, input_length );
855 break;
856#endif
857#if defined(MBEDTLS_SHA1_C)
858 case PSA_ALG_SHA_1:
859 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
860 input, input_length );
861 break;
862#endif
863#if defined(MBEDTLS_SHA256_C)
864 case PSA_ALG_SHA_224:
865 case PSA_ALG_SHA_256:
866 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
867 input, input_length );
868 break;
869#endif
870#if defined(MBEDTLS_SHA512_C)
871 case PSA_ALG_SHA_384:
872 case PSA_ALG_SHA_512:
873 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
874 input, input_length );
875 break;
876#endif
877 default:
878 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
879 break;
880 }
881 if( ret != 0 )
882 psa_hash_abort( operation );
883 return( mbedtls_to_psa_error( ret ) );
884}
885
886psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
887 uint8_t *hash,
888 size_t hash_size,
889 size_t *hash_length )
890{
891 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200892 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100893
894 /* Fill the output buffer with something that isn't a valid hash
895 * (barring an attack on the hash and deliberately-crafted input),
896 * in case the caller doesn't check the return status properly. */
897 *hash_length = actual_hash_length;
898 memset( hash, '!', hash_size );
899
900 if( hash_size < actual_hash_length )
901 return( PSA_ERROR_BUFFER_TOO_SMALL );
902
903 switch( operation->alg )
904 {
905#if defined(MBEDTLS_MD2_C)
906 case PSA_ALG_MD2:
907 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
908 break;
909#endif
910#if defined(MBEDTLS_MD4_C)
911 case PSA_ALG_MD4:
912 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
913 break;
914#endif
915#if defined(MBEDTLS_MD5_C)
916 case PSA_ALG_MD5:
917 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
918 break;
919#endif
920#if defined(MBEDTLS_RIPEMD160_C)
921 case PSA_ALG_RIPEMD160:
922 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
923 break;
924#endif
925#if defined(MBEDTLS_SHA1_C)
926 case PSA_ALG_SHA_1:
927 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
928 break;
929#endif
930#if defined(MBEDTLS_SHA256_C)
931 case PSA_ALG_SHA_224:
932 case PSA_ALG_SHA_256:
933 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
934 break;
935#endif
936#if defined(MBEDTLS_SHA512_C)
937 case PSA_ALG_SHA_384:
938 case PSA_ALG_SHA_512:
939 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
940 break;
941#endif
942 default:
943 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
944 break;
945 }
946
947 if( ret == 0 )
948 {
949 return( psa_hash_abort( operation ) );
950 }
951 else
952 {
953 psa_hash_abort( operation );
954 return( mbedtls_to_psa_error( ret ) );
955 }
956}
957
Gilles Peskine2d277862018-06-18 15:41:12 +0200958psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
959 const uint8_t *hash,
960 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100961{
962 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
963 size_t actual_hash_length;
964 psa_status_t status = psa_hash_finish( operation,
965 actual_hash, sizeof( actual_hash ),
966 &actual_hash_length );
967 if( status != PSA_SUCCESS )
968 return( status );
969 if( actual_hash_length != hash_length )
970 return( PSA_ERROR_INVALID_SIGNATURE );
971 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
972 return( PSA_ERROR_INVALID_SIGNATURE );
973 return( PSA_SUCCESS );
974}
975
976
977
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100978/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +0100979/* MAC */
980/****************************************************************/
981
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100982static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +0100983 psa_algorithm_t alg,
984 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +0200985 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +0300986 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100987{
Gilles Peskine8c9def32018-02-08 10:02:12 +0100988 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +0300989 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100990
991 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
992 {
993 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +0200994 {
995 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
996 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +0200997
Nir Sonnenscheine9664c32018-06-17 14:41:30 +0300998 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100999 {
1000 case PSA_ALG_STREAM_CIPHER:
1001 mode = MBEDTLS_MODE_STREAM;
1002 break;
1003 case PSA_ALG_CBC_BASE:
1004 mode = MBEDTLS_MODE_CBC;
1005 break;
1006 case PSA_ALG_CFB_BASE:
1007 mode = MBEDTLS_MODE_CFB;
1008 break;
1009 case PSA_ALG_OFB_BASE:
1010 mode = MBEDTLS_MODE_OFB;
1011 break;
1012 case PSA_ALG_CTR:
1013 mode = MBEDTLS_MODE_CTR;
1014 break;
1015 case PSA_ALG_CCM:
1016 mode = MBEDTLS_MODE_CCM;
1017 break;
1018 case PSA_ALG_GCM:
1019 mode = MBEDTLS_MODE_GCM;
1020 break;
1021 default:
1022 return( NULL );
1023 }
1024 }
1025 else if( alg == PSA_ALG_CMAC )
1026 mode = MBEDTLS_MODE_ECB;
1027 else if( alg == PSA_ALG_GMAC )
1028 mode = MBEDTLS_MODE_GCM;
1029 else
1030 return( NULL );
1031
1032 switch( key_type )
1033 {
1034 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001035 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001036 break;
1037 case PSA_KEY_TYPE_DES:
1038 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001039 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001040 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001041 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001042 break;
1043 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001044 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001045 break;
1046 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001047 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001048 break;
1049 default:
1050 return( NULL );
1051 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001052 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001053 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001054
mohammad1603f4f0d612018-06-03 15:04:51 +03001055 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001056}
1057
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001058static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001059{
Gilles Peskine2d277862018-06-18 15:41:12 +02001060 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001061 {
1062 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001063 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001064 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001065 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001066 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001067 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001068 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001069 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001070 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001071 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001072 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001073 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001074 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001075 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001076 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001077 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001078 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001079 return( 128 );
1080 default:
1081 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001082 }
1083}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001084
Gilles Peskine8c9def32018-02-08 10:02:12 +01001085psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1086{
1087 switch( operation->alg )
1088 {
1089#if defined(MBEDTLS_CMAC_C)
1090 case PSA_ALG_CMAC:
1091 mbedtls_cipher_free( &operation->ctx.cmac );
1092 break;
1093#endif /* MBEDTLS_CMAC_C */
1094 default:
1095#if defined(MBEDTLS_MD_C)
1096 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001097 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001098 unsigned int block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001099 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001100
Gilles Peskine99bc6492018-06-11 17:13:00 +02001101 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001102 return( PSA_ERROR_NOT_SUPPORTED );
1103
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001104 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001105 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001106 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001107 else
1108#endif /* MBEDTLS_MD_C */
1109 return( PSA_ERROR_NOT_SUPPORTED );
1110 }
Moran Peker41deec42018-04-04 15:43:05 +03001111
Gilles Peskine8c9def32018-02-08 10:02:12 +01001112 operation->alg = 0;
1113 operation->key_set = 0;
1114 operation->iv_set = 0;
1115 operation->iv_required = 0;
1116 operation->has_input = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001117
Gilles Peskine8c9def32018-02-08 10:02:12 +01001118 return( PSA_SUCCESS );
1119}
1120
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001121#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001122static int psa_cmac_start( psa_mac_operation_t *operation,
1123 size_t key_bits,
1124 key_slot_t *slot,
1125 const mbedtls_cipher_info_t *cipher_info )
1126{
1127 int ret;
1128
1129 operation->mac_size = cipher_info->block_size;
1130 operation->iv_required = 0;
1131 mbedtls_cipher_init( &operation->ctx.cmac );
1132
1133 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1134 if( ret != 0 )
1135 return( ret );
1136
1137 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1138 slot->data.raw.data,
1139 key_bits );
1140 return( ret );
1141}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001142#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001143
1144static int psa_hmac_start( psa_mac_operation_t *operation,
1145 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001146 key_slot_t *slot,
1147 psa_algorithm_t alg )
1148{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001149 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001150 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001151 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001152 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001153 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001154 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001155 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001156 size_t key_length = slot->data.raw.bytes;
1157 psa_status_t status;
1158
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001159 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001160 return( PSA_ERROR_NOT_SUPPORTED );
1161
1162 if( key_type != PSA_KEY_TYPE_HMAC )
1163 return( PSA_ERROR_INVALID_ARGUMENT );
1164
1165 operation->iv_required = 0;
1166 operation->mac_size = digest_size;
1167
1168 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1169 PSA_ALG_HMAC_HASH( alg ) );
1170 if( status != PSA_SUCCESS )
1171 return( status );
1172
Gilles Peskined223b522018-06-11 18:12:58 +02001173 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001174 {
1175 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001176 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001177 if( status != PSA_SUCCESS )
1178 return( status );
1179 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001180 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001181 if( status != PSA_SUCCESS )
1182 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001183 }
Gilles Peskined223b522018-06-11 18:12:58 +02001184 else
1185 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001186
Gilles Peskined223b522018-06-11 18:12:58 +02001187 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1188 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001189 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001190 ipad[i] ^= 0x36;
1191 memset( ipad + key_length, 0x36, block_size - key_length );
1192
1193 /* Copy the key material from ipad to opad, flipping the requisite bits,
1194 * and filling the rest of opad with the requisite constant. */
1195 for( i = 0; i < key_length; i++ )
1196 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1197 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001198
1199 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1200 PSA_ALG_HMAC_HASH( alg ) );
1201 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001202 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001203
1204 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1205 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001206
1207cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001208 mbedtls_zeroize( ipad, key_length );
1209 /* opad is in the context. It needs to stay in memory if this function
1210 * succeeds, and it will be wiped by psa_mac_abort() called from
1211 * psa_mac_start in the error case. */
1212
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001213 return( status );
1214}
1215
Gilles Peskine8c9def32018-02-08 10:02:12 +01001216psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1217 psa_key_slot_t key,
1218 psa_algorithm_t alg )
1219{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001220 psa_status_t status;
1221 key_slot_t *slot;
1222 psa_key_type_t key_type;
1223 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001224 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001225
1226 operation->alg = 0;
1227 operation->key_set = 0;
1228 operation->iv_set = 0;
1229 operation->iv_required = 1;
1230 operation->has_input = 0;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001231 operation->key_usage_sign = 0;
1232 operation->key_usage_verify = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001233
1234 status = psa_get_key_information( key, &key_type, &key_bits );
1235 if( status != PSA_SUCCESS )
1236 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001237
Gilles Peskine8c9def32018-02-08 10:02:12 +01001238 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001239 if( slot->type == PSA_KEY_TYPE_NONE )
1240 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001241
Moran Pekerd7326592018-05-29 16:56:39 +03001242 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001243 operation->key_usage_sign = 1;
1244
Moran Pekerd7326592018-05-29 16:56:39 +03001245 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001246 operation->key_usage_verify = 1;
1247
Gilles Peskine8c9def32018-02-08 10:02:12 +01001248 if( ! PSA_ALG_IS_HMAC( alg ) )
1249 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001250 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001251 if( cipher_info == NULL )
1252 return( PSA_ERROR_NOT_SUPPORTED );
1253 operation->mac_size = cipher_info->block_size;
1254 }
1255 switch( alg )
1256 {
1257#if defined(MBEDTLS_CMAC_C)
1258 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001259 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1260 key_bits,
1261 slot,
1262 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001263 break;
1264#endif /* MBEDTLS_CMAC_C */
1265 default:
1266#if defined(MBEDTLS_MD_C)
1267 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001268 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001269 else
1270#endif /* MBEDTLS_MD_C */
1271 return( PSA_ERROR_NOT_SUPPORTED );
1272 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001273
Gilles Peskine8c9def32018-02-08 10:02:12 +01001274 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001275
1276 * context may contain data that needs to be wiped on error. */
1277 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001278 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001279 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001280 }
Gilles Peskine99bc6492018-06-11 17:13:00 +02001281
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001282 else
1283 {
1284 operation->alg = alg;
1285 operation->key_set = 1;
1286 }
1287 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001288}
1289
1290psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1291 const uint8_t *input,
1292 size_t input_length )
1293{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001294 int ret = 0 ;
1295 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001296 if( ! operation->key_set )
1297 return( PSA_ERROR_BAD_STATE );
1298 if( operation->iv_required && ! operation->iv_set )
1299 return( PSA_ERROR_BAD_STATE );
1300 operation->has_input = 1;
1301
1302 switch( operation->alg )
1303 {
1304#if defined(MBEDTLS_CMAC_C)
1305 case PSA_ALG_CMAC:
1306 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1307 input, input_length );
1308 break;
1309#endif /* MBEDTLS_CMAC_C */
1310 default:
1311#if defined(MBEDTLS_MD_C)
1312 if( PSA_ALG_IS_HMAC( operation->alg ) )
1313 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001314 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001315 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001316 }
1317 else
1318#endif /* MBEDTLS_MD_C */
1319 {
1320 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1321 }
1322 break;
1323 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001324 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001325 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001326 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001327 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001328 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001329 }
1330
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001331 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001332}
1333
mohammad16036df908f2018-04-02 08:34:15 -07001334static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001335 uint8_t *mac,
1336 size_t mac_size,
1337 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001338{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001339 int ret = 0;
1340 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001341 if( ! operation->key_set )
1342 return( PSA_ERROR_BAD_STATE );
1343 if( operation->iv_required && ! operation->iv_set )
1344 return( PSA_ERROR_BAD_STATE );
1345
1346 /* Fill the output buffer with something that isn't a valid mac
1347 * (barring an attack on the mac and deliberately-crafted input),
1348 * in case the caller doesn't check the return status properly. */
1349 *mac_length = operation->mac_size;
1350 memset( mac, '!', mac_size );
1351
1352 if( mac_size < operation->mac_size )
1353 return( PSA_ERROR_BUFFER_TOO_SMALL );
1354
1355 switch( operation->alg )
1356 {
1357#if defined(MBEDTLS_CMAC_C)
1358 case PSA_ALG_CMAC:
1359 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1360 break;
1361#endif /* MBEDTLS_CMAC_C */
1362 default:
1363#if defined(MBEDTLS_MD_C)
1364 if( PSA_ALG_IS_HMAC( operation->alg ) )
1365 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001366 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001367 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001368 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001369 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001370 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001371
Gilles Peskine99bc6492018-06-11 17:13:00 +02001372 if( block_size == 0 )
1373 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001374
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001375 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001376 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001377 if( status != PSA_SUCCESS )
1378 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001379 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001380
1381 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1382 PSA_ALG_HMAC_HASH( operation->alg ) );
1383 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001384 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001385
1386 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001387 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001388 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001389 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001390
1391 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001392 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001393 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001394 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001395
1396 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1397 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001398 hmac_cleanup:
1399 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001400 }
1401 else
1402#endif /* MBEDTLS_MD_C */
1403 {
1404 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1405 }
1406 break;
1407 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001408cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001409
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001410 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001411 {
1412 return( psa_mac_abort( operation ) );
1413 }
1414 else
1415 {
1416 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001417 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001418 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001419
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001420 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001421 }
1422}
1423
mohammad16036df908f2018-04-02 08:34:15 -07001424psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1425 uint8_t *mac,
1426 size_t mac_size,
1427 size_t *mac_length )
1428{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001429 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001430 return( PSA_ERROR_NOT_PERMITTED );
1431
Gilles Peskine99bc6492018-06-11 17:13:00 +02001432 return( psa_mac_finish_internal( operation, mac,
1433 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001434}
1435
Gilles Peskine828ed142018-06-18 23:25:51 +02001436#define PSA_MAC_MAX_SIZE \
Gilles Peskine2d277862018-06-18 15:41:12 +02001437 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1438 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001439 MBEDTLS_MAX_BLOCK_LENGTH )
1440psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1441 const uint8_t *mac,
1442 size_t mac_length )
1443{
Gilles Peskine828ed142018-06-18 23:25:51 +02001444 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001445 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001446 psa_status_t status;
1447
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001448 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001449 return( PSA_ERROR_NOT_PERMITTED );
1450
1451 status = psa_mac_finish_internal( operation,
1452 actual_mac, sizeof( actual_mac ),
1453 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001454 if( status != PSA_SUCCESS )
1455 return( status );
1456 if( actual_mac_length != mac_length )
1457 return( PSA_ERROR_INVALID_SIGNATURE );
1458 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1459 return( PSA_ERROR_INVALID_SIGNATURE );
1460 return( PSA_SUCCESS );
1461}
1462
1463
Gilles Peskine20035e32018-02-03 22:44:14 +01001464
Gilles Peskine20035e32018-02-03 22:44:14 +01001465/****************************************************************/
1466/* Asymmetric cryptography */
1467/****************************************************************/
1468
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001469/* Decode the hash algorithm from alg and store the mbedtls encoding in
1470 * md_alg. Verify that the hash length is consistent. */
1471static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1472 size_t hash_length,
1473 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001474{
Gilles Peskine61b91d42018-06-08 16:09:36 +02001475 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
1476 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1477 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1478 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001479 {
1480#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001481 if( hash_length > UINT_MAX )
1482 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001483#endif
1484 }
1485 else
1486 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001487 if( mbedtls_md_get_size( md_info ) != hash_length )
1488 return( PSA_ERROR_INVALID_ARGUMENT );
1489 if( md_info == NULL )
1490 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001491 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001492 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001493}
1494
Gilles Peskine61b91d42018-06-08 16:09:36 +02001495psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1496 psa_algorithm_t alg,
1497 const uint8_t *hash,
1498 size_t hash_length,
1499 const uint8_t *salt,
1500 size_t salt_length,
1501 uint8_t *signature,
1502 size_t signature_size,
1503 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001504{
1505 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001506 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001507 *signature_length = 0;
1508 (void) salt;
1509 (void) salt_length;
1510
Gilles Peskine828ed142018-06-18 23:25:51 +02001511 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine20035e32018-02-03 22:44:14 +01001512 return( PSA_ERROR_EMPTY_SLOT );
1513 slot = &global_data.key_slots[key];
1514 if( slot->type == PSA_KEY_TYPE_NONE )
1515 return( PSA_ERROR_EMPTY_SLOT );
1516 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1517 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001518 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001519 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001520
Gilles Peskine20035e32018-02-03 22:44:14 +01001521#if defined(MBEDTLS_RSA_C)
1522 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1523 {
1524 mbedtls_rsa_context *rsa = slot->data.rsa;
1525 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001526 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001527 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001528 if( status != PSA_SUCCESS )
1529 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001530
Gilles Peskine20035e32018-02-03 22:44:14 +01001531 if( signature_size < rsa->len )
1532 return( PSA_ERROR_BUFFER_TOO_SMALL );
1533#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001534 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001535 {
1536 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1537 MBEDTLS_MD_NONE );
1538 ret = mbedtls_rsa_pkcs1_sign( rsa,
1539 mbedtls_ctr_drbg_random,
1540 &global_data.ctr_drbg,
1541 MBEDTLS_RSA_PRIVATE,
1542 md_alg, hash_length, hash,
1543 signature );
1544 }
1545 else
1546#endif /* MBEDTLS_PKCS1_V15 */
1547#if defined(MBEDTLS_PKCS1_V21)
1548 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1549 {
1550 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1551 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1552 mbedtls_ctr_drbg_random,
1553 &global_data.ctr_drbg,
1554 MBEDTLS_RSA_PRIVATE,
1555 md_alg, hash_length, hash,
1556 signature );
1557 }
1558 else
1559#endif /* MBEDTLS_PKCS1_V21 */
1560 {
1561 return( PSA_ERROR_INVALID_ARGUMENT );
1562 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001563 if( ret == 0 )
1564 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001565 return( mbedtls_to_psa_error( ret ) );
1566 }
1567 else
1568#endif /* defined(MBEDTLS_RSA_C) */
1569#if defined(MBEDTLS_ECP_C)
1570 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1571 {
itayzafrir5c753392018-05-08 11:18:38 +03001572 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1573 int ret;
1574 const mbedtls_md_info_t *md_info;
1575 mbedtls_md_type_t md_alg;
1576 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1577 return( PSA_ERROR_BUFFER_TOO_SMALL );
1578 md_info = mbedtls_md_info_from_psa( alg );
1579 md_alg = mbedtls_md_get_type( md_info );
1580 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001581 signature, signature_length,
1582 mbedtls_ctr_drbg_random,
1583 &global_data.ctr_drbg );
itayzafrir5c753392018-05-08 11:18:38 +03001584 return( mbedtls_to_psa_error( ret ) );
1585 }
1586 else
1587#endif /* defined(MBEDTLS_ECP_C) */
1588 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001589 return( PSA_ERROR_NOT_SUPPORTED );
1590 }
itayzafrir5c753392018-05-08 11:18:38 +03001591}
1592
1593psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1594 psa_algorithm_t alg,
1595 const uint8_t *hash,
1596 size_t hash_length,
1597 const uint8_t *salt,
1598 size_t salt_length,
1599 uint8_t *signature,
1600 size_t signature_size )
1601{
1602 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001603 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001604 (void) salt;
1605 (void) salt_length;
1606
Gilles Peskine828ed142018-06-18 23:25:51 +02001607 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001608 return( PSA_ERROR_INVALID_ARGUMENT );
1609 slot = &global_data.key_slots[key];
1610 if( slot->type == PSA_KEY_TYPE_NONE )
1611 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001612 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001613 return( PSA_ERROR_NOT_PERMITTED );
1614
Gilles Peskine61b91d42018-06-08 16:09:36 +02001615#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001616 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1617 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001618 {
1619 mbedtls_rsa_context *rsa = slot->data.rsa;
1620 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001621 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001622 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001623 if( status != PSA_SUCCESS )
1624 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001625
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001626 if( signature_size < rsa->len )
1627 return( PSA_ERROR_BUFFER_TOO_SMALL );
1628#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001629 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001630 {
1631 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1632 MBEDTLS_MD_NONE );
1633
1634 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001635 mbedtls_ctr_drbg_random,
1636 &global_data.ctr_drbg,
1637 MBEDTLS_RSA_PUBLIC,
1638 md_alg,
1639 hash_length,
1640 hash,
1641 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001642
1643 }
1644 else
1645#endif /* MBEDTLS_PKCS1_V15 */
1646#if defined(MBEDTLS_PKCS1_V21)
1647 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1648 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001649 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1650 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1651 mbedtls_ctr_drbg_random,
1652 &global_data.ctr_drbg,
1653 MBEDTLS_RSA_PUBLIC,
1654 md_alg, hash_length, hash,
1655 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001656 }
1657 else
1658#endif /* MBEDTLS_PKCS1_V21 */
1659 {
1660 return( PSA_ERROR_INVALID_ARGUMENT );
1661 }
1662 return( mbedtls_to_psa_error( ret ) );
1663 }
1664 else
1665#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001666#if defined(MBEDTLS_ECP_C)
1667 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1668 {
1669 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1670 int ret;
Gilles Peskine2d277862018-06-18 15:41:12 +02001671 (void) alg;
Gilles Peskine61b91d42018-06-08 16:09:36 +02001672 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length,
1673 signature, signature_size );
itayzafrir5c753392018-05-08 11:18:38 +03001674 return( mbedtls_to_psa_error( ret ) );
1675 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001676 else
1677#endif /* defined(MBEDTLS_ECP_C) */
1678 {
1679 return( PSA_ERROR_NOT_SUPPORTED );
1680 }
1681}
1682
Gilles Peskine61b91d42018-06-08 16:09:36 +02001683psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1684 psa_algorithm_t alg,
1685 const uint8_t *input,
1686 size_t input_length,
1687 const uint8_t *salt,
1688 size_t salt_length,
1689 uint8_t *output,
1690 size_t output_size,
1691 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001692{
1693 key_slot_t *slot;
1694 (void) salt;
1695 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001696 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001697
Gilles Peskine828ed142018-06-18 23:25:51 +02001698 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001699 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001700 slot = &global_data.key_slots[key];
1701 if( slot->type == PSA_KEY_TYPE_NONE )
1702 return( PSA_ERROR_EMPTY_SLOT );
1703 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1704 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001705 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1706 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001707
1708#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001709 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1710 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001711 {
1712 mbedtls_rsa_context *rsa = slot->data.rsa;
1713 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001714 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001715 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001716#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001717 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001718 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001719 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1720 mbedtls_ctr_drbg_random,
1721 &global_data.ctr_drbg,
1722 MBEDTLS_RSA_PUBLIC,
1723 input_length,
1724 input,
1725 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001726 }
1727 else
1728#endif /* MBEDTLS_PKCS1_V15 */
1729#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001730 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001731 {
1732 return( PSA_ERROR_NOT_SUPPORTED );
1733 }
1734 else
1735#endif /* MBEDTLS_PKCS1_V21 */
1736 {
1737 return( PSA_ERROR_INVALID_ARGUMENT );
1738 }
1739 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001740 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001741 return( mbedtls_to_psa_error( ret ) );
1742 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001743 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001744#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001745 {
1746 return( PSA_ERROR_NOT_SUPPORTED );
1747 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001748}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001749
Gilles Peskine61b91d42018-06-08 16:09:36 +02001750psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1751 psa_algorithm_t alg,
1752 const uint8_t *input,
1753 size_t input_length,
1754 const uint8_t *salt,
1755 size_t salt_length,
1756 uint8_t *output,
1757 size_t output_size,
1758 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001759{
1760 key_slot_t *slot;
1761 (void) salt;
1762 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001763 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001764
Gilles Peskine828ed142018-06-18 23:25:51 +02001765 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001766 return( PSA_ERROR_EMPTY_SLOT );
1767 slot = &global_data.key_slots[key];
1768 if( slot->type == PSA_KEY_TYPE_NONE )
1769 return( PSA_ERROR_EMPTY_SLOT );
1770 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1771 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001772 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1773 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001774
1775#if defined(MBEDTLS_RSA_C)
1776 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1777 {
1778 mbedtls_rsa_context *rsa = slot->data.rsa;
1779 int ret;
1780
Gilles Peskinec4def2f2018-06-08 17:53:48 +02001781 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001782 return( PSA_ERROR_INVALID_ARGUMENT );
1783
1784#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001785 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001786 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001787 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
1788 mbedtls_ctr_drbg_random,
1789 &global_data.ctr_drbg,
1790 MBEDTLS_RSA_PRIVATE,
1791 output_length,
1792 input,
1793 output,
1794 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001795 }
1796 else
1797#endif /* MBEDTLS_PKCS1_V15 */
1798#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001799 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001800 {
1801 return( PSA_ERROR_NOT_SUPPORTED );
1802 }
1803 else
1804#endif /* MBEDTLS_PKCS1_V21 */
1805 {
1806 return( PSA_ERROR_INVALID_ARGUMENT );
1807 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001808
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001809 return( mbedtls_to_psa_error( ret ) );
1810 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001811 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001812#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001813 {
1814 return( PSA_ERROR_NOT_SUPPORTED );
1815 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001816}
Gilles Peskine20035e32018-02-03 22:44:14 +01001817
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001818
1819
mohammad1603503973b2018-03-12 15:59:30 +02001820/****************************************************************/
1821/* Symmetric cryptography */
1822/****************************************************************/
1823
Gilles Peskinee553c652018-06-04 16:22:46 +02001824static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1825 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001826 psa_algorithm_t alg,
1827 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001828{
1829 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1830 psa_status_t status;
1831 key_slot_t *slot;
1832 psa_key_type_t key_type;
1833 size_t key_bits;
1834 const mbedtls_cipher_info_t *cipher_info = NULL;
1835
Moran Peker41deec42018-04-04 15:43:05 +03001836 operation->alg = alg;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001837 operation->key_set = 0;
1838 operation->iv_set = 0;
1839 operation->iv_required = 1;
1840 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001841 operation->block_size = 0;
mohammad1603503973b2018-03-12 15:59:30 +02001842
1843 status = psa_get_key_information( key, &key_type, &key_bits );
1844 if( status != PSA_SUCCESS )
1845 return( status );
1846 slot = &global_data.key_slots[key];
1847
Gilles Peskinebb1072f2018-06-08 18:46:05 +02001848 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02001849 if( cipher_info == NULL )
1850 return( PSA_ERROR_NOT_SUPPORTED );
1851
mohammad1603503973b2018-03-12 15:59:30 +02001852 mbedtls_cipher_init( &operation->ctx.cipher );
1853 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03001854 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001855 {
1856 psa_cipher_abort( operation );
1857 return( mbedtls_to_psa_error( ret ) );
1858 }
1859
1860 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
Gilles Peskinee553c652018-06-04 16:22:46 +02001861 key_bits, cipher_operation );
Moran Peker41deec42018-04-04 15:43:05 +03001862 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001863 {
1864 psa_cipher_abort( operation );
1865 return( mbedtls_to_psa_error( ret ) );
1866 }
1867
mohammad16038481e742018-03-18 13:57:31 +02001868#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03001869 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02001870 {
Gilles Peskine53514202018-06-06 15:11:46 +02001871 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1872 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02001873
Moran Pekera28258c2018-05-29 16:25:04 +03001874 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02001875 {
1876 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
1877 mode = MBEDTLS_PADDING_PKCS7;
1878 break;
1879 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
1880 mode = MBEDTLS_PADDING_NONE;
1881 break;
1882 default:
Moran Pekerae382792018-05-31 14:06:17 +03001883 psa_cipher_abort( operation );
1884 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02001885 }
1886 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03001887 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03001888 {
1889 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02001890 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03001891 }
mohammad16038481e742018-03-18 13:57:31 +02001892 }
1893#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
1894
mohammad1603503973b2018-03-12 15:59:30 +02001895 operation->key_set = 1;
1896 operation->alg = alg;
Gilles Peskine7e928852018-06-04 16:23:10 +02001897 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
1898 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
1899 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001900 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02001901 {
mohammad160389e0f462018-04-12 08:48:45 +03001902 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02001903 }
mohammad1603503973b2018-03-12 15:59:30 +02001904
Moran Peker395db872018-05-31 14:07:14 +03001905 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001906}
1907
Gilles Peskinee553c652018-06-04 16:22:46 +02001908psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
1909 psa_key_slot_t key,
1910 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001911{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001912 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001913}
1914
Gilles Peskinee553c652018-06-04 16:22:46 +02001915psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
1916 psa_key_slot_t key,
1917 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001918{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001919 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001920}
1921
Gilles Peskinee553c652018-06-04 16:22:46 +02001922psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
1923 unsigned char *iv,
1924 size_t iv_size,
1925 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001926{
Moran Peker41deec42018-04-04 15:43:05 +03001927 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001928 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001929 return( PSA_ERROR_BAD_STATE );
1930 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02001931 {
Moran Peker41deec42018-04-04 15:43:05 +03001932 ret = PSA_ERROR_BUFFER_TOO_SMALL;
1933 goto exit;
1934 }
Gilles Peskine7e928852018-06-04 16:23:10 +02001935 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
1936 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03001937 if( ret != 0 )
1938 {
1939 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02001940 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02001941 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001942
mohammad16038481e742018-03-18 13:57:31 +02001943 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03001944 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001945
Moran Peker395db872018-05-31 14:07:14 +03001946exit:
1947 if( ret != PSA_SUCCESS )
1948 psa_cipher_abort( operation );
1949 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02001950}
1951
Gilles Peskinee553c652018-06-04 16:22:46 +02001952psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
1953 const unsigned char *iv,
1954 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001955{
Moran Peker41deec42018-04-04 15:43:05 +03001956 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001957 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001958 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03001959 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03001960 {
Moran Pekerae382792018-05-31 14:06:17 +03001961 psa_cipher_abort( operation );
1962 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03001963 }
mohammad1603503973b2018-03-12 15:59:30 +02001964 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001965 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001966 {
1967 psa_cipher_abort( operation );
1968 return( mbedtls_to_psa_error( ret ) );
1969 }
1970
1971 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02001972
Moran Peker395db872018-05-31 14:07:14 +03001973 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001974}
1975
Gilles Peskinee553c652018-06-04 16:22:46 +02001976psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
1977 const uint8_t *input,
1978 size_t input_length,
1979 unsigned char *output,
1980 size_t output_size,
1981 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001982{
1983 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02001984 size_t expected_output_size;
1985 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
1986 {
1987 /* Take the unprocessed partial block left over from previous
1988 * update calls, if any, plus the input to this call. Remove
1989 * the last partial block, if any. You get the data that will be
1990 * output in this call. */
1991 expected_output_size =
1992 ( operation->ctx.cipher.unprocessed_len + input_length )
1993 / operation->block_size * operation->block_size;
1994 }
1995 else
1996 {
1997 expected_output_size = input_length;
1998 }
1999 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002000 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002001
mohammad1603503973b2018-03-12 15:59:30 +02002002 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002003 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002004 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002005 {
2006 psa_cipher_abort( operation );
2007 return( mbedtls_to_psa_error( ret ) );
2008 }
2009
Moran Peker395db872018-05-31 14:07:14 +03002010 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002011}
2012
Gilles Peskinee553c652018-06-04 16:22:46 +02002013psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2014 uint8_t *output,
2015 size_t output_size,
2016 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002017{
2018 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002019 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002020
mohammad1603503973b2018-03-12 15:59:30 +02002021 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002022 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002023 psa_cipher_abort( operation );
2024 return( PSA_ERROR_BAD_STATE );
2025 }
2026 if( operation->iv_required && ! operation->iv_set )
2027 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002028 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002029 return( PSA_ERROR_BAD_STATE );
2030 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002031 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2032 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002033 {
Gilles Peskine53514202018-06-06 15:11:46 +02002034 psa_algorithm_t padding_mode =
2035 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002036 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002037 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002038 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002039 return( PSA_ERROR_TAMPERING_DETECTED );
2040 }
Gilles Peskine53514202018-06-06 15:11:46 +02002041 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002042 {
2043 if( operation->ctx.cipher.unprocessed_len != 0 )
2044 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002045 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002046 return( PSA_ERROR_INVALID_ARGUMENT );
2047 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002048 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002049 }
2050
2051 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002052 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002053 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002054 {
2055 psa_cipher_abort( operation );
2056 return( mbedtls_to_psa_error( ret ) );
2057 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002058 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002059 memcpy( output, temp_output_buffer, *output_length );
2060 else
2061 {
2062 psa_cipher_abort( operation );
2063 return( PSA_ERROR_BUFFER_TOO_SMALL );
2064 }
mohammad1603503973b2018-03-12 15:59:30 +02002065
Moran Peker4c80d832018-04-22 20:15:31 +03002066 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002067}
2068
Gilles Peskinee553c652018-06-04 16:22:46 +02002069psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2070{
mohammad1603503973b2018-03-12 15:59:30 +02002071 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002072
Moran Peker41deec42018-04-04 15:43:05 +03002073 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002074 operation->key_set = 0;
2075 operation->iv_set = 0;
2076 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002077 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002078 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002079
Moran Peker395db872018-05-31 14:07:14 +03002080 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002081}
2082
Gilles Peskinea0655c32018-04-30 17:06:50 +02002083
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002084
mohammad16038cc1cee2018-03-28 01:21:33 +03002085/****************************************************************/
2086/* Key Policy */
2087/****************************************************************/
2088
Gilles Peskine2d277862018-06-18 15:41:12 +02002089void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002090{
Gilles Peskine803ce742018-06-18 16:07:14 +02002091 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002092}
2093
Gilles Peskine2d277862018-06-18 15:41:12 +02002094void psa_key_policy_set_usage( psa_key_policy_t *policy,
2095 psa_key_usage_t usage,
2096 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002097{
mohammad16034eed7572018-03-28 05:14:59 -07002098 policy->usage = usage;
2099 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002100}
2101
Gilles Peskine2d277862018-06-18 15:41:12 +02002102psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002103{
mohammad16036df908f2018-04-02 08:34:15 -07002104 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002105}
2106
Gilles Peskine2d277862018-06-18 15:41:12 +02002107psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002108{
mohammad16036df908f2018-04-02 08:34:15 -07002109 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002110}
2111
Gilles Peskine2d277862018-06-18 15:41:12 +02002112psa_status_t psa_set_key_policy( psa_key_slot_t key,
2113 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002114{
2115 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002116
Gilles Peskine828ed142018-06-18 23:25:51 +02002117 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002118 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002119
mohammad16038cc1cee2018-03-28 01:21:33 +03002120 slot = &global_data.key_slots[key];
2121 if( slot->type != PSA_KEY_TYPE_NONE )
2122 return( PSA_ERROR_OCCUPIED_SLOT );
2123
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002124 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2125 PSA_KEY_USAGE_ENCRYPT |
2126 PSA_KEY_USAGE_DECRYPT |
2127 PSA_KEY_USAGE_SIGN |
2128 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002129 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002130
mohammad16036df908f2018-04-02 08:34:15 -07002131 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002132
2133 return( PSA_SUCCESS );
2134}
2135
Gilles Peskine2d277862018-06-18 15:41:12 +02002136psa_status_t psa_get_key_policy( psa_key_slot_t key,
2137 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002138{
2139 key_slot_t *slot;
2140
Gilles Peskine828ed142018-06-18 23:25:51 +02002141 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002142 return( PSA_ERROR_INVALID_ARGUMENT );
2143
2144 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002145
mohammad16036df908f2018-04-02 08:34:15 -07002146 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002147
2148 return( PSA_SUCCESS );
2149}
Gilles Peskine20035e32018-02-03 22:44:14 +01002150
Gilles Peskinea0655c32018-04-30 17:06:50 +02002151
2152
mohammad1603804cd712018-03-20 22:44:08 +02002153/****************************************************************/
2154/* Key Lifetime */
2155/****************************************************************/
2156
Gilles Peskine2d277862018-06-18 15:41:12 +02002157psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2158 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002159{
2160 key_slot_t *slot;
2161
Gilles Peskine828ed142018-06-18 23:25:51 +02002162 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002163 return( PSA_ERROR_INVALID_ARGUMENT );
2164
2165 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002166
mohammad1603804cd712018-03-20 22:44:08 +02002167 *lifetime = slot->lifetime;
2168
2169 return( PSA_SUCCESS );
2170}
2171
Gilles Peskine2d277862018-06-18 15:41:12 +02002172psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2173 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002174{
2175 key_slot_t *slot;
2176
Gilles Peskine828ed142018-06-18 23:25:51 +02002177 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002178 return( PSA_ERROR_INVALID_ARGUMENT );
2179
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002180 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2181 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002182 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2183 return( PSA_ERROR_INVALID_ARGUMENT );
2184
mohammad1603804cd712018-03-20 22:44:08 +02002185 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002186 if( slot->type != PSA_KEY_TYPE_NONE )
2187 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002188
Moran Pekerd7326592018-05-29 16:56:39 +03002189 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002190 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002191
mohammad1603060ad8a2018-03-20 14:28:38 -07002192 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002193
2194 return( PSA_SUCCESS );
2195}
2196
Gilles Peskine20035e32018-02-03 22:44:14 +01002197
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002198
mohammad16035955c982018-04-26 00:53:03 +03002199/****************************************************************/
2200/* AEAD */
2201/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002202
mohammad16035955c982018-04-26 00:53:03 +03002203psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2204 psa_algorithm_t alg,
2205 const uint8_t *nonce,
2206 size_t nonce_length,
2207 const uint8_t *additional_data,
2208 size_t additional_data_length,
2209 const uint8_t *plaintext,
2210 size_t plaintext_length,
2211 uint8_t *ciphertext,
2212 size_t ciphertext_size,
2213 size_t *ciphertext_length )
2214{
2215 int ret;
2216 psa_status_t status;
2217 key_slot_t *slot;
2218 psa_key_type_t key_type;
2219 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002220 uint8_t *tag;
2221 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002222 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002223 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002224
mohammad1603f08a5502018-06-03 15:05:47 +03002225 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002226
mohammad16035955c982018-04-26 00:53:03 +03002227 status = psa_get_key_information( key, &key_type, &key_bits );
2228 if( status != PSA_SUCCESS )
2229 return( status );
2230 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002231 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002232 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002233
mohammad16035ed06212018-06-06 13:09:34 +03002234 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2235 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002236 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002237 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002238
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002239 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002240 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002241
Gilles Peskine2d277862018-06-18 15:41:12 +02002242 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2243 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002244 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002245
mohammad16035955c982018-04-26 00:53:03 +03002246 if( alg == PSA_ALG_GCM )
2247 {
2248 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002249 tag_length = 16;
2250
mohammad160396910d82018-06-04 14:33:00 +03002251 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2252 return( PSA_ERROR_INVALID_ARGUMENT );
2253
mohammad160315223a82018-06-03 17:19:55 +03002254 //make sure we have place to hold the tag in the ciphertext buffer
2255 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002256 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002257
2258 //update the tag pointer to point to the end of the ciphertext_length
2259 tag = ciphertext + plaintext_length;
2260
mohammad16035955c982018-04-26 00:53:03 +03002261 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002262 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002263 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002264 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002265 if( ret != 0 )
2266 {
2267 mbedtls_gcm_free( &gcm );
2268 return( mbedtls_to_psa_error( ret ) );
2269 }
2270 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002271 plaintext_length, nonce,
2272 nonce_length, additional_data,
2273 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002274 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002275 mbedtls_gcm_free( &gcm );
2276 }
2277 else if( alg == PSA_ALG_CCM )
2278 {
2279 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002280 tag_length = 16;
2281
mohammad160396910d82018-06-04 14:33:00 +03002282 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2283 return( PSA_ERROR_INVALID_ARGUMENT );
2284
mohammad160347ddf3d2018-04-26 01:11:21 +03002285 if( nonce_length < 7 || nonce_length > 13 )
2286 return( PSA_ERROR_INVALID_ARGUMENT );
2287
mohammad160315223a82018-06-03 17:19:55 +03002288 //make sure we have place to hold the tag in the ciphertext buffer
2289 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002290 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002291
2292 //update the tag pointer to point to the end of the ciphertext_length
2293 tag = ciphertext + plaintext_length;
2294
mohammad16035955c982018-04-26 00:53:03 +03002295 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002296 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002297 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002298 if( ret != 0 )
2299 {
2300 mbedtls_ccm_free( &ccm );
2301 return( mbedtls_to_psa_error( ret ) );
2302 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002303 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002304 nonce, nonce_length,
2305 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002306 additional_data_length,
2307 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002308 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002309 mbedtls_ccm_free( &ccm );
2310 }
mohammad16035c8845f2018-05-09 05:40:09 -07002311 else
2312 {
mohammad1603554faad2018-06-03 15:07:38 +03002313 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002314 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002315
mohammad160315223a82018-06-03 17:19:55 +03002316 if( ret != 0 )
2317 {
2318 memset( ciphertext, 0, ciphertext_size );
2319 return( mbedtls_to_psa_error( ret ) );
2320 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002321
mohammad160315223a82018-06-03 17:19:55 +03002322 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002323 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002324}
2325
Gilles Peskineee652a32018-06-01 19:23:52 +02002326/* Locate the tag in a ciphertext buffer containing the encrypted data
2327 * followed by the tag. Return the length of the part preceding the tag in
2328 * *plaintext_length. This is the size of the plaintext in modes where
2329 * the encrypted data has the same size as the plaintext, such as
2330 * CCM and GCM. */
2331static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2332 const uint8_t *ciphertext,
2333 size_t ciphertext_length,
2334 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002335 const uint8_t **p_tag )
2336{
2337 size_t payload_length;
2338 if( tag_length > ciphertext_length )
2339 return( PSA_ERROR_INVALID_ARGUMENT );
2340 payload_length = ciphertext_length - tag_length;
2341 if( payload_length > plaintext_size )
2342 return( PSA_ERROR_BUFFER_TOO_SMALL );
2343 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002344 return( PSA_SUCCESS );
2345}
2346
mohammad16035955c982018-04-26 00:53:03 +03002347psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2348 psa_algorithm_t alg,
2349 const uint8_t *nonce,
2350 size_t nonce_length,
2351 const uint8_t *additional_data,
2352 size_t additional_data_length,
2353 const uint8_t *ciphertext,
2354 size_t ciphertext_length,
2355 uint8_t *plaintext,
2356 size_t plaintext_size,
2357 size_t *plaintext_length )
2358{
2359 int ret;
2360 psa_status_t status;
2361 key_slot_t *slot;
2362 psa_key_type_t key_type;
2363 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002364 const uint8_t *tag;
2365 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002366 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002367 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002368
Gilles Peskineee652a32018-06-01 19:23:52 +02002369 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002370
mohammad16035955c982018-04-26 00:53:03 +03002371 status = psa_get_key_information( key, &key_type, &key_bits );
2372 if( status != PSA_SUCCESS )
2373 return( status );
2374 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002375 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002376 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002377
mohammad16035ed06212018-06-06 13:09:34 +03002378 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2379 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002380 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002381 return( PSA_ERROR_NOT_SUPPORTED );
2382
mohammad1603f14394b2018-06-04 14:33:19 +03002383 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2384 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002385
Gilles Peskine2d277862018-06-18 15:41:12 +02002386 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2387 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002388 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002389
mohammad16035955c982018-04-26 00:53:03 +03002390 if( alg == PSA_ALG_GCM )
2391 {
2392 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002393
Gilles Peskineee652a32018-06-01 19:23:52 +02002394 tag_length = 16;
2395 status = psa_aead_unpadded_locate_tag( tag_length,
2396 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002397 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002398 if( status != PSA_SUCCESS )
2399 return( status );
2400
mohammad16035955c982018-04-26 00:53:03 +03002401 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002402 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002403 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002404 if( ret != 0 )
2405 {
2406 mbedtls_gcm_free( &gcm );
2407 return( mbedtls_to_psa_error( ret ) );
2408 }
mohammad16035955c982018-04-26 00:53:03 +03002409
Gilles Peskineee652a32018-06-01 19:23:52 +02002410 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002411 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002412 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002413 additional_data,
2414 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002415 tag, tag_length,
2416 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002417 mbedtls_gcm_free( &gcm );
2418 }
2419 else if( alg == PSA_ALG_CCM )
2420 {
2421 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002422
mohammad160347ddf3d2018-04-26 01:11:21 +03002423 if( nonce_length < 7 || nonce_length > 13 )
2424 return( PSA_ERROR_INVALID_ARGUMENT );
2425
mohammad16039375f842018-06-03 14:28:24 +03002426 tag_length = 16;
2427 status = psa_aead_unpadded_locate_tag( tag_length,
2428 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002429 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002430 if( status != PSA_SUCCESS )
2431 return( status );
2432
mohammad16035955c982018-04-26 00:53:03 +03002433 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002434 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002435 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002436 if( ret != 0 )
2437 {
2438 mbedtls_ccm_free( &ccm );
2439 return( mbedtls_to_psa_error( ret ) );
2440 }
mohammad160360a64d02018-06-03 17:20:42 +03002441 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002442 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002443 additional_data,
2444 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002445 ciphertext, plaintext,
2446 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002447 mbedtls_ccm_free( &ccm );
2448 }
mohammad160339574652018-06-01 04:39:53 -07002449 else
2450 {
mohammad1603554faad2018-06-03 15:07:38 +03002451 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002452 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002453
Gilles Peskineee652a32018-06-01 19:23:52 +02002454 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002455 memset( plaintext, 0, plaintext_size );
2456 else
2457 *plaintext_length = ciphertext_length - tag_length;
2458
Gilles Peskineee652a32018-06-01 19:23:52 +02002459 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002460}
2461
Gilles Peskinea0655c32018-04-30 17:06:50 +02002462
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002463
Gilles Peskine20035e32018-02-03 22:44:14 +01002464/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002465/* Key generation */
2466/****************************************************************/
2467
2468psa_status_t psa_generate_random( uint8_t *output,
2469 size_t output_size )
2470{
2471 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2472 output, output_size );
2473 return( mbedtls_to_psa_error( ret ) );
2474}
2475
2476psa_status_t psa_generate_key( psa_key_slot_t key,
2477 psa_key_type_t type,
2478 size_t bits,
2479 const void *parameters,
2480 size_t parameters_size )
2481{
2482 return( PSA_ERROR_NOT_SUPPORTED );
2483}
2484
2485
2486/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002487/* Module setup */
2488/****************************************************************/
2489
Gilles Peskinee59236f2018-01-27 23:32:46 +01002490void mbedtls_psa_crypto_free( void )
2491{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002492 size_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02002493 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002494 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002495 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2496 mbedtls_entropy_free( &global_data.entropy );
2497 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2498}
2499
2500psa_status_t psa_crypto_init( void )
2501{
2502 int ret;
2503 const unsigned char drbg_seed[] = "PSA";
2504
2505 if( global_data.initialized != 0 )
2506 return( PSA_SUCCESS );
2507
2508 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2509 mbedtls_entropy_init( &global_data.entropy );
2510 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2511
2512 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2513 mbedtls_entropy_func,
2514 &global_data.entropy,
2515 drbg_seed, sizeof( drbg_seed ) - 1 );
2516 if( ret != 0 )
2517 goto exit;
2518
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002519 global_data.initialized = 1;
2520
Gilles Peskinee59236f2018-01-27 23:32:46 +01002521exit:
2522 if( ret != 0 )
2523 mbedtls_psa_crypto_free( );
2524 return( mbedtls_to_psa_error( ret ) );
2525}
2526
2527#endif /* MBEDTLS_PSA_CRYPTO_C */