blob: 4d42c8d2b2de10ce7cccc00dff17df92ebda36a0 [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/* Key management */
306/****************************************************************/
307
308psa_status_t psa_import_key(psa_key_slot_t key,
309 psa_key_type_t type,
310 const uint8_t *data,
311 size_t data_length)
312{
313 key_slot_t *slot;
314
315 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
316 return( PSA_ERROR_INVALID_ARGUMENT );
317 slot = &global_data.key_slots[key];
318 if( slot->type != PSA_KEY_TYPE_NONE )
319 return( PSA_ERROR_OCCUPIED_SLOT );
320
Gilles Peskine8c9def32018-02-08 10:02:12 +0100321 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100322 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100323 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100324 if( data_length > SIZE_MAX / 8 )
325 return( PSA_ERROR_NOT_SUPPORTED );
326 slot->data.raw.data = mbedtls_calloc( 1, data_length );
327 if( slot->data.raw.data == NULL )
328 return( PSA_ERROR_INSUFFICIENT_MEMORY );
329 memcpy( slot->data.raw.data, data, data_length );
330 slot->data.raw.bytes = data_length;
331 }
332 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100333#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100334 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
335 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
336 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100337 {
338 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100339 mbedtls_pk_context pk;
340 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100341 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
342 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
343 else
344 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100345 if( ret != 0 )
346 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100347 switch( mbedtls_pk_get_type( &pk ) )
348 {
349#if defined(MBEDTLS_RSA_C)
350 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100351 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
352 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine969ac722018-01-28 18:16:59 +0100353 slot->data.rsa = pk.pk_ctx;
354 else
355 return( PSA_ERROR_INVALID_ARGUMENT );
356 break;
357#endif /* MBEDTLS_RSA_C */
358#if defined(MBEDTLS_ECP_C)
359 case MBEDTLS_PK_ECKEY:
360 if( PSA_KEY_TYPE_IS_ECC( type ) )
361 {
362 // TODO: check curve
363 slot->data.ecp = pk.pk_ctx;
364 }
365 else
366 return( PSA_ERROR_INVALID_ARGUMENT );
367 break;
368#endif /* MBEDTLS_ECP_C */
369 default:
370 return( PSA_ERROR_INVALID_ARGUMENT );
371 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100372 }
373 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100374#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100375 {
376 return( PSA_ERROR_NOT_SUPPORTED );
377 }
378
379 slot->type = type;
380 return( PSA_SUCCESS );
381}
382
383psa_status_t psa_destroy_key(psa_key_slot_t key)
384{
385 key_slot_t *slot;
386
387 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
388 return( PSA_ERROR_INVALID_ARGUMENT );
389 slot = &global_data.key_slots[key];
390 if( slot->type == PSA_KEY_TYPE_NONE )
391 return( PSA_ERROR_EMPTY_SLOT );
392
Gilles Peskine8c9def32018-02-08 10:02:12 +0100393 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100394 {
395 mbedtls_free( slot->data.raw.data );
396 }
397 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100398#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100399 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
400 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100401 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100402 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100403 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100404 }
405 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100406#endif /* defined(MBEDTLS_RSA_C) */
407#if defined(MBEDTLS_ECP_C)
408 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
409 {
410 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100411 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100412 }
413 else
414#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100415 {
416 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100417 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100418 return( PSA_ERROR_TAMPERING_DETECTED );
419 }
420
421 mbedtls_zeroize( slot, sizeof( *slot ) );
422 return( PSA_SUCCESS );
423}
424
425psa_status_t psa_get_key_information(psa_key_slot_t key,
426 psa_key_type_t *type,
427 size_t *bits)
428{
429 key_slot_t *slot;
430
431 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100432 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100433 slot = &global_data.key_slots[key];
434 if( type != NULL )
435 *type = slot->type;
436 if( bits != NULL )
437 *bits = 0;
438 if( slot->type == PSA_KEY_TYPE_NONE )
439 return( PSA_ERROR_EMPTY_SLOT );
440
Gilles Peskine8c9def32018-02-08 10:02:12 +0100441 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100442 {
443 if( bits != NULL )
444 *bits = slot->data.raw.bytes * 8;
445 }
446 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100447#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100448 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
449 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100450 {
451 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100452 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100453 }
454 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100455#endif /* defined(MBEDTLS_RSA_C) */
456#if defined(MBEDTLS_ECP_C)
457 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
458 {
459 if( bits != NULL )
460 *bits = slot->data.ecp->grp.pbits;
461 }
462 else
463#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100464 {
465 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100466 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100467 return( PSA_ERROR_TAMPERING_DETECTED );
468 }
469
470 return( PSA_SUCCESS );
471}
472
Moran Pekera998bc62018-04-16 18:16:20 +0300473static psa_status_t psa_internal_export_key(psa_key_slot_t key,
474 uint8_t *data,
475 size_t data_size,
476 size_t *data_length,
477 int export_public_key)
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100478{
479 key_slot_t *slot;
480
481 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100482 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100483 slot = &global_data.key_slots[key];
484 if( slot->type == PSA_KEY_TYPE_NONE )
485 return( PSA_ERROR_EMPTY_SLOT );
486
Moran Peker87567632018-06-04 18:41:37 +0300487 if( export_public_key && ( !( PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) ) ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300488 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300489
Moran Peker87567632018-06-04 18:41:37 +0300490 if( ( !export_public_key ) && ( !( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ) ) &&
491 ( !( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) ) )
492 return( PSA_ERROR_NOT_PERMITTED );
493
Gilles Peskine8c9def32018-02-08 10:02:12 +0100494 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100495 {
496 if( slot->data.raw.bytes > data_size )
497 return( PSA_ERROR_BUFFER_TOO_SMALL );
498 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
499 *data_length = slot->data.raw.bytes;
500 return( PSA_SUCCESS );
501 }
502 else
Moran Peker17e36e12018-05-02 12:55:20 +0300503 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100504#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100505 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300506 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
507 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100508 {
Moran Pekera998bc62018-04-16 18:16:20 +0300509 mbedtls_pk_context pk;
510 int ret;
511 mbedtls_pk_init( &pk );
512 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
513 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
514 {
515 pk.pk_info = &mbedtls_rsa_info;
516 pk.pk_ctx = slot->data.rsa;
517 }
518 else
519 {
520 pk.pk_info = &mbedtls_eckey_info;
521 pk.pk_ctx = slot->data.ecp;
522 }
Moran Pekerd7326592018-05-29 16:56:39 +0300523 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300524 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300525 else
526 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300527 if( ret < 0 )
Moran Pekera998bc62018-04-16 18:16:20 +0300528 return( mbedtls_to_psa_error( ret ) );
529 *data_length = ret;
530 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100531 }
532 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100533#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300534 {
535 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200536 it is valid for a special-purpose implementation to omit
537 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300538 return( PSA_ERROR_NOT_SUPPORTED );
539 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100540 }
541}
542
Moran Pekera998bc62018-04-16 18:16:20 +0300543psa_status_t psa_export_key(psa_key_slot_t key,
544 uint8_t *data,
545 size_t data_size,
546 size_t *data_length)
547{
548 return psa_internal_export_key( key, data, data_size,
549 data_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100550}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100551
552
Moran Pekerdd4ea382018-04-03 15:30:03 +0300553psa_status_t psa_export_public_key(psa_key_slot_t key,
Moran Pekerb4d0ddd2018-04-04 12:47:52 +0300554 uint8_t *data,
555 size_t data_size,
556 size_t *data_length)
Moran Pekerdd4ea382018-04-03 15:30:03 +0300557{
Moran Pekera998bc62018-04-16 18:16:20 +0300558 return psa_internal_export_key( key, data, data_size,
559 data_length, 1 );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300560}
561
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100562/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100563/* Message digests */
564/****************************************************************/
565
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100566static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100567{
568 switch( alg )
569 {
570#if defined(MBEDTLS_MD2_C)
571 case PSA_ALG_MD2:
572 return( &mbedtls_md2_info );
573#endif
574#if defined(MBEDTLS_MD4_C)
575 case PSA_ALG_MD4:
576 return( &mbedtls_md4_info );
577#endif
578#if defined(MBEDTLS_MD5_C)
579 case PSA_ALG_MD5:
580 return( &mbedtls_md5_info );
581#endif
582#if defined(MBEDTLS_RIPEMD160_C)
583 case PSA_ALG_RIPEMD160:
584 return( &mbedtls_ripemd160_info );
585#endif
586#if defined(MBEDTLS_SHA1_C)
587 case PSA_ALG_SHA_1:
588 return( &mbedtls_sha1_info );
589#endif
590#if defined(MBEDTLS_SHA256_C)
591 case PSA_ALG_SHA_224:
592 return( &mbedtls_sha224_info );
593 case PSA_ALG_SHA_256:
594 return( &mbedtls_sha256_info );
595#endif
596#if defined(MBEDTLS_SHA512_C)
597 case PSA_ALG_SHA_384:
598 return( &mbedtls_sha384_info );
599 case PSA_ALG_SHA_512:
600 return( &mbedtls_sha512_info );
601#endif
602 default:
603 return( NULL );
604 }
605}
606
607#if 0
608static psa_algorithm_t mbedtls_md_alg_to_psa( mbedtls_md_type_t md_alg )
609{
610 switch( md_alg )
611 {
612 case MBEDTLS_MD_NONE:
613 return( 0 );
614 case MBEDTLS_MD_MD2:
615 return( PSA_ALG_MD2 );
616 case MBEDTLS_MD_MD4:
617 return( PSA_ALG_MD4 );
618 case MBEDTLS_MD_MD5:
619 return( PSA_ALG_MD5 );
620 case MBEDTLS_MD_SHA1:
621 return( PSA_ALG_SHA_1 );
622 case MBEDTLS_MD_SHA224:
623 return( PSA_ALG_SHA_224 );
624 case MBEDTLS_MD_SHA256:
625 return( PSA_ALG_SHA_256 );
626 case MBEDTLS_MD_SHA384:
627 return( PSA_ALG_SHA_384 );
628 case MBEDTLS_MD_SHA512:
629 return( PSA_ALG_SHA_512 );
630 case MBEDTLS_MD_RIPEMD160:
631 return( PSA_ALG_RIPEMD160 );
632 default:
Gilles Peskine47c1bc02018-03-20 17:55:04 +0100633 return( 0 );
Gilles Peskine20035e32018-02-03 22:44:14 +0100634 }
635}
636#endif
637
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100638psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
639{
640 switch( operation->alg )
641 {
642#if defined(MBEDTLS_MD2_C)
643 case PSA_ALG_MD2:
644 mbedtls_md2_free( &operation->ctx.md2 );
645 break;
646#endif
647#if defined(MBEDTLS_MD4_C)
648 case PSA_ALG_MD4:
649 mbedtls_md4_free( &operation->ctx.md4 );
650 break;
651#endif
652#if defined(MBEDTLS_MD5_C)
653 case PSA_ALG_MD5:
654 mbedtls_md5_free( &operation->ctx.md5 );
655 break;
656#endif
657#if defined(MBEDTLS_RIPEMD160_C)
658 case PSA_ALG_RIPEMD160:
659 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
660 break;
661#endif
662#if defined(MBEDTLS_SHA1_C)
663 case PSA_ALG_SHA_1:
664 mbedtls_sha1_free( &operation->ctx.sha1 );
665 break;
666#endif
667#if defined(MBEDTLS_SHA256_C)
668 case PSA_ALG_SHA_224:
669 case PSA_ALG_SHA_256:
670 mbedtls_sha256_free( &operation->ctx.sha256 );
671 break;
672#endif
673#if defined(MBEDTLS_SHA512_C)
674 case PSA_ALG_SHA_384:
675 case PSA_ALG_SHA_512:
676 mbedtls_sha512_free( &operation->ctx.sha512 );
677 break;
678#endif
679 default:
680 return( PSA_ERROR_NOT_SUPPORTED );
681 }
682 operation->alg = 0;
683 return( PSA_SUCCESS );
684}
685
686psa_status_t psa_hash_start( psa_hash_operation_t *operation,
687 psa_algorithm_t alg )
688{
689 int ret;
690 operation->alg = 0;
691 switch( alg )
692 {
693#if defined(MBEDTLS_MD2_C)
694 case PSA_ALG_MD2:
695 mbedtls_md2_init( &operation->ctx.md2 );
696 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
697 break;
698#endif
699#if defined(MBEDTLS_MD4_C)
700 case PSA_ALG_MD4:
701 mbedtls_md4_init( &operation->ctx.md4 );
702 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
703 break;
704#endif
705#if defined(MBEDTLS_MD5_C)
706 case PSA_ALG_MD5:
707 mbedtls_md5_init( &operation->ctx.md5 );
708 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
709 break;
710#endif
711#if defined(MBEDTLS_RIPEMD160_C)
712 case PSA_ALG_RIPEMD160:
713 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
714 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
715 break;
716#endif
717#if defined(MBEDTLS_SHA1_C)
718 case PSA_ALG_SHA_1:
719 mbedtls_sha1_init( &operation->ctx.sha1 );
720 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
721 break;
722#endif
723#if defined(MBEDTLS_SHA256_C)
724 case PSA_ALG_SHA_224:
725 mbedtls_sha256_init( &operation->ctx.sha256 );
726 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
727 break;
728 case PSA_ALG_SHA_256:
729 mbedtls_sha256_init( &operation->ctx.sha256 );
730 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
731 break;
732#endif
733#if defined(MBEDTLS_SHA512_C)
734 case PSA_ALG_SHA_384:
735 mbedtls_sha512_init( &operation->ctx.sha512 );
736 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
737 break;
738 case PSA_ALG_SHA_512:
739 mbedtls_sha512_init( &operation->ctx.sha512 );
740 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
741 break;
742#endif
743 default:
744 return( PSA_ERROR_NOT_SUPPORTED );
745 }
746 if( ret == 0 )
747 operation->alg = alg;
748 else
749 psa_hash_abort( operation );
750 return( mbedtls_to_psa_error( ret ) );
751}
752
753psa_status_t psa_hash_update( psa_hash_operation_t *operation,
754 const uint8_t *input,
755 size_t input_length )
756{
757 int ret;
758 switch( operation->alg )
759 {
760#if defined(MBEDTLS_MD2_C)
761 case PSA_ALG_MD2:
762 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
763 input, input_length );
764 break;
765#endif
766#if defined(MBEDTLS_MD4_C)
767 case PSA_ALG_MD4:
768 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
769 input, input_length );
770 break;
771#endif
772#if defined(MBEDTLS_MD5_C)
773 case PSA_ALG_MD5:
774 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
775 input, input_length );
776 break;
777#endif
778#if defined(MBEDTLS_RIPEMD160_C)
779 case PSA_ALG_RIPEMD160:
780 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
781 input, input_length );
782 break;
783#endif
784#if defined(MBEDTLS_SHA1_C)
785 case PSA_ALG_SHA_1:
786 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
787 input, input_length );
788 break;
789#endif
790#if defined(MBEDTLS_SHA256_C)
791 case PSA_ALG_SHA_224:
792 case PSA_ALG_SHA_256:
793 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
794 input, input_length );
795 break;
796#endif
797#if defined(MBEDTLS_SHA512_C)
798 case PSA_ALG_SHA_384:
799 case PSA_ALG_SHA_512:
800 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
801 input, input_length );
802 break;
803#endif
804 default:
805 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
806 break;
807 }
808 if( ret != 0 )
809 psa_hash_abort( operation );
810 return( mbedtls_to_psa_error( ret ) );
811}
812
813psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
814 uint8_t *hash,
815 size_t hash_size,
816 size_t *hash_length )
817{
818 int ret;
819 size_t actual_hash_length = PSA_HASH_FINAL_SIZE( operation->alg );
820
821 /* Fill the output buffer with something that isn't a valid hash
822 * (barring an attack on the hash and deliberately-crafted input),
823 * in case the caller doesn't check the return status properly. */
824 *hash_length = actual_hash_length;
825 memset( hash, '!', hash_size );
826
827 if( hash_size < actual_hash_length )
828 return( PSA_ERROR_BUFFER_TOO_SMALL );
829
830 switch( operation->alg )
831 {
832#if defined(MBEDTLS_MD2_C)
833 case PSA_ALG_MD2:
834 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
835 break;
836#endif
837#if defined(MBEDTLS_MD4_C)
838 case PSA_ALG_MD4:
839 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
840 break;
841#endif
842#if defined(MBEDTLS_MD5_C)
843 case PSA_ALG_MD5:
844 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
845 break;
846#endif
847#if defined(MBEDTLS_RIPEMD160_C)
848 case PSA_ALG_RIPEMD160:
849 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
850 break;
851#endif
852#if defined(MBEDTLS_SHA1_C)
853 case PSA_ALG_SHA_1:
854 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
855 break;
856#endif
857#if defined(MBEDTLS_SHA256_C)
858 case PSA_ALG_SHA_224:
859 case PSA_ALG_SHA_256:
860 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
861 break;
862#endif
863#if defined(MBEDTLS_SHA512_C)
864 case PSA_ALG_SHA_384:
865 case PSA_ALG_SHA_512:
866 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
867 break;
868#endif
869 default:
870 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
871 break;
872 }
873
874 if( ret == 0 )
875 {
876 return( psa_hash_abort( operation ) );
877 }
878 else
879 {
880 psa_hash_abort( operation );
881 return( mbedtls_to_psa_error( ret ) );
882 }
883}
884
885psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
886 const uint8_t *hash,
887 size_t hash_length)
888{
889 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
890 size_t actual_hash_length;
891 psa_status_t status = psa_hash_finish( operation,
892 actual_hash, sizeof( actual_hash ),
893 &actual_hash_length );
894 if( status != PSA_SUCCESS )
895 return( status );
896 if( actual_hash_length != hash_length )
897 return( PSA_ERROR_INVALID_SIGNATURE );
898 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
899 return( PSA_ERROR_INVALID_SIGNATURE );
900 return( PSA_SUCCESS );
901}
902
903
904
905
906/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +0100907/* MAC */
908/****************************************************************/
909
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100910static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +0100911 psa_algorithm_t alg,
912 psa_key_type_t key_type,
mohammad1603f4f0d612018-06-03 15:04:51 +0300913 size_t key_bits,
914 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100915{
Gilles Peskine8c9def32018-02-08 10:02:12 +0100916 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +0300917 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100918
919 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
920 {
921 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +0200922 {
923 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
924 }
Gilles Peskine8c9def32018-02-08 10:02:12 +0100925 switch( alg )
926 {
927 case PSA_ALG_STREAM_CIPHER:
928 mode = MBEDTLS_MODE_STREAM;
929 break;
930 case PSA_ALG_CBC_BASE:
931 mode = MBEDTLS_MODE_CBC;
932 break;
933 case PSA_ALG_CFB_BASE:
934 mode = MBEDTLS_MODE_CFB;
935 break;
936 case PSA_ALG_OFB_BASE:
937 mode = MBEDTLS_MODE_OFB;
938 break;
939 case PSA_ALG_CTR:
940 mode = MBEDTLS_MODE_CTR;
941 break;
942 case PSA_ALG_CCM:
943 mode = MBEDTLS_MODE_CCM;
944 break;
945 case PSA_ALG_GCM:
946 mode = MBEDTLS_MODE_GCM;
947 break;
948 default:
949 return( NULL );
950 }
951 }
952 else if( alg == PSA_ALG_CMAC )
953 mode = MBEDTLS_MODE_ECB;
954 else if( alg == PSA_ALG_GMAC )
955 mode = MBEDTLS_MODE_GCM;
956 else
957 return( NULL );
958
959 switch( key_type )
960 {
961 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +0300962 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100963 break;
964 case PSA_KEY_TYPE_DES:
965 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +0300966 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100967 else
mohammad1603f4f0d612018-06-03 15:04:51 +0300968 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100969 break;
970 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +0300971 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100972 break;
973 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +0300974 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100975 break;
976 default:
977 return( NULL );
978 }
mohammad1603f4f0d612018-06-03 15:04:51 +0300979 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +0300980 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100981
mohammad1603f4f0d612018-06-03 15:04:51 +0300982 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +0100983}
984
985psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
986{
987 switch( operation->alg )
988 {
989#if defined(MBEDTLS_CMAC_C)
990 case PSA_ALG_CMAC:
991 mbedtls_cipher_free( &operation->ctx.cmac );
992 break;
993#endif /* MBEDTLS_CMAC_C */
994 default:
995#if defined(MBEDTLS_MD_C)
996 if( PSA_ALG_IS_HMAC( operation->alg ) )
997 mbedtls_md_free( &operation->ctx.hmac );
998 else
999#endif /* MBEDTLS_MD_C */
1000 return( PSA_ERROR_NOT_SUPPORTED );
1001 }
Moran Peker41deec42018-04-04 15:43:05 +03001002
Gilles Peskine8c9def32018-02-08 10:02:12 +01001003 operation->alg = 0;
1004 operation->key_set = 0;
1005 operation->iv_set = 0;
1006 operation->iv_required = 0;
1007 operation->has_input = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001008
Gilles Peskine8c9def32018-02-08 10:02:12 +01001009 return( PSA_SUCCESS );
1010}
1011
1012psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1013 psa_key_slot_t key,
1014 psa_algorithm_t alg )
1015{
1016 int ret = MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
1017 psa_status_t status;
1018 key_slot_t *slot;
1019 psa_key_type_t key_type;
1020 size_t key_bits;
1021 const mbedtls_cipher_info_t *cipher_info = NULL;
1022
1023 operation->alg = 0;
1024 operation->key_set = 0;
1025 operation->iv_set = 0;
1026 operation->iv_required = 1;
1027 operation->has_input = 0;
1028
1029 status = psa_get_key_information( key, &key_type, &key_bits );
1030 if( status != PSA_SUCCESS )
1031 return( status );
1032 slot = &global_data.key_slots[key];
1033
Moran Pekerd7326592018-05-29 16:56:39 +03001034 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001035 operation->key_usage_sign = 1;
1036
Moran Pekerd7326592018-05-29 16:56:39 +03001037 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001038 operation->key_usage_verify = 1;
1039
Gilles Peskine8c9def32018-02-08 10:02:12 +01001040 if( ! PSA_ALG_IS_HMAC( alg ) )
1041 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001042 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001043 if( cipher_info == NULL )
1044 return( PSA_ERROR_NOT_SUPPORTED );
1045 operation->mac_size = cipher_info->block_size;
1046 }
1047 switch( alg )
1048 {
1049#if defined(MBEDTLS_CMAC_C)
1050 case PSA_ALG_CMAC:
1051 operation->iv_required = 0;
1052 mbedtls_cipher_init( &operation->ctx.cmac );
1053 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1054 if( ret != 0 )
1055 break;
1056 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1057 slot->data.raw.data,
1058 key_bits );
1059 break;
1060#endif /* MBEDTLS_CMAC_C */
1061 default:
1062#if defined(MBEDTLS_MD_C)
1063 if( PSA_ALG_IS_HMAC( alg ) )
1064 {
1065 const mbedtls_md_info_t *md_info =
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001066 mbedtls_md_info_from_psa( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001067 if( md_info == NULL )
1068 return( PSA_ERROR_NOT_SUPPORTED );
1069 if( key_type != PSA_KEY_TYPE_HMAC )
1070 return( PSA_ERROR_INVALID_ARGUMENT );
1071 operation->iv_required = 0;
1072 operation->mac_size = mbedtls_md_get_size( md_info );
1073 mbedtls_md_init( &operation->ctx.hmac );
1074 ret = mbedtls_md_setup( &operation->ctx.hmac, md_info, 1 );
1075 if( ret != 0 )
1076 break;
1077 ret = mbedtls_md_hmac_starts( &operation->ctx.hmac,
1078 slot->data.raw.data,
1079 slot->data.raw.bytes );
1080 break;
1081 }
1082 else
1083#endif /* MBEDTLS_MD_C */
1084 return( PSA_ERROR_NOT_SUPPORTED );
1085 }
1086
1087 /* If we reach this point, then the algorithm-specific part of the
1088 * context has at least been initialized, and may contain data that
1089 * needs to be wiped on error. */
1090 operation->alg = alg;
1091 if( ret != 0 )
1092 {
1093 psa_mac_abort( operation );
1094 return( mbedtls_to_psa_error( ret ) );
1095 }
1096 operation->key_set = 1;
Gilles Peskine47c1bc02018-03-20 17:55:04 +01001097 return( PSA_SUCCESS );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001098}
1099
1100psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1101 const uint8_t *input,
1102 size_t input_length )
1103{
1104 int ret;
1105 if( ! operation->key_set )
1106 return( PSA_ERROR_BAD_STATE );
1107 if( operation->iv_required && ! operation->iv_set )
1108 return( PSA_ERROR_BAD_STATE );
1109 operation->has_input = 1;
1110
1111 switch( operation->alg )
1112 {
1113#if defined(MBEDTLS_CMAC_C)
1114 case PSA_ALG_CMAC:
1115 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1116 input, input_length );
1117 break;
1118#endif /* MBEDTLS_CMAC_C */
1119 default:
1120#if defined(MBEDTLS_MD_C)
1121 if( PSA_ALG_IS_HMAC( operation->alg ) )
1122 {
1123 ret = mbedtls_md_hmac_update( &operation->ctx.hmac,
1124 input, input_length );
1125 }
1126 else
1127#endif /* MBEDTLS_MD_C */
1128 {
1129 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1130 }
1131 break;
1132 }
1133 if( ret != 0 )
1134 psa_mac_abort( operation );
1135 return( mbedtls_to_psa_error( ret ) );
1136}
1137
mohammad16036df908f2018-04-02 08:34:15 -07001138static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine8c9def32018-02-08 10:02:12 +01001139 uint8_t *mac,
1140 size_t mac_size,
1141 size_t *mac_length )
1142{
1143 int ret;
1144 if( ! operation->key_set )
1145 return( PSA_ERROR_BAD_STATE );
1146 if( operation->iv_required && ! operation->iv_set )
1147 return( PSA_ERROR_BAD_STATE );
1148
1149 /* Fill the output buffer with something that isn't a valid mac
1150 * (barring an attack on the mac and deliberately-crafted input),
1151 * in case the caller doesn't check the return status properly. */
1152 *mac_length = operation->mac_size;
1153 memset( mac, '!', mac_size );
1154
1155 if( mac_size < operation->mac_size )
1156 return( PSA_ERROR_BUFFER_TOO_SMALL );
1157
1158 switch( operation->alg )
1159 {
1160#if defined(MBEDTLS_CMAC_C)
1161 case PSA_ALG_CMAC:
1162 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1163 break;
1164#endif /* MBEDTLS_CMAC_C */
1165 default:
1166#if defined(MBEDTLS_MD_C)
1167 if( PSA_ALG_IS_HMAC( operation->alg ) )
1168 {
1169 ret = mbedtls_md_hmac_finish( &operation->ctx.hmac, mac );
1170 }
1171 else
1172#endif /* MBEDTLS_MD_C */
1173 {
1174 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1175 }
1176 break;
1177 }
1178
1179 if( ret == 0 )
1180 {
1181 return( psa_mac_abort( operation ) );
1182 }
1183 else
1184 {
1185 psa_mac_abort( operation );
1186 return( mbedtls_to_psa_error( ret ) );
1187 }
1188}
1189
mohammad16036df908f2018-04-02 08:34:15 -07001190psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1191 uint8_t *mac,
1192 size_t mac_size,
1193 size_t *mac_length )
1194{
1195 if( !( operation->key_usage_sign ) )
1196 return( PSA_ERROR_NOT_PERMITTED );
1197
1198 return( psa_mac_finish_internal(operation, mac, mac_size, mac_length ) );
1199}
1200
Gilles Peskine8c9def32018-02-08 10:02:12 +01001201#define MBEDTLS_PSA_MAC_MAX_SIZE \
1202 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1203 MBEDTLS_MD_MAX_SIZE : \
1204 MBEDTLS_MAX_BLOCK_LENGTH )
1205psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1206 const uint8_t *mac,
1207 size_t mac_length )
1208{
1209 uint8_t actual_mac[MBEDTLS_PSA_MAC_MAX_SIZE];
1210 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001211 psa_status_t status;
1212
1213 if( !( operation->key_usage_verify ) )
1214 return( PSA_ERROR_NOT_PERMITTED );
1215
1216 status = psa_mac_finish_internal( operation,
1217 actual_mac, sizeof( actual_mac ),
1218 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001219 if( status != PSA_SUCCESS )
1220 return( status );
1221 if( actual_mac_length != mac_length )
1222 return( PSA_ERROR_INVALID_SIGNATURE );
1223 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1224 return( PSA_ERROR_INVALID_SIGNATURE );
1225 return( PSA_SUCCESS );
1226}
1227
1228
Gilles Peskine20035e32018-02-03 22:44:14 +01001229
1230
1231/****************************************************************/
1232/* Asymmetric cryptography */
1233/****************************************************************/
1234
1235psa_status_t psa_asymmetric_sign(psa_key_slot_t key,
1236 psa_algorithm_t alg,
1237 const uint8_t *hash,
1238 size_t hash_length,
1239 const uint8_t *salt,
1240 size_t salt_length,
1241 uint8_t *signature,
1242 size_t signature_size,
1243 size_t *signature_length)
1244{
1245 key_slot_t *slot;
1246
Gilles Peskine93aa0332018-02-03 23:58:03 +01001247 *signature_length = 0;
1248 (void) salt;
1249 (void) salt_length;
1250
Gilles Peskine20035e32018-02-03 22:44:14 +01001251 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1252 return( PSA_ERROR_EMPTY_SLOT );
1253 slot = &global_data.key_slots[key];
1254 if( slot->type == PSA_KEY_TYPE_NONE )
1255 return( PSA_ERROR_EMPTY_SLOT );
1256 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1257 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +03001258 if( !( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
1259 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001260
Gilles Peskine20035e32018-02-03 22:44:14 +01001261#if defined(MBEDTLS_RSA_C)
1262 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1263 {
1264 mbedtls_rsa_context *rsa = slot->data.rsa;
1265 int ret;
1266 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001267 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01001268 mbedtls_md_type_t md_alg =
1269 hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1270 if( md_alg == MBEDTLS_MD_NONE )
1271 {
1272#if SIZE_MAX > UINT_MAX
1273 if( hash_length > UINT_MAX )
1274 return( PSA_ERROR_INVALID_ARGUMENT );
1275#endif
1276 }
1277 else
1278 {
1279 if( mbedtls_md_get_size( md_info ) != hash_length )
1280 return( PSA_ERROR_INVALID_ARGUMENT );
1281 if( md_info == NULL )
1282 return( PSA_ERROR_NOT_SUPPORTED );
1283 }
1284 if( signature_size < rsa->len )
1285 return( PSA_ERROR_BUFFER_TOO_SMALL );
1286#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001287 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001288 {
1289 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1290 MBEDTLS_MD_NONE );
1291 ret = mbedtls_rsa_pkcs1_sign( rsa,
1292 mbedtls_ctr_drbg_random,
1293 &global_data.ctr_drbg,
1294 MBEDTLS_RSA_PRIVATE,
1295 md_alg, hash_length, hash,
1296 signature );
1297 }
1298 else
1299#endif /* MBEDTLS_PKCS1_V15 */
1300#if defined(MBEDTLS_PKCS1_V21)
1301 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1302 {
1303 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1304 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1305 mbedtls_ctr_drbg_random,
1306 &global_data.ctr_drbg,
1307 MBEDTLS_RSA_PRIVATE,
1308 md_alg, hash_length, hash,
1309 signature );
1310 }
1311 else
1312#endif /* MBEDTLS_PKCS1_V21 */
1313 {
1314 return( PSA_ERROR_INVALID_ARGUMENT );
1315 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001316 if( ret == 0 )
1317 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001318 return( mbedtls_to_psa_error( ret ) );
1319 }
1320 else
1321#endif /* defined(MBEDTLS_RSA_C) */
1322#if defined(MBEDTLS_ECP_C)
1323 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1324 {
itayzafrir5c753392018-05-08 11:18:38 +03001325 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1326 int ret;
1327 const mbedtls_md_info_t *md_info;
1328 mbedtls_md_type_t md_alg;
1329 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1330 return( PSA_ERROR_BUFFER_TOO_SMALL );
1331 md_info = mbedtls_md_info_from_psa( alg );
1332 md_alg = mbedtls_md_get_type( md_info );
1333 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
1334 signature, signature_length, mbedtls_ctr_drbg_random,
1335 &global_data.ctr_drbg );
1336 return( mbedtls_to_psa_error( ret ) );
1337 }
1338 else
1339#endif /* defined(MBEDTLS_ECP_C) */
1340 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001341 return( PSA_ERROR_NOT_SUPPORTED );
1342 }
itayzafrir5c753392018-05-08 11:18:38 +03001343}
1344
1345psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1346 psa_algorithm_t alg,
1347 const uint8_t *hash,
1348 size_t hash_length,
1349 const uint8_t *salt,
1350 size_t salt_length,
1351 uint8_t *signature,
1352 size_t signature_size )
1353{
1354 key_slot_t *slot;
1355 (void) salt;
1356 (void) salt_length;
1357
1358 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1359 return( PSA_ERROR_INVALID_ARGUMENT );
1360 slot = &global_data.key_slots[key];
1361 if( slot->type == PSA_KEY_TYPE_NONE )
1362 return( PSA_ERROR_EMPTY_SLOT );
1363 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1364 return( PSA_ERROR_INVALID_ARGUMENT );
1365 if( !( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
1366 return( PSA_ERROR_NOT_PERMITTED );
1367
1368#if defined(MBEDTLS_ECP_C)
1369 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1370 {
1371 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1372 int ret;
1373 (void) alg;
1374 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length, signature,
1375 signature_size );
1376 return( mbedtls_to_psa_error( ret ) );
1377 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001378 else
1379#endif /* defined(MBEDTLS_ECP_C) */
1380 {
1381 return( PSA_ERROR_NOT_SUPPORTED );
1382 }
1383}
1384
1385
mohammad1603503973b2018-03-12 15:59:30 +02001386/****************************************************************/
1387/* Symmetric cryptography */
1388/****************************************************************/
1389
Gilles Peskinee553c652018-06-04 16:22:46 +02001390static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1391 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001392 psa_algorithm_t alg,
1393 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001394{
1395 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1396 psa_status_t status;
1397 key_slot_t *slot;
1398 psa_key_type_t key_type;
1399 size_t key_bits;
1400 const mbedtls_cipher_info_t *cipher_info = NULL;
1401
Moran Peker41deec42018-04-04 15:43:05 +03001402 operation->alg = alg;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001403 operation->key_set = 0;
1404 operation->iv_set = 0;
1405 operation->iv_required = 1;
1406 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001407 operation->block_size = 0;
mohammad1603503973b2018-03-12 15:59:30 +02001408
1409 status = psa_get_key_information( key, &key_type, &key_bits );
1410 if( status != PSA_SUCCESS )
1411 return( status );
1412 slot = &global_data.key_slots[key];
1413
1414 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits );
1415 if( cipher_info == NULL )
1416 return( PSA_ERROR_NOT_SUPPORTED );
1417
mohammad1603503973b2018-03-12 15:59:30 +02001418 mbedtls_cipher_init( &operation->ctx.cipher );
1419 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03001420 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001421 {
1422 psa_cipher_abort( operation );
1423 return( mbedtls_to_psa_error( ret ) );
1424 }
1425
1426 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
Gilles Peskinee553c652018-06-04 16:22:46 +02001427 key_bits, cipher_operation );
Moran Peker41deec42018-04-04 15:43:05 +03001428 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001429 {
1430 psa_cipher_abort( operation );
1431 return( mbedtls_to_psa_error( ret ) );
1432 }
1433
mohammad16038481e742018-03-18 13:57:31 +02001434#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03001435 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02001436 {
Gilles Peskine53514202018-06-06 15:11:46 +02001437 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1438 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02001439
Moran Pekera28258c2018-05-29 16:25:04 +03001440 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02001441 {
1442 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
1443 mode = MBEDTLS_PADDING_PKCS7;
1444 break;
1445 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
1446 mode = MBEDTLS_PADDING_NONE;
1447 break;
1448 default:
Moran Pekerae382792018-05-31 14:06:17 +03001449 psa_cipher_abort( operation );
1450 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02001451 }
1452 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03001453 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03001454 {
1455 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02001456 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03001457 }
mohammad16038481e742018-03-18 13:57:31 +02001458 }
1459#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
1460
mohammad1603503973b2018-03-12 15:59:30 +02001461 operation->key_set = 1;
1462 operation->alg = alg;
Gilles Peskine7e928852018-06-04 16:23:10 +02001463 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
1464 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
1465 1 );
Moran Peker41deec42018-04-04 15:43:05 +03001466 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || ( alg == PSA_ALG_CTR ) )
mohammad16038481e742018-03-18 13:57:31 +02001467 {
mohammad160389e0f462018-04-12 08:48:45 +03001468 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02001469 }
mohammad1603503973b2018-03-12 15:59:30 +02001470
Moran Peker395db872018-05-31 14:07:14 +03001471 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001472}
1473
Gilles Peskinee553c652018-06-04 16:22:46 +02001474psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
1475 psa_key_slot_t key,
1476 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001477{
Moran Pekera28258c2018-05-29 16:25:04 +03001478 return psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT );
mohammad16038481e742018-03-18 13:57:31 +02001479}
1480
Gilles Peskinee553c652018-06-04 16:22:46 +02001481psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
1482 psa_key_slot_t key,
1483 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001484{
Moran Pekera28258c2018-05-29 16:25:04 +03001485 return psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT );
mohammad16038481e742018-03-18 13:57:31 +02001486}
1487
Gilles Peskinee553c652018-06-04 16:22:46 +02001488psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
1489 unsigned char *iv,
1490 size_t iv_size,
1491 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001492{
Moran Peker41deec42018-04-04 15:43:05 +03001493 int ret = PSA_SUCCESS;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001494 if( operation->iv_set || !( operation->iv_required ) )
Moran Peker41deec42018-04-04 15:43:05 +03001495 return( PSA_ERROR_BAD_STATE );
1496 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02001497 {
Moran Peker41deec42018-04-04 15:43:05 +03001498 ret = PSA_ERROR_BUFFER_TOO_SMALL;
1499 goto exit;
1500 }
Gilles Peskine7e928852018-06-04 16:23:10 +02001501 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
1502 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03001503 if( ret != 0 )
1504 {
1505 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02001506 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02001507 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001508
mohammad16038481e742018-03-18 13:57:31 +02001509 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03001510 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001511
Moran Peker395db872018-05-31 14:07:14 +03001512exit:
1513 if( ret != PSA_SUCCESS )
1514 psa_cipher_abort( operation );
1515 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02001516}
1517
Gilles Peskinee553c652018-06-04 16:22:46 +02001518psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
1519 const unsigned char *iv,
1520 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001521{
Moran Peker41deec42018-04-04 15:43:05 +03001522 int ret = PSA_SUCCESS;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001523 if( operation->iv_set || !( operation->iv_required ) )
Moran Peker41deec42018-04-04 15:43:05 +03001524 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03001525 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03001526 {
Moran Pekerae382792018-05-31 14:06:17 +03001527 psa_cipher_abort( operation );
1528 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03001529 }
mohammad1603503973b2018-03-12 15:59:30 +02001530 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001531 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001532 {
1533 psa_cipher_abort( operation );
1534 return( mbedtls_to_psa_error( ret ) );
1535 }
1536
1537 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02001538
Moran Peker395db872018-05-31 14:07:14 +03001539 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001540}
1541
Gilles Peskinee553c652018-06-04 16:22:46 +02001542psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
1543 const uint8_t *input,
1544 size_t input_length,
1545 unsigned char *output,
1546 size_t output_size,
1547 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001548{
1549 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02001550 size_t expected_output_size;
1551 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
1552 {
1553 /* Take the unprocessed partial block left over from previous
1554 * update calls, if any, plus the input to this call. Remove
1555 * the last partial block, if any. You get the data that will be
1556 * output in this call. */
1557 expected_output_size =
1558 ( operation->ctx.cipher.unprocessed_len + input_length )
1559 / operation->block_size * operation->block_size;
1560 }
1561 else
1562 {
1563 expected_output_size = input_length;
1564 }
1565 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03001566 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02001567
mohammad1603503973b2018-03-12 15:59:30 +02001568 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02001569 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03001570 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001571 {
1572 psa_cipher_abort( operation );
1573 return( mbedtls_to_psa_error( ret ) );
1574 }
1575
Moran Peker395db872018-05-31 14:07:14 +03001576 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001577}
1578
Gilles Peskinee553c652018-06-04 16:22:46 +02001579psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
1580 uint8_t *output,
1581 size_t output_size,
1582 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001583{
1584 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02001585 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03001586
mohammad1603503973b2018-03-12 15:59:30 +02001587 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001588 {
Moran Peker7cb22b82018-06-05 11:40:02 +03001589 psa_cipher_abort( operation );
1590 return( PSA_ERROR_BAD_STATE );
1591 }
1592 if( operation->iv_required && ! operation->iv_set )
1593 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001594 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001595 return( PSA_ERROR_BAD_STATE );
1596 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001597 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
1598 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03001599 {
Gilles Peskine53514202018-06-06 15:11:46 +02001600 psa_algorithm_t padding_mode =
1601 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03001602 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02001603 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001604 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001605 return( PSA_ERROR_TAMPERING_DETECTED );
1606 }
Gilles Peskine53514202018-06-06 15:11:46 +02001607 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03001608 {
1609 if( operation->ctx.cipher.unprocessed_len != 0 )
1610 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001611 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001612 return( PSA_ERROR_INVALID_ARGUMENT );
1613 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02001614 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001615 }
1616
1617 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02001618 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03001619 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001620 {
1621 psa_cipher_abort( operation );
1622 return( mbedtls_to_psa_error( ret ) );
1623 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001624 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001625 memcpy( output, temp_output_buffer, *output_length );
1626 else
1627 {
1628 psa_cipher_abort( operation );
1629 return( PSA_ERROR_BUFFER_TOO_SMALL );
1630 }
mohammad1603503973b2018-03-12 15:59:30 +02001631
Moran Peker4c80d832018-04-22 20:15:31 +03001632 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001633}
1634
Gilles Peskinee553c652018-06-04 16:22:46 +02001635psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
1636{
mohammad1603503973b2018-03-12 15:59:30 +02001637 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02001638
Moran Peker41deec42018-04-04 15:43:05 +03001639 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001640 operation->key_set = 0;
1641 operation->iv_set = 0;
1642 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001643 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001644 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001645
Moran Peker395db872018-05-31 14:07:14 +03001646 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001647}
1648
Gilles Peskinea0655c32018-04-30 17:06:50 +02001649
mohammad16038cc1cee2018-03-28 01:21:33 +03001650/****************************************************************/
1651/* Key Policy */
1652/****************************************************************/
1653
1654void psa_key_policy_init(psa_key_policy_t *policy)
1655{
mohammad16036df908f2018-04-02 08:34:15 -07001656 memset( policy, 0, sizeof( psa_key_policy_t ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03001657}
1658
1659void psa_key_policy_set_usage(psa_key_policy_t *policy,
1660 psa_key_usage_t usage,
1661 psa_algorithm_t alg)
1662{
mohammad16034eed7572018-03-28 05:14:59 -07001663 policy->usage = usage;
1664 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03001665}
1666
1667psa_key_usage_t psa_key_policy_get_usage(psa_key_policy_t *policy)
1668{
mohammad16036df908f2018-04-02 08:34:15 -07001669 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03001670}
1671
1672psa_algorithm_t psa_key_policy_get_algorithm(psa_key_policy_t *policy)
1673{
mohammad16036df908f2018-04-02 08:34:15 -07001674 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03001675}
1676
1677psa_status_t psa_set_key_policy(psa_key_slot_t key,
1678 const psa_key_policy_t *policy)
1679{
1680 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03001681
1682 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
1683 return( PSA_ERROR_INVALID_ARGUMENT );
1684
1685 slot = &global_data.key_slots[key];
1686 if( slot->type != PSA_KEY_TYPE_NONE )
1687 return( PSA_ERROR_OCCUPIED_SLOT );
1688
mohammad16036df908f2018-04-02 08:34:15 -07001689 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT
1690 | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_SIGN
1691 | PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07001692 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03001693
mohammad16036df908f2018-04-02 08:34:15 -07001694 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03001695
1696 return( PSA_SUCCESS );
1697}
1698
1699psa_status_t psa_get_key_policy(psa_key_slot_t key,
1700 psa_key_policy_t *policy)
1701{
1702 key_slot_t *slot;
1703
1704 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
1705 return( PSA_ERROR_INVALID_ARGUMENT );
1706
1707 slot = &global_data.key_slots[key];
mohammad16038cc1cee2018-03-28 01:21:33 +03001708
mohammad16036df908f2018-04-02 08:34:15 -07001709 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03001710
1711 return( PSA_SUCCESS );
1712}
Gilles Peskine20035e32018-02-03 22:44:14 +01001713
Gilles Peskinea0655c32018-04-30 17:06:50 +02001714
1715
mohammad1603804cd712018-03-20 22:44:08 +02001716/****************************************************************/
1717/* Key Lifetime */
1718/****************************************************************/
1719
1720psa_status_t psa_get_key_lifetime(psa_key_slot_t key,
1721 psa_key_lifetime_t *lifetime)
1722{
1723 key_slot_t *slot;
1724
1725 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1726 return( PSA_ERROR_INVALID_ARGUMENT );
1727
1728 slot = &global_data.key_slots[key];
mohammad1603804cd712018-03-20 22:44:08 +02001729
1730 *lifetime = slot->lifetime;
1731
1732 return( PSA_SUCCESS );
1733}
1734
1735psa_status_t psa_set_key_lifetime(psa_key_slot_t key,
1736 const psa_key_lifetime_t lifetime)
1737{
1738 key_slot_t *slot;
1739
1740 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1741 return( PSA_ERROR_INVALID_ARGUMENT );
1742
mohammad1603ba178512018-03-21 04:35:20 -07001743 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
1744 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
1745 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
1746 return( PSA_ERROR_INVALID_ARGUMENT );
1747
mohammad1603804cd712018-03-20 22:44:08 +02001748 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03001749 if( slot->type != PSA_KEY_TYPE_NONE )
1750 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02001751
Moran Pekerd7326592018-05-29 16:56:39 +03001752 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07001753 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603804cd712018-03-20 22:44:08 +02001754
mohammad1603060ad8a2018-03-20 14:28:38 -07001755 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02001756
1757 return( PSA_SUCCESS );
1758}
1759
Gilles Peskine20035e32018-02-03 22:44:14 +01001760
mohammad16035955c982018-04-26 00:53:03 +03001761/****************************************************************/
1762/* AEAD */
1763/****************************************************************/
1764psa_status_t psa_aead_encrypt( psa_key_slot_t key,
1765 psa_algorithm_t alg,
1766 const uint8_t *nonce,
1767 size_t nonce_length,
1768 const uint8_t *additional_data,
1769 size_t additional_data_length,
1770 const uint8_t *plaintext,
1771 size_t plaintext_length,
1772 uint8_t *ciphertext,
1773 size_t ciphertext_size,
1774 size_t *ciphertext_length )
1775{
1776 int ret;
1777 psa_status_t status;
1778 key_slot_t *slot;
1779 psa_key_type_t key_type;
1780 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03001781 uint8_t *tag;
1782 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07001783 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03001784 const mbedtls_cipher_info_t *cipher_info = NULL;
1785
mohammad1603f08a5502018-06-03 15:05:47 +03001786 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07001787
mohammad16035955c982018-04-26 00:53:03 +03001788 status = psa_get_key_information( key, &key_type, &key_bits );
1789 if( status != PSA_SUCCESS )
1790 return( status );
1791 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03001792 if( slot->type == PSA_KEY_TYPE_NONE )
1793 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03001794
mohammad16035ed06212018-06-06 13:09:34 +03001795 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
1796 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03001797 if( cipher_info == NULL )
1798 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07001799
mohammad1603f14394b2018-06-04 14:33:19 +03001800 if( !( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1801 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03001802
mohammad16036b4d98c2018-06-06 13:19:51 +03001803 if ( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
mohammad16035ed06212018-06-06 13:09:34 +03001804 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03001805 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03001806
mohammad16035955c982018-04-26 00:53:03 +03001807 if( alg == PSA_ALG_GCM )
1808 {
1809 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03001810 tag_length = 16;
1811
mohammad160396910d82018-06-04 14:33:00 +03001812 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
1813 return( PSA_ERROR_INVALID_ARGUMENT );
1814
mohammad160315223a82018-06-03 17:19:55 +03001815 //make sure we have place to hold the tag in the ciphertext buffer
1816 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03001817 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03001818
1819 //update the tag pointer to point to the end of the ciphertext_length
1820 tag = ciphertext + plaintext_length;
1821
mohammad16035955c982018-04-26 00:53:03 +03001822 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02001823 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03001824 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02001825 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03001826 if( ret != 0 )
1827 {
1828 mbedtls_gcm_free( &gcm );
1829 return( mbedtls_to_psa_error( ret ) );
1830 }
1831 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02001832 plaintext_length, nonce,
1833 nonce_length, additional_data,
1834 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03001835 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03001836 mbedtls_gcm_free( &gcm );
1837 }
1838 else if( alg == PSA_ALG_CCM )
1839 {
1840 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03001841 tag_length = 16;
1842
mohammad160396910d82018-06-04 14:33:00 +03001843 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
1844 return( PSA_ERROR_INVALID_ARGUMENT );
1845
mohammad160347ddf3d2018-04-26 01:11:21 +03001846 if( nonce_length < 7 || nonce_length > 13 )
1847 return( PSA_ERROR_INVALID_ARGUMENT );
1848
mohammad160315223a82018-06-03 17:19:55 +03001849 //make sure we have place to hold the tag in the ciphertext buffer
1850 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03001851 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03001852
1853 //update the tag pointer to point to the end of the ciphertext_length
1854 tag = ciphertext + plaintext_length;
1855
1856
1857
mohammad16035955c982018-04-26 00:53:03 +03001858 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02001859 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03001860 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03001861 if( ret != 0 )
1862 {
1863 mbedtls_ccm_free( &ccm );
1864 return( mbedtls_to_psa_error( ret ) );
1865 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02001866 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
1867 nonce, nonce_length, additional_data,
1868 additional_data_length,
1869 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03001870 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03001871 mbedtls_ccm_free( &ccm );
1872 }
mohammad16035c8845f2018-05-09 05:40:09 -07001873 else
1874 {
mohammad1603554faad2018-06-03 15:07:38 +03001875 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07001876 }
mohammad160315223a82018-06-03 17:19:55 +03001877
1878 if( ret != 0 )
1879 {
1880 memset( ciphertext, 0, ciphertext_size );
1881 return( mbedtls_to_psa_error( ret ) );
1882 }
1883
1884 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03001885 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03001886}
1887
Gilles Peskineee652a32018-06-01 19:23:52 +02001888/* Locate the tag in a ciphertext buffer containing the encrypted data
1889 * followed by the tag. Return the length of the part preceding the tag in
1890 * *plaintext_length. This is the size of the plaintext in modes where
1891 * the encrypted data has the same size as the plaintext, such as
1892 * CCM and GCM. */
1893static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
1894 const uint8_t *ciphertext,
1895 size_t ciphertext_length,
1896 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02001897 const uint8_t **p_tag )
1898{
1899 size_t payload_length;
1900 if( tag_length > ciphertext_length )
1901 return( PSA_ERROR_INVALID_ARGUMENT );
1902 payload_length = ciphertext_length - tag_length;
1903 if( payload_length > plaintext_size )
1904 return( PSA_ERROR_BUFFER_TOO_SMALL );
1905 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02001906 return( PSA_SUCCESS );
1907}
1908
mohammad16035955c982018-04-26 00:53:03 +03001909psa_status_t psa_aead_decrypt( psa_key_slot_t key,
1910 psa_algorithm_t alg,
1911 const uint8_t *nonce,
1912 size_t nonce_length,
1913 const uint8_t *additional_data,
1914 size_t additional_data_length,
1915 const uint8_t *ciphertext,
1916 size_t ciphertext_length,
1917 uint8_t *plaintext,
1918 size_t plaintext_size,
1919 size_t *plaintext_length )
1920{
1921 int ret;
1922 psa_status_t status;
1923 key_slot_t *slot;
1924 psa_key_type_t key_type;
1925 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02001926 const uint8_t *tag;
1927 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07001928 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03001929 const mbedtls_cipher_info_t *cipher_info = NULL;
1930
Gilles Peskineee652a32018-06-01 19:23:52 +02001931 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03001932
mohammad16035955c982018-04-26 00:53:03 +03001933 status = psa_get_key_information( key, &key_type, &key_bits );
1934 if( status != PSA_SUCCESS )
1935 return( status );
1936 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03001937 if( slot->type == PSA_KEY_TYPE_NONE )
1938 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03001939
mohammad16035ed06212018-06-06 13:09:34 +03001940 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
1941 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03001942 if( cipher_info == NULL )
1943 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603f14394b2018-06-04 14:33:19 +03001944
1945 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1946 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03001947
mohammad1603fc614b12018-06-07 01:43:52 +03001948 if ( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
1949 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03001950 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03001951
mohammad16035955c982018-04-26 00:53:03 +03001952 if( alg == PSA_ALG_GCM )
1953 {
1954 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03001955
Gilles Peskineee652a32018-06-01 19:23:52 +02001956 tag_length = 16;
1957 status = psa_aead_unpadded_locate_tag( tag_length,
1958 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03001959 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02001960 if( status != PSA_SUCCESS )
1961 return( status );
1962
mohammad16035955c982018-04-26 00:53:03 +03001963 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02001964 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03001965 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03001966 if( ret != 0 )
1967 {
1968 mbedtls_gcm_free( &gcm );
1969 return( mbedtls_to_psa_error( ret ) );
1970 }
mohammad16035955c982018-04-26 00:53:03 +03001971
Gilles Peskineee652a32018-06-01 19:23:52 +02001972 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03001973 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02001974 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03001975 additional_data,
1976 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02001977 tag, tag_length,
1978 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03001979 mbedtls_gcm_free( &gcm );
1980 }
1981 else if( alg == PSA_ALG_CCM )
1982 {
1983 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02001984
mohammad160347ddf3d2018-04-26 01:11:21 +03001985 if( nonce_length < 7 || nonce_length > 13 )
1986 return( PSA_ERROR_INVALID_ARGUMENT );
1987
mohammad16039375f842018-06-03 14:28:24 +03001988 tag_length = 16;
1989 status = psa_aead_unpadded_locate_tag( tag_length,
1990 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03001991 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03001992 if( status != PSA_SUCCESS )
1993 return( status );
1994
mohammad16035955c982018-04-26 00:53:03 +03001995 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02001996 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03001997 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03001998 if( ret != 0 )
1999 {
2000 mbedtls_ccm_free( &ccm );
2001 return( mbedtls_to_psa_error( ret ) );
2002 }
mohammad160360a64d02018-06-03 17:20:42 +03002003 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002004 nonce, nonce_length,
2005 additional_data, additional_data_length,
2006 ciphertext, plaintext,
2007 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002008 mbedtls_ccm_free( &ccm );
2009 }
mohammad160339574652018-06-01 04:39:53 -07002010 else
2011 {
mohammad1603554faad2018-06-03 15:07:38 +03002012 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002013 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002014
Gilles Peskineee652a32018-06-01 19:23:52 +02002015 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002016 memset( plaintext, 0, plaintext_size );
2017 else
2018 *plaintext_length = ciphertext_length - tag_length;
2019
Gilles Peskineee652a32018-06-01 19:23:52 +02002020 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002021}
2022
Gilles Peskinea0655c32018-04-30 17:06:50 +02002023
Gilles Peskine20035e32018-02-03 22:44:14 +01002024/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002025/* Module setup */
2026/****************************************************************/
2027
Gilles Peskinee59236f2018-01-27 23:32:46 +01002028void mbedtls_psa_crypto_free( void )
2029{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002030 size_t key;
2031 for( key = 1; key < MBEDTLS_PSA_KEY_SLOT_COUNT; key++ )
2032 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002033 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2034 mbedtls_entropy_free( &global_data.entropy );
2035 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2036}
2037
2038psa_status_t psa_crypto_init( void )
2039{
2040 int ret;
2041 const unsigned char drbg_seed[] = "PSA";
2042
2043 if( global_data.initialized != 0 )
2044 return( PSA_SUCCESS );
2045
2046 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2047 mbedtls_entropy_init( &global_data.entropy );
2048 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2049
2050 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2051 mbedtls_entropy_func,
2052 &global_data.entropy,
2053 drbg_seed, sizeof( drbg_seed ) - 1 );
2054 if( ret != 0 )
2055 goto exit;
2056
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002057 global_data.initialized = 1;
2058
Gilles Peskinee59236f2018-01-27 23:32:46 +01002059exit:
2060 if( ret != 0 )
2061 mbedtls_psa_crypto_free( );
2062 return( mbedtls_to_psa_error( ret ) );
2063}
2064
2065#endif /* MBEDTLS_PSA_CRYPTO_C */