blob: cb2a4f271a93fc60104631436141950568fba818 [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"
Gilles Peskine9a944802018-06-21 09:35:35 +020042#include "mbedtls/asn1.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020043#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010044#include "mbedtls/blowfish.h"
45#include "mbedtls/camellia.h"
46#include "mbedtls/cipher.h"
47#include "mbedtls/ccm.h"
48#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010049#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010050#include "mbedtls/des.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010051#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010052#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010053#include "mbedtls/error.h"
54#include "mbedtls/gcm.h"
55#include "mbedtls/md2.h"
56#include "mbedtls/md4.h"
57#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010058#include "mbedtls/md.h"
59#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010060#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010061#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010062#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010063#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010064#include "mbedtls/sha1.h"
65#include "mbedtls/sha256.h"
66#include "mbedtls/sha512.h"
67#include "mbedtls/xtea.h"
68
Gilles Peskinee59236f2018-01-27 23:32:46 +010069
70
71/* Implementation that should never be optimized out by the compiler */
72static void mbedtls_zeroize( void *v, size_t n )
73{
74 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
75}
76
Gilles Peskine9ef733f2018-02-07 21:05:37 +010077/* constant-time buffer comparison */
78static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
79{
80 size_t i;
81 unsigned char diff = 0;
82
83 for( i = 0; i < n; i++ )
84 diff |= a[i] ^ b[i];
85
86 return( diff );
87}
88
89
90
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010091/****************************************************************/
92/* Global data, support functions and library management */
93/****************************************************************/
94
95/* Number of key slots (plus one because 0 is not used).
96 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +020097#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010098
Gilles Peskine2d277862018-06-18 15:41:12 +020099typedef struct
100{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100101 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300102 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200103 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200104 union
105 {
106 struct raw_data
107 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100108 uint8_t *data;
109 size_t bytes;
110 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100111#if defined(MBEDTLS_RSA_C)
112 mbedtls_rsa_context *rsa;
113#endif /* MBEDTLS_RSA_C */
114#if defined(MBEDTLS_ECP_C)
115 mbedtls_ecp_keypair *ecp;
116#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100117 } data;
118} key_slot_t;
119
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200120static int key_type_is_raw_bytes( psa_key_type_t type )
121{
122 psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
123 return( category == PSA_KEY_TYPE_RAW_DATA ||
124 category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
125}
126
Gilles Peskine2d277862018-06-18 15:41:12 +0200127typedef struct
128{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100129 int initialized;
130 mbedtls_entropy_context entropy;
131 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200132 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100133} psa_global_data_t;
134
135static psa_global_data_t global_data;
136
137static psa_status_t mbedtls_to_psa_error( int ret )
138{
Gilles Peskinea5905292018-02-07 20:59:33 +0100139 /* If there's both a high-level code and low-level code, dispatch on
140 * the high-level code. */
141 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100142 {
143 case 0:
144 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100145
146 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
147 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
148 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
149 return( PSA_ERROR_NOT_SUPPORTED );
150 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
151 return( PSA_ERROR_HARDWARE_FAILURE );
152
153 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
154 return( PSA_ERROR_HARDWARE_FAILURE );
155
Gilles Peskine9a944802018-06-21 09:35:35 +0200156 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
157 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
158 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
159 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
160 case MBEDTLS_ERR_ASN1_INVALID_DATA:
161 return( PSA_ERROR_INVALID_ARGUMENT );
162 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
163 return( PSA_ERROR_INSUFFICIENT_MEMORY );
164 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
165 return( PSA_ERROR_BUFFER_TOO_SMALL );
166
Gilles Peskinea5905292018-02-07 20:59:33 +0100167 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
168 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
169 return( PSA_ERROR_NOT_SUPPORTED );
170 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
171 return( PSA_ERROR_HARDWARE_FAILURE );
172
173 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
174 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
175 return( PSA_ERROR_NOT_SUPPORTED );
176 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
177 return( PSA_ERROR_HARDWARE_FAILURE );
178
179 case MBEDTLS_ERR_CCM_BAD_INPUT:
180 return( PSA_ERROR_INVALID_ARGUMENT );
181 case MBEDTLS_ERR_CCM_AUTH_FAILED:
182 return( PSA_ERROR_INVALID_SIGNATURE );
183 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
186 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
187 return( PSA_ERROR_NOT_SUPPORTED );
188 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
189 return( PSA_ERROR_INVALID_ARGUMENT );
190 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
191 return( PSA_ERROR_INSUFFICIENT_MEMORY );
192 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
193 return( PSA_ERROR_INVALID_PADDING );
194 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
195 return( PSA_ERROR_BAD_STATE );
196 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
197 return( PSA_ERROR_INVALID_SIGNATURE );
198 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
199 return( PSA_ERROR_TAMPERING_DETECTED );
200 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
201 return( PSA_ERROR_HARDWARE_FAILURE );
202
203 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
204 return( PSA_ERROR_HARDWARE_FAILURE );
205
206 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
207 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
208 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
209 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
210 return( PSA_ERROR_NOT_SUPPORTED );
211 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
212 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
213
214 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
215 return( PSA_ERROR_NOT_SUPPORTED );
216 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
217 return( PSA_ERROR_HARDWARE_FAILURE );
218
Gilles Peskinee59236f2018-01-27 23:32:46 +0100219 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
220 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
221 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
222 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100223
224 case MBEDTLS_ERR_GCM_AUTH_FAILED:
225 return( PSA_ERROR_INVALID_SIGNATURE );
226 case MBEDTLS_ERR_GCM_BAD_INPUT:
227 return( PSA_ERROR_NOT_SUPPORTED );
228 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
229 return( PSA_ERROR_HARDWARE_FAILURE );
230
231 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
232 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
233 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
234 return( PSA_ERROR_HARDWARE_FAILURE );
235
236 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
237 return( PSA_ERROR_NOT_SUPPORTED );
238 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
239 return( PSA_ERROR_INVALID_ARGUMENT );
240 case MBEDTLS_ERR_MD_ALLOC_FAILED:
241 return( PSA_ERROR_INSUFFICIENT_MEMORY );
242 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
243 return( PSA_ERROR_STORAGE_FAILURE );
244 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
245 return( PSA_ERROR_HARDWARE_FAILURE );
246
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100247 case MBEDTLS_ERR_PK_ALLOC_FAILED:
248 return( PSA_ERROR_INSUFFICIENT_MEMORY );
249 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
250 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
251 return( PSA_ERROR_INVALID_ARGUMENT );
252 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100253 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100254 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
255 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
256 return( PSA_ERROR_INVALID_ARGUMENT );
257 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
258 return( PSA_ERROR_NOT_SUPPORTED );
259 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
260 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
261 return( PSA_ERROR_NOT_PERMITTED );
262 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
263 return( PSA_ERROR_INVALID_ARGUMENT );
264 case MBEDTLS_ERR_PK_INVALID_ALG:
265 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
266 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
267 return( PSA_ERROR_NOT_SUPPORTED );
268 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
269 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100270 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
271 return( PSA_ERROR_HARDWARE_FAILURE );
272
273 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
274 return( PSA_ERROR_HARDWARE_FAILURE );
275
276 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
277 return( PSA_ERROR_INVALID_ARGUMENT );
278 case MBEDTLS_ERR_RSA_INVALID_PADDING:
279 return( PSA_ERROR_INVALID_PADDING );
280 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
281 return( PSA_ERROR_HARDWARE_FAILURE );
282 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
283 return( PSA_ERROR_INVALID_ARGUMENT );
284 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
285 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
286 return( PSA_ERROR_TAMPERING_DETECTED );
287 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
288 return( PSA_ERROR_INVALID_SIGNATURE );
289 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
290 return( PSA_ERROR_BUFFER_TOO_SMALL );
291 case MBEDTLS_ERR_RSA_RNG_FAILED:
292 return( PSA_ERROR_INSUFFICIENT_MEMORY );
293 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
294 return( PSA_ERROR_NOT_SUPPORTED );
295 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
296 return( PSA_ERROR_HARDWARE_FAILURE );
297
298 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
299 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
300 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
301 return( PSA_ERROR_HARDWARE_FAILURE );
302
303 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
304 return( PSA_ERROR_INVALID_ARGUMENT );
305 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
306 return( PSA_ERROR_HARDWARE_FAILURE );
307
itayzafrir5c753392018-05-08 11:18:38 +0300308 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300309 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300310 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300311 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
312 return( PSA_ERROR_BUFFER_TOO_SMALL );
313 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
314 return( PSA_ERROR_NOT_SUPPORTED );
315 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
316 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
317 return( PSA_ERROR_INVALID_SIGNATURE );
318 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
319 return( PSA_ERROR_INSUFFICIENT_MEMORY );
320 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
321 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300322
Gilles Peskinee59236f2018-01-27 23:32:46 +0100323 default:
324 return( PSA_ERROR_UNKNOWN_ERROR );
325 }
326}
327
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200328
329
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100330/****************************************************************/
331/* Key management */
332/****************************************************************/
333
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200334static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
335{
336 switch( grpid )
337 {
338 case MBEDTLS_ECP_DP_SECP192R1:
339 return( PSA_ECC_CURVE_SECP192R1 );
340 case MBEDTLS_ECP_DP_SECP224R1:
341 return( PSA_ECC_CURVE_SECP224R1 );
342 case MBEDTLS_ECP_DP_SECP256R1:
343 return( PSA_ECC_CURVE_SECP256R1 );
344 case MBEDTLS_ECP_DP_SECP384R1:
345 return( PSA_ECC_CURVE_SECP384R1 );
346 case MBEDTLS_ECP_DP_SECP521R1:
347 return( PSA_ECC_CURVE_SECP521R1 );
348 case MBEDTLS_ECP_DP_BP256R1:
349 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
350 case MBEDTLS_ECP_DP_BP384R1:
351 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
352 case MBEDTLS_ECP_DP_BP512R1:
353 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
354 case MBEDTLS_ECP_DP_CURVE25519:
355 return( PSA_ECC_CURVE_CURVE25519 );
356 case MBEDTLS_ECP_DP_SECP192K1:
357 return( PSA_ECC_CURVE_SECP192K1 );
358 case MBEDTLS_ECP_DP_SECP224K1:
359 return( PSA_ECC_CURVE_SECP224K1 );
360 case MBEDTLS_ECP_DP_SECP256K1:
361 return( PSA_ECC_CURVE_SECP256K1 );
362 case MBEDTLS_ECP_DP_CURVE448:
363 return( PSA_ECC_CURVE_CURVE448 );
364 default:
365 return( 0 );
366 }
367}
368
Gilles Peskine12313cd2018-06-20 00:20:32 +0200369static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
370{
371 switch( curve )
372 {
373 case PSA_ECC_CURVE_SECP192R1:
374 return( MBEDTLS_ECP_DP_SECP192R1 );
375 case PSA_ECC_CURVE_SECP224R1:
376 return( MBEDTLS_ECP_DP_SECP224R1 );
377 case PSA_ECC_CURVE_SECP256R1:
378 return( MBEDTLS_ECP_DP_SECP256R1 );
379 case PSA_ECC_CURVE_SECP384R1:
380 return( MBEDTLS_ECP_DP_SECP384R1 );
381 case PSA_ECC_CURVE_SECP521R1:
382 return( MBEDTLS_ECP_DP_SECP521R1 );
383 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
384 return( MBEDTLS_ECP_DP_BP256R1 );
385 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
386 return( MBEDTLS_ECP_DP_BP384R1 );
387 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
388 return( MBEDTLS_ECP_DP_BP512R1 );
389 case PSA_ECC_CURVE_CURVE25519:
390 return( MBEDTLS_ECP_DP_CURVE25519 );
391 case PSA_ECC_CURVE_SECP192K1:
392 return( MBEDTLS_ECP_DP_SECP192K1 );
393 case PSA_ECC_CURVE_SECP224K1:
394 return( MBEDTLS_ECP_DP_SECP224K1 );
395 case PSA_ECC_CURVE_SECP256K1:
396 return( MBEDTLS_ECP_DP_SECP256K1 );
397 case PSA_ECC_CURVE_CURVE448:
398 return( MBEDTLS_ECP_DP_CURVE448 );
399 default:
400 return( MBEDTLS_ECP_DP_NONE );
401 }
402}
403
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200404static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
405 size_t bits,
406 struct raw_data *raw )
407{
408 /* Check that the bit size is acceptable for the key type */
409 switch( type )
410 {
411 case PSA_KEY_TYPE_RAW_DATA:
412#if defined(MBEDTLS_MD_C)
413 case PSA_KEY_TYPE_HMAC:
414#endif
415 break;
416#if defined(MBEDTLS_AES_C)
417 case PSA_KEY_TYPE_AES:
418 if( bits != 128 && bits != 192 && bits != 256 )
419 return( PSA_ERROR_INVALID_ARGUMENT );
420 break;
421#endif
422#if defined(MBEDTLS_CAMELLIA_C)
423 case PSA_KEY_TYPE_CAMELLIA:
424 if( bits != 128 && bits != 192 && bits != 256 )
425 return( PSA_ERROR_INVALID_ARGUMENT );
426 break;
427#endif
428#if defined(MBEDTLS_DES_C)
429 case PSA_KEY_TYPE_DES:
430 if( bits != 64 && bits != 128 && bits != 192 )
431 return( PSA_ERROR_INVALID_ARGUMENT );
432 break;
433#endif
434#if defined(MBEDTLS_ARC4_C)
435 case PSA_KEY_TYPE_ARC4:
436 if( bits < 8 || bits > 2048 )
437 return( PSA_ERROR_INVALID_ARGUMENT );
438 break;
439#endif
440 default:
441 return( PSA_ERROR_NOT_SUPPORTED );
442 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200443 if( bits % 8 != 0 )
444 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200445
446 /* Allocate memory for the key */
447 raw->bytes = PSA_BITS_TO_BYTES( bits );
448 raw->data = mbedtls_calloc( 1, raw->bytes );
449 if( raw->data == NULL )
450 {
451 raw->bytes = 0;
452 return( PSA_ERROR_INSUFFICIENT_MEMORY );
453 }
454 return( PSA_SUCCESS );
455}
456
Gilles Peskine2d277862018-06-18 15:41:12 +0200457psa_status_t psa_import_key( psa_key_slot_t key,
458 psa_key_type_t type,
459 const uint8_t *data,
460 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100461{
462 key_slot_t *slot;
463
Gilles Peskine828ed142018-06-18 23:25:51 +0200464 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100465 return( PSA_ERROR_INVALID_ARGUMENT );
466 slot = &global_data.key_slots[key];
467 if( slot->type != PSA_KEY_TYPE_NONE )
468 return( PSA_ERROR_OCCUPIED_SLOT );
469
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200470 if( key_type_is_raw_bytes( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100471 {
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200472 psa_status_t status;
Gilles Peskine6d912132018-03-07 16:41:37 +0100473 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100474 if( data_length > SIZE_MAX / 8 )
475 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200476 status = prepare_raw_data_slot( type,
477 PSA_BYTES_TO_BITS( data_length ),
478 &slot->data.raw );
479 if( status != PSA_SUCCESS )
480 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100481 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100482 }
483 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100484#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100485 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
486 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
487 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100488 {
489 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100490 mbedtls_pk_context pk;
Gilles Peskinec648d692018-06-28 08:46:13 +0200491 psa_status_t status = PSA_SUCCESS;
Gilles Peskine969ac722018-01-28 18:16:59 +0100492 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100493 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
494 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
495 else
496 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100497 if( ret != 0 )
498 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100499 switch( mbedtls_pk_get_type( &pk ) )
500 {
501#if defined(MBEDTLS_RSA_C)
502 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100503 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
504 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200505 slot->data.rsa = mbedtls_pk_rsa( pk );
Gilles Peskine969ac722018-01-28 18:16:59 +0100506 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200507 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100508 break;
509#endif /* MBEDTLS_RSA_C */
510#if defined(MBEDTLS_ECP_C)
511 case MBEDTLS_PK_ECKEY:
512 if( PSA_KEY_TYPE_IS_ECC( type ) )
513 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200514 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
515 psa_ecc_curve_t actual_curve =
516 mbedtls_ecc_group_to_psa( ecp->grp.id );
517 psa_ecc_curve_t expected_curve =
518 PSA_KEY_TYPE_GET_CURVE( type );
519 if( actual_curve != expected_curve )
Gilles Peskinec648d692018-06-28 08:46:13 +0200520 {
521 status = PSA_ERROR_INVALID_ARGUMENT;
522 break;
523 }
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200524 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100525 }
526 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200527 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100528 break;
529#endif /* MBEDTLS_ECP_C */
530 default:
Gilles Peskinec648d692018-06-28 08:46:13 +0200531 status = PSA_ERROR_INVALID_ARGUMENT;
532 break;
533 }
534 /* Free the content of the pk object only on error. On success,
535 * the content of the object has been stored in the slot. */
536 if( status != PSA_SUCCESS )
537 {
538 mbedtls_pk_free( &pk );
539 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100540 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100541 }
542 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100543#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100544 {
545 return( PSA_ERROR_NOT_SUPPORTED );
546 }
547
548 slot->type = type;
549 return( PSA_SUCCESS );
550}
551
Gilles Peskine2d277862018-06-18 15:41:12 +0200552psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100553{
554 key_slot_t *slot;
555
Gilles Peskine828ed142018-06-18 23:25:51 +0200556 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100557 return( PSA_ERROR_INVALID_ARGUMENT );
558 slot = &global_data.key_slots[key];
559 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200560 {
561 /* No key material to clean, but do zeroize the slot below to wipe
562 * metadata such as policies. */
563 }
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200564 else if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100565 {
566 mbedtls_free( slot->data.raw.data );
567 }
568 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100569#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100570 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
571 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100572 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100573 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100574 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100575 }
576 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100577#endif /* defined(MBEDTLS_RSA_C) */
578#if defined(MBEDTLS_ECP_C)
579 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
580 {
581 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100582 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100583 }
584 else
585#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100586 {
587 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100588 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100589 return( PSA_ERROR_TAMPERING_DETECTED );
590 }
591
592 mbedtls_zeroize( slot, sizeof( *slot ) );
593 return( PSA_SUCCESS );
594}
595
Gilles Peskine2d277862018-06-18 15:41:12 +0200596psa_status_t psa_get_key_information( psa_key_slot_t key,
597 psa_key_type_t *type,
598 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100599{
600 key_slot_t *slot;
601
Gilles Peskine828ed142018-06-18 23:25:51 +0200602 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100603 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100604 slot = &global_data.key_slots[key];
605 if( type != NULL )
606 *type = slot->type;
607 if( bits != NULL )
608 *bits = 0;
609 if( slot->type == PSA_KEY_TYPE_NONE )
610 return( PSA_ERROR_EMPTY_SLOT );
611
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200612 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100613 {
614 if( bits != NULL )
615 *bits = slot->data.raw.bytes * 8;
616 }
617 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100618#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100619 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
620 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100621 {
622 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100623 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100624 }
625 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100626#endif /* defined(MBEDTLS_RSA_C) */
627#if defined(MBEDTLS_ECP_C)
628 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
629 {
630 if( bits != NULL )
631 *bits = slot->data.ecp->grp.pbits;
632 }
633 else
634#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100635 {
636 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100637 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100638 return( PSA_ERROR_TAMPERING_DETECTED );
639 }
640
641 return( PSA_SUCCESS );
642}
643
Gilles Peskine2d277862018-06-18 15:41:12 +0200644static psa_status_t psa_internal_export_key( psa_key_slot_t key,
645 uint8_t *data,
646 size_t data_size,
647 size_t *data_length,
648 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100649{
650 key_slot_t *slot;
651
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100652 /* Set the key to empty now, so that even when there are errors, we always
653 * set data_length to a value between 0 and data_size. On error, setting
654 * the key to empty is a good choice because an empty key representation is
655 * unlikely to be accepted anywhere. */
656 *data_length = 0;
657
Gilles Peskine828ed142018-06-18 23:25:51 +0200658 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100659 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100660 slot = &global_data.key_slots[key];
661 if( slot->type == PSA_KEY_TYPE_NONE )
662 return( PSA_ERROR_EMPTY_SLOT );
663
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200664 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300665 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300666
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200667 if( ! export_public_key &&
668 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
669 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300670 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200671
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200672 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100673 {
674 if( slot->data.raw.bytes > data_size )
675 return( PSA_ERROR_BUFFER_TOO_SMALL );
676 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
677 *data_length = slot->data.raw.bytes;
678 return( PSA_SUCCESS );
679 }
680 else
Moran Peker17e36e12018-05-02 12:55:20 +0300681 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100682#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100683 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300684 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
685 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100686 {
Moran Pekera998bc62018-04-16 18:16:20 +0300687 mbedtls_pk_context pk;
688 int ret;
689 mbedtls_pk_init( &pk );
690 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
691 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
692 {
693 pk.pk_info = &mbedtls_rsa_info;
694 pk.pk_ctx = slot->data.rsa;
695 }
696 else
697 {
698 pk.pk_info = &mbedtls_eckey_info;
699 pk.pk_ctx = slot->data.ecp;
700 }
Moran Pekerd7326592018-05-29 16:56:39 +0300701 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300702 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300703 else
704 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300705 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200706 {
707 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300708 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200709 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200710 /* The mbedtls_pk_xxx functions write to the end of the buffer.
711 * Move the data to the beginning and erase remaining data
712 * at the original location. */
713 if( 2 * (size_t) ret <= data_size )
714 {
715 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200716 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200717 }
718 else if( (size_t) ret < data_size )
719 {
720 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200721 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200722 }
Moran Pekera998bc62018-04-16 18:16:20 +0300723 *data_length = ret;
724 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100725 }
726 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100727#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300728 {
729 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200730 it is valid for a special-purpose implementation to omit
731 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300732 return( PSA_ERROR_NOT_SUPPORTED );
733 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100734 }
735}
736
Gilles Peskine2d277862018-06-18 15:41:12 +0200737psa_status_t psa_export_key( psa_key_slot_t key,
738 uint8_t *data,
739 size_t data_size,
740 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300741{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200742 return( psa_internal_export_key( key, data, data_size,
743 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100744}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100745
Gilles Peskine2d277862018-06-18 15:41:12 +0200746psa_status_t psa_export_public_key( psa_key_slot_t key,
747 uint8_t *data,
748 size_t data_size,
749 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300750{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200751 return( psa_internal_export_key( key, data, data_size,
752 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300753}
754
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200755
756
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100757/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100758/* Message digests */
759/****************************************************************/
760
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100761static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100762{
763 switch( alg )
764 {
765#if defined(MBEDTLS_MD2_C)
766 case PSA_ALG_MD2:
767 return( &mbedtls_md2_info );
768#endif
769#if defined(MBEDTLS_MD4_C)
770 case PSA_ALG_MD4:
771 return( &mbedtls_md4_info );
772#endif
773#if defined(MBEDTLS_MD5_C)
774 case PSA_ALG_MD5:
775 return( &mbedtls_md5_info );
776#endif
777#if defined(MBEDTLS_RIPEMD160_C)
778 case PSA_ALG_RIPEMD160:
779 return( &mbedtls_ripemd160_info );
780#endif
781#if defined(MBEDTLS_SHA1_C)
782 case PSA_ALG_SHA_1:
783 return( &mbedtls_sha1_info );
784#endif
785#if defined(MBEDTLS_SHA256_C)
786 case PSA_ALG_SHA_224:
787 return( &mbedtls_sha224_info );
788 case PSA_ALG_SHA_256:
789 return( &mbedtls_sha256_info );
790#endif
791#if defined(MBEDTLS_SHA512_C)
792 case PSA_ALG_SHA_384:
793 return( &mbedtls_sha384_info );
794 case PSA_ALG_SHA_512:
795 return( &mbedtls_sha512_info );
796#endif
797 default:
798 return( NULL );
799 }
800}
801
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100802psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
803{
804 switch( operation->alg )
805 {
Gilles Peskine81736312018-06-26 15:04:31 +0200806 case 0:
807 /* The object has (apparently) been initialized but it is not
808 * in use. It's ok to call abort on such an object, and there's
809 * nothing to do. */
810 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100811#if defined(MBEDTLS_MD2_C)
812 case PSA_ALG_MD2:
813 mbedtls_md2_free( &operation->ctx.md2 );
814 break;
815#endif
816#if defined(MBEDTLS_MD4_C)
817 case PSA_ALG_MD4:
818 mbedtls_md4_free( &operation->ctx.md4 );
819 break;
820#endif
821#if defined(MBEDTLS_MD5_C)
822 case PSA_ALG_MD5:
823 mbedtls_md5_free( &operation->ctx.md5 );
824 break;
825#endif
826#if defined(MBEDTLS_RIPEMD160_C)
827 case PSA_ALG_RIPEMD160:
828 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
829 break;
830#endif
831#if defined(MBEDTLS_SHA1_C)
832 case PSA_ALG_SHA_1:
833 mbedtls_sha1_free( &operation->ctx.sha1 );
834 break;
835#endif
836#if defined(MBEDTLS_SHA256_C)
837 case PSA_ALG_SHA_224:
838 case PSA_ALG_SHA_256:
839 mbedtls_sha256_free( &operation->ctx.sha256 );
840 break;
841#endif
842#if defined(MBEDTLS_SHA512_C)
843 case PSA_ALG_SHA_384:
844 case PSA_ALG_SHA_512:
845 mbedtls_sha512_free( &operation->ctx.sha512 );
846 break;
847#endif
848 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +0200849 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100850 }
851 operation->alg = 0;
852 return( PSA_SUCCESS );
853}
854
855psa_status_t psa_hash_start( psa_hash_operation_t *operation,
856 psa_algorithm_t alg )
857{
858 int ret;
859 operation->alg = 0;
860 switch( alg )
861 {
862#if defined(MBEDTLS_MD2_C)
863 case PSA_ALG_MD2:
864 mbedtls_md2_init( &operation->ctx.md2 );
865 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
866 break;
867#endif
868#if defined(MBEDTLS_MD4_C)
869 case PSA_ALG_MD4:
870 mbedtls_md4_init( &operation->ctx.md4 );
871 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
872 break;
873#endif
874#if defined(MBEDTLS_MD5_C)
875 case PSA_ALG_MD5:
876 mbedtls_md5_init( &operation->ctx.md5 );
877 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
878 break;
879#endif
880#if defined(MBEDTLS_RIPEMD160_C)
881 case PSA_ALG_RIPEMD160:
882 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
883 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
884 break;
885#endif
886#if defined(MBEDTLS_SHA1_C)
887 case PSA_ALG_SHA_1:
888 mbedtls_sha1_init( &operation->ctx.sha1 );
889 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
890 break;
891#endif
892#if defined(MBEDTLS_SHA256_C)
893 case PSA_ALG_SHA_224:
894 mbedtls_sha256_init( &operation->ctx.sha256 );
895 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
896 break;
897 case PSA_ALG_SHA_256:
898 mbedtls_sha256_init( &operation->ctx.sha256 );
899 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
900 break;
901#endif
902#if defined(MBEDTLS_SHA512_C)
903 case PSA_ALG_SHA_384:
904 mbedtls_sha512_init( &operation->ctx.sha512 );
905 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
906 break;
907 case PSA_ALG_SHA_512:
908 mbedtls_sha512_init( &operation->ctx.sha512 );
909 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
910 break;
911#endif
912 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +0200913 return( PSA_ALG_IS_HASH( alg ) ?
914 PSA_ERROR_NOT_SUPPORTED :
915 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100916 }
917 if( ret == 0 )
918 operation->alg = alg;
919 else
920 psa_hash_abort( operation );
921 return( mbedtls_to_psa_error( ret ) );
922}
923
924psa_status_t psa_hash_update( psa_hash_operation_t *operation,
925 const uint8_t *input,
926 size_t input_length )
927{
928 int ret;
929 switch( operation->alg )
930 {
931#if defined(MBEDTLS_MD2_C)
932 case PSA_ALG_MD2:
933 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
934 input, input_length );
935 break;
936#endif
937#if defined(MBEDTLS_MD4_C)
938 case PSA_ALG_MD4:
939 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
940 input, input_length );
941 break;
942#endif
943#if defined(MBEDTLS_MD5_C)
944 case PSA_ALG_MD5:
945 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
946 input, input_length );
947 break;
948#endif
949#if defined(MBEDTLS_RIPEMD160_C)
950 case PSA_ALG_RIPEMD160:
951 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
952 input, input_length );
953 break;
954#endif
955#if defined(MBEDTLS_SHA1_C)
956 case PSA_ALG_SHA_1:
957 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
958 input, input_length );
959 break;
960#endif
961#if defined(MBEDTLS_SHA256_C)
962 case PSA_ALG_SHA_224:
963 case PSA_ALG_SHA_256:
964 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
965 input, input_length );
966 break;
967#endif
968#if defined(MBEDTLS_SHA512_C)
969 case PSA_ALG_SHA_384:
970 case PSA_ALG_SHA_512:
971 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
972 input, input_length );
973 break;
974#endif
975 default:
976 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
977 break;
978 }
979 if( ret != 0 )
980 psa_hash_abort( operation );
981 return( mbedtls_to_psa_error( ret ) );
982}
983
984psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
985 uint8_t *hash,
986 size_t hash_size,
987 size_t *hash_length )
988{
989 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200990 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100991
992 /* Fill the output buffer with something that isn't a valid hash
993 * (barring an attack on the hash and deliberately-crafted input),
994 * in case the caller doesn't check the return status properly. */
995 *hash_length = actual_hash_length;
996 memset( hash, '!', hash_size );
997
998 if( hash_size < actual_hash_length )
999 return( PSA_ERROR_BUFFER_TOO_SMALL );
1000
1001 switch( operation->alg )
1002 {
1003#if defined(MBEDTLS_MD2_C)
1004 case PSA_ALG_MD2:
1005 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1006 break;
1007#endif
1008#if defined(MBEDTLS_MD4_C)
1009 case PSA_ALG_MD4:
1010 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1011 break;
1012#endif
1013#if defined(MBEDTLS_MD5_C)
1014 case PSA_ALG_MD5:
1015 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1016 break;
1017#endif
1018#if defined(MBEDTLS_RIPEMD160_C)
1019 case PSA_ALG_RIPEMD160:
1020 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1021 break;
1022#endif
1023#if defined(MBEDTLS_SHA1_C)
1024 case PSA_ALG_SHA_1:
1025 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1026 break;
1027#endif
1028#if defined(MBEDTLS_SHA256_C)
1029 case PSA_ALG_SHA_224:
1030 case PSA_ALG_SHA_256:
1031 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1032 break;
1033#endif
1034#if defined(MBEDTLS_SHA512_C)
1035 case PSA_ALG_SHA_384:
1036 case PSA_ALG_SHA_512:
1037 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1038 break;
1039#endif
1040 default:
1041 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1042 break;
1043 }
1044
1045 if( ret == 0 )
1046 {
1047 return( psa_hash_abort( operation ) );
1048 }
1049 else
1050 {
1051 psa_hash_abort( operation );
1052 return( mbedtls_to_psa_error( ret ) );
1053 }
1054}
1055
Gilles Peskine2d277862018-06-18 15:41:12 +02001056psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1057 const uint8_t *hash,
1058 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001059{
1060 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1061 size_t actual_hash_length;
1062 psa_status_t status = psa_hash_finish( operation,
1063 actual_hash, sizeof( actual_hash ),
1064 &actual_hash_length );
1065 if( status != PSA_SUCCESS )
1066 return( status );
1067 if( actual_hash_length != hash_length )
1068 return( PSA_ERROR_INVALID_SIGNATURE );
1069 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1070 return( PSA_ERROR_INVALID_SIGNATURE );
1071 return( PSA_SUCCESS );
1072}
1073
1074
1075
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001076/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001077/* MAC */
1078/****************************************************************/
1079
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001080static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001081 psa_algorithm_t alg,
1082 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001083 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001084 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001085{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001086 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001087 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001088
1089 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1090 {
1091 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001092 {
1093 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1094 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001095
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001096 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001097 {
1098 case PSA_ALG_STREAM_CIPHER:
1099 mode = MBEDTLS_MODE_STREAM;
1100 break;
1101 case PSA_ALG_CBC_BASE:
1102 mode = MBEDTLS_MODE_CBC;
1103 break;
1104 case PSA_ALG_CFB_BASE:
1105 mode = MBEDTLS_MODE_CFB;
1106 break;
1107 case PSA_ALG_OFB_BASE:
1108 mode = MBEDTLS_MODE_OFB;
1109 break;
1110 case PSA_ALG_CTR:
1111 mode = MBEDTLS_MODE_CTR;
1112 break;
1113 case PSA_ALG_CCM:
1114 mode = MBEDTLS_MODE_CCM;
1115 break;
1116 case PSA_ALG_GCM:
1117 mode = MBEDTLS_MODE_GCM;
1118 break;
1119 default:
1120 return( NULL );
1121 }
1122 }
1123 else if( alg == PSA_ALG_CMAC )
1124 mode = MBEDTLS_MODE_ECB;
1125 else if( alg == PSA_ALG_GMAC )
1126 mode = MBEDTLS_MODE_GCM;
1127 else
1128 return( NULL );
1129
1130 switch( key_type )
1131 {
1132 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001133 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001134 break;
1135 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001136 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1137 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001138 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001139 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001140 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001141 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001142 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1143 * but two-key Triple-DES is functionally three-key Triple-DES
1144 * with K1=K3, so that's how we present it to mbedtls. */
1145 if( key_bits == 128 )
1146 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001147 break;
1148 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001149 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001150 break;
1151 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001152 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001153 break;
1154 default:
1155 return( NULL );
1156 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001157 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001158 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001159
mohammad1603f4f0d612018-06-03 15:04:51 +03001160 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001161}
1162
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001163static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001164{
Gilles Peskine2d277862018-06-18 15:41:12 +02001165 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001166 {
1167 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001168 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001169 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001170 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001171 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001172 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001173 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001174 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001175 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001176 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001177 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001178 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001179 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001180 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001181 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001182 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001183 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001184 return( 128 );
1185 default:
1186 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001187 }
1188}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001189
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001190/* Initialize the MAC operation structure. Once this function has been
1191 * called, psa_mac_abort can run and will do the right thing. */
1192static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1193 psa_algorithm_t alg )
1194{
1195 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1196
1197 operation->alg = alg;
1198 operation->key_set = 0;
1199 operation->iv_set = 0;
1200 operation->iv_required = 0;
1201 operation->has_input = 0;
1202 operation->key_usage_sign = 0;
1203 operation->key_usage_verify = 0;
1204
1205#if defined(MBEDTLS_CMAC_C)
1206 if( alg == PSA_ALG_CMAC )
1207 {
1208 operation->iv_required = 0;
1209 mbedtls_cipher_init( &operation->ctx.cmac );
1210 status = PSA_SUCCESS;
1211 }
1212 else
1213#endif /* MBEDTLS_CMAC_C */
1214#if defined(MBEDTLS_MD_C)
1215 if( PSA_ALG_IS_HMAC( operation->alg ) )
1216 {
1217 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1218 PSA_ALG_HMAC_HASH( alg ) );
1219 }
1220 else
1221#endif /* MBEDTLS_MD_C */
1222 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001223 if( ! PSA_ALG_IS_MAC( alg ) )
1224 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001225 }
1226
1227 if( status != PSA_SUCCESS )
1228 memset( operation, 0, sizeof( *operation ) );
1229 return( status );
1230}
1231
Gilles Peskine8c9def32018-02-08 10:02:12 +01001232psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1233{
1234 switch( operation->alg )
1235 {
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001236 case 0:
Gilles Peskine81736312018-06-26 15:04:31 +02001237 /* The object has (apparently) been initialized but it is not
1238 * in use. It's ok to call abort on such an object, and there's
1239 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001240 return( PSA_SUCCESS );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001241#if defined(MBEDTLS_CMAC_C)
1242 case PSA_ALG_CMAC:
1243 mbedtls_cipher_free( &operation->ctx.cmac );
1244 break;
1245#endif /* MBEDTLS_CMAC_C */
1246 default:
1247#if defined(MBEDTLS_MD_C)
1248 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001249 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001250 unsigned int block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001251 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001252
Gilles Peskine99bc6492018-06-11 17:13:00 +02001253 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001254 return( PSA_ERROR_NOT_SUPPORTED );
1255
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001256 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001257 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001258 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001259 else
1260#endif /* MBEDTLS_MD_C */
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001261 {
1262 /* Sanity check (shouldn't happen: operation->alg should
1263 * always have been initialized to a valid value). */
1264 return( PSA_ERROR_BAD_STATE );
1265 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001266 }
Moran Peker41deec42018-04-04 15:43:05 +03001267
Gilles Peskine8c9def32018-02-08 10:02:12 +01001268 operation->alg = 0;
1269 operation->key_set = 0;
1270 operation->iv_set = 0;
1271 operation->iv_required = 0;
1272 operation->has_input = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001273 operation->key_usage_sign = 0;
1274 operation->key_usage_verify = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001275
Gilles Peskine8c9def32018-02-08 10:02:12 +01001276 return( PSA_SUCCESS );
1277}
1278
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001279#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001280static int psa_cmac_start( psa_mac_operation_t *operation,
1281 size_t key_bits,
1282 key_slot_t *slot,
1283 const mbedtls_cipher_info_t *cipher_info )
1284{
1285 int ret;
1286
1287 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001288
1289 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1290 if( ret != 0 )
1291 return( ret );
1292
1293 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1294 slot->data.raw.data,
1295 key_bits );
1296 return( ret );
1297}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001298#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001299
Gilles Peskine248051a2018-06-20 16:09:38 +02001300#if defined(MBEDTLS_MD_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001301static int psa_hmac_start( psa_mac_operation_t *operation,
1302 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001303 key_slot_t *slot,
1304 psa_algorithm_t alg )
1305{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001306 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001307 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001308 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001309 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001310 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001311 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001312 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001313 size_t key_length = slot->data.raw.bytes;
1314 psa_status_t status;
1315
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001316 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001317 return( PSA_ERROR_NOT_SUPPORTED );
1318
1319 if( key_type != PSA_KEY_TYPE_HMAC )
1320 return( PSA_ERROR_INVALID_ARGUMENT );
1321
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001322 operation->mac_size = digest_size;
1323
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001324 /* The hash was started earlier in psa_mac_init. */
Gilles Peskined223b522018-06-11 18:12:58 +02001325 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001326 {
1327 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001328 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001329 if( status != PSA_SUCCESS )
1330 return( status );
1331 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001332 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001333 if( status != PSA_SUCCESS )
1334 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001335 }
Gilles Peskined223b522018-06-11 18:12:58 +02001336 else
1337 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001338
Gilles Peskined223b522018-06-11 18:12:58 +02001339 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1340 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001341 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001342 ipad[i] ^= 0x36;
1343 memset( ipad + key_length, 0x36, block_size - key_length );
1344
1345 /* Copy the key material from ipad to opad, flipping the requisite bits,
1346 * and filling the rest of opad with the requisite constant. */
1347 for( i = 0; i < key_length; i++ )
1348 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1349 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001350
1351 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1352 PSA_ALG_HMAC_HASH( alg ) );
1353 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001354 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001355
1356 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1357 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001358
1359cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001360 mbedtls_zeroize( ipad, key_length );
1361 /* opad is in the context. It needs to stay in memory if this function
1362 * succeeds, and it will be wiped by psa_mac_abort() called from
1363 * psa_mac_start in the error case. */
1364
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001365 return( status );
1366}
Gilles Peskine248051a2018-06-20 16:09:38 +02001367#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001368
Gilles Peskine8c9def32018-02-08 10:02:12 +01001369psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1370 psa_key_slot_t key,
1371 psa_algorithm_t alg )
1372{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001373 psa_status_t status;
1374 key_slot_t *slot;
1375 psa_key_type_t key_type;
1376 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001377 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001378
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001379 status = psa_mac_init( operation, alg );
1380 if( status != PSA_SUCCESS )
1381 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001382
1383 status = psa_get_key_information( key, &key_type, &key_bits );
1384 if( status != PSA_SUCCESS )
1385 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001386
Gilles Peskine8c9def32018-02-08 10:02:12 +01001387 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001388 if( slot->type == PSA_KEY_TYPE_NONE )
1389 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001390
Moran Pekerd7326592018-05-29 16:56:39 +03001391 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001392 operation->key_usage_sign = 1;
1393
Moran Pekerd7326592018-05-29 16:56:39 +03001394 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001395 operation->key_usage_verify = 1;
1396
Gilles Peskine8c9def32018-02-08 10:02:12 +01001397 if( ! PSA_ALG_IS_HMAC( alg ) )
1398 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001399 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001400 if( cipher_info == NULL )
1401 return( PSA_ERROR_NOT_SUPPORTED );
1402 operation->mac_size = cipher_info->block_size;
1403 }
1404 switch( alg )
1405 {
1406#if defined(MBEDTLS_CMAC_C)
1407 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001408 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1409 key_bits,
1410 slot,
1411 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001412 break;
1413#endif /* MBEDTLS_CMAC_C */
1414 default:
1415#if defined(MBEDTLS_MD_C)
1416 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001417 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001418 else
1419#endif /* MBEDTLS_MD_C */
1420 return( PSA_ERROR_NOT_SUPPORTED );
1421 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001422
Gilles Peskine8c9def32018-02-08 10:02:12 +01001423 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001424 * context may contain data that needs to be wiped on error. */
1425 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001426 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001427 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001428 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001429 else
1430 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001431 operation->key_set = 1;
1432 }
1433 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001434}
1435
1436psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1437 const uint8_t *input,
1438 size_t input_length )
1439{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001440 int ret = 0 ;
1441 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001442 if( ! operation->key_set )
1443 return( PSA_ERROR_BAD_STATE );
1444 if( operation->iv_required && ! operation->iv_set )
1445 return( PSA_ERROR_BAD_STATE );
1446 operation->has_input = 1;
1447
1448 switch( operation->alg )
1449 {
1450#if defined(MBEDTLS_CMAC_C)
1451 case PSA_ALG_CMAC:
1452 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1453 input, input_length );
1454 break;
1455#endif /* MBEDTLS_CMAC_C */
1456 default:
1457#if defined(MBEDTLS_MD_C)
1458 if( PSA_ALG_IS_HMAC( operation->alg ) )
1459 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001460 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001461 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001462 }
1463 else
1464#endif /* MBEDTLS_MD_C */
1465 {
1466 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1467 }
1468 break;
1469 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001470 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001471 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001472 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001473 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001474 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001475 }
1476
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001477 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001478}
1479
mohammad16036df908f2018-04-02 08:34:15 -07001480static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001481 uint8_t *mac,
1482 size_t mac_size,
1483 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001484{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001485 int ret = 0;
1486 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001487 if( ! operation->key_set )
1488 return( PSA_ERROR_BAD_STATE );
1489 if( operation->iv_required && ! operation->iv_set )
1490 return( PSA_ERROR_BAD_STATE );
1491
1492 /* Fill the output buffer with something that isn't a valid mac
1493 * (barring an attack on the mac and deliberately-crafted input),
1494 * in case the caller doesn't check the return status properly. */
1495 *mac_length = operation->mac_size;
1496 memset( mac, '!', mac_size );
1497
1498 if( mac_size < operation->mac_size )
1499 return( PSA_ERROR_BUFFER_TOO_SMALL );
1500
1501 switch( operation->alg )
1502 {
1503#if defined(MBEDTLS_CMAC_C)
1504 case PSA_ALG_CMAC:
1505 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1506 break;
1507#endif /* MBEDTLS_CMAC_C */
1508 default:
1509#if defined(MBEDTLS_MD_C)
1510 if( PSA_ALG_IS_HMAC( operation->alg ) )
1511 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001512 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001513 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001514 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001515 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001516 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001517
Gilles Peskine99bc6492018-06-11 17:13:00 +02001518 if( block_size == 0 )
1519 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001520
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001521 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001522 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001523 if( status != PSA_SUCCESS )
1524 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001525 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001526
1527 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1528 PSA_ALG_HMAC_HASH( operation->alg ) );
1529 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001530 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001531
1532 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001533 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001534 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001535 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001536
1537 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001538 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001539 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001540 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001541
1542 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1543 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001544 hmac_cleanup:
1545 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001546 }
1547 else
1548#endif /* MBEDTLS_MD_C */
1549 {
1550 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1551 }
1552 break;
1553 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001554cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001555
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001556 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001557 {
1558 return( psa_mac_abort( operation ) );
1559 }
1560 else
1561 {
1562 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001563 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001564 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001565
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001566 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001567 }
1568}
1569
mohammad16036df908f2018-04-02 08:34:15 -07001570psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1571 uint8_t *mac,
1572 size_t mac_size,
1573 size_t *mac_length )
1574{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001575 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001576 return( PSA_ERROR_NOT_PERMITTED );
1577
Gilles Peskine99bc6492018-06-11 17:13:00 +02001578 return( psa_mac_finish_internal( operation, mac,
1579 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001580}
1581
Gilles Peskine828ed142018-06-18 23:25:51 +02001582#define PSA_MAC_MAX_SIZE \
Gilles Peskine2d277862018-06-18 15:41:12 +02001583 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1584 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001585 MBEDTLS_MAX_BLOCK_LENGTH )
1586psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1587 const uint8_t *mac,
1588 size_t mac_length )
1589{
Gilles Peskine828ed142018-06-18 23:25:51 +02001590 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001591 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001592 psa_status_t status;
1593
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001594 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001595 return( PSA_ERROR_NOT_PERMITTED );
1596
1597 status = psa_mac_finish_internal( operation,
1598 actual_mac, sizeof( actual_mac ),
1599 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001600 if( status != PSA_SUCCESS )
1601 return( status );
1602 if( actual_mac_length != mac_length )
1603 return( PSA_ERROR_INVALID_SIGNATURE );
1604 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1605 return( PSA_ERROR_INVALID_SIGNATURE );
1606 return( PSA_SUCCESS );
1607}
1608
1609
Gilles Peskine20035e32018-02-03 22:44:14 +01001610
Gilles Peskine20035e32018-02-03 22:44:14 +01001611/****************************************************************/
1612/* Asymmetric cryptography */
1613/****************************************************************/
1614
Gilles Peskine2b450e32018-06-27 15:42:46 +02001615#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001616/* Decode the hash algorithm from alg and store the mbedtls encoding in
1617 * md_alg. Verify that the hash length is consistent. */
1618static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1619 size_t hash_length,
1620 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001621{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02001622 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001623 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1624 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1625 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001626 {
1627#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001628 if( hash_length > UINT_MAX )
1629 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001630#endif
1631 }
1632 else
1633 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001634 if( mbedtls_md_get_size( md_info ) != hash_length )
1635 return( PSA_ERROR_INVALID_ARGUMENT );
1636 if( md_info == NULL )
1637 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001638 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001639 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001640}
1641
Gilles Peskine2b450e32018-06-27 15:42:46 +02001642static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
1643 psa_algorithm_t alg,
1644 const uint8_t *hash,
1645 size_t hash_length,
1646 uint8_t *signature,
1647 size_t signature_size,
1648 size_t *signature_length )
1649{
1650 psa_status_t status;
1651 int ret;
1652 mbedtls_md_type_t md_alg;
1653
1654 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1655 if( status != PSA_SUCCESS )
1656 return( status );
1657
1658 if( signature_size < rsa->len )
1659 return( PSA_ERROR_BUFFER_TOO_SMALL );
1660
1661#if defined(MBEDTLS_PKCS1_V15)
1662 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1663 {
1664 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1665 MBEDTLS_MD_NONE );
1666 ret = mbedtls_rsa_pkcs1_sign( rsa,
1667 mbedtls_ctr_drbg_random,
1668 &global_data.ctr_drbg,
1669 MBEDTLS_RSA_PRIVATE,
1670 md_alg, hash_length, hash,
1671 signature );
1672 }
1673 else
1674#endif /* MBEDTLS_PKCS1_V15 */
1675#if defined(MBEDTLS_PKCS1_V21)
1676 if( PSA_ALG_IS_RSA_PSS( alg ) )
1677 {
1678 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1679 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1680 mbedtls_ctr_drbg_random,
1681 &global_data.ctr_drbg,
1682 MBEDTLS_RSA_PRIVATE,
1683 md_alg, hash_length, hash,
1684 signature );
1685 }
1686 else
1687#endif /* MBEDTLS_PKCS1_V21 */
1688 {
1689 return( PSA_ERROR_INVALID_ARGUMENT );
1690 }
1691
1692 if( ret == 0 )
1693 *signature_length = rsa->len;
1694 return( mbedtls_to_psa_error( ret ) );
1695}
1696
1697static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
1698 psa_algorithm_t alg,
1699 const uint8_t *hash,
1700 size_t hash_length,
1701 const uint8_t *signature,
1702 size_t signature_length )
1703{
1704 psa_status_t status;
1705 int ret;
1706 mbedtls_md_type_t md_alg;
1707
1708 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1709 if( status != PSA_SUCCESS )
1710 return( status );
1711
1712 if( signature_length < rsa->len )
1713 return( PSA_ERROR_BUFFER_TOO_SMALL );
1714
1715#if defined(MBEDTLS_PKCS1_V15)
1716 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1717 {
1718 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1719 MBEDTLS_MD_NONE );
1720 ret = mbedtls_rsa_pkcs1_verify( rsa,
1721 mbedtls_ctr_drbg_random,
1722 &global_data.ctr_drbg,
1723 MBEDTLS_RSA_PUBLIC,
1724 md_alg,
1725 hash_length,
1726 hash,
1727 signature );
1728 }
1729 else
1730#endif /* MBEDTLS_PKCS1_V15 */
1731#if defined(MBEDTLS_PKCS1_V21)
1732 if( PSA_ALG_IS_RSA_PSS( alg ) )
1733 {
1734 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1735 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1736 mbedtls_ctr_drbg_random,
1737 &global_data.ctr_drbg,
1738 MBEDTLS_RSA_PUBLIC,
1739 md_alg, hash_length, hash,
1740 signature );
1741 }
1742 else
1743#endif /* MBEDTLS_PKCS1_V21 */
1744 {
1745 return( PSA_ERROR_INVALID_ARGUMENT );
1746 }
1747 return( mbedtls_to_psa_error( ret ) );
1748}
1749#endif /* MBEDTLS_RSA_C */
1750
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001751#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001752/* `ecp` cannot be const because `ecp->grp` needs to be non-const
1753 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
1754 * (even though these functions don't modify it). */
1755static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
1756 psa_algorithm_t alg,
1757 const uint8_t *hash,
1758 size_t hash_length,
1759 uint8_t *signature,
1760 size_t signature_size,
1761 size_t *signature_length )
1762{
1763 int ret;
1764 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001765 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001766 mbedtls_mpi_init( &r );
1767 mbedtls_mpi_init( &s );
1768
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001769 *signature_length = 0;
1770 if( signature_size < 2 * curve_bytes )
1771 {
1772 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
1773 goto cleanup;
1774 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001775
1776 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
1777 {
1778 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
1779 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1780 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
1781 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
1782 hash, hash_length,
1783 md_alg ) );
1784 }
1785 else
1786 {
1787 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
1788 hash, hash_length,
1789 mbedtls_ctr_drbg_random,
1790 &global_data.ctr_drbg ) );
1791 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001792
1793 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
1794 signature,
1795 curve_bytes ) );
1796 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
1797 signature + curve_bytes,
1798 curve_bytes ) );
1799
1800cleanup:
1801 mbedtls_mpi_free( &r );
1802 mbedtls_mpi_free( &s );
1803 if( ret == 0 )
1804 *signature_length = 2 * curve_bytes;
1805 memset( signature + *signature_length, 0,
1806 signature_size - *signature_length );
1807 return( mbedtls_to_psa_error( ret ) );
1808}
1809
1810static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
1811 const uint8_t *hash,
1812 size_t hash_length,
1813 const uint8_t *signature,
1814 size_t signature_length )
1815{
1816 int ret;
1817 mbedtls_mpi r, s;
1818 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
1819 mbedtls_mpi_init( &r );
1820 mbedtls_mpi_init( &s );
1821
1822 if( signature_length != 2 * curve_bytes )
1823 return( PSA_ERROR_INVALID_SIGNATURE );
1824
1825 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
1826 signature,
1827 curve_bytes ) );
1828 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
1829 signature + curve_bytes,
1830 curve_bytes ) );
1831
1832 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
1833 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001834
1835cleanup:
1836 mbedtls_mpi_free( &r );
1837 mbedtls_mpi_free( &s );
1838 return( mbedtls_to_psa_error( ret ) );
1839}
1840#endif /* MBEDTLS_ECDSA_C */
1841
Gilles Peskine61b91d42018-06-08 16:09:36 +02001842psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1843 psa_algorithm_t alg,
1844 const uint8_t *hash,
1845 size_t hash_length,
1846 const uint8_t *salt,
1847 size_t salt_length,
1848 uint8_t *signature,
1849 size_t signature_size,
1850 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001851{
1852 key_slot_t *slot;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001853 *signature_length = 0;
1854 (void) salt;
1855 (void) salt_length;
1856
Gilles Peskine828ed142018-06-18 23:25:51 +02001857 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine20035e32018-02-03 22:44:14 +01001858 return( PSA_ERROR_EMPTY_SLOT );
1859 slot = &global_data.key_slots[key];
1860 if( slot->type == PSA_KEY_TYPE_NONE )
1861 return( PSA_ERROR_EMPTY_SLOT );
1862 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1863 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001864 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001865 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001866
Gilles Peskine20035e32018-02-03 22:44:14 +01001867#if defined(MBEDTLS_RSA_C)
1868 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1869 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02001870 return( psa_rsa_sign( slot->data.rsa,
1871 alg,
1872 hash, hash_length,
1873 signature, signature_size,
1874 signature_length ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01001875 }
1876 else
1877#endif /* defined(MBEDTLS_RSA_C) */
1878#if defined(MBEDTLS_ECP_C)
1879 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1880 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001881#if defined(MBEDTLS_ECDSA_C)
1882 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02001883 return( psa_ecdsa_sign( slot->data.ecp,
1884 alg,
1885 hash, hash_length,
1886 signature, signature_size,
1887 signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001888 else
1889#endif /* defined(MBEDTLS_ECDSA_C) */
1890 {
1891 return( PSA_ERROR_INVALID_ARGUMENT );
1892 }
itayzafrir5c753392018-05-08 11:18:38 +03001893 }
1894 else
1895#endif /* defined(MBEDTLS_ECP_C) */
1896 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001897 return( PSA_ERROR_NOT_SUPPORTED );
1898 }
itayzafrir5c753392018-05-08 11:18:38 +03001899}
1900
1901psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1902 psa_algorithm_t alg,
1903 const uint8_t *hash,
1904 size_t hash_length,
1905 const uint8_t *salt,
1906 size_t salt_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02001907 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02001908 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03001909{
1910 key_slot_t *slot;
Gilles Peskine2b450e32018-06-27 15:42:46 +02001911
itayzafrir5c753392018-05-08 11:18:38 +03001912 (void) salt;
1913 (void) salt_length;
1914
Gilles Peskine828ed142018-06-18 23:25:51 +02001915 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001916 return( PSA_ERROR_INVALID_ARGUMENT );
1917 slot = &global_data.key_slots[key];
1918 if( slot->type == PSA_KEY_TYPE_NONE )
1919 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001920 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001921 return( PSA_ERROR_NOT_PERMITTED );
1922
Gilles Peskine61b91d42018-06-08 16:09:36 +02001923#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001924 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1925 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001926 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02001927 return( psa_rsa_verify( slot->data.rsa,
1928 alg,
1929 hash, hash_length,
1930 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001931 }
1932 else
1933#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001934#if defined(MBEDTLS_ECP_C)
1935 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1936 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001937#if defined(MBEDTLS_ECDSA_C)
1938 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001939 return( psa_ecdsa_verify( slot->data.ecp,
1940 hash, hash_length,
1941 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001942 else
1943#endif /* defined(MBEDTLS_ECDSA_C) */
1944 {
1945 return( PSA_ERROR_INVALID_ARGUMENT );
1946 }
itayzafrir5c753392018-05-08 11:18:38 +03001947 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001948 else
1949#endif /* defined(MBEDTLS_ECP_C) */
1950 {
1951 return( PSA_ERROR_NOT_SUPPORTED );
1952 }
1953}
1954
Gilles Peskine61b91d42018-06-08 16:09:36 +02001955psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1956 psa_algorithm_t alg,
1957 const uint8_t *input,
1958 size_t input_length,
1959 const uint8_t *salt,
1960 size_t salt_length,
1961 uint8_t *output,
1962 size_t output_size,
1963 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001964{
1965 key_slot_t *slot;
1966 (void) salt;
1967 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001968 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001969
Gilles Peskine828ed142018-06-18 23:25:51 +02001970 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001971 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001972 slot = &global_data.key_slots[key];
1973 if( slot->type == PSA_KEY_TYPE_NONE )
1974 return( PSA_ERROR_EMPTY_SLOT );
1975 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1976 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001977 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1978 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001979
1980#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001981 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1982 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001983 {
1984 mbedtls_rsa_context *rsa = slot->data.rsa;
1985 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001986 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001987 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001988#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001989 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001990 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001991 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1992 mbedtls_ctr_drbg_random,
1993 &global_data.ctr_drbg,
1994 MBEDTLS_RSA_PUBLIC,
1995 input_length,
1996 input,
1997 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001998 }
1999 else
2000#endif /* MBEDTLS_PKCS1_V15 */
2001#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002002 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002003 {
2004 return( PSA_ERROR_NOT_SUPPORTED );
2005 }
2006 else
2007#endif /* MBEDTLS_PKCS1_V21 */
2008 {
2009 return( PSA_ERROR_INVALID_ARGUMENT );
2010 }
2011 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002012 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002013 return( mbedtls_to_psa_error( ret ) );
2014 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002015 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002016#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002017 {
2018 return( PSA_ERROR_NOT_SUPPORTED );
2019 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002020}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002021
Gilles Peskine61b91d42018-06-08 16:09:36 +02002022psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2023 psa_algorithm_t alg,
2024 const uint8_t *input,
2025 size_t input_length,
2026 const uint8_t *salt,
2027 size_t salt_length,
2028 uint8_t *output,
2029 size_t output_size,
2030 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002031{
2032 key_slot_t *slot;
2033 (void) salt;
2034 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002035 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002036
Gilles Peskine828ed142018-06-18 23:25:51 +02002037 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002038 return( PSA_ERROR_EMPTY_SLOT );
2039 slot = &global_data.key_slots[key];
2040 if( slot->type == PSA_KEY_TYPE_NONE )
2041 return( PSA_ERROR_EMPTY_SLOT );
2042 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2043 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002044 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2045 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002046
2047#if defined(MBEDTLS_RSA_C)
2048 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2049 {
2050 mbedtls_rsa_context *rsa = slot->data.rsa;
2051 int ret;
2052
Gilles Peskinec4def2f2018-06-08 17:53:48 +02002053 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002054 return( PSA_ERROR_INVALID_ARGUMENT );
2055
2056#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002057 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002058 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002059 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2060 mbedtls_ctr_drbg_random,
2061 &global_data.ctr_drbg,
2062 MBEDTLS_RSA_PRIVATE,
2063 output_length,
2064 input,
2065 output,
2066 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002067 }
2068 else
2069#endif /* MBEDTLS_PKCS1_V15 */
2070#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002071 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002072 {
2073 return( PSA_ERROR_NOT_SUPPORTED );
2074 }
2075 else
2076#endif /* MBEDTLS_PKCS1_V21 */
2077 {
2078 return( PSA_ERROR_INVALID_ARGUMENT );
2079 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002080
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002081 return( mbedtls_to_psa_error( ret ) );
2082 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002083 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002084#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002085 {
2086 return( PSA_ERROR_NOT_SUPPORTED );
2087 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002088}
Gilles Peskine20035e32018-02-03 22:44:14 +01002089
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002090
2091
mohammad1603503973b2018-03-12 15:59:30 +02002092/****************************************************************/
2093/* Symmetric cryptography */
2094/****************************************************************/
2095
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002096/* Initialize the cipher operation structure. Once this function has been
2097 * called, psa_cipher_abort can run and will do the right thing. */
2098static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2099 psa_algorithm_t alg )
2100{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002101 if( ! PSA_ALG_IS_CIPHER( alg ) )
2102 {
2103 memset( operation, 0, sizeof( *operation ) );
2104 return( PSA_ERROR_INVALID_ARGUMENT );
2105 }
2106
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002107 operation->alg = alg;
2108 operation->key_set = 0;
2109 operation->iv_set = 0;
2110 operation->iv_required = 1;
2111 operation->iv_size = 0;
2112 operation->block_size = 0;
2113 mbedtls_cipher_init( &operation->ctx.cipher );
2114 return( PSA_SUCCESS );
2115}
2116
Gilles Peskinee553c652018-06-04 16:22:46 +02002117static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2118 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002119 psa_algorithm_t alg,
2120 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002121{
2122 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2123 psa_status_t status;
2124 key_slot_t *slot;
2125 psa_key_type_t key_type;
2126 size_t key_bits;
2127 const mbedtls_cipher_info_t *cipher_info = NULL;
2128
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002129 status = psa_cipher_init( operation, alg );
2130 if( status != PSA_SUCCESS )
2131 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002132
2133 status = psa_get_key_information( key, &key_type, &key_bits );
2134 if( status != PSA_SUCCESS )
2135 return( status );
2136 slot = &global_data.key_slots[key];
2137
Gilles Peskinebb1072f2018-06-08 18:46:05 +02002138 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002139 if( cipher_info == NULL )
2140 return( PSA_ERROR_NOT_SUPPORTED );
2141
mohammad1603503973b2018-03-12 15:59:30 +02002142 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002143 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002144 {
2145 psa_cipher_abort( operation );
2146 return( mbedtls_to_psa_error( ret ) );
2147 }
2148
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002149#if defined(MBEDTLS_DES_C)
2150 if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
2151 {
2152 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2153 unsigned char keys[24];
2154 memcpy( keys, slot->data.raw.data, 16 );
2155 memcpy( keys + 16, slot->data.raw.data, 8 );
2156 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2157 keys,
2158 192, cipher_operation );
2159 }
2160 else
2161#endif
2162 {
2163 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2164 slot->data.raw.data,
2165 key_bits, cipher_operation );
2166 }
Moran Peker41deec42018-04-04 15:43:05 +03002167 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002168 {
2169 psa_cipher_abort( operation );
2170 return( mbedtls_to_psa_error( ret ) );
2171 }
2172
mohammad16038481e742018-03-18 13:57:31 +02002173#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03002174 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02002175 {
Gilles Peskine53514202018-06-06 15:11:46 +02002176 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
2177 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02002178
Moran Pekera28258c2018-05-29 16:25:04 +03002179 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02002180 {
2181 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
2182 mode = MBEDTLS_PADDING_PKCS7;
2183 break;
2184 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
2185 mode = MBEDTLS_PADDING_NONE;
2186 break;
2187 default:
Moran Pekerae382792018-05-31 14:06:17 +03002188 psa_cipher_abort( operation );
2189 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02002190 }
2191 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03002192 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03002193 {
2194 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02002195 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03002196 }
mohammad16038481e742018-03-18 13:57:31 +02002197 }
2198#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2199
mohammad1603503973b2018-03-12 15:59:30 +02002200 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02002201 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
2202 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
2203 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002204 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02002205 {
mohammad160389e0f462018-04-12 08:48:45 +03002206 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02002207 }
mohammad1603503973b2018-03-12 15:59:30 +02002208
Moran Peker395db872018-05-31 14:07:14 +03002209 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002210}
2211
Gilles Peskinee553c652018-06-04 16:22:46 +02002212psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
2213 psa_key_slot_t key,
2214 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002215{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002216 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002217}
2218
Gilles Peskinee553c652018-06-04 16:22:46 +02002219psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
2220 psa_key_slot_t key,
2221 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002222{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002223 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002224}
2225
Gilles Peskinee553c652018-06-04 16:22:46 +02002226psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
2227 unsigned char *iv,
2228 size_t iv_size,
2229 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002230{
Moran Peker41deec42018-04-04 15:43:05 +03002231 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002232 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002233 return( PSA_ERROR_BAD_STATE );
2234 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002235 {
Moran Peker41deec42018-04-04 15:43:05 +03002236 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2237 goto exit;
2238 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002239 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2240 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002241 if( ret != 0 )
2242 {
2243 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002244 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002245 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002246
mohammad16038481e742018-03-18 13:57:31 +02002247 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03002248 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002249
Moran Peker395db872018-05-31 14:07:14 +03002250exit:
2251 if( ret != PSA_SUCCESS )
2252 psa_cipher_abort( operation );
2253 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002254}
2255
Gilles Peskinee553c652018-06-04 16:22:46 +02002256psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
2257 const unsigned char *iv,
2258 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002259{
Moran Peker41deec42018-04-04 15:43:05 +03002260 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002261 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002262 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002263 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002264 {
Moran Pekerae382792018-05-31 14:06:17 +03002265 psa_cipher_abort( operation );
2266 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002267 }
mohammad1603503973b2018-03-12 15:59:30 +02002268 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002269 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002270 {
2271 psa_cipher_abort( operation );
2272 return( mbedtls_to_psa_error( ret ) );
2273 }
2274
2275 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002276
Moran Peker395db872018-05-31 14:07:14 +03002277 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002278}
2279
Gilles Peskinee553c652018-06-04 16:22:46 +02002280psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2281 const uint8_t *input,
2282 size_t input_length,
2283 unsigned char *output,
2284 size_t output_size,
2285 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002286{
2287 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002288 size_t expected_output_size;
2289 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2290 {
2291 /* Take the unprocessed partial block left over from previous
2292 * update calls, if any, plus the input to this call. Remove
2293 * the last partial block, if any. You get the data that will be
2294 * output in this call. */
2295 expected_output_size =
2296 ( operation->ctx.cipher.unprocessed_len + input_length )
2297 / operation->block_size * operation->block_size;
2298 }
2299 else
2300 {
2301 expected_output_size = input_length;
2302 }
2303 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002304 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002305
mohammad1603503973b2018-03-12 15:59:30 +02002306 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002307 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002308 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002309 {
2310 psa_cipher_abort( operation );
2311 return( mbedtls_to_psa_error( ret ) );
2312 }
2313
Moran Peker395db872018-05-31 14:07:14 +03002314 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002315}
2316
Gilles Peskinee553c652018-06-04 16:22:46 +02002317psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2318 uint8_t *output,
2319 size_t output_size,
2320 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002321{
2322 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002323 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002324
mohammad1603503973b2018-03-12 15:59:30 +02002325 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002326 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002327 psa_cipher_abort( operation );
2328 return( PSA_ERROR_BAD_STATE );
2329 }
2330 if( operation->iv_required && ! operation->iv_set )
2331 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002332 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002333 return( PSA_ERROR_BAD_STATE );
2334 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002335 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2336 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002337 {
Gilles Peskine53514202018-06-06 15:11:46 +02002338 psa_algorithm_t padding_mode =
2339 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002340 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002341 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002342 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002343 return( PSA_ERROR_TAMPERING_DETECTED );
2344 }
Gilles Peskine53514202018-06-06 15:11:46 +02002345 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002346 {
2347 if( operation->ctx.cipher.unprocessed_len != 0 )
2348 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002349 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002350 return( PSA_ERROR_INVALID_ARGUMENT );
2351 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002352 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002353 }
2354
2355 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002356 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002357 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002358 {
2359 psa_cipher_abort( operation );
2360 return( mbedtls_to_psa_error( ret ) );
2361 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002362 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002363 memcpy( output, temp_output_buffer, *output_length );
2364 else
2365 {
2366 psa_cipher_abort( operation );
2367 return( PSA_ERROR_BUFFER_TOO_SMALL );
2368 }
mohammad1603503973b2018-03-12 15:59:30 +02002369
Moran Peker4c80d832018-04-22 20:15:31 +03002370 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002371}
2372
Gilles Peskinee553c652018-06-04 16:22:46 +02002373psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2374{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002375 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002376 {
2377 /* The object has (apparently) been initialized but it is not
2378 * in use. It's ok to call abort on such an object, and there's
2379 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002380 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002381 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002382
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002383 /* Sanity check (shouldn't happen: operation->alg should
2384 * always have been initialized to a valid value). */
2385 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2386 return( PSA_ERROR_BAD_STATE );
2387
mohammad1603503973b2018-03-12 15:59:30 +02002388 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002389
Moran Peker41deec42018-04-04 15:43:05 +03002390 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002391 operation->key_set = 0;
2392 operation->iv_set = 0;
2393 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002394 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002395 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002396
Moran Peker395db872018-05-31 14:07:14 +03002397 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002398}
2399
Gilles Peskinea0655c32018-04-30 17:06:50 +02002400
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002401
mohammad16038cc1cee2018-03-28 01:21:33 +03002402/****************************************************************/
2403/* Key Policy */
2404/****************************************************************/
2405
Gilles Peskine2d277862018-06-18 15:41:12 +02002406void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002407{
Gilles Peskine803ce742018-06-18 16:07:14 +02002408 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002409}
2410
Gilles Peskine2d277862018-06-18 15:41:12 +02002411void psa_key_policy_set_usage( psa_key_policy_t *policy,
2412 psa_key_usage_t usage,
2413 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002414{
mohammad16034eed7572018-03-28 05:14:59 -07002415 policy->usage = usage;
2416 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002417}
2418
Gilles Peskine2d277862018-06-18 15:41:12 +02002419psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002420{
mohammad16036df908f2018-04-02 08:34:15 -07002421 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002422}
2423
Gilles Peskine2d277862018-06-18 15:41:12 +02002424psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002425{
mohammad16036df908f2018-04-02 08:34:15 -07002426 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002427}
2428
Gilles Peskine2d277862018-06-18 15:41:12 +02002429psa_status_t psa_set_key_policy( psa_key_slot_t key,
2430 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002431{
2432 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002433
Gilles Peskine828ed142018-06-18 23:25:51 +02002434 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002435 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002436
mohammad16038cc1cee2018-03-28 01:21:33 +03002437 slot = &global_data.key_slots[key];
2438 if( slot->type != PSA_KEY_TYPE_NONE )
2439 return( PSA_ERROR_OCCUPIED_SLOT );
2440
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002441 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2442 PSA_KEY_USAGE_ENCRYPT |
2443 PSA_KEY_USAGE_DECRYPT |
2444 PSA_KEY_USAGE_SIGN |
2445 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002446 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002447
mohammad16036df908f2018-04-02 08:34:15 -07002448 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002449
2450 return( PSA_SUCCESS );
2451}
2452
Gilles Peskine2d277862018-06-18 15:41:12 +02002453psa_status_t psa_get_key_policy( psa_key_slot_t key,
2454 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002455{
2456 key_slot_t *slot;
2457
Gilles Peskine828ed142018-06-18 23:25:51 +02002458 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002459 return( PSA_ERROR_INVALID_ARGUMENT );
2460
2461 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002462
mohammad16036df908f2018-04-02 08:34:15 -07002463 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002464
2465 return( PSA_SUCCESS );
2466}
Gilles Peskine20035e32018-02-03 22:44:14 +01002467
Gilles Peskinea0655c32018-04-30 17:06:50 +02002468
2469
mohammad1603804cd712018-03-20 22:44:08 +02002470/****************************************************************/
2471/* Key Lifetime */
2472/****************************************************************/
2473
Gilles Peskine2d277862018-06-18 15:41:12 +02002474psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2475 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002476{
2477 key_slot_t *slot;
2478
Gilles Peskine828ed142018-06-18 23:25:51 +02002479 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002480 return( PSA_ERROR_INVALID_ARGUMENT );
2481
2482 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002483
mohammad1603804cd712018-03-20 22:44:08 +02002484 *lifetime = slot->lifetime;
2485
2486 return( PSA_SUCCESS );
2487}
2488
Gilles Peskine2d277862018-06-18 15:41:12 +02002489psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2490 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002491{
2492 key_slot_t *slot;
2493
Gilles Peskine828ed142018-06-18 23:25:51 +02002494 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002495 return( PSA_ERROR_INVALID_ARGUMENT );
2496
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002497 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2498 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002499 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2500 return( PSA_ERROR_INVALID_ARGUMENT );
2501
mohammad1603804cd712018-03-20 22:44:08 +02002502 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002503 if( slot->type != PSA_KEY_TYPE_NONE )
2504 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002505
Moran Pekerd7326592018-05-29 16:56:39 +03002506 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002507 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002508
mohammad1603060ad8a2018-03-20 14:28:38 -07002509 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002510
2511 return( PSA_SUCCESS );
2512}
2513
Gilles Peskine20035e32018-02-03 22:44:14 +01002514
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002515
mohammad16035955c982018-04-26 00:53:03 +03002516/****************************************************************/
2517/* AEAD */
2518/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002519
mohammad16035955c982018-04-26 00:53:03 +03002520psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2521 psa_algorithm_t alg,
2522 const uint8_t *nonce,
2523 size_t nonce_length,
2524 const uint8_t *additional_data,
2525 size_t additional_data_length,
2526 const uint8_t *plaintext,
2527 size_t plaintext_length,
2528 uint8_t *ciphertext,
2529 size_t ciphertext_size,
2530 size_t *ciphertext_length )
2531{
2532 int ret;
2533 psa_status_t status;
2534 key_slot_t *slot;
2535 psa_key_type_t key_type;
2536 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002537 uint8_t *tag;
2538 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002539 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002540 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002541
mohammad1603f08a5502018-06-03 15:05:47 +03002542 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002543
mohammad16035955c982018-04-26 00:53:03 +03002544 status = psa_get_key_information( key, &key_type, &key_bits );
2545 if( status != PSA_SUCCESS )
2546 return( status );
2547 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002548 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002549 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002550
mohammad16035ed06212018-06-06 13:09:34 +03002551 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2552 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002553 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002554 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002555
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002556 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002557 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002558
Gilles Peskine2d277862018-06-18 15:41:12 +02002559 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2560 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002561 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002562
mohammad16035955c982018-04-26 00:53:03 +03002563 if( alg == PSA_ALG_GCM )
2564 {
2565 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002566 tag_length = 16;
2567
mohammad160396910d82018-06-04 14:33:00 +03002568 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2569 return( PSA_ERROR_INVALID_ARGUMENT );
2570
mohammad160315223a82018-06-03 17:19:55 +03002571 //make sure we have place to hold the tag in the ciphertext buffer
2572 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002573 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002574
2575 //update the tag pointer to point to the end of the ciphertext_length
2576 tag = ciphertext + plaintext_length;
2577
mohammad16035955c982018-04-26 00:53:03 +03002578 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002579 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002580 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002581 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002582 if( ret != 0 )
2583 {
2584 mbedtls_gcm_free( &gcm );
2585 return( mbedtls_to_psa_error( ret ) );
2586 }
2587 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002588 plaintext_length, nonce,
2589 nonce_length, additional_data,
2590 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002591 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002592 mbedtls_gcm_free( &gcm );
2593 }
2594 else if( alg == PSA_ALG_CCM )
2595 {
2596 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002597 tag_length = 16;
2598
mohammad160396910d82018-06-04 14:33:00 +03002599 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2600 return( PSA_ERROR_INVALID_ARGUMENT );
2601
mohammad160347ddf3d2018-04-26 01:11:21 +03002602 if( nonce_length < 7 || nonce_length > 13 )
2603 return( PSA_ERROR_INVALID_ARGUMENT );
2604
mohammad160315223a82018-06-03 17:19:55 +03002605 //make sure we have place to hold the tag in the ciphertext buffer
2606 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002607 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002608
2609 //update the tag pointer to point to the end of the ciphertext_length
2610 tag = ciphertext + plaintext_length;
2611
mohammad16035955c982018-04-26 00:53:03 +03002612 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002613 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002614 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002615 if( ret != 0 )
2616 {
2617 mbedtls_ccm_free( &ccm );
2618 return( mbedtls_to_psa_error( ret ) );
2619 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002620 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002621 nonce, nonce_length,
2622 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002623 additional_data_length,
2624 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002625 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002626 mbedtls_ccm_free( &ccm );
2627 }
mohammad16035c8845f2018-05-09 05:40:09 -07002628 else
2629 {
mohammad1603554faad2018-06-03 15:07:38 +03002630 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002631 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002632
mohammad160315223a82018-06-03 17:19:55 +03002633 if( ret != 0 )
2634 {
2635 memset( ciphertext, 0, ciphertext_size );
2636 return( mbedtls_to_psa_error( ret ) );
2637 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002638
mohammad160315223a82018-06-03 17:19:55 +03002639 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002640 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002641}
2642
Gilles Peskineee652a32018-06-01 19:23:52 +02002643/* Locate the tag in a ciphertext buffer containing the encrypted data
2644 * followed by the tag. Return the length of the part preceding the tag in
2645 * *plaintext_length. This is the size of the plaintext in modes where
2646 * the encrypted data has the same size as the plaintext, such as
2647 * CCM and GCM. */
2648static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2649 const uint8_t *ciphertext,
2650 size_t ciphertext_length,
2651 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002652 const uint8_t **p_tag )
2653{
2654 size_t payload_length;
2655 if( tag_length > ciphertext_length )
2656 return( PSA_ERROR_INVALID_ARGUMENT );
2657 payload_length = ciphertext_length - tag_length;
2658 if( payload_length > plaintext_size )
2659 return( PSA_ERROR_BUFFER_TOO_SMALL );
2660 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002661 return( PSA_SUCCESS );
2662}
2663
mohammad16035955c982018-04-26 00:53:03 +03002664psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2665 psa_algorithm_t alg,
2666 const uint8_t *nonce,
2667 size_t nonce_length,
2668 const uint8_t *additional_data,
2669 size_t additional_data_length,
2670 const uint8_t *ciphertext,
2671 size_t ciphertext_length,
2672 uint8_t *plaintext,
2673 size_t plaintext_size,
2674 size_t *plaintext_length )
2675{
2676 int ret;
2677 psa_status_t status;
2678 key_slot_t *slot;
2679 psa_key_type_t key_type;
2680 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002681 const uint8_t *tag;
2682 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002683 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002684 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002685
Gilles Peskineee652a32018-06-01 19:23:52 +02002686 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002687
mohammad16035955c982018-04-26 00:53:03 +03002688 status = psa_get_key_information( key, &key_type, &key_bits );
2689 if( status != PSA_SUCCESS )
2690 return( status );
2691 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002692 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002693 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002694
mohammad16035ed06212018-06-06 13:09:34 +03002695 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2696 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002697 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002698 return( PSA_ERROR_NOT_SUPPORTED );
2699
mohammad1603f14394b2018-06-04 14:33:19 +03002700 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2701 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002702
Gilles Peskine2d277862018-06-18 15:41:12 +02002703 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2704 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002705 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002706
mohammad16035955c982018-04-26 00:53:03 +03002707 if( alg == PSA_ALG_GCM )
2708 {
2709 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002710
Gilles Peskineee652a32018-06-01 19:23:52 +02002711 tag_length = 16;
2712 status = psa_aead_unpadded_locate_tag( tag_length,
2713 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002714 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002715 if( status != PSA_SUCCESS )
2716 return( status );
2717
mohammad16035955c982018-04-26 00:53:03 +03002718 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002719 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002720 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002721 if( ret != 0 )
2722 {
2723 mbedtls_gcm_free( &gcm );
2724 return( mbedtls_to_psa_error( ret ) );
2725 }
mohammad16035955c982018-04-26 00:53:03 +03002726
Gilles Peskineee652a32018-06-01 19:23:52 +02002727 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002728 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002729 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002730 additional_data,
2731 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002732 tag, tag_length,
2733 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002734 mbedtls_gcm_free( &gcm );
2735 }
2736 else if( alg == PSA_ALG_CCM )
2737 {
2738 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002739
mohammad160347ddf3d2018-04-26 01:11:21 +03002740 if( nonce_length < 7 || nonce_length > 13 )
2741 return( PSA_ERROR_INVALID_ARGUMENT );
2742
mohammad16039375f842018-06-03 14:28:24 +03002743 tag_length = 16;
2744 status = psa_aead_unpadded_locate_tag( tag_length,
2745 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002746 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002747 if( status != PSA_SUCCESS )
2748 return( status );
2749
mohammad16035955c982018-04-26 00:53:03 +03002750 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002751 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002752 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002753 if( ret != 0 )
2754 {
2755 mbedtls_ccm_free( &ccm );
2756 return( mbedtls_to_psa_error( ret ) );
2757 }
mohammad160360a64d02018-06-03 17:20:42 +03002758 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002759 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002760 additional_data,
2761 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002762 ciphertext, plaintext,
2763 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002764 mbedtls_ccm_free( &ccm );
2765 }
mohammad160339574652018-06-01 04:39:53 -07002766 else
2767 {
mohammad1603554faad2018-06-03 15:07:38 +03002768 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002769 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002770
Gilles Peskineee652a32018-06-01 19:23:52 +02002771 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002772 memset( plaintext, 0, plaintext_size );
2773 else
2774 *plaintext_length = ciphertext_length - tag_length;
2775
Gilles Peskineee652a32018-06-01 19:23:52 +02002776 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002777}
2778
Gilles Peskinea0655c32018-04-30 17:06:50 +02002779
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002780
Gilles Peskine20035e32018-02-03 22:44:14 +01002781/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002782/* Key generation */
2783/****************************************************************/
2784
2785psa_status_t psa_generate_random( uint8_t *output,
2786 size_t output_size )
2787{
2788 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2789 output, output_size );
2790 return( mbedtls_to_psa_error( ret ) );
2791}
2792
2793psa_status_t psa_generate_key( psa_key_slot_t key,
2794 psa_key_type_t type,
2795 size_t bits,
2796 const void *parameters,
2797 size_t parameters_size )
2798{
Gilles Peskine12313cd2018-06-20 00:20:32 +02002799 key_slot_t *slot;
2800
2801 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
2802 return( PSA_ERROR_INVALID_ARGUMENT );
2803 slot = &global_data.key_slots[key];
2804 if( slot->type != PSA_KEY_TYPE_NONE )
2805 return( PSA_ERROR_OCCUPIED_SLOT );
2806 if( parameters == NULL && parameters_size != 0 )
2807 return( PSA_ERROR_INVALID_ARGUMENT );
2808
Gilles Peskine48c0ea12018-06-21 14:15:31 +02002809 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02002810 {
2811 psa_status_t status = prepare_raw_data_slot( type, bits,
2812 &slot->data.raw );
2813 if( status != PSA_SUCCESS )
2814 return( status );
2815 status = psa_generate_random( slot->data.raw.data,
2816 slot->data.raw.bytes );
2817 if( status != PSA_SUCCESS )
2818 {
2819 mbedtls_free( slot->data.raw.data );
2820 return( status );
2821 }
2822#if defined(MBEDTLS_DES_C)
2823 if( type == PSA_KEY_TYPE_DES )
2824 {
2825 mbedtls_des_key_set_parity( slot->data.raw.data );
2826 if( slot->data.raw.bytes >= 16 )
2827 mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
2828 if( slot->data.raw.bytes == 24 )
2829 mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
2830 }
2831#endif /* MBEDTLS_DES_C */
2832 }
2833 else
2834
2835#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
2836 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
2837 {
2838 mbedtls_rsa_context *rsa;
2839 int ret;
2840 int exponent = 65537;
2841 if( parameters != NULL )
2842 {
2843 const unsigned *p = parameters;
2844 if( parameters_size != sizeof( *p ) )
2845 return( PSA_ERROR_INVALID_ARGUMENT );
2846 if( *p > INT_MAX )
2847 return( PSA_ERROR_INVALID_ARGUMENT );
2848 exponent = *p;
2849 }
2850 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
2851 if( rsa == NULL )
2852 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2853 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
2854 ret = mbedtls_rsa_gen_key( rsa,
2855 mbedtls_ctr_drbg_random,
2856 &global_data.ctr_drbg,
2857 bits,
2858 exponent );
2859 if( ret != 0 )
2860 {
2861 mbedtls_rsa_free( rsa );
2862 mbedtls_free( rsa );
2863 return( mbedtls_to_psa_error( ret ) );
2864 }
2865 slot->data.rsa = rsa;
2866 }
2867 else
2868#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
2869
2870#if defined(MBEDTLS_ECP_C)
2871 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
2872 {
2873 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
2874 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
2875 const mbedtls_ecp_curve_info *curve_info =
2876 mbedtls_ecp_curve_info_from_grp_id( grp_id );
2877 mbedtls_ecp_keypair *ecp;
2878 int ret;
2879 if( parameters != NULL )
2880 return( PSA_ERROR_NOT_SUPPORTED );
2881 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
2882 return( PSA_ERROR_NOT_SUPPORTED );
2883 if( curve_info->bit_size != bits )
2884 return( PSA_ERROR_INVALID_ARGUMENT );
2885 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
2886 if( ecp == NULL )
2887 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2888 mbedtls_ecp_keypair_init( ecp );
2889 ret = mbedtls_ecp_gen_key( grp_id, ecp,
2890 mbedtls_ctr_drbg_random,
2891 &global_data.ctr_drbg );
2892 if( ret != 0 )
2893 {
2894 mbedtls_ecp_keypair_free( ecp );
2895 mbedtls_free( ecp );
2896 return( mbedtls_to_psa_error( ret ) );
2897 }
2898 slot->data.ecp = ecp;
2899 }
2900 else
2901#endif /* MBEDTLS_ECP_C */
2902
2903 return( PSA_ERROR_NOT_SUPPORTED );
2904
2905 slot->type = type;
2906 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02002907}
2908
2909
2910/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002911/* Module setup */
2912/****************************************************************/
2913
Gilles Peskinee59236f2018-01-27 23:32:46 +01002914void mbedtls_psa_crypto_free( void )
2915{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002916 size_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02002917 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002918 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002919 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2920 mbedtls_entropy_free( &global_data.entropy );
2921 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2922}
2923
2924psa_status_t psa_crypto_init( void )
2925{
2926 int ret;
2927 const unsigned char drbg_seed[] = "PSA";
2928
2929 if( global_data.initialized != 0 )
2930 return( PSA_SUCCESS );
2931
2932 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2933 mbedtls_entropy_init( &global_data.entropy );
2934 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2935
2936 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2937 mbedtls_entropy_func,
2938 &global_data.entropy,
2939 drbg_seed, sizeof( drbg_seed ) - 1 );
2940 if( ret != 0 )
2941 goto exit;
2942
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002943 global_data.initialized = 1;
2944
Gilles Peskinee59236f2018-01-27 23:32:46 +01002945exit:
2946 if( ret != 0 )
2947 mbedtls_psa_crypto_free( );
2948 return( mbedtls_to_psa_error( ret ) );
2949}
2950
2951#endif /* MBEDTLS_PSA_CRYPTO_C */