blob: e5ac7bd813549a32f4c5ba14b096957a04ae8845 [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
617#if 0
618static psa_algorithm_t mbedtls_md_alg_to_psa( mbedtls_md_type_t md_alg )
619{
620 switch( md_alg )
621 {
622 case MBEDTLS_MD_NONE:
623 return( 0 );
624 case MBEDTLS_MD_MD2:
625 return( PSA_ALG_MD2 );
626 case MBEDTLS_MD_MD4:
627 return( PSA_ALG_MD4 );
628 case MBEDTLS_MD_MD5:
629 return( PSA_ALG_MD5 );
630 case MBEDTLS_MD_SHA1:
631 return( PSA_ALG_SHA_1 );
632 case MBEDTLS_MD_SHA224:
633 return( PSA_ALG_SHA_224 );
634 case MBEDTLS_MD_SHA256:
635 return( PSA_ALG_SHA_256 );
636 case MBEDTLS_MD_SHA384:
637 return( PSA_ALG_SHA_384 );
638 case MBEDTLS_MD_SHA512:
639 return( PSA_ALG_SHA_512 );
640 case MBEDTLS_MD_RIPEMD160:
641 return( PSA_ALG_RIPEMD160 );
642 default:
Gilles Peskine47c1bc02018-03-20 17:55:04 +0100643 return( 0 );
Gilles Peskine20035e32018-02-03 22:44:14 +0100644 }
645}
646#endif
647
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100648psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
649{
650 switch( operation->alg )
651 {
652#if defined(MBEDTLS_MD2_C)
653 case PSA_ALG_MD2:
654 mbedtls_md2_free( &operation->ctx.md2 );
655 break;
656#endif
657#if defined(MBEDTLS_MD4_C)
658 case PSA_ALG_MD4:
659 mbedtls_md4_free( &operation->ctx.md4 );
660 break;
661#endif
662#if defined(MBEDTLS_MD5_C)
663 case PSA_ALG_MD5:
664 mbedtls_md5_free( &operation->ctx.md5 );
665 break;
666#endif
667#if defined(MBEDTLS_RIPEMD160_C)
668 case PSA_ALG_RIPEMD160:
669 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
670 break;
671#endif
672#if defined(MBEDTLS_SHA1_C)
673 case PSA_ALG_SHA_1:
674 mbedtls_sha1_free( &operation->ctx.sha1 );
675 break;
676#endif
677#if defined(MBEDTLS_SHA256_C)
678 case PSA_ALG_SHA_224:
679 case PSA_ALG_SHA_256:
680 mbedtls_sha256_free( &operation->ctx.sha256 );
681 break;
682#endif
683#if defined(MBEDTLS_SHA512_C)
684 case PSA_ALG_SHA_384:
685 case PSA_ALG_SHA_512:
686 mbedtls_sha512_free( &operation->ctx.sha512 );
687 break;
688#endif
689 default:
690 return( PSA_ERROR_NOT_SUPPORTED );
691 }
692 operation->alg = 0;
693 return( PSA_SUCCESS );
694}
695
696psa_status_t psa_hash_start( psa_hash_operation_t *operation,
697 psa_algorithm_t alg )
698{
699 int ret;
700 operation->alg = 0;
701 switch( alg )
702 {
703#if defined(MBEDTLS_MD2_C)
704 case PSA_ALG_MD2:
705 mbedtls_md2_init( &operation->ctx.md2 );
706 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
707 break;
708#endif
709#if defined(MBEDTLS_MD4_C)
710 case PSA_ALG_MD4:
711 mbedtls_md4_init( &operation->ctx.md4 );
712 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
713 break;
714#endif
715#if defined(MBEDTLS_MD5_C)
716 case PSA_ALG_MD5:
717 mbedtls_md5_init( &operation->ctx.md5 );
718 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
719 break;
720#endif
721#if defined(MBEDTLS_RIPEMD160_C)
722 case PSA_ALG_RIPEMD160:
723 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
724 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
725 break;
726#endif
727#if defined(MBEDTLS_SHA1_C)
728 case PSA_ALG_SHA_1:
729 mbedtls_sha1_init( &operation->ctx.sha1 );
730 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
731 break;
732#endif
733#if defined(MBEDTLS_SHA256_C)
734 case PSA_ALG_SHA_224:
735 mbedtls_sha256_init( &operation->ctx.sha256 );
736 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
737 break;
738 case PSA_ALG_SHA_256:
739 mbedtls_sha256_init( &operation->ctx.sha256 );
740 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
741 break;
742#endif
743#if defined(MBEDTLS_SHA512_C)
744 case PSA_ALG_SHA_384:
745 mbedtls_sha512_init( &operation->ctx.sha512 );
746 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
747 break;
748 case PSA_ALG_SHA_512:
749 mbedtls_sha512_init( &operation->ctx.sha512 );
750 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
751 break;
752#endif
753 default:
754 return( PSA_ERROR_NOT_SUPPORTED );
755 }
756 if( ret == 0 )
757 operation->alg = alg;
758 else
759 psa_hash_abort( operation );
760 return( mbedtls_to_psa_error( ret ) );
761}
762
763psa_status_t psa_hash_update( psa_hash_operation_t *operation,
764 const uint8_t *input,
765 size_t input_length )
766{
767 int ret;
768 switch( operation->alg )
769 {
770#if defined(MBEDTLS_MD2_C)
771 case PSA_ALG_MD2:
772 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
773 input, input_length );
774 break;
775#endif
776#if defined(MBEDTLS_MD4_C)
777 case PSA_ALG_MD4:
778 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
779 input, input_length );
780 break;
781#endif
782#if defined(MBEDTLS_MD5_C)
783 case PSA_ALG_MD5:
784 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
785 input, input_length );
786 break;
787#endif
788#if defined(MBEDTLS_RIPEMD160_C)
789 case PSA_ALG_RIPEMD160:
790 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
791 input, input_length );
792 break;
793#endif
794#if defined(MBEDTLS_SHA1_C)
795 case PSA_ALG_SHA_1:
796 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
797 input, input_length );
798 break;
799#endif
800#if defined(MBEDTLS_SHA256_C)
801 case PSA_ALG_SHA_224:
802 case PSA_ALG_SHA_256:
803 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
804 input, input_length );
805 break;
806#endif
807#if defined(MBEDTLS_SHA512_C)
808 case PSA_ALG_SHA_384:
809 case PSA_ALG_SHA_512:
810 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
811 input, input_length );
812 break;
813#endif
814 default:
815 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
816 break;
817 }
818 if( ret != 0 )
819 psa_hash_abort( operation );
820 return( mbedtls_to_psa_error( ret ) );
821}
822
823psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
824 uint8_t *hash,
825 size_t hash_size,
826 size_t *hash_length )
827{
828 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200829 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100830
831 /* Fill the output buffer with something that isn't a valid hash
832 * (barring an attack on the hash and deliberately-crafted input),
833 * in case the caller doesn't check the return status properly. */
834 *hash_length = actual_hash_length;
835 memset( hash, '!', hash_size );
836
837 if( hash_size < actual_hash_length )
838 return( PSA_ERROR_BUFFER_TOO_SMALL );
839
840 switch( operation->alg )
841 {
842#if defined(MBEDTLS_MD2_C)
843 case PSA_ALG_MD2:
844 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
845 break;
846#endif
847#if defined(MBEDTLS_MD4_C)
848 case PSA_ALG_MD4:
849 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
850 break;
851#endif
852#if defined(MBEDTLS_MD5_C)
853 case PSA_ALG_MD5:
854 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
855 break;
856#endif
857#if defined(MBEDTLS_RIPEMD160_C)
858 case PSA_ALG_RIPEMD160:
859 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
860 break;
861#endif
862#if defined(MBEDTLS_SHA1_C)
863 case PSA_ALG_SHA_1:
864 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
865 break;
866#endif
867#if defined(MBEDTLS_SHA256_C)
868 case PSA_ALG_SHA_224:
869 case PSA_ALG_SHA_256:
870 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
871 break;
872#endif
873#if defined(MBEDTLS_SHA512_C)
874 case PSA_ALG_SHA_384:
875 case PSA_ALG_SHA_512:
876 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
877 break;
878#endif
879 default:
880 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
881 break;
882 }
883
884 if( ret == 0 )
885 {
886 return( psa_hash_abort( operation ) );
887 }
888 else
889 {
890 psa_hash_abort( operation );
891 return( mbedtls_to_psa_error( ret ) );
892 }
893}
894
Gilles Peskine2d277862018-06-18 15:41:12 +0200895psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
896 const uint8_t *hash,
897 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100898{
899 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
900 size_t actual_hash_length;
901 psa_status_t status = psa_hash_finish( operation,
902 actual_hash, sizeof( actual_hash ),
903 &actual_hash_length );
904 if( status != PSA_SUCCESS )
905 return( status );
906 if( actual_hash_length != hash_length )
907 return( PSA_ERROR_INVALID_SIGNATURE );
908 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
909 return( PSA_ERROR_INVALID_SIGNATURE );
910 return( PSA_SUCCESS );
911}
912
913
914
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100915/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +0100916/* MAC */
917/****************************************************************/
918
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100919static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +0100920 psa_algorithm_t alg,
921 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +0200922 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +0300923 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100924{
Gilles Peskine8c9def32018-02-08 10:02:12 +0100925 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +0300926 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100927
928 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
929 {
930 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +0200931 {
932 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
933 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +0200934
Nir Sonnenscheine9664c32018-06-17 14:41:30 +0300935 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +0100936 {
937 case PSA_ALG_STREAM_CIPHER:
938 mode = MBEDTLS_MODE_STREAM;
939 break;
940 case PSA_ALG_CBC_BASE:
941 mode = MBEDTLS_MODE_CBC;
942 break;
943 case PSA_ALG_CFB_BASE:
944 mode = MBEDTLS_MODE_CFB;
945 break;
946 case PSA_ALG_OFB_BASE:
947 mode = MBEDTLS_MODE_OFB;
948 break;
949 case PSA_ALG_CTR:
950 mode = MBEDTLS_MODE_CTR;
951 break;
952 case PSA_ALG_CCM:
953 mode = MBEDTLS_MODE_CCM;
954 break;
955 case PSA_ALG_GCM:
956 mode = MBEDTLS_MODE_GCM;
957 break;
958 default:
959 return( NULL );
960 }
961 }
962 else if( alg == PSA_ALG_CMAC )
963 mode = MBEDTLS_MODE_ECB;
964 else if( alg == PSA_ALG_GMAC )
965 mode = MBEDTLS_MODE_GCM;
966 else
967 return( NULL );
968
969 switch( key_type )
970 {
971 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +0300972 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100973 break;
974 case PSA_KEY_TYPE_DES:
975 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +0300976 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100977 else
mohammad1603f4f0d612018-06-03 15:04:51 +0300978 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100979 break;
980 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +0300981 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100982 break;
983 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +0300984 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100985 break;
986 default:
987 return( NULL );
988 }
mohammad1603f4f0d612018-06-03 15:04:51 +0300989 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +0300990 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +0100991
mohammad1603f4f0d612018-06-03 15:04:51 +0300992 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +0100993}
994
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +0300995static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +0300996{
Gilles Peskine2d277862018-06-18 15:41:12 +0200997 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +0300998 {
999 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001000 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001001 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001002 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001003 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001004 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001005 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001006 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001007 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001008 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001009 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001010 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001011 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001012 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001013 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001014 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001015 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001016 return( 128 );
1017 default:
1018 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001019 }
1020}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001021
Gilles Peskine8c9def32018-02-08 10:02:12 +01001022psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1023{
1024 switch( operation->alg )
1025 {
1026#if defined(MBEDTLS_CMAC_C)
1027 case PSA_ALG_CMAC:
1028 mbedtls_cipher_free( &operation->ctx.cmac );
1029 break;
1030#endif /* MBEDTLS_CMAC_C */
1031 default:
1032#if defined(MBEDTLS_MD_C)
1033 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001034 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001035 unsigned int block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001036 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001037
Gilles Peskine99bc6492018-06-11 17:13:00 +02001038 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001039 return( PSA_ERROR_NOT_SUPPORTED );
1040
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001041 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001042 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001043 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001044 else
1045#endif /* MBEDTLS_MD_C */
1046 return( PSA_ERROR_NOT_SUPPORTED );
1047 }
Moran Peker41deec42018-04-04 15:43:05 +03001048
Gilles Peskine8c9def32018-02-08 10:02:12 +01001049 operation->alg = 0;
1050 operation->key_set = 0;
1051 operation->iv_set = 0;
1052 operation->iv_required = 0;
1053 operation->has_input = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001054
Gilles Peskine8c9def32018-02-08 10:02:12 +01001055 return( PSA_SUCCESS );
1056}
1057
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001058static int psa_cmac_start( psa_mac_operation_t *operation,
1059 size_t key_bits,
1060 key_slot_t *slot,
1061 const mbedtls_cipher_info_t *cipher_info )
1062{
1063 int ret;
1064
1065 operation->mac_size = cipher_info->block_size;
1066 operation->iv_required = 0;
1067 mbedtls_cipher_init( &operation->ctx.cmac );
1068
1069 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1070 if( ret != 0 )
1071 return( ret );
1072
1073 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1074 slot->data.raw.data,
1075 key_bits );
1076 return( ret );
1077}
1078
1079static int psa_hmac_start( psa_mac_operation_t *operation,
1080 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001081 key_slot_t *slot,
1082 psa_algorithm_t alg )
1083{
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001084 unsigned char ipad[PSA_CRYPTO_MD_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001085 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001086 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001087 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001088 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001089 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001090 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001091 size_t key_length = slot->data.raw.bytes;
1092 psa_status_t status;
1093
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001094 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001095 return( PSA_ERROR_NOT_SUPPORTED );
1096
1097 if( key_type != PSA_KEY_TYPE_HMAC )
1098 return( PSA_ERROR_INVALID_ARGUMENT );
1099
1100 operation->iv_required = 0;
1101 operation->mac_size = digest_size;
1102
1103 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1104 PSA_ALG_HMAC_HASH( alg ) );
1105 if( status != PSA_SUCCESS )
1106 return( status );
1107
Gilles Peskined223b522018-06-11 18:12:58 +02001108 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001109 {
1110 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001111 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001112 if( status != PSA_SUCCESS )
1113 return( status );
1114 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001115 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001116 if( status != PSA_SUCCESS )
1117 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001118 }
Gilles Peskined223b522018-06-11 18:12:58 +02001119 else
1120 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001121
Gilles Peskined223b522018-06-11 18:12:58 +02001122 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1123 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001124 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001125 ipad[i] ^= 0x36;
1126 memset( ipad + key_length, 0x36, block_size - key_length );
1127
1128 /* Copy the key material from ipad to opad, flipping the requisite bits,
1129 * and filling the rest of opad with the requisite constant. */
1130 for( i = 0; i < key_length; i++ )
1131 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1132 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001133
1134 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1135 PSA_ALG_HMAC_HASH( alg ) );
1136 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001137 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001138
1139 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1140 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001141
1142cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001143 mbedtls_zeroize( ipad, key_length );
1144 /* opad is in the context. It needs to stay in memory if this function
1145 * succeeds, and it will be wiped by psa_mac_abort() called from
1146 * psa_mac_start in the error case. */
1147
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001148 return( status );
1149}
1150
Gilles Peskine8c9def32018-02-08 10:02:12 +01001151psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1152 psa_key_slot_t key,
1153 psa_algorithm_t alg )
1154{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001155 psa_status_t status;
1156 key_slot_t *slot;
1157 psa_key_type_t key_type;
1158 size_t key_bits;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001159 const mbedtls_cipher_info_t *cipher_info;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001160
1161 operation->alg = 0;
1162 operation->key_set = 0;
1163 operation->iv_set = 0;
1164 operation->iv_required = 1;
1165 operation->has_input = 0;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001166 operation->key_usage_sign = 0;
1167 operation->key_usage_verify = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001168
1169 status = psa_get_key_information( key, &key_type, &key_bits );
1170 if( status != PSA_SUCCESS )
1171 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001172
Gilles Peskine8c9def32018-02-08 10:02:12 +01001173 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001174 if( slot->type == PSA_KEY_TYPE_NONE )
1175 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001176
Moran Pekerd7326592018-05-29 16:56:39 +03001177 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001178 operation->key_usage_sign = 1;
1179
Moran Pekerd7326592018-05-29 16:56:39 +03001180 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001181 operation->key_usage_verify = 1;
1182
Gilles Peskine8c9def32018-02-08 10:02:12 +01001183 if( ! PSA_ALG_IS_HMAC( alg ) )
1184 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001185 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001186 if( cipher_info == NULL )
1187 return( PSA_ERROR_NOT_SUPPORTED );
1188 operation->mac_size = cipher_info->block_size;
1189 }
1190 switch( alg )
1191 {
1192#if defined(MBEDTLS_CMAC_C)
1193 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001194 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1195 key_bits,
1196 slot,
1197 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001198 break;
1199#endif /* MBEDTLS_CMAC_C */
1200 default:
1201#if defined(MBEDTLS_MD_C)
1202 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001203 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001204 else
1205#endif /* MBEDTLS_MD_C */
1206 return( PSA_ERROR_NOT_SUPPORTED );
1207 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001208
Gilles Peskine8c9def32018-02-08 10:02:12 +01001209 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001210
1211 * context may contain data that needs to be wiped on error. */
1212 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001213 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001214 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001215 }
Gilles Peskine99bc6492018-06-11 17:13:00 +02001216
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001217 else
1218 {
1219 operation->alg = alg;
1220 operation->key_set = 1;
1221 }
1222 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001223}
1224
1225psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1226 const uint8_t *input,
1227 size_t input_length )
1228{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001229 int ret = 0 ;
1230 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001231 if( ! operation->key_set )
1232 return( PSA_ERROR_BAD_STATE );
1233 if( operation->iv_required && ! operation->iv_set )
1234 return( PSA_ERROR_BAD_STATE );
1235 operation->has_input = 1;
1236
1237 switch( operation->alg )
1238 {
1239#if defined(MBEDTLS_CMAC_C)
1240 case PSA_ALG_CMAC:
1241 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1242 input, input_length );
1243 break;
1244#endif /* MBEDTLS_CMAC_C */
1245 default:
1246#if defined(MBEDTLS_MD_C)
1247 if( PSA_ALG_IS_HMAC( operation->alg ) )
1248 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001249 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001250 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001251 }
1252 else
1253#endif /* MBEDTLS_MD_C */
1254 {
1255 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1256 }
1257 break;
1258 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001259 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001260 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001261 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001262 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001263 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001264 }
1265
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001266 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001267}
1268
mohammad16036df908f2018-04-02 08:34:15 -07001269static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001270 uint8_t *mac,
1271 size_t mac_size,
1272 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001273{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001274 int ret = 0;
1275 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001276 if( ! operation->key_set )
1277 return( PSA_ERROR_BAD_STATE );
1278 if( operation->iv_required && ! operation->iv_set )
1279 return( PSA_ERROR_BAD_STATE );
1280
1281 /* Fill the output buffer with something that isn't a valid mac
1282 * (barring an attack on the mac and deliberately-crafted input),
1283 * in case the caller doesn't check the return status properly. */
1284 *mac_length = operation->mac_size;
1285 memset( mac, '!', mac_size );
1286
1287 if( mac_size < operation->mac_size )
1288 return( PSA_ERROR_BUFFER_TOO_SMALL );
1289
1290 switch( operation->alg )
1291 {
1292#if defined(MBEDTLS_CMAC_C)
1293 case PSA_ALG_CMAC:
1294 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1295 break;
1296#endif /* MBEDTLS_CMAC_C */
1297 default:
1298#if defined(MBEDTLS_MD_C)
1299 if( PSA_ALG_IS_HMAC( operation->alg ) )
1300 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001301 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001302 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001303 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001304 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001305 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001306
Gilles Peskine99bc6492018-06-11 17:13:00 +02001307 if( block_size == 0 )
1308 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001309
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001310 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001311 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001312 if( status != PSA_SUCCESS )
1313 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001314 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001315
1316 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1317 PSA_ALG_HMAC_HASH( operation->alg ) );
1318 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001319 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001320
1321 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001322 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001323 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001324 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001325
1326 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001327 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001328 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001329 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001330
1331 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1332 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001333 hmac_cleanup:
1334 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001335 }
1336 else
1337#endif /* MBEDTLS_MD_C */
1338 {
1339 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1340 }
1341 break;
1342 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001343cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001344
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001345 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001346 {
1347 return( psa_mac_abort( operation ) );
1348 }
1349 else
1350 {
1351 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001352 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001353 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001354
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001355 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001356 }
1357}
1358
mohammad16036df908f2018-04-02 08:34:15 -07001359psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1360 uint8_t *mac,
1361 size_t mac_size,
1362 size_t *mac_length )
1363{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001364 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001365 return( PSA_ERROR_NOT_PERMITTED );
1366
Gilles Peskine99bc6492018-06-11 17:13:00 +02001367 return( psa_mac_finish_internal( operation, mac,
1368 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001369}
1370
Gilles Peskine2d277862018-06-18 15:41:12 +02001371#define MBEDTLS_PSA_MAC_MAX_SIZE \
1372 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1373 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001374 MBEDTLS_MAX_BLOCK_LENGTH )
1375psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1376 const uint8_t *mac,
1377 size_t mac_length )
1378{
1379 uint8_t actual_mac[MBEDTLS_PSA_MAC_MAX_SIZE];
1380 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001381 psa_status_t status;
1382
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001383 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001384 return( PSA_ERROR_NOT_PERMITTED );
1385
1386 status = psa_mac_finish_internal( operation,
1387 actual_mac, sizeof( actual_mac ),
1388 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001389 if( status != PSA_SUCCESS )
1390 return( status );
1391 if( actual_mac_length != mac_length )
1392 return( PSA_ERROR_INVALID_SIGNATURE );
1393 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1394 return( PSA_ERROR_INVALID_SIGNATURE );
1395 return( PSA_SUCCESS );
1396}
1397
1398
Gilles Peskine20035e32018-02-03 22:44:14 +01001399
Gilles Peskine20035e32018-02-03 22:44:14 +01001400/****************************************************************/
1401/* Asymmetric cryptography */
1402/****************************************************************/
1403
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001404/* Decode the hash algorithm from alg and store the mbedtls encoding in
1405 * md_alg. Verify that the hash length is consistent. */
1406static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1407 size_t hash_length,
1408 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001409{
Gilles Peskine61b91d42018-06-08 16:09:36 +02001410 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
1411 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1412 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1413 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001414 {
1415#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001416 if( hash_length > UINT_MAX )
1417 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001418#endif
1419 }
1420 else
1421 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001422 if( mbedtls_md_get_size( md_info ) != hash_length )
1423 return( PSA_ERROR_INVALID_ARGUMENT );
1424 if( md_info == NULL )
1425 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001426 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001427 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001428}
1429
Gilles Peskine61b91d42018-06-08 16:09:36 +02001430psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1431 psa_algorithm_t alg,
1432 const uint8_t *hash,
1433 size_t hash_length,
1434 const uint8_t *salt,
1435 size_t salt_length,
1436 uint8_t *signature,
1437 size_t signature_size,
1438 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001439{
1440 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001441 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001442 *signature_length = 0;
1443 (void) salt;
1444 (void) salt_length;
1445
Gilles Peskine20035e32018-02-03 22:44:14 +01001446 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1447 return( PSA_ERROR_EMPTY_SLOT );
1448 slot = &global_data.key_slots[key];
1449 if( slot->type == PSA_KEY_TYPE_NONE )
1450 return( PSA_ERROR_EMPTY_SLOT );
1451 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1452 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001453 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001454 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001455
Gilles Peskine20035e32018-02-03 22:44:14 +01001456#if defined(MBEDTLS_RSA_C)
1457 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1458 {
1459 mbedtls_rsa_context *rsa = slot->data.rsa;
1460 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001461 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001462 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001463 if( status != PSA_SUCCESS )
1464 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001465
Gilles Peskine20035e32018-02-03 22:44:14 +01001466 if( signature_size < rsa->len )
1467 return( PSA_ERROR_BUFFER_TOO_SMALL );
1468#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001469 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001470 {
1471 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1472 MBEDTLS_MD_NONE );
1473 ret = mbedtls_rsa_pkcs1_sign( rsa,
1474 mbedtls_ctr_drbg_random,
1475 &global_data.ctr_drbg,
1476 MBEDTLS_RSA_PRIVATE,
1477 md_alg, hash_length, hash,
1478 signature );
1479 }
1480 else
1481#endif /* MBEDTLS_PKCS1_V15 */
1482#if defined(MBEDTLS_PKCS1_V21)
1483 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1484 {
1485 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1486 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1487 mbedtls_ctr_drbg_random,
1488 &global_data.ctr_drbg,
1489 MBEDTLS_RSA_PRIVATE,
1490 md_alg, hash_length, hash,
1491 signature );
1492 }
1493 else
1494#endif /* MBEDTLS_PKCS1_V21 */
1495 {
1496 return( PSA_ERROR_INVALID_ARGUMENT );
1497 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001498 if( ret == 0 )
1499 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001500 return( mbedtls_to_psa_error( ret ) );
1501 }
1502 else
1503#endif /* defined(MBEDTLS_RSA_C) */
1504#if defined(MBEDTLS_ECP_C)
1505 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1506 {
itayzafrir5c753392018-05-08 11:18:38 +03001507 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1508 int ret;
1509 const mbedtls_md_info_t *md_info;
1510 mbedtls_md_type_t md_alg;
1511 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1512 return( PSA_ERROR_BUFFER_TOO_SMALL );
1513 md_info = mbedtls_md_info_from_psa( alg );
1514 md_alg = mbedtls_md_get_type( md_info );
1515 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001516 signature, signature_length,
1517 mbedtls_ctr_drbg_random,
1518 &global_data.ctr_drbg );
itayzafrir5c753392018-05-08 11:18:38 +03001519 return( mbedtls_to_psa_error( ret ) );
1520 }
1521 else
1522#endif /* defined(MBEDTLS_ECP_C) */
1523 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001524 return( PSA_ERROR_NOT_SUPPORTED );
1525 }
itayzafrir5c753392018-05-08 11:18:38 +03001526}
1527
1528psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1529 psa_algorithm_t alg,
1530 const uint8_t *hash,
1531 size_t hash_length,
1532 const uint8_t *salt,
1533 size_t salt_length,
1534 uint8_t *signature,
1535 size_t signature_size )
1536{
1537 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001538 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001539 (void) salt;
1540 (void) salt_length;
1541
1542 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1543 return( PSA_ERROR_INVALID_ARGUMENT );
1544 slot = &global_data.key_slots[key];
1545 if( slot->type == PSA_KEY_TYPE_NONE )
1546 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001547 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001548 return( PSA_ERROR_NOT_PERMITTED );
1549
Gilles Peskine61b91d42018-06-08 16:09:36 +02001550#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001551 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1552 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001553 {
1554 mbedtls_rsa_context *rsa = slot->data.rsa;
1555 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001556 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001557 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001558 if( status != PSA_SUCCESS )
1559 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001560
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001561 if( signature_size < rsa->len )
1562 return( PSA_ERROR_BUFFER_TOO_SMALL );
1563#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001564 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001565 {
1566 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1567 MBEDTLS_MD_NONE );
1568
1569 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001570 mbedtls_ctr_drbg_random,
1571 &global_data.ctr_drbg,
1572 MBEDTLS_RSA_PUBLIC,
1573 md_alg,
1574 hash_length,
1575 hash,
1576 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001577
1578 }
1579 else
1580#endif /* MBEDTLS_PKCS1_V15 */
1581#if defined(MBEDTLS_PKCS1_V21)
1582 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1583 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001584 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1585 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1586 mbedtls_ctr_drbg_random,
1587 &global_data.ctr_drbg,
1588 MBEDTLS_RSA_PUBLIC,
1589 md_alg, hash_length, hash,
1590 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001591 }
1592 else
1593#endif /* MBEDTLS_PKCS1_V21 */
1594 {
1595 return( PSA_ERROR_INVALID_ARGUMENT );
1596 }
1597 return( mbedtls_to_psa_error( ret ) );
1598 }
1599 else
1600#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001601#if defined(MBEDTLS_ECP_C)
1602 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1603 {
1604 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1605 int ret;
Gilles Peskine2d277862018-06-18 15:41:12 +02001606 (void) alg;
Gilles Peskine61b91d42018-06-08 16:09:36 +02001607 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length,
1608 signature, signature_size );
itayzafrir5c753392018-05-08 11:18:38 +03001609 return( mbedtls_to_psa_error( ret ) );
1610 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001611 else
1612#endif /* defined(MBEDTLS_ECP_C) */
1613 {
1614 return( PSA_ERROR_NOT_SUPPORTED );
1615 }
1616}
1617
Gilles Peskine61b91d42018-06-08 16:09:36 +02001618psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1619 psa_algorithm_t alg,
1620 const uint8_t *input,
1621 size_t input_length,
1622 const uint8_t *salt,
1623 size_t salt_length,
1624 uint8_t *output,
1625 size_t output_size,
1626 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001627{
1628 key_slot_t *slot;
1629 (void) salt;
1630 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001631 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001632
1633 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001634 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001635 slot = &global_data.key_slots[key];
1636 if( slot->type == PSA_KEY_TYPE_NONE )
1637 return( PSA_ERROR_EMPTY_SLOT );
1638 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1639 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001640 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1641 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001642
1643#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001644 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1645 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001646 {
1647 mbedtls_rsa_context *rsa = slot->data.rsa;
1648 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001649 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001650 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001651#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001652 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001653 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001654 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1655 mbedtls_ctr_drbg_random,
1656 &global_data.ctr_drbg,
1657 MBEDTLS_RSA_PUBLIC,
1658 input_length,
1659 input,
1660 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001661 }
1662 else
1663#endif /* MBEDTLS_PKCS1_V15 */
1664#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001665 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001666 {
1667 return( PSA_ERROR_NOT_SUPPORTED );
1668 }
1669 else
1670#endif /* MBEDTLS_PKCS1_V21 */
1671 {
1672 return( PSA_ERROR_INVALID_ARGUMENT );
1673 }
1674 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001675 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001676 return( mbedtls_to_psa_error( ret ) );
1677 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001678 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001679#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001680 {
1681 return( PSA_ERROR_NOT_SUPPORTED );
1682 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001683}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001684
Gilles Peskine61b91d42018-06-08 16:09:36 +02001685psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1686 psa_algorithm_t alg,
1687 const uint8_t *input,
1688 size_t input_length,
1689 const uint8_t *salt,
1690 size_t salt_length,
1691 uint8_t *output,
1692 size_t output_size,
1693 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001694{
1695 key_slot_t *slot;
1696 (void) salt;
1697 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001698 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001699
1700 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
1701 return( PSA_ERROR_EMPTY_SLOT );
1702 slot = &global_data.key_slots[key];
1703 if( slot->type == PSA_KEY_TYPE_NONE )
1704 return( PSA_ERROR_EMPTY_SLOT );
1705 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1706 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001707 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1708 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001709
1710#if defined(MBEDTLS_RSA_C)
1711 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1712 {
1713 mbedtls_rsa_context *rsa = slot->data.rsa;
1714 int ret;
1715
Gilles Peskinec4def2f2018-06-08 17:53:48 +02001716 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001717 return( PSA_ERROR_INVALID_ARGUMENT );
1718
1719#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001720 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001721 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001722 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
1723 mbedtls_ctr_drbg_random,
1724 &global_data.ctr_drbg,
1725 MBEDTLS_RSA_PRIVATE,
1726 output_length,
1727 input,
1728 output,
1729 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001730 }
1731 else
1732#endif /* MBEDTLS_PKCS1_V15 */
1733#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001734 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001735 {
1736 return( PSA_ERROR_NOT_SUPPORTED );
1737 }
1738 else
1739#endif /* MBEDTLS_PKCS1_V21 */
1740 {
1741 return( PSA_ERROR_INVALID_ARGUMENT );
1742 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001743
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001744 return( mbedtls_to_psa_error( ret ) );
1745 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001746 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001747#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001748 {
1749 return( PSA_ERROR_NOT_SUPPORTED );
1750 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001751}
Gilles Peskine20035e32018-02-03 22:44:14 +01001752
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001753
1754
mohammad1603503973b2018-03-12 15:59:30 +02001755/****************************************************************/
1756/* Symmetric cryptography */
1757/****************************************************************/
1758
Gilles Peskinee553c652018-06-04 16:22:46 +02001759static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1760 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001761 psa_algorithm_t alg,
1762 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001763{
1764 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1765 psa_status_t status;
1766 key_slot_t *slot;
1767 psa_key_type_t key_type;
1768 size_t key_bits;
1769 const mbedtls_cipher_info_t *cipher_info = NULL;
1770
Moran Peker41deec42018-04-04 15:43:05 +03001771 operation->alg = alg;
Moran Pekerad9d82c2018-04-30 12:31:04 +03001772 operation->key_set = 0;
1773 operation->iv_set = 0;
1774 operation->iv_required = 1;
1775 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001776 operation->block_size = 0;
mohammad1603503973b2018-03-12 15:59:30 +02001777
1778 status = psa_get_key_information( key, &key_type, &key_bits );
1779 if( status != PSA_SUCCESS )
1780 return( status );
1781 slot = &global_data.key_slots[key];
1782
Gilles Peskinebb1072f2018-06-08 18:46:05 +02001783 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02001784 if( cipher_info == NULL )
1785 return( PSA_ERROR_NOT_SUPPORTED );
1786
mohammad1603503973b2018-03-12 15:59:30 +02001787 mbedtls_cipher_init( &operation->ctx.cipher );
1788 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03001789 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001790 {
1791 psa_cipher_abort( operation );
1792 return( mbedtls_to_psa_error( ret ) );
1793 }
1794
1795 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
Gilles Peskinee553c652018-06-04 16:22:46 +02001796 key_bits, cipher_operation );
Moran Peker41deec42018-04-04 15:43:05 +03001797 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001798 {
1799 psa_cipher_abort( operation );
1800 return( mbedtls_to_psa_error( ret ) );
1801 }
1802
mohammad16038481e742018-03-18 13:57:31 +02001803#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03001804 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02001805 {
Gilles Peskine53514202018-06-06 15:11:46 +02001806 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1807 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02001808
Moran Pekera28258c2018-05-29 16:25:04 +03001809 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02001810 {
1811 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
1812 mode = MBEDTLS_PADDING_PKCS7;
1813 break;
1814 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
1815 mode = MBEDTLS_PADDING_NONE;
1816 break;
1817 default:
Moran Pekerae382792018-05-31 14:06:17 +03001818 psa_cipher_abort( operation );
1819 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02001820 }
1821 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03001822 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03001823 {
1824 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02001825 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03001826 }
mohammad16038481e742018-03-18 13:57:31 +02001827 }
1828#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
1829
mohammad1603503973b2018-03-12 15:59:30 +02001830 operation->key_set = 1;
1831 operation->alg = alg;
Gilles Peskine7e928852018-06-04 16:23:10 +02001832 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
1833 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
1834 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001835 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02001836 {
mohammad160389e0f462018-04-12 08:48:45 +03001837 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02001838 }
mohammad1603503973b2018-03-12 15:59:30 +02001839
Moran Peker395db872018-05-31 14:07:14 +03001840 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001841}
1842
Gilles Peskinee553c652018-06-04 16:22:46 +02001843psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
1844 psa_key_slot_t key,
1845 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001846{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001847 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001848}
1849
Gilles Peskinee553c652018-06-04 16:22:46 +02001850psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
1851 psa_key_slot_t key,
1852 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02001853{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001854 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02001855}
1856
Gilles Peskinee553c652018-06-04 16:22:46 +02001857psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
1858 unsigned char *iv,
1859 size_t iv_size,
1860 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001861{
Moran Peker41deec42018-04-04 15:43:05 +03001862 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001863 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001864 return( PSA_ERROR_BAD_STATE );
1865 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02001866 {
Moran Peker41deec42018-04-04 15:43:05 +03001867 ret = PSA_ERROR_BUFFER_TOO_SMALL;
1868 goto exit;
1869 }
Gilles Peskine7e928852018-06-04 16:23:10 +02001870 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
1871 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03001872 if( ret != 0 )
1873 {
1874 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02001875 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02001876 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001877
mohammad16038481e742018-03-18 13:57:31 +02001878 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03001879 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001880
Moran Peker395db872018-05-31 14:07:14 +03001881exit:
1882 if( ret != PSA_SUCCESS )
1883 psa_cipher_abort( operation );
1884 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02001885}
1886
Gilles Peskinee553c652018-06-04 16:22:46 +02001887psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
1888 const unsigned char *iv,
1889 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02001890{
Moran Peker41deec42018-04-04 15:43:05 +03001891 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001892 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03001893 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03001894 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03001895 {
Moran Pekerae382792018-05-31 14:06:17 +03001896 psa_cipher_abort( operation );
1897 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03001898 }
mohammad1603503973b2018-03-12 15:59:30 +02001899 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03001900 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001901 {
1902 psa_cipher_abort( operation );
1903 return( mbedtls_to_psa_error( ret ) );
1904 }
1905
1906 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02001907
Moran Peker395db872018-05-31 14:07:14 +03001908 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001909}
1910
Gilles Peskinee553c652018-06-04 16:22:46 +02001911psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
1912 const uint8_t *input,
1913 size_t input_length,
1914 unsigned char *output,
1915 size_t output_size,
1916 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001917{
1918 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02001919 size_t expected_output_size;
1920 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
1921 {
1922 /* Take the unprocessed partial block left over from previous
1923 * update calls, if any, plus the input to this call. Remove
1924 * the last partial block, if any. You get the data that will be
1925 * output in this call. */
1926 expected_output_size =
1927 ( operation->ctx.cipher.unprocessed_len + input_length )
1928 / operation->block_size * operation->block_size;
1929 }
1930 else
1931 {
1932 expected_output_size = input_length;
1933 }
1934 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03001935 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02001936
mohammad1603503973b2018-03-12 15:59:30 +02001937 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02001938 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03001939 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001940 {
1941 psa_cipher_abort( operation );
1942 return( mbedtls_to_psa_error( ret ) );
1943 }
1944
Moran Peker395db872018-05-31 14:07:14 +03001945 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02001946}
1947
Gilles Peskinee553c652018-06-04 16:22:46 +02001948psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
1949 uint8_t *output,
1950 size_t output_size,
1951 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02001952{
1953 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02001954 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03001955
mohammad1603503973b2018-03-12 15:59:30 +02001956 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001957 {
Moran Peker7cb22b82018-06-05 11:40:02 +03001958 psa_cipher_abort( operation );
1959 return( PSA_ERROR_BAD_STATE );
1960 }
1961 if( operation->iv_required && ! operation->iv_set )
1962 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001963 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001964 return( PSA_ERROR_BAD_STATE );
1965 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001966 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
1967 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03001968 {
Gilles Peskine53514202018-06-06 15:11:46 +02001969 psa_algorithm_t padding_mode =
1970 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03001971 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02001972 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001973 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001974 return( PSA_ERROR_TAMPERING_DETECTED );
1975 }
Gilles Peskine53514202018-06-06 15:11:46 +02001976 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03001977 {
1978 if( operation->ctx.cipher.unprocessed_len != 0 )
1979 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02001980 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03001981 return( PSA_ERROR_INVALID_ARGUMENT );
1982 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02001983 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001984 }
1985
1986 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02001987 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03001988 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001989 {
1990 psa_cipher_abort( operation );
1991 return( mbedtls_to_psa_error( ret ) );
1992 }
Gilles Peskinee553c652018-06-04 16:22:46 +02001993 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03001994 memcpy( output, temp_output_buffer, *output_length );
1995 else
1996 {
1997 psa_cipher_abort( operation );
1998 return( PSA_ERROR_BUFFER_TOO_SMALL );
1999 }
mohammad1603503973b2018-03-12 15:59:30 +02002000
Moran Peker4c80d832018-04-22 20:15:31 +03002001 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002002}
2003
Gilles Peskinee553c652018-06-04 16:22:46 +02002004psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2005{
mohammad1603503973b2018-03-12 15:59:30 +02002006 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002007
Moran Peker41deec42018-04-04 15:43:05 +03002008 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002009 operation->key_set = 0;
2010 operation->iv_set = 0;
2011 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002012 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002013 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002014
Moran Peker395db872018-05-31 14:07:14 +03002015 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002016}
2017
Gilles Peskinea0655c32018-04-30 17:06:50 +02002018
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002019
mohammad16038cc1cee2018-03-28 01:21:33 +03002020/****************************************************************/
2021/* Key Policy */
2022/****************************************************************/
2023
Gilles Peskine2d277862018-06-18 15:41:12 +02002024void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002025{
Gilles Peskine803ce742018-06-18 16:07:14 +02002026 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002027}
2028
Gilles Peskine2d277862018-06-18 15:41:12 +02002029void psa_key_policy_set_usage( psa_key_policy_t *policy,
2030 psa_key_usage_t usage,
2031 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002032{
mohammad16034eed7572018-03-28 05:14:59 -07002033 policy->usage = usage;
2034 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002035}
2036
Gilles Peskine2d277862018-06-18 15:41:12 +02002037psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002038{
mohammad16036df908f2018-04-02 08:34:15 -07002039 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002040}
2041
Gilles Peskine2d277862018-06-18 15:41:12 +02002042psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002043{
mohammad16036df908f2018-04-02 08:34:15 -07002044 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002045}
2046
Gilles Peskine2d277862018-06-18 15:41:12 +02002047psa_status_t psa_set_key_policy( psa_key_slot_t key,
2048 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002049{
2050 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002051
2052 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
2053 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002054
mohammad16038cc1cee2018-03-28 01:21:33 +03002055 slot = &global_data.key_slots[key];
2056 if( slot->type != PSA_KEY_TYPE_NONE )
2057 return( PSA_ERROR_OCCUPIED_SLOT );
2058
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002059 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2060 PSA_KEY_USAGE_ENCRYPT |
2061 PSA_KEY_USAGE_DECRYPT |
2062 PSA_KEY_USAGE_SIGN |
2063 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002064 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002065
mohammad16036df908f2018-04-02 08:34:15 -07002066 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002067
2068 return( PSA_SUCCESS );
2069}
2070
Gilles Peskine2d277862018-06-18 15:41:12 +02002071psa_status_t psa_get_key_policy( psa_key_slot_t key,
2072 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002073{
2074 key_slot_t *slot;
2075
2076 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT || policy == NULL )
2077 return( PSA_ERROR_INVALID_ARGUMENT );
2078
2079 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002080
mohammad16036df908f2018-04-02 08:34:15 -07002081 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002082
2083 return( PSA_SUCCESS );
2084}
Gilles Peskine20035e32018-02-03 22:44:14 +01002085
Gilles Peskinea0655c32018-04-30 17:06:50 +02002086
2087
mohammad1603804cd712018-03-20 22:44:08 +02002088/****************************************************************/
2089/* Key Lifetime */
2090/****************************************************************/
2091
Gilles Peskine2d277862018-06-18 15:41:12 +02002092psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2093 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002094{
2095 key_slot_t *slot;
2096
2097 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
2098 return( PSA_ERROR_INVALID_ARGUMENT );
2099
2100 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002101
mohammad1603804cd712018-03-20 22:44:08 +02002102 *lifetime = slot->lifetime;
2103
2104 return( PSA_SUCCESS );
2105}
2106
Gilles Peskine2d277862018-06-18 15:41:12 +02002107psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2108 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002109{
2110 key_slot_t *slot;
2111
2112 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
2113 return( PSA_ERROR_INVALID_ARGUMENT );
2114
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002115 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2116 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002117 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2118 return( PSA_ERROR_INVALID_ARGUMENT );
2119
mohammad1603804cd712018-03-20 22:44:08 +02002120 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002121 if( slot->type != PSA_KEY_TYPE_NONE )
2122 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002123
Moran Pekerd7326592018-05-29 16:56:39 +03002124 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002125 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002126
mohammad1603060ad8a2018-03-20 14:28:38 -07002127 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002128
2129 return( PSA_SUCCESS );
2130}
2131
Gilles Peskine20035e32018-02-03 22:44:14 +01002132
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002133
mohammad16035955c982018-04-26 00:53:03 +03002134/****************************************************************/
2135/* AEAD */
2136/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002137
mohammad16035955c982018-04-26 00:53:03 +03002138psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2139 psa_algorithm_t alg,
2140 const uint8_t *nonce,
2141 size_t nonce_length,
2142 const uint8_t *additional_data,
2143 size_t additional_data_length,
2144 const uint8_t *plaintext,
2145 size_t plaintext_length,
2146 uint8_t *ciphertext,
2147 size_t ciphertext_size,
2148 size_t *ciphertext_length )
2149{
2150 int ret;
2151 psa_status_t status;
2152 key_slot_t *slot;
2153 psa_key_type_t key_type;
2154 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002155 uint8_t *tag;
2156 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002157 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002158 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002159
mohammad1603f08a5502018-06-03 15:05:47 +03002160 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002161
mohammad16035955c982018-04-26 00:53:03 +03002162 status = psa_get_key_information( key, &key_type, &key_bits );
2163 if( status != PSA_SUCCESS )
2164 return( status );
2165 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002166 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002167 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002168
mohammad16035ed06212018-06-06 13:09:34 +03002169 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2170 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002171 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002172 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002173
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002174 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002175 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002176
Gilles Peskine2d277862018-06-18 15:41:12 +02002177 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2178 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002179 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002180
mohammad16035955c982018-04-26 00:53:03 +03002181 if( alg == PSA_ALG_GCM )
2182 {
2183 mbedtls_gcm_context gcm;
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
mohammad160315223a82018-06-03 17:19:55 +03002189 //make sure we have place to hold the tag in the ciphertext buffer
2190 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002191 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002192
2193 //update the tag pointer to point to the end of the ciphertext_length
2194 tag = ciphertext + plaintext_length;
2195
mohammad16035955c982018-04-26 00:53:03 +03002196 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002197 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002198 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002199 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002200 if( ret != 0 )
2201 {
2202 mbedtls_gcm_free( &gcm );
2203 return( mbedtls_to_psa_error( ret ) );
2204 }
2205 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002206 plaintext_length, nonce,
2207 nonce_length, additional_data,
2208 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002209 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002210 mbedtls_gcm_free( &gcm );
2211 }
2212 else if( alg == PSA_ALG_CCM )
2213 {
2214 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002215 tag_length = 16;
2216
mohammad160396910d82018-06-04 14:33:00 +03002217 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2218 return( PSA_ERROR_INVALID_ARGUMENT );
2219
mohammad160347ddf3d2018-04-26 01:11:21 +03002220 if( nonce_length < 7 || nonce_length > 13 )
2221 return( PSA_ERROR_INVALID_ARGUMENT );
2222
mohammad160315223a82018-06-03 17:19:55 +03002223 //make sure we have place to hold the tag in the ciphertext buffer
2224 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002225 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002226
2227 //update the tag pointer to point to the end of the ciphertext_length
2228 tag = ciphertext + plaintext_length;
2229
mohammad16035955c982018-04-26 00:53:03 +03002230 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002231 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002232 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002233 if( ret != 0 )
2234 {
2235 mbedtls_ccm_free( &ccm );
2236 return( mbedtls_to_psa_error( ret ) );
2237 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002238 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002239 nonce, nonce_length,
2240 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002241 additional_data_length,
2242 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002243 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002244 mbedtls_ccm_free( &ccm );
2245 }
mohammad16035c8845f2018-05-09 05:40:09 -07002246 else
2247 {
mohammad1603554faad2018-06-03 15:07:38 +03002248 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002249 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002250
mohammad160315223a82018-06-03 17:19:55 +03002251 if( ret != 0 )
2252 {
2253 memset( ciphertext, 0, ciphertext_size );
2254 return( mbedtls_to_psa_error( ret ) );
2255 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002256
mohammad160315223a82018-06-03 17:19:55 +03002257 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002258 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002259}
2260
Gilles Peskineee652a32018-06-01 19:23:52 +02002261/* Locate the tag in a ciphertext buffer containing the encrypted data
2262 * followed by the tag. Return the length of the part preceding the tag in
2263 * *plaintext_length. This is the size of the plaintext in modes where
2264 * the encrypted data has the same size as the plaintext, such as
2265 * CCM and GCM. */
2266static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2267 const uint8_t *ciphertext,
2268 size_t ciphertext_length,
2269 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002270 const uint8_t **p_tag )
2271{
2272 size_t payload_length;
2273 if( tag_length > ciphertext_length )
2274 return( PSA_ERROR_INVALID_ARGUMENT );
2275 payload_length = ciphertext_length - tag_length;
2276 if( payload_length > plaintext_size )
2277 return( PSA_ERROR_BUFFER_TOO_SMALL );
2278 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002279 return( PSA_SUCCESS );
2280}
2281
mohammad16035955c982018-04-26 00:53:03 +03002282psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2283 psa_algorithm_t alg,
2284 const uint8_t *nonce,
2285 size_t nonce_length,
2286 const uint8_t *additional_data,
2287 size_t additional_data_length,
2288 const uint8_t *ciphertext,
2289 size_t ciphertext_length,
2290 uint8_t *plaintext,
2291 size_t plaintext_size,
2292 size_t *plaintext_length )
2293{
2294 int ret;
2295 psa_status_t status;
2296 key_slot_t *slot;
2297 psa_key_type_t key_type;
2298 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002299 const uint8_t *tag;
2300 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002301 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002302 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002303
Gilles Peskineee652a32018-06-01 19:23:52 +02002304 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002305
mohammad16035955c982018-04-26 00:53:03 +03002306 status = psa_get_key_information( key, &key_type, &key_bits );
2307 if( status != PSA_SUCCESS )
2308 return( status );
2309 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002310 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002311 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002312
mohammad16035ed06212018-06-06 13:09:34 +03002313 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2314 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002315 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002316 return( PSA_ERROR_NOT_SUPPORTED );
2317
mohammad1603f14394b2018-06-04 14:33:19 +03002318 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2319 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002320
Gilles Peskine2d277862018-06-18 15:41:12 +02002321 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2322 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002323 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002324
mohammad16035955c982018-04-26 00:53:03 +03002325 if( alg == PSA_ALG_GCM )
2326 {
2327 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002328
Gilles Peskineee652a32018-06-01 19:23:52 +02002329 tag_length = 16;
2330 status = psa_aead_unpadded_locate_tag( tag_length,
2331 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002332 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002333 if( status != PSA_SUCCESS )
2334 return( status );
2335
mohammad16035955c982018-04-26 00:53:03 +03002336 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002337 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002338 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002339 if( ret != 0 )
2340 {
2341 mbedtls_gcm_free( &gcm );
2342 return( mbedtls_to_psa_error( ret ) );
2343 }
mohammad16035955c982018-04-26 00:53:03 +03002344
Gilles Peskineee652a32018-06-01 19:23:52 +02002345 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002346 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002347 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002348 additional_data,
2349 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002350 tag, tag_length,
2351 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002352 mbedtls_gcm_free( &gcm );
2353 }
2354 else if( alg == PSA_ALG_CCM )
2355 {
2356 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002357
mohammad160347ddf3d2018-04-26 01:11:21 +03002358 if( nonce_length < 7 || nonce_length > 13 )
2359 return( PSA_ERROR_INVALID_ARGUMENT );
2360
mohammad16039375f842018-06-03 14:28:24 +03002361 tag_length = 16;
2362 status = psa_aead_unpadded_locate_tag( tag_length,
2363 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002364 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002365 if( status != PSA_SUCCESS )
2366 return( status );
2367
mohammad16035955c982018-04-26 00:53:03 +03002368 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002369 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002370 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002371 if( ret != 0 )
2372 {
2373 mbedtls_ccm_free( &ccm );
2374 return( mbedtls_to_psa_error( ret ) );
2375 }
mohammad160360a64d02018-06-03 17:20:42 +03002376 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002377 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002378 additional_data,
2379 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002380 ciphertext, plaintext,
2381 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002382 mbedtls_ccm_free( &ccm );
2383 }
mohammad160339574652018-06-01 04:39:53 -07002384 else
2385 {
mohammad1603554faad2018-06-03 15:07:38 +03002386 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002387 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002388
Gilles Peskineee652a32018-06-01 19:23:52 +02002389 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002390 memset( plaintext, 0, plaintext_size );
2391 else
2392 *plaintext_length = ciphertext_length - tag_length;
2393
Gilles Peskineee652a32018-06-01 19:23:52 +02002394 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002395}
2396
Gilles Peskinea0655c32018-04-30 17:06:50 +02002397
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002398
Gilles Peskine20035e32018-02-03 22:44:14 +01002399/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002400/* Module setup */
2401/****************************************************************/
2402
Gilles Peskinee59236f2018-01-27 23:32:46 +01002403void mbedtls_psa_crypto_free( void )
2404{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002405 size_t key;
2406 for( key = 1; key < MBEDTLS_PSA_KEY_SLOT_COUNT; key++ )
2407 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002408 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2409 mbedtls_entropy_free( &global_data.entropy );
2410 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2411}
2412
2413psa_status_t psa_crypto_init( void )
2414{
2415 int ret;
2416 const unsigned char drbg_seed[] = "PSA";
2417
2418 if( global_data.initialized != 0 )
2419 return( PSA_SUCCESS );
2420
2421 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2422 mbedtls_entropy_init( &global_data.entropy );
2423 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2424
2425 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2426 mbedtls_entropy_func,
2427 &global_data.entropy,
2428 drbg_seed, sizeof( drbg_seed ) - 1 );
2429 if( ret != 0 )
2430 goto exit;
2431
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002432 global_data.initialized = 1;
2433
Gilles Peskinee59236f2018-01-27 23:32:46 +01002434exit:
2435 if( ret != 0 )
2436 mbedtls_psa_crypto_free( );
2437 return( mbedtls_to_psa_error( ret ) );
2438}
2439
2440#endif /* MBEDTLS_PSA_CRYPTO_C */