blob: 954895910f12d76773be7e37fd95bb606cbb647d [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 Peskine2f9c4dc2018-01-28 13:16:24 +0100308/****************************************************************/
309/* Key management */
310/****************************************************************/
311
Gilles Peskine2d277862018-06-18 15:41:12 +0200312psa_status_t psa_import_key( psa_key_slot_t key,
313 psa_key_type_t type,
314 const uint8_t *data,
315 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100316{
317 key_slot_t *slot;
318
319 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
320 return( PSA_ERROR_INVALID_ARGUMENT );
321 slot = &global_data.key_slots[key];
322 if( slot->type != PSA_KEY_TYPE_NONE )
323 return( PSA_ERROR_OCCUPIED_SLOT );
324
Gilles Peskine8c9def32018-02-08 10:02:12 +0100325 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100326 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100327 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100328 if( data_length > SIZE_MAX / 8 )
329 return( PSA_ERROR_NOT_SUPPORTED );
330 slot->data.raw.data = mbedtls_calloc( 1, data_length );
331 if( slot->data.raw.data == NULL )
332 return( PSA_ERROR_INSUFFICIENT_MEMORY );
333 memcpy( slot->data.raw.data, data, data_length );
334 slot->data.raw.bytes = data_length;
335 }
336 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100337#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100338 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
339 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
340 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100341 {
342 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100343 mbedtls_pk_context pk;
344 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100345 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
346 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
347 else
348 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100349 if( ret != 0 )
350 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100351 switch( mbedtls_pk_get_type( &pk ) )
352 {
353#if defined(MBEDTLS_RSA_C)
354 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100355 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
356 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine969ac722018-01-28 18:16:59 +0100357 slot->data.rsa = pk.pk_ctx;
358 else
359 return( PSA_ERROR_INVALID_ARGUMENT );
360 break;
361#endif /* MBEDTLS_RSA_C */
362#if defined(MBEDTLS_ECP_C)
363 case MBEDTLS_PK_ECKEY:
364 if( PSA_KEY_TYPE_IS_ECC( type ) )
365 {
366 // TODO: check curve
367 slot->data.ecp = pk.pk_ctx;
368 }
369 else
370 return( PSA_ERROR_INVALID_ARGUMENT );
371 break;
372#endif /* MBEDTLS_ECP_C */
373 default:
374 return( PSA_ERROR_INVALID_ARGUMENT );
375 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100376 }
377 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100378#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100379 {
380 return( PSA_ERROR_NOT_SUPPORTED );
381 }
382
383 slot->type = type;
384 return( PSA_SUCCESS );
385}
386
Gilles Peskine2d277862018-06-18 15:41:12 +0200387psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100388{
389 key_slot_t *slot;
390
391 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
392 return( PSA_ERROR_INVALID_ARGUMENT );
393 slot = &global_data.key_slots[key];
394 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200395 {
396 /* No key material to clean, but do zeroize the slot below to wipe
397 * metadata such as policies. */
398 }
399 else if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100400 {
401 mbedtls_free( slot->data.raw.data );
402 }
403 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100404#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100405 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
406 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100407 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100408 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100409 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100410 }
411 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100412#endif /* defined(MBEDTLS_RSA_C) */
413#if defined(MBEDTLS_ECP_C)
414 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
415 {
416 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100417 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100418 }
419 else
420#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100421 {
422 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100423 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100424 return( PSA_ERROR_TAMPERING_DETECTED );
425 }
426
427 mbedtls_zeroize( slot, sizeof( *slot ) );
428 return( PSA_SUCCESS );
429}
430
Gilles Peskine2d277862018-06-18 15:41:12 +0200431psa_status_t psa_get_key_information( psa_key_slot_t key,
432 psa_key_type_t *type,
433 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100434{
435 key_slot_t *slot;
436
437 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100438 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100439 slot = &global_data.key_slots[key];
440 if( type != NULL )
441 *type = slot->type;
442 if( bits != NULL )
443 *bits = 0;
444 if( slot->type == PSA_KEY_TYPE_NONE )
445 return( PSA_ERROR_EMPTY_SLOT );
446
Gilles Peskine8c9def32018-02-08 10:02:12 +0100447 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100448 {
449 if( bits != NULL )
450 *bits = slot->data.raw.bytes * 8;
451 }
452 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100453#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100454 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
455 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100456 {
457 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100458 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100459 }
460 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100461#endif /* defined(MBEDTLS_RSA_C) */
462#if defined(MBEDTLS_ECP_C)
463 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
464 {
465 if( bits != NULL )
466 *bits = slot->data.ecp->grp.pbits;
467 }
468 else
469#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100470 {
471 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100472 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100473 return( PSA_ERROR_TAMPERING_DETECTED );
474 }
475
476 return( PSA_SUCCESS );
477}
478
Gilles Peskine2d277862018-06-18 15:41:12 +0200479static psa_status_t psa_internal_export_key( psa_key_slot_t key,
480 uint8_t *data,
481 size_t data_size,
482 size_t *data_length,
483 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100484{
485 key_slot_t *slot;
486
487 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100488 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100489 slot = &global_data.key_slots[key];
490 if( slot->type == PSA_KEY_TYPE_NONE )
491 return( PSA_ERROR_EMPTY_SLOT );
492
Moran Peker87567632018-06-04 18:41:37 +0300493 if( export_public_key && ( !( PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) ) ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300494 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300495
Moran Peker87567632018-06-04 18:41:37 +0300496 if( ( !export_public_key ) && ( !( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ) ) &&
497 ( !( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) ) )
498 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200499
Gilles Peskine8c9def32018-02-08 10:02:12 +0100500 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100501 {
502 if( slot->data.raw.bytes > data_size )
503 return( PSA_ERROR_BUFFER_TOO_SMALL );
504 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
505 *data_length = slot->data.raw.bytes;
506 return( PSA_SUCCESS );
507 }
508 else
Moran Peker17e36e12018-05-02 12:55:20 +0300509 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100510#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100511 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300512 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
513 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100514 {
Moran Pekera998bc62018-04-16 18:16:20 +0300515 mbedtls_pk_context pk;
516 int ret;
517 mbedtls_pk_init( &pk );
518 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
519 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
520 {
521 pk.pk_info = &mbedtls_rsa_info;
522 pk.pk_ctx = slot->data.rsa;
523 }
524 else
525 {
526 pk.pk_info = &mbedtls_eckey_info;
527 pk.pk_ctx = slot->data.ecp;
528 }
Moran Pekerd7326592018-05-29 16:56:39 +0300529 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300530 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300531 else
532 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300533 if( ret < 0 )
Moran Pekera998bc62018-04-16 18:16:20 +0300534 return( mbedtls_to_psa_error( ret ) );
535 *data_length = ret;
536 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100537 }
538 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100539#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300540 {
541 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200542 it is valid for a special-purpose implementation to omit
543 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300544 return( PSA_ERROR_NOT_SUPPORTED );
545 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100546 }
547}
548
Gilles Peskine2d277862018-06-18 15:41:12 +0200549psa_status_t psa_export_key( psa_key_slot_t key,
550 uint8_t *data,
551 size_t data_size,
552 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300553{
554 return psa_internal_export_key( key, data, data_size,
Gilles Peskine2d277862018-06-18 15:41:12 +0200555 data_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100556}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100557
558
Gilles Peskine2d277862018-06-18 15:41:12 +0200559psa_status_t psa_export_public_key( psa_key_slot_t key,
560 uint8_t *data,
561 size_t data_size,
562 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300563{
Moran Pekera998bc62018-04-16 18:16:20 +0300564 return psa_internal_export_key( key, data, data_size,
Gilles Peskine2d277862018-06-18 15:41:12 +0200565 data_length, 1 );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300566}
567
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100568/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100569/* Message digests */
570/****************************************************************/
571
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100572static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100573{
574 switch( alg )
575 {
576#if defined(MBEDTLS_MD2_C)
577 case PSA_ALG_MD2:
578 return( &mbedtls_md2_info );
579#endif
580#if defined(MBEDTLS_MD4_C)
581 case PSA_ALG_MD4:
582 return( &mbedtls_md4_info );
583#endif
584#if defined(MBEDTLS_MD5_C)
585 case PSA_ALG_MD5:
586 return( &mbedtls_md5_info );
587#endif
588#if defined(MBEDTLS_RIPEMD160_C)
589 case PSA_ALG_RIPEMD160:
590 return( &mbedtls_ripemd160_info );
591#endif
592#if defined(MBEDTLS_SHA1_C)
593 case PSA_ALG_SHA_1:
594 return( &mbedtls_sha1_info );
595#endif
596#if defined(MBEDTLS_SHA256_C)
597 case PSA_ALG_SHA_224:
598 return( &mbedtls_sha224_info );
599 case PSA_ALG_SHA_256:
600 return( &mbedtls_sha256_info );
601#endif
602#if defined(MBEDTLS_SHA512_C)
603 case PSA_ALG_SHA_384:
604 return( &mbedtls_sha384_info );
605 case PSA_ALG_SHA_512:
606 return( &mbedtls_sha512_info );
607#endif
608 default:
609 return( NULL );
610 }
611}
612
613#if 0
614static psa_algorithm_t mbedtls_md_alg_to_psa( mbedtls_md_type_t md_alg )
615{
616 switch( md_alg )
617 {
618 case MBEDTLS_MD_NONE:
619 return( 0 );
620 case MBEDTLS_MD_MD2:
621 return( PSA_ALG_MD2 );
622 case MBEDTLS_MD_MD4:
623 return( PSA_ALG_MD4 );
624 case MBEDTLS_MD_MD5:
625 return( PSA_ALG_MD5 );
626 case MBEDTLS_MD_SHA1:
627 return( PSA_ALG_SHA_1 );
628 case MBEDTLS_MD_SHA224:
629 return( PSA_ALG_SHA_224 );
630 case MBEDTLS_MD_SHA256:
631 return( PSA_ALG_SHA_256 );
632 case MBEDTLS_MD_SHA384:
633 return( PSA_ALG_SHA_384 );
634 case MBEDTLS_MD_SHA512:
635 return( PSA_ALG_SHA_512 );
636 case MBEDTLS_MD_RIPEMD160:
637 return( PSA_ALG_RIPEMD160 );
638 default:
Gilles Peskine47c1bc02018-03-20 17:55:04 +0100639 return( 0 );
Gilles Peskine20035e32018-02-03 22:44:14 +0100640 }
641}
642#endif
643
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100644psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
645{
646 switch( operation->alg )
647 {
648#if defined(MBEDTLS_MD2_C)
649 case PSA_ALG_MD2:
650 mbedtls_md2_free( &operation->ctx.md2 );
651 break;
652#endif
653#if defined(MBEDTLS_MD4_C)
654 case PSA_ALG_MD4:
655 mbedtls_md4_free( &operation->ctx.md4 );
656 break;
657#endif
658#if defined(MBEDTLS_MD5_C)
659 case PSA_ALG_MD5:
660 mbedtls_md5_free( &operation->ctx.md5 );
661 break;
662#endif
663#if defined(MBEDTLS_RIPEMD160_C)
664 case PSA_ALG_RIPEMD160:
665 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
666 break;
667#endif
668#if defined(MBEDTLS_SHA1_C)
669 case PSA_ALG_SHA_1:
670 mbedtls_sha1_free( &operation->ctx.sha1 );
671 break;
672#endif
673#if defined(MBEDTLS_SHA256_C)
674 case PSA_ALG_SHA_224:
675 case PSA_ALG_SHA_256:
676 mbedtls_sha256_free( &operation->ctx.sha256 );
677 break;
678#endif
679#if defined(MBEDTLS_SHA512_C)
680 case PSA_ALG_SHA_384:
681 case PSA_ALG_SHA_512:
682 mbedtls_sha512_free( &operation->ctx.sha512 );
683 break;
684#endif
685 default:
686 return( PSA_ERROR_NOT_SUPPORTED );
687 }
688 operation->alg = 0;
689 return( PSA_SUCCESS );
690}
691
692psa_status_t psa_hash_start( psa_hash_operation_t *operation,
693 psa_algorithm_t alg )
694{
695 int ret;
696 operation->alg = 0;
697 switch( alg )
698 {
699#if defined(MBEDTLS_MD2_C)
700 case PSA_ALG_MD2:
701 mbedtls_md2_init( &operation->ctx.md2 );
702 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
703 break;
704#endif
705#if defined(MBEDTLS_MD4_C)
706 case PSA_ALG_MD4:
707 mbedtls_md4_init( &operation->ctx.md4 );
708 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
709 break;
710#endif
711#if defined(MBEDTLS_MD5_C)
712 case PSA_ALG_MD5:
713 mbedtls_md5_init( &operation->ctx.md5 );
714 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
715 break;
716#endif
717#if defined(MBEDTLS_RIPEMD160_C)
718 case PSA_ALG_RIPEMD160:
719 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
720 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
721 break;
722#endif
723#if defined(MBEDTLS_SHA1_C)
724 case PSA_ALG_SHA_1:
725 mbedtls_sha1_init( &operation->ctx.sha1 );
726 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
727 break;
728#endif
729#if defined(MBEDTLS_SHA256_C)
730 case PSA_ALG_SHA_224:
731 mbedtls_sha256_init( &operation->ctx.sha256 );
732 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
733 break;
734 case PSA_ALG_SHA_256:
735 mbedtls_sha256_init( &operation->ctx.sha256 );
736 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
737 break;
738#endif
739#if defined(MBEDTLS_SHA512_C)
740 case PSA_ALG_SHA_384:
741 mbedtls_sha512_init( &operation->ctx.sha512 );
742 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
743 break;
744 case PSA_ALG_SHA_512:
745 mbedtls_sha512_init( &operation->ctx.sha512 );
746 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
747 break;
748#endif
749 default:
750 return( PSA_ERROR_NOT_SUPPORTED );
751 }
752 if( ret == 0 )
753 operation->alg = alg;
754 else
755 psa_hash_abort( operation );
756 return( mbedtls_to_psa_error( ret ) );
757}
758
759psa_status_t psa_hash_update( psa_hash_operation_t *operation,
760 const uint8_t *input,
761 size_t input_length )
762{
763 int ret;
764 switch( operation->alg )
765 {
766#if defined(MBEDTLS_MD2_C)
767 case PSA_ALG_MD2:
768 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
769 input, input_length );
770 break;
771#endif
772#if defined(MBEDTLS_MD4_C)
773 case PSA_ALG_MD4:
774 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
775 input, input_length );
776 break;
777#endif
778#if defined(MBEDTLS_MD5_C)
779 case PSA_ALG_MD5:
780 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
781 input, input_length );
782 break;
783#endif
784#if defined(MBEDTLS_RIPEMD160_C)
785 case PSA_ALG_RIPEMD160:
786 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
787 input, input_length );
788 break;
789#endif
790#if defined(MBEDTLS_SHA1_C)
791 case PSA_ALG_SHA_1:
792 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
793 input, input_length );
794 break;
795#endif
796#if defined(MBEDTLS_SHA256_C)
797 case PSA_ALG_SHA_224:
798 case PSA_ALG_SHA_256:
799 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
800 input, input_length );
801 break;
802#endif
803#if defined(MBEDTLS_SHA512_C)
804 case PSA_ALG_SHA_384:
805 case PSA_ALG_SHA_512:
806 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
807 input, input_length );
808 break;
809#endif
810 default:
811 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
812 break;
813 }
814 if( ret != 0 )
815 psa_hash_abort( operation );
816 return( mbedtls_to_psa_error( ret ) );
817}
818
819psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
820 uint8_t *hash,
821 size_t hash_size,
822 size_t *hash_length )
823{
824 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200825 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100826
827 /* Fill the output buffer with something that isn't a valid hash
828 * (barring an attack on the hash and deliberately-crafted input),
829 * in case the caller doesn't check the return status properly. */
830 *hash_length = actual_hash_length;
831 memset( hash, '!', hash_size );
832
833 if( hash_size < actual_hash_length )
834 return( PSA_ERROR_BUFFER_TOO_SMALL );
835
836 switch( operation->alg )
837 {
838#if defined(MBEDTLS_MD2_C)
839 case PSA_ALG_MD2:
840 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
841 break;
842#endif
843#if defined(MBEDTLS_MD4_C)
844 case PSA_ALG_MD4:
845 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
846 break;
847#endif
848#if defined(MBEDTLS_MD5_C)
849 case PSA_ALG_MD5:
850 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
851 break;
852#endif
853#if defined(MBEDTLS_RIPEMD160_C)
854 case PSA_ALG_RIPEMD160:
855 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
856 break;
857#endif
858#if defined(MBEDTLS_SHA1_C)
859 case PSA_ALG_SHA_1:
860 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
861 break;
862#endif
863#if defined(MBEDTLS_SHA256_C)
864 case PSA_ALG_SHA_224:
865 case PSA_ALG_SHA_256:
866 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
867 break;
868#endif
869#if defined(MBEDTLS_SHA512_C)
870 case PSA_ALG_SHA_384:
871 case PSA_ALG_SHA_512:
872 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
873 break;
874#endif
875 default:
876 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
877 break;
878 }
879
880 if( ret == 0 )
881 {
882 return( psa_hash_abort( operation ) );
883 }
884 else
885 {
886 psa_hash_abort( operation );
887 return( mbedtls_to_psa_error( ret ) );
888 }
889}
890
Gilles Peskine2d277862018-06-18 15:41:12 +0200891psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
892 const uint8_t *hash,
893 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100894{
895 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
896 size_t actual_hash_length;
897 psa_status_t status = psa_hash_finish( operation,
898 actual_hash, sizeof( actual_hash ),
899 &actual_hash_length );
900 if( status != PSA_SUCCESS )
901 return( status );
902 if( actual_hash_length != hash_length )
903 return( PSA_ERROR_INVALID_SIGNATURE );
904 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
905 return( PSA_ERROR_INVALID_SIGNATURE );
906 return( PSA_SUCCESS );
907}
908
909
910
911
912/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +0100913/* MAC */
914/****************************************************************/
915
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100916static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +0100917 psa_algorithm_t alg,
918 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +0200919 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +0300920 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100921{
Gilles Peskine8c9def32018-02-08 10:02:12 +0100922 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +0300923 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100924
925 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
926 {
927 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +0200928 {
929 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
930 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +0200931
Nir Sonnenscheine9664c32018-06-17 14:41:30 +0300932 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100933 {
934 case PSA_ALG_STREAM_CIPHER:
935 mode = MBEDTLS_MODE_STREAM;
936 break;
937 case PSA_ALG_CBC_BASE:
938 mode = MBEDTLS_MODE_CBC;
939 break;
940 case PSA_ALG_CFB_BASE:
941 mode = MBEDTLS_MODE_CFB;
942 break;
943 case PSA_ALG_OFB_BASE:
944 mode = MBEDTLS_MODE_OFB;
945 break;
946 case PSA_ALG_CTR:
947 mode = MBEDTLS_MODE_CTR;
948 break;
949 case PSA_ALG_CCM:
950 mode = MBEDTLS_MODE_CCM;
951 break;
952 case PSA_ALG_GCM:
953 mode = MBEDTLS_MODE_GCM;
954 break;
955 default:
956 return( NULL );
957 }
958 }
959 else if( alg == PSA_ALG_CMAC )
960 mode = MBEDTLS_MODE_ECB;
961 else if( alg == PSA_ALG_GMAC )
962 mode = MBEDTLS_MODE_GCM;
963 else
964 return( NULL );
965
966 switch( key_type )
967 {
968 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +0300969 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100970 break;
971 case PSA_KEY_TYPE_DES:
972 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +0300973 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100974 else
mohammad1603f4f0d612018-06-03 15:04:51 +0300975 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100976 break;
977 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +0300978 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100979 break;
980 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +0300981 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100982 break;
983 default:
984 return( NULL );
985 }
mohammad1603f4f0d612018-06-03 15:04:51 +0300986 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +0300987 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100988
mohammad1603f4f0d612018-06-03 15:04:51 +0300989 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +0100990}
991
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300992static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +0300993{
Gilles Peskine2d277862018-06-18 15:41:12 +0200994 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +0300995 {
996 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300997 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +0300998 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300999 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001000 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001001 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001002 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001003 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001004 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001005 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001006 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001007 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001008 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001009 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001010 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001011 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001012 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001013 return( 128 );
1014 default:
1015 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001016 }
1017}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001018
Gilles Peskine8c9def32018-02-08 10:02:12 +01001019psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1020{
1021 switch( operation->alg )
1022 {
1023#if defined(MBEDTLS_CMAC_C)
1024 case PSA_ALG_CMAC:
1025 mbedtls_cipher_free( &operation->ctx.cmac );
1026 break;
1027#endif /* MBEDTLS_CMAC_C */
1028 default:
1029#if defined(MBEDTLS_MD_C)
1030 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001031 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001032 unsigned int block_size =
Nir Sonnenschein96272412018-06-17 14:41:10 +03001033 psa_get_hash_block_size( ( PSA_ALG_HMAC_HASH( operation->alg ) ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001034
Gilles Peskine99bc6492018-06-11 17:13:00 +02001035 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001036 return( PSA_ERROR_NOT_SUPPORTED );
1037
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001038 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001039 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001040 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001041 else
1042#endif /* MBEDTLS_MD_C */
1043 return( PSA_ERROR_NOT_SUPPORTED );
1044 }
Moran Peker41deec42018-04-04 15:43:05 +03001045
Gilles Peskine8c9def32018-02-08 10:02:12 +01001046 operation->alg = 0;
1047 operation->key_set = 0;
1048 operation->iv_set = 0;
1049 operation->iv_required = 0;
1050 operation->has_input = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001051
Gilles Peskine8c9def32018-02-08 10:02:12 +01001052 return( PSA_SUCCESS );
1053}
1054
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001055static int psa_cmac_start( psa_mac_operation_t *operation,
1056 size_t key_bits,
1057 key_slot_t *slot,
1058 const mbedtls_cipher_info_t *cipher_info )
1059{
1060 int ret;
1061
1062 operation->mac_size = cipher_info->block_size;
1063 operation->iv_required = 0;
1064 mbedtls_cipher_init( &operation->ctx.cmac );
1065
1066 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1067 if( ret != 0 )
1068 return( ret );
1069
1070 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1071 slot->data.raw.data,
1072 key_bits );
1073 return( ret );
1074}
1075
1076static int psa_hmac_start( psa_mac_operation_t *operation,
1077 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001078 key_slot_t *slot,
1079 psa_algorithm_t alg )
1080{
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001081 unsigned char ipad[PSA_CRYPTO_MD_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001082 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001083 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001084 size_t block_size =
Nir Sonnenschein96272412018-06-17 14:41:10 +03001085 psa_get_hash_block_size( ( PSA_ALG_HMAC_HASH( alg ) ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001086 unsigned int digest_size =
Nir Sonnenscheincaec7f02018-06-14 15:34:50 +03001087 PSA_HASH_SIZE( ( PSA_ALG_HMAC_HASH( alg ) ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001088 size_t key_length = slot->data.raw.bytes;
1089 psa_status_t status;
1090
1091 if( ( block_size == 0 ) || ( digest_size == 0 ) )
1092 return( PSA_ERROR_NOT_SUPPORTED );
1093
1094 if( key_type != PSA_KEY_TYPE_HMAC )
1095 return( PSA_ERROR_INVALID_ARGUMENT );
1096
1097 operation->iv_required = 0;
1098 operation->mac_size = digest_size;
1099
1100 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1101 PSA_ALG_HMAC_HASH( alg ) );
1102 if( status != PSA_SUCCESS )
1103 return( status );
1104
Gilles Peskined223b522018-06-11 18:12:58 +02001105 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001106 {
1107 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001108 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001109 if( status != PSA_SUCCESS )
1110 return( status );
1111 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001112 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001113 if( status != PSA_SUCCESS )
1114 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001115 }
Gilles Peskined223b522018-06-11 18:12:58 +02001116 else
1117 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001118
Gilles Peskined223b522018-06-11 18:12:58 +02001119 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1120 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001121 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001122 ipad[i] ^= 0x36;
1123 memset( ipad + key_length, 0x36, block_size - key_length );
1124
1125 /* Copy the key material from ipad to opad, flipping the requisite bits,
1126 * and filling the rest of opad with the requisite constant. */
1127 for( i = 0; i < key_length; i++ )
1128 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1129 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001130
1131 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1132 PSA_ALG_HMAC_HASH( alg ) );
1133 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001134 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001135
1136 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1137 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001138
1139cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001140 mbedtls_zeroize( ipad, key_length );
1141 /* opad is in the context. It needs to stay in memory if this function
1142 * succeeds, and it will be wiped by psa_mac_abort() called from
1143 * psa_mac_start in the error case. */
1144
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001145 return( status );
1146}
1147
Gilles Peskine8c9def32018-02-08 10:02:12 +01001148psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1149 psa_key_slot_t key,
1150 psa_algorithm_t alg )
1151{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001152 psa_status_t status;
1153 key_slot_t *slot;
1154 psa_key_type_t key_type;
1155 size_t key_bits;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001156 const mbedtls_cipher_info_t *cipher_info;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001157
1158 operation->alg = 0;
1159 operation->key_set = 0;
1160 operation->iv_set = 0;
1161 operation->iv_required = 1;
1162 operation->has_input = 0;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001163 operation->key_usage_sign = 0;
1164 operation->key_usage_verify = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001165
1166 status = psa_get_key_information( key, &key_type, &key_bits );
1167 if( status != PSA_SUCCESS )
1168 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001169
Gilles Peskine8c9def32018-02-08 10:02:12 +01001170 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001171 if( slot->type == PSA_KEY_TYPE_NONE )
1172 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001173
Moran Pekerd7326592018-05-29 16:56:39 +03001174 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001175 operation->key_usage_sign = 1;
1176
Moran Pekerd7326592018-05-29 16:56:39 +03001177 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001178 operation->key_usage_verify = 1;
1179
Gilles Peskine8c9def32018-02-08 10:02:12 +01001180 if( ! PSA_ALG_IS_HMAC( alg ) )
1181 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001182 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001183 if( cipher_info == NULL )
1184 return( PSA_ERROR_NOT_SUPPORTED );
1185 operation->mac_size = cipher_info->block_size;
1186 }
1187 switch( alg )
1188 {
1189#if defined(MBEDTLS_CMAC_C)
1190 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001191 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1192 key_bits,
1193 slot,
1194 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001195 break;
1196#endif /* MBEDTLS_CMAC_C */
1197 default:
1198#if defined(MBEDTLS_MD_C)
1199 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001200 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001201 else
1202#endif /* MBEDTLS_MD_C */
1203 return( PSA_ERROR_NOT_SUPPORTED );
1204 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001205
Gilles Peskine8c9def32018-02-08 10:02:12 +01001206 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001207
1208 * context may contain data that needs to be wiped on error. */
1209 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001210 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001211 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001212 }
Gilles Peskine99bc6492018-06-11 17:13:00 +02001213
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001214 else
1215 {
1216 operation->alg = alg;
1217 operation->key_set = 1;
1218 }
1219 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001220}
1221
1222psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1223 const uint8_t *input,
1224 size_t input_length )
1225{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001226 int ret = 0 ;
1227 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001228 if( ! operation->key_set )
1229 return( PSA_ERROR_BAD_STATE );
1230 if( operation->iv_required && ! operation->iv_set )
1231 return( PSA_ERROR_BAD_STATE );
1232 operation->has_input = 1;
1233
1234 switch( operation->alg )
1235 {
1236#if defined(MBEDTLS_CMAC_C)
1237 case PSA_ALG_CMAC:
1238 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1239 input, input_length );
1240 break;
1241#endif /* MBEDTLS_CMAC_C */
1242 default:
1243#if defined(MBEDTLS_MD_C)
1244 if( PSA_ALG_IS_HMAC( operation->alg ) )
1245 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001246 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001247 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001248 }
1249 else
1250#endif /* MBEDTLS_MD_C */
1251 {
1252 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1253 }
1254 break;
1255 }
Gilles Peskine2d277862018-06-18 15:41:12 +02001256 if( ( ret != 0 ) || ( status != PSA_SUCCESS ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001257 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001258 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001259 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001260 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001261 }
1262
1263 return status;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001264}
1265
mohammad16036df908f2018-04-02 08:34:15 -07001266static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001267 uint8_t *mac,
1268 size_t mac_size,
1269 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001270{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001271 int ret = 0;
1272 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001273 if( ! operation->key_set )
1274 return( PSA_ERROR_BAD_STATE );
1275 if( operation->iv_required && ! operation->iv_set )
1276 return( PSA_ERROR_BAD_STATE );
1277
1278 /* Fill the output buffer with something that isn't a valid mac
1279 * (barring an attack on the mac and deliberately-crafted input),
1280 * in case the caller doesn't check the return status properly. */
1281 *mac_length = operation->mac_size;
1282 memset( mac, '!', mac_size );
1283
1284 if( mac_size < operation->mac_size )
1285 return( PSA_ERROR_BUFFER_TOO_SMALL );
1286
1287 switch( operation->alg )
1288 {
1289#if defined(MBEDTLS_CMAC_C)
1290 case PSA_ALG_CMAC:
1291 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1292 break;
1293#endif /* MBEDTLS_CMAC_C */
1294 default:
1295#if defined(MBEDTLS_MD_C)
1296 if( PSA_ALG_IS_HMAC( operation->alg ) )
1297 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001298 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001299 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001300 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001301 size_t block_size =
Gilles Peskine2d277862018-06-18 15:41:12 +02001302 psa_get_hash_block_size( ( PSA_ALG_HMAC_HASH( operation->alg ) ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001303
Gilles Peskine99bc6492018-06-11 17:13:00 +02001304 if( block_size == 0 )
1305 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001306
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001307 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001308 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001309 if( status != PSA_SUCCESS )
1310 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001311 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001312
1313 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1314 PSA_ALG_HMAC_HASH( operation->alg ) );
1315 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001316 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001317
1318 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001319 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001320 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001321 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001322
1323 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001324 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001325 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001326 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001327
1328 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1329 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001330 hmac_cleanup:
1331 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001332 }
1333 else
1334#endif /* MBEDTLS_MD_C */
1335 {
1336 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1337 }
1338 break;
1339 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001340cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001341
Gilles Peskine2d277862018-06-18 15:41:12 +02001342 if( ( ret == 0 ) && ( status == PSA_SUCCESS ) )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001343 {
1344 return( psa_mac_abort( operation ) );
1345 }
1346 else
1347 {
1348 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001349 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001350 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001351
1352 return status;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001353 }
1354}
1355
mohammad16036df908f2018-04-02 08:34:15 -07001356psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1357 uint8_t *mac,
1358 size_t mac_size,
1359 size_t *mac_length )
1360{
1361 if( !( operation->key_usage_sign ) )
1362 return( PSA_ERROR_NOT_PERMITTED );
1363
Gilles Peskine99bc6492018-06-11 17:13:00 +02001364 return( psa_mac_finish_internal( operation, mac,
1365 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001366}
1367
Gilles Peskine2d277862018-06-18 15:41:12 +02001368#define MBEDTLS_PSA_MAC_MAX_SIZE \
1369 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1370 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001371 MBEDTLS_MAX_BLOCK_LENGTH )
1372psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1373 const uint8_t *mac,
1374 size_t mac_length )
1375{
1376 uint8_t actual_mac[MBEDTLS_PSA_MAC_MAX_SIZE];
1377 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001378 psa_status_t status;
1379
1380 if( !( operation->key_usage_verify ) )
1381 return( PSA_ERROR_NOT_PERMITTED );
1382
1383 status = psa_mac_finish_internal( operation,
1384 actual_mac, sizeof( actual_mac ),
1385 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001386 if( status != PSA_SUCCESS )
1387 return( status );
1388 if( actual_mac_length != mac_length )
1389 return( PSA_ERROR_INVALID_SIGNATURE );
1390 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1391 return( PSA_ERROR_INVALID_SIGNATURE );
1392 return( PSA_SUCCESS );
1393}
1394
1395
Gilles Peskine20035e32018-02-03 22:44:14 +01001396
1397
1398/****************************************************************/
1399/* Asymmetric cryptography */
1400/****************************************************************/
1401
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001402/* Decode the hash algorithm from alg and store the mbedtls encoding in
1403 * md_alg. Verify that the hash length is consistent. */
1404static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1405 size_t hash_length,
1406 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001407{
Gilles Peskine61b91d42018-06-08 16:09:36 +02001408 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
1409 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1410 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1411 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001412 {
1413#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001414 if( hash_length > UINT_MAX )
1415 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001416#endif
1417 }
1418 else
1419 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001420 if( mbedtls_md_get_size( md_info ) != hash_length )
1421 return( PSA_ERROR_INVALID_ARGUMENT );
1422 if( md_info == NULL )
1423 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001424 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001425 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001426}
1427
Gilles Peskine61b91d42018-06-08 16:09:36 +02001428psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1429 psa_algorithm_t alg,
1430 const uint8_t *hash,
1431 size_t hash_length,
1432 const uint8_t *salt,
1433 size_t salt_length,
1434 uint8_t *signature,
1435 size_t signature_size,
1436 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001437{
1438 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001439 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001440 *signature_length = 0;
1441 (void) salt;
1442 (void) salt_length;
1443
Gilles Peskine20035e32018-02-03 22:44:14 +01001444 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1445 return( PSA_ERROR_EMPTY_SLOT );
1446 slot = &global_data.key_slots[key];
1447 if( slot->type == PSA_KEY_TYPE_NONE )
1448 return( PSA_ERROR_EMPTY_SLOT );
1449 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1450 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001451 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001452 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001453
Gilles Peskine20035e32018-02-03 22:44:14 +01001454#if defined(MBEDTLS_RSA_C)
1455 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1456 {
1457 mbedtls_rsa_context *rsa = slot->data.rsa;
1458 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001459 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001460 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001461 if( status != PSA_SUCCESS )
1462 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001463
Gilles Peskine20035e32018-02-03 22:44:14 +01001464 if( signature_size < rsa->len )
1465 return( PSA_ERROR_BUFFER_TOO_SMALL );
1466#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001467 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001468 {
1469 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1470 MBEDTLS_MD_NONE );
1471 ret = mbedtls_rsa_pkcs1_sign( rsa,
1472 mbedtls_ctr_drbg_random,
1473 &global_data.ctr_drbg,
1474 MBEDTLS_RSA_PRIVATE,
1475 md_alg, hash_length, hash,
1476 signature );
1477 }
1478 else
1479#endif /* MBEDTLS_PKCS1_V15 */
1480#if defined(MBEDTLS_PKCS1_V21)
1481 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1482 {
1483 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1484 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1485 mbedtls_ctr_drbg_random,
1486 &global_data.ctr_drbg,
1487 MBEDTLS_RSA_PRIVATE,
1488 md_alg, hash_length, hash,
1489 signature );
1490 }
1491 else
1492#endif /* MBEDTLS_PKCS1_V21 */
1493 {
1494 return( PSA_ERROR_INVALID_ARGUMENT );
1495 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001496 if( ret == 0 )
1497 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001498 return( mbedtls_to_psa_error( ret ) );
1499 }
1500 else
1501#endif /* defined(MBEDTLS_RSA_C) */
1502#if defined(MBEDTLS_ECP_C)
1503 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1504 {
itayzafrir5c753392018-05-08 11:18:38 +03001505 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1506 int ret;
1507 const mbedtls_md_info_t *md_info;
1508 mbedtls_md_type_t md_alg;
1509 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1510 return( PSA_ERROR_BUFFER_TOO_SMALL );
1511 md_info = mbedtls_md_info_from_psa( alg );
1512 md_alg = mbedtls_md_get_type( md_info );
1513 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001514 signature, signature_length,
1515 mbedtls_ctr_drbg_random,
1516 &global_data.ctr_drbg );
itayzafrir5c753392018-05-08 11:18:38 +03001517 return( mbedtls_to_psa_error( ret ) );
1518 }
1519 else
1520#endif /* defined(MBEDTLS_ECP_C) */
1521 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001522 return( PSA_ERROR_NOT_SUPPORTED );
1523 }
itayzafrir5c753392018-05-08 11:18:38 +03001524}
1525
1526psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1527 psa_algorithm_t alg,
1528 const uint8_t *hash,
1529 size_t hash_length,
1530 const uint8_t *salt,
1531 size_t salt_length,
1532 uint8_t *signature,
1533 size_t signature_size )
1534{
1535 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001536 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001537 (void) salt;
1538 (void) salt_length;
1539
1540 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1541 return( PSA_ERROR_INVALID_ARGUMENT );
1542 slot = &global_data.key_slots[key];
1543 if( slot->type == PSA_KEY_TYPE_NONE )
1544 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001545 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001546 return( PSA_ERROR_NOT_PERMITTED );
1547
Gilles Peskine61b91d42018-06-08 16:09:36 +02001548#if defined(MBEDTLS_RSA_C)
Nir Sonnenschein1c2a7ea2018-06-05 15:01:42 +03001549 if( ( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ) ||
1550 ( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001551 {
1552 mbedtls_rsa_context *rsa = slot->data.rsa;
1553 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001554 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001555 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001556 if( status != PSA_SUCCESS )
1557 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001558
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001559 if( signature_size < rsa->len )
1560 return( PSA_ERROR_BUFFER_TOO_SMALL );
1561#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001562 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001563 {
1564 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1565 MBEDTLS_MD_NONE );
1566
1567 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001568 mbedtls_ctr_drbg_random,
1569 &global_data.ctr_drbg,
1570 MBEDTLS_RSA_PUBLIC,
1571 md_alg,
1572 hash_length,
1573 hash,
1574 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001575
1576 }
1577 else
1578#endif /* MBEDTLS_PKCS1_V15 */
1579#if defined(MBEDTLS_PKCS1_V21)
1580 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1581 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001582 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1583 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1584 mbedtls_ctr_drbg_random,
1585 &global_data.ctr_drbg,
1586 MBEDTLS_RSA_PUBLIC,
1587 md_alg, hash_length, hash,
1588 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001589 }
1590 else
1591#endif /* MBEDTLS_PKCS1_V21 */
1592 {
1593 return( PSA_ERROR_INVALID_ARGUMENT );
1594 }
1595 return( mbedtls_to_psa_error( ret ) );
1596 }
1597 else
1598#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001599#if defined(MBEDTLS_ECP_C)
1600 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1601 {
1602 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1603 int ret;
Gilles Peskine2d277862018-06-18 15:41:12 +02001604 (void) alg;
Gilles Peskine61b91d42018-06-08 16:09:36 +02001605 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length,
1606 signature, signature_size );
itayzafrir5c753392018-05-08 11:18:38 +03001607 return( mbedtls_to_psa_error( ret ) );
1608 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001609 else
1610#endif /* defined(MBEDTLS_ECP_C) */
1611 {
1612 return( PSA_ERROR_NOT_SUPPORTED );
1613 }
1614}
1615
Gilles Peskine61b91d42018-06-08 16:09:36 +02001616psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1617 psa_algorithm_t alg,
1618 const uint8_t *input,
1619 size_t input_length,
1620 const uint8_t *salt,
1621 size_t salt_length,
1622 uint8_t *output,
1623 size_t output_size,
1624 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001625{
1626 key_slot_t *slot;
1627 (void) salt;
1628 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001629 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001630
1631 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001632 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001633 slot = &global_data.key_slots[key];
1634 if( slot->type == PSA_KEY_TYPE_NONE )
1635 return( PSA_ERROR_EMPTY_SLOT );
1636 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1637 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001638 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1639 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001640
1641#if defined(MBEDTLS_RSA_C)
Nir Sonnenschein1c2a7ea2018-06-05 15:01:42 +03001642 if( ( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ) ||
Gilles Peskine61b91d42018-06-08 16:09:36 +02001643 ( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001644 {
1645 mbedtls_rsa_context *rsa = slot->data.rsa;
1646 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001647 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001648 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001649#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001650 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001651 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001652 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1653 mbedtls_ctr_drbg_random,
1654 &global_data.ctr_drbg,
1655 MBEDTLS_RSA_PUBLIC,
1656 input_length,
1657 input,
1658 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001659 }
1660 else
1661#endif /* MBEDTLS_PKCS1_V15 */
1662#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001663 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001664 {
1665 return( PSA_ERROR_NOT_SUPPORTED );
1666 }
1667 else
1668#endif /* MBEDTLS_PKCS1_V21 */
1669 {
1670 return( PSA_ERROR_INVALID_ARGUMENT );
1671 }
1672 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001673 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001674 return( mbedtls_to_psa_error( ret ) );
1675 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001676 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001677#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001678 {
1679 return( PSA_ERROR_NOT_SUPPORTED );
1680 }
1681
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001682}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001683
Gilles Peskine61b91d42018-06-08 16:09:36 +02001684psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1685 psa_algorithm_t alg,
1686 const uint8_t *input,
1687 size_t input_length,
1688 const uint8_t *salt,
1689 size_t salt_length,
1690 uint8_t *output,
1691 size_t output_size,
1692 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001693{
1694 key_slot_t *slot;
1695 (void) salt;
1696 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001697 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001698
1699 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1700 return( PSA_ERROR_EMPTY_SLOT );
1701 slot = &global_data.key_slots[key];
1702 if( slot->type == PSA_KEY_TYPE_NONE )
1703 return( PSA_ERROR_EMPTY_SLOT );
1704 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1705 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001706 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1707 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001708
1709#if defined(MBEDTLS_RSA_C)
1710 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1711 {
1712 mbedtls_rsa_context *rsa = slot->data.rsa;
1713 int ret;
1714
Gilles Peskinec4def2f2018-06-08 17:53:48 +02001715 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001716 return( PSA_ERROR_INVALID_ARGUMENT );
1717
1718#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001719 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001720 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001721 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
1722 mbedtls_ctr_drbg_random,
1723 &global_data.ctr_drbg,
1724 MBEDTLS_RSA_PRIVATE,
1725 output_length,
1726 input,
1727 output,
1728 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001729 }
1730 else
1731#endif /* MBEDTLS_PKCS1_V15 */
1732#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001733 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001734 {
1735 return( PSA_ERROR_NOT_SUPPORTED );
1736 }
1737 else
1738#endif /* MBEDTLS_PKCS1_V21 */
1739 {
1740 return( PSA_ERROR_INVALID_ARGUMENT );
1741 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001742
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001743 return( mbedtls_to_psa_error( ret ) );
1744 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001745 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001746#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001747 {
1748 return( PSA_ERROR_NOT_SUPPORTED );
1749 }
1750
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001751}
Gilles Peskine20035e32018-02-03 22:44:14 +01001752
mohammad1603503973b2018-03-12 15:59:30 +02001753/****************************************************************/
1754/* Symmetric cryptography */
1755/****************************************************************/
1756
Gilles Peskinee553c652018-06-04 16:22:46 +02001757static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1758 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001759 psa_algorithm_t alg,
1760 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001761{
1762 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1763 psa_status_t status;
1764 key_slot_t *slot;
1765 psa_key_type_t key_type;
1766 size_t key_bits;
1767 const mbedtls_cipher_info_t *cipher_info = NULL;
1768
Moran Peker41deec42018-04-04 15:43:05 +03001769 operation->alg = alg;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001770 operation->key_set = 0;
1771 operation->iv_set = 0;
1772 operation->iv_required = 1;
1773 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001774 operation->block_size = 0;
mohammad1603503973b2018-03-12 15:59:30 +02001775
1776 status = psa_get_key_information( key, &key_type, &key_bits );
1777 if( status != PSA_SUCCESS )
1778 return( status );
1779 slot = &global_data.key_slots[key];
1780
Gilles Peskinebb1072f2018-06-08 18:46:05 +02001781 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02001782 if( cipher_info == NULL )
1783 return( PSA_ERROR_NOT_SUPPORTED );
1784
mohammad1603503973b2018-03-12 15:59:30 +02001785 mbedtls_cipher_init( &operation->ctx.cipher );
1786 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03001787 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001788 {
1789 psa_cipher_abort( operation );
1790 return( mbedtls_to_psa_error( ret ) );
1791 }
1792
1793 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
Gilles Peskinee553c652018-06-04 16:22:46 +02001794 key_bits, cipher_operation );
Moran Peker41deec42018-04-04 15:43:05 +03001795 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001796 {
1797 psa_cipher_abort( operation );
1798 return( mbedtls_to_psa_error( ret ) );
1799 }
1800
mohammad16038481e742018-03-18 13:57:31 +02001801#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03001802 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02001803 {
Gilles Peskine53514202018-06-06 15:11:46 +02001804 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1805 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02001806
Moran Pekera28258c2018-05-29 16:25:04 +03001807 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02001808 {
1809 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
1810 mode = MBEDTLS_PADDING_PKCS7;
1811 break;
1812 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
1813 mode = MBEDTLS_PADDING_NONE;
1814 break;
1815 default:
Moran Pekerae382792018-05-31 14:06:17 +03001816 psa_cipher_abort( operation );
1817 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02001818 }
1819 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03001820 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03001821 {
1822 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02001823 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03001824 }
mohammad16038481e742018-03-18 13:57:31 +02001825 }
1826#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
1827
mohammad1603503973b2018-03-12 15:59:30 +02001828 operation->key_set = 1;
1829 operation->alg = alg;
Gilles Peskine7e928852018-06-04 16:23:10 +02001830 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
1831 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
1832 1 );
Moran Peker41deec42018-04-04 15:43:05 +03001833 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || ( alg == PSA_ALG_CTR ) )
mohammad16038481e742018-03-18 13:57:31 +02001834 {
mohammad160389e0f462018-04-12 08:48:45 +03001835 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02001836 }
mohammad1603503973b2018-03-12 15:59:30 +02001837
Moran Peker395db872018-05-31 14:07:14 +03001838 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001839}
1840
Gilles Peskinee553c652018-06-04 16:22:46 +02001841psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
1842 psa_key_slot_t key,
1843 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001844{
Moran Pekera28258c2018-05-29 16:25:04 +03001845 return psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT );
mohammad16038481e742018-03-18 13:57:31 +02001846}
1847
Gilles Peskinee553c652018-06-04 16:22:46 +02001848psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
1849 psa_key_slot_t key,
1850 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001851{
Moran Pekera28258c2018-05-29 16:25:04 +03001852 return psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT );
mohammad16038481e742018-03-18 13:57:31 +02001853}
1854
Gilles Peskinee553c652018-06-04 16:22:46 +02001855psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
1856 unsigned char *iv,
1857 size_t iv_size,
1858 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001859{
Moran Peker41deec42018-04-04 15:43:05 +03001860 int ret = PSA_SUCCESS;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001861 if( operation->iv_set || !( operation->iv_required ) )
Moran Peker41deec42018-04-04 15:43:05 +03001862 return( PSA_ERROR_BAD_STATE );
1863 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02001864 {
Moran Peker41deec42018-04-04 15:43:05 +03001865 ret = PSA_ERROR_BUFFER_TOO_SMALL;
1866 goto exit;
1867 }
Gilles Peskine7e928852018-06-04 16:23:10 +02001868 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
1869 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03001870 if( ret != 0 )
1871 {
1872 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02001873 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02001874 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001875
mohammad16038481e742018-03-18 13:57:31 +02001876 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03001877 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001878
Moran Peker395db872018-05-31 14:07:14 +03001879exit:
1880 if( ret != PSA_SUCCESS )
1881 psa_cipher_abort( operation );
1882 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02001883}
1884
Gilles Peskinee553c652018-06-04 16:22:46 +02001885psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
1886 const unsigned char *iv,
1887 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001888{
Moran Peker41deec42018-04-04 15:43:05 +03001889 int ret = PSA_SUCCESS;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001890 if( operation->iv_set || !( operation->iv_required ) )
Moran Peker41deec42018-04-04 15:43:05 +03001891 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03001892 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03001893 {
Moran Pekerae382792018-05-31 14:06:17 +03001894 psa_cipher_abort( operation );
1895 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03001896 }
mohammad1603503973b2018-03-12 15:59:30 +02001897 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001898 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001899 {
1900 psa_cipher_abort( operation );
1901 return( mbedtls_to_psa_error( ret ) );
1902 }
1903
1904 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02001905
Moran Peker395db872018-05-31 14:07:14 +03001906 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001907}
1908
Gilles Peskinee553c652018-06-04 16:22:46 +02001909psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
1910 const uint8_t *input,
1911 size_t input_length,
1912 unsigned char *output,
1913 size_t output_size,
1914 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001915{
1916 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02001917 size_t expected_output_size;
1918 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
1919 {
1920 /* Take the unprocessed partial block left over from previous
1921 * update calls, if any, plus the input to this call. Remove
1922 * the last partial block, if any. You get the data that will be
1923 * output in this call. */
1924 expected_output_size =
1925 ( operation->ctx.cipher.unprocessed_len + input_length )
1926 / operation->block_size * operation->block_size;
1927 }
1928 else
1929 {
1930 expected_output_size = input_length;
1931 }
1932 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03001933 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02001934
mohammad1603503973b2018-03-12 15:59:30 +02001935 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02001936 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03001937 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001938 {
1939 psa_cipher_abort( operation );
1940 return( mbedtls_to_psa_error( ret ) );
1941 }
1942
Moran Peker395db872018-05-31 14:07:14 +03001943 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001944}
1945
Gilles Peskinee553c652018-06-04 16:22:46 +02001946psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
1947 uint8_t *output,
1948 size_t output_size,
1949 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001950{
1951 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02001952 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03001953
mohammad1603503973b2018-03-12 15:59:30 +02001954 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001955 {
Moran Peker7cb22b82018-06-05 11:40:02 +03001956 psa_cipher_abort( operation );
1957 return( PSA_ERROR_BAD_STATE );
1958 }
1959 if( operation->iv_required && ! operation->iv_set )
1960 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001961 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001962 return( PSA_ERROR_BAD_STATE );
1963 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001964 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
1965 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03001966 {
Gilles Peskine53514202018-06-06 15:11:46 +02001967 psa_algorithm_t padding_mode =
1968 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03001969 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02001970 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001971 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001972 return( PSA_ERROR_TAMPERING_DETECTED );
1973 }
Gilles Peskine53514202018-06-06 15:11:46 +02001974 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03001975 {
1976 if( operation->ctx.cipher.unprocessed_len != 0 )
1977 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001978 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001979 return( PSA_ERROR_INVALID_ARGUMENT );
1980 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02001981 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001982 }
1983
1984 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02001985 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03001986 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001987 {
1988 psa_cipher_abort( operation );
1989 return( mbedtls_to_psa_error( ret ) );
1990 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001991 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001992 memcpy( output, temp_output_buffer, *output_length );
1993 else
1994 {
1995 psa_cipher_abort( operation );
1996 return( PSA_ERROR_BUFFER_TOO_SMALL );
1997 }
mohammad1603503973b2018-03-12 15:59:30 +02001998
Moran Peker4c80d832018-04-22 20:15:31 +03001999 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002000}
2001
Gilles Peskinee553c652018-06-04 16:22:46 +02002002psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2003{
mohammad1603503973b2018-03-12 15:59:30 +02002004 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002005
Moran Peker41deec42018-04-04 15:43:05 +03002006 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002007 operation->key_set = 0;
2008 operation->iv_set = 0;
2009 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002010 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002011 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002012
Moran Peker395db872018-05-31 14:07:14 +03002013 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002014}
2015
Gilles Peskinea0655c32018-04-30 17:06:50 +02002016
mohammad16038cc1cee2018-03-28 01:21:33 +03002017/****************************************************************/
2018/* Key Policy */
2019/****************************************************************/
2020
Gilles Peskine2d277862018-06-18 15:41:12 +02002021void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002022{
mohammad16036df908f2018-04-02 08:34:15 -07002023 memset( policy, 0, sizeof( psa_key_policy_t ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002024}
2025
Gilles Peskine2d277862018-06-18 15:41:12 +02002026void psa_key_policy_set_usage( psa_key_policy_t *policy,
2027 psa_key_usage_t usage,
2028 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002029{
mohammad16034eed7572018-03-28 05:14:59 -07002030 policy->usage = usage;
2031 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002032}
2033
Gilles Peskine2d277862018-06-18 15:41:12 +02002034psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002035{
mohammad16036df908f2018-04-02 08:34:15 -07002036 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002037}
2038
Gilles Peskine2d277862018-06-18 15:41:12 +02002039psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002040{
mohammad16036df908f2018-04-02 08:34:15 -07002041 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002042}
2043
Gilles Peskine2d277862018-06-18 15:41:12 +02002044psa_status_t psa_set_key_policy( psa_key_slot_t key,
2045 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002046{
2047 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002048
2049 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
2050 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002051
mohammad16038cc1cee2018-03-28 01:21:33 +03002052 slot = &global_data.key_slots[key];
2053 if( slot->type != PSA_KEY_TYPE_NONE )
2054 return( PSA_ERROR_OCCUPIED_SLOT );
2055
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002056 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT
Gilles Peskine2d277862018-06-18 15:41:12 +02002057 | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_SIGN
2058 | PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002059 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002060
mohammad16036df908f2018-04-02 08:34:15 -07002061 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002062
2063 return( PSA_SUCCESS );
2064}
2065
Gilles Peskine2d277862018-06-18 15:41:12 +02002066psa_status_t psa_get_key_policy( psa_key_slot_t key,
2067 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002068{
2069 key_slot_t *slot;
2070
2071 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
2072 return( PSA_ERROR_INVALID_ARGUMENT );
2073
2074 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002075
mohammad16036df908f2018-04-02 08:34:15 -07002076 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002077
2078 return( PSA_SUCCESS );
2079}
Gilles Peskine20035e32018-02-03 22:44:14 +01002080
Gilles Peskinea0655c32018-04-30 17:06:50 +02002081
2082
mohammad1603804cd712018-03-20 22:44:08 +02002083/****************************************************************/
2084/* Key Lifetime */
2085/****************************************************************/
2086
Gilles Peskine2d277862018-06-18 15:41:12 +02002087psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2088 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002089{
2090 key_slot_t *slot;
2091
2092 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
2093 return( PSA_ERROR_INVALID_ARGUMENT );
2094
2095 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002096
mohammad1603804cd712018-03-20 22:44:08 +02002097 *lifetime = slot->lifetime;
2098
2099 return( PSA_SUCCESS );
2100}
2101
Gilles Peskine2d277862018-06-18 15:41:12 +02002102psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2103 const 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
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002110 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2111 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002112 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2113 return( PSA_ERROR_INVALID_ARGUMENT );
2114
mohammad1603804cd712018-03-20 22:44:08 +02002115 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002116 if( slot->type != PSA_KEY_TYPE_NONE )
2117 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002118
Moran Pekerd7326592018-05-29 16:56:39 +03002119 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002120 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002121
mohammad1603060ad8a2018-03-20 14:28:38 -07002122 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002123
2124 return( PSA_SUCCESS );
2125}
2126
Gilles Peskine20035e32018-02-03 22:44:14 +01002127
mohammad16035955c982018-04-26 00:53:03 +03002128/****************************************************************/
2129/* AEAD */
2130/****************************************************************/
2131psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2132 psa_algorithm_t alg,
2133 const uint8_t *nonce,
2134 size_t nonce_length,
2135 const uint8_t *additional_data,
2136 size_t additional_data_length,
2137 const uint8_t *plaintext,
2138 size_t plaintext_length,
2139 uint8_t *ciphertext,
2140 size_t ciphertext_size,
2141 size_t *ciphertext_length )
2142{
2143 int ret;
2144 psa_status_t status;
2145 key_slot_t *slot;
2146 psa_key_type_t key_type;
2147 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002148 uint8_t *tag;
2149 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002150 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002151 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002152
mohammad1603f08a5502018-06-03 15:05:47 +03002153 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002154
mohammad16035955c982018-04-26 00:53:03 +03002155 status = psa_get_key_information( key, &key_type, &key_bits );
2156 if( status != PSA_SUCCESS )
2157 return( status );
2158 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002159 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002160 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002161
mohammad16035ed06212018-06-06 13:09:34 +03002162 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2163 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002164 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002165 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002166
mohammad1603f14394b2018-06-04 14:33:19 +03002167 if( !( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
2168 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002169
Gilles Peskine2d277862018-06-18 15:41:12 +02002170 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2171 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002172 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002173
mohammad16035955c982018-04-26 00:53:03 +03002174 if( alg == PSA_ALG_GCM )
2175 {
2176 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002177 tag_length = 16;
2178
mohammad160396910d82018-06-04 14:33:00 +03002179 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2180 return( PSA_ERROR_INVALID_ARGUMENT );
2181
mohammad160315223a82018-06-03 17:19:55 +03002182 //make sure we have place to hold the tag in the ciphertext buffer
2183 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002184 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002185
2186 //update the tag pointer to point to the end of the ciphertext_length
2187 tag = ciphertext + plaintext_length;
2188
mohammad16035955c982018-04-26 00:53:03 +03002189 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002190 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002191 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002192 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002193 if( ret != 0 )
2194 {
2195 mbedtls_gcm_free( &gcm );
2196 return( mbedtls_to_psa_error( ret ) );
2197 }
2198 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002199 plaintext_length, nonce,
2200 nonce_length, additional_data,
2201 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002202 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002203 mbedtls_gcm_free( &gcm );
2204 }
2205 else if( alg == PSA_ALG_CCM )
2206 {
2207 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002208 tag_length = 16;
2209
mohammad160396910d82018-06-04 14:33:00 +03002210 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2211 return( PSA_ERROR_INVALID_ARGUMENT );
2212
mohammad160347ddf3d2018-04-26 01:11:21 +03002213 if( nonce_length < 7 || nonce_length > 13 )
2214 return( PSA_ERROR_INVALID_ARGUMENT );
2215
mohammad160315223a82018-06-03 17:19:55 +03002216 //make sure we have place to hold the tag in the ciphertext buffer
2217 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002218 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002219
2220 //update the tag pointer to point to the end of the ciphertext_length
2221 tag = ciphertext + plaintext_length;
2222
2223
2224
mohammad16035955c982018-04-26 00:53:03 +03002225 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002226 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002227 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002228 if( ret != 0 )
2229 {
2230 mbedtls_ccm_free( &ccm );
2231 return( mbedtls_to_psa_error( ret ) );
2232 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002233 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
2234 nonce, nonce_length, additional_data,
2235 additional_data_length,
2236 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002237 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002238 mbedtls_ccm_free( &ccm );
2239 }
mohammad16035c8845f2018-05-09 05:40:09 -07002240 else
2241 {
mohammad1603554faad2018-06-03 15:07:38 +03002242 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002243 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002244
mohammad160315223a82018-06-03 17:19:55 +03002245 if( ret != 0 )
2246 {
2247 memset( ciphertext, 0, ciphertext_size );
2248 return( mbedtls_to_psa_error( ret ) );
2249 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002250
mohammad160315223a82018-06-03 17:19:55 +03002251 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002252 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002253}
2254
Gilles Peskineee652a32018-06-01 19:23:52 +02002255/* Locate the tag in a ciphertext buffer containing the encrypted data
2256 * followed by the tag. Return the length of the part preceding the tag in
2257 * *plaintext_length. This is the size of the plaintext in modes where
2258 * the encrypted data has the same size as the plaintext, such as
2259 * CCM and GCM. */
2260static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2261 const uint8_t *ciphertext,
2262 size_t ciphertext_length,
2263 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002264 const uint8_t **p_tag )
2265{
2266 size_t payload_length;
2267 if( tag_length > ciphertext_length )
2268 return( PSA_ERROR_INVALID_ARGUMENT );
2269 payload_length = ciphertext_length - tag_length;
2270 if( payload_length > plaintext_size )
2271 return( PSA_ERROR_BUFFER_TOO_SMALL );
2272 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002273 return( PSA_SUCCESS );
2274}
2275
mohammad16035955c982018-04-26 00:53:03 +03002276psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2277 psa_algorithm_t alg,
2278 const uint8_t *nonce,
2279 size_t nonce_length,
2280 const uint8_t *additional_data,
2281 size_t additional_data_length,
2282 const uint8_t *ciphertext,
2283 size_t ciphertext_length,
2284 uint8_t *plaintext,
2285 size_t plaintext_size,
2286 size_t *plaintext_length )
2287{
2288 int ret;
2289 psa_status_t status;
2290 key_slot_t *slot;
2291 psa_key_type_t key_type;
2292 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002293 const uint8_t *tag;
2294 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002295 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002296 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002297
Gilles Peskineee652a32018-06-01 19:23:52 +02002298 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002299
mohammad16035955c982018-04-26 00:53:03 +03002300 status = psa_get_key_information( key, &key_type, &key_bits );
2301 if( status != PSA_SUCCESS )
2302 return( status );
2303 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002304 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002305 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002306
mohammad16035ed06212018-06-06 13:09:34 +03002307 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2308 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002309 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002310 return( PSA_ERROR_NOT_SUPPORTED );
2311
mohammad1603f14394b2018-06-04 14:33:19 +03002312 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2313 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002314
Gilles Peskine2d277862018-06-18 15:41:12 +02002315 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2316 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002317 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002318
mohammad16035955c982018-04-26 00:53:03 +03002319 if( alg == PSA_ALG_GCM )
2320 {
2321 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002322
Gilles Peskineee652a32018-06-01 19:23:52 +02002323 tag_length = 16;
2324 status = psa_aead_unpadded_locate_tag( tag_length,
2325 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002326 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002327 if( status != PSA_SUCCESS )
2328 return( status );
2329
mohammad16035955c982018-04-26 00:53:03 +03002330 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002331 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002332 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002333 if( ret != 0 )
2334 {
2335 mbedtls_gcm_free( &gcm );
2336 return( mbedtls_to_psa_error( ret ) );
2337 }
mohammad16035955c982018-04-26 00:53:03 +03002338
Gilles Peskineee652a32018-06-01 19:23:52 +02002339 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002340 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002341 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002342 additional_data,
2343 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002344 tag, tag_length,
2345 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002346 mbedtls_gcm_free( &gcm );
2347 }
2348 else if( alg == PSA_ALG_CCM )
2349 {
2350 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002351
mohammad160347ddf3d2018-04-26 01:11:21 +03002352 if( nonce_length < 7 || nonce_length > 13 )
2353 return( PSA_ERROR_INVALID_ARGUMENT );
2354
mohammad16039375f842018-06-03 14:28:24 +03002355 tag_length = 16;
2356 status = psa_aead_unpadded_locate_tag( tag_length,
2357 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002358 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002359 if( status != PSA_SUCCESS )
2360 return( status );
2361
mohammad16035955c982018-04-26 00:53:03 +03002362 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002363 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002364 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002365 if( ret != 0 )
2366 {
2367 mbedtls_ccm_free( &ccm );
2368 return( mbedtls_to_psa_error( ret ) );
2369 }
mohammad160360a64d02018-06-03 17:20:42 +03002370 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002371 nonce, nonce_length,
2372 additional_data, additional_data_length,
2373 ciphertext, plaintext,
2374 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002375 mbedtls_ccm_free( &ccm );
2376 }
mohammad160339574652018-06-01 04:39:53 -07002377 else
2378 {
mohammad1603554faad2018-06-03 15:07:38 +03002379 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002380 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002381
Gilles Peskineee652a32018-06-01 19:23:52 +02002382 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002383 memset( plaintext, 0, plaintext_size );
2384 else
2385 *plaintext_length = ciphertext_length - tag_length;
2386
Gilles Peskineee652a32018-06-01 19:23:52 +02002387 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002388}
2389
Gilles Peskinea0655c32018-04-30 17:06:50 +02002390
Gilles Peskine20035e32018-02-03 22:44:14 +01002391/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002392/* Module setup */
2393/****************************************************************/
2394
Gilles Peskinee59236f2018-01-27 23:32:46 +01002395void mbedtls_psa_crypto_free( void )
2396{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002397 size_t key;
2398 for( key = 1; key < MBEDTLS_PSA_KEY_SLOT_COUNT; key++ )
2399 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002400 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2401 mbedtls_entropy_free( &global_data.entropy );
2402 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2403}
2404
2405psa_status_t psa_crypto_init( void )
2406{
2407 int ret;
2408 const unsigned char drbg_seed[] = "PSA";
2409
2410 if( global_data.initialized != 0 )
2411 return( PSA_SUCCESS );
2412
2413 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2414 mbedtls_entropy_init( &global_data.entropy );
2415 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2416
2417 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2418 mbedtls_entropy_func,
2419 &global_data.entropy,
2420 drbg_seed, sizeof( drbg_seed ) - 1 );
2421 if( ret != 0 )
2422 goto exit;
2423
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002424 global_data.initialized = 1;
2425
Gilles Peskinee59236f2018-01-27 23:32:46 +01002426exit:
2427 if( ret != 0 )
2428 mbedtls_psa_crypto_free( );
2429 return( mbedtls_to_psa_error( ret ) );
2430}
2431
2432#endif /* MBEDTLS_PSA_CRYPTO_C */