blob: 8e7aeefa26728f9ead957bfbb9bcd5751a090454 [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 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200631 {
632 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300633 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200634 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200635 /* The mbedtls_pk_xxx functions write to the end of the buffer.
636 * Move the data to the beginning and erase remaining data
637 * at the original location. */
638 if( 2 * (size_t) ret <= data_size )
639 {
640 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200641 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200642 }
643 else if( (size_t) ret < data_size )
644 {
645 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200646 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200647 }
Moran Pekera998bc62018-04-16 18:16:20 +0300648 *data_length = ret;
649 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100650 }
651 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100652#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300653 {
654 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200655 it is valid for a special-purpose implementation to omit
656 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300657 return( PSA_ERROR_NOT_SUPPORTED );
658 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100659 }
660}
661
Gilles Peskine2d277862018-06-18 15:41:12 +0200662psa_status_t psa_export_key( psa_key_slot_t key,
663 uint8_t *data,
664 size_t data_size,
665 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300666{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200667 return( psa_internal_export_key( key, data, data_size,
668 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100669}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100670
Gilles Peskine2d277862018-06-18 15:41:12 +0200671psa_status_t psa_export_public_key( psa_key_slot_t key,
672 uint8_t *data,
673 size_t data_size,
674 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300675{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200676 return( psa_internal_export_key( key, data, data_size,
677 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300678}
679
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200680
681
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100682/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100683/* Message digests */
684/****************************************************************/
685
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100686static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100687{
688 switch( alg )
689 {
690#if defined(MBEDTLS_MD2_C)
691 case PSA_ALG_MD2:
692 return( &mbedtls_md2_info );
693#endif
694#if defined(MBEDTLS_MD4_C)
695 case PSA_ALG_MD4:
696 return( &mbedtls_md4_info );
697#endif
698#if defined(MBEDTLS_MD5_C)
699 case PSA_ALG_MD5:
700 return( &mbedtls_md5_info );
701#endif
702#if defined(MBEDTLS_RIPEMD160_C)
703 case PSA_ALG_RIPEMD160:
704 return( &mbedtls_ripemd160_info );
705#endif
706#if defined(MBEDTLS_SHA1_C)
707 case PSA_ALG_SHA_1:
708 return( &mbedtls_sha1_info );
709#endif
710#if defined(MBEDTLS_SHA256_C)
711 case PSA_ALG_SHA_224:
712 return( &mbedtls_sha224_info );
713 case PSA_ALG_SHA_256:
714 return( &mbedtls_sha256_info );
715#endif
716#if defined(MBEDTLS_SHA512_C)
717 case PSA_ALG_SHA_384:
718 return( &mbedtls_sha384_info );
719 case PSA_ALG_SHA_512:
720 return( &mbedtls_sha512_info );
721#endif
722 default:
723 return( NULL );
724 }
725}
726
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100727psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
728{
729 switch( operation->alg )
730 {
731#if defined(MBEDTLS_MD2_C)
732 case PSA_ALG_MD2:
733 mbedtls_md2_free( &operation->ctx.md2 );
734 break;
735#endif
736#if defined(MBEDTLS_MD4_C)
737 case PSA_ALG_MD4:
738 mbedtls_md4_free( &operation->ctx.md4 );
739 break;
740#endif
741#if defined(MBEDTLS_MD5_C)
742 case PSA_ALG_MD5:
743 mbedtls_md5_free( &operation->ctx.md5 );
744 break;
745#endif
746#if defined(MBEDTLS_RIPEMD160_C)
747 case PSA_ALG_RIPEMD160:
748 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
749 break;
750#endif
751#if defined(MBEDTLS_SHA1_C)
752 case PSA_ALG_SHA_1:
753 mbedtls_sha1_free( &operation->ctx.sha1 );
754 break;
755#endif
756#if defined(MBEDTLS_SHA256_C)
757 case PSA_ALG_SHA_224:
758 case PSA_ALG_SHA_256:
759 mbedtls_sha256_free( &operation->ctx.sha256 );
760 break;
761#endif
762#if defined(MBEDTLS_SHA512_C)
763 case PSA_ALG_SHA_384:
764 case PSA_ALG_SHA_512:
765 mbedtls_sha512_free( &operation->ctx.sha512 );
766 break;
767#endif
768 default:
769 return( PSA_ERROR_NOT_SUPPORTED );
770 }
771 operation->alg = 0;
772 return( PSA_SUCCESS );
773}
774
775psa_status_t psa_hash_start( psa_hash_operation_t *operation,
776 psa_algorithm_t alg )
777{
778 int ret;
779 operation->alg = 0;
780 switch( alg )
781 {
782#if defined(MBEDTLS_MD2_C)
783 case PSA_ALG_MD2:
784 mbedtls_md2_init( &operation->ctx.md2 );
785 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
786 break;
787#endif
788#if defined(MBEDTLS_MD4_C)
789 case PSA_ALG_MD4:
790 mbedtls_md4_init( &operation->ctx.md4 );
791 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
792 break;
793#endif
794#if defined(MBEDTLS_MD5_C)
795 case PSA_ALG_MD5:
796 mbedtls_md5_init( &operation->ctx.md5 );
797 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
798 break;
799#endif
800#if defined(MBEDTLS_RIPEMD160_C)
801 case PSA_ALG_RIPEMD160:
802 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
803 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
804 break;
805#endif
806#if defined(MBEDTLS_SHA1_C)
807 case PSA_ALG_SHA_1:
808 mbedtls_sha1_init( &operation->ctx.sha1 );
809 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
810 break;
811#endif
812#if defined(MBEDTLS_SHA256_C)
813 case PSA_ALG_SHA_224:
814 mbedtls_sha256_init( &operation->ctx.sha256 );
815 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
816 break;
817 case PSA_ALG_SHA_256:
818 mbedtls_sha256_init( &operation->ctx.sha256 );
819 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
820 break;
821#endif
822#if defined(MBEDTLS_SHA512_C)
823 case PSA_ALG_SHA_384:
824 mbedtls_sha512_init( &operation->ctx.sha512 );
825 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
826 break;
827 case PSA_ALG_SHA_512:
828 mbedtls_sha512_init( &operation->ctx.sha512 );
829 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
830 break;
831#endif
832 default:
833 return( PSA_ERROR_NOT_SUPPORTED );
834 }
835 if( ret == 0 )
836 operation->alg = alg;
837 else
838 psa_hash_abort( operation );
839 return( mbedtls_to_psa_error( ret ) );
840}
841
842psa_status_t psa_hash_update( psa_hash_operation_t *operation,
843 const uint8_t *input,
844 size_t input_length )
845{
846 int ret;
847 switch( operation->alg )
848 {
849#if defined(MBEDTLS_MD2_C)
850 case PSA_ALG_MD2:
851 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
852 input, input_length );
853 break;
854#endif
855#if defined(MBEDTLS_MD4_C)
856 case PSA_ALG_MD4:
857 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
858 input, input_length );
859 break;
860#endif
861#if defined(MBEDTLS_MD5_C)
862 case PSA_ALG_MD5:
863 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
864 input, input_length );
865 break;
866#endif
867#if defined(MBEDTLS_RIPEMD160_C)
868 case PSA_ALG_RIPEMD160:
869 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
870 input, input_length );
871 break;
872#endif
873#if defined(MBEDTLS_SHA1_C)
874 case PSA_ALG_SHA_1:
875 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
876 input, input_length );
877 break;
878#endif
879#if defined(MBEDTLS_SHA256_C)
880 case PSA_ALG_SHA_224:
881 case PSA_ALG_SHA_256:
882 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
883 input, input_length );
884 break;
885#endif
886#if defined(MBEDTLS_SHA512_C)
887 case PSA_ALG_SHA_384:
888 case PSA_ALG_SHA_512:
889 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
890 input, input_length );
891 break;
892#endif
893 default:
894 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
895 break;
896 }
897 if( ret != 0 )
898 psa_hash_abort( operation );
899 return( mbedtls_to_psa_error( ret ) );
900}
901
902psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
903 uint8_t *hash,
904 size_t hash_size,
905 size_t *hash_length )
906{
907 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200908 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100909
910 /* Fill the output buffer with something that isn't a valid hash
911 * (barring an attack on the hash and deliberately-crafted input),
912 * in case the caller doesn't check the return status properly. */
913 *hash_length = actual_hash_length;
914 memset( hash, '!', hash_size );
915
916 if( hash_size < actual_hash_length )
917 return( PSA_ERROR_BUFFER_TOO_SMALL );
918
919 switch( operation->alg )
920 {
921#if defined(MBEDTLS_MD2_C)
922 case PSA_ALG_MD2:
923 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
924 break;
925#endif
926#if defined(MBEDTLS_MD4_C)
927 case PSA_ALG_MD4:
928 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
929 break;
930#endif
931#if defined(MBEDTLS_MD5_C)
932 case PSA_ALG_MD5:
933 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
934 break;
935#endif
936#if defined(MBEDTLS_RIPEMD160_C)
937 case PSA_ALG_RIPEMD160:
938 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
939 break;
940#endif
941#if defined(MBEDTLS_SHA1_C)
942 case PSA_ALG_SHA_1:
943 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
944 break;
945#endif
946#if defined(MBEDTLS_SHA256_C)
947 case PSA_ALG_SHA_224:
948 case PSA_ALG_SHA_256:
949 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
950 break;
951#endif
952#if defined(MBEDTLS_SHA512_C)
953 case PSA_ALG_SHA_384:
954 case PSA_ALG_SHA_512:
955 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
956 break;
957#endif
958 default:
959 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
960 break;
961 }
962
963 if( ret == 0 )
964 {
965 return( psa_hash_abort( operation ) );
966 }
967 else
968 {
969 psa_hash_abort( operation );
970 return( mbedtls_to_psa_error( ret ) );
971 }
972}
973
Gilles Peskine2d277862018-06-18 15:41:12 +0200974psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
975 const uint8_t *hash,
976 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100977{
978 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
979 size_t actual_hash_length;
980 psa_status_t status = psa_hash_finish( operation,
981 actual_hash, sizeof( actual_hash ),
982 &actual_hash_length );
983 if( status != PSA_SUCCESS )
984 return( status );
985 if( actual_hash_length != hash_length )
986 return( PSA_ERROR_INVALID_SIGNATURE );
987 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
988 return( PSA_ERROR_INVALID_SIGNATURE );
989 return( PSA_SUCCESS );
990}
991
992
993
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100994/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +0100995/* MAC */
996/****************************************************************/
997
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100998static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +0100999 psa_algorithm_t alg,
1000 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001001 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001002 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001003{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001004 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001005 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001006
1007 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1008 {
1009 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001010 {
1011 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1012 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001013
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001014 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001015 {
1016 case PSA_ALG_STREAM_CIPHER:
1017 mode = MBEDTLS_MODE_STREAM;
1018 break;
1019 case PSA_ALG_CBC_BASE:
1020 mode = MBEDTLS_MODE_CBC;
1021 break;
1022 case PSA_ALG_CFB_BASE:
1023 mode = MBEDTLS_MODE_CFB;
1024 break;
1025 case PSA_ALG_OFB_BASE:
1026 mode = MBEDTLS_MODE_OFB;
1027 break;
1028 case PSA_ALG_CTR:
1029 mode = MBEDTLS_MODE_CTR;
1030 break;
1031 case PSA_ALG_CCM:
1032 mode = MBEDTLS_MODE_CCM;
1033 break;
1034 case PSA_ALG_GCM:
1035 mode = MBEDTLS_MODE_GCM;
1036 break;
1037 default:
1038 return( NULL );
1039 }
1040 }
1041 else if( alg == PSA_ALG_CMAC )
1042 mode = MBEDTLS_MODE_ECB;
1043 else if( alg == PSA_ALG_GMAC )
1044 mode = MBEDTLS_MODE_GCM;
1045 else
1046 return( NULL );
1047
1048 switch( key_type )
1049 {
1050 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001051 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001052 break;
1053 case PSA_KEY_TYPE_DES:
1054 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001055 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001056 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001057 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001058 break;
1059 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001060 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001061 break;
1062 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001063 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001064 break;
1065 default:
1066 return( NULL );
1067 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001068 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001069 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001070
mohammad1603f4f0d612018-06-03 15:04:51 +03001071 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001072}
1073
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001074static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001075{
Gilles Peskine2d277862018-06-18 15:41:12 +02001076 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001077 {
1078 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001079 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001080 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001081 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001082 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001083 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001084 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001085 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001086 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001087 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001088 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001089 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001090 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001091 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001092 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001093 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001094 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001095 return( 128 );
1096 default:
1097 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001098 }
1099}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001100
Gilles Peskine8c9def32018-02-08 10:02:12 +01001101psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1102{
1103 switch( operation->alg )
1104 {
1105#if defined(MBEDTLS_CMAC_C)
1106 case PSA_ALG_CMAC:
1107 mbedtls_cipher_free( &operation->ctx.cmac );
1108 break;
1109#endif /* MBEDTLS_CMAC_C */
1110 default:
1111#if defined(MBEDTLS_MD_C)
1112 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001113 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001114 unsigned int block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001115 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001116
Gilles Peskine99bc6492018-06-11 17:13:00 +02001117 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001118 return( PSA_ERROR_NOT_SUPPORTED );
1119
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001120 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001121 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001122 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001123 else
1124#endif /* MBEDTLS_MD_C */
1125 return( PSA_ERROR_NOT_SUPPORTED );
1126 }
Moran Peker41deec42018-04-04 15:43:05 +03001127
Gilles Peskine8c9def32018-02-08 10:02:12 +01001128 operation->alg = 0;
1129 operation->key_set = 0;
1130 operation->iv_set = 0;
1131 operation->iv_required = 0;
1132 operation->has_input = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001133
Gilles Peskine8c9def32018-02-08 10:02:12 +01001134 return( PSA_SUCCESS );
1135}
1136
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001137#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001138static int psa_cmac_start( psa_mac_operation_t *operation,
1139 size_t key_bits,
1140 key_slot_t *slot,
1141 const mbedtls_cipher_info_t *cipher_info )
1142{
1143 int ret;
1144
1145 operation->mac_size = cipher_info->block_size;
1146 operation->iv_required = 0;
1147 mbedtls_cipher_init( &operation->ctx.cmac );
1148
1149 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1150 if( ret != 0 )
1151 return( ret );
1152
1153 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1154 slot->data.raw.data,
1155 key_bits );
1156 return( ret );
1157}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001158#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001159
1160static int psa_hmac_start( psa_mac_operation_t *operation,
1161 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001162 key_slot_t *slot,
1163 psa_algorithm_t alg )
1164{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001165 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001166 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001167 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001168 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001169 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001170 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001171 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001172 size_t key_length = slot->data.raw.bytes;
1173 psa_status_t status;
1174
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001175 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001176 return( PSA_ERROR_NOT_SUPPORTED );
1177
1178 if( key_type != PSA_KEY_TYPE_HMAC )
1179 return( PSA_ERROR_INVALID_ARGUMENT );
1180
1181 operation->iv_required = 0;
1182 operation->mac_size = digest_size;
1183
1184 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1185 PSA_ALG_HMAC_HASH( alg ) );
1186 if( status != PSA_SUCCESS )
1187 return( status );
1188
Gilles Peskined223b522018-06-11 18:12:58 +02001189 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001190 {
1191 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001192 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001193 if( status != PSA_SUCCESS )
1194 return( status );
1195 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001196 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001197 if( status != PSA_SUCCESS )
1198 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001199 }
Gilles Peskined223b522018-06-11 18:12:58 +02001200 else
1201 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001202
Gilles Peskined223b522018-06-11 18:12:58 +02001203 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1204 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001205 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001206 ipad[i] ^= 0x36;
1207 memset( ipad + key_length, 0x36, block_size - key_length );
1208
1209 /* Copy the key material from ipad to opad, flipping the requisite bits,
1210 * and filling the rest of opad with the requisite constant. */
1211 for( i = 0; i < key_length; i++ )
1212 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1213 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001214
1215 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1216 PSA_ALG_HMAC_HASH( alg ) );
1217 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001218 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001219
1220 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1221 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001222
1223cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001224 mbedtls_zeroize( ipad, key_length );
1225 /* opad is in the context. It needs to stay in memory if this function
1226 * succeeds, and it will be wiped by psa_mac_abort() called from
1227 * psa_mac_start in the error case. */
1228
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001229 return( status );
1230}
1231
Gilles Peskine8c9def32018-02-08 10:02:12 +01001232psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1233 psa_key_slot_t key,
1234 psa_algorithm_t alg )
1235{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001236 psa_status_t status;
1237 key_slot_t *slot;
1238 psa_key_type_t key_type;
1239 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001240 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001241
1242 operation->alg = 0;
1243 operation->key_set = 0;
1244 operation->iv_set = 0;
1245 operation->iv_required = 1;
1246 operation->has_input = 0;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001247 operation->key_usage_sign = 0;
1248 operation->key_usage_verify = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001249
1250 status = psa_get_key_information( key, &key_type, &key_bits );
1251 if( status != PSA_SUCCESS )
1252 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001253
Gilles Peskine8c9def32018-02-08 10:02:12 +01001254 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001255 if( slot->type == PSA_KEY_TYPE_NONE )
1256 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001257
Moran Pekerd7326592018-05-29 16:56:39 +03001258 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001259 operation->key_usage_sign = 1;
1260
Moran Pekerd7326592018-05-29 16:56:39 +03001261 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001262 operation->key_usage_verify = 1;
1263
Gilles Peskine8c9def32018-02-08 10:02:12 +01001264 if( ! PSA_ALG_IS_HMAC( alg ) )
1265 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001266 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001267 if( cipher_info == NULL )
1268 return( PSA_ERROR_NOT_SUPPORTED );
1269 operation->mac_size = cipher_info->block_size;
1270 }
1271 switch( alg )
1272 {
1273#if defined(MBEDTLS_CMAC_C)
1274 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001275 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1276 key_bits,
1277 slot,
1278 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001279 break;
1280#endif /* MBEDTLS_CMAC_C */
1281 default:
1282#if defined(MBEDTLS_MD_C)
1283 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001284 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001285 else
1286#endif /* MBEDTLS_MD_C */
1287 return( PSA_ERROR_NOT_SUPPORTED );
1288 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001289
Gilles Peskine8c9def32018-02-08 10:02:12 +01001290 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001291
1292 * context may contain data that needs to be wiped on error. */
1293 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001294 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001295 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001296 }
Gilles Peskine99bc6492018-06-11 17:13:00 +02001297
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001298 else
1299 {
1300 operation->alg = alg;
1301 operation->key_set = 1;
1302 }
1303 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001304}
1305
1306psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1307 const uint8_t *input,
1308 size_t input_length )
1309{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001310 int ret = 0 ;
1311 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001312 if( ! operation->key_set )
1313 return( PSA_ERROR_BAD_STATE );
1314 if( operation->iv_required && ! operation->iv_set )
1315 return( PSA_ERROR_BAD_STATE );
1316 operation->has_input = 1;
1317
1318 switch( operation->alg )
1319 {
1320#if defined(MBEDTLS_CMAC_C)
1321 case PSA_ALG_CMAC:
1322 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1323 input, input_length );
1324 break;
1325#endif /* MBEDTLS_CMAC_C */
1326 default:
1327#if defined(MBEDTLS_MD_C)
1328 if( PSA_ALG_IS_HMAC( operation->alg ) )
1329 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001330 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001331 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001332 }
1333 else
1334#endif /* MBEDTLS_MD_C */
1335 {
1336 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1337 }
1338 break;
1339 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001340 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001341 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001342 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001343 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001344 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001345 }
1346
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001347 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001348}
1349
mohammad16036df908f2018-04-02 08:34:15 -07001350static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001351 uint8_t *mac,
1352 size_t mac_size,
1353 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001354{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001355 int ret = 0;
1356 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001357 if( ! operation->key_set )
1358 return( PSA_ERROR_BAD_STATE );
1359 if( operation->iv_required && ! operation->iv_set )
1360 return( PSA_ERROR_BAD_STATE );
1361
1362 /* Fill the output buffer with something that isn't a valid mac
1363 * (barring an attack on the mac and deliberately-crafted input),
1364 * in case the caller doesn't check the return status properly. */
1365 *mac_length = operation->mac_size;
1366 memset( mac, '!', mac_size );
1367
1368 if( mac_size < operation->mac_size )
1369 return( PSA_ERROR_BUFFER_TOO_SMALL );
1370
1371 switch( operation->alg )
1372 {
1373#if defined(MBEDTLS_CMAC_C)
1374 case PSA_ALG_CMAC:
1375 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1376 break;
1377#endif /* MBEDTLS_CMAC_C */
1378 default:
1379#if defined(MBEDTLS_MD_C)
1380 if( PSA_ALG_IS_HMAC( operation->alg ) )
1381 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001382 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001383 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001384 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001385 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001386 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001387
Gilles Peskine99bc6492018-06-11 17:13:00 +02001388 if( block_size == 0 )
1389 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001390
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001391 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001392 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001393 if( status != PSA_SUCCESS )
1394 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001395 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001396
1397 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1398 PSA_ALG_HMAC_HASH( operation->alg ) );
1399 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001400 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001401
1402 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001403 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001404 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001405 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001406
1407 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001408 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001409 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001410 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001411
1412 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1413 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001414 hmac_cleanup:
1415 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001416 }
1417 else
1418#endif /* MBEDTLS_MD_C */
1419 {
1420 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1421 }
1422 break;
1423 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001424cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001425
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001426 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001427 {
1428 return( psa_mac_abort( operation ) );
1429 }
1430 else
1431 {
1432 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001433 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001434 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001435
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001436 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001437 }
1438}
1439
mohammad16036df908f2018-04-02 08:34:15 -07001440psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1441 uint8_t *mac,
1442 size_t mac_size,
1443 size_t *mac_length )
1444{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001445 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001446 return( PSA_ERROR_NOT_PERMITTED );
1447
Gilles Peskine99bc6492018-06-11 17:13:00 +02001448 return( psa_mac_finish_internal( operation, mac,
1449 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001450}
1451
Gilles Peskine828ed142018-06-18 23:25:51 +02001452#define PSA_MAC_MAX_SIZE \
Gilles Peskine2d277862018-06-18 15:41:12 +02001453 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1454 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001455 MBEDTLS_MAX_BLOCK_LENGTH )
1456psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1457 const uint8_t *mac,
1458 size_t mac_length )
1459{
Gilles Peskine828ed142018-06-18 23:25:51 +02001460 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001461 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001462 psa_status_t status;
1463
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001464 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001465 return( PSA_ERROR_NOT_PERMITTED );
1466
1467 status = psa_mac_finish_internal( operation,
1468 actual_mac, sizeof( actual_mac ),
1469 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001470 if( status != PSA_SUCCESS )
1471 return( status );
1472 if( actual_mac_length != mac_length )
1473 return( PSA_ERROR_INVALID_SIGNATURE );
1474 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1475 return( PSA_ERROR_INVALID_SIGNATURE );
1476 return( PSA_SUCCESS );
1477}
1478
1479
Gilles Peskine20035e32018-02-03 22:44:14 +01001480
Gilles Peskine20035e32018-02-03 22:44:14 +01001481/****************************************************************/
1482/* Asymmetric cryptography */
1483/****************************************************************/
1484
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001485/* Decode the hash algorithm from alg and store the mbedtls encoding in
1486 * md_alg. Verify that the hash length is consistent. */
1487static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1488 size_t hash_length,
1489 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001490{
Gilles Peskine61b91d42018-06-08 16:09:36 +02001491 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
1492 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1493 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1494 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001495 {
1496#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001497 if( hash_length > UINT_MAX )
1498 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001499#endif
1500 }
1501 else
1502 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001503 if( mbedtls_md_get_size( md_info ) != hash_length )
1504 return( PSA_ERROR_INVALID_ARGUMENT );
1505 if( md_info == NULL )
1506 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001507 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001508 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001509}
1510
Gilles Peskine61b91d42018-06-08 16:09:36 +02001511psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1512 psa_algorithm_t alg,
1513 const uint8_t *hash,
1514 size_t hash_length,
1515 const uint8_t *salt,
1516 size_t salt_length,
1517 uint8_t *signature,
1518 size_t signature_size,
1519 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001520{
1521 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001522 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001523 *signature_length = 0;
1524 (void) salt;
1525 (void) salt_length;
1526
Gilles Peskine828ed142018-06-18 23:25:51 +02001527 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine20035e32018-02-03 22:44:14 +01001528 return( PSA_ERROR_EMPTY_SLOT );
1529 slot = &global_data.key_slots[key];
1530 if( slot->type == PSA_KEY_TYPE_NONE )
1531 return( PSA_ERROR_EMPTY_SLOT );
1532 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1533 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001534 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001535 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001536
Gilles Peskine20035e32018-02-03 22:44:14 +01001537#if defined(MBEDTLS_RSA_C)
1538 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1539 {
1540 mbedtls_rsa_context *rsa = slot->data.rsa;
1541 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001542 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001543 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001544 if( status != PSA_SUCCESS )
1545 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001546
Gilles Peskine20035e32018-02-03 22:44:14 +01001547 if( signature_size < rsa->len )
1548 return( PSA_ERROR_BUFFER_TOO_SMALL );
1549#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001550 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001551 {
1552 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1553 MBEDTLS_MD_NONE );
1554 ret = mbedtls_rsa_pkcs1_sign( rsa,
1555 mbedtls_ctr_drbg_random,
1556 &global_data.ctr_drbg,
1557 MBEDTLS_RSA_PRIVATE,
1558 md_alg, hash_length, hash,
1559 signature );
1560 }
1561 else
1562#endif /* MBEDTLS_PKCS1_V15 */
1563#if defined(MBEDTLS_PKCS1_V21)
1564 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1565 {
1566 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1567 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1568 mbedtls_ctr_drbg_random,
1569 &global_data.ctr_drbg,
1570 MBEDTLS_RSA_PRIVATE,
1571 md_alg, hash_length, hash,
1572 signature );
1573 }
1574 else
1575#endif /* MBEDTLS_PKCS1_V21 */
1576 {
1577 return( PSA_ERROR_INVALID_ARGUMENT );
1578 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001579 if( ret == 0 )
1580 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001581 return( mbedtls_to_psa_error( ret ) );
1582 }
1583 else
1584#endif /* defined(MBEDTLS_RSA_C) */
1585#if defined(MBEDTLS_ECP_C)
1586 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1587 {
itayzafrir5c753392018-05-08 11:18:38 +03001588 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1589 int ret;
1590 const mbedtls_md_info_t *md_info;
1591 mbedtls_md_type_t md_alg;
1592 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1593 return( PSA_ERROR_BUFFER_TOO_SMALL );
1594 md_info = mbedtls_md_info_from_psa( alg );
1595 md_alg = mbedtls_md_get_type( md_info );
1596 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001597 signature, signature_length,
1598 mbedtls_ctr_drbg_random,
1599 &global_data.ctr_drbg );
itayzafrir5c753392018-05-08 11:18:38 +03001600 return( mbedtls_to_psa_error( ret ) );
1601 }
1602 else
1603#endif /* defined(MBEDTLS_ECP_C) */
1604 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001605 return( PSA_ERROR_NOT_SUPPORTED );
1606 }
itayzafrir5c753392018-05-08 11:18:38 +03001607}
1608
1609psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1610 psa_algorithm_t alg,
1611 const uint8_t *hash,
1612 size_t hash_length,
1613 const uint8_t *salt,
1614 size_t salt_length,
1615 uint8_t *signature,
1616 size_t signature_size )
1617{
1618 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001619 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001620 (void) salt;
1621 (void) salt_length;
1622
Gilles Peskine828ed142018-06-18 23:25:51 +02001623 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001624 return( PSA_ERROR_INVALID_ARGUMENT );
1625 slot = &global_data.key_slots[key];
1626 if( slot->type == PSA_KEY_TYPE_NONE )
1627 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001628 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001629 return( PSA_ERROR_NOT_PERMITTED );
1630
Gilles Peskine61b91d42018-06-08 16:09:36 +02001631#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001632 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1633 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001634 {
1635 mbedtls_rsa_context *rsa = slot->data.rsa;
1636 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001637 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001638 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001639 if( status != PSA_SUCCESS )
1640 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001641
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001642 if( signature_size < rsa->len )
1643 return( PSA_ERROR_BUFFER_TOO_SMALL );
1644#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001645 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001646 {
1647 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1648 MBEDTLS_MD_NONE );
1649
1650 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001651 mbedtls_ctr_drbg_random,
1652 &global_data.ctr_drbg,
1653 MBEDTLS_RSA_PUBLIC,
1654 md_alg,
1655 hash_length,
1656 hash,
1657 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001658
1659 }
1660 else
1661#endif /* MBEDTLS_PKCS1_V15 */
1662#if defined(MBEDTLS_PKCS1_V21)
1663 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1664 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001665 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1666 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1667 mbedtls_ctr_drbg_random,
1668 &global_data.ctr_drbg,
1669 MBEDTLS_RSA_PUBLIC,
1670 md_alg, hash_length, hash,
1671 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001672 }
1673 else
1674#endif /* MBEDTLS_PKCS1_V21 */
1675 {
1676 return( PSA_ERROR_INVALID_ARGUMENT );
1677 }
1678 return( mbedtls_to_psa_error( ret ) );
1679 }
1680 else
1681#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001682#if defined(MBEDTLS_ECP_C)
1683 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1684 {
1685 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1686 int ret;
Gilles Peskine2d277862018-06-18 15:41:12 +02001687 (void) alg;
Gilles Peskine61b91d42018-06-08 16:09:36 +02001688 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length,
1689 signature, signature_size );
itayzafrir5c753392018-05-08 11:18:38 +03001690 return( mbedtls_to_psa_error( ret ) );
1691 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001692 else
1693#endif /* defined(MBEDTLS_ECP_C) */
1694 {
1695 return( PSA_ERROR_NOT_SUPPORTED );
1696 }
1697}
1698
Gilles Peskine61b91d42018-06-08 16:09:36 +02001699psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1700 psa_algorithm_t alg,
1701 const uint8_t *input,
1702 size_t input_length,
1703 const uint8_t *salt,
1704 size_t salt_length,
1705 uint8_t *output,
1706 size_t output_size,
1707 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001708{
1709 key_slot_t *slot;
1710 (void) salt;
1711 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001712 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001713
Gilles Peskine828ed142018-06-18 23:25:51 +02001714 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001715 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001716 slot = &global_data.key_slots[key];
1717 if( slot->type == PSA_KEY_TYPE_NONE )
1718 return( PSA_ERROR_EMPTY_SLOT );
1719 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1720 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001721 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1722 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001723
1724#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001725 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1726 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001727 {
1728 mbedtls_rsa_context *rsa = slot->data.rsa;
1729 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001730 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001731 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001732#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001733 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001734 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001735 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1736 mbedtls_ctr_drbg_random,
1737 &global_data.ctr_drbg,
1738 MBEDTLS_RSA_PUBLIC,
1739 input_length,
1740 input,
1741 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001742 }
1743 else
1744#endif /* MBEDTLS_PKCS1_V15 */
1745#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001746 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001747 {
1748 return( PSA_ERROR_NOT_SUPPORTED );
1749 }
1750 else
1751#endif /* MBEDTLS_PKCS1_V21 */
1752 {
1753 return( PSA_ERROR_INVALID_ARGUMENT );
1754 }
1755 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001756 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001757 return( mbedtls_to_psa_error( ret ) );
1758 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001759 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001760#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001761 {
1762 return( PSA_ERROR_NOT_SUPPORTED );
1763 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001764}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001765
Gilles Peskine61b91d42018-06-08 16:09:36 +02001766psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1767 psa_algorithm_t alg,
1768 const uint8_t *input,
1769 size_t input_length,
1770 const uint8_t *salt,
1771 size_t salt_length,
1772 uint8_t *output,
1773 size_t output_size,
1774 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001775{
1776 key_slot_t *slot;
1777 (void) salt;
1778 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001779 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001780
Gilles Peskine828ed142018-06-18 23:25:51 +02001781 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001782 return( PSA_ERROR_EMPTY_SLOT );
1783 slot = &global_data.key_slots[key];
1784 if( slot->type == PSA_KEY_TYPE_NONE )
1785 return( PSA_ERROR_EMPTY_SLOT );
1786 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1787 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001788 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1789 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001790
1791#if defined(MBEDTLS_RSA_C)
1792 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1793 {
1794 mbedtls_rsa_context *rsa = slot->data.rsa;
1795 int ret;
1796
Gilles Peskinec4def2f2018-06-08 17:53:48 +02001797 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001798 return( PSA_ERROR_INVALID_ARGUMENT );
1799
1800#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001801 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001802 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001803 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
1804 mbedtls_ctr_drbg_random,
1805 &global_data.ctr_drbg,
1806 MBEDTLS_RSA_PRIVATE,
1807 output_length,
1808 input,
1809 output,
1810 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001811 }
1812 else
1813#endif /* MBEDTLS_PKCS1_V15 */
1814#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001815 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001816 {
1817 return( PSA_ERROR_NOT_SUPPORTED );
1818 }
1819 else
1820#endif /* MBEDTLS_PKCS1_V21 */
1821 {
1822 return( PSA_ERROR_INVALID_ARGUMENT );
1823 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001824
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001825 return( mbedtls_to_psa_error( ret ) );
1826 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001827 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001828#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001829 {
1830 return( PSA_ERROR_NOT_SUPPORTED );
1831 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001832}
Gilles Peskine20035e32018-02-03 22:44:14 +01001833
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001834
1835
mohammad1603503973b2018-03-12 15:59:30 +02001836/****************************************************************/
1837/* Symmetric cryptography */
1838/****************************************************************/
1839
Gilles Peskinee553c652018-06-04 16:22:46 +02001840static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1841 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001842 psa_algorithm_t alg,
1843 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001844{
1845 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1846 psa_status_t status;
1847 key_slot_t *slot;
1848 psa_key_type_t key_type;
1849 size_t key_bits;
1850 const mbedtls_cipher_info_t *cipher_info = NULL;
1851
Moran Peker41deec42018-04-04 15:43:05 +03001852 operation->alg = alg;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001853 operation->key_set = 0;
1854 operation->iv_set = 0;
1855 operation->iv_required = 1;
1856 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001857 operation->block_size = 0;
mohammad1603503973b2018-03-12 15:59:30 +02001858
1859 status = psa_get_key_information( key, &key_type, &key_bits );
1860 if( status != PSA_SUCCESS )
1861 return( status );
1862 slot = &global_data.key_slots[key];
1863
Gilles Peskinebb1072f2018-06-08 18:46:05 +02001864 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02001865 if( cipher_info == NULL )
1866 return( PSA_ERROR_NOT_SUPPORTED );
1867
mohammad1603503973b2018-03-12 15:59:30 +02001868 mbedtls_cipher_init( &operation->ctx.cipher );
1869 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03001870 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001871 {
1872 psa_cipher_abort( operation );
1873 return( mbedtls_to_psa_error( ret ) );
1874 }
1875
1876 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
Gilles Peskinee553c652018-06-04 16:22:46 +02001877 key_bits, cipher_operation );
Moran Peker41deec42018-04-04 15:43:05 +03001878 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001879 {
1880 psa_cipher_abort( operation );
1881 return( mbedtls_to_psa_error( ret ) );
1882 }
1883
mohammad16038481e742018-03-18 13:57:31 +02001884#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03001885 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02001886 {
Gilles Peskine53514202018-06-06 15:11:46 +02001887 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1888 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02001889
Moran Pekera28258c2018-05-29 16:25:04 +03001890 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02001891 {
1892 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
1893 mode = MBEDTLS_PADDING_PKCS7;
1894 break;
1895 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
1896 mode = MBEDTLS_PADDING_NONE;
1897 break;
1898 default:
Moran Pekerae382792018-05-31 14:06:17 +03001899 psa_cipher_abort( operation );
1900 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02001901 }
1902 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03001903 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03001904 {
1905 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02001906 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03001907 }
mohammad16038481e742018-03-18 13:57:31 +02001908 }
1909#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
1910
mohammad1603503973b2018-03-12 15:59:30 +02001911 operation->key_set = 1;
1912 operation->alg = alg;
Gilles Peskine7e928852018-06-04 16:23:10 +02001913 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
1914 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
1915 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001916 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02001917 {
mohammad160389e0f462018-04-12 08:48:45 +03001918 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02001919 }
mohammad1603503973b2018-03-12 15:59:30 +02001920
Moran Peker395db872018-05-31 14:07:14 +03001921 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001922}
1923
Gilles Peskinee553c652018-06-04 16:22:46 +02001924psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
1925 psa_key_slot_t key,
1926 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001927{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001928 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001929}
1930
Gilles Peskinee553c652018-06-04 16:22:46 +02001931psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
1932 psa_key_slot_t key,
1933 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001934{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001935 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001936}
1937
Gilles Peskinee553c652018-06-04 16:22:46 +02001938psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
1939 unsigned char *iv,
1940 size_t iv_size,
1941 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001942{
Moran Peker41deec42018-04-04 15:43:05 +03001943 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001944 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001945 return( PSA_ERROR_BAD_STATE );
1946 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02001947 {
Moran Peker41deec42018-04-04 15:43:05 +03001948 ret = PSA_ERROR_BUFFER_TOO_SMALL;
1949 goto exit;
1950 }
Gilles Peskine7e928852018-06-04 16:23:10 +02001951 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
1952 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03001953 if( ret != 0 )
1954 {
1955 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02001956 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02001957 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001958
mohammad16038481e742018-03-18 13:57:31 +02001959 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03001960 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001961
Moran Peker395db872018-05-31 14:07:14 +03001962exit:
1963 if( ret != PSA_SUCCESS )
1964 psa_cipher_abort( operation );
1965 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02001966}
1967
Gilles Peskinee553c652018-06-04 16:22:46 +02001968psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
1969 const unsigned char *iv,
1970 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001971{
Moran Peker41deec42018-04-04 15:43:05 +03001972 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001973 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001974 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03001975 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03001976 {
Moran Pekerae382792018-05-31 14:06:17 +03001977 psa_cipher_abort( operation );
1978 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03001979 }
mohammad1603503973b2018-03-12 15:59:30 +02001980 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001981 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001982 {
1983 psa_cipher_abort( operation );
1984 return( mbedtls_to_psa_error( ret ) );
1985 }
1986
1987 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02001988
Moran Peker395db872018-05-31 14:07:14 +03001989 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001990}
1991
Gilles Peskinee553c652018-06-04 16:22:46 +02001992psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
1993 const uint8_t *input,
1994 size_t input_length,
1995 unsigned char *output,
1996 size_t output_size,
1997 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001998{
1999 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002000 size_t expected_output_size;
2001 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2002 {
2003 /* Take the unprocessed partial block left over from previous
2004 * update calls, if any, plus the input to this call. Remove
2005 * the last partial block, if any. You get the data that will be
2006 * output in this call. */
2007 expected_output_size =
2008 ( operation->ctx.cipher.unprocessed_len + input_length )
2009 / operation->block_size * operation->block_size;
2010 }
2011 else
2012 {
2013 expected_output_size = input_length;
2014 }
2015 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002016 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002017
mohammad1603503973b2018-03-12 15:59:30 +02002018 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002019 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002020 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002021 {
2022 psa_cipher_abort( operation );
2023 return( mbedtls_to_psa_error( ret ) );
2024 }
2025
Moran Peker395db872018-05-31 14:07:14 +03002026 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002027}
2028
Gilles Peskinee553c652018-06-04 16:22:46 +02002029psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2030 uint8_t *output,
2031 size_t output_size,
2032 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002033{
2034 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002035 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002036
mohammad1603503973b2018-03-12 15:59:30 +02002037 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002038 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002039 psa_cipher_abort( operation );
2040 return( PSA_ERROR_BAD_STATE );
2041 }
2042 if( operation->iv_required && ! operation->iv_set )
2043 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002044 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002045 return( PSA_ERROR_BAD_STATE );
2046 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002047 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2048 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002049 {
Gilles Peskine53514202018-06-06 15:11:46 +02002050 psa_algorithm_t padding_mode =
2051 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002052 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002053 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002054 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002055 return( PSA_ERROR_TAMPERING_DETECTED );
2056 }
Gilles Peskine53514202018-06-06 15:11:46 +02002057 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002058 {
2059 if( operation->ctx.cipher.unprocessed_len != 0 )
2060 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002061 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002062 return( PSA_ERROR_INVALID_ARGUMENT );
2063 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002064 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002065 }
2066
2067 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002068 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002069 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002070 {
2071 psa_cipher_abort( operation );
2072 return( mbedtls_to_psa_error( ret ) );
2073 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002074 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002075 memcpy( output, temp_output_buffer, *output_length );
2076 else
2077 {
2078 psa_cipher_abort( operation );
2079 return( PSA_ERROR_BUFFER_TOO_SMALL );
2080 }
mohammad1603503973b2018-03-12 15:59:30 +02002081
Moran Peker4c80d832018-04-22 20:15:31 +03002082 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002083}
2084
Gilles Peskinee553c652018-06-04 16:22:46 +02002085psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2086{
mohammad1603503973b2018-03-12 15:59:30 +02002087 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002088
Moran Peker41deec42018-04-04 15:43:05 +03002089 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002090 operation->key_set = 0;
2091 operation->iv_set = 0;
2092 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002093 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002094 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002095
Moran Peker395db872018-05-31 14:07:14 +03002096 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002097}
2098
Gilles Peskinea0655c32018-04-30 17:06:50 +02002099
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002100
mohammad16038cc1cee2018-03-28 01:21:33 +03002101/****************************************************************/
2102/* Key Policy */
2103/****************************************************************/
2104
Gilles Peskine2d277862018-06-18 15:41:12 +02002105void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002106{
Gilles Peskine803ce742018-06-18 16:07:14 +02002107 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002108}
2109
Gilles Peskine2d277862018-06-18 15:41:12 +02002110void psa_key_policy_set_usage( psa_key_policy_t *policy,
2111 psa_key_usage_t usage,
2112 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002113{
mohammad16034eed7572018-03-28 05:14:59 -07002114 policy->usage = usage;
2115 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002116}
2117
Gilles Peskine2d277862018-06-18 15:41:12 +02002118psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002119{
mohammad16036df908f2018-04-02 08:34:15 -07002120 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002121}
2122
Gilles Peskine2d277862018-06-18 15:41:12 +02002123psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002124{
mohammad16036df908f2018-04-02 08:34:15 -07002125 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002126}
2127
Gilles Peskine2d277862018-06-18 15:41:12 +02002128psa_status_t psa_set_key_policy( psa_key_slot_t key,
2129 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002130{
2131 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002132
Gilles Peskine828ed142018-06-18 23:25:51 +02002133 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002134 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002135
mohammad16038cc1cee2018-03-28 01:21:33 +03002136 slot = &global_data.key_slots[key];
2137 if( slot->type != PSA_KEY_TYPE_NONE )
2138 return( PSA_ERROR_OCCUPIED_SLOT );
2139
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002140 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2141 PSA_KEY_USAGE_ENCRYPT |
2142 PSA_KEY_USAGE_DECRYPT |
2143 PSA_KEY_USAGE_SIGN |
2144 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002145 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002146
mohammad16036df908f2018-04-02 08:34:15 -07002147 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002148
2149 return( PSA_SUCCESS );
2150}
2151
Gilles Peskine2d277862018-06-18 15:41:12 +02002152psa_status_t psa_get_key_policy( psa_key_slot_t key,
2153 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002154{
2155 key_slot_t *slot;
2156
Gilles Peskine828ed142018-06-18 23:25:51 +02002157 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002158 return( PSA_ERROR_INVALID_ARGUMENT );
2159
2160 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002161
mohammad16036df908f2018-04-02 08:34:15 -07002162 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002163
2164 return( PSA_SUCCESS );
2165}
Gilles Peskine20035e32018-02-03 22:44:14 +01002166
Gilles Peskinea0655c32018-04-30 17:06:50 +02002167
2168
mohammad1603804cd712018-03-20 22:44:08 +02002169/****************************************************************/
2170/* Key Lifetime */
2171/****************************************************************/
2172
Gilles Peskine2d277862018-06-18 15:41:12 +02002173psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2174 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002175{
2176 key_slot_t *slot;
2177
Gilles Peskine828ed142018-06-18 23:25:51 +02002178 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002179 return( PSA_ERROR_INVALID_ARGUMENT );
2180
2181 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002182
mohammad1603804cd712018-03-20 22:44:08 +02002183 *lifetime = slot->lifetime;
2184
2185 return( PSA_SUCCESS );
2186}
2187
Gilles Peskine2d277862018-06-18 15:41:12 +02002188psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2189 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002190{
2191 key_slot_t *slot;
2192
Gilles Peskine828ed142018-06-18 23:25:51 +02002193 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002194 return( PSA_ERROR_INVALID_ARGUMENT );
2195
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002196 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2197 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002198 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2199 return( PSA_ERROR_INVALID_ARGUMENT );
2200
mohammad1603804cd712018-03-20 22:44:08 +02002201 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002202 if( slot->type != PSA_KEY_TYPE_NONE )
2203 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002204
Moran Pekerd7326592018-05-29 16:56:39 +03002205 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002206 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002207
mohammad1603060ad8a2018-03-20 14:28:38 -07002208 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002209
2210 return( PSA_SUCCESS );
2211}
2212
Gilles Peskine20035e32018-02-03 22:44:14 +01002213
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002214
mohammad16035955c982018-04-26 00:53:03 +03002215/****************************************************************/
2216/* AEAD */
2217/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002218
mohammad16035955c982018-04-26 00:53:03 +03002219psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2220 psa_algorithm_t alg,
2221 const uint8_t *nonce,
2222 size_t nonce_length,
2223 const uint8_t *additional_data,
2224 size_t additional_data_length,
2225 const uint8_t *plaintext,
2226 size_t plaintext_length,
2227 uint8_t *ciphertext,
2228 size_t ciphertext_size,
2229 size_t *ciphertext_length )
2230{
2231 int ret;
2232 psa_status_t status;
2233 key_slot_t *slot;
2234 psa_key_type_t key_type;
2235 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002236 uint8_t *tag;
2237 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002238 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002239 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002240
mohammad1603f08a5502018-06-03 15:05:47 +03002241 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002242
mohammad16035955c982018-04-26 00:53:03 +03002243 status = psa_get_key_information( key, &key_type, &key_bits );
2244 if( status != PSA_SUCCESS )
2245 return( status );
2246 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002247 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002248 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002249
mohammad16035ed06212018-06-06 13:09:34 +03002250 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2251 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002252 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002253 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002254
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002255 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002256 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002257
Gilles Peskine2d277862018-06-18 15:41:12 +02002258 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2259 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002260 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002261
mohammad16035955c982018-04-26 00:53:03 +03002262 if( alg == PSA_ALG_GCM )
2263 {
2264 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002265 tag_length = 16;
2266
mohammad160396910d82018-06-04 14:33:00 +03002267 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2268 return( PSA_ERROR_INVALID_ARGUMENT );
2269
mohammad160315223a82018-06-03 17:19:55 +03002270 //make sure we have place to hold the tag in the ciphertext buffer
2271 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002272 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002273
2274 //update the tag pointer to point to the end of the ciphertext_length
2275 tag = ciphertext + plaintext_length;
2276
mohammad16035955c982018-04-26 00:53:03 +03002277 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002278 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002279 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002280 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002281 if( ret != 0 )
2282 {
2283 mbedtls_gcm_free( &gcm );
2284 return( mbedtls_to_psa_error( ret ) );
2285 }
2286 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002287 plaintext_length, nonce,
2288 nonce_length, additional_data,
2289 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002290 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002291 mbedtls_gcm_free( &gcm );
2292 }
2293 else if( alg == PSA_ALG_CCM )
2294 {
2295 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002296 tag_length = 16;
2297
mohammad160396910d82018-06-04 14:33:00 +03002298 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2299 return( PSA_ERROR_INVALID_ARGUMENT );
2300
mohammad160347ddf3d2018-04-26 01:11:21 +03002301 if( nonce_length < 7 || nonce_length > 13 )
2302 return( PSA_ERROR_INVALID_ARGUMENT );
2303
mohammad160315223a82018-06-03 17:19:55 +03002304 //make sure we have place to hold the tag in the ciphertext buffer
2305 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002306 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002307
2308 //update the tag pointer to point to the end of the ciphertext_length
2309 tag = ciphertext + plaintext_length;
2310
mohammad16035955c982018-04-26 00:53:03 +03002311 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002312 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002313 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002314 if( ret != 0 )
2315 {
2316 mbedtls_ccm_free( &ccm );
2317 return( mbedtls_to_psa_error( ret ) );
2318 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002319 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002320 nonce, nonce_length,
2321 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002322 additional_data_length,
2323 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002324 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002325 mbedtls_ccm_free( &ccm );
2326 }
mohammad16035c8845f2018-05-09 05:40:09 -07002327 else
2328 {
mohammad1603554faad2018-06-03 15:07:38 +03002329 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002330 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002331
mohammad160315223a82018-06-03 17:19:55 +03002332 if( ret != 0 )
2333 {
2334 memset( ciphertext, 0, ciphertext_size );
2335 return( mbedtls_to_psa_error( ret ) );
2336 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002337
mohammad160315223a82018-06-03 17:19:55 +03002338 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002339 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002340}
2341
Gilles Peskineee652a32018-06-01 19:23:52 +02002342/* Locate the tag in a ciphertext buffer containing the encrypted data
2343 * followed by the tag. Return the length of the part preceding the tag in
2344 * *plaintext_length. This is the size of the plaintext in modes where
2345 * the encrypted data has the same size as the plaintext, such as
2346 * CCM and GCM. */
2347static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2348 const uint8_t *ciphertext,
2349 size_t ciphertext_length,
2350 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002351 const uint8_t **p_tag )
2352{
2353 size_t payload_length;
2354 if( tag_length > ciphertext_length )
2355 return( PSA_ERROR_INVALID_ARGUMENT );
2356 payload_length = ciphertext_length - tag_length;
2357 if( payload_length > plaintext_size )
2358 return( PSA_ERROR_BUFFER_TOO_SMALL );
2359 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002360 return( PSA_SUCCESS );
2361}
2362
mohammad16035955c982018-04-26 00:53:03 +03002363psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2364 psa_algorithm_t alg,
2365 const uint8_t *nonce,
2366 size_t nonce_length,
2367 const uint8_t *additional_data,
2368 size_t additional_data_length,
2369 const uint8_t *ciphertext,
2370 size_t ciphertext_length,
2371 uint8_t *plaintext,
2372 size_t plaintext_size,
2373 size_t *plaintext_length )
2374{
2375 int ret;
2376 psa_status_t status;
2377 key_slot_t *slot;
2378 psa_key_type_t key_type;
2379 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002380 const uint8_t *tag;
2381 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002382 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002383 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002384
Gilles Peskineee652a32018-06-01 19:23:52 +02002385 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002386
mohammad16035955c982018-04-26 00:53:03 +03002387 status = psa_get_key_information( key, &key_type, &key_bits );
2388 if( status != PSA_SUCCESS )
2389 return( status );
2390 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002391 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002392 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002393
mohammad16035ed06212018-06-06 13:09:34 +03002394 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2395 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002396 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002397 return( PSA_ERROR_NOT_SUPPORTED );
2398
mohammad1603f14394b2018-06-04 14:33:19 +03002399 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2400 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002401
Gilles Peskine2d277862018-06-18 15:41:12 +02002402 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2403 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002404 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002405
mohammad16035955c982018-04-26 00:53:03 +03002406 if( alg == PSA_ALG_GCM )
2407 {
2408 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002409
Gilles Peskineee652a32018-06-01 19:23:52 +02002410 tag_length = 16;
2411 status = psa_aead_unpadded_locate_tag( tag_length,
2412 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002413 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002414 if( status != PSA_SUCCESS )
2415 return( status );
2416
mohammad16035955c982018-04-26 00:53:03 +03002417 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002418 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002419 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002420 if( ret != 0 )
2421 {
2422 mbedtls_gcm_free( &gcm );
2423 return( mbedtls_to_psa_error( ret ) );
2424 }
mohammad16035955c982018-04-26 00:53:03 +03002425
Gilles Peskineee652a32018-06-01 19:23:52 +02002426 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002427 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002428 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002429 additional_data,
2430 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002431 tag, tag_length,
2432 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002433 mbedtls_gcm_free( &gcm );
2434 }
2435 else if( alg == PSA_ALG_CCM )
2436 {
2437 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002438
mohammad160347ddf3d2018-04-26 01:11:21 +03002439 if( nonce_length < 7 || nonce_length > 13 )
2440 return( PSA_ERROR_INVALID_ARGUMENT );
2441
mohammad16039375f842018-06-03 14:28:24 +03002442 tag_length = 16;
2443 status = psa_aead_unpadded_locate_tag( tag_length,
2444 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002445 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002446 if( status != PSA_SUCCESS )
2447 return( status );
2448
mohammad16035955c982018-04-26 00:53:03 +03002449 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002450 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002451 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002452 if( ret != 0 )
2453 {
2454 mbedtls_ccm_free( &ccm );
2455 return( mbedtls_to_psa_error( ret ) );
2456 }
mohammad160360a64d02018-06-03 17:20:42 +03002457 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002458 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002459 additional_data,
2460 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002461 ciphertext, plaintext,
2462 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002463 mbedtls_ccm_free( &ccm );
2464 }
mohammad160339574652018-06-01 04:39:53 -07002465 else
2466 {
mohammad1603554faad2018-06-03 15:07:38 +03002467 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002468 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002469
Gilles Peskineee652a32018-06-01 19:23:52 +02002470 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002471 memset( plaintext, 0, plaintext_size );
2472 else
2473 *plaintext_length = ciphertext_length - tag_length;
2474
Gilles Peskineee652a32018-06-01 19:23:52 +02002475 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002476}
2477
Gilles Peskinea0655c32018-04-30 17:06:50 +02002478
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002479
Gilles Peskine20035e32018-02-03 22:44:14 +01002480/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002481/* Key generation */
2482/****************************************************************/
2483
2484psa_status_t psa_generate_random( uint8_t *output,
2485 size_t output_size )
2486{
2487 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2488 output, output_size );
2489 return( mbedtls_to_psa_error( ret ) );
2490}
2491
2492psa_status_t psa_generate_key( psa_key_slot_t key,
2493 psa_key_type_t type,
2494 size_t bits,
2495 const void *parameters,
2496 size_t parameters_size )
2497{
2498 return( PSA_ERROR_NOT_SUPPORTED );
2499}
2500
2501
2502/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002503/* Module setup */
2504/****************************************************************/
2505
Gilles Peskinee59236f2018-01-27 23:32:46 +01002506void mbedtls_psa_crypto_free( void )
2507{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002508 size_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02002509 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002510 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002511 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2512 mbedtls_entropy_free( &global_data.entropy );
2513 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2514}
2515
2516psa_status_t psa_crypto_init( void )
2517{
2518 int ret;
2519 const unsigned char drbg_seed[] = "PSA";
2520
2521 if( global_data.initialized != 0 )
2522 return( PSA_SUCCESS );
2523
2524 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2525 mbedtls_entropy_init( &global_data.entropy );
2526 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2527
2528 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2529 mbedtls_entropy_func,
2530 &global_data.entropy,
2531 drbg_seed, sizeof( drbg_seed ) - 1 );
2532 if( ret != 0 )
2533 goto exit;
2534
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002535 global_data.initialized = 1;
2536
Gilles Peskinee59236f2018-01-27 23:32:46 +01002537exit:
2538 if( ret != 0 )
2539 mbedtls_psa_crypto_free( );
2540 return( mbedtls_to_psa_error( ret ) );
2541}
2542
2543#endif /* MBEDTLS_PSA_CRYPTO_C */