blob: 910de1f03f037daea2939b2741d4865a6af1dd41 [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
Darryl Greend49a4992018-06-18 17:27:26 +010046/* Include internal declarations that are useful for implementing persistently
47 * stored keys. */
48#include "psa_crypto_storage.h"
49
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010050#include <stdlib.h>
51#include <string.h>
52#if defined(MBEDTLS_PLATFORM_C)
53#include "mbedtls/platform.h"
54#else
55#define mbedtls_calloc calloc
56#define mbedtls_free free
57#endif
58
Gilles Peskinea5905292018-02-07 20:59:33 +010059#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020060#include "mbedtls/asn1.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020061#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010062#include "mbedtls/blowfish.h"
63#include "mbedtls/camellia.h"
64#include "mbedtls/cipher.h"
65#include "mbedtls/ccm.h"
66#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010067#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010068#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020069#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010070#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010071#include "mbedtls/entropy.h"
Netanel Gonen2bcd3122018-11-19 11:53:02 +020072#include "mbedtls/entropy_poll.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010073#include "mbedtls/error.h"
74#include "mbedtls/gcm.h"
75#include "mbedtls/md2.h"
76#include "mbedtls/md4.h"
77#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010078#include "mbedtls/md.h"
79#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010080#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010081#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010082#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010083#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010084#include "mbedtls/sha1.h"
85#include "mbedtls/sha256.h"
86#include "mbedtls/sha512.h"
87#include "mbedtls/xtea.h"
88
Netanel Gonen2bcd3122018-11-19 11:53:02 +020089#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
90#include "psa_prot_internal_storage.h"
91#endif
Gilles Peskinee59236f2018-01-27 23:32:46 +010092
Gilles Peskine996deb12018-08-01 15:45:45 +020093#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
94
Gilles Peskinee59236f2018-01-27 23:32:46 +010095/* Implementation that should never be optimized out by the compiler */
96static void mbedtls_zeroize( void *v, size_t n )
97{
98 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
99}
100
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100101/* constant-time buffer comparison */
102static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
103{
104 size_t i;
105 unsigned char diff = 0;
106
107 for( i = 0; i < n; i++ )
108 diff |= a[i] ^ b[i];
109
110 return( diff );
111}
112
113
114
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100115/****************************************************************/
116/* Global data, support functions and library management */
117/****************************************************************/
118
119/* Number of key slots (plus one because 0 is not used).
120 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +0200121#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100122
Gilles Peskine2d277862018-06-18 15:41:12 +0200123typedef struct
124{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100125 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300126 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200127 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200128 union
129 {
130 struct raw_data
131 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100132 uint8_t *data;
133 size_t bytes;
134 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100135#if defined(MBEDTLS_RSA_C)
136 mbedtls_rsa_context *rsa;
137#endif /* MBEDTLS_RSA_C */
138#if defined(MBEDTLS_ECP_C)
139 mbedtls_ecp_keypair *ecp;
140#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100141 } data;
142} key_slot_t;
143
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200144static int key_type_is_raw_bytes( psa_key_type_t type )
145{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200146 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200147}
148
Gilles Peskine2d277862018-06-18 15:41:12 +0200149typedef struct
150{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100151 int initialized;
152 mbedtls_entropy_context entropy;
153 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200154 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100155} psa_global_data_t;
156
157static psa_global_data_t global_data;
158
itayzafrir0adf0fc2018-09-06 16:24:41 +0300159#define GUARD_MODULE_INITIALIZED \
160 if( global_data.initialized == 0 ) \
161 return( PSA_ERROR_BAD_STATE );
162
Gilles Peskinee59236f2018-01-27 23:32:46 +0100163static psa_status_t mbedtls_to_psa_error( int ret )
164{
Gilles Peskinea5905292018-02-07 20:59:33 +0100165 /* If there's both a high-level code and low-level code, dispatch on
166 * the high-level code. */
167 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100168 {
169 case 0:
170 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100171
172 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
173 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
174 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
175 return( PSA_ERROR_NOT_SUPPORTED );
176 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
177 return( PSA_ERROR_HARDWARE_FAILURE );
178
179 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
180 return( PSA_ERROR_HARDWARE_FAILURE );
181
Gilles Peskine9a944802018-06-21 09:35:35 +0200182 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
183 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
184 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
185 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
186 case MBEDTLS_ERR_ASN1_INVALID_DATA:
187 return( PSA_ERROR_INVALID_ARGUMENT );
188 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
189 return( PSA_ERROR_INSUFFICIENT_MEMORY );
190 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
191 return( PSA_ERROR_BUFFER_TOO_SMALL );
192
Gilles Peskinea5905292018-02-07 20:59:33 +0100193 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
194 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
195 return( PSA_ERROR_NOT_SUPPORTED );
196 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
197 return( PSA_ERROR_HARDWARE_FAILURE );
198
199 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
200 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
201 return( PSA_ERROR_NOT_SUPPORTED );
202 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
203 return( PSA_ERROR_HARDWARE_FAILURE );
204
205 case MBEDTLS_ERR_CCM_BAD_INPUT:
206 return( PSA_ERROR_INVALID_ARGUMENT );
207 case MBEDTLS_ERR_CCM_AUTH_FAILED:
208 return( PSA_ERROR_INVALID_SIGNATURE );
209 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
210 return( PSA_ERROR_HARDWARE_FAILURE );
211
212 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
213 return( PSA_ERROR_NOT_SUPPORTED );
214 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
215 return( PSA_ERROR_INVALID_ARGUMENT );
216 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
217 return( PSA_ERROR_INSUFFICIENT_MEMORY );
218 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
219 return( PSA_ERROR_INVALID_PADDING );
220 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
221 return( PSA_ERROR_BAD_STATE );
222 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
223 return( PSA_ERROR_INVALID_SIGNATURE );
224 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
225 return( PSA_ERROR_TAMPERING_DETECTED );
226 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
227 return( PSA_ERROR_HARDWARE_FAILURE );
228
229 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
230 return( PSA_ERROR_HARDWARE_FAILURE );
231
232 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
233 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
234 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
235 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
236 return( PSA_ERROR_NOT_SUPPORTED );
237 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
238 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
239
240 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
241 return( PSA_ERROR_NOT_SUPPORTED );
242 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
243 return( PSA_ERROR_HARDWARE_FAILURE );
244
Gilles Peskinee59236f2018-01-27 23:32:46 +0100245 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
246 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
247 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
248 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100249
250 case MBEDTLS_ERR_GCM_AUTH_FAILED:
251 return( PSA_ERROR_INVALID_SIGNATURE );
252 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200253 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100254 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
255 return( PSA_ERROR_HARDWARE_FAILURE );
256
257 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
258 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
259 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
260 return( PSA_ERROR_HARDWARE_FAILURE );
261
262 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
263 return( PSA_ERROR_NOT_SUPPORTED );
264 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
265 return( PSA_ERROR_INVALID_ARGUMENT );
266 case MBEDTLS_ERR_MD_ALLOC_FAILED:
267 return( PSA_ERROR_INSUFFICIENT_MEMORY );
268 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
269 return( PSA_ERROR_STORAGE_FAILURE );
270 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
271 return( PSA_ERROR_HARDWARE_FAILURE );
272
Gilles Peskinef76aa772018-10-29 19:24:33 +0100273 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
274 return( PSA_ERROR_STORAGE_FAILURE );
275 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
276 return( PSA_ERROR_INVALID_ARGUMENT );
277 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
278 return( PSA_ERROR_INVALID_ARGUMENT );
279 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
280 return( PSA_ERROR_BUFFER_TOO_SMALL );
281 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
282 return( PSA_ERROR_INVALID_ARGUMENT );
283 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
284 return( PSA_ERROR_INVALID_ARGUMENT );
285 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
286 return( PSA_ERROR_INVALID_ARGUMENT );
287 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
288 return( PSA_ERROR_INSUFFICIENT_MEMORY );
289
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100290 case MBEDTLS_ERR_PK_ALLOC_FAILED:
291 return( PSA_ERROR_INSUFFICIENT_MEMORY );
292 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
293 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
294 return( PSA_ERROR_INVALID_ARGUMENT );
295 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100296 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100297 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
298 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
299 return( PSA_ERROR_INVALID_ARGUMENT );
300 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
301 return( PSA_ERROR_NOT_SUPPORTED );
302 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
303 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
304 return( PSA_ERROR_NOT_PERMITTED );
305 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
306 return( PSA_ERROR_INVALID_ARGUMENT );
307 case MBEDTLS_ERR_PK_INVALID_ALG:
308 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
309 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
310 return( PSA_ERROR_NOT_SUPPORTED );
311 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
312 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100313 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
314 return( PSA_ERROR_HARDWARE_FAILURE );
315
316 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
317 return( PSA_ERROR_HARDWARE_FAILURE );
318
319 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
320 return( PSA_ERROR_INVALID_ARGUMENT );
321 case MBEDTLS_ERR_RSA_INVALID_PADDING:
322 return( PSA_ERROR_INVALID_PADDING );
323 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
324 return( PSA_ERROR_HARDWARE_FAILURE );
325 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
326 return( PSA_ERROR_INVALID_ARGUMENT );
327 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
328 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
329 return( PSA_ERROR_TAMPERING_DETECTED );
330 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
331 return( PSA_ERROR_INVALID_SIGNATURE );
332 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
333 return( PSA_ERROR_BUFFER_TOO_SMALL );
334 case MBEDTLS_ERR_RSA_RNG_FAILED:
335 return( PSA_ERROR_INSUFFICIENT_MEMORY );
336 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
337 return( PSA_ERROR_NOT_SUPPORTED );
338 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
339 return( PSA_ERROR_HARDWARE_FAILURE );
340
341 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
342 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
343 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
344 return( PSA_ERROR_HARDWARE_FAILURE );
345
346 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
347 return( PSA_ERROR_INVALID_ARGUMENT );
348 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
349 return( PSA_ERROR_HARDWARE_FAILURE );
350
itayzafrir5c753392018-05-08 11:18:38 +0300351 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300352 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300353 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300354 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
355 return( PSA_ERROR_BUFFER_TOO_SMALL );
356 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
357 return( PSA_ERROR_NOT_SUPPORTED );
358 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
359 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
360 return( PSA_ERROR_INVALID_SIGNATURE );
361 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
362 return( PSA_ERROR_INSUFFICIENT_MEMORY );
363 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
364 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300365
Gilles Peskinee59236f2018-01-27 23:32:46 +0100366 default:
367 return( PSA_ERROR_UNKNOWN_ERROR );
368 }
369}
370
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200371
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200372
373
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100374/****************************************************************/
375/* Key management */
376/****************************************************************/
377
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100378#if defined(MBEDTLS_ECP_C)
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200379static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
380{
381 switch( grpid )
382 {
383 case MBEDTLS_ECP_DP_SECP192R1:
384 return( PSA_ECC_CURVE_SECP192R1 );
385 case MBEDTLS_ECP_DP_SECP224R1:
386 return( PSA_ECC_CURVE_SECP224R1 );
387 case MBEDTLS_ECP_DP_SECP256R1:
388 return( PSA_ECC_CURVE_SECP256R1 );
389 case MBEDTLS_ECP_DP_SECP384R1:
390 return( PSA_ECC_CURVE_SECP384R1 );
391 case MBEDTLS_ECP_DP_SECP521R1:
392 return( PSA_ECC_CURVE_SECP521R1 );
393 case MBEDTLS_ECP_DP_BP256R1:
394 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
395 case MBEDTLS_ECP_DP_BP384R1:
396 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
397 case MBEDTLS_ECP_DP_BP512R1:
398 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
399 case MBEDTLS_ECP_DP_CURVE25519:
400 return( PSA_ECC_CURVE_CURVE25519 );
401 case MBEDTLS_ECP_DP_SECP192K1:
402 return( PSA_ECC_CURVE_SECP192K1 );
403 case MBEDTLS_ECP_DP_SECP224K1:
404 return( PSA_ECC_CURVE_SECP224K1 );
405 case MBEDTLS_ECP_DP_SECP256K1:
406 return( PSA_ECC_CURVE_SECP256K1 );
407 case MBEDTLS_ECP_DP_CURVE448:
408 return( PSA_ECC_CURVE_CURVE448 );
409 default:
410 return( 0 );
411 }
412}
413
Gilles Peskine12313cd2018-06-20 00:20:32 +0200414static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
415{
416 switch( curve )
417 {
418 case PSA_ECC_CURVE_SECP192R1:
419 return( MBEDTLS_ECP_DP_SECP192R1 );
420 case PSA_ECC_CURVE_SECP224R1:
421 return( MBEDTLS_ECP_DP_SECP224R1 );
422 case PSA_ECC_CURVE_SECP256R1:
423 return( MBEDTLS_ECP_DP_SECP256R1 );
424 case PSA_ECC_CURVE_SECP384R1:
425 return( MBEDTLS_ECP_DP_SECP384R1 );
426 case PSA_ECC_CURVE_SECP521R1:
427 return( MBEDTLS_ECP_DP_SECP521R1 );
428 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
429 return( MBEDTLS_ECP_DP_BP256R1 );
430 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
431 return( MBEDTLS_ECP_DP_BP384R1 );
432 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
433 return( MBEDTLS_ECP_DP_BP512R1 );
434 case PSA_ECC_CURVE_CURVE25519:
435 return( MBEDTLS_ECP_DP_CURVE25519 );
436 case PSA_ECC_CURVE_SECP192K1:
437 return( MBEDTLS_ECP_DP_SECP192K1 );
438 case PSA_ECC_CURVE_SECP224K1:
439 return( MBEDTLS_ECP_DP_SECP224K1 );
440 case PSA_ECC_CURVE_SECP256K1:
441 return( MBEDTLS_ECP_DP_SECP256K1 );
442 case PSA_ECC_CURVE_CURVE448:
443 return( MBEDTLS_ECP_DP_CURVE448 );
444 default:
445 return( MBEDTLS_ECP_DP_NONE );
446 }
447}
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100448#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200449
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200450static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
451 size_t bits,
452 struct raw_data *raw )
453{
454 /* Check that the bit size is acceptable for the key type */
455 switch( type )
456 {
457 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200458 if( bits == 0 )
459 {
460 raw->bytes = 0;
461 raw->data = NULL;
462 return( PSA_SUCCESS );
463 }
464 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200465#if defined(MBEDTLS_MD_C)
466 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200467#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200468 case PSA_KEY_TYPE_DERIVE:
469 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200470#if defined(MBEDTLS_AES_C)
471 case PSA_KEY_TYPE_AES:
472 if( bits != 128 && bits != 192 && bits != 256 )
473 return( PSA_ERROR_INVALID_ARGUMENT );
474 break;
475#endif
476#if defined(MBEDTLS_CAMELLIA_C)
477 case PSA_KEY_TYPE_CAMELLIA:
478 if( bits != 128 && bits != 192 && bits != 256 )
479 return( PSA_ERROR_INVALID_ARGUMENT );
480 break;
481#endif
482#if defined(MBEDTLS_DES_C)
483 case PSA_KEY_TYPE_DES:
484 if( bits != 64 && bits != 128 && bits != 192 )
485 return( PSA_ERROR_INVALID_ARGUMENT );
486 break;
487#endif
488#if defined(MBEDTLS_ARC4_C)
489 case PSA_KEY_TYPE_ARC4:
490 if( bits < 8 || bits > 2048 )
491 return( PSA_ERROR_INVALID_ARGUMENT );
492 break;
493#endif
494 default:
495 return( PSA_ERROR_NOT_SUPPORTED );
496 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200497 if( bits % 8 != 0 )
498 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200499
500 /* Allocate memory for the key */
501 raw->bytes = PSA_BITS_TO_BYTES( bits );
502 raw->data = mbedtls_calloc( 1, raw->bytes );
503 if( raw->data == NULL )
504 {
505 raw->bytes = 0;
506 return( PSA_ERROR_INSUFFICIENT_MEMORY );
507 }
508 return( PSA_SUCCESS );
509}
510
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200511#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine86a440b2018-11-12 18:39:40 +0100512/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
513 * that are not a multiple of 8) well. For example, there is only
514 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
515 * way to return the exact bit size of a key.
516 * To keep things simple, reject non-byte-aligned key sizes. */
517static psa_status_t psa_check_rsa_key_byte_aligned(
518 const mbedtls_rsa_context *rsa )
519{
520 mbedtls_mpi n;
521 psa_status_t status;
522 mbedtls_mpi_init( &n );
523 status = mbedtls_to_psa_error(
524 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
525 if( status == PSA_SUCCESS )
526 {
527 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
528 status = PSA_ERROR_NOT_SUPPORTED;
529 }
530 mbedtls_mpi_free( &n );
531 return( status );
532}
533
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200534static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
535 mbedtls_rsa_context **p_rsa )
536{
537 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_RSA )
538 return( PSA_ERROR_INVALID_ARGUMENT );
539 else
540 {
541 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *pk );
Gilles Peskineaac64a22018-11-12 18:37:42 +0100542 /* The size of an RSA key doesn't have to be a multiple of 8.
543 * Mbed TLS supports non-byte-aligned key sizes, but not well.
544 * For example, mbedtls_rsa_get_len() returns the key size in
545 * bytes, not in bits. */
546 size_t bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100547 psa_status_t status;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200548 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
549 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100550 status = psa_check_rsa_key_byte_aligned( rsa );
551 if( status != PSA_SUCCESS )
552 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200553 *p_rsa = rsa;
554 return( PSA_SUCCESS );
555 }
556}
557#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
558
559#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinef76aa772018-10-29 19:24:33 +0100560/* Import an elliptic curve parsed by the mbedtls pk module. */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200561static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
562 mbedtls_pk_context *pk,
563 mbedtls_ecp_keypair **p_ecp )
564{
565 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
566 return( PSA_ERROR_INVALID_ARGUMENT );
567 else
568 {
569 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
570 psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
571 if( actual_curve != expected_curve )
572 return( PSA_ERROR_INVALID_ARGUMENT );
573 *p_ecp = ecp;
574 return( PSA_SUCCESS );
575 }
576}
577#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
578
Gilles Peskinef76aa772018-10-29 19:24:33 +0100579#if defined(MBEDTLS_ECP_C)
580/* Import a private key given as a byte string which is the private value
581 * in big-endian order. */
582static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
583 const uint8_t *data,
584 size_t data_length,
585 mbedtls_ecp_keypair **p_ecp )
586{
587 psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
588 mbedtls_ecp_keypair *ecp = NULL;
589 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
590
591 *p_ecp = NULL;
592 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
593 if( ecp == NULL )
594 return( PSA_ERROR_INSUFFICIENT_MEMORY );
595
596 /* Load the group. */
597 status = mbedtls_to_psa_error(
598 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
599 if( status != PSA_SUCCESS )
600 goto exit;
601 /* Load the secret value. */
602 status = mbedtls_to_psa_error(
603 mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
604 if( status != PSA_SUCCESS )
605 goto exit;
606 /* Validate the private key. */
607 status = mbedtls_to_psa_error(
608 mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
609 if( status != PSA_SUCCESS )
610 goto exit;
611 /* Calculate the public key from the private key. */
612 status = mbedtls_to_psa_error(
613 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
614 mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
615 if( status != PSA_SUCCESS )
616 goto exit;
617
618 *p_ecp = ecp;
619 return( PSA_SUCCESS );
620
621exit:
622 if( ecp != NULL )
623 {
624 mbedtls_ecp_keypair_free( ecp );
625 mbedtls_free( ecp );
626 }
627 return( status );
628}
629#endif /* defined(MBEDTLS_ECP_C) */
630
Darryl Green940d72c2018-07-13 13:18:51 +0100631static psa_status_t psa_import_key_into_slot( key_slot_t *slot,
632 const uint8_t *data,
633 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100634{
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200635 psa_status_t status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100636
Darryl Green940d72c2018-07-13 13:18:51 +0100637 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100638 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100639 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100640 if( data_length > SIZE_MAX / 8 )
641 return( PSA_ERROR_NOT_SUPPORTED );
Darryl Green940d72c2018-07-13 13:18:51 +0100642 status = prepare_raw_data_slot( slot->type,
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200643 PSA_BYTES_TO_BITS( data_length ),
644 &slot->data.raw );
645 if( status != PSA_SUCCESS )
646 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200647 if( data_length != 0 )
648 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100649 }
650 else
Gilles Peskinef76aa772018-10-29 19:24:33 +0100651#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100652 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100653 {
Darryl Green940d72c2018-07-13 13:18:51 +0100654 status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskinef76aa772018-10-29 19:24:33 +0100655 data, data_length,
656 &slot->data.ecp );
657 if( status != PSA_SUCCESS )
658 return( status );
659 }
660 else
661#endif /* MBEDTLS_ECP_C */
Gilles Peskine969ac722018-01-28 18:16:59 +0100662#if defined(MBEDTLS_PK_PARSE_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100663 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
664 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100665 {
666 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100667 mbedtls_pk_context pk;
668 mbedtls_pk_init( &pk );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200669
670 /* Parse the data. */
Darryl Green940d72c2018-07-13 13:18:51 +0100671 if( PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100672 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
673 else
674 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100675 if( ret != 0 )
676 return( mbedtls_to_psa_error( ret ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200677
678 /* We have something that the pkparse module recognizes.
679 * If it has the expected type and passes any type-specific
680 * checks, store it. */
Gilles Peskine969ac722018-01-28 18:16:59 +0100681#if defined(MBEDTLS_RSA_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100682 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200683 status = psa_import_rsa_key( &pk, &slot->data.rsa );
684 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100685#endif /* MBEDTLS_RSA_C */
686#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100687 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
688 status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200689 &pk, &slot->data.ecp );
690 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100691#endif /* MBEDTLS_ECP_C */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200692 {
693 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinec648d692018-06-28 08:46:13 +0200694 }
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200695
Gilles Peskinec648d692018-06-28 08:46:13 +0200696 /* Free the content of the pk object only on error. On success,
697 * the content of the object has been stored in the slot. */
698 if( status != PSA_SUCCESS )
699 {
700 mbedtls_pk_free( &pk );
701 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100702 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100703 }
704 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100705#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100706 {
707 return( PSA_ERROR_NOT_SUPPORTED );
708 }
Darryl Green940d72c2018-07-13 13:18:51 +0100709 return( PSA_SUCCESS );
710}
711
Darryl Greend49a4992018-06-18 17:27:26 +0100712#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
713static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t key,
714 key_slot_t *p_slot )
715{
716 psa_status_t status = PSA_SUCCESS;
717 uint8_t *key_data = NULL;
718 size_t key_data_length = 0;
719
720 status = psa_load_persistent_key( key, &( p_slot )->type,
721 &( p_slot )->policy, &key_data,
722 &key_data_length );
723 if( status != PSA_SUCCESS )
724 goto exit;
725 status = psa_import_key_into_slot( p_slot,
726 key_data, key_data_length );
727exit:
728 psa_free_persistent_key_data( key_data, key_data_length );
729 return( status );
730}
731#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
732
Darryl Green06fd18d2018-07-16 11:21:11 +0100733/* Retrieve a key slot, occupied or not. */
734static psa_status_t psa_get_key_slot( psa_key_slot_t key,
735 key_slot_t **p_slot )
736{
737 GUARD_MODULE_INITIALIZED;
738
739 /* 0 is not a valid slot number under any circumstance. This
740 * implementation provides slots number 1 to N where N is the
741 * number of available slots. */
742 if( key == 0 || key > ARRAY_LENGTH( global_data.key_slots ) )
743 return( PSA_ERROR_INVALID_ARGUMENT );
744
745 *p_slot = &global_data.key_slots[key - 1];
Darryl Greend49a4992018-06-18 17:27:26 +0100746
747#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
748 if( ( *p_slot )->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
749 {
750 /* There are two circumstances this can occur: the key material has
751 * not yet been created, or the key exists in storage but has not yet
752 * been loaded into memory. */
753 if( ( *p_slot )->type == PSA_KEY_TYPE_NONE )
754 {
755 psa_status_t status = PSA_SUCCESS;
756 status = psa_load_persistent_key_into_slot( key, *p_slot );
757 if( status != PSA_ERROR_EMPTY_SLOT )
758 return( status );
759 }
760 }
761#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
762
Darryl Green06fd18d2018-07-16 11:21:11 +0100763 return( PSA_SUCCESS );
764}
765
766/* Retrieve an empty key slot (slot with no key data, but possibly
767 * with some metadata such as a policy). */
768static psa_status_t psa_get_empty_key_slot( psa_key_slot_t key,
769 key_slot_t **p_slot )
770{
771 psa_status_t status;
772 key_slot_t *slot = NULL;
773
774 *p_slot = NULL;
775
776 status = psa_get_key_slot( key, &slot );
777 if( status != PSA_SUCCESS )
778 return( status );
779
780 if( slot->type != PSA_KEY_TYPE_NONE )
781 return( PSA_ERROR_OCCUPIED_SLOT );
782
783 *p_slot = slot;
784 return( status );
785}
786
787/** Retrieve a slot which must contain a key. The key must have allow all the
788 * usage flags set in \p usage. If \p alg is nonzero, the key must allow
789 * operations with this algorithm. */
790static psa_status_t psa_get_key_from_slot( psa_key_slot_t key,
791 key_slot_t **p_slot,
792 psa_key_usage_t usage,
793 psa_algorithm_t alg )
794{
795 psa_status_t status;
796 key_slot_t *slot = NULL;
797
798 *p_slot = NULL;
799
800 status = psa_get_key_slot( key, &slot );
801 if( status != PSA_SUCCESS )
802 return( status );
803 if( slot->type == PSA_KEY_TYPE_NONE )
804 return( PSA_ERROR_EMPTY_SLOT );
805
806 /* Enforce that usage policy for the key slot contains all the flags
807 * required by the usage parameter. There is one exception: public
808 * keys can always be exported, so we treat public key objects as
809 * if they had the export flag. */
810 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
811 usage &= ~PSA_KEY_USAGE_EXPORT;
812 if( ( slot->policy.usage & usage ) != usage )
813 return( PSA_ERROR_NOT_PERMITTED );
814 if( alg != 0 && ( alg != slot->policy.alg ) )
815 return( PSA_ERROR_NOT_PERMITTED );
816
817 *p_slot = slot;
818 return( PSA_SUCCESS );
819}
Darryl Green940d72c2018-07-13 13:18:51 +0100820
Darryl Green40225ba2018-11-15 14:48:15 +0000821static psa_status_t psa_remove_key_data_from_memory( key_slot_t *slot )
822{
823 if( slot->type == PSA_KEY_TYPE_NONE )
824 {
825 /* No key material to clean. */
826 }
827 else if( key_type_is_raw_bytes( slot->type ) )
828 {
829 mbedtls_free( slot->data.raw.data );
830 }
831 else
832#if defined(MBEDTLS_RSA_C)
833 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
834 {
835 mbedtls_rsa_free( slot->data.rsa );
836 mbedtls_free( slot->data.rsa );
837 }
838 else
839#endif /* defined(MBEDTLS_RSA_C) */
840#if defined(MBEDTLS_ECP_C)
841 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
842 {
843 mbedtls_ecp_keypair_free( slot->data.ecp );
844 mbedtls_free( slot->data.ecp );
845 }
846 else
847#endif /* defined(MBEDTLS_ECP_C) */
848 {
849 /* Shouldn't happen: the key type is not any type that we
850 * put in. */
851 return( PSA_ERROR_TAMPERING_DETECTED );
852 }
853
854 return( PSA_SUCCESS );
855}
856
Darryl Green940d72c2018-07-13 13:18:51 +0100857psa_status_t psa_import_key( psa_key_slot_t key,
858 psa_key_type_t type,
859 const uint8_t *data,
860 size_t data_length )
861{
862 key_slot_t *slot;
863 psa_status_t status;
864
865 status = psa_get_empty_key_slot( key, &slot );
866 if( status != PSA_SUCCESS )
867 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100868
869 slot->type = type;
Darryl Green940d72c2018-07-13 13:18:51 +0100870
871 status = psa_import_key_into_slot( slot, data, data_length );
872 if( status != PSA_SUCCESS )
873 {
874 slot->type = PSA_KEY_TYPE_NONE;
875 return( status );
876 }
877
Darryl Greend49a4992018-06-18 17:27:26 +0100878#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
879 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
880 {
881 /* Store in file location */
882 status = psa_save_persistent_key( key, slot->type, &slot->policy, data,
883 data_length );
884 if( status != PSA_SUCCESS )
885 {
886 (void) psa_remove_key_data_from_memory( slot );
887 slot->type = PSA_KEY_TYPE_NONE;
888 }
889 }
890#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
891
892 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100893}
894
Gilles Peskine2d277862018-06-18 15:41:12 +0200895psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100896{
897 key_slot_t *slot;
Darryl Greend49a4992018-06-18 17:27:26 +0100898 psa_status_t status = PSA_SUCCESS;
899 psa_status_t storage_status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100900
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200901 status = psa_get_key_slot( key, &slot );
902 if( status != PSA_SUCCESS )
903 return( status );
Darryl Greend49a4992018-06-18 17:27:26 +0100904#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
905 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
906 {
907 storage_status = psa_destroy_persistent_key( key );
908 }
909#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
910 status = psa_remove_key_data_from_memory( slot );
911 /* Zeroize the slot to wipe metadata such as policies. */
912 mbedtls_zeroize( slot, sizeof( *slot ) );
913 if( status != PSA_SUCCESS )
914 return( status );
915 return( storage_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100916}
917
Gilles Peskineb870b182018-07-06 16:02:09 +0200918/* Return the size of the key in the given slot, in bits. */
919static size_t psa_get_key_bits( const key_slot_t *slot )
920{
921 if( key_type_is_raw_bytes( slot->type ) )
922 return( slot->data.raw.bytes * 8 );
923#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200924 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaac64a22018-11-12 18:37:42 +0100925 return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
Gilles Peskineb870b182018-07-06 16:02:09 +0200926#endif /* defined(MBEDTLS_RSA_C) */
927#if defined(MBEDTLS_ECP_C)
928 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
929 return( slot->data.ecp->grp.pbits );
930#endif /* defined(MBEDTLS_ECP_C) */
931 /* Shouldn't happen except on an empty slot. */
932 return( 0 );
933}
934
Gilles Peskine2d277862018-06-18 15:41:12 +0200935psa_status_t psa_get_key_information( psa_key_slot_t key,
936 psa_key_type_t *type,
937 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100938{
939 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200940 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100941
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100942 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200943 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100944 if( bits != NULL )
945 *bits = 0;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200946 status = psa_get_key_slot( key, &slot );
947 if( status != PSA_SUCCESS )
948 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +0200949
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100950 if( slot->type == PSA_KEY_TYPE_NONE )
951 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200952 if( type != NULL )
953 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +0200954 if( bits != NULL )
955 *bits = psa_get_key_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100956 return( PSA_SUCCESS );
957}
958
Darryl Greendd8fb772018-11-07 16:00:44 +0000959static psa_status_t psa_internal_export_key( key_slot_t *slot,
Gilles Peskine2d277862018-06-18 15:41:12 +0200960 uint8_t *data,
961 size_t data_size,
962 size_t *data_length,
963 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100964{
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100965 *data_length = 0;
966
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200967 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300968 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300969
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200970 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100971 {
972 if( slot->data.raw.bytes > data_size )
973 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine52b90182018-10-29 19:26:27 +0100974 if( data_size != 0 )
975 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200976 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine52b90182018-10-29 19:26:27 +0100977 memset( data + slot->data.raw.bytes, 0,
978 data_size - slot->data.raw.bytes );
979 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100980 *data_length = slot->data.raw.bytes;
981 return( PSA_SUCCESS );
982 }
Gilles Peskine188c71e2018-10-29 19:26:02 +0100983#if defined(MBEDTLS_ECP_C)
984 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) && !export_public_key )
985 {
Darryl Greendd8fb772018-11-07 16:00:44 +0000986 psa_status_t status;
987
Gilles Peskine188c71e2018-10-29 19:26:02 +0100988 size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( slot ) );
989 if( bytes > data_size )
990 return( PSA_ERROR_BUFFER_TOO_SMALL );
991 status = mbedtls_to_psa_error(
992 mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
993 if( status != PSA_SUCCESS )
994 return( status );
995 memset( data + bytes, 0, data_size - bytes );
996 *data_length = bytes;
997 return( PSA_SUCCESS );
998 }
999#endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001000 else
Moran Peker17e36e12018-05-02 12:55:20 +03001001 {
Gilles Peskine969ac722018-01-28 18:16:59 +01001002#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02001003 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
Moran Pekera998bc62018-04-16 18:16:20 +03001004 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +01001005 {
Moran Pekera998bc62018-04-16 18:16:20 +03001006 mbedtls_pk_context pk;
1007 int ret;
Gilles Peskined8008d62018-06-29 19:51:51 +02001008 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001009 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001010#if defined(MBEDTLS_RSA_C)
1011 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001012 pk.pk_info = &mbedtls_rsa_info;
1013 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001014#else
1015 return( PSA_ERROR_NOT_SUPPORTED );
1016#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001017 }
1018 else
1019 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001020#if defined(MBEDTLS_ECP_C)
1021 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001022 pk.pk_info = &mbedtls_eckey_info;
1023 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001024#else
1025 return( PSA_ERROR_NOT_SUPPORTED );
1026#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001027 }
Moran Pekerd7326592018-05-29 16:56:39 +03001028 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001029 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +03001030 else
1031 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +03001032 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001033 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001034 /* If data_size is 0 then data may be NULL and then the
1035 * call to memset would have undefined behavior. */
1036 if( data_size != 0 )
1037 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +03001038 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001039 }
Gilles Peskine0e231582018-06-20 00:11:07 +02001040 /* The mbedtls_pk_xxx functions write to the end of the buffer.
1041 * Move the data to the beginning and erase remaining data
1042 * at the original location. */
1043 if( 2 * (size_t) ret <= data_size )
1044 {
1045 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001046 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001047 }
1048 else if( (size_t) ret < data_size )
1049 {
1050 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001051 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001052 }
Moran Pekera998bc62018-04-16 18:16:20 +03001053 *data_length = ret;
1054 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +01001055 }
1056 else
Gilles Peskine6d912132018-03-07 16:41:37 +01001057#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +03001058 {
1059 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +02001060 it is valid for a special-purpose implementation to omit
1061 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +03001062 return( PSA_ERROR_NOT_SUPPORTED );
1063 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001064 }
1065}
1066
Gilles Peskine2d277862018-06-18 15:41:12 +02001067psa_status_t psa_export_key( psa_key_slot_t key,
1068 uint8_t *data,
1069 size_t data_size,
1070 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001071{
Darryl Greendd8fb772018-11-07 16:00:44 +00001072 key_slot_t *slot;
1073 psa_status_t status;
1074
1075 /* Set the key to empty now, so that even when there are errors, we always
1076 * set data_length to a value between 0 and data_size. On error, setting
1077 * the key to empty is a good choice because an empty key representation is
1078 * unlikely to be accepted anywhere. */
1079 *data_length = 0;
1080
1081 /* Export requires the EXPORT flag. There is an exception for public keys,
1082 * which don't require any flag, but psa_get_key_from_slot takes
1083 * care of this. */
1084 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_EXPORT, 0 );
1085 if( status != PSA_SUCCESS )
1086 return( status );
1087 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001088 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001089}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001090
Gilles Peskine2d277862018-06-18 15:41:12 +02001091psa_status_t psa_export_public_key( psa_key_slot_t key,
1092 uint8_t *data,
1093 size_t data_size,
1094 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001095{
Darryl Greendd8fb772018-11-07 16:00:44 +00001096 key_slot_t *slot;
1097 psa_status_t status;
1098
1099 /* Set the key to empty now, so that even when there are errors, we always
1100 * set data_length to a value between 0 and data_size. On error, setting
1101 * the key to empty is a good choice because an empty key representation is
1102 * unlikely to be accepted anywhere. */
1103 *data_length = 0;
1104
1105 /* Exporting a public key doesn't require a usage flag. */
1106 status = psa_get_key_from_slot( key, &slot, 0, 0 );
1107 if( status != PSA_SUCCESS )
1108 return( status );
1109 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001110 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001111}
1112
Darryl Green0c6575a2018-11-07 16:05:30 +00001113#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
1114static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t key,
1115 key_slot_t *slot,
1116 size_t bits )
1117{
1118 psa_status_t status;
1119 uint8_t *data;
1120 size_t key_length;
1121 size_t data_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type, bits );
1122 data = mbedtls_calloc( 1, data_size );
itayzafrir910c76b2018-11-21 16:03:21 +02001123 if( data == NULL )
1124 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Darryl Green0c6575a2018-11-07 16:05:30 +00001125 /* Get key data in export format */
1126 status = psa_internal_export_key( slot, data, data_size, &key_length, 0 );
1127 if( status != PSA_SUCCESS )
1128 {
1129 slot->type = PSA_KEY_TYPE_NONE;
1130 goto exit;
1131 }
1132 /* Store in file location */
1133 status = psa_save_persistent_key( key, slot->type, &slot->policy,
1134 data, key_length );
1135 if( status != PSA_SUCCESS )
1136 {
1137 slot->type = PSA_KEY_TYPE_NONE;
1138 }
1139exit:
1140 mbedtls_zeroize( data, key_length );
1141 mbedtls_free( data );
1142 return( status );
1143}
1144#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1145
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001146
1147
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001148/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01001149/* Message digests */
1150/****************************************************************/
1151
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001152static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01001153{
1154 switch( alg )
1155 {
1156#if defined(MBEDTLS_MD2_C)
1157 case PSA_ALG_MD2:
1158 return( &mbedtls_md2_info );
1159#endif
1160#if defined(MBEDTLS_MD4_C)
1161 case PSA_ALG_MD4:
1162 return( &mbedtls_md4_info );
1163#endif
1164#if defined(MBEDTLS_MD5_C)
1165 case PSA_ALG_MD5:
1166 return( &mbedtls_md5_info );
1167#endif
1168#if defined(MBEDTLS_RIPEMD160_C)
1169 case PSA_ALG_RIPEMD160:
1170 return( &mbedtls_ripemd160_info );
1171#endif
1172#if defined(MBEDTLS_SHA1_C)
1173 case PSA_ALG_SHA_1:
1174 return( &mbedtls_sha1_info );
1175#endif
1176#if defined(MBEDTLS_SHA256_C)
1177 case PSA_ALG_SHA_224:
1178 return( &mbedtls_sha224_info );
1179 case PSA_ALG_SHA_256:
1180 return( &mbedtls_sha256_info );
1181#endif
1182#if defined(MBEDTLS_SHA512_C)
1183 case PSA_ALG_SHA_384:
1184 return( &mbedtls_sha384_info );
1185 case PSA_ALG_SHA_512:
1186 return( &mbedtls_sha512_info );
1187#endif
1188 default:
1189 return( NULL );
1190 }
1191}
1192
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001193psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
1194{
1195 switch( operation->alg )
1196 {
Gilles Peskine81736312018-06-26 15:04:31 +02001197 case 0:
1198 /* The object has (apparently) been initialized but it is not
1199 * in use. It's ok to call abort on such an object, and there's
1200 * nothing to do. */
1201 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001202#if defined(MBEDTLS_MD2_C)
1203 case PSA_ALG_MD2:
1204 mbedtls_md2_free( &operation->ctx.md2 );
1205 break;
1206#endif
1207#if defined(MBEDTLS_MD4_C)
1208 case PSA_ALG_MD4:
1209 mbedtls_md4_free( &operation->ctx.md4 );
1210 break;
1211#endif
1212#if defined(MBEDTLS_MD5_C)
1213 case PSA_ALG_MD5:
1214 mbedtls_md5_free( &operation->ctx.md5 );
1215 break;
1216#endif
1217#if defined(MBEDTLS_RIPEMD160_C)
1218 case PSA_ALG_RIPEMD160:
1219 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
1220 break;
1221#endif
1222#if defined(MBEDTLS_SHA1_C)
1223 case PSA_ALG_SHA_1:
1224 mbedtls_sha1_free( &operation->ctx.sha1 );
1225 break;
1226#endif
1227#if defined(MBEDTLS_SHA256_C)
1228 case PSA_ALG_SHA_224:
1229 case PSA_ALG_SHA_256:
1230 mbedtls_sha256_free( &operation->ctx.sha256 );
1231 break;
1232#endif
1233#if defined(MBEDTLS_SHA512_C)
1234 case PSA_ALG_SHA_384:
1235 case PSA_ALG_SHA_512:
1236 mbedtls_sha512_free( &operation->ctx.sha512 );
1237 break;
1238#endif
1239 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001240 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001241 }
1242 operation->alg = 0;
1243 return( PSA_SUCCESS );
1244}
1245
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02001246psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001247 psa_algorithm_t alg )
1248{
1249 int ret;
1250 operation->alg = 0;
1251 switch( alg )
1252 {
1253#if defined(MBEDTLS_MD2_C)
1254 case PSA_ALG_MD2:
1255 mbedtls_md2_init( &operation->ctx.md2 );
1256 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
1257 break;
1258#endif
1259#if defined(MBEDTLS_MD4_C)
1260 case PSA_ALG_MD4:
1261 mbedtls_md4_init( &operation->ctx.md4 );
1262 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
1263 break;
1264#endif
1265#if defined(MBEDTLS_MD5_C)
1266 case PSA_ALG_MD5:
1267 mbedtls_md5_init( &operation->ctx.md5 );
1268 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
1269 break;
1270#endif
1271#if defined(MBEDTLS_RIPEMD160_C)
1272 case PSA_ALG_RIPEMD160:
1273 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
1274 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
1275 break;
1276#endif
1277#if defined(MBEDTLS_SHA1_C)
1278 case PSA_ALG_SHA_1:
1279 mbedtls_sha1_init( &operation->ctx.sha1 );
1280 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
1281 break;
1282#endif
1283#if defined(MBEDTLS_SHA256_C)
1284 case PSA_ALG_SHA_224:
1285 mbedtls_sha256_init( &operation->ctx.sha256 );
1286 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
1287 break;
1288 case PSA_ALG_SHA_256:
1289 mbedtls_sha256_init( &operation->ctx.sha256 );
1290 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
1291 break;
1292#endif
1293#if defined(MBEDTLS_SHA512_C)
1294 case PSA_ALG_SHA_384:
1295 mbedtls_sha512_init( &operation->ctx.sha512 );
1296 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
1297 break;
1298 case PSA_ALG_SHA_512:
1299 mbedtls_sha512_init( &operation->ctx.sha512 );
1300 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1301 break;
1302#endif
1303 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001304 return( PSA_ALG_IS_HASH( alg ) ?
1305 PSA_ERROR_NOT_SUPPORTED :
1306 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001307 }
1308 if( ret == 0 )
1309 operation->alg = alg;
1310 else
1311 psa_hash_abort( operation );
1312 return( mbedtls_to_psa_error( ret ) );
1313}
1314
1315psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1316 const uint8_t *input,
1317 size_t input_length )
1318{
1319 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001320
1321 /* Don't require hash implementations to behave correctly on a
1322 * zero-length input, which may have an invalid pointer. */
1323 if( input_length == 0 )
1324 return( PSA_SUCCESS );
1325
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001326 switch( operation->alg )
1327 {
1328#if defined(MBEDTLS_MD2_C)
1329 case PSA_ALG_MD2:
1330 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1331 input, input_length );
1332 break;
1333#endif
1334#if defined(MBEDTLS_MD4_C)
1335 case PSA_ALG_MD4:
1336 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1337 input, input_length );
1338 break;
1339#endif
1340#if defined(MBEDTLS_MD5_C)
1341 case PSA_ALG_MD5:
1342 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1343 input, input_length );
1344 break;
1345#endif
1346#if defined(MBEDTLS_RIPEMD160_C)
1347 case PSA_ALG_RIPEMD160:
1348 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1349 input, input_length );
1350 break;
1351#endif
1352#if defined(MBEDTLS_SHA1_C)
1353 case PSA_ALG_SHA_1:
1354 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1355 input, input_length );
1356 break;
1357#endif
1358#if defined(MBEDTLS_SHA256_C)
1359 case PSA_ALG_SHA_224:
1360 case PSA_ALG_SHA_256:
1361 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1362 input, input_length );
1363 break;
1364#endif
1365#if defined(MBEDTLS_SHA512_C)
1366 case PSA_ALG_SHA_384:
1367 case PSA_ALG_SHA_512:
1368 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1369 input, input_length );
1370 break;
1371#endif
1372 default:
1373 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1374 break;
1375 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001376
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001377 if( ret != 0 )
1378 psa_hash_abort( operation );
1379 return( mbedtls_to_psa_error( ret ) );
1380}
1381
1382psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1383 uint8_t *hash,
1384 size_t hash_size,
1385 size_t *hash_length )
1386{
itayzafrir40835d42018-08-02 13:14:17 +03001387 psa_status_t status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001388 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001389 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001390
1391 /* Fill the output buffer with something that isn't a valid hash
1392 * (barring an attack on the hash and deliberately-crafted input),
1393 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001394 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001395 /* If hash_size is 0 then hash may be NULL and then the
1396 * call to memset would have undefined behavior. */
1397 if( hash_size != 0 )
1398 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001399
1400 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03001401 {
1402 status = PSA_ERROR_BUFFER_TOO_SMALL;
1403 goto exit;
1404 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001405
1406 switch( operation->alg )
1407 {
1408#if defined(MBEDTLS_MD2_C)
1409 case PSA_ALG_MD2:
1410 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1411 break;
1412#endif
1413#if defined(MBEDTLS_MD4_C)
1414 case PSA_ALG_MD4:
1415 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1416 break;
1417#endif
1418#if defined(MBEDTLS_MD5_C)
1419 case PSA_ALG_MD5:
1420 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1421 break;
1422#endif
1423#if defined(MBEDTLS_RIPEMD160_C)
1424 case PSA_ALG_RIPEMD160:
1425 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1426 break;
1427#endif
1428#if defined(MBEDTLS_SHA1_C)
1429 case PSA_ALG_SHA_1:
1430 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1431 break;
1432#endif
1433#if defined(MBEDTLS_SHA256_C)
1434 case PSA_ALG_SHA_224:
1435 case PSA_ALG_SHA_256:
1436 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1437 break;
1438#endif
1439#if defined(MBEDTLS_SHA512_C)
1440 case PSA_ALG_SHA_384:
1441 case PSA_ALG_SHA_512:
1442 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1443 break;
1444#endif
1445 default:
1446 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1447 break;
1448 }
itayzafrir40835d42018-08-02 13:14:17 +03001449 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001450
itayzafrir40835d42018-08-02 13:14:17 +03001451exit:
1452 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001453 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001454 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001455 return( psa_hash_abort( operation ) );
1456 }
1457 else
1458 {
1459 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03001460 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001461 }
1462}
1463
Gilles Peskine2d277862018-06-18 15:41:12 +02001464psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1465 const uint8_t *hash,
1466 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001467{
1468 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1469 size_t actual_hash_length;
1470 psa_status_t status = psa_hash_finish( operation,
1471 actual_hash, sizeof( actual_hash ),
1472 &actual_hash_length );
1473 if( status != PSA_SUCCESS )
1474 return( status );
1475 if( actual_hash_length != hash_length )
1476 return( PSA_ERROR_INVALID_SIGNATURE );
1477 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1478 return( PSA_ERROR_INVALID_SIGNATURE );
1479 return( PSA_SUCCESS );
1480}
1481
1482
1483
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001484/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001485/* MAC */
1486/****************************************************************/
1487
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001488static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001489 psa_algorithm_t alg,
1490 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001491 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001492 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001493{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001494 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001495 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001496
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001497 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001498 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001499
Gilles Peskine8c9def32018-02-08 10:02:12 +01001500 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1501 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001502 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001503 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001504 case PSA_ALG_ARC4:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001505 mode = MBEDTLS_MODE_STREAM;
1506 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001507 case PSA_ALG_CTR:
1508 mode = MBEDTLS_MODE_CTR;
1509 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001510 case PSA_ALG_CFB:
1511 mode = MBEDTLS_MODE_CFB;
1512 break;
1513 case PSA_ALG_OFB:
1514 mode = MBEDTLS_MODE_OFB;
1515 break;
1516 case PSA_ALG_CBC_NO_PADDING:
1517 mode = MBEDTLS_MODE_CBC;
1518 break;
1519 case PSA_ALG_CBC_PKCS7:
1520 mode = MBEDTLS_MODE_CBC;
1521 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001522 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001523 mode = MBEDTLS_MODE_CCM;
1524 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001525 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001526 mode = MBEDTLS_MODE_GCM;
1527 break;
1528 default:
1529 return( NULL );
1530 }
1531 }
1532 else if( alg == PSA_ALG_CMAC )
1533 mode = MBEDTLS_MODE_ECB;
1534 else if( alg == PSA_ALG_GMAC )
1535 mode = MBEDTLS_MODE_GCM;
1536 else
1537 return( NULL );
1538
1539 switch( key_type )
1540 {
1541 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001542 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001543 break;
1544 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001545 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1546 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001547 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001548 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001549 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001550 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001551 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1552 * but two-key Triple-DES is functionally three-key Triple-DES
1553 * with K1=K3, so that's how we present it to mbedtls. */
1554 if( key_bits == 128 )
1555 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001556 break;
1557 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001558 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001559 break;
1560 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001561 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001562 break;
1563 default:
1564 return( NULL );
1565 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001566 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001567 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001568
Jaeden Amero23bbb752018-06-26 14:16:54 +01001569 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1570 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001571}
1572
Gilles Peskinea05219c2018-11-16 16:02:56 +01001573#if defined(MBEDTLS_MD_C)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001574static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001575{
Gilles Peskine2d277862018-06-18 15:41:12 +02001576 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001577 {
1578 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001579 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001580 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001581 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001582 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001583 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001584 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001585 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001586 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001587 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001588 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001589 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001590 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001591 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001592 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001593 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001594 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001595 return( 128 );
1596 default:
1597 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001598 }
1599}
Gilles Peskinea05219c2018-11-16 16:02:56 +01001600#endif /* MBEDTLS_MD_C */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001601
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001602/* Initialize the MAC operation structure. Once this function has been
1603 * called, psa_mac_abort can run and will do the right thing. */
1604static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1605 psa_algorithm_t alg )
1606{
1607 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1608
1609 operation->alg = alg;
1610 operation->key_set = 0;
1611 operation->iv_set = 0;
1612 operation->iv_required = 0;
1613 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001614 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001615
1616#if defined(MBEDTLS_CMAC_C)
1617 if( alg == PSA_ALG_CMAC )
1618 {
1619 operation->iv_required = 0;
1620 mbedtls_cipher_init( &operation->ctx.cmac );
1621 status = PSA_SUCCESS;
1622 }
1623 else
1624#endif /* MBEDTLS_CMAC_C */
1625#if defined(MBEDTLS_MD_C)
1626 if( PSA_ALG_IS_HMAC( operation->alg ) )
1627 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02001628 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
1629 operation->ctx.hmac.hash_ctx.alg = 0;
1630 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001631 }
1632 else
1633#endif /* MBEDTLS_MD_C */
1634 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001635 if( ! PSA_ALG_IS_MAC( alg ) )
1636 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001637 }
1638
1639 if( status != PSA_SUCCESS )
1640 memset( operation, 0, sizeof( *operation ) );
1641 return( status );
1642}
1643
Gilles Peskine01126fa2018-07-12 17:04:55 +02001644#if defined(MBEDTLS_MD_C)
1645static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
1646{
1647 mbedtls_zeroize( hmac->opad, sizeof( hmac->opad ) );
1648 return( psa_hash_abort( &hmac->hash_ctx ) );
1649}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01001650
1651static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
1652{
1653 /* Instances of psa_hash_operation_s can be initialized by zeroization. */
1654 memset( hmac, 0, sizeof( *hmac ) );
1655}
Gilles Peskine01126fa2018-07-12 17:04:55 +02001656#endif /* MBEDTLS_MD_C */
1657
Gilles Peskine8c9def32018-02-08 10:02:12 +01001658psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1659{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001660 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001661 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001662 /* The object has (apparently) been initialized but it is not
1663 * in use. It's ok to call abort on such an object, and there's
1664 * nothing to do. */
1665 return( PSA_SUCCESS );
1666 }
1667 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001668#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001669 if( operation->alg == PSA_ALG_CMAC )
1670 {
1671 mbedtls_cipher_free( &operation->ctx.cmac );
1672 }
1673 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001674#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001675#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001676 if( PSA_ALG_IS_HMAC( operation->alg ) )
1677 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001678 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001679 }
1680 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001681#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001682 {
1683 /* Sanity check (shouldn't happen: operation->alg should
1684 * always have been initialized to a valid value). */
1685 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001686 }
Moran Peker41deec42018-04-04 15:43:05 +03001687
Gilles Peskine8c9def32018-02-08 10:02:12 +01001688 operation->alg = 0;
1689 operation->key_set = 0;
1690 operation->iv_set = 0;
1691 operation->iv_required = 0;
1692 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001693 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001694
Gilles Peskine8c9def32018-02-08 10:02:12 +01001695 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001696
1697bad_state:
1698 /* If abort is called on an uninitialized object, we can't trust
1699 * anything. Wipe the object in case it contains confidential data.
1700 * This may result in a memory leak if a pointer gets overwritten,
1701 * but it's too late to do anything about this. */
1702 memset( operation, 0, sizeof( *operation ) );
1703 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001704}
1705
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001706#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02001707static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001708 size_t key_bits,
1709 key_slot_t *slot,
1710 const mbedtls_cipher_info_t *cipher_info )
1711{
1712 int ret;
1713
1714 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001715
1716 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1717 if( ret != 0 )
1718 return( ret );
1719
1720 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1721 slot->data.raw.data,
1722 key_bits );
1723 return( ret );
1724}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001725#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001726
Gilles Peskine248051a2018-06-20 16:09:38 +02001727#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02001728static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
1729 const uint8_t *key,
1730 size_t key_length,
1731 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001732{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001733 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001734 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001735 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001736 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001737 psa_status_t status;
1738
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001739 /* Sanity checks on block_size, to guarantee that there won't be a buffer
1740 * overflow below. This should never trigger if the hash algorithm
1741 * is implemented correctly. */
1742 /* The size checks against the ipad and opad buffers cannot be written
1743 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
1744 * because that triggers -Wlogical-op on GCC 7.3. */
1745 if( block_size > sizeof( ipad ) )
1746 return( PSA_ERROR_NOT_SUPPORTED );
1747 if( block_size > sizeof( hmac->opad ) )
1748 return( PSA_ERROR_NOT_SUPPORTED );
1749 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001750 return( PSA_ERROR_NOT_SUPPORTED );
1751
Gilles Peskined223b522018-06-11 18:12:58 +02001752 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001753 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001754 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001755 if( status != PSA_SUCCESS )
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001756 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001757 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001758 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001759 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001760 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001761 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001762 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001763 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001764 }
Gilles Peskine96889972018-07-12 17:07:03 +02001765 /* A 0-length key is not commonly used in HMAC when used as a MAC,
1766 * but it is permitted. It is common when HMAC is used in HKDF, for
1767 * example. Don't call `memcpy` in the 0-length because `key` could be
1768 * an invalid pointer which would make the behavior undefined. */
1769 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001770 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001771
Gilles Peskined223b522018-06-11 18:12:58 +02001772 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1773 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001774 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001775 ipad[i] ^= 0x36;
1776 memset( ipad + key_length, 0x36, block_size - key_length );
1777
1778 /* Copy the key material from ipad to opad, flipping the requisite bits,
1779 * and filling the rest of opad with the requisite constant. */
1780 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001781 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1782 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001783
Gilles Peskine01126fa2018-07-12 17:04:55 +02001784 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001785 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001786 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001787
Gilles Peskine01126fa2018-07-12 17:04:55 +02001788 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001789
1790cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001791 mbedtls_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001792
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001793 return( status );
1794}
Gilles Peskine248051a2018-06-20 16:09:38 +02001795#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001796
Gilles Peskine89167cb2018-07-08 20:12:23 +02001797static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
1798 psa_key_slot_t key,
1799 psa_algorithm_t alg,
1800 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001801{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001802 psa_status_t status;
1803 key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001804 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001805 psa_key_usage_t usage =
1806 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskined911eb72018-08-14 15:18:45 +02001807 unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02001808 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001809
Gilles Peskined911eb72018-08-14 15:18:45 +02001810 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001811 if( status != PSA_SUCCESS )
1812 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001813 if( is_sign )
1814 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001815
Gilles Peskine89167cb2018-07-08 20:12:23 +02001816 status = psa_get_key_from_slot( key, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001817 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001818 goto exit;
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02001819 key_bits = psa_get_key_bits( slot );
1820
Gilles Peskine8c9def32018-02-08 10:02:12 +01001821#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001822 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001823 {
1824 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02001825 mbedtls_cipher_info_from_psa( full_length_alg,
1826 slot->type, key_bits, NULL );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001827 int ret;
1828 if( cipher_info == NULL )
1829 {
1830 status = PSA_ERROR_NOT_SUPPORTED;
1831 goto exit;
1832 }
1833 operation->mac_size = cipher_info->block_size;
1834 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
1835 status = mbedtls_to_psa_error( ret );
1836 }
1837 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001838#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001839#if defined(MBEDTLS_MD_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001840 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001841 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02001842 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001843 if( hash_alg == 0 )
1844 {
1845 status = PSA_ERROR_NOT_SUPPORTED;
1846 goto exit;
1847 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001848
1849 operation->mac_size = PSA_HASH_SIZE( hash_alg );
1850 /* Sanity check. This shouldn't fail on a valid configuration. */
1851 if( operation->mac_size == 0 ||
1852 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
1853 {
1854 status = PSA_ERROR_NOT_SUPPORTED;
1855 goto exit;
1856 }
1857
Gilles Peskine01126fa2018-07-12 17:04:55 +02001858 if( slot->type != PSA_KEY_TYPE_HMAC )
1859 {
1860 status = PSA_ERROR_INVALID_ARGUMENT;
1861 goto exit;
1862 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001863
Gilles Peskine01126fa2018-07-12 17:04:55 +02001864 status = psa_hmac_setup_internal( &operation->ctx.hmac,
1865 slot->data.raw.data,
1866 slot->data.raw.bytes,
1867 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001868 }
1869 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001870#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001871 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00001872 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02001873 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001874 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001875
Gilles Peskined911eb72018-08-14 15:18:45 +02001876 if( truncated == 0 )
1877 {
1878 /* The "normal" case: untruncated algorithm. Nothing to do. */
1879 }
1880 else if( truncated < 4 )
1881 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02001882 /* A very short MAC is too short for security since it can be
1883 * brute-forced. Ancient protocols with 32-bit MACs do exist,
1884 * so we make this our minimum, even though 32 bits is still
1885 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02001886 status = PSA_ERROR_NOT_SUPPORTED;
1887 }
1888 else if( truncated > operation->mac_size )
1889 {
1890 /* It's impossible to "truncate" to a larger length. */
1891 status = PSA_ERROR_INVALID_ARGUMENT;
1892 }
1893 else
1894 operation->mac_size = truncated;
1895
Gilles Peskinefbfac682018-07-08 20:51:54 +02001896exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001897 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001898 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001899 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001900 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001901 else
1902 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001903 operation->key_set = 1;
1904 }
1905 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001906}
1907
Gilles Peskine89167cb2018-07-08 20:12:23 +02001908psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
1909 psa_key_slot_t key,
1910 psa_algorithm_t alg )
1911{
1912 return( psa_mac_setup( operation, key, alg, 1 ) );
1913}
1914
1915psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
1916 psa_key_slot_t key,
1917 psa_algorithm_t alg )
1918{
1919 return( psa_mac_setup( operation, key, alg, 0 ) );
1920}
1921
Gilles Peskine8c9def32018-02-08 10:02:12 +01001922psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1923 const uint8_t *input,
1924 size_t input_length )
1925{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001926 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001927 if( ! operation->key_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001928 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001929 if( operation->iv_required && ! operation->iv_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001930 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001931 operation->has_input = 1;
1932
Gilles Peskine8c9def32018-02-08 10:02:12 +01001933#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001934 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001935 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001936 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1937 input, input_length );
1938 status = mbedtls_to_psa_error( ret );
1939 }
1940 else
1941#endif /* MBEDTLS_CMAC_C */
1942#if defined(MBEDTLS_MD_C)
1943 if( PSA_ALG_IS_HMAC( operation->alg ) )
1944 {
1945 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
1946 input_length );
1947 }
1948 else
1949#endif /* MBEDTLS_MD_C */
1950 {
1951 /* This shouldn't happen if `operation` was initialized by
1952 * a setup function. */
1953 status = PSA_ERROR_BAD_STATE;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001954 }
1955
Gilles Peskinefbfac682018-07-08 20:51:54 +02001956cleanup:
1957 if( status != PSA_SUCCESS )
1958 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001959 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001960}
1961
Gilles Peskine01126fa2018-07-12 17:04:55 +02001962#if defined(MBEDTLS_MD_C)
1963static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
1964 uint8_t *mac,
1965 size_t mac_size )
1966{
1967 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
1968 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
1969 size_t hash_size = 0;
1970 size_t block_size = psa_get_hash_block_size( hash_alg );
1971 psa_status_t status;
1972
Gilles Peskine01126fa2018-07-12 17:04:55 +02001973 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1974 if( status != PSA_SUCCESS )
1975 return( status );
1976 /* From here on, tmp needs to be wiped. */
1977
1978 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
1979 if( status != PSA_SUCCESS )
1980 goto exit;
1981
1982 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
1983 if( status != PSA_SUCCESS )
1984 goto exit;
1985
1986 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
1987 if( status != PSA_SUCCESS )
1988 goto exit;
1989
Gilles Peskined911eb72018-08-14 15:18:45 +02001990 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1991 if( status != PSA_SUCCESS )
1992 goto exit;
1993
1994 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001995
1996exit:
1997 mbedtls_zeroize( tmp, hash_size );
1998 return( status );
1999}
2000#endif /* MBEDTLS_MD_C */
2001
mohammad16036df908f2018-04-02 08:34:15 -07002002static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02002003 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002004 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002005{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02002006 if( ! operation->key_set )
2007 return( PSA_ERROR_BAD_STATE );
2008 if( operation->iv_required && ! operation->iv_set )
2009 return( PSA_ERROR_BAD_STATE );
2010
Gilles Peskine8c9def32018-02-08 10:02:12 +01002011 if( mac_size < operation->mac_size )
2012 return( PSA_ERROR_BUFFER_TOO_SMALL );
2013
Gilles Peskine8c9def32018-02-08 10:02:12 +01002014#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002015 if( operation->alg == PSA_ALG_CMAC )
2016 {
Gilles Peskined911eb72018-08-14 15:18:45 +02002017 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
2018 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
2019 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02002020 memcpy( mac, tmp, operation->mac_size );
Gilles Peskined911eb72018-08-14 15:18:45 +02002021 mbedtls_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002022 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002023 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02002024 else
2025#endif /* MBEDTLS_CMAC_C */
2026#if defined(MBEDTLS_MD_C)
2027 if( PSA_ALG_IS_HMAC( operation->alg ) )
2028 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002029 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02002030 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002031 }
2032 else
2033#endif /* MBEDTLS_MD_C */
2034 {
2035 /* This shouldn't happen if `operation` was initialized by
2036 * a setup function. */
2037 return( PSA_ERROR_BAD_STATE );
2038 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01002039}
2040
Gilles Peskineacd4be32018-07-08 19:56:25 +02002041psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
2042 uint8_t *mac,
2043 size_t mac_size,
2044 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07002045{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002046 psa_status_t status;
2047
2048 /* Fill the output buffer with something that isn't a valid mac
2049 * (barring an attack on the mac and deliberately-crafted input),
2050 * in case the caller doesn't check the return status properly. */
2051 *mac_length = mac_size;
2052 /* If mac_size is 0 then mac may be NULL and then the
2053 * call to memset would have undefined behavior. */
2054 if( mac_size != 0 )
2055 memset( mac, '!', mac_size );
2056
Gilles Peskine89167cb2018-07-08 20:12:23 +02002057 if( ! operation->is_sign )
2058 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002059 status = PSA_ERROR_BAD_STATE;
2060 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002061 }
mohammad16036df908f2018-04-02 08:34:15 -07002062
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002063 status = psa_mac_finish_internal( operation, mac, mac_size );
2064
2065cleanup:
2066 if( status == PSA_SUCCESS )
2067 {
2068 status = psa_mac_abort( operation );
2069 if( status == PSA_SUCCESS )
2070 *mac_length = operation->mac_size;
2071 else
2072 memset( mac, '!', mac_size );
2073 }
2074 else
2075 psa_mac_abort( operation );
2076 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07002077}
2078
Gilles Peskineacd4be32018-07-08 19:56:25 +02002079psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
2080 const uint8_t *mac,
2081 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002082{
Gilles Peskine828ed142018-06-18 23:25:51 +02002083 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07002084 psa_status_t status;
2085
Gilles Peskine89167cb2018-07-08 20:12:23 +02002086 if( operation->is_sign )
2087 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002088 status = PSA_ERROR_BAD_STATE;
2089 goto cleanup;
2090 }
2091 if( operation->mac_size != mac_length )
2092 {
2093 status = PSA_ERROR_INVALID_SIGNATURE;
2094 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002095 }
mohammad16036df908f2018-04-02 08:34:15 -07002096
2097 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002098 actual_mac, sizeof( actual_mac ) );
2099
2100 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
2101 status = PSA_ERROR_INVALID_SIGNATURE;
2102
2103cleanup:
2104 if( status == PSA_SUCCESS )
2105 status = psa_mac_abort( operation );
2106 else
2107 psa_mac_abort( operation );
2108
Gilles Peskine99b7d6b2018-08-21 14:56:19 +02002109 mbedtls_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02002110
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002111 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002112}
2113
2114
Gilles Peskine20035e32018-02-03 22:44:14 +01002115
Gilles Peskine20035e32018-02-03 22:44:14 +01002116/****************************************************************/
2117/* Asymmetric cryptography */
2118/****************************************************************/
2119
Gilles Peskine2b450e32018-06-27 15:42:46 +02002120#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002121/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002122 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002123static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
2124 size_t hash_length,
2125 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002126{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02002127 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002128 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002129 *md_alg = mbedtls_md_get_type( md_info );
2130
2131 /* The Mbed TLS RSA module uses an unsigned int for hash length
2132 * parameters. Validate that it fits so that we don't risk an
2133 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002134#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002135 if( hash_length > UINT_MAX )
2136 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002137#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002138
2139#if defined(MBEDTLS_PKCS1_V15)
2140 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
2141 * must be correct. */
2142 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
2143 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002144 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002145 if( md_info == NULL )
2146 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002147 if( mbedtls_md_get_size( md_info ) != hash_length )
2148 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002149 }
2150#endif /* MBEDTLS_PKCS1_V15 */
2151
2152#if defined(MBEDTLS_PKCS1_V21)
2153 /* PSS requires a hash internally. */
2154 if( PSA_ALG_IS_RSA_PSS( alg ) )
2155 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002156 if( md_info == NULL )
2157 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002158 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002159#endif /* MBEDTLS_PKCS1_V21 */
2160
Gilles Peskine61b91d42018-06-08 16:09:36 +02002161 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002162}
2163
Gilles Peskine2b450e32018-06-27 15:42:46 +02002164static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
2165 psa_algorithm_t alg,
2166 const uint8_t *hash,
2167 size_t hash_length,
2168 uint8_t *signature,
2169 size_t signature_size,
2170 size_t *signature_length )
2171{
2172 psa_status_t status;
2173 int ret;
2174 mbedtls_md_type_t md_alg;
2175
2176 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2177 if( status != PSA_SUCCESS )
2178 return( status );
2179
Gilles Peskine630a18a2018-06-29 17:49:35 +02002180 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002181 return( PSA_ERROR_BUFFER_TOO_SMALL );
2182
2183#if defined(MBEDTLS_PKCS1_V15)
2184 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2185 {
2186 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2187 MBEDTLS_MD_NONE );
2188 ret = mbedtls_rsa_pkcs1_sign( rsa,
2189 mbedtls_ctr_drbg_random,
2190 &global_data.ctr_drbg,
2191 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002192 md_alg,
2193 (unsigned int) hash_length,
2194 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002195 signature );
2196 }
2197 else
2198#endif /* MBEDTLS_PKCS1_V15 */
2199#if defined(MBEDTLS_PKCS1_V21)
2200 if( PSA_ALG_IS_RSA_PSS( alg ) )
2201 {
2202 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2203 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
2204 mbedtls_ctr_drbg_random,
2205 &global_data.ctr_drbg,
2206 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002207 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002208 (unsigned int) hash_length,
2209 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002210 signature );
2211 }
2212 else
2213#endif /* MBEDTLS_PKCS1_V21 */
2214 {
2215 return( PSA_ERROR_INVALID_ARGUMENT );
2216 }
2217
2218 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002219 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002220 return( mbedtls_to_psa_error( ret ) );
2221}
2222
2223static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
2224 psa_algorithm_t alg,
2225 const uint8_t *hash,
2226 size_t hash_length,
2227 const uint8_t *signature,
2228 size_t signature_length )
2229{
2230 psa_status_t status;
2231 int ret;
2232 mbedtls_md_type_t md_alg;
2233
2234 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2235 if( status != PSA_SUCCESS )
2236 return( status );
2237
Gilles Peskine630a18a2018-06-29 17:49:35 +02002238 if( signature_length < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002239 return( PSA_ERROR_BUFFER_TOO_SMALL );
2240
2241#if defined(MBEDTLS_PKCS1_V15)
2242 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2243 {
2244 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2245 MBEDTLS_MD_NONE );
2246 ret = mbedtls_rsa_pkcs1_verify( rsa,
2247 mbedtls_ctr_drbg_random,
2248 &global_data.ctr_drbg,
2249 MBEDTLS_RSA_PUBLIC,
2250 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002251 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002252 hash,
2253 signature );
2254 }
2255 else
2256#endif /* MBEDTLS_PKCS1_V15 */
2257#if defined(MBEDTLS_PKCS1_V21)
2258 if( PSA_ALG_IS_RSA_PSS( alg ) )
2259 {
2260 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2261 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
2262 mbedtls_ctr_drbg_random,
2263 &global_data.ctr_drbg,
2264 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002265 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002266 (unsigned int) hash_length,
2267 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002268 signature );
2269 }
2270 else
2271#endif /* MBEDTLS_PKCS1_V21 */
2272 {
2273 return( PSA_ERROR_INVALID_ARGUMENT );
2274 }
Gilles Peskineef12c632018-09-13 20:37:48 +02002275
2276 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
2277 * the rest of the signature is invalid". This has little use in
2278 * practice and PSA doesn't report this distinction. */
2279 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
2280 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002281 return( mbedtls_to_psa_error( ret ) );
2282}
2283#endif /* MBEDTLS_RSA_C */
2284
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002285#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002286/* `ecp` cannot be const because `ecp->grp` needs to be non-const
2287 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
2288 * (even though these functions don't modify it). */
2289static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
2290 psa_algorithm_t alg,
2291 const uint8_t *hash,
2292 size_t hash_length,
2293 uint8_t *signature,
2294 size_t signature_size,
2295 size_t *signature_length )
2296{
2297 int ret;
2298 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002299 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002300 mbedtls_mpi_init( &r );
2301 mbedtls_mpi_init( &s );
2302
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002303 if( signature_size < 2 * curve_bytes )
2304 {
2305 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
2306 goto cleanup;
2307 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002308
Gilles Peskinea05219c2018-11-16 16:02:56 +01002309#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002310 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
2311 {
2312 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
2313 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2314 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2315 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
2316 hash, hash_length,
2317 md_alg ) );
2318 }
2319 else
Gilles Peskinea05219c2018-11-16 16:02:56 +01002320#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002321 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01002322 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002323 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
2324 hash, hash_length,
2325 mbedtls_ctr_drbg_random,
2326 &global_data.ctr_drbg ) );
2327 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002328
2329 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
2330 signature,
2331 curve_bytes ) );
2332 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
2333 signature + curve_bytes,
2334 curve_bytes ) );
2335
2336cleanup:
2337 mbedtls_mpi_free( &r );
2338 mbedtls_mpi_free( &s );
2339 if( ret == 0 )
2340 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002341 return( mbedtls_to_psa_error( ret ) );
2342}
2343
2344static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
2345 const uint8_t *hash,
2346 size_t hash_length,
2347 const uint8_t *signature,
2348 size_t signature_length )
2349{
2350 int ret;
2351 mbedtls_mpi r, s;
2352 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
2353 mbedtls_mpi_init( &r );
2354 mbedtls_mpi_init( &s );
2355
2356 if( signature_length != 2 * curve_bytes )
2357 return( PSA_ERROR_INVALID_SIGNATURE );
2358
2359 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2360 signature,
2361 curve_bytes ) );
2362 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2363 signature + curve_bytes,
2364 curve_bytes ) );
2365
2366 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2367 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002368
2369cleanup:
2370 mbedtls_mpi_free( &r );
2371 mbedtls_mpi_free( &s );
2372 return( mbedtls_to_psa_error( ret ) );
2373}
2374#endif /* MBEDTLS_ECDSA_C */
2375
Gilles Peskine61b91d42018-06-08 16:09:36 +02002376psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
2377 psa_algorithm_t alg,
2378 const uint8_t *hash,
2379 size_t hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002380 uint8_t *signature,
2381 size_t signature_size,
2382 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002383{
2384 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002385 psa_status_t status;
2386
2387 *signature_length = signature_size;
2388
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002389 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_SIGN, alg );
2390 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002391 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002392 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002393 {
2394 status = PSA_ERROR_INVALID_ARGUMENT;
2395 goto exit;
2396 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002397
Gilles Peskine20035e32018-02-03 22:44:14 +01002398#if defined(MBEDTLS_RSA_C)
2399 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2400 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002401 status = psa_rsa_sign( slot->data.rsa,
2402 alg,
2403 hash, hash_length,
2404 signature, signature_size,
2405 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002406 }
2407 else
2408#endif /* defined(MBEDTLS_RSA_C) */
2409#if defined(MBEDTLS_ECP_C)
2410 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2411 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002412#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea05219c2018-11-16 16:02:56 +01002413 if(
2414#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
2415 PSA_ALG_IS_ECDSA( alg )
2416#else
2417 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
2418#endif
2419 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002420 status = psa_ecdsa_sign( slot->data.ecp,
2421 alg,
2422 hash, hash_length,
2423 signature, signature_size,
2424 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002425 else
2426#endif /* defined(MBEDTLS_ECDSA_C) */
2427 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002428 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002429 }
itayzafrir5c753392018-05-08 11:18:38 +03002430 }
2431 else
2432#endif /* defined(MBEDTLS_ECP_C) */
2433 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002434 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002435 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002436
2437exit:
2438 /* Fill the unused part of the output buffer (the whole buffer on error,
2439 * the trailing part on success) with something that isn't a valid mac
2440 * (barring an attack on the mac and deliberately-crafted input),
2441 * in case the caller doesn't check the return status properly. */
2442 if( status == PSA_SUCCESS )
2443 memset( signature + *signature_length, '!',
2444 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002445 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002446 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002447 /* If signature_size is 0 then we have nothing to do. We must not call
2448 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002449 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002450}
2451
2452psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
2453 psa_algorithm_t alg,
2454 const uint8_t *hash,
2455 size_t hash_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002456 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002457 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002458{
2459 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002460 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002461
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002462 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_VERIFY, alg );
2463 if( status != PSA_SUCCESS )
2464 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002465
Gilles Peskine61b91d42018-06-08 16:09:36 +02002466#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002467 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002468 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002469 return( psa_rsa_verify( slot->data.rsa,
2470 alg,
2471 hash, hash_length,
2472 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002473 }
2474 else
2475#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002476#if defined(MBEDTLS_ECP_C)
2477 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2478 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002479#if defined(MBEDTLS_ECDSA_C)
2480 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002481 return( psa_ecdsa_verify( slot->data.ecp,
2482 hash, hash_length,
2483 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002484 else
2485#endif /* defined(MBEDTLS_ECDSA_C) */
2486 {
2487 return( PSA_ERROR_INVALID_ARGUMENT );
2488 }
itayzafrir5c753392018-05-08 11:18:38 +03002489 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002490 else
2491#endif /* defined(MBEDTLS_ECP_C) */
2492 {
2493 return( PSA_ERROR_NOT_SUPPORTED );
2494 }
2495}
2496
Gilles Peskine072ac562018-06-30 00:21:29 +02002497#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
2498static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
2499 mbedtls_rsa_context *rsa )
2500{
2501 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
2502 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2503 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2504 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2505}
2506#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
2507
Gilles Peskine61b91d42018-06-08 16:09:36 +02002508psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
2509 psa_algorithm_t alg,
2510 const uint8_t *input,
2511 size_t input_length,
2512 const uint8_t *salt,
2513 size_t salt_length,
2514 uint8_t *output,
2515 size_t output_size,
2516 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002517{
2518 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002519 psa_status_t status;
2520
Darryl Green5cc689a2018-07-24 15:34:10 +01002521 (void) input;
2522 (void) input_length;
2523 (void) salt;
2524 (void) output;
2525 (void) output_size;
2526
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002527 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002528
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002529 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2530 return( PSA_ERROR_INVALID_ARGUMENT );
2531
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002532 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
2533 if( status != PSA_SUCCESS )
2534 return( status );
Gilles Peskine35da9a22018-06-29 19:17:49 +02002535 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
2536 PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002537 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002538
2539#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002540 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002541 {
2542 mbedtls_rsa_context *rsa = slot->data.rsa;
2543 int ret;
Gilles Peskine630a18a2018-06-29 17:49:35 +02002544 if( output_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002545 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002546#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002547 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002548 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002549 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2550 mbedtls_ctr_drbg_random,
2551 &global_data.ctr_drbg,
2552 MBEDTLS_RSA_PUBLIC,
2553 input_length,
2554 input,
2555 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002556 }
2557 else
2558#endif /* MBEDTLS_PKCS1_V15 */
2559#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002560 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002561 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002562 psa_rsa_oaep_set_padding_mode( alg, rsa );
2563 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
2564 mbedtls_ctr_drbg_random,
2565 &global_data.ctr_drbg,
2566 MBEDTLS_RSA_PUBLIC,
2567 salt, salt_length,
2568 input_length,
2569 input,
2570 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002571 }
2572 else
2573#endif /* MBEDTLS_PKCS1_V21 */
2574 {
2575 return( PSA_ERROR_INVALID_ARGUMENT );
2576 }
2577 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002578 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002579 return( mbedtls_to_psa_error( ret ) );
2580 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002581 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002582#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002583 {
2584 return( PSA_ERROR_NOT_SUPPORTED );
2585 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002586}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002587
Gilles Peskine61b91d42018-06-08 16:09:36 +02002588psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2589 psa_algorithm_t alg,
2590 const uint8_t *input,
2591 size_t input_length,
2592 const uint8_t *salt,
2593 size_t salt_length,
2594 uint8_t *output,
2595 size_t output_size,
2596 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002597{
2598 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002599 psa_status_t status;
2600
Darryl Green5cc689a2018-07-24 15:34:10 +01002601 (void) input;
2602 (void) input_length;
2603 (void) salt;
2604 (void) output;
2605 (void) output_size;
2606
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002607 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002608
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002609 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2610 return( PSA_ERROR_INVALID_ARGUMENT );
2611
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002612 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
2613 if( status != PSA_SUCCESS )
2614 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002615 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2616 return( PSA_ERROR_INVALID_ARGUMENT );
2617
2618#if defined(MBEDTLS_RSA_C)
2619 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2620 {
2621 mbedtls_rsa_context *rsa = slot->data.rsa;
2622 int ret;
2623
Gilles Peskine630a18a2018-06-29 17:49:35 +02002624 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002625 return( PSA_ERROR_INVALID_ARGUMENT );
2626
2627#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002628 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002629 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002630 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2631 mbedtls_ctr_drbg_random,
2632 &global_data.ctr_drbg,
2633 MBEDTLS_RSA_PRIVATE,
2634 output_length,
2635 input,
2636 output,
2637 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002638 }
2639 else
2640#endif /* MBEDTLS_PKCS1_V15 */
2641#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002642 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002643 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002644 psa_rsa_oaep_set_padding_mode( alg, rsa );
2645 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
2646 mbedtls_ctr_drbg_random,
2647 &global_data.ctr_drbg,
2648 MBEDTLS_RSA_PRIVATE,
2649 salt, salt_length,
2650 output_length,
2651 input,
2652 output,
2653 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002654 }
2655 else
2656#endif /* MBEDTLS_PKCS1_V21 */
2657 {
2658 return( PSA_ERROR_INVALID_ARGUMENT );
2659 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002660
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002661 return( mbedtls_to_psa_error( ret ) );
2662 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002663 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002664#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002665 {
2666 return( PSA_ERROR_NOT_SUPPORTED );
2667 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002668}
Gilles Peskine20035e32018-02-03 22:44:14 +01002669
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002670
2671
mohammad1603503973b2018-03-12 15:59:30 +02002672/****************************************************************/
2673/* Symmetric cryptography */
2674/****************************************************************/
2675
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002676/* Initialize the cipher operation structure. Once this function has been
2677 * called, psa_cipher_abort can run and will do the right thing. */
2678static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2679 psa_algorithm_t alg )
2680{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002681 if( ! PSA_ALG_IS_CIPHER( alg ) )
2682 {
2683 memset( operation, 0, sizeof( *operation ) );
2684 return( PSA_ERROR_INVALID_ARGUMENT );
2685 }
2686
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002687 operation->alg = alg;
2688 operation->key_set = 0;
2689 operation->iv_set = 0;
2690 operation->iv_required = 1;
2691 operation->iv_size = 0;
2692 operation->block_size = 0;
2693 mbedtls_cipher_init( &operation->ctx.cipher );
2694 return( PSA_SUCCESS );
2695}
2696
Gilles Peskinee553c652018-06-04 16:22:46 +02002697static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2698 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002699 psa_algorithm_t alg,
2700 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002701{
2702 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2703 psa_status_t status;
2704 key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02002705 size_t key_bits;
2706 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002707 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
2708 PSA_KEY_USAGE_ENCRYPT :
2709 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02002710
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002711 status = psa_cipher_init( operation, alg );
2712 if( status != PSA_SUCCESS )
2713 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002714
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002715 status = psa_get_key_from_slot( key, &slot, usage, alg);
2716 if( status != PSA_SUCCESS )
2717 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002718 key_bits = psa_get_key_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02002719
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002720 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002721 if( cipher_info == NULL )
2722 return( PSA_ERROR_NOT_SUPPORTED );
2723
mohammad1603503973b2018-03-12 15:59:30 +02002724 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002725 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002726 {
2727 psa_cipher_abort( operation );
2728 return( mbedtls_to_psa_error( ret ) );
2729 }
2730
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002731#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002732 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002733 {
2734 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2735 unsigned char keys[24];
2736 memcpy( keys, slot->data.raw.data, 16 );
2737 memcpy( keys + 16, slot->data.raw.data, 8 );
2738 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2739 keys,
2740 192, cipher_operation );
2741 }
2742 else
2743#endif
2744 {
2745 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2746 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002747 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002748 }
Moran Peker41deec42018-04-04 15:43:05 +03002749 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002750 {
2751 psa_cipher_abort( operation );
2752 return( mbedtls_to_psa_error( ret ) );
2753 }
2754
mohammad16038481e742018-03-18 13:57:31 +02002755#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002756 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02002757 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002758 case PSA_ALG_CBC_NO_PADDING:
2759 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2760 MBEDTLS_PADDING_NONE );
2761 break;
2762 case PSA_ALG_CBC_PKCS7:
2763 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2764 MBEDTLS_PADDING_PKCS7 );
2765 break;
2766 default:
2767 /* The algorithm doesn't involve padding. */
2768 ret = 0;
2769 break;
2770 }
2771 if( ret != 0 )
2772 {
2773 psa_cipher_abort( operation );
2774 return( mbedtls_to_psa_error( ret ) );
mohammad16038481e742018-03-18 13:57:31 +02002775 }
2776#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2777
mohammad1603503973b2018-03-12 15:59:30 +02002778 operation->key_set = 1;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002779 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
2780 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
2781 if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
mohammad16038481e742018-03-18 13:57:31 +02002782 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002783 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02002784 }
mohammad1603503973b2018-03-12 15:59:30 +02002785
Moran Peker395db872018-05-31 14:07:14 +03002786 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002787}
2788
Gilles Peskinefe119512018-07-08 21:39:34 +02002789psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
2790 psa_key_slot_t key,
2791 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002792{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002793 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002794}
2795
Gilles Peskinefe119512018-07-08 21:39:34 +02002796psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
2797 psa_key_slot_t key,
2798 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002799{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002800 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002801}
2802
Gilles Peskinefe119512018-07-08 21:39:34 +02002803psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
2804 unsigned char *iv,
2805 size_t iv_size,
2806 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002807{
itayzafrir534bd7c2018-08-02 13:56:32 +03002808 psa_status_t status;
2809 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002810 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002811 {
2812 status = PSA_ERROR_BAD_STATE;
2813 goto exit;
2814 }
Moran Peker41deec42018-04-04 15:43:05 +03002815 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002816 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002817 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03002818 goto exit;
2819 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002820 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2821 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002822 if( ret != 0 )
2823 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002824 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002825 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002826 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002827
mohammad16038481e742018-03-18 13:57:31 +02002828 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03002829 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002830
Moran Peker395db872018-05-31 14:07:14 +03002831exit:
itayzafrir534bd7c2018-08-02 13:56:32 +03002832 if( status != PSA_SUCCESS )
Moran Peker395db872018-05-31 14:07:14 +03002833 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002834 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002835}
2836
Gilles Peskinefe119512018-07-08 21:39:34 +02002837psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
2838 const unsigned char *iv,
2839 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002840{
itayzafrir534bd7c2018-08-02 13:56:32 +03002841 psa_status_t status;
2842 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002843 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002844 {
2845 status = PSA_ERROR_BAD_STATE;
2846 goto exit;
2847 }
Moran Pekera28258c2018-05-29 16:25:04 +03002848 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002849 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002850 status = PSA_ERROR_INVALID_ARGUMENT;
2851 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03002852 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002853 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
2854 status = mbedtls_to_psa_error( ret );
2855exit:
2856 if( status == PSA_SUCCESS )
2857 operation->iv_set = 1;
2858 else
mohammad1603503973b2018-03-12 15:59:30 +02002859 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002860 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002861}
2862
Gilles Peskinee553c652018-06-04 16:22:46 +02002863psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2864 const uint8_t *input,
2865 size_t input_length,
2866 unsigned char *output,
2867 size_t output_size,
2868 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002869{
itayzafrir534bd7c2018-08-02 13:56:32 +03002870 psa_status_t status;
2871 int ret;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002872 size_t expected_output_size;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002873 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002874 {
2875 /* Take the unprocessed partial block left over from previous
2876 * update calls, if any, plus the input to this call. Remove
2877 * the last partial block, if any. You get the data that will be
2878 * output in this call. */
2879 expected_output_size =
2880 ( operation->ctx.cipher.unprocessed_len + input_length )
2881 / operation->block_size * operation->block_size;
2882 }
2883 else
2884 {
2885 expected_output_size = input_length;
2886 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002887
Gilles Peskine89d789c2018-06-04 17:17:16 +02002888 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03002889 {
2890 status = PSA_ERROR_BUFFER_TOO_SMALL;
2891 goto exit;
2892 }
mohammad160382759612018-03-12 18:16:40 +02002893
mohammad1603503973b2018-03-12 15:59:30 +02002894 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002895 input_length, output, output_length );
itayzafrir534bd7c2018-08-02 13:56:32 +03002896 status = mbedtls_to_psa_error( ret );
2897exit:
2898 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02002899 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002900 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002901}
2902
Gilles Peskinee553c652018-06-04 16:22:46 +02002903psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2904 uint8_t *output,
2905 size_t output_size,
2906 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002907{
Janos Follath315b51c2018-07-09 16:04:51 +01002908 psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
2909 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002910 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002911
mohammad1603503973b2018-03-12 15:59:30 +02002912 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002913 {
Janos Follath315b51c2018-07-09 16:04:51 +01002914 status = PSA_ERROR_BAD_STATE;
2915 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002916 }
2917 if( operation->iv_required && ! operation->iv_set )
2918 {
Janos Follath315b51c2018-07-09 16:04:51 +01002919 status = PSA_ERROR_BAD_STATE;
2920 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002921 }
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002922
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002923 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002924 operation->alg == PSA_ALG_CBC_NO_PADDING &&
2925 operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03002926 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002927 status = PSA_ERROR_INVALID_ARGUMENT;
Janos Follath315b51c2018-07-09 16:04:51 +01002928 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002929 }
2930
Janos Follath315b51c2018-07-09 16:04:51 +01002931 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
2932 temp_output_buffer,
2933 output_length );
2934 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002935 {
Janos Follath315b51c2018-07-09 16:04:51 +01002936 status = mbedtls_to_psa_error( cipher_ret );
2937 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02002938 }
Janos Follath315b51c2018-07-09 16:04:51 +01002939
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002940 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01002941 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002942 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002943 memcpy( output, temp_output_buffer, *output_length );
2944 else
2945 {
Janos Follath315b51c2018-07-09 16:04:51 +01002946 status = PSA_ERROR_BUFFER_TOO_SMALL;
2947 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002948 }
mohammad1603503973b2018-03-12 15:59:30 +02002949
Janos Follath279ab8e2018-07-09 16:13:21 +01002950 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002951 status = psa_cipher_abort( operation );
2952
2953 return( status );
2954
2955error:
2956
2957 *output_length = 0;
2958
Janos Follath279ab8e2018-07-09 16:13:21 +01002959 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002960 (void) psa_cipher_abort( operation );
2961
2962 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002963}
2964
Gilles Peskinee553c652018-06-04 16:22:46 +02002965psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2966{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002967 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002968 {
2969 /* The object has (apparently) been initialized but it is not
2970 * in use. It's ok to call abort on such an object, and there's
2971 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002972 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002973 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002974
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002975 /* Sanity check (shouldn't happen: operation->alg should
2976 * always have been initialized to a valid value). */
2977 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2978 return( PSA_ERROR_BAD_STATE );
2979
mohammad1603503973b2018-03-12 15:59:30 +02002980 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002981
Moran Peker41deec42018-04-04 15:43:05 +03002982 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002983 operation->key_set = 0;
2984 operation->iv_set = 0;
2985 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002986 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002987 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002988
Moran Peker395db872018-05-31 14:07:14 +03002989 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002990}
2991
Gilles Peskinea0655c32018-04-30 17:06:50 +02002992
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002993
mohammad16038cc1cee2018-03-28 01:21:33 +03002994/****************************************************************/
2995/* Key Policy */
2996/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002997
mohammad160327010052018-07-03 13:16:15 +03002998#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02002999void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003000{
Gilles Peskine803ce742018-06-18 16:07:14 +02003001 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03003002}
3003
Gilles Peskine2d277862018-06-18 15:41:12 +02003004void psa_key_policy_set_usage( psa_key_policy_t *policy,
3005 psa_key_usage_t usage,
3006 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03003007{
mohammad16034eed7572018-03-28 05:14:59 -07003008 policy->usage = usage;
3009 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03003010}
3011
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003012psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003013{
mohammad16036df908f2018-04-02 08:34:15 -07003014 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03003015}
3016
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003017psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003018{
mohammad16036df908f2018-04-02 08:34:15 -07003019 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03003020}
mohammad160327010052018-07-03 13:16:15 +03003021#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003022
Gilles Peskine2d277862018-06-18 15:41:12 +02003023psa_status_t psa_set_key_policy( psa_key_slot_t key,
3024 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003025{
3026 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003027 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003028
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003029 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003030 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003031
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003032 status = psa_get_empty_key_slot( key, &slot );
3033 if( status != PSA_SUCCESS )
3034 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03003035
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003036 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
3037 PSA_KEY_USAGE_ENCRYPT |
3038 PSA_KEY_USAGE_DECRYPT |
3039 PSA_KEY_USAGE_SIGN |
Gilles Peskineea0fb492018-07-12 17:17:20 +02003040 PSA_KEY_USAGE_VERIFY |
3041 PSA_KEY_USAGE_DERIVE ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07003042 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03003043
mohammad16036df908f2018-04-02 08:34:15 -07003044 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003045
3046 return( PSA_SUCCESS );
3047}
3048
Gilles Peskine2d277862018-06-18 15:41:12 +02003049psa_status_t psa_get_key_policy( psa_key_slot_t key,
3050 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003051{
3052 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003053 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003054
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003055 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003056 return( PSA_ERROR_INVALID_ARGUMENT );
3057
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003058 status = psa_get_key_slot( key, &slot );
3059 if( status != PSA_SUCCESS )
3060 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003061
mohammad16036df908f2018-04-02 08:34:15 -07003062 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003063
3064 return( PSA_SUCCESS );
3065}
Gilles Peskine20035e32018-02-03 22:44:14 +01003066
Gilles Peskinea0655c32018-04-30 17:06:50 +02003067
3068
mohammad1603804cd712018-03-20 22:44:08 +02003069/****************************************************************/
3070/* Key Lifetime */
3071/****************************************************************/
3072
Gilles Peskine2d277862018-06-18 15:41:12 +02003073psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
3074 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003075{
3076 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003077 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003078
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003079 status = psa_get_key_slot( key, &slot );
3080 if( status != PSA_SUCCESS )
3081 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003082
mohammad1603804cd712018-03-20 22:44:08 +02003083 *lifetime = slot->lifetime;
3084
3085 return( PSA_SUCCESS );
3086}
3087
Gilles Peskine2d277862018-06-18 15:41:12 +02003088psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
Jaeden Amero65fb2362018-06-26 13:55:30 +01003089 psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003090{
3091 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003092 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003093
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003094 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
3095 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
Darryl Greend49a4992018-06-18 17:27:26 +01003096 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE )
mohammad1603ba178512018-03-21 04:35:20 -07003097 return( PSA_ERROR_INVALID_ARGUMENT );
3098
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003099 status = psa_get_empty_key_slot( key, &slot );
3100 if( status != PSA_SUCCESS )
3101 return( status );
mohammad1603804cd712018-03-20 22:44:08 +02003102
Darryl Greend49a4992018-06-18 17:27:26 +01003103 if( lifetime == PSA_KEY_LIFETIME_WRITE_ONCE )
mohammad1603ba178512018-03-21 04:35:20 -07003104 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003105
Darryl Greend49a4992018-06-18 17:27:26 +01003106#if !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
3107 if( lifetime == PSA_KEY_LIFETIME_PERSISTENT )
3108 return( PSA_ERROR_NOT_SUPPORTED );
3109#endif
3110
mohammad1603060ad8a2018-03-20 14:28:38 -07003111 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02003112
3113 return( PSA_SUCCESS );
3114}
3115
Gilles Peskine20035e32018-02-03 22:44:14 +01003116
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003117
mohammad16035955c982018-04-26 00:53:03 +03003118/****************************************************************/
3119/* AEAD */
3120/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003121
Gilles Peskineedf9a652018-08-17 18:11:56 +02003122typedef struct
3123{
3124 key_slot_t *slot;
3125 const mbedtls_cipher_info_t *cipher_info;
3126 union
3127 {
3128#if defined(MBEDTLS_CCM_C)
3129 mbedtls_ccm_context ccm;
3130#endif /* MBEDTLS_CCM_C */
3131#if defined(MBEDTLS_GCM_C)
3132 mbedtls_gcm_context gcm;
3133#endif /* MBEDTLS_GCM_C */
3134 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003135 psa_algorithm_t core_alg;
3136 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003137 uint8_t tag_length;
3138} aead_operation_t;
3139
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003140static void psa_aead_abort( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003141{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003142 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003143 {
3144#if defined(MBEDTLS_CCM_C)
3145 case PSA_ALG_CCM:
3146 mbedtls_ccm_free( &operation->ctx.ccm );
3147 break;
3148#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003149#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02003150 case PSA_ALG_GCM:
3151 mbedtls_gcm_free( &operation->ctx.gcm );
3152 break;
3153#endif /* MBEDTLS_GCM_C */
3154 }
3155}
3156
3157static psa_status_t psa_aead_setup( aead_operation_t *operation,
3158 psa_key_slot_t key,
3159 psa_key_usage_t usage,
3160 psa_algorithm_t alg )
3161{
3162 psa_status_t status;
3163 size_t key_bits;
3164 mbedtls_cipher_id_t cipher_id;
3165
3166 status = psa_get_key_from_slot( key, &operation->slot, usage, alg );
3167 if( status != PSA_SUCCESS )
3168 return( status );
3169
3170 key_bits = psa_get_key_bits( operation->slot );
3171
3172 operation->cipher_info =
3173 mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
3174 &cipher_id );
3175 if( operation->cipher_info == NULL )
3176 return( PSA_ERROR_NOT_SUPPORTED );
3177
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003178 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003179 {
3180#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003181 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
3182 operation->core_alg = PSA_ALG_CCM;
3183 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003184 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3185 return( PSA_ERROR_INVALID_ARGUMENT );
3186 mbedtls_ccm_init( &operation->ctx.ccm );
3187 status = mbedtls_to_psa_error(
3188 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
3189 operation->slot->data.raw.data,
3190 (unsigned int) key_bits ) );
3191 if( status != 0 )
3192 goto cleanup;
3193 break;
3194#endif /* MBEDTLS_CCM_C */
3195
3196#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003197 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
3198 operation->core_alg = PSA_ALG_GCM;
3199 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003200 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3201 return( PSA_ERROR_INVALID_ARGUMENT );
3202 mbedtls_gcm_init( &operation->ctx.gcm );
3203 status = mbedtls_to_psa_error(
3204 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
3205 operation->slot->data.raw.data,
3206 (unsigned int) key_bits ) );
3207 break;
3208#endif /* MBEDTLS_GCM_C */
3209
3210 default:
3211 return( PSA_ERROR_NOT_SUPPORTED );
3212 }
3213
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003214 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
3215 {
3216 status = PSA_ERROR_INVALID_ARGUMENT;
3217 goto cleanup;
3218 }
3219 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
3220 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
3221 * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
3222 * In both cases, mbedtls_xxx will validate the tag length below. */
3223
Gilles Peskineedf9a652018-08-17 18:11:56 +02003224 return( PSA_SUCCESS );
3225
3226cleanup:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003227 psa_aead_abort( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003228 return( status );
3229}
3230
mohammad16035955c982018-04-26 00:53:03 +03003231psa_status_t psa_aead_encrypt( psa_key_slot_t key,
3232 psa_algorithm_t alg,
3233 const uint8_t *nonce,
3234 size_t nonce_length,
3235 const uint8_t *additional_data,
3236 size_t additional_data_length,
3237 const uint8_t *plaintext,
3238 size_t plaintext_length,
3239 uint8_t *ciphertext,
3240 size_t ciphertext_size,
3241 size_t *ciphertext_length )
3242{
mohammad16035955c982018-04-26 00:53:03 +03003243 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003244 aead_operation_t operation;
mohammad160315223a82018-06-03 17:19:55 +03003245 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02003246
mohammad1603f08a5502018-06-03 15:05:47 +03003247 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07003248
Gilles Peskineedf9a652018-08-17 18:11:56 +02003249 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003250 if( status != PSA_SUCCESS )
3251 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003252
Gilles Peskineedf9a652018-08-17 18:11:56 +02003253 /* For all currently supported modes, the tag is at the end of the
3254 * ciphertext. */
3255 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
3256 {
3257 status = PSA_ERROR_BUFFER_TOO_SMALL;
3258 goto exit;
3259 }
3260 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03003261
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003262#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003263 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003264 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003265 status = mbedtls_to_psa_error(
3266 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
3267 MBEDTLS_GCM_ENCRYPT,
3268 plaintext_length,
3269 nonce, nonce_length,
3270 additional_data, additional_data_length,
3271 plaintext, ciphertext,
3272 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03003273 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003274 else
3275#endif /* MBEDTLS_GCM_C */
3276#if defined(MBEDTLS_CCM_C)
3277 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003278 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003279 status = mbedtls_to_psa_error(
3280 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
3281 plaintext_length,
3282 nonce, nonce_length,
3283 additional_data,
3284 additional_data_length,
3285 plaintext, ciphertext,
3286 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003287 }
mohammad16035c8845f2018-05-09 05:40:09 -07003288 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003289#endif /* MBEDTLS_CCM_C */
mohammad16035c8845f2018-05-09 05:40:09 -07003290 {
mohammad1603554faad2018-06-03 15:07:38 +03003291 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07003292 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003293
Gilles Peskineedf9a652018-08-17 18:11:56 +02003294 if( status != PSA_SUCCESS && ciphertext_size != 0 )
3295 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003296
Gilles Peskineedf9a652018-08-17 18:11:56 +02003297exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003298 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003299 if( status == PSA_SUCCESS )
3300 *ciphertext_length = plaintext_length + operation.tag_length;
3301 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003302}
3303
Gilles Peskineee652a32018-06-01 19:23:52 +02003304/* Locate the tag in a ciphertext buffer containing the encrypted data
3305 * followed by the tag. Return the length of the part preceding the tag in
3306 * *plaintext_length. This is the size of the plaintext in modes where
3307 * the encrypted data has the same size as the plaintext, such as
3308 * CCM and GCM. */
3309static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
3310 const uint8_t *ciphertext,
3311 size_t ciphertext_length,
3312 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02003313 const uint8_t **p_tag )
3314{
3315 size_t payload_length;
3316 if( tag_length > ciphertext_length )
3317 return( PSA_ERROR_INVALID_ARGUMENT );
3318 payload_length = ciphertext_length - tag_length;
3319 if( payload_length > plaintext_size )
3320 return( PSA_ERROR_BUFFER_TOO_SMALL );
3321 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02003322 return( PSA_SUCCESS );
3323}
3324
mohammad16035955c982018-04-26 00:53:03 +03003325psa_status_t psa_aead_decrypt( psa_key_slot_t key,
3326 psa_algorithm_t alg,
3327 const uint8_t *nonce,
3328 size_t nonce_length,
3329 const uint8_t *additional_data,
3330 size_t additional_data_length,
3331 const uint8_t *ciphertext,
3332 size_t ciphertext_length,
3333 uint8_t *plaintext,
3334 size_t plaintext_size,
3335 size_t *plaintext_length )
3336{
mohammad16035955c982018-04-26 00:53:03 +03003337 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003338 aead_operation_t operation;
3339 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02003340
Gilles Peskineee652a32018-06-01 19:23:52 +02003341 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03003342
Gilles Peskineedf9a652018-08-17 18:11:56 +02003343 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003344 if( status != PSA_SUCCESS )
3345 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003346
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003347#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003348 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003349 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003350 status = psa_aead_unpadded_locate_tag( operation.tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003351 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003352 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02003353 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003354 goto exit;
Gilles Peskineee652a32018-06-01 19:23:52 +02003355
Gilles Peskineedf9a652018-08-17 18:11:56 +02003356 status = mbedtls_to_psa_error(
3357 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
3358 ciphertext_length - operation.tag_length,
3359 nonce, nonce_length,
3360 additional_data,
3361 additional_data_length,
3362 tag, operation.tag_length,
3363 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03003364 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003365 else
3366#endif /* MBEDTLS_GCM_C */
3367#if defined(MBEDTLS_CCM_C)
3368 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003369 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003370 status = psa_aead_unpadded_locate_tag( operation.tag_length,
mohammad16039375f842018-06-03 14:28:24 +03003371 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003372 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03003373 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003374 goto exit;
mohammad16039375f842018-06-03 14:28:24 +03003375
Gilles Peskineedf9a652018-08-17 18:11:56 +02003376 status = mbedtls_to_psa_error(
3377 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
3378 ciphertext_length - operation.tag_length,
3379 nonce, nonce_length,
3380 additional_data,
3381 additional_data_length,
3382 ciphertext, plaintext,
3383 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003384 }
mohammad160339574652018-06-01 04:39:53 -07003385 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003386#endif /* MBEDTLS_CCM_C */
mohammad160339574652018-06-01 04:39:53 -07003387 {
mohammad1603554faad2018-06-03 15:07:38 +03003388 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07003389 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02003390
Gilles Peskineedf9a652018-08-17 18:11:56 +02003391 if( status != PSA_SUCCESS && plaintext_size != 0 )
3392 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03003393
Gilles Peskineedf9a652018-08-17 18:11:56 +02003394exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003395 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003396 if( status == PSA_SUCCESS )
3397 *plaintext_length = ciphertext_length - operation.tag_length;
3398 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003399}
3400
Gilles Peskinea0655c32018-04-30 17:06:50 +02003401
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003402
Gilles Peskine20035e32018-02-03 22:44:14 +01003403/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003404/* Generators */
3405/****************************************************************/
3406
3407psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
3408{
3409 psa_status_t status = PSA_SUCCESS;
3410 if( generator->alg == 0 )
3411 {
3412 /* The object has (apparently) been initialized but it is not
3413 * in use. It's ok to call abort on such an object, and there's
3414 * nothing to do. */
3415 }
3416 else
Gilles Peskine751d9652018-09-18 12:05:44 +02003417 if( generator->alg == PSA_ALG_SELECT_RAW )
3418 {
3419 if( generator->ctx.buffer.data != NULL )
3420 {
3421 mbedtls_zeroize( generator->ctx.buffer.data,
3422 generator->ctx.buffer.size );
3423 mbedtls_free( generator->ctx.buffer.data );
3424 }
3425 }
3426 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003427#if defined(MBEDTLS_MD_C)
3428 if( PSA_ALG_IS_HKDF( generator->alg ) )
3429 {
3430 mbedtls_free( generator->ctx.hkdf.info );
3431 status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
3432 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003433 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3434 /* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
3435 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003436 {
3437 if( generator->ctx.tls12_prf.key != NULL )
3438 {
3439 mbedtls_zeroize( generator->ctx.tls12_prf.key,
3440 generator->ctx.tls12_prf.key_len );
3441 mbedtls_free( generator->ctx.tls12_prf.key );
3442 }
Hanno Becker580fba12018-11-13 20:50:45 +00003443
3444 if( generator->ctx.tls12_prf.Ai_with_seed != NULL )
3445 {
3446 mbedtls_zeroize( generator->ctx.tls12_prf.Ai_with_seed,
3447 generator->ctx.tls12_prf.Ai_with_seed_len );
3448 mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed );
3449 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003450 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003451 else
3452#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003453 {
3454 status = PSA_ERROR_BAD_STATE;
3455 }
3456 memset( generator, 0, sizeof( *generator ) );
3457 return( status );
3458}
3459
3460
3461psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3462 size_t *capacity)
3463{
3464 *capacity = generator->capacity;
3465 return( PSA_SUCCESS );
3466}
3467
Gilles Peskinebef7f142018-07-12 17:22:21 +02003468#if defined(MBEDTLS_MD_C)
3469/* Read some bytes from an HKDF-based generator. This performs a chunk
3470 * of the expand phase of the HKDF algorithm. */
3471static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
3472 psa_algorithm_t hash_alg,
3473 uint8_t *output,
3474 size_t output_length )
3475{
3476 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3477 psa_status_t status;
3478
3479 while( output_length != 0 )
3480 {
3481 /* Copy what remains of the current block */
3482 uint8_t n = hash_length - hkdf->offset_in_block;
3483 if( n > output_length )
3484 n = (uint8_t) output_length;
3485 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
3486 output += n;
3487 output_length -= n;
3488 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02003489 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003490 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003491 /* We can't be wanting more output after block 0xff, otherwise
3492 * the capacity check in psa_generator_read() would have
3493 * prevented this call. It could happen only if the generator
3494 * object was corrupted or if this function is called directly
3495 * inside the library. */
3496 if( hkdf->block_number == 0xff )
3497 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003498
3499 /* We need a new block */
3500 ++hkdf->block_number;
3501 hkdf->offset_in_block = 0;
3502 status = psa_hmac_setup_internal( &hkdf->hmac,
3503 hkdf->prk, hash_length,
3504 hash_alg );
3505 if( status != PSA_SUCCESS )
3506 return( status );
3507 if( hkdf->block_number != 1 )
3508 {
3509 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3510 hkdf->output_block,
3511 hash_length );
3512 if( status != PSA_SUCCESS )
3513 return( status );
3514 }
3515 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3516 hkdf->info,
3517 hkdf->info_length );
3518 if( status != PSA_SUCCESS )
3519 return( status );
3520 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3521 &hkdf->block_number, 1 );
3522 if( status != PSA_SUCCESS )
3523 return( status );
3524 status = psa_hmac_finish_internal( &hkdf->hmac,
3525 hkdf->output_block,
3526 sizeof( hkdf->output_block ) );
3527 if( status != PSA_SUCCESS )
3528 return( status );
3529 }
3530
3531 return( PSA_SUCCESS );
3532}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003533
3534static psa_status_t psa_generator_tls12_prf_generate_next_block(
3535 psa_tls12_prf_generator_t *tls12_prf,
3536 psa_algorithm_t alg )
3537{
3538 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3539 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3540 psa_hmac_internal_data hmac;
3541 psa_status_t status, cleanup_status;
3542
Hanno Becker3b339e22018-11-13 20:56:14 +00003543 unsigned char *Ai;
3544 size_t Ai_len;
3545
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003546 /* We can't be wanting more output after block 0xff, otherwise
3547 * the capacity check in psa_generator_read() would have
3548 * prevented this call. It could happen only if the generator
3549 * object was corrupted or if this function is called directly
3550 * inside the library. */
3551 if( tls12_prf->block_number == 0xff )
3552 return( PSA_ERROR_BAD_STATE );
3553
3554 /* We need a new block */
3555 ++tls12_prf->block_number;
3556 tls12_prf->offset_in_block = 0;
3557
3558 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
3559 *
3560 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
3561 *
3562 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
3563 * HMAC_hash(secret, A(2) + seed) +
3564 * HMAC_hash(secret, A(3) + seed) + ...
3565 *
3566 * A(0) = seed
3567 * A(i) = HMAC_hash( secret, A(i-1) )
3568 *
3569 * The `psa_tls12_prf_generator` structures saves the block
3570 * `HMAC_hash(secret, A(i) + seed)` from which the output
3571 * is currently extracted as `output_block`, while
3572 * `A(i) + seed` is stored in `Ai_with_seed`.
3573 *
3574 * Generating a new block means recalculating `Ai_with_seed`
3575 * from the A(i)-part of it, and afterwards recalculating
3576 * `output_block`.
3577 *
3578 * A(0) is computed at setup time.
3579 *
3580 */
3581
3582 psa_hmac_init_internal( &hmac );
3583
3584 /* We must distinguish the calculation of A(1) from those
3585 * of A(2) and higher, because A(0)=seed has a different
3586 * length than the other A(i). */
3587 if( tls12_prf->block_number == 1 )
3588 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003589 Ai = tls12_prf->Ai_with_seed + hash_length;
3590 Ai_len = tls12_prf->Ai_with_seed_len - hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003591 }
3592 else
3593 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003594 Ai = tls12_prf->Ai_with_seed;
3595 Ai_len = hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003596 }
3597
Hanno Becker3b339e22018-11-13 20:56:14 +00003598 /* Compute A(i+1) = HMAC_hash(secret, A(i)) */
3599 status = psa_hmac_setup_internal( &hmac,
3600 tls12_prf->key,
3601 tls12_prf->key_len,
3602 hash_alg );
3603 if( status != PSA_SUCCESS )
3604 goto cleanup;
3605
3606 status = psa_hash_update( &hmac.hash_ctx,
3607 Ai, Ai_len );
3608 if( status != PSA_SUCCESS )
3609 goto cleanup;
3610
3611 status = psa_hmac_finish_internal( &hmac,
3612 tls12_prf->Ai_with_seed,
3613 hash_length );
3614 if( status != PSA_SUCCESS )
3615 goto cleanup;
3616
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003617 /* Compute the next block `HMAC_hash(secret, A(i+1) + seed)`. */
3618 status = psa_hmac_setup_internal( &hmac,
3619 tls12_prf->key,
3620 tls12_prf->key_len,
3621 hash_alg );
3622 if( status != PSA_SUCCESS )
3623 goto cleanup;
3624
3625 status = psa_hash_update( &hmac.hash_ctx,
3626 tls12_prf->Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003627 tls12_prf->Ai_with_seed_len );
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003628 if( status != PSA_SUCCESS )
3629 goto cleanup;
3630
3631 status = psa_hmac_finish_internal( &hmac,
3632 tls12_prf->output_block,
3633 hash_length );
3634 if( status != PSA_SUCCESS )
3635 goto cleanup;
3636
3637cleanup:
3638
3639 cleanup_status = psa_hmac_abort_internal( &hmac );
3640 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
3641 status = cleanup_status;
3642
3643 return( status );
3644}
3645
3646/* Read some bytes from an TLS-1.2-PRF-based generator.
3647 * See Section 5 of RFC 5246. */
3648static psa_status_t psa_generator_tls12_prf_read(
3649 psa_tls12_prf_generator_t *tls12_prf,
3650 psa_algorithm_t alg,
3651 uint8_t *output,
3652 size_t output_length )
3653{
3654 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3655 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3656 psa_status_t status;
3657
3658 while( output_length != 0 )
3659 {
3660 /* Copy what remains of the current block */
3661 uint8_t n = hash_length - tls12_prf->offset_in_block;
3662
3663 /* Check if we have fully processed the current block. */
3664 if( n == 0 )
3665 {
3666 status = psa_generator_tls12_prf_generate_next_block( tls12_prf,
3667 alg );
3668 if( status != PSA_SUCCESS )
3669 return( status );
3670
3671 continue;
3672 }
3673
3674 if( n > output_length )
3675 n = (uint8_t) output_length;
3676 memcpy( output, tls12_prf->output_block + tls12_prf->offset_in_block,
3677 n );
3678 output += n;
3679 output_length -= n;
3680 tls12_prf->offset_in_block += n;
3681 }
3682
3683 return( PSA_SUCCESS );
3684}
Gilles Peskinebef7f142018-07-12 17:22:21 +02003685#endif /* MBEDTLS_MD_C */
3686
Gilles Peskineeab56e42018-07-12 17:12:33 +02003687psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
3688 uint8_t *output,
3689 size_t output_length )
3690{
3691 psa_status_t status;
3692
3693 if( output_length > generator->capacity )
3694 {
3695 generator->capacity = 0;
3696 /* Go through the error path to wipe all confidential data now
3697 * that the generator object is useless. */
3698 status = PSA_ERROR_INSUFFICIENT_CAPACITY;
3699 goto exit;
3700 }
3701 if( output_length == 0 &&
3702 generator->capacity == 0 && generator->alg == 0 )
3703 {
3704 /* Edge case: this is a blank or finished generator, and 0
3705 * bytes were requested. The right error in this case could
3706 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3707 * INSUFFICIENT_CAPACITY, which is right for a finished
3708 * generator, for consistency with the case when
3709 * output_length > 0. */
3710 return( PSA_ERROR_INSUFFICIENT_CAPACITY );
3711 }
3712 generator->capacity -= output_length;
3713
Gilles Peskine751d9652018-09-18 12:05:44 +02003714 if( generator->alg == PSA_ALG_SELECT_RAW )
3715 {
Gilles Peskine211a4362018-10-25 22:22:31 +02003716 /* Initially, the capacity of a selection generator is always
3717 * the size of the buffer, i.e. `generator->ctx.buffer.size`,
3718 * abbreviated in this comment as `size`. When the remaining
3719 * capacity is `c`, the next bytes to serve start `c` bytes
3720 * from the end of the buffer, i.e. `size - c` from the
3721 * beginning of the buffer. Since `generator->capacity` was just
3722 * decremented above, we need to serve the bytes from
3723 * `size - generator->capacity - output_length` to
3724 * `size - generator->capacity`. */
Gilles Peskine751d9652018-09-18 12:05:44 +02003725 size_t offset =
3726 generator->ctx.buffer.size - generator->capacity - output_length;
3727 memcpy( output, generator->ctx.buffer.data + offset, output_length );
3728 status = PSA_SUCCESS;
3729 }
3730 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003731#if defined(MBEDTLS_MD_C)
3732 if( PSA_ALG_IS_HKDF( generator->alg ) )
3733 {
3734 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
3735 status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
3736 output, output_length );
3737 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003738 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3739 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003740 {
3741 status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
3742 generator->alg, output,
3743 output_length );
3744 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003745 else
3746#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003747 {
3748 return( PSA_ERROR_BAD_STATE );
3749 }
3750
3751exit:
3752 if( status != PSA_SUCCESS )
3753 {
3754 psa_generator_abort( generator );
3755 memset( output, '!', output_length );
3756 }
3757 return( status );
3758}
3759
Gilles Peskine08542d82018-07-19 17:05:42 +02003760#if defined(MBEDTLS_DES_C)
3761static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
3762{
3763 if( data_size >= 8 )
3764 mbedtls_des_key_set_parity( data );
3765 if( data_size >= 16 )
3766 mbedtls_des_key_set_parity( data + 8 );
3767 if( data_size >= 24 )
3768 mbedtls_des_key_set_parity( data + 16 );
3769}
3770#endif /* MBEDTLS_DES_C */
3771
Gilles Peskineeab56e42018-07-12 17:12:33 +02003772psa_status_t psa_generator_import_key( psa_key_slot_t key,
3773 psa_key_type_t type,
3774 size_t bits,
3775 psa_crypto_generator_t *generator )
3776{
3777 uint8_t *data = NULL;
3778 size_t bytes = PSA_BITS_TO_BYTES( bits );
3779 psa_status_t status;
3780
3781 if( ! key_type_is_raw_bytes( type ) )
3782 return( PSA_ERROR_INVALID_ARGUMENT );
3783 if( bits % 8 != 0 )
3784 return( PSA_ERROR_INVALID_ARGUMENT );
3785 data = mbedtls_calloc( 1, bytes );
3786 if( data == NULL )
3787 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3788
3789 status = psa_generator_read( generator, data, bytes );
3790 if( status != PSA_SUCCESS )
3791 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02003792#if defined(MBEDTLS_DES_C)
3793 if( type == PSA_KEY_TYPE_DES )
3794 psa_des_set_key_parity( data, bytes );
3795#endif /* MBEDTLS_DES_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003796 status = psa_import_key( key, type, data, bytes );
3797
3798exit:
3799 mbedtls_free( data );
3800 return( status );
3801}
3802
3803
3804
3805/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003806/* Key derivation */
3807/****************************************************************/
3808
Gilles Peskinea05219c2018-11-16 16:02:56 +01003809#if defined(MBEDTLS_MD_C)
Gilles Peskinebef7f142018-07-12 17:22:21 +02003810/* Set up an HKDF-based generator. This is exactly the extract phase
Gilles Peskine346797d2018-11-16 16:05:06 +01003811 * of the HKDF algorithm.
3812 *
3813 * Note that if this function fails, you must call psa_generator_abort()
3814 * to potentially free embedded data structures and wipe confidential data.
3815 */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003816static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003817 const uint8_t *secret,
3818 size_t secret_length,
Gilles Peskinebef7f142018-07-12 17:22:21 +02003819 psa_algorithm_t hash_alg,
3820 const uint8_t *salt,
3821 size_t salt_length,
3822 const uint8_t *label,
3823 size_t label_length )
3824{
3825 psa_status_t status;
3826 status = psa_hmac_setup_internal( &hkdf->hmac,
3827 salt, salt_length,
Gilles Peskine00709fa2018-08-22 18:25:41 +02003828 PSA_ALG_HMAC_GET_HASH( hash_alg ) );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003829 if( status != PSA_SUCCESS )
3830 return( status );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003831 status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003832 if( status != PSA_SUCCESS )
3833 return( status );
3834 status = psa_hmac_finish_internal( &hkdf->hmac,
3835 hkdf->prk,
3836 sizeof( hkdf->prk ) );
3837 if( status != PSA_SUCCESS )
3838 return( status );
3839 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
3840 hkdf->block_number = 0;
3841 hkdf->info_length = label_length;
3842 if( label_length != 0 )
3843 {
3844 hkdf->info = mbedtls_calloc( 1, label_length );
3845 if( hkdf->info == NULL )
3846 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3847 memcpy( hkdf->info, label, label_length );
3848 }
3849 return( PSA_SUCCESS );
3850}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003851#endif /* MBEDTLS_MD_C */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003852
Gilles Peskinea05219c2018-11-16 16:02:56 +01003853#if defined(MBEDTLS_MD_C)
Gilles Peskine346797d2018-11-16 16:05:06 +01003854/* Set up a TLS-1.2-prf-based generator (see RFC 5246, Section 5).
3855 *
3856 * Note that if this function fails, you must call psa_generator_abort()
3857 * to potentially free embedded data structures and wipe confidential data.
3858 */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003859static psa_status_t psa_generator_tls12_prf_setup(
3860 psa_tls12_prf_generator_t *tls12_prf,
3861 const unsigned char *key,
3862 size_t key_len,
3863 psa_algorithm_t hash_alg,
3864 const uint8_t *salt,
3865 size_t salt_length,
3866 const uint8_t *label,
3867 size_t label_length )
3868{
3869 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Hanno Becker580fba12018-11-13 20:50:45 +00003870 size_t Ai_with_seed_len = hash_length + salt_length + label_length;
3871 int overflow;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003872
3873 tls12_prf->key = mbedtls_calloc( 1, key_len );
3874 if( tls12_prf->key == NULL )
3875 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3876 tls12_prf->key_len = key_len;
3877 memcpy( tls12_prf->key, key, key_len );
3878
Hanno Becker580fba12018-11-13 20:50:45 +00003879 overflow = ( salt_length + label_length < salt_length ) ||
3880 ( salt_length + label_length + hash_length < hash_length );
3881 if( overflow )
3882 return( PSA_ERROR_INVALID_ARGUMENT );
3883
3884 tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len );
3885 if( tls12_prf->Ai_with_seed == NULL )
3886 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3887 tls12_prf->Ai_with_seed_len = Ai_with_seed_len;
3888
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003889 /* Write `label + seed' at the end of the `A(i) + seed` buffer,
3890 * leaving the initial `hash_length` bytes unspecified for now. */
Hanno Becker353e4532018-11-15 09:53:57 +00003891 if( label_length != 0 )
3892 {
3893 memcpy( tls12_prf->Ai_with_seed + hash_length,
3894 label, label_length );
3895 }
3896
3897 if( salt_length != 0 )
3898 {
3899 memcpy( tls12_prf->Ai_with_seed + hash_length + label_length,
3900 salt, salt_length );
3901 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003902
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003903 /* The first block gets generated when
3904 * psa_generator_read() is called. */
3905 tls12_prf->block_number = 0;
3906 tls12_prf->offset_in_block = hash_length;
3907
3908 return( PSA_SUCCESS );
3909}
Hanno Becker1aaedc02018-11-16 11:35:34 +00003910
3911/* Set up a TLS-1.2-PSK-to-MS-based generator. */
3912static psa_status_t psa_generator_tls12_psk_to_ms_setup(
3913 psa_tls12_prf_generator_t *tls12_prf,
3914 const unsigned char *psk,
3915 size_t psk_len,
3916 psa_algorithm_t hash_alg,
3917 const uint8_t *salt,
3918 size_t salt_length,
3919 const uint8_t *label,
3920 size_t label_length )
3921{
3922 psa_status_t status;
3923 unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
3924
3925 if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
3926 return( PSA_ERROR_INVALID_ARGUMENT );
3927
3928 /* Quoting RFC 4279, Section 2:
3929 *
3930 * The premaster secret is formed as follows: if the PSK is N octets
3931 * long, concatenate a uint16 with the value N, N zero octets, a second
3932 * uint16 with the value N, and the PSK itself.
3933 */
3934
3935 pms[0] = ( psk_len >> 8 ) & 0xff;
3936 pms[1] = ( psk_len >> 0 ) & 0xff;
3937 memset( pms + 2, 0, psk_len );
3938 pms[2 + psk_len + 0] = pms[0];
3939 pms[2 + psk_len + 1] = pms[1];
3940 memcpy( pms + 4 + psk_len, psk, psk_len );
3941
3942 status = psa_generator_tls12_prf_setup( tls12_prf,
3943 pms, 4 + 2 * psk_len,
3944 hash_alg,
3945 salt, salt_length,
3946 label, label_length );
3947
3948 mbedtls_zeroize( pms, sizeof( pms ) );
3949 return( status );
3950}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003951#endif /* MBEDTLS_MD_C */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003952
Gilles Peskine346797d2018-11-16 16:05:06 +01003953/* Note that if this function fails, you must call psa_generator_abort()
3954 * to potentially free embedded data structures and wipe confidential data.
3955 */
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003956static psa_status_t psa_key_derivation_internal(
3957 psa_crypto_generator_t *generator,
3958 const uint8_t *secret, size_t secret_length,
3959 psa_algorithm_t alg,
3960 const uint8_t *salt, size_t salt_length,
3961 const uint8_t *label, size_t label_length,
3962 size_t capacity )
3963{
3964 psa_status_t status;
3965 size_t max_capacity;
3966
3967 /* Set generator->alg even on failure so that abort knows what to do. */
3968 generator->alg = alg;
3969
Gilles Peskine751d9652018-09-18 12:05:44 +02003970 if( alg == PSA_ALG_SELECT_RAW )
3971 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003972 (void) salt;
Gilles Peskine751d9652018-09-18 12:05:44 +02003973 if( salt_length != 0 )
3974 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea05219c2018-11-16 16:02:56 +01003975 (void) label;
Gilles Peskine751d9652018-09-18 12:05:44 +02003976 if( label_length != 0 )
3977 return( PSA_ERROR_INVALID_ARGUMENT );
3978 generator->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
3979 if( generator->ctx.buffer.data == NULL )
3980 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3981 memcpy( generator->ctx.buffer.data, secret, secret_length );
3982 generator->ctx.buffer.size = secret_length;
3983 max_capacity = secret_length;
3984 status = PSA_SUCCESS;
3985 }
3986 else
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003987#if defined(MBEDTLS_MD_C)
3988 if( PSA_ALG_IS_HKDF( alg ) )
3989 {
3990 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3991 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3992 if( hash_size == 0 )
3993 return( PSA_ERROR_NOT_SUPPORTED );
3994 max_capacity = 255 * hash_size;
3995 status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
3996 secret, secret_length,
3997 hash_alg,
3998 salt, salt_length,
3999 label, label_length );
4000 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00004001 /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
4002 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
4003 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004004 {
4005 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
4006 size_t hash_size = PSA_HASH_SIZE( hash_alg );
4007
4008 /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */
4009 if( hash_alg != PSA_ALG_SHA_256 &&
4010 hash_alg != PSA_ALG_SHA_384 )
4011 {
4012 return( PSA_ERROR_NOT_SUPPORTED );
4013 }
4014
4015 max_capacity = 255 * hash_size;
Hanno Becker1aaedc02018-11-16 11:35:34 +00004016
4017 if( PSA_ALG_IS_TLS12_PRF( alg ) )
4018 {
4019 status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
4020 secret, secret_length,
4021 hash_alg, salt, salt_length,
4022 label, label_length );
4023 }
4024 else
4025 {
4026 status = psa_generator_tls12_psk_to_ms_setup(
4027 &generator->ctx.tls12_prf,
4028 secret, secret_length,
4029 hash_alg, salt, salt_length,
4030 label, label_length );
4031 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004032 }
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004033 else
4034#endif
4035 {
4036 return( PSA_ERROR_NOT_SUPPORTED );
4037 }
4038
4039 if( status != PSA_SUCCESS )
4040 return( status );
4041
4042 if( capacity <= max_capacity )
4043 generator->capacity = capacity;
Gilles Peskine8feb3a82018-09-18 12:06:11 +02004044 else if( capacity == PSA_GENERATOR_UNBRIDLED_CAPACITY )
4045 generator->capacity = max_capacity;
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004046 else
4047 return( PSA_ERROR_INVALID_ARGUMENT );
4048
4049 return( PSA_SUCCESS );
4050}
4051
Gilles Peskineea0fb492018-07-12 17:17:20 +02004052psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
Darryl Green88001362018-07-26 13:59:04 +01004053 psa_key_slot_t key,
Gilles Peskineea0fb492018-07-12 17:17:20 +02004054 psa_algorithm_t alg,
4055 const uint8_t *salt,
4056 size_t salt_length,
4057 const uint8_t *label,
4058 size_t label_length,
4059 size_t capacity )
4060{
4061 key_slot_t *slot;
4062 psa_status_t status;
4063
4064 if( generator->alg != 0 )
4065 return( PSA_ERROR_BAD_STATE );
4066
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004067 /* Make sure that alg is a key derivation algorithm. This prevents
4068 * key selection algorithms, which psa_key_derivation_internal
4069 * accepts for the sake of key agreement. */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004070 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
4071 return( PSA_ERROR_INVALID_ARGUMENT );
4072
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004073 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DERIVE, alg );
4074 if( status != PSA_SUCCESS )
4075 return( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004076
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004077 if( slot->type != PSA_KEY_TYPE_DERIVE )
4078 return( PSA_ERROR_INVALID_ARGUMENT );
4079
4080 status = psa_key_derivation_internal( generator,
4081 slot->data.raw.data,
4082 slot->data.raw.bytes,
4083 alg,
4084 salt, salt_length,
4085 label, label_length,
4086 capacity );
4087 if( status != PSA_SUCCESS )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004088 psa_generator_abort( generator );
4089 return( status );
4090}
4091
4092
4093
4094/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02004095/* Key agreement */
4096/****************************************************************/
4097
Gilles Peskinea05219c2018-11-16 16:02:56 +01004098#if defined(MBEDTLS_ECDH_C)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004099static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
4100 size_t peer_key_length,
4101 const mbedtls_ecp_keypair *our_key,
4102 uint8_t *shared_secret,
4103 size_t shared_secret_size,
4104 size_t *shared_secret_length )
4105{
4106 mbedtls_pk_context pk;
4107 mbedtls_ecp_keypair *their_key = NULL;
4108 mbedtls_ecdh_context ecdh;
4109 int ret;
4110 mbedtls_ecdh_init( &ecdh );
4111 mbedtls_pk_init( &pk );
4112
4113 ret = mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length );
4114 if( ret != 0 )
4115 goto exit;
Gilles Peskine88714d72018-10-25 23:07:25 +02004116 switch( mbedtls_pk_get_type( &pk ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004117 {
Gilles Peskine88714d72018-10-25 23:07:25 +02004118 case MBEDTLS_PK_ECKEY:
4119 case MBEDTLS_PK_ECKEY_DH:
4120 break;
4121 default:
4122 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4123 goto exit;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004124 }
4125 their_key = mbedtls_pk_ec( pk );
Gilles Peskineb4086612018-11-14 20:51:23 +01004126 if( their_key->grp.id != our_key->grp.id )
4127 {
4128 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4129 goto exit;
4130 }
4131
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004132 ret = mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS );
4133 if( ret != 0 )
4134 goto exit;
4135 ret = mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS );
4136 if( ret != 0 )
4137 goto exit;
4138
4139 ret = mbedtls_ecdh_calc_secret( &ecdh,
4140 shared_secret_length,
4141 shared_secret, shared_secret_size,
4142 mbedtls_ctr_drbg_random,
4143 &global_data.ctr_drbg );
4144
4145exit:
4146 mbedtls_pk_free( &pk );
4147 mbedtls_ecdh_free( &ecdh );
4148 return( mbedtls_to_psa_error( ret ) );
4149}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004150#endif /* MBEDTLS_ECDH_C */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004151
Gilles Peskine01d718c2018-09-18 12:01:02 +02004152#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
4153
Gilles Peskine346797d2018-11-16 16:05:06 +01004154/* Note that if this function fails, you must call psa_generator_abort()
4155 * to potentially free embedded data structures and wipe confidential data.
4156 */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004157static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
4158 key_slot_t *private_key,
4159 const uint8_t *peer_key,
4160 size_t peer_key_length,
4161 psa_algorithm_t alg )
4162{
4163 psa_status_t status;
4164 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
4165 size_t shared_secret_length = 0;
4166
4167 /* Step 1: run the secret agreement algorithm to generate the shared
4168 * secret. */
4169 switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
4170 {
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004171#if defined(MBEDTLS_ECDH_C)
4172 case PSA_ALG_ECDH_BASE:
4173 if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
4174 return( PSA_ERROR_INVALID_ARGUMENT );
4175 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
4176 private_key->data.ecp,
4177 shared_secret,
4178 sizeof( shared_secret ),
4179 &shared_secret_length );
4180 break;
4181#endif /* MBEDTLS_ECDH_C */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004182 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01004183 (void) private_key;
4184 (void) peer_key;
4185 (void) peer_key_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004186 return( PSA_ERROR_NOT_SUPPORTED );
4187 }
4188 if( status != PSA_SUCCESS )
4189 goto exit;
4190
4191 /* Step 2: set up the key derivation to generate key material from
4192 * the shared secret. */
4193 status = psa_key_derivation_internal( generator,
4194 shared_secret, shared_secret_length,
4195 PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ),
4196 NULL, 0, NULL, 0,
4197 PSA_GENERATOR_UNBRIDLED_CAPACITY );
4198exit:
4199 mbedtls_zeroize( shared_secret, shared_secret_length );
4200 return( status );
4201}
4202
4203psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
4204 psa_key_slot_t private_key,
4205 const uint8_t *peer_key,
4206 size_t peer_key_length,
4207 psa_algorithm_t alg )
4208{
4209 key_slot_t *slot;
4210 psa_status_t status;
4211 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
4212 return( PSA_ERROR_INVALID_ARGUMENT );
4213 status = psa_get_key_from_slot( private_key, &slot,
4214 PSA_KEY_USAGE_DERIVE, alg );
4215 if( status != PSA_SUCCESS )
4216 return( status );
Gilles Peskine346797d2018-11-16 16:05:06 +01004217 status = psa_key_agreement_internal( generator,
4218 slot,
4219 peer_key, peer_key_length,
4220 alg );
4221 if( status != PSA_SUCCESS )
4222 psa_generator_abort( generator );
4223 return( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004224}
4225
4226
4227
4228/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004229/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02004230/****************************************************************/
4231
4232psa_status_t psa_generate_random( uint8_t *output,
4233 size_t output_size )
4234{
itayzafrir0adf0fc2018-09-06 16:24:41 +03004235 int ret;
4236 GUARD_MODULE_INITIALIZED;
4237
4238 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
Gilles Peskine05d69892018-06-19 22:00:52 +02004239 return( mbedtls_to_psa_error( ret ) );
4240}
4241
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004242#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
avolinski13beb102018-11-20 16:51:49 +02004243
4244/* Support function for error conversion between psa_its error codes to psa crypto */
4245static psa_status_t its_to_psa_error( psa_its_status_t ret )
4246{
4247 switch( ret )
4248 {
4249 case PSA_ITS_SUCCESS:
4250 return( PSA_SUCCESS );
4251
4252 case PSA_ITS_ERROR_KEY_NOT_FOUND:
4253 return( PSA_ERROR_EMPTY_SLOT );
4254
4255 case PSA_ITS_ERROR_STORAGE_FAILURE:
4256 return( PSA_ERROR_STORAGE_FAILURE );
4257
4258 case PSA_ITS_ERROR_INSUFFICIENT_SPACE:
4259 return( PSA_ERROR_INSUFFICIENT_STORAGE );
4260
4261 case PSA_ITS_ERROR_INVALID_KEY:
4262 case PSA_PS_ERROR_OFFSET_INVALID:
4263 case PSA_ITS_ERROR_INCORRECT_SIZE:
4264 case PSA_ITS_ERROR_BAD_POINTER:
4265 return( PSA_ERROR_INVALID_ARGUMENT );
4266
4267 case PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED:
4268 return( PSA_ERROR_NOT_SUPPORTED );
4269
4270 case PSA_ITS_ERROR_WRITE_ONCE:
4271 return( PSA_ERROR_OCCUPIED_SLOT );
4272
4273 default:
4274 return( PSA_ERROR_UNKNOWN_ERROR );
4275 }
4276}
4277
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004278psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
4279 size_t seed_size )
4280{
4281 psa_status_t status;
avolinski13beb102018-11-20 16:51:49 +02004282 psa_its_status_t its_status;
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004283 struct psa_its_info_t p_info;
4284 if( global_data.initialized )
4285 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02004286
4287 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
4288 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
4289 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
4290 return( PSA_ERROR_INVALID_ARGUMENT );
4291
avolinski0d2c2662018-11-21 17:31:07 +02004292 its_status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
avolinski13beb102018-11-20 16:51:49 +02004293 status = its_to_psa_error( its_status );
4294
4295 if( PSA_ITS_ERROR_KEY_NOT_FOUND == its_status ) /* No seed exists */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004296 {
avolinski0d2c2662018-11-21 17:31:07 +02004297 its_status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
avolinski13beb102018-11-20 16:51:49 +02004298 status = its_to_psa_error( its_status );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004299 }
avolinski13beb102018-11-20 16:51:49 +02004300 else if( PSA_ITS_SUCCESS == its_status )
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004301 {
4302 /* You should not be here. Seed needs to be injected only once */
4303 status = PSA_ERROR_NOT_PERMITTED;
4304 }
4305 return( status );
4306}
4307#endif
4308
Gilles Peskine05d69892018-06-19 22:00:52 +02004309psa_status_t psa_generate_key( psa_key_slot_t key,
4310 psa_key_type_t type,
4311 size_t bits,
Gilles Peskine53d991e2018-07-12 01:14:59 +02004312 const void *extra,
4313 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02004314{
Gilles Peskine12313cd2018-06-20 00:20:32 +02004315 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004316 psa_status_t status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004317
Gilles Peskine53d991e2018-07-12 01:14:59 +02004318 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004319 return( PSA_ERROR_INVALID_ARGUMENT );
4320
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004321 status = psa_get_empty_key_slot( key, &slot );
4322 if( status != PSA_SUCCESS )
4323 return( status );
4324
Gilles Peskine48c0ea12018-06-21 14:15:31 +02004325 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004326 {
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004327 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004328 if( status != PSA_SUCCESS )
4329 return( status );
4330 status = psa_generate_random( slot->data.raw.data,
4331 slot->data.raw.bytes );
4332 if( status != PSA_SUCCESS )
4333 {
4334 mbedtls_free( slot->data.raw.data );
4335 return( status );
4336 }
4337#if defined(MBEDTLS_DES_C)
4338 if( type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02004339 psa_des_set_key_parity( slot->data.raw.data,
4340 slot->data.raw.bytes );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004341#endif /* MBEDTLS_DES_C */
4342 }
4343 else
4344
4345#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
4346 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
4347 {
4348 mbedtls_rsa_context *rsa;
4349 int ret;
4350 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02004351 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
4352 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +01004353 /* Accept only byte-aligned keys, for the same reasons as
4354 * in psa_import_rsa_key(). */
4355 if( bits % 8 != 0 )
4356 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02004357 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004358 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02004359 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004360 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004361 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02004362#if INT_MAX < 0xffffffff
4363 /* Check that the uint32_t value passed by the caller fits
4364 * in the range supported by this implementation. */
4365 if( p->e > INT_MAX )
4366 return( PSA_ERROR_NOT_SUPPORTED );
4367#endif
4368 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004369 }
4370 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
4371 if( rsa == NULL )
4372 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4373 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
4374 ret = mbedtls_rsa_gen_key( rsa,
4375 mbedtls_ctr_drbg_random,
4376 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004377 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02004378 exponent );
4379 if( ret != 0 )
4380 {
4381 mbedtls_rsa_free( rsa );
4382 mbedtls_free( rsa );
4383 return( mbedtls_to_psa_error( ret ) );
4384 }
4385 slot->data.rsa = rsa;
4386 }
4387 else
4388#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
4389
4390#if defined(MBEDTLS_ECP_C)
4391 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
4392 {
4393 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
4394 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
4395 const mbedtls_ecp_curve_info *curve_info =
4396 mbedtls_ecp_curve_info_from_grp_id( grp_id );
4397 mbedtls_ecp_keypair *ecp;
4398 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004399 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004400 return( PSA_ERROR_NOT_SUPPORTED );
4401 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
4402 return( PSA_ERROR_NOT_SUPPORTED );
4403 if( curve_info->bit_size != bits )
4404 return( PSA_ERROR_INVALID_ARGUMENT );
4405 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
4406 if( ecp == NULL )
4407 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4408 mbedtls_ecp_keypair_init( ecp );
4409 ret = mbedtls_ecp_gen_key( grp_id, ecp,
4410 mbedtls_ctr_drbg_random,
4411 &global_data.ctr_drbg );
4412 if( ret != 0 )
4413 {
4414 mbedtls_ecp_keypair_free( ecp );
4415 mbedtls_free( ecp );
4416 return( mbedtls_to_psa_error( ret ) );
4417 }
4418 slot->data.ecp = ecp;
4419 }
4420 else
4421#endif /* MBEDTLS_ECP_C */
4422
4423 return( PSA_ERROR_NOT_SUPPORTED );
4424
4425 slot->type = type;
Darryl Green0c6575a2018-11-07 16:05:30 +00004426
4427#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
4428 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
4429 {
4430 return( psa_save_generated_persistent_key( key, slot, bits ) );
4431 }
4432#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
4433
4434 return( status );
Gilles Peskine05d69892018-06-19 22:00:52 +02004435}
4436
4437
4438/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01004439/* Module setup */
4440/****************************************************************/
4441
Gilles Peskinee59236f2018-01-27 23:32:46 +01004442void mbedtls_psa_crypto_free( void )
4443{
Jaeden Amero045bd502018-06-26 14:00:08 +01004444 psa_key_slot_t key;
Darryl Green40225ba2018-11-15 14:48:15 +00004445 key_slot_t *slot;
4446 psa_status_t status;
4447
Gilles Peskine9a056342018-08-01 15:46:54 +02004448 for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ )
Darryl Green40225ba2018-11-15 14:48:15 +00004449 {
4450 status = psa_get_key_slot( key, &slot );
4451 if( status != PSA_SUCCESS )
4452 continue;
4453 psa_remove_key_data_from_memory( slot );
4454 /* Zeroize the slot to wipe metadata such as policies. */
4455 mbedtls_zeroize( slot, sizeof( *slot ) );
4456 }
Gilles Peskinee59236f2018-01-27 23:32:46 +01004457 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
4458 mbedtls_entropy_free( &global_data.entropy );
4459 mbedtls_zeroize( &global_data, sizeof( global_data ) );
4460}
4461
4462psa_status_t psa_crypto_init( void )
4463{
4464 int ret;
4465 const unsigned char drbg_seed[] = "PSA";
4466
4467 if( global_data.initialized != 0 )
4468 return( PSA_SUCCESS );
4469
4470 mbedtls_zeroize( &global_data, sizeof( global_data ) );
4471 mbedtls_entropy_init( &global_data.entropy );
4472 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
4473
4474 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
4475 mbedtls_entropy_func,
4476 &global_data.entropy,
4477 drbg_seed, sizeof( drbg_seed ) - 1 );
4478 if( ret != 0 )
4479 goto exit;
4480
Gilles Peskinee4ebc122018-03-07 14:16:44 +01004481 global_data.initialized = 1;
4482
Gilles Peskinee59236f2018-01-27 23:32:46 +01004483exit:
4484 if( ret != 0 )
4485 mbedtls_psa_crypto_free( );
4486 return( mbedtls_to_psa_error( ret ) );
4487}
4488
4489#endif /* MBEDTLS_PSA_CRYPTO_C */