blob: cc59ca800e7fd75774c362e6062574f9e323124a [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)
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +030029/*
30 * In case MBEDTLS_PSA_CRYPTO_SPM is defined the code is built for SPM (Secure
31 * Partition Manager) integration which separate the code into two parts
32 * NSPE (Non-Secure Process Environment) and SPE (Secure Process Environment).
33 * In this mode an additional header file should be included.
34 */
mohammad160327010052018-07-03 13:16:15 +030035#if defined(MBEDTLS_PSA_CRYPTO_SPM)
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +030036/*
37 * PSA_CRYPTO_SECURE means that this file is compiled to the SPE side.
38 * some headers will be affected by this flag.
39 */
mohammad160327010052018-07-03 13:16:15 +030040#define PSA_CRYPTO_SECURE 1
41#include "crypto_spe.h"
42#endif
43
Gilles Peskinee59236f2018-01-27 23:32:46 +010044#include "psa/crypto.h"
45
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010046#include <stdlib.h>
47#include <string.h>
48#if defined(MBEDTLS_PLATFORM_C)
49#include "mbedtls/platform.h"
50#else
51#define mbedtls_calloc calloc
52#define mbedtls_free free
53#endif
54
Gilles Peskinea5905292018-02-07 20:59:33 +010055#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020056#include "mbedtls/asn1.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020057#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010058#include "mbedtls/blowfish.h"
59#include "mbedtls/camellia.h"
60#include "mbedtls/cipher.h"
61#include "mbedtls/ccm.h"
62#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010063#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010064#include "mbedtls/des.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010065#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010066#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010067#include "mbedtls/error.h"
68#include "mbedtls/gcm.h"
69#include "mbedtls/md2.h"
70#include "mbedtls/md4.h"
71#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010072#include "mbedtls/md.h"
73#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010074#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010075#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010076#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010077#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010078#include "mbedtls/sha1.h"
79#include "mbedtls/sha256.h"
80#include "mbedtls/sha512.h"
81#include "mbedtls/xtea.h"
82
Gilles Peskinee59236f2018-01-27 23:32:46 +010083
84
85/* Implementation that should never be optimized out by the compiler */
86static void mbedtls_zeroize( void *v, size_t n )
87{
88 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
89}
90
Gilles Peskine9ef733f2018-02-07 21:05:37 +010091/* constant-time buffer comparison */
92static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
93{
94 size_t i;
95 unsigned char diff = 0;
96
97 for( i = 0; i < n; i++ )
98 diff |= a[i] ^ b[i];
99
100 return( diff );
101}
102
103
104
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100105/****************************************************************/
106/* Global data, support functions and library management */
107/****************************************************************/
108
109/* Number of key slots (plus one because 0 is not used).
110 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +0200111#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100112
Gilles Peskine2d277862018-06-18 15:41:12 +0200113typedef struct
114{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100115 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300116 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200117 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200118 union
119 {
120 struct raw_data
121 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100122 uint8_t *data;
123 size_t bytes;
124 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100125#if defined(MBEDTLS_RSA_C)
126 mbedtls_rsa_context *rsa;
127#endif /* MBEDTLS_RSA_C */
128#if defined(MBEDTLS_ECP_C)
129 mbedtls_ecp_keypair *ecp;
130#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100131 } data;
132} key_slot_t;
133
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200134static int key_type_is_raw_bytes( psa_key_type_t type )
135{
136 psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
137 return( category == PSA_KEY_TYPE_RAW_DATA ||
138 category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
139}
140
Gilles Peskine2d277862018-06-18 15:41:12 +0200141typedef struct
142{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100143 int initialized;
144 mbedtls_entropy_context entropy;
145 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200146 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100147} psa_global_data_t;
148
149static psa_global_data_t global_data;
150
151static psa_status_t mbedtls_to_psa_error( int ret )
152{
Gilles Peskinea5905292018-02-07 20:59:33 +0100153 /* If there's both a high-level code and low-level code, dispatch on
154 * the high-level code. */
155 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100156 {
157 case 0:
158 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100159
160 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
161 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
162 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
163 return( PSA_ERROR_NOT_SUPPORTED );
164 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
165 return( PSA_ERROR_HARDWARE_FAILURE );
166
167 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
168 return( PSA_ERROR_HARDWARE_FAILURE );
169
Gilles Peskine9a944802018-06-21 09:35:35 +0200170 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
171 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
172 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
173 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
174 case MBEDTLS_ERR_ASN1_INVALID_DATA:
175 return( PSA_ERROR_INVALID_ARGUMENT );
176 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
177 return( PSA_ERROR_INSUFFICIENT_MEMORY );
178 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
179 return( PSA_ERROR_BUFFER_TOO_SMALL );
180
Gilles Peskinea5905292018-02-07 20:59:33 +0100181 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
182 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
183 return( PSA_ERROR_NOT_SUPPORTED );
184 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
185 return( PSA_ERROR_HARDWARE_FAILURE );
186
187 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
188 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
189 return( PSA_ERROR_NOT_SUPPORTED );
190 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
191 return( PSA_ERROR_HARDWARE_FAILURE );
192
193 case MBEDTLS_ERR_CCM_BAD_INPUT:
194 return( PSA_ERROR_INVALID_ARGUMENT );
195 case MBEDTLS_ERR_CCM_AUTH_FAILED:
196 return( PSA_ERROR_INVALID_SIGNATURE );
197 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
198 return( PSA_ERROR_HARDWARE_FAILURE );
199
200 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
201 return( PSA_ERROR_NOT_SUPPORTED );
202 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
203 return( PSA_ERROR_INVALID_ARGUMENT );
204 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
205 return( PSA_ERROR_INSUFFICIENT_MEMORY );
206 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
207 return( PSA_ERROR_INVALID_PADDING );
208 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
209 return( PSA_ERROR_BAD_STATE );
210 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
211 return( PSA_ERROR_INVALID_SIGNATURE );
212 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
213 return( PSA_ERROR_TAMPERING_DETECTED );
214 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
215 return( PSA_ERROR_HARDWARE_FAILURE );
216
217 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
218 return( PSA_ERROR_HARDWARE_FAILURE );
219
220 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
221 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
222 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
223 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
224 return( PSA_ERROR_NOT_SUPPORTED );
225 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
226 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
227
228 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
229 return( PSA_ERROR_NOT_SUPPORTED );
230 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
231 return( PSA_ERROR_HARDWARE_FAILURE );
232
Gilles Peskinee59236f2018-01-27 23:32:46 +0100233 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
234 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
235 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
236 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100237
238 case MBEDTLS_ERR_GCM_AUTH_FAILED:
239 return( PSA_ERROR_INVALID_SIGNATURE );
240 case MBEDTLS_ERR_GCM_BAD_INPUT:
241 return( PSA_ERROR_NOT_SUPPORTED );
242 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
243 return( PSA_ERROR_HARDWARE_FAILURE );
244
245 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
246 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
247 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
248 return( PSA_ERROR_HARDWARE_FAILURE );
249
250 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
251 return( PSA_ERROR_NOT_SUPPORTED );
252 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
253 return( PSA_ERROR_INVALID_ARGUMENT );
254 case MBEDTLS_ERR_MD_ALLOC_FAILED:
255 return( PSA_ERROR_INSUFFICIENT_MEMORY );
256 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
257 return( PSA_ERROR_STORAGE_FAILURE );
258 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
259 return( PSA_ERROR_HARDWARE_FAILURE );
260
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100261 case MBEDTLS_ERR_PK_ALLOC_FAILED:
262 return( PSA_ERROR_INSUFFICIENT_MEMORY );
263 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
264 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
265 return( PSA_ERROR_INVALID_ARGUMENT );
266 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100267 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100268 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
269 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
270 return( PSA_ERROR_INVALID_ARGUMENT );
271 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
272 return( PSA_ERROR_NOT_SUPPORTED );
273 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
274 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
275 return( PSA_ERROR_NOT_PERMITTED );
276 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
277 return( PSA_ERROR_INVALID_ARGUMENT );
278 case MBEDTLS_ERR_PK_INVALID_ALG:
279 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
280 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
281 return( PSA_ERROR_NOT_SUPPORTED );
282 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
283 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100284 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
285 return( PSA_ERROR_HARDWARE_FAILURE );
286
287 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
288 return( PSA_ERROR_HARDWARE_FAILURE );
289
290 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
291 return( PSA_ERROR_INVALID_ARGUMENT );
292 case MBEDTLS_ERR_RSA_INVALID_PADDING:
293 return( PSA_ERROR_INVALID_PADDING );
294 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
295 return( PSA_ERROR_HARDWARE_FAILURE );
296 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
297 return( PSA_ERROR_INVALID_ARGUMENT );
298 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
299 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
300 return( PSA_ERROR_TAMPERING_DETECTED );
301 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
302 return( PSA_ERROR_INVALID_SIGNATURE );
303 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
304 return( PSA_ERROR_BUFFER_TOO_SMALL );
305 case MBEDTLS_ERR_RSA_RNG_FAILED:
306 return( PSA_ERROR_INSUFFICIENT_MEMORY );
307 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
308 return( PSA_ERROR_NOT_SUPPORTED );
309 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
310 return( PSA_ERROR_HARDWARE_FAILURE );
311
312 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
313 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
314 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
315 return( PSA_ERROR_HARDWARE_FAILURE );
316
317 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
318 return( PSA_ERROR_INVALID_ARGUMENT );
319 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
320 return( PSA_ERROR_HARDWARE_FAILURE );
321
itayzafrir5c753392018-05-08 11:18:38 +0300322 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300323 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300324 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300325 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
326 return( PSA_ERROR_BUFFER_TOO_SMALL );
327 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
328 return( PSA_ERROR_NOT_SUPPORTED );
329 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
330 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
331 return( PSA_ERROR_INVALID_SIGNATURE );
332 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
333 return( PSA_ERROR_INSUFFICIENT_MEMORY );
334 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
335 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300336
Gilles Peskinee59236f2018-01-27 23:32:46 +0100337 default:
338 return( PSA_ERROR_UNKNOWN_ERROR );
339 }
340}
341
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200342/* Retrieve a key slot, occupied or not. */
343static psa_status_t psa_get_key_slot( psa_key_slot_t key,
344 key_slot_t **p_slot )
345{
346 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
347 return( PSA_ERROR_INVALID_ARGUMENT );
348
349 *p_slot = &global_data.key_slots[key];
350 return( PSA_SUCCESS );
351}
352
353/* Retrieve an empty key slot (slot with no key data, but possibly
354 * with some metadata such as a policy). */
355static psa_status_t psa_get_empty_key_slot( psa_key_slot_t key,
356 key_slot_t **p_slot )
357{
358 psa_status_t status;
359 key_slot_t *slot = NULL;
360
361 *p_slot = NULL;
362
363 status = psa_get_key_slot( key, &slot );
364 if( status != PSA_SUCCESS )
365 return( status );
366
367 if( slot->type != PSA_KEY_TYPE_NONE )
368 return( PSA_ERROR_OCCUPIED_SLOT );
369
370 *p_slot = slot;
371 return( status );
372}
373
Jaeden Amerob4fa8c92018-07-11 15:57:44 +0100374/** Retrieve a slot which must contain a key. The key must have allow all the
375 * usage flags set in \p usage. If \p alg is nonzero, the key must allow
376 * operations with this algorithm. */
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200377static psa_status_t psa_get_key_from_slot( psa_key_slot_t key,
378 key_slot_t **p_slot,
379 psa_key_usage_t usage,
380 psa_algorithm_t alg )
381{
382 psa_status_t status;
383 key_slot_t *slot = NULL;
384
385 *p_slot = NULL;
386
387 status = psa_get_key_slot( key, &slot );
388 if( status != PSA_SUCCESS )
389 return( status );
390 if( slot->type == PSA_KEY_TYPE_NONE )
391 return( PSA_ERROR_EMPTY_SLOT );
392
393 /* Enforce that usage policy for the key slot contains all the flags
394 * required by the usage parameter. There is one exception: public
395 * keys can always be exported, so we treat public key objects as
396 * if they had the export flag. */
397 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
398 usage &= ~PSA_KEY_USAGE_EXPORT;
399 if( ( slot->policy.usage & usage ) != usage )
400 return( PSA_ERROR_NOT_PERMITTED );
401 if( alg != 0 && ( alg != slot->policy.alg ) )
402 return( PSA_ERROR_NOT_PERMITTED );
403
404 *p_slot = slot;
405 return( PSA_SUCCESS );
406}
407
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200408
409
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100410/****************************************************************/
411/* Key management */
412/****************************************************************/
413
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200414static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
415{
416 switch( grpid )
417 {
418 case MBEDTLS_ECP_DP_SECP192R1:
419 return( PSA_ECC_CURVE_SECP192R1 );
420 case MBEDTLS_ECP_DP_SECP224R1:
421 return( PSA_ECC_CURVE_SECP224R1 );
422 case MBEDTLS_ECP_DP_SECP256R1:
423 return( PSA_ECC_CURVE_SECP256R1 );
424 case MBEDTLS_ECP_DP_SECP384R1:
425 return( PSA_ECC_CURVE_SECP384R1 );
426 case MBEDTLS_ECP_DP_SECP521R1:
427 return( PSA_ECC_CURVE_SECP521R1 );
428 case MBEDTLS_ECP_DP_BP256R1:
429 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
430 case MBEDTLS_ECP_DP_BP384R1:
431 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
432 case MBEDTLS_ECP_DP_BP512R1:
433 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
434 case MBEDTLS_ECP_DP_CURVE25519:
435 return( PSA_ECC_CURVE_CURVE25519 );
436 case MBEDTLS_ECP_DP_SECP192K1:
437 return( PSA_ECC_CURVE_SECP192K1 );
438 case MBEDTLS_ECP_DP_SECP224K1:
439 return( PSA_ECC_CURVE_SECP224K1 );
440 case MBEDTLS_ECP_DP_SECP256K1:
441 return( PSA_ECC_CURVE_SECP256K1 );
442 case MBEDTLS_ECP_DP_CURVE448:
443 return( PSA_ECC_CURVE_CURVE448 );
444 default:
445 return( 0 );
446 }
447}
448
Gilles Peskine12313cd2018-06-20 00:20:32 +0200449static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
450{
451 switch( curve )
452 {
453 case PSA_ECC_CURVE_SECP192R1:
454 return( MBEDTLS_ECP_DP_SECP192R1 );
455 case PSA_ECC_CURVE_SECP224R1:
456 return( MBEDTLS_ECP_DP_SECP224R1 );
457 case PSA_ECC_CURVE_SECP256R1:
458 return( MBEDTLS_ECP_DP_SECP256R1 );
459 case PSA_ECC_CURVE_SECP384R1:
460 return( MBEDTLS_ECP_DP_SECP384R1 );
461 case PSA_ECC_CURVE_SECP521R1:
462 return( MBEDTLS_ECP_DP_SECP521R1 );
463 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
464 return( MBEDTLS_ECP_DP_BP256R1 );
465 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
466 return( MBEDTLS_ECP_DP_BP384R1 );
467 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
468 return( MBEDTLS_ECP_DP_BP512R1 );
469 case PSA_ECC_CURVE_CURVE25519:
470 return( MBEDTLS_ECP_DP_CURVE25519 );
471 case PSA_ECC_CURVE_SECP192K1:
472 return( MBEDTLS_ECP_DP_SECP192K1 );
473 case PSA_ECC_CURVE_SECP224K1:
474 return( MBEDTLS_ECP_DP_SECP224K1 );
475 case PSA_ECC_CURVE_SECP256K1:
476 return( MBEDTLS_ECP_DP_SECP256K1 );
477 case PSA_ECC_CURVE_CURVE448:
478 return( MBEDTLS_ECP_DP_CURVE448 );
479 default:
480 return( MBEDTLS_ECP_DP_NONE );
481 }
482}
483
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200484static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
485 size_t bits,
486 struct raw_data *raw )
487{
488 /* Check that the bit size is acceptable for the key type */
489 switch( type )
490 {
491 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200492 if( bits == 0 )
493 {
494 raw->bytes = 0;
495 raw->data = NULL;
496 return( PSA_SUCCESS );
497 }
498 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200499#if defined(MBEDTLS_MD_C)
500 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200501#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200502 case PSA_KEY_TYPE_DERIVE:
503 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200504#if defined(MBEDTLS_AES_C)
505 case PSA_KEY_TYPE_AES:
506 if( bits != 128 && bits != 192 && bits != 256 )
507 return( PSA_ERROR_INVALID_ARGUMENT );
508 break;
509#endif
510#if defined(MBEDTLS_CAMELLIA_C)
511 case PSA_KEY_TYPE_CAMELLIA:
512 if( bits != 128 && bits != 192 && bits != 256 )
513 return( PSA_ERROR_INVALID_ARGUMENT );
514 break;
515#endif
516#if defined(MBEDTLS_DES_C)
517 case PSA_KEY_TYPE_DES:
518 if( bits != 64 && bits != 128 && bits != 192 )
519 return( PSA_ERROR_INVALID_ARGUMENT );
520 break;
521#endif
522#if defined(MBEDTLS_ARC4_C)
523 case PSA_KEY_TYPE_ARC4:
524 if( bits < 8 || bits > 2048 )
525 return( PSA_ERROR_INVALID_ARGUMENT );
526 break;
527#endif
528 default:
529 return( PSA_ERROR_NOT_SUPPORTED );
530 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200531 if( bits % 8 != 0 )
532 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200533
534 /* Allocate memory for the key */
535 raw->bytes = PSA_BITS_TO_BYTES( bits );
536 raw->data = mbedtls_calloc( 1, raw->bytes );
537 if( raw->data == NULL )
538 {
539 raw->bytes = 0;
540 return( PSA_ERROR_INSUFFICIENT_MEMORY );
541 }
542 return( PSA_SUCCESS );
543}
544
Gilles Peskine2d277862018-06-18 15:41:12 +0200545psa_status_t psa_import_key( psa_key_slot_t key,
546 psa_key_type_t type,
547 const uint8_t *data,
548 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100549{
550 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200551 psa_status_t status = PSA_SUCCESS;
552 status = psa_get_empty_key_slot( key, &slot );
553 if( status != PSA_SUCCESS )
554 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100555
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200556 if( key_type_is_raw_bytes( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100557 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100558 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100559 if( data_length > SIZE_MAX / 8 )
560 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200561 status = prepare_raw_data_slot( type,
562 PSA_BYTES_TO_BITS( data_length ),
563 &slot->data.raw );
564 if( status != PSA_SUCCESS )
565 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200566 if( data_length != 0 )
567 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100568 }
569 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100570#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100571 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
572 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
573 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100574 {
575 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100576 mbedtls_pk_context pk;
577 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100578 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
579 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
580 else
581 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100582 if( ret != 0 )
583 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100584 switch( mbedtls_pk_get_type( &pk ) )
585 {
586#if defined(MBEDTLS_RSA_C)
587 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100588 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
589 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskineaf3baab2018-06-27 22:55:52 +0200590 {
591 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( pk );
592 size_t bits = mbedtls_rsa_get_bitlen( rsa );
593 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
Gilles Peskine1ae05142018-06-30 17:46:59 +0200594 {
595 status = PSA_ERROR_NOT_SUPPORTED;
596 break;
597 }
Gilles Peskineaf3baab2018-06-27 22:55:52 +0200598 slot->data.rsa = rsa;
599 }
Gilles Peskine969ac722018-01-28 18:16:59 +0100600 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200601 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100602 break;
603#endif /* MBEDTLS_RSA_C */
604#if defined(MBEDTLS_ECP_C)
605 case MBEDTLS_PK_ECKEY:
606 if( PSA_KEY_TYPE_IS_ECC( type ) )
607 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200608 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
609 psa_ecc_curve_t actual_curve =
610 mbedtls_ecc_group_to_psa( ecp->grp.id );
611 psa_ecc_curve_t expected_curve =
612 PSA_KEY_TYPE_GET_CURVE( type );
613 if( actual_curve != expected_curve )
Gilles Peskinec648d692018-06-28 08:46:13 +0200614 {
615 status = PSA_ERROR_INVALID_ARGUMENT;
616 break;
617 }
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200618 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100619 }
620 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200621 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100622 break;
623#endif /* MBEDTLS_ECP_C */
624 default:
Gilles Peskinec648d692018-06-28 08:46:13 +0200625 status = PSA_ERROR_INVALID_ARGUMENT;
626 break;
627 }
628 /* Free the content of the pk object only on error. On success,
629 * the content of the object has been stored in the slot. */
630 if( status != PSA_SUCCESS )
631 {
632 mbedtls_pk_free( &pk );
633 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100634 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100635 }
636 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100637#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100638 {
639 return( PSA_ERROR_NOT_SUPPORTED );
640 }
641
642 slot->type = type;
643 return( PSA_SUCCESS );
644}
645
Gilles Peskine2d277862018-06-18 15:41:12 +0200646psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100647{
648 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200649 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100650
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200651 status = psa_get_key_slot( key, &slot );
652 if( status != PSA_SUCCESS )
653 return( status );
654
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100655 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200656 {
657 /* No key material to clean, but do zeroize the slot below to wipe
658 * metadata such as policies. */
659 }
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200660 else if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100661 {
662 mbedtls_free( slot->data.raw.data );
663 }
664 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100665#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100666 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
667 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100668 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100669 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100670 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100671 }
672 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100673#endif /* defined(MBEDTLS_RSA_C) */
674#if defined(MBEDTLS_ECP_C)
675 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
676 {
677 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100678 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100679 }
680 else
681#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100682 {
683 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100684 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100685 return( PSA_ERROR_TAMPERING_DETECTED );
686 }
687
688 mbedtls_zeroize( slot, sizeof( *slot ) );
689 return( PSA_SUCCESS );
690}
691
Gilles Peskineb870b182018-07-06 16:02:09 +0200692/* Return the size of the key in the given slot, in bits. */
693static size_t psa_get_key_bits( const key_slot_t *slot )
694{
695 if( key_type_is_raw_bytes( slot->type ) )
696 return( slot->data.raw.bytes * 8 );
697#if defined(MBEDTLS_RSA_C)
698 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
699 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
700 return( mbedtls_rsa_get_bitlen( slot->data.rsa ) );
701#endif /* defined(MBEDTLS_RSA_C) */
702#if defined(MBEDTLS_ECP_C)
703 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
704 return( slot->data.ecp->grp.pbits );
705#endif /* defined(MBEDTLS_ECP_C) */
706 /* Shouldn't happen except on an empty slot. */
707 return( 0 );
708}
709
Gilles Peskine2d277862018-06-18 15:41:12 +0200710psa_status_t psa_get_key_information( psa_key_slot_t key,
711 psa_key_type_t *type,
712 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100713{
714 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200715 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100716
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100717 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200718 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100719 if( bits != NULL )
720 *bits = 0;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200721 status = psa_get_key_slot( key, &slot );
722 if( status != PSA_SUCCESS )
723 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +0200724
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100725 if( slot->type == PSA_KEY_TYPE_NONE )
726 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200727 if( type != NULL )
728 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +0200729 if( bits != NULL )
730 *bits = psa_get_key_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100731 return( PSA_SUCCESS );
732}
733
Gilles Peskine2d277862018-06-18 15:41:12 +0200734static psa_status_t psa_internal_export_key( psa_key_slot_t key,
735 uint8_t *data,
736 size_t data_size,
737 size_t *data_length,
738 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100739{
740 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200741 psa_status_t status;
742 /* Exporting a public key doesn't require a usage flag. If we're
743 * called by psa_export_public_key(), don't require the EXPORT flag.
744 * If we're called by psa_export_key(), do require the EXPORT flag;
745 * if the key turns out to be public key object, psa_get_key_from_slot()
746 * will ignore this flag. */
747 psa_key_usage_t usage = export_public_key ? 0 : PSA_KEY_USAGE_EXPORT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100748
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100749 /* Set the key to empty now, so that even when there are errors, we always
750 * set data_length to a value between 0 and data_size. On error, setting
751 * the key to empty is a good choice because an empty key representation is
752 * unlikely to be accepted anywhere. */
753 *data_length = 0;
754
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200755 status = psa_get_key_from_slot( key, &slot, usage, 0 );
756 if( status != PSA_SUCCESS )
757 return( status );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200758 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300759 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300760
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200761 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100762 {
763 if( slot->data.raw.bytes > data_size )
764 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200765 if( slot->data.raw.bytes != 0 )
766 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100767 *data_length = slot->data.raw.bytes;
768 return( PSA_SUCCESS );
769 }
770 else
Moran Peker17e36e12018-05-02 12:55:20 +0300771 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100772#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100773 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300774 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
775 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100776 {
Moran Pekera998bc62018-04-16 18:16:20 +0300777 mbedtls_pk_context pk;
778 int ret;
779 mbedtls_pk_init( &pk );
780 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
781 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
782 {
783 pk.pk_info = &mbedtls_rsa_info;
784 pk.pk_ctx = slot->data.rsa;
785 }
786 else
787 {
788 pk.pk_info = &mbedtls_eckey_info;
789 pk.pk_ctx = slot->data.ecp;
790 }
Moran Pekerd7326592018-05-29 16:56:39 +0300791 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300792 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300793 else
794 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300795 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200796 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200797 /* If data_size is 0 then data may be NULL and then the
798 * call to memset would have undefined behavior. */
799 if( data_size != 0 )
800 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300801 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200802 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200803 /* The mbedtls_pk_xxx functions write to the end of the buffer.
804 * Move the data to the beginning and erase remaining data
805 * at the original location. */
806 if( 2 * (size_t) ret <= data_size )
807 {
808 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200809 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200810 }
811 else if( (size_t) ret < data_size )
812 {
813 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200814 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200815 }
Moran Pekera998bc62018-04-16 18:16:20 +0300816 *data_length = ret;
817 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100818 }
819 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100820#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300821 {
822 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200823 it is valid for a special-purpose implementation to omit
824 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300825 return( PSA_ERROR_NOT_SUPPORTED );
826 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100827 }
828}
829
Gilles Peskine2d277862018-06-18 15:41:12 +0200830psa_status_t psa_export_key( psa_key_slot_t key,
831 uint8_t *data,
832 size_t data_size,
833 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300834{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200835 return( psa_internal_export_key( key, data, data_size,
836 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100837}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100838
Gilles Peskine2d277862018-06-18 15:41:12 +0200839psa_status_t psa_export_public_key( psa_key_slot_t key,
840 uint8_t *data,
841 size_t data_size,
842 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300843{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200844 return( psa_internal_export_key( key, data, data_size,
845 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300846}
847
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200848
849
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100850/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100851/* Message digests */
852/****************************************************************/
853
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100854static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100855{
856 switch( alg )
857 {
858#if defined(MBEDTLS_MD2_C)
859 case PSA_ALG_MD2:
860 return( &mbedtls_md2_info );
861#endif
862#if defined(MBEDTLS_MD4_C)
863 case PSA_ALG_MD4:
864 return( &mbedtls_md4_info );
865#endif
866#if defined(MBEDTLS_MD5_C)
867 case PSA_ALG_MD5:
868 return( &mbedtls_md5_info );
869#endif
870#if defined(MBEDTLS_RIPEMD160_C)
871 case PSA_ALG_RIPEMD160:
872 return( &mbedtls_ripemd160_info );
873#endif
874#if defined(MBEDTLS_SHA1_C)
875 case PSA_ALG_SHA_1:
876 return( &mbedtls_sha1_info );
877#endif
878#if defined(MBEDTLS_SHA256_C)
879 case PSA_ALG_SHA_224:
880 return( &mbedtls_sha224_info );
881 case PSA_ALG_SHA_256:
882 return( &mbedtls_sha256_info );
883#endif
884#if defined(MBEDTLS_SHA512_C)
885 case PSA_ALG_SHA_384:
886 return( &mbedtls_sha384_info );
887 case PSA_ALG_SHA_512:
888 return( &mbedtls_sha512_info );
889#endif
890 default:
891 return( NULL );
892 }
893}
894
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100895psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
896{
897 switch( operation->alg )
898 {
Gilles Peskine81736312018-06-26 15:04:31 +0200899 case 0:
900 /* The object has (apparently) been initialized but it is not
901 * in use. It's ok to call abort on such an object, and there's
902 * nothing to do. */
903 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100904#if defined(MBEDTLS_MD2_C)
905 case PSA_ALG_MD2:
906 mbedtls_md2_free( &operation->ctx.md2 );
907 break;
908#endif
909#if defined(MBEDTLS_MD4_C)
910 case PSA_ALG_MD4:
911 mbedtls_md4_free( &operation->ctx.md4 );
912 break;
913#endif
914#if defined(MBEDTLS_MD5_C)
915 case PSA_ALG_MD5:
916 mbedtls_md5_free( &operation->ctx.md5 );
917 break;
918#endif
919#if defined(MBEDTLS_RIPEMD160_C)
920 case PSA_ALG_RIPEMD160:
921 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
922 break;
923#endif
924#if defined(MBEDTLS_SHA1_C)
925 case PSA_ALG_SHA_1:
926 mbedtls_sha1_free( &operation->ctx.sha1 );
927 break;
928#endif
929#if defined(MBEDTLS_SHA256_C)
930 case PSA_ALG_SHA_224:
931 case PSA_ALG_SHA_256:
932 mbedtls_sha256_free( &operation->ctx.sha256 );
933 break;
934#endif
935#if defined(MBEDTLS_SHA512_C)
936 case PSA_ALG_SHA_384:
937 case PSA_ALG_SHA_512:
938 mbedtls_sha512_free( &operation->ctx.sha512 );
939 break;
940#endif
941 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +0200942 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100943 }
944 operation->alg = 0;
945 return( PSA_SUCCESS );
946}
947
Gilles Peskineda8191d1c2018-07-08 19:46:38 +0200948psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100949 psa_algorithm_t alg )
950{
951 int ret;
952 operation->alg = 0;
953 switch( alg )
954 {
955#if defined(MBEDTLS_MD2_C)
956 case PSA_ALG_MD2:
957 mbedtls_md2_init( &operation->ctx.md2 );
958 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
959 break;
960#endif
961#if defined(MBEDTLS_MD4_C)
962 case PSA_ALG_MD4:
963 mbedtls_md4_init( &operation->ctx.md4 );
964 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
965 break;
966#endif
967#if defined(MBEDTLS_MD5_C)
968 case PSA_ALG_MD5:
969 mbedtls_md5_init( &operation->ctx.md5 );
970 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
971 break;
972#endif
973#if defined(MBEDTLS_RIPEMD160_C)
974 case PSA_ALG_RIPEMD160:
975 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
976 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
977 break;
978#endif
979#if defined(MBEDTLS_SHA1_C)
980 case PSA_ALG_SHA_1:
981 mbedtls_sha1_init( &operation->ctx.sha1 );
982 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
983 break;
984#endif
985#if defined(MBEDTLS_SHA256_C)
986 case PSA_ALG_SHA_224:
987 mbedtls_sha256_init( &operation->ctx.sha256 );
988 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
989 break;
990 case PSA_ALG_SHA_256:
991 mbedtls_sha256_init( &operation->ctx.sha256 );
992 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
993 break;
994#endif
995#if defined(MBEDTLS_SHA512_C)
996 case PSA_ALG_SHA_384:
997 mbedtls_sha512_init( &operation->ctx.sha512 );
998 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
999 break;
1000 case PSA_ALG_SHA_512:
1001 mbedtls_sha512_init( &operation->ctx.sha512 );
1002 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1003 break;
1004#endif
1005 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001006 return( PSA_ALG_IS_HASH( alg ) ?
1007 PSA_ERROR_NOT_SUPPORTED :
1008 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001009 }
1010 if( ret == 0 )
1011 operation->alg = alg;
1012 else
1013 psa_hash_abort( operation );
1014 return( mbedtls_to_psa_error( ret ) );
1015}
1016
1017psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1018 const uint8_t *input,
1019 size_t input_length )
1020{
1021 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001022
1023 /* Don't require hash implementations to behave correctly on a
1024 * zero-length input, which may have an invalid pointer. */
1025 if( input_length == 0 )
1026 return( PSA_SUCCESS );
1027
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001028 switch( operation->alg )
1029 {
1030#if defined(MBEDTLS_MD2_C)
1031 case PSA_ALG_MD2:
1032 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1033 input, input_length );
1034 break;
1035#endif
1036#if defined(MBEDTLS_MD4_C)
1037 case PSA_ALG_MD4:
1038 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1039 input, input_length );
1040 break;
1041#endif
1042#if defined(MBEDTLS_MD5_C)
1043 case PSA_ALG_MD5:
1044 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1045 input, input_length );
1046 break;
1047#endif
1048#if defined(MBEDTLS_RIPEMD160_C)
1049 case PSA_ALG_RIPEMD160:
1050 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1051 input, input_length );
1052 break;
1053#endif
1054#if defined(MBEDTLS_SHA1_C)
1055 case PSA_ALG_SHA_1:
1056 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1057 input, input_length );
1058 break;
1059#endif
1060#if defined(MBEDTLS_SHA256_C)
1061 case PSA_ALG_SHA_224:
1062 case PSA_ALG_SHA_256:
1063 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1064 input, input_length );
1065 break;
1066#endif
1067#if defined(MBEDTLS_SHA512_C)
1068 case PSA_ALG_SHA_384:
1069 case PSA_ALG_SHA_512:
1070 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1071 input, input_length );
1072 break;
1073#endif
1074 default:
1075 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1076 break;
1077 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001078
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001079 if( ret != 0 )
1080 psa_hash_abort( operation );
1081 return( mbedtls_to_psa_error( ret ) );
1082}
1083
1084psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1085 uint8_t *hash,
1086 size_t hash_size,
1087 size_t *hash_length )
1088{
1089 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001090 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001091
1092 /* Fill the output buffer with something that isn't a valid hash
1093 * (barring an attack on the hash and deliberately-crafted input),
1094 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001095 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001096 /* If hash_size is 0 then hash may be NULL and then the
1097 * call to memset would have undefined behavior. */
1098 if( hash_size != 0 )
1099 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001100
1101 if( hash_size < actual_hash_length )
1102 return( PSA_ERROR_BUFFER_TOO_SMALL );
1103
1104 switch( operation->alg )
1105 {
1106#if defined(MBEDTLS_MD2_C)
1107 case PSA_ALG_MD2:
1108 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1109 break;
1110#endif
1111#if defined(MBEDTLS_MD4_C)
1112 case PSA_ALG_MD4:
1113 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1114 break;
1115#endif
1116#if defined(MBEDTLS_MD5_C)
1117 case PSA_ALG_MD5:
1118 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1119 break;
1120#endif
1121#if defined(MBEDTLS_RIPEMD160_C)
1122 case PSA_ALG_RIPEMD160:
1123 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1124 break;
1125#endif
1126#if defined(MBEDTLS_SHA1_C)
1127 case PSA_ALG_SHA_1:
1128 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1129 break;
1130#endif
1131#if defined(MBEDTLS_SHA256_C)
1132 case PSA_ALG_SHA_224:
1133 case PSA_ALG_SHA_256:
1134 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1135 break;
1136#endif
1137#if defined(MBEDTLS_SHA512_C)
1138 case PSA_ALG_SHA_384:
1139 case PSA_ALG_SHA_512:
1140 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1141 break;
1142#endif
1143 default:
1144 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1145 break;
1146 }
1147
1148 if( ret == 0 )
1149 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001150 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001151 return( psa_hash_abort( operation ) );
1152 }
1153 else
1154 {
1155 psa_hash_abort( operation );
1156 return( mbedtls_to_psa_error( ret ) );
1157 }
1158}
1159
Gilles Peskine2d277862018-06-18 15:41:12 +02001160psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1161 const uint8_t *hash,
1162 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001163{
1164 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1165 size_t actual_hash_length;
1166 psa_status_t status = psa_hash_finish( operation,
1167 actual_hash, sizeof( actual_hash ),
1168 &actual_hash_length );
1169 if( status != PSA_SUCCESS )
1170 return( status );
1171 if( actual_hash_length != hash_length )
1172 return( PSA_ERROR_INVALID_SIGNATURE );
1173 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1174 return( PSA_ERROR_INVALID_SIGNATURE );
1175 return( PSA_SUCCESS );
1176}
1177
1178
1179
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001180/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001181/* MAC */
1182/****************************************************************/
1183
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001184static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001185 psa_algorithm_t alg,
1186 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001187 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001188 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001189{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001190 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001191 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001192
1193 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1194 {
1195 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001196 {
1197 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1198 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001199
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001200 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001201 {
Gilles Peskine5d1888e2018-07-12 00:32:42 +02001202 case PSA_ALG_STREAM_CIPHER_BASE:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001203 mode = MBEDTLS_MODE_STREAM;
1204 break;
1205 case PSA_ALG_CBC_BASE:
1206 mode = MBEDTLS_MODE_CBC;
1207 break;
1208 case PSA_ALG_CFB_BASE:
1209 mode = MBEDTLS_MODE_CFB;
1210 break;
1211 case PSA_ALG_OFB_BASE:
1212 mode = MBEDTLS_MODE_OFB;
1213 break;
1214 case PSA_ALG_CTR:
1215 mode = MBEDTLS_MODE_CTR;
1216 break;
1217 case PSA_ALG_CCM:
1218 mode = MBEDTLS_MODE_CCM;
1219 break;
1220 case PSA_ALG_GCM:
1221 mode = MBEDTLS_MODE_GCM;
1222 break;
1223 default:
1224 return( NULL );
1225 }
1226 }
1227 else if( alg == PSA_ALG_CMAC )
1228 mode = MBEDTLS_MODE_ECB;
1229 else if( alg == PSA_ALG_GMAC )
1230 mode = MBEDTLS_MODE_GCM;
1231 else
1232 return( NULL );
1233
1234 switch( key_type )
1235 {
1236 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001237 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001238 break;
1239 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001240 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1241 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001242 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001243 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001244 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001245 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001246 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1247 * but two-key Triple-DES is functionally three-key Triple-DES
1248 * with K1=K3, so that's how we present it to mbedtls. */
1249 if( key_bits == 128 )
1250 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001251 break;
1252 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001253 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001254 break;
1255 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001256 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001257 break;
1258 default:
1259 return( NULL );
1260 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001261 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001262 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001263
Jaeden Amero23bbb752018-06-26 14:16:54 +01001264 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1265 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001266}
1267
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001268static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001269{
Gilles Peskine2d277862018-06-18 15:41:12 +02001270 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001271 {
1272 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001273 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001274 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001275 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001276 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001277 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001278 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001279 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001280 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001281 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001282 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001283 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001284 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001285 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001286 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001287 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001288 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001289 return( 128 );
1290 default:
1291 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001292 }
1293}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001294
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001295/* Initialize the MAC operation structure. Once this function has been
1296 * called, psa_mac_abort can run and will do the right thing. */
1297static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1298 psa_algorithm_t alg )
1299{
1300 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1301
1302 operation->alg = alg;
1303 operation->key_set = 0;
1304 operation->iv_set = 0;
1305 operation->iv_required = 0;
1306 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001307 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001308
1309#if defined(MBEDTLS_CMAC_C)
1310 if( alg == PSA_ALG_CMAC )
1311 {
1312 operation->iv_required = 0;
1313 mbedtls_cipher_init( &operation->ctx.cmac );
1314 status = PSA_SUCCESS;
1315 }
1316 else
1317#endif /* MBEDTLS_CMAC_C */
1318#if defined(MBEDTLS_MD_C)
1319 if( PSA_ALG_IS_HMAC( operation->alg ) )
1320 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02001321 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
1322 operation->ctx.hmac.hash_ctx.alg = 0;
1323 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001324 }
1325 else
1326#endif /* MBEDTLS_MD_C */
1327 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001328 if( ! PSA_ALG_IS_MAC( alg ) )
1329 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001330 }
1331
1332 if( status != PSA_SUCCESS )
1333 memset( operation, 0, sizeof( *operation ) );
1334 return( status );
1335}
1336
Gilles Peskine01126fa2018-07-12 17:04:55 +02001337#if defined(MBEDTLS_MD_C)
1338static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
1339{
1340 mbedtls_zeroize( hmac->opad, sizeof( hmac->opad ) );
1341 return( psa_hash_abort( &hmac->hash_ctx ) );
1342}
1343#endif /* MBEDTLS_MD_C */
1344
Gilles Peskine8c9def32018-02-08 10:02:12 +01001345psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1346{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001347 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001348 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001349 /* The object has (apparently) been initialized but it is not
1350 * in use. It's ok to call abort on such an object, and there's
1351 * nothing to do. */
1352 return( PSA_SUCCESS );
1353 }
1354 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001355#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001356 if( operation->alg == PSA_ALG_CMAC )
1357 {
1358 mbedtls_cipher_free( &operation->ctx.cmac );
1359 }
1360 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001361#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001362#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001363 if( PSA_ALG_IS_HMAC( operation->alg ) )
1364 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001365 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001366 }
1367 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001368#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001369 {
1370 /* Sanity check (shouldn't happen: operation->alg should
1371 * always have been initialized to a valid value). */
1372 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001373 }
Moran Peker41deec42018-04-04 15:43:05 +03001374
Gilles Peskine8c9def32018-02-08 10:02:12 +01001375 operation->alg = 0;
1376 operation->key_set = 0;
1377 operation->iv_set = 0;
1378 operation->iv_required = 0;
1379 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001380 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001381
Gilles Peskine8c9def32018-02-08 10:02:12 +01001382 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001383
1384bad_state:
1385 /* If abort is called on an uninitialized object, we can't trust
1386 * anything. Wipe the object in case it contains confidential data.
1387 * This may result in a memory leak if a pointer gets overwritten,
1388 * but it's too late to do anything about this. */
1389 memset( operation, 0, sizeof( *operation ) );
1390 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001391}
1392
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001393#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02001394static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001395 size_t key_bits,
1396 key_slot_t *slot,
1397 const mbedtls_cipher_info_t *cipher_info )
1398{
1399 int ret;
1400
1401 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001402
1403 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1404 if( ret != 0 )
1405 return( ret );
1406
1407 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1408 slot->data.raw.data,
1409 key_bits );
1410 return( ret );
1411}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001412#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001413
Gilles Peskine248051a2018-06-20 16:09:38 +02001414#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02001415static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
1416 const uint8_t *key,
1417 size_t key_length,
1418 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001419{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001420 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001421 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001422 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001423 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001424 psa_status_t status;
1425
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001426 /* Sanity checks on block_size, to guarantee that there won't be a buffer
1427 * overflow below. This should never trigger if the hash algorithm
1428 * is implemented correctly. */
1429 /* The size checks against the ipad and opad buffers cannot be written
1430 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
1431 * because that triggers -Wlogical-op on GCC 7.3. */
1432 if( block_size > sizeof( ipad ) )
1433 return( PSA_ERROR_NOT_SUPPORTED );
1434 if( block_size > sizeof( hmac->opad ) )
1435 return( PSA_ERROR_NOT_SUPPORTED );
1436 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001437 return( PSA_ERROR_NOT_SUPPORTED );
1438
Gilles Peskined223b522018-06-11 18:12:58 +02001439 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001440 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001441 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
1442 if( status != PSA_SUCCESS )
1443 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001444 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001445 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001446 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001447 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001448 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001449 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001450 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001451 }
Gilles Peskine96889972018-07-12 17:07:03 +02001452 /* A 0-length key is not commonly used in HMAC when used as a MAC,
1453 * but it is permitted. It is common when HMAC is used in HKDF, for
1454 * example. Don't call `memcpy` in the 0-length because `key` could be
1455 * an invalid pointer which would make the behavior undefined. */
1456 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001457 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001458
Gilles Peskined223b522018-06-11 18:12:58 +02001459 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1460 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001461 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001462 ipad[i] ^= 0x36;
1463 memset( ipad + key_length, 0x36, block_size - key_length );
1464
1465 /* Copy the key material from ipad to opad, flipping the requisite bits,
1466 * and filling the rest of opad with the requisite constant. */
1467 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001468 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1469 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001470
Gilles Peskine01126fa2018-07-12 17:04:55 +02001471 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001472 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001473 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001474
Gilles Peskine01126fa2018-07-12 17:04:55 +02001475 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001476
1477cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001478 mbedtls_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001479
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001480 return( status );
1481}
Gilles Peskine248051a2018-06-20 16:09:38 +02001482#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001483
Gilles Peskine89167cb2018-07-08 20:12:23 +02001484static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
1485 psa_key_slot_t key,
1486 psa_algorithm_t alg,
1487 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001488{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001489 psa_status_t status;
1490 key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001491 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001492 psa_key_usage_t usage =
1493 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001494
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001495 status = psa_mac_init( operation, alg );
1496 if( status != PSA_SUCCESS )
1497 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001498 if( is_sign )
1499 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001500
Gilles Peskine89167cb2018-07-08 20:12:23 +02001501 status = psa_get_key_from_slot( key, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001502 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001503 goto exit;
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02001504 key_bits = psa_get_key_bits( slot );
1505
Gilles Peskine8c9def32018-02-08 10:02:12 +01001506#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001507 if( alg == PSA_ALG_CMAC )
1508 {
1509 const mbedtls_cipher_info_t *cipher_info =
1510 mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
1511 int ret;
1512 if( cipher_info == NULL )
1513 {
1514 status = PSA_ERROR_NOT_SUPPORTED;
1515 goto exit;
1516 }
1517 operation->mac_size = cipher_info->block_size;
1518 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
1519 status = mbedtls_to_psa_error( ret );
1520 }
1521 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001522#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001523#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001524 if( PSA_ALG_IS_HMAC( alg ) )
1525 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001526 psa_algorithm_t hash_alg = PSA_ALG_HMAC_HASH( alg );
1527 if( hash_alg == 0 )
1528 {
1529 status = PSA_ERROR_NOT_SUPPORTED;
1530 goto exit;
1531 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001532
1533 operation->mac_size = PSA_HASH_SIZE( hash_alg );
1534 /* Sanity check. This shouldn't fail on a valid configuration. */
1535 if( operation->mac_size == 0 ||
1536 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
1537 {
1538 status = PSA_ERROR_NOT_SUPPORTED;
1539 goto exit;
1540 }
1541
Gilles Peskine01126fa2018-07-12 17:04:55 +02001542 if( slot->type != PSA_KEY_TYPE_HMAC )
1543 {
1544 status = PSA_ERROR_INVALID_ARGUMENT;
1545 goto exit;
1546 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001547
Gilles Peskine01126fa2018-07-12 17:04:55 +02001548 status = psa_hmac_setup_internal( &operation->ctx.hmac,
1549 slot->data.raw.data,
1550 slot->data.raw.bytes,
1551 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001552 }
1553 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001554#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001555 {
1556 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001557 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001558
Gilles Peskinefbfac682018-07-08 20:51:54 +02001559exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001560 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001561 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001562 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001563 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001564 else
1565 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001566 operation->key_set = 1;
1567 }
1568 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001569}
1570
Gilles Peskine89167cb2018-07-08 20:12:23 +02001571psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
1572 psa_key_slot_t key,
1573 psa_algorithm_t alg )
1574{
1575 return( psa_mac_setup( operation, key, alg, 1 ) );
1576}
1577
1578psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
1579 psa_key_slot_t key,
1580 psa_algorithm_t alg )
1581{
1582 return( psa_mac_setup( operation, key, alg, 0 ) );
1583}
1584
Gilles Peskine8c9def32018-02-08 10:02:12 +01001585psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1586 const uint8_t *input,
1587 size_t input_length )
1588{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001589 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001590 if( ! operation->key_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001591 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001592 if( operation->iv_required && ! operation->iv_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001593 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001594 operation->has_input = 1;
1595
Gilles Peskine8c9def32018-02-08 10:02:12 +01001596#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001597 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001598 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001599 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1600 input, input_length );
1601 status = mbedtls_to_psa_error( ret );
1602 }
1603 else
1604#endif /* MBEDTLS_CMAC_C */
1605#if defined(MBEDTLS_MD_C)
1606 if( PSA_ALG_IS_HMAC( operation->alg ) )
1607 {
1608 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
1609 input_length );
1610 }
1611 else
1612#endif /* MBEDTLS_MD_C */
1613 {
1614 /* This shouldn't happen if `operation` was initialized by
1615 * a setup function. */
1616 status = PSA_ERROR_BAD_STATE;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001617 }
1618
Gilles Peskinefbfac682018-07-08 20:51:54 +02001619cleanup:
1620 if( status != PSA_SUCCESS )
1621 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001622 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001623}
1624
Gilles Peskine01126fa2018-07-12 17:04:55 +02001625#if defined(MBEDTLS_MD_C)
1626static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
1627 uint8_t *mac,
1628 size_t mac_size )
1629{
1630 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
1631 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
1632 size_t hash_size = 0;
1633 size_t block_size = psa_get_hash_block_size( hash_alg );
1634 psa_status_t status;
1635
Gilles Peskine01126fa2018-07-12 17:04:55 +02001636 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1637 if( status != PSA_SUCCESS )
1638 return( status );
1639 /* From here on, tmp needs to be wiped. */
1640
1641 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
1642 if( status != PSA_SUCCESS )
1643 goto exit;
1644
1645 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
1646 if( status != PSA_SUCCESS )
1647 goto exit;
1648
1649 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
1650 if( status != PSA_SUCCESS )
1651 goto exit;
1652
1653 status = psa_hash_finish( &hmac->hash_ctx, mac, mac_size, &hash_size );
1654
1655exit:
1656 mbedtls_zeroize( tmp, hash_size );
1657 return( status );
1658}
1659#endif /* MBEDTLS_MD_C */
1660
mohammad16036df908f2018-04-02 08:34:15 -07001661static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001662 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001663 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001664{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02001665 if( ! operation->key_set )
1666 return( PSA_ERROR_BAD_STATE );
1667 if( operation->iv_required && ! operation->iv_set )
1668 return( PSA_ERROR_BAD_STATE );
1669
Gilles Peskine8c9def32018-02-08 10:02:12 +01001670 if( mac_size < operation->mac_size )
1671 return( PSA_ERROR_BUFFER_TOO_SMALL );
1672
Gilles Peskine8c9def32018-02-08 10:02:12 +01001673#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001674 if( operation->alg == PSA_ALG_CMAC )
1675 {
1676 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1677 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001678 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02001679 else
1680#endif /* MBEDTLS_CMAC_C */
1681#if defined(MBEDTLS_MD_C)
1682 if( PSA_ALG_IS_HMAC( operation->alg ) )
1683 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001684 return( psa_hmac_finish_internal( &operation->ctx.hmac,
1685 mac, mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001686 }
1687 else
1688#endif /* MBEDTLS_MD_C */
1689 {
1690 /* This shouldn't happen if `operation` was initialized by
1691 * a setup function. */
1692 return( PSA_ERROR_BAD_STATE );
1693 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001694}
1695
Gilles Peskineacd4be32018-07-08 19:56:25 +02001696psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
1697 uint8_t *mac,
1698 size_t mac_size,
1699 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07001700{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001701 psa_status_t status;
1702
1703 /* Fill the output buffer with something that isn't a valid mac
1704 * (barring an attack on the mac and deliberately-crafted input),
1705 * in case the caller doesn't check the return status properly. */
1706 *mac_length = mac_size;
1707 /* If mac_size is 0 then mac may be NULL and then the
1708 * call to memset would have undefined behavior. */
1709 if( mac_size != 0 )
1710 memset( mac, '!', mac_size );
1711
Gilles Peskine89167cb2018-07-08 20:12:23 +02001712 if( ! operation->is_sign )
1713 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001714 status = PSA_ERROR_BAD_STATE;
1715 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001716 }
mohammad16036df908f2018-04-02 08:34:15 -07001717
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001718 status = psa_mac_finish_internal( operation, mac, mac_size );
1719
1720cleanup:
1721 if( status == PSA_SUCCESS )
1722 {
1723 status = psa_mac_abort( operation );
1724 if( status == PSA_SUCCESS )
1725 *mac_length = operation->mac_size;
1726 else
1727 memset( mac, '!', mac_size );
1728 }
1729 else
1730 psa_mac_abort( operation );
1731 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07001732}
1733
Gilles Peskineacd4be32018-07-08 19:56:25 +02001734psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
1735 const uint8_t *mac,
1736 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001737{
Gilles Peskine828ed142018-06-18 23:25:51 +02001738 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07001739 psa_status_t status;
1740
Gilles Peskine89167cb2018-07-08 20:12:23 +02001741 if( operation->is_sign )
1742 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001743 status = PSA_ERROR_BAD_STATE;
1744 goto cleanup;
1745 }
1746 if( operation->mac_size != mac_length )
1747 {
1748 status = PSA_ERROR_INVALID_SIGNATURE;
1749 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001750 }
mohammad16036df908f2018-04-02 08:34:15 -07001751
1752 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001753 actual_mac, sizeof( actual_mac ) );
1754
1755 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
1756 status = PSA_ERROR_INVALID_SIGNATURE;
1757
1758cleanup:
1759 if( status == PSA_SUCCESS )
1760 status = psa_mac_abort( operation );
1761 else
1762 psa_mac_abort( operation );
1763
1764 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001765}
1766
1767
Gilles Peskine20035e32018-02-03 22:44:14 +01001768
Gilles Peskine20035e32018-02-03 22:44:14 +01001769/****************************************************************/
1770/* Asymmetric cryptography */
1771/****************************************************************/
1772
Gilles Peskine2b450e32018-06-27 15:42:46 +02001773#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001774/* Decode the hash algorithm from alg and store the mbedtls encoding in
1775 * md_alg. Verify that the hash length is consistent. */
1776static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1777 size_t hash_length,
1778 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001779{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02001780 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001781 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1782 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1783 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001784 {
1785#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001786 if( hash_length > UINT_MAX )
1787 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001788#endif
1789 }
1790 else
1791 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001792 if( mbedtls_md_get_size( md_info ) != hash_length )
1793 return( PSA_ERROR_INVALID_ARGUMENT );
1794 if( md_info == NULL )
1795 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001796 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001797 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001798}
1799
Gilles Peskine2b450e32018-06-27 15:42:46 +02001800static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
1801 psa_algorithm_t alg,
1802 const uint8_t *hash,
1803 size_t hash_length,
1804 uint8_t *signature,
1805 size_t signature_size,
1806 size_t *signature_length )
1807{
1808 psa_status_t status;
1809 int ret;
1810 mbedtls_md_type_t md_alg;
1811
1812 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1813 if( status != PSA_SUCCESS )
1814 return( status );
1815
1816 if( signature_size < rsa->len )
1817 return( PSA_ERROR_BUFFER_TOO_SMALL );
1818
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001819 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1820 * hash_length will fit and return an error if it doesn't. */
1821#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1822#if SIZE_MAX > UINT_MAX
1823 if( hash_length > UINT_MAX )
1824 return( PSA_ERROR_NOT_SUPPORTED );
1825#endif
1826#endif
1827
Gilles Peskine2b450e32018-06-27 15:42:46 +02001828#if defined(MBEDTLS_PKCS1_V15)
1829 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1830 {
1831 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1832 MBEDTLS_MD_NONE );
1833 ret = mbedtls_rsa_pkcs1_sign( rsa,
1834 mbedtls_ctr_drbg_random,
1835 &global_data.ctr_drbg,
1836 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001837 md_alg,
1838 (unsigned int) hash_length,
1839 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001840 signature );
1841 }
1842 else
1843#endif /* MBEDTLS_PKCS1_V15 */
1844#if defined(MBEDTLS_PKCS1_V21)
1845 if( PSA_ALG_IS_RSA_PSS( alg ) )
1846 {
1847 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1848 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1849 mbedtls_ctr_drbg_random,
1850 &global_data.ctr_drbg,
1851 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001852 md_alg,
1853 (unsigned int) hash_length,
1854 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001855 signature );
1856 }
1857 else
1858#endif /* MBEDTLS_PKCS1_V21 */
1859 {
1860 return( PSA_ERROR_INVALID_ARGUMENT );
1861 }
1862
1863 if( ret == 0 )
1864 *signature_length = rsa->len;
1865 return( mbedtls_to_psa_error( ret ) );
1866}
1867
1868static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
1869 psa_algorithm_t alg,
1870 const uint8_t *hash,
1871 size_t hash_length,
1872 const uint8_t *signature,
1873 size_t signature_length )
1874{
1875 psa_status_t status;
1876 int ret;
1877 mbedtls_md_type_t md_alg;
1878
1879 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1880 if( status != PSA_SUCCESS )
1881 return( status );
1882
1883 if( signature_length < rsa->len )
1884 return( PSA_ERROR_BUFFER_TOO_SMALL );
1885
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001886#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1887#if SIZE_MAX > UINT_MAX
1888 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1889 * hash_length will fit and return an error if it doesn't. */
1890 if( hash_length > UINT_MAX )
1891 return( PSA_ERROR_NOT_SUPPORTED );
1892#endif
1893#endif
1894
Gilles Peskine2b450e32018-06-27 15:42:46 +02001895#if defined(MBEDTLS_PKCS1_V15)
1896 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1897 {
1898 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1899 MBEDTLS_MD_NONE );
1900 ret = mbedtls_rsa_pkcs1_verify( rsa,
1901 mbedtls_ctr_drbg_random,
1902 &global_data.ctr_drbg,
1903 MBEDTLS_RSA_PUBLIC,
1904 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001905 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001906 hash,
1907 signature );
1908 }
1909 else
1910#endif /* MBEDTLS_PKCS1_V15 */
1911#if defined(MBEDTLS_PKCS1_V21)
1912 if( PSA_ALG_IS_RSA_PSS( alg ) )
1913 {
1914 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1915 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1916 mbedtls_ctr_drbg_random,
1917 &global_data.ctr_drbg,
1918 MBEDTLS_RSA_PUBLIC,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001919 md_alg,
1920 (unsigned int) hash_length,
1921 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001922 signature );
1923 }
1924 else
1925#endif /* MBEDTLS_PKCS1_V21 */
1926 {
1927 return( PSA_ERROR_INVALID_ARGUMENT );
1928 }
1929 return( mbedtls_to_psa_error( ret ) );
1930}
1931#endif /* MBEDTLS_RSA_C */
1932
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001933#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001934/* `ecp` cannot be const because `ecp->grp` needs to be non-const
1935 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
1936 * (even though these functions don't modify it). */
1937static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
1938 psa_algorithm_t alg,
1939 const uint8_t *hash,
1940 size_t hash_length,
1941 uint8_t *signature,
1942 size_t signature_size,
1943 size_t *signature_length )
1944{
1945 int ret;
1946 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001947 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001948 mbedtls_mpi_init( &r );
1949 mbedtls_mpi_init( &s );
1950
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001951 if( signature_size < 2 * curve_bytes )
1952 {
1953 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
1954 goto cleanup;
1955 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001956
1957 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
1958 {
1959 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
1960 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1961 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
1962 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
1963 hash, hash_length,
1964 md_alg ) );
1965 }
1966 else
1967 {
1968 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
1969 hash, hash_length,
1970 mbedtls_ctr_drbg_random,
1971 &global_data.ctr_drbg ) );
1972 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001973
1974 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
1975 signature,
1976 curve_bytes ) );
1977 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
1978 signature + curve_bytes,
1979 curve_bytes ) );
1980
1981cleanup:
1982 mbedtls_mpi_free( &r );
1983 mbedtls_mpi_free( &s );
1984 if( ret == 0 )
1985 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001986 return( mbedtls_to_psa_error( ret ) );
1987}
1988
1989static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
1990 const uint8_t *hash,
1991 size_t hash_length,
1992 const uint8_t *signature,
1993 size_t signature_length )
1994{
1995 int ret;
1996 mbedtls_mpi r, s;
1997 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
1998 mbedtls_mpi_init( &r );
1999 mbedtls_mpi_init( &s );
2000
2001 if( signature_length != 2 * curve_bytes )
2002 return( PSA_ERROR_INVALID_SIGNATURE );
2003
2004 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2005 signature,
2006 curve_bytes ) );
2007 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2008 signature + curve_bytes,
2009 curve_bytes ) );
2010
2011 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2012 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002013
2014cleanup:
2015 mbedtls_mpi_free( &r );
2016 mbedtls_mpi_free( &s );
2017 return( mbedtls_to_psa_error( ret ) );
2018}
2019#endif /* MBEDTLS_ECDSA_C */
2020
Gilles Peskine61b91d42018-06-08 16:09:36 +02002021psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
2022 psa_algorithm_t alg,
2023 const uint8_t *hash,
2024 size_t hash_length,
2025 const uint8_t *salt,
2026 size_t salt_length,
2027 uint8_t *signature,
2028 size_t signature_size,
2029 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002030{
2031 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002032 psa_status_t status;
2033
2034 *signature_length = signature_size;
2035
Gilles Peskine93aa0332018-02-03 23:58:03 +01002036 (void) salt;
2037 (void) salt_length;
2038
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002039 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_SIGN, alg );
2040 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002041 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002042 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002043 {
2044 status = PSA_ERROR_INVALID_ARGUMENT;
2045 goto exit;
2046 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002047
Gilles Peskine20035e32018-02-03 22:44:14 +01002048#if defined(MBEDTLS_RSA_C)
2049 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2050 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002051 status = psa_rsa_sign( slot->data.rsa,
2052 alg,
2053 hash, hash_length,
2054 signature, signature_size,
2055 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002056 }
2057 else
2058#endif /* defined(MBEDTLS_RSA_C) */
2059#if defined(MBEDTLS_ECP_C)
2060 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2061 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002062#if defined(MBEDTLS_ECDSA_C)
2063 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002064 status = psa_ecdsa_sign( slot->data.ecp,
2065 alg,
2066 hash, hash_length,
2067 signature, signature_size,
2068 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002069 else
2070#endif /* defined(MBEDTLS_ECDSA_C) */
2071 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002072 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002073 }
itayzafrir5c753392018-05-08 11:18:38 +03002074 }
2075 else
2076#endif /* defined(MBEDTLS_ECP_C) */
2077 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002078 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002079 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002080
2081exit:
2082 /* Fill the unused part of the output buffer (the whole buffer on error,
2083 * the trailing part on success) with something that isn't a valid mac
2084 * (barring an attack on the mac and deliberately-crafted input),
2085 * in case the caller doesn't check the return status properly. */
2086 if( status == PSA_SUCCESS )
2087 memset( signature + *signature_length, '!',
2088 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002089 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002090 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002091 /* If signature_size is 0 then we have nothing to do. We must not call
2092 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002093 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002094}
2095
2096psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
2097 psa_algorithm_t alg,
2098 const uint8_t *hash,
2099 size_t hash_length,
2100 const uint8_t *salt,
2101 size_t salt_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002102 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002103 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002104{
2105 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002106 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002107
itayzafrir5c753392018-05-08 11:18:38 +03002108 (void) salt;
2109 (void) salt_length;
2110
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002111 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_VERIFY, alg );
2112 if( status != PSA_SUCCESS )
2113 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002114
Gilles Peskine61b91d42018-06-08 16:09:36 +02002115#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002116 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
2117 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002118 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002119 return( psa_rsa_verify( slot->data.rsa,
2120 alg,
2121 hash, hash_length,
2122 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002123 }
2124 else
2125#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002126#if defined(MBEDTLS_ECP_C)
2127 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2128 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002129#if defined(MBEDTLS_ECDSA_C)
2130 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002131 return( psa_ecdsa_verify( slot->data.ecp,
2132 hash, hash_length,
2133 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002134 else
2135#endif /* defined(MBEDTLS_ECDSA_C) */
2136 {
2137 return( PSA_ERROR_INVALID_ARGUMENT );
2138 }
itayzafrir5c753392018-05-08 11:18:38 +03002139 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002140 else
2141#endif /* defined(MBEDTLS_ECP_C) */
2142 {
2143 return( PSA_ERROR_NOT_SUPPORTED );
2144 }
2145}
2146
Gilles Peskine61b91d42018-06-08 16:09:36 +02002147psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
2148 psa_algorithm_t alg,
2149 const uint8_t *input,
2150 size_t input_length,
2151 const uint8_t *salt,
2152 size_t salt_length,
2153 uint8_t *output,
2154 size_t output_size,
2155 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002156{
2157 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002158 psa_status_t status;
2159
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002160 (void) salt;
2161 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002162 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002163
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002164 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
2165 if( status != PSA_SUCCESS )
2166 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002167 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2168 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002169
2170#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002171 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
2172 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002173 {
2174 mbedtls_rsa_context *rsa = slot->data.rsa;
2175 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002176 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002177 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002178#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002179 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002180 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002181 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2182 mbedtls_ctr_drbg_random,
2183 &global_data.ctr_drbg,
2184 MBEDTLS_RSA_PUBLIC,
2185 input_length,
2186 input,
2187 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002188 }
2189 else
2190#endif /* MBEDTLS_PKCS1_V15 */
2191#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002192 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002193 {
2194 return( PSA_ERROR_NOT_SUPPORTED );
2195 }
2196 else
2197#endif /* MBEDTLS_PKCS1_V21 */
2198 {
2199 return( PSA_ERROR_INVALID_ARGUMENT );
2200 }
2201 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002202 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002203 return( mbedtls_to_psa_error( ret ) );
2204 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002205 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002206#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002207 {
2208 return( PSA_ERROR_NOT_SUPPORTED );
2209 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002210}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002211
Gilles Peskine61b91d42018-06-08 16:09:36 +02002212psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2213 psa_algorithm_t alg,
2214 const uint8_t *input,
2215 size_t input_length,
2216 const uint8_t *salt,
2217 size_t salt_length,
2218 uint8_t *output,
2219 size_t output_size,
2220 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002221{
2222 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002223 psa_status_t status;
2224
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002225 (void) salt;
2226 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002227 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002228
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002229 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
2230 if( status != PSA_SUCCESS )
2231 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002232 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2233 return( PSA_ERROR_INVALID_ARGUMENT );
2234
2235#if defined(MBEDTLS_RSA_C)
2236 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2237 {
2238 mbedtls_rsa_context *rsa = slot->data.rsa;
2239 int ret;
2240
Gilles Peskinec4def2f2018-06-08 17:53:48 +02002241 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002242 return( PSA_ERROR_INVALID_ARGUMENT );
2243
2244#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002245 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002246 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002247 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2248 mbedtls_ctr_drbg_random,
2249 &global_data.ctr_drbg,
2250 MBEDTLS_RSA_PRIVATE,
2251 output_length,
2252 input,
2253 output,
2254 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002255 }
2256 else
2257#endif /* MBEDTLS_PKCS1_V15 */
2258#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002259 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002260 {
2261 return( PSA_ERROR_NOT_SUPPORTED );
2262 }
2263 else
2264#endif /* MBEDTLS_PKCS1_V21 */
2265 {
2266 return( PSA_ERROR_INVALID_ARGUMENT );
2267 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002268
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002269 return( mbedtls_to_psa_error( ret ) );
2270 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002271 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002272#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002273 {
2274 return( PSA_ERROR_NOT_SUPPORTED );
2275 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002276}
Gilles Peskine20035e32018-02-03 22:44:14 +01002277
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002278
2279
mohammad1603503973b2018-03-12 15:59:30 +02002280/****************************************************************/
2281/* Symmetric cryptography */
2282/****************************************************************/
2283
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002284/* Initialize the cipher operation structure. Once this function has been
2285 * called, psa_cipher_abort can run and will do the right thing. */
2286static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2287 psa_algorithm_t alg )
2288{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002289 if( ! PSA_ALG_IS_CIPHER( alg ) )
2290 {
2291 memset( operation, 0, sizeof( *operation ) );
2292 return( PSA_ERROR_INVALID_ARGUMENT );
2293 }
2294
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002295 operation->alg = alg;
2296 operation->key_set = 0;
2297 operation->iv_set = 0;
2298 operation->iv_required = 1;
2299 operation->iv_size = 0;
2300 operation->block_size = 0;
2301 mbedtls_cipher_init( &operation->ctx.cipher );
2302 return( PSA_SUCCESS );
2303}
2304
Gilles Peskinee553c652018-06-04 16:22:46 +02002305static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2306 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002307 psa_algorithm_t alg,
2308 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002309{
2310 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2311 psa_status_t status;
2312 key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02002313 size_t key_bits;
2314 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002315 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
2316 PSA_KEY_USAGE_ENCRYPT :
2317 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02002318
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002319 status = psa_cipher_init( operation, alg );
2320 if( status != PSA_SUCCESS )
2321 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002322
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002323 status = psa_get_key_from_slot( key, &slot, usage, alg);
2324 if( status != PSA_SUCCESS )
2325 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002326 key_bits = psa_get_key_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02002327
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002328 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002329 if( cipher_info == NULL )
2330 return( PSA_ERROR_NOT_SUPPORTED );
2331
mohammad1603503973b2018-03-12 15:59:30 +02002332 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002333 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002334 {
2335 psa_cipher_abort( operation );
2336 return( mbedtls_to_psa_error( ret ) );
2337 }
2338
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002339#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002340 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002341 {
2342 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2343 unsigned char keys[24];
2344 memcpy( keys, slot->data.raw.data, 16 );
2345 memcpy( keys + 16, slot->data.raw.data, 8 );
2346 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2347 keys,
2348 192, cipher_operation );
2349 }
2350 else
2351#endif
2352 {
2353 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2354 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002355 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002356 }
Moran Peker41deec42018-04-04 15:43:05 +03002357 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002358 {
2359 psa_cipher_abort( operation );
2360 return( mbedtls_to_psa_error( ret ) );
2361 }
2362
mohammad16038481e742018-03-18 13:57:31 +02002363#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03002364 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02002365 {
Gilles Peskine53514202018-06-06 15:11:46 +02002366 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
2367 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02002368
Moran Pekera28258c2018-05-29 16:25:04 +03002369 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02002370 {
2371 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
2372 mode = MBEDTLS_PADDING_PKCS7;
2373 break;
2374 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
2375 mode = MBEDTLS_PADDING_NONE;
2376 break;
2377 default:
Moran Pekerae382792018-05-31 14:06:17 +03002378 psa_cipher_abort( operation );
2379 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02002380 }
2381 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03002382 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03002383 {
2384 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02002385 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03002386 }
mohammad16038481e742018-03-18 13:57:31 +02002387 }
2388#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2389
mohammad1603503973b2018-03-12 15:59:30 +02002390 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02002391 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002392 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) :
Gilles Peskine7e928852018-06-04 16:23:10 +02002393 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002394 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02002395 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002396 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02002397 }
mohammad1603503973b2018-03-12 15:59:30 +02002398
Moran Peker395db872018-05-31 14:07:14 +03002399 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002400}
2401
Gilles Peskinefe119512018-07-08 21:39:34 +02002402psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
2403 psa_key_slot_t key,
2404 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002405{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002406 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002407}
2408
Gilles Peskinefe119512018-07-08 21:39:34 +02002409psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
2410 psa_key_slot_t key,
2411 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002412{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002413 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002414}
2415
Gilles Peskinefe119512018-07-08 21:39:34 +02002416psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
2417 unsigned char *iv,
2418 size_t iv_size,
2419 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002420{
Moran Peker41deec42018-04-04 15:43:05 +03002421 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002422 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002423 return( PSA_ERROR_BAD_STATE );
2424 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002425 {
Moran Peker41deec42018-04-04 15:43:05 +03002426 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2427 goto exit;
2428 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002429 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2430 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002431 if( ret != 0 )
2432 {
2433 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002434 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002435 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002436
mohammad16038481e742018-03-18 13:57:31 +02002437 *iv_length = operation->iv_size;
Gilles Peskinefe119512018-07-08 21:39:34 +02002438 ret = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002439
Moran Peker395db872018-05-31 14:07:14 +03002440exit:
2441 if( ret != PSA_SUCCESS )
2442 psa_cipher_abort( operation );
2443 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002444}
2445
Gilles Peskinefe119512018-07-08 21:39:34 +02002446psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
2447 const unsigned char *iv,
2448 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002449{
Moran Peker41deec42018-04-04 15:43:05 +03002450 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002451 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002452 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002453 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002454 {
Moran Pekerae382792018-05-31 14:06:17 +03002455 psa_cipher_abort( operation );
2456 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002457 }
mohammad1603503973b2018-03-12 15:59:30 +02002458 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002459 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002460 {
2461 psa_cipher_abort( operation );
2462 return( mbedtls_to_psa_error( ret ) );
2463 }
2464
2465 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002466
Moran Peker395db872018-05-31 14:07:14 +03002467 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002468}
2469
Gilles Peskinee553c652018-06-04 16:22:46 +02002470psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2471 const uint8_t *input,
2472 size_t input_length,
2473 unsigned char *output,
2474 size_t output_size,
2475 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002476{
2477 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002478 size_t expected_output_size;
2479 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2480 {
2481 /* Take the unprocessed partial block left over from previous
2482 * update calls, if any, plus the input to this call. Remove
2483 * the last partial block, if any. You get the data that will be
2484 * output in this call. */
2485 expected_output_size =
2486 ( operation->ctx.cipher.unprocessed_len + input_length )
2487 / operation->block_size * operation->block_size;
2488 }
2489 else
2490 {
2491 expected_output_size = input_length;
2492 }
2493 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002494 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002495
mohammad1603503973b2018-03-12 15:59:30 +02002496 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002497 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002498 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002499 {
2500 psa_cipher_abort( operation );
2501 return( mbedtls_to_psa_error( ret ) );
2502 }
2503
Moran Peker395db872018-05-31 14:07:14 +03002504 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002505}
2506
Gilles Peskinee553c652018-06-04 16:22:46 +02002507psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2508 uint8_t *output,
2509 size_t output_size,
2510 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002511{
Janos Follath315b51c2018-07-09 16:04:51 +01002512 psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
2513 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002514 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002515
mohammad1603503973b2018-03-12 15:59:30 +02002516 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002517 {
Janos Follath315b51c2018-07-09 16:04:51 +01002518 status = PSA_ERROR_BAD_STATE;
2519 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002520 }
2521 if( operation->iv_required && ! operation->iv_set )
2522 {
Janos Follath315b51c2018-07-09 16:04:51 +01002523 status = PSA_ERROR_BAD_STATE;
2524 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002525 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002526 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2527 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002528 {
Gilles Peskine53514202018-06-06 15:11:46 +02002529 psa_algorithm_t padding_mode =
2530 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002531 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002532 {
Janos Follath315b51c2018-07-09 16:04:51 +01002533 status = PSA_ERROR_TAMPERING_DETECTED;
2534 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002535 }
Gilles Peskine53514202018-06-06 15:11:46 +02002536 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002537 {
2538 if( operation->ctx.cipher.unprocessed_len != 0 )
2539 {
Janos Follath315b51c2018-07-09 16:04:51 +01002540 status = PSA_ERROR_INVALID_ARGUMENT;
2541 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002542 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002543 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002544 }
2545
Janos Follath315b51c2018-07-09 16:04:51 +01002546 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
2547 temp_output_buffer,
2548 output_length );
2549 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002550 {
Janos Follath315b51c2018-07-09 16:04:51 +01002551 status = mbedtls_to_psa_error( cipher_ret );
2552 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02002553 }
Janos Follath315b51c2018-07-09 16:04:51 +01002554
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002555 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01002556 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002557 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002558 memcpy( output, temp_output_buffer, *output_length );
2559 else
2560 {
Janos Follath315b51c2018-07-09 16:04:51 +01002561 status = PSA_ERROR_BUFFER_TOO_SMALL;
2562 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002563 }
mohammad1603503973b2018-03-12 15:59:30 +02002564
Janos Follath279ab8e2018-07-09 16:13:21 +01002565 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002566 status = psa_cipher_abort( operation );
2567
2568 return( status );
2569
2570error:
2571
2572 *output_length = 0;
2573
Janos Follath279ab8e2018-07-09 16:13:21 +01002574 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002575 (void) psa_cipher_abort( operation );
2576
2577 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002578}
2579
Gilles Peskinee553c652018-06-04 16:22:46 +02002580psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2581{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002582 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002583 {
2584 /* The object has (apparently) been initialized but it is not
2585 * in use. It's ok to call abort on such an object, and there's
2586 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002587 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002588 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002589
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002590 /* Sanity check (shouldn't happen: operation->alg should
2591 * always have been initialized to a valid value). */
2592 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2593 return( PSA_ERROR_BAD_STATE );
2594
mohammad1603503973b2018-03-12 15:59:30 +02002595 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002596
Moran Peker41deec42018-04-04 15:43:05 +03002597 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002598 operation->key_set = 0;
2599 operation->iv_set = 0;
2600 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002601 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002602 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002603
Moran Peker395db872018-05-31 14:07:14 +03002604 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002605}
2606
Gilles Peskinea0655c32018-04-30 17:06:50 +02002607
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002608
mohammad16038cc1cee2018-03-28 01:21:33 +03002609/****************************************************************/
2610/* Key Policy */
2611/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002612
mohammad160327010052018-07-03 13:16:15 +03002613#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02002614void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002615{
Gilles Peskine803ce742018-06-18 16:07:14 +02002616 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002617}
2618
Gilles Peskine2d277862018-06-18 15:41:12 +02002619void psa_key_policy_set_usage( psa_key_policy_t *policy,
2620 psa_key_usage_t usage,
2621 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002622{
mohammad16034eed7572018-03-28 05:14:59 -07002623 policy->usage = usage;
2624 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002625}
2626
Gilles Peskineaa7bc472018-07-12 00:54:56 +02002627psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002628{
mohammad16036df908f2018-04-02 08:34:15 -07002629 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002630}
2631
Gilles Peskineaa7bc472018-07-12 00:54:56 +02002632psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002633{
mohammad16036df908f2018-04-02 08:34:15 -07002634 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002635}
mohammad160327010052018-07-03 13:16:15 +03002636#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002637
Gilles Peskine2d277862018-06-18 15:41:12 +02002638psa_status_t psa_set_key_policy( psa_key_slot_t key,
2639 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002640{
2641 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002642 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03002643
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002644 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002645 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002646
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002647 status = psa_get_empty_key_slot( key, &slot );
2648 if( status != PSA_SUCCESS )
2649 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03002650
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002651 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2652 PSA_KEY_USAGE_ENCRYPT |
2653 PSA_KEY_USAGE_DECRYPT |
2654 PSA_KEY_USAGE_SIGN |
Gilles Peskineea0fb492018-07-12 17:17:20 +02002655 PSA_KEY_USAGE_VERIFY |
2656 PSA_KEY_USAGE_DERIVE ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002657 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002658
mohammad16036df908f2018-04-02 08:34:15 -07002659 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002660
2661 return( PSA_SUCCESS );
2662}
2663
Gilles Peskine2d277862018-06-18 15:41:12 +02002664psa_status_t psa_get_key_policy( psa_key_slot_t key,
2665 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002666{
2667 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002668 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03002669
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002670 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002671 return( PSA_ERROR_INVALID_ARGUMENT );
2672
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002673 status = psa_get_key_slot( key, &slot );
2674 if( status != PSA_SUCCESS )
2675 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002676
mohammad16036df908f2018-04-02 08:34:15 -07002677 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002678
2679 return( PSA_SUCCESS );
2680}
Gilles Peskine20035e32018-02-03 22:44:14 +01002681
Gilles Peskinea0655c32018-04-30 17:06:50 +02002682
2683
mohammad1603804cd712018-03-20 22:44:08 +02002684/****************************************************************/
2685/* Key Lifetime */
2686/****************************************************************/
2687
Gilles Peskine2d277862018-06-18 15:41:12 +02002688psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2689 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002690{
2691 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002692 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02002693
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002694 status = psa_get_key_slot( key, &slot );
2695 if( status != PSA_SUCCESS )
2696 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002697
mohammad1603804cd712018-03-20 22:44:08 +02002698 *lifetime = slot->lifetime;
2699
2700 return( PSA_SUCCESS );
2701}
2702
Gilles Peskine2d277862018-06-18 15:41:12 +02002703psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
Jaeden Amero65fb2362018-06-26 13:55:30 +01002704 psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002705{
2706 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002707 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02002708
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002709 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2710 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002711 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2712 return( PSA_ERROR_INVALID_ARGUMENT );
2713
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002714 status = psa_get_empty_key_slot( key, &slot );
2715 if( status != PSA_SUCCESS )
2716 return( status );
mohammad1603804cd712018-03-20 22:44:08 +02002717
Moran Pekerd7326592018-05-29 16:56:39 +03002718 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002719 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002720
mohammad1603060ad8a2018-03-20 14:28:38 -07002721 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002722
2723 return( PSA_SUCCESS );
2724}
2725
Gilles Peskine20035e32018-02-03 22:44:14 +01002726
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002727
mohammad16035955c982018-04-26 00:53:03 +03002728/****************************************************************/
2729/* AEAD */
2730/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002731
mohammad16035955c982018-04-26 00:53:03 +03002732psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2733 psa_algorithm_t alg,
2734 const uint8_t *nonce,
2735 size_t nonce_length,
2736 const uint8_t *additional_data,
2737 size_t additional_data_length,
2738 const uint8_t *plaintext,
2739 size_t plaintext_length,
2740 uint8_t *ciphertext,
2741 size_t ciphertext_size,
2742 size_t *ciphertext_length )
2743{
2744 int ret;
2745 psa_status_t status;
2746 key_slot_t *slot;
mohammad16035955c982018-04-26 00:53:03 +03002747 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002748 uint8_t *tag;
2749 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002750 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002751 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002752
mohammad1603f08a5502018-06-03 15:05:47 +03002753 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002754
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002755 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
2756 if( status != PSA_SUCCESS )
2757 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002758 key_bits = psa_get_key_bits( slot );
mohammad16035955c982018-04-26 00:53:03 +03002759
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002760 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type,
mohammad16035ed06212018-06-06 13:09:34 +03002761 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002762 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002763 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002764
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002765 if( ( slot->type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
Gilles Peskine2d277862018-06-18 15:41:12 +02002766 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002767 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002768
mohammad16035955c982018-04-26 00:53:03 +03002769 if( alg == PSA_ALG_GCM )
2770 {
2771 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002772 tag_length = 16;
2773
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002774 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) != 16 )
mohammad160396910d82018-06-04 14:33:00 +03002775 return( PSA_ERROR_INVALID_ARGUMENT );
2776
mohammad160315223a82018-06-03 17:19:55 +03002777 //make sure we have place to hold the tag in the ciphertext buffer
2778 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002779 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002780
2781 //update the tag pointer to point to the end of the ciphertext_length
2782 tag = ciphertext + plaintext_length;
2783
mohammad16035955c982018-04-26 00:53:03 +03002784 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002785 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002786 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002787 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002788 if( ret != 0 )
2789 {
2790 mbedtls_gcm_free( &gcm );
2791 return( mbedtls_to_psa_error( ret ) );
2792 }
2793 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002794 plaintext_length, nonce,
2795 nonce_length, additional_data,
2796 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002797 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002798 mbedtls_gcm_free( &gcm );
2799 }
2800 else if( alg == PSA_ALG_CCM )
2801 {
2802 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002803 tag_length = 16;
2804
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002805 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) != 16 )
mohammad160396910d82018-06-04 14:33:00 +03002806 return( PSA_ERROR_INVALID_ARGUMENT );
2807
mohammad160347ddf3d2018-04-26 01:11:21 +03002808 if( nonce_length < 7 || nonce_length > 13 )
2809 return( PSA_ERROR_INVALID_ARGUMENT );
2810
mohammad160315223a82018-06-03 17:19:55 +03002811 //make sure we have place to hold the tag in the ciphertext buffer
2812 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002813 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002814
2815 //update the tag pointer to point to the end of the ciphertext_length
2816 tag = ciphertext + plaintext_length;
2817
mohammad16035955c982018-04-26 00:53:03 +03002818 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002819 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002820 slot->data.raw.data,
2821 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002822 if( ret != 0 )
2823 {
2824 mbedtls_ccm_free( &ccm );
2825 return( mbedtls_to_psa_error( ret ) );
2826 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002827 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002828 nonce, nonce_length,
2829 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002830 additional_data_length,
2831 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002832 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002833 mbedtls_ccm_free( &ccm );
2834 }
mohammad16035c8845f2018-05-09 05:40:09 -07002835 else
2836 {
mohammad1603554faad2018-06-03 15:07:38 +03002837 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002838 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002839
mohammad160315223a82018-06-03 17:19:55 +03002840 if( ret != 0 )
2841 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002842 /* If ciphertext_size is 0 then ciphertext may be NULL and then the
2843 * call to memset would have undefined behavior. */
2844 if( ciphertext_size != 0 )
2845 memset( ciphertext, 0, ciphertext_size );
mohammad160315223a82018-06-03 17:19:55 +03002846 return( mbedtls_to_psa_error( ret ) );
2847 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002848
mohammad160315223a82018-06-03 17:19:55 +03002849 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002850 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002851}
2852
Gilles Peskineee652a32018-06-01 19:23:52 +02002853/* Locate the tag in a ciphertext buffer containing the encrypted data
2854 * followed by the tag. Return the length of the part preceding the tag in
2855 * *plaintext_length. This is the size of the plaintext in modes where
2856 * the encrypted data has the same size as the plaintext, such as
2857 * CCM and GCM. */
2858static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2859 const uint8_t *ciphertext,
2860 size_t ciphertext_length,
2861 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002862 const uint8_t **p_tag )
2863{
2864 size_t payload_length;
2865 if( tag_length > ciphertext_length )
2866 return( PSA_ERROR_INVALID_ARGUMENT );
2867 payload_length = ciphertext_length - tag_length;
2868 if( payload_length > plaintext_size )
2869 return( PSA_ERROR_BUFFER_TOO_SMALL );
2870 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002871 return( PSA_SUCCESS );
2872}
2873
mohammad16035955c982018-04-26 00:53:03 +03002874psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2875 psa_algorithm_t alg,
2876 const uint8_t *nonce,
2877 size_t nonce_length,
2878 const uint8_t *additional_data,
2879 size_t additional_data_length,
2880 const uint8_t *ciphertext,
2881 size_t ciphertext_length,
2882 uint8_t *plaintext,
2883 size_t plaintext_size,
2884 size_t *plaintext_length )
2885{
2886 int ret;
2887 psa_status_t status;
2888 key_slot_t *slot;
mohammad16035955c982018-04-26 00:53:03 +03002889 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002890 const uint8_t *tag;
2891 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002892 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002893 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002894
Gilles Peskineee652a32018-06-01 19:23:52 +02002895 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002896
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002897 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
2898 if( status != PSA_SUCCESS )
2899 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002900 key_bits = psa_get_key_bits( slot );
mohammad16035955c982018-04-26 00:53:03 +03002901
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002902 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type,
mohammad16035ed06212018-06-06 13:09:34 +03002903 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002904 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002905 return( PSA_ERROR_NOT_SUPPORTED );
2906
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002907 if( ( slot->type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
Gilles Peskine2d277862018-06-18 15:41:12 +02002908 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002909 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002910
mohammad16035955c982018-04-26 00:53:03 +03002911 if( alg == PSA_ALG_GCM )
2912 {
2913 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002914
Gilles Peskineee652a32018-06-01 19:23:52 +02002915 tag_length = 16;
2916 status = psa_aead_unpadded_locate_tag( tag_length,
2917 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002918 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002919 if( status != PSA_SUCCESS )
2920 return( status );
2921
mohammad16035955c982018-04-26 00:53:03 +03002922 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002923 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002924 slot->data.raw.data,
2925 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002926 if( ret != 0 )
2927 {
2928 mbedtls_gcm_free( &gcm );
2929 return( mbedtls_to_psa_error( ret ) );
2930 }
mohammad16035955c982018-04-26 00:53:03 +03002931
Gilles Peskineee652a32018-06-01 19:23:52 +02002932 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002933 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002934 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002935 additional_data,
2936 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002937 tag, tag_length,
2938 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002939 mbedtls_gcm_free( &gcm );
2940 }
2941 else if( alg == PSA_ALG_CCM )
2942 {
2943 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002944
mohammad160347ddf3d2018-04-26 01:11:21 +03002945 if( nonce_length < 7 || nonce_length > 13 )
2946 return( PSA_ERROR_INVALID_ARGUMENT );
2947
mohammad16039375f842018-06-03 14:28:24 +03002948 tag_length = 16;
2949 status = psa_aead_unpadded_locate_tag( tag_length,
2950 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002951 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002952 if( status != PSA_SUCCESS )
2953 return( status );
2954
mohammad16035955c982018-04-26 00:53:03 +03002955 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002956 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002957 slot->data.raw.data,
2958 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002959 if( ret != 0 )
2960 {
2961 mbedtls_ccm_free( &ccm );
2962 return( mbedtls_to_psa_error( ret ) );
2963 }
mohammad160360a64d02018-06-03 17:20:42 +03002964 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002965 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002966 additional_data,
2967 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002968 ciphertext, plaintext,
2969 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002970 mbedtls_ccm_free( &ccm );
2971 }
mohammad160339574652018-06-01 04:39:53 -07002972 else
2973 {
mohammad1603554faad2018-06-03 15:07:38 +03002974 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002975 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002976
Gilles Peskineee652a32018-06-01 19:23:52 +02002977 if( ret != 0 )
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002978 {
2979 /* If plaintext_size is 0 then plaintext may be NULL and then the
2980 * call to memset has undefined behavior. */
2981 if( plaintext_size != 0 )
2982 memset( plaintext, 0, plaintext_size );
2983 }
mohammad160360a64d02018-06-03 17:20:42 +03002984 else
2985 *plaintext_length = ciphertext_length - tag_length;
2986
Gilles Peskineee652a32018-06-01 19:23:52 +02002987 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002988}
2989
Gilles Peskinea0655c32018-04-30 17:06:50 +02002990
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002991
Gilles Peskine20035e32018-02-03 22:44:14 +01002992/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02002993/* Generators */
2994/****************************************************************/
2995
2996psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
2997{
2998 psa_status_t status = PSA_SUCCESS;
2999 if( generator->alg == 0 )
3000 {
3001 /* The object has (apparently) been initialized but it is not
3002 * in use. It's ok to call abort on such an object, and there's
3003 * nothing to do. */
3004 }
3005 else
3006 {
3007 status = PSA_ERROR_BAD_STATE;
3008 }
3009 memset( generator, 0, sizeof( *generator ) );
3010 return( status );
3011}
3012
3013
3014psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3015 size_t *capacity)
3016{
3017 *capacity = generator->capacity;
3018 return( PSA_SUCCESS );
3019}
3020
3021psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
3022 uint8_t *output,
3023 size_t output_length )
3024{
3025 psa_status_t status;
3026
3027 if( output_length > generator->capacity )
3028 {
3029 generator->capacity = 0;
3030 /* Go through the error path to wipe all confidential data now
3031 * that the generator object is useless. */
3032 status = PSA_ERROR_INSUFFICIENT_CAPACITY;
3033 goto exit;
3034 }
3035 if( output_length == 0 &&
3036 generator->capacity == 0 && generator->alg == 0 )
3037 {
3038 /* Edge case: this is a blank or finished generator, and 0
3039 * bytes were requested. The right error in this case could
3040 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3041 * INSUFFICIENT_CAPACITY, which is right for a finished
3042 * generator, for consistency with the case when
3043 * output_length > 0. */
3044 return( PSA_ERROR_INSUFFICIENT_CAPACITY );
3045 }
3046 generator->capacity -= output_length;
3047
3048 {
3049 return( PSA_ERROR_BAD_STATE );
3050 }
3051
3052exit:
3053 if( status != PSA_SUCCESS )
3054 {
3055 psa_generator_abort( generator );
3056 memset( output, '!', output_length );
3057 }
3058 return( status );
3059}
3060
3061psa_status_t psa_generator_import_key( psa_key_slot_t key,
3062 psa_key_type_t type,
3063 size_t bits,
3064 psa_crypto_generator_t *generator )
3065{
3066 uint8_t *data = NULL;
3067 size_t bytes = PSA_BITS_TO_BYTES( bits );
3068 psa_status_t status;
3069
3070 if( ! key_type_is_raw_bytes( type ) )
3071 return( PSA_ERROR_INVALID_ARGUMENT );
3072 if( bits % 8 != 0 )
3073 return( PSA_ERROR_INVALID_ARGUMENT );
3074 data = mbedtls_calloc( 1, bytes );
3075 if( data == NULL )
3076 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3077
3078 status = psa_generator_read( generator, data, bytes );
3079 if( status != PSA_SUCCESS )
3080 goto exit;
3081 status = psa_import_key( key, type, data, bytes );
3082
3083exit:
3084 mbedtls_free( data );
3085 return( status );
3086}
3087
3088
3089
3090/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003091/* Key derivation */
3092/****************************************************************/
3093
3094psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
3095 psa_key_type_t key,
3096 psa_algorithm_t alg,
3097 const uint8_t *salt,
3098 size_t salt_length,
3099 const uint8_t *label,
3100 size_t label_length,
3101 size_t capacity )
3102{
3103 key_slot_t *slot;
3104 psa_status_t status;
3105
3106 if( generator->alg != 0 )
3107 return( PSA_ERROR_BAD_STATE );
3108
3109 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DERIVE, alg );
3110 if( status != PSA_SUCCESS )
3111 return( status );
3112 if( slot->type != PSA_KEY_TYPE_DERIVE )
3113 return( PSA_ERROR_INVALID_ARGUMENT );
3114
3115 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
3116 return( PSA_ERROR_INVALID_ARGUMENT );
3117
3118 {
3119 return( PSA_ERROR_NOT_SUPPORTED );
3120 }
3121
3122 /* Set generator->alg even on failure so that abort knows what to do. */
3123 generator->alg = alg;
3124 if( status == PSA_SUCCESS )
3125 generator->capacity = capacity;
3126 else
3127 psa_generator_abort( generator );
3128 return( status );
3129}
3130
3131
3132
3133/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003134/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02003135/****************************************************************/
3136
3137psa_status_t psa_generate_random( uint8_t *output,
3138 size_t output_size )
3139{
3140 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
3141 output, output_size );
3142 return( mbedtls_to_psa_error( ret ) );
3143}
3144
3145psa_status_t psa_generate_key( psa_key_slot_t key,
3146 psa_key_type_t type,
3147 size_t bits,
Gilles Peskine53d991e2018-07-12 01:14:59 +02003148 const void *extra,
3149 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02003150{
Gilles Peskine12313cd2018-06-20 00:20:32 +02003151 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003152 psa_status_t status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02003153
Gilles Peskine53d991e2018-07-12 01:14:59 +02003154 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02003155 return( PSA_ERROR_INVALID_ARGUMENT );
3156
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003157 status = psa_get_empty_key_slot( key, &slot );
3158 if( status != PSA_SUCCESS )
3159 return( status );
3160
Gilles Peskine48c0ea12018-06-21 14:15:31 +02003161 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02003162 {
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003163 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02003164 if( status != PSA_SUCCESS )
3165 return( status );
3166 status = psa_generate_random( slot->data.raw.data,
3167 slot->data.raw.bytes );
3168 if( status != PSA_SUCCESS )
3169 {
3170 mbedtls_free( slot->data.raw.data );
3171 return( status );
3172 }
3173#if defined(MBEDTLS_DES_C)
3174 if( type == PSA_KEY_TYPE_DES )
3175 {
3176 mbedtls_des_key_set_parity( slot->data.raw.data );
3177 if( slot->data.raw.bytes >= 16 )
3178 mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
3179 if( slot->data.raw.bytes == 24 )
3180 mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
3181 }
3182#endif /* MBEDTLS_DES_C */
3183 }
3184 else
3185
3186#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
3187 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
3188 {
3189 mbedtls_rsa_context *rsa;
3190 int ret;
3191 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02003192 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
3193 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02003194 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02003195 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02003196 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02003197 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02003198 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02003199#if INT_MAX < 0xffffffff
3200 /* Check that the uint32_t value passed by the caller fits
3201 * in the range supported by this implementation. */
3202 if( p->e > INT_MAX )
3203 return( PSA_ERROR_NOT_SUPPORTED );
3204#endif
3205 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02003206 }
3207 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
3208 if( rsa == NULL )
3209 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3210 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
3211 ret = mbedtls_rsa_gen_key( rsa,
3212 mbedtls_ctr_drbg_random,
3213 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01003214 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02003215 exponent );
3216 if( ret != 0 )
3217 {
3218 mbedtls_rsa_free( rsa );
3219 mbedtls_free( rsa );
3220 return( mbedtls_to_psa_error( ret ) );
3221 }
3222 slot->data.rsa = rsa;
3223 }
3224 else
3225#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
3226
3227#if defined(MBEDTLS_ECP_C)
3228 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
3229 {
3230 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
3231 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
3232 const mbedtls_ecp_curve_info *curve_info =
3233 mbedtls_ecp_curve_info_from_grp_id( grp_id );
3234 mbedtls_ecp_keypair *ecp;
3235 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02003236 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02003237 return( PSA_ERROR_NOT_SUPPORTED );
3238 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
3239 return( PSA_ERROR_NOT_SUPPORTED );
3240 if( curve_info->bit_size != bits )
3241 return( PSA_ERROR_INVALID_ARGUMENT );
3242 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
3243 if( ecp == NULL )
3244 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3245 mbedtls_ecp_keypair_init( ecp );
3246 ret = mbedtls_ecp_gen_key( grp_id, ecp,
3247 mbedtls_ctr_drbg_random,
3248 &global_data.ctr_drbg );
3249 if( ret != 0 )
3250 {
3251 mbedtls_ecp_keypair_free( ecp );
3252 mbedtls_free( ecp );
3253 return( mbedtls_to_psa_error( ret ) );
3254 }
3255 slot->data.ecp = ecp;
3256 }
3257 else
3258#endif /* MBEDTLS_ECP_C */
3259
3260 return( PSA_ERROR_NOT_SUPPORTED );
3261
3262 slot->type = type;
3263 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02003264}
3265
3266
3267/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003268/* Module setup */
3269/****************************************************************/
3270
Gilles Peskinee59236f2018-01-27 23:32:46 +01003271void mbedtls_psa_crypto_free( void )
3272{
Jaeden Amero045bd502018-06-26 14:00:08 +01003273 psa_key_slot_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02003274 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003275 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003276 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
3277 mbedtls_entropy_free( &global_data.entropy );
3278 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3279}
3280
3281psa_status_t psa_crypto_init( void )
3282{
3283 int ret;
3284 const unsigned char drbg_seed[] = "PSA";
3285
3286 if( global_data.initialized != 0 )
3287 return( PSA_SUCCESS );
3288
3289 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3290 mbedtls_entropy_init( &global_data.entropy );
3291 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
3292
3293 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
3294 mbedtls_entropy_func,
3295 &global_data.entropy,
3296 drbg_seed, sizeof( drbg_seed ) - 1 );
3297 if( ret != 0 )
3298 goto exit;
3299
Gilles Peskinee4ebc122018-03-07 14:16:44 +01003300 global_data.initialized = 1;
3301
Gilles Peskinee59236f2018-01-27 23:32:46 +01003302exit:
3303 if( ret != 0 )
3304 mbedtls_psa_crypto_free( );
3305 return( mbedtls_to_psa_error( ret ) );
3306}
3307
3308#endif /* MBEDTLS_PSA_CRYPTO_C */