blob: ba80912dde656b1466591e2de32f08ff9b88cdee [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 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200423 if( bits % 8 != 0 )
424 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200425
426 /* Allocate memory for the key */
427 raw->bytes = PSA_BITS_TO_BYTES( bits );
428 raw->data = mbedtls_calloc( 1, raw->bytes );
429 if( raw->data == NULL )
430 {
431 raw->bytes = 0;
432 return( PSA_ERROR_INSUFFICIENT_MEMORY );
433 }
434 return( PSA_SUCCESS );
435}
436
Gilles Peskine2d277862018-06-18 15:41:12 +0200437psa_status_t psa_import_key( psa_key_slot_t key,
438 psa_key_type_t type,
439 const uint8_t *data,
440 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100441{
442 key_slot_t *slot;
443
Gilles Peskine828ed142018-06-18 23:25:51 +0200444 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100445 return( PSA_ERROR_INVALID_ARGUMENT );
446 slot = &global_data.key_slots[key];
447 if( slot->type != PSA_KEY_TYPE_NONE )
448 return( PSA_ERROR_OCCUPIED_SLOT );
449
Gilles Peskine8c9def32018-02-08 10:02:12 +0100450 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100451 {
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200452 psa_status_t status;
Gilles Peskine6d912132018-03-07 16:41:37 +0100453 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100454 if( data_length > SIZE_MAX / 8 )
455 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200456 status = prepare_raw_data_slot( type,
457 PSA_BYTES_TO_BITS( data_length ),
458 &slot->data.raw );
459 if( status != PSA_SUCCESS )
460 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100461 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100462 }
463 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100464#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100465 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
466 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
467 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100468 {
469 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100470 mbedtls_pk_context pk;
471 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100472 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
473 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
474 else
475 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100476 if( ret != 0 )
477 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100478 switch( mbedtls_pk_get_type( &pk ) )
479 {
480#if defined(MBEDTLS_RSA_C)
481 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100482 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
483 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200484 slot->data.rsa = mbedtls_pk_rsa( pk );
Gilles Peskine969ac722018-01-28 18:16:59 +0100485 else
486 return( PSA_ERROR_INVALID_ARGUMENT );
487 break;
488#endif /* MBEDTLS_RSA_C */
489#if defined(MBEDTLS_ECP_C)
490 case MBEDTLS_PK_ECKEY:
491 if( PSA_KEY_TYPE_IS_ECC( type ) )
492 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200493 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
494 psa_ecc_curve_t actual_curve =
495 mbedtls_ecc_group_to_psa( ecp->grp.id );
496 psa_ecc_curve_t expected_curve =
497 PSA_KEY_TYPE_GET_CURVE( type );
498 if( actual_curve != expected_curve )
499 return( PSA_ERROR_INVALID_ARGUMENT );
500 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100501 }
502 else
503 return( PSA_ERROR_INVALID_ARGUMENT );
504 break;
505#endif /* MBEDTLS_ECP_C */
506 default:
507 return( PSA_ERROR_INVALID_ARGUMENT );
508 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100509 }
510 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100511#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100512 {
513 return( PSA_ERROR_NOT_SUPPORTED );
514 }
515
516 slot->type = type;
517 return( PSA_SUCCESS );
518}
519
Gilles Peskine2d277862018-06-18 15:41:12 +0200520psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100521{
522 key_slot_t *slot;
523
Gilles Peskine828ed142018-06-18 23:25:51 +0200524 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100525 return( PSA_ERROR_INVALID_ARGUMENT );
526 slot = &global_data.key_slots[key];
527 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200528 {
529 /* No key material to clean, but do zeroize the slot below to wipe
530 * metadata such as policies. */
531 }
532 else if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100533 {
534 mbedtls_free( slot->data.raw.data );
535 }
536 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100537#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100538 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
539 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100540 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100541 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100542 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100543 }
544 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100545#endif /* defined(MBEDTLS_RSA_C) */
546#if defined(MBEDTLS_ECP_C)
547 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
548 {
549 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100550 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100551 }
552 else
553#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100554 {
555 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100556 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100557 return( PSA_ERROR_TAMPERING_DETECTED );
558 }
559
560 mbedtls_zeroize( slot, sizeof( *slot ) );
561 return( PSA_SUCCESS );
562}
563
Gilles Peskine2d277862018-06-18 15:41:12 +0200564psa_status_t psa_get_key_information( psa_key_slot_t key,
565 psa_key_type_t *type,
566 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100567{
568 key_slot_t *slot;
569
Gilles Peskine828ed142018-06-18 23:25:51 +0200570 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100571 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100572 slot = &global_data.key_slots[key];
573 if( type != NULL )
574 *type = slot->type;
575 if( bits != NULL )
576 *bits = 0;
577 if( slot->type == PSA_KEY_TYPE_NONE )
578 return( PSA_ERROR_EMPTY_SLOT );
579
Gilles Peskine8c9def32018-02-08 10:02:12 +0100580 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100581 {
582 if( bits != NULL )
583 *bits = slot->data.raw.bytes * 8;
584 }
585 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100586#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100587 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
588 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100589 {
590 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100591 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100592 }
593 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100594#endif /* defined(MBEDTLS_RSA_C) */
595#if defined(MBEDTLS_ECP_C)
596 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
597 {
598 if( bits != NULL )
599 *bits = slot->data.ecp->grp.pbits;
600 }
601 else
602#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100603 {
604 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100605 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100606 return( PSA_ERROR_TAMPERING_DETECTED );
607 }
608
609 return( PSA_SUCCESS );
610}
611
Gilles Peskine2d277862018-06-18 15:41:12 +0200612static psa_status_t psa_internal_export_key( psa_key_slot_t key,
613 uint8_t *data,
614 size_t data_size,
615 size_t *data_length,
616 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100617{
618 key_slot_t *slot;
619
Gilles Peskine828ed142018-06-18 23:25:51 +0200620 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100621 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100622 slot = &global_data.key_slots[key];
623 if( slot->type == PSA_KEY_TYPE_NONE )
624 return( PSA_ERROR_EMPTY_SLOT );
625
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200626 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300627 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300628
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200629 if( ! export_public_key &&
630 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
631 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300632 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200633
Gilles Peskine8c9def32018-02-08 10:02:12 +0100634 if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100635 {
636 if( slot->data.raw.bytes > data_size )
637 return( PSA_ERROR_BUFFER_TOO_SMALL );
638 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
639 *data_length = slot->data.raw.bytes;
640 return( PSA_SUCCESS );
641 }
642 else
Moran Peker17e36e12018-05-02 12:55:20 +0300643 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100644#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100645 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300646 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
647 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100648 {
Moran Pekera998bc62018-04-16 18:16:20 +0300649 mbedtls_pk_context pk;
650 int ret;
651 mbedtls_pk_init( &pk );
652 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
653 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
654 {
655 pk.pk_info = &mbedtls_rsa_info;
656 pk.pk_ctx = slot->data.rsa;
657 }
658 else
659 {
660 pk.pk_info = &mbedtls_eckey_info;
661 pk.pk_ctx = slot->data.ecp;
662 }
Moran Pekerd7326592018-05-29 16:56:39 +0300663 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300664 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300665 else
666 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300667 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200668 {
669 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300670 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200671 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200672 /* The mbedtls_pk_xxx functions write to the end of the buffer.
673 * Move the data to the beginning and erase remaining data
674 * at the original location. */
675 if( 2 * (size_t) ret <= data_size )
676 {
677 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200678 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200679 }
680 else if( (size_t) ret < data_size )
681 {
682 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200683 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200684 }
Moran Pekera998bc62018-04-16 18:16:20 +0300685 *data_length = ret;
686 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100687 }
688 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100689#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300690 {
691 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200692 it is valid for a special-purpose implementation to omit
693 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300694 return( PSA_ERROR_NOT_SUPPORTED );
695 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100696 }
697}
698
Gilles Peskine2d277862018-06-18 15:41:12 +0200699psa_status_t psa_export_key( psa_key_slot_t key,
700 uint8_t *data,
701 size_t data_size,
702 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300703{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200704 return( psa_internal_export_key( key, data, data_size,
705 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100706}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100707
Gilles Peskine2d277862018-06-18 15:41:12 +0200708psa_status_t psa_export_public_key( psa_key_slot_t key,
709 uint8_t *data,
710 size_t data_size,
711 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300712{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200713 return( psa_internal_export_key( key, data, data_size,
714 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300715}
716
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200717
718
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100719/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100720/* Message digests */
721/****************************************************************/
722
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100723static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100724{
725 switch( alg )
726 {
727#if defined(MBEDTLS_MD2_C)
728 case PSA_ALG_MD2:
729 return( &mbedtls_md2_info );
730#endif
731#if defined(MBEDTLS_MD4_C)
732 case PSA_ALG_MD4:
733 return( &mbedtls_md4_info );
734#endif
735#if defined(MBEDTLS_MD5_C)
736 case PSA_ALG_MD5:
737 return( &mbedtls_md5_info );
738#endif
739#if defined(MBEDTLS_RIPEMD160_C)
740 case PSA_ALG_RIPEMD160:
741 return( &mbedtls_ripemd160_info );
742#endif
743#if defined(MBEDTLS_SHA1_C)
744 case PSA_ALG_SHA_1:
745 return( &mbedtls_sha1_info );
746#endif
747#if defined(MBEDTLS_SHA256_C)
748 case PSA_ALG_SHA_224:
749 return( &mbedtls_sha224_info );
750 case PSA_ALG_SHA_256:
751 return( &mbedtls_sha256_info );
752#endif
753#if defined(MBEDTLS_SHA512_C)
754 case PSA_ALG_SHA_384:
755 return( &mbedtls_sha384_info );
756 case PSA_ALG_SHA_512:
757 return( &mbedtls_sha512_info );
758#endif
759 default:
760 return( NULL );
761 }
762}
763
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100764psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
765{
766 switch( operation->alg )
767 {
768#if defined(MBEDTLS_MD2_C)
769 case PSA_ALG_MD2:
770 mbedtls_md2_free( &operation->ctx.md2 );
771 break;
772#endif
773#if defined(MBEDTLS_MD4_C)
774 case PSA_ALG_MD4:
775 mbedtls_md4_free( &operation->ctx.md4 );
776 break;
777#endif
778#if defined(MBEDTLS_MD5_C)
779 case PSA_ALG_MD5:
780 mbedtls_md5_free( &operation->ctx.md5 );
781 break;
782#endif
783#if defined(MBEDTLS_RIPEMD160_C)
784 case PSA_ALG_RIPEMD160:
785 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
786 break;
787#endif
788#if defined(MBEDTLS_SHA1_C)
789 case PSA_ALG_SHA_1:
790 mbedtls_sha1_free( &operation->ctx.sha1 );
791 break;
792#endif
793#if defined(MBEDTLS_SHA256_C)
794 case PSA_ALG_SHA_224:
795 case PSA_ALG_SHA_256:
796 mbedtls_sha256_free( &operation->ctx.sha256 );
797 break;
798#endif
799#if defined(MBEDTLS_SHA512_C)
800 case PSA_ALG_SHA_384:
801 case PSA_ALG_SHA_512:
802 mbedtls_sha512_free( &operation->ctx.sha512 );
803 break;
804#endif
805 default:
806 return( PSA_ERROR_NOT_SUPPORTED );
807 }
808 operation->alg = 0;
809 return( PSA_SUCCESS );
810}
811
812psa_status_t psa_hash_start( psa_hash_operation_t *operation,
813 psa_algorithm_t alg )
814{
815 int ret;
816 operation->alg = 0;
817 switch( alg )
818 {
819#if defined(MBEDTLS_MD2_C)
820 case PSA_ALG_MD2:
821 mbedtls_md2_init( &operation->ctx.md2 );
822 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
823 break;
824#endif
825#if defined(MBEDTLS_MD4_C)
826 case PSA_ALG_MD4:
827 mbedtls_md4_init( &operation->ctx.md4 );
828 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
829 break;
830#endif
831#if defined(MBEDTLS_MD5_C)
832 case PSA_ALG_MD5:
833 mbedtls_md5_init( &operation->ctx.md5 );
834 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
835 break;
836#endif
837#if defined(MBEDTLS_RIPEMD160_C)
838 case PSA_ALG_RIPEMD160:
839 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
840 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
841 break;
842#endif
843#if defined(MBEDTLS_SHA1_C)
844 case PSA_ALG_SHA_1:
845 mbedtls_sha1_init( &operation->ctx.sha1 );
846 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
847 break;
848#endif
849#if defined(MBEDTLS_SHA256_C)
850 case PSA_ALG_SHA_224:
851 mbedtls_sha256_init( &operation->ctx.sha256 );
852 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
853 break;
854 case PSA_ALG_SHA_256:
855 mbedtls_sha256_init( &operation->ctx.sha256 );
856 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
857 break;
858#endif
859#if defined(MBEDTLS_SHA512_C)
860 case PSA_ALG_SHA_384:
861 mbedtls_sha512_init( &operation->ctx.sha512 );
862 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
863 break;
864 case PSA_ALG_SHA_512:
865 mbedtls_sha512_init( &operation->ctx.sha512 );
866 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
867 break;
868#endif
869 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +0200870 return( PSA_ALG_IS_HASH( alg ) ?
871 PSA_ERROR_NOT_SUPPORTED :
872 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100873 }
874 if( ret == 0 )
875 operation->alg = alg;
876 else
877 psa_hash_abort( operation );
878 return( mbedtls_to_psa_error( ret ) );
879}
880
881psa_status_t psa_hash_update( psa_hash_operation_t *operation,
882 const uint8_t *input,
883 size_t input_length )
884{
885 int ret;
886 switch( operation->alg )
887 {
888#if defined(MBEDTLS_MD2_C)
889 case PSA_ALG_MD2:
890 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
891 input, input_length );
892 break;
893#endif
894#if defined(MBEDTLS_MD4_C)
895 case PSA_ALG_MD4:
896 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
897 input, input_length );
898 break;
899#endif
900#if defined(MBEDTLS_MD5_C)
901 case PSA_ALG_MD5:
902 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
903 input, input_length );
904 break;
905#endif
906#if defined(MBEDTLS_RIPEMD160_C)
907 case PSA_ALG_RIPEMD160:
908 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
909 input, input_length );
910 break;
911#endif
912#if defined(MBEDTLS_SHA1_C)
913 case PSA_ALG_SHA_1:
914 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
915 input, input_length );
916 break;
917#endif
918#if defined(MBEDTLS_SHA256_C)
919 case PSA_ALG_SHA_224:
920 case PSA_ALG_SHA_256:
921 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
922 input, input_length );
923 break;
924#endif
925#if defined(MBEDTLS_SHA512_C)
926 case PSA_ALG_SHA_384:
927 case PSA_ALG_SHA_512:
928 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
929 input, input_length );
930 break;
931#endif
932 default:
933 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
934 break;
935 }
936 if( ret != 0 )
937 psa_hash_abort( operation );
938 return( mbedtls_to_psa_error( ret ) );
939}
940
941psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
942 uint8_t *hash,
943 size_t hash_size,
944 size_t *hash_length )
945{
946 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200947 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100948
949 /* Fill the output buffer with something that isn't a valid hash
950 * (barring an attack on the hash and deliberately-crafted input),
951 * in case the caller doesn't check the return status properly. */
952 *hash_length = actual_hash_length;
953 memset( hash, '!', hash_size );
954
955 if( hash_size < actual_hash_length )
956 return( PSA_ERROR_BUFFER_TOO_SMALL );
957
958 switch( operation->alg )
959 {
960#if defined(MBEDTLS_MD2_C)
961 case PSA_ALG_MD2:
962 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
963 break;
964#endif
965#if defined(MBEDTLS_MD4_C)
966 case PSA_ALG_MD4:
967 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
968 break;
969#endif
970#if defined(MBEDTLS_MD5_C)
971 case PSA_ALG_MD5:
972 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
973 break;
974#endif
975#if defined(MBEDTLS_RIPEMD160_C)
976 case PSA_ALG_RIPEMD160:
977 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
978 break;
979#endif
980#if defined(MBEDTLS_SHA1_C)
981 case PSA_ALG_SHA_1:
982 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
983 break;
984#endif
985#if defined(MBEDTLS_SHA256_C)
986 case PSA_ALG_SHA_224:
987 case PSA_ALG_SHA_256:
988 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
989 break;
990#endif
991#if defined(MBEDTLS_SHA512_C)
992 case PSA_ALG_SHA_384:
993 case PSA_ALG_SHA_512:
994 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
995 break;
996#endif
997 default:
998 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
999 break;
1000 }
1001
1002 if( ret == 0 )
1003 {
1004 return( psa_hash_abort( operation ) );
1005 }
1006 else
1007 {
1008 psa_hash_abort( operation );
1009 return( mbedtls_to_psa_error( ret ) );
1010 }
1011}
1012
Gilles Peskine2d277862018-06-18 15:41:12 +02001013psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1014 const uint8_t *hash,
1015 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001016{
1017 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1018 size_t actual_hash_length;
1019 psa_status_t status = psa_hash_finish( operation,
1020 actual_hash, sizeof( actual_hash ),
1021 &actual_hash_length );
1022 if( status != PSA_SUCCESS )
1023 return( status );
1024 if( actual_hash_length != hash_length )
1025 return( PSA_ERROR_INVALID_SIGNATURE );
1026 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1027 return( PSA_ERROR_INVALID_SIGNATURE );
1028 return( PSA_SUCCESS );
1029}
1030
1031
1032
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001033/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001034/* MAC */
1035/****************************************************************/
1036
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001037static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001038 psa_algorithm_t alg,
1039 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001040 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001041 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001042{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001043 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001044 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001045
1046 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1047 {
1048 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001049 {
1050 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1051 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001052
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001053 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001054 {
1055 case PSA_ALG_STREAM_CIPHER:
1056 mode = MBEDTLS_MODE_STREAM;
1057 break;
1058 case PSA_ALG_CBC_BASE:
1059 mode = MBEDTLS_MODE_CBC;
1060 break;
1061 case PSA_ALG_CFB_BASE:
1062 mode = MBEDTLS_MODE_CFB;
1063 break;
1064 case PSA_ALG_OFB_BASE:
1065 mode = MBEDTLS_MODE_OFB;
1066 break;
1067 case PSA_ALG_CTR:
1068 mode = MBEDTLS_MODE_CTR;
1069 break;
1070 case PSA_ALG_CCM:
1071 mode = MBEDTLS_MODE_CCM;
1072 break;
1073 case PSA_ALG_GCM:
1074 mode = MBEDTLS_MODE_GCM;
1075 break;
1076 default:
1077 return( NULL );
1078 }
1079 }
1080 else if( alg == PSA_ALG_CMAC )
1081 mode = MBEDTLS_MODE_ECB;
1082 else if( alg == PSA_ALG_GMAC )
1083 mode = MBEDTLS_MODE_GCM;
1084 else
1085 return( NULL );
1086
1087 switch( key_type )
1088 {
1089 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001090 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001091 break;
1092 case PSA_KEY_TYPE_DES:
1093 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001094 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001095 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001096 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001097 break;
1098 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001099 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001100 break;
1101 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001102 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001103 break;
1104 default:
1105 return( NULL );
1106 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001107 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001108 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001109
mohammad1603f4f0d612018-06-03 15:04:51 +03001110 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001111}
1112
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001113static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001114{
Gilles Peskine2d277862018-06-18 15:41:12 +02001115 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001116 {
1117 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001118 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001119 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001120 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001121 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001122 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001123 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001124 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001125 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001126 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001127 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001128 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001129 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001130 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001131 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001132 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001133 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001134 return( 128 );
1135 default:
1136 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001137 }
1138}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001139
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001140/* Initialize the MAC operation structure. Once this function has been
1141 * called, psa_mac_abort can run and will do the right thing. */
1142static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1143 psa_algorithm_t alg )
1144{
1145 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1146
1147 operation->alg = alg;
1148 operation->key_set = 0;
1149 operation->iv_set = 0;
1150 operation->iv_required = 0;
1151 operation->has_input = 0;
1152 operation->key_usage_sign = 0;
1153 operation->key_usage_verify = 0;
1154
1155#if defined(MBEDTLS_CMAC_C)
1156 if( alg == PSA_ALG_CMAC )
1157 {
1158 operation->iv_required = 0;
1159 mbedtls_cipher_init( &operation->ctx.cmac );
1160 status = PSA_SUCCESS;
1161 }
1162 else
1163#endif /* MBEDTLS_CMAC_C */
1164#if defined(MBEDTLS_MD_C)
1165 if( PSA_ALG_IS_HMAC( operation->alg ) )
1166 {
1167 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1168 PSA_ALG_HMAC_HASH( alg ) );
1169 }
1170 else
1171#endif /* MBEDTLS_MD_C */
1172 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001173 if( ! PSA_ALG_IS_MAC( alg ) )
1174 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001175 }
1176
1177 if( status != PSA_SUCCESS )
1178 memset( operation, 0, sizeof( *operation ) );
1179 return( status );
1180}
1181
Gilles Peskine8c9def32018-02-08 10:02:12 +01001182psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1183{
1184 switch( operation->alg )
1185 {
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001186 case 0:
1187 return( PSA_SUCCESS );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001188#if defined(MBEDTLS_CMAC_C)
1189 case PSA_ALG_CMAC:
1190 mbedtls_cipher_free( &operation->ctx.cmac );
1191 break;
1192#endif /* MBEDTLS_CMAC_C */
1193 default:
1194#if defined(MBEDTLS_MD_C)
1195 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001196 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001197 unsigned int block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001198 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001199
Gilles Peskine99bc6492018-06-11 17:13:00 +02001200 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001201 return( PSA_ERROR_NOT_SUPPORTED );
1202
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001203 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001204 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001205 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001206 else
1207#endif /* MBEDTLS_MD_C */
1208 return( PSA_ERROR_NOT_SUPPORTED );
1209 }
Moran Peker41deec42018-04-04 15:43:05 +03001210
Gilles Peskine8c9def32018-02-08 10:02:12 +01001211 operation->alg = 0;
1212 operation->key_set = 0;
1213 operation->iv_set = 0;
1214 operation->iv_required = 0;
1215 operation->has_input = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001216 operation->key_usage_sign = 0;
1217 operation->key_usage_verify = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001218
Gilles Peskine8c9def32018-02-08 10:02:12 +01001219 return( PSA_SUCCESS );
1220}
1221
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001222#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001223static int psa_cmac_start( psa_mac_operation_t *operation,
1224 size_t key_bits,
1225 key_slot_t *slot,
1226 const mbedtls_cipher_info_t *cipher_info )
1227{
1228 int ret;
1229
1230 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001231
1232 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1233 if( ret != 0 )
1234 return( ret );
1235
1236 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1237 slot->data.raw.data,
1238 key_bits );
1239 return( ret );
1240}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001241#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001242
Gilles Peskine248051a2018-06-20 16:09:38 +02001243#if defined(MBEDTLS_MD_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001244static int psa_hmac_start( psa_mac_operation_t *operation,
1245 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001246 key_slot_t *slot,
1247 psa_algorithm_t alg )
1248{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001249 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001250 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001251 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001252 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001253 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001254 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001255 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001256 size_t key_length = slot->data.raw.bytes;
1257 psa_status_t status;
1258
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001259 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001260 return( PSA_ERROR_NOT_SUPPORTED );
1261
1262 if( key_type != PSA_KEY_TYPE_HMAC )
1263 return( PSA_ERROR_INVALID_ARGUMENT );
1264
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001265 operation->mac_size = digest_size;
1266
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001267 /* The hash was started earlier in psa_mac_init. */
Gilles Peskined223b522018-06-11 18:12:58 +02001268 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001269 {
1270 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001271 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001272 if( status != PSA_SUCCESS )
1273 return( status );
1274 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001275 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001276 if( status != PSA_SUCCESS )
1277 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001278 }
Gilles Peskined223b522018-06-11 18:12:58 +02001279 else
1280 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001281
Gilles Peskined223b522018-06-11 18:12:58 +02001282 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1283 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001284 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001285 ipad[i] ^= 0x36;
1286 memset( ipad + key_length, 0x36, block_size - key_length );
1287
1288 /* Copy the key material from ipad to opad, flipping the requisite bits,
1289 * and filling the rest of opad with the requisite constant. */
1290 for( i = 0; i < key_length; i++ )
1291 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1292 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001293
1294 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1295 PSA_ALG_HMAC_HASH( alg ) );
1296 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001297 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001298
1299 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1300 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001301
1302cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001303 mbedtls_zeroize( ipad, key_length );
1304 /* opad is in the context. It needs to stay in memory if this function
1305 * succeeds, and it will be wiped by psa_mac_abort() called from
1306 * psa_mac_start in the error case. */
1307
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001308 return( status );
1309}
Gilles Peskine248051a2018-06-20 16:09:38 +02001310#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001311
Gilles Peskine8c9def32018-02-08 10:02:12 +01001312psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1313 psa_key_slot_t key,
1314 psa_algorithm_t alg )
1315{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001316 psa_status_t status;
1317 key_slot_t *slot;
1318 psa_key_type_t key_type;
1319 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001320 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001321
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001322 status = psa_mac_init( operation, alg );
1323 if( status != PSA_SUCCESS )
1324 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001325
1326 status = psa_get_key_information( key, &key_type, &key_bits );
1327 if( status != PSA_SUCCESS )
1328 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001329
Gilles Peskine8c9def32018-02-08 10:02:12 +01001330 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001331 if( slot->type == PSA_KEY_TYPE_NONE )
1332 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001333
Moran Pekerd7326592018-05-29 16:56:39 +03001334 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001335 operation->key_usage_sign = 1;
1336
Moran Pekerd7326592018-05-29 16:56:39 +03001337 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001338 operation->key_usage_verify = 1;
1339
Gilles Peskine8c9def32018-02-08 10:02:12 +01001340 if( ! PSA_ALG_IS_HMAC( alg ) )
1341 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001342 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001343 if( cipher_info == NULL )
1344 return( PSA_ERROR_NOT_SUPPORTED );
1345 operation->mac_size = cipher_info->block_size;
1346 }
1347 switch( alg )
1348 {
1349#if defined(MBEDTLS_CMAC_C)
1350 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001351 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1352 key_bits,
1353 slot,
1354 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001355 break;
1356#endif /* MBEDTLS_CMAC_C */
1357 default:
1358#if defined(MBEDTLS_MD_C)
1359 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001360 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001361 else
1362#endif /* MBEDTLS_MD_C */
1363 return( PSA_ERROR_NOT_SUPPORTED );
1364 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001365
Gilles Peskine8c9def32018-02-08 10:02:12 +01001366 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001367 * context may contain data that needs to be wiped on error. */
1368 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001369 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001370 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001371 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001372 else
1373 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001374 operation->key_set = 1;
1375 }
1376 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001377}
1378
1379psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1380 const uint8_t *input,
1381 size_t input_length )
1382{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001383 int ret = 0 ;
1384 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001385 if( ! operation->key_set )
1386 return( PSA_ERROR_BAD_STATE );
1387 if( operation->iv_required && ! operation->iv_set )
1388 return( PSA_ERROR_BAD_STATE );
1389 operation->has_input = 1;
1390
1391 switch( operation->alg )
1392 {
1393#if defined(MBEDTLS_CMAC_C)
1394 case PSA_ALG_CMAC:
1395 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1396 input, input_length );
1397 break;
1398#endif /* MBEDTLS_CMAC_C */
1399 default:
1400#if defined(MBEDTLS_MD_C)
1401 if( PSA_ALG_IS_HMAC( operation->alg ) )
1402 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001403 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001404 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001405 }
1406 else
1407#endif /* MBEDTLS_MD_C */
1408 {
1409 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1410 }
1411 break;
1412 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001413 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001414 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001415 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001416 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001417 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001418 }
1419
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001420 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001421}
1422
mohammad16036df908f2018-04-02 08:34:15 -07001423static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001424 uint8_t *mac,
1425 size_t mac_size,
1426 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001427{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001428 int ret = 0;
1429 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001430 if( ! operation->key_set )
1431 return( PSA_ERROR_BAD_STATE );
1432 if( operation->iv_required && ! operation->iv_set )
1433 return( PSA_ERROR_BAD_STATE );
1434
1435 /* Fill the output buffer with something that isn't a valid mac
1436 * (barring an attack on the mac and deliberately-crafted input),
1437 * in case the caller doesn't check the return status properly. */
1438 *mac_length = operation->mac_size;
1439 memset( mac, '!', mac_size );
1440
1441 if( mac_size < operation->mac_size )
1442 return( PSA_ERROR_BUFFER_TOO_SMALL );
1443
1444 switch( operation->alg )
1445 {
1446#if defined(MBEDTLS_CMAC_C)
1447 case PSA_ALG_CMAC:
1448 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1449 break;
1450#endif /* MBEDTLS_CMAC_C */
1451 default:
1452#if defined(MBEDTLS_MD_C)
1453 if( PSA_ALG_IS_HMAC( operation->alg ) )
1454 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001455 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001456 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001457 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001458 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001459 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001460
Gilles Peskine99bc6492018-06-11 17:13:00 +02001461 if( block_size == 0 )
1462 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001463
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001464 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001465 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001466 if( status != PSA_SUCCESS )
1467 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001468 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001469
1470 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1471 PSA_ALG_HMAC_HASH( operation->alg ) );
1472 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, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001476 block_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_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001481 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001482 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001483 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001484
1485 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1486 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001487 hmac_cleanup:
1488 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001489 }
1490 else
1491#endif /* MBEDTLS_MD_C */
1492 {
1493 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1494 }
1495 break;
1496 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001497cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001498
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001499 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001500 {
1501 return( psa_mac_abort( operation ) );
1502 }
1503 else
1504 {
1505 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001506 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001507 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001508
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001509 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001510 }
1511}
1512
mohammad16036df908f2018-04-02 08:34:15 -07001513psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1514 uint8_t *mac,
1515 size_t mac_size,
1516 size_t *mac_length )
1517{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001518 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001519 return( PSA_ERROR_NOT_PERMITTED );
1520
Gilles Peskine99bc6492018-06-11 17:13:00 +02001521 return( psa_mac_finish_internal( operation, mac,
1522 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001523}
1524
Gilles Peskine828ed142018-06-18 23:25:51 +02001525#define PSA_MAC_MAX_SIZE \
Gilles Peskine2d277862018-06-18 15:41:12 +02001526 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1527 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001528 MBEDTLS_MAX_BLOCK_LENGTH )
1529psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1530 const uint8_t *mac,
1531 size_t mac_length )
1532{
Gilles Peskine828ed142018-06-18 23:25:51 +02001533 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001534 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001535 psa_status_t status;
1536
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001537 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001538 return( PSA_ERROR_NOT_PERMITTED );
1539
1540 status = psa_mac_finish_internal( operation,
1541 actual_mac, sizeof( actual_mac ),
1542 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001543 if( status != PSA_SUCCESS )
1544 return( status );
1545 if( actual_mac_length != mac_length )
1546 return( PSA_ERROR_INVALID_SIGNATURE );
1547 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1548 return( PSA_ERROR_INVALID_SIGNATURE );
1549 return( PSA_SUCCESS );
1550}
1551
1552
Gilles Peskine20035e32018-02-03 22:44:14 +01001553
Gilles Peskine20035e32018-02-03 22:44:14 +01001554/****************************************************************/
1555/* Asymmetric cryptography */
1556/****************************************************************/
1557
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001558/* Decode the hash algorithm from alg and store the mbedtls encoding in
1559 * md_alg. Verify that the hash length is consistent. */
1560static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1561 size_t hash_length,
1562 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001563{
Gilles Peskine61b91d42018-06-08 16:09:36 +02001564 psa_algorithm_t hash_alg = PSA_ALG_RSA_GET_HASH( alg );
1565 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1566 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1567 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001568 {
1569#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001570 if( hash_length > UINT_MAX )
1571 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001572#endif
1573 }
1574 else
1575 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001576 if( mbedtls_md_get_size( md_info ) != hash_length )
1577 return( PSA_ERROR_INVALID_ARGUMENT );
1578 if( md_info == NULL )
1579 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001580 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001581 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001582}
1583
Gilles Peskine61b91d42018-06-08 16:09:36 +02001584psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1585 psa_algorithm_t alg,
1586 const uint8_t *hash,
1587 size_t hash_length,
1588 const uint8_t *salt,
1589 size_t salt_length,
1590 uint8_t *signature,
1591 size_t signature_size,
1592 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001593{
1594 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001595 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001596 *signature_length = 0;
1597 (void) salt;
1598 (void) salt_length;
1599
Gilles Peskine828ed142018-06-18 23:25:51 +02001600 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine20035e32018-02-03 22:44:14 +01001601 return( PSA_ERROR_EMPTY_SLOT );
1602 slot = &global_data.key_slots[key];
1603 if( slot->type == PSA_KEY_TYPE_NONE )
1604 return( PSA_ERROR_EMPTY_SLOT );
1605 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1606 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001607 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001608 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001609
Gilles Peskine20035e32018-02-03 22:44:14 +01001610#if defined(MBEDTLS_RSA_C)
1611 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1612 {
1613 mbedtls_rsa_context *rsa = slot->data.rsa;
1614 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001615 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001616 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001617 if( status != PSA_SUCCESS )
1618 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001619
Gilles Peskine20035e32018-02-03 22:44:14 +01001620 if( signature_size < rsa->len )
1621 return( PSA_ERROR_BUFFER_TOO_SMALL );
1622#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001623 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001624 {
1625 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1626 MBEDTLS_MD_NONE );
1627 ret = mbedtls_rsa_pkcs1_sign( rsa,
1628 mbedtls_ctr_drbg_random,
1629 &global_data.ctr_drbg,
1630 MBEDTLS_RSA_PRIVATE,
1631 md_alg, hash_length, hash,
1632 signature );
1633 }
1634 else
1635#endif /* MBEDTLS_PKCS1_V15 */
1636#if defined(MBEDTLS_PKCS1_V21)
1637 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1638 {
1639 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1640 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1641 mbedtls_ctr_drbg_random,
1642 &global_data.ctr_drbg,
1643 MBEDTLS_RSA_PRIVATE,
1644 md_alg, hash_length, hash,
1645 signature );
1646 }
1647 else
1648#endif /* MBEDTLS_PKCS1_V21 */
1649 {
1650 return( PSA_ERROR_INVALID_ARGUMENT );
1651 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001652 if( ret == 0 )
1653 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001654 return( mbedtls_to_psa_error( ret ) );
1655 }
1656 else
1657#endif /* defined(MBEDTLS_RSA_C) */
1658#if defined(MBEDTLS_ECP_C)
1659 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1660 {
itayzafrir5c753392018-05-08 11:18:38 +03001661 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1662 int ret;
1663 const mbedtls_md_info_t *md_info;
1664 mbedtls_md_type_t md_alg;
1665 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1666 return( PSA_ERROR_BUFFER_TOO_SMALL );
1667 md_info = mbedtls_md_info_from_psa( alg );
1668 md_alg = mbedtls_md_get_type( md_info );
1669 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001670 signature, signature_length,
1671 mbedtls_ctr_drbg_random,
1672 &global_data.ctr_drbg );
itayzafrir5c753392018-05-08 11:18:38 +03001673 return( mbedtls_to_psa_error( ret ) );
1674 }
1675 else
1676#endif /* defined(MBEDTLS_ECP_C) */
1677 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001678 return( PSA_ERROR_NOT_SUPPORTED );
1679 }
itayzafrir5c753392018-05-08 11:18:38 +03001680}
1681
1682psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1683 psa_algorithm_t alg,
1684 const uint8_t *hash,
1685 size_t hash_length,
1686 const uint8_t *salt,
1687 size_t salt_length,
1688 uint8_t *signature,
1689 size_t signature_size )
1690{
1691 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001692 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001693 (void) salt;
1694 (void) salt_length;
1695
Gilles Peskine828ed142018-06-18 23:25:51 +02001696 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001697 return( PSA_ERROR_INVALID_ARGUMENT );
1698 slot = &global_data.key_slots[key];
1699 if( slot->type == PSA_KEY_TYPE_NONE )
1700 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001701 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001702 return( PSA_ERROR_NOT_PERMITTED );
1703
Gilles Peskine61b91d42018-06-08 16:09:36 +02001704#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001705 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1706 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001707 {
1708 mbedtls_rsa_context *rsa = slot->data.rsa;
1709 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001710 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001711 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001712 if( status != PSA_SUCCESS )
1713 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001714
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001715 if( signature_size < rsa->len )
1716 return( PSA_ERROR_BUFFER_TOO_SMALL );
1717#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001718 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001719 {
1720 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1721 MBEDTLS_MD_NONE );
1722
1723 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001724 mbedtls_ctr_drbg_random,
1725 &global_data.ctr_drbg,
1726 MBEDTLS_RSA_PUBLIC,
1727 md_alg,
1728 hash_length,
1729 hash,
1730 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001731
1732 }
1733 else
1734#endif /* MBEDTLS_PKCS1_V15 */
1735#if defined(MBEDTLS_PKCS1_V21)
1736 if( alg == PSA_ALG_RSA_PSS_MGF1 )
1737 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001738 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1739 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1740 mbedtls_ctr_drbg_random,
1741 &global_data.ctr_drbg,
1742 MBEDTLS_RSA_PUBLIC,
1743 md_alg, hash_length, hash,
1744 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001745 }
1746 else
1747#endif /* MBEDTLS_PKCS1_V21 */
1748 {
1749 return( PSA_ERROR_INVALID_ARGUMENT );
1750 }
1751 return( mbedtls_to_psa_error( ret ) );
1752 }
1753 else
1754#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001755#if defined(MBEDTLS_ECP_C)
1756 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1757 {
1758 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1759 int ret;
Gilles Peskine2d277862018-06-18 15:41:12 +02001760 (void) alg;
Gilles Peskine61b91d42018-06-08 16:09:36 +02001761 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length,
1762 signature, signature_size );
itayzafrir5c753392018-05-08 11:18:38 +03001763 return( mbedtls_to_psa_error( ret ) );
1764 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001765 else
1766#endif /* defined(MBEDTLS_ECP_C) */
1767 {
1768 return( PSA_ERROR_NOT_SUPPORTED );
1769 }
1770}
1771
Gilles Peskine61b91d42018-06-08 16:09:36 +02001772psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1773 psa_algorithm_t alg,
1774 const uint8_t *input,
1775 size_t input_length,
1776 const uint8_t *salt,
1777 size_t salt_length,
1778 uint8_t *output,
1779 size_t output_size,
1780 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001781{
1782 key_slot_t *slot;
1783 (void) salt;
1784 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001785 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001786
Gilles Peskine828ed142018-06-18 23:25:51 +02001787 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001788 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001789 slot = &global_data.key_slots[key];
1790 if( slot->type == PSA_KEY_TYPE_NONE )
1791 return( PSA_ERROR_EMPTY_SLOT );
1792 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1793 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001794 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1795 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001796
1797#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001798 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1799 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001800 {
1801 mbedtls_rsa_context *rsa = slot->data.rsa;
1802 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001803 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001804 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001805#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001806 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001807 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001808 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1809 mbedtls_ctr_drbg_random,
1810 &global_data.ctr_drbg,
1811 MBEDTLS_RSA_PUBLIC,
1812 input_length,
1813 input,
1814 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001815 }
1816 else
1817#endif /* MBEDTLS_PKCS1_V15 */
1818#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001819 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001820 {
1821 return( PSA_ERROR_NOT_SUPPORTED );
1822 }
1823 else
1824#endif /* MBEDTLS_PKCS1_V21 */
1825 {
1826 return( PSA_ERROR_INVALID_ARGUMENT );
1827 }
1828 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001829 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001830 return( mbedtls_to_psa_error( ret ) );
1831 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001832 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001833#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001834 {
1835 return( PSA_ERROR_NOT_SUPPORTED );
1836 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001837}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001838
Gilles Peskine61b91d42018-06-08 16:09:36 +02001839psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1840 psa_algorithm_t alg,
1841 const uint8_t *input,
1842 size_t input_length,
1843 const uint8_t *salt,
1844 size_t salt_length,
1845 uint8_t *output,
1846 size_t output_size,
1847 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001848{
1849 key_slot_t *slot;
1850 (void) salt;
1851 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001852 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001853
Gilles Peskine828ed142018-06-18 23:25:51 +02001854 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001855 return( PSA_ERROR_EMPTY_SLOT );
1856 slot = &global_data.key_slots[key];
1857 if( slot->type == PSA_KEY_TYPE_NONE )
1858 return( PSA_ERROR_EMPTY_SLOT );
1859 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1860 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001861 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1862 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001863
1864#if defined(MBEDTLS_RSA_C)
1865 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1866 {
1867 mbedtls_rsa_context *rsa = slot->data.rsa;
1868 int ret;
1869
Gilles Peskinec4def2f2018-06-08 17:53:48 +02001870 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001871 return( PSA_ERROR_INVALID_ARGUMENT );
1872
1873#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001874 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001875 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001876 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
1877 mbedtls_ctr_drbg_random,
1878 &global_data.ctr_drbg,
1879 MBEDTLS_RSA_PRIVATE,
1880 output_length,
1881 input,
1882 output,
1883 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001884 }
1885 else
1886#endif /* MBEDTLS_PKCS1_V15 */
1887#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine625b01c2018-06-08 17:43:16 +02001888 if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001889 {
1890 return( PSA_ERROR_NOT_SUPPORTED );
1891 }
1892 else
1893#endif /* MBEDTLS_PKCS1_V21 */
1894 {
1895 return( PSA_ERROR_INVALID_ARGUMENT );
1896 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001897
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001898 return( mbedtls_to_psa_error( ret ) );
1899 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001900 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001901#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001902 {
1903 return( PSA_ERROR_NOT_SUPPORTED );
1904 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001905}
Gilles Peskine20035e32018-02-03 22:44:14 +01001906
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001907
1908
mohammad1603503973b2018-03-12 15:59:30 +02001909/****************************************************************/
1910/* Symmetric cryptography */
1911/****************************************************************/
1912
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001913/* Initialize the cipher operation structure. Once this function has been
1914 * called, psa_cipher_abort can run and will do the right thing. */
1915static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
1916 psa_algorithm_t alg )
1917{
Gilles Peskinec06e0712018-06-20 16:21:04 +02001918 if( ! PSA_ALG_IS_CIPHER( alg ) )
1919 {
1920 memset( operation, 0, sizeof( *operation ) );
1921 return( PSA_ERROR_INVALID_ARGUMENT );
1922 }
1923
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001924 operation->alg = alg;
1925 operation->key_set = 0;
1926 operation->iv_set = 0;
1927 operation->iv_required = 1;
1928 operation->iv_size = 0;
1929 operation->block_size = 0;
1930 mbedtls_cipher_init( &operation->ctx.cipher );
1931 return( PSA_SUCCESS );
1932}
1933
Gilles Peskinee553c652018-06-04 16:22:46 +02001934static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1935 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001936 psa_algorithm_t alg,
1937 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001938{
1939 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1940 psa_status_t status;
1941 key_slot_t *slot;
1942 psa_key_type_t key_type;
1943 size_t key_bits;
1944 const mbedtls_cipher_info_t *cipher_info = NULL;
1945
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001946 status = psa_cipher_init( operation, alg );
1947 if( status != PSA_SUCCESS )
1948 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02001949
1950 status = psa_get_key_information( key, &key_type, &key_bits );
1951 if( status != PSA_SUCCESS )
1952 return( status );
1953 slot = &global_data.key_slots[key];
1954
Gilles Peskinebb1072f2018-06-08 18:46:05 +02001955 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02001956 if( cipher_info == NULL )
1957 return( PSA_ERROR_NOT_SUPPORTED );
1958
mohammad1603503973b2018-03-12 15:59:30 +02001959 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03001960 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001961 {
1962 psa_cipher_abort( operation );
1963 return( mbedtls_to_psa_error( ret ) );
1964 }
1965
1966 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
Gilles Peskinee553c652018-06-04 16:22:46 +02001967 key_bits, cipher_operation );
Moran Peker41deec42018-04-04 15:43:05 +03001968 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02001969 {
1970 psa_cipher_abort( operation );
1971 return( mbedtls_to_psa_error( ret ) );
1972 }
1973
mohammad16038481e742018-03-18 13:57:31 +02001974#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03001975 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02001976 {
Gilles Peskine53514202018-06-06 15:11:46 +02001977 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1978 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02001979
Moran Pekera28258c2018-05-29 16:25:04 +03001980 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02001981 {
1982 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
1983 mode = MBEDTLS_PADDING_PKCS7;
1984 break;
1985 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
1986 mode = MBEDTLS_PADDING_NONE;
1987 break;
1988 default:
Moran Pekerae382792018-05-31 14:06:17 +03001989 psa_cipher_abort( operation );
1990 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02001991 }
1992 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03001993 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03001994 {
1995 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02001996 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03001997 }
mohammad16038481e742018-03-18 13:57:31 +02001998 }
1999#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2000
mohammad1603503973b2018-03-12 15:59:30 +02002001 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02002002 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
2003 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
2004 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002005 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02002006 {
mohammad160389e0f462018-04-12 08:48:45 +03002007 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02002008 }
mohammad1603503973b2018-03-12 15:59:30 +02002009
Moran Peker395db872018-05-31 14:07:14 +03002010 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002011}
2012
Gilles Peskinee553c652018-06-04 16:22:46 +02002013psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
2014 psa_key_slot_t key,
2015 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002016{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002017 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002018}
2019
Gilles Peskinee553c652018-06-04 16:22:46 +02002020psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
2021 psa_key_slot_t key,
2022 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002023{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002024 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002025}
2026
Gilles Peskinee553c652018-06-04 16:22:46 +02002027psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
2028 unsigned char *iv,
2029 size_t iv_size,
2030 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002031{
Moran Peker41deec42018-04-04 15:43:05 +03002032 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002033 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002034 return( PSA_ERROR_BAD_STATE );
2035 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002036 {
Moran Peker41deec42018-04-04 15:43:05 +03002037 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2038 goto exit;
2039 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002040 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2041 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002042 if( ret != 0 )
2043 {
2044 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002045 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002046 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002047
mohammad16038481e742018-03-18 13:57:31 +02002048 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03002049 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002050
Moran Peker395db872018-05-31 14:07:14 +03002051exit:
2052 if( ret != PSA_SUCCESS )
2053 psa_cipher_abort( operation );
2054 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002055}
2056
Gilles Peskinee553c652018-06-04 16:22:46 +02002057psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
2058 const unsigned char *iv,
2059 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002060{
Moran Peker41deec42018-04-04 15:43:05 +03002061 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002062 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002063 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002064 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002065 {
Moran Pekerae382792018-05-31 14:06:17 +03002066 psa_cipher_abort( operation );
2067 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002068 }
mohammad1603503973b2018-03-12 15:59:30 +02002069 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002070 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002071 {
2072 psa_cipher_abort( operation );
2073 return( mbedtls_to_psa_error( ret ) );
2074 }
2075
2076 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002077
Moran Peker395db872018-05-31 14:07:14 +03002078 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002079}
2080
Gilles Peskinee553c652018-06-04 16:22:46 +02002081psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2082 const uint8_t *input,
2083 size_t input_length,
2084 unsigned char *output,
2085 size_t output_size,
2086 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002087{
2088 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002089 size_t expected_output_size;
2090 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2091 {
2092 /* Take the unprocessed partial block left over from previous
2093 * update calls, if any, plus the input to this call. Remove
2094 * the last partial block, if any. You get the data that will be
2095 * output in this call. */
2096 expected_output_size =
2097 ( operation->ctx.cipher.unprocessed_len + input_length )
2098 / operation->block_size * operation->block_size;
2099 }
2100 else
2101 {
2102 expected_output_size = input_length;
2103 }
2104 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002105 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002106
mohammad1603503973b2018-03-12 15:59:30 +02002107 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002108 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002109 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002110 {
2111 psa_cipher_abort( operation );
2112 return( mbedtls_to_psa_error( ret ) );
2113 }
2114
Moran Peker395db872018-05-31 14:07:14 +03002115 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002116}
2117
Gilles Peskinee553c652018-06-04 16:22:46 +02002118psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2119 uint8_t *output,
2120 size_t output_size,
2121 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002122{
2123 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002124 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002125
mohammad1603503973b2018-03-12 15:59:30 +02002126 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002127 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002128 psa_cipher_abort( operation );
2129 return( PSA_ERROR_BAD_STATE );
2130 }
2131 if( operation->iv_required && ! operation->iv_set )
2132 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002133 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002134 return( PSA_ERROR_BAD_STATE );
2135 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002136 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2137 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002138 {
Gilles Peskine53514202018-06-06 15:11:46 +02002139 psa_algorithm_t padding_mode =
2140 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002141 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002142 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002143 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002144 return( PSA_ERROR_TAMPERING_DETECTED );
2145 }
Gilles Peskine53514202018-06-06 15:11:46 +02002146 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002147 {
2148 if( operation->ctx.cipher.unprocessed_len != 0 )
2149 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002150 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002151 return( PSA_ERROR_INVALID_ARGUMENT );
2152 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002153 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002154 }
2155
2156 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002157 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002158 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002159 {
2160 psa_cipher_abort( operation );
2161 return( mbedtls_to_psa_error( ret ) );
2162 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002163 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002164 memcpy( output, temp_output_buffer, *output_length );
2165 else
2166 {
2167 psa_cipher_abort( operation );
2168 return( PSA_ERROR_BUFFER_TOO_SMALL );
2169 }
mohammad1603503973b2018-03-12 15:59:30 +02002170
Moran Peker4c80d832018-04-22 20:15:31 +03002171 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002172}
2173
Gilles Peskinee553c652018-06-04 16:22:46 +02002174psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2175{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002176 if( operation->alg == 0 )
2177 return( PSA_SUCCESS );
2178
mohammad1603503973b2018-03-12 15:59:30 +02002179 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002180
Moran Peker41deec42018-04-04 15:43:05 +03002181 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002182 operation->key_set = 0;
2183 operation->iv_set = 0;
2184 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002185 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002186 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002187
Moran Peker395db872018-05-31 14:07:14 +03002188 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002189}
2190
Gilles Peskinea0655c32018-04-30 17:06:50 +02002191
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002192
mohammad16038cc1cee2018-03-28 01:21:33 +03002193/****************************************************************/
2194/* Key Policy */
2195/****************************************************************/
2196
Gilles Peskine2d277862018-06-18 15:41:12 +02002197void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002198{
Gilles Peskine803ce742018-06-18 16:07:14 +02002199 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002200}
2201
Gilles Peskine2d277862018-06-18 15:41:12 +02002202void psa_key_policy_set_usage( psa_key_policy_t *policy,
2203 psa_key_usage_t usage,
2204 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002205{
mohammad16034eed7572018-03-28 05:14:59 -07002206 policy->usage = usage;
2207 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002208}
2209
Gilles Peskine2d277862018-06-18 15:41:12 +02002210psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002211{
mohammad16036df908f2018-04-02 08:34:15 -07002212 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002213}
2214
Gilles Peskine2d277862018-06-18 15:41:12 +02002215psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002216{
mohammad16036df908f2018-04-02 08:34:15 -07002217 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002218}
2219
Gilles Peskine2d277862018-06-18 15:41:12 +02002220psa_status_t psa_set_key_policy( psa_key_slot_t key,
2221 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002222{
2223 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002224
Gilles Peskine828ed142018-06-18 23:25:51 +02002225 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002226 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002227
mohammad16038cc1cee2018-03-28 01:21:33 +03002228 slot = &global_data.key_slots[key];
2229 if( slot->type != PSA_KEY_TYPE_NONE )
2230 return( PSA_ERROR_OCCUPIED_SLOT );
2231
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002232 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2233 PSA_KEY_USAGE_ENCRYPT |
2234 PSA_KEY_USAGE_DECRYPT |
2235 PSA_KEY_USAGE_SIGN |
2236 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002237 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002238
mohammad16036df908f2018-04-02 08:34:15 -07002239 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002240
2241 return( PSA_SUCCESS );
2242}
2243
Gilles Peskine2d277862018-06-18 15:41:12 +02002244psa_status_t psa_get_key_policy( psa_key_slot_t key,
2245 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002246{
2247 key_slot_t *slot;
2248
Gilles Peskine828ed142018-06-18 23:25:51 +02002249 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002250 return( PSA_ERROR_INVALID_ARGUMENT );
2251
2252 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002253
mohammad16036df908f2018-04-02 08:34:15 -07002254 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002255
2256 return( PSA_SUCCESS );
2257}
Gilles Peskine20035e32018-02-03 22:44:14 +01002258
Gilles Peskinea0655c32018-04-30 17:06:50 +02002259
2260
mohammad1603804cd712018-03-20 22:44:08 +02002261/****************************************************************/
2262/* Key Lifetime */
2263/****************************************************************/
2264
Gilles Peskine2d277862018-06-18 15:41:12 +02002265psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2266 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002267{
2268 key_slot_t *slot;
2269
Gilles Peskine828ed142018-06-18 23:25:51 +02002270 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002271 return( PSA_ERROR_INVALID_ARGUMENT );
2272
2273 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002274
mohammad1603804cd712018-03-20 22:44:08 +02002275 *lifetime = slot->lifetime;
2276
2277 return( PSA_SUCCESS );
2278}
2279
Gilles Peskine2d277862018-06-18 15:41:12 +02002280psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2281 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002282{
2283 key_slot_t *slot;
2284
Gilles Peskine828ed142018-06-18 23:25:51 +02002285 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002286 return( PSA_ERROR_INVALID_ARGUMENT );
2287
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002288 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2289 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002290 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2291 return( PSA_ERROR_INVALID_ARGUMENT );
2292
mohammad1603804cd712018-03-20 22:44:08 +02002293 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002294 if( slot->type != PSA_KEY_TYPE_NONE )
2295 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002296
Moran Pekerd7326592018-05-29 16:56:39 +03002297 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002298 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002299
mohammad1603060ad8a2018-03-20 14:28:38 -07002300 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002301
2302 return( PSA_SUCCESS );
2303}
2304
Gilles Peskine20035e32018-02-03 22:44:14 +01002305
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002306
mohammad16035955c982018-04-26 00:53:03 +03002307/****************************************************************/
2308/* AEAD */
2309/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002310
mohammad16035955c982018-04-26 00:53:03 +03002311psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2312 psa_algorithm_t alg,
2313 const uint8_t *nonce,
2314 size_t nonce_length,
2315 const uint8_t *additional_data,
2316 size_t additional_data_length,
2317 const uint8_t *plaintext,
2318 size_t plaintext_length,
2319 uint8_t *ciphertext,
2320 size_t ciphertext_size,
2321 size_t *ciphertext_length )
2322{
2323 int ret;
2324 psa_status_t status;
2325 key_slot_t *slot;
2326 psa_key_type_t key_type;
2327 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002328 uint8_t *tag;
2329 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002330 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002331 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002332
mohammad1603f08a5502018-06-03 15:05:47 +03002333 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002334
mohammad16035955c982018-04-26 00:53:03 +03002335 status = psa_get_key_information( key, &key_type, &key_bits );
2336 if( status != PSA_SUCCESS )
2337 return( status );
2338 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002339 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002340 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002341
mohammad16035ed06212018-06-06 13:09:34 +03002342 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2343 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002344 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002345 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002346
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002347 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002348 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002349
Gilles Peskine2d277862018-06-18 15:41:12 +02002350 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2351 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002352 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002353
mohammad16035955c982018-04-26 00:53:03 +03002354 if( alg == PSA_ALG_GCM )
2355 {
2356 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002357 tag_length = 16;
2358
mohammad160396910d82018-06-04 14:33:00 +03002359 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2360 return( PSA_ERROR_INVALID_ARGUMENT );
2361
mohammad160315223a82018-06-03 17:19:55 +03002362 //make sure we have place to hold the tag in the ciphertext buffer
2363 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002364 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002365
2366 //update the tag pointer to point to the end of the ciphertext_length
2367 tag = ciphertext + plaintext_length;
2368
mohammad16035955c982018-04-26 00:53:03 +03002369 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002370 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002371 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002372 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002373 if( ret != 0 )
2374 {
2375 mbedtls_gcm_free( &gcm );
2376 return( mbedtls_to_psa_error( ret ) );
2377 }
2378 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002379 plaintext_length, nonce,
2380 nonce_length, additional_data,
2381 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002382 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002383 mbedtls_gcm_free( &gcm );
2384 }
2385 else if( alg == PSA_ALG_CCM )
2386 {
2387 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002388 tag_length = 16;
2389
mohammad160396910d82018-06-04 14:33:00 +03002390 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2391 return( PSA_ERROR_INVALID_ARGUMENT );
2392
mohammad160347ddf3d2018-04-26 01:11:21 +03002393 if( nonce_length < 7 || nonce_length > 13 )
2394 return( PSA_ERROR_INVALID_ARGUMENT );
2395
mohammad160315223a82018-06-03 17:19:55 +03002396 //make sure we have place to hold the tag in the ciphertext buffer
2397 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002398 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002399
2400 //update the tag pointer to point to the end of the ciphertext_length
2401 tag = ciphertext + plaintext_length;
2402
mohammad16035955c982018-04-26 00:53:03 +03002403 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002404 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002405 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002406 if( ret != 0 )
2407 {
2408 mbedtls_ccm_free( &ccm );
2409 return( mbedtls_to_psa_error( ret ) );
2410 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002411 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002412 nonce, nonce_length,
2413 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002414 additional_data_length,
2415 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002416 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002417 mbedtls_ccm_free( &ccm );
2418 }
mohammad16035c8845f2018-05-09 05:40:09 -07002419 else
2420 {
mohammad1603554faad2018-06-03 15:07:38 +03002421 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002422 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002423
mohammad160315223a82018-06-03 17:19:55 +03002424 if( ret != 0 )
2425 {
2426 memset( ciphertext, 0, ciphertext_size );
2427 return( mbedtls_to_psa_error( ret ) );
2428 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002429
mohammad160315223a82018-06-03 17:19:55 +03002430 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002431 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002432}
2433
Gilles Peskineee652a32018-06-01 19:23:52 +02002434/* Locate the tag in a ciphertext buffer containing the encrypted data
2435 * followed by the tag. Return the length of the part preceding the tag in
2436 * *plaintext_length. This is the size of the plaintext in modes where
2437 * the encrypted data has the same size as the plaintext, such as
2438 * CCM and GCM. */
2439static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2440 const uint8_t *ciphertext,
2441 size_t ciphertext_length,
2442 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002443 const uint8_t **p_tag )
2444{
2445 size_t payload_length;
2446 if( tag_length > ciphertext_length )
2447 return( PSA_ERROR_INVALID_ARGUMENT );
2448 payload_length = ciphertext_length - tag_length;
2449 if( payload_length > plaintext_size )
2450 return( PSA_ERROR_BUFFER_TOO_SMALL );
2451 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002452 return( PSA_SUCCESS );
2453}
2454
mohammad16035955c982018-04-26 00:53:03 +03002455psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2456 psa_algorithm_t alg,
2457 const uint8_t *nonce,
2458 size_t nonce_length,
2459 const uint8_t *additional_data,
2460 size_t additional_data_length,
2461 const uint8_t *ciphertext,
2462 size_t ciphertext_length,
2463 uint8_t *plaintext,
2464 size_t plaintext_size,
2465 size_t *plaintext_length )
2466{
2467 int ret;
2468 psa_status_t status;
2469 key_slot_t *slot;
2470 psa_key_type_t key_type;
2471 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002472 const uint8_t *tag;
2473 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002474 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002475 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002476
Gilles Peskineee652a32018-06-01 19:23:52 +02002477 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002478
mohammad16035955c982018-04-26 00:53:03 +03002479 status = psa_get_key_information( key, &key_type, &key_bits );
2480 if( status != PSA_SUCCESS )
2481 return( status );
2482 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002483 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002484 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002485
mohammad16035ed06212018-06-06 13:09:34 +03002486 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2487 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002488 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002489 return( PSA_ERROR_NOT_SUPPORTED );
2490
mohammad1603f14394b2018-06-04 14:33:19 +03002491 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2492 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002493
Gilles Peskine2d277862018-06-18 15:41:12 +02002494 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2495 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002496 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002497
mohammad16035955c982018-04-26 00:53:03 +03002498 if( alg == PSA_ALG_GCM )
2499 {
2500 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002501
Gilles Peskineee652a32018-06-01 19:23:52 +02002502 tag_length = 16;
2503 status = psa_aead_unpadded_locate_tag( tag_length,
2504 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002505 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002506 if( status != PSA_SUCCESS )
2507 return( status );
2508
mohammad16035955c982018-04-26 00:53:03 +03002509 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002510 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002511 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002512 if( ret != 0 )
2513 {
2514 mbedtls_gcm_free( &gcm );
2515 return( mbedtls_to_psa_error( ret ) );
2516 }
mohammad16035955c982018-04-26 00:53:03 +03002517
Gilles Peskineee652a32018-06-01 19:23:52 +02002518 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002519 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002520 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002521 additional_data,
2522 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002523 tag, tag_length,
2524 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002525 mbedtls_gcm_free( &gcm );
2526 }
2527 else if( alg == PSA_ALG_CCM )
2528 {
2529 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002530
mohammad160347ddf3d2018-04-26 01:11:21 +03002531 if( nonce_length < 7 || nonce_length > 13 )
2532 return( PSA_ERROR_INVALID_ARGUMENT );
2533
mohammad16039375f842018-06-03 14:28:24 +03002534 tag_length = 16;
2535 status = psa_aead_unpadded_locate_tag( tag_length,
2536 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002537 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002538 if( status != PSA_SUCCESS )
2539 return( status );
2540
mohammad16035955c982018-04-26 00:53:03 +03002541 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002542 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002543 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002544 if( ret != 0 )
2545 {
2546 mbedtls_ccm_free( &ccm );
2547 return( mbedtls_to_psa_error( ret ) );
2548 }
mohammad160360a64d02018-06-03 17:20:42 +03002549 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002550 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002551 additional_data,
2552 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002553 ciphertext, plaintext,
2554 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002555 mbedtls_ccm_free( &ccm );
2556 }
mohammad160339574652018-06-01 04:39:53 -07002557 else
2558 {
mohammad1603554faad2018-06-03 15:07:38 +03002559 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002560 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002561
Gilles Peskineee652a32018-06-01 19:23:52 +02002562 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002563 memset( plaintext, 0, plaintext_size );
2564 else
2565 *plaintext_length = ciphertext_length - tag_length;
2566
Gilles Peskineee652a32018-06-01 19:23:52 +02002567 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002568}
2569
Gilles Peskinea0655c32018-04-30 17:06:50 +02002570
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002571
Gilles Peskine20035e32018-02-03 22:44:14 +01002572/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002573/* Key generation */
2574/****************************************************************/
2575
2576psa_status_t psa_generate_random( uint8_t *output,
2577 size_t output_size )
2578{
2579 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2580 output, output_size );
2581 return( mbedtls_to_psa_error( ret ) );
2582}
2583
2584psa_status_t psa_generate_key( psa_key_slot_t key,
2585 psa_key_type_t type,
2586 size_t bits,
2587 const void *parameters,
2588 size_t parameters_size )
2589{
Gilles Peskine12313cd2018-06-20 00:20:32 +02002590 key_slot_t *slot;
2591
2592 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
2593 return( PSA_ERROR_INVALID_ARGUMENT );
2594 slot = &global_data.key_slots[key];
2595 if( slot->type != PSA_KEY_TYPE_NONE )
2596 return( PSA_ERROR_OCCUPIED_SLOT );
2597 if( parameters == NULL && parameters_size != 0 )
2598 return( PSA_ERROR_INVALID_ARGUMENT );
2599
2600 if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
2601 {
2602 psa_status_t status = prepare_raw_data_slot( type, bits,
2603 &slot->data.raw );
2604 if( status != PSA_SUCCESS )
2605 return( status );
2606 status = psa_generate_random( slot->data.raw.data,
2607 slot->data.raw.bytes );
2608 if( status != PSA_SUCCESS )
2609 {
2610 mbedtls_free( slot->data.raw.data );
2611 return( status );
2612 }
2613#if defined(MBEDTLS_DES_C)
2614 if( type == PSA_KEY_TYPE_DES )
2615 {
2616 mbedtls_des_key_set_parity( slot->data.raw.data );
2617 if( slot->data.raw.bytes >= 16 )
2618 mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
2619 if( slot->data.raw.bytes == 24 )
2620 mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
2621 }
2622#endif /* MBEDTLS_DES_C */
2623 }
2624 else
2625
2626#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
2627 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
2628 {
2629 mbedtls_rsa_context *rsa;
2630 int ret;
2631 int exponent = 65537;
2632 if( parameters != NULL )
2633 {
2634 const unsigned *p = parameters;
2635 if( parameters_size != sizeof( *p ) )
2636 return( PSA_ERROR_INVALID_ARGUMENT );
2637 if( *p > INT_MAX )
2638 return( PSA_ERROR_INVALID_ARGUMENT );
2639 exponent = *p;
2640 }
2641 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
2642 if( rsa == NULL )
2643 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2644 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
2645 ret = mbedtls_rsa_gen_key( rsa,
2646 mbedtls_ctr_drbg_random,
2647 &global_data.ctr_drbg,
2648 bits,
2649 exponent );
2650 if( ret != 0 )
2651 {
2652 mbedtls_rsa_free( rsa );
2653 mbedtls_free( rsa );
2654 return( mbedtls_to_psa_error( ret ) );
2655 }
2656 slot->data.rsa = rsa;
2657 }
2658 else
2659#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
2660
2661#if defined(MBEDTLS_ECP_C)
2662 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
2663 {
2664 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
2665 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
2666 const mbedtls_ecp_curve_info *curve_info =
2667 mbedtls_ecp_curve_info_from_grp_id( grp_id );
2668 mbedtls_ecp_keypair *ecp;
2669 int ret;
2670 if( parameters != NULL )
2671 return( PSA_ERROR_NOT_SUPPORTED );
2672 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
2673 return( PSA_ERROR_NOT_SUPPORTED );
2674 if( curve_info->bit_size != bits )
2675 return( PSA_ERROR_INVALID_ARGUMENT );
2676 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
2677 if( ecp == NULL )
2678 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2679 mbedtls_ecp_keypair_init( ecp );
2680 ret = mbedtls_ecp_gen_key( grp_id, ecp,
2681 mbedtls_ctr_drbg_random,
2682 &global_data.ctr_drbg );
2683 if( ret != 0 )
2684 {
2685 mbedtls_ecp_keypair_free( ecp );
2686 mbedtls_free( ecp );
2687 return( mbedtls_to_psa_error( ret ) );
2688 }
2689 slot->data.ecp = ecp;
2690 }
2691 else
2692#endif /* MBEDTLS_ECP_C */
2693
2694 return( PSA_ERROR_NOT_SUPPORTED );
2695
2696 slot->type = type;
2697 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02002698}
2699
2700
2701/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002702/* Module setup */
2703/****************************************************************/
2704
Gilles Peskinee59236f2018-01-27 23:32:46 +01002705void mbedtls_psa_crypto_free( void )
2706{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002707 size_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02002708 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002709 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002710 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2711 mbedtls_entropy_free( &global_data.entropy );
2712 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2713}
2714
2715psa_status_t psa_crypto_init( void )
2716{
2717 int ret;
2718 const unsigned char drbg_seed[] = "PSA";
2719
2720 if( global_data.initialized != 0 )
2721 return( PSA_SUCCESS );
2722
2723 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2724 mbedtls_entropy_init( &global_data.entropy );
2725 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2726
2727 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2728 mbedtls_entropy_func,
2729 &global_data.entropy,
2730 drbg_seed, sizeof( drbg_seed ) - 1 );
2731 if( ret != 0 )
2732 goto exit;
2733
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002734 global_data.initialized = 1;
2735
Gilles Peskinee59236f2018-01-27 23:32:46 +01002736exit:
2737 if( ret != 0 )
2738 mbedtls_psa_crypto_free( );
2739 return( mbedtls_to_psa_error( ret ) );
2740}
2741
2742#endif /* MBEDTLS_PSA_CRYPTO_C */