blob: 959b9ecc4c95a8f7b95b95392719e06e9199abc8 [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
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100414#if defined(MBEDTLS_ECP_C)
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200415static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
416{
417 switch( grpid )
418 {
419 case MBEDTLS_ECP_DP_SECP192R1:
420 return( PSA_ECC_CURVE_SECP192R1 );
421 case MBEDTLS_ECP_DP_SECP224R1:
422 return( PSA_ECC_CURVE_SECP224R1 );
423 case MBEDTLS_ECP_DP_SECP256R1:
424 return( PSA_ECC_CURVE_SECP256R1 );
425 case MBEDTLS_ECP_DP_SECP384R1:
426 return( PSA_ECC_CURVE_SECP384R1 );
427 case MBEDTLS_ECP_DP_SECP521R1:
428 return( PSA_ECC_CURVE_SECP521R1 );
429 case MBEDTLS_ECP_DP_BP256R1:
430 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
431 case MBEDTLS_ECP_DP_BP384R1:
432 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
433 case MBEDTLS_ECP_DP_BP512R1:
434 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
435 case MBEDTLS_ECP_DP_CURVE25519:
436 return( PSA_ECC_CURVE_CURVE25519 );
437 case MBEDTLS_ECP_DP_SECP192K1:
438 return( PSA_ECC_CURVE_SECP192K1 );
439 case MBEDTLS_ECP_DP_SECP224K1:
440 return( PSA_ECC_CURVE_SECP224K1 );
441 case MBEDTLS_ECP_DP_SECP256K1:
442 return( PSA_ECC_CURVE_SECP256K1 );
443 case MBEDTLS_ECP_DP_CURVE448:
444 return( PSA_ECC_CURVE_CURVE448 );
445 default:
446 return( 0 );
447 }
448}
449
Gilles Peskine12313cd2018-06-20 00:20:32 +0200450static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
451{
452 switch( curve )
453 {
454 case PSA_ECC_CURVE_SECP192R1:
455 return( MBEDTLS_ECP_DP_SECP192R1 );
456 case PSA_ECC_CURVE_SECP224R1:
457 return( MBEDTLS_ECP_DP_SECP224R1 );
458 case PSA_ECC_CURVE_SECP256R1:
459 return( MBEDTLS_ECP_DP_SECP256R1 );
460 case PSA_ECC_CURVE_SECP384R1:
461 return( MBEDTLS_ECP_DP_SECP384R1 );
462 case PSA_ECC_CURVE_SECP521R1:
463 return( MBEDTLS_ECP_DP_SECP521R1 );
464 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
465 return( MBEDTLS_ECP_DP_BP256R1 );
466 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
467 return( MBEDTLS_ECP_DP_BP384R1 );
468 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
469 return( MBEDTLS_ECP_DP_BP512R1 );
470 case PSA_ECC_CURVE_CURVE25519:
471 return( MBEDTLS_ECP_DP_CURVE25519 );
472 case PSA_ECC_CURVE_SECP192K1:
473 return( MBEDTLS_ECP_DP_SECP192K1 );
474 case PSA_ECC_CURVE_SECP224K1:
475 return( MBEDTLS_ECP_DP_SECP224K1 );
476 case PSA_ECC_CURVE_SECP256K1:
477 return( MBEDTLS_ECP_DP_SECP256K1 );
478 case PSA_ECC_CURVE_CURVE448:
479 return( MBEDTLS_ECP_DP_CURVE448 );
480 default:
481 return( MBEDTLS_ECP_DP_NONE );
482 }
483}
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100484#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200485
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200486static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
487 size_t bits,
488 struct raw_data *raw )
489{
490 /* Check that the bit size is acceptable for the key type */
491 switch( type )
492 {
493 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200494 if( bits == 0 )
495 {
496 raw->bytes = 0;
497 raw->data = NULL;
498 return( PSA_SUCCESS );
499 }
500 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200501#if defined(MBEDTLS_MD_C)
502 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200503#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200504 case PSA_KEY_TYPE_DERIVE:
505 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200506#if defined(MBEDTLS_AES_C)
507 case PSA_KEY_TYPE_AES:
508 if( bits != 128 && bits != 192 && bits != 256 )
509 return( PSA_ERROR_INVALID_ARGUMENT );
510 break;
511#endif
512#if defined(MBEDTLS_CAMELLIA_C)
513 case PSA_KEY_TYPE_CAMELLIA:
514 if( bits != 128 && bits != 192 && bits != 256 )
515 return( PSA_ERROR_INVALID_ARGUMENT );
516 break;
517#endif
518#if defined(MBEDTLS_DES_C)
519 case PSA_KEY_TYPE_DES:
520 if( bits != 64 && bits != 128 && bits != 192 )
521 return( PSA_ERROR_INVALID_ARGUMENT );
522 break;
523#endif
524#if defined(MBEDTLS_ARC4_C)
525 case PSA_KEY_TYPE_ARC4:
526 if( bits < 8 || bits > 2048 )
527 return( PSA_ERROR_INVALID_ARGUMENT );
528 break;
529#endif
530 default:
531 return( PSA_ERROR_NOT_SUPPORTED );
532 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200533 if( bits % 8 != 0 )
534 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200535
536 /* Allocate memory for the key */
537 raw->bytes = PSA_BITS_TO_BYTES( bits );
538 raw->data = mbedtls_calloc( 1, raw->bytes );
539 if( raw->data == NULL )
540 {
541 raw->bytes = 0;
542 return( PSA_ERROR_INSUFFICIENT_MEMORY );
543 }
544 return( PSA_SUCCESS );
545}
546
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200547#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
548static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
549 mbedtls_rsa_context **p_rsa )
550{
551 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_RSA )
552 return( PSA_ERROR_INVALID_ARGUMENT );
553 else
554 {
555 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *pk );
556 size_t bits = mbedtls_rsa_get_bitlen( rsa );
557 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
558 return( PSA_ERROR_NOT_SUPPORTED );
559 *p_rsa = rsa;
560 return( PSA_SUCCESS );
561 }
562}
563#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
564
565#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
566static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
567 mbedtls_pk_context *pk,
568 mbedtls_ecp_keypair **p_ecp )
569{
570 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
571 return( PSA_ERROR_INVALID_ARGUMENT );
572 else
573 {
574 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
575 psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
576 if( actual_curve != expected_curve )
577 return( PSA_ERROR_INVALID_ARGUMENT );
578 *p_ecp = ecp;
579 return( PSA_SUCCESS );
580 }
581}
582#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
583
Gilles Peskine2d277862018-06-18 15:41:12 +0200584psa_status_t psa_import_key( psa_key_slot_t key,
585 psa_key_type_t type,
586 const uint8_t *data,
587 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100588{
589 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200590 psa_status_t status = PSA_SUCCESS;
591 status = psa_get_empty_key_slot( key, &slot );
592 if( status != PSA_SUCCESS )
593 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100594
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200595 if( key_type_is_raw_bytes( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100596 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100597 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100598 if( data_length > SIZE_MAX / 8 )
599 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200600 status = prepare_raw_data_slot( type,
601 PSA_BYTES_TO_BITS( data_length ),
602 &slot->data.raw );
603 if( status != PSA_SUCCESS )
604 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200605 if( data_length != 0 )
606 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100607 }
608 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100609#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200610 if( PSA_KEY_TYPE_IS_RSA( type ) || PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100611 {
612 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100613 mbedtls_pk_context pk;
614 mbedtls_pk_init( &pk );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200615
616 /* Parse the data. */
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100617 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
618 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
619 else
620 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100621 if( ret != 0 )
622 return( mbedtls_to_psa_error( ret ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200623
624 /* We have something that the pkparse module recognizes.
625 * If it has the expected type and passes any type-specific
626 * checks, store it. */
Gilles Peskine969ac722018-01-28 18:16:59 +0100627#if defined(MBEDTLS_RSA_C)
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200628 if( PSA_KEY_TYPE_IS_RSA( type ) )
629 status = psa_import_rsa_key( &pk, &slot->data.rsa );
630 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100631#endif /* MBEDTLS_RSA_C */
632#if defined(MBEDTLS_ECP_C)
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200633 if( PSA_KEY_TYPE_IS_ECC( type ) )
634 status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( type ),
635 &pk, &slot->data.ecp );
636 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100637#endif /* MBEDTLS_ECP_C */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200638 {
639 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinec648d692018-06-28 08:46:13 +0200640 }
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200641
Gilles Peskinec648d692018-06-28 08:46:13 +0200642 /* Free the content of the pk object only on error. On success,
643 * the content of the object has been stored in the slot. */
644 if( status != PSA_SUCCESS )
645 {
646 mbedtls_pk_free( &pk );
647 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100648 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100649 }
650 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100651#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100652 {
653 return( PSA_ERROR_NOT_SUPPORTED );
654 }
655
656 slot->type = type;
657 return( PSA_SUCCESS );
658}
659
Gilles Peskine2d277862018-06-18 15:41:12 +0200660psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100661{
662 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200663 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100664
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200665 status = psa_get_key_slot( key, &slot );
666 if( status != PSA_SUCCESS )
667 return( status );
668
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100669 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200670 {
671 /* No key material to clean, but do zeroize the slot below to wipe
672 * metadata such as policies. */
673 }
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200674 else if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100675 {
676 mbedtls_free( slot->data.raw.data );
677 }
678 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100679#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200680 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100681 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100682 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100683 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100684 }
685 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100686#endif /* defined(MBEDTLS_RSA_C) */
687#if defined(MBEDTLS_ECP_C)
688 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
689 {
690 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100691 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100692 }
693 else
694#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100695 {
696 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100697 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100698 return( PSA_ERROR_TAMPERING_DETECTED );
699 }
700
701 mbedtls_zeroize( slot, sizeof( *slot ) );
702 return( PSA_SUCCESS );
703}
704
Gilles Peskineb870b182018-07-06 16:02:09 +0200705/* Return the size of the key in the given slot, in bits. */
706static size_t psa_get_key_bits( const key_slot_t *slot )
707{
708 if( key_type_is_raw_bytes( slot->type ) )
709 return( slot->data.raw.bytes * 8 );
710#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200711 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineb870b182018-07-06 16:02:09 +0200712 return( mbedtls_rsa_get_bitlen( slot->data.rsa ) );
713#endif /* defined(MBEDTLS_RSA_C) */
714#if defined(MBEDTLS_ECP_C)
715 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
716 return( slot->data.ecp->grp.pbits );
717#endif /* defined(MBEDTLS_ECP_C) */
718 /* Shouldn't happen except on an empty slot. */
719 return( 0 );
720}
721
Gilles Peskine2d277862018-06-18 15:41:12 +0200722psa_status_t psa_get_key_information( psa_key_slot_t key,
723 psa_key_type_t *type,
724 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100725{
726 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200727 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100728
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100729 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200730 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100731 if( bits != NULL )
732 *bits = 0;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200733 status = psa_get_key_slot( key, &slot );
734 if( status != PSA_SUCCESS )
735 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +0200736
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100737 if( slot->type == PSA_KEY_TYPE_NONE )
738 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200739 if( type != NULL )
740 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +0200741 if( bits != NULL )
742 *bits = psa_get_key_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100743 return( PSA_SUCCESS );
744}
745
Gilles Peskine2d277862018-06-18 15:41:12 +0200746static psa_status_t psa_internal_export_key( psa_key_slot_t key,
747 uint8_t *data,
748 size_t data_size,
749 size_t *data_length,
750 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100751{
752 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200753 psa_status_t status;
754 /* Exporting a public key doesn't require a usage flag. If we're
755 * called by psa_export_public_key(), don't require the EXPORT flag.
756 * If we're called by psa_export_key(), do require the EXPORT flag;
757 * if the key turns out to be public key object, psa_get_key_from_slot()
758 * will ignore this flag. */
759 psa_key_usage_t usage = export_public_key ? 0 : PSA_KEY_USAGE_EXPORT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100760
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100761 /* Set the key to empty now, so that even when there are errors, we always
762 * set data_length to a value between 0 and data_size. On error, setting
763 * the key to empty is a good choice because an empty key representation is
764 * unlikely to be accepted anywhere. */
765 *data_length = 0;
766
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200767 status = psa_get_key_from_slot( key, &slot, usage, 0 );
768 if( status != PSA_SUCCESS )
769 return( status );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200770 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300771 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300772
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200773 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100774 {
775 if( slot->data.raw.bytes > data_size )
776 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200777 if( slot->data.raw.bytes != 0 )
778 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100779 *data_length = slot->data.raw.bytes;
780 return( PSA_SUCCESS );
781 }
782 else
Moran Peker17e36e12018-05-02 12:55:20 +0300783 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100784#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200785 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
Moran Pekera998bc62018-04-16 18:16:20 +0300786 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100787 {
Moran Pekera998bc62018-04-16 18:16:20 +0300788 mbedtls_pk_context pk;
789 int ret;
Gilles Peskined8008d62018-06-29 19:51:51 +0200790 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300791 {
Darryl Green9e2d7a02018-07-24 16:33:30 +0100792#if defined(MBEDTLS_RSA_C)
793 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +0300794 pk.pk_info = &mbedtls_rsa_info;
795 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +0100796#else
797 return( PSA_ERROR_NOT_SUPPORTED );
798#endif
Moran Pekera998bc62018-04-16 18:16:20 +0300799 }
800 else
801 {
Darryl Green9e2d7a02018-07-24 16:33:30 +0100802#if defined(MBEDTLS_ECP_C)
803 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +0300804 pk.pk_info = &mbedtls_eckey_info;
805 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +0100806#else
807 return( PSA_ERROR_NOT_SUPPORTED );
808#endif
Moran Pekera998bc62018-04-16 18:16:20 +0300809 }
Moran Pekerd7326592018-05-29 16:56:39 +0300810 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300811 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300812 else
813 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300814 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200815 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200816 /* If data_size is 0 then data may be NULL and then the
817 * call to memset would have undefined behavior. */
818 if( data_size != 0 )
819 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300820 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200821 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200822 /* The mbedtls_pk_xxx functions write to the end of the buffer.
823 * Move the data to the beginning and erase remaining data
824 * at the original location. */
825 if( 2 * (size_t) ret <= data_size )
826 {
827 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200828 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200829 }
830 else if( (size_t) ret < data_size )
831 {
832 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200833 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200834 }
Moran Pekera998bc62018-04-16 18:16:20 +0300835 *data_length = ret;
836 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100837 }
838 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100839#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300840 {
841 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200842 it is valid for a special-purpose implementation to omit
843 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300844 return( PSA_ERROR_NOT_SUPPORTED );
845 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100846 }
847}
848
Gilles Peskine2d277862018-06-18 15:41:12 +0200849psa_status_t psa_export_key( psa_key_slot_t key,
850 uint8_t *data,
851 size_t data_size,
852 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300853{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200854 return( psa_internal_export_key( key, data, data_size,
855 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100856}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100857
Gilles Peskine2d277862018-06-18 15:41:12 +0200858psa_status_t psa_export_public_key( psa_key_slot_t key,
859 uint8_t *data,
860 size_t data_size,
861 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300862{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200863 return( psa_internal_export_key( key, data, data_size,
864 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300865}
866
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200867
868
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100869/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100870/* Message digests */
871/****************************************************************/
872
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100873static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100874{
875 switch( alg )
876 {
877#if defined(MBEDTLS_MD2_C)
878 case PSA_ALG_MD2:
879 return( &mbedtls_md2_info );
880#endif
881#if defined(MBEDTLS_MD4_C)
882 case PSA_ALG_MD4:
883 return( &mbedtls_md4_info );
884#endif
885#if defined(MBEDTLS_MD5_C)
886 case PSA_ALG_MD5:
887 return( &mbedtls_md5_info );
888#endif
889#if defined(MBEDTLS_RIPEMD160_C)
890 case PSA_ALG_RIPEMD160:
891 return( &mbedtls_ripemd160_info );
892#endif
893#if defined(MBEDTLS_SHA1_C)
894 case PSA_ALG_SHA_1:
895 return( &mbedtls_sha1_info );
896#endif
897#if defined(MBEDTLS_SHA256_C)
898 case PSA_ALG_SHA_224:
899 return( &mbedtls_sha224_info );
900 case PSA_ALG_SHA_256:
901 return( &mbedtls_sha256_info );
902#endif
903#if defined(MBEDTLS_SHA512_C)
904 case PSA_ALG_SHA_384:
905 return( &mbedtls_sha384_info );
906 case PSA_ALG_SHA_512:
907 return( &mbedtls_sha512_info );
908#endif
909 default:
910 return( NULL );
911 }
912}
913
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100914psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
915{
916 switch( operation->alg )
917 {
Gilles Peskine81736312018-06-26 15:04:31 +0200918 case 0:
919 /* The object has (apparently) been initialized but it is not
920 * in use. It's ok to call abort on such an object, and there's
921 * nothing to do. */
922 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100923#if defined(MBEDTLS_MD2_C)
924 case PSA_ALG_MD2:
925 mbedtls_md2_free( &operation->ctx.md2 );
926 break;
927#endif
928#if defined(MBEDTLS_MD4_C)
929 case PSA_ALG_MD4:
930 mbedtls_md4_free( &operation->ctx.md4 );
931 break;
932#endif
933#if defined(MBEDTLS_MD5_C)
934 case PSA_ALG_MD5:
935 mbedtls_md5_free( &operation->ctx.md5 );
936 break;
937#endif
938#if defined(MBEDTLS_RIPEMD160_C)
939 case PSA_ALG_RIPEMD160:
940 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
941 break;
942#endif
943#if defined(MBEDTLS_SHA1_C)
944 case PSA_ALG_SHA_1:
945 mbedtls_sha1_free( &operation->ctx.sha1 );
946 break;
947#endif
948#if defined(MBEDTLS_SHA256_C)
949 case PSA_ALG_SHA_224:
950 case PSA_ALG_SHA_256:
951 mbedtls_sha256_free( &operation->ctx.sha256 );
952 break;
953#endif
954#if defined(MBEDTLS_SHA512_C)
955 case PSA_ALG_SHA_384:
956 case PSA_ALG_SHA_512:
957 mbedtls_sha512_free( &operation->ctx.sha512 );
958 break;
959#endif
960 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +0200961 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100962 }
963 operation->alg = 0;
964 return( PSA_SUCCESS );
965}
966
Gilles Peskineda8191d1c2018-07-08 19:46:38 +0200967psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100968 psa_algorithm_t alg )
969{
970 int ret;
971 operation->alg = 0;
972 switch( alg )
973 {
974#if defined(MBEDTLS_MD2_C)
975 case PSA_ALG_MD2:
976 mbedtls_md2_init( &operation->ctx.md2 );
977 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
978 break;
979#endif
980#if defined(MBEDTLS_MD4_C)
981 case PSA_ALG_MD4:
982 mbedtls_md4_init( &operation->ctx.md4 );
983 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
984 break;
985#endif
986#if defined(MBEDTLS_MD5_C)
987 case PSA_ALG_MD5:
988 mbedtls_md5_init( &operation->ctx.md5 );
989 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
990 break;
991#endif
992#if defined(MBEDTLS_RIPEMD160_C)
993 case PSA_ALG_RIPEMD160:
994 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
995 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
996 break;
997#endif
998#if defined(MBEDTLS_SHA1_C)
999 case PSA_ALG_SHA_1:
1000 mbedtls_sha1_init( &operation->ctx.sha1 );
1001 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
1002 break;
1003#endif
1004#if defined(MBEDTLS_SHA256_C)
1005 case PSA_ALG_SHA_224:
1006 mbedtls_sha256_init( &operation->ctx.sha256 );
1007 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
1008 break;
1009 case PSA_ALG_SHA_256:
1010 mbedtls_sha256_init( &operation->ctx.sha256 );
1011 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
1012 break;
1013#endif
1014#if defined(MBEDTLS_SHA512_C)
1015 case PSA_ALG_SHA_384:
1016 mbedtls_sha512_init( &operation->ctx.sha512 );
1017 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
1018 break;
1019 case PSA_ALG_SHA_512:
1020 mbedtls_sha512_init( &operation->ctx.sha512 );
1021 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1022 break;
1023#endif
1024 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001025 return( PSA_ALG_IS_HASH( alg ) ?
1026 PSA_ERROR_NOT_SUPPORTED :
1027 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001028 }
1029 if( ret == 0 )
1030 operation->alg = alg;
1031 else
1032 psa_hash_abort( operation );
1033 return( mbedtls_to_psa_error( ret ) );
1034}
1035
1036psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1037 const uint8_t *input,
1038 size_t input_length )
1039{
1040 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001041
1042 /* Don't require hash implementations to behave correctly on a
1043 * zero-length input, which may have an invalid pointer. */
1044 if( input_length == 0 )
1045 return( PSA_SUCCESS );
1046
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001047 switch( operation->alg )
1048 {
1049#if defined(MBEDTLS_MD2_C)
1050 case PSA_ALG_MD2:
1051 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1052 input, input_length );
1053 break;
1054#endif
1055#if defined(MBEDTLS_MD4_C)
1056 case PSA_ALG_MD4:
1057 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1058 input, input_length );
1059 break;
1060#endif
1061#if defined(MBEDTLS_MD5_C)
1062 case PSA_ALG_MD5:
1063 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1064 input, input_length );
1065 break;
1066#endif
1067#if defined(MBEDTLS_RIPEMD160_C)
1068 case PSA_ALG_RIPEMD160:
1069 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1070 input, input_length );
1071 break;
1072#endif
1073#if defined(MBEDTLS_SHA1_C)
1074 case PSA_ALG_SHA_1:
1075 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1076 input, input_length );
1077 break;
1078#endif
1079#if defined(MBEDTLS_SHA256_C)
1080 case PSA_ALG_SHA_224:
1081 case PSA_ALG_SHA_256:
1082 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1083 input, input_length );
1084 break;
1085#endif
1086#if defined(MBEDTLS_SHA512_C)
1087 case PSA_ALG_SHA_384:
1088 case PSA_ALG_SHA_512:
1089 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1090 input, input_length );
1091 break;
1092#endif
1093 default:
1094 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1095 break;
1096 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001097
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001098 if( ret != 0 )
1099 psa_hash_abort( operation );
1100 return( mbedtls_to_psa_error( ret ) );
1101}
1102
1103psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1104 uint8_t *hash,
1105 size_t hash_size,
1106 size_t *hash_length )
1107{
1108 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001109 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001110
1111 /* Fill the output buffer with something that isn't a valid hash
1112 * (barring an attack on the hash and deliberately-crafted input),
1113 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001114 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001115 /* If hash_size is 0 then hash may be NULL and then the
1116 * call to memset would have undefined behavior. */
1117 if( hash_size != 0 )
1118 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001119
1120 if( hash_size < actual_hash_length )
1121 return( PSA_ERROR_BUFFER_TOO_SMALL );
1122
1123 switch( operation->alg )
1124 {
1125#if defined(MBEDTLS_MD2_C)
1126 case PSA_ALG_MD2:
1127 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1128 break;
1129#endif
1130#if defined(MBEDTLS_MD4_C)
1131 case PSA_ALG_MD4:
1132 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1133 break;
1134#endif
1135#if defined(MBEDTLS_MD5_C)
1136 case PSA_ALG_MD5:
1137 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1138 break;
1139#endif
1140#if defined(MBEDTLS_RIPEMD160_C)
1141 case PSA_ALG_RIPEMD160:
1142 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1143 break;
1144#endif
1145#if defined(MBEDTLS_SHA1_C)
1146 case PSA_ALG_SHA_1:
1147 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1148 break;
1149#endif
1150#if defined(MBEDTLS_SHA256_C)
1151 case PSA_ALG_SHA_224:
1152 case PSA_ALG_SHA_256:
1153 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1154 break;
1155#endif
1156#if defined(MBEDTLS_SHA512_C)
1157 case PSA_ALG_SHA_384:
1158 case PSA_ALG_SHA_512:
1159 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1160 break;
1161#endif
1162 default:
1163 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1164 break;
1165 }
1166
1167 if( ret == 0 )
1168 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001169 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001170 return( psa_hash_abort( operation ) );
1171 }
1172 else
1173 {
1174 psa_hash_abort( operation );
1175 return( mbedtls_to_psa_error( ret ) );
1176 }
1177}
1178
Gilles Peskine2d277862018-06-18 15:41:12 +02001179psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1180 const uint8_t *hash,
1181 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001182{
1183 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1184 size_t actual_hash_length;
1185 psa_status_t status = psa_hash_finish( operation,
1186 actual_hash, sizeof( actual_hash ),
1187 &actual_hash_length );
1188 if( status != PSA_SUCCESS )
1189 return( status );
1190 if( actual_hash_length != hash_length )
1191 return( PSA_ERROR_INVALID_SIGNATURE );
1192 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1193 return( PSA_ERROR_INVALID_SIGNATURE );
1194 return( PSA_SUCCESS );
1195}
1196
1197
1198
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001199/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001200/* MAC */
1201/****************************************************************/
1202
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001203static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001204 psa_algorithm_t alg,
1205 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001206 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001207 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001208{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001209 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001210 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001211
1212 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1213 {
1214 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001215 {
1216 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1217 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001218
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001219 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001220 {
Gilles Peskine5d1888e2018-07-12 00:32:42 +02001221 case PSA_ALG_STREAM_CIPHER_BASE:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001222 mode = MBEDTLS_MODE_STREAM;
1223 break;
1224 case PSA_ALG_CBC_BASE:
1225 mode = MBEDTLS_MODE_CBC;
1226 break;
1227 case PSA_ALG_CFB_BASE:
1228 mode = MBEDTLS_MODE_CFB;
1229 break;
1230 case PSA_ALG_OFB_BASE:
1231 mode = MBEDTLS_MODE_OFB;
1232 break;
1233 case PSA_ALG_CTR:
1234 mode = MBEDTLS_MODE_CTR;
1235 break;
1236 case PSA_ALG_CCM:
1237 mode = MBEDTLS_MODE_CCM;
1238 break;
1239 case PSA_ALG_GCM:
1240 mode = MBEDTLS_MODE_GCM;
1241 break;
1242 default:
1243 return( NULL );
1244 }
1245 }
1246 else if( alg == PSA_ALG_CMAC )
1247 mode = MBEDTLS_MODE_ECB;
1248 else if( alg == PSA_ALG_GMAC )
1249 mode = MBEDTLS_MODE_GCM;
1250 else
1251 return( NULL );
1252
1253 switch( key_type )
1254 {
1255 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001256 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001257 break;
1258 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001259 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1260 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001261 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001262 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001263 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001264 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001265 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1266 * but two-key Triple-DES is functionally three-key Triple-DES
1267 * with K1=K3, so that's how we present it to mbedtls. */
1268 if( key_bits == 128 )
1269 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001270 break;
1271 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001272 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001273 break;
1274 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001275 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001276 break;
1277 default:
1278 return( NULL );
1279 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001280 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001281 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001282
Jaeden Amero23bbb752018-06-26 14:16:54 +01001283 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1284 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001285}
1286
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001287static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001288{
Gilles Peskine2d277862018-06-18 15:41:12 +02001289 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001290 {
1291 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001292 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001293 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001294 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001295 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001296 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001297 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001298 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001299 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001300 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001301 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001302 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001303 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001304 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001305 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001306 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001307 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001308 return( 128 );
1309 default:
1310 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001311 }
1312}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001313
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001314/* Initialize the MAC operation structure. Once this function has been
1315 * called, psa_mac_abort can run and will do the right thing. */
1316static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1317 psa_algorithm_t alg )
1318{
1319 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1320
1321 operation->alg = alg;
1322 operation->key_set = 0;
1323 operation->iv_set = 0;
1324 operation->iv_required = 0;
1325 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001326 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001327
1328#if defined(MBEDTLS_CMAC_C)
1329 if( alg == PSA_ALG_CMAC )
1330 {
1331 operation->iv_required = 0;
1332 mbedtls_cipher_init( &operation->ctx.cmac );
1333 status = PSA_SUCCESS;
1334 }
1335 else
1336#endif /* MBEDTLS_CMAC_C */
1337#if defined(MBEDTLS_MD_C)
1338 if( PSA_ALG_IS_HMAC( operation->alg ) )
1339 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02001340 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
1341 operation->ctx.hmac.hash_ctx.alg = 0;
1342 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001343 }
1344 else
1345#endif /* MBEDTLS_MD_C */
1346 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001347 if( ! PSA_ALG_IS_MAC( alg ) )
1348 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001349 }
1350
1351 if( status != PSA_SUCCESS )
1352 memset( operation, 0, sizeof( *operation ) );
1353 return( status );
1354}
1355
Gilles Peskine01126fa2018-07-12 17:04:55 +02001356#if defined(MBEDTLS_MD_C)
1357static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
1358{
1359 mbedtls_zeroize( hmac->opad, sizeof( hmac->opad ) );
1360 return( psa_hash_abort( &hmac->hash_ctx ) );
1361}
1362#endif /* MBEDTLS_MD_C */
1363
Gilles Peskine8c9def32018-02-08 10:02:12 +01001364psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1365{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001366 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001367 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001368 /* The object has (apparently) been initialized but it is not
1369 * in use. It's ok to call abort on such an object, and there's
1370 * nothing to do. */
1371 return( PSA_SUCCESS );
1372 }
1373 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001374#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001375 if( operation->alg == PSA_ALG_CMAC )
1376 {
1377 mbedtls_cipher_free( &operation->ctx.cmac );
1378 }
1379 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001380#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001381#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001382 if( PSA_ALG_IS_HMAC( operation->alg ) )
1383 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001384 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001385 }
1386 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001387#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001388 {
1389 /* Sanity check (shouldn't happen: operation->alg should
1390 * always have been initialized to a valid value). */
1391 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001392 }
Moran Peker41deec42018-04-04 15:43:05 +03001393
Gilles Peskine8c9def32018-02-08 10:02:12 +01001394 operation->alg = 0;
1395 operation->key_set = 0;
1396 operation->iv_set = 0;
1397 operation->iv_required = 0;
1398 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001399 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001400
Gilles Peskine8c9def32018-02-08 10:02:12 +01001401 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001402
1403bad_state:
1404 /* If abort is called on an uninitialized object, we can't trust
1405 * anything. Wipe the object in case it contains confidential data.
1406 * This may result in a memory leak if a pointer gets overwritten,
1407 * but it's too late to do anything about this. */
1408 memset( operation, 0, sizeof( *operation ) );
1409 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001410}
1411
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001412#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02001413static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001414 size_t key_bits,
1415 key_slot_t *slot,
1416 const mbedtls_cipher_info_t *cipher_info )
1417{
1418 int ret;
1419
1420 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001421
1422 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1423 if( ret != 0 )
1424 return( ret );
1425
1426 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1427 slot->data.raw.data,
1428 key_bits );
1429 return( ret );
1430}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001431#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001432
Gilles Peskine248051a2018-06-20 16:09:38 +02001433#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02001434static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
1435 const uint8_t *key,
1436 size_t key_length,
1437 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001438{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001439 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001440 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001441 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001442 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001443 psa_status_t status;
1444
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001445 /* Sanity checks on block_size, to guarantee that there won't be a buffer
1446 * overflow below. This should never trigger if the hash algorithm
1447 * is implemented correctly. */
1448 /* The size checks against the ipad and opad buffers cannot be written
1449 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
1450 * because that triggers -Wlogical-op on GCC 7.3. */
1451 if( block_size > sizeof( ipad ) )
1452 return( PSA_ERROR_NOT_SUPPORTED );
1453 if( block_size > sizeof( hmac->opad ) )
1454 return( PSA_ERROR_NOT_SUPPORTED );
1455 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001456 return( PSA_ERROR_NOT_SUPPORTED );
1457
Gilles Peskined223b522018-06-11 18:12:58 +02001458 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001459 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001460 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001461 if( status != PSA_SUCCESS )
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001462 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001463 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001464 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001465 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001466 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001467 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001468 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001469 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001470 }
Gilles Peskine96889972018-07-12 17:07:03 +02001471 /* A 0-length key is not commonly used in HMAC when used as a MAC,
1472 * but it is permitted. It is common when HMAC is used in HKDF, for
1473 * example. Don't call `memcpy` in the 0-length because `key` could be
1474 * an invalid pointer which would make the behavior undefined. */
1475 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001476 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001477
Gilles Peskined223b522018-06-11 18:12:58 +02001478 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1479 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001480 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001481 ipad[i] ^= 0x36;
1482 memset( ipad + key_length, 0x36, block_size - key_length );
1483
1484 /* Copy the key material from ipad to opad, flipping the requisite bits,
1485 * and filling the rest of opad with the requisite constant. */
1486 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001487 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1488 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001489
Gilles Peskine01126fa2018-07-12 17:04:55 +02001490 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001491 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001492 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001493
Gilles Peskine01126fa2018-07-12 17:04:55 +02001494 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001495
1496cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001497 mbedtls_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001498
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001499 return( status );
1500}
Gilles Peskine248051a2018-06-20 16:09:38 +02001501#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001502
Gilles Peskine89167cb2018-07-08 20:12:23 +02001503static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
1504 psa_key_slot_t key,
1505 psa_algorithm_t alg,
1506 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001507{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001508 psa_status_t status;
1509 key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001510 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001511 psa_key_usage_t usage =
1512 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001513
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001514 status = psa_mac_init( operation, alg );
1515 if( status != PSA_SUCCESS )
1516 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001517 if( is_sign )
1518 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001519
Gilles Peskine89167cb2018-07-08 20:12:23 +02001520 status = psa_get_key_from_slot( key, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001521 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001522 goto exit;
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02001523 key_bits = psa_get_key_bits( slot );
1524
Gilles Peskine8c9def32018-02-08 10:02:12 +01001525#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001526 if( alg == PSA_ALG_CMAC )
1527 {
1528 const mbedtls_cipher_info_t *cipher_info =
1529 mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
1530 int ret;
1531 if( cipher_info == NULL )
1532 {
1533 status = PSA_ERROR_NOT_SUPPORTED;
1534 goto exit;
1535 }
1536 operation->mac_size = cipher_info->block_size;
1537 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
1538 status = mbedtls_to_psa_error( ret );
1539 }
1540 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001541#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001542#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001543 if( PSA_ALG_IS_HMAC( alg ) )
1544 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001545 psa_algorithm_t hash_alg = PSA_ALG_HMAC_HASH( alg );
1546 if( hash_alg == 0 )
1547 {
1548 status = PSA_ERROR_NOT_SUPPORTED;
1549 goto exit;
1550 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001551
1552 operation->mac_size = PSA_HASH_SIZE( hash_alg );
1553 /* Sanity check. This shouldn't fail on a valid configuration. */
1554 if( operation->mac_size == 0 ||
1555 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
1556 {
1557 status = PSA_ERROR_NOT_SUPPORTED;
1558 goto exit;
1559 }
1560
Gilles Peskine01126fa2018-07-12 17:04:55 +02001561 if( slot->type != PSA_KEY_TYPE_HMAC )
1562 {
1563 status = PSA_ERROR_INVALID_ARGUMENT;
1564 goto exit;
1565 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001566
Gilles Peskine01126fa2018-07-12 17:04:55 +02001567 status = psa_hmac_setup_internal( &operation->ctx.hmac,
1568 slot->data.raw.data,
1569 slot->data.raw.bytes,
1570 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001571 }
1572 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001573#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001574 {
1575 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001576 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001577
Gilles Peskinefbfac682018-07-08 20:51:54 +02001578exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001579 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001580 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001581 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001582 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001583 else
1584 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001585 operation->key_set = 1;
1586 }
1587 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001588}
1589
Gilles Peskine89167cb2018-07-08 20:12:23 +02001590psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
1591 psa_key_slot_t key,
1592 psa_algorithm_t alg )
1593{
1594 return( psa_mac_setup( operation, key, alg, 1 ) );
1595}
1596
1597psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
1598 psa_key_slot_t key,
1599 psa_algorithm_t alg )
1600{
1601 return( psa_mac_setup( operation, key, alg, 0 ) );
1602}
1603
Gilles Peskine8c9def32018-02-08 10:02:12 +01001604psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1605 const uint8_t *input,
1606 size_t input_length )
1607{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001608 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001609 if( ! operation->key_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001610 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001611 if( operation->iv_required && ! operation->iv_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001612 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001613 operation->has_input = 1;
1614
Gilles Peskine8c9def32018-02-08 10:02:12 +01001615#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001616 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001617 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001618 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1619 input, input_length );
1620 status = mbedtls_to_psa_error( ret );
1621 }
1622 else
1623#endif /* MBEDTLS_CMAC_C */
1624#if defined(MBEDTLS_MD_C)
1625 if( PSA_ALG_IS_HMAC( operation->alg ) )
1626 {
1627 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
1628 input_length );
1629 }
1630 else
1631#endif /* MBEDTLS_MD_C */
1632 {
1633 /* This shouldn't happen if `operation` was initialized by
1634 * a setup function. */
1635 status = PSA_ERROR_BAD_STATE;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001636 }
1637
Gilles Peskinefbfac682018-07-08 20:51:54 +02001638cleanup:
1639 if( status != PSA_SUCCESS )
1640 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001641 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001642}
1643
Gilles Peskine01126fa2018-07-12 17:04:55 +02001644#if defined(MBEDTLS_MD_C)
1645static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
1646 uint8_t *mac,
1647 size_t mac_size )
1648{
1649 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
1650 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
1651 size_t hash_size = 0;
1652 size_t block_size = psa_get_hash_block_size( hash_alg );
1653 psa_status_t status;
1654
Gilles Peskine01126fa2018-07-12 17:04:55 +02001655 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1656 if( status != PSA_SUCCESS )
1657 return( status );
1658 /* From here on, tmp needs to be wiped. */
1659
1660 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
1661 if( status != PSA_SUCCESS )
1662 goto exit;
1663
1664 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
1665 if( status != PSA_SUCCESS )
1666 goto exit;
1667
1668 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
1669 if( status != PSA_SUCCESS )
1670 goto exit;
1671
1672 status = psa_hash_finish( &hmac->hash_ctx, mac, mac_size, &hash_size );
1673
1674exit:
1675 mbedtls_zeroize( tmp, hash_size );
1676 return( status );
1677}
1678#endif /* MBEDTLS_MD_C */
1679
mohammad16036df908f2018-04-02 08:34:15 -07001680static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001681 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001682 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001683{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02001684 if( ! operation->key_set )
1685 return( PSA_ERROR_BAD_STATE );
1686 if( operation->iv_required && ! operation->iv_set )
1687 return( PSA_ERROR_BAD_STATE );
1688
Gilles Peskine8c9def32018-02-08 10:02:12 +01001689 if( mac_size < operation->mac_size )
1690 return( PSA_ERROR_BUFFER_TOO_SMALL );
1691
Gilles Peskine8c9def32018-02-08 10:02:12 +01001692#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001693 if( operation->alg == PSA_ALG_CMAC )
1694 {
1695 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1696 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001697 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02001698 else
1699#endif /* MBEDTLS_CMAC_C */
1700#if defined(MBEDTLS_MD_C)
1701 if( PSA_ALG_IS_HMAC( operation->alg ) )
1702 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001703 return( psa_hmac_finish_internal( &operation->ctx.hmac,
1704 mac, mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001705 }
1706 else
1707#endif /* MBEDTLS_MD_C */
1708 {
1709 /* This shouldn't happen if `operation` was initialized by
1710 * a setup function. */
1711 return( PSA_ERROR_BAD_STATE );
1712 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001713}
1714
Gilles Peskineacd4be32018-07-08 19:56:25 +02001715psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
1716 uint8_t *mac,
1717 size_t mac_size,
1718 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07001719{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001720 psa_status_t status;
1721
1722 /* Fill the output buffer with something that isn't a valid mac
1723 * (barring an attack on the mac and deliberately-crafted input),
1724 * in case the caller doesn't check the return status properly. */
1725 *mac_length = mac_size;
1726 /* If mac_size is 0 then mac may be NULL and then the
1727 * call to memset would have undefined behavior. */
1728 if( mac_size != 0 )
1729 memset( mac, '!', mac_size );
1730
Gilles Peskine89167cb2018-07-08 20:12:23 +02001731 if( ! operation->is_sign )
1732 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001733 status = PSA_ERROR_BAD_STATE;
1734 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001735 }
mohammad16036df908f2018-04-02 08:34:15 -07001736
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001737 status = psa_mac_finish_internal( operation, mac, mac_size );
1738
1739cleanup:
1740 if( status == PSA_SUCCESS )
1741 {
1742 status = psa_mac_abort( operation );
1743 if( status == PSA_SUCCESS )
1744 *mac_length = operation->mac_size;
1745 else
1746 memset( mac, '!', mac_size );
1747 }
1748 else
1749 psa_mac_abort( operation );
1750 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07001751}
1752
Gilles Peskineacd4be32018-07-08 19:56:25 +02001753psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
1754 const uint8_t *mac,
1755 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001756{
Gilles Peskine828ed142018-06-18 23:25:51 +02001757 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07001758 psa_status_t status;
1759
Gilles Peskine89167cb2018-07-08 20:12:23 +02001760 if( operation->is_sign )
1761 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001762 status = PSA_ERROR_BAD_STATE;
1763 goto cleanup;
1764 }
1765 if( operation->mac_size != mac_length )
1766 {
1767 status = PSA_ERROR_INVALID_SIGNATURE;
1768 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001769 }
mohammad16036df908f2018-04-02 08:34:15 -07001770
1771 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001772 actual_mac, sizeof( actual_mac ) );
1773
1774 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
1775 status = PSA_ERROR_INVALID_SIGNATURE;
1776
1777cleanup:
1778 if( status == PSA_SUCCESS )
1779 status = psa_mac_abort( operation );
1780 else
1781 psa_mac_abort( operation );
1782
1783 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001784}
1785
1786
Gilles Peskine20035e32018-02-03 22:44:14 +01001787
Gilles Peskine20035e32018-02-03 22:44:14 +01001788/****************************************************************/
1789/* Asymmetric cryptography */
1790/****************************************************************/
1791
Gilles Peskine2b450e32018-06-27 15:42:46 +02001792#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001793/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02001794 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001795static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1796 size_t hash_length,
1797 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001798{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02001799 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001800 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02001801 *md_alg = mbedtls_md_get_type( md_info );
1802
1803 /* The Mbed TLS RSA module uses an unsigned int for hash length
1804 * parameters. Validate that it fits so that we don't risk an
1805 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001806#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02001807 if( hash_length > UINT_MAX )
1808 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001809#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02001810
1811#if defined(MBEDTLS_PKCS1_V15)
1812 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
1813 * must be correct. */
1814 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
1815 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001816 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02001817 if( md_info == NULL )
1818 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001819 if( mbedtls_md_get_size( md_info ) != hash_length )
1820 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02001821 }
1822#endif /* MBEDTLS_PKCS1_V15 */
1823
1824#if defined(MBEDTLS_PKCS1_V21)
1825 /* PSS requires a hash internally. */
1826 if( PSA_ALG_IS_RSA_PSS( alg ) )
1827 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001828 if( md_info == NULL )
1829 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001830 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02001831#endif /* MBEDTLS_PKCS1_V21 */
1832
Gilles Peskine61b91d42018-06-08 16:09:36 +02001833 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001834}
1835
Gilles Peskine2b450e32018-06-27 15:42:46 +02001836static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
1837 psa_algorithm_t alg,
1838 const uint8_t *hash,
1839 size_t hash_length,
1840 uint8_t *signature,
1841 size_t signature_size,
1842 size_t *signature_length )
1843{
1844 psa_status_t status;
1845 int ret;
1846 mbedtls_md_type_t md_alg;
1847
1848 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1849 if( status != PSA_SUCCESS )
1850 return( status );
1851
Gilles Peskine630a18a2018-06-29 17:49:35 +02001852 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02001853 return( PSA_ERROR_BUFFER_TOO_SMALL );
1854
1855#if defined(MBEDTLS_PKCS1_V15)
1856 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1857 {
1858 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1859 MBEDTLS_MD_NONE );
1860 ret = mbedtls_rsa_pkcs1_sign( rsa,
1861 mbedtls_ctr_drbg_random,
1862 &global_data.ctr_drbg,
1863 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001864 md_alg,
1865 (unsigned int) hash_length,
1866 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001867 signature );
1868 }
1869 else
1870#endif /* MBEDTLS_PKCS1_V15 */
1871#if defined(MBEDTLS_PKCS1_V21)
1872 if( PSA_ALG_IS_RSA_PSS( alg ) )
1873 {
1874 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1875 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1876 mbedtls_ctr_drbg_random,
1877 &global_data.ctr_drbg,
1878 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02001879 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001880 (unsigned int) hash_length,
1881 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001882 signature );
1883 }
1884 else
1885#endif /* MBEDTLS_PKCS1_V21 */
1886 {
1887 return( PSA_ERROR_INVALID_ARGUMENT );
1888 }
1889
1890 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02001891 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02001892 return( mbedtls_to_psa_error( ret ) );
1893}
1894
1895static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
1896 psa_algorithm_t alg,
1897 const uint8_t *hash,
1898 size_t hash_length,
1899 const uint8_t *signature,
1900 size_t signature_length )
1901{
1902 psa_status_t status;
1903 int ret;
1904 mbedtls_md_type_t md_alg;
1905
1906 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1907 if( status != PSA_SUCCESS )
1908 return( status );
1909
Gilles Peskine630a18a2018-06-29 17:49:35 +02001910 if( signature_length < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02001911 return( PSA_ERROR_BUFFER_TOO_SMALL );
1912
1913#if defined(MBEDTLS_PKCS1_V15)
1914 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1915 {
1916 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1917 MBEDTLS_MD_NONE );
1918 ret = mbedtls_rsa_pkcs1_verify( rsa,
1919 mbedtls_ctr_drbg_random,
1920 &global_data.ctr_drbg,
1921 MBEDTLS_RSA_PUBLIC,
1922 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001923 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001924 hash,
1925 signature );
1926 }
1927 else
1928#endif /* MBEDTLS_PKCS1_V15 */
1929#if defined(MBEDTLS_PKCS1_V21)
1930 if( PSA_ALG_IS_RSA_PSS( alg ) )
1931 {
1932 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1933 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1934 mbedtls_ctr_drbg_random,
1935 &global_data.ctr_drbg,
1936 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02001937 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001938 (unsigned int) hash_length,
1939 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001940 signature );
1941 }
1942 else
1943#endif /* MBEDTLS_PKCS1_V21 */
1944 {
1945 return( PSA_ERROR_INVALID_ARGUMENT );
1946 }
1947 return( mbedtls_to_psa_error( ret ) );
1948}
1949#endif /* MBEDTLS_RSA_C */
1950
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001951#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001952/* `ecp` cannot be const because `ecp->grp` needs to be non-const
1953 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
1954 * (even though these functions don't modify it). */
1955static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
1956 psa_algorithm_t alg,
1957 const uint8_t *hash,
1958 size_t hash_length,
1959 uint8_t *signature,
1960 size_t signature_size,
1961 size_t *signature_length )
1962{
1963 int ret;
1964 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001965 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001966 mbedtls_mpi_init( &r );
1967 mbedtls_mpi_init( &s );
1968
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001969 if( signature_size < 2 * curve_bytes )
1970 {
1971 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
1972 goto cleanup;
1973 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001974
1975 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
1976 {
1977 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
1978 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1979 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
1980 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
1981 hash, hash_length,
1982 md_alg ) );
1983 }
1984 else
1985 {
1986 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
1987 hash, hash_length,
1988 mbedtls_ctr_drbg_random,
1989 &global_data.ctr_drbg ) );
1990 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001991
1992 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
1993 signature,
1994 curve_bytes ) );
1995 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
1996 signature + curve_bytes,
1997 curve_bytes ) );
1998
1999cleanup:
2000 mbedtls_mpi_free( &r );
2001 mbedtls_mpi_free( &s );
2002 if( ret == 0 )
2003 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002004 return( mbedtls_to_psa_error( ret ) );
2005}
2006
2007static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
2008 const uint8_t *hash,
2009 size_t hash_length,
2010 const uint8_t *signature,
2011 size_t signature_length )
2012{
2013 int ret;
2014 mbedtls_mpi r, s;
2015 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
2016 mbedtls_mpi_init( &r );
2017 mbedtls_mpi_init( &s );
2018
2019 if( signature_length != 2 * curve_bytes )
2020 return( PSA_ERROR_INVALID_SIGNATURE );
2021
2022 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2023 signature,
2024 curve_bytes ) );
2025 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2026 signature + curve_bytes,
2027 curve_bytes ) );
2028
2029 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2030 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002031
2032cleanup:
2033 mbedtls_mpi_free( &r );
2034 mbedtls_mpi_free( &s );
2035 return( mbedtls_to_psa_error( ret ) );
2036}
2037#endif /* MBEDTLS_ECDSA_C */
2038
Gilles Peskine61b91d42018-06-08 16:09:36 +02002039psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
2040 psa_algorithm_t alg,
2041 const uint8_t *hash,
2042 size_t hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002043 uint8_t *signature,
2044 size_t signature_size,
2045 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002046{
2047 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002048 psa_status_t status;
2049
2050 *signature_length = signature_size;
2051
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002052 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_SIGN, alg );
2053 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002054 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002055 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002056 {
2057 status = PSA_ERROR_INVALID_ARGUMENT;
2058 goto exit;
2059 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002060
Gilles Peskine20035e32018-02-03 22:44:14 +01002061#if defined(MBEDTLS_RSA_C)
2062 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2063 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002064 status = psa_rsa_sign( slot->data.rsa,
2065 alg,
2066 hash, hash_length,
2067 signature, signature_size,
2068 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002069 }
2070 else
2071#endif /* defined(MBEDTLS_RSA_C) */
2072#if defined(MBEDTLS_ECP_C)
2073 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2074 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002075#if defined(MBEDTLS_ECDSA_C)
2076 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002077 status = psa_ecdsa_sign( slot->data.ecp,
2078 alg,
2079 hash, hash_length,
2080 signature, signature_size,
2081 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002082 else
2083#endif /* defined(MBEDTLS_ECDSA_C) */
2084 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002085 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002086 }
itayzafrir5c753392018-05-08 11:18:38 +03002087 }
2088 else
2089#endif /* defined(MBEDTLS_ECP_C) */
2090 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002091 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002092 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002093
2094exit:
2095 /* Fill the unused part of the output buffer (the whole buffer on error,
2096 * the trailing part on success) with something that isn't a valid mac
2097 * (barring an attack on the mac and deliberately-crafted input),
2098 * in case the caller doesn't check the return status properly. */
2099 if( status == PSA_SUCCESS )
2100 memset( signature + *signature_length, '!',
2101 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002102 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002103 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002104 /* If signature_size is 0 then we have nothing to do. We must not call
2105 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002106 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002107}
2108
2109psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
2110 psa_algorithm_t alg,
2111 const uint8_t *hash,
2112 size_t hash_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002113 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002114 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002115{
2116 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002117 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002118
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002119 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_VERIFY, alg );
2120 if( status != PSA_SUCCESS )
2121 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002122
Gilles Peskine61b91d42018-06-08 16:09:36 +02002123#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002124 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002125 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002126 return( psa_rsa_verify( slot->data.rsa,
2127 alg,
2128 hash, hash_length,
2129 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002130 }
2131 else
2132#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002133#if defined(MBEDTLS_ECP_C)
2134 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2135 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002136#if defined(MBEDTLS_ECDSA_C)
2137 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002138 return( psa_ecdsa_verify( slot->data.ecp,
2139 hash, hash_length,
2140 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002141 else
2142#endif /* defined(MBEDTLS_ECDSA_C) */
2143 {
2144 return( PSA_ERROR_INVALID_ARGUMENT );
2145 }
itayzafrir5c753392018-05-08 11:18:38 +03002146 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002147 else
2148#endif /* defined(MBEDTLS_ECP_C) */
2149 {
2150 return( PSA_ERROR_NOT_SUPPORTED );
2151 }
2152}
2153
Gilles Peskine072ac562018-06-30 00:21:29 +02002154#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
2155static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
2156 mbedtls_rsa_context *rsa )
2157{
2158 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
2159 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2160 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2161 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2162}
2163#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
2164
Gilles Peskine61b91d42018-06-08 16:09:36 +02002165psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
2166 psa_algorithm_t alg,
2167 const uint8_t *input,
2168 size_t input_length,
2169 const uint8_t *salt,
2170 size_t salt_length,
2171 uint8_t *output,
2172 size_t output_size,
2173 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002174{
2175 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002176 psa_status_t status;
2177
Darryl Green5cc689a2018-07-24 15:34:10 +01002178 (void) input;
2179 (void) input_length;
2180 (void) salt;
2181 (void) output;
2182 (void) output_size;
2183
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002184 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002185
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002186 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2187 return( PSA_ERROR_INVALID_ARGUMENT );
2188
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002189 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
2190 if( status != PSA_SUCCESS )
2191 return( status );
Gilles Peskine35da9a22018-06-29 19:17:49 +02002192 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
2193 PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002194 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002195
2196#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002197 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002198 {
2199 mbedtls_rsa_context *rsa = slot->data.rsa;
2200 int ret;
Gilles Peskine630a18a2018-06-29 17:49:35 +02002201 if( output_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002202 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002203#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002204 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002205 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002206 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2207 mbedtls_ctr_drbg_random,
2208 &global_data.ctr_drbg,
2209 MBEDTLS_RSA_PUBLIC,
2210 input_length,
2211 input,
2212 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002213 }
2214 else
2215#endif /* MBEDTLS_PKCS1_V15 */
2216#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002217 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002218 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002219 psa_rsa_oaep_set_padding_mode( alg, rsa );
2220 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
2221 mbedtls_ctr_drbg_random,
2222 &global_data.ctr_drbg,
2223 MBEDTLS_RSA_PUBLIC,
2224 salt, salt_length,
2225 input_length,
2226 input,
2227 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002228 }
2229 else
2230#endif /* MBEDTLS_PKCS1_V21 */
2231 {
2232 return( PSA_ERROR_INVALID_ARGUMENT );
2233 }
2234 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002235 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002236 return( mbedtls_to_psa_error( ret ) );
2237 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002238 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002239#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002240 {
2241 return( PSA_ERROR_NOT_SUPPORTED );
2242 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002243}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002244
Gilles Peskine61b91d42018-06-08 16:09:36 +02002245psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2246 psa_algorithm_t alg,
2247 const uint8_t *input,
2248 size_t input_length,
2249 const uint8_t *salt,
2250 size_t salt_length,
2251 uint8_t *output,
2252 size_t output_size,
2253 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002254{
2255 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002256 psa_status_t status;
2257
Darryl Green5cc689a2018-07-24 15:34:10 +01002258 (void) input;
2259 (void) input_length;
2260 (void) salt;
2261 (void) output;
2262 (void) output_size;
2263
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002264 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002265
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002266 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2267 return( PSA_ERROR_INVALID_ARGUMENT );
2268
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002269 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
2270 if( status != PSA_SUCCESS )
2271 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002272 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2273 return( PSA_ERROR_INVALID_ARGUMENT );
2274
2275#if defined(MBEDTLS_RSA_C)
2276 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2277 {
2278 mbedtls_rsa_context *rsa = slot->data.rsa;
2279 int ret;
2280
Gilles Peskine630a18a2018-06-29 17:49:35 +02002281 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002282 return( PSA_ERROR_INVALID_ARGUMENT );
2283
2284#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002285 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002286 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002287 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2288 mbedtls_ctr_drbg_random,
2289 &global_data.ctr_drbg,
2290 MBEDTLS_RSA_PRIVATE,
2291 output_length,
2292 input,
2293 output,
2294 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002295 }
2296 else
2297#endif /* MBEDTLS_PKCS1_V15 */
2298#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002299 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002300 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002301 psa_rsa_oaep_set_padding_mode( alg, rsa );
2302 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
2303 mbedtls_ctr_drbg_random,
2304 &global_data.ctr_drbg,
2305 MBEDTLS_RSA_PRIVATE,
2306 salt, salt_length,
2307 output_length,
2308 input,
2309 output,
2310 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002311 }
2312 else
2313#endif /* MBEDTLS_PKCS1_V21 */
2314 {
2315 return( PSA_ERROR_INVALID_ARGUMENT );
2316 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002317
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002318 return( mbedtls_to_psa_error( ret ) );
2319 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002320 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002321#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002322 {
2323 return( PSA_ERROR_NOT_SUPPORTED );
2324 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002325}
Gilles Peskine20035e32018-02-03 22:44:14 +01002326
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002327
2328
mohammad1603503973b2018-03-12 15:59:30 +02002329/****************************************************************/
2330/* Symmetric cryptography */
2331/****************************************************************/
2332
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002333/* Initialize the cipher operation structure. Once this function has been
2334 * called, psa_cipher_abort can run and will do the right thing. */
2335static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2336 psa_algorithm_t alg )
2337{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002338 if( ! PSA_ALG_IS_CIPHER( alg ) )
2339 {
2340 memset( operation, 0, sizeof( *operation ) );
2341 return( PSA_ERROR_INVALID_ARGUMENT );
2342 }
2343
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002344 operation->alg = alg;
2345 operation->key_set = 0;
2346 operation->iv_set = 0;
2347 operation->iv_required = 1;
2348 operation->iv_size = 0;
2349 operation->block_size = 0;
2350 mbedtls_cipher_init( &operation->ctx.cipher );
2351 return( PSA_SUCCESS );
2352}
2353
Gilles Peskinee553c652018-06-04 16:22:46 +02002354static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2355 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002356 psa_algorithm_t alg,
2357 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002358{
2359 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2360 psa_status_t status;
2361 key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02002362 size_t key_bits;
2363 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002364 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
2365 PSA_KEY_USAGE_ENCRYPT :
2366 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02002367
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002368 status = psa_cipher_init( operation, alg );
2369 if( status != PSA_SUCCESS )
2370 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002371
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002372 status = psa_get_key_from_slot( key, &slot, usage, alg);
2373 if( status != PSA_SUCCESS )
2374 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002375 key_bits = psa_get_key_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02002376
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002377 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002378 if( cipher_info == NULL )
2379 return( PSA_ERROR_NOT_SUPPORTED );
2380
mohammad1603503973b2018-03-12 15:59:30 +02002381 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002382 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002383 {
2384 psa_cipher_abort( operation );
2385 return( mbedtls_to_psa_error( ret ) );
2386 }
2387
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002388#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002389 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002390 {
2391 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2392 unsigned char keys[24];
2393 memcpy( keys, slot->data.raw.data, 16 );
2394 memcpy( keys + 16, slot->data.raw.data, 8 );
2395 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2396 keys,
2397 192, cipher_operation );
2398 }
2399 else
2400#endif
2401 {
2402 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2403 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002404 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002405 }
Moran Peker41deec42018-04-04 15:43:05 +03002406 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002407 {
2408 psa_cipher_abort( operation );
2409 return( mbedtls_to_psa_error( ret ) );
2410 }
2411
mohammad16038481e742018-03-18 13:57:31 +02002412#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03002413 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02002414 {
Gilles Peskine53514202018-06-06 15:11:46 +02002415 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
2416 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02002417
Moran Pekera28258c2018-05-29 16:25:04 +03002418 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02002419 {
2420 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
2421 mode = MBEDTLS_PADDING_PKCS7;
2422 break;
2423 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
2424 mode = MBEDTLS_PADDING_NONE;
2425 break;
2426 default:
Moran Pekerae382792018-05-31 14:06:17 +03002427 psa_cipher_abort( operation );
2428 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02002429 }
2430 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03002431 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03002432 {
2433 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02002434 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03002435 }
mohammad16038481e742018-03-18 13:57:31 +02002436 }
2437#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2438
mohammad1603503973b2018-03-12 15:59:30 +02002439 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02002440 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002441 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) :
Gilles Peskine7e928852018-06-04 16:23:10 +02002442 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002443 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02002444 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002445 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02002446 }
mohammad1603503973b2018-03-12 15:59:30 +02002447
Moran Peker395db872018-05-31 14:07:14 +03002448 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002449}
2450
Gilles Peskinefe119512018-07-08 21:39:34 +02002451psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
2452 psa_key_slot_t key,
2453 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002454{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002455 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002456}
2457
Gilles Peskinefe119512018-07-08 21:39:34 +02002458psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
2459 psa_key_slot_t key,
2460 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002461{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002462 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002463}
2464
Gilles Peskinefe119512018-07-08 21:39:34 +02002465psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
2466 unsigned char *iv,
2467 size_t iv_size,
2468 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002469{
Moran Peker41deec42018-04-04 15:43:05 +03002470 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002471 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002472 return( PSA_ERROR_BAD_STATE );
2473 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002474 {
Moran Peker41deec42018-04-04 15:43:05 +03002475 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2476 goto exit;
2477 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002478 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2479 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002480 if( ret != 0 )
2481 {
2482 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002483 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002484 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002485
mohammad16038481e742018-03-18 13:57:31 +02002486 *iv_length = operation->iv_size;
Gilles Peskinefe119512018-07-08 21:39:34 +02002487 ret = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002488
Moran Peker395db872018-05-31 14:07:14 +03002489exit:
2490 if( ret != PSA_SUCCESS )
2491 psa_cipher_abort( operation );
2492 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002493}
2494
Gilles Peskinefe119512018-07-08 21:39:34 +02002495psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
2496 const unsigned char *iv,
2497 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002498{
Moran Peker41deec42018-04-04 15:43:05 +03002499 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002500 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002501 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002502 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002503 {
Moran Pekerae382792018-05-31 14:06:17 +03002504 psa_cipher_abort( operation );
2505 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002506 }
mohammad1603503973b2018-03-12 15:59:30 +02002507 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002508 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002509 {
2510 psa_cipher_abort( operation );
2511 return( mbedtls_to_psa_error( ret ) );
2512 }
2513
2514 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002515
Moran Peker395db872018-05-31 14:07:14 +03002516 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002517}
2518
Gilles Peskinee553c652018-06-04 16:22:46 +02002519psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2520 const uint8_t *input,
2521 size_t input_length,
2522 unsigned char *output,
2523 size_t output_size,
2524 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002525{
2526 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002527 size_t expected_output_size;
2528 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2529 {
2530 /* Take the unprocessed partial block left over from previous
2531 * update calls, if any, plus the input to this call. Remove
2532 * the last partial block, if any. You get the data that will be
2533 * output in this call. */
2534 expected_output_size =
2535 ( operation->ctx.cipher.unprocessed_len + input_length )
2536 / operation->block_size * operation->block_size;
2537 }
2538 else
2539 {
2540 expected_output_size = input_length;
2541 }
2542 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002543 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002544
mohammad1603503973b2018-03-12 15:59:30 +02002545 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002546 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002547 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002548 {
2549 psa_cipher_abort( operation );
2550 return( mbedtls_to_psa_error( ret ) );
2551 }
2552
Moran Peker395db872018-05-31 14:07:14 +03002553 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002554}
2555
Gilles Peskinee553c652018-06-04 16:22:46 +02002556psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2557 uint8_t *output,
2558 size_t output_size,
2559 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002560{
Janos Follath315b51c2018-07-09 16:04:51 +01002561 psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
2562 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002563 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002564
mohammad1603503973b2018-03-12 15:59:30 +02002565 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002566 {
Janos Follath315b51c2018-07-09 16:04:51 +01002567 status = PSA_ERROR_BAD_STATE;
2568 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002569 }
2570 if( operation->iv_required && ! operation->iv_set )
2571 {
Janos Follath315b51c2018-07-09 16:04:51 +01002572 status = PSA_ERROR_BAD_STATE;
2573 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002574 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002575 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2576 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002577 {
Gilles Peskine53514202018-06-06 15:11:46 +02002578 psa_algorithm_t padding_mode =
2579 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002580 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002581 {
Janos Follath315b51c2018-07-09 16:04:51 +01002582 status = PSA_ERROR_TAMPERING_DETECTED;
2583 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002584 }
Gilles Peskine53514202018-06-06 15:11:46 +02002585 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002586 {
2587 if( operation->ctx.cipher.unprocessed_len != 0 )
2588 {
Janos Follath315b51c2018-07-09 16:04:51 +01002589 status = PSA_ERROR_INVALID_ARGUMENT;
2590 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002591 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002592 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002593 }
2594
Janos Follath315b51c2018-07-09 16:04:51 +01002595 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
2596 temp_output_buffer,
2597 output_length );
2598 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002599 {
Janos Follath315b51c2018-07-09 16:04:51 +01002600 status = mbedtls_to_psa_error( cipher_ret );
2601 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02002602 }
Janos Follath315b51c2018-07-09 16:04:51 +01002603
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002604 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01002605 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002606 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002607 memcpy( output, temp_output_buffer, *output_length );
2608 else
2609 {
Janos Follath315b51c2018-07-09 16:04:51 +01002610 status = PSA_ERROR_BUFFER_TOO_SMALL;
2611 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002612 }
mohammad1603503973b2018-03-12 15:59:30 +02002613
Janos Follath279ab8e2018-07-09 16:13:21 +01002614 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002615 status = psa_cipher_abort( operation );
2616
2617 return( status );
2618
2619error:
2620
2621 *output_length = 0;
2622
Janos Follath279ab8e2018-07-09 16:13:21 +01002623 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002624 (void) psa_cipher_abort( operation );
2625
2626 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002627}
2628
Gilles Peskinee553c652018-06-04 16:22:46 +02002629psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2630{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002631 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002632 {
2633 /* The object has (apparently) been initialized but it is not
2634 * in use. It's ok to call abort on such an object, and there's
2635 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002636 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002637 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002638
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002639 /* Sanity check (shouldn't happen: operation->alg should
2640 * always have been initialized to a valid value). */
2641 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2642 return( PSA_ERROR_BAD_STATE );
2643
mohammad1603503973b2018-03-12 15:59:30 +02002644 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002645
Moran Peker41deec42018-04-04 15:43:05 +03002646 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002647 operation->key_set = 0;
2648 operation->iv_set = 0;
2649 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002650 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002651 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002652
Moran Peker395db872018-05-31 14:07:14 +03002653 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002654}
2655
Gilles Peskinea0655c32018-04-30 17:06:50 +02002656
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002657
mohammad16038cc1cee2018-03-28 01:21:33 +03002658/****************************************************************/
2659/* Key Policy */
2660/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002661
mohammad160327010052018-07-03 13:16:15 +03002662#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02002663void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002664{
Gilles Peskine803ce742018-06-18 16:07:14 +02002665 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002666}
2667
Gilles Peskine2d277862018-06-18 15:41:12 +02002668void psa_key_policy_set_usage( psa_key_policy_t *policy,
2669 psa_key_usage_t usage,
2670 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002671{
mohammad16034eed7572018-03-28 05:14:59 -07002672 policy->usage = usage;
2673 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002674}
2675
Gilles Peskineaa7bc472018-07-12 00:54:56 +02002676psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002677{
mohammad16036df908f2018-04-02 08:34:15 -07002678 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002679}
2680
Gilles Peskineaa7bc472018-07-12 00:54:56 +02002681psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002682{
mohammad16036df908f2018-04-02 08:34:15 -07002683 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002684}
mohammad160327010052018-07-03 13:16:15 +03002685#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002686
Gilles Peskine2d277862018-06-18 15:41:12 +02002687psa_status_t psa_set_key_policy( psa_key_slot_t key,
2688 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002689{
2690 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002691 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03002692
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002693 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002694 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002695
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002696 status = psa_get_empty_key_slot( key, &slot );
2697 if( status != PSA_SUCCESS )
2698 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03002699
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002700 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2701 PSA_KEY_USAGE_ENCRYPT |
2702 PSA_KEY_USAGE_DECRYPT |
2703 PSA_KEY_USAGE_SIGN |
Gilles Peskineea0fb492018-07-12 17:17:20 +02002704 PSA_KEY_USAGE_VERIFY |
2705 PSA_KEY_USAGE_DERIVE ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002706 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002707
mohammad16036df908f2018-04-02 08:34:15 -07002708 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002709
2710 return( PSA_SUCCESS );
2711}
2712
Gilles Peskine2d277862018-06-18 15:41:12 +02002713psa_status_t psa_get_key_policy( psa_key_slot_t key,
2714 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002715{
2716 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002717 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03002718
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002719 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002720 return( PSA_ERROR_INVALID_ARGUMENT );
2721
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002722 status = psa_get_key_slot( key, &slot );
2723 if( status != PSA_SUCCESS )
2724 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002725
mohammad16036df908f2018-04-02 08:34:15 -07002726 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002727
2728 return( PSA_SUCCESS );
2729}
Gilles Peskine20035e32018-02-03 22:44:14 +01002730
Gilles Peskinea0655c32018-04-30 17:06:50 +02002731
2732
mohammad1603804cd712018-03-20 22:44:08 +02002733/****************************************************************/
2734/* Key Lifetime */
2735/****************************************************************/
2736
Gilles Peskine2d277862018-06-18 15:41:12 +02002737psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2738 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002739{
2740 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002741 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02002742
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002743 status = psa_get_key_slot( key, &slot );
2744 if( status != PSA_SUCCESS )
2745 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002746
mohammad1603804cd712018-03-20 22:44:08 +02002747 *lifetime = slot->lifetime;
2748
2749 return( PSA_SUCCESS );
2750}
2751
Gilles Peskine2d277862018-06-18 15:41:12 +02002752psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
Jaeden Amero65fb2362018-06-26 13:55:30 +01002753 psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002754{
2755 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002756 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02002757
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002758 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2759 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002760 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2761 return( PSA_ERROR_INVALID_ARGUMENT );
2762
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002763 status = psa_get_empty_key_slot( key, &slot );
2764 if( status != PSA_SUCCESS )
2765 return( status );
mohammad1603804cd712018-03-20 22:44:08 +02002766
Moran Pekerd7326592018-05-29 16:56:39 +03002767 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002768 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002769
mohammad1603060ad8a2018-03-20 14:28:38 -07002770 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002771
2772 return( PSA_SUCCESS );
2773}
2774
Gilles Peskine20035e32018-02-03 22:44:14 +01002775
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002776
mohammad16035955c982018-04-26 00:53:03 +03002777/****************************************************************/
2778/* AEAD */
2779/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002780
mohammad16035955c982018-04-26 00:53:03 +03002781psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2782 psa_algorithm_t alg,
2783 const uint8_t *nonce,
2784 size_t nonce_length,
2785 const uint8_t *additional_data,
2786 size_t additional_data_length,
2787 const uint8_t *plaintext,
2788 size_t plaintext_length,
2789 uint8_t *ciphertext,
2790 size_t ciphertext_size,
2791 size_t *ciphertext_length )
2792{
2793 int ret;
2794 psa_status_t status;
2795 key_slot_t *slot;
mohammad16035955c982018-04-26 00:53:03 +03002796 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002797 uint8_t *tag;
2798 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002799 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002800 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002801
mohammad1603f08a5502018-06-03 15:05:47 +03002802 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002803
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002804 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
2805 if( status != PSA_SUCCESS )
2806 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002807 key_bits = psa_get_key_bits( slot );
mohammad16035955c982018-04-26 00:53:03 +03002808
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002809 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type,
mohammad16035ed06212018-06-06 13:09:34 +03002810 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002811 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002812 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002813
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002814 if( ( slot->type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
Gilles Peskine2d277862018-06-18 15:41:12 +02002815 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002816 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002817
mohammad16035955c982018-04-26 00:53:03 +03002818 if( alg == PSA_ALG_GCM )
2819 {
2820 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002821 tag_length = 16;
2822
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002823 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) != 16 )
mohammad160396910d82018-06-04 14:33:00 +03002824 return( PSA_ERROR_INVALID_ARGUMENT );
2825
mohammad160315223a82018-06-03 17:19:55 +03002826 //make sure we have place to hold the tag in the ciphertext buffer
2827 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002828 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002829
2830 //update the tag pointer to point to the end of the ciphertext_length
2831 tag = ciphertext + plaintext_length;
2832
mohammad16035955c982018-04-26 00:53:03 +03002833 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002834 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002835 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002836 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002837 if( ret != 0 )
2838 {
2839 mbedtls_gcm_free( &gcm );
2840 return( mbedtls_to_psa_error( ret ) );
2841 }
2842 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002843 plaintext_length, nonce,
2844 nonce_length, additional_data,
2845 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002846 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002847 mbedtls_gcm_free( &gcm );
2848 }
2849 else if( alg == PSA_ALG_CCM )
2850 {
2851 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002852 tag_length = 16;
2853
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002854 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) != 16 )
mohammad160396910d82018-06-04 14:33:00 +03002855 return( PSA_ERROR_INVALID_ARGUMENT );
2856
mohammad160347ddf3d2018-04-26 01:11:21 +03002857 if( nonce_length < 7 || nonce_length > 13 )
2858 return( PSA_ERROR_INVALID_ARGUMENT );
2859
mohammad160315223a82018-06-03 17:19:55 +03002860 //make sure we have place to hold the tag in the ciphertext buffer
2861 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002862 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002863
2864 //update the tag pointer to point to the end of the ciphertext_length
2865 tag = ciphertext + plaintext_length;
2866
mohammad16035955c982018-04-26 00:53:03 +03002867 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002868 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002869 slot->data.raw.data,
2870 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002871 if( ret != 0 )
2872 {
2873 mbedtls_ccm_free( &ccm );
2874 return( mbedtls_to_psa_error( ret ) );
2875 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002876 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002877 nonce, nonce_length,
2878 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002879 additional_data_length,
2880 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002881 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002882 mbedtls_ccm_free( &ccm );
2883 }
mohammad16035c8845f2018-05-09 05:40:09 -07002884 else
2885 {
mohammad1603554faad2018-06-03 15:07:38 +03002886 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002887 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002888
mohammad160315223a82018-06-03 17:19:55 +03002889 if( ret != 0 )
2890 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002891 /* If ciphertext_size is 0 then ciphertext may be NULL and then the
2892 * call to memset would have undefined behavior. */
2893 if( ciphertext_size != 0 )
2894 memset( ciphertext, 0, ciphertext_size );
mohammad160315223a82018-06-03 17:19:55 +03002895 return( mbedtls_to_psa_error( ret ) );
2896 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002897
mohammad160315223a82018-06-03 17:19:55 +03002898 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002899 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002900}
2901
Gilles Peskineee652a32018-06-01 19:23:52 +02002902/* Locate the tag in a ciphertext buffer containing the encrypted data
2903 * followed by the tag. Return the length of the part preceding the tag in
2904 * *plaintext_length. This is the size of the plaintext in modes where
2905 * the encrypted data has the same size as the plaintext, such as
2906 * CCM and GCM. */
2907static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2908 const uint8_t *ciphertext,
2909 size_t ciphertext_length,
2910 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002911 const uint8_t **p_tag )
2912{
2913 size_t payload_length;
2914 if( tag_length > ciphertext_length )
2915 return( PSA_ERROR_INVALID_ARGUMENT );
2916 payload_length = ciphertext_length - tag_length;
2917 if( payload_length > plaintext_size )
2918 return( PSA_ERROR_BUFFER_TOO_SMALL );
2919 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002920 return( PSA_SUCCESS );
2921}
2922
mohammad16035955c982018-04-26 00:53:03 +03002923psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2924 psa_algorithm_t alg,
2925 const uint8_t *nonce,
2926 size_t nonce_length,
2927 const uint8_t *additional_data,
2928 size_t additional_data_length,
2929 const uint8_t *ciphertext,
2930 size_t ciphertext_length,
2931 uint8_t *plaintext,
2932 size_t plaintext_size,
2933 size_t *plaintext_length )
2934{
2935 int ret;
2936 psa_status_t status;
2937 key_slot_t *slot;
mohammad16035955c982018-04-26 00:53:03 +03002938 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002939 const uint8_t *tag;
2940 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002941 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002942 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002943
Gilles Peskineee652a32018-06-01 19:23:52 +02002944 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002945
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002946 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
2947 if( status != PSA_SUCCESS )
2948 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002949 key_bits = psa_get_key_bits( slot );
mohammad16035955c982018-04-26 00:53:03 +03002950
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002951 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type,
mohammad16035ed06212018-06-06 13:09:34 +03002952 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002953 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002954 return( PSA_ERROR_NOT_SUPPORTED );
2955
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002956 if( ( slot->type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
Gilles Peskine2d277862018-06-18 15:41:12 +02002957 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002958 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002959
mohammad16035955c982018-04-26 00:53:03 +03002960 if( alg == PSA_ALG_GCM )
2961 {
2962 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002963
Gilles Peskineee652a32018-06-01 19:23:52 +02002964 tag_length = 16;
2965 status = psa_aead_unpadded_locate_tag( tag_length,
2966 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002967 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002968 if( status != PSA_SUCCESS )
2969 return( status );
2970
mohammad16035955c982018-04-26 00:53:03 +03002971 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002972 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002973 slot->data.raw.data,
2974 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002975 if( ret != 0 )
2976 {
2977 mbedtls_gcm_free( &gcm );
2978 return( mbedtls_to_psa_error( ret ) );
2979 }
mohammad16035955c982018-04-26 00:53:03 +03002980
Gilles Peskineee652a32018-06-01 19:23:52 +02002981 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002982 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002983 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002984 additional_data,
2985 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002986 tag, tag_length,
2987 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002988 mbedtls_gcm_free( &gcm );
2989 }
2990 else if( alg == PSA_ALG_CCM )
2991 {
2992 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002993
mohammad160347ddf3d2018-04-26 01:11:21 +03002994 if( nonce_length < 7 || nonce_length > 13 )
2995 return( PSA_ERROR_INVALID_ARGUMENT );
2996
mohammad16039375f842018-06-03 14:28:24 +03002997 tag_length = 16;
2998 status = psa_aead_unpadded_locate_tag( tag_length,
2999 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003000 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03003001 if( status != PSA_SUCCESS )
3002 return( status );
3003
mohammad16035955c982018-04-26 00:53:03 +03003004 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02003005 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01003006 slot->data.raw.data,
3007 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03003008 if( ret != 0 )
3009 {
3010 mbedtls_ccm_free( &ccm );
3011 return( mbedtls_to_psa_error( ret ) );
3012 }
mohammad160360a64d02018-06-03 17:20:42 +03003013 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003014 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003015 additional_data,
3016 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003017 ciphertext, plaintext,
3018 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03003019 mbedtls_ccm_free( &ccm );
3020 }
mohammad160339574652018-06-01 04:39:53 -07003021 else
3022 {
mohammad1603554faad2018-06-03 15:07:38 +03003023 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07003024 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02003025
Gilles Peskineee652a32018-06-01 19:23:52 +02003026 if( ret != 0 )
Gilles Peskine46f1fd72018-06-28 19:31:31 +02003027 {
3028 /* If plaintext_size is 0 then plaintext may be NULL and then the
3029 * call to memset has undefined behavior. */
3030 if( plaintext_size != 0 )
3031 memset( plaintext, 0, plaintext_size );
3032 }
mohammad160360a64d02018-06-03 17:20:42 +03003033 else
3034 *plaintext_length = ciphertext_length - tag_length;
3035
Gilles Peskineee652a32018-06-01 19:23:52 +02003036 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03003037}
3038
Gilles Peskinea0655c32018-04-30 17:06:50 +02003039
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003040
Gilles Peskine20035e32018-02-03 22:44:14 +01003041/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003042/* Generators */
3043/****************************************************************/
3044
3045psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
3046{
3047 psa_status_t status = PSA_SUCCESS;
3048 if( generator->alg == 0 )
3049 {
3050 /* The object has (apparently) been initialized but it is not
3051 * in use. It's ok to call abort on such an object, and there's
3052 * nothing to do. */
3053 }
3054 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003055#if defined(MBEDTLS_MD_C)
3056 if( PSA_ALG_IS_HKDF( generator->alg ) )
3057 {
3058 mbedtls_free( generator->ctx.hkdf.info );
3059 status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
3060 }
3061 else
3062#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003063 {
3064 status = PSA_ERROR_BAD_STATE;
3065 }
3066 memset( generator, 0, sizeof( *generator ) );
3067 return( status );
3068}
3069
3070
3071psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3072 size_t *capacity)
3073{
3074 *capacity = generator->capacity;
3075 return( PSA_SUCCESS );
3076}
3077
Gilles Peskinebef7f142018-07-12 17:22:21 +02003078#if defined(MBEDTLS_MD_C)
3079/* Read some bytes from an HKDF-based generator. This performs a chunk
3080 * of the expand phase of the HKDF algorithm. */
3081static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
3082 psa_algorithm_t hash_alg,
3083 uint8_t *output,
3084 size_t output_length )
3085{
3086 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3087 psa_status_t status;
3088
3089 while( output_length != 0 )
3090 {
3091 /* Copy what remains of the current block */
3092 uint8_t n = hash_length - hkdf->offset_in_block;
3093 if( n > output_length )
3094 n = (uint8_t) output_length;
3095 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
3096 output += n;
3097 output_length -= n;
3098 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02003099 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003100 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003101 /* We can't be wanting more output after block 0xff, otherwise
3102 * the capacity check in psa_generator_read() would have
3103 * prevented this call. It could happen only if the generator
3104 * object was corrupted or if this function is called directly
3105 * inside the library. */
3106 if( hkdf->block_number == 0xff )
3107 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003108
3109 /* We need a new block */
3110 ++hkdf->block_number;
3111 hkdf->offset_in_block = 0;
3112 status = psa_hmac_setup_internal( &hkdf->hmac,
3113 hkdf->prk, hash_length,
3114 hash_alg );
3115 if( status != PSA_SUCCESS )
3116 return( status );
3117 if( hkdf->block_number != 1 )
3118 {
3119 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3120 hkdf->output_block,
3121 hash_length );
3122 if( status != PSA_SUCCESS )
3123 return( status );
3124 }
3125 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3126 hkdf->info,
3127 hkdf->info_length );
3128 if( status != PSA_SUCCESS )
3129 return( status );
3130 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3131 &hkdf->block_number, 1 );
3132 if( status != PSA_SUCCESS )
3133 return( status );
3134 status = psa_hmac_finish_internal( &hkdf->hmac,
3135 hkdf->output_block,
3136 sizeof( hkdf->output_block ) );
3137 if( status != PSA_SUCCESS )
3138 return( status );
3139 }
3140
3141 return( PSA_SUCCESS );
3142}
3143#endif /* MBEDTLS_MD_C */
3144
Gilles Peskineeab56e42018-07-12 17:12:33 +02003145psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
3146 uint8_t *output,
3147 size_t output_length )
3148{
3149 psa_status_t status;
3150
3151 if( output_length > generator->capacity )
3152 {
3153 generator->capacity = 0;
3154 /* Go through the error path to wipe all confidential data now
3155 * that the generator object is useless. */
3156 status = PSA_ERROR_INSUFFICIENT_CAPACITY;
3157 goto exit;
3158 }
3159 if( output_length == 0 &&
3160 generator->capacity == 0 && generator->alg == 0 )
3161 {
3162 /* Edge case: this is a blank or finished generator, and 0
3163 * bytes were requested. The right error in this case could
3164 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3165 * INSUFFICIENT_CAPACITY, which is right for a finished
3166 * generator, for consistency with the case when
3167 * output_length > 0. */
3168 return( PSA_ERROR_INSUFFICIENT_CAPACITY );
3169 }
3170 generator->capacity -= output_length;
3171
Gilles Peskinebef7f142018-07-12 17:22:21 +02003172#if defined(MBEDTLS_MD_C)
3173 if( PSA_ALG_IS_HKDF( generator->alg ) )
3174 {
3175 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
3176 status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
3177 output, output_length );
3178 }
3179 else
3180#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003181 {
3182 return( PSA_ERROR_BAD_STATE );
3183 }
3184
3185exit:
3186 if( status != PSA_SUCCESS )
3187 {
3188 psa_generator_abort( generator );
3189 memset( output, '!', output_length );
3190 }
3191 return( status );
3192}
3193
Gilles Peskine08542d82018-07-19 17:05:42 +02003194#if defined(MBEDTLS_DES_C)
3195static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
3196{
3197 if( data_size >= 8 )
3198 mbedtls_des_key_set_parity( data );
3199 if( data_size >= 16 )
3200 mbedtls_des_key_set_parity( data + 8 );
3201 if( data_size >= 24 )
3202 mbedtls_des_key_set_parity( data + 16 );
3203}
3204#endif /* MBEDTLS_DES_C */
3205
Gilles Peskineeab56e42018-07-12 17:12:33 +02003206psa_status_t psa_generator_import_key( psa_key_slot_t key,
3207 psa_key_type_t type,
3208 size_t bits,
3209 psa_crypto_generator_t *generator )
3210{
3211 uint8_t *data = NULL;
3212 size_t bytes = PSA_BITS_TO_BYTES( bits );
3213 psa_status_t status;
3214
3215 if( ! key_type_is_raw_bytes( type ) )
3216 return( PSA_ERROR_INVALID_ARGUMENT );
3217 if( bits % 8 != 0 )
3218 return( PSA_ERROR_INVALID_ARGUMENT );
3219 data = mbedtls_calloc( 1, bytes );
3220 if( data == NULL )
3221 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3222
3223 status = psa_generator_read( generator, data, bytes );
3224 if( status != PSA_SUCCESS )
3225 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02003226#if defined(MBEDTLS_DES_C)
3227 if( type == PSA_KEY_TYPE_DES )
3228 psa_des_set_key_parity( data, bytes );
3229#endif /* MBEDTLS_DES_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003230 status = psa_import_key( key, type, data, bytes );
3231
3232exit:
3233 mbedtls_free( data );
3234 return( status );
3235}
3236
3237
3238
3239/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003240/* Key derivation */
3241/****************************************************************/
3242
Gilles Peskinebef7f142018-07-12 17:22:21 +02003243/* Set up an HKDF-based generator. This is exactly the extract phase
3244 * of the HKDF algorithm. */
3245static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
3246 key_slot_t *slot,
3247 psa_algorithm_t hash_alg,
3248 const uint8_t *salt,
3249 size_t salt_length,
3250 const uint8_t *label,
3251 size_t label_length )
3252{
3253 psa_status_t status;
3254 status = psa_hmac_setup_internal( &hkdf->hmac,
3255 salt, salt_length,
3256 PSA_ALG_HMAC_HASH( hash_alg ) );
3257 if( status != PSA_SUCCESS )
3258 return( status );
3259 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3260 slot->data.raw.data,
3261 slot->data.raw.bytes );
3262 if( status != PSA_SUCCESS )
3263 return( status );
3264 status = psa_hmac_finish_internal( &hkdf->hmac,
3265 hkdf->prk,
3266 sizeof( hkdf->prk ) );
3267 if( status != PSA_SUCCESS )
3268 return( status );
3269 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
3270 hkdf->block_number = 0;
3271 hkdf->info_length = label_length;
3272 if( label_length != 0 )
3273 {
3274 hkdf->info = mbedtls_calloc( 1, label_length );
3275 if( hkdf->info == NULL )
3276 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3277 memcpy( hkdf->info, label, label_length );
3278 }
3279 return( PSA_SUCCESS );
3280}
3281
Gilles Peskineea0fb492018-07-12 17:17:20 +02003282psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
Darryl Green88001362018-07-26 13:59:04 +01003283 psa_key_slot_t key,
Gilles Peskineea0fb492018-07-12 17:17:20 +02003284 psa_algorithm_t alg,
3285 const uint8_t *salt,
3286 size_t salt_length,
3287 const uint8_t *label,
3288 size_t label_length,
3289 size_t capacity )
3290{
3291 key_slot_t *slot;
3292 psa_status_t status;
3293
3294 if( generator->alg != 0 )
3295 return( PSA_ERROR_BAD_STATE );
3296
3297 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DERIVE, alg );
3298 if( status != PSA_SUCCESS )
3299 return( status );
3300 if( slot->type != PSA_KEY_TYPE_DERIVE )
3301 return( PSA_ERROR_INVALID_ARGUMENT );
3302
3303 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
3304 return( PSA_ERROR_INVALID_ARGUMENT );
3305
Gilles Peskinebef7f142018-07-12 17:22:21 +02003306#if defined(MBEDTLS_MD_C)
3307 if( PSA_ALG_IS_HKDF( alg ) )
3308 {
3309 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3310 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3311 if( hash_size == 0 )
3312 return( PSA_ERROR_NOT_SUPPORTED );
3313 if( capacity > 255 * hash_size )
3314 return( PSA_ERROR_INVALID_ARGUMENT );
3315 status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
3316 slot,
3317 hash_alg,
3318 salt, salt_length,
3319 label, label_length );
3320 }
3321 else
3322#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +02003323 {
3324 return( PSA_ERROR_NOT_SUPPORTED );
3325 }
3326
3327 /* Set generator->alg even on failure so that abort knows what to do. */
3328 generator->alg = alg;
3329 if( status == PSA_SUCCESS )
3330 generator->capacity = capacity;
3331 else
3332 psa_generator_abort( generator );
3333 return( status );
3334}
3335
3336
3337
3338/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003339/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02003340/****************************************************************/
3341
3342psa_status_t psa_generate_random( uint8_t *output,
3343 size_t output_size )
3344{
3345 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
3346 output, output_size );
3347 return( mbedtls_to_psa_error( ret ) );
3348}
3349
3350psa_status_t psa_generate_key( psa_key_slot_t key,
3351 psa_key_type_t type,
3352 size_t bits,
Gilles Peskine53d991e2018-07-12 01:14:59 +02003353 const void *extra,
3354 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02003355{
Gilles Peskine12313cd2018-06-20 00:20:32 +02003356 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003357 psa_status_t status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02003358
Gilles Peskine53d991e2018-07-12 01:14:59 +02003359 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02003360 return( PSA_ERROR_INVALID_ARGUMENT );
3361
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003362 status = psa_get_empty_key_slot( key, &slot );
3363 if( status != PSA_SUCCESS )
3364 return( status );
3365
Gilles Peskine48c0ea12018-06-21 14:15:31 +02003366 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02003367 {
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003368 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02003369 if( status != PSA_SUCCESS )
3370 return( status );
3371 status = psa_generate_random( slot->data.raw.data,
3372 slot->data.raw.bytes );
3373 if( status != PSA_SUCCESS )
3374 {
3375 mbedtls_free( slot->data.raw.data );
3376 return( status );
3377 }
3378#if defined(MBEDTLS_DES_C)
3379 if( type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02003380 psa_des_set_key_parity( slot->data.raw.data,
3381 slot->data.raw.bytes );
Gilles Peskine12313cd2018-06-20 00:20:32 +02003382#endif /* MBEDTLS_DES_C */
3383 }
3384 else
3385
3386#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
3387 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
3388 {
3389 mbedtls_rsa_context *rsa;
3390 int ret;
3391 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02003392 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
3393 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02003394 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02003395 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02003396 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02003397 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02003398 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02003399#if INT_MAX < 0xffffffff
3400 /* Check that the uint32_t value passed by the caller fits
3401 * in the range supported by this implementation. */
3402 if( p->e > INT_MAX )
3403 return( PSA_ERROR_NOT_SUPPORTED );
3404#endif
3405 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02003406 }
3407 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
3408 if( rsa == NULL )
3409 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3410 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
3411 ret = mbedtls_rsa_gen_key( rsa,
3412 mbedtls_ctr_drbg_random,
3413 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01003414 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02003415 exponent );
3416 if( ret != 0 )
3417 {
3418 mbedtls_rsa_free( rsa );
3419 mbedtls_free( rsa );
3420 return( mbedtls_to_psa_error( ret ) );
3421 }
3422 slot->data.rsa = rsa;
3423 }
3424 else
3425#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
3426
3427#if defined(MBEDTLS_ECP_C)
3428 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
3429 {
3430 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
3431 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
3432 const mbedtls_ecp_curve_info *curve_info =
3433 mbedtls_ecp_curve_info_from_grp_id( grp_id );
3434 mbedtls_ecp_keypair *ecp;
3435 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02003436 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02003437 return( PSA_ERROR_NOT_SUPPORTED );
3438 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
3439 return( PSA_ERROR_NOT_SUPPORTED );
3440 if( curve_info->bit_size != bits )
3441 return( PSA_ERROR_INVALID_ARGUMENT );
3442 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
3443 if( ecp == NULL )
3444 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3445 mbedtls_ecp_keypair_init( ecp );
3446 ret = mbedtls_ecp_gen_key( grp_id, ecp,
3447 mbedtls_ctr_drbg_random,
3448 &global_data.ctr_drbg );
3449 if( ret != 0 )
3450 {
3451 mbedtls_ecp_keypair_free( ecp );
3452 mbedtls_free( ecp );
3453 return( mbedtls_to_psa_error( ret ) );
3454 }
3455 slot->data.ecp = ecp;
3456 }
3457 else
3458#endif /* MBEDTLS_ECP_C */
3459
3460 return( PSA_ERROR_NOT_SUPPORTED );
3461
3462 slot->type = type;
3463 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02003464}
3465
3466
3467/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003468/* Module setup */
3469/****************************************************************/
3470
Gilles Peskinee59236f2018-01-27 23:32:46 +01003471void mbedtls_psa_crypto_free( void )
3472{
Jaeden Amero045bd502018-06-26 14:00:08 +01003473 psa_key_slot_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02003474 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003475 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003476 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
3477 mbedtls_entropy_free( &global_data.entropy );
3478 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3479}
3480
3481psa_status_t psa_crypto_init( void )
3482{
3483 int ret;
3484 const unsigned char drbg_seed[] = "PSA";
3485
3486 if( global_data.initialized != 0 )
3487 return( PSA_SUCCESS );
3488
3489 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3490 mbedtls_entropy_init( &global_data.entropy );
3491 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
3492
3493 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
3494 mbedtls_entropy_func,
3495 &global_data.entropy,
3496 drbg_seed, sizeof( drbg_seed ) - 1 );
3497 if( ret != 0 )
3498 goto exit;
3499
Gilles Peskinee4ebc122018-03-07 14:16:44 +01003500 global_data.initialized = 1;
3501
Gilles Peskinee59236f2018-01-27 23:32:46 +01003502exit:
3503 if( ret != 0 )
3504 mbedtls_psa_crypto_free( );
3505 return( mbedtls_to_psa_error( ret ) );
3506}
3507
3508#endif /* MBEDTLS_PSA_CRYPTO_C */