blob: 535384c42b9793eb88de48561bb4665c08b34435 [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
4/* Copyright (C) 2018, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PSA_CRYPTO_C)
29
30#include "psa/crypto.h"
31
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010032#include <stdlib.h>
33#include <string.h>
34#if defined(MBEDTLS_PLATFORM_C)
35#include "mbedtls/platform.h"
36#else
37#define mbedtls_calloc calloc
38#define mbedtls_free free
39#endif
40
Gilles Peskinea5905292018-02-07 20:59:33 +010041#include "mbedtls/arc4.h"
42#include "mbedtls/blowfish.h"
43#include "mbedtls/camellia.h"
44#include "mbedtls/cipher.h"
45#include "mbedtls/ccm.h"
46#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010047#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010048#include "mbedtls/des.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010049#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010050#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010051#include "mbedtls/error.h"
52#include "mbedtls/gcm.h"
53#include "mbedtls/md2.h"
54#include "mbedtls/md4.h"
55#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010056#include "mbedtls/md.h"
57#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010058#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010059#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010060#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010061#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010062#include "mbedtls/sha1.h"
63#include "mbedtls/sha256.h"
64#include "mbedtls/sha512.h"
65#include "mbedtls/xtea.h"
66
Gilles Peskinee59236f2018-01-27 23:32:46 +010067
68
69/* Implementation that should never be optimized out by the compiler */
70static void mbedtls_zeroize( void *v, size_t n )
71{
72 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
73}
74
Gilles Peskine9ef733f2018-02-07 21:05:37 +010075/* constant-time buffer comparison */
76static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
77{
78 size_t i;
79 unsigned char diff = 0;
80
81 for( i = 0; i < n; i++ )
82 diff |= a[i] ^ b[i];
83
84 return( diff );
85}
86
87
88
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010089/****************************************************************/
90/* Global data, support functions and library management */
91/****************************************************************/
92
93/* Number of key slots (plus one because 0 is not used).
94 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +020095#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010096
Gilles Peskine2d277862018-06-18 15:41:12 +020097typedef struct
98{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010099 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300100 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200101 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200102 union
103 {
104 struct raw_data
105 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100106 uint8_t *data;
107 size_t bytes;
108 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100109#if defined(MBEDTLS_RSA_C)
110 mbedtls_rsa_context *rsa;
111#endif /* MBEDTLS_RSA_C */
112#if defined(MBEDTLS_ECP_C)
113 mbedtls_ecp_keypair *ecp;
114#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100115 } data;
116} key_slot_t;
117
Gilles Peskine2d277862018-06-18 15:41:12 +0200118typedef struct
119{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100120 int initialized;
121 mbedtls_entropy_context entropy;
122 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200123 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100124} psa_global_data_t;
125
126static psa_global_data_t global_data;
127
128static psa_status_t mbedtls_to_psa_error( int ret )
129{
Gilles Peskinea5905292018-02-07 20:59:33 +0100130 /* If there's both a high-level code and low-level code, dispatch on
131 * the high-level code. */
132 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100133 {
134 case 0:
135 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100136
137 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
138 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
139 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
140 return( PSA_ERROR_NOT_SUPPORTED );
141 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
142 return( PSA_ERROR_HARDWARE_FAILURE );
143
144 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
145 return( PSA_ERROR_HARDWARE_FAILURE );
146
147 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
148 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
149 return( PSA_ERROR_NOT_SUPPORTED );
150 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
151 return( PSA_ERROR_HARDWARE_FAILURE );
152
153 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
154 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
155 return( PSA_ERROR_NOT_SUPPORTED );
156 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
157 return( PSA_ERROR_HARDWARE_FAILURE );
158
159 case MBEDTLS_ERR_CCM_BAD_INPUT:
160 return( PSA_ERROR_INVALID_ARGUMENT );
161 case MBEDTLS_ERR_CCM_AUTH_FAILED:
162 return( PSA_ERROR_INVALID_SIGNATURE );
163 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
164 return( PSA_ERROR_HARDWARE_FAILURE );
165
166 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
167 return( PSA_ERROR_NOT_SUPPORTED );
168 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
169 return( PSA_ERROR_INVALID_ARGUMENT );
170 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
171 return( PSA_ERROR_INSUFFICIENT_MEMORY );
172 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
173 return( PSA_ERROR_INVALID_PADDING );
174 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
175 return( PSA_ERROR_BAD_STATE );
176 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
177 return( PSA_ERROR_INVALID_SIGNATURE );
178 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
179 return( PSA_ERROR_TAMPERING_DETECTED );
180 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
181 return( PSA_ERROR_HARDWARE_FAILURE );
182
183 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
186 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
187 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
188 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
189 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
190 return( PSA_ERROR_NOT_SUPPORTED );
191 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
192 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
193
194 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
195 return( PSA_ERROR_NOT_SUPPORTED );
196 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
197 return( PSA_ERROR_HARDWARE_FAILURE );
198
Gilles Peskinee59236f2018-01-27 23:32:46 +0100199 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
200 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
201 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
202 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100203
204 case MBEDTLS_ERR_GCM_AUTH_FAILED:
205 return( PSA_ERROR_INVALID_SIGNATURE );
206 case MBEDTLS_ERR_GCM_BAD_INPUT:
207 return( PSA_ERROR_NOT_SUPPORTED );
208 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
209 return( PSA_ERROR_HARDWARE_FAILURE );
210
211 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
212 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
213 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
214 return( PSA_ERROR_HARDWARE_FAILURE );
215
216 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
217 return( PSA_ERROR_NOT_SUPPORTED );
218 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
219 return( PSA_ERROR_INVALID_ARGUMENT );
220 case MBEDTLS_ERR_MD_ALLOC_FAILED:
221 return( PSA_ERROR_INSUFFICIENT_MEMORY );
222 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
223 return( PSA_ERROR_STORAGE_FAILURE );
224 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
225 return( PSA_ERROR_HARDWARE_FAILURE );
226
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100227 case MBEDTLS_ERR_PK_ALLOC_FAILED:
228 return( PSA_ERROR_INSUFFICIENT_MEMORY );
229 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
230 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
231 return( PSA_ERROR_INVALID_ARGUMENT );
232 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100233 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100234 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
235 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
236 return( PSA_ERROR_INVALID_ARGUMENT );
237 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
238 return( PSA_ERROR_NOT_SUPPORTED );
239 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
240 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
241 return( PSA_ERROR_NOT_PERMITTED );
242 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
243 return( PSA_ERROR_INVALID_ARGUMENT );
244 case MBEDTLS_ERR_PK_INVALID_ALG:
245 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
246 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
247 return( PSA_ERROR_NOT_SUPPORTED );
248 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
249 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100250 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
251 return( PSA_ERROR_HARDWARE_FAILURE );
252
253 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
254 return( PSA_ERROR_HARDWARE_FAILURE );
255
256 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
257 return( PSA_ERROR_INVALID_ARGUMENT );
258 case MBEDTLS_ERR_RSA_INVALID_PADDING:
259 return( PSA_ERROR_INVALID_PADDING );
260 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
261 return( PSA_ERROR_HARDWARE_FAILURE );
262 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
263 return( PSA_ERROR_INVALID_ARGUMENT );
264 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
265 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
266 return( PSA_ERROR_TAMPERING_DETECTED );
267 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
268 return( PSA_ERROR_INVALID_SIGNATURE );
269 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
270 return( PSA_ERROR_BUFFER_TOO_SMALL );
271 case MBEDTLS_ERR_RSA_RNG_FAILED:
272 return( PSA_ERROR_INSUFFICIENT_MEMORY );
273 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
274 return( PSA_ERROR_NOT_SUPPORTED );
275 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
276 return( PSA_ERROR_HARDWARE_FAILURE );
277
278 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
279 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
280 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
281 return( PSA_ERROR_HARDWARE_FAILURE );
282
283 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
284 return( PSA_ERROR_INVALID_ARGUMENT );
285 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
286 return( PSA_ERROR_HARDWARE_FAILURE );
287
itayzafrir5c753392018-05-08 11:18:38 +0300288 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300289 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300290 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300291 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
292 return( PSA_ERROR_BUFFER_TOO_SMALL );
293 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
294 return( PSA_ERROR_NOT_SUPPORTED );
295 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
296 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
297 return( PSA_ERROR_INVALID_SIGNATURE );
298 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
299 return( PSA_ERROR_INSUFFICIENT_MEMORY );
300 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
301 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300302
Gilles Peskinee59236f2018-01-27 23:32:46 +0100303 default:
304 return( PSA_ERROR_UNKNOWN_ERROR );
305 }
306}
307
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200308
309
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100310/****************************************************************/
311/* Key management */
312/****************************************************************/
313
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200314static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
315{
316 switch( grpid )
317 {
318 case MBEDTLS_ECP_DP_SECP192R1:
319 return( PSA_ECC_CURVE_SECP192R1 );
320 case MBEDTLS_ECP_DP_SECP224R1:
321 return( PSA_ECC_CURVE_SECP224R1 );
322 case MBEDTLS_ECP_DP_SECP256R1:
323 return( PSA_ECC_CURVE_SECP256R1 );
324 case MBEDTLS_ECP_DP_SECP384R1:
325 return( PSA_ECC_CURVE_SECP384R1 );
326 case MBEDTLS_ECP_DP_SECP521R1:
327 return( PSA_ECC_CURVE_SECP521R1 );
328 case MBEDTLS_ECP_DP_BP256R1:
329 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
330 case MBEDTLS_ECP_DP_BP384R1:
331 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
332 case MBEDTLS_ECP_DP_BP512R1:
333 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
334 case MBEDTLS_ECP_DP_CURVE25519:
335 return( PSA_ECC_CURVE_CURVE25519 );
336 case MBEDTLS_ECP_DP_SECP192K1:
337 return( PSA_ECC_CURVE_SECP192K1 );
338 case MBEDTLS_ECP_DP_SECP224K1:
339 return( PSA_ECC_CURVE_SECP224K1 );
340 case MBEDTLS_ECP_DP_SECP256K1:
341 return( PSA_ECC_CURVE_SECP256K1 );
342 case MBEDTLS_ECP_DP_CURVE448:
343 return( PSA_ECC_CURVE_CURVE448 );
344 default:
345 return( 0 );
346 }
347}
348
Gilles Peskine12313cd2018-06-20 00:20:32 +0200349static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
350{
351 switch( curve )
352 {
353 case PSA_ECC_CURVE_SECP192R1:
354 return( MBEDTLS_ECP_DP_SECP192R1 );
355 case PSA_ECC_CURVE_SECP224R1:
356 return( MBEDTLS_ECP_DP_SECP224R1 );
357 case PSA_ECC_CURVE_SECP256R1:
358 return( MBEDTLS_ECP_DP_SECP256R1 );
359 case PSA_ECC_CURVE_SECP384R1:
360 return( MBEDTLS_ECP_DP_SECP384R1 );
361 case PSA_ECC_CURVE_SECP521R1:
362 return( MBEDTLS_ECP_DP_SECP521R1 );
363 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
364 return( MBEDTLS_ECP_DP_BP256R1 );
365 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
366 return( MBEDTLS_ECP_DP_BP384R1 );
367 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
368 return( MBEDTLS_ECP_DP_BP512R1 );
369 case PSA_ECC_CURVE_CURVE25519:
370 return( MBEDTLS_ECP_DP_CURVE25519 );
371 case PSA_ECC_CURVE_SECP192K1:
372 return( MBEDTLS_ECP_DP_SECP192K1 );
373 case PSA_ECC_CURVE_SECP224K1:
374 return( MBEDTLS_ECP_DP_SECP224K1 );
375 case PSA_ECC_CURVE_SECP256K1:
376 return( MBEDTLS_ECP_DP_SECP256K1 );
377 case PSA_ECC_CURVE_CURVE448:
378 return( MBEDTLS_ECP_DP_CURVE448 );
379 default:
380 return( MBEDTLS_ECP_DP_NONE );
381 }
382}
383
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200384static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
385 size_t bits,
386 struct raw_data *raw )
387{
388 /* Check that the bit size is acceptable for the key type */
389 switch( type )
390 {
391 case PSA_KEY_TYPE_RAW_DATA:
392#if defined(MBEDTLS_MD_C)
393 case PSA_KEY_TYPE_HMAC:
394#endif
395 break;
396#if defined(MBEDTLS_AES_C)
397 case PSA_KEY_TYPE_AES:
398 if( bits != 128 && bits != 192 && bits != 256 )
399 return( PSA_ERROR_INVALID_ARGUMENT );
400 break;
401#endif
402#if defined(MBEDTLS_CAMELLIA_C)
403 case PSA_KEY_TYPE_CAMELLIA:
404 if( bits != 128 && bits != 192 && bits != 256 )
405 return( PSA_ERROR_INVALID_ARGUMENT );
406 break;
407#endif
408#if defined(MBEDTLS_DES_C)
409 case PSA_KEY_TYPE_DES:
410 if( bits != 64 && bits != 128 && bits != 192 )
411 return( PSA_ERROR_INVALID_ARGUMENT );
412 break;
413#endif
414#if defined(MBEDTLS_ARC4_C)
415 case PSA_KEY_TYPE_ARC4:
416 if( bits < 8 || bits > 2048 )
417 return( PSA_ERROR_INVALID_ARGUMENT );
418 break;
419#endif
420 default:
421 return( PSA_ERROR_NOT_SUPPORTED );
422 }
423
424 /* Allocate memory for the key */
425 raw->bytes = PSA_BITS_TO_BYTES( bits );
426 raw->data = mbedtls_calloc( 1, raw->bytes );
427 if( raw->data == NULL )
428 {
429 raw->bytes = 0;
430 return( PSA_ERROR_INSUFFICIENT_MEMORY );
431 }
432 return( PSA_SUCCESS );
433}
434
Gilles Peskine2d277862018-06-18 15:41:12 +0200435psa_status_t psa_import_key( psa_key_slot_t key,
436 psa_key_type_t type,
437 const uint8_t *data,
438 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100439{
440 key_slot_t *slot;
441
Gilles Peskine828ed142018-06-18 23:25:51 +0200442 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100443 return( PSA_ERROR_INVALID_ARGUMENT );
444 slot = &global_data.key_slots[key];
445 if( slot->type != PSA_KEY_TYPE_NONE )
446 return( PSA_ERROR_OCCUPIED_SLOT );
447
Gilles Peskine8c9def32018-02-08 10:02:12 +0100448 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100449 {
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200450 psa_status_t status;
Gilles Peskine6d912132018-03-07 16:41:37 +0100451 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100452 if( data_length > SIZE_MAX / 8 )
453 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200454 status = prepare_raw_data_slot( type,
455 PSA_BYTES_TO_BITS( data_length ),
456 &slot->data.raw );
457 if( status != PSA_SUCCESS )
458 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100459 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100460 }
461 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100462#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100463 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
464 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
465 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100466 {
467 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100468 mbedtls_pk_context pk;
469 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100470 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
471 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
472 else
473 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100474 if( ret != 0 )
475 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100476 switch( mbedtls_pk_get_type( &pk ) )
477 {
478#if defined(MBEDTLS_RSA_C)
479 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100480 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
481 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200482 slot->data.rsa = mbedtls_pk_rsa( pk );
Gilles Peskine969ac722018-01-28 18:16:59 +0100483 else
484 return( PSA_ERROR_INVALID_ARGUMENT );
485 break;
486#endif /* MBEDTLS_RSA_C */
487#if defined(MBEDTLS_ECP_C)
488 case MBEDTLS_PK_ECKEY:
489 if( PSA_KEY_TYPE_IS_ECC( type ) )
490 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200491 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
492 psa_ecc_curve_t actual_curve =
493 mbedtls_ecc_group_to_psa( ecp->grp.id );
494 psa_ecc_curve_t expected_curve =
495 PSA_KEY_TYPE_GET_CURVE( type );
496 if( actual_curve != expected_curve )
497 return( PSA_ERROR_INVALID_ARGUMENT );
498 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100499 }
500 else
501 return( PSA_ERROR_INVALID_ARGUMENT );
502 break;
503#endif /* MBEDTLS_ECP_C */
504 default:
505 return( PSA_ERROR_INVALID_ARGUMENT );
506 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100507 }
508 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100509#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100510 {
511 return( PSA_ERROR_NOT_SUPPORTED );
512 }
513
514 slot->type = type;
515 return( PSA_SUCCESS );
516}
517
Gilles Peskine2d277862018-06-18 15:41:12 +0200518psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100519{
520 key_slot_t *slot;
521
Gilles Peskine828ed142018-06-18 23:25:51 +0200522 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100523 return( PSA_ERROR_INVALID_ARGUMENT );
524 slot = &global_data.key_slots[key];
525 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200526 {
527 /* No key material to clean, but do zeroize the slot below to wipe
528 * metadata such as policies. */
529 }
530 else if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100531 {
532 mbedtls_free( slot->data.raw.data );
533 }
534 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100535#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100536 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
537 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100538 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100539 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100540 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100541 }
542 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100543#endif /* defined(MBEDTLS_RSA_C) */
544#if defined(MBEDTLS_ECP_C)
545 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
546 {
547 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100548 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100549 }
550 else
551#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100552 {
553 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100554 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100555 return( PSA_ERROR_TAMPERING_DETECTED );
556 }
557
558 mbedtls_zeroize( slot, sizeof( *slot ) );
559 return( PSA_SUCCESS );
560}
561
Gilles Peskine2d277862018-06-18 15:41:12 +0200562psa_status_t psa_get_key_information( psa_key_slot_t key,
563 psa_key_type_t *type,
564 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100565{
566 key_slot_t *slot;
567
Gilles Peskine828ed142018-06-18 23:25:51 +0200568 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100569 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100570 slot = &global_data.key_slots[key];
571 if( type != NULL )
572 *type = slot->type;
573 if( bits != NULL )
574 *bits = 0;
575 if( slot->type == PSA_KEY_TYPE_NONE )
576 return( PSA_ERROR_EMPTY_SLOT );
577
Gilles Peskine8c9def32018-02-08 10:02:12 +0100578 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100579 {
580 if( bits != NULL )
581 *bits = slot->data.raw.bytes * 8;
582 }
583 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100584#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100585 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
586 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100587 {
588 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100589 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100590 }
591 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100592#endif /* defined(MBEDTLS_RSA_C) */
593#if defined(MBEDTLS_ECP_C)
594 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
595 {
596 if( bits != NULL )
597 *bits = slot->data.ecp->grp.pbits;
598 }
599 else
600#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100601 {
602 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100603 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100604 return( PSA_ERROR_TAMPERING_DETECTED );
605 }
606
607 return( PSA_SUCCESS );
608}
609
Gilles Peskine2d277862018-06-18 15:41:12 +0200610static psa_status_t psa_internal_export_key( psa_key_slot_t key,
611 uint8_t *data,
612 size_t data_size,
613 size_t *data_length,
614 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100615{
616 key_slot_t *slot;
617
Gilles Peskine828ed142018-06-18 23:25:51 +0200618 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100619 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100620 slot = &global_data.key_slots[key];
621 if( slot->type == PSA_KEY_TYPE_NONE )
622 return( PSA_ERROR_EMPTY_SLOT );
623
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200624 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300625 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300626
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200627 if( ! export_public_key &&
628 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
629 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300630 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200631
Gilles Peskine8c9def32018-02-08 10:02:12 +0100632 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100633 {
634 if( slot->data.raw.bytes > data_size )
635 return( PSA_ERROR_BUFFER_TOO_SMALL );
636 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
637 *data_length = slot->data.raw.bytes;
638 return( PSA_SUCCESS );
639 }
640 else
Moran Peker17e36e12018-05-02 12:55:20 +0300641 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100642#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100643 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300644 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
645 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100646 {
Moran Pekera998bc62018-04-16 18:16:20 +0300647 mbedtls_pk_context pk;
648 int ret;
649 mbedtls_pk_init( &pk );
650 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
651 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
652 {
653 pk.pk_info = &mbedtls_rsa_info;
654 pk.pk_ctx = slot->data.rsa;
655 }
656 else
657 {
658 pk.pk_info = &mbedtls_eckey_info;
659 pk.pk_ctx = slot->data.ecp;
660 }
Moran Pekerd7326592018-05-29 16:56:39 +0300661 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300662 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300663 else
664 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300665 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200666 {
667 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300668 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200669 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200670 /* The mbedtls_pk_xxx functions write to the end of the buffer.
671 * Move the data to the beginning and erase remaining data
672 * at the original location. */
673 if( 2 * (size_t) ret <= data_size )
674 {
675 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200676 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200677 }
678 else if( (size_t) ret < data_size )
679 {
680 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200681 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200682 }
Moran Pekera998bc62018-04-16 18:16:20 +0300683 *data_length = ret;
684 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100685 }
686 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100687#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300688 {
689 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200690 it is valid for a special-purpose implementation to omit
691 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300692 return( PSA_ERROR_NOT_SUPPORTED );
693 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100694 }
695}
696
Gilles Peskine2d277862018-06-18 15:41:12 +0200697psa_status_t psa_export_key( psa_key_slot_t key,
698 uint8_t *data,
699 size_t data_size,
700 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300701{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200702 return( psa_internal_export_key( key, data, data_size,
703 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100704}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100705
Gilles Peskine2d277862018-06-18 15:41:12 +0200706psa_status_t psa_export_public_key( psa_key_slot_t key,
707 uint8_t *data,
708 size_t data_size,
709 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300710{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200711 return( psa_internal_export_key( key, data, data_size,
712 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300713}
714
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200715
716
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100717/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100718/* Message digests */
719/****************************************************************/
720
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100721static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100722{
723 switch( alg )
724 {
725#if defined(MBEDTLS_MD2_C)
726 case PSA_ALG_MD2:
727 return( &mbedtls_md2_info );
728#endif
729#if defined(MBEDTLS_MD4_C)
730 case PSA_ALG_MD4:
731 return( &mbedtls_md4_info );
732#endif
733#if defined(MBEDTLS_MD5_C)
734 case PSA_ALG_MD5:
735 return( &mbedtls_md5_info );
736#endif
737#if defined(MBEDTLS_RIPEMD160_C)
738 case PSA_ALG_RIPEMD160:
739 return( &mbedtls_ripemd160_info );
740#endif
741#if defined(MBEDTLS_SHA1_C)
742 case PSA_ALG_SHA_1:
743 return( &mbedtls_sha1_info );
744#endif
745#if defined(MBEDTLS_SHA256_C)
746 case PSA_ALG_SHA_224:
747 return( &mbedtls_sha224_info );
748 case PSA_ALG_SHA_256:
749 return( &mbedtls_sha256_info );
750#endif
751#if defined(MBEDTLS_SHA512_C)
752 case PSA_ALG_SHA_384:
753 return( &mbedtls_sha384_info );
754 case PSA_ALG_SHA_512:
755 return( &mbedtls_sha512_info );
756#endif
757 default:
758 return( NULL );
759 }
760}
761
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100762psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
763{
764 switch( operation->alg )
765 {
766#if defined(MBEDTLS_MD2_C)
767 case PSA_ALG_MD2:
768 mbedtls_md2_free( &operation->ctx.md2 );
769 break;
770#endif
771#if defined(MBEDTLS_MD4_C)
772 case PSA_ALG_MD4:
773 mbedtls_md4_free( &operation->ctx.md4 );
774 break;
775#endif
776#if defined(MBEDTLS_MD5_C)
777 case PSA_ALG_MD5:
778 mbedtls_md5_free( &operation->ctx.md5 );
779 break;
780#endif
781#if defined(MBEDTLS_RIPEMD160_C)
782 case PSA_ALG_RIPEMD160:
783 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
784 break;
785#endif
786#if defined(MBEDTLS_SHA1_C)
787 case PSA_ALG_SHA_1:
788 mbedtls_sha1_free( &operation->ctx.sha1 );
789 break;
790#endif
791#if defined(MBEDTLS_SHA256_C)
792 case PSA_ALG_SHA_224:
793 case PSA_ALG_SHA_256:
794 mbedtls_sha256_free( &operation->ctx.sha256 );
795 break;
796#endif
797#if defined(MBEDTLS_SHA512_C)
798 case PSA_ALG_SHA_384:
799 case PSA_ALG_SHA_512:
800 mbedtls_sha512_free( &operation->ctx.sha512 );
801 break;
802#endif
803 default:
804 return( PSA_ERROR_NOT_SUPPORTED );
805 }
806 operation->alg = 0;
807 return( PSA_SUCCESS );
808}
809
810psa_status_t psa_hash_start( psa_hash_operation_t *operation,
811 psa_algorithm_t alg )
812{
813 int ret;
814 operation->alg = 0;
815 switch( alg )
816 {
817#if defined(MBEDTLS_MD2_C)
818 case PSA_ALG_MD2:
819 mbedtls_md2_init( &operation->ctx.md2 );
820 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
821 break;
822#endif
823#if defined(MBEDTLS_MD4_C)
824 case PSA_ALG_MD4:
825 mbedtls_md4_init( &operation->ctx.md4 );
826 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
827 break;
828#endif
829#if defined(MBEDTLS_MD5_C)
830 case PSA_ALG_MD5:
831 mbedtls_md5_init( &operation->ctx.md5 );
832 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
833 break;
834#endif
835#if defined(MBEDTLS_RIPEMD160_C)
836 case PSA_ALG_RIPEMD160:
837 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
838 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
839 break;
840#endif
841#if defined(MBEDTLS_SHA1_C)
842 case PSA_ALG_SHA_1:
843 mbedtls_sha1_init( &operation->ctx.sha1 );
844 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
845 break;
846#endif
847#if defined(MBEDTLS_SHA256_C)
848 case PSA_ALG_SHA_224:
849 mbedtls_sha256_init( &operation->ctx.sha256 );
850 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
851 break;
852 case PSA_ALG_SHA_256:
853 mbedtls_sha256_init( &operation->ctx.sha256 );
854 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
855 break;
856#endif
857#if defined(MBEDTLS_SHA512_C)
858 case PSA_ALG_SHA_384:
859 mbedtls_sha512_init( &operation->ctx.sha512 );
860 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
861 break;
862 case PSA_ALG_SHA_512:
863 mbedtls_sha512_init( &operation->ctx.sha512 );
864 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
865 break;
866#endif
867 default:
868 return( PSA_ERROR_NOT_SUPPORTED );
869 }
870 if( ret == 0 )
871 operation->alg = alg;
872 else
873 psa_hash_abort( operation );
874 return( mbedtls_to_psa_error( ret ) );
875}
876
877psa_status_t psa_hash_update( psa_hash_operation_t *operation,
878 const uint8_t *input,
879 size_t input_length )
880{
881 int ret;
882 switch( operation->alg )
883 {
884#if defined(MBEDTLS_MD2_C)
885 case PSA_ALG_MD2:
886 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
887 input, input_length );
888 break;
889#endif
890#if defined(MBEDTLS_MD4_C)
891 case PSA_ALG_MD4:
892 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
893 input, input_length );
894 break;
895#endif
896#if defined(MBEDTLS_MD5_C)
897 case PSA_ALG_MD5:
898 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
899 input, input_length );
900 break;
901#endif
902#if defined(MBEDTLS_RIPEMD160_C)
903 case PSA_ALG_RIPEMD160:
904 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
905 input, input_length );
906 break;
907#endif
908#if defined(MBEDTLS_SHA1_C)
909 case PSA_ALG_SHA_1:
910 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
911 input, input_length );
912 break;
913#endif
914#if defined(MBEDTLS_SHA256_C)
915 case PSA_ALG_SHA_224:
916 case PSA_ALG_SHA_256:
917 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
918 input, input_length );
919 break;
920#endif
921#if defined(MBEDTLS_SHA512_C)
922 case PSA_ALG_SHA_384:
923 case PSA_ALG_SHA_512:
924 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
925 input, input_length );
926 break;
927#endif
928 default:
929 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
930 break;
931 }
932 if( ret != 0 )
933 psa_hash_abort( operation );
934 return( mbedtls_to_psa_error( ret ) );
935}
936
937psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
938 uint8_t *hash,
939 size_t hash_size,
940 size_t *hash_length )
941{
942 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200943 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100944
945 /* Fill the output buffer with something that isn't a valid hash
946 * (barring an attack on the hash and deliberately-crafted input),
947 * in case the caller doesn't check the return status properly. */
948 *hash_length = actual_hash_length;
949 memset( hash, '!', hash_size );
950
951 if( hash_size < actual_hash_length )
952 return( PSA_ERROR_BUFFER_TOO_SMALL );
953
954 switch( operation->alg )
955 {
956#if defined(MBEDTLS_MD2_C)
957 case PSA_ALG_MD2:
958 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
959 break;
960#endif
961#if defined(MBEDTLS_MD4_C)
962 case PSA_ALG_MD4:
963 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
964 break;
965#endif
966#if defined(MBEDTLS_MD5_C)
967 case PSA_ALG_MD5:
968 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
969 break;
970#endif
971#if defined(MBEDTLS_RIPEMD160_C)
972 case PSA_ALG_RIPEMD160:
973 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
974 break;
975#endif
976#if defined(MBEDTLS_SHA1_C)
977 case PSA_ALG_SHA_1:
978 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
979 break;
980#endif
981#if defined(MBEDTLS_SHA256_C)
982 case PSA_ALG_SHA_224:
983 case PSA_ALG_SHA_256:
984 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
985 break;
986#endif
987#if defined(MBEDTLS_SHA512_C)
988 case PSA_ALG_SHA_384:
989 case PSA_ALG_SHA_512:
990 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
991 break;
992#endif
993 default:
994 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
995 break;
996 }
997
998 if( ret == 0 )
999 {
1000 return( psa_hash_abort( operation ) );
1001 }
1002 else
1003 {
1004 psa_hash_abort( operation );
1005 return( mbedtls_to_psa_error( ret ) );
1006 }
1007}
1008
Gilles Peskine2d277862018-06-18 15:41:12 +02001009psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1010 const uint8_t *hash,
1011 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001012{
1013 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1014 size_t actual_hash_length;
1015 psa_status_t status = psa_hash_finish( operation,
1016 actual_hash, sizeof( actual_hash ),
1017 &actual_hash_length );
1018 if( status != PSA_SUCCESS )
1019 return( status );
1020 if( actual_hash_length != hash_length )
1021 return( PSA_ERROR_INVALID_SIGNATURE );
1022 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1023 return( PSA_ERROR_INVALID_SIGNATURE );
1024 return( PSA_SUCCESS );
1025}
1026
1027
1028
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001029/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001030/* MAC */
1031/****************************************************************/
1032
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001033static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001034 psa_algorithm_t alg,
1035 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001036 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001037 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001038{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001039 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001040 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001041
1042 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1043 {
1044 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001045 {
1046 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1047 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001048
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001049 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001050 {
1051 case PSA_ALG_STREAM_CIPHER:
1052 mode = MBEDTLS_MODE_STREAM;
1053 break;
1054 case PSA_ALG_CBC_BASE:
1055 mode = MBEDTLS_MODE_CBC;
1056 break;
1057 case PSA_ALG_CFB_BASE:
1058 mode = MBEDTLS_MODE_CFB;
1059 break;
1060 case PSA_ALG_OFB_BASE:
1061 mode = MBEDTLS_MODE_OFB;
1062 break;
1063 case PSA_ALG_CTR:
1064 mode = MBEDTLS_MODE_CTR;
1065 break;
1066 case PSA_ALG_CCM:
1067 mode = MBEDTLS_MODE_CCM;
1068 break;
1069 case PSA_ALG_GCM:
1070 mode = MBEDTLS_MODE_GCM;
1071 break;
1072 default:
1073 return( NULL );
1074 }
1075 }
1076 else if( alg == PSA_ALG_CMAC )
1077 mode = MBEDTLS_MODE_ECB;
1078 else if( alg == PSA_ALG_GMAC )
1079 mode = MBEDTLS_MODE_GCM;
1080 else
1081 return( NULL );
1082
1083 switch( key_type )
1084 {
1085 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001086 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001087 break;
1088 case PSA_KEY_TYPE_DES:
1089 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001090 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001091 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001092 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001093 break;
1094 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001095 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001096 break;
1097 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001098 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001099 break;
1100 default:
1101 return( NULL );
1102 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001103 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001104 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001105
mohammad1603f4f0d612018-06-03 15:04:51 +03001106 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001107}
1108
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001109static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001110{
Gilles Peskine2d277862018-06-18 15:41:12 +02001111 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001112 {
1113 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001114 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001115 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001116 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001117 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001118 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001119 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001120 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001121 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001122 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001123 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001124 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001125 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001126 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001127 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001128 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001129 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001130 return( 128 );
1131 default:
1132 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001133 }
1134}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001135
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001136/* Initialize the MAC operation structure. Once this function has been
1137 * called, psa_mac_abort can run and will do the right thing. */
1138static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1139 psa_algorithm_t alg )
1140{
1141 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1142
1143 operation->alg = alg;
1144 operation->key_set = 0;
1145 operation->iv_set = 0;
1146 operation->iv_required = 0;
1147 operation->has_input = 0;
1148 operation->key_usage_sign = 0;
1149 operation->key_usage_verify = 0;
1150
1151#if defined(MBEDTLS_CMAC_C)
1152 if( alg == PSA_ALG_CMAC )
1153 {
1154 operation->iv_required = 0;
1155 mbedtls_cipher_init( &operation->ctx.cmac );
1156 status = PSA_SUCCESS;
1157 }
1158 else
1159#endif /* MBEDTLS_CMAC_C */
1160#if defined(MBEDTLS_MD_C)
1161 if( PSA_ALG_IS_HMAC( operation->alg ) )
1162 {
1163 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1164 PSA_ALG_HMAC_HASH( alg ) );
1165 }
1166 else
1167#endif /* MBEDTLS_MD_C */
1168 {
1169 /* fall through with NOT_SUPPORTED */
1170 }
1171
1172 if( status != PSA_SUCCESS )
1173 memset( operation, 0, sizeof( *operation ) );
1174 return( status );
1175}
1176
Gilles Peskine8c9def32018-02-08 10:02:12 +01001177psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1178{
1179 switch( operation->alg )
1180 {
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001181 case 0:
1182 return( PSA_SUCCESS );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001183#if defined(MBEDTLS_CMAC_C)
1184 case PSA_ALG_CMAC:
1185 mbedtls_cipher_free( &operation->ctx.cmac );
1186 break;
1187#endif /* MBEDTLS_CMAC_C */
1188 default:
1189#if defined(MBEDTLS_MD_C)
1190 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001191 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001192 unsigned int block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001193 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001194
Gilles Peskine99bc6492018-06-11 17:13:00 +02001195 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001196 return( PSA_ERROR_NOT_SUPPORTED );
1197
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001198 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001199 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001200 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001201 else
1202#endif /* MBEDTLS_MD_C */
1203 return( PSA_ERROR_NOT_SUPPORTED );
1204 }
Moran Peker41deec42018-04-04 15:43:05 +03001205
Gilles Peskine8c9def32018-02-08 10:02:12 +01001206 operation->alg = 0;
1207 operation->key_set = 0;
1208 operation->iv_set = 0;
1209 operation->iv_required = 0;
1210 operation->has_input = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001211 operation->key_usage_sign = 0;
1212 operation->key_usage_verify = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001213
Gilles Peskine8c9def32018-02-08 10:02:12 +01001214 return( PSA_SUCCESS );
1215}
1216
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001217#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001218static int psa_cmac_start( psa_mac_operation_t *operation,
1219 size_t key_bits,
1220 key_slot_t *slot,
1221 const mbedtls_cipher_info_t *cipher_info )
1222{
1223 int ret;
1224
1225 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001226
1227 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1228 if( ret != 0 )
1229 return( ret );
1230
1231 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1232 slot->data.raw.data,
1233 key_bits );
1234 return( ret );
1235}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001236#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001237
1238static int psa_hmac_start( psa_mac_operation_t *operation,
1239 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001240 key_slot_t *slot,
1241 psa_algorithm_t alg )
1242{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001243 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001244 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001245 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001246 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001247 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001248 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001249 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001250 size_t key_length = slot->data.raw.bytes;
1251 psa_status_t status;
1252
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001253 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001254 return( PSA_ERROR_NOT_SUPPORTED );
1255
1256 if( key_type != PSA_KEY_TYPE_HMAC )
1257 return( PSA_ERROR_INVALID_ARGUMENT );
1258
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001259 operation->mac_size = digest_size;
1260
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001261 /* The hash was started earlier in psa_mac_init. */
Gilles Peskined223b522018-06-11 18:12:58 +02001262 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001263 {
1264 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001265 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001266 if( status != PSA_SUCCESS )
1267 return( status );
1268 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001269 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001270 if( status != PSA_SUCCESS )
1271 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001272 }
Gilles Peskined223b522018-06-11 18:12:58 +02001273 else
1274 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001275
Gilles Peskined223b522018-06-11 18:12:58 +02001276 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1277 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001278 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001279 ipad[i] ^= 0x36;
1280 memset( ipad + key_length, 0x36, block_size - key_length );
1281
1282 /* Copy the key material from ipad to opad, flipping the requisite bits,
1283 * and filling the rest of opad with the requisite constant. */
1284 for( i = 0; i < key_length; i++ )
1285 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1286 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001287
1288 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1289 PSA_ALG_HMAC_HASH( alg ) );
1290 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001291 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001292
1293 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1294 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001295
1296cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001297 mbedtls_zeroize( ipad, key_length );
1298 /* opad is in the context. It needs to stay in memory if this function
1299 * succeeds, and it will be wiped by psa_mac_abort() called from
1300 * psa_mac_start in the error case. */
1301
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001302 return( status );
1303}
1304
Gilles Peskine8c9def32018-02-08 10:02:12 +01001305psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1306 psa_key_slot_t key,
1307 psa_algorithm_t alg )
1308{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001309 psa_status_t status;
1310 key_slot_t *slot;
1311 psa_key_type_t key_type;
1312 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001313 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001314
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001315 status = psa_mac_init( operation, alg );
1316 if( status != PSA_SUCCESS )
1317 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001318
1319 status = psa_get_key_information( key, &key_type, &key_bits );
1320 if( status != PSA_SUCCESS )
1321 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001322
Gilles Peskine8c9def32018-02-08 10:02:12 +01001323 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001324 if( slot->type == PSA_KEY_TYPE_NONE )
1325 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001326
Moran Pekerd7326592018-05-29 16:56:39 +03001327 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001328 operation->key_usage_sign = 1;
1329
Moran Pekerd7326592018-05-29 16:56:39 +03001330 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001331 operation->key_usage_verify = 1;
1332
Gilles Peskine8c9def32018-02-08 10:02:12 +01001333 if( ! PSA_ALG_IS_HMAC( alg ) )
1334 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001335 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001336 if( cipher_info == NULL )
1337 return( PSA_ERROR_NOT_SUPPORTED );
1338 operation->mac_size = cipher_info->block_size;
1339 }
1340 switch( alg )
1341 {
1342#if defined(MBEDTLS_CMAC_C)
1343 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001344 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1345 key_bits,
1346 slot,
1347 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001348 break;
1349#endif /* MBEDTLS_CMAC_C */
1350 default:
1351#if defined(MBEDTLS_MD_C)
1352 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001353 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001354 else
1355#endif /* MBEDTLS_MD_C */
1356 return( PSA_ERROR_NOT_SUPPORTED );
1357 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001358
Gilles Peskine8c9def32018-02-08 10:02:12 +01001359 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001360
1361 * context may contain data that needs to be wiped on error. */
1362 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001363 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001364 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001365 }
Gilles Peskine99bc6492018-06-11 17:13:00 +02001366
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001367 else
1368 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001369 operation->key_set = 1;
1370 }
1371 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001372}
1373
1374psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1375 const uint8_t *input,
1376 size_t input_length )
1377{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001378 int ret = 0 ;
1379 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001380 if( ! operation->key_set )
1381 return( PSA_ERROR_BAD_STATE );
1382 if( operation->iv_required && ! operation->iv_set )
1383 return( PSA_ERROR_BAD_STATE );
1384 operation->has_input = 1;
1385
1386 switch( operation->alg )
1387 {
1388#if defined(MBEDTLS_CMAC_C)
1389 case PSA_ALG_CMAC:
1390 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1391 input, input_length );
1392 break;
1393#endif /* MBEDTLS_CMAC_C */
1394 default:
1395#if defined(MBEDTLS_MD_C)
1396 if( PSA_ALG_IS_HMAC( operation->alg ) )
1397 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001398 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001399 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001400 }
1401 else
1402#endif /* MBEDTLS_MD_C */
1403 {
1404 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1405 }
1406 break;
1407 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001408 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001409 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001410 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001411 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001412 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001413 }
1414
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001415 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001416}
1417
mohammad16036df908f2018-04-02 08:34:15 -07001418static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001419 uint8_t *mac,
1420 size_t mac_size,
1421 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001422{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001423 int ret = 0;
1424 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001425 if( ! operation->key_set )
1426 return( PSA_ERROR_BAD_STATE );
1427 if( operation->iv_required && ! operation->iv_set )
1428 return( PSA_ERROR_BAD_STATE );
1429
1430 /* Fill the output buffer with something that isn't a valid mac
1431 * (barring an attack on the mac and deliberately-crafted input),
1432 * in case the caller doesn't check the return status properly. */
1433 *mac_length = operation->mac_size;
1434 memset( mac, '!', mac_size );
1435
1436 if( mac_size < operation->mac_size )
1437 return( PSA_ERROR_BUFFER_TOO_SMALL );
1438
1439 switch( operation->alg )
1440 {
1441#if defined(MBEDTLS_CMAC_C)
1442 case PSA_ALG_CMAC:
1443 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1444 break;
1445#endif /* MBEDTLS_CMAC_C */
1446 default:
1447#if defined(MBEDTLS_MD_C)
1448 if( PSA_ALG_IS_HMAC( operation->alg ) )
1449 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001450 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001451 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001452 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001453 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001454 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001455
Gilles Peskine99bc6492018-06-11 17:13:00 +02001456 if( block_size == 0 )
1457 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001458
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001459 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001460 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001461 if( status != PSA_SUCCESS )
1462 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001463 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001464
1465 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1466 PSA_ALG_HMAC_HASH( operation->alg ) );
1467 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001468 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001469
1470 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001471 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001472 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001473 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001474
1475 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001476 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001477 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001478 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001479
1480 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1481 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001482 hmac_cleanup:
1483 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001484 }
1485 else
1486#endif /* MBEDTLS_MD_C */
1487 {
1488 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1489 }
1490 break;
1491 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001492cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001493
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001494 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001495 {
1496 return( psa_mac_abort( operation ) );
1497 }
1498 else
1499 {
1500 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001501 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001502 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001503
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001504 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001505 }
1506}
1507
mohammad16036df908f2018-04-02 08:34:15 -07001508psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1509 uint8_t *mac,
1510 size_t mac_size,
1511 size_t *mac_length )
1512{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001513 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001514 return( PSA_ERROR_NOT_PERMITTED );
1515
Gilles Peskine99bc6492018-06-11 17:13:00 +02001516 return( psa_mac_finish_internal( operation, mac,
1517 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001518}
1519
Gilles Peskine828ed142018-06-18 23:25:51 +02001520#define PSA_MAC_MAX_SIZE \
Gilles Peskine2d277862018-06-18 15:41:12 +02001521 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1522 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001523 MBEDTLS_MAX_BLOCK_LENGTH )
1524psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1525 const uint8_t *mac,
1526 size_t mac_length )
1527{
Gilles Peskine828ed142018-06-18 23:25:51 +02001528 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001529 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001530 psa_status_t status;
1531
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001532 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001533 return( PSA_ERROR_NOT_PERMITTED );
1534
1535 status = psa_mac_finish_internal( operation,
1536 actual_mac, sizeof( actual_mac ),
1537 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001538 if( status != PSA_SUCCESS )
1539 return( status );
1540 if( actual_mac_length != mac_length )
1541 return( PSA_ERROR_INVALID_SIGNATURE );
1542 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1543 return( PSA_ERROR_INVALID_SIGNATURE );
1544 return( PSA_SUCCESS );
1545}
1546
1547
Gilles Peskine20035e32018-02-03 22:44:14 +01001548
Gilles Peskine20035e32018-02-03 22:44:14 +01001549/****************************************************************/
1550/* Asymmetric cryptography */
1551/****************************************************************/
1552
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001553/* Decode the hash algorithm from alg and store the mbedtls encoding in
1554 * md_alg. Verify that the hash length is consistent. */
1555static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1556 size_t hash_length,
1557 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001558{
Gilles Peskine61b91d42018-06-08 16:09:36 +02001559 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
1560 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1561 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1562 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001563 {
1564#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001565 if( hash_length > UINT_MAX )
1566 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001567#endif
1568 }
1569 else
1570 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001571 if( mbedtls_md_get_size( md_info ) != hash_length )
1572 return( PSA_ERROR_INVALID_ARGUMENT );
1573 if( md_info == NULL )
1574 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001575 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001576 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001577}
1578
Gilles Peskine61b91d42018-06-08 16:09:36 +02001579psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1580 psa_algorithm_t alg,
1581 const uint8_t *hash,
1582 size_t hash_length,
1583 const uint8_t *salt,
1584 size_t salt_length,
1585 uint8_t *signature,
1586 size_t signature_size,
1587 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001588{
1589 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001590 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001591 *signature_length = 0;
1592 (void) salt;
1593 (void) salt_length;
1594
Gilles Peskine828ed142018-06-18 23:25:51 +02001595 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine20035e32018-02-03 22:44:14 +01001596 return( PSA_ERROR_EMPTY_SLOT );
1597 slot = &global_data.key_slots[key];
1598 if( slot->type == PSA_KEY_TYPE_NONE )
1599 return( PSA_ERROR_EMPTY_SLOT );
1600 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1601 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001602 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001603 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001604
Gilles Peskine20035e32018-02-03 22:44:14 +01001605#if defined(MBEDTLS_RSA_C)
1606 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1607 {
1608 mbedtls_rsa_context *rsa = slot->data.rsa;
1609 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001610 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001611 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001612 if( status != PSA_SUCCESS )
1613 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001614
Gilles Peskine20035e32018-02-03 22:44:14 +01001615 if( signature_size < rsa->len )
1616 return( PSA_ERROR_BUFFER_TOO_SMALL );
1617#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001618 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001619 {
1620 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1621 MBEDTLS_MD_NONE );
1622 ret = mbedtls_rsa_pkcs1_sign( rsa,
1623 mbedtls_ctr_drbg_random,
1624 &global_data.ctr_drbg,
1625 MBEDTLS_RSA_PRIVATE,
1626 md_alg, hash_length, hash,
1627 signature );
1628 }
1629 else
1630#endif /* MBEDTLS_PKCS1_V15 */
1631#if defined(MBEDTLS_PKCS1_V21)
1632 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1633 {
1634 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1635 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1636 mbedtls_ctr_drbg_random,
1637 &global_data.ctr_drbg,
1638 MBEDTLS_RSA_PRIVATE,
1639 md_alg, hash_length, hash,
1640 signature );
1641 }
1642 else
1643#endif /* MBEDTLS_PKCS1_V21 */
1644 {
1645 return( PSA_ERROR_INVALID_ARGUMENT );
1646 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001647 if( ret == 0 )
1648 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001649 return( mbedtls_to_psa_error( ret ) );
1650 }
1651 else
1652#endif /* defined(MBEDTLS_RSA_C) */
1653#if defined(MBEDTLS_ECP_C)
1654 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1655 {
itayzafrir5c753392018-05-08 11:18:38 +03001656 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1657 int ret;
1658 const mbedtls_md_info_t *md_info;
1659 mbedtls_md_type_t md_alg;
1660 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1661 return( PSA_ERROR_BUFFER_TOO_SMALL );
1662 md_info = mbedtls_md_info_from_psa( alg );
1663 md_alg = mbedtls_md_get_type( md_info );
1664 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001665 signature, signature_length,
1666 mbedtls_ctr_drbg_random,
1667 &global_data.ctr_drbg );
itayzafrir5c753392018-05-08 11:18:38 +03001668 return( mbedtls_to_psa_error( ret ) );
1669 }
1670 else
1671#endif /* defined(MBEDTLS_ECP_C) */
1672 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001673 return( PSA_ERROR_NOT_SUPPORTED );
1674 }
itayzafrir5c753392018-05-08 11:18:38 +03001675}
1676
1677psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1678 psa_algorithm_t alg,
1679 const uint8_t *hash,
1680 size_t hash_length,
1681 const uint8_t *salt,
1682 size_t salt_length,
1683 uint8_t *signature,
1684 size_t signature_size )
1685{
1686 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001687 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001688 (void) salt;
1689 (void) salt_length;
1690
Gilles Peskine828ed142018-06-18 23:25:51 +02001691 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001692 return( PSA_ERROR_INVALID_ARGUMENT );
1693 slot = &global_data.key_slots[key];
1694 if( slot->type == PSA_KEY_TYPE_NONE )
1695 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001696 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001697 return( PSA_ERROR_NOT_PERMITTED );
1698
Gilles Peskine61b91d42018-06-08 16:09:36 +02001699#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001700 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1701 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001702 {
1703 mbedtls_rsa_context *rsa = slot->data.rsa;
1704 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001705 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001706 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001707 if( status != PSA_SUCCESS )
1708 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001709
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001710 if( signature_size < rsa->len )
1711 return( PSA_ERROR_BUFFER_TOO_SMALL );
1712#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001713 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001714 {
1715 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1716 MBEDTLS_MD_NONE );
1717
1718 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001719 mbedtls_ctr_drbg_random,
1720 &global_data.ctr_drbg,
1721 MBEDTLS_RSA_PUBLIC,
1722 md_alg,
1723 hash_length,
1724 hash,
1725 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001726
1727 }
1728 else
1729#endif /* MBEDTLS_PKCS1_V15 */
1730#if defined(MBEDTLS_PKCS1_V21)
1731 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1732 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001733 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1734 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1735 mbedtls_ctr_drbg_random,
1736 &global_data.ctr_drbg,
1737 MBEDTLS_RSA_PUBLIC,
1738 md_alg, hash_length, hash,
1739 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001740 }
1741 else
1742#endif /* MBEDTLS_PKCS1_V21 */
1743 {
1744 return( PSA_ERROR_INVALID_ARGUMENT );
1745 }
1746 return( mbedtls_to_psa_error( ret ) );
1747 }
1748 else
1749#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001750#if defined(MBEDTLS_ECP_C)
1751 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1752 {
1753 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1754 int ret;
Gilles Peskine2d277862018-06-18 15:41:12 +02001755 (void) alg;
Gilles Peskine61b91d42018-06-08 16:09:36 +02001756 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length,
1757 signature, signature_size );
itayzafrir5c753392018-05-08 11:18:38 +03001758 return( mbedtls_to_psa_error( ret ) );
1759 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001760 else
1761#endif /* defined(MBEDTLS_ECP_C) */
1762 {
1763 return( PSA_ERROR_NOT_SUPPORTED );
1764 }
1765}
1766
Gilles Peskine61b91d42018-06-08 16:09:36 +02001767psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1768 psa_algorithm_t alg,
1769 const uint8_t *input,
1770 size_t input_length,
1771 const uint8_t *salt,
1772 size_t salt_length,
1773 uint8_t *output,
1774 size_t output_size,
1775 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001776{
1777 key_slot_t *slot;
1778 (void) salt;
1779 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001780 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001781
Gilles Peskine828ed142018-06-18 23:25:51 +02001782 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001783 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001784 slot = &global_data.key_slots[key];
1785 if( slot->type == PSA_KEY_TYPE_NONE )
1786 return( PSA_ERROR_EMPTY_SLOT );
1787 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1788 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001789 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1790 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001791
1792#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001793 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1794 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001795 {
1796 mbedtls_rsa_context *rsa = slot->data.rsa;
1797 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001798 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001799 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001800#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001801 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001802 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001803 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1804 mbedtls_ctr_drbg_random,
1805 &global_data.ctr_drbg,
1806 MBEDTLS_RSA_PUBLIC,
1807 input_length,
1808 input,
1809 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001810 }
1811 else
1812#endif /* MBEDTLS_PKCS1_V15 */
1813#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001814 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001815 {
1816 return( PSA_ERROR_NOT_SUPPORTED );
1817 }
1818 else
1819#endif /* MBEDTLS_PKCS1_V21 */
1820 {
1821 return( PSA_ERROR_INVALID_ARGUMENT );
1822 }
1823 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001824 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001825 return( mbedtls_to_psa_error( ret ) );
1826 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001827 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001828#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001829 {
1830 return( PSA_ERROR_NOT_SUPPORTED );
1831 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001832}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001833
Gilles Peskine61b91d42018-06-08 16:09:36 +02001834psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1835 psa_algorithm_t alg,
1836 const uint8_t *input,
1837 size_t input_length,
1838 const uint8_t *salt,
1839 size_t salt_length,
1840 uint8_t *output,
1841 size_t output_size,
1842 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001843{
1844 key_slot_t *slot;
1845 (void) salt;
1846 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001847 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001848
Gilles Peskine828ed142018-06-18 23:25:51 +02001849 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001850 return( PSA_ERROR_EMPTY_SLOT );
1851 slot = &global_data.key_slots[key];
1852 if( slot->type == PSA_KEY_TYPE_NONE )
1853 return( PSA_ERROR_EMPTY_SLOT );
1854 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1855 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001856 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1857 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001858
1859#if defined(MBEDTLS_RSA_C)
1860 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1861 {
1862 mbedtls_rsa_context *rsa = slot->data.rsa;
1863 int ret;
1864
Gilles Peskinec4def2f2018-06-08 17:53:48 +02001865 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001866 return( PSA_ERROR_INVALID_ARGUMENT );
1867
1868#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001869 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001870 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001871 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
1872 mbedtls_ctr_drbg_random,
1873 &global_data.ctr_drbg,
1874 MBEDTLS_RSA_PRIVATE,
1875 output_length,
1876 input,
1877 output,
1878 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001879 }
1880 else
1881#endif /* MBEDTLS_PKCS1_V15 */
1882#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001883 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001884 {
1885 return( PSA_ERROR_NOT_SUPPORTED );
1886 }
1887 else
1888#endif /* MBEDTLS_PKCS1_V21 */
1889 {
1890 return( PSA_ERROR_INVALID_ARGUMENT );
1891 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001892
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001893 return( mbedtls_to_psa_error( ret ) );
1894 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001895 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001896#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001897 {
1898 return( PSA_ERROR_NOT_SUPPORTED );
1899 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001900}
Gilles Peskine20035e32018-02-03 22:44:14 +01001901
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001902
1903
mohammad1603503973b2018-03-12 15:59:30 +02001904/****************************************************************/
1905/* Symmetric cryptography */
1906/****************************************************************/
1907
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001908/* Initialize the cipher operation structure. Once this function has been
1909 * called, psa_cipher_abort can run and will do the right thing. */
1910static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
1911 psa_algorithm_t alg )
1912{
1913 operation->alg = alg;
1914 operation->key_set = 0;
1915 operation->iv_set = 0;
1916 operation->iv_required = 1;
1917 operation->iv_size = 0;
1918 operation->block_size = 0;
1919 mbedtls_cipher_init( &operation->ctx.cipher );
1920 return( PSA_SUCCESS );
1921}
1922
Gilles Peskinee553c652018-06-04 16:22:46 +02001923static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1924 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001925 psa_algorithm_t alg,
1926 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001927{
1928 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1929 psa_status_t status;
1930 key_slot_t *slot;
1931 psa_key_type_t key_type;
1932 size_t key_bits;
1933 const mbedtls_cipher_info_t *cipher_info = NULL;
1934
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001935 status = psa_cipher_init( operation, alg );
1936 if( status != PSA_SUCCESS )
1937 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02001938
1939 status = psa_get_key_information( key, &key_type, &key_bits );
1940 if( status != PSA_SUCCESS )
1941 return( status );
1942 slot = &global_data.key_slots[key];
1943
Gilles Peskinebb1072f2018-06-08 18:46:05 +02001944 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02001945 if( cipher_info == NULL )
1946 return( PSA_ERROR_NOT_SUPPORTED );
1947
mohammad1603503973b2018-03-12 15:59:30 +02001948 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03001949 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001950 {
1951 psa_cipher_abort( operation );
1952 return( mbedtls_to_psa_error( ret ) );
1953 }
1954
1955 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
Gilles Peskinee553c652018-06-04 16:22:46 +02001956 key_bits, cipher_operation );
Moran Peker41deec42018-04-04 15:43:05 +03001957 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001958 {
1959 psa_cipher_abort( operation );
1960 return( mbedtls_to_psa_error( ret ) );
1961 }
1962
mohammad16038481e742018-03-18 13:57:31 +02001963#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03001964 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02001965 {
Gilles Peskine53514202018-06-06 15:11:46 +02001966 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1967 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02001968
Moran Pekera28258c2018-05-29 16:25:04 +03001969 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02001970 {
1971 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
1972 mode = MBEDTLS_PADDING_PKCS7;
1973 break;
1974 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
1975 mode = MBEDTLS_PADDING_NONE;
1976 break;
1977 default:
Moran Pekerae382792018-05-31 14:06:17 +03001978 psa_cipher_abort( operation );
1979 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02001980 }
1981 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03001982 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03001983 {
1984 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02001985 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03001986 }
mohammad16038481e742018-03-18 13:57:31 +02001987 }
1988#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
1989
mohammad1603503973b2018-03-12 15:59:30 +02001990 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02001991 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
1992 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
1993 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001994 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02001995 {
mohammad160389e0f462018-04-12 08:48:45 +03001996 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02001997 }
mohammad1603503973b2018-03-12 15:59:30 +02001998
Moran Peker395db872018-05-31 14:07:14 +03001999 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002000}
2001
Gilles Peskinee553c652018-06-04 16:22:46 +02002002psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
2003 psa_key_slot_t key,
2004 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002005{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002006 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002007}
2008
Gilles Peskinee553c652018-06-04 16:22:46 +02002009psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
2010 psa_key_slot_t key,
2011 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002012{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002013 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002014}
2015
Gilles Peskinee553c652018-06-04 16:22:46 +02002016psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
2017 unsigned char *iv,
2018 size_t iv_size,
2019 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002020{
Moran Peker41deec42018-04-04 15:43:05 +03002021 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002022 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002023 return( PSA_ERROR_BAD_STATE );
2024 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002025 {
Moran Peker41deec42018-04-04 15:43:05 +03002026 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2027 goto exit;
2028 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002029 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2030 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002031 if( ret != 0 )
2032 {
2033 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002034 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002035 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002036
mohammad16038481e742018-03-18 13:57:31 +02002037 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03002038 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002039
Moran Peker395db872018-05-31 14:07:14 +03002040exit:
2041 if( ret != PSA_SUCCESS )
2042 psa_cipher_abort( operation );
2043 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002044}
2045
Gilles Peskinee553c652018-06-04 16:22:46 +02002046psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
2047 const unsigned char *iv,
2048 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002049{
Moran Peker41deec42018-04-04 15:43:05 +03002050 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002051 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002052 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002053 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002054 {
Moran Pekerae382792018-05-31 14:06:17 +03002055 psa_cipher_abort( operation );
2056 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002057 }
mohammad1603503973b2018-03-12 15:59:30 +02002058 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002059 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002060 {
2061 psa_cipher_abort( operation );
2062 return( mbedtls_to_psa_error( ret ) );
2063 }
2064
2065 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002066
Moran Peker395db872018-05-31 14:07:14 +03002067 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002068}
2069
Gilles Peskinee553c652018-06-04 16:22:46 +02002070psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2071 const uint8_t *input,
2072 size_t input_length,
2073 unsigned char *output,
2074 size_t output_size,
2075 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002076{
2077 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002078 size_t expected_output_size;
2079 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2080 {
2081 /* Take the unprocessed partial block left over from previous
2082 * update calls, if any, plus the input to this call. Remove
2083 * the last partial block, if any. You get the data that will be
2084 * output in this call. */
2085 expected_output_size =
2086 ( operation->ctx.cipher.unprocessed_len + input_length )
2087 / operation->block_size * operation->block_size;
2088 }
2089 else
2090 {
2091 expected_output_size = input_length;
2092 }
2093 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002094 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002095
mohammad1603503973b2018-03-12 15:59:30 +02002096 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002097 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002098 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002099 {
2100 psa_cipher_abort( operation );
2101 return( mbedtls_to_psa_error( ret ) );
2102 }
2103
Moran Peker395db872018-05-31 14:07:14 +03002104 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002105}
2106
Gilles Peskinee553c652018-06-04 16:22:46 +02002107psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2108 uint8_t *output,
2109 size_t output_size,
2110 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002111{
2112 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002113 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002114
mohammad1603503973b2018-03-12 15:59:30 +02002115 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002116 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002117 psa_cipher_abort( operation );
2118 return( PSA_ERROR_BAD_STATE );
2119 }
2120 if( operation->iv_required && ! operation->iv_set )
2121 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002122 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002123 return( PSA_ERROR_BAD_STATE );
2124 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002125 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2126 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002127 {
Gilles Peskine53514202018-06-06 15:11:46 +02002128 psa_algorithm_t padding_mode =
2129 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002130 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002131 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002132 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002133 return( PSA_ERROR_TAMPERING_DETECTED );
2134 }
Gilles Peskine53514202018-06-06 15:11:46 +02002135 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002136 {
2137 if( operation->ctx.cipher.unprocessed_len != 0 )
2138 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002139 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002140 return( PSA_ERROR_INVALID_ARGUMENT );
2141 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002142 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002143 }
2144
2145 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002146 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002147 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002148 {
2149 psa_cipher_abort( operation );
2150 return( mbedtls_to_psa_error( ret ) );
2151 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002152 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002153 memcpy( output, temp_output_buffer, *output_length );
2154 else
2155 {
2156 psa_cipher_abort( operation );
2157 return( PSA_ERROR_BUFFER_TOO_SMALL );
2158 }
mohammad1603503973b2018-03-12 15:59:30 +02002159
Moran Peker4c80d832018-04-22 20:15:31 +03002160 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002161}
2162
Gilles Peskinee553c652018-06-04 16:22:46 +02002163psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2164{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002165 if( operation->alg == 0 )
2166 return( PSA_SUCCESS );
2167
mohammad1603503973b2018-03-12 15:59:30 +02002168 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002169
Moran Peker41deec42018-04-04 15:43:05 +03002170 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002171 operation->key_set = 0;
2172 operation->iv_set = 0;
2173 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002174 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002175 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002176
Moran Peker395db872018-05-31 14:07:14 +03002177 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002178}
2179
Gilles Peskinea0655c32018-04-30 17:06:50 +02002180
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002181
mohammad16038cc1cee2018-03-28 01:21:33 +03002182/****************************************************************/
2183/* Key Policy */
2184/****************************************************************/
2185
Gilles Peskine2d277862018-06-18 15:41:12 +02002186void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002187{
Gilles Peskine803ce742018-06-18 16:07:14 +02002188 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002189}
2190
Gilles Peskine2d277862018-06-18 15:41:12 +02002191void psa_key_policy_set_usage( psa_key_policy_t *policy,
2192 psa_key_usage_t usage,
2193 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002194{
mohammad16034eed7572018-03-28 05:14:59 -07002195 policy->usage = usage;
2196 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002197}
2198
Gilles Peskine2d277862018-06-18 15:41:12 +02002199psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002200{
mohammad16036df908f2018-04-02 08:34:15 -07002201 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002202}
2203
Gilles Peskine2d277862018-06-18 15:41:12 +02002204psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002205{
mohammad16036df908f2018-04-02 08:34:15 -07002206 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002207}
2208
Gilles Peskine2d277862018-06-18 15:41:12 +02002209psa_status_t psa_set_key_policy( psa_key_slot_t key,
2210 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002211{
2212 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002213
Gilles Peskine828ed142018-06-18 23:25:51 +02002214 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002215 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002216
mohammad16038cc1cee2018-03-28 01:21:33 +03002217 slot = &global_data.key_slots[key];
2218 if( slot->type != PSA_KEY_TYPE_NONE )
2219 return( PSA_ERROR_OCCUPIED_SLOT );
2220
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002221 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2222 PSA_KEY_USAGE_ENCRYPT |
2223 PSA_KEY_USAGE_DECRYPT |
2224 PSA_KEY_USAGE_SIGN |
2225 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002226 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002227
mohammad16036df908f2018-04-02 08:34:15 -07002228 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002229
2230 return( PSA_SUCCESS );
2231}
2232
Gilles Peskine2d277862018-06-18 15:41:12 +02002233psa_status_t psa_get_key_policy( psa_key_slot_t key,
2234 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002235{
2236 key_slot_t *slot;
2237
Gilles Peskine828ed142018-06-18 23:25:51 +02002238 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002239 return( PSA_ERROR_INVALID_ARGUMENT );
2240
2241 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002242
mohammad16036df908f2018-04-02 08:34:15 -07002243 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002244
2245 return( PSA_SUCCESS );
2246}
Gilles Peskine20035e32018-02-03 22:44:14 +01002247
Gilles Peskinea0655c32018-04-30 17:06:50 +02002248
2249
mohammad1603804cd712018-03-20 22:44:08 +02002250/****************************************************************/
2251/* Key Lifetime */
2252/****************************************************************/
2253
Gilles Peskine2d277862018-06-18 15:41:12 +02002254psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2255 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002256{
2257 key_slot_t *slot;
2258
Gilles Peskine828ed142018-06-18 23:25:51 +02002259 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002260 return( PSA_ERROR_INVALID_ARGUMENT );
2261
2262 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002263
mohammad1603804cd712018-03-20 22:44:08 +02002264 *lifetime = slot->lifetime;
2265
2266 return( PSA_SUCCESS );
2267}
2268
Gilles Peskine2d277862018-06-18 15:41:12 +02002269psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2270 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002271{
2272 key_slot_t *slot;
2273
Gilles Peskine828ed142018-06-18 23:25:51 +02002274 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002275 return( PSA_ERROR_INVALID_ARGUMENT );
2276
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002277 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2278 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002279 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2280 return( PSA_ERROR_INVALID_ARGUMENT );
2281
mohammad1603804cd712018-03-20 22:44:08 +02002282 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002283 if( slot->type != PSA_KEY_TYPE_NONE )
2284 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002285
Moran Pekerd7326592018-05-29 16:56:39 +03002286 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002287 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002288
mohammad1603060ad8a2018-03-20 14:28:38 -07002289 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002290
2291 return( PSA_SUCCESS );
2292}
2293
Gilles Peskine20035e32018-02-03 22:44:14 +01002294
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002295
mohammad16035955c982018-04-26 00:53:03 +03002296/****************************************************************/
2297/* AEAD */
2298/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002299
mohammad16035955c982018-04-26 00:53:03 +03002300psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2301 psa_algorithm_t alg,
2302 const uint8_t *nonce,
2303 size_t nonce_length,
2304 const uint8_t *additional_data,
2305 size_t additional_data_length,
2306 const uint8_t *plaintext,
2307 size_t plaintext_length,
2308 uint8_t *ciphertext,
2309 size_t ciphertext_size,
2310 size_t *ciphertext_length )
2311{
2312 int ret;
2313 psa_status_t status;
2314 key_slot_t *slot;
2315 psa_key_type_t key_type;
2316 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002317 uint8_t *tag;
2318 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002319 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002320 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002321
mohammad1603f08a5502018-06-03 15:05:47 +03002322 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002323
mohammad16035955c982018-04-26 00:53:03 +03002324 status = psa_get_key_information( key, &key_type, &key_bits );
2325 if( status != PSA_SUCCESS )
2326 return( status );
2327 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002328 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002329 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002330
mohammad16035ed06212018-06-06 13:09:34 +03002331 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2332 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002333 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002334 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002335
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002336 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002337 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002338
Gilles Peskine2d277862018-06-18 15:41:12 +02002339 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2340 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002341 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002342
mohammad16035955c982018-04-26 00:53:03 +03002343 if( alg == PSA_ALG_GCM )
2344 {
2345 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002346 tag_length = 16;
2347
mohammad160396910d82018-06-04 14:33:00 +03002348 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2349 return( PSA_ERROR_INVALID_ARGUMENT );
2350
mohammad160315223a82018-06-03 17:19:55 +03002351 //make sure we have place to hold the tag in the ciphertext buffer
2352 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002353 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002354
2355 //update the tag pointer to point to the end of the ciphertext_length
2356 tag = ciphertext + plaintext_length;
2357
mohammad16035955c982018-04-26 00:53:03 +03002358 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002359 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002360 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002361 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002362 if( ret != 0 )
2363 {
2364 mbedtls_gcm_free( &gcm );
2365 return( mbedtls_to_psa_error( ret ) );
2366 }
2367 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002368 plaintext_length, nonce,
2369 nonce_length, additional_data,
2370 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002371 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002372 mbedtls_gcm_free( &gcm );
2373 }
2374 else if( alg == PSA_ALG_CCM )
2375 {
2376 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002377 tag_length = 16;
2378
mohammad160396910d82018-06-04 14:33:00 +03002379 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2380 return( PSA_ERROR_INVALID_ARGUMENT );
2381
mohammad160347ddf3d2018-04-26 01:11:21 +03002382 if( nonce_length < 7 || nonce_length > 13 )
2383 return( PSA_ERROR_INVALID_ARGUMENT );
2384
mohammad160315223a82018-06-03 17:19:55 +03002385 //make sure we have place to hold the tag in the ciphertext buffer
2386 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002387 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002388
2389 //update the tag pointer to point to the end of the ciphertext_length
2390 tag = ciphertext + plaintext_length;
2391
mohammad16035955c982018-04-26 00:53:03 +03002392 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002393 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002394 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002395 if( ret != 0 )
2396 {
2397 mbedtls_ccm_free( &ccm );
2398 return( mbedtls_to_psa_error( ret ) );
2399 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002400 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002401 nonce, nonce_length,
2402 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002403 additional_data_length,
2404 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002405 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002406 mbedtls_ccm_free( &ccm );
2407 }
mohammad16035c8845f2018-05-09 05:40:09 -07002408 else
2409 {
mohammad1603554faad2018-06-03 15:07:38 +03002410 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002411 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002412
mohammad160315223a82018-06-03 17:19:55 +03002413 if( ret != 0 )
2414 {
2415 memset( ciphertext, 0, ciphertext_size );
2416 return( mbedtls_to_psa_error( ret ) );
2417 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002418
mohammad160315223a82018-06-03 17:19:55 +03002419 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002420 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002421}
2422
Gilles Peskineee652a32018-06-01 19:23:52 +02002423/* Locate the tag in a ciphertext buffer containing the encrypted data
2424 * followed by the tag. Return the length of the part preceding the tag in
2425 * *plaintext_length. This is the size of the plaintext in modes where
2426 * the encrypted data has the same size as the plaintext, such as
2427 * CCM and GCM. */
2428static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2429 const uint8_t *ciphertext,
2430 size_t ciphertext_length,
2431 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002432 const uint8_t **p_tag )
2433{
2434 size_t payload_length;
2435 if( tag_length > ciphertext_length )
2436 return( PSA_ERROR_INVALID_ARGUMENT );
2437 payload_length = ciphertext_length - tag_length;
2438 if( payload_length > plaintext_size )
2439 return( PSA_ERROR_BUFFER_TOO_SMALL );
2440 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002441 return( PSA_SUCCESS );
2442}
2443
mohammad16035955c982018-04-26 00:53:03 +03002444psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2445 psa_algorithm_t alg,
2446 const uint8_t *nonce,
2447 size_t nonce_length,
2448 const uint8_t *additional_data,
2449 size_t additional_data_length,
2450 const uint8_t *ciphertext,
2451 size_t ciphertext_length,
2452 uint8_t *plaintext,
2453 size_t plaintext_size,
2454 size_t *plaintext_length )
2455{
2456 int ret;
2457 psa_status_t status;
2458 key_slot_t *slot;
2459 psa_key_type_t key_type;
2460 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002461 const uint8_t *tag;
2462 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002463 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002464 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002465
Gilles Peskineee652a32018-06-01 19:23:52 +02002466 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002467
mohammad16035955c982018-04-26 00:53:03 +03002468 status = psa_get_key_information( key, &key_type, &key_bits );
2469 if( status != PSA_SUCCESS )
2470 return( status );
2471 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002472 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002473 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002474
mohammad16035ed06212018-06-06 13:09:34 +03002475 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2476 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002477 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002478 return( PSA_ERROR_NOT_SUPPORTED );
2479
mohammad1603f14394b2018-06-04 14:33:19 +03002480 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2481 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002482
Gilles Peskine2d277862018-06-18 15:41:12 +02002483 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2484 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002485 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002486
mohammad16035955c982018-04-26 00:53:03 +03002487 if( alg == PSA_ALG_GCM )
2488 {
2489 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002490
Gilles Peskineee652a32018-06-01 19:23:52 +02002491 tag_length = 16;
2492 status = psa_aead_unpadded_locate_tag( tag_length,
2493 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002494 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002495 if( status != PSA_SUCCESS )
2496 return( status );
2497
mohammad16035955c982018-04-26 00:53:03 +03002498 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002499 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002500 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002501 if( ret != 0 )
2502 {
2503 mbedtls_gcm_free( &gcm );
2504 return( mbedtls_to_psa_error( ret ) );
2505 }
mohammad16035955c982018-04-26 00:53:03 +03002506
Gilles Peskineee652a32018-06-01 19:23:52 +02002507 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002508 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002509 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002510 additional_data,
2511 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002512 tag, tag_length,
2513 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002514 mbedtls_gcm_free( &gcm );
2515 }
2516 else if( alg == PSA_ALG_CCM )
2517 {
2518 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002519
mohammad160347ddf3d2018-04-26 01:11:21 +03002520 if( nonce_length < 7 || nonce_length > 13 )
2521 return( PSA_ERROR_INVALID_ARGUMENT );
2522
mohammad16039375f842018-06-03 14:28:24 +03002523 tag_length = 16;
2524 status = psa_aead_unpadded_locate_tag( tag_length,
2525 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002526 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002527 if( status != PSA_SUCCESS )
2528 return( status );
2529
mohammad16035955c982018-04-26 00:53:03 +03002530 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002531 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002532 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002533 if( ret != 0 )
2534 {
2535 mbedtls_ccm_free( &ccm );
2536 return( mbedtls_to_psa_error( ret ) );
2537 }
mohammad160360a64d02018-06-03 17:20:42 +03002538 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002539 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002540 additional_data,
2541 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002542 ciphertext, plaintext,
2543 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002544 mbedtls_ccm_free( &ccm );
2545 }
mohammad160339574652018-06-01 04:39:53 -07002546 else
2547 {
mohammad1603554faad2018-06-03 15:07:38 +03002548 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002549 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002550
Gilles Peskineee652a32018-06-01 19:23:52 +02002551 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002552 memset( plaintext, 0, plaintext_size );
2553 else
2554 *plaintext_length = ciphertext_length - tag_length;
2555
Gilles Peskineee652a32018-06-01 19:23:52 +02002556 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002557}
2558
Gilles Peskinea0655c32018-04-30 17:06:50 +02002559
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002560
Gilles Peskine20035e32018-02-03 22:44:14 +01002561/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002562/* Key generation */
2563/****************************************************************/
2564
2565psa_status_t psa_generate_random( uint8_t *output,
2566 size_t output_size )
2567{
2568 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2569 output, output_size );
2570 return( mbedtls_to_psa_error( ret ) );
2571}
2572
2573psa_status_t psa_generate_key( psa_key_slot_t key,
2574 psa_key_type_t type,
2575 size_t bits,
2576 const void *parameters,
2577 size_t parameters_size )
2578{
Gilles Peskine12313cd2018-06-20 00:20:32 +02002579 key_slot_t *slot;
2580
2581 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
2582 return( PSA_ERROR_INVALID_ARGUMENT );
2583 slot = &global_data.key_slots[key];
2584 if( slot->type != PSA_KEY_TYPE_NONE )
2585 return( PSA_ERROR_OCCUPIED_SLOT );
2586 if( parameters == NULL && parameters_size != 0 )
2587 return( PSA_ERROR_INVALID_ARGUMENT );
2588
2589 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
2590 {
2591 psa_status_t status = prepare_raw_data_slot( type, bits,
2592 &slot->data.raw );
2593 if( status != PSA_SUCCESS )
2594 return( status );
2595 status = psa_generate_random( slot->data.raw.data,
2596 slot->data.raw.bytes );
2597 if( status != PSA_SUCCESS )
2598 {
2599 mbedtls_free( slot->data.raw.data );
2600 return( status );
2601 }
2602#if defined(MBEDTLS_DES_C)
2603 if( type == PSA_KEY_TYPE_DES )
2604 {
2605 mbedtls_des_key_set_parity( slot->data.raw.data );
2606 if( slot->data.raw.bytes >= 16 )
2607 mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
2608 if( slot->data.raw.bytes == 24 )
2609 mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
2610 }
2611#endif /* MBEDTLS_DES_C */
2612 }
2613 else
2614
2615#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
2616 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
2617 {
2618 mbedtls_rsa_context *rsa;
2619 int ret;
2620 int exponent = 65537;
2621 if( parameters != NULL )
2622 {
2623 const unsigned *p = parameters;
2624 if( parameters_size != sizeof( *p ) )
2625 return( PSA_ERROR_INVALID_ARGUMENT );
2626 if( *p > INT_MAX )
2627 return( PSA_ERROR_INVALID_ARGUMENT );
2628 exponent = *p;
2629 }
2630 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
2631 if( rsa == NULL )
2632 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2633 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
2634 ret = mbedtls_rsa_gen_key( rsa,
2635 mbedtls_ctr_drbg_random,
2636 &global_data.ctr_drbg,
2637 bits,
2638 exponent );
2639 if( ret != 0 )
2640 {
2641 mbedtls_rsa_free( rsa );
2642 mbedtls_free( rsa );
2643 return( mbedtls_to_psa_error( ret ) );
2644 }
2645 slot->data.rsa = rsa;
2646 }
2647 else
2648#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
2649
2650#if defined(MBEDTLS_ECP_C)
2651 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
2652 {
2653 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
2654 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
2655 const mbedtls_ecp_curve_info *curve_info =
2656 mbedtls_ecp_curve_info_from_grp_id( grp_id );
2657 mbedtls_ecp_keypair *ecp;
2658 int ret;
2659 if( parameters != NULL )
2660 return( PSA_ERROR_NOT_SUPPORTED );
2661 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
2662 return( PSA_ERROR_NOT_SUPPORTED );
2663 if( curve_info->bit_size != bits )
2664 return( PSA_ERROR_INVALID_ARGUMENT );
2665 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
2666 if( ecp == NULL )
2667 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2668 mbedtls_ecp_keypair_init( ecp );
2669 ret = mbedtls_ecp_gen_key( grp_id, ecp,
2670 mbedtls_ctr_drbg_random,
2671 &global_data.ctr_drbg );
2672 if( ret != 0 )
2673 {
2674 mbedtls_ecp_keypair_free( ecp );
2675 mbedtls_free( ecp );
2676 return( mbedtls_to_psa_error( ret ) );
2677 }
2678 slot->data.ecp = ecp;
2679 }
2680 else
2681#endif /* MBEDTLS_ECP_C */
2682
2683 return( PSA_ERROR_NOT_SUPPORTED );
2684
2685 slot->type = type;
2686 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02002687}
2688
2689
2690/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002691/* Module setup */
2692/****************************************************************/
2693
Gilles Peskinee59236f2018-01-27 23:32:46 +01002694void mbedtls_psa_crypto_free( void )
2695{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002696 size_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02002697 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002698 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002699 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2700 mbedtls_entropy_free( &global_data.entropy );
2701 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2702}
2703
2704psa_status_t psa_crypto_init( void )
2705{
2706 int ret;
2707 const unsigned char drbg_seed[] = "PSA";
2708
2709 if( global_data.initialized != 0 )
2710 return( PSA_SUCCESS );
2711
2712 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2713 mbedtls_entropy_init( &global_data.entropy );
2714 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2715
2716 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2717 mbedtls_entropy_func,
2718 &global_data.entropy,
2719 drbg_seed, sizeof( drbg_seed ) - 1 );
2720 if( ret != 0 )
2721 goto exit;
2722
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002723 global_data.initialized = 1;
2724
Gilles Peskinee59236f2018-01-27 23:32:46 +01002725exit:
2726 if( ret != 0 )
2727 mbedtls_psa_crypto_free( );
2728 return( mbedtls_to_psa_error( ret ) );
2729}
2730
2731#endif /* MBEDTLS_PSA_CRYPTO_C */