blob: eadd4289033feb817866b2f0dd58bbc141319656 [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
97typedef struct {
98 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +030099 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200100 psa_key_lifetime_t lifetime;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100101 union {
102 struct raw_data {
103 uint8_t *data;
104 size_t bytes;
105 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100106#if defined(MBEDTLS_RSA_C)
107 mbedtls_rsa_context *rsa;
108#endif /* MBEDTLS_RSA_C */
109#if defined(MBEDTLS_ECP_C)
110 mbedtls_ecp_keypair *ecp;
111#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100112 } data;
113} key_slot_t;
114
Gilles Peskinee59236f2018-01-27 23:32:46 +0100115typedef struct {
116 int initialized;
117 mbedtls_entropy_context entropy;
118 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100119 key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100120} psa_global_data_t;
121
122static psa_global_data_t global_data;
123
124static psa_status_t mbedtls_to_psa_error( int ret )
125{
Gilles Peskinea5905292018-02-07 20:59:33 +0100126 /* If there's both a high-level code and low-level code, dispatch on
127 * the high-level code. */
128 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100129 {
130 case 0:
131 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100132
133 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
134 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
135 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
136 return( PSA_ERROR_NOT_SUPPORTED );
137 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
138 return( PSA_ERROR_HARDWARE_FAILURE );
139
140 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
141 return( PSA_ERROR_HARDWARE_FAILURE );
142
143 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
144 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
145 return( PSA_ERROR_NOT_SUPPORTED );
146 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
147 return( PSA_ERROR_HARDWARE_FAILURE );
148
149 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
150 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
151 return( PSA_ERROR_NOT_SUPPORTED );
152 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
153 return( PSA_ERROR_HARDWARE_FAILURE );
154
155 case MBEDTLS_ERR_CCM_BAD_INPUT:
156 return( PSA_ERROR_INVALID_ARGUMENT );
157 case MBEDTLS_ERR_CCM_AUTH_FAILED:
158 return( PSA_ERROR_INVALID_SIGNATURE );
159 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
160 return( PSA_ERROR_HARDWARE_FAILURE );
161
162 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
163 return( PSA_ERROR_NOT_SUPPORTED );
164 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
165 return( PSA_ERROR_INVALID_ARGUMENT );
166 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
167 return( PSA_ERROR_INSUFFICIENT_MEMORY );
168 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
169 return( PSA_ERROR_INVALID_PADDING );
170 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
171 return( PSA_ERROR_BAD_STATE );
172 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
173 return( PSA_ERROR_INVALID_SIGNATURE );
174 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
175 return( PSA_ERROR_TAMPERING_DETECTED );
176 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
177 return( PSA_ERROR_HARDWARE_FAILURE );
178
179 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
180 return( PSA_ERROR_HARDWARE_FAILURE );
181
182 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
183 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
184 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
185 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
186 return( PSA_ERROR_NOT_SUPPORTED );
187 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
188 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
189
190 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
191 return( PSA_ERROR_NOT_SUPPORTED );
192 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
193 return( PSA_ERROR_HARDWARE_FAILURE );
194
Gilles Peskinee59236f2018-01-27 23:32:46 +0100195 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
196 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
197 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
198 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100199
200 case MBEDTLS_ERR_GCM_AUTH_FAILED:
201 return( PSA_ERROR_INVALID_SIGNATURE );
202 case MBEDTLS_ERR_GCM_BAD_INPUT:
203 return( PSA_ERROR_NOT_SUPPORTED );
204 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
205 return( PSA_ERROR_HARDWARE_FAILURE );
206
207 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
208 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
209 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
210 return( PSA_ERROR_HARDWARE_FAILURE );
211
212 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
213 return( PSA_ERROR_NOT_SUPPORTED );
214 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
215 return( PSA_ERROR_INVALID_ARGUMENT );
216 case MBEDTLS_ERR_MD_ALLOC_FAILED:
217 return( PSA_ERROR_INSUFFICIENT_MEMORY );
218 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
219 return( PSA_ERROR_STORAGE_FAILURE );
220 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
221 return( PSA_ERROR_HARDWARE_FAILURE );
222
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100223 case MBEDTLS_ERR_PK_ALLOC_FAILED:
224 return( PSA_ERROR_INSUFFICIENT_MEMORY );
225 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
226 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
227 return( PSA_ERROR_INVALID_ARGUMENT );
228 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100229 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100230 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
231 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
232 return( PSA_ERROR_INVALID_ARGUMENT );
233 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
234 return( PSA_ERROR_NOT_SUPPORTED );
235 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
236 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
237 return( PSA_ERROR_NOT_PERMITTED );
238 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
239 return( PSA_ERROR_INVALID_ARGUMENT );
240 case MBEDTLS_ERR_PK_INVALID_ALG:
241 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
242 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
243 return( PSA_ERROR_NOT_SUPPORTED );
244 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
245 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100246 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
247 return( PSA_ERROR_HARDWARE_FAILURE );
248
249 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
250 return( PSA_ERROR_HARDWARE_FAILURE );
251
252 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
253 return( PSA_ERROR_INVALID_ARGUMENT );
254 case MBEDTLS_ERR_RSA_INVALID_PADDING:
255 return( PSA_ERROR_INVALID_PADDING );
256 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
257 return( PSA_ERROR_HARDWARE_FAILURE );
258 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
259 return( PSA_ERROR_INVALID_ARGUMENT );
260 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
261 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
262 return( PSA_ERROR_TAMPERING_DETECTED );
263 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
264 return( PSA_ERROR_INVALID_SIGNATURE );
265 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
266 return( PSA_ERROR_BUFFER_TOO_SMALL );
267 case MBEDTLS_ERR_RSA_RNG_FAILED:
268 return( PSA_ERROR_INSUFFICIENT_MEMORY );
269 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
270 return( PSA_ERROR_NOT_SUPPORTED );
271 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
272 return( PSA_ERROR_HARDWARE_FAILURE );
273
274 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
275 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
276 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
277 return( PSA_ERROR_HARDWARE_FAILURE );
278
279 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
280 return( PSA_ERROR_INVALID_ARGUMENT );
281 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
282 return( PSA_ERROR_HARDWARE_FAILURE );
283
itayzafrir5c753392018-05-08 11:18:38 +0300284 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300285 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300286 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300287 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
288 return( PSA_ERROR_BUFFER_TOO_SMALL );
289 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
290 return( PSA_ERROR_NOT_SUPPORTED );
291 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
292 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
293 return( PSA_ERROR_INVALID_SIGNATURE );
294 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
295 return( PSA_ERROR_INSUFFICIENT_MEMORY );
296 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
297 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300298
Gilles Peskinee59236f2018-01-27 23:32:46 +0100299 default:
300 return( PSA_ERROR_UNKNOWN_ERROR );
301 }
302}
303
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100304
305
306/****************************************************************/
307/* Key management */
308/****************************************************************/
309
310psa_status_t psa_import_key(psa_key_slot_t key,
311 psa_key_type_t type,
312 const uint8_t *data,
313 size_t data_length)
314{
315 key_slot_t *slot;
316
317 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
318 return( PSA_ERROR_INVALID_ARGUMENT );
319 slot = &global_data.key_slots[key];
320 if( slot->type != PSA_KEY_TYPE_NONE )
321 return( PSA_ERROR_OCCUPIED_SLOT );
322
Gilles Peskine8c9def32018-02-08 10:02:12 +0100323 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100324 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100325 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100326 if( data_length > SIZE_MAX / 8 )
327 return( PSA_ERROR_NOT_SUPPORTED );
328 slot->data.raw.data = mbedtls_calloc( 1, data_length );
329 if( slot->data.raw.data == NULL )
330 return( PSA_ERROR_INSUFFICIENT_MEMORY );
331 memcpy( slot->data.raw.data, data, data_length );
332 slot->data.raw.bytes = data_length;
333 }
334 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100335#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100336 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
337 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
338 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100339 {
340 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100341 mbedtls_pk_context pk;
342 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100343 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
344 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
345 else
346 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100347 if( ret != 0 )
348 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100349 switch( mbedtls_pk_get_type( &pk ) )
350 {
351#if defined(MBEDTLS_RSA_C)
352 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100353 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
354 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine969ac722018-01-28 18:16:59 +0100355 slot->data.rsa = pk.pk_ctx;
356 else
357 return( PSA_ERROR_INVALID_ARGUMENT );
358 break;
359#endif /* MBEDTLS_RSA_C */
360#if defined(MBEDTLS_ECP_C)
361 case MBEDTLS_PK_ECKEY:
362 if( PSA_KEY_TYPE_IS_ECC( type ) )
363 {
364 // TODO: check curve
365 slot->data.ecp = pk.pk_ctx;
366 }
367 else
368 return( PSA_ERROR_INVALID_ARGUMENT );
369 break;
370#endif /* MBEDTLS_ECP_C */
371 default:
372 return( PSA_ERROR_INVALID_ARGUMENT );
373 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100374 }
375 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100376#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100377 {
378 return( PSA_ERROR_NOT_SUPPORTED );
379 }
380
381 slot->type = type;
382 return( PSA_SUCCESS );
383}
384
385psa_status_t psa_destroy_key(psa_key_slot_t key)
386{
387 key_slot_t *slot;
388
389 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
390 return( PSA_ERROR_INVALID_ARGUMENT );
391 slot = &global_data.key_slots[key];
392 if( slot->type == PSA_KEY_TYPE_NONE )
393 return( PSA_ERROR_EMPTY_SLOT );
394
Gilles Peskine8c9def32018-02-08 10:02:12 +0100395 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100396 {
397 mbedtls_free( slot->data.raw.data );
398 }
399 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100400#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100401 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
402 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100403 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100404 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100405 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100406 }
407 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100408#endif /* defined(MBEDTLS_RSA_C) */
409#if defined(MBEDTLS_ECP_C)
410 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
411 {
412 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100413 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100414 }
415 else
416#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100417 {
418 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100419 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100420 return( PSA_ERROR_TAMPERING_DETECTED );
421 }
422
423 mbedtls_zeroize( slot, sizeof( *slot ) );
424 return( PSA_SUCCESS );
425}
426
427psa_status_t psa_get_key_information(psa_key_slot_t key,
428 psa_key_type_t *type,
429 size_t *bits)
430{
431 key_slot_t *slot;
432
433 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100434 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100435 slot = &global_data.key_slots[key];
436 if( type != NULL )
437 *type = slot->type;
438 if( bits != NULL )
439 *bits = 0;
440 if( slot->type == PSA_KEY_TYPE_NONE )
441 return( PSA_ERROR_EMPTY_SLOT );
442
Gilles Peskine8c9def32018-02-08 10:02:12 +0100443 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100444 {
445 if( bits != NULL )
446 *bits = slot->data.raw.bytes * 8;
447 }
448 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100449#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100450 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
451 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100452 {
453 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100454 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100455 }
456 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100457#endif /* defined(MBEDTLS_RSA_C) */
458#if defined(MBEDTLS_ECP_C)
459 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
460 {
461 if( bits != NULL )
462 *bits = slot->data.ecp->grp.pbits;
463 }
464 else
465#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100466 {
467 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100468 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100469 return( PSA_ERROR_TAMPERING_DETECTED );
470 }
471
472 return( PSA_SUCCESS );
473}
474
475psa_status_t psa_export_key(psa_key_slot_t key,
476 uint8_t *data,
477 size_t data_size,
478 size_t *data_length)
479{
480 key_slot_t *slot;
481
482 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100483 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100484 slot = &global_data.key_slots[key];
485 if( slot->type == PSA_KEY_TYPE_NONE )
486 return( PSA_ERROR_EMPTY_SLOT );
487
mohammad160306e79202018-03-28 13:17:44 +0300488 if( !( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) )
489 return( PSA_ERROR_NOT_PERMITTED );
490
Gilles Peskine8c9def32018-02-08 10:02:12 +0100491 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100492 {
493 if( slot->data.raw.bytes > data_size )
494 return( PSA_ERROR_BUFFER_TOO_SMALL );
495 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
496 *data_length = slot->data.raw.bytes;
497 return( PSA_SUCCESS );
498 }
499 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100500#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100501 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
502 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100503 PSA_KEY_TYPE_IS_ECC( slot->type ) )
504 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100505 mbedtls_pk_context pk;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100506 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100507 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100508 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
509 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine969ac722018-01-28 18:16:59 +0100510 {
511 pk.pk_info = &mbedtls_rsa_info;
512 pk.pk_ctx = slot->data.rsa;
513 }
514 else
515 {
516 pk.pk_info = &mbedtls_eckey_info;
517 pk.pk_ctx = slot->data.ecp;
518 }
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100519 if( PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
520 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
521 else
522 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100523 if( ret < 0 )
524 return( mbedtls_to_psa_error( ret ) );
525 *data_length = ret;
526 return( PSA_SUCCESS );
527 }
528 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100529#endif /* defined(MBEDTLS_PK_WRITE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100530 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100531 /* This shouldn't happen in the reference implementation, but
532 it is valid for a special-purpose implementation to omit
533 support for exporting certain key types. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100534 return( PSA_ERROR_NOT_SUPPORTED );
535 }
536}
537
538
539
540/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100541/* Message digests */
542/****************************************************************/
543
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100544static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100545{
546 switch( alg )
547 {
548#if defined(MBEDTLS_MD2_C)
549 case PSA_ALG_MD2:
550 return( &mbedtls_md2_info );
551#endif
552#if defined(MBEDTLS_MD4_C)
553 case PSA_ALG_MD4:
554 return( &mbedtls_md4_info );
555#endif
556#if defined(MBEDTLS_MD5_C)
557 case PSA_ALG_MD5:
558 return( &mbedtls_md5_info );
559#endif
560#if defined(MBEDTLS_RIPEMD160_C)
561 case PSA_ALG_RIPEMD160:
562 return( &mbedtls_ripemd160_info );
563#endif
564#if defined(MBEDTLS_SHA1_C)
565 case PSA_ALG_SHA_1:
566 return( &mbedtls_sha1_info );
567#endif
568#if defined(MBEDTLS_SHA256_C)
569 case PSA_ALG_SHA_224:
570 return( &mbedtls_sha224_info );
571 case PSA_ALG_SHA_256:
572 return( &mbedtls_sha256_info );
573#endif
574#if defined(MBEDTLS_SHA512_C)
575 case PSA_ALG_SHA_384:
576 return( &mbedtls_sha384_info );
577 case PSA_ALG_SHA_512:
578 return( &mbedtls_sha512_info );
579#endif
580 default:
581 return( NULL );
582 }
583}
584
585#if 0
586static psa_algorithm_t mbedtls_md_alg_to_psa( mbedtls_md_type_t md_alg )
587{
588 switch( md_alg )
589 {
590 case MBEDTLS_MD_NONE:
591 return( 0 );
592 case MBEDTLS_MD_MD2:
593 return( PSA_ALG_MD2 );
594 case MBEDTLS_MD_MD4:
595 return( PSA_ALG_MD4 );
596 case MBEDTLS_MD_MD5:
597 return( PSA_ALG_MD5 );
598 case MBEDTLS_MD_SHA1:
599 return( PSA_ALG_SHA_1 );
600 case MBEDTLS_MD_SHA224:
601 return( PSA_ALG_SHA_224 );
602 case MBEDTLS_MD_SHA256:
603 return( PSA_ALG_SHA_256 );
604 case MBEDTLS_MD_SHA384:
605 return( PSA_ALG_SHA_384 );
606 case MBEDTLS_MD_SHA512:
607 return( PSA_ALG_SHA_512 );
608 case MBEDTLS_MD_RIPEMD160:
609 return( PSA_ALG_RIPEMD160 );
610 default:
Gilles Peskine47c1bc02018-03-20 17:55:04 +0100611 return( 0 );
Gilles Peskine20035e32018-02-03 22:44:14 +0100612 }
613}
614#endif
615
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100616psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
617{
618 switch( operation->alg )
619 {
620#if defined(MBEDTLS_MD2_C)
621 case PSA_ALG_MD2:
622 mbedtls_md2_free( &operation->ctx.md2 );
623 break;
624#endif
625#if defined(MBEDTLS_MD4_C)
626 case PSA_ALG_MD4:
627 mbedtls_md4_free( &operation->ctx.md4 );
628 break;
629#endif
630#if defined(MBEDTLS_MD5_C)
631 case PSA_ALG_MD5:
632 mbedtls_md5_free( &operation->ctx.md5 );
633 break;
634#endif
635#if defined(MBEDTLS_RIPEMD160_C)
636 case PSA_ALG_RIPEMD160:
637 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
638 break;
639#endif
640#if defined(MBEDTLS_SHA1_C)
641 case PSA_ALG_SHA_1:
642 mbedtls_sha1_free( &operation->ctx.sha1 );
643 break;
644#endif
645#if defined(MBEDTLS_SHA256_C)
646 case PSA_ALG_SHA_224:
647 case PSA_ALG_SHA_256:
648 mbedtls_sha256_free( &operation->ctx.sha256 );
649 break;
650#endif
651#if defined(MBEDTLS_SHA512_C)
652 case PSA_ALG_SHA_384:
653 case PSA_ALG_SHA_512:
654 mbedtls_sha512_free( &operation->ctx.sha512 );
655 break;
656#endif
657 default:
658 return( PSA_ERROR_NOT_SUPPORTED );
659 }
660 operation->alg = 0;
661 return( PSA_SUCCESS );
662}
663
664psa_status_t psa_hash_start( psa_hash_operation_t *operation,
665 psa_algorithm_t alg )
666{
667 int ret;
668 operation->alg = 0;
669 switch( alg )
670 {
671#if defined(MBEDTLS_MD2_C)
672 case PSA_ALG_MD2:
673 mbedtls_md2_init( &operation->ctx.md2 );
674 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
675 break;
676#endif
677#if defined(MBEDTLS_MD4_C)
678 case PSA_ALG_MD4:
679 mbedtls_md4_init( &operation->ctx.md4 );
680 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
681 break;
682#endif
683#if defined(MBEDTLS_MD5_C)
684 case PSA_ALG_MD5:
685 mbedtls_md5_init( &operation->ctx.md5 );
686 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
687 break;
688#endif
689#if defined(MBEDTLS_RIPEMD160_C)
690 case PSA_ALG_RIPEMD160:
691 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
692 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
693 break;
694#endif
695#if defined(MBEDTLS_SHA1_C)
696 case PSA_ALG_SHA_1:
697 mbedtls_sha1_init( &operation->ctx.sha1 );
698 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
699 break;
700#endif
701#if defined(MBEDTLS_SHA256_C)
702 case PSA_ALG_SHA_224:
703 mbedtls_sha256_init( &operation->ctx.sha256 );
704 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
705 break;
706 case PSA_ALG_SHA_256:
707 mbedtls_sha256_init( &operation->ctx.sha256 );
708 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
709 break;
710#endif
711#if defined(MBEDTLS_SHA512_C)
712 case PSA_ALG_SHA_384:
713 mbedtls_sha512_init( &operation->ctx.sha512 );
714 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
715 break;
716 case PSA_ALG_SHA_512:
717 mbedtls_sha512_init( &operation->ctx.sha512 );
718 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
719 break;
720#endif
721 default:
722 return( PSA_ERROR_NOT_SUPPORTED );
723 }
724 if( ret == 0 )
725 operation->alg = alg;
726 else
727 psa_hash_abort( operation );
728 return( mbedtls_to_psa_error( ret ) );
729}
730
731psa_status_t psa_hash_update( psa_hash_operation_t *operation,
732 const uint8_t *input,
733 size_t input_length )
734{
735 int ret;
736 switch( operation->alg )
737 {
738#if defined(MBEDTLS_MD2_C)
739 case PSA_ALG_MD2:
740 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
741 input, input_length );
742 break;
743#endif
744#if defined(MBEDTLS_MD4_C)
745 case PSA_ALG_MD4:
746 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
747 input, input_length );
748 break;
749#endif
750#if defined(MBEDTLS_MD5_C)
751 case PSA_ALG_MD5:
752 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
753 input, input_length );
754 break;
755#endif
756#if defined(MBEDTLS_RIPEMD160_C)
757 case PSA_ALG_RIPEMD160:
758 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
759 input, input_length );
760 break;
761#endif
762#if defined(MBEDTLS_SHA1_C)
763 case PSA_ALG_SHA_1:
764 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
765 input, input_length );
766 break;
767#endif
768#if defined(MBEDTLS_SHA256_C)
769 case PSA_ALG_SHA_224:
770 case PSA_ALG_SHA_256:
771 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
772 input, input_length );
773 break;
774#endif
775#if defined(MBEDTLS_SHA512_C)
776 case PSA_ALG_SHA_384:
777 case PSA_ALG_SHA_512:
778 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
779 input, input_length );
780 break;
781#endif
782 default:
783 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
784 break;
785 }
786 if( ret != 0 )
787 psa_hash_abort( operation );
788 return( mbedtls_to_psa_error( ret ) );
789}
790
791psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
792 uint8_t *hash,
793 size_t hash_size,
794 size_t *hash_length )
795{
796 int ret;
797 size_t actual_hash_length = PSA_HASH_FINAL_SIZE( operation->alg );
798
799 /* Fill the output buffer with something that isn't a valid hash
800 * (barring an attack on the hash and deliberately-crafted input),
801 * in case the caller doesn't check the return status properly. */
802 *hash_length = actual_hash_length;
803 memset( hash, '!', hash_size );
804
805 if( hash_size < actual_hash_length )
806 return( PSA_ERROR_BUFFER_TOO_SMALL );
807
808 switch( operation->alg )
809 {
810#if defined(MBEDTLS_MD2_C)
811 case PSA_ALG_MD2:
812 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
813 break;
814#endif
815#if defined(MBEDTLS_MD4_C)
816 case PSA_ALG_MD4:
817 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
818 break;
819#endif
820#if defined(MBEDTLS_MD5_C)
821 case PSA_ALG_MD5:
822 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
823 break;
824#endif
825#if defined(MBEDTLS_RIPEMD160_C)
826 case PSA_ALG_RIPEMD160:
827 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
828 break;
829#endif
830#if defined(MBEDTLS_SHA1_C)
831 case PSA_ALG_SHA_1:
832 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
833 break;
834#endif
835#if defined(MBEDTLS_SHA256_C)
836 case PSA_ALG_SHA_224:
837 case PSA_ALG_SHA_256:
838 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
839 break;
840#endif
841#if defined(MBEDTLS_SHA512_C)
842 case PSA_ALG_SHA_384:
843 case PSA_ALG_SHA_512:
844 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
845 break;
846#endif
847 default:
848 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
849 break;
850 }
851
852 if( ret == 0 )
853 {
854 return( psa_hash_abort( operation ) );
855 }
856 else
857 {
858 psa_hash_abort( operation );
859 return( mbedtls_to_psa_error( ret ) );
860 }
861}
862
863psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
864 const uint8_t *hash,
865 size_t hash_length)
866{
867 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
868 size_t actual_hash_length;
869 psa_status_t status = psa_hash_finish( operation,
870 actual_hash, sizeof( actual_hash ),
871 &actual_hash_length );
872 if( status != PSA_SUCCESS )
873 return( status );
874 if( actual_hash_length != hash_length )
875 return( PSA_ERROR_INVALID_SIGNATURE );
876 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
877 return( PSA_ERROR_INVALID_SIGNATURE );
878 return( PSA_SUCCESS );
879}
880
881
882
883
884/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +0100885/* MAC */
886/****************************************************************/
887
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100888static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +0100889 psa_algorithm_t alg,
890 psa_key_type_t key_type,
mohammad1603f4f0d612018-06-03 15:04:51 +0300891 size_t key_bits,
892 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100893{
Gilles Peskine8c9def32018-02-08 10:02:12 +0100894 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +0300895 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100896
897 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
898 {
899 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
900 alg &= ~PSA_ALG_BLOCK_CIPHER_MODE_MASK;
901 switch( alg )
902 {
903 case PSA_ALG_STREAM_CIPHER:
904 mode = MBEDTLS_MODE_STREAM;
905 break;
906 case PSA_ALG_CBC_BASE:
907 mode = MBEDTLS_MODE_CBC;
908 break;
909 case PSA_ALG_CFB_BASE:
910 mode = MBEDTLS_MODE_CFB;
911 break;
912 case PSA_ALG_OFB_BASE:
913 mode = MBEDTLS_MODE_OFB;
914 break;
915 case PSA_ALG_CTR:
916 mode = MBEDTLS_MODE_CTR;
917 break;
918 case PSA_ALG_CCM:
919 mode = MBEDTLS_MODE_CCM;
920 break;
921 case PSA_ALG_GCM:
922 mode = MBEDTLS_MODE_GCM;
923 break;
924 default:
925 return( NULL );
926 }
927 }
928 else if( alg == PSA_ALG_CMAC )
929 mode = MBEDTLS_MODE_ECB;
930 else if( alg == PSA_ALG_GMAC )
931 mode = MBEDTLS_MODE_GCM;
932 else
933 return( NULL );
934
935 switch( key_type )
936 {
937 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +0300938 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100939 break;
940 case PSA_KEY_TYPE_DES:
941 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +0300942 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100943 else
mohammad1603f4f0d612018-06-03 15:04:51 +0300944 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100945 break;
946 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +0300947 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100948 break;
949 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +0300950 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100951 break;
952 default:
953 return( NULL );
954 }
mohammad1603f4f0d612018-06-03 15:04:51 +0300955 if( cipher_id != NULL )
956 *cipher_id == cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100957
mohammad1603f4f0d612018-06-03 15:04:51 +0300958 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +0100959}
960
961psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
962{
963 switch( operation->alg )
964 {
965#if defined(MBEDTLS_CMAC_C)
966 case PSA_ALG_CMAC:
967 mbedtls_cipher_free( &operation->ctx.cmac );
968 break;
969#endif /* MBEDTLS_CMAC_C */
970 default:
971#if defined(MBEDTLS_MD_C)
972 if( PSA_ALG_IS_HMAC( operation->alg ) )
973 mbedtls_md_free( &operation->ctx.hmac );
974 else
975#endif /* MBEDTLS_MD_C */
976 return( PSA_ERROR_NOT_SUPPORTED );
977 }
978 operation->alg = 0;
979 operation->key_set = 0;
980 operation->iv_set = 0;
981 operation->iv_required = 0;
982 operation->has_input = 0;
983 return( PSA_SUCCESS );
984}
985
986psa_status_t psa_mac_start( psa_mac_operation_t *operation,
987 psa_key_slot_t key,
988 psa_algorithm_t alg )
989{
990 int ret = MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
991 psa_status_t status;
992 key_slot_t *slot;
993 psa_key_type_t key_type;
994 size_t key_bits;
995 const mbedtls_cipher_info_t *cipher_info = NULL;
996
997 operation->alg = 0;
998 operation->key_set = 0;
999 operation->iv_set = 0;
1000 operation->iv_required = 1;
1001 operation->has_input = 0;
1002
1003 status = psa_get_key_information( key, &key_type, &key_bits );
1004 if( status != PSA_SUCCESS )
1005 return( status );
1006 slot = &global_data.key_slots[key];
1007
mohammad16036df908f2018-04-02 08:34:15 -07001008 if ( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
1009 operation->key_usage_sign = 1;
1010
1011 if ( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
1012 operation->key_usage_verify = 1;
1013
Gilles Peskine8c9def32018-02-08 10:02:12 +01001014 if( ! PSA_ALG_IS_HMAC( alg ) )
1015 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001016 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001017 if( cipher_info == NULL )
1018 return( PSA_ERROR_NOT_SUPPORTED );
1019 operation->mac_size = cipher_info->block_size;
1020 }
1021 switch( alg )
1022 {
1023#if defined(MBEDTLS_CMAC_C)
1024 case PSA_ALG_CMAC:
1025 operation->iv_required = 0;
1026 mbedtls_cipher_init( &operation->ctx.cmac );
1027 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1028 if( ret != 0 )
1029 break;
1030 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1031 slot->data.raw.data,
1032 key_bits );
1033 break;
1034#endif /* MBEDTLS_CMAC_C */
1035 default:
1036#if defined(MBEDTLS_MD_C)
1037 if( PSA_ALG_IS_HMAC( alg ) )
1038 {
1039 const mbedtls_md_info_t *md_info =
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001040 mbedtls_md_info_from_psa( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001041 if( md_info == NULL )
1042 return( PSA_ERROR_NOT_SUPPORTED );
1043 if( key_type != PSA_KEY_TYPE_HMAC )
1044 return( PSA_ERROR_INVALID_ARGUMENT );
1045 operation->iv_required = 0;
1046 operation->mac_size = mbedtls_md_get_size( md_info );
1047 mbedtls_md_init( &operation->ctx.hmac );
1048 ret = mbedtls_md_setup( &operation->ctx.hmac, md_info, 1 );
1049 if( ret != 0 )
1050 break;
1051 ret = mbedtls_md_hmac_starts( &operation->ctx.hmac,
1052 slot->data.raw.data,
1053 slot->data.raw.bytes );
1054 break;
1055 }
1056 else
1057#endif /* MBEDTLS_MD_C */
1058 return( PSA_ERROR_NOT_SUPPORTED );
1059 }
1060
1061 /* If we reach this point, then the algorithm-specific part of the
1062 * context has at least been initialized, and may contain data that
1063 * needs to be wiped on error. */
1064 operation->alg = alg;
1065 if( ret != 0 )
1066 {
1067 psa_mac_abort( operation );
1068 return( mbedtls_to_psa_error( ret ) );
1069 }
1070 operation->key_set = 1;
Gilles Peskine47c1bc02018-03-20 17:55:04 +01001071 return( PSA_SUCCESS );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001072}
1073
1074psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1075 const uint8_t *input,
1076 size_t input_length )
1077{
1078 int ret;
1079 if( ! operation->key_set )
1080 return( PSA_ERROR_BAD_STATE );
1081 if( operation->iv_required && ! operation->iv_set )
1082 return( PSA_ERROR_BAD_STATE );
1083 operation->has_input = 1;
1084
1085 switch( operation->alg )
1086 {
1087#if defined(MBEDTLS_CMAC_C)
1088 case PSA_ALG_CMAC:
1089 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1090 input, input_length );
1091 break;
1092#endif /* MBEDTLS_CMAC_C */
1093 default:
1094#if defined(MBEDTLS_MD_C)
1095 if( PSA_ALG_IS_HMAC( operation->alg ) )
1096 {
1097 ret = mbedtls_md_hmac_update( &operation->ctx.hmac,
1098 input, input_length );
1099 }
1100 else
1101#endif /* MBEDTLS_MD_C */
1102 {
1103 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1104 }
1105 break;
1106 }
1107 if( ret != 0 )
1108 psa_mac_abort( operation );
1109 return( mbedtls_to_psa_error( ret ) );
1110}
1111
mohammad16036df908f2018-04-02 08:34:15 -07001112static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine8c9def32018-02-08 10:02:12 +01001113 uint8_t *mac,
1114 size_t mac_size,
1115 size_t *mac_length )
1116{
1117 int ret;
1118 if( ! operation->key_set )
1119 return( PSA_ERROR_BAD_STATE );
1120 if( operation->iv_required && ! operation->iv_set )
1121 return( PSA_ERROR_BAD_STATE );
1122
1123 /* Fill the output buffer with something that isn't a valid mac
1124 * (barring an attack on the mac and deliberately-crafted input),
1125 * in case the caller doesn't check the return status properly. */
1126 *mac_length = operation->mac_size;
1127 memset( mac, '!', mac_size );
1128
1129 if( mac_size < operation->mac_size )
1130 return( PSA_ERROR_BUFFER_TOO_SMALL );
1131
1132 switch( operation->alg )
1133 {
1134#if defined(MBEDTLS_CMAC_C)
1135 case PSA_ALG_CMAC:
1136 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1137 break;
1138#endif /* MBEDTLS_CMAC_C */
1139 default:
1140#if defined(MBEDTLS_MD_C)
1141 if( PSA_ALG_IS_HMAC( operation->alg ) )
1142 {
1143 ret = mbedtls_md_hmac_finish( &operation->ctx.hmac, mac );
1144 }
1145 else
1146#endif /* MBEDTLS_MD_C */
1147 {
1148 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1149 }
1150 break;
1151 }
1152
1153 if( ret == 0 )
1154 {
1155 return( psa_mac_abort( operation ) );
1156 }
1157 else
1158 {
1159 psa_mac_abort( operation );
1160 return( mbedtls_to_psa_error( ret ) );
1161 }
1162}
1163
mohammad16036df908f2018-04-02 08:34:15 -07001164psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1165 uint8_t *mac,
1166 size_t mac_size,
1167 size_t *mac_length )
1168{
1169 if( !( operation->key_usage_sign ) )
1170 return( PSA_ERROR_NOT_PERMITTED );
1171
1172 return( psa_mac_finish_internal(operation, mac, mac_size, mac_length ) );
1173}
1174
Gilles Peskine8c9def32018-02-08 10:02:12 +01001175#define MBEDTLS_PSA_MAC_MAX_SIZE \
1176 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1177 MBEDTLS_MD_MAX_SIZE : \
1178 MBEDTLS_MAX_BLOCK_LENGTH )
1179psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1180 const uint8_t *mac,
1181 size_t mac_length )
1182{
1183 uint8_t actual_mac[MBEDTLS_PSA_MAC_MAX_SIZE];
1184 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001185 psa_status_t status;
1186
1187 if( !( operation->key_usage_verify ) )
1188 return( PSA_ERROR_NOT_PERMITTED );
1189
1190 status = psa_mac_finish_internal( operation,
1191 actual_mac, sizeof( actual_mac ),
1192 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001193 if( status != PSA_SUCCESS )
1194 return( status );
1195 if( actual_mac_length != mac_length )
1196 return( PSA_ERROR_INVALID_SIGNATURE );
1197 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1198 return( PSA_ERROR_INVALID_SIGNATURE );
1199 return( PSA_SUCCESS );
1200}
1201
1202
Gilles Peskine20035e32018-02-03 22:44:14 +01001203
1204
1205/****************************************************************/
1206/* Asymmetric cryptography */
1207/****************************************************************/
1208
1209psa_status_t psa_asymmetric_sign(psa_key_slot_t key,
1210 psa_algorithm_t alg,
1211 const uint8_t *hash,
1212 size_t hash_length,
1213 const uint8_t *salt,
1214 size_t salt_length,
1215 uint8_t *signature,
1216 size_t signature_size,
1217 size_t *signature_length)
1218{
1219 key_slot_t *slot;
1220
Gilles Peskine93aa0332018-02-03 23:58:03 +01001221 *signature_length = 0;
1222 (void) salt;
1223 (void) salt_length;
1224
Gilles Peskine20035e32018-02-03 22:44:14 +01001225 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1226 return( PSA_ERROR_EMPTY_SLOT );
1227 slot = &global_data.key_slots[key];
1228 if( slot->type == PSA_KEY_TYPE_NONE )
1229 return( PSA_ERROR_EMPTY_SLOT );
1230 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1231 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +03001232 if( !( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
1233 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001234
Gilles Peskine20035e32018-02-03 22:44:14 +01001235#if defined(MBEDTLS_RSA_C)
1236 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1237 {
1238 mbedtls_rsa_context *rsa = slot->data.rsa;
1239 int ret;
1240 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001241 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01001242 mbedtls_md_type_t md_alg =
1243 hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1244 if( md_alg == MBEDTLS_MD_NONE )
1245 {
1246#if SIZE_MAX > UINT_MAX
1247 if( hash_length > UINT_MAX )
1248 return( PSA_ERROR_INVALID_ARGUMENT );
1249#endif
1250 }
1251 else
1252 {
1253 if( mbedtls_md_get_size( md_info ) != hash_length )
1254 return( PSA_ERROR_INVALID_ARGUMENT );
1255 if( md_info == NULL )
1256 return( PSA_ERROR_NOT_SUPPORTED );
1257 }
1258 if( signature_size < rsa->len )
1259 return( PSA_ERROR_BUFFER_TOO_SMALL );
1260#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001261 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001262 {
1263 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1264 MBEDTLS_MD_NONE );
1265 ret = mbedtls_rsa_pkcs1_sign( rsa,
1266 mbedtls_ctr_drbg_random,
1267 &global_data.ctr_drbg,
1268 MBEDTLS_RSA_PRIVATE,
1269 md_alg, hash_length, hash,
1270 signature );
1271 }
1272 else
1273#endif /* MBEDTLS_PKCS1_V15 */
1274#if defined(MBEDTLS_PKCS1_V21)
1275 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1276 {
1277 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1278 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1279 mbedtls_ctr_drbg_random,
1280 &global_data.ctr_drbg,
1281 MBEDTLS_RSA_PRIVATE,
1282 md_alg, hash_length, hash,
1283 signature );
1284 }
1285 else
1286#endif /* MBEDTLS_PKCS1_V21 */
1287 {
1288 return( PSA_ERROR_INVALID_ARGUMENT );
1289 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001290 if( ret == 0 )
1291 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001292 return( mbedtls_to_psa_error( ret ) );
1293 }
1294 else
1295#endif /* defined(MBEDTLS_RSA_C) */
1296#if defined(MBEDTLS_ECP_C)
1297 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1298 {
itayzafrir5c753392018-05-08 11:18:38 +03001299 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1300 int ret;
1301 const mbedtls_md_info_t *md_info;
1302 mbedtls_md_type_t md_alg;
1303 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1304 return( PSA_ERROR_BUFFER_TOO_SMALL );
1305 md_info = mbedtls_md_info_from_psa( alg );
1306 md_alg = mbedtls_md_get_type( md_info );
1307 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
1308 signature, signature_length, mbedtls_ctr_drbg_random,
1309 &global_data.ctr_drbg );
1310 return( mbedtls_to_psa_error( ret ) );
1311 }
1312 else
1313#endif /* defined(MBEDTLS_ECP_C) */
1314 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001315 return( PSA_ERROR_NOT_SUPPORTED );
1316 }
itayzafrir5c753392018-05-08 11:18:38 +03001317}
1318
1319psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1320 psa_algorithm_t alg,
1321 const uint8_t *hash,
1322 size_t hash_length,
1323 const uint8_t *salt,
1324 size_t salt_length,
1325 uint8_t *signature,
1326 size_t signature_size )
1327{
1328 key_slot_t *slot;
1329 (void) salt;
1330 (void) salt_length;
1331
1332 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1333 return( PSA_ERROR_INVALID_ARGUMENT );
1334 slot = &global_data.key_slots[key];
1335 if( slot->type == PSA_KEY_TYPE_NONE )
1336 return( PSA_ERROR_EMPTY_SLOT );
1337 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1338 return( PSA_ERROR_INVALID_ARGUMENT );
1339 if( !( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
1340 return( PSA_ERROR_NOT_PERMITTED );
1341
1342#if defined(MBEDTLS_ECP_C)
1343 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1344 {
1345 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1346 int ret;
1347 (void) alg;
1348 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length, signature,
1349 signature_size );
1350 return( mbedtls_to_psa_error( ret ) );
1351 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001352 else
1353#endif /* defined(MBEDTLS_ECP_C) */
1354 {
1355 return( PSA_ERROR_NOT_SUPPORTED );
1356 }
1357}
1358
1359
Gilles Peskinea0655c32018-04-30 17:06:50 +02001360
mohammad16038cc1cee2018-03-28 01:21:33 +03001361/****************************************************************/
1362/* Key Policy */
1363/****************************************************************/
1364
1365void psa_key_policy_init(psa_key_policy_t *policy)
1366{
mohammad16036df908f2018-04-02 08:34:15 -07001367 memset( policy, 0, sizeof( psa_key_policy_t ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03001368}
1369
1370void psa_key_policy_set_usage(psa_key_policy_t *policy,
1371 psa_key_usage_t usage,
1372 psa_algorithm_t alg)
1373{
mohammad16034eed7572018-03-28 05:14:59 -07001374 policy->usage = usage;
1375 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03001376}
1377
1378psa_key_usage_t psa_key_policy_get_usage(psa_key_policy_t *policy)
1379{
mohammad16036df908f2018-04-02 08:34:15 -07001380 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03001381}
1382
1383psa_algorithm_t psa_key_policy_get_algorithm(psa_key_policy_t *policy)
1384{
mohammad16036df908f2018-04-02 08:34:15 -07001385 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03001386}
1387
1388psa_status_t psa_set_key_policy(psa_key_slot_t key,
1389 const psa_key_policy_t *policy)
1390{
1391 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03001392
1393 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
1394 return( PSA_ERROR_INVALID_ARGUMENT );
1395
1396 slot = &global_data.key_slots[key];
1397 if( slot->type != PSA_KEY_TYPE_NONE )
1398 return( PSA_ERROR_OCCUPIED_SLOT );
1399
mohammad16036df908f2018-04-02 08:34:15 -07001400 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT
1401 | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_SIGN
1402 | PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07001403 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03001404
mohammad16036df908f2018-04-02 08:34:15 -07001405 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03001406
1407 return( PSA_SUCCESS );
1408}
1409
1410psa_status_t psa_get_key_policy(psa_key_slot_t key,
1411 psa_key_policy_t *policy)
1412{
1413 key_slot_t *slot;
1414
1415 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
1416 return( PSA_ERROR_INVALID_ARGUMENT );
1417
1418 slot = &global_data.key_slots[key];
mohammad16038cc1cee2018-03-28 01:21:33 +03001419
mohammad16036df908f2018-04-02 08:34:15 -07001420 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03001421
1422 return( PSA_SUCCESS );
1423}
Gilles Peskine20035e32018-02-03 22:44:14 +01001424
Gilles Peskinea0655c32018-04-30 17:06:50 +02001425
1426
mohammad1603804cd712018-03-20 22:44:08 +02001427/****************************************************************/
1428/* Key Lifetime */
1429/****************************************************************/
1430
1431psa_status_t psa_get_key_lifetime(psa_key_slot_t key,
1432 psa_key_lifetime_t *lifetime)
1433{
1434 key_slot_t *slot;
1435
1436 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1437 return( PSA_ERROR_INVALID_ARGUMENT );
1438
1439 slot = &global_data.key_slots[key];
mohammad1603804cd712018-03-20 22:44:08 +02001440
1441 *lifetime = slot->lifetime;
1442
1443 return( PSA_SUCCESS );
1444}
1445
1446psa_status_t psa_set_key_lifetime(psa_key_slot_t key,
1447 const psa_key_lifetime_t lifetime)
1448{
1449 key_slot_t *slot;
1450
1451 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1452 return( PSA_ERROR_INVALID_ARGUMENT );
1453
mohammad1603ba178512018-03-21 04:35:20 -07001454 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
1455 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
1456 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
1457 return( PSA_ERROR_INVALID_ARGUMENT );
1458
mohammad1603804cd712018-03-20 22:44:08 +02001459 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03001460 if( slot->type != PSA_KEY_TYPE_NONE )
1461 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02001462
mohammad1603ba178512018-03-21 04:35:20 -07001463 if ( lifetime != PSA_KEY_LIFETIME_VOLATILE )
1464 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603804cd712018-03-20 22:44:08 +02001465
mohammad1603060ad8a2018-03-20 14:28:38 -07001466 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02001467
1468 return( PSA_SUCCESS );
1469}
1470
Gilles Peskine20035e32018-02-03 22:44:14 +01001471
mohammad16035955c982018-04-26 00:53:03 +03001472/****************************************************************/
1473/* AEAD */
1474/****************************************************************/
1475psa_status_t psa_aead_encrypt( psa_key_slot_t key,
1476 psa_algorithm_t alg,
1477 const uint8_t *nonce,
1478 size_t nonce_length,
1479 const uint8_t *additional_data,
1480 size_t additional_data_length,
1481 const uint8_t *plaintext,
1482 size_t plaintext_length,
1483 uint8_t *ciphertext,
1484 size_t ciphertext_size,
1485 size_t *ciphertext_length )
1486{
1487 int ret;
1488 psa_status_t status;
1489 key_slot_t *slot;
1490 psa_key_type_t key_type;
1491 size_t key_bits;
mohammad16035955c982018-04-26 00:53:03 +03001492 unsigned char tag[16];
mohammad1603dad36fa2018-05-09 02:24:42 -07001493 mbedtls_cipher_id_t cipher_id;
mohammad1603f08a5502018-06-03 15:05:47 +03001494 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07001495
mohammad16039e5a5152018-04-26 12:07:35 +03001496 if( ciphertext_size < ( plaintext_length + sizeof( tag ) ) )
Gilles Peskinea40d7742018-06-01 16:28:30 +02001497 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16039e5a5152018-04-26 12:07:35 +03001498
mohammad16035955c982018-04-26 00:53:03 +03001499 status = psa_get_key_information( key, &key_type, &key_bits );
1500 if( status != PSA_SUCCESS )
1501 return( status );
1502 slot = &global_data.key_slots[key];
1503
mohammad1603dad36fa2018-05-09 02:24:42 -07001504 if ( key_type == PSA_KEY_TYPE_AES )
1505 {
1506 cipher_id = MBEDTLS_CIPHER_ID_AES;
1507 }
1508 else
1509 {
1510 return( PSA_ERROR_INVALID_ARGUMENT );
1511 }
1512
mohammad16035955c982018-04-26 00:53:03 +03001513 //TODO: check key policy
1514
mohammad1603e58e6842018-05-09 04:58:32 -07001515 if ( !( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) == PSA_KEY_TYPE_CATEGORY_CIPHER
Gilles Peskinea40d7742018-06-01 16:28:30 +02001516 && PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) == 16 ) )
mohammad1603db624732018-04-30 17:21:50 +03001517 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03001518
mohammad16035955c982018-04-26 00:53:03 +03001519 if( alg == PSA_ALG_GCM )
1520 {
1521 mbedtls_gcm_context gcm;
1522 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02001523 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03001524 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02001525 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03001526 if( ret != 0 )
1527 {
1528 mbedtls_gcm_free( &gcm );
1529 return( mbedtls_to_psa_error( ret ) );
1530 }
1531 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02001532 plaintext_length, nonce,
1533 nonce_length, additional_data,
1534 additional_data_length, plaintext,
1535 ciphertext, sizeof( tag ), tag );
mohammad16035955c982018-04-26 00:53:03 +03001536 if( ret != 0 )
1537 {
1538 mbedtls_gcm_free( &gcm );
mohammad16034f5eb7c2018-04-30 17:23:47 +03001539 mbedtls_zeroize( ciphertext, plaintext_length );
mohammad16035955c982018-04-26 00:53:03 +03001540 return( mbedtls_to_psa_error( ret ) );
1541 }
1542
mohammad16035955c982018-04-26 00:53:03 +03001543 mbedtls_gcm_free( &gcm );
1544 }
1545 else if( alg == PSA_ALG_CCM )
1546 {
1547 mbedtls_ccm_context ccm;
mohammad160347ddf3d2018-04-26 01:11:21 +03001548 if( nonce_length < 7 || nonce_length > 13 )
1549 return( PSA_ERROR_INVALID_ARGUMENT );
1550
mohammad16035955c982018-04-26 00:53:03 +03001551 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02001552 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03001553 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03001554 if( ret != 0 )
1555 {
1556 mbedtls_ccm_free( &ccm );
1557 return( mbedtls_to_psa_error( ret ) );
1558 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02001559 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
1560 nonce, nonce_length, additional_data,
1561 additional_data_length,
1562 plaintext, ciphertext,
1563 tag, sizeof( tag ) );
mohammad16035955c982018-04-26 00:53:03 +03001564 if( ret != 0 )
1565 {
1566 mbedtls_ccm_free( &ccm );
mohammad16034f5eb7c2018-04-30 17:23:47 +03001567 mbedtls_zeroize( ciphertext, plaintext_length );
mohammad16035955c982018-04-26 00:53:03 +03001568 return( mbedtls_to_psa_error( ret ) );
1569 }
1570
mohammad16035955c982018-04-26 00:53:03 +03001571 mbedtls_ccm_free( &ccm );
1572 }
mohammad16035c8845f2018-05-09 05:40:09 -07001573 else
1574 {
1575 return( PSA_ERROR_INVALID_ARGUMENT );
1576 }
mohammad160347ddf3d2018-04-26 01:11:21 +03001577 memcpy( ciphertext + plaintext_length, tag, sizeof( tag ) );
mohammad1603ce5cba92018-04-26 12:08:21 +03001578 *ciphertext_length = plaintext_length + sizeof( tag );
mohammad160347ddf3d2018-04-26 01:11:21 +03001579 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03001580}
1581
Gilles Peskineee652a32018-06-01 19:23:52 +02001582/* Locate the tag in a ciphertext buffer containing the encrypted data
1583 * followed by the tag. Return the length of the part preceding the tag in
1584 * *plaintext_length. This is the size of the plaintext in modes where
1585 * the encrypted data has the same size as the plaintext, such as
1586 * CCM and GCM. */
1587static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
1588 const uint8_t *ciphertext,
1589 size_t ciphertext_length,
1590 size_t plaintext_size,
1591 size_t *plaintext_length,
1592 const uint8_t **p_tag )
1593{
1594 size_t payload_length;
1595 if( tag_length > ciphertext_length )
1596 return( PSA_ERROR_INVALID_ARGUMENT );
1597 payload_length = ciphertext_length - tag_length;
1598 if( payload_length > plaintext_size )
1599 return( PSA_ERROR_BUFFER_TOO_SMALL );
1600 *p_tag = ciphertext + payload_length;
1601 *plaintext_length = payload_length;
1602 return( PSA_SUCCESS );
1603}
1604
mohammad16035955c982018-04-26 00:53:03 +03001605psa_status_t psa_aead_decrypt( psa_key_slot_t key,
1606 psa_algorithm_t alg,
1607 const uint8_t *nonce,
1608 size_t nonce_length,
1609 const uint8_t *additional_data,
1610 size_t additional_data_length,
1611 const uint8_t *ciphertext,
1612 size_t ciphertext_length,
1613 uint8_t *plaintext,
1614 size_t plaintext_size,
1615 size_t *plaintext_length )
1616{
1617 int ret;
1618 psa_status_t status;
1619 key_slot_t *slot;
1620 psa_key_type_t key_type;
1621 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02001622 const uint8_t *tag;
1623 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07001624 mbedtls_cipher_id_t cipher_id;
mohammad16035955c982018-04-26 00:53:03 +03001625
Gilles Peskineee652a32018-06-01 19:23:52 +02001626 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03001627
mohammad16035955c982018-04-26 00:53:03 +03001628 status = psa_get_key_information( key, &key_type, &key_bits );
1629 if( status != PSA_SUCCESS )
1630 return( status );
1631 slot = &global_data.key_slots[key];
1632
mohammad1603dad36fa2018-05-09 02:24:42 -07001633 if ( key_type == PSA_KEY_TYPE_AES )
1634 {
1635 cipher_id = MBEDTLS_CIPHER_ID_AES;
1636 }
1637 else
1638 {
1639 return( PSA_ERROR_INVALID_ARGUMENT );
1640 }
1641
mohammad16035955c982018-04-26 00:53:03 +03001642 //TODO: check key policy
1643
mohammad1603e58e6842018-05-09 04:58:32 -07001644 if ( !( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) == PSA_KEY_TYPE_CATEGORY_CIPHER
Gilles Peskinea40d7742018-06-01 16:28:30 +02001645 && PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) == 16 ) )
mohammad1603a7e6df72018-04-30 17:25:45 +03001646 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03001647
mohammad16035955c982018-04-26 00:53:03 +03001648 if( alg == PSA_ALG_GCM )
1649 {
1650 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03001651
Gilles Peskineee652a32018-06-01 19:23:52 +02001652 tag_length = 16;
1653 status = psa_aead_unpadded_locate_tag( tag_length,
1654 ciphertext, ciphertext_length,
1655 plaintext_size, plaintext_length,
1656 &tag );
1657 if( status != PSA_SUCCESS )
1658 return( status );
1659
mohammad16035955c982018-04-26 00:53:03 +03001660 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02001661 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03001662 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03001663 if( ret != 0 )
1664 {
1665 mbedtls_gcm_free( &gcm );
1666 return( mbedtls_to_psa_error( ret ) );
1667 }
mohammad16035955c982018-04-26 00:53:03 +03001668
Gilles Peskineee652a32018-06-01 19:23:52 +02001669 ret = mbedtls_gcm_auth_decrypt( &gcm,
1670 *plaintext_length,
1671 nonce, nonce_length,
1672 additional_data, additional_data_length,
1673 tag, tag_length,
1674 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03001675 mbedtls_gcm_free( &gcm );
1676 }
1677 else if( alg == PSA_ALG_CCM )
1678 {
1679 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02001680
mohammad160347ddf3d2018-04-26 01:11:21 +03001681 if( nonce_length < 7 || nonce_length > 13 )
1682 return( PSA_ERROR_INVALID_ARGUMENT );
1683
mohammad16039375f842018-06-03 14:28:24 +03001684 tag_length = 16;
1685 status = psa_aead_unpadded_locate_tag( tag_length,
1686 ciphertext, ciphertext_length,
1687 plaintext_size, plaintext_length,
1688 &tag );
1689 if( status != PSA_SUCCESS )
1690 return( status );
1691
mohammad16035955c982018-04-26 00:53:03 +03001692 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02001693 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03001694 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03001695 if( ret != 0 )
1696 {
1697 mbedtls_ccm_free( &ccm );
1698 return( mbedtls_to_psa_error( ret ) );
1699 }
Gilles Peskineee652a32018-06-01 19:23:52 +02001700 ret = mbedtls_ccm_auth_decrypt( &ccm, *plaintext_length,
1701 nonce, nonce_length,
1702 additional_data, additional_data_length,
1703 ciphertext, plaintext,
1704 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03001705 mbedtls_ccm_free( &ccm );
1706 }
mohammad160339574652018-06-01 04:39:53 -07001707 else
1708 {
1709 return( PSA_ERROR_INVALID_ARGUMENT );
1710 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02001711
Gilles Peskineee652a32018-06-01 19:23:52 +02001712 if( ret != 0 )
1713 {
1714 mbedtls_zeroize( plaintext, *plaintext_length );
1715 *plaintext_length = 0;
1716 }
1717 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03001718}
1719
Gilles Peskinea0655c32018-04-30 17:06:50 +02001720
Gilles Peskine20035e32018-02-03 22:44:14 +01001721/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001722/* Module setup */
1723/****************************************************************/
1724
Gilles Peskinee59236f2018-01-27 23:32:46 +01001725void mbedtls_psa_crypto_free( void )
1726{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001727 size_t key;
1728 for( key = 1; key < MBEDTLS_PSA_KEY_SLOT_COUNT; key++ )
1729 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01001730 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
1731 mbedtls_entropy_free( &global_data.entropy );
1732 mbedtls_zeroize( &global_data, sizeof( global_data ) );
1733}
1734
1735psa_status_t psa_crypto_init( void )
1736{
1737 int ret;
1738 const unsigned char drbg_seed[] = "PSA";
1739
1740 if( global_data.initialized != 0 )
1741 return( PSA_SUCCESS );
1742
1743 mbedtls_zeroize( &global_data, sizeof( global_data ) );
1744 mbedtls_entropy_init( &global_data.entropy );
1745 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
1746
1747 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
1748 mbedtls_entropy_func,
1749 &global_data.entropy,
1750 drbg_seed, sizeof( drbg_seed ) - 1 );
1751 if( ret != 0 )
1752 goto exit;
1753
Gilles Peskinee4ebc122018-03-07 14:16:44 +01001754 global_data.initialized = 1;
1755
Gilles Peskinee59236f2018-01-27 23:32:46 +01001756exit:
1757 if( ret != 0 )
1758 mbedtls_psa_crypto_free( );
1759 return( mbedtls_to_psa_error( ret ) );
1760}
1761
1762#endif /* MBEDTLS_PSA_CRYPTO_C */