blob: e8697a75229a1f0e9d9498145fe7e9869eeaf833 [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
4/* Copyright (C) 2018, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PSA_CRYPTO_C)
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +030029/*
30 * In case MBEDTLS_PSA_CRYPTO_SPM is defined the code is built for SPM (Secure
31 * Partition Manager) integration which separate the code into two parts
32 * NSPE (Non-Secure Process Environment) and SPE (Secure Process Environment).
33 * In this mode an additional header file should be included.
34 */
mohammad160327010052018-07-03 13:16:15 +030035#if defined(MBEDTLS_PSA_CRYPTO_SPM)
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +030036/*
37 * PSA_CRYPTO_SECURE means that this file is compiled to the SPE side.
38 * some headers will be affected by this flag.
39 */
mohammad160327010052018-07-03 13:16:15 +030040#define PSA_CRYPTO_SECURE 1
41#include "crypto_spe.h"
42#endif
43
Gilles Peskinee59236f2018-01-27 23:32:46 +010044#include "psa/crypto.h"
45
Gilles Peskine039b90c2018-12-07 18:24:41 +010046#include "psa_crypto_core.h"
Gilles Peskine5e769522018-11-20 21:59:56 +010047#include "psa_crypto_invasive.h"
Gilles Peskine961849f2018-11-30 18:54:54 +010048#include "psa_crypto_slot_management.h"
Darryl Greend49a4992018-06-18 17:27:26 +010049/* Include internal declarations that are useful for implementing persistently
50 * stored keys. */
51#include "psa_crypto_storage.h"
52
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010053#include <stdlib.h>
54#include <string.h>
55#if defined(MBEDTLS_PLATFORM_C)
56#include "mbedtls/platform.h"
57#else
58#define mbedtls_calloc calloc
59#define mbedtls_free free
60#endif
61
Gilles Peskinea5905292018-02-07 20:59:33 +010062#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020063#include "mbedtls/asn1.h"
Jaeden Amero25384a22019-01-10 10:23:21 +000064#include "mbedtls/asn1write.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020065#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010066#include "mbedtls/blowfish.h"
67#include "mbedtls/camellia.h"
68#include "mbedtls/cipher.h"
69#include "mbedtls/ccm.h"
70#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010071#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010072#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020073#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010074#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010075#include "mbedtls/entropy.h"
Netanel Gonen2bcd3122018-11-19 11:53:02 +020076#include "mbedtls/entropy_poll.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010077#include "mbedtls/error.h"
78#include "mbedtls/gcm.h"
79#include "mbedtls/md2.h"
80#include "mbedtls/md4.h"
81#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010082#include "mbedtls/md.h"
83#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010084#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010085#include "mbedtls/pk_internal.h"
Gilles Peskine3f108122018-12-07 18:14:53 +010086#include "mbedtls/platform_util.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010087#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010088#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010089#include "mbedtls/sha1.h"
90#include "mbedtls/sha256.h"
91#include "mbedtls/sha512.h"
92#include "mbedtls/xtea.h"
93
Netanel Gonen2bcd3122018-11-19 11:53:02 +020094#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
95#include "psa_prot_internal_storage.h"
96#endif
Gilles Peskinee59236f2018-01-27 23:32:46 +010097
Gilles Peskine996deb12018-08-01 15:45:45 +020098#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
99
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100100/* constant-time buffer comparison */
101static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
102{
103 size_t i;
104 unsigned char diff = 0;
105
106 for( i = 0; i < n; i++ )
107 diff |= a[i] ^ b[i];
108
109 return( diff );
110}
111
112
113
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100114/****************************************************************/
115/* Global data, support functions and library management */
116/****************************************************************/
117
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200118static int key_type_is_raw_bytes( psa_key_type_t type )
119{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200120 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200121}
122
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100123/* Values for psa_global_data_t::rng_state */
124#define RNG_NOT_INITIALIZED 0
125#define RNG_INITIALIZED 1
126#define RNG_SEEDED 2
Gilles Peskinec6b69072018-11-20 21:42:52 +0100127
Gilles Peskine2d277862018-06-18 15:41:12 +0200128typedef struct
129{
Gilles Peskine5e769522018-11-20 21:59:56 +0100130 void (* entropy_init )( mbedtls_entropy_context *ctx );
131 void (* entropy_free )( mbedtls_entropy_context *ctx );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100132 mbedtls_entropy_context entropy;
133 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskinec6b69072018-11-20 21:42:52 +0100134 unsigned initialized : 1;
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100135 unsigned rng_state : 2;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100136} psa_global_data_t;
137
138static psa_global_data_t global_data;
139
itayzafrir0adf0fc2018-09-06 16:24:41 +0300140#define GUARD_MODULE_INITIALIZED \
141 if( global_data.initialized == 0 ) \
142 return( PSA_ERROR_BAD_STATE );
143
Gilles Peskinee59236f2018-01-27 23:32:46 +0100144static psa_status_t mbedtls_to_psa_error( int ret )
145{
Gilles Peskinea5905292018-02-07 20:59:33 +0100146 /* If there's both a high-level code and low-level code, dispatch on
147 * the high-level code. */
148 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100149 {
150 case 0:
151 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100152
153 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
154 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
155 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
156 return( PSA_ERROR_NOT_SUPPORTED );
157 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
158 return( PSA_ERROR_HARDWARE_FAILURE );
159
160 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
161 return( PSA_ERROR_HARDWARE_FAILURE );
162
Gilles Peskine9a944802018-06-21 09:35:35 +0200163 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
164 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
165 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
166 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
167 case MBEDTLS_ERR_ASN1_INVALID_DATA:
168 return( PSA_ERROR_INVALID_ARGUMENT );
169 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
170 return( PSA_ERROR_INSUFFICIENT_MEMORY );
171 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
172 return( PSA_ERROR_BUFFER_TOO_SMALL );
173
Gilles Peskinea5905292018-02-07 20:59:33 +0100174 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
175 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
176 return( PSA_ERROR_NOT_SUPPORTED );
177 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
178 return( PSA_ERROR_HARDWARE_FAILURE );
179
180 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
181 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
182 return( PSA_ERROR_NOT_SUPPORTED );
183 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
186 case MBEDTLS_ERR_CCM_BAD_INPUT:
187 return( PSA_ERROR_INVALID_ARGUMENT );
188 case MBEDTLS_ERR_CCM_AUTH_FAILED:
189 return( PSA_ERROR_INVALID_SIGNATURE );
190 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
191 return( PSA_ERROR_HARDWARE_FAILURE );
192
193 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
194 return( PSA_ERROR_NOT_SUPPORTED );
195 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
196 return( PSA_ERROR_INVALID_ARGUMENT );
197 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
198 return( PSA_ERROR_INSUFFICIENT_MEMORY );
199 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
200 return( PSA_ERROR_INVALID_PADDING );
201 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
202 return( PSA_ERROR_BAD_STATE );
203 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
204 return( PSA_ERROR_INVALID_SIGNATURE );
205 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
206 return( PSA_ERROR_TAMPERING_DETECTED );
207 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
208 return( PSA_ERROR_HARDWARE_FAILURE );
209
210 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
211 return( PSA_ERROR_HARDWARE_FAILURE );
212
213 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
214 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
215 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
216 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
217 return( PSA_ERROR_NOT_SUPPORTED );
218 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
219 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
220
221 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
222 return( PSA_ERROR_NOT_SUPPORTED );
223 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
224 return( PSA_ERROR_HARDWARE_FAILURE );
225
Gilles Peskinee59236f2018-01-27 23:32:46 +0100226 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
227 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
228 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
229 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100230
231 case MBEDTLS_ERR_GCM_AUTH_FAILED:
232 return( PSA_ERROR_INVALID_SIGNATURE );
233 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200234 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100235 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
236 return( PSA_ERROR_HARDWARE_FAILURE );
237
238 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
239 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
240 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
241 return( PSA_ERROR_HARDWARE_FAILURE );
242
243 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
244 return( PSA_ERROR_NOT_SUPPORTED );
245 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
246 return( PSA_ERROR_INVALID_ARGUMENT );
247 case MBEDTLS_ERR_MD_ALLOC_FAILED:
248 return( PSA_ERROR_INSUFFICIENT_MEMORY );
249 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
250 return( PSA_ERROR_STORAGE_FAILURE );
251 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
252 return( PSA_ERROR_HARDWARE_FAILURE );
253
Gilles Peskinef76aa772018-10-29 19:24:33 +0100254 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
255 return( PSA_ERROR_STORAGE_FAILURE );
256 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
257 return( PSA_ERROR_INVALID_ARGUMENT );
258 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
259 return( PSA_ERROR_INVALID_ARGUMENT );
260 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
261 return( PSA_ERROR_BUFFER_TOO_SMALL );
262 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
263 return( PSA_ERROR_INVALID_ARGUMENT );
264 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
265 return( PSA_ERROR_INVALID_ARGUMENT );
266 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
267 return( PSA_ERROR_INVALID_ARGUMENT );
268 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
269 return( PSA_ERROR_INSUFFICIENT_MEMORY );
270
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100271 case MBEDTLS_ERR_PK_ALLOC_FAILED:
272 return( PSA_ERROR_INSUFFICIENT_MEMORY );
273 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
274 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
275 return( PSA_ERROR_INVALID_ARGUMENT );
276 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100277 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100278 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
279 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
280 return( PSA_ERROR_INVALID_ARGUMENT );
281 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
282 return( PSA_ERROR_NOT_SUPPORTED );
283 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
284 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
285 return( PSA_ERROR_NOT_PERMITTED );
286 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
287 return( PSA_ERROR_INVALID_ARGUMENT );
288 case MBEDTLS_ERR_PK_INVALID_ALG:
289 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
290 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
291 return( PSA_ERROR_NOT_SUPPORTED );
292 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
293 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100294 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
295 return( PSA_ERROR_HARDWARE_FAILURE );
296
297 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
298 return( PSA_ERROR_HARDWARE_FAILURE );
299
300 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
301 return( PSA_ERROR_INVALID_ARGUMENT );
302 case MBEDTLS_ERR_RSA_INVALID_PADDING:
303 return( PSA_ERROR_INVALID_PADDING );
304 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
305 return( PSA_ERROR_HARDWARE_FAILURE );
306 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
307 return( PSA_ERROR_INVALID_ARGUMENT );
308 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
309 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
310 return( PSA_ERROR_TAMPERING_DETECTED );
311 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
312 return( PSA_ERROR_INVALID_SIGNATURE );
313 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
314 return( PSA_ERROR_BUFFER_TOO_SMALL );
315 case MBEDTLS_ERR_RSA_RNG_FAILED:
316 return( PSA_ERROR_INSUFFICIENT_MEMORY );
317 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
318 return( PSA_ERROR_NOT_SUPPORTED );
319 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
320 return( PSA_ERROR_HARDWARE_FAILURE );
321
322 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
323 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
324 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
325 return( PSA_ERROR_HARDWARE_FAILURE );
326
327 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
328 return( PSA_ERROR_INVALID_ARGUMENT );
329 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
330 return( PSA_ERROR_HARDWARE_FAILURE );
331
itayzafrir5c753392018-05-08 11:18:38 +0300332 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300333 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300334 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300335 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
336 return( PSA_ERROR_BUFFER_TOO_SMALL );
337 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
338 return( PSA_ERROR_NOT_SUPPORTED );
339 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
340 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
341 return( PSA_ERROR_INVALID_SIGNATURE );
342 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
343 return( PSA_ERROR_INSUFFICIENT_MEMORY );
344 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
345 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300346
Gilles Peskinee59236f2018-01-27 23:32:46 +0100347 default:
348 return( PSA_ERROR_UNKNOWN_ERROR );
349 }
350}
351
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200352
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200353
354
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100355/****************************************************************/
356/* Key management */
357/****************************************************************/
358
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100359#if defined(MBEDTLS_ECP_C)
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200360static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
361{
362 switch( grpid )
363 {
364 case MBEDTLS_ECP_DP_SECP192R1:
365 return( PSA_ECC_CURVE_SECP192R1 );
366 case MBEDTLS_ECP_DP_SECP224R1:
367 return( PSA_ECC_CURVE_SECP224R1 );
368 case MBEDTLS_ECP_DP_SECP256R1:
369 return( PSA_ECC_CURVE_SECP256R1 );
370 case MBEDTLS_ECP_DP_SECP384R1:
371 return( PSA_ECC_CURVE_SECP384R1 );
372 case MBEDTLS_ECP_DP_SECP521R1:
373 return( PSA_ECC_CURVE_SECP521R1 );
374 case MBEDTLS_ECP_DP_BP256R1:
375 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
376 case MBEDTLS_ECP_DP_BP384R1:
377 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
378 case MBEDTLS_ECP_DP_BP512R1:
379 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
380 case MBEDTLS_ECP_DP_CURVE25519:
381 return( PSA_ECC_CURVE_CURVE25519 );
382 case MBEDTLS_ECP_DP_SECP192K1:
383 return( PSA_ECC_CURVE_SECP192K1 );
384 case MBEDTLS_ECP_DP_SECP224K1:
385 return( PSA_ECC_CURVE_SECP224K1 );
386 case MBEDTLS_ECP_DP_SECP256K1:
387 return( PSA_ECC_CURVE_SECP256K1 );
388 case MBEDTLS_ECP_DP_CURVE448:
389 return( PSA_ECC_CURVE_CURVE448 );
390 default:
391 return( 0 );
392 }
393}
394
Gilles Peskine12313cd2018-06-20 00:20:32 +0200395static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
396{
397 switch( curve )
398 {
399 case PSA_ECC_CURVE_SECP192R1:
400 return( MBEDTLS_ECP_DP_SECP192R1 );
401 case PSA_ECC_CURVE_SECP224R1:
402 return( MBEDTLS_ECP_DP_SECP224R1 );
403 case PSA_ECC_CURVE_SECP256R1:
404 return( MBEDTLS_ECP_DP_SECP256R1 );
405 case PSA_ECC_CURVE_SECP384R1:
406 return( MBEDTLS_ECP_DP_SECP384R1 );
407 case PSA_ECC_CURVE_SECP521R1:
408 return( MBEDTLS_ECP_DP_SECP521R1 );
409 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
410 return( MBEDTLS_ECP_DP_BP256R1 );
411 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
412 return( MBEDTLS_ECP_DP_BP384R1 );
413 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
414 return( MBEDTLS_ECP_DP_BP512R1 );
415 case PSA_ECC_CURVE_CURVE25519:
416 return( MBEDTLS_ECP_DP_CURVE25519 );
417 case PSA_ECC_CURVE_SECP192K1:
418 return( MBEDTLS_ECP_DP_SECP192K1 );
419 case PSA_ECC_CURVE_SECP224K1:
420 return( MBEDTLS_ECP_DP_SECP224K1 );
421 case PSA_ECC_CURVE_SECP256K1:
422 return( MBEDTLS_ECP_DP_SECP256K1 );
423 case PSA_ECC_CURVE_CURVE448:
424 return( MBEDTLS_ECP_DP_CURVE448 );
425 default:
426 return( MBEDTLS_ECP_DP_NONE );
427 }
428}
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100429#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200430
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200431static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
432 size_t bits,
433 struct raw_data *raw )
434{
435 /* Check that the bit size is acceptable for the key type */
436 switch( type )
437 {
438 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200439 if( bits == 0 )
440 {
441 raw->bytes = 0;
442 raw->data = NULL;
443 return( PSA_SUCCESS );
444 }
445 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200446#if defined(MBEDTLS_MD_C)
447 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200448#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200449 case PSA_KEY_TYPE_DERIVE:
450 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200451#if defined(MBEDTLS_AES_C)
452 case PSA_KEY_TYPE_AES:
453 if( bits != 128 && bits != 192 && bits != 256 )
454 return( PSA_ERROR_INVALID_ARGUMENT );
455 break;
456#endif
457#if defined(MBEDTLS_CAMELLIA_C)
458 case PSA_KEY_TYPE_CAMELLIA:
459 if( bits != 128 && bits != 192 && bits != 256 )
460 return( PSA_ERROR_INVALID_ARGUMENT );
461 break;
462#endif
463#if defined(MBEDTLS_DES_C)
464 case PSA_KEY_TYPE_DES:
465 if( bits != 64 && bits != 128 && bits != 192 )
466 return( PSA_ERROR_INVALID_ARGUMENT );
467 break;
468#endif
469#if defined(MBEDTLS_ARC4_C)
470 case PSA_KEY_TYPE_ARC4:
471 if( bits < 8 || bits > 2048 )
472 return( PSA_ERROR_INVALID_ARGUMENT );
473 break;
474#endif
475 default:
476 return( PSA_ERROR_NOT_SUPPORTED );
477 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200478 if( bits % 8 != 0 )
479 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200480
481 /* Allocate memory for the key */
482 raw->bytes = PSA_BITS_TO_BYTES( bits );
483 raw->data = mbedtls_calloc( 1, raw->bytes );
484 if( raw->data == NULL )
485 {
486 raw->bytes = 0;
487 return( PSA_ERROR_INSUFFICIENT_MEMORY );
488 }
489 return( PSA_SUCCESS );
490}
491
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200492#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine86a440b2018-11-12 18:39:40 +0100493/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
494 * that are not a multiple of 8) well. For example, there is only
495 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
496 * way to return the exact bit size of a key.
497 * To keep things simple, reject non-byte-aligned key sizes. */
498static psa_status_t psa_check_rsa_key_byte_aligned(
499 const mbedtls_rsa_context *rsa )
500{
501 mbedtls_mpi n;
502 psa_status_t status;
503 mbedtls_mpi_init( &n );
504 status = mbedtls_to_psa_error(
505 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
506 if( status == PSA_SUCCESS )
507 {
508 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
509 status = PSA_ERROR_NOT_SUPPORTED;
510 }
511 mbedtls_mpi_free( &n );
512 return( status );
513}
514
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200515static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
516 mbedtls_rsa_context **p_rsa )
517{
518 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_RSA )
519 return( PSA_ERROR_INVALID_ARGUMENT );
520 else
521 {
522 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *pk );
Gilles Peskineaac64a22018-11-12 18:37:42 +0100523 /* The size of an RSA key doesn't have to be a multiple of 8.
524 * Mbed TLS supports non-byte-aligned key sizes, but not well.
525 * For example, mbedtls_rsa_get_len() returns the key size in
526 * bytes, not in bits. */
527 size_t bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100528 psa_status_t status;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200529 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
530 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100531 status = psa_check_rsa_key_byte_aligned( rsa );
532 if( status != PSA_SUCCESS )
533 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200534 *p_rsa = rsa;
535 return( PSA_SUCCESS );
536 }
537}
538#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
539
540#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinef76aa772018-10-29 19:24:33 +0100541/* Import an elliptic curve parsed by the mbedtls pk module. */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200542static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
543 mbedtls_pk_context *pk,
544 mbedtls_ecp_keypair **p_ecp )
545{
546 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
547 return( PSA_ERROR_INVALID_ARGUMENT );
548 else
549 {
550 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
551 psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
552 if( actual_curve != expected_curve )
553 return( PSA_ERROR_INVALID_ARGUMENT );
554 *p_ecp = ecp;
555 return( PSA_SUCCESS );
556 }
557}
558#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
559
Gilles Peskinef76aa772018-10-29 19:24:33 +0100560#if defined(MBEDTLS_ECP_C)
561/* Import a private key given as a byte string which is the private value
562 * in big-endian order. */
563static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
564 const uint8_t *data,
565 size_t data_length,
566 mbedtls_ecp_keypair **p_ecp )
567{
568 psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
569 mbedtls_ecp_keypair *ecp = NULL;
570 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
571
572 *p_ecp = NULL;
573 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
574 if( ecp == NULL )
575 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Jaeden Amero83d29392019-01-10 20:17:42 +0000576 mbedtls_ecp_keypair_init( ecp );
Gilles Peskinef76aa772018-10-29 19:24:33 +0100577
578 /* Load the group. */
579 status = mbedtls_to_psa_error(
580 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
581 if( status != PSA_SUCCESS )
582 goto exit;
583 /* Load the secret value. */
584 status = mbedtls_to_psa_error(
585 mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
586 if( status != PSA_SUCCESS )
587 goto exit;
588 /* Validate the private key. */
589 status = mbedtls_to_psa_error(
590 mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
591 if( status != PSA_SUCCESS )
592 goto exit;
593 /* Calculate the public key from the private key. */
594 status = mbedtls_to_psa_error(
595 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
596 mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
597 if( status != PSA_SUCCESS )
598 goto exit;
599
600 *p_ecp = ecp;
601 return( PSA_SUCCESS );
602
603exit:
604 if( ecp != NULL )
605 {
606 mbedtls_ecp_keypair_free( ecp );
607 mbedtls_free( ecp );
608 }
609 return( status );
610}
611#endif /* defined(MBEDTLS_ECP_C) */
612
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100613/** Import key data into a slot. `slot->type` must have been set
614 * previously. This function assumes that the slot does not contain
615 * any key material yet. On failure, the slot content is unchanged. */
Gilles Peskinefa4135b2018-12-10 16:48:53 +0100616psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
617 const uint8_t *data,
618 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100619{
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200620 psa_status_t status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100621
Darryl Green940d72c2018-07-13 13:18:51 +0100622 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100623 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100624 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100625 if( data_length > SIZE_MAX / 8 )
626 return( PSA_ERROR_NOT_SUPPORTED );
Darryl Green940d72c2018-07-13 13:18:51 +0100627 status = prepare_raw_data_slot( slot->type,
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200628 PSA_BYTES_TO_BITS( data_length ),
629 &slot->data.raw );
630 if( status != PSA_SUCCESS )
631 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200632 if( data_length != 0 )
633 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100634 }
635 else
Gilles Peskinef76aa772018-10-29 19:24:33 +0100636#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100637 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100638 {
Darryl Green940d72c2018-07-13 13:18:51 +0100639 status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskinef76aa772018-10-29 19:24:33 +0100640 data, data_length,
641 &slot->data.ecp );
642 if( status != PSA_SUCCESS )
643 return( status );
644 }
645 else
646#endif /* MBEDTLS_ECP_C */
Gilles Peskine969ac722018-01-28 18:16:59 +0100647#if defined(MBEDTLS_PK_PARSE_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100648 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
649 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100650 {
651 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100652 mbedtls_pk_context pk;
653 mbedtls_pk_init( &pk );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200654
655 /* Parse the data. */
Darryl Green940d72c2018-07-13 13:18:51 +0100656 if( PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100657 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
658 else
659 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100660 if( ret != 0 )
661 return( mbedtls_to_psa_error( ret ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200662
663 /* We have something that the pkparse module recognizes.
664 * If it has the expected type and passes any type-specific
665 * checks, store it. */
Gilles Peskine969ac722018-01-28 18:16:59 +0100666#if defined(MBEDTLS_RSA_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100667 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200668 status = psa_import_rsa_key( &pk, &slot->data.rsa );
669 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100670#endif /* MBEDTLS_RSA_C */
671#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100672 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
673 status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200674 &pk, &slot->data.ecp );
675 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100676#endif /* MBEDTLS_ECP_C */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200677 {
678 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinec648d692018-06-28 08:46:13 +0200679 }
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200680
Gilles Peskinec648d692018-06-28 08:46:13 +0200681 /* Free the content of the pk object only on error. On success,
682 * the content of the object has been stored in the slot. */
683 if( status != PSA_SUCCESS )
684 {
685 mbedtls_pk_free( &pk );
686 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100687 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100688 }
689 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100690#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100691 {
692 return( PSA_ERROR_NOT_SUPPORTED );
693 }
Darryl Green940d72c2018-07-13 13:18:51 +0100694 return( PSA_SUCCESS );
695}
696
Darryl Green06fd18d2018-07-16 11:21:11 +0100697/* Retrieve an empty key slot (slot with no key data, but possibly
698 * with some metadata such as a policy). */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100699static psa_status_t psa_get_empty_key_slot( psa_key_handle_t handle,
Gilles Peskine2f060a82018-12-04 17:12:32 +0100700 psa_key_slot_t **p_slot )
Darryl Green06fd18d2018-07-16 11:21:11 +0100701{
702 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +0100703 psa_key_slot_t *slot = NULL;
Darryl Green06fd18d2018-07-16 11:21:11 +0100704
705 *p_slot = NULL;
706
Gilles Peskinec5487a82018-12-03 18:08:14 +0100707 status = psa_get_key_slot( handle, &slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100708 if( status != PSA_SUCCESS )
709 return( status );
710
711 if( slot->type != PSA_KEY_TYPE_NONE )
712 return( PSA_ERROR_OCCUPIED_SLOT );
713
714 *p_slot = slot;
715 return( status );
716}
717
718/** Retrieve a slot which must contain a key. The key must have allow all the
719 * usage flags set in \p usage. If \p alg is nonzero, the key must allow
720 * operations with this algorithm. */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100721static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle,
Gilles Peskine2f060a82018-12-04 17:12:32 +0100722 psa_key_slot_t **p_slot,
Darryl Green06fd18d2018-07-16 11:21:11 +0100723 psa_key_usage_t usage,
724 psa_algorithm_t alg )
725{
726 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +0100727 psa_key_slot_t *slot = NULL;
Darryl Green06fd18d2018-07-16 11:21:11 +0100728
729 *p_slot = NULL;
730
Gilles Peskinec5487a82018-12-03 18:08:14 +0100731 status = psa_get_key_slot( handle, &slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100732 if( status != PSA_SUCCESS )
733 return( status );
734 if( slot->type == PSA_KEY_TYPE_NONE )
735 return( PSA_ERROR_EMPTY_SLOT );
736
737 /* Enforce that usage policy for the key slot contains all the flags
738 * required by the usage parameter. There is one exception: public
739 * keys can always be exported, so we treat public key objects as
740 * if they had the export flag. */
741 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
742 usage &= ~PSA_KEY_USAGE_EXPORT;
743 if( ( slot->policy.usage & usage ) != usage )
744 return( PSA_ERROR_NOT_PERMITTED );
745 if( alg != 0 && ( alg != slot->policy.alg ) )
746 return( PSA_ERROR_NOT_PERMITTED );
747
748 *p_slot = slot;
749 return( PSA_SUCCESS );
750}
Darryl Green940d72c2018-07-13 13:18:51 +0100751
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100752/** Wipe key data from a slot. Preserve metadata such as the policy. */
Gilles Peskine2f060a82018-12-04 17:12:32 +0100753static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
Darryl Green40225ba2018-11-15 14:48:15 +0000754{
755 if( slot->type == PSA_KEY_TYPE_NONE )
756 {
757 /* No key material to clean. */
758 }
759 else if( key_type_is_raw_bytes( slot->type ) )
760 {
761 mbedtls_free( slot->data.raw.data );
762 }
763 else
764#if defined(MBEDTLS_RSA_C)
765 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
766 {
767 mbedtls_rsa_free( slot->data.rsa );
768 mbedtls_free( slot->data.rsa );
769 }
770 else
771#endif /* defined(MBEDTLS_RSA_C) */
772#if defined(MBEDTLS_ECP_C)
773 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
774 {
775 mbedtls_ecp_keypair_free( slot->data.ecp );
776 mbedtls_free( slot->data.ecp );
777 }
778 else
779#endif /* defined(MBEDTLS_ECP_C) */
780 {
781 /* Shouldn't happen: the key type is not any type that we
782 * put in. */
783 return( PSA_ERROR_TAMPERING_DETECTED );
784 }
785
786 return( PSA_SUCCESS );
787}
788
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100789/** Completely wipe a slot in memory, including its policy.
790 * Persistent storage is not affected. */
Gilles Peskine66fb1262018-12-10 16:29:04 +0100791psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot )
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100792{
793 psa_status_t status = psa_remove_key_data_from_memory( slot );
794 /* At this point, key material and other type-specific content has
795 * been wiped. Clear remaining metadata. We can call memset and not
796 * zeroize because the metadata is not particularly sensitive. */
797 memset( slot, 0, sizeof( *slot ) );
798 return( status );
799}
800
Gilles Peskinec5487a82018-12-03 18:08:14 +0100801psa_status_t psa_import_key( psa_key_handle_t handle,
Darryl Green940d72c2018-07-13 13:18:51 +0100802 psa_key_type_t type,
803 const uint8_t *data,
804 size_t data_length )
805{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100806 psa_key_slot_t *slot;
Darryl Green940d72c2018-07-13 13:18:51 +0100807 psa_status_t status;
808
Gilles Peskinec5487a82018-12-03 18:08:14 +0100809 status = psa_get_empty_key_slot( handle, &slot );
Darryl Green940d72c2018-07-13 13:18:51 +0100810 if( status != PSA_SUCCESS )
811 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100812
813 slot->type = type;
Darryl Green940d72c2018-07-13 13:18:51 +0100814
815 status = psa_import_key_into_slot( slot, data, data_length );
816 if( status != PSA_SUCCESS )
817 {
818 slot->type = PSA_KEY_TYPE_NONE;
819 return( status );
820 }
821
Darryl Greend49a4992018-06-18 17:27:26 +0100822#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
823 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
824 {
825 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +0100826 status = psa_save_persistent_key( slot->persistent_storage_id,
827 slot->type, &slot->policy, data,
Darryl Greend49a4992018-06-18 17:27:26 +0100828 data_length );
829 if( status != PSA_SUCCESS )
830 {
831 (void) psa_remove_key_data_from_memory( slot );
832 slot->type = PSA_KEY_TYPE_NONE;
833 }
834 }
835#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
836
837 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100838}
839
Gilles Peskinec5487a82018-12-03 18:08:14 +0100840psa_status_t psa_destroy_key( psa_key_handle_t handle )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100841{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100842 psa_key_slot_t *slot;
Darryl Greend49a4992018-06-18 17:27:26 +0100843 psa_status_t status = PSA_SUCCESS;
844 psa_status_t storage_status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100845
Gilles Peskinec5487a82018-12-03 18:08:14 +0100846 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200847 if( status != PSA_SUCCESS )
848 return( status );
Darryl Greend49a4992018-06-18 17:27:26 +0100849#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
850 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
851 {
Gilles Peskine69f976b2018-11-30 18:46:56 +0100852 storage_status =
853 psa_destroy_persistent_key( slot->persistent_storage_id );
Darryl Greend49a4992018-06-18 17:27:26 +0100854 }
855#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100856 status = psa_wipe_key_slot( slot );
Darryl Greend49a4992018-06-18 17:27:26 +0100857 if( status != PSA_SUCCESS )
858 return( status );
859 return( storage_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100860}
861
Gilles Peskineb870b182018-07-06 16:02:09 +0200862/* Return the size of the key in the given slot, in bits. */
Gilles Peskine2f060a82018-12-04 17:12:32 +0100863static size_t psa_get_key_bits( const psa_key_slot_t *slot )
Gilles Peskineb870b182018-07-06 16:02:09 +0200864{
865 if( key_type_is_raw_bytes( slot->type ) )
866 return( slot->data.raw.bytes * 8 );
867#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200868 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaac64a22018-11-12 18:37:42 +0100869 return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
Gilles Peskineb870b182018-07-06 16:02:09 +0200870#endif /* defined(MBEDTLS_RSA_C) */
871#if defined(MBEDTLS_ECP_C)
872 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
873 return( slot->data.ecp->grp.pbits );
874#endif /* defined(MBEDTLS_ECP_C) */
875 /* Shouldn't happen except on an empty slot. */
876 return( 0 );
877}
878
Gilles Peskinec5487a82018-12-03 18:08:14 +0100879psa_status_t psa_get_key_information( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +0200880 psa_key_type_t *type,
881 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100882{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100883 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200884 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100885
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100886 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200887 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100888 if( bits != NULL )
889 *bits = 0;
Gilles Peskinec5487a82018-12-03 18:08:14 +0100890 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200891 if( status != PSA_SUCCESS )
892 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +0200893
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100894 if( slot->type == PSA_KEY_TYPE_NONE )
895 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200896 if( type != NULL )
897 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +0200898 if( bits != NULL )
899 *bits = psa_get_key_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100900 return( PSA_SUCCESS );
901}
902
Jaeden Amero25384a22019-01-10 10:23:21 +0000903#if defined(MBEDTLS_RSA_C)
904static int pk_write_pubkey_simple( mbedtls_pk_context *key,
905 unsigned char *buf, size_t size )
906{
907 int ret;
908 unsigned char *c;
909 size_t len = 0;
910
911 c = buf + size;
912
913 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
914
915 return( (int) len );
916}
917#endif /* defined(MBEDTLS_RSA_C) */
918
Gilles Peskine2f060a82018-12-04 17:12:32 +0100919static psa_status_t psa_internal_export_key( psa_key_slot_t *slot,
Gilles Peskine2d277862018-06-18 15:41:12 +0200920 uint8_t *data,
921 size_t data_size,
922 size_t *data_length,
923 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100924{
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100925 *data_length = 0;
926
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200927 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300928 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300929
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200930 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100931 {
932 if( slot->data.raw.bytes > data_size )
933 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine52b90182018-10-29 19:26:27 +0100934 if( data_size != 0 )
935 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200936 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine52b90182018-10-29 19:26:27 +0100937 memset( data + slot->data.raw.bytes, 0,
938 data_size - slot->data.raw.bytes );
939 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100940 *data_length = slot->data.raw.bytes;
941 return( PSA_SUCCESS );
942 }
Gilles Peskine188c71e2018-10-29 19:26:02 +0100943#if defined(MBEDTLS_ECP_C)
944 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) && !export_public_key )
945 {
Darryl Greendd8fb772018-11-07 16:00:44 +0000946 psa_status_t status;
947
Gilles Peskine188c71e2018-10-29 19:26:02 +0100948 size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( slot ) );
949 if( bytes > data_size )
950 return( PSA_ERROR_BUFFER_TOO_SMALL );
951 status = mbedtls_to_psa_error(
952 mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
953 if( status != PSA_SUCCESS )
954 return( status );
955 memset( data + bytes, 0, data_size - bytes );
956 *data_length = bytes;
957 return( PSA_SUCCESS );
958 }
959#endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100960 else
Moran Peker17e36e12018-05-02 12:55:20 +0300961 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100962#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200963 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
Moran Pekera998bc62018-04-16 18:16:20 +0300964 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100965 {
Moran Pekera998bc62018-04-16 18:16:20 +0300966 mbedtls_pk_context pk;
967 int ret;
Gilles Peskined8008d62018-06-29 19:51:51 +0200968 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300969 {
Darryl Green9e2d7a02018-07-24 16:33:30 +0100970#if defined(MBEDTLS_RSA_C)
971 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +0300972 pk.pk_info = &mbedtls_rsa_info;
973 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +0100974#else
975 return( PSA_ERROR_NOT_SUPPORTED );
976#endif
Moran Pekera998bc62018-04-16 18:16:20 +0300977 }
978 else
979 {
Darryl Green9e2d7a02018-07-24 16:33:30 +0100980#if defined(MBEDTLS_ECP_C)
981 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +0300982 pk.pk_info = &mbedtls_eckey_info;
983 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +0100984#else
985 return( PSA_ERROR_NOT_SUPPORTED );
986#endif
Moran Pekera998bc62018-04-16 18:16:20 +0300987 }
Moran Pekerd7326592018-05-29 16:56:39 +0300988 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Jaeden Amero25384a22019-01-10 10:23:21 +0000989 {
990 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
991 {
992 ret = pk_write_pubkey_simple( &pk, data, data_size );
993 }
994 else
995 {
996 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
997 }
998 }
Moran Peker17e36e12018-05-02 12:55:20 +0300999 else
Jaeden Amero25384a22019-01-10 10:23:21 +00001000 {
Moran Peker17e36e12018-05-02 12:55:20 +03001001 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Jaeden Amero25384a22019-01-10 10:23:21 +00001002 }
Moran Peker60364322018-04-29 11:34:58 +03001003 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001004 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001005 /* If data_size is 0 then data may be NULL and then the
1006 * call to memset would have undefined behavior. */
1007 if( data_size != 0 )
1008 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +03001009 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001010 }
Gilles Peskine0e231582018-06-20 00:11:07 +02001011 /* The mbedtls_pk_xxx functions write to the end of the buffer.
1012 * Move the data to the beginning and erase remaining data
1013 * at the original location. */
1014 if( 2 * (size_t) ret <= data_size )
1015 {
1016 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001017 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001018 }
1019 else if( (size_t) ret < data_size )
1020 {
1021 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001022 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001023 }
Moran Pekera998bc62018-04-16 18:16:20 +03001024 *data_length = ret;
1025 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +01001026 }
1027 else
Gilles Peskine6d912132018-03-07 16:41:37 +01001028#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +03001029 {
1030 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +02001031 it is valid for a special-purpose implementation to omit
1032 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +03001033 return( PSA_ERROR_NOT_SUPPORTED );
1034 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001035 }
1036}
1037
Gilles Peskinec5487a82018-12-03 18:08:14 +01001038psa_status_t psa_export_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001039 uint8_t *data,
1040 size_t data_size,
1041 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001042{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001043 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001044 psa_status_t status;
1045
1046 /* Set the key to empty now, so that even when there are errors, we always
1047 * set data_length to a value between 0 and data_size. On error, setting
1048 * the key to empty is a good choice because an empty key representation is
1049 * unlikely to be accepted anywhere. */
1050 *data_length = 0;
1051
1052 /* Export requires the EXPORT flag. There is an exception for public keys,
1053 * which don't require any flag, but psa_get_key_from_slot takes
1054 * care of this. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001055 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_EXPORT, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001056 if( status != PSA_SUCCESS )
1057 return( status );
1058 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001059 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001060}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001061
Gilles Peskinec5487a82018-12-03 18:08:14 +01001062psa_status_t psa_export_public_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001063 uint8_t *data,
1064 size_t data_size,
1065 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001066{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001067 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001068 psa_status_t status;
1069
1070 /* Set the key to empty now, so that even when there are errors, we always
1071 * set data_length to a value between 0 and data_size. On error, setting
1072 * the key to empty is a good choice because an empty key representation is
1073 * unlikely to be accepted anywhere. */
1074 *data_length = 0;
1075
1076 /* Exporting a public key doesn't require a usage flag. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001077 status = psa_get_key_from_slot( handle, &slot, 0, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001078 if( status != PSA_SUCCESS )
1079 return( status );
1080 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001081 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001082}
1083
Darryl Green0c6575a2018-11-07 16:05:30 +00001084#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine2f060a82018-12-04 17:12:32 +01001085static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t *slot,
Darryl Green0c6575a2018-11-07 16:05:30 +00001086 size_t bits )
1087{
1088 psa_status_t status;
1089 uint8_t *data;
1090 size_t key_length;
1091 size_t data_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type, bits );
1092 data = mbedtls_calloc( 1, data_size );
itayzafrir910c76b2018-11-21 16:03:21 +02001093 if( data == NULL )
1094 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Darryl Green0c6575a2018-11-07 16:05:30 +00001095 /* Get key data in export format */
1096 status = psa_internal_export_key( slot, data, data_size, &key_length, 0 );
1097 if( status != PSA_SUCCESS )
1098 {
1099 slot->type = PSA_KEY_TYPE_NONE;
1100 goto exit;
1101 }
1102 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +01001103 status = psa_save_persistent_key( slot->persistent_storage_id,
1104 slot->type, &slot->policy,
Darryl Green0c6575a2018-11-07 16:05:30 +00001105 data, key_length );
1106 if( status != PSA_SUCCESS )
1107 {
1108 slot->type = PSA_KEY_TYPE_NONE;
1109 }
1110exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01001111 mbedtls_platform_zeroize( data, key_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00001112 mbedtls_free( data );
1113 return( status );
1114}
1115#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1116
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001117
1118
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001119/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01001120/* Message digests */
1121/****************************************************************/
1122
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001123static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01001124{
1125 switch( alg )
1126 {
1127#if defined(MBEDTLS_MD2_C)
1128 case PSA_ALG_MD2:
1129 return( &mbedtls_md2_info );
1130#endif
1131#if defined(MBEDTLS_MD4_C)
1132 case PSA_ALG_MD4:
1133 return( &mbedtls_md4_info );
1134#endif
1135#if defined(MBEDTLS_MD5_C)
1136 case PSA_ALG_MD5:
1137 return( &mbedtls_md5_info );
1138#endif
1139#if defined(MBEDTLS_RIPEMD160_C)
1140 case PSA_ALG_RIPEMD160:
1141 return( &mbedtls_ripemd160_info );
1142#endif
1143#if defined(MBEDTLS_SHA1_C)
1144 case PSA_ALG_SHA_1:
1145 return( &mbedtls_sha1_info );
1146#endif
1147#if defined(MBEDTLS_SHA256_C)
1148 case PSA_ALG_SHA_224:
1149 return( &mbedtls_sha224_info );
1150 case PSA_ALG_SHA_256:
1151 return( &mbedtls_sha256_info );
1152#endif
1153#if defined(MBEDTLS_SHA512_C)
1154 case PSA_ALG_SHA_384:
1155 return( &mbedtls_sha384_info );
1156 case PSA_ALG_SHA_512:
1157 return( &mbedtls_sha512_info );
1158#endif
1159 default:
1160 return( NULL );
1161 }
1162}
1163
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001164psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
1165{
1166 switch( operation->alg )
1167 {
Gilles Peskine81736312018-06-26 15:04:31 +02001168 case 0:
1169 /* The object has (apparently) been initialized but it is not
1170 * in use. It's ok to call abort on such an object, and there's
1171 * nothing to do. */
1172 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001173#if defined(MBEDTLS_MD2_C)
1174 case PSA_ALG_MD2:
1175 mbedtls_md2_free( &operation->ctx.md2 );
1176 break;
1177#endif
1178#if defined(MBEDTLS_MD4_C)
1179 case PSA_ALG_MD4:
1180 mbedtls_md4_free( &operation->ctx.md4 );
1181 break;
1182#endif
1183#if defined(MBEDTLS_MD5_C)
1184 case PSA_ALG_MD5:
1185 mbedtls_md5_free( &operation->ctx.md5 );
1186 break;
1187#endif
1188#if defined(MBEDTLS_RIPEMD160_C)
1189 case PSA_ALG_RIPEMD160:
1190 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
1191 break;
1192#endif
1193#if defined(MBEDTLS_SHA1_C)
1194 case PSA_ALG_SHA_1:
1195 mbedtls_sha1_free( &operation->ctx.sha1 );
1196 break;
1197#endif
1198#if defined(MBEDTLS_SHA256_C)
1199 case PSA_ALG_SHA_224:
1200 case PSA_ALG_SHA_256:
1201 mbedtls_sha256_free( &operation->ctx.sha256 );
1202 break;
1203#endif
1204#if defined(MBEDTLS_SHA512_C)
1205 case PSA_ALG_SHA_384:
1206 case PSA_ALG_SHA_512:
1207 mbedtls_sha512_free( &operation->ctx.sha512 );
1208 break;
1209#endif
1210 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001211 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001212 }
1213 operation->alg = 0;
1214 return( PSA_SUCCESS );
1215}
1216
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02001217psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001218 psa_algorithm_t alg )
1219{
1220 int ret;
1221 operation->alg = 0;
1222 switch( alg )
1223 {
1224#if defined(MBEDTLS_MD2_C)
1225 case PSA_ALG_MD2:
1226 mbedtls_md2_init( &operation->ctx.md2 );
1227 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
1228 break;
1229#endif
1230#if defined(MBEDTLS_MD4_C)
1231 case PSA_ALG_MD4:
1232 mbedtls_md4_init( &operation->ctx.md4 );
1233 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
1234 break;
1235#endif
1236#if defined(MBEDTLS_MD5_C)
1237 case PSA_ALG_MD5:
1238 mbedtls_md5_init( &operation->ctx.md5 );
1239 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
1240 break;
1241#endif
1242#if defined(MBEDTLS_RIPEMD160_C)
1243 case PSA_ALG_RIPEMD160:
1244 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
1245 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
1246 break;
1247#endif
1248#if defined(MBEDTLS_SHA1_C)
1249 case PSA_ALG_SHA_1:
1250 mbedtls_sha1_init( &operation->ctx.sha1 );
1251 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
1252 break;
1253#endif
1254#if defined(MBEDTLS_SHA256_C)
1255 case PSA_ALG_SHA_224:
1256 mbedtls_sha256_init( &operation->ctx.sha256 );
1257 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
1258 break;
1259 case PSA_ALG_SHA_256:
1260 mbedtls_sha256_init( &operation->ctx.sha256 );
1261 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
1262 break;
1263#endif
1264#if defined(MBEDTLS_SHA512_C)
1265 case PSA_ALG_SHA_384:
1266 mbedtls_sha512_init( &operation->ctx.sha512 );
1267 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
1268 break;
1269 case PSA_ALG_SHA_512:
1270 mbedtls_sha512_init( &operation->ctx.sha512 );
1271 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1272 break;
1273#endif
1274 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001275 return( PSA_ALG_IS_HASH( alg ) ?
1276 PSA_ERROR_NOT_SUPPORTED :
1277 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001278 }
1279 if( ret == 0 )
1280 operation->alg = alg;
1281 else
1282 psa_hash_abort( operation );
1283 return( mbedtls_to_psa_error( ret ) );
1284}
1285
1286psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1287 const uint8_t *input,
1288 size_t input_length )
1289{
1290 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001291
1292 /* Don't require hash implementations to behave correctly on a
1293 * zero-length input, which may have an invalid pointer. */
1294 if( input_length == 0 )
1295 return( PSA_SUCCESS );
1296
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001297 switch( operation->alg )
1298 {
1299#if defined(MBEDTLS_MD2_C)
1300 case PSA_ALG_MD2:
1301 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1302 input, input_length );
1303 break;
1304#endif
1305#if defined(MBEDTLS_MD4_C)
1306 case PSA_ALG_MD4:
1307 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1308 input, input_length );
1309 break;
1310#endif
1311#if defined(MBEDTLS_MD5_C)
1312 case PSA_ALG_MD5:
1313 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1314 input, input_length );
1315 break;
1316#endif
1317#if defined(MBEDTLS_RIPEMD160_C)
1318 case PSA_ALG_RIPEMD160:
1319 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1320 input, input_length );
1321 break;
1322#endif
1323#if defined(MBEDTLS_SHA1_C)
1324 case PSA_ALG_SHA_1:
1325 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1326 input, input_length );
1327 break;
1328#endif
1329#if defined(MBEDTLS_SHA256_C)
1330 case PSA_ALG_SHA_224:
1331 case PSA_ALG_SHA_256:
1332 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1333 input, input_length );
1334 break;
1335#endif
1336#if defined(MBEDTLS_SHA512_C)
1337 case PSA_ALG_SHA_384:
1338 case PSA_ALG_SHA_512:
1339 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1340 input, input_length );
1341 break;
1342#endif
1343 default:
1344 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1345 break;
1346 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001347
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001348 if( ret != 0 )
1349 psa_hash_abort( operation );
1350 return( mbedtls_to_psa_error( ret ) );
1351}
1352
1353psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1354 uint8_t *hash,
1355 size_t hash_size,
1356 size_t *hash_length )
1357{
itayzafrir40835d42018-08-02 13:14:17 +03001358 psa_status_t status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001359 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001360 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001361
1362 /* Fill the output buffer with something that isn't a valid hash
1363 * (barring an attack on the hash and deliberately-crafted input),
1364 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001365 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001366 /* If hash_size is 0 then hash may be NULL and then the
1367 * call to memset would have undefined behavior. */
1368 if( hash_size != 0 )
1369 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001370
1371 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03001372 {
1373 status = PSA_ERROR_BUFFER_TOO_SMALL;
1374 goto exit;
1375 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001376
1377 switch( operation->alg )
1378 {
1379#if defined(MBEDTLS_MD2_C)
1380 case PSA_ALG_MD2:
1381 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1382 break;
1383#endif
1384#if defined(MBEDTLS_MD4_C)
1385 case PSA_ALG_MD4:
1386 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1387 break;
1388#endif
1389#if defined(MBEDTLS_MD5_C)
1390 case PSA_ALG_MD5:
1391 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1392 break;
1393#endif
1394#if defined(MBEDTLS_RIPEMD160_C)
1395 case PSA_ALG_RIPEMD160:
1396 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1397 break;
1398#endif
1399#if defined(MBEDTLS_SHA1_C)
1400 case PSA_ALG_SHA_1:
1401 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1402 break;
1403#endif
1404#if defined(MBEDTLS_SHA256_C)
1405 case PSA_ALG_SHA_224:
1406 case PSA_ALG_SHA_256:
1407 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1408 break;
1409#endif
1410#if defined(MBEDTLS_SHA512_C)
1411 case PSA_ALG_SHA_384:
1412 case PSA_ALG_SHA_512:
1413 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1414 break;
1415#endif
1416 default:
1417 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1418 break;
1419 }
itayzafrir40835d42018-08-02 13:14:17 +03001420 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001421
itayzafrir40835d42018-08-02 13:14:17 +03001422exit:
1423 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001424 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001425 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001426 return( psa_hash_abort( operation ) );
1427 }
1428 else
1429 {
1430 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03001431 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001432 }
1433}
1434
Gilles Peskine2d277862018-06-18 15:41:12 +02001435psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1436 const uint8_t *hash,
1437 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001438{
1439 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1440 size_t actual_hash_length;
1441 psa_status_t status = psa_hash_finish( operation,
1442 actual_hash, sizeof( actual_hash ),
1443 &actual_hash_length );
1444 if( status != PSA_SUCCESS )
1445 return( status );
1446 if( actual_hash_length != hash_length )
1447 return( PSA_ERROR_INVALID_SIGNATURE );
1448 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1449 return( PSA_ERROR_INVALID_SIGNATURE );
1450 return( PSA_SUCCESS );
1451}
1452
1453
1454
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001455/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001456/* MAC */
1457/****************************************************************/
1458
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001459static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001460 psa_algorithm_t alg,
1461 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001462 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001463 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001464{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001465 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001466 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001467
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001468 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001469 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001470
Gilles Peskine8c9def32018-02-08 10:02:12 +01001471 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1472 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001473 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001474 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001475 case PSA_ALG_ARC4:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001476 mode = MBEDTLS_MODE_STREAM;
1477 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001478 case PSA_ALG_CTR:
1479 mode = MBEDTLS_MODE_CTR;
1480 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001481 case PSA_ALG_CFB:
1482 mode = MBEDTLS_MODE_CFB;
1483 break;
1484 case PSA_ALG_OFB:
1485 mode = MBEDTLS_MODE_OFB;
1486 break;
1487 case PSA_ALG_CBC_NO_PADDING:
1488 mode = MBEDTLS_MODE_CBC;
1489 break;
1490 case PSA_ALG_CBC_PKCS7:
1491 mode = MBEDTLS_MODE_CBC;
1492 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001493 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001494 mode = MBEDTLS_MODE_CCM;
1495 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001496 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001497 mode = MBEDTLS_MODE_GCM;
1498 break;
1499 default:
1500 return( NULL );
1501 }
1502 }
1503 else if( alg == PSA_ALG_CMAC )
1504 mode = MBEDTLS_MODE_ECB;
1505 else if( alg == PSA_ALG_GMAC )
1506 mode = MBEDTLS_MODE_GCM;
1507 else
1508 return( NULL );
1509
1510 switch( key_type )
1511 {
1512 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001513 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001514 break;
1515 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001516 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1517 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001518 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001519 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001520 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001521 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001522 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1523 * but two-key Triple-DES is functionally three-key Triple-DES
1524 * with K1=K3, so that's how we present it to mbedtls. */
1525 if( key_bits == 128 )
1526 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001527 break;
1528 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001529 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001530 break;
1531 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001532 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001533 break;
1534 default:
1535 return( NULL );
1536 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001537 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001538 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001539
Jaeden Amero23bbb752018-06-26 14:16:54 +01001540 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1541 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001542}
1543
Gilles Peskinea05219c2018-11-16 16:02:56 +01001544#if defined(MBEDTLS_MD_C)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001545static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001546{
Gilles Peskine2d277862018-06-18 15:41:12 +02001547 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001548 {
1549 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001550 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001551 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001552 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001553 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001554 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001555 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001556 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001557 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001558 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001559 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001560 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001561 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001562 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001563 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001564 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001565 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001566 return( 128 );
1567 default:
1568 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001569 }
1570}
Gilles Peskinea05219c2018-11-16 16:02:56 +01001571#endif /* MBEDTLS_MD_C */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001572
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001573/* Initialize the MAC operation structure. Once this function has been
1574 * called, psa_mac_abort can run and will do the right thing. */
1575static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1576 psa_algorithm_t alg )
1577{
1578 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1579
1580 operation->alg = alg;
1581 operation->key_set = 0;
1582 operation->iv_set = 0;
1583 operation->iv_required = 0;
1584 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001585 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001586
1587#if defined(MBEDTLS_CMAC_C)
1588 if( alg == PSA_ALG_CMAC )
1589 {
1590 operation->iv_required = 0;
1591 mbedtls_cipher_init( &operation->ctx.cmac );
1592 status = PSA_SUCCESS;
1593 }
1594 else
1595#endif /* MBEDTLS_CMAC_C */
1596#if defined(MBEDTLS_MD_C)
1597 if( PSA_ALG_IS_HMAC( operation->alg ) )
1598 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02001599 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
1600 operation->ctx.hmac.hash_ctx.alg = 0;
1601 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001602 }
1603 else
1604#endif /* MBEDTLS_MD_C */
1605 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001606 if( ! PSA_ALG_IS_MAC( alg ) )
1607 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001608 }
1609
1610 if( status != PSA_SUCCESS )
1611 memset( operation, 0, sizeof( *operation ) );
1612 return( status );
1613}
1614
Gilles Peskine01126fa2018-07-12 17:04:55 +02001615#if defined(MBEDTLS_MD_C)
1616static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
1617{
Gilles Peskine3f108122018-12-07 18:14:53 +01001618 mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001619 return( psa_hash_abort( &hmac->hash_ctx ) );
1620}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01001621
1622static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
1623{
1624 /* Instances of psa_hash_operation_s can be initialized by zeroization. */
1625 memset( hmac, 0, sizeof( *hmac ) );
1626}
Gilles Peskine01126fa2018-07-12 17:04:55 +02001627#endif /* MBEDTLS_MD_C */
1628
Gilles Peskine8c9def32018-02-08 10:02:12 +01001629psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1630{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001631 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001632 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001633 /* The object has (apparently) been initialized but it is not
1634 * in use. It's ok to call abort on such an object, and there's
1635 * nothing to do. */
1636 return( PSA_SUCCESS );
1637 }
1638 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001639#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001640 if( operation->alg == PSA_ALG_CMAC )
1641 {
1642 mbedtls_cipher_free( &operation->ctx.cmac );
1643 }
1644 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001645#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001646#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001647 if( PSA_ALG_IS_HMAC( operation->alg ) )
1648 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001649 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001650 }
1651 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001652#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001653 {
1654 /* Sanity check (shouldn't happen: operation->alg should
1655 * always have been initialized to a valid value). */
1656 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001657 }
Moran Peker41deec42018-04-04 15:43:05 +03001658
Gilles Peskine8c9def32018-02-08 10:02:12 +01001659 operation->alg = 0;
1660 operation->key_set = 0;
1661 operation->iv_set = 0;
1662 operation->iv_required = 0;
1663 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001664 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001665
Gilles Peskine8c9def32018-02-08 10:02:12 +01001666 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001667
1668bad_state:
1669 /* If abort is called on an uninitialized object, we can't trust
1670 * anything. Wipe the object in case it contains confidential data.
1671 * This may result in a memory leak if a pointer gets overwritten,
1672 * but it's too late to do anything about this. */
1673 memset( operation, 0, sizeof( *operation ) );
1674 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001675}
1676
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001677#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02001678static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001679 size_t key_bits,
Gilles Peskine2f060a82018-12-04 17:12:32 +01001680 psa_key_slot_t *slot,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001681 const mbedtls_cipher_info_t *cipher_info )
1682{
1683 int ret;
1684
1685 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001686
1687 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1688 if( ret != 0 )
1689 return( ret );
1690
1691 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1692 slot->data.raw.data,
1693 key_bits );
1694 return( ret );
1695}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001696#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001697
Gilles Peskine248051a2018-06-20 16:09:38 +02001698#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02001699static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
1700 const uint8_t *key,
1701 size_t key_length,
1702 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001703{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001704 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001705 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001706 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001707 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001708 psa_status_t status;
1709
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001710 /* Sanity checks on block_size, to guarantee that there won't be a buffer
1711 * overflow below. This should never trigger if the hash algorithm
1712 * is implemented correctly. */
1713 /* The size checks against the ipad and opad buffers cannot be written
1714 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
1715 * because that triggers -Wlogical-op on GCC 7.3. */
1716 if( block_size > sizeof( ipad ) )
1717 return( PSA_ERROR_NOT_SUPPORTED );
1718 if( block_size > sizeof( hmac->opad ) )
1719 return( PSA_ERROR_NOT_SUPPORTED );
1720 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001721 return( PSA_ERROR_NOT_SUPPORTED );
1722
Gilles Peskined223b522018-06-11 18:12:58 +02001723 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001724 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001725 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001726 if( status != PSA_SUCCESS )
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001727 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001728 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001729 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001730 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001731 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001732 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001733 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001734 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001735 }
Gilles Peskine96889972018-07-12 17:07:03 +02001736 /* A 0-length key is not commonly used in HMAC when used as a MAC,
1737 * but it is permitted. It is common when HMAC is used in HKDF, for
1738 * example. Don't call `memcpy` in the 0-length because `key` could be
1739 * an invalid pointer which would make the behavior undefined. */
1740 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001741 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001742
Gilles Peskined223b522018-06-11 18:12:58 +02001743 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1744 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001745 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001746 ipad[i] ^= 0x36;
1747 memset( ipad + key_length, 0x36, block_size - key_length );
1748
1749 /* Copy the key material from ipad to opad, flipping the requisite bits,
1750 * and filling the rest of opad with the requisite constant. */
1751 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001752 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1753 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001754
Gilles Peskine01126fa2018-07-12 17:04:55 +02001755 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001756 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001757 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001758
Gilles Peskine01126fa2018-07-12 17:04:55 +02001759 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001760
1761cleanup:
Gilles Peskine3f108122018-12-07 18:14:53 +01001762 mbedtls_platform_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001763
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001764 return( status );
1765}
Gilles Peskine248051a2018-06-20 16:09:38 +02001766#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001767
Gilles Peskine89167cb2018-07-08 20:12:23 +02001768static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001769 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001770 psa_algorithm_t alg,
1771 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001772{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001773 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001774 psa_key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001775 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001776 psa_key_usage_t usage =
1777 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskined911eb72018-08-14 15:18:45 +02001778 unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02001779 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001780
Gilles Peskined911eb72018-08-14 15:18:45 +02001781 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001782 if( status != PSA_SUCCESS )
1783 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001784 if( is_sign )
1785 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001786
Gilles Peskinec5487a82018-12-03 18:08:14 +01001787 status = psa_get_key_from_slot( handle, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001788 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001789 goto exit;
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02001790 key_bits = psa_get_key_bits( slot );
1791
Gilles Peskine8c9def32018-02-08 10:02:12 +01001792#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001793 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001794 {
1795 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02001796 mbedtls_cipher_info_from_psa( full_length_alg,
1797 slot->type, key_bits, NULL );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001798 int ret;
1799 if( cipher_info == NULL )
1800 {
1801 status = PSA_ERROR_NOT_SUPPORTED;
1802 goto exit;
1803 }
1804 operation->mac_size = cipher_info->block_size;
1805 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
1806 status = mbedtls_to_psa_error( ret );
1807 }
1808 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001809#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001810#if defined(MBEDTLS_MD_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001811 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001812 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02001813 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001814 if( hash_alg == 0 )
1815 {
1816 status = PSA_ERROR_NOT_SUPPORTED;
1817 goto exit;
1818 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001819
1820 operation->mac_size = PSA_HASH_SIZE( hash_alg );
1821 /* Sanity check. This shouldn't fail on a valid configuration. */
1822 if( operation->mac_size == 0 ||
1823 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
1824 {
1825 status = PSA_ERROR_NOT_SUPPORTED;
1826 goto exit;
1827 }
1828
Gilles Peskine01126fa2018-07-12 17:04:55 +02001829 if( slot->type != PSA_KEY_TYPE_HMAC )
1830 {
1831 status = PSA_ERROR_INVALID_ARGUMENT;
1832 goto exit;
1833 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001834
Gilles Peskine01126fa2018-07-12 17:04:55 +02001835 status = psa_hmac_setup_internal( &operation->ctx.hmac,
1836 slot->data.raw.data,
1837 slot->data.raw.bytes,
1838 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001839 }
1840 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001841#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001842 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00001843 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02001844 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001845 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001846
Gilles Peskined911eb72018-08-14 15:18:45 +02001847 if( truncated == 0 )
1848 {
1849 /* The "normal" case: untruncated algorithm. Nothing to do. */
1850 }
1851 else if( truncated < 4 )
1852 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02001853 /* A very short MAC is too short for security since it can be
1854 * brute-forced. Ancient protocols with 32-bit MACs do exist,
1855 * so we make this our minimum, even though 32 bits is still
1856 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02001857 status = PSA_ERROR_NOT_SUPPORTED;
1858 }
1859 else if( truncated > operation->mac_size )
1860 {
1861 /* It's impossible to "truncate" to a larger length. */
1862 status = PSA_ERROR_INVALID_ARGUMENT;
1863 }
1864 else
1865 operation->mac_size = truncated;
1866
Gilles Peskinefbfac682018-07-08 20:51:54 +02001867exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001868 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001869 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001870 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001871 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001872 else
1873 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001874 operation->key_set = 1;
1875 }
1876 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001877}
1878
Gilles Peskine89167cb2018-07-08 20:12:23 +02001879psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001880 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001881 psa_algorithm_t alg )
1882{
Gilles Peskinec5487a82018-12-03 18:08:14 +01001883 return( psa_mac_setup( operation, handle, alg, 1 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001884}
1885
1886psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001887 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001888 psa_algorithm_t alg )
1889{
Gilles Peskinec5487a82018-12-03 18:08:14 +01001890 return( psa_mac_setup( operation, handle, alg, 0 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001891}
1892
Gilles Peskine8c9def32018-02-08 10:02:12 +01001893psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1894 const uint8_t *input,
1895 size_t input_length )
1896{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001897 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001898 if( ! operation->key_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001899 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001900 if( operation->iv_required && ! operation->iv_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001901 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001902 operation->has_input = 1;
1903
Gilles Peskine8c9def32018-02-08 10:02:12 +01001904#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001905 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001906 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001907 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1908 input, input_length );
1909 status = mbedtls_to_psa_error( ret );
1910 }
1911 else
1912#endif /* MBEDTLS_CMAC_C */
1913#if defined(MBEDTLS_MD_C)
1914 if( PSA_ALG_IS_HMAC( operation->alg ) )
1915 {
1916 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
1917 input_length );
1918 }
1919 else
1920#endif /* MBEDTLS_MD_C */
1921 {
1922 /* This shouldn't happen if `operation` was initialized by
1923 * a setup function. */
1924 status = PSA_ERROR_BAD_STATE;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001925 }
1926
Gilles Peskinefbfac682018-07-08 20:51:54 +02001927cleanup:
1928 if( status != PSA_SUCCESS )
1929 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001930 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001931}
1932
Gilles Peskine01126fa2018-07-12 17:04:55 +02001933#if defined(MBEDTLS_MD_C)
1934static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
1935 uint8_t *mac,
1936 size_t mac_size )
1937{
1938 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
1939 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
1940 size_t hash_size = 0;
1941 size_t block_size = psa_get_hash_block_size( hash_alg );
1942 psa_status_t status;
1943
Gilles Peskine01126fa2018-07-12 17:04:55 +02001944 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1945 if( status != PSA_SUCCESS )
1946 return( status );
1947 /* From here on, tmp needs to be wiped. */
1948
1949 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
1950 if( status != PSA_SUCCESS )
1951 goto exit;
1952
1953 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
1954 if( status != PSA_SUCCESS )
1955 goto exit;
1956
1957 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
1958 if( status != PSA_SUCCESS )
1959 goto exit;
1960
Gilles Peskined911eb72018-08-14 15:18:45 +02001961 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1962 if( status != PSA_SUCCESS )
1963 goto exit;
1964
1965 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001966
1967exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01001968 mbedtls_platform_zeroize( tmp, hash_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001969 return( status );
1970}
1971#endif /* MBEDTLS_MD_C */
1972
mohammad16036df908f2018-04-02 08:34:15 -07001973static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001974 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001975 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001976{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02001977 if( ! operation->key_set )
1978 return( PSA_ERROR_BAD_STATE );
1979 if( operation->iv_required && ! operation->iv_set )
1980 return( PSA_ERROR_BAD_STATE );
1981
Gilles Peskine8c9def32018-02-08 10:02:12 +01001982 if( mac_size < operation->mac_size )
1983 return( PSA_ERROR_BUFFER_TOO_SMALL );
1984
Gilles Peskine8c9def32018-02-08 10:02:12 +01001985#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001986 if( operation->alg == PSA_ALG_CMAC )
1987 {
Gilles Peskined911eb72018-08-14 15:18:45 +02001988 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
1989 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
1990 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02001991 memcpy( mac, tmp, operation->mac_size );
Gilles Peskine3f108122018-12-07 18:14:53 +01001992 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001993 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001994 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02001995 else
1996#endif /* MBEDTLS_CMAC_C */
1997#if defined(MBEDTLS_MD_C)
1998 if( PSA_ALG_IS_HMAC( operation->alg ) )
1999 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002000 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02002001 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002002 }
2003 else
2004#endif /* MBEDTLS_MD_C */
2005 {
2006 /* This shouldn't happen if `operation` was initialized by
2007 * a setup function. */
2008 return( PSA_ERROR_BAD_STATE );
2009 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01002010}
2011
Gilles Peskineacd4be32018-07-08 19:56:25 +02002012psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
2013 uint8_t *mac,
2014 size_t mac_size,
2015 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07002016{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002017 psa_status_t status;
2018
2019 /* Fill the output buffer with something that isn't a valid mac
2020 * (barring an attack on the mac and deliberately-crafted input),
2021 * in case the caller doesn't check the return status properly. */
2022 *mac_length = mac_size;
2023 /* If mac_size is 0 then mac may be NULL and then the
2024 * call to memset would have undefined behavior. */
2025 if( mac_size != 0 )
2026 memset( mac, '!', mac_size );
2027
Gilles Peskine89167cb2018-07-08 20:12:23 +02002028 if( ! operation->is_sign )
2029 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002030 status = PSA_ERROR_BAD_STATE;
2031 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002032 }
mohammad16036df908f2018-04-02 08:34:15 -07002033
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002034 status = psa_mac_finish_internal( operation, mac, mac_size );
2035
2036cleanup:
2037 if( status == PSA_SUCCESS )
2038 {
2039 status = psa_mac_abort( operation );
2040 if( status == PSA_SUCCESS )
2041 *mac_length = operation->mac_size;
2042 else
2043 memset( mac, '!', mac_size );
2044 }
2045 else
2046 psa_mac_abort( operation );
2047 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07002048}
2049
Gilles Peskineacd4be32018-07-08 19:56:25 +02002050psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
2051 const uint8_t *mac,
2052 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002053{
Gilles Peskine828ed142018-06-18 23:25:51 +02002054 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07002055 psa_status_t status;
2056
Gilles Peskine89167cb2018-07-08 20:12:23 +02002057 if( operation->is_sign )
2058 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002059 status = PSA_ERROR_BAD_STATE;
2060 goto cleanup;
2061 }
2062 if( operation->mac_size != mac_length )
2063 {
2064 status = PSA_ERROR_INVALID_SIGNATURE;
2065 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002066 }
mohammad16036df908f2018-04-02 08:34:15 -07002067
2068 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002069 actual_mac, sizeof( actual_mac ) );
2070
2071 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
2072 status = PSA_ERROR_INVALID_SIGNATURE;
2073
2074cleanup:
2075 if( status == PSA_SUCCESS )
2076 status = psa_mac_abort( operation );
2077 else
2078 psa_mac_abort( operation );
2079
Gilles Peskine3f108122018-12-07 18:14:53 +01002080 mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02002081
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002082 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002083}
2084
2085
Gilles Peskine20035e32018-02-03 22:44:14 +01002086
Gilles Peskine20035e32018-02-03 22:44:14 +01002087/****************************************************************/
2088/* Asymmetric cryptography */
2089/****************************************************************/
2090
Gilles Peskine2b450e32018-06-27 15:42:46 +02002091#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002092/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002093 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002094static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
2095 size_t hash_length,
2096 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002097{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02002098 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002099 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002100 *md_alg = mbedtls_md_get_type( md_info );
2101
2102 /* The Mbed TLS RSA module uses an unsigned int for hash length
2103 * parameters. Validate that it fits so that we don't risk an
2104 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002105#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002106 if( hash_length > UINT_MAX )
2107 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002108#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002109
2110#if defined(MBEDTLS_PKCS1_V15)
2111 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
2112 * must be correct. */
2113 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
2114 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002115 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002116 if( md_info == NULL )
2117 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002118 if( mbedtls_md_get_size( md_info ) != hash_length )
2119 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002120 }
2121#endif /* MBEDTLS_PKCS1_V15 */
2122
2123#if defined(MBEDTLS_PKCS1_V21)
2124 /* PSS requires a hash internally. */
2125 if( PSA_ALG_IS_RSA_PSS( alg ) )
2126 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002127 if( md_info == NULL )
2128 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002129 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002130#endif /* MBEDTLS_PKCS1_V21 */
2131
Gilles Peskine61b91d42018-06-08 16:09:36 +02002132 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002133}
2134
Gilles Peskine2b450e32018-06-27 15:42:46 +02002135static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
2136 psa_algorithm_t alg,
2137 const uint8_t *hash,
2138 size_t hash_length,
2139 uint8_t *signature,
2140 size_t signature_size,
2141 size_t *signature_length )
2142{
2143 psa_status_t status;
2144 int ret;
2145 mbedtls_md_type_t md_alg;
2146
2147 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2148 if( status != PSA_SUCCESS )
2149 return( status );
2150
Gilles Peskine630a18a2018-06-29 17:49:35 +02002151 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002152 return( PSA_ERROR_BUFFER_TOO_SMALL );
2153
2154#if defined(MBEDTLS_PKCS1_V15)
2155 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2156 {
2157 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2158 MBEDTLS_MD_NONE );
2159 ret = mbedtls_rsa_pkcs1_sign( rsa,
2160 mbedtls_ctr_drbg_random,
2161 &global_data.ctr_drbg,
2162 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002163 md_alg,
2164 (unsigned int) hash_length,
2165 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002166 signature );
2167 }
2168 else
2169#endif /* MBEDTLS_PKCS1_V15 */
2170#if defined(MBEDTLS_PKCS1_V21)
2171 if( PSA_ALG_IS_RSA_PSS( alg ) )
2172 {
2173 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2174 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
2175 mbedtls_ctr_drbg_random,
2176 &global_data.ctr_drbg,
2177 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002178 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002179 (unsigned int) hash_length,
2180 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002181 signature );
2182 }
2183 else
2184#endif /* MBEDTLS_PKCS1_V21 */
2185 {
2186 return( PSA_ERROR_INVALID_ARGUMENT );
2187 }
2188
2189 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002190 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002191 return( mbedtls_to_psa_error( ret ) );
2192}
2193
2194static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
2195 psa_algorithm_t alg,
2196 const uint8_t *hash,
2197 size_t hash_length,
2198 const uint8_t *signature,
2199 size_t signature_length )
2200{
2201 psa_status_t status;
2202 int ret;
2203 mbedtls_md_type_t md_alg;
2204
2205 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2206 if( status != PSA_SUCCESS )
2207 return( status );
2208
Gilles Peskine630a18a2018-06-29 17:49:35 +02002209 if( signature_length < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002210 return( PSA_ERROR_BUFFER_TOO_SMALL );
2211
2212#if defined(MBEDTLS_PKCS1_V15)
2213 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2214 {
2215 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2216 MBEDTLS_MD_NONE );
2217 ret = mbedtls_rsa_pkcs1_verify( rsa,
2218 mbedtls_ctr_drbg_random,
2219 &global_data.ctr_drbg,
2220 MBEDTLS_RSA_PUBLIC,
2221 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002222 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002223 hash,
2224 signature );
2225 }
2226 else
2227#endif /* MBEDTLS_PKCS1_V15 */
2228#if defined(MBEDTLS_PKCS1_V21)
2229 if( PSA_ALG_IS_RSA_PSS( alg ) )
2230 {
2231 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2232 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
2233 mbedtls_ctr_drbg_random,
2234 &global_data.ctr_drbg,
2235 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002236 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002237 (unsigned int) hash_length,
2238 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002239 signature );
2240 }
2241 else
2242#endif /* MBEDTLS_PKCS1_V21 */
2243 {
2244 return( PSA_ERROR_INVALID_ARGUMENT );
2245 }
Gilles Peskineef12c632018-09-13 20:37:48 +02002246
2247 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
2248 * the rest of the signature is invalid". This has little use in
2249 * practice and PSA doesn't report this distinction. */
2250 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
2251 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002252 return( mbedtls_to_psa_error( ret ) );
2253}
2254#endif /* MBEDTLS_RSA_C */
2255
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002256#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002257/* `ecp` cannot be const because `ecp->grp` needs to be non-const
2258 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
2259 * (even though these functions don't modify it). */
2260static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
2261 psa_algorithm_t alg,
2262 const uint8_t *hash,
2263 size_t hash_length,
2264 uint8_t *signature,
2265 size_t signature_size,
2266 size_t *signature_length )
2267{
2268 int ret;
2269 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002270 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002271 mbedtls_mpi_init( &r );
2272 mbedtls_mpi_init( &s );
2273
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002274 if( signature_size < 2 * curve_bytes )
2275 {
2276 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
2277 goto cleanup;
2278 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002279
Gilles Peskinea05219c2018-11-16 16:02:56 +01002280#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002281 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
2282 {
2283 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
2284 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2285 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2286 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
2287 hash, hash_length,
2288 md_alg ) );
2289 }
2290 else
Gilles Peskinea05219c2018-11-16 16:02:56 +01002291#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002292 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01002293 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002294 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
2295 hash, hash_length,
2296 mbedtls_ctr_drbg_random,
2297 &global_data.ctr_drbg ) );
2298 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002299
2300 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
2301 signature,
2302 curve_bytes ) );
2303 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
2304 signature + curve_bytes,
2305 curve_bytes ) );
2306
2307cleanup:
2308 mbedtls_mpi_free( &r );
2309 mbedtls_mpi_free( &s );
2310 if( ret == 0 )
2311 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002312 return( mbedtls_to_psa_error( ret ) );
2313}
2314
2315static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
2316 const uint8_t *hash,
2317 size_t hash_length,
2318 const uint8_t *signature,
2319 size_t signature_length )
2320{
2321 int ret;
2322 mbedtls_mpi r, s;
2323 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
2324 mbedtls_mpi_init( &r );
2325 mbedtls_mpi_init( &s );
2326
2327 if( signature_length != 2 * curve_bytes )
2328 return( PSA_ERROR_INVALID_SIGNATURE );
2329
2330 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2331 signature,
2332 curve_bytes ) );
2333 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2334 signature + curve_bytes,
2335 curve_bytes ) );
2336
2337 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2338 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002339
2340cleanup:
2341 mbedtls_mpi_free( &r );
2342 mbedtls_mpi_free( &s );
2343 return( mbedtls_to_psa_error( ret ) );
2344}
2345#endif /* MBEDTLS_ECDSA_C */
2346
Gilles Peskinec5487a82018-12-03 18:08:14 +01002347psa_status_t psa_asymmetric_sign( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002348 psa_algorithm_t alg,
2349 const uint8_t *hash,
2350 size_t hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002351 uint8_t *signature,
2352 size_t signature_size,
2353 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002354{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002355 psa_key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002356 psa_status_t status;
2357
2358 *signature_length = signature_size;
2359
Gilles Peskinec5487a82018-12-03 18:08:14 +01002360 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002361 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002362 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002363 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002364 {
2365 status = PSA_ERROR_INVALID_ARGUMENT;
2366 goto exit;
2367 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002368
Gilles Peskine20035e32018-02-03 22:44:14 +01002369#if defined(MBEDTLS_RSA_C)
2370 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2371 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002372 status = psa_rsa_sign( slot->data.rsa,
2373 alg,
2374 hash, hash_length,
2375 signature, signature_size,
2376 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002377 }
2378 else
2379#endif /* defined(MBEDTLS_RSA_C) */
2380#if defined(MBEDTLS_ECP_C)
2381 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2382 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002383#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea05219c2018-11-16 16:02:56 +01002384 if(
2385#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
2386 PSA_ALG_IS_ECDSA( alg )
2387#else
2388 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
2389#endif
2390 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002391 status = psa_ecdsa_sign( slot->data.ecp,
2392 alg,
2393 hash, hash_length,
2394 signature, signature_size,
2395 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002396 else
2397#endif /* defined(MBEDTLS_ECDSA_C) */
2398 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002399 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002400 }
itayzafrir5c753392018-05-08 11:18:38 +03002401 }
2402 else
2403#endif /* defined(MBEDTLS_ECP_C) */
2404 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002405 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002406 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002407
2408exit:
2409 /* Fill the unused part of the output buffer (the whole buffer on error,
2410 * the trailing part on success) with something that isn't a valid mac
2411 * (barring an attack on the mac and deliberately-crafted input),
2412 * in case the caller doesn't check the return status properly. */
2413 if( status == PSA_SUCCESS )
2414 memset( signature + *signature_length, '!',
2415 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002416 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002417 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002418 /* If signature_size is 0 then we have nothing to do. We must not call
2419 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002420 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002421}
2422
Gilles Peskinec5487a82018-12-03 18:08:14 +01002423psa_status_t psa_asymmetric_verify( psa_key_handle_t handle,
itayzafrir5c753392018-05-08 11:18:38 +03002424 psa_algorithm_t alg,
2425 const uint8_t *hash,
2426 size_t hash_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002427 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002428 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002429{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002430 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002431 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002432
Gilles Peskinec5487a82018-12-03 18:08:14 +01002433 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002434 if( status != PSA_SUCCESS )
2435 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002436
Gilles Peskine61b91d42018-06-08 16:09:36 +02002437#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002438 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002439 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002440 return( psa_rsa_verify( slot->data.rsa,
2441 alg,
2442 hash, hash_length,
2443 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002444 }
2445 else
2446#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002447#if defined(MBEDTLS_ECP_C)
2448 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2449 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002450#if defined(MBEDTLS_ECDSA_C)
2451 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002452 return( psa_ecdsa_verify( slot->data.ecp,
2453 hash, hash_length,
2454 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002455 else
2456#endif /* defined(MBEDTLS_ECDSA_C) */
2457 {
2458 return( PSA_ERROR_INVALID_ARGUMENT );
2459 }
itayzafrir5c753392018-05-08 11:18:38 +03002460 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002461 else
2462#endif /* defined(MBEDTLS_ECP_C) */
2463 {
2464 return( PSA_ERROR_NOT_SUPPORTED );
2465 }
2466}
2467
Gilles Peskine072ac562018-06-30 00:21:29 +02002468#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
2469static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
2470 mbedtls_rsa_context *rsa )
2471{
2472 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
2473 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2474 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2475 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2476}
2477#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
2478
Gilles Peskinec5487a82018-12-03 18:08:14 +01002479psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002480 psa_algorithm_t alg,
2481 const uint8_t *input,
2482 size_t input_length,
2483 const uint8_t *salt,
2484 size_t salt_length,
2485 uint8_t *output,
2486 size_t output_size,
2487 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002488{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002489 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002490 psa_status_t status;
2491
Darryl Green5cc689a2018-07-24 15:34:10 +01002492 (void) input;
2493 (void) input_length;
2494 (void) salt;
2495 (void) output;
2496 (void) output_size;
2497
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002498 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002499
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002500 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2501 return( PSA_ERROR_INVALID_ARGUMENT );
2502
Gilles Peskinec5487a82018-12-03 18:08:14 +01002503 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002504 if( status != PSA_SUCCESS )
2505 return( status );
Gilles Peskine35da9a22018-06-29 19:17:49 +02002506 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
2507 PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002508 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002509
2510#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002511 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002512 {
2513 mbedtls_rsa_context *rsa = slot->data.rsa;
2514 int ret;
Gilles Peskine630a18a2018-06-29 17:49:35 +02002515 if( output_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002516 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002517#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002518 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002519 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002520 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2521 mbedtls_ctr_drbg_random,
2522 &global_data.ctr_drbg,
2523 MBEDTLS_RSA_PUBLIC,
2524 input_length,
2525 input,
2526 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002527 }
2528 else
2529#endif /* MBEDTLS_PKCS1_V15 */
2530#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002531 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002532 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002533 psa_rsa_oaep_set_padding_mode( alg, rsa );
2534 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
2535 mbedtls_ctr_drbg_random,
2536 &global_data.ctr_drbg,
2537 MBEDTLS_RSA_PUBLIC,
2538 salt, salt_length,
2539 input_length,
2540 input,
2541 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002542 }
2543 else
2544#endif /* MBEDTLS_PKCS1_V21 */
2545 {
2546 return( PSA_ERROR_INVALID_ARGUMENT );
2547 }
2548 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002549 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002550 return( mbedtls_to_psa_error( ret ) );
2551 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002552 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002553#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002554 {
2555 return( PSA_ERROR_NOT_SUPPORTED );
2556 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002557}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002558
Gilles Peskinec5487a82018-12-03 18:08:14 +01002559psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002560 psa_algorithm_t alg,
2561 const uint8_t *input,
2562 size_t input_length,
2563 const uint8_t *salt,
2564 size_t salt_length,
2565 uint8_t *output,
2566 size_t output_size,
2567 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002568{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002569 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002570 psa_status_t status;
2571
Darryl Green5cc689a2018-07-24 15:34:10 +01002572 (void) input;
2573 (void) input_length;
2574 (void) salt;
2575 (void) output;
2576 (void) output_size;
2577
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002578 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002579
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002580 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2581 return( PSA_ERROR_INVALID_ARGUMENT );
2582
Gilles Peskinec5487a82018-12-03 18:08:14 +01002583 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002584 if( status != PSA_SUCCESS )
2585 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002586 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2587 return( PSA_ERROR_INVALID_ARGUMENT );
2588
2589#if defined(MBEDTLS_RSA_C)
2590 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2591 {
2592 mbedtls_rsa_context *rsa = slot->data.rsa;
2593 int ret;
2594
Gilles Peskine630a18a2018-06-29 17:49:35 +02002595 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002596 return( PSA_ERROR_INVALID_ARGUMENT );
2597
2598#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002599 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002600 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002601 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2602 mbedtls_ctr_drbg_random,
2603 &global_data.ctr_drbg,
2604 MBEDTLS_RSA_PRIVATE,
2605 output_length,
2606 input,
2607 output,
2608 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002609 }
2610 else
2611#endif /* MBEDTLS_PKCS1_V15 */
2612#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002613 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002614 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002615 psa_rsa_oaep_set_padding_mode( alg, rsa );
2616 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
2617 mbedtls_ctr_drbg_random,
2618 &global_data.ctr_drbg,
2619 MBEDTLS_RSA_PRIVATE,
2620 salt, salt_length,
2621 output_length,
2622 input,
2623 output,
2624 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002625 }
2626 else
2627#endif /* MBEDTLS_PKCS1_V21 */
2628 {
2629 return( PSA_ERROR_INVALID_ARGUMENT );
2630 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002631
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002632 return( mbedtls_to_psa_error( ret ) );
2633 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002634 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002635#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002636 {
2637 return( PSA_ERROR_NOT_SUPPORTED );
2638 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002639}
Gilles Peskine20035e32018-02-03 22:44:14 +01002640
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002641
2642
mohammad1603503973b2018-03-12 15:59:30 +02002643/****************************************************************/
2644/* Symmetric cryptography */
2645/****************************************************************/
2646
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002647/* Initialize the cipher operation structure. Once this function has been
2648 * called, psa_cipher_abort can run and will do the right thing. */
2649static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2650 psa_algorithm_t alg )
2651{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002652 if( ! PSA_ALG_IS_CIPHER( alg ) )
2653 {
2654 memset( operation, 0, sizeof( *operation ) );
2655 return( PSA_ERROR_INVALID_ARGUMENT );
2656 }
2657
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002658 operation->alg = alg;
2659 operation->key_set = 0;
2660 operation->iv_set = 0;
2661 operation->iv_required = 1;
2662 operation->iv_size = 0;
2663 operation->block_size = 0;
2664 mbedtls_cipher_init( &operation->ctx.cipher );
2665 return( PSA_SUCCESS );
2666}
2667
Gilles Peskinee553c652018-06-04 16:22:46 +02002668static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002669 psa_key_handle_t handle,
Gilles Peskine7e928852018-06-04 16:23:10 +02002670 psa_algorithm_t alg,
2671 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002672{
2673 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2674 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +01002675 psa_key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02002676 size_t key_bits;
2677 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002678 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
2679 PSA_KEY_USAGE_ENCRYPT :
2680 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02002681
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002682 status = psa_cipher_init( operation, alg );
2683 if( status != PSA_SUCCESS )
2684 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002685
Gilles Peskinec5487a82018-12-03 18:08:14 +01002686 status = psa_get_key_from_slot( handle, &slot, usage, alg);
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002687 if( status != PSA_SUCCESS )
2688 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002689 key_bits = psa_get_key_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02002690
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002691 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002692 if( cipher_info == NULL )
2693 return( PSA_ERROR_NOT_SUPPORTED );
2694
mohammad1603503973b2018-03-12 15:59:30 +02002695 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002696 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002697 {
2698 psa_cipher_abort( operation );
2699 return( mbedtls_to_psa_error( ret ) );
2700 }
2701
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002702#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002703 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002704 {
2705 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2706 unsigned char keys[24];
2707 memcpy( keys, slot->data.raw.data, 16 );
2708 memcpy( keys + 16, slot->data.raw.data, 8 );
2709 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2710 keys,
2711 192, cipher_operation );
2712 }
2713 else
2714#endif
2715 {
2716 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2717 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002718 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002719 }
Moran Peker41deec42018-04-04 15:43:05 +03002720 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002721 {
2722 psa_cipher_abort( operation );
2723 return( mbedtls_to_psa_error( ret ) );
2724 }
2725
mohammad16038481e742018-03-18 13:57:31 +02002726#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002727 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02002728 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002729 case PSA_ALG_CBC_NO_PADDING:
2730 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2731 MBEDTLS_PADDING_NONE );
2732 break;
2733 case PSA_ALG_CBC_PKCS7:
2734 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2735 MBEDTLS_PADDING_PKCS7 );
2736 break;
2737 default:
2738 /* The algorithm doesn't involve padding. */
2739 ret = 0;
2740 break;
2741 }
2742 if( ret != 0 )
2743 {
2744 psa_cipher_abort( operation );
2745 return( mbedtls_to_psa_error( ret ) );
mohammad16038481e742018-03-18 13:57:31 +02002746 }
2747#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2748
mohammad1603503973b2018-03-12 15:59:30 +02002749 operation->key_set = 1;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002750 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
2751 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
2752 if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
mohammad16038481e742018-03-18 13:57:31 +02002753 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002754 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02002755 }
mohammad1603503973b2018-03-12 15:59:30 +02002756
Moran Peker395db872018-05-31 14:07:14 +03002757 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002758}
2759
Gilles Peskinefe119512018-07-08 21:39:34 +02002760psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002761 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02002762 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002763{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002764 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002765}
2766
Gilles Peskinefe119512018-07-08 21:39:34 +02002767psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002768 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02002769 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002770{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002771 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002772}
2773
Gilles Peskinefe119512018-07-08 21:39:34 +02002774psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
2775 unsigned char *iv,
2776 size_t iv_size,
2777 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002778{
itayzafrir534bd7c2018-08-02 13:56:32 +03002779 psa_status_t status;
2780 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002781 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002782 {
2783 status = PSA_ERROR_BAD_STATE;
2784 goto exit;
2785 }
Moran Peker41deec42018-04-04 15:43:05 +03002786 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002787 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002788 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03002789 goto exit;
2790 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002791 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2792 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002793 if( ret != 0 )
2794 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002795 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002796 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002797 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002798
mohammad16038481e742018-03-18 13:57:31 +02002799 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03002800 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002801
Moran Peker395db872018-05-31 14:07:14 +03002802exit:
itayzafrir534bd7c2018-08-02 13:56:32 +03002803 if( status != PSA_SUCCESS )
Moran Peker395db872018-05-31 14:07:14 +03002804 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002805 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002806}
2807
Gilles Peskinefe119512018-07-08 21:39:34 +02002808psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
2809 const unsigned char *iv,
2810 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002811{
itayzafrir534bd7c2018-08-02 13:56:32 +03002812 psa_status_t status;
2813 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002814 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002815 {
2816 status = PSA_ERROR_BAD_STATE;
2817 goto exit;
2818 }
Moran Pekera28258c2018-05-29 16:25:04 +03002819 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002820 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002821 status = PSA_ERROR_INVALID_ARGUMENT;
2822 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03002823 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002824 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
2825 status = mbedtls_to_psa_error( ret );
2826exit:
2827 if( status == PSA_SUCCESS )
2828 operation->iv_set = 1;
2829 else
mohammad1603503973b2018-03-12 15:59:30 +02002830 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002831 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002832}
2833
Gilles Peskinee553c652018-06-04 16:22:46 +02002834psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2835 const uint8_t *input,
2836 size_t input_length,
2837 unsigned char *output,
2838 size_t output_size,
2839 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002840{
itayzafrir534bd7c2018-08-02 13:56:32 +03002841 psa_status_t status;
2842 int ret;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002843 size_t expected_output_size;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002844 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002845 {
2846 /* Take the unprocessed partial block left over from previous
2847 * update calls, if any, plus the input to this call. Remove
2848 * the last partial block, if any. You get the data that will be
2849 * output in this call. */
2850 expected_output_size =
2851 ( operation->ctx.cipher.unprocessed_len + input_length )
2852 / operation->block_size * operation->block_size;
2853 }
2854 else
2855 {
2856 expected_output_size = input_length;
2857 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002858
Gilles Peskine89d789c2018-06-04 17:17:16 +02002859 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03002860 {
2861 status = PSA_ERROR_BUFFER_TOO_SMALL;
2862 goto exit;
2863 }
mohammad160382759612018-03-12 18:16:40 +02002864
mohammad1603503973b2018-03-12 15:59:30 +02002865 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002866 input_length, output, output_length );
itayzafrir534bd7c2018-08-02 13:56:32 +03002867 status = mbedtls_to_psa_error( ret );
2868exit:
2869 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02002870 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002871 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002872}
2873
Gilles Peskinee553c652018-06-04 16:22:46 +02002874psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2875 uint8_t *output,
2876 size_t output_size,
2877 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002878{
Janos Follath315b51c2018-07-09 16:04:51 +01002879 psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
2880 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002881 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002882
mohammad1603503973b2018-03-12 15:59:30 +02002883 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002884 {
Janos Follath315b51c2018-07-09 16:04:51 +01002885 status = PSA_ERROR_BAD_STATE;
2886 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002887 }
2888 if( operation->iv_required && ! operation->iv_set )
2889 {
Janos Follath315b51c2018-07-09 16:04:51 +01002890 status = PSA_ERROR_BAD_STATE;
2891 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002892 }
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002893
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002894 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002895 operation->alg == PSA_ALG_CBC_NO_PADDING &&
2896 operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03002897 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002898 status = PSA_ERROR_INVALID_ARGUMENT;
Janos Follath315b51c2018-07-09 16:04:51 +01002899 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002900 }
2901
Janos Follath315b51c2018-07-09 16:04:51 +01002902 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
2903 temp_output_buffer,
2904 output_length );
2905 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002906 {
Janos Follath315b51c2018-07-09 16:04:51 +01002907 status = mbedtls_to_psa_error( cipher_ret );
2908 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02002909 }
Janos Follath315b51c2018-07-09 16:04:51 +01002910
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002911 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01002912 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002913 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002914 memcpy( output, temp_output_buffer, *output_length );
2915 else
2916 {
Janos Follath315b51c2018-07-09 16:04:51 +01002917 status = PSA_ERROR_BUFFER_TOO_SMALL;
2918 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002919 }
mohammad1603503973b2018-03-12 15:59:30 +02002920
Gilles Peskine3f108122018-12-07 18:14:53 +01002921 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002922 status = psa_cipher_abort( operation );
2923
2924 return( status );
2925
2926error:
2927
2928 *output_length = 0;
2929
Gilles Peskine3f108122018-12-07 18:14:53 +01002930 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002931 (void) psa_cipher_abort( operation );
2932
2933 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002934}
2935
Gilles Peskinee553c652018-06-04 16:22:46 +02002936psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2937{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002938 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002939 {
2940 /* The object has (apparently) been initialized but it is not
2941 * in use. It's ok to call abort on such an object, and there's
2942 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002943 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002944 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002945
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002946 /* Sanity check (shouldn't happen: operation->alg should
2947 * always have been initialized to a valid value). */
2948 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2949 return( PSA_ERROR_BAD_STATE );
2950
mohammad1603503973b2018-03-12 15:59:30 +02002951 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002952
Moran Peker41deec42018-04-04 15:43:05 +03002953 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002954 operation->key_set = 0;
2955 operation->iv_set = 0;
2956 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002957 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002958 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002959
Moran Peker395db872018-05-31 14:07:14 +03002960 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002961}
2962
Gilles Peskinea0655c32018-04-30 17:06:50 +02002963
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002964
mohammad16038cc1cee2018-03-28 01:21:33 +03002965/****************************************************************/
2966/* Key Policy */
2967/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002968
mohammad160327010052018-07-03 13:16:15 +03002969#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02002970void psa_key_policy_set_usage( psa_key_policy_t *policy,
2971 psa_key_usage_t usage,
2972 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002973{
mohammad16034eed7572018-03-28 05:14:59 -07002974 policy->usage = usage;
2975 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002976}
2977
Gilles Peskineaa7bc472018-07-12 00:54:56 +02002978psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002979{
mohammad16036df908f2018-04-02 08:34:15 -07002980 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002981}
2982
Gilles Peskineaa7bc472018-07-12 00:54:56 +02002983psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002984{
mohammad16036df908f2018-04-02 08:34:15 -07002985 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002986}
mohammad160327010052018-07-03 13:16:15 +03002987#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002988
Gilles Peskinec5487a82018-12-03 18:08:14 +01002989psa_status_t psa_set_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02002990 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002991{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002992 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002993 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03002994
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002995 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002996 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002997
Gilles Peskinec5487a82018-12-03 18:08:14 +01002998 status = psa_get_empty_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002999 if( status != PSA_SUCCESS )
3000 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03003001
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003002 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
3003 PSA_KEY_USAGE_ENCRYPT |
3004 PSA_KEY_USAGE_DECRYPT |
3005 PSA_KEY_USAGE_SIGN |
Gilles Peskineea0fb492018-07-12 17:17:20 +02003006 PSA_KEY_USAGE_VERIFY |
3007 PSA_KEY_USAGE_DERIVE ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07003008 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03003009
mohammad16036df908f2018-04-02 08:34:15 -07003010 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003011
3012 return( PSA_SUCCESS );
3013}
3014
Gilles Peskinec5487a82018-12-03 18:08:14 +01003015psa_status_t psa_get_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003016 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003017{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003018 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003019 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003020
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003021 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003022 return( PSA_ERROR_INVALID_ARGUMENT );
3023
Gilles Peskinec5487a82018-12-03 18:08:14 +01003024 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003025 if( status != PSA_SUCCESS )
3026 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003027
mohammad16036df908f2018-04-02 08:34:15 -07003028 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003029
3030 return( PSA_SUCCESS );
3031}
Gilles Peskine20035e32018-02-03 22:44:14 +01003032
Gilles Peskinea0655c32018-04-30 17:06:50 +02003033
3034
mohammad1603804cd712018-03-20 22:44:08 +02003035/****************************************************************/
3036/* Key Lifetime */
3037/****************************************************************/
3038
Gilles Peskinec5487a82018-12-03 18:08:14 +01003039psa_status_t psa_get_key_lifetime( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003040 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003041{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003042 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003043 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003044
Gilles Peskinec5487a82018-12-03 18:08:14 +01003045 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003046 if( status != PSA_SUCCESS )
3047 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003048
mohammad1603804cd712018-03-20 22:44:08 +02003049 *lifetime = slot->lifetime;
3050
3051 return( PSA_SUCCESS );
3052}
3053
Gilles Peskine20035e32018-02-03 22:44:14 +01003054
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003055
mohammad16035955c982018-04-26 00:53:03 +03003056/****************************************************************/
3057/* AEAD */
3058/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003059
Gilles Peskineedf9a652018-08-17 18:11:56 +02003060typedef struct
3061{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003062 psa_key_slot_t *slot;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003063 const mbedtls_cipher_info_t *cipher_info;
3064 union
3065 {
3066#if defined(MBEDTLS_CCM_C)
3067 mbedtls_ccm_context ccm;
3068#endif /* MBEDTLS_CCM_C */
3069#if defined(MBEDTLS_GCM_C)
3070 mbedtls_gcm_context gcm;
3071#endif /* MBEDTLS_GCM_C */
3072 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003073 psa_algorithm_t core_alg;
3074 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003075 uint8_t tag_length;
3076} aead_operation_t;
3077
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003078static void psa_aead_abort( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003079{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003080 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003081 {
3082#if defined(MBEDTLS_CCM_C)
3083 case PSA_ALG_CCM:
3084 mbedtls_ccm_free( &operation->ctx.ccm );
3085 break;
3086#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003087#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02003088 case PSA_ALG_GCM:
3089 mbedtls_gcm_free( &operation->ctx.gcm );
3090 break;
3091#endif /* MBEDTLS_GCM_C */
3092 }
3093}
3094
3095static psa_status_t psa_aead_setup( aead_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003096 psa_key_handle_t handle,
Gilles Peskineedf9a652018-08-17 18:11:56 +02003097 psa_key_usage_t usage,
3098 psa_algorithm_t alg )
3099{
3100 psa_status_t status;
3101 size_t key_bits;
3102 mbedtls_cipher_id_t cipher_id;
3103
Gilles Peskinec5487a82018-12-03 18:08:14 +01003104 status = psa_get_key_from_slot( handle, &operation->slot, usage, alg );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003105 if( status != PSA_SUCCESS )
3106 return( status );
3107
3108 key_bits = psa_get_key_bits( operation->slot );
3109
3110 operation->cipher_info =
3111 mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
3112 &cipher_id );
3113 if( operation->cipher_info == NULL )
3114 return( PSA_ERROR_NOT_SUPPORTED );
3115
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003116 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003117 {
3118#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003119 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
3120 operation->core_alg = PSA_ALG_CCM;
3121 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003122 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3123 return( PSA_ERROR_INVALID_ARGUMENT );
3124 mbedtls_ccm_init( &operation->ctx.ccm );
3125 status = mbedtls_to_psa_error(
3126 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
3127 operation->slot->data.raw.data,
3128 (unsigned int) key_bits ) );
3129 if( status != 0 )
3130 goto cleanup;
3131 break;
3132#endif /* MBEDTLS_CCM_C */
3133
3134#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003135 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
3136 operation->core_alg = PSA_ALG_GCM;
3137 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003138 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3139 return( PSA_ERROR_INVALID_ARGUMENT );
3140 mbedtls_gcm_init( &operation->ctx.gcm );
3141 status = mbedtls_to_psa_error(
3142 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
3143 operation->slot->data.raw.data,
3144 (unsigned int) key_bits ) );
3145 break;
3146#endif /* MBEDTLS_GCM_C */
3147
3148 default:
3149 return( PSA_ERROR_NOT_SUPPORTED );
3150 }
3151
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003152 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
3153 {
3154 status = PSA_ERROR_INVALID_ARGUMENT;
3155 goto cleanup;
3156 }
3157 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
3158 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
3159 * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
3160 * In both cases, mbedtls_xxx will validate the tag length below. */
3161
Gilles Peskineedf9a652018-08-17 18:11:56 +02003162 return( PSA_SUCCESS );
3163
3164cleanup:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003165 psa_aead_abort( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003166 return( status );
3167}
3168
Gilles Peskinec5487a82018-12-03 18:08:14 +01003169psa_status_t psa_aead_encrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003170 psa_algorithm_t alg,
3171 const uint8_t *nonce,
3172 size_t nonce_length,
3173 const uint8_t *additional_data,
3174 size_t additional_data_length,
3175 const uint8_t *plaintext,
3176 size_t plaintext_length,
3177 uint8_t *ciphertext,
3178 size_t ciphertext_size,
3179 size_t *ciphertext_length )
3180{
mohammad16035955c982018-04-26 00:53:03 +03003181 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003182 aead_operation_t operation;
mohammad160315223a82018-06-03 17:19:55 +03003183 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02003184
mohammad1603f08a5502018-06-03 15:05:47 +03003185 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07003186
Gilles Peskinec5487a82018-12-03 18:08:14 +01003187 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003188 if( status != PSA_SUCCESS )
3189 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003190
Gilles Peskineedf9a652018-08-17 18:11:56 +02003191 /* For all currently supported modes, the tag is at the end of the
3192 * ciphertext. */
3193 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
3194 {
3195 status = PSA_ERROR_BUFFER_TOO_SMALL;
3196 goto exit;
3197 }
3198 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03003199
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003200#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003201 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003202 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003203 status = mbedtls_to_psa_error(
3204 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
3205 MBEDTLS_GCM_ENCRYPT,
3206 plaintext_length,
3207 nonce, nonce_length,
3208 additional_data, additional_data_length,
3209 plaintext, ciphertext,
3210 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03003211 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003212 else
3213#endif /* MBEDTLS_GCM_C */
3214#if defined(MBEDTLS_CCM_C)
3215 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003216 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003217 status = mbedtls_to_psa_error(
3218 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
3219 plaintext_length,
3220 nonce, nonce_length,
3221 additional_data,
3222 additional_data_length,
3223 plaintext, ciphertext,
3224 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003225 }
mohammad16035c8845f2018-05-09 05:40:09 -07003226 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003227#endif /* MBEDTLS_CCM_C */
mohammad16035c8845f2018-05-09 05:40:09 -07003228 {
mohammad1603554faad2018-06-03 15:07:38 +03003229 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07003230 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003231
Gilles Peskineedf9a652018-08-17 18:11:56 +02003232 if( status != PSA_SUCCESS && ciphertext_size != 0 )
3233 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003234
Gilles Peskineedf9a652018-08-17 18:11:56 +02003235exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003236 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003237 if( status == PSA_SUCCESS )
3238 *ciphertext_length = plaintext_length + operation.tag_length;
3239 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003240}
3241
Gilles Peskineee652a32018-06-01 19:23:52 +02003242/* Locate the tag in a ciphertext buffer containing the encrypted data
3243 * followed by the tag. Return the length of the part preceding the tag in
3244 * *plaintext_length. This is the size of the plaintext in modes where
3245 * the encrypted data has the same size as the plaintext, such as
3246 * CCM and GCM. */
3247static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
3248 const uint8_t *ciphertext,
3249 size_t ciphertext_length,
3250 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02003251 const uint8_t **p_tag )
3252{
3253 size_t payload_length;
3254 if( tag_length > ciphertext_length )
3255 return( PSA_ERROR_INVALID_ARGUMENT );
3256 payload_length = ciphertext_length - tag_length;
3257 if( payload_length > plaintext_size )
3258 return( PSA_ERROR_BUFFER_TOO_SMALL );
3259 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02003260 return( PSA_SUCCESS );
3261}
3262
Gilles Peskinec5487a82018-12-03 18:08:14 +01003263psa_status_t psa_aead_decrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003264 psa_algorithm_t alg,
3265 const uint8_t *nonce,
3266 size_t nonce_length,
3267 const uint8_t *additional_data,
3268 size_t additional_data_length,
3269 const uint8_t *ciphertext,
3270 size_t ciphertext_length,
3271 uint8_t *plaintext,
3272 size_t plaintext_size,
3273 size_t *plaintext_length )
3274{
mohammad16035955c982018-04-26 00:53:03 +03003275 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003276 aead_operation_t operation;
3277 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02003278
Gilles Peskineee652a32018-06-01 19:23:52 +02003279 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03003280
Gilles Peskinec5487a82018-12-03 18:08:14 +01003281 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003282 if( status != PSA_SUCCESS )
3283 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003284
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003285#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003286 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003287 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003288 status = psa_aead_unpadded_locate_tag( operation.tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003289 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003290 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02003291 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003292 goto exit;
Gilles Peskineee652a32018-06-01 19:23:52 +02003293
Gilles Peskineedf9a652018-08-17 18:11:56 +02003294 status = mbedtls_to_psa_error(
3295 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
3296 ciphertext_length - operation.tag_length,
3297 nonce, nonce_length,
3298 additional_data,
3299 additional_data_length,
3300 tag, operation.tag_length,
3301 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03003302 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003303 else
3304#endif /* MBEDTLS_GCM_C */
3305#if defined(MBEDTLS_CCM_C)
3306 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003307 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003308 status = psa_aead_unpadded_locate_tag( operation.tag_length,
mohammad16039375f842018-06-03 14:28:24 +03003309 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003310 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03003311 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003312 goto exit;
mohammad16039375f842018-06-03 14:28:24 +03003313
Gilles Peskineedf9a652018-08-17 18:11:56 +02003314 status = mbedtls_to_psa_error(
3315 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
3316 ciphertext_length - operation.tag_length,
3317 nonce, nonce_length,
3318 additional_data,
3319 additional_data_length,
3320 ciphertext, plaintext,
3321 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003322 }
mohammad160339574652018-06-01 04:39:53 -07003323 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003324#endif /* MBEDTLS_CCM_C */
mohammad160339574652018-06-01 04:39:53 -07003325 {
mohammad1603554faad2018-06-03 15:07:38 +03003326 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07003327 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02003328
Gilles Peskineedf9a652018-08-17 18:11:56 +02003329 if( status != PSA_SUCCESS && plaintext_size != 0 )
3330 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03003331
Gilles Peskineedf9a652018-08-17 18:11:56 +02003332exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003333 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003334 if( status == PSA_SUCCESS )
3335 *plaintext_length = ciphertext_length - operation.tag_length;
3336 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003337}
3338
Gilles Peskinea0655c32018-04-30 17:06:50 +02003339
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003340
Gilles Peskine20035e32018-02-03 22:44:14 +01003341/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003342/* Generators */
3343/****************************************************************/
3344
3345psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
3346{
3347 psa_status_t status = PSA_SUCCESS;
3348 if( generator->alg == 0 )
3349 {
3350 /* The object has (apparently) been initialized but it is not
3351 * in use. It's ok to call abort on such an object, and there's
3352 * nothing to do. */
3353 }
3354 else
Gilles Peskine751d9652018-09-18 12:05:44 +02003355 if( generator->alg == PSA_ALG_SELECT_RAW )
3356 {
3357 if( generator->ctx.buffer.data != NULL )
3358 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003359 mbedtls_platform_zeroize( generator->ctx.buffer.data,
Gilles Peskine751d9652018-09-18 12:05:44 +02003360 generator->ctx.buffer.size );
3361 mbedtls_free( generator->ctx.buffer.data );
3362 }
3363 }
3364 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003365#if defined(MBEDTLS_MD_C)
3366 if( PSA_ALG_IS_HKDF( generator->alg ) )
3367 {
3368 mbedtls_free( generator->ctx.hkdf.info );
3369 status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
3370 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003371 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3372 /* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
3373 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003374 {
3375 if( generator->ctx.tls12_prf.key != NULL )
3376 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003377 mbedtls_platform_zeroize( generator->ctx.tls12_prf.key,
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003378 generator->ctx.tls12_prf.key_len );
3379 mbedtls_free( generator->ctx.tls12_prf.key );
3380 }
Hanno Becker580fba12018-11-13 20:50:45 +00003381
3382 if( generator->ctx.tls12_prf.Ai_with_seed != NULL )
3383 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003384 mbedtls_platform_zeroize( generator->ctx.tls12_prf.Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003385 generator->ctx.tls12_prf.Ai_with_seed_len );
3386 mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed );
3387 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003388 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003389 else
3390#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003391 {
3392 status = PSA_ERROR_BAD_STATE;
3393 }
3394 memset( generator, 0, sizeof( *generator ) );
3395 return( status );
3396}
3397
3398
3399psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3400 size_t *capacity)
3401{
3402 *capacity = generator->capacity;
3403 return( PSA_SUCCESS );
3404}
3405
Gilles Peskinebef7f142018-07-12 17:22:21 +02003406#if defined(MBEDTLS_MD_C)
3407/* Read some bytes from an HKDF-based generator. This performs a chunk
3408 * of the expand phase of the HKDF algorithm. */
3409static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
3410 psa_algorithm_t hash_alg,
3411 uint8_t *output,
3412 size_t output_length )
3413{
3414 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3415 psa_status_t status;
3416
3417 while( output_length != 0 )
3418 {
3419 /* Copy what remains of the current block */
3420 uint8_t n = hash_length - hkdf->offset_in_block;
3421 if( n > output_length )
3422 n = (uint8_t) output_length;
3423 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
3424 output += n;
3425 output_length -= n;
3426 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02003427 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003428 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003429 /* We can't be wanting more output after block 0xff, otherwise
3430 * the capacity check in psa_generator_read() would have
3431 * prevented this call. It could happen only if the generator
3432 * object was corrupted or if this function is called directly
3433 * inside the library. */
3434 if( hkdf->block_number == 0xff )
3435 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003436
3437 /* We need a new block */
3438 ++hkdf->block_number;
3439 hkdf->offset_in_block = 0;
3440 status = psa_hmac_setup_internal( &hkdf->hmac,
3441 hkdf->prk, hash_length,
3442 hash_alg );
3443 if( status != PSA_SUCCESS )
3444 return( status );
3445 if( hkdf->block_number != 1 )
3446 {
3447 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3448 hkdf->output_block,
3449 hash_length );
3450 if( status != PSA_SUCCESS )
3451 return( status );
3452 }
3453 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3454 hkdf->info,
3455 hkdf->info_length );
3456 if( status != PSA_SUCCESS )
3457 return( status );
3458 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3459 &hkdf->block_number, 1 );
3460 if( status != PSA_SUCCESS )
3461 return( status );
3462 status = psa_hmac_finish_internal( &hkdf->hmac,
3463 hkdf->output_block,
3464 sizeof( hkdf->output_block ) );
3465 if( status != PSA_SUCCESS )
3466 return( status );
3467 }
3468
3469 return( PSA_SUCCESS );
3470}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003471
3472static psa_status_t psa_generator_tls12_prf_generate_next_block(
3473 psa_tls12_prf_generator_t *tls12_prf,
3474 psa_algorithm_t alg )
3475{
3476 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3477 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3478 psa_hmac_internal_data hmac;
3479 psa_status_t status, cleanup_status;
3480
Hanno Becker3b339e22018-11-13 20:56:14 +00003481 unsigned char *Ai;
3482 size_t Ai_len;
3483
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003484 /* We can't be wanting more output after block 0xff, otherwise
3485 * the capacity check in psa_generator_read() would have
3486 * prevented this call. It could happen only if the generator
3487 * object was corrupted or if this function is called directly
3488 * inside the library. */
3489 if( tls12_prf->block_number == 0xff )
3490 return( PSA_ERROR_BAD_STATE );
3491
3492 /* We need a new block */
3493 ++tls12_prf->block_number;
3494 tls12_prf->offset_in_block = 0;
3495
3496 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
3497 *
3498 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
3499 *
3500 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
3501 * HMAC_hash(secret, A(2) + seed) +
3502 * HMAC_hash(secret, A(3) + seed) + ...
3503 *
3504 * A(0) = seed
3505 * A(i) = HMAC_hash( secret, A(i-1) )
3506 *
3507 * The `psa_tls12_prf_generator` structures saves the block
3508 * `HMAC_hash(secret, A(i) + seed)` from which the output
3509 * is currently extracted as `output_block`, while
3510 * `A(i) + seed` is stored in `Ai_with_seed`.
3511 *
3512 * Generating a new block means recalculating `Ai_with_seed`
3513 * from the A(i)-part of it, and afterwards recalculating
3514 * `output_block`.
3515 *
3516 * A(0) is computed at setup time.
3517 *
3518 */
3519
3520 psa_hmac_init_internal( &hmac );
3521
3522 /* We must distinguish the calculation of A(1) from those
3523 * of A(2) and higher, because A(0)=seed has a different
3524 * length than the other A(i). */
3525 if( tls12_prf->block_number == 1 )
3526 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003527 Ai = tls12_prf->Ai_with_seed + hash_length;
3528 Ai_len = tls12_prf->Ai_with_seed_len - hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003529 }
3530 else
3531 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003532 Ai = tls12_prf->Ai_with_seed;
3533 Ai_len = hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003534 }
3535
Hanno Becker3b339e22018-11-13 20:56:14 +00003536 /* Compute A(i+1) = HMAC_hash(secret, A(i)) */
3537 status = psa_hmac_setup_internal( &hmac,
3538 tls12_prf->key,
3539 tls12_prf->key_len,
3540 hash_alg );
3541 if( status != PSA_SUCCESS )
3542 goto cleanup;
3543
3544 status = psa_hash_update( &hmac.hash_ctx,
3545 Ai, Ai_len );
3546 if( status != PSA_SUCCESS )
3547 goto cleanup;
3548
3549 status = psa_hmac_finish_internal( &hmac,
3550 tls12_prf->Ai_with_seed,
3551 hash_length );
3552 if( status != PSA_SUCCESS )
3553 goto cleanup;
3554
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003555 /* Compute the next block `HMAC_hash(secret, A(i+1) + seed)`. */
3556 status = psa_hmac_setup_internal( &hmac,
3557 tls12_prf->key,
3558 tls12_prf->key_len,
3559 hash_alg );
3560 if( status != PSA_SUCCESS )
3561 goto cleanup;
3562
3563 status = psa_hash_update( &hmac.hash_ctx,
3564 tls12_prf->Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003565 tls12_prf->Ai_with_seed_len );
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003566 if( status != PSA_SUCCESS )
3567 goto cleanup;
3568
3569 status = psa_hmac_finish_internal( &hmac,
3570 tls12_prf->output_block,
3571 hash_length );
3572 if( status != PSA_SUCCESS )
3573 goto cleanup;
3574
3575cleanup:
3576
3577 cleanup_status = psa_hmac_abort_internal( &hmac );
3578 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
3579 status = cleanup_status;
3580
3581 return( status );
3582}
3583
3584/* Read some bytes from an TLS-1.2-PRF-based generator.
3585 * See Section 5 of RFC 5246. */
3586static psa_status_t psa_generator_tls12_prf_read(
3587 psa_tls12_prf_generator_t *tls12_prf,
3588 psa_algorithm_t alg,
3589 uint8_t *output,
3590 size_t output_length )
3591{
3592 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3593 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3594 psa_status_t status;
3595
3596 while( output_length != 0 )
3597 {
3598 /* Copy what remains of the current block */
3599 uint8_t n = hash_length - tls12_prf->offset_in_block;
3600
3601 /* Check if we have fully processed the current block. */
3602 if( n == 0 )
3603 {
3604 status = psa_generator_tls12_prf_generate_next_block( tls12_prf,
3605 alg );
3606 if( status != PSA_SUCCESS )
3607 return( status );
3608
3609 continue;
3610 }
3611
3612 if( n > output_length )
3613 n = (uint8_t) output_length;
3614 memcpy( output, tls12_prf->output_block + tls12_prf->offset_in_block,
3615 n );
3616 output += n;
3617 output_length -= n;
3618 tls12_prf->offset_in_block += n;
3619 }
3620
3621 return( PSA_SUCCESS );
3622}
Gilles Peskinebef7f142018-07-12 17:22:21 +02003623#endif /* MBEDTLS_MD_C */
3624
Gilles Peskineeab56e42018-07-12 17:12:33 +02003625psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
3626 uint8_t *output,
3627 size_t output_length )
3628{
3629 psa_status_t status;
3630
3631 if( output_length > generator->capacity )
3632 {
3633 generator->capacity = 0;
3634 /* Go through the error path to wipe all confidential data now
3635 * that the generator object is useless. */
3636 status = PSA_ERROR_INSUFFICIENT_CAPACITY;
3637 goto exit;
3638 }
3639 if( output_length == 0 &&
3640 generator->capacity == 0 && generator->alg == 0 )
3641 {
3642 /* Edge case: this is a blank or finished generator, and 0
3643 * bytes were requested. The right error in this case could
3644 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3645 * INSUFFICIENT_CAPACITY, which is right for a finished
3646 * generator, for consistency with the case when
3647 * output_length > 0. */
3648 return( PSA_ERROR_INSUFFICIENT_CAPACITY );
3649 }
3650 generator->capacity -= output_length;
3651
Gilles Peskine751d9652018-09-18 12:05:44 +02003652 if( generator->alg == PSA_ALG_SELECT_RAW )
3653 {
Gilles Peskine211a4362018-10-25 22:22:31 +02003654 /* Initially, the capacity of a selection generator is always
3655 * the size of the buffer, i.e. `generator->ctx.buffer.size`,
3656 * abbreviated in this comment as `size`. When the remaining
3657 * capacity is `c`, the next bytes to serve start `c` bytes
3658 * from the end of the buffer, i.e. `size - c` from the
3659 * beginning of the buffer. Since `generator->capacity` was just
3660 * decremented above, we need to serve the bytes from
3661 * `size - generator->capacity - output_length` to
3662 * `size - generator->capacity`. */
Gilles Peskine751d9652018-09-18 12:05:44 +02003663 size_t offset =
3664 generator->ctx.buffer.size - generator->capacity - output_length;
3665 memcpy( output, generator->ctx.buffer.data + offset, output_length );
3666 status = PSA_SUCCESS;
3667 }
3668 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003669#if defined(MBEDTLS_MD_C)
3670 if( PSA_ALG_IS_HKDF( generator->alg ) )
3671 {
3672 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
3673 status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
3674 output, output_length );
3675 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003676 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3677 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003678 {
3679 status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
3680 generator->alg, output,
3681 output_length );
3682 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003683 else
3684#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003685 {
3686 return( PSA_ERROR_BAD_STATE );
3687 }
3688
3689exit:
3690 if( status != PSA_SUCCESS )
3691 {
3692 psa_generator_abort( generator );
3693 memset( output, '!', output_length );
3694 }
3695 return( status );
3696}
3697
Gilles Peskine08542d82018-07-19 17:05:42 +02003698#if defined(MBEDTLS_DES_C)
3699static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
3700{
3701 if( data_size >= 8 )
3702 mbedtls_des_key_set_parity( data );
3703 if( data_size >= 16 )
3704 mbedtls_des_key_set_parity( data + 8 );
3705 if( data_size >= 24 )
3706 mbedtls_des_key_set_parity( data + 16 );
3707}
3708#endif /* MBEDTLS_DES_C */
3709
Gilles Peskinec5487a82018-12-03 18:08:14 +01003710psa_status_t psa_generator_import_key( psa_key_handle_t handle,
Gilles Peskineeab56e42018-07-12 17:12:33 +02003711 psa_key_type_t type,
3712 size_t bits,
3713 psa_crypto_generator_t *generator )
3714{
3715 uint8_t *data = NULL;
3716 size_t bytes = PSA_BITS_TO_BYTES( bits );
3717 psa_status_t status;
3718
3719 if( ! key_type_is_raw_bytes( type ) )
3720 return( PSA_ERROR_INVALID_ARGUMENT );
3721 if( bits % 8 != 0 )
3722 return( PSA_ERROR_INVALID_ARGUMENT );
3723 data = mbedtls_calloc( 1, bytes );
3724 if( data == NULL )
3725 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3726
3727 status = psa_generator_read( generator, data, bytes );
3728 if( status != PSA_SUCCESS )
3729 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02003730#if defined(MBEDTLS_DES_C)
3731 if( type == PSA_KEY_TYPE_DES )
3732 psa_des_set_key_parity( data, bytes );
3733#endif /* MBEDTLS_DES_C */
Gilles Peskinec5487a82018-12-03 18:08:14 +01003734 status = psa_import_key( handle, type, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02003735
3736exit:
3737 mbedtls_free( data );
3738 return( status );
3739}
3740
3741
3742
3743/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003744/* Key derivation */
3745/****************************************************************/
3746
Gilles Peskinea05219c2018-11-16 16:02:56 +01003747#if defined(MBEDTLS_MD_C)
Gilles Peskinebef7f142018-07-12 17:22:21 +02003748/* Set up an HKDF-based generator. This is exactly the extract phase
Gilles Peskine346797d2018-11-16 16:05:06 +01003749 * of the HKDF algorithm.
3750 *
3751 * Note that if this function fails, you must call psa_generator_abort()
3752 * to potentially free embedded data structures and wipe confidential data.
3753 */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003754static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003755 const uint8_t *secret,
3756 size_t secret_length,
Gilles Peskinebef7f142018-07-12 17:22:21 +02003757 psa_algorithm_t hash_alg,
3758 const uint8_t *salt,
3759 size_t salt_length,
3760 const uint8_t *label,
3761 size_t label_length )
3762{
3763 psa_status_t status;
3764 status = psa_hmac_setup_internal( &hkdf->hmac,
3765 salt, salt_length,
Gilles Peskine00709fa2018-08-22 18:25:41 +02003766 PSA_ALG_HMAC_GET_HASH( hash_alg ) );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003767 if( status != PSA_SUCCESS )
3768 return( status );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003769 status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003770 if( status != PSA_SUCCESS )
3771 return( status );
3772 status = psa_hmac_finish_internal( &hkdf->hmac,
3773 hkdf->prk,
3774 sizeof( hkdf->prk ) );
3775 if( status != PSA_SUCCESS )
3776 return( status );
3777 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
3778 hkdf->block_number = 0;
3779 hkdf->info_length = label_length;
3780 if( label_length != 0 )
3781 {
3782 hkdf->info = mbedtls_calloc( 1, label_length );
3783 if( hkdf->info == NULL )
3784 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3785 memcpy( hkdf->info, label, label_length );
3786 }
3787 return( PSA_SUCCESS );
3788}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003789#endif /* MBEDTLS_MD_C */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003790
Gilles Peskinea05219c2018-11-16 16:02:56 +01003791#if defined(MBEDTLS_MD_C)
Gilles Peskine346797d2018-11-16 16:05:06 +01003792/* Set up a TLS-1.2-prf-based generator (see RFC 5246, Section 5).
3793 *
3794 * Note that if this function fails, you must call psa_generator_abort()
3795 * to potentially free embedded data structures and wipe confidential data.
3796 */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003797static psa_status_t psa_generator_tls12_prf_setup(
3798 psa_tls12_prf_generator_t *tls12_prf,
3799 const unsigned char *key,
3800 size_t key_len,
3801 psa_algorithm_t hash_alg,
3802 const uint8_t *salt,
3803 size_t salt_length,
3804 const uint8_t *label,
3805 size_t label_length )
3806{
3807 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Hanno Becker580fba12018-11-13 20:50:45 +00003808 size_t Ai_with_seed_len = hash_length + salt_length + label_length;
3809 int overflow;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003810
3811 tls12_prf->key = mbedtls_calloc( 1, key_len );
3812 if( tls12_prf->key == NULL )
3813 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3814 tls12_prf->key_len = key_len;
3815 memcpy( tls12_prf->key, key, key_len );
3816
Hanno Becker580fba12018-11-13 20:50:45 +00003817 overflow = ( salt_length + label_length < salt_length ) ||
3818 ( salt_length + label_length + hash_length < hash_length );
3819 if( overflow )
3820 return( PSA_ERROR_INVALID_ARGUMENT );
3821
3822 tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len );
3823 if( tls12_prf->Ai_with_seed == NULL )
3824 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3825 tls12_prf->Ai_with_seed_len = Ai_with_seed_len;
3826
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003827 /* Write `label + seed' at the end of the `A(i) + seed` buffer,
3828 * leaving the initial `hash_length` bytes unspecified for now. */
Hanno Becker353e4532018-11-15 09:53:57 +00003829 if( label_length != 0 )
3830 {
3831 memcpy( tls12_prf->Ai_with_seed + hash_length,
3832 label, label_length );
3833 }
3834
3835 if( salt_length != 0 )
3836 {
3837 memcpy( tls12_prf->Ai_with_seed + hash_length + label_length,
3838 salt, salt_length );
3839 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003840
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003841 /* The first block gets generated when
3842 * psa_generator_read() is called. */
3843 tls12_prf->block_number = 0;
3844 tls12_prf->offset_in_block = hash_length;
3845
3846 return( PSA_SUCCESS );
3847}
Hanno Becker1aaedc02018-11-16 11:35:34 +00003848
3849/* Set up a TLS-1.2-PSK-to-MS-based generator. */
3850static psa_status_t psa_generator_tls12_psk_to_ms_setup(
3851 psa_tls12_prf_generator_t *tls12_prf,
3852 const unsigned char *psk,
3853 size_t psk_len,
3854 psa_algorithm_t hash_alg,
3855 const uint8_t *salt,
3856 size_t salt_length,
3857 const uint8_t *label,
3858 size_t label_length )
3859{
3860 psa_status_t status;
3861 unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
3862
3863 if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
3864 return( PSA_ERROR_INVALID_ARGUMENT );
3865
3866 /* Quoting RFC 4279, Section 2:
3867 *
3868 * The premaster secret is formed as follows: if the PSK is N octets
3869 * long, concatenate a uint16 with the value N, N zero octets, a second
3870 * uint16 with the value N, and the PSK itself.
3871 */
3872
3873 pms[0] = ( psk_len >> 8 ) & 0xff;
3874 pms[1] = ( psk_len >> 0 ) & 0xff;
3875 memset( pms + 2, 0, psk_len );
3876 pms[2 + psk_len + 0] = pms[0];
3877 pms[2 + psk_len + 1] = pms[1];
3878 memcpy( pms + 4 + psk_len, psk, psk_len );
3879
3880 status = psa_generator_tls12_prf_setup( tls12_prf,
3881 pms, 4 + 2 * psk_len,
3882 hash_alg,
3883 salt, salt_length,
3884 label, label_length );
3885
Gilles Peskine3f108122018-12-07 18:14:53 +01003886 mbedtls_platform_zeroize( pms, sizeof( pms ) );
Hanno Becker1aaedc02018-11-16 11:35:34 +00003887 return( status );
3888}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003889#endif /* MBEDTLS_MD_C */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003890
Gilles Peskine346797d2018-11-16 16:05:06 +01003891/* Note that if this function fails, you must call psa_generator_abort()
3892 * to potentially free embedded data structures and wipe confidential data.
3893 */
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003894static psa_status_t psa_key_derivation_internal(
3895 psa_crypto_generator_t *generator,
3896 const uint8_t *secret, size_t secret_length,
3897 psa_algorithm_t alg,
3898 const uint8_t *salt, size_t salt_length,
3899 const uint8_t *label, size_t label_length,
3900 size_t capacity )
3901{
3902 psa_status_t status;
3903 size_t max_capacity;
3904
3905 /* Set generator->alg even on failure so that abort knows what to do. */
3906 generator->alg = alg;
3907
Gilles Peskine751d9652018-09-18 12:05:44 +02003908 if( alg == PSA_ALG_SELECT_RAW )
3909 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003910 (void) salt;
Gilles Peskine751d9652018-09-18 12:05:44 +02003911 if( salt_length != 0 )
3912 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea05219c2018-11-16 16:02:56 +01003913 (void) label;
Gilles Peskine751d9652018-09-18 12:05:44 +02003914 if( label_length != 0 )
3915 return( PSA_ERROR_INVALID_ARGUMENT );
3916 generator->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
3917 if( generator->ctx.buffer.data == NULL )
3918 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3919 memcpy( generator->ctx.buffer.data, secret, secret_length );
3920 generator->ctx.buffer.size = secret_length;
3921 max_capacity = secret_length;
3922 status = PSA_SUCCESS;
3923 }
3924 else
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003925#if defined(MBEDTLS_MD_C)
3926 if( PSA_ALG_IS_HKDF( alg ) )
3927 {
3928 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3929 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3930 if( hash_size == 0 )
3931 return( PSA_ERROR_NOT_SUPPORTED );
3932 max_capacity = 255 * hash_size;
3933 status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
3934 secret, secret_length,
3935 hash_alg,
3936 salt, salt_length,
3937 label, label_length );
3938 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003939 /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
3940 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
3941 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003942 {
3943 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3944 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3945
3946 /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */
3947 if( hash_alg != PSA_ALG_SHA_256 &&
3948 hash_alg != PSA_ALG_SHA_384 )
3949 {
3950 return( PSA_ERROR_NOT_SUPPORTED );
3951 }
3952
3953 max_capacity = 255 * hash_size;
Hanno Becker1aaedc02018-11-16 11:35:34 +00003954
3955 if( PSA_ALG_IS_TLS12_PRF( alg ) )
3956 {
3957 status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
3958 secret, secret_length,
3959 hash_alg, salt, salt_length,
3960 label, label_length );
3961 }
3962 else
3963 {
3964 status = psa_generator_tls12_psk_to_ms_setup(
3965 &generator->ctx.tls12_prf,
3966 secret, secret_length,
3967 hash_alg, salt, salt_length,
3968 label, label_length );
3969 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003970 }
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003971 else
3972#endif
3973 {
3974 return( PSA_ERROR_NOT_SUPPORTED );
3975 }
3976
3977 if( status != PSA_SUCCESS )
3978 return( status );
3979
3980 if( capacity <= max_capacity )
3981 generator->capacity = capacity;
Gilles Peskine8feb3a82018-09-18 12:06:11 +02003982 else if( capacity == PSA_GENERATOR_UNBRIDLED_CAPACITY )
3983 generator->capacity = max_capacity;
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003984 else
3985 return( PSA_ERROR_INVALID_ARGUMENT );
3986
3987 return( PSA_SUCCESS );
3988}
3989
Gilles Peskineea0fb492018-07-12 17:17:20 +02003990psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003991 psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02003992 psa_algorithm_t alg,
3993 const uint8_t *salt,
3994 size_t salt_length,
3995 const uint8_t *label,
3996 size_t label_length,
3997 size_t capacity )
3998{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003999 psa_key_slot_t *slot;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004000 psa_status_t status;
4001
4002 if( generator->alg != 0 )
4003 return( PSA_ERROR_BAD_STATE );
4004
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004005 /* Make sure that alg is a key derivation algorithm. This prevents
4006 * key selection algorithms, which psa_key_derivation_internal
4007 * accepts for the sake of key agreement. */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004008 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
4009 return( PSA_ERROR_INVALID_ARGUMENT );
4010
Gilles Peskinec5487a82018-12-03 18:08:14 +01004011 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004012 if( status != PSA_SUCCESS )
4013 return( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004014
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004015 if( slot->type != PSA_KEY_TYPE_DERIVE )
4016 return( PSA_ERROR_INVALID_ARGUMENT );
4017
4018 status = psa_key_derivation_internal( generator,
4019 slot->data.raw.data,
4020 slot->data.raw.bytes,
4021 alg,
4022 salt, salt_length,
4023 label, label_length,
4024 capacity );
4025 if( status != PSA_SUCCESS )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004026 psa_generator_abort( generator );
4027 return( status );
4028}
4029
4030
4031
4032/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02004033/* Key agreement */
4034/****************************************************************/
4035
Gilles Peskinea05219c2018-11-16 16:02:56 +01004036#if defined(MBEDTLS_ECDH_C)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004037static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
4038 size_t peer_key_length,
4039 const mbedtls_ecp_keypair *our_key,
4040 uint8_t *shared_secret,
4041 size_t shared_secret_size,
4042 size_t *shared_secret_length )
4043{
4044 mbedtls_pk_context pk;
4045 mbedtls_ecp_keypair *their_key = NULL;
4046 mbedtls_ecdh_context ecdh;
4047 int ret;
4048 mbedtls_ecdh_init( &ecdh );
4049 mbedtls_pk_init( &pk );
4050
4051 ret = mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length );
4052 if( ret != 0 )
4053 goto exit;
Gilles Peskine88714d72018-10-25 23:07:25 +02004054 switch( mbedtls_pk_get_type( &pk ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004055 {
Gilles Peskine88714d72018-10-25 23:07:25 +02004056 case MBEDTLS_PK_ECKEY:
4057 case MBEDTLS_PK_ECKEY_DH:
4058 break;
4059 default:
4060 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4061 goto exit;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004062 }
4063 their_key = mbedtls_pk_ec( pk );
Gilles Peskineb4086612018-11-14 20:51:23 +01004064 if( their_key->grp.id != our_key->grp.id )
4065 {
4066 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4067 goto exit;
4068 }
4069
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004070 ret = mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS );
4071 if( ret != 0 )
4072 goto exit;
4073 ret = mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS );
4074 if( ret != 0 )
4075 goto exit;
4076
4077 ret = mbedtls_ecdh_calc_secret( &ecdh,
4078 shared_secret_length,
4079 shared_secret, shared_secret_size,
4080 mbedtls_ctr_drbg_random,
4081 &global_data.ctr_drbg );
4082
4083exit:
4084 mbedtls_pk_free( &pk );
4085 mbedtls_ecdh_free( &ecdh );
4086 return( mbedtls_to_psa_error( ret ) );
4087}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004088#endif /* MBEDTLS_ECDH_C */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004089
Gilles Peskine01d718c2018-09-18 12:01:02 +02004090#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
4091
Gilles Peskine346797d2018-11-16 16:05:06 +01004092/* Note that if this function fails, you must call psa_generator_abort()
4093 * to potentially free embedded data structures and wipe confidential data.
4094 */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004095static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
Gilles Peskine2f060a82018-12-04 17:12:32 +01004096 psa_key_slot_t *private_key,
Gilles Peskine01d718c2018-09-18 12:01:02 +02004097 const uint8_t *peer_key,
4098 size_t peer_key_length,
4099 psa_algorithm_t alg )
4100{
4101 psa_status_t status;
4102 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
4103 size_t shared_secret_length = 0;
4104
4105 /* Step 1: run the secret agreement algorithm to generate the shared
4106 * secret. */
4107 switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
4108 {
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004109#if defined(MBEDTLS_ECDH_C)
4110 case PSA_ALG_ECDH_BASE:
4111 if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
4112 return( PSA_ERROR_INVALID_ARGUMENT );
4113 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
4114 private_key->data.ecp,
4115 shared_secret,
4116 sizeof( shared_secret ),
4117 &shared_secret_length );
4118 break;
4119#endif /* MBEDTLS_ECDH_C */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004120 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01004121 (void) private_key;
4122 (void) peer_key;
4123 (void) peer_key_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004124 return( PSA_ERROR_NOT_SUPPORTED );
4125 }
4126 if( status != PSA_SUCCESS )
4127 goto exit;
4128
4129 /* Step 2: set up the key derivation to generate key material from
4130 * the shared secret. */
4131 status = psa_key_derivation_internal( generator,
4132 shared_secret, shared_secret_length,
4133 PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ),
4134 NULL, 0, NULL, 0,
4135 PSA_GENERATOR_UNBRIDLED_CAPACITY );
4136exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01004137 mbedtls_platform_zeroize( shared_secret, shared_secret_length );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004138 return( status );
4139}
4140
4141psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
Gilles Peskinec5487a82018-12-03 18:08:14 +01004142 psa_key_handle_t private_key,
Gilles Peskine01d718c2018-09-18 12:01:02 +02004143 const uint8_t *peer_key,
4144 size_t peer_key_length,
4145 psa_algorithm_t alg )
4146{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004147 psa_key_slot_t *slot;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004148 psa_status_t status;
4149 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
4150 return( PSA_ERROR_INVALID_ARGUMENT );
4151 status = psa_get_key_from_slot( private_key, &slot,
4152 PSA_KEY_USAGE_DERIVE, alg );
4153 if( status != PSA_SUCCESS )
4154 return( status );
Gilles Peskine346797d2018-11-16 16:05:06 +01004155 status = psa_key_agreement_internal( generator,
4156 slot,
4157 peer_key, peer_key_length,
4158 alg );
4159 if( status != PSA_SUCCESS )
4160 psa_generator_abort( generator );
4161 return( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004162}
4163
4164
4165
4166/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004167/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02004168/****************************************************************/
4169
4170psa_status_t psa_generate_random( uint8_t *output,
4171 size_t output_size )
4172{
itayzafrir0adf0fc2018-09-06 16:24:41 +03004173 int ret;
4174 GUARD_MODULE_INITIALIZED;
4175
4176 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
Gilles Peskine05d69892018-06-19 22:00:52 +02004177 return( mbedtls_to_psa_error( ret ) );
4178}
4179
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004180#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
avolinski13beb102018-11-20 16:51:49 +02004181
4182/* Support function for error conversion between psa_its error codes to psa crypto */
4183static psa_status_t its_to_psa_error( psa_its_status_t ret )
4184{
4185 switch( ret )
4186 {
4187 case PSA_ITS_SUCCESS:
4188 return( PSA_SUCCESS );
4189
4190 case PSA_ITS_ERROR_KEY_NOT_FOUND:
4191 return( PSA_ERROR_EMPTY_SLOT );
4192
4193 case PSA_ITS_ERROR_STORAGE_FAILURE:
4194 return( PSA_ERROR_STORAGE_FAILURE );
4195
4196 case PSA_ITS_ERROR_INSUFFICIENT_SPACE:
4197 return( PSA_ERROR_INSUFFICIENT_STORAGE );
4198
4199 case PSA_ITS_ERROR_INVALID_KEY:
Jaeden Amero58600552018-11-30 12:04:38 +00004200 case PSA_ITS_ERROR_OFFSET_INVALID:
avolinski13beb102018-11-20 16:51:49 +02004201 case PSA_ITS_ERROR_INCORRECT_SIZE:
4202 case PSA_ITS_ERROR_BAD_POINTER:
4203 return( PSA_ERROR_INVALID_ARGUMENT );
4204
4205 case PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED:
4206 return( PSA_ERROR_NOT_SUPPORTED );
4207
4208 case PSA_ITS_ERROR_WRITE_ONCE:
4209 return( PSA_ERROR_OCCUPIED_SLOT );
4210
4211 default:
4212 return( PSA_ERROR_UNKNOWN_ERROR );
4213 }
4214}
4215
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004216psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
4217 size_t seed_size )
4218{
4219 psa_status_t status;
avolinski13beb102018-11-20 16:51:49 +02004220 psa_its_status_t its_status;
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004221 struct psa_its_info_t p_info;
4222 if( global_data.initialized )
4223 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02004224
4225 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
4226 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
4227 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
4228 return( PSA_ERROR_INVALID_ARGUMENT );
4229
avolinski0d2c2662018-11-21 17:31:07 +02004230 its_status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
avolinski13beb102018-11-20 16:51:49 +02004231 status = its_to_psa_error( its_status );
4232
4233 if( PSA_ITS_ERROR_KEY_NOT_FOUND == its_status ) /* No seed exists */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004234 {
avolinski0d2c2662018-11-21 17:31:07 +02004235 its_status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
avolinski13beb102018-11-20 16:51:49 +02004236 status = its_to_psa_error( its_status );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004237 }
avolinski13beb102018-11-20 16:51:49 +02004238 else if( PSA_ITS_SUCCESS == its_status )
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004239 {
4240 /* You should not be here. Seed needs to be injected only once */
4241 status = PSA_ERROR_NOT_PERMITTED;
4242 }
4243 return( status );
4244}
4245#endif
4246
Gilles Peskinec5487a82018-12-03 18:08:14 +01004247psa_status_t psa_generate_key( psa_key_handle_t handle,
Gilles Peskine05d69892018-06-19 22:00:52 +02004248 psa_key_type_t type,
4249 size_t bits,
Gilles Peskine53d991e2018-07-12 01:14:59 +02004250 const void *extra,
4251 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02004252{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004253 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004254 psa_status_t status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004255
Gilles Peskine53d991e2018-07-12 01:14:59 +02004256 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004257 return( PSA_ERROR_INVALID_ARGUMENT );
4258
Gilles Peskinec5487a82018-12-03 18:08:14 +01004259 status = psa_get_empty_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004260 if( status != PSA_SUCCESS )
4261 return( status );
4262
Gilles Peskine48c0ea12018-06-21 14:15:31 +02004263 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004264 {
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004265 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004266 if( status != PSA_SUCCESS )
4267 return( status );
4268 status = psa_generate_random( slot->data.raw.data,
4269 slot->data.raw.bytes );
4270 if( status != PSA_SUCCESS )
4271 {
4272 mbedtls_free( slot->data.raw.data );
4273 return( status );
4274 }
4275#if defined(MBEDTLS_DES_C)
4276 if( type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02004277 psa_des_set_key_parity( slot->data.raw.data,
4278 slot->data.raw.bytes );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004279#endif /* MBEDTLS_DES_C */
4280 }
4281 else
4282
4283#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
4284 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
4285 {
4286 mbedtls_rsa_context *rsa;
4287 int ret;
4288 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02004289 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
4290 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +01004291 /* Accept only byte-aligned keys, for the same reasons as
4292 * in psa_import_rsa_key(). */
4293 if( bits % 8 != 0 )
4294 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02004295 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004296 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02004297 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004298 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004299 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02004300#if INT_MAX < 0xffffffff
4301 /* Check that the uint32_t value passed by the caller fits
4302 * in the range supported by this implementation. */
4303 if( p->e > INT_MAX )
4304 return( PSA_ERROR_NOT_SUPPORTED );
4305#endif
4306 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004307 }
4308 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
4309 if( rsa == NULL )
4310 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4311 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
4312 ret = mbedtls_rsa_gen_key( rsa,
4313 mbedtls_ctr_drbg_random,
4314 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004315 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02004316 exponent );
4317 if( ret != 0 )
4318 {
4319 mbedtls_rsa_free( rsa );
4320 mbedtls_free( rsa );
4321 return( mbedtls_to_psa_error( ret ) );
4322 }
4323 slot->data.rsa = rsa;
4324 }
4325 else
4326#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
4327
4328#if defined(MBEDTLS_ECP_C)
4329 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
4330 {
4331 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
4332 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
4333 const mbedtls_ecp_curve_info *curve_info =
4334 mbedtls_ecp_curve_info_from_grp_id( grp_id );
4335 mbedtls_ecp_keypair *ecp;
4336 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004337 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004338 return( PSA_ERROR_NOT_SUPPORTED );
4339 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
4340 return( PSA_ERROR_NOT_SUPPORTED );
4341 if( curve_info->bit_size != bits )
4342 return( PSA_ERROR_INVALID_ARGUMENT );
4343 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
4344 if( ecp == NULL )
4345 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4346 mbedtls_ecp_keypair_init( ecp );
4347 ret = mbedtls_ecp_gen_key( grp_id, ecp,
4348 mbedtls_ctr_drbg_random,
4349 &global_data.ctr_drbg );
4350 if( ret != 0 )
4351 {
4352 mbedtls_ecp_keypair_free( ecp );
4353 mbedtls_free( ecp );
4354 return( mbedtls_to_psa_error( ret ) );
4355 }
4356 slot->data.ecp = ecp;
4357 }
4358 else
4359#endif /* MBEDTLS_ECP_C */
4360
4361 return( PSA_ERROR_NOT_SUPPORTED );
4362
4363 slot->type = type;
Darryl Green0c6575a2018-11-07 16:05:30 +00004364
4365#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
4366 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
4367 {
Gilles Peskine69f976b2018-11-30 18:46:56 +01004368 return( psa_save_generated_persistent_key( slot, bits ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004369 }
4370#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
4371
4372 return( status );
Gilles Peskine05d69892018-06-19 22:00:52 +02004373}
4374
4375
4376/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01004377/* Module setup */
4378/****************************************************************/
4379
Gilles Peskine5e769522018-11-20 21:59:56 +01004380psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
4381 void (* entropy_init )( mbedtls_entropy_context *ctx ),
4382 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
4383{
4384 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4385 return( PSA_ERROR_BAD_STATE );
4386 global_data.entropy_init = entropy_init;
4387 global_data.entropy_free = entropy_free;
4388 return( PSA_SUCCESS );
4389}
4390
Gilles Peskinee59236f2018-01-27 23:32:46 +01004391void mbedtls_psa_crypto_free( void )
4392{
Gilles Peskine66fb1262018-12-10 16:29:04 +01004393 psa_wipe_all_key_slots( );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004394 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4395 {
4396 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
Gilles Peskine5e769522018-11-20 21:59:56 +01004397 global_data.entropy_free( &global_data.entropy );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004398 }
4399 /* Wipe all remaining data, including configuration.
4400 * In particular, this sets all state indicator to the value
4401 * indicating "uninitialized". */
Gilles Peskine3f108122018-12-07 18:14:53 +01004402 mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004403}
4404
4405psa_status_t psa_crypto_init( void )
4406{
Gilles Peskine66fb1262018-12-10 16:29:04 +01004407 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004408 const unsigned char drbg_seed[] = "PSA";
4409
Gilles Peskinec6b69072018-11-20 21:42:52 +01004410 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004411 if( global_data.initialized != 0 )
4412 return( PSA_SUCCESS );
4413
Gilles Peskine5e769522018-11-20 21:59:56 +01004414 /* Set default configuration if
4415 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
4416 if( global_data.entropy_init == NULL )
4417 global_data.entropy_init = mbedtls_entropy_init;
4418 if( global_data.entropy_free == NULL )
4419 global_data.entropy_free = mbedtls_entropy_free;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004420
Gilles Peskinec6b69072018-11-20 21:42:52 +01004421 /* Initialize the random generator. */
Gilles Peskine5e769522018-11-20 21:59:56 +01004422 global_data.entropy_init( &global_data.entropy );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004423 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004424 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskine66fb1262018-12-10 16:29:04 +01004425 status = mbedtls_to_psa_error(
4426 mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
4427 mbedtls_entropy_func,
4428 &global_data.entropy,
4429 drbg_seed, sizeof( drbg_seed ) - 1 ) );
4430 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01004431 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004432 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004433
Gilles Peskine66fb1262018-12-10 16:29:04 +01004434 status = psa_initialize_key_slots( );
4435 if( status != PSA_SUCCESS )
4436 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004437
4438 /* All done. */
Gilles Peskinee4ebc122018-03-07 14:16:44 +01004439 global_data.initialized = 1;
4440
Gilles Peskinee59236f2018-01-27 23:32:46 +01004441exit:
Gilles Peskine66fb1262018-12-10 16:29:04 +01004442 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01004443 mbedtls_psa_crypto_free( );
Gilles Peskine66fb1262018-12-10 16:29:04 +01004444 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004445}
4446
4447#endif /* MBEDTLS_PSA_CRYPTO_C */