blob: 446c90ea04d7dddc4f3daa9399608777e95e4fe6 [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
4/* Copyright (C) 2018, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PSA_CRYPTO_C)
29
30#include "psa/crypto.h"
31
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010032#include <stdlib.h>
33#include <string.h>
34#if defined(MBEDTLS_PLATFORM_C)
35#include "mbedtls/platform.h"
36#else
37#define mbedtls_calloc calloc
38#define mbedtls_free free
39#endif
40
Gilles Peskinea5905292018-02-07 20:59:33 +010041#include "mbedtls/arc4.h"
42#include "mbedtls/blowfish.h"
43#include "mbedtls/camellia.h"
44#include "mbedtls/cipher.h"
45#include "mbedtls/ccm.h"
46#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010047#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010048#include "mbedtls/des.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010049#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010050#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010051#include "mbedtls/error.h"
52#include "mbedtls/gcm.h"
53#include "mbedtls/md2.h"
54#include "mbedtls/md4.h"
55#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010056#include "mbedtls/md.h"
57#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010058#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010059#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010060#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010061#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010062#include "mbedtls/sha1.h"
63#include "mbedtls/sha256.h"
64#include "mbedtls/sha512.h"
65#include "mbedtls/xtea.h"
66
Gilles Peskinee59236f2018-01-27 23:32:46 +010067
68
69/* Implementation that should never be optimized out by the compiler */
70static void mbedtls_zeroize( void *v, size_t n )
71{
72 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
73}
74
Gilles Peskine9ef733f2018-02-07 21:05:37 +010075/* constant-time buffer comparison */
76static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
77{
78 size_t i;
79 unsigned char diff = 0;
80
81 for( i = 0; i < n; i++ )
82 diff |= a[i] ^ b[i];
83
84 return( diff );
85}
86
87
88
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010089/****************************************************************/
90/* Global data, support functions and library management */
91/****************************************************************/
92
93/* Number of key slots (plus one because 0 is not used).
94 * The value is a compile-time constant for now, for simplicity. */
95#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
96
Gilles Peskine2d277862018-06-18 15:41:12 +020097typedef struct
98{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010099 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300100 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200101 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200102 union
103 {
104 struct raw_data
105 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100106 uint8_t *data;
107 size_t bytes;
108 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100109#if defined(MBEDTLS_RSA_C)
110 mbedtls_rsa_context *rsa;
111#endif /* MBEDTLS_RSA_C */
112#if defined(MBEDTLS_ECP_C)
113 mbedtls_ecp_keypair *ecp;
114#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100115 } data;
116} key_slot_t;
117
Gilles Peskine2d277862018-06-18 15:41:12 +0200118typedef struct
119{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100120 int initialized;
121 mbedtls_entropy_context entropy;
122 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100123 key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100124} psa_global_data_t;
125
126static psa_global_data_t global_data;
127
128static psa_status_t mbedtls_to_psa_error( int ret )
129{
Gilles Peskinea5905292018-02-07 20:59:33 +0100130 /* If there's both a high-level code and low-level code, dispatch on
131 * the high-level code. */
132 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100133 {
134 case 0:
135 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100136
137 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
138 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
139 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
140 return( PSA_ERROR_NOT_SUPPORTED );
141 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
142 return( PSA_ERROR_HARDWARE_FAILURE );
143
144 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
145 return( PSA_ERROR_HARDWARE_FAILURE );
146
147 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
148 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
149 return( PSA_ERROR_NOT_SUPPORTED );
150 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
151 return( PSA_ERROR_HARDWARE_FAILURE );
152
153 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
154 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
155 return( PSA_ERROR_NOT_SUPPORTED );
156 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
157 return( PSA_ERROR_HARDWARE_FAILURE );
158
159 case MBEDTLS_ERR_CCM_BAD_INPUT:
160 return( PSA_ERROR_INVALID_ARGUMENT );
161 case MBEDTLS_ERR_CCM_AUTH_FAILED:
162 return( PSA_ERROR_INVALID_SIGNATURE );
163 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
164 return( PSA_ERROR_HARDWARE_FAILURE );
165
166 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
167 return( PSA_ERROR_NOT_SUPPORTED );
168 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
169 return( PSA_ERROR_INVALID_ARGUMENT );
170 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
171 return( PSA_ERROR_INSUFFICIENT_MEMORY );
172 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
173 return( PSA_ERROR_INVALID_PADDING );
174 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
175 return( PSA_ERROR_BAD_STATE );
176 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
177 return( PSA_ERROR_INVALID_SIGNATURE );
178 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
179 return( PSA_ERROR_TAMPERING_DETECTED );
180 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
181 return( PSA_ERROR_HARDWARE_FAILURE );
182
183 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
186 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
187 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
188 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
189 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
190 return( PSA_ERROR_NOT_SUPPORTED );
191 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
192 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
193
194 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
195 return( PSA_ERROR_NOT_SUPPORTED );
196 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
197 return( PSA_ERROR_HARDWARE_FAILURE );
198
Gilles Peskinee59236f2018-01-27 23:32:46 +0100199 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
200 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
201 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
202 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100203
204 case MBEDTLS_ERR_GCM_AUTH_FAILED:
205 return( PSA_ERROR_INVALID_SIGNATURE );
206 case MBEDTLS_ERR_GCM_BAD_INPUT:
207 return( PSA_ERROR_NOT_SUPPORTED );
208 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
209 return( PSA_ERROR_HARDWARE_FAILURE );
210
211 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
212 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
213 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
214 return( PSA_ERROR_HARDWARE_FAILURE );
215
216 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
217 return( PSA_ERROR_NOT_SUPPORTED );
218 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
219 return( PSA_ERROR_INVALID_ARGUMENT );
220 case MBEDTLS_ERR_MD_ALLOC_FAILED:
221 return( PSA_ERROR_INSUFFICIENT_MEMORY );
222 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
223 return( PSA_ERROR_STORAGE_FAILURE );
224 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
225 return( PSA_ERROR_HARDWARE_FAILURE );
226
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100227 case MBEDTLS_ERR_PK_ALLOC_FAILED:
228 return( PSA_ERROR_INSUFFICIENT_MEMORY );
229 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
230 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
231 return( PSA_ERROR_INVALID_ARGUMENT );
232 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100233 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100234 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
235 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
236 return( PSA_ERROR_INVALID_ARGUMENT );
237 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
238 return( PSA_ERROR_NOT_SUPPORTED );
239 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
240 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
241 return( PSA_ERROR_NOT_PERMITTED );
242 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
243 return( PSA_ERROR_INVALID_ARGUMENT );
244 case MBEDTLS_ERR_PK_INVALID_ALG:
245 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
246 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
247 return( PSA_ERROR_NOT_SUPPORTED );
248 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
249 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100250 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
251 return( PSA_ERROR_HARDWARE_FAILURE );
252
253 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
254 return( PSA_ERROR_HARDWARE_FAILURE );
255
256 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
257 return( PSA_ERROR_INVALID_ARGUMENT );
258 case MBEDTLS_ERR_RSA_INVALID_PADDING:
259 return( PSA_ERROR_INVALID_PADDING );
260 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
261 return( PSA_ERROR_HARDWARE_FAILURE );
262 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
263 return( PSA_ERROR_INVALID_ARGUMENT );
264 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
265 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
266 return( PSA_ERROR_TAMPERING_DETECTED );
267 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
268 return( PSA_ERROR_INVALID_SIGNATURE );
269 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
270 return( PSA_ERROR_BUFFER_TOO_SMALL );
271 case MBEDTLS_ERR_RSA_RNG_FAILED:
272 return( PSA_ERROR_INSUFFICIENT_MEMORY );
273 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
274 return( PSA_ERROR_NOT_SUPPORTED );
275 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
276 return( PSA_ERROR_HARDWARE_FAILURE );
277
278 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
279 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
280 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
281 return( PSA_ERROR_HARDWARE_FAILURE );
282
283 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
284 return( PSA_ERROR_INVALID_ARGUMENT );
285 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
286 return( PSA_ERROR_HARDWARE_FAILURE );
287
itayzafrir5c753392018-05-08 11:18:38 +0300288 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300289 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300290 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300291 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
292 return( PSA_ERROR_BUFFER_TOO_SMALL );
293 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
294 return( PSA_ERROR_NOT_SUPPORTED );
295 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
296 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
297 return( PSA_ERROR_INVALID_SIGNATURE );
298 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
299 return( PSA_ERROR_INSUFFICIENT_MEMORY );
300 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
301 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300302
Gilles Peskinee59236f2018-01-27 23:32:46 +0100303 default:
304 return( PSA_ERROR_UNKNOWN_ERROR );
305 }
306}
307
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200308
309
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100310/****************************************************************/
311/* Key management */
312/****************************************************************/
313
Gilles Peskine2d277862018-06-18 15:41:12 +0200314psa_status_t psa_import_key( psa_key_slot_t key,
315 psa_key_type_t type,
316 const uint8_t *data,
317 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100318{
319 key_slot_t *slot;
320
321 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
322 return( PSA_ERROR_INVALID_ARGUMENT );
323 slot = &global_data.key_slots[key];
324 if( slot->type != PSA_KEY_TYPE_NONE )
325 return( PSA_ERROR_OCCUPIED_SLOT );
326
Gilles Peskine8c9def32018-02-08 10:02:12 +0100327 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100328 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100329 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100330 if( data_length > SIZE_MAX / 8 )
331 return( PSA_ERROR_NOT_SUPPORTED );
332 slot->data.raw.data = mbedtls_calloc( 1, data_length );
333 if( slot->data.raw.data == NULL )
334 return( PSA_ERROR_INSUFFICIENT_MEMORY );
335 memcpy( slot->data.raw.data, data, data_length );
336 slot->data.raw.bytes = data_length;
337 }
338 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100339#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100340 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
341 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
342 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100343 {
344 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100345 mbedtls_pk_context pk;
346 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100347 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
348 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
349 else
350 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100351 if( ret != 0 )
352 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100353 switch( mbedtls_pk_get_type( &pk ) )
354 {
355#if defined(MBEDTLS_RSA_C)
356 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100357 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
358 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine969ac722018-01-28 18:16:59 +0100359 slot->data.rsa = pk.pk_ctx;
360 else
361 return( PSA_ERROR_INVALID_ARGUMENT );
362 break;
363#endif /* MBEDTLS_RSA_C */
364#if defined(MBEDTLS_ECP_C)
365 case MBEDTLS_PK_ECKEY:
366 if( PSA_KEY_TYPE_IS_ECC( type ) )
367 {
368 // TODO: check curve
369 slot->data.ecp = pk.pk_ctx;
370 }
371 else
372 return( PSA_ERROR_INVALID_ARGUMENT );
373 break;
374#endif /* MBEDTLS_ECP_C */
375 default:
376 return( PSA_ERROR_INVALID_ARGUMENT );
377 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100378 }
379 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100380#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100381 {
382 return( PSA_ERROR_NOT_SUPPORTED );
383 }
384
385 slot->type = type;
386 return( PSA_SUCCESS );
387}
388
Gilles Peskine2d277862018-06-18 15:41:12 +0200389psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100390{
391 key_slot_t *slot;
392
393 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
394 return( PSA_ERROR_INVALID_ARGUMENT );
395 slot = &global_data.key_slots[key];
396 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200397 {
398 /* No key material to clean, but do zeroize the slot below to wipe
399 * metadata such as policies. */
400 }
401 else if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100402 {
403 mbedtls_free( slot->data.raw.data );
404 }
405 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100406#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100407 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
408 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100409 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100410 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100411 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100412 }
413 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100414#endif /* defined(MBEDTLS_RSA_C) */
415#if defined(MBEDTLS_ECP_C)
416 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
417 {
418 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100419 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100420 }
421 else
422#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100423 {
424 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100425 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100426 return( PSA_ERROR_TAMPERING_DETECTED );
427 }
428
429 mbedtls_zeroize( slot, sizeof( *slot ) );
430 return( PSA_SUCCESS );
431}
432
Gilles Peskine2d277862018-06-18 15:41:12 +0200433psa_status_t psa_get_key_information( psa_key_slot_t key,
434 psa_key_type_t *type,
435 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100436{
437 key_slot_t *slot;
438
439 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100440 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100441 slot = &global_data.key_slots[key];
442 if( type != NULL )
443 *type = slot->type;
444 if( bits != NULL )
445 *bits = 0;
446 if( slot->type == PSA_KEY_TYPE_NONE )
447 return( PSA_ERROR_EMPTY_SLOT );
448
Gilles Peskine8c9def32018-02-08 10:02:12 +0100449 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100450 {
451 if( bits != NULL )
452 *bits = slot->data.raw.bytes * 8;
453 }
454 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100455#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100456 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
457 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100458 {
459 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100460 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100461 }
462 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100463#endif /* defined(MBEDTLS_RSA_C) */
464#if defined(MBEDTLS_ECP_C)
465 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
466 {
467 if( bits != NULL )
468 *bits = slot->data.ecp->grp.pbits;
469 }
470 else
471#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100472 {
473 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100474 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100475 return( PSA_ERROR_TAMPERING_DETECTED );
476 }
477
478 return( PSA_SUCCESS );
479}
480
Gilles Peskine2d277862018-06-18 15:41:12 +0200481static psa_status_t psa_internal_export_key( psa_key_slot_t key,
482 uint8_t *data,
483 size_t data_size,
484 size_t *data_length,
485 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100486{
487 key_slot_t *slot;
488
489 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100490 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100491 slot = &global_data.key_slots[key];
492 if( slot->type == PSA_KEY_TYPE_NONE )
493 return( PSA_ERROR_EMPTY_SLOT );
494
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200495 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300496 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300497
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200498 if( ! export_public_key &&
499 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
500 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300501 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200502
Gilles Peskine8c9def32018-02-08 10:02:12 +0100503 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100504 {
505 if( slot->data.raw.bytes > data_size )
506 return( PSA_ERROR_BUFFER_TOO_SMALL );
507 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
508 *data_length = slot->data.raw.bytes;
509 return( PSA_SUCCESS );
510 }
511 else
Moran Peker17e36e12018-05-02 12:55:20 +0300512 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100513#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100514 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300515 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
516 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100517 {
Moran Pekera998bc62018-04-16 18:16:20 +0300518 mbedtls_pk_context pk;
519 int ret;
520 mbedtls_pk_init( &pk );
521 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
522 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
523 {
524 pk.pk_info = &mbedtls_rsa_info;
525 pk.pk_ctx = slot->data.rsa;
526 }
527 else
528 {
529 pk.pk_info = &mbedtls_eckey_info;
530 pk.pk_ctx = slot->data.ecp;
531 }
Moran Pekerd7326592018-05-29 16:56:39 +0300532 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300533 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300534 else
535 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300536 if( ret < 0 )
Moran Pekera998bc62018-04-16 18:16:20 +0300537 return( mbedtls_to_psa_error( ret ) );
538 *data_length = ret;
539 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100540 }
541 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100542#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300543 {
544 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200545 it is valid for a special-purpose implementation to omit
546 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300547 return( PSA_ERROR_NOT_SUPPORTED );
548 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100549 }
550}
551
Gilles Peskine2d277862018-06-18 15:41:12 +0200552psa_status_t psa_export_key( psa_key_slot_t key,
553 uint8_t *data,
554 size_t data_size,
555 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300556{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200557 return( psa_internal_export_key( key, data, data_size,
558 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100559}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100560
Gilles Peskine2d277862018-06-18 15:41:12 +0200561psa_status_t psa_export_public_key( psa_key_slot_t key,
562 uint8_t *data,
563 size_t data_size,
564 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300565{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200566 return( psa_internal_export_key( key, data, data_size,
567 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300568}
569
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200570
571
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100572/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100573/* Message digests */
574/****************************************************************/
575
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100576static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100577{
578 switch( alg )
579 {
580#if defined(MBEDTLS_MD2_C)
581 case PSA_ALG_MD2:
582 return( &mbedtls_md2_info );
583#endif
584#if defined(MBEDTLS_MD4_C)
585 case PSA_ALG_MD4:
586 return( &mbedtls_md4_info );
587#endif
588#if defined(MBEDTLS_MD5_C)
589 case PSA_ALG_MD5:
590 return( &mbedtls_md5_info );
591#endif
592#if defined(MBEDTLS_RIPEMD160_C)
593 case PSA_ALG_RIPEMD160:
594 return( &mbedtls_ripemd160_info );
595#endif
596#if defined(MBEDTLS_SHA1_C)
597 case PSA_ALG_SHA_1:
598 return( &mbedtls_sha1_info );
599#endif
600#if defined(MBEDTLS_SHA256_C)
601 case PSA_ALG_SHA_224:
602 return( &mbedtls_sha224_info );
603 case PSA_ALG_SHA_256:
604 return( &mbedtls_sha256_info );
605#endif
606#if defined(MBEDTLS_SHA512_C)
607 case PSA_ALG_SHA_384:
608 return( &mbedtls_sha384_info );
609 case PSA_ALG_SHA_512:
610 return( &mbedtls_sha512_info );
611#endif
612 default:
613 return( NULL );
614 }
615}
616
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100617psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
618{
619 switch( operation->alg )
620 {
621#if defined(MBEDTLS_MD2_C)
622 case PSA_ALG_MD2:
623 mbedtls_md2_free( &operation->ctx.md2 );
624 break;
625#endif
626#if defined(MBEDTLS_MD4_C)
627 case PSA_ALG_MD4:
628 mbedtls_md4_free( &operation->ctx.md4 );
629 break;
630#endif
631#if defined(MBEDTLS_MD5_C)
632 case PSA_ALG_MD5:
633 mbedtls_md5_free( &operation->ctx.md5 );
634 break;
635#endif
636#if defined(MBEDTLS_RIPEMD160_C)
637 case PSA_ALG_RIPEMD160:
638 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
639 break;
640#endif
641#if defined(MBEDTLS_SHA1_C)
642 case PSA_ALG_SHA_1:
643 mbedtls_sha1_free( &operation->ctx.sha1 );
644 break;
645#endif
646#if defined(MBEDTLS_SHA256_C)
647 case PSA_ALG_SHA_224:
648 case PSA_ALG_SHA_256:
649 mbedtls_sha256_free( &operation->ctx.sha256 );
650 break;
651#endif
652#if defined(MBEDTLS_SHA512_C)
653 case PSA_ALG_SHA_384:
654 case PSA_ALG_SHA_512:
655 mbedtls_sha512_free( &operation->ctx.sha512 );
656 break;
657#endif
658 default:
659 return( PSA_ERROR_NOT_SUPPORTED );
660 }
661 operation->alg = 0;
662 return( PSA_SUCCESS );
663}
664
665psa_status_t psa_hash_start( psa_hash_operation_t *operation,
666 psa_algorithm_t alg )
667{
668 int ret;
669 operation->alg = 0;
670 switch( alg )
671 {
672#if defined(MBEDTLS_MD2_C)
673 case PSA_ALG_MD2:
674 mbedtls_md2_init( &operation->ctx.md2 );
675 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
676 break;
677#endif
678#if defined(MBEDTLS_MD4_C)
679 case PSA_ALG_MD4:
680 mbedtls_md4_init( &operation->ctx.md4 );
681 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
682 break;
683#endif
684#if defined(MBEDTLS_MD5_C)
685 case PSA_ALG_MD5:
686 mbedtls_md5_init( &operation->ctx.md5 );
687 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
688 break;
689#endif
690#if defined(MBEDTLS_RIPEMD160_C)
691 case PSA_ALG_RIPEMD160:
692 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
693 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
694 break;
695#endif
696#if defined(MBEDTLS_SHA1_C)
697 case PSA_ALG_SHA_1:
698 mbedtls_sha1_init( &operation->ctx.sha1 );
699 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
700 break;
701#endif
702#if defined(MBEDTLS_SHA256_C)
703 case PSA_ALG_SHA_224:
704 mbedtls_sha256_init( &operation->ctx.sha256 );
705 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
706 break;
707 case PSA_ALG_SHA_256:
708 mbedtls_sha256_init( &operation->ctx.sha256 );
709 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
710 break;
711#endif
712#if defined(MBEDTLS_SHA512_C)
713 case PSA_ALG_SHA_384:
714 mbedtls_sha512_init( &operation->ctx.sha512 );
715 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
716 break;
717 case PSA_ALG_SHA_512:
718 mbedtls_sha512_init( &operation->ctx.sha512 );
719 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
720 break;
721#endif
722 default:
723 return( PSA_ERROR_NOT_SUPPORTED );
724 }
725 if( ret == 0 )
726 operation->alg = alg;
727 else
728 psa_hash_abort( operation );
729 return( mbedtls_to_psa_error( ret ) );
730}
731
732psa_status_t psa_hash_update( psa_hash_operation_t *operation,
733 const uint8_t *input,
734 size_t input_length )
735{
736 int ret;
737 switch( operation->alg )
738 {
739#if defined(MBEDTLS_MD2_C)
740 case PSA_ALG_MD2:
741 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
742 input, input_length );
743 break;
744#endif
745#if defined(MBEDTLS_MD4_C)
746 case PSA_ALG_MD4:
747 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
748 input, input_length );
749 break;
750#endif
751#if defined(MBEDTLS_MD5_C)
752 case PSA_ALG_MD5:
753 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
754 input, input_length );
755 break;
756#endif
757#if defined(MBEDTLS_RIPEMD160_C)
758 case PSA_ALG_RIPEMD160:
759 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
760 input, input_length );
761 break;
762#endif
763#if defined(MBEDTLS_SHA1_C)
764 case PSA_ALG_SHA_1:
765 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
766 input, input_length );
767 break;
768#endif
769#if defined(MBEDTLS_SHA256_C)
770 case PSA_ALG_SHA_224:
771 case PSA_ALG_SHA_256:
772 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
773 input, input_length );
774 break;
775#endif
776#if defined(MBEDTLS_SHA512_C)
777 case PSA_ALG_SHA_384:
778 case PSA_ALG_SHA_512:
779 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
780 input, input_length );
781 break;
782#endif
783 default:
784 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
785 break;
786 }
787 if( ret != 0 )
788 psa_hash_abort( operation );
789 return( mbedtls_to_psa_error( ret ) );
790}
791
792psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
793 uint8_t *hash,
794 size_t hash_size,
795 size_t *hash_length )
796{
797 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200798 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100799
800 /* Fill the output buffer with something that isn't a valid hash
801 * (barring an attack on the hash and deliberately-crafted input),
802 * in case the caller doesn't check the return status properly. */
803 *hash_length = actual_hash_length;
804 memset( hash, '!', hash_size );
805
806 if( hash_size < actual_hash_length )
807 return( PSA_ERROR_BUFFER_TOO_SMALL );
808
809 switch( operation->alg )
810 {
811#if defined(MBEDTLS_MD2_C)
812 case PSA_ALG_MD2:
813 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
814 break;
815#endif
816#if defined(MBEDTLS_MD4_C)
817 case PSA_ALG_MD4:
818 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
819 break;
820#endif
821#if defined(MBEDTLS_MD5_C)
822 case PSA_ALG_MD5:
823 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
824 break;
825#endif
826#if defined(MBEDTLS_RIPEMD160_C)
827 case PSA_ALG_RIPEMD160:
828 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
829 break;
830#endif
831#if defined(MBEDTLS_SHA1_C)
832 case PSA_ALG_SHA_1:
833 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
834 break;
835#endif
836#if defined(MBEDTLS_SHA256_C)
837 case PSA_ALG_SHA_224:
838 case PSA_ALG_SHA_256:
839 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
840 break;
841#endif
842#if defined(MBEDTLS_SHA512_C)
843 case PSA_ALG_SHA_384:
844 case PSA_ALG_SHA_512:
845 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
846 break;
847#endif
848 default:
849 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
850 break;
851 }
852
853 if( ret == 0 )
854 {
855 return( psa_hash_abort( operation ) );
856 }
857 else
858 {
859 psa_hash_abort( operation );
860 return( mbedtls_to_psa_error( ret ) );
861 }
862}
863
Gilles Peskine2d277862018-06-18 15:41:12 +0200864psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
865 const uint8_t *hash,
866 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100867{
868 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
869 size_t actual_hash_length;
870 psa_status_t status = psa_hash_finish( operation,
871 actual_hash, sizeof( actual_hash ),
872 &actual_hash_length );
873 if( status != PSA_SUCCESS )
874 return( status );
875 if( actual_hash_length != hash_length )
876 return( PSA_ERROR_INVALID_SIGNATURE );
877 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
878 return( PSA_ERROR_INVALID_SIGNATURE );
879 return( PSA_SUCCESS );
880}
881
882
883
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100884/****************************************************************/
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,
Gilles Peskine2d277862018-06-18 15:41:12 +0200891 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +0300892 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 ) )
mohammad16038481e742018-03-18 13:57:31 +0200900 {
901 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
902 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +0200903
Nir Sonnenscheine9664c32018-06-17 14:41:30 +0300904 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100905 {
906 case PSA_ALG_STREAM_CIPHER:
907 mode = MBEDTLS_MODE_STREAM;
908 break;
909 case PSA_ALG_CBC_BASE:
910 mode = MBEDTLS_MODE_CBC;
911 break;
912 case PSA_ALG_CFB_BASE:
913 mode = MBEDTLS_MODE_CFB;
914 break;
915 case PSA_ALG_OFB_BASE:
916 mode = MBEDTLS_MODE_OFB;
917 break;
918 case PSA_ALG_CTR:
919 mode = MBEDTLS_MODE_CTR;
920 break;
921 case PSA_ALG_CCM:
922 mode = MBEDTLS_MODE_CCM;
923 break;
924 case PSA_ALG_GCM:
925 mode = MBEDTLS_MODE_GCM;
926 break;
927 default:
928 return( NULL );
929 }
930 }
931 else if( alg == PSA_ALG_CMAC )
932 mode = MBEDTLS_MODE_ECB;
933 else if( alg == PSA_ALG_GMAC )
934 mode = MBEDTLS_MODE_GCM;
935 else
936 return( NULL );
937
938 switch( key_type )
939 {
940 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +0300941 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100942 break;
943 case PSA_KEY_TYPE_DES:
944 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +0300945 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100946 else
mohammad1603f4f0d612018-06-03 15:04:51 +0300947 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100948 break;
949 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +0300950 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100951 break;
952 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +0300953 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100954 break;
955 default:
956 return( NULL );
957 }
mohammad1603f4f0d612018-06-03 15:04:51 +0300958 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +0300959 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100960
mohammad1603f4f0d612018-06-03 15:04:51 +0300961 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +0100962}
963
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300964static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +0300965{
Gilles Peskine2d277862018-06-18 15:41:12 +0200966 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +0300967 {
968 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300969 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +0300970 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300971 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +0300972 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300973 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +0300974 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300975 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +0300976 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300977 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +0300978 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300979 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +0300980 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300981 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +0300982 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300983 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +0300984 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +0200985 return( 128 );
986 default:
987 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +0300988 }
989}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +0300990
Gilles Peskine8c9def32018-02-08 10:02:12 +0100991psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
992{
993 switch( operation->alg )
994 {
995#if defined(MBEDTLS_CMAC_C)
996 case PSA_ALG_CMAC:
997 mbedtls_cipher_free( &operation->ctx.cmac );
998 break;
999#endif /* MBEDTLS_CMAC_C */
1000 default:
1001#if defined(MBEDTLS_MD_C)
1002 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001003 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001004 unsigned int block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001005 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001006
Gilles Peskine99bc6492018-06-11 17:13:00 +02001007 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001008 return( PSA_ERROR_NOT_SUPPORTED );
1009
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001010 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001011 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001012 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001013 else
1014#endif /* MBEDTLS_MD_C */
1015 return( PSA_ERROR_NOT_SUPPORTED );
1016 }
Moran Peker41deec42018-04-04 15:43:05 +03001017
Gilles Peskine8c9def32018-02-08 10:02:12 +01001018 operation->alg = 0;
1019 operation->key_set = 0;
1020 operation->iv_set = 0;
1021 operation->iv_required = 0;
1022 operation->has_input = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001023
Gilles Peskine8c9def32018-02-08 10:02:12 +01001024 return( PSA_SUCCESS );
1025}
1026
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001027static int psa_cmac_start( psa_mac_operation_t *operation,
1028 size_t key_bits,
1029 key_slot_t *slot,
1030 const mbedtls_cipher_info_t *cipher_info )
1031{
1032 int ret;
1033
1034 operation->mac_size = cipher_info->block_size;
1035 operation->iv_required = 0;
1036 mbedtls_cipher_init( &operation->ctx.cmac );
1037
1038 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1039 if( ret != 0 )
1040 return( ret );
1041
1042 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1043 slot->data.raw.data,
1044 key_bits );
1045 return( ret );
1046}
1047
1048static int psa_hmac_start( psa_mac_operation_t *operation,
1049 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001050 key_slot_t *slot,
1051 psa_algorithm_t alg )
1052{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001053 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001054 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001055 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001056 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001057 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001058 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001059 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001060 size_t key_length = slot->data.raw.bytes;
1061 psa_status_t status;
1062
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001063 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001064 return( PSA_ERROR_NOT_SUPPORTED );
1065
1066 if( key_type != PSA_KEY_TYPE_HMAC )
1067 return( PSA_ERROR_INVALID_ARGUMENT );
1068
1069 operation->iv_required = 0;
1070 operation->mac_size = digest_size;
1071
1072 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1073 PSA_ALG_HMAC_HASH( alg ) );
1074 if( status != PSA_SUCCESS )
1075 return( status );
1076
Gilles Peskined223b522018-06-11 18:12:58 +02001077 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001078 {
1079 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001080 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001081 if( status != PSA_SUCCESS )
1082 return( status );
1083 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001084 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001085 if( status != PSA_SUCCESS )
1086 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001087 }
Gilles Peskined223b522018-06-11 18:12:58 +02001088 else
1089 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001090
Gilles Peskined223b522018-06-11 18:12:58 +02001091 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1092 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001093 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001094 ipad[i] ^= 0x36;
1095 memset( ipad + key_length, 0x36, block_size - key_length );
1096
1097 /* Copy the key material from ipad to opad, flipping the requisite bits,
1098 * and filling the rest of opad with the requisite constant. */
1099 for( i = 0; i < key_length; i++ )
1100 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1101 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001102
1103 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1104 PSA_ALG_HMAC_HASH( alg ) );
1105 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001106 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001107
1108 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1109 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001110
1111cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001112 mbedtls_zeroize( ipad, key_length );
1113 /* opad is in the context. It needs to stay in memory if this function
1114 * succeeds, and it will be wiped by psa_mac_abort() called from
1115 * psa_mac_start in the error case. */
1116
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001117 return( status );
1118}
1119
Gilles Peskine8c9def32018-02-08 10:02:12 +01001120psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1121 psa_key_slot_t key,
1122 psa_algorithm_t alg )
1123{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001124 psa_status_t status;
1125 key_slot_t *slot;
1126 psa_key_type_t key_type;
1127 size_t key_bits;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001128 const mbedtls_cipher_info_t *cipher_info;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001129
1130 operation->alg = 0;
1131 operation->key_set = 0;
1132 operation->iv_set = 0;
1133 operation->iv_required = 1;
1134 operation->has_input = 0;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001135 operation->key_usage_sign = 0;
1136 operation->key_usage_verify = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001137
1138 status = psa_get_key_information( key, &key_type, &key_bits );
1139 if( status != PSA_SUCCESS )
1140 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001141
Gilles Peskine8c9def32018-02-08 10:02:12 +01001142 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001143 if( slot->type == PSA_KEY_TYPE_NONE )
1144 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001145
Moran Pekerd7326592018-05-29 16:56:39 +03001146 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001147 operation->key_usage_sign = 1;
1148
Moran Pekerd7326592018-05-29 16:56:39 +03001149 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001150 operation->key_usage_verify = 1;
1151
Gilles Peskine8c9def32018-02-08 10:02:12 +01001152 if( ! PSA_ALG_IS_HMAC( alg ) )
1153 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001154 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001155 if( cipher_info == NULL )
1156 return( PSA_ERROR_NOT_SUPPORTED );
1157 operation->mac_size = cipher_info->block_size;
1158 }
1159 switch( alg )
1160 {
1161#if defined(MBEDTLS_CMAC_C)
1162 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001163 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1164 key_bits,
1165 slot,
1166 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001167 break;
1168#endif /* MBEDTLS_CMAC_C */
1169 default:
1170#if defined(MBEDTLS_MD_C)
1171 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001172 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001173 else
1174#endif /* MBEDTLS_MD_C */
1175 return( PSA_ERROR_NOT_SUPPORTED );
1176 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001177
Gilles Peskine8c9def32018-02-08 10:02:12 +01001178 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001179
1180 * context may contain data that needs to be wiped on error. */
1181 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001182 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001183 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001184 }
Gilles Peskine99bc6492018-06-11 17:13:00 +02001185
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001186 else
1187 {
1188 operation->alg = alg;
1189 operation->key_set = 1;
1190 }
1191 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001192}
1193
1194psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1195 const uint8_t *input,
1196 size_t input_length )
1197{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001198 int ret = 0 ;
1199 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001200 if( ! operation->key_set )
1201 return( PSA_ERROR_BAD_STATE );
1202 if( operation->iv_required && ! operation->iv_set )
1203 return( PSA_ERROR_BAD_STATE );
1204 operation->has_input = 1;
1205
1206 switch( operation->alg )
1207 {
1208#if defined(MBEDTLS_CMAC_C)
1209 case PSA_ALG_CMAC:
1210 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1211 input, input_length );
1212 break;
1213#endif /* MBEDTLS_CMAC_C */
1214 default:
1215#if defined(MBEDTLS_MD_C)
1216 if( PSA_ALG_IS_HMAC( operation->alg ) )
1217 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001218 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001219 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001220 }
1221 else
1222#endif /* MBEDTLS_MD_C */
1223 {
1224 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1225 }
1226 break;
1227 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001228 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001229 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001230 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001231 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001232 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001233 }
1234
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001235 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001236}
1237
mohammad16036df908f2018-04-02 08:34:15 -07001238static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001239 uint8_t *mac,
1240 size_t mac_size,
1241 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001242{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001243 int ret = 0;
1244 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001245 if( ! operation->key_set )
1246 return( PSA_ERROR_BAD_STATE );
1247 if( operation->iv_required && ! operation->iv_set )
1248 return( PSA_ERROR_BAD_STATE );
1249
1250 /* Fill the output buffer with something that isn't a valid mac
1251 * (barring an attack on the mac and deliberately-crafted input),
1252 * in case the caller doesn't check the return status properly. */
1253 *mac_length = operation->mac_size;
1254 memset( mac, '!', mac_size );
1255
1256 if( mac_size < operation->mac_size )
1257 return( PSA_ERROR_BUFFER_TOO_SMALL );
1258
1259 switch( operation->alg )
1260 {
1261#if defined(MBEDTLS_CMAC_C)
1262 case PSA_ALG_CMAC:
1263 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1264 break;
1265#endif /* MBEDTLS_CMAC_C */
1266 default:
1267#if defined(MBEDTLS_MD_C)
1268 if( PSA_ALG_IS_HMAC( operation->alg ) )
1269 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001270 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001271 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001272 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001273 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001274 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001275
Gilles Peskine99bc6492018-06-11 17:13:00 +02001276 if( block_size == 0 )
1277 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001278
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001279 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001280 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001281 if( status != PSA_SUCCESS )
1282 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001283 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001284
1285 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1286 PSA_ALG_HMAC_HASH( operation->alg ) );
1287 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001288 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001289
1290 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001291 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001292 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001293 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001294
1295 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001296 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001297 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001298 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001299
1300 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1301 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001302 hmac_cleanup:
1303 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001304 }
1305 else
1306#endif /* MBEDTLS_MD_C */
1307 {
1308 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1309 }
1310 break;
1311 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001312cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001313
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001314 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001315 {
1316 return( psa_mac_abort( operation ) );
1317 }
1318 else
1319 {
1320 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001321 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001322 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001323
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001324 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001325 }
1326}
1327
mohammad16036df908f2018-04-02 08:34:15 -07001328psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1329 uint8_t *mac,
1330 size_t mac_size,
1331 size_t *mac_length )
1332{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001333 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001334 return( PSA_ERROR_NOT_PERMITTED );
1335
Gilles Peskine99bc6492018-06-11 17:13:00 +02001336 return( psa_mac_finish_internal( operation, mac,
1337 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001338}
1339
Gilles Peskine2d277862018-06-18 15:41:12 +02001340#define MBEDTLS_PSA_MAC_MAX_SIZE \
1341 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1342 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001343 MBEDTLS_MAX_BLOCK_LENGTH )
1344psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1345 const uint8_t *mac,
1346 size_t mac_length )
1347{
1348 uint8_t actual_mac[MBEDTLS_PSA_MAC_MAX_SIZE];
1349 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001350 psa_status_t status;
1351
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001352 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001353 return( PSA_ERROR_NOT_PERMITTED );
1354
1355 status = psa_mac_finish_internal( operation,
1356 actual_mac, sizeof( actual_mac ),
1357 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001358 if( status != PSA_SUCCESS )
1359 return( status );
1360 if( actual_mac_length != mac_length )
1361 return( PSA_ERROR_INVALID_SIGNATURE );
1362 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1363 return( PSA_ERROR_INVALID_SIGNATURE );
1364 return( PSA_SUCCESS );
1365}
1366
1367
Gilles Peskine20035e32018-02-03 22:44:14 +01001368
Gilles Peskine20035e32018-02-03 22:44:14 +01001369/****************************************************************/
1370/* Asymmetric cryptography */
1371/****************************************************************/
1372
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001373/* Decode the hash algorithm from alg and store the mbedtls encoding in
1374 * md_alg. Verify that the hash length is consistent. */
1375static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1376 size_t hash_length,
1377 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001378{
Gilles Peskine61b91d42018-06-08 16:09:36 +02001379 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
1380 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1381 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1382 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001383 {
1384#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001385 if( hash_length > UINT_MAX )
1386 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001387#endif
1388 }
1389 else
1390 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001391 if( mbedtls_md_get_size( md_info ) != hash_length )
1392 return( PSA_ERROR_INVALID_ARGUMENT );
1393 if( md_info == NULL )
1394 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001395 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001396 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001397}
1398
Gilles Peskine61b91d42018-06-08 16:09:36 +02001399psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1400 psa_algorithm_t alg,
1401 const uint8_t *hash,
1402 size_t hash_length,
1403 const uint8_t *salt,
1404 size_t salt_length,
1405 uint8_t *signature,
1406 size_t signature_size,
1407 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001408{
1409 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001410 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001411 *signature_length = 0;
1412 (void) salt;
1413 (void) salt_length;
1414
Gilles Peskine20035e32018-02-03 22:44:14 +01001415 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1416 return( PSA_ERROR_EMPTY_SLOT );
1417 slot = &global_data.key_slots[key];
1418 if( slot->type == PSA_KEY_TYPE_NONE )
1419 return( PSA_ERROR_EMPTY_SLOT );
1420 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1421 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001422 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001423 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001424
Gilles Peskine20035e32018-02-03 22:44:14 +01001425#if defined(MBEDTLS_RSA_C)
1426 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1427 {
1428 mbedtls_rsa_context *rsa = slot->data.rsa;
1429 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001430 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001431 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001432 if( status != PSA_SUCCESS )
1433 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001434
Gilles Peskine20035e32018-02-03 22:44:14 +01001435 if( signature_size < rsa->len )
1436 return( PSA_ERROR_BUFFER_TOO_SMALL );
1437#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001438 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001439 {
1440 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1441 MBEDTLS_MD_NONE );
1442 ret = mbedtls_rsa_pkcs1_sign( rsa,
1443 mbedtls_ctr_drbg_random,
1444 &global_data.ctr_drbg,
1445 MBEDTLS_RSA_PRIVATE,
1446 md_alg, hash_length, hash,
1447 signature );
1448 }
1449 else
1450#endif /* MBEDTLS_PKCS1_V15 */
1451#if defined(MBEDTLS_PKCS1_V21)
1452 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1453 {
1454 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1455 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1456 mbedtls_ctr_drbg_random,
1457 &global_data.ctr_drbg,
1458 MBEDTLS_RSA_PRIVATE,
1459 md_alg, hash_length, hash,
1460 signature );
1461 }
1462 else
1463#endif /* MBEDTLS_PKCS1_V21 */
1464 {
1465 return( PSA_ERROR_INVALID_ARGUMENT );
1466 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001467 if( ret == 0 )
1468 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001469 return( mbedtls_to_psa_error( ret ) );
1470 }
1471 else
1472#endif /* defined(MBEDTLS_RSA_C) */
1473#if defined(MBEDTLS_ECP_C)
1474 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1475 {
itayzafrir5c753392018-05-08 11:18:38 +03001476 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1477 int ret;
1478 const mbedtls_md_info_t *md_info;
1479 mbedtls_md_type_t md_alg;
1480 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1481 return( PSA_ERROR_BUFFER_TOO_SMALL );
1482 md_info = mbedtls_md_info_from_psa( alg );
1483 md_alg = mbedtls_md_get_type( md_info );
1484 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001485 signature, signature_length,
1486 mbedtls_ctr_drbg_random,
1487 &global_data.ctr_drbg );
itayzafrir5c753392018-05-08 11:18:38 +03001488 return( mbedtls_to_psa_error( ret ) );
1489 }
1490 else
1491#endif /* defined(MBEDTLS_ECP_C) */
1492 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001493 return( PSA_ERROR_NOT_SUPPORTED );
1494 }
itayzafrir5c753392018-05-08 11:18:38 +03001495}
1496
1497psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1498 psa_algorithm_t alg,
1499 const uint8_t *hash,
1500 size_t hash_length,
1501 const uint8_t *salt,
1502 size_t salt_length,
1503 uint8_t *signature,
1504 size_t signature_size )
1505{
1506 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001507 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001508 (void) salt;
1509 (void) salt_length;
1510
1511 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1512 return( PSA_ERROR_INVALID_ARGUMENT );
1513 slot = &global_data.key_slots[key];
1514 if( slot->type == PSA_KEY_TYPE_NONE )
1515 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001516 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001517 return( PSA_ERROR_NOT_PERMITTED );
1518
Gilles Peskine61b91d42018-06-08 16:09:36 +02001519#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001520 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1521 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001522 {
1523 mbedtls_rsa_context *rsa = slot->data.rsa;
1524 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001525 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001526 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001527 if( status != PSA_SUCCESS )
1528 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001529
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001530 if( signature_size < rsa->len )
1531 return( PSA_ERROR_BUFFER_TOO_SMALL );
1532#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001533 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001534 {
1535 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1536 MBEDTLS_MD_NONE );
1537
1538 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001539 mbedtls_ctr_drbg_random,
1540 &global_data.ctr_drbg,
1541 MBEDTLS_RSA_PUBLIC,
1542 md_alg,
1543 hash_length,
1544 hash,
1545 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001546
1547 }
1548 else
1549#endif /* MBEDTLS_PKCS1_V15 */
1550#if defined(MBEDTLS_PKCS1_V21)
1551 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1552 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001553 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1554 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1555 mbedtls_ctr_drbg_random,
1556 &global_data.ctr_drbg,
1557 MBEDTLS_RSA_PUBLIC,
1558 md_alg, hash_length, hash,
1559 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001560 }
1561 else
1562#endif /* MBEDTLS_PKCS1_V21 */
1563 {
1564 return( PSA_ERROR_INVALID_ARGUMENT );
1565 }
1566 return( mbedtls_to_psa_error( ret ) );
1567 }
1568 else
1569#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001570#if defined(MBEDTLS_ECP_C)
1571 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1572 {
1573 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1574 int ret;
Gilles Peskine2d277862018-06-18 15:41:12 +02001575 (void) alg;
Gilles Peskine61b91d42018-06-08 16:09:36 +02001576 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length,
1577 signature, signature_size );
itayzafrir5c753392018-05-08 11:18:38 +03001578 return( mbedtls_to_psa_error( ret ) );
1579 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001580 else
1581#endif /* defined(MBEDTLS_ECP_C) */
1582 {
1583 return( PSA_ERROR_NOT_SUPPORTED );
1584 }
1585}
1586
Gilles Peskine61b91d42018-06-08 16:09:36 +02001587psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1588 psa_algorithm_t alg,
1589 const uint8_t *input,
1590 size_t input_length,
1591 const uint8_t *salt,
1592 size_t salt_length,
1593 uint8_t *output,
1594 size_t output_size,
1595 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001596{
1597 key_slot_t *slot;
1598 (void) salt;
1599 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001600 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001601
1602 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001603 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001604 slot = &global_data.key_slots[key];
1605 if( slot->type == PSA_KEY_TYPE_NONE )
1606 return( PSA_ERROR_EMPTY_SLOT );
1607 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1608 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001609 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1610 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001611
1612#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001613 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1614 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001615 {
1616 mbedtls_rsa_context *rsa = slot->data.rsa;
1617 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001618 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001619 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001620#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001621 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001622 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001623 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1624 mbedtls_ctr_drbg_random,
1625 &global_data.ctr_drbg,
1626 MBEDTLS_RSA_PUBLIC,
1627 input_length,
1628 input,
1629 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001630 }
1631 else
1632#endif /* MBEDTLS_PKCS1_V15 */
1633#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001634 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001635 {
1636 return( PSA_ERROR_NOT_SUPPORTED );
1637 }
1638 else
1639#endif /* MBEDTLS_PKCS1_V21 */
1640 {
1641 return( PSA_ERROR_INVALID_ARGUMENT );
1642 }
1643 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001644 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001645 return( mbedtls_to_psa_error( ret ) );
1646 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001647 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001648#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001649 {
1650 return( PSA_ERROR_NOT_SUPPORTED );
1651 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001652}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001653
Gilles Peskine61b91d42018-06-08 16:09:36 +02001654psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1655 psa_algorithm_t alg,
1656 const uint8_t *input,
1657 size_t input_length,
1658 const uint8_t *salt,
1659 size_t salt_length,
1660 uint8_t *output,
1661 size_t output_size,
1662 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001663{
1664 key_slot_t *slot;
1665 (void) salt;
1666 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001667 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001668
1669 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1670 return( PSA_ERROR_EMPTY_SLOT );
1671 slot = &global_data.key_slots[key];
1672 if( slot->type == PSA_KEY_TYPE_NONE )
1673 return( PSA_ERROR_EMPTY_SLOT );
1674 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1675 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001676 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1677 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001678
1679#if defined(MBEDTLS_RSA_C)
1680 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1681 {
1682 mbedtls_rsa_context *rsa = slot->data.rsa;
1683 int ret;
1684
Gilles Peskinec4def2f2018-06-08 17:53:48 +02001685 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001686 return( PSA_ERROR_INVALID_ARGUMENT );
1687
1688#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001689 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001690 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001691 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
1692 mbedtls_ctr_drbg_random,
1693 &global_data.ctr_drbg,
1694 MBEDTLS_RSA_PRIVATE,
1695 output_length,
1696 input,
1697 output,
1698 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001699 }
1700 else
1701#endif /* MBEDTLS_PKCS1_V15 */
1702#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001703 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001704 {
1705 return( PSA_ERROR_NOT_SUPPORTED );
1706 }
1707 else
1708#endif /* MBEDTLS_PKCS1_V21 */
1709 {
1710 return( PSA_ERROR_INVALID_ARGUMENT );
1711 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001712
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001713 return( mbedtls_to_psa_error( ret ) );
1714 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001715 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001716#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001717 {
1718 return( PSA_ERROR_NOT_SUPPORTED );
1719 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001720}
Gilles Peskine20035e32018-02-03 22:44:14 +01001721
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001722
1723
mohammad1603503973b2018-03-12 15:59:30 +02001724/****************************************************************/
1725/* Symmetric cryptography */
1726/****************************************************************/
1727
Gilles Peskinee553c652018-06-04 16:22:46 +02001728static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1729 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001730 psa_algorithm_t alg,
1731 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001732{
1733 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1734 psa_status_t status;
1735 key_slot_t *slot;
1736 psa_key_type_t key_type;
1737 size_t key_bits;
1738 const mbedtls_cipher_info_t *cipher_info = NULL;
1739
Moran Peker41deec42018-04-04 15:43:05 +03001740 operation->alg = alg;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001741 operation->key_set = 0;
1742 operation->iv_set = 0;
1743 operation->iv_required = 1;
1744 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001745 operation->block_size = 0;
mohammad1603503973b2018-03-12 15:59:30 +02001746
1747 status = psa_get_key_information( key, &key_type, &key_bits );
1748 if( status != PSA_SUCCESS )
1749 return( status );
1750 slot = &global_data.key_slots[key];
1751
Gilles Peskinebb1072f2018-06-08 18:46:05 +02001752 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02001753 if( cipher_info == NULL )
1754 return( PSA_ERROR_NOT_SUPPORTED );
1755
mohammad1603503973b2018-03-12 15:59:30 +02001756 mbedtls_cipher_init( &operation->ctx.cipher );
1757 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03001758 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001759 {
1760 psa_cipher_abort( operation );
1761 return( mbedtls_to_psa_error( ret ) );
1762 }
1763
1764 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
Gilles Peskinee553c652018-06-04 16:22:46 +02001765 key_bits, cipher_operation );
Moran Peker41deec42018-04-04 15:43:05 +03001766 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001767 {
1768 psa_cipher_abort( operation );
1769 return( mbedtls_to_psa_error( ret ) );
1770 }
1771
mohammad16038481e742018-03-18 13:57:31 +02001772#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03001773 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02001774 {
Gilles Peskine53514202018-06-06 15:11:46 +02001775 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1776 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02001777
Moran Pekera28258c2018-05-29 16:25:04 +03001778 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02001779 {
1780 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
1781 mode = MBEDTLS_PADDING_PKCS7;
1782 break;
1783 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
1784 mode = MBEDTLS_PADDING_NONE;
1785 break;
1786 default:
Moran Pekerae382792018-05-31 14:06:17 +03001787 psa_cipher_abort( operation );
1788 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02001789 }
1790 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03001791 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03001792 {
1793 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02001794 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03001795 }
mohammad16038481e742018-03-18 13:57:31 +02001796 }
1797#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
1798
mohammad1603503973b2018-03-12 15:59:30 +02001799 operation->key_set = 1;
1800 operation->alg = alg;
Gilles Peskine7e928852018-06-04 16:23:10 +02001801 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
1802 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
1803 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001804 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02001805 {
mohammad160389e0f462018-04-12 08:48:45 +03001806 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02001807 }
mohammad1603503973b2018-03-12 15:59:30 +02001808
Moran Peker395db872018-05-31 14:07:14 +03001809 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001810}
1811
Gilles Peskinee553c652018-06-04 16:22:46 +02001812psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
1813 psa_key_slot_t key,
1814 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001815{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001816 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001817}
1818
Gilles Peskinee553c652018-06-04 16:22:46 +02001819psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
1820 psa_key_slot_t key,
1821 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001822{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001823 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001824}
1825
Gilles Peskinee553c652018-06-04 16:22:46 +02001826psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
1827 unsigned char *iv,
1828 size_t iv_size,
1829 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001830{
Moran Peker41deec42018-04-04 15:43:05 +03001831 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001832 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001833 return( PSA_ERROR_BAD_STATE );
1834 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02001835 {
Moran Peker41deec42018-04-04 15:43:05 +03001836 ret = PSA_ERROR_BUFFER_TOO_SMALL;
1837 goto exit;
1838 }
Gilles Peskine7e928852018-06-04 16:23:10 +02001839 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
1840 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03001841 if( ret != 0 )
1842 {
1843 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02001844 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02001845 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001846
mohammad16038481e742018-03-18 13:57:31 +02001847 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03001848 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001849
Moran Peker395db872018-05-31 14:07:14 +03001850exit:
1851 if( ret != PSA_SUCCESS )
1852 psa_cipher_abort( operation );
1853 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02001854}
1855
Gilles Peskinee553c652018-06-04 16:22:46 +02001856psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
1857 const unsigned char *iv,
1858 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001859{
Moran Peker41deec42018-04-04 15:43:05 +03001860 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001861 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001862 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03001863 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03001864 {
Moran Pekerae382792018-05-31 14:06:17 +03001865 psa_cipher_abort( operation );
1866 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03001867 }
mohammad1603503973b2018-03-12 15:59:30 +02001868 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001869 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001870 {
1871 psa_cipher_abort( operation );
1872 return( mbedtls_to_psa_error( ret ) );
1873 }
1874
1875 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02001876
Moran Peker395db872018-05-31 14:07:14 +03001877 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001878}
1879
Gilles Peskinee553c652018-06-04 16:22:46 +02001880psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
1881 const uint8_t *input,
1882 size_t input_length,
1883 unsigned char *output,
1884 size_t output_size,
1885 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001886{
1887 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02001888 size_t expected_output_size;
1889 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
1890 {
1891 /* Take the unprocessed partial block left over from previous
1892 * update calls, if any, plus the input to this call. Remove
1893 * the last partial block, if any. You get the data that will be
1894 * output in this call. */
1895 expected_output_size =
1896 ( operation->ctx.cipher.unprocessed_len + input_length )
1897 / operation->block_size * operation->block_size;
1898 }
1899 else
1900 {
1901 expected_output_size = input_length;
1902 }
1903 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03001904 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02001905
mohammad1603503973b2018-03-12 15:59:30 +02001906 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02001907 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03001908 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001909 {
1910 psa_cipher_abort( operation );
1911 return( mbedtls_to_psa_error( ret ) );
1912 }
1913
Moran Peker395db872018-05-31 14:07:14 +03001914 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001915}
1916
Gilles Peskinee553c652018-06-04 16:22:46 +02001917psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
1918 uint8_t *output,
1919 size_t output_size,
1920 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001921{
1922 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02001923 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03001924
mohammad1603503973b2018-03-12 15:59:30 +02001925 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001926 {
Moran Peker7cb22b82018-06-05 11:40:02 +03001927 psa_cipher_abort( operation );
1928 return( PSA_ERROR_BAD_STATE );
1929 }
1930 if( operation->iv_required && ! operation->iv_set )
1931 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001932 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001933 return( PSA_ERROR_BAD_STATE );
1934 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001935 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
1936 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03001937 {
Gilles Peskine53514202018-06-06 15:11:46 +02001938 psa_algorithm_t padding_mode =
1939 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03001940 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02001941 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001942 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001943 return( PSA_ERROR_TAMPERING_DETECTED );
1944 }
Gilles Peskine53514202018-06-06 15:11:46 +02001945 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03001946 {
1947 if( operation->ctx.cipher.unprocessed_len != 0 )
1948 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001949 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001950 return( PSA_ERROR_INVALID_ARGUMENT );
1951 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02001952 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001953 }
1954
1955 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02001956 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03001957 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001958 {
1959 psa_cipher_abort( operation );
1960 return( mbedtls_to_psa_error( ret ) );
1961 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001962 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001963 memcpy( output, temp_output_buffer, *output_length );
1964 else
1965 {
1966 psa_cipher_abort( operation );
1967 return( PSA_ERROR_BUFFER_TOO_SMALL );
1968 }
mohammad1603503973b2018-03-12 15:59:30 +02001969
Moran Peker4c80d832018-04-22 20:15:31 +03001970 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001971}
1972
Gilles Peskinee553c652018-06-04 16:22:46 +02001973psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
1974{
mohammad1603503973b2018-03-12 15:59:30 +02001975 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02001976
Moran Peker41deec42018-04-04 15:43:05 +03001977 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001978 operation->key_set = 0;
1979 operation->iv_set = 0;
1980 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001981 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001982 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001983
Moran Peker395db872018-05-31 14:07:14 +03001984 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001985}
1986
Gilles Peskinea0655c32018-04-30 17:06:50 +02001987
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001988
mohammad16038cc1cee2018-03-28 01:21:33 +03001989/****************************************************************/
1990/* Key Policy */
1991/****************************************************************/
1992
Gilles Peskine2d277862018-06-18 15:41:12 +02001993void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03001994{
Gilles Peskine803ce742018-06-18 16:07:14 +02001995 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03001996}
1997
Gilles Peskine2d277862018-06-18 15:41:12 +02001998void psa_key_policy_set_usage( psa_key_policy_t *policy,
1999 psa_key_usage_t usage,
2000 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002001{
mohammad16034eed7572018-03-28 05:14:59 -07002002 policy->usage = usage;
2003 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002004}
2005
Gilles Peskine2d277862018-06-18 15:41:12 +02002006psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002007{
mohammad16036df908f2018-04-02 08:34:15 -07002008 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002009}
2010
Gilles Peskine2d277862018-06-18 15:41:12 +02002011psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002012{
mohammad16036df908f2018-04-02 08:34:15 -07002013 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002014}
2015
Gilles Peskine2d277862018-06-18 15:41:12 +02002016psa_status_t psa_set_key_policy( psa_key_slot_t key,
2017 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002018{
2019 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002020
2021 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
2022 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002023
mohammad16038cc1cee2018-03-28 01:21:33 +03002024 slot = &global_data.key_slots[key];
2025 if( slot->type != PSA_KEY_TYPE_NONE )
2026 return( PSA_ERROR_OCCUPIED_SLOT );
2027
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002028 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2029 PSA_KEY_USAGE_ENCRYPT |
2030 PSA_KEY_USAGE_DECRYPT |
2031 PSA_KEY_USAGE_SIGN |
2032 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002033 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002034
mohammad16036df908f2018-04-02 08:34:15 -07002035 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002036
2037 return( PSA_SUCCESS );
2038}
2039
Gilles Peskine2d277862018-06-18 15:41:12 +02002040psa_status_t psa_get_key_policy( psa_key_slot_t key,
2041 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002042{
2043 key_slot_t *slot;
2044
2045 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
2046 return( PSA_ERROR_INVALID_ARGUMENT );
2047
2048 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002049
mohammad16036df908f2018-04-02 08:34:15 -07002050 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002051
2052 return( PSA_SUCCESS );
2053}
Gilles Peskine20035e32018-02-03 22:44:14 +01002054
Gilles Peskinea0655c32018-04-30 17:06:50 +02002055
2056
mohammad1603804cd712018-03-20 22:44:08 +02002057/****************************************************************/
2058/* Key Lifetime */
2059/****************************************************************/
2060
Gilles Peskine2d277862018-06-18 15:41:12 +02002061psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2062 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002063{
2064 key_slot_t *slot;
2065
2066 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
2067 return( PSA_ERROR_INVALID_ARGUMENT );
2068
2069 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002070
mohammad1603804cd712018-03-20 22:44:08 +02002071 *lifetime = slot->lifetime;
2072
2073 return( PSA_SUCCESS );
2074}
2075
Gilles Peskine2d277862018-06-18 15:41:12 +02002076psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2077 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002078{
2079 key_slot_t *slot;
2080
2081 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
2082 return( PSA_ERROR_INVALID_ARGUMENT );
2083
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002084 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2085 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002086 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2087 return( PSA_ERROR_INVALID_ARGUMENT );
2088
mohammad1603804cd712018-03-20 22:44:08 +02002089 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002090 if( slot->type != PSA_KEY_TYPE_NONE )
2091 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002092
Moran Pekerd7326592018-05-29 16:56:39 +03002093 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002094 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002095
mohammad1603060ad8a2018-03-20 14:28:38 -07002096 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002097
2098 return( PSA_SUCCESS );
2099}
2100
Gilles Peskine20035e32018-02-03 22:44:14 +01002101
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002102
mohammad16035955c982018-04-26 00:53:03 +03002103/****************************************************************/
2104/* AEAD */
2105/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002106
mohammad16035955c982018-04-26 00:53:03 +03002107psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2108 psa_algorithm_t alg,
2109 const uint8_t *nonce,
2110 size_t nonce_length,
2111 const uint8_t *additional_data,
2112 size_t additional_data_length,
2113 const uint8_t *plaintext,
2114 size_t plaintext_length,
2115 uint8_t *ciphertext,
2116 size_t ciphertext_size,
2117 size_t *ciphertext_length )
2118{
2119 int ret;
2120 psa_status_t status;
2121 key_slot_t *slot;
2122 psa_key_type_t key_type;
2123 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002124 uint8_t *tag;
2125 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002126 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002127 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002128
mohammad1603f08a5502018-06-03 15:05:47 +03002129 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002130
mohammad16035955c982018-04-26 00:53:03 +03002131 status = psa_get_key_information( key, &key_type, &key_bits );
2132 if( status != PSA_SUCCESS )
2133 return( status );
2134 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002135 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002136 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002137
mohammad16035ed06212018-06-06 13:09:34 +03002138 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2139 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002140 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002141 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002142
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002143 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002144 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002145
Gilles Peskine2d277862018-06-18 15:41:12 +02002146 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2147 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002148 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002149
mohammad16035955c982018-04-26 00:53:03 +03002150 if( alg == PSA_ALG_GCM )
2151 {
2152 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002153 tag_length = 16;
2154
mohammad160396910d82018-06-04 14:33:00 +03002155 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2156 return( PSA_ERROR_INVALID_ARGUMENT );
2157
mohammad160315223a82018-06-03 17:19:55 +03002158 //make sure we have place to hold the tag in the ciphertext buffer
2159 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002160 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002161
2162 //update the tag pointer to point to the end of the ciphertext_length
2163 tag = ciphertext + plaintext_length;
2164
mohammad16035955c982018-04-26 00:53:03 +03002165 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002166 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002167 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002168 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002169 if( ret != 0 )
2170 {
2171 mbedtls_gcm_free( &gcm );
2172 return( mbedtls_to_psa_error( ret ) );
2173 }
2174 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002175 plaintext_length, nonce,
2176 nonce_length, additional_data,
2177 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002178 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002179 mbedtls_gcm_free( &gcm );
2180 }
2181 else if( alg == PSA_ALG_CCM )
2182 {
2183 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002184 tag_length = 16;
2185
mohammad160396910d82018-06-04 14:33:00 +03002186 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2187 return( PSA_ERROR_INVALID_ARGUMENT );
2188
mohammad160347ddf3d2018-04-26 01:11:21 +03002189 if( nonce_length < 7 || nonce_length > 13 )
2190 return( PSA_ERROR_INVALID_ARGUMENT );
2191
mohammad160315223a82018-06-03 17:19:55 +03002192 //make sure we have place to hold the tag in the ciphertext buffer
2193 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002194 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002195
2196 //update the tag pointer to point to the end of the ciphertext_length
2197 tag = ciphertext + plaintext_length;
2198
mohammad16035955c982018-04-26 00:53:03 +03002199 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002200 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002201 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002202 if( ret != 0 )
2203 {
2204 mbedtls_ccm_free( &ccm );
2205 return( mbedtls_to_psa_error( ret ) );
2206 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002207 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002208 nonce, nonce_length,
2209 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002210 additional_data_length,
2211 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002212 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002213 mbedtls_ccm_free( &ccm );
2214 }
mohammad16035c8845f2018-05-09 05:40:09 -07002215 else
2216 {
mohammad1603554faad2018-06-03 15:07:38 +03002217 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002218 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002219
mohammad160315223a82018-06-03 17:19:55 +03002220 if( ret != 0 )
2221 {
2222 memset( ciphertext, 0, ciphertext_size );
2223 return( mbedtls_to_psa_error( ret ) );
2224 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002225
mohammad160315223a82018-06-03 17:19:55 +03002226 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002227 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002228}
2229
Gilles Peskineee652a32018-06-01 19:23:52 +02002230/* Locate the tag in a ciphertext buffer containing the encrypted data
2231 * followed by the tag. Return the length of the part preceding the tag in
2232 * *plaintext_length. This is the size of the plaintext in modes where
2233 * the encrypted data has the same size as the plaintext, such as
2234 * CCM and GCM. */
2235static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2236 const uint8_t *ciphertext,
2237 size_t ciphertext_length,
2238 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002239 const uint8_t **p_tag )
2240{
2241 size_t payload_length;
2242 if( tag_length > ciphertext_length )
2243 return( PSA_ERROR_INVALID_ARGUMENT );
2244 payload_length = ciphertext_length - tag_length;
2245 if( payload_length > plaintext_size )
2246 return( PSA_ERROR_BUFFER_TOO_SMALL );
2247 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002248 return( PSA_SUCCESS );
2249}
2250
mohammad16035955c982018-04-26 00:53:03 +03002251psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2252 psa_algorithm_t alg,
2253 const uint8_t *nonce,
2254 size_t nonce_length,
2255 const uint8_t *additional_data,
2256 size_t additional_data_length,
2257 const uint8_t *ciphertext,
2258 size_t ciphertext_length,
2259 uint8_t *plaintext,
2260 size_t plaintext_size,
2261 size_t *plaintext_length )
2262{
2263 int ret;
2264 psa_status_t status;
2265 key_slot_t *slot;
2266 psa_key_type_t key_type;
2267 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002268 const uint8_t *tag;
2269 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002270 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002271 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002272
Gilles Peskineee652a32018-06-01 19:23:52 +02002273 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002274
mohammad16035955c982018-04-26 00:53:03 +03002275 status = psa_get_key_information( key, &key_type, &key_bits );
2276 if( status != PSA_SUCCESS )
2277 return( status );
2278 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002279 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002280 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002281
mohammad16035ed06212018-06-06 13:09:34 +03002282 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2283 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002284 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002285 return( PSA_ERROR_NOT_SUPPORTED );
2286
mohammad1603f14394b2018-06-04 14:33:19 +03002287 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2288 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002289
Gilles Peskine2d277862018-06-18 15:41:12 +02002290 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2291 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002292 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002293
mohammad16035955c982018-04-26 00:53:03 +03002294 if( alg == PSA_ALG_GCM )
2295 {
2296 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002297
Gilles Peskineee652a32018-06-01 19:23:52 +02002298 tag_length = 16;
2299 status = psa_aead_unpadded_locate_tag( tag_length,
2300 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002301 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002302 if( status != PSA_SUCCESS )
2303 return( status );
2304
mohammad16035955c982018-04-26 00:53:03 +03002305 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002306 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002307 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002308 if( ret != 0 )
2309 {
2310 mbedtls_gcm_free( &gcm );
2311 return( mbedtls_to_psa_error( ret ) );
2312 }
mohammad16035955c982018-04-26 00:53:03 +03002313
Gilles Peskineee652a32018-06-01 19:23:52 +02002314 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002315 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002316 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002317 additional_data,
2318 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002319 tag, tag_length,
2320 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002321 mbedtls_gcm_free( &gcm );
2322 }
2323 else if( alg == PSA_ALG_CCM )
2324 {
2325 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002326
mohammad160347ddf3d2018-04-26 01:11:21 +03002327 if( nonce_length < 7 || nonce_length > 13 )
2328 return( PSA_ERROR_INVALID_ARGUMENT );
2329
mohammad16039375f842018-06-03 14:28:24 +03002330 tag_length = 16;
2331 status = psa_aead_unpadded_locate_tag( tag_length,
2332 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002333 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002334 if( status != PSA_SUCCESS )
2335 return( status );
2336
mohammad16035955c982018-04-26 00:53:03 +03002337 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002338 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002339 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002340 if( ret != 0 )
2341 {
2342 mbedtls_ccm_free( &ccm );
2343 return( mbedtls_to_psa_error( ret ) );
2344 }
mohammad160360a64d02018-06-03 17:20:42 +03002345 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002346 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002347 additional_data,
2348 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002349 ciphertext, plaintext,
2350 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002351 mbedtls_ccm_free( &ccm );
2352 }
mohammad160339574652018-06-01 04:39:53 -07002353 else
2354 {
mohammad1603554faad2018-06-03 15:07:38 +03002355 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002356 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002357
Gilles Peskineee652a32018-06-01 19:23:52 +02002358 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002359 memset( plaintext, 0, plaintext_size );
2360 else
2361 *plaintext_length = ciphertext_length - tag_length;
2362
Gilles Peskineee652a32018-06-01 19:23:52 +02002363 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002364}
2365
Gilles Peskinea0655c32018-04-30 17:06:50 +02002366
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002367
Gilles Peskine20035e32018-02-03 22:44:14 +01002368/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002369/* Module setup */
2370/****************************************************************/
2371
Gilles Peskinee59236f2018-01-27 23:32:46 +01002372void mbedtls_psa_crypto_free( void )
2373{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002374 size_t key;
2375 for( key = 1; key < MBEDTLS_PSA_KEY_SLOT_COUNT; key++ )
2376 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002377 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2378 mbedtls_entropy_free( &global_data.entropy );
2379 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2380}
2381
2382psa_status_t psa_crypto_init( void )
2383{
2384 int ret;
2385 const unsigned char drbg_seed[] = "PSA";
2386
2387 if( global_data.initialized != 0 )
2388 return( PSA_SUCCESS );
2389
2390 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2391 mbedtls_entropy_init( &global_data.entropy );
2392 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2393
2394 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2395 mbedtls_entropy_func,
2396 &global_data.entropy,
2397 drbg_seed, sizeof( drbg_seed ) - 1 );
2398 if( ret != 0 )
2399 goto exit;
2400
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002401 global_data.initialized = 1;
2402
Gilles Peskinee59236f2018-01-27 23:32:46 +01002403exit:
2404 if( ret != 0 )
2405 mbedtls_psa_crypto_free( );
2406 return( mbedtls_to_psa_error( ret ) );
2407}
2408
2409#endif /* MBEDTLS_PSA_CRYPTO_C */