blob: 603a5101c08ad6d4b275dfb76de4f83424c9f68c [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. */
95#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
96
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 Peskine2f9c4dc2018-01-28 13:16:24 +0100123 key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100124} psa_global_data_t;
125
126static psa_global_data_t global_data;
127
128static psa_status_t mbedtls_to_psa_error( int ret )
129{
Gilles Peskinea5905292018-02-07 20:59:33 +0100130 /* If there's both a high-level code and low-level code, dispatch on
131 * the high-level code. */
132 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100133 {
134 case 0:
135 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100136
137 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
138 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
139 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
140 return( PSA_ERROR_NOT_SUPPORTED );
141 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
142 return( PSA_ERROR_HARDWARE_FAILURE );
143
144 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
145 return( PSA_ERROR_HARDWARE_FAILURE );
146
147 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
148 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
149 return( PSA_ERROR_NOT_SUPPORTED );
150 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
151 return( PSA_ERROR_HARDWARE_FAILURE );
152
153 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
154 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
155 return( PSA_ERROR_NOT_SUPPORTED );
156 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
157 return( PSA_ERROR_HARDWARE_FAILURE );
158
159 case MBEDTLS_ERR_CCM_BAD_INPUT:
160 return( PSA_ERROR_INVALID_ARGUMENT );
161 case MBEDTLS_ERR_CCM_AUTH_FAILED:
162 return( PSA_ERROR_INVALID_SIGNATURE );
163 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
164 return( PSA_ERROR_HARDWARE_FAILURE );
165
166 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
167 return( PSA_ERROR_NOT_SUPPORTED );
168 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
169 return( PSA_ERROR_INVALID_ARGUMENT );
170 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
171 return( PSA_ERROR_INSUFFICIENT_MEMORY );
172 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
173 return( PSA_ERROR_INVALID_PADDING );
174 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
175 return( PSA_ERROR_BAD_STATE );
176 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
177 return( PSA_ERROR_INVALID_SIGNATURE );
178 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
179 return( PSA_ERROR_TAMPERING_DETECTED );
180 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
181 return( PSA_ERROR_HARDWARE_FAILURE );
182
183 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
186 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
187 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
188 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
189 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
190 return( PSA_ERROR_NOT_SUPPORTED );
191 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
192 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
193
194 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
195 return( PSA_ERROR_NOT_SUPPORTED );
196 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
197 return( PSA_ERROR_HARDWARE_FAILURE );
198
Gilles Peskinee59236f2018-01-27 23:32:46 +0100199 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
200 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
201 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
202 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100203
204 case MBEDTLS_ERR_GCM_AUTH_FAILED:
205 return( PSA_ERROR_INVALID_SIGNATURE );
206 case MBEDTLS_ERR_GCM_BAD_INPUT:
207 return( PSA_ERROR_NOT_SUPPORTED );
208 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
209 return( PSA_ERROR_HARDWARE_FAILURE );
210
211 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
212 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
213 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
214 return( PSA_ERROR_HARDWARE_FAILURE );
215
216 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
217 return( PSA_ERROR_NOT_SUPPORTED );
218 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
219 return( PSA_ERROR_INVALID_ARGUMENT );
220 case MBEDTLS_ERR_MD_ALLOC_FAILED:
221 return( PSA_ERROR_INSUFFICIENT_MEMORY );
222 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
223 return( PSA_ERROR_STORAGE_FAILURE );
224 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
225 return( PSA_ERROR_HARDWARE_FAILURE );
226
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100227 case MBEDTLS_ERR_PK_ALLOC_FAILED:
228 return( PSA_ERROR_INSUFFICIENT_MEMORY );
229 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
230 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
231 return( PSA_ERROR_INVALID_ARGUMENT );
232 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100233 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100234 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
235 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
236 return( PSA_ERROR_INVALID_ARGUMENT );
237 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
238 return( PSA_ERROR_NOT_SUPPORTED );
239 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
240 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
241 return( PSA_ERROR_NOT_PERMITTED );
242 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
243 return( PSA_ERROR_INVALID_ARGUMENT );
244 case MBEDTLS_ERR_PK_INVALID_ALG:
245 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
246 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
247 return( PSA_ERROR_NOT_SUPPORTED );
248 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
249 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100250 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
251 return( PSA_ERROR_HARDWARE_FAILURE );
252
253 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
254 return( PSA_ERROR_HARDWARE_FAILURE );
255
256 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
257 return( PSA_ERROR_INVALID_ARGUMENT );
258 case MBEDTLS_ERR_RSA_INVALID_PADDING:
259 return( PSA_ERROR_INVALID_PADDING );
260 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
261 return( PSA_ERROR_HARDWARE_FAILURE );
262 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
263 return( PSA_ERROR_INVALID_ARGUMENT );
264 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
265 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
266 return( PSA_ERROR_TAMPERING_DETECTED );
267 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
268 return( PSA_ERROR_INVALID_SIGNATURE );
269 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
270 return( PSA_ERROR_BUFFER_TOO_SMALL );
271 case MBEDTLS_ERR_RSA_RNG_FAILED:
272 return( PSA_ERROR_INSUFFICIENT_MEMORY );
273 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
274 return( PSA_ERROR_NOT_SUPPORTED );
275 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
276 return( PSA_ERROR_HARDWARE_FAILURE );
277
278 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
279 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
280 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
281 return( PSA_ERROR_HARDWARE_FAILURE );
282
283 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
284 return( PSA_ERROR_INVALID_ARGUMENT );
285 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
286 return( PSA_ERROR_HARDWARE_FAILURE );
287
itayzafrir5c753392018-05-08 11:18:38 +0300288 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300289 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300290 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300291 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
292 return( PSA_ERROR_BUFFER_TOO_SMALL );
293 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
294 return( PSA_ERROR_NOT_SUPPORTED );
295 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
296 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
297 return( PSA_ERROR_INVALID_SIGNATURE );
298 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
299 return( PSA_ERROR_INSUFFICIENT_MEMORY );
300 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
301 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300302
Gilles Peskinee59236f2018-01-27 23:32:46 +0100303 default:
304 return( PSA_ERROR_UNKNOWN_ERROR );
305 }
306}
307
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200308
309
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100310/****************************************************************/
311/* Key management */
312/****************************************************************/
313
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200314static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
315{
316 switch( grpid )
317 {
318 case MBEDTLS_ECP_DP_SECP192R1:
319 return( PSA_ECC_CURVE_SECP192R1 );
320 case MBEDTLS_ECP_DP_SECP224R1:
321 return( PSA_ECC_CURVE_SECP224R1 );
322 case MBEDTLS_ECP_DP_SECP256R1:
323 return( PSA_ECC_CURVE_SECP256R1 );
324 case MBEDTLS_ECP_DP_SECP384R1:
325 return( PSA_ECC_CURVE_SECP384R1 );
326 case MBEDTLS_ECP_DP_SECP521R1:
327 return( PSA_ECC_CURVE_SECP521R1 );
328 case MBEDTLS_ECP_DP_BP256R1:
329 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
330 case MBEDTLS_ECP_DP_BP384R1:
331 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
332 case MBEDTLS_ECP_DP_BP512R1:
333 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
334 case MBEDTLS_ECP_DP_CURVE25519:
335 return( PSA_ECC_CURVE_CURVE25519 );
336 case MBEDTLS_ECP_DP_SECP192K1:
337 return( PSA_ECC_CURVE_SECP192K1 );
338 case MBEDTLS_ECP_DP_SECP224K1:
339 return( PSA_ECC_CURVE_SECP224K1 );
340 case MBEDTLS_ECP_DP_SECP256K1:
341 return( PSA_ECC_CURVE_SECP256K1 );
342 case MBEDTLS_ECP_DP_CURVE448:
343 return( PSA_ECC_CURVE_CURVE448 );
344 default:
345 return( 0 );
346 }
347}
348
Gilles Peskine2d277862018-06-18 15:41:12 +0200349psa_status_t psa_import_key( psa_key_slot_t key,
350 psa_key_type_t type,
351 const uint8_t *data,
352 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100353{
354 key_slot_t *slot;
355
356 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
357 return( PSA_ERROR_INVALID_ARGUMENT );
358 slot = &global_data.key_slots[key];
359 if( slot->type != PSA_KEY_TYPE_NONE )
360 return( PSA_ERROR_OCCUPIED_SLOT );
361
Gilles Peskine8c9def32018-02-08 10:02:12 +0100362 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100363 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100364 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100365 if( data_length > SIZE_MAX / 8 )
366 return( PSA_ERROR_NOT_SUPPORTED );
367 slot->data.raw.data = mbedtls_calloc( 1, data_length );
368 if( slot->data.raw.data == NULL )
369 return( PSA_ERROR_INSUFFICIENT_MEMORY );
370 memcpy( slot->data.raw.data, data, data_length );
371 slot->data.raw.bytes = data_length;
372 }
373 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100374#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100375 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
376 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
377 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100378 {
379 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100380 mbedtls_pk_context pk;
381 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100382 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
383 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
384 else
385 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100386 if( ret != 0 )
387 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100388 switch( mbedtls_pk_get_type( &pk ) )
389 {
390#if defined(MBEDTLS_RSA_C)
391 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100392 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
393 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200394 slot->data.rsa = mbedtls_pk_rsa( pk );
Gilles Peskine969ac722018-01-28 18:16:59 +0100395 else
396 return( PSA_ERROR_INVALID_ARGUMENT );
397 break;
398#endif /* MBEDTLS_RSA_C */
399#if defined(MBEDTLS_ECP_C)
400 case MBEDTLS_PK_ECKEY:
401 if( PSA_KEY_TYPE_IS_ECC( type ) )
402 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200403 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
404 psa_ecc_curve_t actual_curve =
405 mbedtls_ecc_group_to_psa( ecp->grp.id );
406 psa_ecc_curve_t expected_curve =
407 PSA_KEY_TYPE_GET_CURVE( type );
408 if( actual_curve != expected_curve )
409 return( PSA_ERROR_INVALID_ARGUMENT );
410 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100411 }
412 else
413 return( PSA_ERROR_INVALID_ARGUMENT );
414 break;
415#endif /* MBEDTLS_ECP_C */
416 default:
417 return( PSA_ERROR_INVALID_ARGUMENT );
418 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100419 }
420 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100421#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100422 {
423 return( PSA_ERROR_NOT_SUPPORTED );
424 }
425
426 slot->type = type;
427 return( PSA_SUCCESS );
428}
429
Gilles Peskine2d277862018-06-18 15:41:12 +0200430psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100431{
432 key_slot_t *slot;
433
434 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
435 return( PSA_ERROR_INVALID_ARGUMENT );
436 slot = &global_data.key_slots[key];
437 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200438 {
439 /* No key material to clean, but do zeroize the slot below to wipe
440 * metadata such as policies. */
441 }
442 else if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100443 {
444 mbedtls_free( slot->data.raw.data );
445 }
446 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100447#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100448 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
449 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100450 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100451 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100452 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100453 }
454 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100455#endif /* defined(MBEDTLS_RSA_C) */
456#if defined(MBEDTLS_ECP_C)
457 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
458 {
459 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100460 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100461 }
462 else
463#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100464 {
465 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100466 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100467 return( PSA_ERROR_TAMPERING_DETECTED );
468 }
469
470 mbedtls_zeroize( slot, sizeof( *slot ) );
471 return( PSA_SUCCESS );
472}
473
Gilles Peskine2d277862018-06-18 15:41:12 +0200474psa_status_t psa_get_key_information( psa_key_slot_t key,
475 psa_key_type_t *type,
476 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100477{
478 key_slot_t *slot;
479
480 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100481 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100482 slot = &global_data.key_slots[key];
483 if( type != NULL )
484 *type = slot->type;
485 if( bits != NULL )
486 *bits = 0;
487 if( slot->type == PSA_KEY_TYPE_NONE )
488 return( PSA_ERROR_EMPTY_SLOT );
489
Gilles Peskine8c9def32018-02-08 10:02:12 +0100490 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100491 {
492 if( bits != NULL )
493 *bits = slot->data.raw.bytes * 8;
494 }
495 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100496#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100497 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
498 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100499 {
500 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100501 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100502 }
503 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100504#endif /* defined(MBEDTLS_RSA_C) */
505#if defined(MBEDTLS_ECP_C)
506 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
507 {
508 if( bits != NULL )
509 *bits = slot->data.ecp->grp.pbits;
510 }
511 else
512#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100513 {
514 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100515 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100516 return( PSA_ERROR_TAMPERING_DETECTED );
517 }
518
519 return( PSA_SUCCESS );
520}
521
Gilles Peskine2d277862018-06-18 15:41:12 +0200522static psa_status_t psa_internal_export_key( psa_key_slot_t key,
523 uint8_t *data,
524 size_t data_size,
525 size_t *data_length,
526 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100527{
528 key_slot_t *slot;
529
530 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100531 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100532 slot = &global_data.key_slots[key];
533 if( slot->type == PSA_KEY_TYPE_NONE )
534 return( PSA_ERROR_EMPTY_SLOT );
535
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200536 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300537 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300538
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200539 if( ! export_public_key &&
540 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
541 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300542 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200543
Gilles Peskine8c9def32018-02-08 10:02:12 +0100544 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100545 {
546 if( slot->data.raw.bytes > data_size )
547 return( PSA_ERROR_BUFFER_TOO_SMALL );
548 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
549 *data_length = slot->data.raw.bytes;
550 return( PSA_SUCCESS );
551 }
552 else
Moran Peker17e36e12018-05-02 12:55:20 +0300553 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100554#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100555 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300556 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
557 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100558 {
Moran Pekera998bc62018-04-16 18:16:20 +0300559 mbedtls_pk_context pk;
560 int ret;
561 mbedtls_pk_init( &pk );
562 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
563 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
564 {
565 pk.pk_info = &mbedtls_rsa_info;
566 pk.pk_ctx = slot->data.rsa;
567 }
568 else
569 {
570 pk.pk_info = &mbedtls_eckey_info;
571 pk.pk_ctx = slot->data.ecp;
572 }
Moran Pekerd7326592018-05-29 16:56:39 +0300573 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300574 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300575 else
576 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300577 if( ret < 0 )
Moran Pekera998bc62018-04-16 18:16:20 +0300578 return( mbedtls_to_psa_error( ret ) );
579 *data_length = ret;
580 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100581 }
582 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100583#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300584 {
585 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200586 it is valid for a special-purpose implementation to omit
587 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300588 return( PSA_ERROR_NOT_SUPPORTED );
589 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100590 }
591}
592
Gilles Peskine2d277862018-06-18 15:41:12 +0200593psa_status_t psa_export_key( psa_key_slot_t key,
594 uint8_t *data,
595 size_t data_size,
596 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300597{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200598 return( psa_internal_export_key( key, data, data_size,
599 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100600}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100601
Gilles Peskine2d277862018-06-18 15:41:12 +0200602psa_status_t psa_export_public_key( psa_key_slot_t key,
603 uint8_t *data,
604 size_t data_size,
605 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300606{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200607 return( psa_internal_export_key( key, data, data_size,
608 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300609}
610
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200611
612
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100613/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100614/* Message digests */
615/****************************************************************/
616
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100617static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100618{
619 switch( alg )
620 {
621#if defined(MBEDTLS_MD2_C)
622 case PSA_ALG_MD2:
623 return( &mbedtls_md2_info );
624#endif
625#if defined(MBEDTLS_MD4_C)
626 case PSA_ALG_MD4:
627 return( &mbedtls_md4_info );
628#endif
629#if defined(MBEDTLS_MD5_C)
630 case PSA_ALG_MD5:
631 return( &mbedtls_md5_info );
632#endif
633#if defined(MBEDTLS_RIPEMD160_C)
634 case PSA_ALG_RIPEMD160:
635 return( &mbedtls_ripemd160_info );
636#endif
637#if defined(MBEDTLS_SHA1_C)
638 case PSA_ALG_SHA_1:
639 return( &mbedtls_sha1_info );
640#endif
641#if defined(MBEDTLS_SHA256_C)
642 case PSA_ALG_SHA_224:
643 return( &mbedtls_sha224_info );
644 case PSA_ALG_SHA_256:
645 return( &mbedtls_sha256_info );
646#endif
647#if defined(MBEDTLS_SHA512_C)
648 case PSA_ALG_SHA_384:
649 return( &mbedtls_sha384_info );
650 case PSA_ALG_SHA_512:
651 return( &mbedtls_sha512_info );
652#endif
653 default:
654 return( NULL );
655 }
656}
657
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100658psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
659{
660 switch( operation->alg )
661 {
662#if defined(MBEDTLS_MD2_C)
663 case PSA_ALG_MD2:
664 mbedtls_md2_free( &operation->ctx.md2 );
665 break;
666#endif
667#if defined(MBEDTLS_MD4_C)
668 case PSA_ALG_MD4:
669 mbedtls_md4_free( &operation->ctx.md4 );
670 break;
671#endif
672#if defined(MBEDTLS_MD5_C)
673 case PSA_ALG_MD5:
674 mbedtls_md5_free( &operation->ctx.md5 );
675 break;
676#endif
677#if defined(MBEDTLS_RIPEMD160_C)
678 case PSA_ALG_RIPEMD160:
679 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
680 break;
681#endif
682#if defined(MBEDTLS_SHA1_C)
683 case PSA_ALG_SHA_1:
684 mbedtls_sha1_free( &operation->ctx.sha1 );
685 break;
686#endif
687#if defined(MBEDTLS_SHA256_C)
688 case PSA_ALG_SHA_224:
689 case PSA_ALG_SHA_256:
690 mbedtls_sha256_free( &operation->ctx.sha256 );
691 break;
692#endif
693#if defined(MBEDTLS_SHA512_C)
694 case PSA_ALG_SHA_384:
695 case PSA_ALG_SHA_512:
696 mbedtls_sha512_free( &operation->ctx.sha512 );
697 break;
698#endif
699 default:
700 return( PSA_ERROR_NOT_SUPPORTED );
701 }
702 operation->alg = 0;
703 return( PSA_SUCCESS );
704}
705
706psa_status_t psa_hash_start( psa_hash_operation_t *operation,
707 psa_algorithm_t alg )
708{
709 int ret;
710 operation->alg = 0;
711 switch( alg )
712 {
713#if defined(MBEDTLS_MD2_C)
714 case PSA_ALG_MD2:
715 mbedtls_md2_init( &operation->ctx.md2 );
716 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
717 break;
718#endif
719#if defined(MBEDTLS_MD4_C)
720 case PSA_ALG_MD4:
721 mbedtls_md4_init( &operation->ctx.md4 );
722 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
723 break;
724#endif
725#if defined(MBEDTLS_MD5_C)
726 case PSA_ALG_MD5:
727 mbedtls_md5_init( &operation->ctx.md5 );
728 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
729 break;
730#endif
731#if defined(MBEDTLS_RIPEMD160_C)
732 case PSA_ALG_RIPEMD160:
733 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
734 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
735 break;
736#endif
737#if defined(MBEDTLS_SHA1_C)
738 case PSA_ALG_SHA_1:
739 mbedtls_sha1_init( &operation->ctx.sha1 );
740 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
741 break;
742#endif
743#if defined(MBEDTLS_SHA256_C)
744 case PSA_ALG_SHA_224:
745 mbedtls_sha256_init( &operation->ctx.sha256 );
746 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
747 break;
748 case PSA_ALG_SHA_256:
749 mbedtls_sha256_init( &operation->ctx.sha256 );
750 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
751 break;
752#endif
753#if defined(MBEDTLS_SHA512_C)
754 case PSA_ALG_SHA_384:
755 mbedtls_sha512_init( &operation->ctx.sha512 );
756 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
757 break;
758 case PSA_ALG_SHA_512:
759 mbedtls_sha512_init( &operation->ctx.sha512 );
760 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
761 break;
762#endif
763 default:
764 return( PSA_ERROR_NOT_SUPPORTED );
765 }
766 if( ret == 0 )
767 operation->alg = alg;
768 else
769 psa_hash_abort( operation );
770 return( mbedtls_to_psa_error( ret ) );
771}
772
773psa_status_t psa_hash_update( psa_hash_operation_t *operation,
774 const uint8_t *input,
775 size_t input_length )
776{
777 int ret;
778 switch( operation->alg )
779 {
780#if defined(MBEDTLS_MD2_C)
781 case PSA_ALG_MD2:
782 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
783 input, input_length );
784 break;
785#endif
786#if defined(MBEDTLS_MD4_C)
787 case PSA_ALG_MD4:
788 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
789 input, input_length );
790 break;
791#endif
792#if defined(MBEDTLS_MD5_C)
793 case PSA_ALG_MD5:
794 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
795 input, input_length );
796 break;
797#endif
798#if defined(MBEDTLS_RIPEMD160_C)
799 case PSA_ALG_RIPEMD160:
800 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
801 input, input_length );
802 break;
803#endif
804#if defined(MBEDTLS_SHA1_C)
805 case PSA_ALG_SHA_1:
806 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
807 input, input_length );
808 break;
809#endif
810#if defined(MBEDTLS_SHA256_C)
811 case PSA_ALG_SHA_224:
812 case PSA_ALG_SHA_256:
813 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
814 input, input_length );
815 break;
816#endif
817#if defined(MBEDTLS_SHA512_C)
818 case PSA_ALG_SHA_384:
819 case PSA_ALG_SHA_512:
820 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
821 input, input_length );
822 break;
823#endif
824 default:
825 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
826 break;
827 }
828 if( ret != 0 )
829 psa_hash_abort( operation );
830 return( mbedtls_to_psa_error( ret ) );
831}
832
833psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
834 uint8_t *hash,
835 size_t hash_size,
836 size_t *hash_length )
837{
838 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200839 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100840
841 /* Fill the output buffer with something that isn't a valid hash
842 * (barring an attack on the hash and deliberately-crafted input),
843 * in case the caller doesn't check the return status properly. */
844 *hash_length = actual_hash_length;
845 memset( hash, '!', hash_size );
846
847 if( hash_size < actual_hash_length )
848 return( PSA_ERROR_BUFFER_TOO_SMALL );
849
850 switch( operation->alg )
851 {
852#if defined(MBEDTLS_MD2_C)
853 case PSA_ALG_MD2:
854 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
855 break;
856#endif
857#if defined(MBEDTLS_MD4_C)
858 case PSA_ALG_MD4:
859 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
860 break;
861#endif
862#if defined(MBEDTLS_MD5_C)
863 case PSA_ALG_MD5:
864 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
865 break;
866#endif
867#if defined(MBEDTLS_RIPEMD160_C)
868 case PSA_ALG_RIPEMD160:
869 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
870 break;
871#endif
872#if defined(MBEDTLS_SHA1_C)
873 case PSA_ALG_SHA_1:
874 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
875 break;
876#endif
877#if defined(MBEDTLS_SHA256_C)
878 case PSA_ALG_SHA_224:
879 case PSA_ALG_SHA_256:
880 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
881 break;
882#endif
883#if defined(MBEDTLS_SHA512_C)
884 case PSA_ALG_SHA_384:
885 case PSA_ALG_SHA_512:
886 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
887 break;
888#endif
889 default:
890 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
891 break;
892 }
893
894 if( ret == 0 )
895 {
896 return( psa_hash_abort( operation ) );
897 }
898 else
899 {
900 psa_hash_abort( operation );
901 return( mbedtls_to_psa_error( ret ) );
902 }
903}
904
Gilles Peskine2d277862018-06-18 15:41:12 +0200905psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
906 const uint8_t *hash,
907 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100908{
909 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
910 size_t actual_hash_length;
911 psa_status_t status = psa_hash_finish( operation,
912 actual_hash, sizeof( actual_hash ),
913 &actual_hash_length );
914 if( status != PSA_SUCCESS )
915 return( status );
916 if( actual_hash_length != hash_length )
917 return( PSA_ERROR_INVALID_SIGNATURE );
918 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
919 return( PSA_ERROR_INVALID_SIGNATURE );
920 return( PSA_SUCCESS );
921}
922
923
924
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100925/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +0100926/* MAC */
927/****************************************************************/
928
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100929static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +0100930 psa_algorithm_t alg,
931 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +0200932 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +0300933 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100934{
Gilles Peskine8c9def32018-02-08 10:02:12 +0100935 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +0300936 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100937
938 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
939 {
940 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +0200941 {
942 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
943 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +0200944
Nir Sonnenscheine9664c32018-06-17 14:41:30 +0300945 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100946 {
947 case PSA_ALG_STREAM_CIPHER:
948 mode = MBEDTLS_MODE_STREAM;
949 break;
950 case PSA_ALG_CBC_BASE:
951 mode = MBEDTLS_MODE_CBC;
952 break;
953 case PSA_ALG_CFB_BASE:
954 mode = MBEDTLS_MODE_CFB;
955 break;
956 case PSA_ALG_OFB_BASE:
957 mode = MBEDTLS_MODE_OFB;
958 break;
959 case PSA_ALG_CTR:
960 mode = MBEDTLS_MODE_CTR;
961 break;
962 case PSA_ALG_CCM:
963 mode = MBEDTLS_MODE_CCM;
964 break;
965 case PSA_ALG_GCM:
966 mode = MBEDTLS_MODE_GCM;
967 break;
968 default:
969 return( NULL );
970 }
971 }
972 else if( alg == PSA_ALG_CMAC )
973 mode = MBEDTLS_MODE_ECB;
974 else if( alg == PSA_ALG_GMAC )
975 mode = MBEDTLS_MODE_GCM;
976 else
977 return( NULL );
978
979 switch( key_type )
980 {
981 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +0300982 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100983 break;
984 case PSA_KEY_TYPE_DES:
985 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +0300986 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100987 else
mohammad1603f4f0d612018-06-03 15:04:51 +0300988 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100989 break;
990 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +0300991 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100992 break;
993 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +0300994 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100995 break;
996 default:
997 return( NULL );
998 }
mohammad1603f4f0d612018-06-03 15:04:51 +0300999 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001000 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001001
mohammad1603f4f0d612018-06-03 15:04:51 +03001002 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001003}
1004
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001005static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001006{
Gilles Peskine2d277862018-06-18 15:41:12 +02001007 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001008 {
1009 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001010 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001011 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001012 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001013 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001014 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001015 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001016 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001017 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001018 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001019 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001020 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001021 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001022 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001023 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001024 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001025 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001026 return( 128 );
1027 default:
1028 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001029 }
1030}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001031
Gilles Peskine8c9def32018-02-08 10:02:12 +01001032psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1033{
1034 switch( operation->alg )
1035 {
1036#if defined(MBEDTLS_CMAC_C)
1037 case PSA_ALG_CMAC:
1038 mbedtls_cipher_free( &operation->ctx.cmac );
1039 break;
1040#endif /* MBEDTLS_CMAC_C */
1041 default:
1042#if defined(MBEDTLS_MD_C)
1043 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001044 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001045 unsigned int block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001046 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001047
Gilles Peskine99bc6492018-06-11 17:13:00 +02001048 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001049 return( PSA_ERROR_NOT_SUPPORTED );
1050
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001051 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001052 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001053 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001054 else
1055#endif /* MBEDTLS_MD_C */
1056 return( PSA_ERROR_NOT_SUPPORTED );
1057 }
Moran Peker41deec42018-04-04 15:43:05 +03001058
Gilles Peskine8c9def32018-02-08 10:02:12 +01001059 operation->alg = 0;
1060 operation->key_set = 0;
1061 operation->iv_set = 0;
1062 operation->iv_required = 0;
1063 operation->has_input = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001064
Gilles Peskine8c9def32018-02-08 10:02:12 +01001065 return( PSA_SUCCESS );
1066}
1067
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001068static int psa_cmac_start( psa_mac_operation_t *operation,
1069 size_t key_bits,
1070 key_slot_t *slot,
1071 const mbedtls_cipher_info_t *cipher_info )
1072{
1073 int ret;
1074
1075 operation->mac_size = cipher_info->block_size;
1076 operation->iv_required = 0;
1077 mbedtls_cipher_init( &operation->ctx.cmac );
1078
1079 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1080 if( ret != 0 )
1081 return( ret );
1082
1083 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1084 slot->data.raw.data,
1085 key_bits );
1086 return( ret );
1087}
1088
1089static int psa_hmac_start( psa_mac_operation_t *operation,
1090 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001091 key_slot_t *slot,
1092 psa_algorithm_t alg )
1093{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001094 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001095 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001096 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001097 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001098 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001099 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001100 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001101 size_t key_length = slot->data.raw.bytes;
1102 psa_status_t status;
1103
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001104 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001105 return( PSA_ERROR_NOT_SUPPORTED );
1106
1107 if( key_type != PSA_KEY_TYPE_HMAC )
1108 return( PSA_ERROR_INVALID_ARGUMENT );
1109
1110 operation->iv_required = 0;
1111 operation->mac_size = digest_size;
1112
1113 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1114 PSA_ALG_HMAC_HASH( alg ) );
1115 if( status != PSA_SUCCESS )
1116 return( status );
1117
Gilles Peskined223b522018-06-11 18:12:58 +02001118 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001119 {
1120 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001121 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001122 if( status != PSA_SUCCESS )
1123 return( status );
1124 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001125 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001126 if( status != PSA_SUCCESS )
1127 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001128 }
Gilles Peskined223b522018-06-11 18:12:58 +02001129 else
1130 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001131
Gilles Peskined223b522018-06-11 18:12:58 +02001132 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1133 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001134 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001135 ipad[i] ^= 0x36;
1136 memset( ipad + key_length, 0x36, block_size - key_length );
1137
1138 /* Copy the key material from ipad to opad, flipping the requisite bits,
1139 * and filling the rest of opad with the requisite constant. */
1140 for( i = 0; i < key_length; i++ )
1141 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1142 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001143
1144 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1145 PSA_ALG_HMAC_HASH( alg ) );
1146 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001147 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001148
1149 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1150 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001151
1152cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001153 mbedtls_zeroize( ipad, key_length );
1154 /* opad is in the context. It needs to stay in memory if this function
1155 * succeeds, and it will be wiped by psa_mac_abort() called from
1156 * psa_mac_start in the error case. */
1157
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001158 return( status );
1159}
1160
Gilles Peskine8c9def32018-02-08 10:02:12 +01001161psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1162 psa_key_slot_t key,
1163 psa_algorithm_t alg )
1164{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001165 psa_status_t status;
1166 key_slot_t *slot;
1167 psa_key_type_t key_type;
1168 size_t key_bits;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001169 const mbedtls_cipher_info_t *cipher_info;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001170
1171 operation->alg = 0;
1172 operation->key_set = 0;
1173 operation->iv_set = 0;
1174 operation->iv_required = 1;
1175 operation->has_input = 0;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001176 operation->key_usage_sign = 0;
1177 operation->key_usage_verify = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001178
1179 status = psa_get_key_information( key, &key_type, &key_bits );
1180 if( status != PSA_SUCCESS )
1181 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001182
Gilles Peskine8c9def32018-02-08 10:02:12 +01001183 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001184 if( slot->type == PSA_KEY_TYPE_NONE )
1185 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001186
Moran Pekerd7326592018-05-29 16:56:39 +03001187 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001188 operation->key_usage_sign = 1;
1189
Moran Pekerd7326592018-05-29 16:56:39 +03001190 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001191 operation->key_usage_verify = 1;
1192
Gilles Peskine8c9def32018-02-08 10:02:12 +01001193 if( ! PSA_ALG_IS_HMAC( alg ) )
1194 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001195 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001196 if( cipher_info == NULL )
1197 return( PSA_ERROR_NOT_SUPPORTED );
1198 operation->mac_size = cipher_info->block_size;
1199 }
1200 switch( alg )
1201 {
1202#if defined(MBEDTLS_CMAC_C)
1203 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001204 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1205 key_bits,
1206 slot,
1207 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001208 break;
1209#endif /* MBEDTLS_CMAC_C */
1210 default:
1211#if defined(MBEDTLS_MD_C)
1212 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001213 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001214 else
1215#endif /* MBEDTLS_MD_C */
1216 return( PSA_ERROR_NOT_SUPPORTED );
1217 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001218
Gilles Peskine8c9def32018-02-08 10:02:12 +01001219 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001220
1221 * context may contain data that needs to be wiped on error. */
1222 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001223 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001224 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001225 }
Gilles Peskine99bc6492018-06-11 17:13:00 +02001226
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001227 else
1228 {
1229 operation->alg = alg;
1230 operation->key_set = 1;
1231 }
1232 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001233}
1234
1235psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1236 const uint8_t *input,
1237 size_t input_length )
1238{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001239 int ret = 0 ;
1240 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001241 if( ! operation->key_set )
1242 return( PSA_ERROR_BAD_STATE );
1243 if( operation->iv_required && ! operation->iv_set )
1244 return( PSA_ERROR_BAD_STATE );
1245 operation->has_input = 1;
1246
1247 switch( operation->alg )
1248 {
1249#if defined(MBEDTLS_CMAC_C)
1250 case PSA_ALG_CMAC:
1251 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1252 input, input_length );
1253 break;
1254#endif /* MBEDTLS_CMAC_C */
1255 default:
1256#if defined(MBEDTLS_MD_C)
1257 if( PSA_ALG_IS_HMAC( operation->alg ) )
1258 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001259 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001260 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001261 }
1262 else
1263#endif /* MBEDTLS_MD_C */
1264 {
1265 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1266 }
1267 break;
1268 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001269 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001270 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001271 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001272 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001273 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001274 }
1275
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001276 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001277}
1278
mohammad16036df908f2018-04-02 08:34:15 -07001279static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001280 uint8_t *mac,
1281 size_t mac_size,
1282 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001283{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001284 int ret = 0;
1285 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001286 if( ! operation->key_set )
1287 return( PSA_ERROR_BAD_STATE );
1288 if( operation->iv_required && ! operation->iv_set )
1289 return( PSA_ERROR_BAD_STATE );
1290
1291 /* Fill the output buffer with something that isn't a valid mac
1292 * (barring an attack on the mac and deliberately-crafted input),
1293 * in case the caller doesn't check the return status properly. */
1294 *mac_length = operation->mac_size;
1295 memset( mac, '!', mac_size );
1296
1297 if( mac_size < operation->mac_size )
1298 return( PSA_ERROR_BUFFER_TOO_SMALL );
1299
1300 switch( operation->alg )
1301 {
1302#if defined(MBEDTLS_CMAC_C)
1303 case PSA_ALG_CMAC:
1304 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1305 break;
1306#endif /* MBEDTLS_CMAC_C */
1307 default:
1308#if defined(MBEDTLS_MD_C)
1309 if( PSA_ALG_IS_HMAC( operation->alg ) )
1310 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001311 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001312 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001313 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001314 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001315 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001316
Gilles Peskine99bc6492018-06-11 17:13:00 +02001317 if( block_size == 0 )
1318 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001319
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001320 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001321 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001322 if( status != PSA_SUCCESS )
1323 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001324 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001325
1326 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1327 PSA_ALG_HMAC_HASH( operation->alg ) );
1328 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001329 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001330
1331 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001332 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001333 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001334 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001335
1336 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001337 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001338 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001339 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001340
1341 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1342 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001343 hmac_cleanup:
1344 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001345 }
1346 else
1347#endif /* MBEDTLS_MD_C */
1348 {
1349 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1350 }
1351 break;
1352 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001353cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001354
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001355 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001356 {
1357 return( psa_mac_abort( operation ) );
1358 }
1359 else
1360 {
1361 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001362 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001363 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001364
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001365 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001366 }
1367}
1368
mohammad16036df908f2018-04-02 08:34:15 -07001369psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1370 uint8_t *mac,
1371 size_t mac_size,
1372 size_t *mac_length )
1373{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001374 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001375 return( PSA_ERROR_NOT_PERMITTED );
1376
Gilles Peskine99bc6492018-06-11 17:13:00 +02001377 return( psa_mac_finish_internal( operation, mac,
1378 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001379}
1380
Gilles Peskine2d277862018-06-18 15:41:12 +02001381#define MBEDTLS_PSA_MAC_MAX_SIZE \
1382 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1383 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001384 MBEDTLS_MAX_BLOCK_LENGTH )
1385psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1386 const uint8_t *mac,
1387 size_t mac_length )
1388{
1389 uint8_t actual_mac[MBEDTLS_PSA_MAC_MAX_SIZE];
1390 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001391 psa_status_t status;
1392
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001393 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001394 return( PSA_ERROR_NOT_PERMITTED );
1395
1396 status = psa_mac_finish_internal( operation,
1397 actual_mac, sizeof( actual_mac ),
1398 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001399 if( status != PSA_SUCCESS )
1400 return( status );
1401 if( actual_mac_length != mac_length )
1402 return( PSA_ERROR_INVALID_SIGNATURE );
1403 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1404 return( PSA_ERROR_INVALID_SIGNATURE );
1405 return( PSA_SUCCESS );
1406}
1407
1408
Gilles Peskine20035e32018-02-03 22:44:14 +01001409
Gilles Peskine20035e32018-02-03 22:44:14 +01001410/****************************************************************/
1411/* Asymmetric cryptography */
1412/****************************************************************/
1413
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001414/* Decode the hash algorithm from alg and store the mbedtls encoding in
1415 * md_alg. Verify that the hash length is consistent. */
1416static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1417 size_t hash_length,
1418 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001419{
Gilles Peskine61b91d42018-06-08 16:09:36 +02001420 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
1421 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1422 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1423 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001424 {
1425#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001426 if( hash_length > UINT_MAX )
1427 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001428#endif
1429 }
1430 else
1431 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001432 if( mbedtls_md_get_size( md_info ) != hash_length )
1433 return( PSA_ERROR_INVALID_ARGUMENT );
1434 if( md_info == NULL )
1435 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001436 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001437 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001438}
1439
Gilles Peskine61b91d42018-06-08 16:09:36 +02001440psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1441 psa_algorithm_t alg,
1442 const uint8_t *hash,
1443 size_t hash_length,
1444 const uint8_t *salt,
1445 size_t salt_length,
1446 uint8_t *signature,
1447 size_t signature_size,
1448 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001449{
1450 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001451 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001452 *signature_length = 0;
1453 (void) salt;
1454 (void) salt_length;
1455
Gilles Peskine20035e32018-02-03 22:44:14 +01001456 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1457 return( PSA_ERROR_EMPTY_SLOT );
1458 slot = &global_data.key_slots[key];
1459 if( slot->type == PSA_KEY_TYPE_NONE )
1460 return( PSA_ERROR_EMPTY_SLOT );
1461 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1462 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001463 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001464 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001465
Gilles Peskine20035e32018-02-03 22:44:14 +01001466#if defined(MBEDTLS_RSA_C)
1467 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1468 {
1469 mbedtls_rsa_context *rsa = slot->data.rsa;
1470 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001471 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001472 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001473 if( status != PSA_SUCCESS )
1474 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001475
Gilles Peskine20035e32018-02-03 22:44:14 +01001476 if( signature_size < rsa->len )
1477 return( PSA_ERROR_BUFFER_TOO_SMALL );
1478#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001479 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001480 {
1481 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1482 MBEDTLS_MD_NONE );
1483 ret = mbedtls_rsa_pkcs1_sign( rsa,
1484 mbedtls_ctr_drbg_random,
1485 &global_data.ctr_drbg,
1486 MBEDTLS_RSA_PRIVATE,
1487 md_alg, hash_length, hash,
1488 signature );
1489 }
1490 else
1491#endif /* MBEDTLS_PKCS1_V15 */
1492#if defined(MBEDTLS_PKCS1_V21)
1493 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1494 {
1495 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1496 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1497 mbedtls_ctr_drbg_random,
1498 &global_data.ctr_drbg,
1499 MBEDTLS_RSA_PRIVATE,
1500 md_alg, hash_length, hash,
1501 signature );
1502 }
1503 else
1504#endif /* MBEDTLS_PKCS1_V21 */
1505 {
1506 return( PSA_ERROR_INVALID_ARGUMENT );
1507 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001508 if( ret == 0 )
1509 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001510 return( mbedtls_to_psa_error( ret ) );
1511 }
1512 else
1513#endif /* defined(MBEDTLS_RSA_C) */
1514#if defined(MBEDTLS_ECP_C)
1515 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1516 {
itayzafrir5c753392018-05-08 11:18:38 +03001517 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1518 int ret;
1519 const mbedtls_md_info_t *md_info;
1520 mbedtls_md_type_t md_alg;
1521 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1522 return( PSA_ERROR_BUFFER_TOO_SMALL );
1523 md_info = mbedtls_md_info_from_psa( alg );
1524 md_alg = mbedtls_md_get_type( md_info );
1525 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001526 signature, signature_length,
1527 mbedtls_ctr_drbg_random,
1528 &global_data.ctr_drbg );
itayzafrir5c753392018-05-08 11:18:38 +03001529 return( mbedtls_to_psa_error( ret ) );
1530 }
1531 else
1532#endif /* defined(MBEDTLS_ECP_C) */
1533 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001534 return( PSA_ERROR_NOT_SUPPORTED );
1535 }
itayzafrir5c753392018-05-08 11:18:38 +03001536}
1537
1538psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1539 psa_algorithm_t alg,
1540 const uint8_t *hash,
1541 size_t hash_length,
1542 const uint8_t *salt,
1543 size_t salt_length,
1544 uint8_t *signature,
1545 size_t signature_size )
1546{
1547 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001548 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001549 (void) salt;
1550 (void) salt_length;
1551
1552 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1553 return( PSA_ERROR_INVALID_ARGUMENT );
1554 slot = &global_data.key_slots[key];
1555 if( slot->type == PSA_KEY_TYPE_NONE )
1556 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001557 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001558 return( PSA_ERROR_NOT_PERMITTED );
1559
Gilles Peskine61b91d42018-06-08 16:09:36 +02001560#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001561 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1562 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001563 {
1564 mbedtls_rsa_context *rsa = slot->data.rsa;
1565 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001566 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001567 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001568 if( status != PSA_SUCCESS )
1569 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001570
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001571 if( signature_size < rsa->len )
1572 return( PSA_ERROR_BUFFER_TOO_SMALL );
1573#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001574 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001575 {
1576 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1577 MBEDTLS_MD_NONE );
1578
1579 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001580 mbedtls_ctr_drbg_random,
1581 &global_data.ctr_drbg,
1582 MBEDTLS_RSA_PUBLIC,
1583 md_alg,
1584 hash_length,
1585 hash,
1586 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001587
1588 }
1589 else
1590#endif /* MBEDTLS_PKCS1_V15 */
1591#if defined(MBEDTLS_PKCS1_V21)
1592 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1593 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001594 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1595 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1596 mbedtls_ctr_drbg_random,
1597 &global_data.ctr_drbg,
1598 MBEDTLS_RSA_PUBLIC,
1599 md_alg, hash_length, hash,
1600 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001601 }
1602 else
1603#endif /* MBEDTLS_PKCS1_V21 */
1604 {
1605 return( PSA_ERROR_INVALID_ARGUMENT );
1606 }
1607 return( mbedtls_to_psa_error( ret ) );
1608 }
1609 else
1610#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001611#if defined(MBEDTLS_ECP_C)
1612 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1613 {
1614 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1615 int ret;
Gilles Peskine2d277862018-06-18 15:41:12 +02001616 (void) alg;
Gilles Peskine61b91d42018-06-08 16:09:36 +02001617 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length,
1618 signature, signature_size );
itayzafrir5c753392018-05-08 11:18:38 +03001619 return( mbedtls_to_psa_error( ret ) );
1620 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001621 else
1622#endif /* defined(MBEDTLS_ECP_C) */
1623 {
1624 return( PSA_ERROR_NOT_SUPPORTED );
1625 }
1626}
1627
Gilles Peskine61b91d42018-06-08 16:09:36 +02001628psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1629 psa_algorithm_t alg,
1630 const uint8_t *input,
1631 size_t input_length,
1632 const uint8_t *salt,
1633 size_t salt_length,
1634 uint8_t *output,
1635 size_t output_size,
1636 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001637{
1638 key_slot_t *slot;
1639 (void) salt;
1640 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001641 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001642
1643 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001644 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001645 slot = &global_data.key_slots[key];
1646 if( slot->type == PSA_KEY_TYPE_NONE )
1647 return( PSA_ERROR_EMPTY_SLOT );
1648 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1649 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001650 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1651 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001652
1653#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001654 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1655 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001656 {
1657 mbedtls_rsa_context *rsa = slot->data.rsa;
1658 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001659 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001660 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001661#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001662 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001663 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001664 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1665 mbedtls_ctr_drbg_random,
1666 &global_data.ctr_drbg,
1667 MBEDTLS_RSA_PUBLIC,
1668 input_length,
1669 input,
1670 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001671 }
1672 else
1673#endif /* MBEDTLS_PKCS1_V15 */
1674#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001675 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001676 {
1677 return( PSA_ERROR_NOT_SUPPORTED );
1678 }
1679 else
1680#endif /* MBEDTLS_PKCS1_V21 */
1681 {
1682 return( PSA_ERROR_INVALID_ARGUMENT );
1683 }
1684 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001685 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001686 return( mbedtls_to_psa_error( ret ) );
1687 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001688 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001689#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001690 {
1691 return( PSA_ERROR_NOT_SUPPORTED );
1692 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001693}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001694
Gilles Peskine61b91d42018-06-08 16:09:36 +02001695psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1696 psa_algorithm_t alg,
1697 const uint8_t *input,
1698 size_t input_length,
1699 const uint8_t *salt,
1700 size_t salt_length,
1701 uint8_t *output,
1702 size_t output_size,
1703 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001704{
1705 key_slot_t *slot;
1706 (void) salt;
1707 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001708 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001709
1710 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1711 return( PSA_ERROR_EMPTY_SLOT );
1712 slot = &global_data.key_slots[key];
1713 if( slot->type == PSA_KEY_TYPE_NONE )
1714 return( PSA_ERROR_EMPTY_SLOT );
1715 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1716 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001717 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1718 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001719
1720#if defined(MBEDTLS_RSA_C)
1721 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1722 {
1723 mbedtls_rsa_context *rsa = slot->data.rsa;
1724 int ret;
1725
Gilles Peskinec4def2f2018-06-08 17:53:48 +02001726 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001727 return( PSA_ERROR_INVALID_ARGUMENT );
1728
1729#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001730 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001731 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001732 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
1733 mbedtls_ctr_drbg_random,
1734 &global_data.ctr_drbg,
1735 MBEDTLS_RSA_PRIVATE,
1736 output_length,
1737 input,
1738 output,
1739 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001740 }
1741 else
1742#endif /* MBEDTLS_PKCS1_V15 */
1743#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001744 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001745 {
1746 return( PSA_ERROR_NOT_SUPPORTED );
1747 }
1748 else
1749#endif /* MBEDTLS_PKCS1_V21 */
1750 {
1751 return( PSA_ERROR_INVALID_ARGUMENT );
1752 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001753
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001754 return( mbedtls_to_psa_error( ret ) );
1755 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001756 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001757#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001758 {
1759 return( PSA_ERROR_NOT_SUPPORTED );
1760 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001761}
Gilles Peskine20035e32018-02-03 22:44:14 +01001762
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001763
1764
mohammad1603503973b2018-03-12 15:59:30 +02001765/****************************************************************/
1766/* Symmetric cryptography */
1767/****************************************************************/
1768
Gilles Peskinee553c652018-06-04 16:22:46 +02001769static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1770 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001771 psa_algorithm_t alg,
1772 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001773{
1774 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1775 psa_status_t status;
1776 key_slot_t *slot;
1777 psa_key_type_t key_type;
1778 size_t key_bits;
1779 const mbedtls_cipher_info_t *cipher_info = NULL;
1780
Moran Peker41deec42018-04-04 15:43:05 +03001781 operation->alg = alg;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001782 operation->key_set = 0;
1783 operation->iv_set = 0;
1784 operation->iv_required = 1;
1785 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001786 operation->block_size = 0;
mohammad1603503973b2018-03-12 15:59:30 +02001787
1788 status = psa_get_key_information( key, &key_type, &key_bits );
1789 if( status != PSA_SUCCESS )
1790 return( status );
1791 slot = &global_data.key_slots[key];
1792
Gilles Peskinebb1072f2018-06-08 18:46:05 +02001793 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02001794 if( cipher_info == NULL )
1795 return( PSA_ERROR_NOT_SUPPORTED );
1796
mohammad1603503973b2018-03-12 15:59:30 +02001797 mbedtls_cipher_init( &operation->ctx.cipher );
1798 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03001799 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001800 {
1801 psa_cipher_abort( operation );
1802 return( mbedtls_to_psa_error( ret ) );
1803 }
1804
1805 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
Gilles Peskinee553c652018-06-04 16:22:46 +02001806 key_bits, cipher_operation );
Moran Peker41deec42018-04-04 15:43:05 +03001807 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001808 {
1809 psa_cipher_abort( operation );
1810 return( mbedtls_to_psa_error( ret ) );
1811 }
1812
mohammad16038481e742018-03-18 13:57:31 +02001813#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03001814 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02001815 {
Gilles Peskine53514202018-06-06 15:11:46 +02001816 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1817 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02001818
Moran Pekera28258c2018-05-29 16:25:04 +03001819 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02001820 {
1821 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
1822 mode = MBEDTLS_PADDING_PKCS7;
1823 break;
1824 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
1825 mode = MBEDTLS_PADDING_NONE;
1826 break;
1827 default:
Moran Pekerae382792018-05-31 14:06:17 +03001828 psa_cipher_abort( operation );
1829 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02001830 }
1831 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03001832 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03001833 {
1834 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02001835 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03001836 }
mohammad16038481e742018-03-18 13:57:31 +02001837 }
1838#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
1839
mohammad1603503973b2018-03-12 15:59:30 +02001840 operation->key_set = 1;
1841 operation->alg = alg;
Gilles Peskine7e928852018-06-04 16:23:10 +02001842 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
1843 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
1844 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001845 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02001846 {
mohammad160389e0f462018-04-12 08:48:45 +03001847 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02001848 }
mohammad1603503973b2018-03-12 15:59:30 +02001849
Moran Peker395db872018-05-31 14:07:14 +03001850 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001851}
1852
Gilles Peskinee553c652018-06-04 16:22:46 +02001853psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
1854 psa_key_slot_t key,
1855 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001856{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001857 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001858}
1859
Gilles Peskinee553c652018-06-04 16:22:46 +02001860psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
1861 psa_key_slot_t key,
1862 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001863{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001864 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001865}
1866
Gilles Peskinee553c652018-06-04 16:22:46 +02001867psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
1868 unsigned char *iv,
1869 size_t iv_size,
1870 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001871{
Moran Peker41deec42018-04-04 15:43:05 +03001872 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001873 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001874 return( PSA_ERROR_BAD_STATE );
1875 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02001876 {
Moran Peker41deec42018-04-04 15:43:05 +03001877 ret = PSA_ERROR_BUFFER_TOO_SMALL;
1878 goto exit;
1879 }
Gilles Peskine7e928852018-06-04 16:23:10 +02001880 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
1881 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03001882 if( ret != 0 )
1883 {
1884 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02001885 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02001886 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001887
mohammad16038481e742018-03-18 13:57:31 +02001888 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03001889 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001890
Moran Peker395db872018-05-31 14:07:14 +03001891exit:
1892 if( ret != PSA_SUCCESS )
1893 psa_cipher_abort( operation );
1894 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02001895}
1896
Gilles Peskinee553c652018-06-04 16:22:46 +02001897psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
1898 const unsigned char *iv,
1899 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001900{
Moran Peker41deec42018-04-04 15:43:05 +03001901 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001902 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001903 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03001904 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03001905 {
Moran Pekerae382792018-05-31 14:06:17 +03001906 psa_cipher_abort( operation );
1907 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03001908 }
mohammad1603503973b2018-03-12 15:59:30 +02001909 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001910 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001911 {
1912 psa_cipher_abort( operation );
1913 return( mbedtls_to_psa_error( ret ) );
1914 }
1915
1916 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02001917
Moran Peker395db872018-05-31 14:07:14 +03001918 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001919}
1920
Gilles Peskinee553c652018-06-04 16:22:46 +02001921psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
1922 const uint8_t *input,
1923 size_t input_length,
1924 unsigned char *output,
1925 size_t output_size,
1926 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001927{
1928 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02001929 size_t expected_output_size;
1930 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
1931 {
1932 /* Take the unprocessed partial block left over from previous
1933 * update calls, if any, plus the input to this call. Remove
1934 * the last partial block, if any. You get the data that will be
1935 * output in this call. */
1936 expected_output_size =
1937 ( operation->ctx.cipher.unprocessed_len + input_length )
1938 / operation->block_size * operation->block_size;
1939 }
1940 else
1941 {
1942 expected_output_size = input_length;
1943 }
1944 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03001945 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02001946
mohammad1603503973b2018-03-12 15:59:30 +02001947 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02001948 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03001949 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001950 {
1951 psa_cipher_abort( operation );
1952 return( mbedtls_to_psa_error( ret ) );
1953 }
1954
Moran Peker395db872018-05-31 14:07:14 +03001955 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001956}
1957
Gilles Peskinee553c652018-06-04 16:22:46 +02001958psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
1959 uint8_t *output,
1960 size_t output_size,
1961 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001962{
1963 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02001964 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03001965
mohammad1603503973b2018-03-12 15:59:30 +02001966 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001967 {
Moran Peker7cb22b82018-06-05 11:40:02 +03001968 psa_cipher_abort( operation );
1969 return( PSA_ERROR_BAD_STATE );
1970 }
1971 if( operation->iv_required && ! operation->iv_set )
1972 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001973 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001974 return( PSA_ERROR_BAD_STATE );
1975 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001976 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
1977 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03001978 {
Gilles Peskine53514202018-06-06 15:11:46 +02001979 psa_algorithm_t padding_mode =
1980 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03001981 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02001982 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001983 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001984 return( PSA_ERROR_TAMPERING_DETECTED );
1985 }
Gilles Peskine53514202018-06-06 15:11:46 +02001986 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03001987 {
1988 if( operation->ctx.cipher.unprocessed_len != 0 )
1989 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001990 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001991 return( PSA_ERROR_INVALID_ARGUMENT );
1992 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02001993 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001994 }
1995
1996 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02001997 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03001998 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001999 {
2000 psa_cipher_abort( operation );
2001 return( mbedtls_to_psa_error( ret ) );
2002 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002003 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002004 memcpy( output, temp_output_buffer, *output_length );
2005 else
2006 {
2007 psa_cipher_abort( operation );
2008 return( PSA_ERROR_BUFFER_TOO_SMALL );
2009 }
mohammad1603503973b2018-03-12 15:59:30 +02002010
Moran Peker4c80d832018-04-22 20:15:31 +03002011 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002012}
2013
Gilles Peskinee553c652018-06-04 16:22:46 +02002014psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2015{
mohammad1603503973b2018-03-12 15:59:30 +02002016 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002017
Moran Peker41deec42018-04-04 15:43:05 +03002018 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002019 operation->key_set = 0;
2020 operation->iv_set = 0;
2021 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002022 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002023 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002024
Moran Peker395db872018-05-31 14:07:14 +03002025 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002026}
2027
Gilles Peskinea0655c32018-04-30 17:06:50 +02002028
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002029
mohammad16038cc1cee2018-03-28 01:21:33 +03002030/****************************************************************/
2031/* Key Policy */
2032/****************************************************************/
2033
Gilles Peskine2d277862018-06-18 15:41:12 +02002034void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002035{
Gilles Peskine803ce742018-06-18 16:07:14 +02002036 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002037}
2038
Gilles Peskine2d277862018-06-18 15:41:12 +02002039void psa_key_policy_set_usage( psa_key_policy_t *policy,
2040 psa_key_usage_t usage,
2041 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002042{
mohammad16034eed7572018-03-28 05:14:59 -07002043 policy->usage = usage;
2044 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002045}
2046
Gilles Peskine2d277862018-06-18 15:41:12 +02002047psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002048{
mohammad16036df908f2018-04-02 08:34:15 -07002049 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002050}
2051
Gilles Peskine2d277862018-06-18 15:41:12 +02002052psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002053{
mohammad16036df908f2018-04-02 08:34:15 -07002054 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002055}
2056
Gilles Peskine2d277862018-06-18 15:41:12 +02002057psa_status_t psa_set_key_policy( psa_key_slot_t key,
2058 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002059{
2060 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002061
2062 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
2063 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002064
mohammad16038cc1cee2018-03-28 01:21:33 +03002065 slot = &global_data.key_slots[key];
2066 if( slot->type != PSA_KEY_TYPE_NONE )
2067 return( PSA_ERROR_OCCUPIED_SLOT );
2068
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002069 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2070 PSA_KEY_USAGE_ENCRYPT |
2071 PSA_KEY_USAGE_DECRYPT |
2072 PSA_KEY_USAGE_SIGN |
2073 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002074 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002075
mohammad16036df908f2018-04-02 08:34:15 -07002076 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002077
2078 return( PSA_SUCCESS );
2079}
2080
Gilles Peskine2d277862018-06-18 15:41:12 +02002081psa_status_t psa_get_key_policy( psa_key_slot_t key,
2082 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002083{
2084 key_slot_t *slot;
2085
2086 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
2087 return( PSA_ERROR_INVALID_ARGUMENT );
2088
2089 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002090
mohammad16036df908f2018-04-02 08:34:15 -07002091 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002092
2093 return( PSA_SUCCESS );
2094}
Gilles Peskine20035e32018-02-03 22:44:14 +01002095
Gilles Peskinea0655c32018-04-30 17:06:50 +02002096
2097
mohammad1603804cd712018-03-20 22:44:08 +02002098/****************************************************************/
2099/* Key Lifetime */
2100/****************************************************************/
2101
Gilles Peskine2d277862018-06-18 15:41:12 +02002102psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2103 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002104{
2105 key_slot_t *slot;
2106
2107 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
2108 return( PSA_ERROR_INVALID_ARGUMENT );
2109
2110 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002111
mohammad1603804cd712018-03-20 22:44:08 +02002112 *lifetime = slot->lifetime;
2113
2114 return( PSA_SUCCESS );
2115}
2116
Gilles Peskine2d277862018-06-18 15:41:12 +02002117psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2118 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002119{
2120 key_slot_t *slot;
2121
2122 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
2123 return( PSA_ERROR_INVALID_ARGUMENT );
2124
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002125 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2126 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002127 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2128 return( PSA_ERROR_INVALID_ARGUMENT );
2129
mohammad1603804cd712018-03-20 22:44:08 +02002130 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002131 if( slot->type != PSA_KEY_TYPE_NONE )
2132 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002133
Moran Pekerd7326592018-05-29 16:56:39 +03002134 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002135 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002136
mohammad1603060ad8a2018-03-20 14:28:38 -07002137 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002138
2139 return( PSA_SUCCESS );
2140}
2141
Gilles Peskine20035e32018-02-03 22:44:14 +01002142
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002143
mohammad16035955c982018-04-26 00:53:03 +03002144/****************************************************************/
2145/* AEAD */
2146/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002147
mohammad16035955c982018-04-26 00:53:03 +03002148psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2149 psa_algorithm_t alg,
2150 const uint8_t *nonce,
2151 size_t nonce_length,
2152 const uint8_t *additional_data,
2153 size_t additional_data_length,
2154 const uint8_t *plaintext,
2155 size_t plaintext_length,
2156 uint8_t *ciphertext,
2157 size_t ciphertext_size,
2158 size_t *ciphertext_length )
2159{
2160 int ret;
2161 psa_status_t status;
2162 key_slot_t *slot;
2163 psa_key_type_t key_type;
2164 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002165 uint8_t *tag;
2166 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002167 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002168 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002169
mohammad1603f08a5502018-06-03 15:05:47 +03002170 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002171
mohammad16035955c982018-04-26 00:53:03 +03002172 status = psa_get_key_information( key, &key_type, &key_bits );
2173 if( status != PSA_SUCCESS )
2174 return( status );
2175 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002176 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002177 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002178
mohammad16035ed06212018-06-06 13:09:34 +03002179 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2180 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002181 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002182 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002183
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002184 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002185 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002186
Gilles Peskine2d277862018-06-18 15:41:12 +02002187 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2188 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002189 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002190
mohammad16035955c982018-04-26 00:53:03 +03002191 if( alg == PSA_ALG_GCM )
2192 {
2193 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002194 tag_length = 16;
2195
mohammad160396910d82018-06-04 14:33:00 +03002196 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2197 return( PSA_ERROR_INVALID_ARGUMENT );
2198
mohammad160315223a82018-06-03 17:19:55 +03002199 //make sure we have place to hold the tag in the ciphertext buffer
2200 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002201 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002202
2203 //update the tag pointer to point to the end of the ciphertext_length
2204 tag = ciphertext + plaintext_length;
2205
mohammad16035955c982018-04-26 00:53:03 +03002206 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002207 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002208 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002209 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002210 if( ret != 0 )
2211 {
2212 mbedtls_gcm_free( &gcm );
2213 return( mbedtls_to_psa_error( ret ) );
2214 }
2215 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002216 plaintext_length, nonce,
2217 nonce_length, additional_data,
2218 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002219 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002220 mbedtls_gcm_free( &gcm );
2221 }
2222 else if( alg == PSA_ALG_CCM )
2223 {
2224 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002225 tag_length = 16;
2226
mohammad160396910d82018-06-04 14:33:00 +03002227 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2228 return( PSA_ERROR_INVALID_ARGUMENT );
2229
mohammad160347ddf3d2018-04-26 01:11:21 +03002230 if( nonce_length < 7 || nonce_length > 13 )
2231 return( PSA_ERROR_INVALID_ARGUMENT );
2232
mohammad160315223a82018-06-03 17:19:55 +03002233 //make sure we have place to hold the tag in the ciphertext buffer
2234 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002235 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002236
2237 //update the tag pointer to point to the end of the ciphertext_length
2238 tag = ciphertext + plaintext_length;
2239
mohammad16035955c982018-04-26 00:53:03 +03002240 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002241 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002242 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002243 if( ret != 0 )
2244 {
2245 mbedtls_ccm_free( &ccm );
2246 return( mbedtls_to_psa_error( ret ) );
2247 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002248 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002249 nonce, nonce_length,
2250 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002251 additional_data_length,
2252 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002253 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002254 mbedtls_ccm_free( &ccm );
2255 }
mohammad16035c8845f2018-05-09 05:40:09 -07002256 else
2257 {
mohammad1603554faad2018-06-03 15:07:38 +03002258 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002259 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002260
mohammad160315223a82018-06-03 17:19:55 +03002261 if( ret != 0 )
2262 {
2263 memset( ciphertext, 0, ciphertext_size );
2264 return( mbedtls_to_psa_error( ret ) );
2265 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002266
mohammad160315223a82018-06-03 17:19:55 +03002267 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002268 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002269}
2270
Gilles Peskineee652a32018-06-01 19:23:52 +02002271/* Locate the tag in a ciphertext buffer containing the encrypted data
2272 * followed by the tag. Return the length of the part preceding the tag in
2273 * *plaintext_length. This is the size of the plaintext in modes where
2274 * the encrypted data has the same size as the plaintext, such as
2275 * CCM and GCM. */
2276static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2277 const uint8_t *ciphertext,
2278 size_t ciphertext_length,
2279 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002280 const uint8_t **p_tag )
2281{
2282 size_t payload_length;
2283 if( tag_length > ciphertext_length )
2284 return( PSA_ERROR_INVALID_ARGUMENT );
2285 payload_length = ciphertext_length - tag_length;
2286 if( payload_length > plaintext_size )
2287 return( PSA_ERROR_BUFFER_TOO_SMALL );
2288 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002289 return( PSA_SUCCESS );
2290}
2291
mohammad16035955c982018-04-26 00:53:03 +03002292psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2293 psa_algorithm_t alg,
2294 const uint8_t *nonce,
2295 size_t nonce_length,
2296 const uint8_t *additional_data,
2297 size_t additional_data_length,
2298 const uint8_t *ciphertext,
2299 size_t ciphertext_length,
2300 uint8_t *plaintext,
2301 size_t plaintext_size,
2302 size_t *plaintext_length )
2303{
2304 int ret;
2305 psa_status_t status;
2306 key_slot_t *slot;
2307 psa_key_type_t key_type;
2308 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002309 const uint8_t *tag;
2310 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002311 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002312 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002313
Gilles Peskineee652a32018-06-01 19:23:52 +02002314 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002315
mohammad16035955c982018-04-26 00:53:03 +03002316 status = psa_get_key_information( key, &key_type, &key_bits );
2317 if( status != PSA_SUCCESS )
2318 return( status );
2319 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002320 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002321 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002322
mohammad16035ed06212018-06-06 13:09:34 +03002323 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2324 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002325 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002326 return( PSA_ERROR_NOT_SUPPORTED );
2327
mohammad1603f14394b2018-06-04 14:33:19 +03002328 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2329 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002330
Gilles Peskine2d277862018-06-18 15:41:12 +02002331 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2332 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002333 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002334
mohammad16035955c982018-04-26 00:53:03 +03002335 if( alg == PSA_ALG_GCM )
2336 {
2337 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002338
Gilles Peskineee652a32018-06-01 19:23:52 +02002339 tag_length = 16;
2340 status = psa_aead_unpadded_locate_tag( tag_length,
2341 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002342 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002343 if( status != PSA_SUCCESS )
2344 return( status );
2345
mohammad16035955c982018-04-26 00:53:03 +03002346 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002347 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002348 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002349 if( ret != 0 )
2350 {
2351 mbedtls_gcm_free( &gcm );
2352 return( mbedtls_to_psa_error( ret ) );
2353 }
mohammad16035955c982018-04-26 00:53:03 +03002354
Gilles Peskineee652a32018-06-01 19:23:52 +02002355 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002356 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002357 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002358 additional_data,
2359 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002360 tag, tag_length,
2361 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002362 mbedtls_gcm_free( &gcm );
2363 }
2364 else if( alg == PSA_ALG_CCM )
2365 {
2366 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002367
mohammad160347ddf3d2018-04-26 01:11:21 +03002368 if( nonce_length < 7 || nonce_length > 13 )
2369 return( PSA_ERROR_INVALID_ARGUMENT );
2370
mohammad16039375f842018-06-03 14:28:24 +03002371 tag_length = 16;
2372 status = psa_aead_unpadded_locate_tag( tag_length,
2373 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002374 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002375 if( status != PSA_SUCCESS )
2376 return( status );
2377
mohammad16035955c982018-04-26 00:53:03 +03002378 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002379 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002380 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002381 if( ret != 0 )
2382 {
2383 mbedtls_ccm_free( &ccm );
2384 return( mbedtls_to_psa_error( ret ) );
2385 }
mohammad160360a64d02018-06-03 17:20:42 +03002386 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002387 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002388 additional_data,
2389 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002390 ciphertext, plaintext,
2391 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002392 mbedtls_ccm_free( &ccm );
2393 }
mohammad160339574652018-06-01 04:39:53 -07002394 else
2395 {
mohammad1603554faad2018-06-03 15:07:38 +03002396 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002397 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002398
Gilles Peskineee652a32018-06-01 19:23:52 +02002399 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002400 memset( plaintext, 0, plaintext_size );
2401 else
2402 *plaintext_length = ciphertext_length - tag_length;
2403
Gilles Peskineee652a32018-06-01 19:23:52 +02002404 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002405}
2406
Gilles Peskinea0655c32018-04-30 17:06:50 +02002407
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002408
Gilles Peskine20035e32018-02-03 22:44:14 +01002409/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002410/* Module setup */
2411/****************************************************************/
2412
Gilles Peskinee59236f2018-01-27 23:32:46 +01002413void mbedtls_psa_crypto_free( void )
2414{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002415 size_t key;
2416 for( key = 1; key < MBEDTLS_PSA_KEY_SLOT_COUNT; key++ )
2417 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002418 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2419 mbedtls_entropy_free( &global_data.entropy );
2420 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2421}
2422
2423psa_status_t psa_crypto_init( void )
2424{
2425 int ret;
2426 const unsigned char drbg_seed[] = "PSA";
2427
2428 if( global_data.initialized != 0 )
2429 return( PSA_SUCCESS );
2430
2431 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2432 mbedtls_entropy_init( &global_data.entropy );
2433 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2434
2435 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2436 mbedtls_entropy_func,
2437 &global_data.entropy,
2438 drbg_seed, sizeof( drbg_seed ) - 1 );
2439 if( ret != 0 )
2440 goto exit;
2441
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002442 global_data.initialized = 1;
2443
Gilles Peskinee59236f2018-01-27 23:32:46 +01002444exit:
2445 if( ret != 0 )
2446 mbedtls_psa_crypto_free( );
2447 return( mbedtls_to_psa_error( ret ) );
2448}
2449
2450#endif /* MBEDTLS_PSA_CRYPTO_C */