blob: c552b53310f0e3ee65c53cf51e05c16ef8a9cf4e [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
4/* Copyright (C) 2018, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PSA_CRYPTO_C)
29
30#include "psa/crypto.h"
31
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010032#include <stdlib.h>
33#include <string.h>
34#if defined(MBEDTLS_PLATFORM_C)
35#include "mbedtls/platform.h"
36#else
37#define mbedtls_calloc calloc
38#define mbedtls_free free
39#endif
40
Gilles Peskinea5905292018-02-07 20:59:33 +010041#include "mbedtls/arc4.h"
42#include "mbedtls/blowfish.h"
43#include "mbedtls/camellia.h"
44#include "mbedtls/cipher.h"
45#include "mbedtls/ccm.h"
46#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010047#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010048#include "mbedtls/des.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010049#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010050#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010051#include "mbedtls/error.h"
52#include "mbedtls/gcm.h"
53#include "mbedtls/md2.h"
54#include "mbedtls/md4.h"
55#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010056#include "mbedtls/md.h"
57#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010058#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010059#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010060#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010061#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010062#include "mbedtls/sha1.h"
63#include "mbedtls/sha256.h"
64#include "mbedtls/sha512.h"
65#include "mbedtls/xtea.h"
66
Gilles Peskinee59236f2018-01-27 23:32:46 +010067
68
69/* Implementation that should never be optimized out by the compiler */
70static void mbedtls_zeroize( void *v, size_t n )
71{
72 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
73}
74
Gilles Peskine9ef733f2018-02-07 21:05:37 +010075/* constant-time buffer comparison */
76static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
77{
78 size_t i;
79 unsigned char diff = 0;
80
81 for( i = 0; i < n; i++ )
82 diff |= a[i] ^ b[i];
83
84 return( diff );
85}
86
87
88
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010089/****************************************************************/
90/* Global data, support functions and library management */
91/****************************************************************/
92
93/* Number of key slots (plus one because 0 is not used).
94 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +020095#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010096
Gilles Peskine2d277862018-06-18 15:41:12 +020097typedef struct
98{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010099 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300100 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200101 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200102 union
103 {
104 struct raw_data
105 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100106 uint8_t *data;
107 size_t bytes;
108 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100109#if defined(MBEDTLS_RSA_C)
110 mbedtls_rsa_context *rsa;
111#endif /* MBEDTLS_RSA_C */
112#if defined(MBEDTLS_ECP_C)
113 mbedtls_ecp_keypair *ecp;
114#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100115 } data;
116} key_slot_t;
117
Gilles Peskine2d277862018-06-18 15:41:12 +0200118typedef struct
119{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100120 int initialized;
121 mbedtls_entropy_context entropy;
122 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200123 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100124} psa_global_data_t;
125
126static psa_global_data_t global_data;
127
128static psa_status_t mbedtls_to_psa_error( int ret )
129{
Gilles Peskinea5905292018-02-07 20:59:33 +0100130 /* If there's both a high-level code and low-level code, dispatch on
131 * the high-level code. */
132 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100133 {
134 case 0:
135 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100136
137 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
138 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
139 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
140 return( PSA_ERROR_NOT_SUPPORTED );
141 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
142 return( PSA_ERROR_HARDWARE_FAILURE );
143
144 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
145 return( PSA_ERROR_HARDWARE_FAILURE );
146
147 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
148 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
149 return( PSA_ERROR_NOT_SUPPORTED );
150 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
151 return( PSA_ERROR_HARDWARE_FAILURE );
152
153 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
154 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
155 return( PSA_ERROR_NOT_SUPPORTED );
156 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
157 return( PSA_ERROR_HARDWARE_FAILURE );
158
159 case MBEDTLS_ERR_CCM_BAD_INPUT:
160 return( PSA_ERROR_INVALID_ARGUMENT );
161 case MBEDTLS_ERR_CCM_AUTH_FAILED:
162 return( PSA_ERROR_INVALID_SIGNATURE );
163 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
164 return( PSA_ERROR_HARDWARE_FAILURE );
165
166 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
167 return( PSA_ERROR_NOT_SUPPORTED );
168 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
169 return( PSA_ERROR_INVALID_ARGUMENT );
170 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
171 return( PSA_ERROR_INSUFFICIENT_MEMORY );
172 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
173 return( PSA_ERROR_INVALID_PADDING );
174 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
175 return( PSA_ERROR_BAD_STATE );
176 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
177 return( PSA_ERROR_INVALID_SIGNATURE );
178 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
179 return( PSA_ERROR_TAMPERING_DETECTED );
180 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
181 return( PSA_ERROR_HARDWARE_FAILURE );
182
183 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
186 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
187 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
188 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
189 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
190 return( PSA_ERROR_NOT_SUPPORTED );
191 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
192 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
193
194 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
195 return( PSA_ERROR_NOT_SUPPORTED );
196 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
197 return( PSA_ERROR_HARDWARE_FAILURE );
198
Gilles Peskinee59236f2018-01-27 23:32:46 +0100199 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
200 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
201 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
202 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100203
204 case MBEDTLS_ERR_GCM_AUTH_FAILED:
205 return( PSA_ERROR_INVALID_SIGNATURE );
206 case MBEDTLS_ERR_GCM_BAD_INPUT:
207 return( PSA_ERROR_NOT_SUPPORTED );
208 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
209 return( PSA_ERROR_HARDWARE_FAILURE );
210
211 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
212 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
213 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
214 return( PSA_ERROR_HARDWARE_FAILURE );
215
216 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
217 return( PSA_ERROR_NOT_SUPPORTED );
218 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
219 return( PSA_ERROR_INVALID_ARGUMENT );
220 case MBEDTLS_ERR_MD_ALLOC_FAILED:
221 return( PSA_ERROR_INSUFFICIENT_MEMORY );
222 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
223 return( PSA_ERROR_STORAGE_FAILURE );
224 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
225 return( PSA_ERROR_HARDWARE_FAILURE );
226
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100227 case MBEDTLS_ERR_PK_ALLOC_FAILED:
228 return( PSA_ERROR_INSUFFICIENT_MEMORY );
229 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
230 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
231 return( PSA_ERROR_INVALID_ARGUMENT );
232 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100233 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100234 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
235 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
236 return( PSA_ERROR_INVALID_ARGUMENT );
237 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
238 return( PSA_ERROR_NOT_SUPPORTED );
239 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
240 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
241 return( PSA_ERROR_NOT_PERMITTED );
242 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
243 return( PSA_ERROR_INVALID_ARGUMENT );
244 case MBEDTLS_ERR_PK_INVALID_ALG:
245 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
246 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
247 return( PSA_ERROR_NOT_SUPPORTED );
248 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
249 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100250 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
251 return( PSA_ERROR_HARDWARE_FAILURE );
252
253 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
254 return( PSA_ERROR_HARDWARE_FAILURE );
255
256 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
257 return( PSA_ERROR_INVALID_ARGUMENT );
258 case MBEDTLS_ERR_RSA_INVALID_PADDING:
259 return( PSA_ERROR_INVALID_PADDING );
260 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
261 return( PSA_ERROR_HARDWARE_FAILURE );
262 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
263 return( PSA_ERROR_INVALID_ARGUMENT );
264 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
265 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
266 return( PSA_ERROR_TAMPERING_DETECTED );
267 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
268 return( PSA_ERROR_INVALID_SIGNATURE );
269 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
270 return( PSA_ERROR_BUFFER_TOO_SMALL );
271 case MBEDTLS_ERR_RSA_RNG_FAILED:
272 return( PSA_ERROR_INSUFFICIENT_MEMORY );
273 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
274 return( PSA_ERROR_NOT_SUPPORTED );
275 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
276 return( PSA_ERROR_HARDWARE_FAILURE );
277
278 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
279 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
280 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
281 return( PSA_ERROR_HARDWARE_FAILURE );
282
283 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
284 return( PSA_ERROR_INVALID_ARGUMENT );
285 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
286 return( PSA_ERROR_HARDWARE_FAILURE );
287
itayzafrir5c753392018-05-08 11:18:38 +0300288 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300289 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300290 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300291 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
292 return( PSA_ERROR_BUFFER_TOO_SMALL );
293 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
294 return( PSA_ERROR_NOT_SUPPORTED );
295 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
296 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
297 return( PSA_ERROR_INVALID_SIGNATURE );
298 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
299 return( PSA_ERROR_INSUFFICIENT_MEMORY );
300 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
301 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300302
Gilles Peskinee59236f2018-01-27 23:32:46 +0100303 default:
304 return( PSA_ERROR_UNKNOWN_ERROR );
305 }
306}
307
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200308
309
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100310/****************************************************************/
311/* Key management */
312/****************************************************************/
313
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200314static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
315{
316 switch( grpid )
317 {
318 case MBEDTLS_ECP_DP_SECP192R1:
319 return( PSA_ECC_CURVE_SECP192R1 );
320 case MBEDTLS_ECP_DP_SECP224R1:
321 return( PSA_ECC_CURVE_SECP224R1 );
322 case MBEDTLS_ECP_DP_SECP256R1:
323 return( PSA_ECC_CURVE_SECP256R1 );
324 case MBEDTLS_ECP_DP_SECP384R1:
325 return( PSA_ECC_CURVE_SECP384R1 );
326 case MBEDTLS_ECP_DP_SECP521R1:
327 return( PSA_ECC_CURVE_SECP521R1 );
328 case MBEDTLS_ECP_DP_BP256R1:
329 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
330 case MBEDTLS_ECP_DP_BP384R1:
331 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
332 case MBEDTLS_ECP_DP_BP512R1:
333 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
334 case MBEDTLS_ECP_DP_CURVE25519:
335 return( PSA_ECC_CURVE_CURVE25519 );
336 case MBEDTLS_ECP_DP_SECP192K1:
337 return( PSA_ECC_CURVE_SECP192K1 );
338 case MBEDTLS_ECP_DP_SECP224K1:
339 return( PSA_ECC_CURVE_SECP224K1 );
340 case MBEDTLS_ECP_DP_SECP256K1:
341 return( PSA_ECC_CURVE_SECP256K1 );
342 case MBEDTLS_ECP_DP_CURVE448:
343 return( PSA_ECC_CURVE_CURVE448 );
344 default:
345 return( 0 );
346 }
347}
348
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200349static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
350 size_t bits,
351 struct raw_data *raw )
352{
353 /* Check that the bit size is acceptable for the key type */
354 switch( type )
355 {
356 case PSA_KEY_TYPE_RAW_DATA:
357#if defined(MBEDTLS_MD_C)
358 case PSA_KEY_TYPE_HMAC:
359#endif
360 break;
361#if defined(MBEDTLS_AES_C)
362 case PSA_KEY_TYPE_AES:
363 if( bits != 128 && bits != 192 && bits != 256 )
364 return( PSA_ERROR_INVALID_ARGUMENT );
365 break;
366#endif
367#if defined(MBEDTLS_CAMELLIA_C)
368 case PSA_KEY_TYPE_CAMELLIA:
369 if( bits != 128 && bits != 192 && bits != 256 )
370 return( PSA_ERROR_INVALID_ARGUMENT );
371 break;
372#endif
373#if defined(MBEDTLS_DES_C)
374 case PSA_KEY_TYPE_DES:
375 if( bits != 64 && bits != 128 && bits != 192 )
376 return( PSA_ERROR_INVALID_ARGUMENT );
377 break;
378#endif
379#if defined(MBEDTLS_ARC4_C)
380 case PSA_KEY_TYPE_ARC4:
381 if( bits < 8 || bits > 2048 )
382 return( PSA_ERROR_INVALID_ARGUMENT );
383 break;
384#endif
385 default:
386 return( PSA_ERROR_NOT_SUPPORTED );
387 }
388
389 /* Allocate memory for the key */
390 raw->bytes = PSA_BITS_TO_BYTES( bits );
391 raw->data = mbedtls_calloc( 1, raw->bytes );
392 if( raw->data == NULL )
393 {
394 raw->bytes = 0;
395 return( PSA_ERROR_INSUFFICIENT_MEMORY );
396 }
397 return( PSA_SUCCESS );
398}
399
Gilles Peskine2d277862018-06-18 15:41:12 +0200400psa_status_t psa_import_key( psa_key_slot_t key,
401 psa_key_type_t type,
402 const uint8_t *data,
403 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100404{
405 key_slot_t *slot;
406
Gilles Peskine828ed142018-06-18 23:25:51 +0200407 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100408 return( PSA_ERROR_INVALID_ARGUMENT );
409 slot = &global_data.key_slots[key];
410 if( slot->type != PSA_KEY_TYPE_NONE )
411 return( PSA_ERROR_OCCUPIED_SLOT );
412
Gilles Peskine8c9def32018-02-08 10:02:12 +0100413 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100414 {
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200415 psa_status_t status;
Gilles Peskine6d912132018-03-07 16:41:37 +0100416 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100417 if( data_length > SIZE_MAX / 8 )
418 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200419 status = prepare_raw_data_slot( type,
420 PSA_BYTES_TO_BITS( data_length ),
421 &slot->data.raw );
422 if( status != PSA_SUCCESS )
423 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100424 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100425 }
426 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100427#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100428 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
429 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
430 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100431 {
432 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100433 mbedtls_pk_context pk;
434 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100435 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
436 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
437 else
438 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100439 if( ret != 0 )
440 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100441 switch( mbedtls_pk_get_type( &pk ) )
442 {
443#if defined(MBEDTLS_RSA_C)
444 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100445 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
446 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200447 slot->data.rsa = mbedtls_pk_rsa( pk );
Gilles Peskine969ac722018-01-28 18:16:59 +0100448 else
449 return( PSA_ERROR_INVALID_ARGUMENT );
450 break;
451#endif /* MBEDTLS_RSA_C */
452#if defined(MBEDTLS_ECP_C)
453 case MBEDTLS_PK_ECKEY:
454 if( PSA_KEY_TYPE_IS_ECC( type ) )
455 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200456 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
457 psa_ecc_curve_t actual_curve =
458 mbedtls_ecc_group_to_psa( ecp->grp.id );
459 psa_ecc_curve_t expected_curve =
460 PSA_KEY_TYPE_GET_CURVE( type );
461 if( actual_curve != expected_curve )
462 return( PSA_ERROR_INVALID_ARGUMENT );
463 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100464 }
465 else
466 return( PSA_ERROR_INVALID_ARGUMENT );
467 break;
468#endif /* MBEDTLS_ECP_C */
469 default:
470 return( PSA_ERROR_INVALID_ARGUMENT );
471 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100472 }
473 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100474#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100475 {
476 return( PSA_ERROR_NOT_SUPPORTED );
477 }
478
479 slot->type = type;
480 return( PSA_SUCCESS );
481}
482
Gilles Peskine2d277862018-06-18 15:41:12 +0200483psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100484{
485 key_slot_t *slot;
486
Gilles Peskine828ed142018-06-18 23:25:51 +0200487 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100488 return( PSA_ERROR_INVALID_ARGUMENT );
489 slot = &global_data.key_slots[key];
490 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200491 {
492 /* No key material to clean, but do zeroize the slot below to wipe
493 * metadata such as policies. */
494 }
495 else if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100496 {
497 mbedtls_free( slot->data.raw.data );
498 }
499 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100500#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100501 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
502 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100503 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100504 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100505 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100506 }
507 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100508#endif /* defined(MBEDTLS_RSA_C) */
509#if defined(MBEDTLS_ECP_C)
510 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
511 {
512 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100513 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100514 }
515 else
516#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100517 {
518 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100519 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100520 return( PSA_ERROR_TAMPERING_DETECTED );
521 }
522
523 mbedtls_zeroize( slot, sizeof( *slot ) );
524 return( PSA_SUCCESS );
525}
526
Gilles Peskine2d277862018-06-18 15:41:12 +0200527psa_status_t psa_get_key_information( psa_key_slot_t key,
528 psa_key_type_t *type,
529 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100530{
531 key_slot_t *slot;
532
Gilles Peskine828ed142018-06-18 23:25:51 +0200533 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100534 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100535 slot = &global_data.key_slots[key];
536 if( type != NULL )
537 *type = slot->type;
538 if( bits != NULL )
539 *bits = 0;
540 if( slot->type == PSA_KEY_TYPE_NONE )
541 return( PSA_ERROR_EMPTY_SLOT );
542
Gilles Peskine8c9def32018-02-08 10:02:12 +0100543 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100544 {
545 if( bits != NULL )
546 *bits = slot->data.raw.bytes * 8;
547 }
548 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100549#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100550 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
551 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100552 {
553 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100554 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100555 }
556 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100557#endif /* defined(MBEDTLS_RSA_C) */
558#if defined(MBEDTLS_ECP_C)
559 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
560 {
561 if( bits != NULL )
562 *bits = slot->data.ecp->grp.pbits;
563 }
564 else
565#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100566 {
567 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100568 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100569 return( PSA_ERROR_TAMPERING_DETECTED );
570 }
571
572 return( PSA_SUCCESS );
573}
574
Gilles Peskine2d277862018-06-18 15:41:12 +0200575static psa_status_t psa_internal_export_key( psa_key_slot_t key,
576 uint8_t *data,
577 size_t data_size,
578 size_t *data_length,
579 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100580{
581 key_slot_t *slot;
582
Gilles Peskine828ed142018-06-18 23:25:51 +0200583 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100584 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100585 slot = &global_data.key_slots[key];
586 if( slot->type == PSA_KEY_TYPE_NONE )
587 return( PSA_ERROR_EMPTY_SLOT );
588
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200589 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300590 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300591
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200592 if( ! export_public_key &&
593 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
594 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300595 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200596
Gilles Peskine8c9def32018-02-08 10:02:12 +0100597 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100598 {
599 if( slot->data.raw.bytes > data_size )
600 return( PSA_ERROR_BUFFER_TOO_SMALL );
601 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
602 *data_length = slot->data.raw.bytes;
603 return( PSA_SUCCESS );
604 }
605 else
Moran Peker17e36e12018-05-02 12:55:20 +0300606 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100607#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100608 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300609 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
610 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100611 {
Moran Pekera998bc62018-04-16 18:16:20 +0300612 mbedtls_pk_context pk;
613 int ret;
614 mbedtls_pk_init( &pk );
615 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
616 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
617 {
618 pk.pk_info = &mbedtls_rsa_info;
619 pk.pk_ctx = slot->data.rsa;
620 }
621 else
622 {
623 pk.pk_info = &mbedtls_eckey_info;
624 pk.pk_ctx = slot->data.ecp;
625 }
Moran Pekerd7326592018-05-29 16:56:39 +0300626 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300627 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300628 else
629 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300630 if( ret < 0 )
Moran Pekera998bc62018-04-16 18:16:20 +0300631 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine0e231582018-06-20 00:11:07 +0200632 /* The mbedtls_pk_xxx functions write to the end of the buffer.
633 * Move the data to the beginning and erase remaining data
634 * at the original location. */
635 if( 2 * (size_t) ret <= data_size )
636 {
637 memcpy( data, data + data_size - ret, ret );
638 }
639 else if( (size_t) ret < data_size )
640 {
641 memmove( data, data + data_size - ret, ret );
642 }
Moran Pekera998bc62018-04-16 18:16:20 +0300643 *data_length = ret;
644 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100645 }
646 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100647#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300648 {
649 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200650 it is valid for a special-purpose implementation to omit
651 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300652 return( PSA_ERROR_NOT_SUPPORTED );
653 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100654 }
655}
656
Gilles Peskine2d277862018-06-18 15:41:12 +0200657psa_status_t psa_export_key( psa_key_slot_t key,
658 uint8_t *data,
659 size_t data_size,
660 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300661{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200662 return( psa_internal_export_key( key, data, data_size,
663 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100664}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100665
Gilles Peskine2d277862018-06-18 15:41:12 +0200666psa_status_t psa_export_public_key( psa_key_slot_t key,
667 uint8_t *data,
668 size_t data_size,
669 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300670{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200671 return( psa_internal_export_key( key, data, data_size,
672 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300673}
674
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200675
676
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100677/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100678/* Message digests */
679/****************************************************************/
680
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100681static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100682{
683 switch( alg )
684 {
685#if defined(MBEDTLS_MD2_C)
686 case PSA_ALG_MD2:
687 return( &mbedtls_md2_info );
688#endif
689#if defined(MBEDTLS_MD4_C)
690 case PSA_ALG_MD4:
691 return( &mbedtls_md4_info );
692#endif
693#if defined(MBEDTLS_MD5_C)
694 case PSA_ALG_MD5:
695 return( &mbedtls_md5_info );
696#endif
697#if defined(MBEDTLS_RIPEMD160_C)
698 case PSA_ALG_RIPEMD160:
699 return( &mbedtls_ripemd160_info );
700#endif
701#if defined(MBEDTLS_SHA1_C)
702 case PSA_ALG_SHA_1:
703 return( &mbedtls_sha1_info );
704#endif
705#if defined(MBEDTLS_SHA256_C)
706 case PSA_ALG_SHA_224:
707 return( &mbedtls_sha224_info );
708 case PSA_ALG_SHA_256:
709 return( &mbedtls_sha256_info );
710#endif
711#if defined(MBEDTLS_SHA512_C)
712 case PSA_ALG_SHA_384:
713 return( &mbedtls_sha384_info );
714 case PSA_ALG_SHA_512:
715 return( &mbedtls_sha512_info );
716#endif
717 default:
718 return( NULL );
719 }
720}
721
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100722psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
723{
724 switch( operation->alg )
725 {
726#if defined(MBEDTLS_MD2_C)
727 case PSA_ALG_MD2:
728 mbedtls_md2_free( &operation->ctx.md2 );
729 break;
730#endif
731#if defined(MBEDTLS_MD4_C)
732 case PSA_ALG_MD4:
733 mbedtls_md4_free( &operation->ctx.md4 );
734 break;
735#endif
736#if defined(MBEDTLS_MD5_C)
737 case PSA_ALG_MD5:
738 mbedtls_md5_free( &operation->ctx.md5 );
739 break;
740#endif
741#if defined(MBEDTLS_RIPEMD160_C)
742 case PSA_ALG_RIPEMD160:
743 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
744 break;
745#endif
746#if defined(MBEDTLS_SHA1_C)
747 case PSA_ALG_SHA_1:
748 mbedtls_sha1_free( &operation->ctx.sha1 );
749 break;
750#endif
751#if defined(MBEDTLS_SHA256_C)
752 case PSA_ALG_SHA_224:
753 case PSA_ALG_SHA_256:
754 mbedtls_sha256_free( &operation->ctx.sha256 );
755 break;
756#endif
757#if defined(MBEDTLS_SHA512_C)
758 case PSA_ALG_SHA_384:
759 case PSA_ALG_SHA_512:
760 mbedtls_sha512_free( &operation->ctx.sha512 );
761 break;
762#endif
763 default:
764 return( PSA_ERROR_NOT_SUPPORTED );
765 }
766 operation->alg = 0;
767 return( PSA_SUCCESS );
768}
769
770psa_status_t psa_hash_start( psa_hash_operation_t *operation,
771 psa_algorithm_t alg )
772{
773 int ret;
774 operation->alg = 0;
775 switch( alg )
776 {
777#if defined(MBEDTLS_MD2_C)
778 case PSA_ALG_MD2:
779 mbedtls_md2_init( &operation->ctx.md2 );
780 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
781 break;
782#endif
783#if defined(MBEDTLS_MD4_C)
784 case PSA_ALG_MD4:
785 mbedtls_md4_init( &operation->ctx.md4 );
786 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
787 break;
788#endif
789#if defined(MBEDTLS_MD5_C)
790 case PSA_ALG_MD5:
791 mbedtls_md5_init( &operation->ctx.md5 );
792 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
793 break;
794#endif
795#if defined(MBEDTLS_RIPEMD160_C)
796 case PSA_ALG_RIPEMD160:
797 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
798 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
799 break;
800#endif
801#if defined(MBEDTLS_SHA1_C)
802 case PSA_ALG_SHA_1:
803 mbedtls_sha1_init( &operation->ctx.sha1 );
804 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
805 break;
806#endif
807#if defined(MBEDTLS_SHA256_C)
808 case PSA_ALG_SHA_224:
809 mbedtls_sha256_init( &operation->ctx.sha256 );
810 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
811 break;
812 case PSA_ALG_SHA_256:
813 mbedtls_sha256_init( &operation->ctx.sha256 );
814 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
815 break;
816#endif
817#if defined(MBEDTLS_SHA512_C)
818 case PSA_ALG_SHA_384:
819 mbedtls_sha512_init( &operation->ctx.sha512 );
820 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
821 break;
822 case PSA_ALG_SHA_512:
823 mbedtls_sha512_init( &operation->ctx.sha512 );
824 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
825 break;
826#endif
827 default:
828 return( PSA_ERROR_NOT_SUPPORTED );
829 }
830 if( ret == 0 )
831 operation->alg = alg;
832 else
833 psa_hash_abort( operation );
834 return( mbedtls_to_psa_error( ret ) );
835}
836
837psa_status_t psa_hash_update( psa_hash_operation_t *operation,
838 const uint8_t *input,
839 size_t input_length )
840{
841 int ret;
842 switch( operation->alg )
843 {
844#if defined(MBEDTLS_MD2_C)
845 case PSA_ALG_MD2:
846 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
847 input, input_length );
848 break;
849#endif
850#if defined(MBEDTLS_MD4_C)
851 case PSA_ALG_MD4:
852 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
853 input, input_length );
854 break;
855#endif
856#if defined(MBEDTLS_MD5_C)
857 case PSA_ALG_MD5:
858 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
859 input, input_length );
860 break;
861#endif
862#if defined(MBEDTLS_RIPEMD160_C)
863 case PSA_ALG_RIPEMD160:
864 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
865 input, input_length );
866 break;
867#endif
868#if defined(MBEDTLS_SHA1_C)
869 case PSA_ALG_SHA_1:
870 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
871 input, input_length );
872 break;
873#endif
874#if defined(MBEDTLS_SHA256_C)
875 case PSA_ALG_SHA_224:
876 case PSA_ALG_SHA_256:
877 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
878 input, input_length );
879 break;
880#endif
881#if defined(MBEDTLS_SHA512_C)
882 case PSA_ALG_SHA_384:
883 case PSA_ALG_SHA_512:
884 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
885 input, input_length );
886 break;
887#endif
888 default:
889 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
890 break;
891 }
892 if( ret != 0 )
893 psa_hash_abort( operation );
894 return( mbedtls_to_psa_error( ret ) );
895}
896
897psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
898 uint8_t *hash,
899 size_t hash_size,
900 size_t *hash_length )
901{
902 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200903 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100904
905 /* Fill the output buffer with something that isn't a valid hash
906 * (barring an attack on the hash and deliberately-crafted input),
907 * in case the caller doesn't check the return status properly. */
908 *hash_length = actual_hash_length;
909 memset( hash, '!', hash_size );
910
911 if( hash_size < actual_hash_length )
912 return( PSA_ERROR_BUFFER_TOO_SMALL );
913
914 switch( operation->alg )
915 {
916#if defined(MBEDTLS_MD2_C)
917 case PSA_ALG_MD2:
918 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
919 break;
920#endif
921#if defined(MBEDTLS_MD4_C)
922 case PSA_ALG_MD4:
923 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
924 break;
925#endif
926#if defined(MBEDTLS_MD5_C)
927 case PSA_ALG_MD5:
928 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
929 break;
930#endif
931#if defined(MBEDTLS_RIPEMD160_C)
932 case PSA_ALG_RIPEMD160:
933 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
934 break;
935#endif
936#if defined(MBEDTLS_SHA1_C)
937 case PSA_ALG_SHA_1:
938 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
939 break;
940#endif
941#if defined(MBEDTLS_SHA256_C)
942 case PSA_ALG_SHA_224:
943 case PSA_ALG_SHA_256:
944 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
945 break;
946#endif
947#if defined(MBEDTLS_SHA512_C)
948 case PSA_ALG_SHA_384:
949 case PSA_ALG_SHA_512:
950 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
951 break;
952#endif
953 default:
954 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
955 break;
956 }
957
958 if( ret == 0 )
959 {
960 return( psa_hash_abort( operation ) );
961 }
962 else
963 {
964 psa_hash_abort( operation );
965 return( mbedtls_to_psa_error( ret ) );
966 }
967}
968
Gilles Peskine2d277862018-06-18 15:41:12 +0200969psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
970 const uint8_t *hash,
971 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100972{
973 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
974 size_t actual_hash_length;
975 psa_status_t status = psa_hash_finish( operation,
976 actual_hash, sizeof( actual_hash ),
977 &actual_hash_length );
978 if( status != PSA_SUCCESS )
979 return( status );
980 if( actual_hash_length != hash_length )
981 return( PSA_ERROR_INVALID_SIGNATURE );
982 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
983 return( PSA_ERROR_INVALID_SIGNATURE );
984 return( PSA_SUCCESS );
985}
986
987
988
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100989/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +0100990/* MAC */
991/****************************************************************/
992
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100993static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +0100994 psa_algorithm_t alg,
995 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +0200996 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +0300997 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100998{
Gilles Peskine8c9def32018-02-08 10:02:12 +0100999 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001000 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001001
1002 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1003 {
1004 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001005 {
1006 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1007 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001008
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001009 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001010 {
1011 case PSA_ALG_STREAM_CIPHER:
1012 mode = MBEDTLS_MODE_STREAM;
1013 break;
1014 case PSA_ALG_CBC_BASE:
1015 mode = MBEDTLS_MODE_CBC;
1016 break;
1017 case PSA_ALG_CFB_BASE:
1018 mode = MBEDTLS_MODE_CFB;
1019 break;
1020 case PSA_ALG_OFB_BASE:
1021 mode = MBEDTLS_MODE_OFB;
1022 break;
1023 case PSA_ALG_CTR:
1024 mode = MBEDTLS_MODE_CTR;
1025 break;
1026 case PSA_ALG_CCM:
1027 mode = MBEDTLS_MODE_CCM;
1028 break;
1029 case PSA_ALG_GCM:
1030 mode = MBEDTLS_MODE_GCM;
1031 break;
1032 default:
1033 return( NULL );
1034 }
1035 }
1036 else if( alg == PSA_ALG_CMAC )
1037 mode = MBEDTLS_MODE_ECB;
1038 else if( alg == PSA_ALG_GMAC )
1039 mode = MBEDTLS_MODE_GCM;
1040 else
1041 return( NULL );
1042
1043 switch( key_type )
1044 {
1045 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001046 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001047 break;
1048 case PSA_KEY_TYPE_DES:
1049 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001050 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001051 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001052 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001053 break;
1054 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001055 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001056 break;
1057 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001058 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001059 break;
1060 default:
1061 return( NULL );
1062 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001063 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001064 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001065
mohammad1603f4f0d612018-06-03 15:04:51 +03001066 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001067}
1068
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001069static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001070{
Gilles Peskine2d277862018-06-18 15:41:12 +02001071 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001072 {
1073 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001074 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001075 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001076 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001077 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001078 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001079 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001080 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001081 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001082 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001083 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001084 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001085 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001086 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001087 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001088 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001089 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001090 return( 128 );
1091 default:
1092 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001093 }
1094}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001095
Gilles Peskine8c9def32018-02-08 10:02:12 +01001096psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1097{
1098 switch( operation->alg )
1099 {
1100#if defined(MBEDTLS_CMAC_C)
1101 case PSA_ALG_CMAC:
1102 mbedtls_cipher_free( &operation->ctx.cmac );
1103 break;
1104#endif /* MBEDTLS_CMAC_C */
1105 default:
1106#if defined(MBEDTLS_MD_C)
1107 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001108 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001109 unsigned int block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001110 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001111
Gilles Peskine99bc6492018-06-11 17:13:00 +02001112 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001113 return( PSA_ERROR_NOT_SUPPORTED );
1114
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001115 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001116 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001117 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001118 else
1119#endif /* MBEDTLS_MD_C */
1120 return( PSA_ERROR_NOT_SUPPORTED );
1121 }
Moran Peker41deec42018-04-04 15:43:05 +03001122
Gilles Peskine8c9def32018-02-08 10:02:12 +01001123 operation->alg = 0;
1124 operation->key_set = 0;
1125 operation->iv_set = 0;
1126 operation->iv_required = 0;
1127 operation->has_input = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001128
Gilles Peskine8c9def32018-02-08 10:02:12 +01001129 return( PSA_SUCCESS );
1130}
1131
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001132#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001133static int psa_cmac_start( psa_mac_operation_t *operation,
1134 size_t key_bits,
1135 key_slot_t *slot,
1136 const mbedtls_cipher_info_t *cipher_info )
1137{
1138 int ret;
1139
1140 operation->mac_size = cipher_info->block_size;
1141 operation->iv_required = 0;
1142 mbedtls_cipher_init( &operation->ctx.cmac );
1143
1144 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1145 if( ret != 0 )
1146 return( ret );
1147
1148 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1149 slot->data.raw.data,
1150 key_bits );
1151 return( ret );
1152}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001153#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001154
1155static int psa_hmac_start( psa_mac_operation_t *operation,
1156 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001157 key_slot_t *slot,
1158 psa_algorithm_t alg )
1159{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001160 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001161 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001162 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001163 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001164 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001165 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001166 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001167 size_t key_length = slot->data.raw.bytes;
1168 psa_status_t status;
1169
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001170 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001171 return( PSA_ERROR_NOT_SUPPORTED );
1172
1173 if( key_type != PSA_KEY_TYPE_HMAC )
1174 return( PSA_ERROR_INVALID_ARGUMENT );
1175
1176 operation->iv_required = 0;
1177 operation->mac_size = digest_size;
1178
1179 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1180 PSA_ALG_HMAC_HASH( alg ) );
1181 if( status != PSA_SUCCESS )
1182 return( status );
1183
Gilles Peskined223b522018-06-11 18:12:58 +02001184 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001185 {
1186 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001187 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001188 if( status != PSA_SUCCESS )
1189 return( status );
1190 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001191 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001192 if( status != PSA_SUCCESS )
1193 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001194 }
Gilles Peskined223b522018-06-11 18:12:58 +02001195 else
1196 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001197
Gilles Peskined223b522018-06-11 18:12:58 +02001198 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1199 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001200 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001201 ipad[i] ^= 0x36;
1202 memset( ipad + key_length, 0x36, block_size - key_length );
1203
1204 /* Copy the key material from ipad to opad, flipping the requisite bits,
1205 * and filling the rest of opad with the requisite constant. */
1206 for( i = 0; i < key_length; i++ )
1207 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1208 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001209
1210 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1211 PSA_ALG_HMAC_HASH( alg ) );
1212 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001213 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001214
1215 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1216 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001217
1218cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001219 mbedtls_zeroize( ipad, key_length );
1220 /* opad is in the context. It needs to stay in memory if this function
1221 * succeeds, and it will be wiped by psa_mac_abort() called from
1222 * psa_mac_start in the error case. */
1223
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001224 return( status );
1225}
1226
Gilles Peskine8c9def32018-02-08 10:02:12 +01001227psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1228 psa_key_slot_t key,
1229 psa_algorithm_t alg )
1230{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001231 psa_status_t status;
1232 key_slot_t *slot;
1233 psa_key_type_t key_type;
1234 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001235 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001236
1237 operation->alg = 0;
1238 operation->key_set = 0;
1239 operation->iv_set = 0;
1240 operation->iv_required = 1;
1241 operation->has_input = 0;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001242 operation->key_usage_sign = 0;
1243 operation->key_usage_verify = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001244
1245 status = psa_get_key_information( key, &key_type, &key_bits );
1246 if( status != PSA_SUCCESS )
1247 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001248
Gilles Peskine8c9def32018-02-08 10:02:12 +01001249 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001250 if( slot->type == PSA_KEY_TYPE_NONE )
1251 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001252
Moran Pekerd7326592018-05-29 16:56:39 +03001253 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001254 operation->key_usage_sign = 1;
1255
Moran Pekerd7326592018-05-29 16:56:39 +03001256 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001257 operation->key_usage_verify = 1;
1258
Gilles Peskine8c9def32018-02-08 10:02:12 +01001259 if( ! PSA_ALG_IS_HMAC( alg ) )
1260 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001261 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001262 if( cipher_info == NULL )
1263 return( PSA_ERROR_NOT_SUPPORTED );
1264 operation->mac_size = cipher_info->block_size;
1265 }
1266 switch( alg )
1267 {
1268#if defined(MBEDTLS_CMAC_C)
1269 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001270 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1271 key_bits,
1272 slot,
1273 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001274 break;
1275#endif /* MBEDTLS_CMAC_C */
1276 default:
1277#if defined(MBEDTLS_MD_C)
1278 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001279 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001280 else
1281#endif /* MBEDTLS_MD_C */
1282 return( PSA_ERROR_NOT_SUPPORTED );
1283 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001284
Gilles Peskine8c9def32018-02-08 10:02:12 +01001285 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001286
1287 * context may contain data that needs to be wiped on error. */
1288 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001289 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001290 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001291 }
Gilles Peskine99bc6492018-06-11 17:13:00 +02001292
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001293 else
1294 {
1295 operation->alg = alg;
1296 operation->key_set = 1;
1297 }
1298 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001299}
1300
1301psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1302 const uint8_t *input,
1303 size_t input_length )
1304{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001305 int ret = 0 ;
1306 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001307 if( ! operation->key_set )
1308 return( PSA_ERROR_BAD_STATE );
1309 if( operation->iv_required && ! operation->iv_set )
1310 return( PSA_ERROR_BAD_STATE );
1311 operation->has_input = 1;
1312
1313 switch( operation->alg )
1314 {
1315#if defined(MBEDTLS_CMAC_C)
1316 case PSA_ALG_CMAC:
1317 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1318 input, input_length );
1319 break;
1320#endif /* MBEDTLS_CMAC_C */
1321 default:
1322#if defined(MBEDTLS_MD_C)
1323 if( PSA_ALG_IS_HMAC( operation->alg ) )
1324 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001325 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001326 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001327 }
1328 else
1329#endif /* MBEDTLS_MD_C */
1330 {
1331 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1332 }
1333 break;
1334 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001335 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001336 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001337 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001338 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001339 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001340 }
1341
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001342 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001343}
1344
mohammad16036df908f2018-04-02 08:34:15 -07001345static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001346 uint8_t *mac,
1347 size_t mac_size,
1348 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001349{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001350 int ret = 0;
1351 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001352 if( ! operation->key_set )
1353 return( PSA_ERROR_BAD_STATE );
1354 if( operation->iv_required && ! operation->iv_set )
1355 return( PSA_ERROR_BAD_STATE );
1356
1357 /* Fill the output buffer with something that isn't a valid mac
1358 * (barring an attack on the mac and deliberately-crafted input),
1359 * in case the caller doesn't check the return status properly. */
1360 *mac_length = operation->mac_size;
1361 memset( mac, '!', mac_size );
1362
1363 if( mac_size < operation->mac_size )
1364 return( PSA_ERROR_BUFFER_TOO_SMALL );
1365
1366 switch( operation->alg )
1367 {
1368#if defined(MBEDTLS_CMAC_C)
1369 case PSA_ALG_CMAC:
1370 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1371 break;
1372#endif /* MBEDTLS_CMAC_C */
1373 default:
1374#if defined(MBEDTLS_MD_C)
1375 if( PSA_ALG_IS_HMAC( operation->alg ) )
1376 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001377 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001378 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001379 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001380 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001381 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001382
Gilles Peskine99bc6492018-06-11 17:13:00 +02001383 if( block_size == 0 )
1384 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001385
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001386 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001387 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001388 if( status != PSA_SUCCESS )
1389 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001390 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001391
1392 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1393 PSA_ALG_HMAC_HASH( operation->alg ) );
1394 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001395 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001396
1397 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001398 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001399 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, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001403 hash_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_finish( &operation->ctx.hmac.hash_ctx, mac,
1408 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001409 hmac_cleanup:
1410 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001411 }
1412 else
1413#endif /* MBEDTLS_MD_C */
1414 {
1415 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1416 }
1417 break;
1418 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001419cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001420
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001421 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001422 {
1423 return( psa_mac_abort( operation ) );
1424 }
1425 else
1426 {
1427 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001428 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001429 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001430
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001431 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001432 }
1433}
1434
mohammad16036df908f2018-04-02 08:34:15 -07001435psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1436 uint8_t *mac,
1437 size_t mac_size,
1438 size_t *mac_length )
1439{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001440 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001441 return( PSA_ERROR_NOT_PERMITTED );
1442
Gilles Peskine99bc6492018-06-11 17:13:00 +02001443 return( psa_mac_finish_internal( operation, mac,
1444 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001445}
1446
Gilles Peskine828ed142018-06-18 23:25:51 +02001447#define PSA_MAC_MAX_SIZE \
Gilles Peskine2d277862018-06-18 15:41:12 +02001448 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1449 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001450 MBEDTLS_MAX_BLOCK_LENGTH )
1451psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1452 const uint8_t *mac,
1453 size_t mac_length )
1454{
Gilles Peskine828ed142018-06-18 23:25:51 +02001455 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001456 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001457 psa_status_t status;
1458
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001459 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001460 return( PSA_ERROR_NOT_PERMITTED );
1461
1462 status = psa_mac_finish_internal( operation,
1463 actual_mac, sizeof( actual_mac ),
1464 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001465 if( status != PSA_SUCCESS )
1466 return( status );
1467 if( actual_mac_length != mac_length )
1468 return( PSA_ERROR_INVALID_SIGNATURE );
1469 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1470 return( PSA_ERROR_INVALID_SIGNATURE );
1471 return( PSA_SUCCESS );
1472}
1473
1474
Gilles Peskine20035e32018-02-03 22:44:14 +01001475
Gilles Peskine20035e32018-02-03 22:44:14 +01001476/****************************************************************/
1477/* Asymmetric cryptography */
1478/****************************************************************/
1479
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001480/* Decode the hash algorithm from alg and store the mbedtls encoding in
1481 * md_alg. Verify that the hash length is consistent. */
1482static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1483 size_t hash_length,
1484 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001485{
Gilles Peskine61b91d42018-06-08 16:09:36 +02001486 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
1487 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1488 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1489 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001490 {
1491#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001492 if( hash_length > UINT_MAX )
1493 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001494#endif
1495 }
1496 else
1497 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001498 if( mbedtls_md_get_size( md_info ) != hash_length )
1499 return( PSA_ERROR_INVALID_ARGUMENT );
1500 if( md_info == NULL )
1501 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001502 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001503 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001504}
1505
Gilles Peskine61b91d42018-06-08 16:09:36 +02001506psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1507 psa_algorithm_t alg,
1508 const uint8_t *hash,
1509 size_t hash_length,
1510 const uint8_t *salt,
1511 size_t salt_length,
1512 uint8_t *signature,
1513 size_t signature_size,
1514 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001515{
1516 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001517 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001518 *signature_length = 0;
1519 (void) salt;
1520 (void) salt_length;
1521
Gilles Peskine828ed142018-06-18 23:25:51 +02001522 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine20035e32018-02-03 22:44:14 +01001523 return( PSA_ERROR_EMPTY_SLOT );
1524 slot = &global_data.key_slots[key];
1525 if( slot->type == PSA_KEY_TYPE_NONE )
1526 return( PSA_ERROR_EMPTY_SLOT );
1527 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1528 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001529 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001530 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001531
Gilles Peskine20035e32018-02-03 22:44:14 +01001532#if defined(MBEDTLS_RSA_C)
1533 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1534 {
1535 mbedtls_rsa_context *rsa = slot->data.rsa;
1536 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001537 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001538 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001539 if( status != PSA_SUCCESS )
1540 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001541
Gilles Peskine20035e32018-02-03 22:44:14 +01001542 if( signature_size < rsa->len )
1543 return( PSA_ERROR_BUFFER_TOO_SMALL );
1544#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001545 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001546 {
1547 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1548 MBEDTLS_MD_NONE );
1549 ret = mbedtls_rsa_pkcs1_sign( rsa,
1550 mbedtls_ctr_drbg_random,
1551 &global_data.ctr_drbg,
1552 MBEDTLS_RSA_PRIVATE,
1553 md_alg, hash_length, hash,
1554 signature );
1555 }
1556 else
1557#endif /* MBEDTLS_PKCS1_V15 */
1558#if defined(MBEDTLS_PKCS1_V21)
1559 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1560 {
1561 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1562 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1563 mbedtls_ctr_drbg_random,
1564 &global_data.ctr_drbg,
1565 MBEDTLS_RSA_PRIVATE,
1566 md_alg, hash_length, hash,
1567 signature );
1568 }
1569 else
1570#endif /* MBEDTLS_PKCS1_V21 */
1571 {
1572 return( PSA_ERROR_INVALID_ARGUMENT );
1573 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001574 if( ret == 0 )
1575 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001576 return( mbedtls_to_psa_error( ret ) );
1577 }
1578 else
1579#endif /* defined(MBEDTLS_RSA_C) */
1580#if defined(MBEDTLS_ECP_C)
1581 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1582 {
itayzafrir5c753392018-05-08 11:18:38 +03001583 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1584 int ret;
1585 const mbedtls_md_info_t *md_info;
1586 mbedtls_md_type_t md_alg;
1587 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1588 return( PSA_ERROR_BUFFER_TOO_SMALL );
1589 md_info = mbedtls_md_info_from_psa( alg );
1590 md_alg = mbedtls_md_get_type( md_info );
1591 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001592 signature, signature_length,
1593 mbedtls_ctr_drbg_random,
1594 &global_data.ctr_drbg );
itayzafrir5c753392018-05-08 11:18:38 +03001595 return( mbedtls_to_psa_error( ret ) );
1596 }
1597 else
1598#endif /* defined(MBEDTLS_ECP_C) */
1599 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001600 return( PSA_ERROR_NOT_SUPPORTED );
1601 }
itayzafrir5c753392018-05-08 11:18:38 +03001602}
1603
1604psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1605 psa_algorithm_t alg,
1606 const uint8_t *hash,
1607 size_t hash_length,
1608 const uint8_t *salt,
1609 size_t salt_length,
1610 uint8_t *signature,
1611 size_t signature_size )
1612{
1613 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001614 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001615 (void) salt;
1616 (void) salt_length;
1617
Gilles Peskine828ed142018-06-18 23:25:51 +02001618 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001619 return( PSA_ERROR_INVALID_ARGUMENT );
1620 slot = &global_data.key_slots[key];
1621 if( slot->type == PSA_KEY_TYPE_NONE )
1622 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001623 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001624 return( PSA_ERROR_NOT_PERMITTED );
1625
Gilles Peskine61b91d42018-06-08 16:09:36 +02001626#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001627 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1628 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001629 {
1630 mbedtls_rsa_context *rsa = slot->data.rsa;
1631 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001632 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001633 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001634 if( status != PSA_SUCCESS )
1635 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001636
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001637 if( signature_size < rsa->len )
1638 return( PSA_ERROR_BUFFER_TOO_SMALL );
1639#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001640 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001641 {
1642 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1643 MBEDTLS_MD_NONE );
1644
1645 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001646 mbedtls_ctr_drbg_random,
1647 &global_data.ctr_drbg,
1648 MBEDTLS_RSA_PUBLIC,
1649 md_alg,
1650 hash_length,
1651 hash,
1652 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001653
1654 }
1655 else
1656#endif /* MBEDTLS_PKCS1_V15 */
1657#if defined(MBEDTLS_PKCS1_V21)
1658 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1659 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001660 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1661 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1662 mbedtls_ctr_drbg_random,
1663 &global_data.ctr_drbg,
1664 MBEDTLS_RSA_PUBLIC,
1665 md_alg, hash_length, hash,
1666 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001667 }
1668 else
1669#endif /* MBEDTLS_PKCS1_V21 */
1670 {
1671 return( PSA_ERROR_INVALID_ARGUMENT );
1672 }
1673 return( mbedtls_to_psa_error( ret ) );
1674 }
1675 else
1676#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001677#if defined(MBEDTLS_ECP_C)
1678 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1679 {
1680 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1681 int ret;
Gilles Peskine2d277862018-06-18 15:41:12 +02001682 (void) alg;
Gilles Peskine61b91d42018-06-08 16:09:36 +02001683 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length,
1684 signature, signature_size );
itayzafrir5c753392018-05-08 11:18:38 +03001685 return( mbedtls_to_psa_error( ret ) );
1686 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001687 else
1688#endif /* defined(MBEDTLS_ECP_C) */
1689 {
1690 return( PSA_ERROR_NOT_SUPPORTED );
1691 }
1692}
1693
Gilles Peskine61b91d42018-06-08 16:09:36 +02001694psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1695 psa_algorithm_t alg,
1696 const uint8_t *input,
1697 size_t input_length,
1698 const uint8_t *salt,
1699 size_t salt_length,
1700 uint8_t *output,
1701 size_t output_size,
1702 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001703{
1704 key_slot_t *slot;
1705 (void) salt;
1706 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001707 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001708
Gilles Peskine828ed142018-06-18 23:25:51 +02001709 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001710 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001711 slot = &global_data.key_slots[key];
1712 if( slot->type == PSA_KEY_TYPE_NONE )
1713 return( PSA_ERROR_EMPTY_SLOT );
1714 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1715 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001716 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1717 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001718
1719#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001720 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1721 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001722 {
1723 mbedtls_rsa_context *rsa = slot->data.rsa;
1724 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001725 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001726 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001727#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001728 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001729 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001730 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1731 mbedtls_ctr_drbg_random,
1732 &global_data.ctr_drbg,
1733 MBEDTLS_RSA_PUBLIC,
1734 input_length,
1735 input,
1736 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001737 }
1738 else
1739#endif /* MBEDTLS_PKCS1_V15 */
1740#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001741 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001742 {
1743 return( PSA_ERROR_NOT_SUPPORTED );
1744 }
1745 else
1746#endif /* MBEDTLS_PKCS1_V21 */
1747 {
1748 return( PSA_ERROR_INVALID_ARGUMENT );
1749 }
1750 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001751 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001752 return( mbedtls_to_psa_error( ret ) );
1753 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001754 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001755#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001756 {
1757 return( PSA_ERROR_NOT_SUPPORTED );
1758 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001759}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001760
Gilles Peskine61b91d42018-06-08 16:09:36 +02001761psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1762 psa_algorithm_t alg,
1763 const uint8_t *input,
1764 size_t input_length,
1765 const uint8_t *salt,
1766 size_t salt_length,
1767 uint8_t *output,
1768 size_t output_size,
1769 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001770{
1771 key_slot_t *slot;
1772 (void) salt;
1773 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001774 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001775
Gilles Peskine828ed142018-06-18 23:25:51 +02001776 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001777 return( PSA_ERROR_EMPTY_SLOT );
1778 slot = &global_data.key_slots[key];
1779 if( slot->type == PSA_KEY_TYPE_NONE )
1780 return( PSA_ERROR_EMPTY_SLOT );
1781 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1782 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001783 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1784 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001785
1786#if defined(MBEDTLS_RSA_C)
1787 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1788 {
1789 mbedtls_rsa_context *rsa = slot->data.rsa;
1790 int ret;
1791
Gilles Peskinec4def2f2018-06-08 17:53:48 +02001792 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001793 return( PSA_ERROR_INVALID_ARGUMENT );
1794
1795#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001796 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001797 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001798 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
1799 mbedtls_ctr_drbg_random,
1800 &global_data.ctr_drbg,
1801 MBEDTLS_RSA_PRIVATE,
1802 output_length,
1803 input,
1804 output,
1805 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001806 }
1807 else
1808#endif /* MBEDTLS_PKCS1_V15 */
1809#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001810 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001811 {
1812 return( PSA_ERROR_NOT_SUPPORTED );
1813 }
1814 else
1815#endif /* MBEDTLS_PKCS1_V21 */
1816 {
1817 return( PSA_ERROR_INVALID_ARGUMENT );
1818 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001819
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001820 return( mbedtls_to_psa_error( ret ) );
1821 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001822 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001823#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001824 {
1825 return( PSA_ERROR_NOT_SUPPORTED );
1826 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001827}
Gilles Peskine20035e32018-02-03 22:44:14 +01001828
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001829
1830
mohammad1603503973b2018-03-12 15:59:30 +02001831/****************************************************************/
1832/* Symmetric cryptography */
1833/****************************************************************/
1834
Gilles Peskinee553c652018-06-04 16:22:46 +02001835static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1836 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001837 psa_algorithm_t alg,
1838 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001839{
1840 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1841 psa_status_t status;
1842 key_slot_t *slot;
1843 psa_key_type_t key_type;
1844 size_t key_bits;
1845 const mbedtls_cipher_info_t *cipher_info = NULL;
1846
Moran Peker41deec42018-04-04 15:43:05 +03001847 operation->alg = alg;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001848 operation->key_set = 0;
1849 operation->iv_set = 0;
1850 operation->iv_required = 1;
1851 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001852 operation->block_size = 0;
mohammad1603503973b2018-03-12 15:59:30 +02001853
1854 status = psa_get_key_information( key, &key_type, &key_bits );
1855 if( status != PSA_SUCCESS )
1856 return( status );
1857 slot = &global_data.key_slots[key];
1858
Gilles Peskinebb1072f2018-06-08 18:46:05 +02001859 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02001860 if( cipher_info == NULL )
1861 return( PSA_ERROR_NOT_SUPPORTED );
1862
mohammad1603503973b2018-03-12 15:59:30 +02001863 mbedtls_cipher_init( &operation->ctx.cipher );
1864 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03001865 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001866 {
1867 psa_cipher_abort( operation );
1868 return( mbedtls_to_psa_error( ret ) );
1869 }
1870
1871 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
Gilles Peskinee553c652018-06-04 16:22:46 +02001872 key_bits, cipher_operation );
Moran Peker41deec42018-04-04 15:43:05 +03001873 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001874 {
1875 psa_cipher_abort( operation );
1876 return( mbedtls_to_psa_error( ret ) );
1877 }
1878
mohammad16038481e742018-03-18 13:57:31 +02001879#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03001880 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02001881 {
Gilles Peskine53514202018-06-06 15:11:46 +02001882 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1883 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02001884
Moran Pekera28258c2018-05-29 16:25:04 +03001885 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02001886 {
1887 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
1888 mode = MBEDTLS_PADDING_PKCS7;
1889 break;
1890 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
1891 mode = MBEDTLS_PADDING_NONE;
1892 break;
1893 default:
Moran Pekerae382792018-05-31 14:06:17 +03001894 psa_cipher_abort( operation );
1895 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02001896 }
1897 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03001898 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03001899 {
1900 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02001901 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03001902 }
mohammad16038481e742018-03-18 13:57:31 +02001903 }
1904#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
1905
mohammad1603503973b2018-03-12 15:59:30 +02001906 operation->key_set = 1;
1907 operation->alg = alg;
Gilles Peskine7e928852018-06-04 16:23:10 +02001908 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
1909 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
1910 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001911 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02001912 {
mohammad160389e0f462018-04-12 08:48:45 +03001913 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02001914 }
mohammad1603503973b2018-03-12 15:59:30 +02001915
Moran Peker395db872018-05-31 14:07:14 +03001916 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001917}
1918
Gilles Peskinee553c652018-06-04 16:22:46 +02001919psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
1920 psa_key_slot_t key,
1921 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001922{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001923 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001924}
1925
Gilles Peskinee553c652018-06-04 16:22:46 +02001926psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
1927 psa_key_slot_t key,
1928 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001929{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001930 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001931}
1932
Gilles Peskinee553c652018-06-04 16:22:46 +02001933psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
1934 unsigned char *iv,
1935 size_t iv_size,
1936 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001937{
Moran Peker41deec42018-04-04 15:43:05 +03001938 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001939 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001940 return( PSA_ERROR_BAD_STATE );
1941 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02001942 {
Moran Peker41deec42018-04-04 15:43:05 +03001943 ret = PSA_ERROR_BUFFER_TOO_SMALL;
1944 goto exit;
1945 }
Gilles Peskine7e928852018-06-04 16:23:10 +02001946 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
1947 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03001948 if( ret != 0 )
1949 {
1950 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02001951 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02001952 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001953
mohammad16038481e742018-03-18 13:57:31 +02001954 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03001955 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001956
Moran Peker395db872018-05-31 14:07:14 +03001957exit:
1958 if( ret != PSA_SUCCESS )
1959 psa_cipher_abort( operation );
1960 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02001961}
1962
Gilles Peskinee553c652018-06-04 16:22:46 +02001963psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
1964 const unsigned char *iv,
1965 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001966{
Moran Peker41deec42018-04-04 15:43:05 +03001967 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001968 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001969 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03001970 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03001971 {
Moran Pekerae382792018-05-31 14:06:17 +03001972 psa_cipher_abort( operation );
1973 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03001974 }
mohammad1603503973b2018-03-12 15:59:30 +02001975 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001976 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001977 {
1978 psa_cipher_abort( operation );
1979 return( mbedtls_to_psa_error( ret ) );
1980 }
1981
1982 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02001983
Moran Peker395db872018-05-31 14:07:14 +03001984 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001985}
1986
Gilles Peskinee553c652018-06-04 16:22:46 +02001987psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
1988 const uint8_t *input,
1989 size_t input_length,
1990 unsigned char *output,
1991 size_t output_size,
1992 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001993{
1994 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02001995 size_t expected_output_size;
1996 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
1997 {
1998 /* Take the unprocessed partial block left over from previous
1999 * update calls, if any, plus the input to this call. Remove
2000 * the last partial block, if any. You get the data that will be
2001 * output in this call. */
2002 expected_output_size =
2003 ( operation->ctx.cipher.unprocessed_len + input_length )
2004 / operation->block_size * operation->block_size;
2005 }
2006 else
2007 {
2008 expected_output_size = input_length;
2009 }
2010 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002011 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002012
mohammad1603503973b2018-03-12 15:59:30 +02002013 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002014 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002015 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002016 {
2017 psa_cipher_abort( operation );
2018 return( mbedtls_to_psa_error( ret ) );
2019 }
2020
Moran Peker395db872018-05-31 14:07:14 +03002021 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002022}
2023
Gilles Peskinee553c652018-06-04 16:22:46 +02002024psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2025 uint8_t *output,
2026 size_t output_size,
2027 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002028{
2029 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002030 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002031
mohammad1603503973b2018-03-12 15:59:30 +02002032 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002033 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002034 psa_cipher_abort( operation );
2035 return( PSA_ERROR_BAD_STATE );
2036 }
2037 if( operation->iv_required && ! operation->iv_set )
2038 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002039 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002040 return( PSA_ERROR_BAD_STATE );
2041 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002042 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2043 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002044 {
Gilles Peskine53514202018-06-06 15:11:46 +02002045 psa_algorithm_t padding_mode =
2046 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002047 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002048 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002049 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002050 return( PSA_ERROR_TAMPERING_DETECTED );
2051 }
Gilles Peskine53514202018-06-06 15:11:46 +02002052 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002053 {
2054 if( operation->ctx.cipher.unprocessed_len != 0 )
2055 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002056 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002057 return( PSA_ERROR_INVALID_ARGUMENT );
2058 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002059 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002060 }
2061
2062 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002063 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002064 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002065 {
2066 psa_cipher_abort( operation );
2067 return( mbedtls_to_psa_error( ret ) );
2068 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002069 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002070 memcpy( output, temp_output_buffer, *output_length );
2071 else
2072 {
2073 psa_cipher_abort( operation );
2074 return( PSA_ERROR_BUFFER_TOO_SMALL );
2075 }
mohammad1603503973b2018-03-12 15:59:30 +02002076
Moran Peker4c80d832018-04-22 20:15:31 +03002077 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002078}
2079
Gilles Peskinee553c652018-06-04 16:22:46 +02002080psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2081{
mohammad1603503973b2018-03-12 15:59:30 +02002082 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002083
Moran Peker41deec42018-04-04 15:43:05 +03002084 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002085 operation->key_set = 0;
2086 operation->iv_set = 0;
2087 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002088 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002089 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002090
Moran Peker395db872018-05-31 14:07:14 +03002091 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002092}
2093
Gilles Peskinea0655c32018-04-30 17:06:50 +02002094
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002095
mohammad16038cc1cee2018-03-28 01:21:33 +03002096/****************************************************************/
2097/* Key Policy */
2098/****************************************************************/
2099
Gilles Peskine2d277862018-06-18 15:41:12 +02002100void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002101{
Gilles Peskine803ce742018-06-18 16:07:14 +02002102 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002103}
2104
Gilles Peskine2d277862018-06-18 15:41:12 +02002105void psa_key_policy_set_usage( psa_key_policy_t *policy,
2106 psa_key_usage_t usage,
2107 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002108{
mohammad16034eed7572018-03-28 05:14:59 -07002109 policy->usage = usage;
2110 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002111}
2112
Gilles Peskine2d277862018-06-18 15:41:12 +02002113psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002114{
mohammad16036df908f2018-04-02 08:34:15 -07002115 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002116}
2117
Gilles Peskine2d277862018-06-18 15:41:12 +02002118psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002119{
mohammad16036df908f2018-04-02 08:34:15 -07002120 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002121}
2122
Gilles Peskine2d277862018-06-18 15:41:12 +02002123psa_status_t psa_set_key_policy( psa_key_slot_t key,
2124 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002125{
2126 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002127
Gilles Peskine828ed142018-06-18 23:25:51 +02002128 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002129 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002130
mohammad16038cc1cee2018-03-28 01:21:33 +03002131 slot = &global_data.key_slots[key];
2132 if( slot->type != PSA_KEY_TYPE_NONE )
2133 return( PSA_ERROR_OCCUPIED_SLOT );
2134
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002135 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2136 PSA_KEY_USAGE_ENCRYPT |
2137 PSA_KEY_USAGE_DECRYPT |
2138 PSA_KEY_USAGE_SIGN |
2139 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002140 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002141
mohammad16036df908f2018-04-02 08:34:15 -07002142 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002143
2144 return( PSA_SUCCESS );
2145}
2146
Gilles Peskine2d277862018-06-18 15:41:12 +02002147psa_status_t psa_get_key_policy( psa_key_slot_t key,
2148 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002149{
2150 key_slot_t *slot;
2151
Gilles Peskine828ed142018-06-18 23:25:51 +02002152 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002153 return( PSA_ERROR_INVALID_ARGUMENT );
2154
2155 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002156
mohammad16036df908f2018-04-02 08:34:15 -07002157 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002158
2159 return( PSA_SUCCESS );
2160}
Gilles Peskine20035e32018-02-03 22:44:14 +01002161
Gilles Peskinea0655c32018-04-30 17:06:50 +02002162
2163
mohammad1603804cd712018-03-20 22:44:08 +02002164/****************************************************************/
2165/* Key Lifetime */
2166/****************************************************************/
2167
Gilles Peskine2d277862018-06-18 15:41:12 +02002168psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2169 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002170{
2171 key_slot_t *slot;
2172
Gilles Peskine828ed142018-06-18 23:25:51 +02002173 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002174 return( PSA_ERROR_INVALID_ARGUMENT );
2175
2176 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002177
mohammad1603804cd712018-03-20 22:44:08 +02002178 *lifetime = slot->lifetime;
2179
2180 return( PSA_SUCCESS );
2181}
2182
Gilles Peskine2d277862018-06-18 15:41:12 +02002183psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2184 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002185{
2186 key_slot_t *slot;
2187
Gilles Peskine828ed142018-06-18 23:25:51 +02002188 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002189 return( PSA_ERROR_INVALID_ARGUMENT );
2190
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002191 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2192 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002193 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2194 return( PSA_ERROR_INVALID_ARGUMENT );
2195
mohammad1603804cd712018-03-20 22:44:08 +02002196 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002197 if( slot->type != PSA_KEY_TYPE_NONE )
2198 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002199
Moran Pekerd7326592018-05-29 16:56:39 +03002200 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002201 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002202
mohammad1603060ad8a2018-03-20 14:28:38 -07002203 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002204
2205 return( PSA_SUCCESS );
2206}
2207
Gilles Peskine20035e32018-02-03 22:44:14 +01002208
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002209
mohammad16035955c982018-04-26 00:53:03 +03002210/****************************************************************/
2211/* AEAD */
2212/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002213
mohammad16035955c982018-04-26 00:53:03 +03002214psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2215 psa_algorithm_t alg,
2216 const uint8_t *nonce,
2217 size_t nonce_length,
2218 const uint8_t *additional_data,
2219 size_t additional_data_length,
2220 const uint8_t *plaintext,
2221 size_t plaintext_length,
2222 uint8_t *ciphertext,
2223 size_t ciphertext_size,
2224 size_t *ciphertext_length )
2225{
2226 int ret;
2227 psa_status_t status;
2228 key_slot_t *slot;
2229 psa_key_type_t key_type;
2230 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002231 uint8_t *tag;
2232 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002233 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002234 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002235
mohammad1603f08a5502018-06-03 15:05:47 +03002236 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002237
mohammad16035955c982018-04-26 00:53:03 +03002238 status = psa_get_key_information( key, &key_type, &key_bits );
2239 if( status != PSA_SUCCESS )
2240 return( status );
2241 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002242 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002243 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002244
mohammad16035ed06212018-06-06 13:09:34 +03002245 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2246 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002247 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002248 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002249
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002250 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002251 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002252
Gilles Peskine2d277862018-06-18 15:41:12 +02002253 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2254 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002255 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002256
mohammad16035955c982018-04-26 00:53:03 +03002257 if( alg == PSA_ALG_GCM )
2258 {
2259 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002260 tag_length = 16;
2261
mohammad160396910d82018-06-04 14:33:00 +03002262 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2263 return( PSA_ERROR_INVALID_ARGUMENT );
2264
mohammad160315223a82018-06-03 17:19:55 +03002265 //make sure we have place to hold the tag in the ciphertext buffer
2266 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002267 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002268
2269 //update the tag pointer to point to the end of the ciphertext_length
2270 tag = ciphertext + plaintext_length;
2271
mohammad16035955c982018-04-26 00:53:03 +03002272 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002273 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002274 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002275 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002276 if( ret != 0 )
2277 {
2278 mbedtls_gcm_free( &gcm );
2279 return( mbedtls_to_psa_error( ret ) );
2280 }
2281 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002282 plaintext_length, nonce,
2283 nonce_length, additional_data,
2284 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002285 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002286 mbedtls_gcm_free( &gcm );
2287 }
2288 else if( alg == PSA_ALG_CCM )
2289 {
2290 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002291 tag_length = 16;
2292
mohammad160396910d82018-06-04 14:33:00 +03002293 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2294 return( PSA_ERROR_INVALID_ARGUMENT );
2295
mohammad160347ddf3d2018-04-26 01:11:21 +03002296 if( nonce_length < 7 || nonce_length > 13 )
2297 return( PSA_ERROR_INVALID_ARGUMENT );
2298
mohammad160315223a82018-06-03 17:19:55 +03002299 //make sure we have place to hold the tag in the ciphertext buffer
2300 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002301 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002302
2303 //update the tag pointer to point to the end of the ciphertext_length
2304 tag = ciphertext + plaintext_length;
2305
mohammad16035955c982018-04-26 00:53:03 +03002306 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002307 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002308 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002309 if( ret != 0 )
2310 {
2311 mbedtls_ccm_free( &ccm );
2312 return( mbedtls_to_psa_error( ret ) );
2313 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002314 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002315 nonce, nonce_length,
2316 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002317 additional_data_length,
2318 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002319 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002320 mbedtls_ccm_free( &ccm );
2321 }
mohammad16035c8845f2018-05-09 05:40:09 -07002322 else
2323 {
mohammad1603554faad2018-06-03 15:07:38 +03002324 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002325 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002326
mohammad160315223a82018-06-03 17:19:55 +03002327 if( ret != 0 )
2328 {
2329 memset( ciphertext, 0, ciphertext_size );
2330 return( mbedtls_to_psa_error( ret ) );
2331 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002332
mohammad160315223a82018-06-03 17:19:55 +03002333 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002334 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002335}
2336
Gilles Peskineee652a32018-06-01 19:23:52 +02002337/* Locate the tag in a ciphertext buffer containing the encrypted data
2338 * followed by the tag. Return the length of the part preceding the tag in
2339 * *plaintext_length. This is the size of the plaintext in modes where
2340 * the encrypted data has the same size as the plaintext, such as
2341 * CCM and GCM. */
2342static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2343 const uint8_t *ciphertext,
2344 size_t ciphertext_length,
2345 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002346 const uint8_t **p_tag )
2347{
2348 size_t payload_length;
2349 if( tag_length > ciphertext_length )
2350 return( PSA_ERROR_INVALID_ARGUMENT );
2351 payload_length = ciphertext_length - tag_length;
2352 if( payload_length > plaintext_size )
2353 return( PSA_ERROR_BUFFER_TOO_SMALL );
2354 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002355 return( PSA_SUCCESS );
2356}
2357
mohammad16035955c982018-04-26 00:53:03 +03002358psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2359 psa_algorithm_t alg,
2360 const uint8_t *nonce,
2361 size_t nonce_length,
2362 const uint8_t *additional_data,
2363 size_t additional_data_length,
2364 const uint8_t *ciphertext,
2365 size_t ciphertext_length,
2366 uint8_t *plaintext,
2367 size_t plaintext_size,
2368 size_t *plaintext_length )
2369{
2370 int ret;
2371 psa_status_t status;
2372 key_slot_t *slot;
2373 psa_key_type_t key_type;
2374 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002375 const uint8_t *tag;
2376 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002377 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002378 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002379
Gilles Peskineee652a32018-06-01 19:23:52 +02002380 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002381
mohammad16035955c982018-04-26 00:53:03 +03002382 status = psa_get_key_information( key, &key_type, &key_bits );
2383 if( status != PSA_SUCCESS )
2384 return( status );
2385 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002386 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002387 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002388
mohammad16035ed06212018-06-06 13:09:34 +03002389 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2390 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002391 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002392 return( PSA_ERROR_NOT_SUPPORTED );
2393
mohammad1603f14394b2018-06-04 14:33:19 +03002394 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2395 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002396
Gilles Peskine2d277862018-06-18 15:41:12 +02002397 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2398 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002399 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002400
mohammad16035955c982018-04-26 00:53:03 +03002401 if( alg == PSA_ALG_GCM )
2402 {
2403 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002404
Gilles Peskineee652a32018-06-01 19:23:52 +02002405 tag_length = 16;
2406 status = psa_aead_unpadded_locate_tag( tag_length,
2407 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002408 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002409 if( status != PSA_SUCCESS )
2410 return( status );
2411
mohammad16035955c982018-04-26 00:53:03 +03002412 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002413 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002414 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002415 if( ret != 0 )
2416 {
2417 mbedtls_gcm_free( &gcm );
2418 return( mbedtls_to_psa_error( ret ) );
2419 }
mohammad16035955c982018-04-26 00:53:03 +03002420
Gilles Peskineee652a32018-06-01 19:23:52 +02002421 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002422 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002423 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002424 additional_data,
2425 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002426 tag, tag_length,
2427 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002428 mbedtls_gcm_free( &gcm );
2429 }
2430 else if( alg == PSA_ALG_CCM )
2431 {
2432 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002433
mohammad160347ddf3d2018-04-26 01:11:21 +03002434 if( nonce_length < 7 || nonce_length > 13 )
2435 return( PSA_ERROR_INVALID_ARGUMENT );
2436
mohammad16039375f842018-06-03 14:28:24 +03002437 tag_length = 16;
2438 status = psa_aead_unpadded_locate_tag( tag_length,
2439 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002440 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002441 if( status != PSA_SUCCESS )
2442 return( status );
2443
mohammad16035955c982018-04-26 00:53:03 +03002444 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002445 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002446 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002447 if( ret != 0 )
2448 {
2449 mbedtls_ccm_free( &ccm );
2450 return( mbedtls_to_psa_error( ret ) );
2451 }
mohammad160360a64d02018-06-03 17:20:42 +03002452 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002453 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002454 additional_data,
2455 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002456 ciphertext, plaintext,
2457 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002458 mbedtls_ccm_free( &ccm );
2459 }
mohammad160339574652018-06-01 04:39:53 -07002460 else
2461 {
mohammad1603554faad2018-06-03 15:07:38 +03002462 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002463 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002464
Gilles Peskineee652a32018-06-01 19:23:52 +02002465 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002466 memset( plaintext, 0, plaintext_size );
2467 else
2468 *plaintext_length = ciphertext_length - tag_length;
2469
Gilles Peskineee652a32018-06-01 19:23:52 +02002470 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002471}
2472
Gilles Peskinea0655c32018-04-30 17:06:50 +02002473
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002474
Gilles Peskine20035e32018-02-03 22:44:14 +01002475/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002476/* Key generation */
2477/****************************************************************/
2478
2479psa_status_t psa_generate_random( uint8_t *output,
2480 size_t output_size )
2481{
2482 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2483 output, output_size );
2484 return( mbedtls_to_psa_error( ret ) );
2485}
2486
2487psa_status_t psa_generate_key( psa_key_slot_t key,
2488 psa_key_type_t type,
2489 size_t bits,
2490 const void *parameters,
2491 size_t parameters_size )
2492{
2493 return( PSA_ERROR_NOT_SUPPORTED );
2494}
2495
2496
2497/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002498/* Module setup */
2499/****************************************************************/
2500
Gilles Peskinee59236f2018-01-27 23:32:46 +01002501void mbedtls_psa_crypto_free( void )
2502{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002503 size_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02002504 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002505 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002506 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2507 mbedtls_entropy_free( &global_data.entropy );
2508 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2509}
2510
2511psa_status_t psa_crypto_init( void )
2512{
2513 int ret;
2514 const unsigned char drbg_seed[] = "PSA";
2515
2516 if( global_data.initialized != 0 )
2517 return( PSA_SUCCESS );
2518
2519 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2520 mbedtls_entropy_init( &global_data.entropy );
2521 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2522
2523 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2524 mbedtls_entropy_func,
2525 &global_data.entropy,
2526 drbg_seed, sizeof( drbg_seed ) - 1 );
2527 if( ret != 0 )
2528 goto exit;
2529
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002530 global_data.initialized = 1;
2531
Gilles Peskinee59236f2018-01-27 23:32:46 +01002532exit:
2533 if( ret != 0 )
2534 mbedtls_psa_crypto_free( );
2535 return( mbedtls_to_psa_error( ret ) );
2536}
2537
2538#endif /* MBEDTLS_PSA_CRYPTO_C */