blob: 58cb738309b1cf86633bf1e0a428aab519092671 [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"
Gilles Peskinea5905292018-02-07 20:59:33 +010072#include "mbedtls/error.h"
73#include "mbedtls/gcm.h"
74#include "mbedtls/md2.h"
75#include "mbedtls/md4.h"
76#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010077#include "mbedtls/md.h"
78#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010079#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010080#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010081#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010082#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010083#include "mbedtls/sha1.h"
84#include "mbedtls/sha256.h"
85#include "mbedtls/sha512.h"
86#include "mbedtls/xtea.h"
87
Gilles Peskinee59236f2018-01-27 23:32:46 +010088
89
Gilles Peskine996deb12018-08-01 15:45:45 +020090#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
91
Gilles Peskinee59236f2018-01-27 23:32:46 +010092/* Implementation that should never be optimized out by the compiler */
93static void mbedtls_zeroize( void *v, size_t n )
94{
95 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
96}
97
Gilles Peskine9ef733f2018-02-07 21:05:37 +010098/* constant-time buffer comparison */
99static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
100{
101 size_t i;
102 unsigned char diff = 0;
103
104 for( i = 0; i < n; i++ )
105 diff |= a[i] ^ b[i];
106
107 return( diff );
108}
109
110
111
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100112/****************************************************************/
113/* Global data, support functions and library management */
114/****************************************************************/
115
116/* Number of key slots (plus one because 0 is not used).
117 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +0200118#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100119
Gilles Peskine2d277862018-06-18 15:41:12 +0200120typedef struct
121{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100122 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300123 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200124 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200125 union
126 {
127 struct raw_data
128 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100129 uint8_t *data;
130 size_t bytes;
131 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100132#if defined(MBEDTLS_RSA_C)
133 mbedtls_rsa_context *rsa;
134#endif /* MBEDTLS_RSA_C */
135#if defined(MBEDTLS_ECP_C)
136 mbedtls_ecp_keypair *ecp;
137#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100138 } data;
139} key_slot_t;
140
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200141static int key_type_is_raw_bytes( psa_key_type_t type )
142{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200143 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200144}
145
Gilles Peskine2d277862018-06-18 15:41:12 +0200146typedef struct
147{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100148 int initialized;
149 mbedtls_entropy_context entropy;
150 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200151 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100152} psa_global_data_t;
153
154static psa_global_data_t global_data;
155
itayzafrir0adf0fc2018-09-06 16:24:41 +0300156#define GUARD_MODULE_INITIALIZED \
157 if( global_data.initialized == 0 ) \
158 return( PSA_ERROR_BAD_STATE );
159
Gilles Peskinee59236f2018-01-27 23:32:46 +0100160static psa_status_t mbedtls_to_psa_error( int ret )
161{
Gilles Peskinea5905292018-02-07 20:59:33 +0100162 /* If there's both a high-level code and low-level code, dispatch on
163 * the high-level code. */
164 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100165 {
166 case 0:
167 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100168
169 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
170 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
171 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
172 return( PSA_ERROR_NOT_SUPPORTED );
173 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
174 return( PSA_ERROR_HARDWARE_FAILURE );
175
176 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
177 return( PSA_ERROR_HARDWARE_FAILURE );
178
Gilles Peskine9a944802018-06-21 09:35:35 +0200179 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
180 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
181 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
182 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
183 case MBEDTLS_ERR_ASN1_INVALID_DATA:
184 return( PSA_ERROR_INVALID_ARGUMENT );
185 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
186 return( PSA_ERROR_INSUFFICIENT_MEMORY );
187 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
188 return( PSA_ERROR_BUFFER_TOO_SMALL );
189
Gilles Peskinea5905292018-02-07 20:59:33 +0100190 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
191 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
192 return( PSA_ERROR_NOT_SUPPORTED );
193 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
194 return( PSA_ERROR_HARDWARE_FAILURE );
195
196 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
197 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
198 return( PSA_ERROR_NOT_SUPPORTED );
199 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
200 return( PSA_ERROR_HARDWARE_FAILURE );
201
202 case MBEDTLS_ERR_CCM_BAD_INPUT:
203 return( PSA_ERROR_INVALID_ARGUMENT );
204 case MBEDTLS_ERR_CCM_AUTH_FAILED:
205 return( PSA_ERROR_INVALID_SIGNATURE );
206 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
207 return( PSA_ERROR_HARDWARE_FAILURE );
208
209 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
210 return( PSA_ERROR_NOT_SUPPORTED );
211 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
212 return( PSA_ERROR_INVALID_ARGUMENT );
213 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
214 return( PSA_ERROR_INSUFFICIENT_MEMORY );
215 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
216 return( PSA_ERROR_INVALID_PADDING );
217 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
218 return( PSA_ERROR_BAD_STATE );
219 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
220 return( PSA_ERROR_INVALID_SIGNATURE );
221 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
222 return( PSA_ERROR_TAMPERING_DETECTED );
223 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
224 return( PSA_ERROR_HARDWARE_FAILURE );
225
226 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
227 return( PSA_ERROR_HARDWARE_FAILURE );
228
229 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
230 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
231 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
232 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
233 return( PSA_ERROR_NOT_SUPPORTED );
234 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
235 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
236
237 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
238 return( PSA_ERROR_NOT_SUPPORTED );
239 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
240 return( PSA_ERROR_HARDWARE_FAILURE );
241
Gilles Peskinee59236f2018-01-27 23:32:46 +0100242 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
243 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
244 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
245 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100246
247 case MBEDTLS_ERR_GCM_AUTH_FAILED:
248 return( PSA_ERROR_INVALID_SIGNATURE );
249 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200250 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100251 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
252 return( PSA_ERROR_HARDWARE_FAILURE );
253
254 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
255 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
256 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
257 return( PSA_ERROR_HARDWARE_FAILURE );
258
259 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
260 return( PSA_ERROR_NOT_SUPPORTED );
261 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
262 return( PSA_ERROR_INVALID_ARGUMENT );
263 case MBEDTLS_ERR_MD_ALLOC_FAILED:
264 return( PSA_ERROR_INSUFFICIENT_MEMORY );
265 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
266 return( PSA_ERROR_STORAGE_FAILURE );
267 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
268 return( PSA_ERROR_HARDWARE_FAILURE );
269
Gilles Peskinef76aa772018-10-29 19:24:33 +0100270 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
271 return( PSA_ERROR_STORAGE_FAILURE );
272 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
273 return( PSA_ERROR_INVALID_ARGUMENT );
274 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
275 return( PSA_ERROR_INVALID_ARGUMENT );
276 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
277 return( PSA_ERROR_BUFFER_TOO_SMALL );
278 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
279 return( PSA_ERROR_INVALID_ARGUMENT );
280 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
281 return( PSA_ERROR_INVALID_ARGUMENT );
282 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
283 return( PSA_ERROR_INVALID_ARGUMENT );
284 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
285 return( PSA_ERROR_INSUFFICIENT_MEMORY );
286
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100287 case MBEDTLS_ERR_PK_ALLOC_FAILED:
288 return( PSA_ERROR_INSUFFICIENT_MEMORY );
289 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
290 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
291 return( PSA_ERROR_INVALID_ARGUMENT );
292 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100293 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100294 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
295 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
296 return( PSA_ERROR_INVALID_ARGUMENT );
297 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
298 return( PSA_ERROR_NOT_SUPPORTED );
299 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
300 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
301 return( PSA_ERROR_NOT_PERMITTED );
302 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
303 return( PSA_ERROR_INVALID_ARGUMENT );
304 case MBEDTLS_ERR_PK_INVALID_ALG:
305 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
306 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
307 return( PSA_ERROR_NOT_SUPPORTED );
308 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
309 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100310 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
311 return( PSA_ERROR_HARDWARE_FAILURE );
312
313 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
314 return( PSA_ERROR_HARDWARE_FAILURE );
315
316 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
317 return( PSA_ERROR_INVALID_ARGUMENT );
318 case MBEDTLS_ERR_RSA_INVALID_PADDING:
319 return( PSA_ERROR_INVALID_PADDING );
320 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
321 return( PSA_ERROR_HARDWARE_FAILURE );
322 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
323 return( PSA_ERROR_INVALID_ARGUMENT );
324 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
325 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
326 return( PSA_ERROR_TAMPERING_DETECTED );
327 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
328 return( PSA_ERROR_INVALID_SIGNATURE );
329 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
330 return( PSA_ERROR_BUFFER_TOO_SMALL );
331 case MBEDTLS_ERR_RSA_RNG_FAILED:
332 return( PSA_ERROR_INSUFFICIENT_MEMORY );
333 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
334 return( PSA_ERROR_NOT_SUPPORTED );
335 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
336 return( PSA_ERROR_HARDWARE_FAILURE );
337
338 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
339 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
340 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
341 return( PSA_ERROR_HARDWARE_FAILURE );
342
343 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
344 return( PSA_ERROR_INVALID_ARGUMENT );
345 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
346 return( PSA_ERROR_HARDWARE_FAILURE );
347
itayzafrir5c753392018-05-08 11:18:38 +0300348 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300349 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300350 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300351 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
352 return( PSA_ERROR_BUFFER_TOO_SMALL );
353 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
354 return( PSA_ERROR_NOT_SUPPORTED );
355 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
356 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
357 return( PSA_ERROR_INVALID_SIGNATURE );
358 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
359 return( PSA_ERROR_INSUFFICIENT_MEMORY );
360 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
361 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300362
Gilles Peskinee59236f2018-01-27 23:32:46 +0100363 default:
364 return( PSA_ERROR_UNKNOWN_ERROR );
365 }
366}
367
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200368
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200369
370
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100371/****************************************************************/
372/* Key management */
373/****************************************************************/
374
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100375#if defined(MBEDTLS_ECP_C)
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200376static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
377{
378 switch( grpid )
379 {
380 case MBEDTLS_ECP_DP_SECP192R1:
381 return( PSA_ECC_CURVE_SECP192R1 );
382 case MBEDTLS_ECP_DP_SECP224R1:
383 return( PSA_ECC_CURVE_SECP224R1 );
384 case MBEDTLS_ECP_DP_SECP256R1:
385 return( PSA_ECC_CURVE_SECP256R1 );
386 case MBEDTLS_ECP_DP_SECP384R1:
387 return( PSA_ECC_CURVE_SECP384R1 );
388 case MBEDTLS_ECP_DP_SECP521R1:
389 return( PSA_ECC_CURVE_SECP521R1 );
390 case MBEDTLS_ECP_DP_BP256R1:
391 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
392 case MBEDTLS_ECP_DP_BP384R1:
393 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
394 case MBEDTLS_ECP_DP_BP512R1:
395 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
396 case MBEDTLS_ECP_DP_CURVE25519:
397 return( PSA_ECC_CURVE_CURVE25519 );
398 case MBEDTLS_ECP_DP_SECP192K1:
399 return( PSA_ECC_CURVE_SECP192K1 );
400 case MBEDTLS_ECP_DP_SECP224K1:
401 return( PSA_ECC_CURVE_SECP224K1 );
402 case MBEDTLS_ECP_DP_SECP256K1:
403 return( PSA_ECC_CURVE_SECP256K1 );
404 case MBEDTLS_ECP_DP_CURVE448:
405 return( PSA_ECC_CURVE_CURVE448 );
406 default:
407 return( 0 );
408 }
409}
410
Gilles Peskine12313cd2018-06-20 00:20:32 +0200411static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
412{
413 switch( curve )
414 {
415 case PSA_ECC_CURVE_SECP192R1:
416 return( MBEDTLS_ECP_DP_SECP192R1 );
417 case PSA_ECC_CURVE_SECP224R1:
418 return( MBEDTLS_ECP_DP_SECP224R1 );
419 case PSA_ECC_CURVE_SECP256R1:
420 return( MBEDTLS_ECP_DP_SECP256R1 );
421 case PSA_ECC_CURVE_SECP384R1:
422 return( MBEDTLS_ECP_DP_SECP384R1 );
423 case PSA_ECC_CURVE_SECP521R1:
424 return( MBEDTLS_ECP_DP_SECP521R1 );
425 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
426 return( MBEDTLS_ECP_DP_BP256R1 );
427 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
428 return( MBEDTLS_ECP_DP_BP384R1 );
429 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
430 return( MBEDTLS_ECP_DP_BP512R1 );
431 case PSA_ECC_CURVE_CURVE25519:
432 return( MBEDTLS_ECP_DP_CURVE25519 );
433 case PSA_ECC_CURVE_SECP192K1:
434 return( MBEDTLS_ECP_DP_SECP192K1 );
435 case PSA_ECC_CURVE_SECP224K1:
436 return( MBEDTLS_ECP_DP_SECP224K1 );
437 case PSA_ECC_CURVE_SECP256K1:
438 return( MBEDTLS_ECP_DP_SECP256K1 );
439 case PSA_ECC_CURVE_CURVE448:
440 return( MBEDTLS_ECP_DP_CURVE448 );
441 default:
442 return( MBEDTLS_ECP_DP_NONE );
443 }
444}
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100445#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200446
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200447static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
448 size_t bits,
449 struct raw_data *raw )
450{
451 /* Check that the bit size is acceptable for the key type */
452 switch( type )
453 {
454 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200455 if( bits == 0 )
456 {
457 raw->bytes = 0;
458 raw->data = NULL;
459 return( PSA_SUCCESS );
460 }
461 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200462#if defined(MBEDTLS_MD_C)
463 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200464#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200465 case PSA_KEY_TYPE_DERIVE:
466 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200467#if defined(MBEDTLS_AES_C)
468 case PSA_KEY_TYPE_AES:
469 if( bits != 128 && bits != 192 && bits != 256 )
470 return( PSA_ERROR_INVALID_ARGUMENT );
471 break;
472#endif
473#if defined(MBEDTLS_CAMELLIA_C)
474 case PSA_KEY_TYPE_CAMELLIA:
475 if( bits != 128 && bits != 192 && bits != 256 )
476 return( PSA_ERROR_INVALID_ARGUMENT );
477 break;
478#endif
479#if defined(MBEDTLS_DES_C)
480 case PSA_KEY_TYPE_DES:
481 if( bits != 64 && bits != 128 && bits != 192 )
482 return( PSA_ERROR_INVALID_ARGUMENT );
483 break;
484#endif
485#if defined(MBEDTLS_ARC4_C)
486 case PSA_KEY_TYPE_ARC4:
487 if( bits < 8 || bits > 2048 )
488 return( PSA_ERROR_INVALID_ARGUMENT );
489 break;
490#endif
491 default:
492 return( PSA_ERROR_NOT_SUPPORTED );
493 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200494 if( bits % 8 != 0 )
495 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200496
497 /* Allocate memory for the key */
498 raw->bytes = PSA_BITS_TO_BYTES( bits );
499 raw->data = mbedtls_calloc( 1, raw->bytes );
500 if( raw->data == NULL )
501 {
502 raw->bytes = 0;
503 return( PSA_ERROR_INSUFFICIENT_MEMORY );
504 }
505 return( PSA_SUCCESS );
506}
507
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200508#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine86a440b2018-11-12 18:39:40 +0100509/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
510 * that are not a multiple of 8) well. For example, there is only
511 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
512 * way to return the exact bit size of a key.
513 * To keep things simple, reject non-byte-aligned key sizes. */
514static psa_status_t psa_check_rsa_key_byte_aligned(
515 const mbedtls_rsa_context *rsa )
516{
517 mbedtls_mpi n;
518 psa_status_t status;
519 mbedtls_mpi_init( &n );
520 status = mbedtls_to_psa_error(
521 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
522 if( status == PSA_SUCCESS )
523 {
524 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
525 status = PSA_ERROR_NOT_SUPPORTED;
526 }
527 mbedtls_mpi_free( &n );
528 return( status );
529}
530
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200531static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
532 mbedtls_rsa_context **p_rsa )
533{
534 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_RSA )
535 return( PSA_ERROR_INVALID_ARGUMENT );
536 else
537 {
538 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *pk );
Gilles Peskineaac64a22018-11-12 18:37:42 +0100539 /* The size of an RSA key doesn't have to be a multiple of 8.
540 * Mbed TLS supports non-byte-aligned key sizes, but not well.
541 * For example, mbedtls_rsa_get_len() returns the key size in
542 * bytes, not in bits. */
543 size_t bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100544 psa_status_t status;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200545 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
546 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100547 status = psa_check_rsa_key_byte_aligned( rsa );
548 if( status != PSA_SUCCESS )
549 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200550 *p_rsa = rsa;
551 return( PSA_SUCCESS );
552 }
553}
554#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
555
556#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinef76aa772018-10-29 19:24:33 +0100557/* Import an elliptic curve parsed by the mbedtls pk module. */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200558static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
559 mbedtls_pk_context *pk,
560 mbedtls_ecp_keypair **p_ecp )
561{
562 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
563 return( PSA_ERROR_INVALID_ARGUMENT );
564 else
565 {
566 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
567 psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
568 if( actual_curve != expected_curve )
569 return( PSA_ERROR_INVALID_ARGUMENT );
570 *p_ecp = ecp;
571 return( PSA_SUCCESS );
572 }
573}
574#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
575
Gilles Peskinef76aa772018-10-29 19:24:33 +0100576#if defined(MBEDTLS_ECP_C)
577/* Import a private key given as a byte string which is the private value
578 * in big-endian order. */
579static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
580 const uint8_t *data,
581 size_t data_length,
582 mbedtls_ecp_keypair **p_ecp )
583{
584 psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
585 mbedtls_ecp_keypair *ecp = NULL;
586 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
587
588 *p_ecp = NULL;
589 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
590 if( ecp == NULL )
591 return( PSA_ERROR_INSUFFICIENT_MEMORY );
592
593 /* Load the group. */
594 status = mbedtls_to_psa_error(
595 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
596 if( status != PSA_SUCCESS )
597 goto exit;
598 /* Load the secret value. */
599 status = mbedtls_to_psa_error(
600 mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
601 if( status != PSA_SUCCESS )
602 goto exit;
603 /* Validate the private key. */
604 status = mbedtls_to_psa_error(
605 mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
606 if( status != PSA_SUCCESS )
607 goto exit;
608 /* Calculate the public key from the private key. */
609 status = mbedtls_to_psa_error(
610 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
611 mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
612 if( status != PSA_SUCCESS )
613 goto exit;
614
615 *p_ecp = ecp;
616 return( PSA_SUCCESS );
617
618exit:
619 if( ecp != NULL )
620 {
621 mbedtls_ecp_keypair_free( ecp );
622 mbedtls_free( ecp );
623 }
624 return( status );
625}
626#endif /* defined(MBEDTLS_ECP_C) */
627
Darryl Green940d72c2018-07-13 13:18:51 +0100628static psa_status_t psa_import_key_into_slot( key_slot_t *slot,
629 const uint8_t *data,
630 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100631{
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200632 psa_status_t status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100633
Darryl Green940d72c2018-07-13 13:18:51 +0100634 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100635 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100636 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100637 if( data_length > SIZE_MAX / 8 )
638 return( PSA_ERROR_NOT_SUPPORTED );
Darryl Green940d72c2018-07-13 13:18:51 +0100639 status = prepare_raw_data_slot( slot->type,
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200640 PSA_BYTES_TO_BITS( data_length ),
641 &slot->data.raw );
642 if( status != PSA_SUCCESS )
643 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200644 if( data_length != 0 )
645 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100646 }
647 else
Gilles Peskinef76aa772018-10-29 19:24:33 +0100648#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100649 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100650 {
Darryl Green940d72c2018-07-13 13:18:51 +0100651 status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskinef76aa772018-10-29 19:24:33 +0100652 data, data_length,
653 &slot->data.ecp );
654 if( status != PSA_SUCCESS )
655 return( status );
656 }
657 else
658#endif /* MBEDTLS_ECP_C */
Gilles Peskine969ac722018-01-28 18:16:59 +0100659#if defined(MBEDTLS_PK_PARSE_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100660 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
661 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100662 {
663 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100664 mbedtls_pk_context pk;
665 mbedtls_pk_init( &pk );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200666
667 /* Parse the data. */
Darryl Green940d72c2018-07-13 13:18:51 +0100668 if( PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100669 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
670 else
671 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100672 if( ret != 0 )
673 return( mbedtls_to_psa_error( ret ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200674
675 /* We have something that the pkparse module recognizes.
676 * If it has the expected type and passes any type-specific
677 * checks, store it. */
Gilles Peskine969ac722018-01-28 18:16:59 +0100678#if defined(MBEDTLS_RSA_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100679 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200680 status = psa_import_rsa_key( &pk, &slot->data.rsa );
681 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100682#endif /* MBEDTLS_RSA_C */
683#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100684 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
685 status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200686 &pk, &slot->data.ecp );
687 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100688#endif /* MBEDTLS_ECP_C */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200689 {
690 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinec648d692018-06-28 08:46:13 +0200691 }
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200692
Gilles Peskinec648d692018-06-28 08:46:13 +0200693 /* Free the content of the pk object only on error. On success,
694 * the content of the object has been stored in the slot. */
695 if( status != PSA_SUCCESS )
696 {
697 mbedtls_pk_free( &pk );
698 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100699 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100700 }
701 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100702#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100703 {
704 return( PSA_ERROR_NOT_SUPPORTED );
705 }
Darryl Green940d72c2018-07-13 13:18:51 +0100706 return( PSA_SUCCESS );
707}
708
Darryl Greend49a4992018-06-18 17:27:26 +0100709#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
710static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t key,
711 key_slot_t *p_slot )
712{
713 psa_status_t status = PSA_SUCCESS;
714 uint8_t *key_data = NULL;
715 size_t key_data_length = 0;
716
717 status = psa_load_persistent_key( key, &( p_slot )->type,
718 &( p_slot )->policy, &key_data,
719 &key_data_length );
720 if( status != PSA_SUCCESS )
721 goto exit;
722 status = psa_import_key_into_slot( p_slot,
723 key_data, key_data_length );
724exit:
725 psa_free_persistent_key_data( key_data, key_data_length );
726 return( status );
727}
728#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
729
Darryl Green06fd18d2018-07-16 11:21:11 +0100730/* Retrieve a key slot, occupied or not. */
731static psa_status_t psa_get_key_slot( psa_key_slot_t key,
732 key_slot_t **p_slot )
733{
734 GUARD_MODULE_INITIALIZED;
735
736 /* 0 is not a valid slot number under any circumstance. This
737 * implementation provides slots number 1 to N where N is the
738 * number of available slots. */
739 if( key == 0 || key > ARRAY_LENGTH( global_data.key_slots ) )
740 return( PSA_ERROR_INVALID_ARGUMENT );
741
742 *p_slot = &global_data.key_slots[key - 1];
Darryl Greend49a4992018-06-18 17:27:26 +0100743
744#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
745 if( ( *p_slot )->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
746 {
747 /* There are two circumstances this can occur: the key material has
748 * not yet been created, or the key exists in storage but has not yet
749 * been loaded into memory. */
750 if( ( *p_slot )->type == PSA_KEY_TYPE_NONE )
751 {
752 psa_status_t status = PSA_SUCCESS;
753 status = psa_load_persistent_key_into_slot( key, *p_slot );
754 if( status != PSA_ERROR_EMPTY_SLOT )
755 return( status );
756 }
757 }
758#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
759
Darryl Green06fd18d2018-07-16 11:21:11 +0100760 return( PSA_SUCCESS );
761}
762
763/* Retrieve an empty key slot (slot with no key data, but possibly
764 * with some metadata such as a policy). */
765static psa_status_t psa_get_empty_key_slot( psa_key_slot_t key,
766 key_slot_t **p_slot )
767{
768 psa_status_t status;
769 key_slot_t *slot = NULL;
770
771 *p_slot = NULL;
772
773 status = psa_get_key_slot( key, &slot );
774 if( status != PSA_SUCCESS )
775 return( status );
776
777 if( slot->type != PSA_KEY_TYPE_NONE )
778 return( PSA_ERROR_OCCUPIED_SLOT );
779
780 *p_slot = slot;
781 return( status );
782}
783
784/** Retrieve a slot which must contain a key. The key must have allow all the
785 * usage flags set in \p usage. If \p alg is nonzero, the key must allow
786 * operations with this algorithm. */
787static psa_status_t psa_get_key_from_slot( psa_key_slot_t key,
788 key_slot_t **p_slot,
789 psa_key_usage_t usage,
790 psa_algorithm_t alg )
791{
792 psa_status_t status;
793 key_slot_t *slot = NULL;
794
795 *p_slot = NULL;
796
797 status = psa_get_key_slot( key, &slot );
798 if( status != PSA_SUCCESS )
799 return( status );
800 if( slot->type == PSA_KEY_TYPE_NONE )
801 return( PSA_ERROR_EMPTY_SLOT );
802
803 /* Enforce that usage policy for the key slot contains all the flags
804 * required by the usage parameter. There is one exception: public
805 * keys can always be exported, so we treat public key objects as
806 * if they had the export flag. */
807 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
808 usage &= ~PSA_KEY_USAGE_EXPORT;
809 if( ( slot->policy.usage & usage ) != usage )
810 return( PSA_ERROR_NOT_PERMITTED );
811 if( alg != 0 && ( alg != slot->policy.alg ) )
812 return( PSA_ERROR_NOT_PERMITTED );
813
814 *p_slot = slot;
815 return( PSA_SUCCESS );
816}
Darryl Green940d72c2018-07-13 13:18:51 +0100817
Darryl Green40225ba2018-11-15 14:48:15 +0000818static psa_status_t psa_remove_key_data_from_memory( key_slot_t *slot )
819{
820 if( slot->type == PSA_KEY_TYPE_NONE )
821 {
822 /* No key material to clean. */
823 }
824 else if( key_type_is_raw_bytes( slot->type ) )
825 {
826 mbedtls_free( slot->data.raw.data );
827 }
828 else
829#if defined(MBEDTLS_RSA_C)
830 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
831 {
832 mbedtls_rsa_free( slot->data.rsa );
833 mbedtls_free( slot->data.rsa );
834 }
835 else
836#endif /* defined(MBEDTLS_RSA_C) */
837#if defined(MBEDTLS_ECP_C)
838 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
839 {
840 mbedtls_ecp_keypair_free( slot->data.ecp );
841 mbedtls_free( slot->data.ecp );
842 }
843 else
844#endif /* defined(MBEDTLS_ECP_C) */
845 {
846 /* Shouldn't happen: the key type is not any type that we
847 * put in. */
848 return( PSA_ERROR_TAMPERING_DETECTED );
849 }
850
851 return( PSA_SUCCESS );
852}
853
Darryl Green940d72c2018-07-13 13:18:51 +0100854psa_status_t psa_import_key( psa_key_slot_t key,
855 psa_key_type_t type,
856 const uint8_t *data,
857 size_t data_length )
858{
859 key_slot_t *slot;
860 psa_status_t status;
861
862 status = psa_get_empty_key_slot( key, &slot );
863 if( status != PSA_SUCCESS )
864 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100865
866 slot->type = type;
Darryl Green940d72c2018-07-13 13:18:51 +0100867
868 status = psa_import_key_into_slot( slot, data, data_length );
869 if( status != PSA_SUCCESS )
870 {
871 slot->type = PSA_KEY_TYPE_NONE;
872 return( status );
873 }
874
Darryl Greend49a4992018-06-18 17:27:26 +0100875#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
876 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
877 {
878 /* Store in file location */
879 status = psa_save_persistent_key( key, slot->type, &slot->policy, data,
880 data_length );
881 if( status != PSA_SUCCESS )
882 {
883 (void) psa_remove_key_data_from_memory( slot );
884 slot->type = PSA_KEY_TYPE_NONE;
885 }
886 }
887#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
888
889 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100890}
891
Gilles Peskine2d277862018-06-18 15:41:12 +0200892psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100893{
894 key_slot_t *slot;
Darryl Greend49a4992018-06-18 17:27:26 +0100895 psa_status_t status = PSA_SUCCESS;
896 psa_status_t storage_status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100897
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200898 status = psa_get_key_slot( key, &slot );
899 if( status != PSA_SUCCESS )
900 return( status );
Darryl Greend49a4992018-06-18 17:27:26 +0100901#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
902 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
903 {
904 storage_status = psa_destroy_persistent_key( key );
905 }
906#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
907 status = psa_remove_key_data_from_memory( slot );
908 /* Zeroize the slot to wipe metadata such as policies. */
909 mbedtls_zeroize( slot, sizeof( *slot ) );
910 if( status != PSA_SUCCESS )
911 return( status );
912 return( storage_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100913}
914
Gilles Peskineb870b182018-07-06 16:02:09 +0200915/* Return the size of the key in the given slot, in bits. */
916static size_t psa_get_key_bits( const key_slot_t *slot )
917{
918 if( key_type_is_raw_bytes( slot->type ) )
919 return( slot->data.raw.bytes * 8 );
920#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200921 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaac64a22018-11-12 18:37:42 +0100922 return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
Gilles Peskineb870b182018-07-06 16:02:09 +0200923#endif /* defined(MBEDTLS_RSA_C) */
924#if defined(MBEDTLS_ECP_C)
925 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
926 return( slot->data.ecp->grp.pbits );
927#endif /* defined(MBEDTLS_ECP_C) */
928 /* Shouldn't happen except on an empty slot. */
929 return( 0 );
930}
931
Gilles Peskine2d277862018-06-18 15:41:12 +0200932psa_status_t psa_get_key_information( psa_key_slot_t key,
933 psa_key_type_t *type,
934 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100935{
936 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200937 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100938
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100939 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200940 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100941 if( bits != NULL )
942 *bits = 0;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200943 status = psa_get_key_slot( key, &slot );
944 if( status != PSA_SUCCESS )
945 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +0200946
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100947 if( slot->type == PSA_KEY_TYPE_NONE )
948 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200949 if( type != NULL )
950 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +0200951 if( bits != NULL )
952 *bits = psa_get_key_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100953 return( PSA_SUCCESS );
954}
955
Darryl Greendd8fb772018-11-07 16:00:44 +0000956static psa_status_t psa_internal_export_key( key_slot_t *slot,
Gilles Peskine2d277862018-06-18 15:41:12 +0200957 uint8_t *data,
958 size_t data_size,
959 size_t *data_length,
960 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100961{
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100962 *data_length = 0;
963
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200964 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300965 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300966
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200967 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100968 {
969 if( slot->data.raw.bytes > data_size )
970 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine52b90182018-10-29 19:26:27 +0100971 if( data_size != 0 )
972 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200973 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine52b90182018-10-29 19:26:27 +0100974 memset( data + slot->data.raw.bytes, 0,
975 data_size - slot->data.raw.bytes );
976 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100977 *data_length = slot->data.raw.bytes;
978 return( PSA_SUCCESS );
979 }
Gilles Peskine188c71e2018-10-29 19:26:02 +0100980#if defined(MBEDTLS_ECP_C)
981 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) && !export_public_key )
982 {
Darryl Greendd8fb772018-11-07 16:00:44 +0000983 psa_status_t status;
984
Gilles Peskine188c71e2018-10-29 19:26:02 +0100985 size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( slot ) );
986 if( bytes > data_size )
987 return( PSA_ERROR_BUFFER_TOO_SMALL );
988 status = mbedtls_to_psa_error(
989 mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
990 if( status != PSA_SUCCESS )
991 return( status );
992 memset( data + bytes, 0, data_size - bytes );
993 *data_length = bytes;
994 return( PSA_SUCCESS );
995 }
996#endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100997 else
Moran Peker17e36e12018-05-02 12:55:20 +0300998 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100999#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02001000 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
Moran Pekera998bc62018-04-16 18:16:20 +03001001 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +01001002 {
Moran Pekera998bc62018-04-16 18:16:20 +03001003 mbedtls_pk_context pk;
1004 int ret;
Gilles Peskined8008d62018-06-29 19:51:51 +02001005 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001006 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001007#if defined(MBEDTLS_RSA_C)
1008 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001009 pk.pk_info = &mbedtls_rsa_info;
1010 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001011#else
1012 return( PSA_ERROR_NOT_SUPPORTED );
1013#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001014 }
1015 else
1016 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001017#if defined(MBEDTLS_ECP_C)
1018 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001019 pk.pk_info = &mbedtls_eckey_info;
1020 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001021#else
1022 return( PSA_ERROR_NOT_SUPPORTED );
1023#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001024 }
Moran Pekerd7326592018-05-29 16:56:39 +03001025 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001026 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +03001027 else
1028 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +03001029 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001030 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001031 /* If data_size is 0 then data may be NULL and then the
1032 * call to memset would have undefined behavior. */
1033 if( data_size != 0 )
1034 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +03001035 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001036 }
Gilles Peskine0e231582018-06-20 00:11:07 +02001037 /* The mbedtls_pk_xxx functions write to the end of the buffer.
1038 * Move the data to the beginning and erase remaining data
1039 * at the original location. */
1040 if( 2 * (size_t) ret <= data_size )
1041 {
1042 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001043 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001044 }
1045 else if( (size_t) ret < data_size )
1046 {
1047 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001048 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001049 }
Moran Pekera998bc62018-04-16 18:16:20 +03001050 *data_length = ret;
1051 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +01001052 }
1053 else
Gilles Peskine6d912132018-03-07 16:41:37 +01001054#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +03001055 {
1056 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +02001057 it is valid for a special-purpose implementation to omit
1058 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +03001059 return( PSA_ERROR_NOT_SUPPORTED );
1060 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001061 }
1062}
1063
Gilles Peskine2d277862018-06-18 15:41:12 +02001064psa_status_t psa_export_key( psa_key_slot_t key,
1065 uint8_t *data,
1066 size_t data_size,
1067 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001068{
Darryl Greendd8fb772018-11-07 16:00:44 +00001069 key_slot_t *slot;
1070 psa_status_t status;
1071
1072 /* Set the key to empty now, so that even when there are errors, we always
1073 * set data_length to a value between 0 and data_size. On error, setting
1074 * the key to empty is a good choice because an empty key representation is
1075 * unlikely to be accepted anywhere. */
1076 *data_length = 0;
1077
1078 /* Export requires the EXPORT flag. There is an exception for public keys,
1079 * which don't require any flag, but psa_get_key_from_slot takes
1080 * care of this. */
1081 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_EXPORT, 0 );
1082 if( status != PSA_SUCCESS )
1083 return( status );
1084 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001085 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001086}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001087
Gilles Peskine2d277862018-06-18 15:41:12 +02001088psa_status_t psa_export_public_key( psa_key_slot_t key,
1089 uint8_t *data,
1090 size_t data_size,
1091 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001092{
Darryl Greendd8fb772018-11-07 16:00:44 +00001093 key_slot_t *slot;
1094 psa_status_t status;
1095
1096 /* Set the key to empty now, so that even when there are errors, we always
1097 * set data_length to a value between 0 and data_size. On error, setting
1098 * the key to empty is a good choice because an empty key representation is
1099 * unlikely to be accepted anywhere. */
1100 *data_length = 0;
1101
1102 /* Exporting a public key doesn't require a usage flag. */
1103 status = psa_get_key_from_slot( key, &slot, 0, 0 );
1104 if( status != PSA_SUCCESS )
1105 return( status );
1106 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001107 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001108}
1109
Darryl Green0c6575a2018-11-07 16:05:30 +00001110#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
1111static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t key,
1112 key_slot_t *slot,
1113 size_t bits )
1114{
1115 psa_status_t status;
1116 uint8_t *data;
1117 size_t key_length;
1118 size_t data_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type, bits );
1119 data = mbedtls_calloc( 1, data_size );
1120 /* Get key data in export format */
1121 status = psa_internal_export_key( slot, data, data_size, &key_length, 0 );
1122 if( status != PSA_SUCCESS )
1123 {
1124 slot->type = PSA_KEY_TYPE_NONE;
1125 goto exit;
1126 }
1127 /* Store in file location */
1128 status = psa_save_persistent_key( key, slot->type, &slot->policy,
1129 data, key_length );
1130 if( status != PSA_SUCCESS )
1131 {
1132 slot->type = PSA_KEY_TYPE_NONE;
1133 }
1134exit:
1135 mbedtls_zeroize( data, key_length );
1136 mbedtls_free( data );
1137 return( status );
1138}
1139#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1140
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001141
1142
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001143/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01001144/* Message digests */
1145/****************************************************************/
1146
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001147static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01001148{
1149 switch( alg )
1150 {
1151#if defined(MBEDTLS_MD2_C)
1152 case PSA_ALG_MD2:
1153 return( &mbedtls_md2_info );
1154#endif
1155#if defined(MBEDTLS_MD4_C)
1156 case PSA_ALG_MD4:
1157 return( &mbedtls_md4_info );
1158#endif
1159#if defined(MBEDTLS_MD5_C)
1160 case PSA_ALG_MD5:
1161 return( &mbedtls_md5_info );
1162#endif
1163#if defined(MBEDTLS_RIPEMD160_C)
1164 case PSA_ALG_RIPEMD160:
1165 return( &mbedtls_ripemd160_info );
1166#endif
1167#if defined(MBEDTLS_SHA1_C)
1168 case PSA_ALG_SHA_1:
1169 return( &mbedtls_sha1_info );
1170#endif
1171#if defined(MBEDTLS_SHA256_C)
1172 case PSA_ALG_SHA_224:
1173 return( &mbedtls_sha224_info );
1174 case PSA_ALG_SHA_256:
1175 return( &mbedtls_sha256_info );
1176#endif
1177#if defined(MBEDTLS_SHA512_C)
1178 case PSA_ALG_SHA_384:
1179 return( &mbedtls_sha384_info );
1180 case PSA_ALG_SHA_512:
1181 return( &mbedtls_sha512_info );
1182#endif
1183 default:
1184 return( NULL );
1185 }
1186}
1187
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001188psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
1189{
1190 switch( operation->alg )
1191 {
Gilles Peskine81736312018-06-26 15:04:31 +02001192 case 0:
1193 /* The object has (apparently) been initialized but it is not
1194 * in use. It's ok to call abort on such an object, and there's
1195 * nothing to do. */
1196 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001197#if defined(MBEDTLS_MD2_C)
1198 case PSA_ALG_MD2:
1199 mbedtls_md2_free( &operation->ctx.md2 );
1200 break;
1201#endif
1202#if defined(MBEDTLS_MD4_C)
1203 case PSA_ALG_MD4:
1204 mbedtls_md4_free( &operation->ctx.md4 );
1205 break;
1206#endif
1207#if defined(MBEDTLS_MD5_C)
1208 case PSA_ALG_MD5:
1209 mbedtls_md5_free( &operation->ctx.md5 );
1210 break;
1211#endif
1212#if defined(MBEDTLS_RIPEMD160_C)
1213 case PSA_ALG_RIPEMD160:
1214 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
1215 break;
1216#endif
1217#if defined(MBEDTLS_SHA1_C)
1218 case PSA_ALG_SHA_1:
1219 mbedtls_sha1_free( &operation->ctx.sha1 );
1220 break;
1221#endif
1222#if defined(MBEDTLS_SHA256_C)
1223 case PSA_ALG_SHA_224:
1224 case PSA_ALG_SHA_256:
1225 mbedtls_sha256_free( &operation->ctx.sha256 );
1226 break;
1227#endif
1228#if defined(MBEDTLS_SHA512_C)
1229 case PSA_ALG_SHA_384:
1230 case PSA_ALG_SHA_512:
1231 mbedtls_sha512_free( &operation->ctx.sha512 );
1232 break;
1233#endif
1234 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001235 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001236 }
1237 operation->alg = 0;
1238 return( PSA_SUCCESS );
1239}
1240
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02001241psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001242 psa_algorithm_t alg )
1243{
1244 int ret;
1245 operation->alg = 0;
1246 switch( alg )
1247 {
1248#if defined(MBEDTLS_MD2_C)
1249 case PSA_ALG_MD2:
1250 mbedtls_md2_init( &operation->ctx.md2 );
1251 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
1252 break;
1253#endif
1254#if defined(MBEDTLS_MD4_C)
1255 case PSA_ALG_MD4:
1256 mbedtls_md4_init( &operation->ctx.md4 );
1257 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
1258 break;
1259#endif
1260#if defined(MBEDTLS_MD5_C)
1261 case PSA_ALG_MD5:
1262 mbedtls_md5_init( &operation->ctx.md5 );
1263 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
1264 break;
1265#endif
1266#if defined(MBEDTLS_RIPEMD160_C)
1267 case PSA_ALG_RIPEMD160:
1268 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
1269 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
1270 break;
1271#endif
1272#if defined(MBEDTLS_SHA1_C)
1273 case PSA_ALG_SHA_1:
1274 mbedtls_sha1_init( &operation->ctx.sha1 );
1275 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
1276 break;
1277#endif
1278#if defined(MBEDTLS_SHA256_C)
1279 case PSA_ALG_SHA_224:
1280 mbedtls_sha256_init( &operation->ctx.sha256 );
1281 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
1282 break;
1283 case PSA_ALG_SHA_256:
1284 mbedtls_sha256_init( &operation->ctx.sha256 );
1285 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
1286 break;
1287#endif
1288#if defined(MBEDTLS_SHA512_C)
1289 case PSA_ALG_SHA_384:
1290 mbedtls_sha512_init( &operation->ctx.sha512 );
1291 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
1292 break;
1293 case PSA_ALG_SHA_512:
1294 mbedtls_sha512_init( &operation->ctx.sha512 );
1295 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1296 break;
1297#endif
1298 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001299 return( PSA_ALG_IS_HASH( alg ) ?
1300 PSA_ERROR_NOT_SUPPORTED :
1301 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001302 }
1303 if( ret == 0 )
1304 operation->alg = alg;
1305 else
1306 psa_hash_abort( operation );
1307 return( mbedtls_to_psa_error( ret ) );
1308}
1309
1310psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1311 const uint8_t *input,
1312 size_t input_length )
1313{
1314 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001315
1316 /* Don't require hash implementations to behave correctly on a
1317 * zero-length input, which may have an invalid pointer. */
1318 if( input_length == 0 )
1319 return( PSA_SUCCESS );
1320
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001321 switch( operation->alg )
1322 {
1323#if defined(MBEDTLS_MD2_C)
1324 case PSA_ALG_MD2:
1325 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1326 input, input_length );
1327 break;
1328#endif
1329#if defined(MBEDTLS_MD4_C)
1330 case PSA_ALG_MD4:
1331 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1332 input, input_length );
1333 break;
1334#endif
1335#if defined(MBEDTLS_MD5_C)
1336 case PSA_ALG_MD5:
1337 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1338 input, input_length );
1339 break;
1340#endif
1341#if defined(MBEDTLS_RIPEMD160_C)
1342 case PSA_ALG_RIPEMD160:
1343 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1344 input, input_length );
1345 break;
1346#endif
1347#if defined(MBEDTLS_SHA1_C)
1348 case PSA_ALG_SHA_1:
1349 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1350 input, input_length );
1351 break;
1352#endif
1353#if defined(MBEDTLS_SHA256_C)
1354 case PSA_ALG_SHA_224:
1355 case PSA_ALG_SHA_256:
1356 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1357 input, input_length );
1358 break;
1359#endif
1360#if defined(MBEDTLS_SHA512_C)
1361 case PSA_ALG_SHA_384:
1362 case PSA_ALG_SHA_512:
1363 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1364 input, input_length );
1365 break;
1366#endif
1367 default:
1368 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1369 break;
1370 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001371
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001372 if( ret != 0 )
1373 psa_hash_abort( operation );
1374 return( mbedtls_to_psa_error( ret ) );
1375}
1376
1377psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1378 uint8_t *hash,
1379 size_t hash_size,
1380 size_t *hash_length )
1381{
itayzafrir40835d42018-08-02 13:14:17 +03001382 psa_status_t status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001383 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001384 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001385
1386 /* Fill the output buffer with something that isn't a valid hash
1387 * (barring an attack on the hash and deliberately-crafted input),
1388 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001389 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001390 /* If hash_size is 0 then hash may be NULL and then the
1391 * call to memset would have undefined behavior. */
1392 if( hash_size != 0 )
1393 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001394
1395 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03001396 {
1397 status = PSA_ERROR_BUFFER_TOO_SMALL;
1398 goto exit;
1399 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001400
1401 switch( operation->alg )
1402 {
1403#if defined(MBEDTLS_MD2_C)
1404 case PSA_ALG_MD2:
1405 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1406 break;
1407#endif
1408#if defined(MBEDTLS_MD4_C)
1409 case PSA_ALG_MD4:
1410 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1411 break;
1412#endif
1413#if defined(MBEDTLS_MD5_C)
1414 case PSA_ALG_MD5:
1415 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1416 break;
1417#endif
1418#if defined(MBEDTLS_RIPEMD160_C)
1419 case PSA_ALG_RIPEMD160:
1420 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1421 break;
1422#endif
1423#if defined(MBEDTLS_SHA1_C)
1424 case PSA_ALG_SHA_1:
1425 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1426 break;
1427#endif
1428#if defined(MBEDTLS_SHA256_C)
1429 case PSA_ALG_SHA_224:
1430 case PSA_ALG_SHA_256:
1431 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1432 break;
1433#endif
1434#if defined(MBEDTLS_SHA512_C)
1435 case PSA_ALG_SHA_384:
1436 case PSA_ALG_SHA_512:
1437 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1438 break;
1439#endif
1440 default:
1441 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1442 break;
1443 }
itayzafrir40835d42018-08-02 13:14:17 +03001444 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001445
itayzafrir40835d42018-08-02 13:14:17 +03001446exit:
1447 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001448 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001449 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001450 return( psa_hash_abort( operation ) );
1451 }
1452 else
1453 {
1454 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03001455 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001456 }
1457}
1458
Gilles Peskine2d277862018-06-18 15:41:12 +02001459psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1460 const uint8_t *hash,
1461 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001462{
1463 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1464 size_t actual_hash_length;
1465 psa_status_t status = psa_hash_finish( operation,
1466 actual_hash, sizeof( actual_hash ),
1467 &actual_hash_length );
1468 if( status != PSA_SUCCESS )
1469 return( status );
1470 if( actual_hash_length != hash_length )
1471 return( PSA_ERROR_INVALID_SIGNATURE );
1472 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1473 return( PSA_ERROR_INVALID_SIGNATURE );
1474 return( PSA_SUCCESS );
1475}
1476
1477
1478
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001479/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001480/* MAC */
1481/****************************************************************/
1482
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001483static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001484 psa_algorithm_t alg,
1485 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001486 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001487 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001488{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001489 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001490 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001491
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001492 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001493 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001494
Gilles Peskine8c9def32018-02-08 10:02:12 +01001495 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1496 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001497 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001498 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001499 case PSA_ALG_ARC4:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001500 mode = MBEDTLS_MODE_STREAM;
1501 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001502 case PSA_ALG_CTR:
1503 mode = MBEDTLS_MODE_CTR;
1504 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001505 case PSA_ALG_CFB:
1506 mode = MBEDTLS_MODE_CFB;
1507 break;
1508 case PSA_ALG_OFB:
1509 mode = MBEDTLS_MODE_OFB;
1510 break;
1511 case PSA_ALG_CBC_NO_PADDING:
1512 mode = MBEDTLS_MODE_CBC;
1513 break;
1514 case PSA_ALG_CBC_PKCS7:
1515 mode = MBEDTLS_MODE_CBC;
1516 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001517 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001518 mode = MBEDTLS_MODE_CCM;
1519 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001520 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001521 mode = MBEDTLS_MODE_GCM;
1522 break;
1523 default:
1524 return( NULL );
1525 }
1526 }
1527 else if( alg == PSA_ALG_CMAC )
1528 mode = MBEDTLS_MODE_ECB;
1529 else if( alg == PSA_ALG_GMAC )
1530 mode = MBEDTLS_MODE_GCM;
1531 else
1532 return( NULL );
1533
1534 switch( key_type )
1535 {
1536 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001537 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001538 break;
1539 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001540 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1541 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001542 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001543 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001544 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001545 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001546 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1547 * but two-key Triple-DES is functionally three-key Triple-DES
1548 * with K1=K3, so that's how we present it to mbedtls. */
1549 if( key_bits == 128 )
1550 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001551 break;
1552 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001553 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001554 break;
1555 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001556 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001557 break;
1558 default:
1559 return( NULL );
1560 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001561 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001562 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001563
Jaeden Amero23bbb752018-06-26 14:16:54 +01001564 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1565 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001566}
1567
Gilles Peskinea05219c2018-11-16 16:02:56 +01001568#if defined(MBEDTLS_MD_C)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001569static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001570{
Gilles Peskine2d277862018-06-18 15:41:12 +02001571 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001572 {
1573 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001574 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001575 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001576 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001577 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001578 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001579 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001580 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001581 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001582 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001583 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001584 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001585 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001586 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001587 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001588 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001589 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001590 return( 128 );
1591 default:
1592 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001593 }
1594}
Gilles Peskinea05219c2018-11-16 16:02:56 +01001595#endif /* MBEDTLS_MD_C */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001596
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001597/* Initialize the MAC operation structure. Once this function has been
1598 * called, psa_mac_abort can run and will do the right thing. */
1599static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1600 psa_algorithm_t alg )
1601{
1602 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1603
1604 operation->alg = alg;
1605 operation->key_set = 0;
1606 operation->iv_set = 0;
1607 operation->iv_required = 0;
1608 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001609 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001610
1611#if defined(MBEDTLS_CMAC_C)
1612 if( alg == PSA_ALG_CMAC )
1613 {
1614 operation->iv_required = 0;
1615 mbedtls_cipher_init( &operation->ctx.cmac );
1616 status = PSA_SUCCESS;
1617 }
1618 else
1619#endif /* MBEDTLS_CMAC_C */
1620#if defined(MBEDTLS_MD_C)
1621 if( PSA_ALG_IS_HMAC( operation->alg ) )
1622 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02001623 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
1624 operation->ctx.hmac.hash_ctx.alg = 0;
1625 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001626 }
1627 else
1628#endif /* MBEDTLS_MD_C */
1629 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001630 if( ! PSA_ALG_IS_MAC( alg ) )
1631 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001632 }
1633
1634 if( status != PSA_SUCCESS )
1635 memset( operation, 0, sizeof( *operation ) );
1636 return( status );
1637}
1638
Gilles Peskine01126fa2018-07-12 17:04:55 +02001639#if defined(MBEDTLS_MD_C)
1640static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
1641{
1642 mbedtls_zeroize( hmac->opad, sizeof( hmac->opad ) );
1643 return( psa_hash_abort( &hmac->hash_ctx ) );
1644}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01001645
1646static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
1647{
1648 /* Instances of psa_hash_operation_s can be initialized by zeroization. */
1649 memset( hmac, 0, sizeof( *hmac ) );
1650}
Gilles Peskine01126fa2018-07-12 17:04:55 +02001651#endif /* MBEDTLS_MD_C */
1652
Gilles Peskine8c9def32018-02-08 10:02:12 +01001653psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1654{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001655 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001656 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001657 /* The object has (apparently) been initialized but it is not
1658 * in use. It's ok to call abort on such an object, and there's
1659 * nothing to do. */
1660 return( PSA_SUCCESS );
1661 }
1662 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001663#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001664 if( operation->alg == PSA_ALG_CMAC )
1665 {
1666 mbedtls_cipher_free( &operation->ctx.cmac );
1667 }
1668 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001669#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001670#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001671 if( PSA_ALG_IS_HMAC( operation->alg ) )
1672 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001673 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001674 }
1675 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001676#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001677 {
1678 /* Sanity check (shouldn't happen: operation->alg should
1679 * always have been initialized to a valid value). */
1680 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001681 }
Moran Peker41deec42018-04-04 15:43:05 +03001682
Gilles Peskine8c9def32018-02-08 10:02:12 +01001683 operation->alg = 0;
1684 operation->key_set = 0;
1685 operation->iv_set = 0;
1686 operation->iv_required = 0;
1687 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001688 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001689
Gilles Peskine8c9def32018-02-08 10:02:12 +01001690 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001691
1692bad_state:
1693 /* If abort is called on an uninitialized object, we can't trust
1694 * anything. Wipe the object in case it contains confidential data.
1695 * This may result in a memory leak if a pointer gets overwritten,
1696 * but it's too late to do anything about this. */
1697 memset( operation, 0, sizeof( *operation ) );
1698 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001699}
1700
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001701#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02001702static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001703 size_t key_bits,
1704 key_slot_t *slot,
1705 const mbedtls_cipher_info_t *cipher_info )
1706{
1707 int ret;
1708
1709 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001710
1711 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1712 if( ret != 0 )
1713 return( ret );
1714
1715 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1716 slot->data.raw.data,
1717 key_bits );
1718 return( ret );
1719}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001720#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001721
Gilles Peskine248051a2018-06-20 16:09:38 +02001722#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02001723static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
1724 const uint8_t *key,
1725 size_t key_length,
1726 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001727{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001728 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001729 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001730 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001731 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001732 psa_status_t status;
1733
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001734 /* Sanity checks on block_size, to guarantee that there won't be a buffer
1735 * overflow below. This should never trigger if the hash algorithm
1736 * is implemented correctly. */
1737 /* The size checks against the ipad and opad buffers cannot be written
1738 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
1739 * because that triggers -Wlogical-op on GCC 7.3. */
1740 if( block_size > sizeof( ipad ) )
1741 return( PSA_ERROR_NOT_SUPPORTED );
1742 if( block_size > sizeof( hmac->opad ) )
1743 return( PSA_ERROR_NOT_SUPPORTED );
1744 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001745 return( PSA_ERROR_NOT_SUPPORTED );
1746
Gilles Peskined223b522018-06-11 18:12:58 +02001747 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001748 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001749 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001750 if( status != PSA_SUCCESS )
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001751 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001752 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001753 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001754 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001755 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001756 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001757 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001758 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001759 }
Gilles Peskine96889972018-07-12 17:07:03 +02001760 /* A 0-length key is not commonly used in HMAC when used as a MAC,
1761 * but it is permitted. It is common when HMAC is used in HKDF, for
1762 * example. Don't call `memcpy` in the 0-length because `key` could be
1763 * an invalid pointer which would make the behavior undefined. */
1764 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001765 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001766
Gilles Peskined223b522018-06-11 18:12:58 +02001767 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1768 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001769 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001770 ipad[i] ^= 0x36;
1771 memset( ipad + key_length, 0x36, block_size - key_length );
1772
1773 /* Copy the key material from ipad to opad, flipping the requisite bits,
1774 * and filling the rest of opad with the requisite constant. */
1775 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001776 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1777 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001778
Gilles Peskine01126fa2018-07-12 17:04:55 +02001779 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001780 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001781 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001782
Gilles Peskine01126fa2018-07-12 17:04:55 +02001783 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001784
1785cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001786 mbedtls_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001787
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001788 return( status );
1789}
Gilles Peskine248051a2018-06-20 16:09:38 +02001790#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001791
Gilles Peskine89167cb2018-07-08 20:12:23 +02001792static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
1793 psa_key_slot_t key,
1794 psa_algorithm_t alg,
1795 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001796{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001797 psa_status_t status;
1798 key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001799 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001800 psa_key_usage_t usage =
1801 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskined911eb72018-08-14 15:18:45 +02001802 unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02001803 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001804
Gilles Peskined911eb72018-08-14 15:18:45 +02001805 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001806 if( status != PSA_SUCCESS )
1807 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001808 if( is_sign )
1809 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001810
Gilles Peskine89167cb2018-07-08 20:12:23 +02001811 status = psa_get_key_from_slot( key, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001812 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001813 goto exit;
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02001814 key_bits = psa_get_key_bits( slot );
1815
Gilles Peskine8c9def32018-02-08 10:02:12 +01001816#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001817 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001818 {
1819 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02001820 mbedtls_cipher_info_from_psa( full_length_alg,
1821 slot->type, key_bits, NULL );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001822 int ret;
1823 if( cipher_info == NULL )
1824 {
1825 status = PSA_ERROR_NOT_SUPPORTED;
1826 goto exit;
1827 }
1828 operation->mac_size = cipher_info->block_size;
1829 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
1830 status = mbedtls_to_psa_error( ret );
1831 }
1832 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001833#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001834#if defined(MBEDTLS_MD_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001835 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001836 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02001837 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001838 if( hash_alg == 0 )
1839 {
1840 status = PSA_ERROR_NOT_SUPPORTED;
1841 goto exit;
1842 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001843
1844 operation->mac_size = PSA_HASH_SIZE( hash_alg );
1845 /* Sanity check. This shouldn't fail on a valid configuration. */
1846 if( operation->mac_size == 0 ||
1847 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
1848 {
1849 status = PSA_ERROR_NOT_SUPPORTED;
1850 goto exit;
1851 }
1852
Gilles Peskine01126fa2018-07-12 17:04:55 +02001853 if( slot->type != PSA_KEY_TYPE_HMAC )
1854 {
1855 status = PSA_ERROR_INVALID_ARGUMENT;
1856 goto exit;
1857 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001858
Gilles Peskine01126fa2018-07-12 17:04:55 +02001859 status = psa_hmac_setup_internal( &operation->ctx.hmac,
1860 slot->data.raw.data,
1861 slot->data.raw.bytes,
1862 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001863 }
1864 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001865#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001866 {
1867 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001868 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001869
Gilles Peskined911eb72018-08-14 15:18:45 +02001870 if( truncated == 0 )
1871 {
1872 /* The "normal" case: untruncated algorithm. Nothing to do. */
1873 }
1874 else if( truncated < 4 )
1875 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02001876 /* A very short MAC is too short for security since it can be
1877 * brute-forced. Ancient protocols with 32-bit MACs do exist,
1878 * so we make this our minimum, even though 32 bits is still
1879 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02001880 status = PSA_ERROR_NOT_SUPPORTED;
1881 }
1882 else if( truncated > operation->mac_size )
1883 {
1884 /* It's impossible to "truncate" to a larger length. */
1885 status = PSA_ERROR_INVALID_ARGUMENT;
1886 }
1887 else
1888 operation->mac_size = truncated;
1889
Gilles Peskinefbfac682018-07-08 20:51:54 +02001890exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001891 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001892 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001893 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001894 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001895 else
1896 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001897 operation->key_set = 1;
1898 }
1899 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001900}
1901
Gilles Peskine89167cb2018-07-08 20:12:23 +02001902psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
1903 psa_key_slot_t key,
1904 psa_algorithm_t alg )
1905{
1906 return( psa_mac_setup( operation, key, alg, 1 ) );
1907}
1908
1909psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
1910 psa_key_slot_t key,
1911 psa_algorithm_t alg )
1912{
1913 return( psa_mac_setup( operation, key, alg, 0 ) );
1914}
1915
Gilles Peskine8c9def32018-02-08 10:02:12 +01001916psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1917 const uint8_t *input,
1918 size_t input_length )
1919{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001920 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001921 if( ! operation->key_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001922 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001923 if( operation->iv_required && ! operation->iv_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001924 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001925 operation->has_input = 1;
1926
Gilles Peskine8c9def32018-02-08 10:02:12 +01001927#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001928 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001929 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001930 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1931 input, input_length );
1932 status = mbedtls_to_psa_error( ret );
1933 }
1934 else
1935#endif /* MBEDTLS_CMAC_C */
1936#if defined(MBEDTLS_MD_C)
1937 if( PSA_ALG_IS_HMAC( operation->alg ) )
1938 {
1939 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
1940 input_length );
1941 }
1942 else
1943#endif /* MBEDTLS_MD_C */
1944 {
1945 /* This shouldn't happen if `operation` was initialized by
1946 * a setup function. */
1947 status = PSA_ERROR_BAD_STATE;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001948 }
1949
Gilles Peskinefbfac682018-07-08 20:51:54 +02001950cleanup:
1951 if( status != PSA_SUCCESS )
1952 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001953 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001954}
1955
Gilles Peskine01126fa2018-07-12 17:04:55 +02001956#if defined(MBEDTLS_MD_C)
1957static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
1958 uint8_t *mac,
1959 size_t mac_size )
1960{
1961 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
1962 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
1963 size_t hash_size = 0;
1964 size_t block_size = psa_get_hash_block_size( hash_alg );
1965 psa_status_t status;
1966
Gilles Peskine01126fa2018-07-12 17:04:55 +02001967 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1968 if( status != PSA_SUCCESS )
1969 return( status );
1970 /* From here on, tmp needs to be wiped. */
1971
1972 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
1973 if( status != PSA_SUCCESS )
1974 goto exit;
1975
1976 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
1977 if( status != PSA_SUCCESS )
1978 goto exit;
1979
1980 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
1981 if( status != PSA_SUCCESS )
1982 goto exit;
1983
Gilles Peskined911eb72018-08-14 15:18:45 +02001984 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1985 if( status != PSA_SUCCESS )
1986 goto exit;
1987
1988 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001989
1990exit:
1991 mbedtls_zeroize( tmp, hash_size );
1992 return( status );
1993}
1994#endif /* MBEDTLS_MD_C */
1995
mohammad16036df908f2018-04-02 08:34:15 -07001996static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001997 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001998 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001999{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02002000 if( ! operation->key_set )
2001 return( PSA_ERROR_BAD_STATE );
2002 if( operation->iv_required && ! operation->iv_set )
2003 return( PSA_ERROR_BAD_STATE );
2004
Gilles Peskine8c9def32018-02-08 10:02:12 +01002005 if( mac_size < operation->mac_size )
2006 return( PSA_ERROR_BUFFER_TOO_SMALL );
2007
Gilles Peskine8c9def32018-02-08 10:02:12 +01002008#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002009 if( operation->alg == PSA_ALG_CMAC )
2010 {
Gilles Peskined911eb72018-08-14 15:18:45 +02002011 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
2012 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
2013 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02002014 memcpy( mac, tmp, operation->mac_size );
Gilles Peskined911eb72018-08-14 15:18:45 +02002015 mbedtls_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002016 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002017 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02002018 else
2019#endif /* MBEDTLS_CMAC_C */
2020#if defined(MBEDTLS_MD_C)
2021 if( PSA_ALG_IS_HMAC( operation->alg ) )
2022 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002023 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02002024 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002025 }
2026 else
2027#endif /* MBEDTLS_MD_C */
2028 {
2029 /* This shouldn't happen if `operation` was initialized by
2030 * a setup function. */
2031 return( PSA_ERROR_BAD_STATE );
2032 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01002033}
2034
Gilles Peskineacd4be32018-07-08 19:56:25 +02002035psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
2036 uint8_t *mac,
2037 size_t mac_size,
2038 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07002039{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002040 psa_status_t status;
2041
2042 /* Fill the output buffer with something that isn't a valid mac
2043 * (barring an attack on the mac and deliberately-crafted input),
2044 * in case the caller doesn't check the return status properly. */
2045 *mac_length = mac_size;
2046 /* If mac_size is 0 then mac may be NULL and then the
2047 * call to memset would have undefined behavior. */
2048 if( mac_size != 0 )
2049 memset( mac, '!', mac_size );
2050
Gilles Peskine89167cb2018-07-08 20:12:23 +02002051 if( ! operation->is_sign )
2052 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002053 status = PSA_ERROR_BAD_STATE;
2054 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002055 }
mohammad16036df908f2018-04-02 08:34:15 -07002056
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002057 status = psa_mac_finish_internal( operation, mac, mac_size );
2058
2059cleanup:
2060 if( status == PSA_SUCCESS )
2061 {
2062 status = psa_mac_abort( operation );
2063 if( status == PSA_SUCCESS )
2064 *mac_length = operation->mac_size;
2065 else
2066 memset( mac, '!', mac_size );
2067 }
2068 else
2069 psa_mac_abort( operation );
2070 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07002071}
2072
Gilles Peskineacd4be32018-07-08 19:56:25 +02002073psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
2074 const uint8_t *mac,
2075 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002076{
Gilles Peskine828ed142018-06-18 23:25:51 +02002077 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07002078 psa_status_t status;
2079
Gilles Peskine89167cb2018-07-08 20:12:23 +02002080 if( operation->is_sign )
2081 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002082 status = PSA_ERROR_BAD_STATE;
2083 goto cleanup;
2084 }
2085 if( operation->mac_size != mac_length )
2086 {
2087 status = PSA_ERROR_INVALID_SIGNATURE;
2088 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002089 }
mohammad16036df908f2018-04-02 08:34:15 -07002090
2091 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002092 actual_mac, sizeof( actual_mac ) );
2093
2094 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
2095 status = PSA_ERROR_INVALID_SIGNATURE;
2096
2097cleanup:
2098 if( status == PSA_SUCCESS )
2099 status = psa_mac_abort( operation );
2100 else
2101 psa_mac_abort( operation );
2102
Gilles Peskine99b7d6b2018-08-21 14:56:19 +02002103 mbedtls_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02002104
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002105 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002106}
2107
2108
Gilles Peskine20035e32018-02-03 22:44:14 +01002109
Gilles Peskine20035e32018-02-03 22:44:14 +01002110/****************************************************************/
2111/* Asymmetric cryptography */
2112/****************************************************************/
2113
Gilles Peskine2b450e32018-06-27 15:42:46 +02002114#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002115/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002116 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002117static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
2118 size_t hash_length,
2119 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002120{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02002121 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002122 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002123 *md_alg = mbedtls_md_get_type( md_info );
2124
2125 /* The Mbed TLS RSA module uses an unsigned int for hash length
2126 * parameters. Validate that it fits so that we don't risk an
2127 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002128#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002129 if( hash_length > UINT_MAX )
2130 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002131#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002132
2133#if defined(MBEDTLS_PKCS1_V15)
2134 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
2135 * must be correct. */
2136 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
2137 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002138 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002139 if( md_info == NULL )
2140 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002141 if( mbedtls_md_get_size( md_info ) != hash_length )
2142 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002143 }
2144#endif /* MBEDTLS_PKCS1_V15 */
2145
2146#if defined(MBEDTLS_PKCS1_V21)
2147 /* PSS requires a hash internally. */
2148 if( PSA_ALG_IS_RSA_PSS( alg ) )
2149 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002150 if( md_info == NULL )
2151 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002152 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002153#endif /* MBEDTLS_PKCS1_V21 */
2154
Gilles Peskine61b91d42018-06-08 16:09:36 +02002155 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002156}
2157
Gilles Peskine2b450e32018-06-27 15:42:46 +02002158static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
2159 psa_algorithm_t alg,
2160 const uint8_t *hash,
2161 size_t hash_length,
2162 uint8_t *signature,
2163 size_t signature_size,
2164 size_t *signature_length )
2165{
2166 psa_status_t status;
2167 int ret;
2168 mbedtls_md_type_t md_alg;
2169
2170 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2171 if( status != PSA_SUCCESS )
2172 return( status );
2173
Gilles Peskine630a18a2018-06-29 17:49:35 +02002174 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002175 return( PSA_ERROR_BUFFER_TOO_SMALL );
2176
2177#if defined(MBEDTLS_PKCS1_V15)
2178 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2179 {
2180 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2181 MBEDTLS_MD_NONE );
2182 ret = mbedtls_rsa_pkcs1_sign( rsa,
2183 mbedtls_ctr_drbg_random,
2184 &global_data.ctr_drbg,
2185 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002186 md_alg,
2187 (unsigned int) hash_length,
2188 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002189 signature );
2190 }
2191 else
2192#endif /* MBEDTLS_PKCS1_V15 */
2193#if defined(MBEDTLS_PKCS1_V21)
2194 if( PSA_ALG_IS_RSA_PSS( alg ) )
2195 {
2196 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2197 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
2198 mbedtls_ctr_drbg_random,
2199 &global_data.ctr_drbg,
2200 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002201 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002202 (unsigned int) hash_length,
2203 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002204 signature );
2205 }
2206 else
2207#endif /* MBEDTLS_PKCS1_V21 */
2208 {
2209 return( PSA_ERROR_INVALID_ARGUMENT );
2210 }
2211
2212 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002213 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002214 return( mbedtls_to_psa_error( ret ) );
2215}
2216
2217static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
2218 psa_algorithm_t alg,
2219 const uint8_t *hash,
2220 size_t hash_length,
2221 const uint8_t *signature,
2222 size_t signature_length )
2223{
2224 psa_status_t status;
2225 int ret;
2226 mbedtls_md_type_t md_alg;
2227
2228 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2229 if( status != PSA_SUCCESS )
2230 return( status );
2231
Gilles Peskine630a18a2018-06-29 17:49:35 +02002232 if( signature_length < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002233 return( PSA_ERROR_BUFFER_TOO_SMALL );
2234
2235#if defined(MBEDTLS_PKCS1_V15)
2236 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2237 {
2238 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2239 MBEDTLS_MD_NONE );
2240 ret = mbedtls_rsa_pkcs1_verify( rsa,
2241 mbedtls_ctr_drbg_random,
2242 &global_data.ctr_drbg,
2243 MBEDTLS_RSA_PUBLIC,
2244 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002245 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002246 hash,
2247 signature );
2248 }
2249 else
2250#endif /* MBEDTLS_PKCS1_V15 */
2251#if defined(MBEDTLS_PKCS1_V21)
2252 if( PSA_ALG_IS_RSA_PSS( alg ) )
2253 {
2254 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2255 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
2256 mbedtls_ctr_drbg_random,
2257 &global_data.ctr_drbg,
2258 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002259 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002260 (unsigned int) hash_length,
2261 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002262 signature );
2263 }
2264 else
2265#endif /* MBEDTLS_PKCS1_V21 */
2266 {
2267 return( PSA_ERROR_INVALID_ARGUMENT );
2268 }
Gilles Peskineef12c632018-09-13 20:37:48 +02002269
2270 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
2271 * the rest of the signature is invalid". This has little use in
2272 * practice and PSA doesn't report this distinction. */
2273 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
2274 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002275 return( mbedtls_to_psa_error( ret ) );
2276}
2277#endif /* MBEDTLS_RSA_C */
2278
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002279#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002280/* `ecp` cannot be const because `ecp->grp` needs to be non-const
2281 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
2282 * (even though these functions don't modify it). */
2283static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
2284 psa_algorithm_t alg,
2285 const uint8_t *hash,
2286 size_t hash_length,
2287 uint8_t *signature,
2288 size_t signature_size,
2289 size_t *signature_length )
2290{
2291 int ret;
2292 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002293 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002294 mbedtls_mpi_init( &r );
2295 mbedtls_mpi_init( &s );
2296
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002297 if( signature_size < 2 * curve_bytes )
2298 {
2299 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
2300 goto cleanup;
2301 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002302
Gilles Peskinea05219c2018-11-16 16:02:56 +01002303#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002304 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
2305 {
2306 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
2307 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2308 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2309 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
2310 hash, hash_length,
2311 md_alg ) );
2312 }
2313 else
Gilles Peskinea05219c2018-11-16 16:02:56 +01002314#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002315 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01002316 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002317 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
2318 hash, hash_length,
2319 mbedtls_ctr_drbg_random,
2320 &global_data.ctr_drbg ) );
2321 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002322
2323 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
2324 signature,
2325 curve_bytes ) );
2326 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
2327 signature + curve_bytes,
2328 curve_bytes ) );
2329
2330cleanup:
2331 mbedtls_mpi_free( &r );
2332 mbedtls_mpi_free( &s );
2333 if( ret == 0 )
2334 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002335 return( mbedtls_to_psa_error( ret ) );
2336}
2337
2338static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
2339 const uint8_t *hash,
2340 size_t hash_length,
2341 const uint8_t *signature,
2342 size_t signature_length )
2343{
2344 int ret;
2345 mbedtls_mpi r, s;
2346 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
2347 mbedtls_mpi_init( &r );
2348 mbedtls_mpi_init( &s );
2349
2350 if( signature_length != 2 * curve_bytes )
2351 return( PSA_ERROR_INVALID_SIGNATURE );
2352
2353 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2354 signature,
2355 curve_bytes ) );
2356 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2357 signature + curve_bytes,
2358 curve_bytes ) );
2359
2360 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2361 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002362
2363cleanup:
2364 mbedtls_mpi_free( &r );
2365 mbedtls_mpi_free( &s );
2366 return( mbedtls_to_psa_error( ret ) );
2367}
2368#endif /* MBEDTLS_ECDSA_C */
2369
Gilles Peskine61b91d42018-06-08 16:09:36 +02002370psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
2371 psa_algorithm_t alg,
2372 const uint8_t *hash,
2373 size_t hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002374 uint8_t *signature,
2375 size_t signature_size,
2376 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002377{
2378 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002379 psa_status_t status;
2380
2381 *signature_length = signature_size;
2382
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002383 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_SIGN, alg );
2384 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002385 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002386 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002387 {
2388 status = PSA_ERROR_INVALID_ARGUMENT;
2389 goto exit;
2390 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002391
Gilles Peskine20035e32018-02-03 22:44:14 +01002392#if defined(MBEDTLS_RSA_C)
2393 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2394 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002395 status = psa_rsa_sign( slot->data.rsa,
2396 alg,
2397 hash, hash_length,
2398 signature, signature_size,
2399 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002400 }
2401 else
2402#endif /* defined(MBEDTLS_RSA_C) */
2403#if defined(MBEDTLS_ECP_C)
2404 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2405 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002406#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea05219c2018-11-16 16:02:56 +01002407 if(
2408#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
2409 PSA_ALG_IS_ECDSA( alg )
2410#else
2411 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
2412#endif
2413 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002414 status = psa_ecdsa_sign( slot->data.ecp,
2415 alg,
2416 hash, hash_length,
2417 signature, signature_size,
2418 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002419 else
2420#endif /* defined(MBEDTLS_ECDSA_C) */
2421 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002422 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002423 }
itayzafrir5c753392018-05-08 11:18:38 +03002424 }
2425 else
2426#endif /* defined(MBEDTLS_ECP_C) */
2427 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002428 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002429 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002430
2431exit:
2432 /* Fill the unused part of the output buffer (the whole buffer on error,
2433 * the trailing part on success) with something that isn't a valid mac
2434 * (barring an attack on the mac and deliberately-crafted input),
2435 * in case the caller doesn't check the return status properly. */
2436 if( status == PSA_SUCCESS )
2437 memset( signature + *signature_length, '!',
2438 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002439 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002440 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002441 /* If signature_size is 0 then we have nothing to do. We must not call
2442 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002443 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002444}
2445
2446psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
2447 psa_algorithm_t alg,
2448 const uint8_t *hash,
2449 size_t hash_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002450 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002451 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002452{
2453 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002454 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002455
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002456 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_VERIFY, alg );
2457 if( status != PSA_SUCCESS )
2458 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002459
Gilles Peskine61b91d42018-06-08 16:09:36 +02002460#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002461 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002462 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002463 return( psa_rsa_verify( slot->data.rsa,
2464 alg,
2465 hash, hash_length,
2466 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002467 }
2468 else
2469#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002470#if defined(MBEDTLS_ECP_C)
2471 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2472 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002473#if defined(MBEDTLS_ECDSA_C)
2474 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002475 return( psa_ecdsa_verify( slot->data.ecp,
2476 hash, hash_length,
2477 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002478 else
2479#endif /* defined(MBEDTLS_ECDSA_C) */
2480 {
2481 return( PSA_ERROR_INVALID_ARGUMENT );
2482 }
itayzafrir5c753392018-05-08 11:18:38 +03002483 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002484 else
2485#endif /* defined(MBEDTLS_ECP_C) */
2486 {
2487 return( PSA_ERROR_NOT_SUPPORTED );
2488 }
2489}
2490
Gilles Peskine072ac562018-06-30 00:21:29 +02002491#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
2492static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
2493 mbedtls_rsa_context *rsa )
2494{
2495 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
2496 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2497 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2498 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2499}
2500#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
2501
Gilles Peskine61b91d42018-06-08 16:09:36 +02002502psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
2503 psa_algorithm_t alg,
2504 const uint8_t *input,
2505 size_t input_length,
2506 const uint8_t *salt,
2507 size_t salt_length,
2508 uint8_t *output,
2509 size_t output_size,
2510 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002511{
2512 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002513 psa_status_t status;
2514
Darryl Green5cc689a2018-07-24 15:34:10 +01002515 (void) input;
2516 (void) input_length;
2517 (void) salt;
2518 (void) output;
2519 (void) output_size;
2520
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002521 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002522
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002523 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2524 return( PSA_ERROR_INVALID_ARGUMENT );
2525
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002526 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
2527 if( status != PSA_SUCCESS )
2528 return( status );
Gilles Peskine35da9a22018-06-29 19:17:49 +02002529 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
2530 PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002531 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002532
2533#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002534 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002535 {
2536 mbedtls_rsa_context *rsa = slot->data.rsa;
2537 int ret;
Gilles Peskine630a18a2018-06-29 17:49:35 +02002538 if( output_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002539 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002540#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002541 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002542 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002543 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2544 mbedtls_ctr_drbg_random,
2545 &global_data.ctr_drbg,
2546 MBEDTLS_RSA_PUBLIC,
2547 input_length,
2548 input,
2549 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002550 }
2551 else
2552#endif /* MBEDTLS_PKCS1_V15 */
2553#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002554 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002555 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002556 psa_rsa_oaep_set_padding_mode( alg, rsa );
2557 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
2558 mbedtls_ctr_drbg_random,
2559 &global_data.ctr_drbg,
2560 MBEDTLS_RSA_PUBLIC,
2561 salt, salt_length,
2562 input_length,
2563 input,
2564 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002565 }
2566 else
2567#endif /* MBEDTLS_PKCS1_V21 */
2568 {
2569 return( PSA_ERROR_INVALID_ARGUMENT );
2570 }
2571 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002572 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002573 return( mbedtls_to_psa_error( ret ) );
2574 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002575 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002576#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002577 {
2578 return( PSA_ERROR_NOT_SUPPORTED );
2579 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002580}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002581
Gilles Peskine61b91d42018-06-08 16:09:36 +02002582psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2583 psa_algorithm_t alg,
2584 const uint8_t *input,
2585 size_t input_length,
2586 const uint8_t *salt,
2587 size_t salt_length,
2588 uint8_t *output,
2589 size_t output_size,
2590 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002591{
2592 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002593 psa_status_t status;
2594
Darryl Green5cc689a2018-07-24 15:34:10 +01002595 (void) input;
2596 (void) input_length;
2597 (void) salt;
2598 (void) output;
2599 (void) output_size;
2600
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002601 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002602
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002603 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2604 return( PSA_ERROR_INVALID_ARGUMENT );
2605
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002606 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
2607 if( status != PSA_SUCCESS )
2608 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002609 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2610 return( PSA_ERROR_INVALID_ARGUMENT );
2611
2612#if defined(MBEDTLS_RSA_C)
2613 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2614 {
2615 mbedtls_rsa_context *rsa = slot->data.rsa;
2616 int ret;
2617
Gilles Peskine630a18a2018-06-29 17:49:35 +02002618 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002619 return( PSA_ERROR_INVALID_ARGUMENT );
2620
2621#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002622 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002623 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002624 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2625 mbedtls_ctr_drbg_random,
2626 &global_data.ctr_drbg,
2627 MBEDTLS_RSA_PRIVATE,
2628 output_length,
2629 input,
2630 output,
2631 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002632 }
2633 else
2634#endif /* MBEDTLS_PKCS1_V15 */
2635#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002636 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002637 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002638 psa_rsa_oaep_set_padding_mode( alg, rsa );
2639 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
2640 mbedtls_ctr_drbg_random,
2641 &global_data.ctr_drbg,
2642 MBEDTLS_RSA_PRIVATE,
2643 salt, salt_length,
2644 output_length,
2645 input,
2646 output,
2647 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002648 }
2649 else
2650#endif /* MBEDTLS_PKCS1_V21 */
2651 {
2652 return( PSA_ERROR_INVALID_ARGUMENT );
2653 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002654
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002655 return( mbedtls_to_psa_error( ret ) );
2656 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002657 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002658#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002659 {
2660 return( PSA_ERROR_NOT_SUPPORTED );
2661 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002662}
Gilles Peskine20035e32018-02-03 22:44:14 +01002663
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002664
2665
mohammad1603503973b2018-03-12 15:59:30 +02002666/****************************************************************/
2667/* Symmetric cryptography */
2668/****************************************************************/
2669
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002670/* Initialize the cipher operation structure. Once this function has been
2671 * called, psa_cipher_abort can run and will do the right thing. */
2672static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2673 psa_algorithm_t alg )
2674{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002675 if( ! PSA_ALG_IS_CIPHER( alg ) )
2676 {
2677 memset( operation, 0, sizeof( *operation ) );
2678 return( PSA_ERROR_INVALID_ARGUMENT );
2679 }
2680
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002681 operation->alg = alg;
2682 operation->key_set = 0;
2683 operation->iv_set = 0;
2684 operation->iv_required = 1;
2685 operation->iv_size = 0;
2686 operation->block_size = 0;
2687 mbedtls_cipher_init( &operation->ctx.cipher );
2688 return( PSA_SUCCESS );
2689}
2690
Gilles Peskinee553c652018-06-04 16:22:46 +02002691static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2692 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002693 psa_algorithm_t alg,
2694 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002695{
2696 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2697 psa_status_t status;
2698 key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02002699 size_t key_bits;
2700 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002701 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
2702 PSA_KEY_USAGE_ENCRYPT :
2703 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02002704
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002705 status = psa_cipher_init( operation, alg );
2706 if( status != PSA_SUCCESS )
2707 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002708
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002709 status = psa_get_key_from_slot( key, &slot, usage, alg);
2710 if( status != PSA_SUCCESS )
2711 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002712 key_bits = psa_get_key_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02002713
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002714 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002715 if( cipher_info == NULL )
2716 return( PSA_ERROR_NOT_SUPPORTED );
2717
mohammad1603503973b2018-03-12 15:59:30 +02002718 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002719 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002720 {
2721 psa_cipher_abort( operation );
2722 return( mbedtls_to_psa_error( ret ) );
2723 }
2724
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002725#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002726 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002727 {
2728 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2729 unsigned char keys[24];
2730 memcpy( keys, slot->data.raw.data, 16 );
2731 memcpy( keys + 16, slot->data.raw.data, 8 );
2732 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2733 keys,
2734 192, cipher_operation );
2735 }
2736 else
2737#endif
2738 {
2739 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2740 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002741 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002742 }
Moran Peker41deec42018-04-04 15:43:05 +03002743 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002744 {
2745 psa_cipher_abort( operation );
2746 return( mbedtls_to_psa_error( ret ) );
2747 }
2748
mohammad16038481e742018-03-18 13:57:31 +02002749#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002750 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02002751 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002752 case PSA_ALG_CBC_NO_PADDING:
2753 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2754 MBEDTLS_PADDING_NONE );
2755 break;
2756 case PSA_ALG_CBC_PKCS7:
2757 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2758 MBEDTLS_PADDING_PKCS7 );
2759 break;
2760 default:
2761 /* The algorithm doesn't involve padding. */
2762 ret = 0;
2763 break;
2764 }
2765 if( ret != 0 )
2766 {
2767 psa_cipher_abort( operation );
2768 return( mbedtls_to_psa_error( ret ) );
mohammad16038481e742018-03-18 13:57:31 +02002769 }
2770#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2771
mohammad1603503973b2018-03-12 15:59:30 +02002772 operation->key_set = 1;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002773 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
2774 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
2775 if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
mohammad16038481e742018-03-18 13:57:31 +02002776 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002777 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02002778 }
mohammad1603503973b2018-03-12 15:59:30 +02002779
Moran Peker395db872018-05-31 14:07:14 +03002780 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002781}
2782
Gilles Peskinefe119512018-07-08 21:39:34 +02002783psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
2784 psa_key_slot_t key,
2785 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002786{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002787 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002788}
2789
Gilles Peskinefe119512018-07-08 21:39:34 +02002790psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
2791 psa_key_slot_t key,
2792 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002793{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002794 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002795}
2796
Gilles Peskinefe119512018-07-08 21:39:34 +02002797psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
2798 unsigned char *iv,
2799 size_t iv_size,
2800 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002801{
itayzafrir534bd7c2018-08-02 13:56:32 +03002802 psa_status_t status;
2803 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002804 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002805 {
2806 status = PSA_ERROR_BAD_STATE;
2807 goto exit;
2808 }
Moran Peker41deec42018-04-04 15:43:05 +03002809 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002810 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002811 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03002812 goto exit;
2813 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002814 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2815 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002816 if( ret != 0 )
2817 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002818 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002819 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002820 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002821
mohammad16038481e742018-03-18 13:57:31 +02002822 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03002823 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002824
Moran Peker395db872018-05-31 14:07:14 +03002825exit:
itayzafrir534bd7c2018-08-02 13:56:32 +03002826 if( status != PSA_SUCCESS )
Moran Peker395db872018-05-31 14:07:14 +03002827 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002828 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002829}
2830
Gilles Peskinefe119512018-07-08 21:39:34 +02002831psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
2832 const unsigned char *iv,
2833 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002834{
itayzafrir534bd7c2018-08-02 13:56:32 +03002835 psa_status_t status;
2836 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002837 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002838 {
2839 status = PSA_ERROR_BAD_STATE;
2840 goto exit;
2841 }
Moran Pekera28258c2018-05-29 16:25:04 +03002842 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002843 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002844 status = PSA_ERROR_INVALID_ARGUMENT;
2845 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03002846 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002847 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
2848 status = mbedtls_to_psa_error( ret );
2849exit:
2850 if( status == PSA_SUCCESS )
2851 operation->iv_set = 1;
2852 else
mohammad1603503973b2018-03-12 15:59:30 +02002853 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002854 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002855}
2856
Gilles Peskinee553c652018-06-04 16:22:46 +02002857psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2858 const uint8_t *input,
2859 size_t input_length,
2860 unsigned char *output,
2861 size_t output_size,
2862 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002863{
itayzafrir534bd7c2018-08-02 13:56:32 +03002864 psa_status_t status;
2865 int ret;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002866 size_t expected_output_size;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002867 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002868 {
2869 /* Take the unprocessed partial block left over from previous
2870 * update calls, if any, plus the input to this call. Remove
2871 * the last partial block, if any. You get the data that will be
2872 * output in this call. */
2873 expected_output_size =
2874 ( operation->ctx.cipher.unprocessed_len + input_length )
2875 / operation->block_size * operation->block_size;
2876 }
2877 else
2878 {
2879 expected_output_size = input_length;
2880 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002881
Gilles Peskine89d789c2018-06-04 17:17:16 +02002882 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03002883 {
2884 status = PSA_ERROR_BUFFER_TOO_SMALL;
2885 goto exit;
2886 }
mohammad160382759612018-03-12 18:16:40 +02002887
mohammad1603503973b2018-03-12 15:59:30 +02002888 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002889 input_length, output, output_length );
itayzafrir534bd7c2018-08-02 13:56:32 +03002890 status = mbedtls_to_psa_error( ret );
2891exit:
2892 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02002893 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002894 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002895}
2896
Gilles Peskinee553c652018-06-04 16:22:46 +02002897psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2898 uint8_t *output,
2899 size_t output_size,
2900 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002901{
Janos Follath315b51c2018-07-09 16:04:51 +01002902 psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
2903 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002904 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002905
mohammad1603503973b2018-03-12 15:59:30 +02002906 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002907 {
Janos Follath315b51c2018-07-09 16:04:51 +01002908 status = PSA_ERROR_BAD_STATE;
2909 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002910 }
2911 if( operation->iv_required && ! operation->iv_set )
2912 {
Janos Follath315b51c2018-07-09 16:04:51 +01002913 status = PSA_ERROR_BAD_STATE;
2914 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002915 }
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002916
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002917 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002918 operation->alg == PSA_ALG_CBC_NO_PADDING &&
2919 operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03002920 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002921 status = PSA_ERROR_INVALID_ARGUMENT;
Janos Follath315b51c2018-07-09 16:04:51 +01002922 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002923 }
2924
Janos Follath315b51c2018-07-09 16:04:51 +01002925 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
2926 temp_output_buffer,
2927 output_length );
2928 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002929 {
Janos Follath315b51c2018-07-09 16:04:51 +01002930 status = mbedtls_to_psa_error( cipher_ret );
2931 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02002932 }
Janos Follath315b51c2018-07-09 16:04:51 +01002933
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002934 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01002935 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002936 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002937 memcpy( output, temp_output_buffer, *output_length );
2938 else
2939 {
Janos Follath315b51c2018-07-09 16:04:51 +01002940 status = PSA_ERROR_BUFFER_TOO_SMALL;
2941 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002942 }
mohammad1603503973b2018-03-12 15:59:30 +02002943
Janos Follath279ab8e2018-07-09 16:13:21 +01002944 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002945 status = psa_cipher_abort( operation );
2946
2947 return( status );
2948
2949error:
2950
2951 *output_length = 0;
2952
Janos Follath279ab8e2018-07-09 16:13:21 +01002953 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002954 (void) psa_cipher_abort( operation );
2955
2956 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002957}
2958
Gilles Peskinee553c652018-06-04 16:22:46 +02002959psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2960{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002961 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002962 {
2963 /* The object has (apparently) been initialized but it is not
2964 * in use. It's ok to call abort on such an object, and there's
2965 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002966 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002967 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002968
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002969 /* Sanity check (shouldn't happen: operation->alg should
2970 * always have been initialized to a valid value). */
2971 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2972 return( PSA_ERROR_BAD_STATE );
2973
mohammad1603503973b2018-03-12 15:59:30 +02002974 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002975
Moran Peker41deec42018-04-04 15:43:05 +03002976 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002977 operation->key_set = 0;
2978 operation->iv_set = 0;
2979 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002980 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002981 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002982
Moran Peker395db872018-05-31 14:07:14 +03002983 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002984}
2985
Gilles Peskinea0655c32018-04-30 17:06:50 +02002986
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002987
mohammad16038cc1cee2018-03-28 01:21:33 +03002988/****************************************************************/
2989/* Key Policy */
2990/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002991
mohammad160327010052018-07-03 13:16:15 +03002992#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02002993void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002994{
Gilles Peskine803ce742018-06-18 16:07:14 +02002995 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002996}
2997
Gilles Peskine2d277862018-06-18 15:41:12 +02002998void psa_key_policy_set_usage( psa_key_policy_t *policy,
2999 psa_key_usage_t usage,
3000 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03003001{
mohammad16034eed7572018-03-28 05:14:59 -07003002 policy->usage = usage;
3003 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03003004}
3005
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003006psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003007{
mohammad16036df908f2018-04-02 08:34:15 -07003008 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03003009}
3010
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003011psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003012{
mohammad16036df908f2018-04-02 08:34:15 -07003013 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03003014}
mohammad160327010052018-07-03 13:16:15 +03003015#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003016
Gilles Peskine2d277862018-06-18 15:41:12 +02003017psa_status_t psa_set_key_policy( psa_key_slot_t key,
3018 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003019{
3020 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003021 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003022
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003023 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003024 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003025
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003026 status = psa_get_empty_key_slot( key, &slot );
3027 if( status != PSA_SUCCESS )
3028 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03003029
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003030 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
3031 PSA_KEY_USAGE_ENCRYPT |
3032 PSA_KEY_USAGE_DECRYPT |
3033 PSA_KEY_USAGE_SIGN |
Gilles Peskineea0fb492018-07-12 17:17:20 +02003034 PSA_KEY_USAGE_VERIFY |
3035 PSA_KEY_USAGE_DERIVE ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07003036 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03003037
mohammad16036df908f2018-04-02 08:34:15 -07003038 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003039
3040 return( PSA_SUCCESS );
3041}
3042
Gilles Peskine2d277862018-06-18 15:41:12 +02003043psa_status_t psa_get_key_policy( psa_key_slot_t key,
3044 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003045{
3046 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003047 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003048
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003049 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003050 return( PSA_ERROR_INVALID_ARGUMENT );
3051
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003052 status = psa_get_key_slot( key, &slot );
3053 if( status != PSA_SUCCESS )
3054 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003055
mohammad16036df908f2018-04-02 08:34:15 -07003056 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003057
3058 return( PSA_SUCCESS );
3059}
Gilles Peskine20035e32018-02-03 22:44:14 +01003060
Gilles Peskinea0655c32018-04-30 17:06:50 +02003061
3062
mohammad1603804cd712018-03-20 22:44:08 +02003063/****************************************************************/
3064/* Key Lifetime */
3065/****************************************************************/
3066
Gilles Peskine2d277862018-06-18 15:41:12 +02003067psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
3068 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003069{
3070 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003071 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003072
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003073 status = psa_get_key_slot( key, &slot );
3074 if( status != PSA_SUCCESS )
3075 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003076
mohammad1603804cd712018-03-20 22:44:08 +02003077 *lifetime = slot->lifetime;
3078
3079 return( PSA_SUCCESS );
3080}
3081
Gilles Peskine2d277862018-06-18 15:41:12 +02003082psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
Jaeden Amero65fb2362018-06-26 13:55:30 +01003083 psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003084{
3085 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003086 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003087
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003088 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
3089 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
Darryl Greend49a4992018-06-18 17:27:26 +01003090 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE )
mohammad1603ba178512018-03-21 04:35:20 -07003091 return( PSA_ERROR_INVALID_ARGUMENT );
3092
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003093 status = psa_get_empty_key_slot( key, &slot );
3094 if( status != PSA_SUCCESS )
3095 return( status );
mohammad1603804cd712018-03-20 22:44:08 +02003096
Darryl Greend49a4992018-06-18 17:27:26 +01003097 if( lifetime == PSA_KEY_LIFETIME_WRITE_ONCE )
mohammad1603ba178512018-03-21 04:35:20 -07003098 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003099
Darryl Greend49a4992018-06-18 17:27:26 +01003100#if !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
3101 if( lifetime == PSA_KEY_LIFETIME_PERSISTENT )
3102 return( PSA_ERROR_NOT_SUPPORTED );
3103#endif
3104
mohammad1603060ad8a2018-03-20 14:28:38 -07003105 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02003106
3107 return( PSA_SUCCESS );
3108}
3109
Gilles Peskine20035e32018-02-03 22:44:14 +01003110
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003111
mohammad16035955c982018-04-26 00:53:03 +03003112/****************************************************************/
3113/* AEAD */
3114/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003115
Gilles Peskineedf9a652018-08-17 18:11:56 +02003116typedef struct
3117{
3118 key_slot_t *slot;
3119 const mbedtls_cipher_info_t *cipher_info;
3120 union
3121 {
3122#if defined(MBEDTLS_CCM_C)
3123 mbedtls_ccm_context ccm;
3124#endif /* MBEDTLS_CCM_C */
3125#if defined(MBEDTLS_GCM_C)
3126 mbedtls_gcm_context gcm;
3127#endif /* MBEDTLS_GCM_C */
3128 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003129 psa_algorithm_t core_alg;
3130 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003131 uint8_t tag_length;
3132} aead_operation_t;
3133
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003134static void psa_aead_abort( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003135{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003136 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003137 {
3138#if defined(MBEDTLS_CCM_C)
3139 case PSA_ALG_CCM:
3140 mbedtls_ccm_free( &operation->ctx.ccm );
3141 break;
3142#endif /* MBEDTLS_CCM_C */
3143#if defined(MBEDTLS_CCM_C)
3144 case PSA_ALG_GCM:
3145 mbedtls_gcm_free( &operation->ctx.gcm );
3146 break;
3147#endif /* MBEDTLS_GCM_C */
3148 }
3149}
3150
3151static psa_status_t psa_aead_setup( aead_operation_t *operation,
3152 psa_key_slot_t key,
3153 psa_key_usage_t usage,
3154 psa_algorithm_t alg )
3155{
3156 psa_status_t status;
3157 size_t key_bits;
3158 mbedtls_cipher_id_t cipher_id;
3159
3160 status = psa_get_key_from_slot( key, &operation->slot, usage, alg );
3161 if( status != PSA_SUCCESS )
3162 return( status );
3163
3164 key_bits = psa_get_key_bits( operation->slot );
3165
3166 operation->cipher_info =
3167 mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
3168 &cipher_id );
3169 if( operation->cipher_info == NULL )
3170 return( PSA_ERROR_NOT_SUPPORTED );
3171
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003172 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003173 {
3174#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003175 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
3176 operation->core_alg = PSA_ALG_CCM;
3177 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003178 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3179 return( PSA_ERROR_INVALID_ARGUMENT );
3180 mbedtls_ccm_init( &operation->ctx.ccm );
3181 status = mbedtls_to_psa_error(
3182 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
3183 operation->slot->data.raw.data,
3184 (unsigned int) key_bits ) );
3185 if( status != 0 )
3186 goto cleanup;
3187 break;
3188#endif /* MBEDTLS_CCM_C */
3189
3190#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003191 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
3192 operation->core_alg = PSA_ALG_GCM;
3193 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003194 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3195 return( PSA_ERROR_INVALID_ARGUMENT );
3196 mbedtls_gcm_init( &operation->ctx.gcm );
3197 status = mbedtls_to_psa_error(
3198 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
3199 operation->slot->data.raw.data,
3200 (unsigned int) key_bits ) );
3201 break;
3202#endif /* MBEDTLS_GCM_C */
3203
3204 default:
3205 return( PSA_ERROR_NOT_SUPPORTED );
3206 }
3207
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003208 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
3209 {
3210 status = PSA_ERROR_INVALID_ARGUMENT;
3211 goto cleanup;
3212 }
3213 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
3214 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
3215 * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
3216 * In both cases, mbedtls_xxx will validate the tag length below. */
3217
Gilles Peskineedf9a652018-08-17 18:11:56 +02003218 return( PSA_SUCCESS );
3219
3220cleanup:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003221 psa_aead_abort( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003222 return( status );
3223}
3224
mohammad16035955c982018-04-26 00:53:03 +03003225psa_status_t psa_aead_encrypt( psa_key_slot_t key,
3226 psa_algorithm_t alg,
3227 const uint8_t *nonce,
3228 size_t nonce_length,
3229 const uint8_t *additional_data,
3230 size_t additional_data_length,
3231 const uint8_t *plaintext,
3232 size_t plaintext_length,
3233 uint8_t *ciphertext,
3234 size_t ciphertext_size,
3235 size_t *ciphertext_length )
3236{
mohammad16035955c982018-04-26 00:53:03 +03003237 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003238 aead_operation_t operation;
mohammad160315223a82018-06-03 17:19:55 +03003239 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02003240
mohammad1603f08a5502018-06-03 15:05:47 +03003241 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07003242
Gilles Peskineedf9a652018-08-17 18:11:56 +02003243 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003244 if( status != PSA_SUCCESS )
3245 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003246
Gilles Peskineedf9a652018-08-17 18:11:56 +02003247 /* For all currently supported modes, the tag is at the end of the
3248 * ciphertext. */
3249 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
3250 {
3251 status = PSA_ERROR_BUFFER_TOO_SMALL;
3252 goto exit;
3253 }
3254 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03003255
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003256 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003257 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003258 status = mbedtls_to_psa_error(
3259 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
3260 MBEDTLS_GCM_ENCRYPT,
3261 plaintext_length,
3262 nonce, nonce_length,
3263 additional_data, additional_data_length,
3264 plaintext, ciphertext,
3265 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03003266 }
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003267 else if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003268 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003269 status = mbedtls_to_psa_error(
3270 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
3271 plaintext_length,
3272 nonce, nonce_length,
3273 additional_data,
3274 additional_data_length,
3275 plaintext, ciphertext,
3276 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003277 }
mohammad16035c8845f2018-05-09 05:40:09 -07003278 else
3279 {
mohammad1603554faad2018-06-03 15:07:38 +03003280 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07003281 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003282
Gilles Peskineedf9a652018-08-17 18:11:56 +02003283 if( status != PSA_SUCCESS && ciphertext_size != 0 )
3284 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003285
Gilles Peskineedf9a652018-08-17 18:11:56 +02003286exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003287 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003288 if( status == PSA_SUCCESS )
3289 *ciphertext_length = plaintext_length + operation.tag_length;
3290 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003291}
3292
Gilles Peskineee652a32018-06-01 19:23:52 +02003293/* Locate the tag in a ciphertext buffer containing the encrypted data
3294 * followed by the tag. Return the length of the part preceding the tag in
3295 * *plaintext_length. This is the size of the plaintext in modes where
3296 * the encrypted data has the same size as the plaintext, such as
3297 * CCM and GCM. */
3298static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
3299 const uint8_t *ciphertext,
3300 size_t ciphertext_length,
3301 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02003302 const uint8_t **p_tag )
3303{
3304 size_t payload_length;
3305 if( tag_length > ciphertext_length )
3306 return( PSA_ERROR_INVALID_ARGUMENT );
3307 payload_length = ciphertext_length - tag_length;
3308 if( payload_length > plaintext_size )
3309 return( PSA_ERROR_BUFFER_TOO_SMALL );
3310 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02003311 return( PSA_SUCCESS );
3312}
3313
mohammad16035955c982018-04-26 00:53:03 +03003314psa_status_t psa_aead_decrypt( psa_key_slot_t key,
3315 psa_algorithm_t alg,
3316 const uint8_t *nonce,
3317 size_t nonce_length,
3318 const uint8_t *additional_data,
3319 size_t additional_data_length,
3320 const uint8_t *ciphertext,
3321 size_t ciphertext_length,
3322 uint8_t *plaintext,
3323 size_t plaintext_size,
3324 size_t *plaintext_length )
3325{
mohammad16035955c982018-04-26 00:53:03 +03003326 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003327 aead_operation_t operation;
3328 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02003329
Gilles Peskineee652a32018-06-01 19:23:52 +02003330 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03003331
Gilles Peskineedf9a652018-08-17 18:11:56 +02003332 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003333 if( status != PSA_SUCCESS )
3334 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003335
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003336 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003337 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003338 status = psa_aead_unpadded_locate_tag( operation.tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003339 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003340 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02003341 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003342 goto exit;
Gilles Peskineee652a32018-06-01 19:23:52 +02003343
Gilles Peskineedf9a652018-08-17 18:11:56 +02003344 status = mbedtls_to_psa_error(
3345 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
3346 ciphertext_length - operation.tag_length,
3347 nonce, nonce_length,
3348 additional_data,
3349 additional_data_length,
3350 tag, operation.tag_length,
3351 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03003352 }
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003353 else if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003354 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003355 status = psa_aead_unpadded_locate_tag( operation.tag_length,
mohammad16039375f842018-06-03 14:28:24 +03003356 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003357 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03003358 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003359 goto exit;
mohammad16039375f842018-06-03 14:28:24 +03003360
Gilles Peskineedf9a652018-08-17 18:11:56 +02003361 status = mbedtls_to_psa_error(
3362 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
3363 ciphertext_length - operation.tag_length,
3364 nonce, nonce_length,
3365 additional_data,
3366 additional_data_length,
3367 ciphertext, plaintext,
3368 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003369 }
mohammad160339574652018-06-01 04:39:53 -07003370 else
3371 {
mohammad1603554faad2018-06-03 15:07:38 +03003372 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07003373 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02003374
Gilles Peskineedf9a652018-08-17 18:11:56 +02003375 if( status != PSA_SUCCESS && plaintext_size != 0 )
3376 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03003377
Gilles Peskineedf9a652018-08-17 18:11:56 +02003378exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003379 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003380 if( status == PSA_SUCCESS )
3381 *plaintext_length = ciphertext_length - operation.tag_length;
3382 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003383}
3384
Gilles Peskinea0655c32018-04-30 17:06:50 +02003385
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003386
Gilles Peskine20035e32018-02-03 22:44:14 +01003387/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003388/* Generators */
3389/****************************************************************/
3390
3391psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
3392{
3393 psa_status_t status = PSA_SUCCESS;
3394 if( generator->alg == 0 )
3395 {
3396 /* The object has (apparently) been initialized but it is not
3397 * in use. It's ok to call abort on such an object, and there's
3398 * nothing to do. */
3399 }
3400 else
Gilles Peskine751d9652018-09-18 12:05:44 +02003401 if( generator->alg == PSA_ALG_SELECT_RAW )
3402 {
3403 if( generator->ctx.buffer.data != NULL )
3404 {
3405 mbedtls_zeroize( generator->ctx.buffer.data,
3406 generator->ctx.buffer.size );
3407 mbedtls_free( generator->ctx.buffer.data );
3408 }
3409 }
3410 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003411#if defined(MBEDTLS_MD_C)
3412 if( PSA_ALG_IS_HKDF( generator->alg ) )
3413 {
3414 mbedtls_free( generator->ctx.hkdf.info );
3415 status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
3416 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003417 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3418 /* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
3419 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003420 {
3421 if( generator->ctx.tls12_prf.key != NULL )
3422 {
3423 mbedtls_zeroize( generator->ctx.tls12_prf.key,
3424 generator->ctx.tls12_prf.key_len );
3425 mbedtls_free( generator->ctx.tls12_prf.key );
3426 }
Hanno Becker580fba12018-11-13 20:50:45 +00003427
3428 if( generator->ctx.tls12_prf.Ai_with_seed != NULL )
3429 {
3430 mbedtls_zeroize( generator->ctx.tls12_prf.Ai_with_seed,
3431 generator->ctx.tls12_prf.Ai_with_seed_len );
3432 mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed );
3433 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003434 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003435 else
3436#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003437 {
3438 status = PSA_ERROR_BAD_STATE;
3439 }
3440 memset( generator, 0, sizeof( *generator ) );
3441 return( status );
3442}
3443
3444
3445psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3446 size_t *capacity)
3447{
3448 *capacity = generator->capacity;
3449 return( PSA_SUCCESS );
3450}
3451
Gilles Peskinebef7f142018-07-12 17:22:21 +02003452#if defined(MBEDTLS_MD_C)
3453/* Read some bytes from an HKDF-based generator. This performs a chunk
3454 * of the expand phase of the HKDF algorithm. */
3455static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
3456 psa_algorithm_t hash_alg,
3457 uint8_t *output,
3458 size_t output_length )
3459{
3460 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3461 psa_status_t status;
3462
3463 while( output_length != 0 )
3464 {
3465 /* Copy what remains of the current block */
3466 uint8_t n = hash_length - hkdf->offset_in_block;
3467 if( n > output_length )
3468 n = (uint8_t) output_length;
3469 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
3470 output += n;
3471 output_length -= n;
3472 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02003473 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003474 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003475 /* We can't be wanting more output after block 0xff, otherwise
3476 * the capacity check in psa_generator_read() would have
3477 * prevented this call. It could happen only if the generator
3478 * object was corrupted or if this function is called directly
3479 * inside the library. */
3480 if( hkdf->block_number == 0xff )
3481 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003482
3483 /* We need a new block */
3484 ++hkdf->block_number;
3485 hkdf->offset_in_block = 0;
3486 status = psa_hmac_setup_internal( &hkdf->hmac,
3487 hkdf->prk, hash_length,
3488 hash_alg );
3489 if( status != PSA_SUCCESS )
3490 return( status );
3491 if( hkdf->block_number != 1 )
3492 {
3493 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3494 hkdf->output_block,
3495 hash_length );
3496 if( status != PSA_SUCCESS )
3497 return( status );
3498 }
3499 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3500 hkdf->info,
3501 hkdf->info_length );
3502 if( status != PSA_SUCCESS )
3503 return( status );
3504 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3505 &hkdf->block_number, 1 );
3506 if( status != PSA_SUCCESS )
3507 return( status );
3508 status = psa_hmac_finish_internal( &hkdf->hmac,
3509 hkdf->output_block,
3510 sizeof( hkdf->output_block ) );
3511 if( status != PSA_SUCCESS )
3512 return( status );
3513 }
3514
3515 return( PSA_SUCCESS );
3516}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003517
3518static psa_status_t psa_generator_tls12_prf_generate_next_block(
3519 psa_tls12_prf_generator_t *tls12_prf,
3520 psa_algorithm_t alg )
3521{
3522 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3523 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3524 psa_hmac_internal_data hmac;
3525 psa_status_t status, cleanup_status;
3526
Hanno Becker3b339e22018-11-13 20:56:14 +00003527 unsigned char *Ai;
3528 size_t Ai_len;
3529
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003530 /* We can't be wanting more output after block 0xff, otherwise
3531 * the capacity check in psa_generator_read() would have
3532 * prevented this call. It could happen only if the generator
3533 * object was corrupted or if this function is called directly
3534 * inside the library. */
3535 if( tls12_prf->block_number == 0xff )
3536 return( PSA_ERROR_BAD_STATE );
3537
3538 /* We need a new block */
3539 ++tls12_prf->block_number;
3540 tls12_prf->offset_in_block = 0;
3541
3542 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
3543 *
3544 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
3545 *
3546 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
3547 * HMAC_hash(secret, A(2) + seed) +
3548 * HMAC_hash(secret, A(3) + seed) + ...
3549 *
3550 * A(0) = seed
3551 * A(i) = HMAC_hash( secret, A(i-1) )
3552 *
3553 * The `psa_tls12_prf_generator` structures saves the block
3554 * `HMAC_hash(secret, A(i) + seed)` from which the output
3555 * is currently extracted as `output_block`, while
3556 * `A(i) + seed` is stored in `Ai_with_seed`.
3557 *
3558 * Generating a new block means recalculating `Ai_with_seed`
3559 * from the A(i)-part of it, and afterwards recalculating
3560 * `output_block`.
3561 *
3562 * A(0) is computed at setup time.
3563 *
3564 */
3565
3566 psa_hmac_init_internal( &hmac );
3567
3568 /* We must distinguish the calculation of A(1) from those
3569 * of A(2) and higher, because A(0)=seed has a different
3570 * length than the other A(i). */
3571 if( tls12_prf->block_number == 1 )
3572 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003573 Ai = tls12_prf->Ai_with_seed + hash_length;
3574 Ai_len = tls12_prf->Ai_with_seed_len - hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003575 }
3576 else
3577 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003578 Ai = tls12_prf->Ai_with_seed;
3579 Ai_len = hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003580 }
3581
Hanno Becker3b339e22018-11-13 20:56:14 +00003582 /* Compute A(i+1) = HMAC_hash(secret, A(i)) */
3583 status = psa_hmac_setup_internal( &hmac,
3584 tls12_prf->key,
3585 tls12_prf->key_len,
3586 hash_alg );
3587 if( status != PSA_SUCCESS )
3588 goto cleanup;
3589
3590 status = psa_hash_update( &hmac.hash_ctx,
3591 Ai, Ai_len );
3592 if( status != PSA_SUCCESS )
3593 goto cleanup;
3594
3595 status = psa_hmac_finish_internal( &hmac,
3596 tls12_prf->Ai_with_seed,
3597 hash_length );
3598 if( status != PSA_SUCCESS )
3599 goto cleanup;
3600
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003601 /* Compute the next block `HMAC_hash(secret, A(i+1) + seed)`. */
3602 status = psa_hmac_setup_internal( &hmac,
3603 tls12_prf->key,
3604 tls12_prf->key_len,
3605 hash_alg );
3606 if( status != PSA_SUCCESS )
3607 goto cleanup;
3608
3609 status = psa_hash_update( &hmac.hash_ctx,
3610 tls12_prf->Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003611 tls12_prf->Ai_with_seed_len );
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003612 if( status != PSA_SUCCESS )
3613 goto cleanup;
3614
3615 status = psa_hmac_finish_internal( &hmac,
3616 tls12_prf->output_block,
3617 hash_length );
3618 if( status != PSA_SUCCESS )
3619 goto cleanup;
3620
3621cleanup:
3622
3623 cleanup_status = psa_hmac_abort_internal( &hmac );
3624 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
3625 status = cleanup_status;
3626
3627 return( status );
3628}
3629
3630/* Read some bytes from an TLS-1.2-PRF-based generator.
3631 * See Section 5 of RFC 5246. */
3632static psa_status_t psa_generator_tls12_prf_read(
3633 psa_tls12_prf_generator_t *tls12_prf,
3634 psa_algorithm_t alg,
3635 uint8_t *output,
3636 size_t output_length )
3637{
3638 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3639 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3640 psa_status_t status;
3641
3642 while( output_length != 0 )
3643 {
3644 /* Copy what remains of the current block */
3645 uint8_t n = hash_length - tls12_prf->offset_in_block;
3646
3647 /* Check if we have fully processed the current block. */
3648 if( n == 0 )
3649 {
3650 status = psa_generator_tls12_prf_generate_next_block( tls12_prf,
3651 alg );
3652 if( status != PSA_SUCCESS )
3653 return( status );
3654
3655 continue;
3656 }
3657
3658 if( n > output_length )
3659 n = (uint8_t) output_length;
3660 memcpy( output, tls12_prf->output_block + tls12_prf->offset_in_block,
3661 n );
3662 output += n;
3663 output_length -= n;
3664 tls12_prf->offset_in_block += n;
3665 }
3666
3667 return( PSA_SUCCESS );
3668}
Gilles Peskinebef7f142018-07-12 17:22:21 +02003669#endif /* MBEDTLS_MD_C */
3670
Gilles Peskineeab56e42018-07-12 17:12:33 +02003671psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
3672 uint8_t *output,
3673 size_t output_length )
3674{
3675 psa_status_t status;
3676
3677 if( output_length > generator->capacity )
3678 {
3679 generator->capacity = 0;
3680 /* Go through the error path to wipe all confidential data now
3681 * that the generator object is useless. */
3682 status = PSA_ERROR_INSUFFICIENT_CAPACITY;
3683 goto exit;
3684 }
3685 if( output_length == 0 &&
3686 generator->capacity == 0 && generator->alg == 0 )
3687 {
3688 /* Edge case: this is a blank or finished generator, and 0
3689 * bytes were requested. The right error in this case could
3690 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3691 * INSUFFICIENT_CAPACITY, which is right for a finished
3692 * generator, for consistency with the case when
3693 * output_length > 0. */
3694 return( PSA_ERROR_INSUFFICIENT_CAPACITY );
3695 }
3696 generator->capacity -= output_length;
3697
Gilles Peskine751d9652018-09-18 12:05:44 +02003698 if( generator->alg == PSA_ALG_SELECT_RAW )
3699 {
Gilles Peskine211a4362018-10-25 22:22:31 +02003700 /* Initially, the capacity of a selection generator is always
3701 * the size of the buffer, i.e. `generator->ctx.buffer.size`,
3702 * abbreviated in this comment as `size`. When the remaining
3703 * capacity is `c`, the next bytes to serve start `c` bytes
3704 * from the end of the buffer, i.e. `size - c` from the
3705 * beginning of the buffer. Since `generator->capacity` was just
3706 * decremented above, we need to serve the bytes from
3707 * `size - generator->capacity - output_length` to
3708 * `size - generator->capacity`. */
Gilles Peskine751d9652018-09-18 12:05:44 +02003709 size_t offset =
3710 generator->ctx.buffer.size - generator->capacity - output_length;
3711 memcpy( output, generator->ctx.buffer.data + offset, output_length );
3712 status = PSA_SUCCESS;
3713 }
3714 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003715#if defined(MBEDTLS_MD_C)
3716 if( PSA_ALG_IS_HKDF( generator->alg ) )
3717 {
3718 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
3719 status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
3720 output, output_length );
3721 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003722 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3723 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003724 {
3725 status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
3726 generator->alg, output,
3727 output_length );
3728 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003729 else
3730#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003731 {
3732 return( PSA_ERROR_BAD_STATE );
3733 }
3734
3735exit:
3736 if( status != PSA_SUCCESS )
3737 {
3738 psa_generator_abort( generator );
3739 memset( output, '!', output_length );
3740 }
3741 return( status );
3742}
3743
Gilles Peskine08542d82018-07-19 17:05:42 +02003744#if defined(MBEDTLS_DES_C)
3745static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
3746{
3747 if( data_size >= 8 )
3748 mbedtls_des_key_set_parity( data );
3749 if( data_size >= 16 )
3750 mbedtls_des_key_set_parity( data + 8 );
3751 if( data_size >= 24 )
3752 mbedtls_des_key_set_parity( data + 16 );
3753}
3754#endif /* MBEDTLS_DES_C */
3755
Gilles Peskineeab56e42018-07-12 17:12:33 +02003756psa_status_t psa_generator_import_key( psa_key_slot_t key,
3757 psa_key_type_t type,
3758 size_t bits,
3759 psa_crypto_generator_t *generator )
3760{
3761 uint8_t *data = NULL;
3762 size_t bytes = PSA_BITS_TO_BYTES( bits );
3763 psa_status_t status;
3764
3765 if( ! key_type_is_raw_bytes( type ) )
3766 return( PSA_ERROR_INVALID_ARGUMENT );
3767 if( bits % 8 != 0 )
3768 return( PSA_ERROR_INVALID_ARGUMENT );
3769 data = mbedtls_calloc( 1, bytes );
3770 if( data == NULL )
3771 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3772
3773 status = psa_generator_read( generator, data, bytes );
3774 if( status != PSA_SUCCESS )
3775 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02003776#if defined(MBEDTLS_DES_C)
3777 if( type == PSA_KEY_TYPE_DES )
3778 psa_des_set_key_parity( data, bytes );
3779#endif /* MBEDTLS_DES_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003780 status = psa_import_key( key, type, data, bytes );
3781
3782exit:
3783 mbedtls_free( data );
3784 return( status );
3785}
3786
3787
3788
3789/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003790/* Key derivation */
3791/****************************************************************/
3792
Gilles Peskinea05219c2018-11-16 16:02:56 +01003793#if defined(MBEDTLS_MD_C)
Gilles Peskinebef7f142018-07-12 17:22:21 +02003794/* Set up an HKDF-based generator. This is exactly the extract phase
Gilles Peskine346797d2018-11-16 16:05:06 +01003795 * of the HKDF algorithm.
3796 *
3797 * Note that if this function fails, you must call psa_generator_abort()
3798 * to potentially free embedded data structures and wipe confidential data.
3799 */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003800static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003801 const uint8_t *secret,
3802 size_t secret_length,
Gilles Peskinebef7f142018-07-12 17:22:21 +02003803 psa_algorithm_t hash_alg,
3804 const uint8_t *salt,
3805 size_t salt_length,
3806 const uint8_t *label,
3807 size_t label_length )
3808{
3809 psa_status_t status;
3810 status = psa_hmac_setup_internal( &hkdf->hmac,
3811 salt, salt_length,
Gilles Peskine00709fa2018-08-22 18:25:41 +02003812 PSA_ALG_HMAC_GET_HASH( hash_alg ) );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003813 if( status != PSA_SUCCESS )
3814 return( status );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003815 status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003816 if( status != PSA_SUCCESS )
3817 return( status );
3818 status = psa_hmac_finish_internal( &hkdf->hmac,
3819 hkdf->prk,
3820 sizeof( hkdf->prk ) );
3821 if( status != PSA_SUCCESS )
3822 return( status );
3823 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
3824 hkdf->block_number = 0;
3825 hkdf->info_length = label_length;
3826 if( label_length != 0 )
3827 {
3828 hkdf->info = mbedtls_calloc( 1, label_length );
3829 if( hkdf->info == NULL )
3830 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3831 memcpy( hkdf->info, label, label_length );
3832 }
3833 return( PSA_SUCCESS );
3834}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003835#endif /* MBEDTLS_MD_C */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003836
Gilles Peskinea05219c2018-11-16 16:02:56 +01003837#if defined(MBEDTLS_MD_C)
Gilles Peskine346797d2018-11-16 16:05:06 +01003838/* Set up a TLS-1.2-prf-based generator (see RFC 5246, Section 5).
3839 *
3840 * Note that if this function fails, you must call psa_generator_abort()
3841 * to potentially free embedded data structures and wipe confidential data.
3842 */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003843static psa_status_t psa_generator_tls12_prf_setup(
3844 psa_tls12_prf_generator_t *tls12_prf,
3845 const unsigned char *key,
3846 size_t key_len,
3847 psa_algorithm_t hash_alg,
3848 const uint8_t *salt,
3849 size_t salt_length,
3850 const uint8_t *label,
3851 size_t label_length )
3852{
3853 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Hanno Becker580fba12018-11-13 20:50:45 +00003854 size_t Ai_with_seed_len = hash_length + salt_length + label_length;
3855 int overflow;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003856
3857 tls12_prf->key = mbedtls_calloc( 1, key_len );
3858 if( tls12_prf->key == NULL )
3859 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3860 tls12_prf->key_len = key_len;
3861 memcpy( tls12_prf->key, key, key_len );
3862
Hanno Becker580fba12018-11-13 20:50:45 +00003863 overflow = ( salt_length + label_length < salt_length ) ||
3864 ( salt_length + label_length + hash_length < hash_length );
3865 if( overflow )
3866 return( PSA_ERROR_INVALID_ARGUMENT );
3867
3868 tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len );
3869 if( tls12_prf->Ai_with_seed == NULL )
3870 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3871 tls12_prf->Ai_with_seed_len = Ai_with_seed_len;
3872
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003873 /* Write `label + seed' at the end of the `A(i) + seed` buffer,
3874 * leaving the initial `hash_length` bytes unspecified for now. */
Hanno Becker353e4532018-11-15 09:53:57 +00003875 if( label_length != 0 )
3876 {
3877 memcpy( tls12_prf->Ai_with_seed + hash_length,
3878 label, label_length );
3879 }
3880
3881 if( salt_length != 0 )
3882 {
3883 memcpy( tls12_prf->Ai_with_seed + hash_length + label_length,
3884 salt, salt_length );
3885 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003886
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003887 /* The first block gets generated when
3888 * psa_generator_read() is called. */
3889 tls12_prf->block_number = 0;
3890 tls12_prf->offset_in_block = hash_length;
3891
3892 return( PSA_SUCCESS );
3893}
Hanno Becker1aaedc02018-11-16 11:35:34 +00003894
3895/* Set up a TLS-1.2-PSK-to-MS-based generator. */
3896static psa_status_t psa_generator_tls12_psk_to_ms_setup(
3897 psa_tls12_prf_generator_t *tls12_prf,
3898 const unsigned char *psk,
3899 size_t psk_len,
3900 psa_algorithm_t hash_alg,
3901 const uint8_t *salt,
3902 size_t salt_length,
3903 const uint8_t *label,
3904 size_t label_length )
3905{
3906 psa_status_t status;
3907 unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
3908
3909 if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
3910 return( PSA_ERROR_INVALID_ARGUMENT );
3911
3912 /* Quoting RFC 4279, Section 2:
3913 *
3914 * The premaster secret is formed as follows: if the PSK is N octets
3915 * long, concatenate a uint16 with the value N, N zero octets, a second
3916 * uint16 with the value N, and the PSK itself.
3917 */
3918
3919 pms[0] = ( psk_len >> 8 ) & 0xff;
3920 pms[1] = ( psk_len >> 0 ) & 0xff;
3921 memset( pms + 2, 0, psk_len );
3922 pms[2 + psk_len + 0] = pms[0];
3923 pms[2 + psk_len + 1] = pms[1];
3924 memcpy( pms + 4 + psk_len, psk, psk_len );
3925
3926 status = psa_generator_tls12_prf_setup( tls12_prf,
3927 pms, 4 + 2 * psk_len,
3928 hash_alg,
3929 salt, salt_length,
3930 label, label_length );
3931
3932 mbedtls_zeroize( pms, sizeof( pms ) );
3933 return( status );
3934}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003935#endif /* MBEDTLS_MD_C */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003936
Gilles Peskine346797d2018-11-16 16:05:06 +01003937/* Note that if this function fails, you must call psa_generator_abort()
3938 * to potentially free embedded data structures and wipe confidential data.
3939 */
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003940static psa_status_t psa_key_derivation_internal(
3941 psa_crypto_generator_t *generator,
3942 const uint8_t *secret, size_t secret_length,
3943 psa_algorithm_t alg,
3944 const uint8_t *salt, size_t salt_length,
3945 const uint8_t *label, size_t label_length,
3946 size_t capacity )
3947{
3948 psa_status_t status;
3949 size_t max_capacity;
3950
3951 /* Set generator->alg even on failure so that abort knows what to do. */
3952 generator->alg = alg;
3953
Gilles Peskine751d9652018-09-18 12:05:44 +02003954 if( alg == PSA_ALG_SELECT_RAW )
3955 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003956 (void) salt;
Gilles Peskine751d9652018-09-18 12:05:44 +02003957 if( salt_length != 0 )
3958 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea05219c2018-11-16 16:02:56 +01003959 (void) label;
Gilles Peskine751d9652018-09-18 12:05:44 +02003960 if( label_length != 0 )
3961 return( PSA_ERROR_INVALID_ARGUMENT );
3962 generator->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
3963 if( generator->ctx.buffer.data == NULL )
3964 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3965 memcpy( generator->ctx.buffer.data, secret, secret_length );
3966 generator->ctx.buffer.size = secret_length;
3967 max_capacity = secret_length;
3968 status = PSA_SUCCESS;
3969 }
3970 else
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003971#if defined(MBEDTLS_MD_C)
3972 if( PSA_ALG_IS_HKDF( alg ) )
3973 {
3974 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3975 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3976 if( hash_size == 0 )
3977 return( PSA_ERROR_NOT_SUPPORTED );
3978 max_capacity = 255 * hash_size;
3979 status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
3980 secret, secret_length,
3981 hash_alg,
3982 salt, salt_length,
3983 label, label_length );
3984 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003985 /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
3986 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
3987 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003988 {
3989 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3990 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3991
3992 /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */
3993 if( hash_alg != PSA_ALG_SHA_256 &&
3994 hash_alg != PSA_ALG_SHA_384 )
3995 {
3996 return( PSA_ERROR_NOT_SUPPORTED );
3997 }
3998
3999 max_capacity = 255 * hash_size;
Hanno Becker1aaedc02018-11-16 11:35:34 +00004000
4001 if( PSA_ALG_IS_TLS12_PRF( alg ) )
4002 {
4003 status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
4004 secret, secret_length,
4005 hash_alg, salt, salt_length,
4006 label, label_length );
4007 }
4008 else
4009 {
4010 status = psa_generator_tls12_psk_to_ms_setup(
4011 &generator->ctx.tls12_prf,
4012 secret, secret_length,
4013 hash_alg, salt, salt_length,
4014 label, label_length );
4015 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004016 }
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004017 else
4018#endif
4019 {
4020 return( PSA_ERROR_NOT_SUPPORTED );
4021 }
4022
4023 if( status != PSA_SUCCESS )
4024 return( status );
4025
4026 if( capacity <= max_capacity )
4027 generator->capacity = capacity;
Gilles Peskine8feb3a82018-09-18 12:06:11 +02004028 else if( capacity == PSA_GENERATOR_UNBRIDLED_CAPACITY )
4029 generator->capacity = max_capacity;
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004030 else
4031 return( PSA_ERROR_INVALID_ARGUMENT );
4032
4033 return( PSA_SUCCESS );
4034}
4035
Gilles Peskineea0fb492018-07-12 17:17:20 +02004036psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
Darryl Green88001362018-07-26 13:59:04 +01004037 psa_key_slot_t key,
Gilles Peskineea0fb492018-07-12 17:17:20 +02004038 psa_algorithm_t alg,
4039 const uint8_t *salt,
4040 size_t salt_length,
4041 const uint8_t *label,
4042 size_t label_length,
4043 size_t capacity )
4044{
4045 key_slot_t *slot;
4046 psa_status_t status;
4047
4048 if( generator->alg != 0 )
4049 return( PSA_ERROR_BAD_STATE );
4050
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004051 /* Make sure that alg is a key derivation algorithm. This prevents
4052 * key selection algorithms, which psa_key_derivation_internal
4053 * accepts for the sake of key agreement. */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004054 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
4055 return( PSA_ERROR_INVALID_ARGUMENT );
4056
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004057 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DERIVE, alg );
4058 if( status != PSA_SUCCESS )
4059 return( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004060
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004061 if( slot->type != PSA_KEY_TYPE_DERIVE )
4062 return( PSA_ERROR_INVALID_ARGUMENT );
4063
4064 status = psa_key_derivation_internal( generator,
4065 slot->data.raw.data,
4066 slot->data.raw.bytes,
4067 alg,
4068 salt, salt_length,
4069 label, label_length,
4070 capacity );
4071 if( status != PSA_SUCCESS )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004072 psa_generator_abort( generator );
4073 return( status );
4074}
4075
4076
4077
4078/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02004079/* Key agreement */
4080/****************************************************************/
4081
Gilles Peskinea05219c2018-11-16 16:02:56 +01004082#if defined(MBEDTLS_ECDH_C)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004083static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
4084 size_t peer_key_length,
4085 const mbedtls_ecp_keypair *our_key,
4086 uint8_t *shared_secret,
4087 size_t shared_secret_size,
4088 size_t *shared_secret_length )
4089{
4090 mbedtls_pk_context pk;
4091 mbedtls_ecp_keypair *their_key = NULL;
4092 mbedtls_ecdh_context ecdh;
4093 int ret;
4094 mbedtls_ecdh_init( &ecdh );
4095 mbedtls_pk_init( &pk );
4096
4097 ret = mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length );
4098 if( ret != 0 )
4099 goto exit;
Gilles Peskine88714d72018-10-25 23:07:25 +02004100 switch( mbedtls_pk_get_type( &pk ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004101 {
Gilles Peskine88714d72018-10-25 23:07:25 +02004102 case MBEDTLS_PK_ECKEY:
4103 case MBEDTLS_PK_ECKEY_DH:
4104 break;
4105 default:
4106 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4107 goto exit;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004108 }
4109 their_key = mbedtls_pk_ec( pk );
Gilles Peskineb4086612018-11-14 20:51:23 +01004110 if( their_key->grp.id != our_key->grp.id )
4111 {
4112 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4113 goto exit;
4114 }
4115
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004116 ret = mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS );
4117 if( ret != 0 )
4118 goto exit;
4119 ret = mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS );
4120 if( ret != 0 )
4121 goto exit;
4122
4123 ret = mbedtls_ecdh_calc_secret( &ecdh,
4124 shared_secret_length,
4125 shared_secret, shared_secret_size,
4126 mbedtls_ctr_drbg_random,
4127 &global_data.ctr_drbg );
4128
4129exit:
4130 mbedtls_pk_free( &pk );
4131 mbedtls_ecdh_free( &ecdh );
4132 return( mbedtls_to_psa_error( ret ) );
4133}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004134#endif /* MBEDTLS_ECDH_C */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004135
Gilles Peskine01d718c2018-09-18 12:01:02 +02004136#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
4137
Gilles Peskine346797d2018-11-16 16:05:06 +01004138/* Note that if this function fails, you must call psa_generator_abort()
4139 * to potentially free embedded data structures and wipe confidential data.
4140 */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004141static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
4142 key_slot_t *private_key,
4143 const uint8_t *peer_key,
4144 size_t peer_key_length,
4145 psa_algorithm_t alg )
4146{
4147 psa_status_t status;
4148 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
4149 size_t shared_secret_length = 0;
4150
4151 /* Step 1: run the secret agreement algorithm to generate the shared
4152 * secret. */
4153 switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
4154 {
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004155#if defined(MBEDTLS_ECDH_C)
4156 case PSA_ALG_ECDH_BASE:
4157 if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
4158 return( PSA_ERROR_INVALID_ARGUMENT );
4159 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
4160 private_key->data.ecp,
4161 shared_secret,
4162 sizeof( shared_secret ),
4163 &shared_secret_length );
4164 break;
4165#endif /* MBEDTLS_ECDH_C */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004166 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01004167 (void) private_key;
4168 (void) peer_key;
4169 (void) peer_key_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004170 return( PSA_ERROR_NOT_SUPPORTED );
4171 }
4172 if( status != PSA_SUCCESS )
4173 goto exit;
4174
4175 /* Step 2: set up the key derivation to generate key material from
4176 * the shared secret. */
4177 status = psa_key_derivation_internal( generator,
4178 shared_secret, shared_secret_length,
4179 PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ),
4180 NULL, 0, NULL, 0,
4181 PSA_GENERATOR_UNBRIDLED_CAPACITY );
4182exit:
4183 mbedtls_zeroize( shared_secret, shared_secret_length );
4184 return( status );
4185}
4186
4187psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
4188 psa_key_slot_t private_key,
4189 const uint8_t *peer_key,
4190 size_t peer_key_length,
4191 psa_algorithm_t alg )
4192{
4193 key_slot_t *slot;
4194 psa_status_t status;
4195 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
4196 return( PSA_ERROR_INVALID_ARGUMENT );
4197 status = psa_get_key_from_slot( private_key, &slot,
4198 PSA_KEY_USAGE_DERIVE, alg );
4199 if( status != PSA_SUCCESS )
4200 return( status );
Gilles Peskine346797d2018-11-16 16:05:06 +01004201 status = psa_key_agreement_internal( generator,
4202 slot,
4203 peer_key, peer_key_length,
4204 alg );
4205 if( status != PSA_SUCCESS )
4206 psa_generator_abort( generator );
4207 return( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004208}
4209
4210
4211
4212/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004213/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02004214/****************************************************************/
4215
4216psa_status_t psa_generate_random( uint8_t *output,
4217 size_t output_size )
4218{
itayzafrir0adf0fc2018-09-06 16:24:41 +03004219 int ret;
4220 GUARD_MODULE_INITIALIZED;
4221
4222 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
Gilles Peskine05d69892018-06-19 22:00:52 +02004223 return( mbedtls_to_psa_error( ret ) );
4224}
4225
4226psa_status_t psa_generate_key( psa_key_slot_t key,
4227 psa_key_type_t type,
4228 size_t bits,
Gilles Peskine53d991e2018-07-12 01:14:59 +02004229 const void *extra,
4230 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02004231{
Gilles Peskine12313cd2018-06-20 00:20:32 +02004232 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004233 psa_status_t status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004234
Gilles Peskine53d991e2018-07-12 01:14:59 +02004235 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004236 return( PSA_ERROR_INVALID_ARGUMENT );
4237
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004238 status = psa_get_empty_key_slot( key, &slot );
4239 if( status != PSA_SUCCESS )
4240 return( status );
4241
Gilles Peskine48c0ea12018-06-21 14:15:31 +02004242 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004243 {
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004244 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004245 if( status != PSA_SUCCESS )
4246 return( status );
4247 status = psa_generate_random( slot->data.raw.data,
4248 slot->data.raw.bytes );
4249 if( status != PSA_SUCCESS )
4250 {
4251 mbedtls_free( slot->data.raw.data );
4252 return( status );
4253 }
4254#if defined(MBEDTLS_DES_C)
4255 if( type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02004256 psa_des_set_key_parity( slot->data.raw.data,
4257 slot->data.raw.bytes );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004258#endif /* MBEDTLS_DES_C */
4259 }
4260 else
4261
4262#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
4263 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
4264 {
4265 mbedtls_rsa_context *rsa;
4266 int ret;
4267 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02004268 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
4269 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +01004270 /* Accept only byte-aligned keys, for the same reasons as
4271 * in psa_import_rsa_key(). */
4272 if( bits % 8 != 0 )
4273 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02004274 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004275 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02004276 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004277 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004278 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02004279#if INT_MAX < 0xffffffff
4280 /* Check that the uint32_t value passed by the caller fits
4281 * in the range supported by this implementation. */
4282 if( p->e > INT_MAX )
4283 return( PSA_ERROR_NOT_SUPPORTED );
4284#endif
4285 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004286 }
4287 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
4288 if( rsa == NULL )
4289 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4290 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
4291 ret = mbedtls_rsa_gen_key( rsa,
4292 mbedtls_ctr_drbg_random,
4293 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004294 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02004295 exponent );
4296 if( ret != 0 )
4297 {
4298 mbedtls_rsa_free( rsa );
4299 mbedtls_free( rsa );
4300 return( mbedtls_to_psa_error( ret ) );
4301 }
4302 slot->data.rsa = rsa;
4303 }
4304 else
4305#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
4306
4307#if defined(MBEDTLS_ECP_C)
4308 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
4309 {
4310 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
4311 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
4312 const mbedtls_ecp_curve_info *curve_info =
4313 mbedtls_ecp_curve_info_from_grp_id( grp_id );
4314 mbedtls_ecp_keypair *ecp;
4315 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004316 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004317 return( PSA_ERROR_NOT_SUPPORTED );
4318 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
4319 return( PSA_ERROR_NOT_SUPPORTED );
4320 if( curve_info->bit_size != bits )
4321 return( PSA_ERROR_INVALID_ARGUMENT );
4322 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
4323 if( ecp == NULL )
4324 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4325 mbedtls_ecp_keypair_init( ecp );
4326 ret = mbedtls_ecp_gen_key( grp_id, ecp,
4327 mbedtls_ctr_drbg_random,
4328 &global_data.ctr_drbg );
4329 if( ret != 0 )
4330 {
4331 mbedtls_ecp_keypair_free( ecp );
4332 mbedtls_free( ecp );
4333 return( mbedtls_to_psa_error( ret ) );
4334 }
4335 slot->data.ecp = ecp;
4336 }
4337 else
4338#endif /* MBEDTLS_ECP_C */
4339
4340 return( PSA_ERROR_NOT_SUPPORTED );
4341
4342 slot->type = type;
Darryl Green0c6575a2018-11-07 16:05:30 +00004343
4344#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
4345 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
4346 {
4347 return( psa_save_generated_persistent_key( key, slot, bits ) );
4348 }
4349#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
4350
4351 return( status );
Gilles Peskine05d69892018-06-19 22:00:52 +02004352}
4353
4354
4355/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01004356/* Module setup */
4357/****************************************************************/
4358
Gilles Peskinee59236f2018-01-27 23:32:46 +01004359void mbedtls_psa_crypto_free( void )
4360{
Jaeden Amero045bd502018-06-26 14:00:08 +01004361 psa_key_slot_t key;
Darryl Green40225ba2018-11-15 14:48:15 +00004362 key_slot_t *slot;
4363 psa_status_t status;
4364
Gilles Peskine9a056342018-08-01 15:46:54 +02004365 for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ )
Darryl Green40225ba2018-11-15 14:48:15 +00004366 {
4367 status = psa_get_key_slot( key, &slot );
4368 if( status != PSA_SUCCESS )
4369 continue;
4370 psa_remove_key_data_from_memory( slot );
4371 /* Zeroize the slot to wipe metadata such as policies. */
4372 mbedtls_zeroize( slot, sizeof( *slot ) );
4373 }
Gilles Peskinee59236f2018-01-27 23:32:46 +01004374 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
4375 mbedtls_entropy_free( &global_data.entropy );
4376 mbedtls_zeroize( &global_data, sizeof( global_data ) );
4377}
4378
4379psa_status_t psa_crypto_init( void )
4380{
4381 int ret;
4382 const unsigned char drbg_seed[] = "PSA";
4383
4384 if( global_data.initialized != 0 )
4385 return( PSA_SUCCESS );
4386
4387 mbedtls_zeroize( &global_data, sizeof( global_data ) );
4388 mbedtls_entropy_init( &global_data.entropy );
4389 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
4390
4391 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
4392 mbedtls_entropy_func,
4393 &global_data.entropy,
4394 drbg_seed, sizeof( drbg_seed ) - 1 );
4395 if( ret != 0 )
4396 goto exit;
4397
Gilles Peskinee4ebc122018-03-07 14:16:44 +01004398 global_data.initialized = 1;
4399
Gilles Peskinee59236f2018-01-27 23:32:46 +01004400exit:
4401 if( ret != 0 )
4402 mbedtls_psa_crypto_free( );
4403 return( mbedtls_to_psa_error( ret ) );
4404}
4405
4406#endif /* MBEDTLS_PSA_CRYPTO_C */