blob: 9454f478c6535bc9dd6925c426f250f4f9051c19 [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 Peskine8b18a4f2018-06-08 16:34:46 +02001615/* Decode the hash algorithm from alg and store the mbedtls encoding in
1616 * md_alg. Verify that the hash length is consistent. */
1617static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1618 size_t hash_length,
1619 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001620{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02001621 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001622 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1623 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1624 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001625 {
1626#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001627 if( hash_length > UINT_MAX )
1628 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001629#endif
1630 }
1631 else
1632 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001633 if( mbedtls_md_get_size( md_info ) != hash_length )
1634 return( PSA_ERROR_INVALID_ARGUMENT );
1635 if( md_info == NULL )
1636 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001637 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001638 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001639}
1640
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001641#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001642/* `ecp` cannot be const because `ecp->grp` needs to be non-const
1643 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
1644 * (even though these functions don't modify it). */
1645static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
1646 psa_algorithm_t alg,
1647 const uint8_t *hash,
1648 size_t hash_length,
1649 uint8_t *signature,
1650 size_t signature_size,
1651 size_t *signature_length )
1652{
1653 int ret;
1654 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001655 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001656 mbedtls_mpi_init( &r );
1657 mbedtls_mpi_init( &s );
1658
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001659 *signature_length = 0;
1660 if( signature_size < 2 * curve_bytes )
1661 {
1662 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
1663 goto cleanup;
1664 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001665
1666 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
1667 {
1668 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
1669 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1670 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
1671 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
1672 hash, hash_length,
1673 md_alg ) );
1674 }
1675 else
1676 {
1677 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
1678 hash, hash_length,
1679 mbedtls_ctr_drbg_random,
1680 &global_data.ctr_drbg ) );
1681 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001682
1683 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
1684 signature,
1685 curve_bytes ) );
1686 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
1687 signature + curve_bytes,
1688 curve_bytes ) );
1689
1690cleanup:
1691 mbedtls_mpi_free( &r );
1692 mbedtls_mpi_free( &s );
1693 if( ret == 0 )
1694 *signature_length = 2 * curve_bytes;
1695 memset( signature + *signature_length, 0,
1696 signature_size - *signature_length );
1697 return( mbedtls_to_psa_error( ret ) );
1698}
1699
1700static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
1701 const uint8_t *hash,
1702 size_t hash_length,
1703 const uint8_t *signature,
1704 size_t signature_length )
1705{
1706 int ret;
1707 mbedtls_mpi r, s;
1708 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
1709 mbedtls_mpi_init( &r );
1710 mbedtls_mpi_init( &s );
1711
1712 if( signature_length != 2 * curve_bytes )
1713 return( PSA_ERROR_INVALID_SIGNATURE );
1714
1715 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
1716 signature,
1717 curve_bytes ) );
1718 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
1719 signature + curve_bytes,
1720 curve_bytes ) );
1721
1722 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
1723 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001724
1725cleanup:
1726 mbedtls_mpi_free( &r );
1727 mbedtls_mpi_free( &s );
1728 return( mbedtls_to_psa_error( ret ) );
1729}
1730#endif /* MBEDTLS_ECDSA_C */
1731
Gilles Peskine61b91d42018-06-08 16:09:36 +02001732psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1733 psa_algorithm_t alg,
1734 const uint8_t *hash,
1735 size_t hash_length,
1736 const uint8_t *salt,
1737 size_t salt_length,
1738 uint8_t *signature,
1739 size_t signature_size,
1740 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001741{
1742 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001743 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001744 *signature_length = 0;
1745 (void) salt;
1746 (void) salt_length;
1747
Gilles Peskine828ed142018-06-18 23:25:51 +02001748 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine20035e32018-02-03 22:44:14 +01001749 return( PSA_ERROR_EMPTY_SLOT );
1750 slot = &global_data.key_slots[key];
1751 if( slot->type == PSA_KEY_TYPE_NONE )
1752 return( PSA_ERROR_EMPTY_SLOT );
1753 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1754 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001755 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001756 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001757
Gilles Peskine20035e32018-02-03 22:44:14 +01001758#if defined(MBEDTLS_RSA_C)
1759 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1760 {
1761 mbedtls_rsa_context *rsa = slot->data.rsa;
1762 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001763 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001764 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001765 if( status != PSA_SUCCESS )
1766 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001767
Gilles Peskine20035e32018-02-03 22:44:14 +01001768 if( signature_size < rsa->len )
1769 return( PSA_ERROR_BUFFER_TOO_SMALL );
1770#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001771 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001772 {
1773 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1774 MBEDTLS_MD_NONE );
1775 ret = mbedtls_rsa_pkcs1_sign( rsa,
1776 mbedtls_ctr_drbg_random,
1777 &global_data.ctr_drbg,
1778 MBEDTLS_RSA_PRIVATE,
1779 md_alg, hash_length, hash,
1780 signature );
1781 }
1782 else
1783#endif /* MBEDTLS_PKCS1_V15 */
1784#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02001785 if( PSA_ALG_IS_RSA_PSS( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001786 {
1787 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1788 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1789 mbedtls_ctr_drbg_random,
1790 &global_data.ctr_drbg,
1791 MBEDTLS_RSA_PRIVATE,
1792 md_alg, hash_length, hash,
1793 signature );
1794 }
1795 else
1796#endif /* MBEDTLS_PKCS1_V21 */
1797 {
1798 return( PSA_ERROR_INVALID_ARGUMENT );
1799 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001800 if( ret == 0 )
1801 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001802 return( mbedtls_to_psa_error( ret ) );
1803 }
1804 else
1805#endif /* defined(MBEDTLS_RSA_C) */
1806#if defined(MBEDTLS_ECP_C)
1807 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1808 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001809#if defined(MBEDTLS_ECDSA_C)
1810 if( PSA_ALG_IS_ECDSA( alg ) )
1811 status = psa_ecdsa_sign( slot->data.ecp,
1812 alg,
1813 hash, hash_length,
1814 signature, signature_size,
1815 signature_length );
1816 else
1817#endif /* defined(MBEDTLS_ECDSA_C) */
1818 {
1819 return( PSA_ERROR_INVALID_ARGUMENT );
1820 }
1821 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03001822 }
1823 else
1824#endif /* defined(MBEDTLS_ECP_C) */
1825 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001826 return( PSA_ERROR_NOT_SUPPORTED );
1827 }
itayzafrir5c753392018-05-08 11:18:38 +03001828}
1829
1830psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1831 psa_algorithm_t alg,
1832 const uint8_t *hash,
1833 size_t hash_length,
1834 const uint8_t *salt,
1835 size_t salt_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02001836 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02001837 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03001838{
1839 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001840 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001841 (void) salt;
1842 (void) salt_length;
1843
Gilles Peskine828ed142018-06-18 23:25:51 +02001844 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001845 return( PSA_ERROR_INVALID_ARGUMENT );
1846 slot = &global_data.key_slots[key];
1847 if( slot->type == PSA_KEY_TYPE_NONE )
1848 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001849 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001850 return( PSA_ERROR_NOT_PERMITTED );
1851
Gilles Peskine61b91d42018-06-08 16:09:36 +02001852#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001853 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1854 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001855 {
1856 mbedtls_rsa_context *rsa = slot->data.rsa;
1857 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001858 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001859 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001860 if( status != PSA_SUCCESS )
1861 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001862
Gilles Peskine526fab02018-06-27 18:19:40 +02001863 if( signature_length < rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001864 return( PSA_ERROR_BUFFER_TOO_SMALL );
1865#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001866 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001867 {
1868 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1869 MBEDTLS_MD_NONE );
1870
1871 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001872 mbedtls_ctr_drbg_random,
1873 &global_data.ctr_drbg,
1874 MBEDTLS_RSA_PUBLIC,
1875 md_alg,
1876 hash_length,
1877 hash,
1878 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001879
1880 }
1881 else
1882#endif /* MBEDTLS_PKCS1_V15 */
1883#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02001884 if( PSA_ALG_IS_RSA_PSS( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001885 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001886 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1887 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1888 mbedtls_ctr_drbg_random,
1889 &global_data.ctr_drbg,
1890 MBEDTLS_RSA_PUBLIC,
1891 md_alg, hash_length, hash,
1892 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001893 }
1894 else
1895#endif /* MBEDTLS_PKCS1_V21 */
1896 {
1897 return( PSA_ERROR_INVALID_ARGUMENT );
1898 }
1899 return( mbedtls_to_psa_error( ret ) );
1900 }
1901 else
1902#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001903#if defined(MBEDTLS_ECP_C)
1904 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1905 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001906#if defined(MBEDTLS_ECDSA_C)
1907 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001908 return( psa_ecdsa_verify( slot->data.ecp,
1909 hash, hash_length,
1910 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001911 else
1912#endif /* defined(MBEDTLS_ECDSA_C) */
1913 {
1914 return( PSA_ERROR_INVALID_ARGUMENT );
1915 }
itayzafrir5c753392018-05-08 11:18:38 +03001916 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001917 else
1918#endif /* defined(MBEDTLS_ECP_C) */
1919 {
1920 return( PSA_ERROR_NOT_SUPPORTED );
1921 }
1922}
1923
Gilles Peskine61b91d42018-06-08 16:09:36 +02001924psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1925 psa_algorithm_t alg,
1926 const uint8_t *input,
1927 size_t input_length,
1928 const uint8_t *salt,
1929 size_t salt_length,
1930 uint8_t *output,
1931 size_t output_size,
1932 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001933{
1934 key_slot_t *slot;
1935 (void) salt;
1936 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001937 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001938
Gilles Peskine828ed142018-06-18 23:25:51 +02001939 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001940 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001941 slot = &global_data.key_slots[key];
1942 if( slot->type == PSA_KEY_TYPE_NONE )
1943 return( PSA_ERROR_EMPTY_SLOT );
1944 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1945 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001946 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1947 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001948
1949#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001950 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1951 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001952 {
1953 mbedtls_rsa_context *rsa = slot->data.rsa;
1954 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001955 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001956 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001957#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001958 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001959 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001960 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1961 mbedtls_ctr_drbg_random,
1962 &global_data.ctr_drbg,
1963 MBEDTLS_RSA_PUBLIC,
1964 input_length,
1965 input,
1966 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001967 }
1968 else
1969#endif /* MBEDTLS_PKCS1_V15 */
1970#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02001971 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001972 {
1973 return( PSA_ERROR_NOT_SUPPORTED );
1974 }
1975 else
1976#endif /* MBEDTLS_PKCS1_V21 */
1977 {
1978 return( PSA_ERROR_INVALID_ARGUMENT );
1979 }
1980 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001981 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001982 return( mbedtls_to_psa_error( ret ) );
1983 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001984 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001985#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001986 {
1987 return( PSA_ERROR_NOT_SUPPORTED );
1988 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001989}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001990
Gilles Peskine61b91d42018-06-08 16:09:36 +02001991psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1992 psa_algorithm_t alg,
1993 const uint8_t *input,
1994 size_t input_length,
1995 const uint8_t *salt,
1996 size_t salt_length,
1997 uint8_t *output,
1998 size_t output_size,
1999 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002000{
2001 key_slot_t *slot;
2002 (void) salt;
2003 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002004 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002005
Gilles Peskine828ed142018-06-18 23:25:51 +02002006 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002007 return( PSA_ERROR_EMPTY_SLOT );
2008 slot = &global_data.key_slots[key];
2009 if( slot->type == PSA_KEY_TYPE_NONE )
2010 return( PSA_ERROR_EMPTY_SLOT );
2011 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2012 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002013 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2014 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002015
2016#if defined(MBEDTLS_RSA_C)
2017 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2018 {
2019 mbedtls_rsa_context *rsa = slot->data.rsa;
2020 int ret;
2021
Gilles Peskinec4def2f2018-06-08 17:53:48 +02002022 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002023 return( PSA_ERROR_INVALID_ARGUMENT );
2024
2025#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002026 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002027 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002028 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2029 mbedtls_ctr_drbg_random,
2030 &global_data.ctr_drbg,
2031 MBEDTLS_RSA_PRIVATE,
2032 output_length,
2033 input,
2034 output,
2035 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002036 }
2037 else
2038#endif /* MBEDTLS_PKCS1_V15 */
2039#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002040 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002041 {
2042 return( PSA_ERROR_NOT_SUPPORTED );
2043 }
2044 else
2045#endif /* MBEDTLS_PKCS1_V21 */
2046 {
2047 return( PSA_ERROR_INVALID_ARGUMENT );
2048 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002049
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002050 return( mbedtls_to_psa_error( ret ) );
2051 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002052 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002053#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002054 {
2055 return( PSA_ERROR_NOT_SUPPORTED );
2056 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002057}
Gilles Peskine20035e32018-02-03 22:44:14 +01002058
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002059
2060
mohammad1603503973b2018-03-12 15:59:30 +02002061/****************************************************************/
2062/* Symmetric cryptography */
2063/****************************************************************/
2064
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002065/* Initialize the cipher operation structure. Once this function has been
2066 * called, psa_cipher_abort can run and will do the right thing. */
2067static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2068 psa_algorithm_t alg )
2069{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002070 if( ! PSA_ALG_IS_CIPHER( alg ) )
2071 {
2072 memset( operation, 0, sizeof( *operation ) );
2073 return( PSA_ERROR_INVALID_ARGUMENT );
2074 }
2075
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002076 operation->alg = alg;
2077 operation->key_set = 0;
2078 operation->iv_set = 0;
2079 operation->iv_required = 1;
2080 operation->iv_size = 0;
2081 operation->block_size = 0;
2082 mbedtls_cipher_init( &operation->ctx.cipher );
2083 return( PSA_SUCCESS );
2084}
2085
Gilles Peskinee553c652018-06-04 16:22:46 +02002086static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2087 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002088 psa_algorithm_t alg,
2089 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002090{
2091 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2092 psa_status_t status;
2093 key_slot_t *slot;
2094 psa_key_type_t key_type;
2095 size_t key_bits;
2096 const mbedtls_cipher_info_t *cipher_info = NULL;
2097
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002098 status = psa_cipher_init( operation, alg );
2099 if( status != PSA_SUCCESS )
2100 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002101
2102 status = psa_get_key_information( key, &key_type, &key_bits );
2103 if( status != PSA_SUCCESS )
2104 return( status );
2105 slot = &global_data.key_slots[key];
2106
Gilles Peskinebb1072f2018-06-08 18:46:05 +02002107 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002108 if( cipher_info == NULL )
2109 return( PSA_ERROR_NOT_SUPPORTED );
2110
mohammad1603503973b2018-03-12 15:59:30 +02002111 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002112 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002113 {
2114 psa_cipher_abort( operation );
2115 return( mbedtls_to_psa_error( ret ) );
2116 }
2117
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002118#if defined(MBEDTLS_DES_C)
2119 if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
2120 {
2121 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2122 unsigned char keys[24];
2123 memcpy( keys, slot->data.raw.data, 16 );
2124 memcpy( keys + 16, slot->data.raw.data, 8 );
2125 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2126 keys,
2127 192, cipher_operation );
2128 }
2129 else
2130#endif
2131 {
2132 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2133 slot->data.raw.data,
2134 key_bits, cipher_operation );
2135 }
Moran Peker41deec42018-04-04 15:43:05 +03002136 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002137 {
2138 psa_cipher_abort( operation );
2139 return( mbedtls_to_psa_error( ret ) );
2140 }
2141
mohammad16038481e742018-03-18 13:57:31 +02002142#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03002143 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02002144 {
Gilles Peskine53514202018-06-06 15:11:46 +02002145 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
2146 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02002147
Moran Pekera28258c2018-05-29 16:25:04 +03002148 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02002149 {
2150 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
2151 mode = MBEDTLS_PADDING_PKCS7;
2152 break;
2153 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
2154 mode = MBEDTLS_PADDING_NONE;
2155 break;
2156 default:
Moran Pekerae382792018-05-31 14:06:17 +03002157 psa_cipher_abort( operation );
2158 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02002159 }
2160 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03002161 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03002162 {
2163 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02002164 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03002165 }
mohammad16038481e742018-03-18 13:57:31 +02002166 }
2167#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2168
mohammad1603503973b2018-03-12 15:59:30 +02002169 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02002170 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
2171 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
2172 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002173 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02002174 {
mohammad160389e0f462018-04-12 08:48:45 +03002175 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02002176 }
mohammad1603503973b2018-03-12 15:59:30 +02002177
Moran Peker395db872018-05-31 14:07:14 +03002178 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002179}
2180
Gilles Peskinee553c652018-06-04 16:22:46 +02002181psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
2182 psa_key_slot_t key,
2183 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002184{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002185 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002186}
2187
Gilles Peskinee553c652018-06-04 16:22:46 +02002188psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
2189 psa_key_slot_t key,
2190 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002191{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002192 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002193}
2194
Gilles Peskinee553c652018-06-04 16:22:46 +02002195psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
2196 unsigned char *iv,
2197 size_t iv_size,
2198 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002199{
Moran Peker41deec42018-04-04 15:43:05 +03002200 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002201 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002202 return( PSA_ERROR_BAD_STATE );
2203 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002204 {
Moran Peker41deec42018-04-04 15:43:05 +03002205 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2206 goto exit;
2207 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002208 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2209 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002210 if( ret != 0 )
2211 {
2212 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002213 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002214 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002215
mohammad16038481e742018-03-18 13:57:31 +02002216 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03002217 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002218
Moran Peker395db872018-05-31 14:07:14 +03002219exit:
2220 if( ret != PSA_SUCCESS )
2221 psa_cipher_abort( operation );
2222 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002223}
2224
Gilles Peskinee553c652018-06-04 16:22:46 +02002225psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
2226 const unsigned char *iv,
2227 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002228{
Moran Peker41deec42018-04-04 15:43:05 +03002229 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002230 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002231 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002232 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002233 {
Moran Pekerae382792018-05-31 14:06:17 +03002234 psa_cipher_abort( operation );
2235 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002236 }
mohammad1603503973b2018-03-12 15:59:30 +02002237 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002238 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002239 {
2240 psa_cipher_abort( operation );
2241 return( mbedtls_to_psa_error( ret ) );
2242 }
2243
2244 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002245
Moran Peker395db872018-05-31 14:07:14 +03002246 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002247}
2248
Gilles Peskinee553c652018-06-04 16:22:46 +02002249psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2250 const uint8_t *input,
2251 size_t input_length,
2252 unsigned char *output,
2253 size_t output_size,
2254 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002255{
2256 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002257 size_t expected_output_size;
2258 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2259 {
2260 /* Take the unprocessed partial block left over from previous
2261 * update calls, if any, plus the input to this call. Remove
2262 * the last partial block, if any. You get the data that will be
2263 * output in this call. */
2264 expected_output_size =
2265 ( operation->ctx.cipher.unprocessed_len + input_length )
2266 / operation->block_size * operation->block_size;
2267 }
2268 else
2269 {
2270 expected_output_size = input_length;
2271 }
2272 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002273 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002274
mohammad1603503973b2018-03-12 15:59:30 +02002275 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002276 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002277 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002278 {
2279 psa_cipher_abort( operation );
2280 return( mbedtls_to_psa_error( ret ) );
2281 }
2282
Moran Peker395db872018-05-31 14:07:14 +03002283 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002284}
2285
Gilles Peskinee553c652018-06-04 16:22:46 +02002286psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2287 uint8_t *output,
2288 size_t output_size,
2289 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002290{
2291 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002292 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002293
mohammad1603503973b2018-03-12 15:59:30 +02002294 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002295 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002296 psa_cipher_abort( operation );
2297 return( PSA_ERROR_BAD_STATE );
2298 }
2299 if( operation->iv_required && ! operation->iv_set )
2300 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002301 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002302 return( PSA_ERROR_BAD_STATE );
2303 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002304 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2305 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002306 {
Gilles Peskine53514202018-06-06 15:11:46 +02002307 psa_algorithm_t padding_mode =
2308 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002309 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002310 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002311 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002312 return( PSA_ERROR_TAMPERING_DETECTED );
2313 }
Gilles Peskine53514202018-06-06 15:11:46 +02002314 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002315 {
2316 if( operation->ctx.cipher.unprocessed_len != 0 )
2317 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002318 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002319 return( PSA_ERROR_INVALID_ARGUMENT );
2320 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002321 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002322 }
2323
2324 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002325 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002326 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002327 {
2328 psa_cipher_abort( operation );
2329 return( mbedtls_to_psa_error( ret ) );
2330 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002331 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002332 memcpy( output, temp_output_buffer, *output_length );
2333 else
2334 {
2335 psa_cipher_abort( operation );
2336 return( PSA_ERROR_BUFFER_TOO_SMALL );
2337 }
mohammad1603503973b2018-03-12 15:59:30 +02002338
Moran Peker4c80d832018-04-22 20:15:31 +03002339 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002340}
2341
Gilles Peskinee553c652018-06-04 16:22:46 +02002342psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2343{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002344 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002345 {
2346 /* The object has (apparently) been initialized but it is not
2347 * in use. It's ok to call abort on such an object, and there's
2348 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002349 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002350 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002351
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002352 /* Sanity check (shouldn't happen: operation->alg should
2353 * always have been initialized to a valid value). */
2354 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2355 return( PSA_ERROR_BAD_STATE );
2356
mohammad1603503973b2018-03-12 15:59:30 +02002357 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002358
Moran Peker41deec42018-04-04 15:43:05 +03002359 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002360 operation->key_set = 0;
2361 operation->iv_set = 0;
2362 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002363 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002364 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002365
Moran Peker395db872018-05-31 14:07:14 +03002366 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002367}
2368
Gilles Peskinea0655c32018-04-30 17:06:50 +02002369
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002370
mohammad16038cc1cee2018-03-28 01:21:33 +03002371/****************************************************************/
2372/* Key Policy */
2373/****************************************************************/
2374
Gilles Peskine2d277862018-06-18 15:41:12 +02002375void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002376{
Gilles Peskine803ce742018-06-18 16:07:14 +02002377 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002378}
2379
Gilles Peskine2d277862018-06-18 15:41:12 +02002380void psa_key_policy_set_usage( psa_key_policy_t *policy,
2381 psa_key_usage_t usage,
2382 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002383{
mohammad16034eed7572018-03-28 05:14:59 -07002384 policy->usage = usage;
2385 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002386}
2387
Gilles Peskine2d277862018-06-18 15:41:12 +02002388psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002389{
mohammad16036df908f2018-04-02 08:34:15 -07002390 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002391}
2392
Gilles Peskine2d277862018-06-18 15:41:12 +02002393psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002394{
mohammad16036df908f2018-04-02 08:34:15 -07002395 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002396}
2397
Gilles Peskine2d277862018-06-18 15:41:12 +02002398psa_status_t psa_set_key_policy( psa_key_slot_t key,
2399 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002400{
2401 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002402
Gilles Peskine828ed142018-06-18 23:25:51 +02002403 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002404 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002405
mohammad16038cc1cee2018-03-28 01:21:33 +03002406 slot = &global_data.key_slots[key];
2407 if( slot->type != PSA_KEY_TYPE_NONE )
2408 return( PSA_ERROR_OCCUPIED_SLOT );
2409
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002410 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2411 PSA_KEY_USAGE_ENCRYPT |
2412 PSA_KEY_USAGE_DECRYPT |
2413 PSA_KEY_USAGE_SIGN |
2414 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002415 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002416
mohammad16036df908f2018-04-02 08:34:15 -07002417 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002418
2419 return( PSA_SUCCESS );
2420}
2421
Gilles Peskine2d277862018-06-18 15:41:12 +02002422psa_status_t psa_get_key_policy( psa_key_slot_t key,
2423 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002424{
2425 key_slot_t *slot;
2426
Gilles Peskine828ed142018-06-18 23:25:51 +02002427 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002428 return( PSA_ERROR_INVALID_ARGUMENT );
2429
2430 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002431
mohammad16036df908f2018-04-02 08:34:15 -07002432 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002433
2434 return( PSA_SUCCESS );
2435}
Gilles Peskine20035e32018-02-03 22:44:14 +01002436
Gilles Peskinea0655c32018-04-30 17:06:50 +02002437
2438
mohammad1603804cd712018-03-20 22:44:08 +02002439/****************************************************************/
2440/* Key Lifetime */
2441/****************************************************************/
2442
Gilles Peskine2d277862018-06-18 15:41:12 +02002443psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2444 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002445{
2446 key_slot_t *slot;
2447
Gilles Peskine828ed142018-06-18 23:25:51 +02002448 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002449 return( PSA_ERROR_INVALID_ARGUMENT );
2450
2451 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002452
mohammad1603804cd712018-03-20 22:44:08 +02002453 *lifetime = slot->lifetime;
2454
2455 return( PSA_SUCCESS );
2456}
2457
Gilles Peskine2d277862018-06-18 15:41:12 +02002458psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2459 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002460{
2461 key_slot_t *slot;
2462
Gilles Peskine828ed142018-06-18 23:25:51 +02002463 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002464 return( PSA_ERROR_INVALID_ARGUMENT );
2465
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002466 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2467 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002468 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2469 return( PSA_ERROR_INVALID_ARGUMENT );
2470
mohammad1603804cd712018-03-20 22:44:08 +02002471 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002472 if( slot->type != PSA_KEY_TYPE_NONE )
2473 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002474
Moran Pekerd7326592018-05-29 16:56:39 +03002475 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002476 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002477
mohammad1603060ad8a2018-03-20 14:28:38 -07002478 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002479
2480 return( PSA_SUCCESS );
2481}
2482
Gilles Peskine20035e32018-02-03 22:44:14 +01002483
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002484
mohammad16035955c982018-04-26 00:53:03 +03002485/****************************************************************/
2486/* AEAD */
2487/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002488
mohammad16035955c982018-04-26 00:53:03 +03002489psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2490 psa_algorithm_t alg,
2491 const uint8_t *nonce,
2492 size_t nonce_length,
2493 const uint8_t *additional_data,
2494 size_t additional_data_length,
2495 const uint8_t *plaintext,
2496 size_t plaintext_length,
2497 uint8_t *ciphertext,
2498 size_t ciphertext_size,
2499 size_t *ciphertext_length )
2500{
2501 int ret;
2502 psa_status_t status;
2503 key_slot_t *slot;
2504 psa_key_type_t key_type;
2505 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002506 uint8_t *tag;
2507 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002508 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002509 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002510
mohammad1603f08a5502018-06-03 15:05:47 +03002511 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002512
mohammad16035955c982018-04-26 00:53:03 +03002513 status = psa_get_key_information( key, &key_type, &key_bits );
2514 if( status != PSA_SUCCESS )
2515 return( status );
2516 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002517 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002518 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002519
mohammad16035ed06212018-06-06 13:09:34 +03002520 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2521 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002522 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002523 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002524
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002525 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002526 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002527
Gilles Peskine2d277862018-06-18 15:41:12 +02002528 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2529 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002530 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002531
mohammad16035955c982018-04-26 00:53:03 +03002532 if( alg == PSA_ALG_GCM )
2533 {
2534 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002535 tag_length = 16;
2536
mohammad160396910d82018-06-04 14:33:00 +03002537 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2538 return( PSA_ERROR_INVALID_ARGUMENT );
2539
mohammad160315223a82018-06-03 17:19:55 +03002540 //make sure we have place to hold the tag in the ciphertext buffer
2541 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002542 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002543
2544 //update the tag pointer to point to the end of the ciphertext_length
2545 tag = ciphertext + plaintext_length;
2546
mohammad16035955c982018-04-26 00:53:03 +03002547 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002548 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002549 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002550 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002551 if( ret != 0 )
2552 {
2553 mbedtls_gcm_free( &gcm );
2554 return( mbedtls_to_psa_error( ret ) );
2555 }
2556 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002557 plaintext_length, nonce,
2558 nonce_length, additional_data,
2559 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002560 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002561 mbedtls_gcm_free( &gcm );
2562 }
2563 else if( alg == PSA_ALG_CCM )
2564 {
2565 mbedtls_ccm_context ccm;
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
mohammad160347ddf3d2018-04-26 01:11:21 +03002571 if( nonce_length < 7 || nonce_length > 13 )
2572 return( PSA_ERROR_INVALID_ARGUMENT );
2573
mohammad160315223a82018-06-03 17:19:55 +03002574 //make sure we have place to hold the tag in the ciphertext buffer
2575 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002576 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002577
2578 //update the tag pointer to point to the end of the ciphertext_length
2579 tag = ciphertext + plaintext_length;
2580
mohammad16035955c982018-04-26 00:53:03 +03002581 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002582 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002583 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002584 if( ret != 0 )
2585 {
2586 mbedtls_ccm_free( &ccm );
2587 return( mbedtls_to_psa_error( ret ) );
2588 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002589 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002590 nonce, nonce_length,
2591 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002592 additional_data_length,
2593 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002594 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002595 mbedtls_ccm_free( &ccm );
2596 }
mohammad16035c8845f2018-05-09 05:40:09 -07002597 else
2598 {
mohammad1603554faad2018-06-03 15:07:38 +03002599 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002600 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002601
mohammad160315223a82018-06-03 17:19:55 +03002602 if( ret != 0 )
2603 {
2604 memset( ciphertext, 0, ciphertext_size );
2605 return( mbedtls_to_psa_error( ret ) );
2606 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002607
mohammad160315223a82018-06-03 17:19:55 +03002608 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002609 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002610}
2611
Gilles Peskineee652a32018-06-01 19:23:52 +02002612/* Locate the tag in a ciphertext buffer containing the encrypted data
2613 * followed by the tag. Return the length of the part preceding the tag in
2614 * *plaintext_length. This is the size of the plaintext in modes where
2615 * the encrypted data has the same size as the plaintext, such as
2616 * CCM and GCM. */
2617static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2618 const uint8_t *ciphertext,
2619 size_t ciphertext_length,
2620 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002621 const uint8_t **p_tag )
2622{
2623 size_t payload_length;
2624 if( tag_length > ciphertext_length )
2625 return( PSA_ERROR_INVALID_ARGUMENT );
2626 payload_length = ciphertext_length - tag_length;
2627 if( payload_length > plaintext_size )
2628 return( PSA_ERROR_BUFFER_TOO_SMALL );
2629 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002630 return( PSA_SUCCESS );
2631}
2632
mohammad16035955c982018-04-26 00:53:03 +03002633psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2634 psa_algorithm_t alg,
2635 const uint8_t *nonce,
2636 size_t nonce_length,
2637 const uint8_t *additional_data,
2638 size_t additional_data_length,
2639 const uint8_t *ciphertext,
2640 size_t ciphertext_length,
2641 uint8_t *plaintext,
2642 size_t plaintext_size,
2643 size_t *plaintext_length )
2644{
2645 int ret;
2646 psa_status_t status;
2647 key_slot_t *slot;
2648 psa_key_type_t key_type;
2649 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002650 const uint8_t *tag;
2651 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002652 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002653 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002654
Gilles Peskineee652a32018-06-01 19:23:52 +02002655 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002656
mohammad16035955c982018-04-26 00:53:03 +03002657 status = psa_get_key_information( key, &key_type, &key_bits );
2658 if( status != PSA_SUCCESS )
2659 return( status );
2660 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002661 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002662 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002663
mohammad16035ed06212018-06-06 13:09:34 +03002664 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2665 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002666 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002667 return( PSA_ERROR_NOT_SUPPORTED );
2668
mohammad1603f14394b2018-06-04 14:33:19 +03002669 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2670 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002671
Gilles Peskine2d277862018-06-18 15:41:12 +02002672 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2673 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002674 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002675
mohammad16035955c982018-04-26 00:53:03 +03002676 if( alg == PSA_ALG_GCM )
2677 {
2678 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002679
Gilles Peskineee652a32018-06-01 19:23:52 +02002680 tag_length = 16;
2681 status = psa_aead_unpadded_locate_tag( tag_length,
2682 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002683 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002684 if( status != PSA_SUCCESS )
2685 return( status );
2686
mohammad16035955c982018-04-26 00:53:03 +03002687 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002688 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002689 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002690 if( ret != 0 )
2691 {
2692 mbedtls_gcm_free( &gcm );
2693 return( mbedtls_to_psa_error( ret ) );
2694 }
mohammad16035955c982018-04-26 00:53:03 +03002695
Gilles Peskineee652a32018-06-01 19:23:52 +02002696 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002697 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002698 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002699 additional_data,
2700 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002701 tag, tag_length,
2702 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002703 mbedtls_gcm_free( &gcm );
2704 }
2705 else if( alg == PSA_ALG_CCM )
2706 {
2707 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002708
mohammad160347ddf3d2018-04-26 01:11:21 +03002709 if( nonce_length < 7 || nonce_length > 13 )
2710 return( PSA_ERROR_INVALID_ARGUMENT );
2711
mohammad16039375f842018-06-03 14:28:24 +03002712 tag_length = 16;
2713 status = psa_aead_unpadded_locate_tag( tag_length,
2714 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002715 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002716 if( status != PSA_SUCCESS )
2717 return( status );
2718
mohammad16035955c982018-04-26 00:53:03 +03002719 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002720 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002721 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002722 if( ret != 0 )
2723 {
2724 mbedtls_ccm_free( &ccm );
2725 return( mbedtls_to_psa_error( ret ) );
2726 }
mohammad160360a64d02018-06-03 17:20:42 +03002727 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002728 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002729 additional_data,
2730 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002731 ciphertext, plaintext,
2732 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002733 mbedtls_ccm_free( &ccm );
2734 }
mohammad160339574652018-06-01 04:39:53 -07002735 else
2736 {
mohammad1603554faad2018-06-03 15:07:38 +03002737 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002738 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002739
Gilles Peskineee652a32018-06-01 19:23:52 +02002740 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002741 memset( plaintext, 0, plaintext_size );
2742 else
2743 *plaintext_length = ciphertext_length - tag_length;
2744
Gilles Peskineee652a32018-06-01 19:23:52 +02002745 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002746}
2747
Gilles Peskinea0655c32018-04-30 17:06:50 +02002748
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002749
Gilles Peskine20035e32018-02-03 22:44:14 +01002750/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002751/* Key generation */
2752/****************************************************************/
2753
2754psa_status_t psa_generate_random( uint8_t *output,
2755 size_t output_size )
2756{
2757 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2758 output, output_size );
2759 return( mbedtls_to_psa_error( ret ) );
2760}
2761
2762psa_status_t psa_generate_key( psa_key_slot_t key,
2763 psa_key_type_t type,
2764 size_t bits,
2765 const void *parameters,
2766 size_t parameters_size )
2767{
Gilles Peskine12313cd2018-06-20 00:20:32 +02002768 key_slot_t *slot;
2769
2770 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
2771 return( PSA_ERROR_INVALID_ARGUMENT );
2772 slot = &global_data.key_slots[key];
2773 if( slot->type != PSA_KEY_TYPE_NONE )
2774 return( PSA_ERROR_OCCUPIED_SLOT );
2775 if( parameters == NULL && parameters_size != 0 )
2776 return( PSA_ERROR_INVALID_ARGUMENT );
2777
Gilles Peskine48c0ea12018-06-21 14:15:31 +02002778 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02002779 {
2780 psa_status_t status = prepare_raw_data_slot( type, bits,
2781 &slot->data.raw );
2782 if( status != PSA_SUCCESS )
2783 return( status );
2784 status = psa_generate_random( slot->data.raw.data,
2785 slot->data.raw.bytes );
2786 if( status != PSA_SUCCESS )
2787 {
2788 mbedtls_free( slot->data.raw.data );
2789 return( status );
2790 }
2791#if defined(MBEDTLS_DES_C)
2792 if( type == PSA_KEY_TYPE_DES )
2793 {
2794 mbedtls_des_key_set_parity( slot->data.raw.data );
2795 if( slot->data.raw.bytes >= 16 )
2796 mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
2797 if( slot->data.raw.bytes == 24 )
2798 mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
2799 }
2800#endif /* MBEDTLS_DES_C */
2801 }
2802 else
2803
2804#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
2805 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
2806 {
2807 mbedtls_rsa_context *rsa;
2808 int ret;
2809 int exponent = 65537;
2810 if( parameters != NULL )
2811 {
2812 const unsigned *p = parameters;
2813 if( parameters_size != sizeof( *p ) )
2814 return( PSA_ERROR_INVALID_ARGUMENT );
2815 if( *p > INT_MAX )
2816 return( PSA_ERROR_INVALID_ARGUMENT );
2817 exponent = *p;
2818 }
2819 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
2820 if( rsa == NULL )
2821 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2822 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
2823 ret = mbedtls_rsa_gen_key( rsa,
2824 mbedtls_ctr_drbg_random,
2825 &global_data.ctr_drbg,
2826 bits,
2827 exponent );
2828 if( ret != 0 )
2829 {
2830 mbedtls_rsa_free( rsa );
2831 mbedtls_free( rsa );
2832 return( mbedtls_to_psa_error( ret ) );
2833 }
2834 slot->data.rsa = rsa;
2835 }
2836 else
2837#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
2838
2839#if defined(MBEDTLS_ECP_C)
2840 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
2841 {
2842 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
2843 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
2844 const mbedtls_ecp_curve_info *curve_info =
2845 mbedtls_ecp_curve_info_from_grp_id( grp_id );
2846 mbedtls_ecp_keypair *ecp;
2847 int ret;
2848 if( parameters != NULL )
2849 return( PSA_ERROR_NOT_SUPPORTED );
2850 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
2851 return( PSA_ERROR_NOT_SUPPORTED );
2852 if( curve_info->bit_size != bits )
2853 return( PSA_ERROR_INVALID_ARGUMENT );
2854 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
2855 if( ecp == NULL )
2856 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2857 mbedtls_ecp_keypair_init( ecp );
2858 ret = mbedtls_ecp_gen_key( grp_id, ecp,
2859 mbedtls_ctr_drbg_random,
2860 &global_data.ctr_drbg );
2861 if( ret != 0 )
2862 {
2863 mbedtls_ecp_keypair_free( ecp );
2864 mbedtls_free( ecp );
2865 return( mbedtls_to_psa_error( ret ) );
2866 }
2867 slot->data.ecp = ecp;
2868 }
2869 else
2870#endif /* MBEDTLS_ECP_C */
2871
2872 return( PSA_ERROR_NOT_SUPPORTED );
2873
2874 slot->type = type;
2875 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02002876}
2877
2878
2879/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002880/* Module setup */
2881/****************************************************************/
2882
Gilles Peskinee59236f2018-01-27 23:32:46 +01002883void mbedtls_psa_crypto_free( void )
2884{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002885 size_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02002886 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002887 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002888 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2889 mbedtls_entropy_free( &global_data.entropy );
2890 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2891}
2892
2893psa_status_t psa_crypto_init( void )
2894{
2895 int ret;
2896 const unsigned char drbg_seed[] = "PSA";
2897
2898 if( global_data.initialized != 0 )
2899 return( PSA_SUCCESS );
2900
2901 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2902 mbedtls_entropy_init( &global_data.entropy );
2903 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2904
2905 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2906 mbedtls_entropy_func,
2907 &global_data.entropy,
2908 drbg_seed, sizeof( drbg_seed ) - 1 );
2909 if( ret != 0 )
2910 goto exit;
2911
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002912 global_data.initialized = 1;
2913
Gilles Peskinee59236f2018-01-27 23:32:46 +01002914exit:
2915 if( ret != 0 )
2916 mbedtls_psa_crypto_free( );
2917 return( mbedtls_to_psa_error( ret ) );
2918}
2919
2920#endif /* MBEDTLS_PSA_CRYPTO_C */