blob: ce9e3e5f23c087a0ee4d8afbb72fcc6add0c5fa8 [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 Peskine5e769522018-11-20 21:59:56 +010046#include "psa_crypto_invasive.h"
Gilles Peskine961849f2018-11-30 18:54:54 +010047#include "psa_crypto_slot_management.h"
Darryl Greend49a4992018-06-18 17:27:26 +010048/* Include internal declarations that are useful for implementing persistently
49 * stored keys. */
50#include "psa_crypto_storage.h"
51
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010052#include <stdlib.h>
53#include <string.h>
54#if defined(MBEDTLS_PLATFORM_C)
55#include "mbedtls/platform.h"
56#else
57#define mbedtls_calloc calloc
58#define mbedtls_free free
59#endif
60
Gilles Peskinea5905292018-02-07 20:59:33 +010061#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020062#include "mbedtls/asn1.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020063#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010064#include "mbedtls/blowfish.h"
65#include "mbedtls/camellia.h"
66#include "mbedtls/cipher.h"
67#include "mbedtls/ccm.h"
68#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010069#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010070#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020071#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010072#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010073#include "mbedtls/entropy.h"
Netanel Gonen2bcd3122018-11-19 11:53:02 +020074#include "mbedtls/entropy_poll.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010075#include "mbedtls/error.h"
76#include "mbedtls/gcm.h"
77#include "mbedtls/md2.h"
78#include "mbedtls/md4.h"
79#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010080#include "mbedtls/md.h"
81#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010082#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010083#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010084#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010085#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010086#include "mbedtls/sha1.h"
87#include "mbedtls/sha256.h"
88#include "mbedtls/sha512.h"
89#include "mbedtls/xtea.h"
90
Netanel Gonen2bcd3122018-11-19 11:53:02 +020091#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
92#include "psa_prot_internal_storage.h"
93#endif
Gilles Peskinee59236f2018-01-27 23:32:46 +010094
Gilles Peskine996deb12018-08-01 15:45:45 +020095#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
96
Gilles Peskinee59236f2018-01-27 23:32:46 +010097/* Implementation that should never be optimized out by the compiler */
98static void mbedtls_zeroize( void *v, size_t n )
99{
100 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
101}
102
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100103/* constant-time buffer comparison */
104static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
105{
106 size_t i;
107 unsigned char diff = 0;
108
109 for( i = 0; i < n; i++ )
110 diff |= a[i] ^ b[i];
111
112 return( diff );
113}
114
115
116
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100117/****************************************************************/
118/* Global data, support functions and library management */
119/****************************************************************/
120
Gilles Peskine2d277862018-06-18 15:41:12 +0200121typedef struct
122{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100123 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300124 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200125 psa_key_lifetime_t lifetime;
Gilles Peskine69f976b2018-11-30 18:46:56 +0100126 psa_key_id_t persistent_storage_id;
Gilles Peskine961849f2018-11-30 18:54:54 +0100127 unsigned allocated : 1;
Gilles Peskine2d277862018-06-18 15:41:12 +0200128 union
129 {
130 struct raw_data
131 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100132 uint8_t *data;
133 size_t bytes;
134 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100135#if defined(MBEDTLS_RSA_C)
136 mbedtls_rsa_context *rsa;
137#endif /* MBEDTLS_RSA_C */
138#if defined(MBEDTLS_ECP_C)
139 mbedtls_ecp_keypair *ecp;
140#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100141 } data;
142} key_slot_t;
143
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200144static int key_type_is_raw_bytes( psa_key_type_t type )
145{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200146 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200147}
148
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100149/* Values for psa_global_data_t::rng_state */
150#define RNG_NOT_INITIALIZED 0
151#define RNG_INITIALIZED 1
152#define RNG_SEEDED 2
Gilles Peskinec6b69072018-11-20 21:42:52 +0100153
Gilles Peskine2d277862018-06-18 15:41:12 +0200154typedef struct
155{
Gilles Peskine5e769522018-11-20 21:59:56 +0100156 void (* entropy_init )( mbedtls_entropy_context *ctx );
157 void (* entropy_free )( mbedtls_entropy_context *ctx );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100158 mbedtls_entropy_context entropy;
159 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200160 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinec6b69072018-11-20 21:42:52 +0100161 unsigned initialized : 1;
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100162 unsigned rng_state : 2;
Gilles Peskinec6b69072018-11-20 21:42:52 +0100163 unsigned key_slots_initialized : 1;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100164} psa_global_data_t;
165
166static psa_global_data_t global_data;
167
itayzafrir0adf0fc2018-09-06 16:24:41 +0300168#define GUARD_MODULE_INITIALIZED \
169 if( global_data.initialized == 0 ) \
170 return( PSA_ERROR_BAD_STATE );
171
Gilles Peskinee59236f2018-01-27 23:32:46 +0100172static psa_status_t mbedtls_to_psa_error( int ret )
173{
Gilles Peskinea5905292018-02-07 20:59:33 +0100174 /* If there's both a high-level code and low-level code, dispatch on
175 * the high-level code. */
176 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100177 {
178 case 0:
179 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100180
181 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
182 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
183 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
184 return( PSA_ERROR_NOT_SUPPORTED );
185 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
186 return( PSA_ERROR_HARDWARE_FAILURE );
187
188 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
189 return( PSA_ERROR_HARDWARE_FAILURE );
190
Gilles Peskine9a944802018-06-21 09:35:35 +0200191 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
192 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
193 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
194 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
195 case MBEDTLS_ERR_ASN1_INVALID_DATA:
196 return( PSA_ERROR_INVALID_ARGUMENT );
197 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
198 return( PSA_ERROR_INSUFFICIENT_MEMORY );
199 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
200 return( PSA_ERROR_BUFFER_TOO_SMALL );
201
Gilles Peskinea5905292018-02-07 20:59:33 +0100202 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
203 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
204 return( PSA_ERROR_NOT_SUPPORTED );
205 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
206 return( PSA_ERROR_HARDWARE_FAILURE );
207
208 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
209 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
210 return( PSA_ERROR_NOT_SUPPORTED );
211 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
212 return( PSA_ERROR_HARDWARE_FAILURE );
213
214 case MBEDTLS_ERR_CCM_BAD_INPUT:
215 return( PSA_ERROR_INVALID_ARGUMENT );
216 case MBEDTLS_ERR_CCM_AUTH_FAILED:
217 return( PSA_ERROR_INVALID_SIGNATURE );
218 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
219 return( PSA_ERROR_HARDWARE_FAILURE );
220
221 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
222 return( PSA_ERROR_NOT_SUPPORTED );
223 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
224 return( PSA_ERROR_INVALID_ARGUMENT );
225 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
226 return( PSA_ERROR_INSUFFICIENT_MEMORY );
227 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
228 return( PSA_ERROR_INVALID_PADDING );
229 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
230 return( PSA_ERROR_BAD_STATE );
231 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
232 return( PSA_ERROR_INVALID_SIGNATURE );
233 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
234 return( PSA_ERROR_TAMPERING_DETECTED );
235 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
236 return( PSA_ERROR_HARDWARE_FAILURE );
237
238 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
239 return( PSA_ERROR_HARDWARE_FAILURE );
240
241 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
242 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
243 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
244 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
245 return( PSA_ERROR_NOT_SUPPORTED );
246 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
247 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
248
249 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
250 return( PSA_ERROR_NOT_SUPPORTED );
251 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
252 return( PSA_ERROR_HARDWARE_FAILURE );
253
Gilles Peskinee59236f2018-01-27 23:32:46 +0100254 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
255 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
256 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
257 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100258
259 case MBEDTLS_ERR_GCM_AUTH_FAILED:
260 return( PSA_ERROR_INVALID_SIGNATURE );
261 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200262 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100263 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
264 return( PSA_ERROR_HARDWARE_FAILURE );
265
266 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
267 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
268 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
269 return( PSA_ERROR_HARDWARE_FAILURE );
270
271 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
272 return( PSA_ERROR_NOT_SUPPORTED );
273 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
274 return( PSA_ERROR_INVALID_ARGUMENT );
275 case MBEDTLS_ERR_MD_ALLOC_FAILED:
276 return( PSA_ERROR_INSUFFICIENT_MEMORY );
277 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
278 return( PSA_ERROR_STORAGE_FAILURE );
279 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
280 return( PSA_ERROR_HARDWARE_FAILURE );
281
Gilles Peskinef76aa772018-10-29 19:24:33 +0100282 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
283 return( PSA_ERROR_STORAGE_FAILURE );
284 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
285 return( PSA_ERROR_INVALID_ARGUMENT );
286 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
287 return( PSA_ERROR_INVALID_ARGUMENT );
288 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
289 return( PSA_ERROR_BUFFER_TOO_SMALL );
290 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
291 return( PSA_ERROR_INVALID_ARGUMENT );
292 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
293 return( PSA_ERROR_INVALID_ARGUMENT );
294 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
295 return( PSA_ERROR_INVALID_ARGUMENT );
296 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
297 return( PSA_ERROR_INSUFFICIENT_MEMORY );
298
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100299 case MBEDTLS_ERR_PK_ALLOC_FAILED:
300 return( PSA_ERROR_INSUFFICIENT_MEMORY );
301 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
302 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
303 return( PSA_ERROR_INVALID_ARGUMENT );
304 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100305 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100306 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
307 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
308 return( PSA_ERROR_INVALID_ARGUMENT );
309 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
310 return( PSA_ERROR_NOT_SUPPORTED );
311 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
312 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
313 return( PSA_ERROR_NOT_PERMITTED );
314 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
315 return( PSA_ERROR_INVALID_ARGUMENT );
316 case MBEDTLS_ERR_PK_INVALID_ALG:
317 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
318 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
319 return( PSA_ERROR_NOT_SUPPORTED );
320 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
321 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100322 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
323 return( PSA_ERROR_HARDWARE_FAILURE );
324
325 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
326 return( PSA_ERROR_HARDWARE_FAILURE );
327
328 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
329 return( PSA_ERROR_INVALID_ARGUMENT );
330 case MBEDTLS_ERR_RSA_INVALID_PADDING:
331 return( PSA_ERROR_INVALID_PADDING );
332 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
333 return( PSA_ERROR_HARDWARE_FAILURE );
334 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
335 return( PSA_ERROR_INVALID_ARGUMENT );
336 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
337 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
338 return( PSA_ERROR_TAMPERING_DETECTED );
339 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
340 return( PSA_ERROR_INVALID_SIGNATURE );
341 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
342 return( PSA_ERROR_BUFFER_TOO_SMALL );
343 case MBEDTLS_ERR_RSA_RNG_FAILED:
344 return( PSA_ERROR_INSUFFICIENT_MEMORY );
345 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
346 return( PSA_ERROR_NOT_SUPPORTED );
347 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
348 return( PSA_ERROR_HARDWARE_FAILURE );
349
350 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
351 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
352 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
353 return( PSA_ERROR_HARDWARE_FAILURE );
354
355 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
356 return( PSA_ERROR_INVALID_ARGUMENT );
357 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
358 return( PSA_ERROR_HARDWARE_FAILURE );
359
itayzafrir5c753392018-05-08 11:18:38 +0300360 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300361 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300362 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300363 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
364 return( PSA_ERROR_BUFFER_TOO_SMALL );
365 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
366 return( PSA_ERROR_NOT_SUPPORTED );
367 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
368 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
369 return( PSA_ERROR_INVALID_SIGNATURE );
370 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
371 return( PSA_ERROR_INSUFFICIENT_MEMORY );
372 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
373 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300374
Gilles Peskinee59236f2018-01-27 23:32:46 +0100375 default:
376 return( PSA_ERROR_UNKNOWN_ERROR );
377 }
378}
379
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200380
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200381
382
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100383/****************************************************************/
384/* Key management */
385/****************************************************************/
386
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100387#if defined(MBEDTLS_ECP_C)
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200388static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
389{
390 switch( grpid )
391 {
392 case MBEDTLS_ECP_DP_SECP192R1:
393 return( PSA_ECC_CURVE_SECP192R1 );
394 case MBEDTLS_ECP_DP_SECP224R1:
395 return( PSA_ECC_CURVE_SECP224R1 );
396 case MBEDTLS_ECP_DP_SECP256R1:
397 return( PSA_ECC_CURVE_SECP256R1 );
398 case MBEDTLS_ECP_DP_SECP384R1:
399 return( PSA_ECC_CURVE_SECP384R1 );
400 case MBEDTLS_ECP_DP_SECP521R1:
401 return( PSA_ECC_CURVE_SECP521R1 );
402 case MBEDTLS_ECP_DP_BP256R1:
403 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
404 case MBEDTLS_ECP_DP_BP384R1:
405 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
406 case MBEDTLS_ECP_DP_BP512R1:
407 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
408 case MBEDTLS_ECP_DP_CURVE25519:
409 return( PSA_ECC_CURVE_CURVE25519 );
410 case MBEDTLS_ECP_DP_SECP192K1:
411 return( PSA_ECC_CURVE_SECP192K1 );
412 case MBEDTLS_ECP_DP_SECP224K1:
413 return( PSA_ECC_CURVE_SECP224K1 );
414 case MBEDTLS_ECP_DP_SECP256K1:
415 return( PSA_ECC_CURVE_SECP256K1 );
416 case MBEDTLS_ECP_DP_CURVE448:
417 return( PSA_ECC_CURVE_CURVE448 );
418 default:
419 return( 0 );
420 }
421}
422
Gilles Peskine12313cd2018-06-20 00:20:32 +0200423static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
424{
425 switch( curve )
426 {
427 case PSA_ECC_CURVE_SECP192R1:
428 return( MBEDTLS_ECP_DP_SECP192R1 );
429 case PSA_ECC_CURVE_SECP224R1:
430 return( MBEDTLS_ECP_DP_SECP224R1 );
431 case PSA_ECC_CURVE_SECP256R1:
432 return( MBEDTLS_ECP_DP_SECP256R1 );
433 case PSA_ECC_CURVE_SECP384R1:
434 return( MBEDTLS_ECP_DP_SECP384R1 );
435 case PSA_ECC_CURVE_SECP521R1:
436 return( MBEDTLS_ECP_DP_SECP521R1 );
437 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
438 return( MBEDTLS_ECP_DP_BP256R1 );
439 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
440 return( MBEDTLS_ECP_DP_BP384R1 );
441 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
442 return( MBEDTLS_ECP_DP_BP512R1 );
443 case PSA_ECC_CURVE_CURVE25519:
444 return( MBEDTLS_ECP_DP_CURVE25519 );
445 case PSA_ECC_CURVE_SECP192K1:
446 return( MBEDTLS_ECP_DP_SECP192K1 );
447 case PSA_ECC_CURVE_SECP224K1:
448 return( MBEDTLS_ECP_DP_SECP224K1 );
449 case PSA_ECC_CURVE_SECP256K1:
450 return( MBEDTLS_ECP_DP_SECP256K1 );
451 case PSA_ECC_CURVE_CURVE448:
452 return( MBEDTLS_ECP_DP_CURVE448 );
453 default:
454 return( MBEDTLS_ECP_DP_NONE );
455 }
456}
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100457#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200458
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200459static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
460 size_t bits,
461 struct raw_data *raw )
462{
463 /* Check that the bit size is acceptable for the key type */
464 switch( type )
465 {
466 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200467 if( bits == 0 )
468 {
469 raw->bytes = 0;
470 raw->data = NULL;
471 return( PSA_SUCCESS );
472 }
473 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200474#if defined(MBEDTLS_MD_C)
475 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200476#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200477 case PSA_KEY_TYPE_DERIVE:
478 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200479#if defined(MBEDTLS_AES_C)
480 case PSA_KEY_TYPE_AES:
481 if( bits != 128 && bits != 192 && bits != 256 )
482 return( PSA_ERROR_INVALID_ARGUMENT );
483 break;
484#endif
485#if defined(MBEDTLS_CAMELLIA_C)
486 case PSA_KEY_TYPE_CAMELLIA:
487 if( bits != 128 && bits != 192 && bits != 256 )
488 return( PSA_ERROR_INVALID_ARGUMENT );
489 break;
490#endif
491#if defined(MBEDTLS_DES_C)
492 case PSA_KEY_TYPE_DES:
493 if( bits != 64 && bits != 128 && bits != 192 )
494 return( PSA_ERROR_INVALID_ARGUMENT );
495 break;
496#endif
497#if defined(MBEDTLS_ARC4_C)
498 case PSA_KEY_TYPE_ARC4:
499 if( bits < 8 || bits > 2048 )
500 return( PSA_ERROR_INVALID_ARGUMENT );
501 break;
502#endif
503 default:
504 return( PSA_ERROR_NOT_SUPPORTED );
505 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200506 if( bits % 8 != 0 )
507 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200508
509 /* Allocate memory for the key */
510 raw->bytes = PSA_BITS_TO_BYTES( bits );
511 raw->data = mbedtls_calloc( 1, raw->bytes );
512 if( raw->data == NULL )
513 {
514 raw->bytes = 0;
515 return( PSA_ERROR_INSUFFICIENT_MEMORY );
516 }
517 return( PSA_SUCCESS );
518}
519
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200520#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine86a440b2018-11-12 18:39:40 +0100521/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
522 * that are not a multiple of 8) well. For example, there is only
523 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
524 * way to return the exact bit size of a key.
525 * To keep things simple, reject non-byte-aligned key sizes. */
526static psa_status_t psa_check_rsa_key_byte_aligned(
527 const mbedtls_rsa_context *rsa )
528{
529 mbedtls_mpi n;
530 psa_status_t status;
531 mbedtls_mpi_init( &n );
532 status = mbedtls_to_psa_error(
533 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
534 if( status == PSA_SUCCESS )
535 {
536 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
537 status = PSA_ERROR_NOT_SUPPORTED;
538 }
539 mbedtls_mpi_free( &n );
540 return( status );
541}
542
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200543static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
544 mbedtls_rsa_context **p_rsa )
545{
546 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_RSA )
547 return( PSA_ERROR_INVALID_ARGUMENT );
548 else
549 {
550 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *pk );
Gilles Peskineaac64a22018-11-12 18:37:42 +0100551 /* The size of an RSA key doesn't have to be a multiple of 8.
552 * Mbed TLS supports non-byte-aligned key sizes, but not well.
553 * For example, mbedtls_rsa_get_len() returns the key size in
554 * bytes, not in bits. */
555 size_t bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100556 psa_status_t status;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200557 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
558 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100559 status = psa_check_rsa_key_byte_aligned( rsa );
560 if( status != PSA_SUCCESS )
561 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200562 *p_rsa = rsa;
563 return( PSA_SUCCESS );
564 }
565}
566#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
567
568#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinef76aa772018-10-29 19:24:33 +0100569/* Import an elliptic curve parsed by the mbedtls pk module. */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200570static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
571 mbedtls_pk_context *pk,
572 mbedtls_ecp_keypair **p_ecp )
573{
574 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
575 return( PSA_ERROR_INVALID_ARGUMENT );
576 else
577 {
578 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
579 psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
580 if( actual_curve != expected_curve )
581 return( PSA_ERROR_INVALID_ARGUMENT );
582 *p_ecp = ecp;
583 return( PSA_SUCCESS );
584 }
585}
586#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
587
Gilles Peskinef76aa772018-10-29 19:24:33 +0100588#if defined(MBEDTLS_ECP_C)
589/* Import a private key given as a byte string which is the private value
590 * in big-endian order. */
591static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
592 const uint8_t *data,
593 size_t data_length,
594 mbedtls_ecp_keypair **p_ecp )
595{
596 psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
597 mbedtls_ecp_keypair *ecp = NULL;
598 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
599
600 *p_ecp = NULL;
601 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
602 if( ecp == NULL )
603 return( PSA_ERROR_INSUFFICIENT_MEMORY );
604
605 /* Load the group. */
606 status = mbedtls_to_psa_error(
607 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
608 if( status != PSA_SUCCESS )
609 goto exit;
610 /* Load the secret value. */
611 status = mbedtls_to_psa_error(
612 mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
613 if( status != PSA_SUCCESS )
614 goto exit;
615 /* Validate the private key. */
616 status = mbedtls_to_psa_error(
617 mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
618 if( status != PSA_SUCCESS )
619 goto exit;
620 /* Calculate the public key from the private key. */
621 status = mbedtls_to_psa_error(
622 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
623 mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
624 if( status != PSA_SUCCESS )
625 goto exit;
626
627 *p_ecp = ecp;
628 return( PSA_SUCCESS );
629
630exit:
631 if( ecp != NULL )
632 {
633 mbedtls_ecp_keypair_free( ecp );
634 mbedtls_free( ecp );
635 }
636 return( status );
637}
638#endif /* defined(MBEDTLS_ECP_C) */
639
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100640/** Import key data into a slot. `slot->type` must have been set
641 * previously. This function assumes that the slot does not contain
642 * any key material yet. On failure, the slot content is unchanged. */
Darryl Green940d72c2018-07-13 13:18:51 +0100643static psa_status_t psa_import_key_into_slot( key_slot_t *slot,
644 const uint8_t *data,
645 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100646{
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200647 psa_status_t status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100648
Darryl Green940d72c2018-07-13 13:18:51 +0100649 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100650 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100651 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100652 if( data_length > SIZE_MAX / 8 )
653 return( PSA_ERROR_NOT_SUPPORTED );
Darryl Green940d72c2018-07-13 13:18:51 +0100654 status = prepare_raw_data_slot( slot->type,
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200655 PSA_BYTES_TO_BITS( data_length ),
656 &slot->data.raw );
657 if( status != PSA_SUCCESS )
658 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200659 if( data_length != 0 )
660 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100661 }
662 else
Gilles Peskinef76aa772018-10-29 19:24:33 +0100663#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100664 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100665 {
Darryl Green940d72c2018-07-13 13:18:51 +0100666 status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskinef76aa772018-10-29 19:24:33 +0100667 data, data_length,
668 &slot->data.ecp );
669 if( status != PSA_SUCCESS )
670 return( status );
671 }
672 else
673#endif /* MBEDTLS_ECP_C */
Gilles Peskine969ac722018-01-28 18:16:59 +0100674#if defined(MBEDTLS_PK_PARSE_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100675 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
676 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100677 {
678 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100679 mbedtls_pk_context pk;
680 mbedtls_pk_init( &pk );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200681
682 /* Parse the data. */
Darryl Green940d72c2018-07-13 13:18:51 +0100683 if( PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100684 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
685 else
686 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100687 if( ret != 0 )
688 return( mbedtls_to_psa_error( ret ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200689
690 /* We have something that the pkparse module recognizes.
691 * If it has the expected type and passes any type-specific
692 * checks, store it. */
Gilles Peskine969ac722018-01-28 18:16:59 +0100693#if defined(MBEDTLS_RSA_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100694 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200695 status = psa_import_rsa_key( &pk, &slot->data.rsa );
696 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100697#endif /* MBEDTLS_RSA_C */
698#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100699 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
700 status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200701 &pk, &slot->data.ecp );
702 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100703#endif /* MBEDTLS_ECP_C */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200704 {
705 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinec648d692018-06-28 08:46:13 +0200706 }
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200707
Gilles Peskinec648d692018-06-28 08:46:13 +0200708 /* Free the content of the pk object only on error. On success,
709 * the content of the object has been stored in the slot. */
710 if( status != PSA_SUCCESS )
711 {
712 mbedtls_pk_free( &pk );
713 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100714 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100715 }
716 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100717#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100718 {
719 return( PSA_ERROR_NOT_SUPPORTED );
720 }
Darryl Green940d72c2018-07-13 13:18:51 +0100721 return( PSA_SUCCESS );
722}
723
Darryl Greend49a4992018-06-18 17:27:26 +0100724#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine69f976b2018-11-30 18:46:56 +0100725static psa_status_t psa_load_persistent_key_into_slot( key_slot_t *p_slot )
Darryl Greend49a4992018-06-18 17:27:26 +0100726{
727 psa_status_t status = PSA_SUCCESS;
728 uint8_t *key_data = NULL;
729 size_t key_data_length = 0;
730
Gilles Peskine69f976b2018-11-30 18:46:56 +0100731 status = psa_load_persistent_key( p_slot->persistent_storage_id,
732 &( p_slot )->type,
Darryl Greend49a4992018-06-18 17:27:26 +0100733 &( p_slot )->policy, &key_data,
734 &key_data_length );
735 if( status != PSA_SUCCESS )
736 goto exit;
737 status = psa_import_key_into_slot( p_slot,
738 key_data, key_data_length );
739exit:
740 psa_free_persistent_key_data( key_data, key_data_length );
741 return( status );
742}
743#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
744
Gilles Peskinec5487a82018-12-03 18:08:14 +0100745/* Access a key slot at the given handle. The handle of a key slot is
746 * the index of the slot in the global slot array, plus one so that handles
747 * start at 1 and not 0. */
748static psa_status_t psa_get_key_slot( psa_key_handle_t handle,
Darryl Green06fd18d2018-07-16 11:21:11 +0100749 key_slot_t **p_slot )
750{
Gilles Peskinec5487a82018-12-03 18:08:14 +0100751 key_slot_t *slot = NULL;
Gilles Peskine961849f2018-11-30 18:54:54 +0100752
Darryl Green06fd18d2018-07-16 11:21:11 +0100753 GUARD_MODULE_INITIALIZED;
754
Gilles Peskinec5487a82018-12-03 18:08:14 +0100755 /* 0 is not a valid handle under any circumstance. This
Darryl Green06fd18d2018-07-16 11:21:11 +0100756 * implementation provides slots number 1 to N where N is the
757 * number of available slots. */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100758 if( handle == 0 || handle > ARRAY_LENGTH( global_data.key_slots ) )
759 return( PSA_ERROR_INVALID_HANDLE );
760 slot = &global_data.key_slots[handle - 1];
Darryl Green06fd18d2018-07-16 11:21:11 +0100761
Gilles Peskinec5487a82018-12-03 18:08:14 +0100762 /* If the slot hasn't been allocated, the handle is invalid. */
763 if( ! slot->allocated )
764 return( PSA_ERROR_INVALID_HANDLE );
Darryl Greend49a4992018-06-18 17:27:26 +0100765
Gilles Peskinec5487a82018-12-03 18:08:14 +0100766 *p_slot = slot;
Darryl Green06fd18d2018-07-16 11:21:11 +0100767 return( PSA_SUCCESS );
768}
769
770/* Retrieve an empty key slot (slot with no key data, but possibly
771 * with some metadata such as a policy). */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100772static psa_status_t psa_get_empty_key_slot( psa_key_handle_t handle,
Darryl Green06fd18d2018-07-16 11:21:11 +0100773 key_slot_t **p_slot )
774{
775 psa_status_t status;
776 key_slot_t *slot = NULL;
777
778 *p_slot = NULL;
779
Gilles Peskinec5487a82018-12-03 18:08:14 +0100780 status = psa_get_key_slot( handle, &slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100781 if( status != PSA_SUCCESS )
782 return( status );
783
784 if( slot->type != PSA_KEY_TYPE_NONE )
785 return( PSA_ERROR_OCCUPIED_SLOT );
786
787 *p_slot = slot;
788 return( status );
789}
790
791/** Retrieve a slot which must contain a key. The key must have allow all the
792 * usage flags set in \p usage. If \p alg is nonzero, the key must allow
793 * operations with this algorithm. */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100794static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle,
Darryl Green06fd18d2018-07-16 11:21:11 +0100795 key_slot_t **p_slot,
796 psa_key_usage_t usage,
797 psa_algorithm_t alg )
798{
799 psa_status_t status;
800 key_slot_t *slot = NULL;
801
802 *p_slot = NULL;
803
Gilles Peskinec5487a82018-12-03 18:08:14 +0100804 status = psa_get_key_slot( handle, &slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100805 if( status != PSA_SUCCESS )
806 return( status );
807 if( slot->type == PSA_KEY_TYPE_NONE )
808 return( PSA_ERROR_EMPTY_SLOT );
809
810 /* Enforce that usage policy for the key slot contains all the flags
811 * required by the usage parameter. There is one exception: public
812 * keys can always be exported, so we treat public key objects as
813 * if they had the export flag. */
814 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
815 usage &= ~PSA_KEY_USAGE_EXPORT;
816 if( ( slot->policy.usage & usage ) != usage )
817 return( PSA_ERROR_NOT_PERMITTED );
818 if( alg != 0 && ( alg != slot->policy.alg ) )
819 return( PSA_ERROR_NOT_PERMITTED );
820
821 *p_slot = slot;
822 return( PSA_SUCCESS );
823}
Darryl Green940d72c2018-07-13 13:18:51 +0100824
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100825/** Wipe key data from a slot. Preserve metadata such as the policy. */
Darryl Green40225ba2018-11-15 14:48:15 +0000826static psa_status_t psa_remove_key_data_from_memory( key_slot_t *slot )
827{
828 if( slot->type == PSA_KEY_TYPE_NONE )
829 {
830 /* No key material to clean. */
831 }
832 else if( key_type_is_raw_bytes( slot->type ) )
833 {
834 mbedtls_free( slot->data.raw.data );
835 }
836 else
837#if defined(MBEDTLS_RSA_C)
838 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
839 {
840 mbedtls_rsa_free( slot->data.rsa );
841 mbedtls_free( slot->data.rsa );
842 }
843 else
844#endif /* defined(MBEDTLS_RSA_C) */
845#if defined(MBEDTLS_ECP_C)
846 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
847 {
848 mbedtls_ecp_keypair_free( slot->data.ecp );
849 mbedtls_free( slot->data.ecp );
850 }
851 else
852#endif /* defined(MBEDTLS_ECP_C) */
853 {
854 /* Shouldn't happen: the key type is not any type that we
855 * put in. */
856 return( PSA_ERROR_TAMPERING_DETECTED );
857 }
858
859 return( PSA_SUCCESS );
860}
861
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100862/** Completely wipe a slot in memory, including its policy.
863 * Persistent storage is not affected. */
864static psa_status_t psa_wipe_key_slot( key_slot_t *slot )
865{
866 psa_status_t status = psa_remove_key_data_from_memory( slot );
867 /* At this point, key material and other type-specific content has
868 * been wiped. Clear remaining metadata. We can call memset and not
869 * zeroize because the metadata is not particularly sensitive. */
870 memset( slot, 0, sizeof( *slot ) );
871 return( status );
872}
873
Gilles Peskine961849f2018-11-30 18:54:54 +0100874psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle )
875{
Gilles Peskinec5487a82018-12-03 18:08:14 +0100876 for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) )
Gilles Peskine961849f2018-11-30 18:54:54 +0100877 {
Gilles Peskinec5487a82018-12-03 18:08:14 +0100878 key_slot_t *slot = &global_data.key_slots[*handle - 1];
879 if( ! slot->allocated )
Gilles Peskine961849f2018-11-30 18:54:54 +0100880 {
881 slot->allocated = 1;
Gilles Peskine961849f2018-11-30 18:54:54 +0100882 return( PSA_SUCCESS );
883 }
884 }
885 return( PSA_ERROR_INSUFFICIENT_MEMORY );
886}
887
888psa_status_t psa_internal_make_key_persistent( psa_key_handle_t handle,
889 psa_key_id_t id )
890{
891 key_slot_t *slot;
892 psa_status_t status;
893
894 /* Reject id=0 because by general library conventions, 0 is an invalid
895 * value wherever possible. */
896 if( id == 0 )
897 return( PSA_ERROR_INVALID_ARGUMENT );
898 /* Reject high values because the file names are reserved for the
899 * library's internal use. */
900 if( id >= 0xffff0000 )
901 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine961849f2018-11-30 18:54:54 +0100902
903 status = psa_get_key_slot( handle, &slot );
904 if( status != PSA_SUCCESS )
905 return( status );
906
907 slot->lifetime = PSA_KEY_LIFETIME_PERSISTENT;
908 slot->persistent_storage_id = id;
909 status = psa_load_persistent_key_into_slot( slot );
910
911 return( status );
912}
913
914psa_status_t psa_internal_release_key_slot( psa_key_handle_t handle )
915{
Gilles Peskine961849f2018-11-30 18:54:54 +0100916 key_slot_t *slot;
Gilles Peskinec5487a82018-12-03 18:08:14 +0100917 psa_status_t status;
918
919 status = psa_get_key_slot( handle, &slot );
920 if( status != PSA_SUCCESS )
921 return( status );
Gilles Peskine961849f2018-11-30 18:54:54 +0100922 if( ! slot->allocated )
923 return( PSA_ERROR_INVALID_HANDLE );
Gilles Peskinec5487a82018-12-03 18:08:14 +0100924
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100925 return( psa_wipe_key_slot( slot ) );
Gilles Peskine961849f2018-11-30 18:54:54 +0100926}
927
Gilles Peskinec5487a82018-12-03 18:08:14 +0100928psa_status_t psa_import_key( psa_key_handle_t handle,
Darryl Green940d72c2018-07-13 13:18:51 +0100929 psa_key_type_t type,
930 const uint8_t *data,
931 size_t data_length )
932{
933 key_slot_t *slot;
934 psa_status_t status;
935
Gilles Peskinec5487a82018-12-03 18:08:14 +0100936 status = psa_get_empty_key_slot( handle, &slot );
Darryl Green940d72c2018-07-13 13:18:51 +0100937 if( status != PSA_SUCCESS )
938 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100939
940 slot->type = type;
Darryl Green940d72c2018-07-13 13:18:51 +0100941
942 status = psa_import_key_into_slot( slot, data, data_length );
943 if( status != PSA_SUCCESS )
944 {
945 slot->type = PSA_KEY_TYPE_NONE;
946 return( status );
947 }
948
Darryl Greend49a4992018-06-18 17:27:26 +0100949#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
950 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
951 {
952 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +0100953 status = psa_save_persistent_key( slot->persistent_storage_id,
954 slot->type, &slot->policy, data,
Darryl Greend49a4992018-06-18 17:27:26 +0100955 data_length );
956 if( status != PSA_SUCCESS )
957 {
958 (void) psa_remove_key_data_from_memory( slot );
959 slot->type = PSA_KEY_TYPE_NONE;
960 }
961 }
962#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
963
964 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100965}
966
Gilles Peskinec5487a82018-12-03 18:08:14 +0100967psa_status_t psa_destroy_key( psa_key_handle_t handle )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100968{
969 key_slot_t *slot;
Darryl Greend49a4992018-06-18 17:27:26 +0100970 psa_status_t status = PSA_SUCCESS;
971 psa_status_t storage_status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100972
Gilles Peskinec5487a82018-12-03 18:08:14 +0100973 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200974 if( status != PSA_SUCCESS )
975 return( status );
Darryl Greend49a4992018-06-18 17:27:26 +0100976#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
977 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
978 {
Gilles Peskine69f976b2018-11-30 18:46:56 +0100979 storage_status =
980 psa_destroy_persistent_key( slot->persistent_storage_id );
Darryl Greend49a4992018-06-18 17:27:26 +0100981 }
982#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100983 status = psa_wipe_key_slot( slot );
Darryl Greend49a4992018-06-18 17:27:26 +0100984 if( status != PSA_SUCCESS )
985 return( status );
986 return( storage_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100987}
988
Gilles Peskineb870b182018-07-06 16:02:09 +0200989/* Return the size of the key in the given slot, in bits. */
990static size_t psa_get_key_bits( const key_slot_t *slot )
991{
992 if( key_type_is_raw_bytes( slot->type ) )
993 return( slot->data.raw.bytes * 8 );
994#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200995 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaac64a22018-11-12 18:37:42 +0100996 return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
Gilles Peskineb870b182018-07-06 16:02:09 +0200997#endif /* defined(MBEDTLS_RSA_C) */
998#if defined(MBEDTLS_ECP_C)
999 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1000 return( slot->data.ecp->grp.pbits );
1001#endif /* defined(MBEDTLS_ECP_C) */
1002 /* Shouldn't happen except on an empty slot. */
1003 return( 0 );
1004}
1005
Gilles Peskinec5487a82018-12-03 18:08:14 +01001006psa_status_t psa_get_key_information( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001007 psa_key_type_t *type,
1008 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001009{
1010 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001011 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001012
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001013 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001014 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001015 if( bits != NULL )
1016 *bits = 0;
Gilles Peskinec5487a82018-12-03 18:08:14 +01001017 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001018 if( status != PSA_SUCCESS )
1019 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +02001020
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001021 if( slot->type == PSA_KEY_TYPE_NONE )
1022 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001023 if( type != NULL )
1024 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +02001025 if( bits != NULL )
1026 *bits = psa_get_key_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001027 return( PSA_SUCCESS );
1028}
1029
Darryl Greendd8fb772018-11-07 16:00:44 +00001030static psa_status_t psa_internal_export_key( key_slot_t *slot,
Gilles Peskine2d277862018-06-18 15:41:12 +02001031 uint8_t *data,
1032 size_t data_size,
1033 size_t *data_length,
1034 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001035{
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001036 *data_length = 0;
1037
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001038 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001039 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +03001040
Gilles Peskine48c0ea12018-06-21 14:15:31 +02001041 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001042 {
1043 if( slot->data.raw.bytes > data_size )
1044 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine52b90182018-10-29 19:26:27 +01001045 if( data_size != 0 )
1046 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001047 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine52b90182018-10-29 19:26:27 +01001048 memset( data + slot->data.raw.bytes, 0,
1049 data_size - slot->data.raw.bytes );
1050 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001051 *data_length = slot->data.raw.bytes;
1052 return( PSA_SUCCESS );
1053 }
Gilles Peskine188c71e2018-10-29 19:26:02 +01001054#if defined(MBEDTLS_ECP_C)
1055 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) && !export_public_key )
1056 {
Darryl Greendd8fb772018-11-07 16:00:44 +00001057 psa_status_t status;
1058
Gilles Peskine188c71e2018-10-29 19:26:02 +01001059 size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( slot ) );
1060 if( bytes > data_size )
1061 return( PSA_ERROR_BUFFER_TOO_SMALL );
1062 status = mbedtls_to_psa_error(
1063 mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
1064 if( status != PSA_SUCCESS )
1065 return( status );
1066 memset( data + bytes, 0, data_size - bytes );
1067 *data_length = bytes;
1068 return( PSA_SUCCESS );
1069 }
1070#endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001071 else
Moran Peker17e36e12018-05-02 12:55:20 +03001072 {
Gilles Peskine969ac722018-01-28 18:16:59 +01001073#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02001074 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
Moran Pekera998bc62018-04-16 18:16:20 +03001075 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +01001076 {
Moran Pekera998bc62018-04-16 18:16:20 +03001077 mbedtls_pk_context pk;
1078 int ret;
Gilles Peskined8008d62018-06-29 19:51:51 +02001079 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001080 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001081#if defined(MBEDTLS_RSA_C)
1082 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001083 pk.pk_info = &mbedtls_rsa_info;
1084 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001085#else
1086 return( PSA_ERROR_NOT_SUPPORTED );
1087#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001088 }
1089 else
1090 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001091#if defined(MBEDTLS_ECP_C)
1092 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001093 pk.pk_info = &mbedtls_eckey_info;
1094 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001095#else
1096 return( PSA_ERROR_NOT_SUPPORTED );
1097#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001098 }
Moran Pekerd7326592018-05-29 16:56:39 +03001099 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001100 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +03001101 else
1102 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +03001103 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001104 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001105 /* If data_size is 0 then data may be NULL and then the
1106 * call to memset would have undefined behavior. */
1107 if( data_size != 0 )
1108 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +03001109 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001110 }
Gilles Peskine0e231582018-06-20 00:11:07 +02001111 /* The mbedtls_pk_xxx functions write to the end of the buffer.
1112 * Move the data to the beginning and erase remaining data
1113 * at the original location. */
1114 if( 2 * (size_t) ret <= data_size )
1115 {
1116 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001117 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001118 }
1119 else if( (size_t) ret < data_size )
1120 {
1121 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001122 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001123 }
Moran Pekera998bc62018-04-16 18:16:20 +03001124 *data_length = ret;
1125 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +01001126 }
1127 else
Gilles Peskine6d912132018-03-07 16:41:37 +01001128#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +03001129 {
1130 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +02001131 it is valid for a special-purpose implementation to omit
1132 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +03001133 return( PSA_ERROR_NOT_SUPPORTED );
1134 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001135 }
1136}
1137
Gilles Peskinec5487a82018-12-03 18:08:14 +01001138psa_status_t psa_export_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001139 uint8_t *data,
1140 size_t data_size,
1141 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001142{
Darryl Greendd8fb772018-11-07 16:00:44 +00001143 key_slot_t *slot;
1144 psa_status_t status;
1145
1146 /* Set the key to empty now, so that even when there are errors, we always
1147 * set data_length to a value between 0 and data_size. On error, setting
1148 * the key to empty is a good choice because an empty key representation is
1149 * unlikely to be accepted anywhere. */
1150 *data_length = 0;
1151
1152 /* Export requires the EXPORT flag. There is an exception for public keys,
1153 * which don't require any flag, but psa_get_key_from_slot takes
1154 * care of this. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001155 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_EXPORT, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001156 if( status != PSA_SUCCESS )
1157 return( status );
1158 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001159 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001160}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001161
Gilles Peskinec5487a82018-12-03 18:08:14 +01001162psa_status_t psa_export_public_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001163 uint8_t *data,
1164 size_t data_size,
1165 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001166{
Darryl Greendd8fb772018-11-07 16:00:44 +00001167 key_slot_t *slot;
1168 psa_status_t status;
1169
1170 /* Set the key to empty now, so that even when there are errors, we always
1171 * set data_length to a value between 0 and data_size. On error, setting
1172 * the key to empty is a good choice because an empty key representation is
1173 * unlikely to be accepted anywhere. */
1174 *data_length = 0;
1175
1176 /* Exporting a public key doesn't require a usage flag. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001177 status = psa_get_key_from_slot( handle, &slot, 0, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001178 if( status != PSA_SUCCESS )
1179 return( status );
1180 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001181 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001182}
1183
Darryl Green0c6575a2018-11-07 16:05:30 +00001184#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine69f976b2018-11-30 18:46:56 +01001185static psa_status_t psa_save_generated_persistent_key( key_slot_t *slot,
Darryl Green0c6575a2018-11-07 16:05:30 +00001186 size_t bits )
1187{
1188 psa_status_t status;
1189 uint8_t *data;
1190 size_t key_length;
1191 size_t data_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type, bits );
1192 data = mbedtls_calloc( 1, data_size );
itayzafrir910c76b2018-11-21 16:03:21 +02001193 if( data == NULL )
1194 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Darryl Green0c6575a2018-11-07 16:05:30 +00001195 /* Get key data in export format */
1196 status = psa_internal_export_key( slot, data, data_size, &key_length, 0 );
1197 if( status != PSA_SUCCESS )
1198 {
1199 slot->type = PSA_KEY_TYPE_NONE;
1200 goto exit;
1201 }
1202 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +01001203 status = psa_save_persistent_key( slot->persistent_storage_id,
1204 slot->type, &slot->policy,
Darryl Green0c6575a2018-11-07 16:05:30 +00001205 data, key_length );
1206 if( status != PSA_SUCCESS )
1207 {
1208 slot->type = PSA_KEY_TYPE_NONE;
1209 }
1210exit:
1211 mbedtls_zeroize( data, key_length );
1212 mbedtls_free( data );
1213 return( status );
1214}
1215#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1216
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001217
1218
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001219/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01001220/* Message digests */
1221/****************************************************************/
1222
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001223static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01001224{
1225 switch( alg )
1226 {
1227#if defined(MBEDTLS_MD2_C)
1228 case PSA_ALG_MD2:
1229 return( &mbedtls_md2_info );
1230#endif
1231#if defined(MBEDTLS_MD4_C)
1232 case PSA_ALG_MD4:
1233 return( &mbedtls_md4_info );
1234#endif
1235#if defined(MBEDTLS_MD5_C)
1236 case PSA_ALG_MD5:
1237 return( &mbedtls_md5_info );
1238#endif
1239#if defined(MBEDTLS_RIPEMD160_C)
1240 case PSA_ALG_RIPEMD160:
1241 return( &mbedtls_ripemd160_info );
1242#endif
1243#if defined(MBEDTLS_SHA1_C)
1244 case PSA_ALG_SHA_1:
1245 return( &mbedtls_sha1_info );
1246#endif
1247#if defined(MBEDTLS_SHA256_C)
1248 case PSA_ALG_SHA_224:
1249 return( &mbedtls_sha224_info );
1250 case PSA_ALG_SHA_256:
1251 return( &mbedtls_sha256_info );
1252#endif
1253#if defined(MBEDTLS_SHA512_C)
1254 case PSA_ALG_SHA_384:
1255 return( &mbedtls_sha384_info );
1256 case PSA_ALG_SHA_512:
1257 return( &mbedtls_sha512_info );
1258#endif
1259 default:
1260 return( NULL );
1261 }
1262}
1263
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001264psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
1265{
1266 switch( operation->alg )
1267 {
Gilles Peskine81736312018-06-26 15:04:31 +02001268 case 0:
1269 /* The object has (apparently) been initialized but it is not
1270 * in use. It's ok to call abort on such an object, and there's
1271 * nothing to do. */
1272 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001273#if defined(MBEDTLS_MD2_C)
1274 case PSA_ALG_MD2:
1275 mbedtls_md2_free( &operation->ctx.md2 );
1276 break;
1277#endif
1278#if defined(MBEDTLS_MD4_C)
1279 case PSA_ALG_MD4:
1280 mbedtls_md4_free( &operation->ctx.md4 );
1281 break;
1282#endif
1283#if defined(MBEDTLS_MD5_C)
1284 case PSA_ALG_MD5:
1285 mbedtls_md5_free( &operation->ctx.md5 );
1286 break;
1287#endif
1288#if defined(MBEDTLS_RIPEMD160_C)
1289 case PSA_ALG_RIPEMD160:
1290 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
1291 break;
1292#endif
1293#if defined(MBEDTLS_SHA1_C)
1294 case PSA_ALG_SHA_1:
1295 mbedtls_sha1_free( &operation->ctx.sha1 );
1296 break;
1297#endif
1298#if defined(MBEDTLS_SHA256_C)
1299 case PSA_ALG_SHA_224:
1300 case PSA_ALG_SHA_256:
1301 mbedtls_sha256_free( &operation->ctx.sha256 );
1302 break;
1303#endif
1304#if defined(MBEDTLS_SHA512_C)
1305 case PSA_ALG_SHA_384:
1306 case PSA_ALG_SHA_512:
1307 mbedtls_sha512_free( &operation->ctx.sha512 );
1308 break;
1309#endif
1310 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001311 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001312 }
1313 operation->alg = 0;
1314 return( PSA_SUCCESS );
1315}
1316
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02001317psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001318 psa_algorithm_t alg )
1319{
1320 int ret;
1321 operation->alg = 0;
1322 switch( alg )
1323 {
1324#if defined(MBEDTLS_MD2_C)
1325 case PSA_ALG_MD2:
1326 mbedtls_md2_init( &operation->ctx.md2 );
1327 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
1328 break;
1329#endif
1330#if defined(MBEDTLS_MD4_C)
1331 case PSA_ALG_MD4:
1332 mbedtls_md4_init( &operation->ctx.md4 );
1333 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
1334 break;
1335#endif
1336#if defined(MBEDTLS_MD5_C)
1337 case PSA_ALG_MD5:
1338 mbedtls_md5_init( &operation->ctx.md5 );
1339 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
1340 break;
1341#endif
1342#if defined(MBEDTLS_RIPEMD160_C)
1343 case PSA_ALG_RIPEMD160:
1344 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
1345 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
1346 break;
1347#endif
1348#if defined(MBEDTLS_SHA1_C)
1349 case PSA_ALG_SHA_1:
1350 mbedtls_sha1_init( &operation->ctx.sha1 );
1351 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
1352 break;
1353#endif
1354#if defined(MBEDTLS_SHA256_C)
1355 case PSA_ALG_SHA_224:
1356 mbedtls_sha256_init( &operation->ctx.sha256 );
1357 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
1358 break;
1359 case PSA_ALG_SHA_256:
1360 mbedtls_sha256_init( &operation->ctx.sha256 );
1361 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
1362 break;
1363#endif
1364#if defined(MBEDTLS_SHA512_C)
1365 case PSA_ALG_SHA_384:
1366 mbedtls_sha512_init( &operation->ctx.sha512 );
1367 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
1368 break;
1369 case PSA_ALG_SHA_512:
1370 mbedtls_sha512_init( &operation->ctx.sha512 );
1371 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1372 break;
1373#endif
1374 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001375 return( PSA_ALG_IS_HASH( alg ) ?
1376 PSA_ERROR_NOT_SUPPORTED :
1377 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001378 }
1379 if( ret == 0 )
1380 operation->alg = alg;
1381 else
1382 psa_hash_abort( operation );
1383 return( mbedtls_to_psa_error( ret ) );
1384}
1385
1386psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1387 const uint8_t *input,
1388 size_t input_length )
1389{
1390 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001391
1392 /* Don't require hash implementations to behave correctly on a
1393 * zero-length input, which may have an invalid pointer. */
1394 if( input_length == 0 )
1395 return( PSA_SUCCESS );
1396
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001397 switch( operation->alg )
1398 {
1399#if defined(MBEDTLS_MD2_C)
1400 case PSA_ALG_MD2:
1401 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1402 input, input_length );
1403 break;
1404#endif
1405#if defined(MBEDTLS_MD4_C)
1406 case PSA_ALG_MD4:
1407 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1408 input, input_length );
1409 break;
1410#endif
1411#if defined(MBEDTLS_MD5_C)
1412 case PSA_ALG_MD5:
1413 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1414 input, input_length );
1415 break;
1416#endif
1417#if defined(MBEDTLS_RIPEMD160_C)
1418 case PSA_ALG_RIPEMD160:
1419 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1420 input, input_length );
1421 break;
1422#endif
1423#if defined(MBEDTLS_SHA1_C)
1424 case PSA_ALG_SHA_1:
1425 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1426 input, input_length );
1427 break;
1428#endif
1429#if defined(MBEDTLS_SHA256_C)
1430 case PSA_ALG_SHA_224:
1431 case PSA_ALG_SHA_256:
1432 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1433 input, input_length );
1434 break;
1435#endif
1436#if defined(MBEDTLS_SHA512_C)
1437 case PSA_ALG_SHA_384:
1438 case PSA_ALG_SHA_512:
1439 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1440 input, input_length );
1441 break;
1442#endif
1443 default:
1444 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1445 break;
1446 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001447
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001448 if( ret != 0 )
1449 psa_hash_abort( operation );
1450 return( mbedtls_to_psa_error( ret ) );
1451}
1452
1453psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1454 uint8_t *hash,
1455 size_t hash_size,
1456 size_t *hash_length )
1457{
itayzafrir40835d42018-08-02 13:14:17 +03001458 psa_status_t status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001459 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001460 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001461
1462 /* Fill the output buffer with something that isn't a valid hash
1463 * (barring an attack on the hash and deliberately-crafted input),
1464 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001465 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001466 /* If hash_size is 0 then hash may be NULL and then the
1467 * call to memset would have undefined behavior. */
1468 if( hash_size != 0 )
1469 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001470
1471 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03001472 {
1473 status = PSA_ERROR_BUFFER_TOO_SMALL;
1474 goto exit;
1475 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001476
1477 switch( operation->alg )
1478 {
1479#if defined(MBEDTLS_MD2_C)
1480 case PSA_ALG_MD2:
1481 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1482 break;
1483#endif
1484#if defined(MBEDTLS_MD4_C)
1485 case PSA_ALG_MD4:
1486 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1487 break;
1488#endif
1489#if defined(MBEDTLS_MD5_C)
1490 case PSA_ALG_MD5:
1491 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1492 break;
1493#endif
1494#if defined(MBEDTLS_RIPEMD160_C)
1495 case PSA_ALG_RIPEMD160:
1496 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1497 break;
1498#endif
1499#if defined(MBEDTLS_SHA1_C)
1500 case PSA_ALG_SHA_1:
1501 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1502 break;
1503#endif
1504#if defined(MBEDTLS_SHA256_C)
1505 case PSA_ALG_SHA_224:
1506 case PSA_ALG_SHA_256:
1507 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1508 break;
1509#endif
1510#if defined(MBEDTLS_SHA512_C)
1511 case PSA_ALG_SHA_384:
1512 case PSA_ALG_SHA_512:
1513 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1514 break;
1515#endif
1516 default:
1517 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1518 break;
1519 }
itayzafrir40835d42018-08-02 13:14:17 +03001520 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001521
itayzafrir40835d42018-08-02 13:14:17 +03001522exit:
1523 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001524 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001525 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001526 return( psa_hash_abort( operation ) );
1527 }
1528 else
1529 {
1530 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03001531 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001532 }
1533}
1534
Gilles Peskine2d277862018-06-18 15:41:12 +02001535psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1536 const uint8_t *hash,
1537 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001538{
1539 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1540 size_t actual_hash_length;
1541 psa_status_t status = psa_hash_finish( operation,
1542 actual_hash, sizeof( actual_hash ),
1543 &actual_hash_length );
1544 if( status != PSA_SUCCESS )
1545 return( status );
1546 if( actual_hash_length != hash_length )
1547 return( PSA_ERROR_INVALID_SIGNATURE );
1548 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1549 return( PSA_ERROR_INVALID_SIGNATURE );
1550 return( PSA_SUCCESS );
1551}
1552
1553
1554
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001555/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001556/* MAC */
1557/****************************************************************/
1558
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001559static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001560 psa_algorithm_t alg,
1561 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001562 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001563 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001564{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001565 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001566 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001567
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001568 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001569 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001570
Gilles Peskine8c9def32018-02-08 10:02:12 +01001571 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1572 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001573 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001574 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001575 case PSA_ALG_ARC4:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001576 mode = MBEDTLS_MODE_STREAM;
1577 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001578 case PSA_ALG_CTR:
1579 mode = MBEDTLS_MODE_CTR;
1580 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001581 case PSA_ALG_CFB:
1582 mode = MBEDTLS_MODE_CFB;
1583 break;
1584 case PSA_ALG_OFB:
1585 mode = MBEDTLS_MODE_OFB;
1586 break;
1587 case PSA_ALG_CBC_NO_PADDING:
1588 mode = MBEDTLS_MODE_CBC;
1589 break;
1590 case PSA_ALG_CBC_PKCS7:
1591 mode = MBEDTLS_MODE_CBC;
1592 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001593 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001594 mode = MBEDTLS_MODE_CCM;
1595 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001596 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001597 mode = MBEDTLS_MODE_GCM;
1598 break;
1599 default:
1600 return( NULL );
1601 }
1602 }
1603 else if( alg == PSA_ALG_CMAC )
1604 mode = MBEDTLS_MODE_ECB;
1605 else if( alg == PSA_ALG_GMAC )
1606 mode = MBEDTLS_MODE_GCM;
1607 else
1608 return( NULL );
1609
1610 switch( key_type )
1611 {
1612 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001613 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001614 break;
1615 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001616 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1617 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001618 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001619 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001620 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001621 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001622 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1623 * but two-key Triple-DES is functionally three-key Triple-DES
1624 * with K1=K3, so that's how we present it to mbedtls. */
1625 if( key_bits == 128 )
1626 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001627 break;
1628 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001629 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001630 break;
1631 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001632 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001633 break;
1634 default:
1635 return( NULL );
1636 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001637 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001638 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001639
Jaeden Amero23bbb752018-06-26 14:16:54 +01001640 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1641 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001642}
1643
Gilles Peskinea05219c2018-11-16 16:02:56 +01001644#if defined(MBEDTLS_MD_C)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001645static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001646{
Gilles Peskine2d277862018-06-18 15:41:12 +02001647 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001648 {
1649 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001650 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001651 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001652 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001653 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001654 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001655 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001656 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001657 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001658 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001659 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001660 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001661 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001662 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001663 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001664 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001665 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001666 return( 128 );
1667 default:
1668 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001669 }
1670}
Gilles Peskinea05219c2018-11-16 16:02:56 +01001671#endif /* MBEDTLS_MD_C */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001672
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001673/* Initialize the MAC operation structure. Once this function has been
1674 * called, psa_mac_abort can run and will do the right thing. */
1675static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1676 psa_algorithm_t alg )
1677{
1678 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1679
1680 operation->alg = alg;
1681 operation->key_set = 0;
1682 operation->iv_set = 0;
1683 operation->iv_required = 0;
1684 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001685 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001686
1687#if defined(MBEDTLS_CMAC_C)
1688 if( alg == PSA_ALG_CMAC )
1689 {
1690 operation->iv_required = 0;
1691 mbedtls_cipher_init( &operation->ctx.cmac );
1692 status = PSA_SUCCESS;
1693 }
1694 else
1695#endif /* MBEDTLS_CMAC_C */
1696#if defined(MBEDTLS_MD_C)
1697 if( PSA_ALG_IS_HMAC( operation->alg ) )
1698 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02001699 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
1700 operation->ctx.hmac.hash_ctx.alg = 0;
1701 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001702 }
1703 else
1704#endif /* MBEDTLS_MD_C */
1705 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001706 if( ! PSA_ALG_IS_MAC( alg ) )
1707 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001708 }
1709
1710 if( status != PSA_SUCCESS )
1711 memset( operation, 0, sizeof( *operation ) );
1712 return( status );
1713}
1714
Gilles Peskine01126fa2018-07-12 17:04:55 +02001715#if defined(MBEDTLS_MD_C)
1716static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
1717{
1718 mbedtls_zeroize( hmac->opad, sizeof( hmac->opad ) );
1719 return( psa_hash_abort( &hmac->hash_ctx ) );
1720}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01001721
1722static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
1723{
1724 /* Instances of psa_hash_operation_s can be initialized by zeroization. */
1725 memset( hmac, 0, sizeof( *hmac ) );
1726}
Gilles Peskine01126fa2018-07-12 17:04:55 +02001727#endif /* MBEDTLS_MD_C */
1728
Gilles Peskine8c9def32018-02-08 10:02:12 +01001729psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1730{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001731 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001732 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001733 /* The object has (apparently) been initialized but it is not
1734 * in use. It's ok to call abort on such an object, and there's
1735 * nothing to do. */
1736 return( PSA_SUCCESS );
1737 }
1738 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001739#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001740 if( operation->alg == PSA_ALG_CMAC )
1741 {
1742 mbedtls_cipher_free( &operation->ctx.cmac );
1743 }
1744 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001745#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001746#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001747 if( PSA_ALG_IS_HMAC( operation->alg ) )
1748 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001749 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001750 }
1751 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001752#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001753 {
1754 /* Sanity check (shouldn't happen: operation->alg should
1755 * always have been initialized to a valid value). */
1756 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001757 }
Moran Peker41deec42018-04-04 15:43:05 +03001758
Gilles Peskine8c9def32018-02-08 10:02:12 +01001759 operation->alg = 0;
1760 operation->key_set = 0;
1761 operation->iv_set = 0;
1762 operation->iv_required = 0;
1763 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001764 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001765
Gilles Peskine8c9def32018-02-08 10:02:12 +01001766 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001767
1768bad_state:
1769 /* If abort is called on an uninitialized object, we can't trust
1770 * anything. Wipe the object in case it contains confidential data.
1771 * This may result in a memory leak if a pointer gets overwritten,
1772 * but it's too late to do anything about this. */
1773 memset( operation, 0, sizeof( *operation ) );
1774 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001775}
1776
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001777#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02001778static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001779 size_t key_bits,
1780 key_slot_t *slot,
1781 const mbedtls_cipher_info_t *cipher_info )
1782{
1783 int ret;
1784
1785 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001786
1787 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1788 if( ret != 0 )
1789 return( ret );
1790
1791 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1792 slot->data.raw.data,
1793 key_bits );
1794 return( ret );
1795}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001796#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001797
Gilles Peskine248051a2018-06-20 16:09:38 +02001798#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02001799static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
1800 const uint8_t *key,
1801 size_t key_length,
1802 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001803{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001804 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001805 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001806 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001807 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001808 psa_status_t status;
1809
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001810 /* Sanity checks on block_size, to guarantee that there won't be a buffer
1811 * overflow below. This should never trigger if the hash algorithm
1812 * is implemented correctly. */
1813 /* The size checks against the ipad and opad buffers cannot be written
1814 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
1815 * because that triggers -Wlogical-op on GCC 7.3. */
1816 if( block_size > sizeof( ipad ) )
1817 return( PSA_ERROR_NOT_SUPPORTED );
1818 if( block_size > sizeof( hmac->opad ) )
1819 return( PSA_ERROR_NOT_SUPPORTED );
1820 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001821 return( PSA_ERROR_NOT_SUPPORTED );
1822
Gilles Peskined223b522018-06-11 18:12:58 +02001823 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001824 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001825 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001826 if( status != PSA_SUCCESS )
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001827 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001828 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001829 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001830 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001831 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001832 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001833 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001834 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001835 }
Gilles Peskine96889972018-07-12 17:07:03 +02001836 /* A 0-length key is not commonly used in HMAC when used as a MAC,
1837 * but it is permitted. It is common when HMAC is used in HKDF, for
1838 * example. Don't call `memcpy` in the 0-length because `key` could be
1839 * an invalid pointer which would make the behavior undefined. */
1840 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001841 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001842
Gilles Peskined223b522018-06-11 18:12:58 +02001843 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1844 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001845 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001846 ipad[i] ^= 0x36;
1847 memset( ipad + key_length, 0x36, block_size - key_length );
1848
1849 /* Copy the key material from ipad to opad, flipping the requisite bits,
1850 * and filling the rest of opad with the requisite constant. */
1851 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001852 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1853 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001854
Gilles Peskine01126fa2018-07-12 17:04:55 +02001855 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001856 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001857 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001858
Gilles Peskine01126fa2018-07-12 17:04:55 +02001859 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001860
1861cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001862 mbedtls_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001863
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001864 return( status );
1865}
Gilles Peskine248051a2018-06-20 16:09:38 +02001866#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001867
Gilles Peskine89167cb2018-07-08 20:12:23 +02001868static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001869 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001870 psa_algorithm_t alg,
1871 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001872{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001873 psa_status_t status;
1874 key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001875 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001876 psa_key_usage_t usage =
1877 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskined911eb72018-08-14 15:18:45 +02001878 unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02001879 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001880
Gilles Peskined911eb72018-08-14 15:18:45 +02001881 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001882 if( status != PSA_SUCCESS )
1883 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001884 if( is_sign )
1885 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001886
Gilles Peskinec5487a82018-12-03 18:08:14 +01001887 status = psa_get_key_from_slot( handle, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001888 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001889 goto exit;
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02001890 key_bits = psa_get_key_bits( slot );
1891
Gilles Peskine8c9def32018-02-08 10:02:12 +01001892#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001893 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001894 {
1895 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02001896 mbedtls_cipher_info_from_psa( full_length_alg,
1897 slot->type, key_bits, NULL );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001898 int ret;
1899 if( cipher_info == NULL )
1900 {
1901 status = PSA_ERROR_NOT_SUPPORTED;
1902 goto exit;
1903 }
1904 operation->mac_size = cipher_info->block_size;
1905 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
1906 status = mbedtls_to_psa_error( ret );
1907 }
1908 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001909#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001910#if defined(MBEDTLS_MD_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001911 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001912 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02001913 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001914 if( hash_alg == 0 )
1915 {
1916 status = PSA_ERROR_NOT_SUPPORTED;
1917 goto exit;
1918 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001919
1920 operation->mac_size = PSA_HASH_SIZE( hash_alg );
1921 /* Sanity check. This shouldn't fail on a valid configuration. */
1922 if( operation->mac_size == 0 ||
1923 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
1924 {
1925 status = PSA_ERROR_NOT_SUPPORTED;
1926 goto exit;
1927 }
1928
Gilles Peskine01126fa2018-07-12 17:04:55 +02001929 if( slot->type != PSA_KEY_TYPE_HMAC )
1930 {
1931 status = PSA_ERROR_INVALID_ARGUMENT;
1932 goto exit;
1933 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001934
Gilles Peskine01126fa2018-07-12 17:04:55 +02001935 status = psa_hmac_setup_internal( &operation->ctx.hmac,
1936 slot->data.raw.data,
1937 slot->data.raw.bytes,
1938 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001939 }
1940 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001941#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001942 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00001943 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02001944 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001945 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001946
Gilles Peskined911eb72018-08-14 15:18:45 +02001947 if( truncated == 0 )
1948 {
1949 /* The "normal" case: untruncated algorithm. Nothing to do. */
1950 }
1951 else if( truncated < 4 )
1952 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02001953 /* A very short MAC is too short for security since it can be
1954 * brute-forced. Ancient protocols with 32-bit MACs do exist,
1955 * so we make this our minimum, even though 32 bits is still
1956 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02001957 status = PSA_ERROR_NOT_SUPPORTED;
1958 }
1959 else if( truncated > operation->mac_size )
1960 {
1961 /* It's impossible to "truncate" to a larger length. */
1962 status = PSA_ERROR_INVALID_ARGUMENT;
1963 }
1964 else
1965 operation->mac_size = truncated;
1966
Gilles Peskinefbfac682018-07-08 20:51:54 +02001967exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001968 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001969 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001970 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001971 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001972 else
1973 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001974 operation->key_set = 1;
1975 }
1976 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001977}
1978
Gilles Peskine89167cb2018-07-08 20:12:23 +02001979psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001980 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001981 psa_algorithm_t alg )
1982{
Gilles Peskinec5487a82018-12-03 18:08:14 +01001983 return( psa_mac_setup( operation, handle, alg, 1 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001984}
1985
1986psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001987 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001988 psa_algorithm_t alg )
1989{
Gilles Peskinec5487a82018-12-03 18:08:14 +01001990 return( psa_mac_setup( operation, handle, alg, 0 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001991}
1992
Gilles Peskine8c9def32018-02-08 10:02:12 +01001993psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1994 const uint8_t *input,
1995 size_t input_length )
1996{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001997 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001998 if( ! operation->key_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001999 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002000 if( operation->iv_required && ! operation->iv_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002001 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002002 operation->has_input = 1;
2003
Gilles Peskine8c9def32018-02-08 10:02:12 +01002004#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002005 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03002006 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02002007 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
2008 input, input_length );
2009 status = mbedtls_to_psa_error( ret );
2010 }
2011 else
2012#endif /* MBEDTLS_CMAC_C */
2013#if defined(MBEDTLS_MD_C)
2014 if( PSA_ALG_IS_HMAC( operation->alg ) )
2015 {
2016 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
2017 input_length );
2018 }
2019 else
2020#endif /* MBEDTLS_MD_C */
2021 {
2022 /* This shouldn't happen if `operation` was initialized by
2023 * a setup function. */
2024 status = PSA_ERROR_BAD_STATE;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03002025 }
2026
Gilles Peskinefbfac682018-07-08 20:51:54 +02002027cleanup:
2028 if( status != PSA_SUCCESS )
2029 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002030 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002031}
2032
Gilles Peskine01126fa2018-07-12 17:04:55 +02002033#if defined(MBEDTLS_MD_C)
2034static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
2035 uint8_t *mac,
2036 size_t mac_size )
2037{
2038 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
2039 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
2040 size_t hash_size = 0;
2041 size_t block_size = psa_get_hash_block_size( hash_alg );
2042 psa_status_t status;
2043
Gilles Peskine01126fa2018-07-12 17:04:55 +02002044 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
2045 if( status != PSA_SUCCESS )
2046 return( status );
2047 /* From here on, tmp needs to be wiped. */
2048
2049 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
2050 if( status != PSA_SUCCESS )
2051 goto exit;
2052
2053 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
2054 if( status != PSA_SUCCESS )
2055 goto exit;
2056
2057 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
2058 if( status != PSA_SUCCESS )
2059 goto exit;
2060
Gilles Peskined911eb72018-08-14 15:18:45 +02002061 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
2062 if( status != PSA_SUCCESS )
2063 goto exit;
2064
2065 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002066
2067exit:
2068 mbedtls_zeroize( tmp, hash_size );
2069 return( status );
2070}
2071#endif /* MBEDTLS_MD_C */
2072
mohammad16036df908f2018-04-02 08:34:15 -07002073static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02002074 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002075 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002076{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02002077 if( ! operation->key_set )
2078 return( PSA_ERROR_BAD_STATE );
2079 if( operation->iv_required && ! operation->iv_set )
2080 return( PSA_ERROR_BAD_STATE );
2081
Gilles Peskine8c9def32018-02-08 10:02:12 +01002082 if( mac_size < operation->mac_size )
2083 return( PSA_ERROR_BUFFER_TOO_SMALL );
2084
Gilles Peskine8c9def32018-02-08 10:02:12 +01002085#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002086 if( operation->alg == PSA_ALG_CMAC )
2087 {
Gilles Peskined911eb72018-08-14 15:18:45 +02002088 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
2089 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
2090 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02002091 memcpy( mac, tmp, operation->mac_size );
Gilles Peskined911eb72018-08-14 15:18:45 +02002092 mbedtls_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002093 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002094 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02002095 else
2096#endif /* MBEDTLS_CMAC_C */
2097#if defined(MBEDTLS_MD_C)
2098 if( PSA_ALG_IS_HMAC( operation->alg ) )
2099 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002100 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02002101 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002102 }
2103 else
2104#endif /* MBEDTLS_MD_C */
2105 {
2106 /* This shouldn't happen if `operation` was initialized by
2107 * a setup function. */
2108 return( PSA_ERROR_BAD_STATE );
2109 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01002110}
2111
Gilles Peskineacd4be32018-07-08 19:56:25 +02002112psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
2113 uint8_t *mac,
2114 size_t mac_size,
2115 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07002116{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002117 psa_status_t status;
2118
2119 /* Fill the output buffer with something that isn't a valid mac
2120 * (barring an attack on the mac and deliberately-crafted input),
2121 * in case the caller doesn't check the return status properly. */
2122 *mac_length = mac_size;
2123 /* If mac_size is 0 then mac may be NULL and then the
2124 * call to memset would have undefined behavior. */
2125 if( mac_size != 0 )
2126 memset( mac, '!', mac_size );
2127
Gilles Peskine89167cb2018-07-08 20:12:23 +02002128 if( ! operation->is_sign )
2129 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002130 status = PSA_ERROR_BAD_STATE;
2131 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002132 }
mohammad16036df908f2018-04-02 08:34:15 -07002133
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002134 status = psa_mac_finish_internal( operation, mac, mac_size );
2135
2136cleanup:
2137 if( status == PSA_SUCCESS )
2138 {
2139 status = psa_mac_abort( operation );
2140 if( status == PSA_SUCCESS )
2141 *mac_length = operation->mac_size;
2142 else
2143 memset( mac, '!', mac_size );
2144 }
2145 else
2146 psa_mac_abort( operation );
2147 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07002148}
2149
Gilles Peskineacd4be32018-07-08 19:56:25 +02002150psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
2151 const uint8_t *mac,
2152 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002153{
Gilles Peskine828ed142018-06-18 23:25:51 +02002154 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07002155 psa_status_t status;
2156
Gilles Peskine89167cb2018-07-08 20:12:23 +02002157 if( operation->is_sign )
2158 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002159 status = PSA_ERROR_BAD_STATE;
2160 goto cleanup;
2161 }
2162 if( operation->mac_size != mac_length )
2163 {
2164 status = PSA_ERROR_INVALID_SIGNATURE;
2165 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002166 }
mohammad16036df908f2018-04-02 08:34:15 -07002167
2168 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002169 actual_mac, sizeof( actual_mac ) );
2170
2171 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
2172 status = PSA_ERROR_INVALID_SIGNATURE;
2173
2174cleanup:
2175 if( status == PSA_SUCCESS )
2176 status = psa_mac_abort( operation );
2177 else
2178 psa_mac_abort( operation );
2179
Gilles Peskine99b7d6b2018-08-21 14:56:19 +02002180 mbedtls_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02002181
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002182 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002183}
2184
2185
Gilles Peskine20035e32018-02-03 22:44:14 +01002186
Gilles Peskine20035e32018-02-03 22:44:14 +01002187/****************************************************************/
2188/* Asymmetric cryptography */
2189/****************************************************************/
2190
Gilles Peskine2b450e32018-06-27 15:42:46 +02002191#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002192/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002193 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002194static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
2195 size_t hash_length,
2196 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002197{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02002198 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002199 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002200 *md_alg = mbedtls_md_get_type( md_info );
2201
2202 /* The Mbed TLS RSA module uses an unsigned int for hash length
2203 * parameters. Validate that it fits so that we don't risk an
2204 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002205#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002206 if( hash_length > UINT_MAX )
2207 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002208#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002209
2210#if defined(MBEDTLS_PKCS1_V15)
2211 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
2212 * must be correct. */
2213 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
2214 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002215 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002216 if( md_info == NULL )
2217 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002218 if( mbedtls_md_get_size( md_info ) != hash_length )
2219 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002220 }
2221#endif /* MBEDTLS_PKCS1_V15 */
2222
2223#if defined(MBEDTLS_PKCS1_V21)
2224 /* PSS requires a hash internally. */
2225 if( PSA_ALG_IS_RSA_PSS( alg ) )
2226 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002227 if( md_info == NULL )
2228 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002229 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002230#endif /* MBEDTLS_PKCS1_V21 */
2231
Gilles Peskine61b91d42018-06-08 16:09:36 +02002232 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002233}
2234
Gilles Peskine2b450e32018-06-27 15:42:46 +02002235static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
2236 psa_algorithm_t alg,
2237 const uint8_t *hash,
2238 size_t hash_length,
2239 uint8_t *signature,
2240 size_t signature_size,
2241 size_t *signature_length )
2242{
2243 psa_status_t status;
2244 int ret;
2245 mbedtls_md_type_t md_alg;
2246
2247 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2248 if( status != PSA_SUCCESS )
2249 return( status );
2250
Gilles Peskine630a18a2018-06-29 17:49:35 +02002251 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002252 return( PSA_ERROR_BUFFER_TOO_SMALL );
2253
2254#if defined(MBEDTLS_PKCS1_V15)
2255 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2256 {
2257 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2258 MBEDTLS_MD_NONE );
2259 ret = mbedtls_rsa_pkcs1_sign( rsa,
2260 mbedtls_ctr_drbg_random,
2261 &global_data.ctr_drbg,
2262 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002263 md_alg,
2264 (unsigned int) hash_length,
2265 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002266 signature );
2267 }
2268 else
2269#endif /* MBEDTLS_PKCS1_V15 */
2270#if defined(MBEDTLS_PKCS1_V21)
2271 if( PSA_ALG_IS_RSA_PSS( alg ) )
2272 {
2273 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2274 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
2275 mbedtls_ctr_drbg_random,
2276 &global_data.ctr_drbg,
2277 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002278 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002279 (unsigned int) hash_length,
2280 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002281 signature );
2282 }
2283 else
2284#endif /* MBEDTLS_PKCS1_V21 */
2285 {
2286 return( PSA_ERROR_INVALID_ARGUMENT );
2287 }
2288
2289 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002290 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002291 return( mbedtls_to_psa_error( ret ) );
2292}
2293
2294static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
2295 psa_algorithm_t alg,
2296 const uint8_t *hash,
2297 size_t hash_length,
2298 const uint8_t *signature,
2299 size_t signature_length )
2300{
2301 psa_status_t status;
2302 int ret;
2303 mbedtls_md_type_t md_alg;
2304
2305 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2306 if( status != PSA_SUCCESS )
2307 return( status );
2308
Gilles Peskine630a18a2018-06-29 17:49:35 +02002309 if( signature_length < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002310 return( PSA_ERROR_BUFFER_TOO_SMALL );
2311
2312#if defined(MBEDTLS_PKCS1_V15)
2313 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2314 {
2315 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2316 MBEDTLS_MD_NONE );
2317 ret = mbedtls_rsa_pkcs1_verify( rsa,
2318 mbedtls_ctr_drbg_random,
2319 &global_data.ctr_drbg,
2320 MBEDTLS_RSA_PUBLIC,
2321 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002322 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002323 hash,
2324 signature );
2325 }
2326 else
2327#endif /* MBEDTLS_PKCS1_V15 */
2328#if defined(MBEDTLS_PKCS1_V21)
2329 if( PSA_ALG_IS_RSA_PSS( alg ) )
2330 {
2331 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2332 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
2333 mbedtls_ctr_drbg_random,
2334 &global_data.ctr_drbg,
2335 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002336 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002337 (unsigned int) hash_length,
2338 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002339 signature );
2340 }
2341 else
2342#endif /* MBEDTLS_PKCS1_V21 */
2343 {
2344 return( PSA_ERROR_INVALID_ARGUMENT );
2345 }
Gilles Peskineef12c632018-09-13 20:37:48 +02002346
2347 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
2348 * the rest of the signature is invalid". This has little use in
2349 * practice and PSA doesn't report this distinction. */
2350 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
2351 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002352 return( mbedtls_to_psa_error( ret ) );
2353}
2354#endif /* MBEDTLS_RSA_C */
2355
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002356#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002357/* `ecp` cannot be const because `ecp->grp` needs to be non-const
2358 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
2359 * (even though these functions don't modify it). */
2360static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
2361 psa_algorithm_t alg,
2362 const uint8_t *hash,
2363 size_t hash_length,
2364 uint8_t *signature,
2365 size_t signature_size,
2366 size_t *signature_length )
2367{
2368 int ret;
2369 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002370 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002371 mbedtls_mpi_init( &r );
2372 mbedtls_mpi_init( &s );
2373
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002374 if( signature_size < 2 * curve_bytes )
2375 {
2376 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
2377 goto cleanup;
2378 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002379
Gilles Peskinea05219c2018-11-16 16:02:56 +01002380#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002381 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
2382 {
2383 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
2384 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2385 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2386 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
2387 hash, hash_length,
2388 md_alg ) );
2389 }
2390 else
Gilles Peskinea05219c2018-11-16 16:02:56 +01002391#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002392 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01002393 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002394 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
2395 hash, hash_length,
2396 mbedtls_ctr_drbg_random,
2397 &global_data.ctr_drbg ) );
2398 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002399
2400 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
2401 signature,
2402 curve_bytes ) );
2403 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
2404 signature + curve_bytes,
2405 curve_bytes ) );
2406
2407cleanup:
2408 mbedtls_mpi_free( &r );
2409 mbedtls_mpi_free( &s );
2410 if( ret == 0 )
2411 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002412 return( mbedtls_to_psa_error( ret ) );
2413}
2414
2415static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
2416 const uint8_t *hash,
2417 size_t hash_length,
2418 const uint8_t *signature,
2419 size_t signature_length )
2420{
2421 int ret;
2422 mbedtls_mpi r, s;
2423 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
2424 mbedtls_mpi_init( &r );
2425 mbedtls_mpi_init( &s );
2426
2427 if( signature_length != 2 * curve_bytes )
2428 return( PSA_ERROR_INVALID_SIGNATURE );
2429
2430 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2431 signature,
2432 curve_bytes ) );
2433 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2434 signature + curve_bytes,
2435 curve_bytes ) );
2436
2437 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2438 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002439
2440cleanup:
2441 mbedtls_mpi_free( &r );
2442 mbedtls_mpi_free( &s );
2443 return( mbedtls_to_psa_error( ret ) );
2444}
2445#endif /* MBEDTLS_ECDSA_C */
2446
Gilles Peskinec5487a82018-12-03 18:08:14 +01002447psa_status_t psa_asymmetric_sign( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002448 psa_algorithm_t alg,
2449 const uint8_t *hash,
2450 size_t hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002451 uint8_t *signature,
2452 size_t signature_size,
2453 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002454{
2455 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002456 psa_status_t status;
2457
2458 *signature_length = signature_size;
2459
Gilles Peskinec5487a82018-12-03 18:08:14 +01002460 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002461 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002462 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002463 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002464 {
2465 status = PSA_ERROR_INVALID_ARGUMENT;
2466 goto exit;
2467 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002468
Gilles Peskine20035e32018-02-03 22:44:14 +01002469#if defined(MBEDTLS_RSA_C)
2470 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2471 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002472 status = psa_rsa_sign( slot->data.rsa,
2473 alg,
2474 hash, hash_length,
2475 signature, signature_size,
2476 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002477 }
2478 else
2479#endif /* defined(MBEDTLS_RSA_C) */
2480#if defined(MBEDTLS_ECP_C)
2481 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2482 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002483#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea05219c2018-11-16 16:02:56 +01002484 if(
2485#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
2486 PSA_ALG_IS_ECDSA( alg )
2487#else
2488 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
2489#endif
2490 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002491 status = psa_ecdsa_sign( slot->data.ecp,
2492 alg,
2493 hash, hash_length,
2494 signature, signature_size,
2495 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002496 else
2497#endif /* defined(MBEDTLS_ECDSA_C) */
2498 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002499 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002500 }
itayzafrir5c753392018-05-08 11:18:38 +03002501 }
2502 else
2503#endif /* defined(MBEDTLS_ECP_C) */
2504 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002505 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002506 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002507
2508exit:
2509 /* Fill the unused part of the output buffer (the whole buffer on error,
2510 * the trailing part on success) with something that isn't a valid mac
2511 * (barring an attack on the mac and deliberately-crafted input),
2512 * in case the caller doesn't check the return status properly. */
2513 if( status == PSA_SUCCESS )
2514 memset( signature + *signature_length, '!',
2515 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002516 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002517 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002518 /* If signature_size is 0 then we have nothing to do. We must not call
2519 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002520 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002521}
2522
Gilles Peskinec5487a82018-12-03 18:08:14 +01002523psa_status_t psa_asymmetric_verify( psa_key_handle_t handle,
itayzafrir5c753392018-05-08 11:18:38 +03002524 psa_algorithm_t alg,
2525 const uint8_t *hash,
2526 size_t hash_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002527 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002528 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002529{
2530 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002531 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002532
Gilles Peskinec5487a82018-12-03 18:08:14 +01002533 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002534 if( status != PSA_SUCCESS )
2535 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002536
Gilles Peskine61b91d42018-06-08 16:09:36 +02002537#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002538 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002539 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002540 return( psa_rsa_verify( slot->data.rsa,
2541 alg,
2542 hash, hash_length,
2543 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002544 }
2545 else
2546#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002547#if defined(MBEDTLS_ECP_C)
2548 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2549 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002550#if defined(MBEDTLS_ECDSA_C)
2551 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002552 return( psa_ecdsa_verify( slot->data.ecp,
2553 hash, hash_length,
2554 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002555 else
2556#endif /* defined(MBEDTLS_ECDSA_C) */
2557 {
2558 return( PSA_ERROR_INVALID_ARGUMENT );
2559 }
itayzafrir5c753392018-05-08 11:18:38 +03002560 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002561 else
2562#endif /* defined(MBEDTLS_ECP_C) */
2563 {
2564 return( PSA_ERROR_NOT_SUPPORTED );
2565 }
2566}
2567
Gilles Peskine072ac562018-06-30 00:21:29 +02002568#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
2569static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
2570 mbedtls_rsa_context *rsa )
2571{
2572 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
2573 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2574 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2575 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2576}
2577#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
2578
Gilles Peskinec5487a82018-12-03 18:08:14 +01002579psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002580 psa_algorithm_t alg,
2581 const uint8_t *input,
2582 size_t input_length,
2583 const uint8_t *salt,
2584 size_t salt_length,
2585 uint8_t *output,
2586 size_t output_size,
2587 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002588{
2589 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002590 psa_status_t status;
2591
Darryl Green5cc689a2018-07-24 15:34:10 +01002592 (void) input;
2593 (void) input_length;
2594 (void) salt;
2595 (void) output;
2596 (void) output_size;
2597
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002598 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002599
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002600 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2601 return( PSA_ERROR_INVALID_ARGUMENT );
2602
Gilles Peskinec5487a82018-12-03 18:08:14 +01002603 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002604 if( status != PSA_SUCCESS )
2605 return( status );
Gilles Peskine35da9a22018-06-29 19:17:49 +02002606 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
2607 PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002608 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002609
2610#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002611 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002612 {
2613 mbedtls_rsa_context *rsa = slot->data.rsa;
2614 int ret;
Gilles Peskine630a18a2018-06-29 17:49:35 +02002615 if( output_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002616 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002617#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002618 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002619 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002620 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2621 mbedtls_ctr_drbg_random,
2622 &global_data.ctr_drbg,
2623 MBEDTLS_RSA_PUBLIC,
2624 input_length,
2625 input,
2626 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002627 }
2628 else
2629#endif /* MBEDTLS_PKCS1_V15 */
2630#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002631 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002632 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002633 psa_rsa_oaep_set_padding_mode( alg, rsa );
2634 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
2635 mbedtls_ctr_drbg_random,
2636 &global_data.ctr_drbg,
2637 MBEDTLS_RSA_PUBLIC,
2638 salt, salt_length,
2639 input_length,
2640 input,
2641 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002642 }
2643 else
2644#endif /* MBEDTLS_PKCS1_V21 */
2645 {
2646 return( PSA_ERROR_INVALID_ARGUMENT );
2647 }
2648 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002649 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002650 return( mbedtls_to_psa_error( ret ) );
2651 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002652 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002653#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002654 {
2655 return( PSA_ERROR_NOT_SUPPORTED );
2656 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002657}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002658
Gilles Peskinec5487a82018-12-03 18:08:14 +01002659psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002660 psa_algorithm_t alg,
2661 const uint8_t *input,
2662 size_t input_length,
2663 const uint8_t *salt,
2664 size_t salt_length,
2665 uint8_t *output,
2666 size_t output_size,
2667 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002668{
2669 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002670 psa_status_t status;
2671
Darryl Green5cc689a2018-07-24 15:34:10 +01002672 (void) input;
2673 (void) input_length;
2674 (void) salt;
2675 (void) output;
2676 (void) output_size;
2677
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002678 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002679
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002680 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2681 return( PSA_ERROR_INVALID_ARGUMENT );
2682
Gilles Peskinec5487a82018-12-03 18:08:14 +01002683 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002684 if( status != PSA_SUCCESS )
2685 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002686 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2687 return( PSA_ERROR_INVALID_ARGUMENT );
2688
2689#if defined(MBEDTLS_RSA_C)
2690 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2691 {
2692 mbedtls_rsa_context *rsa = slot->data.rsa;
2693 int ret;
2694
Gilles Peskine630a18a2018-06-29 17:49:35 +02002695 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002696 return( PSA_ERROR_INVALID_ARGUMENT );
2697
2698#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002699 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002700 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002701 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2702 mbedtls_ctr_drbg_random,
2703 &global_data.ctr_drbg,
2704 MBEDTLS_RSA_PRIVATE,
2705 output_length,
2706 input,
2707 output,
2708 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002709 }
2710 else
2711#endif /* MBEDTLS_PKCS1_V15 */
2712#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002713 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002714 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002715 psa_rsa_oaep_set_padding_mode( alg, rsa );
2716 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
2717 mbedtls_ctr_drbg_random,
2718 &global_data.ctr_drbg,
2719 MBEDTLS_RSA_PRIVATE,
2720 salt, salt_length,
2721 output_length,
2722 input,
2723 output,
2724 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002725 }
2726 else
2727#endif /* MBEDTLS_PKCS1_V21 */
2728 {
2729 return( PSA_ERROR_INVALID_ARGUMENT );
2730 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002731
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002732 return( mbedtls_to_psa_error( ret ) );
2733 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002734 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002735#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002736 {
2737 return( PSA_ERROR_NOT_SUPPORTED );
2738 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002739}
Gilles Peskine20035e32018-02-03 22:44:14 +01002740
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002741
2742
mohammad1603503973b2018-03-12 15:59:30 +02002743/****************************************************************/
2744/* Symmetric cryptography */
2745/****************************************************************/
2746
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002747/* Initialize the cipher operation structure. Once this function has been
2748 * called, psa_cipher_abort can run and will do the right thing. */
2749static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2750 psa_algorithm_t alg )
2751{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002752 if( ! PSA_ALG_IS_CIPHER( alg ) )
2753 {
2754 memset( operation, 0, sizeof( *operation ) );
2755 return( PSA_ERROR_INVALID_ARGUMENT );
2756 }
2757
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002758 operation->alg = alg;
2759 operation->key_set = 0;
2760 operation->iv_set = 0;
2761 operation->iv_required = 1;
2762 operation->iv_size = 0;
2763 operation->block_size = 0;
2764 mbedtls_cipher_init( &operation->ctx.cipher );
2765 return( PSA_SUCCESS );
2766}
2767
Gilles Peskinee553c652018-06-04 16:22:46 +02002768static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002769 psa_key_handle_t handle,
Gilles Peskine7e928852018-06-04 16:23:10 +02002770 psa_algorithm_t alg,
2771 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002772{
2773 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2774 psa_status_t status;
2775 key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02002776 size_t key_bits;
2777 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002778 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
2779 PSA_KEY_USAGE_ENCRYPT :
2780 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02002781
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002782 status = psa_cipher_init( operation, alg );
2783 if( status != PSA_SUCCESS )
2784 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002785
Gilles Peskinec5487a82018-12-03 18:08:14 +01002786 status = psa_get_key_from_slot( handle, &slot, usage, alg);
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002787 if( status != PSA_SUCCESS )
2788 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002789 key_bits = psa_get_key_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02002790
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002791 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002792 if( cipher_info == NULL )
2793 return( PSA_ERROR_NOT_SUPPORTED );
2794
mohammad1603503973b2018-03-12 15:59:30 +02002795 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002796 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002797 {
2798 psa_cipher_abort( operation );
2799 return( mbedtls_to_psa_error( ret ) );
2800 }
2801
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002802#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002803 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002804 {
2805 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2806 unsigned char keys[24];
2807 memcpy( keys, slot->data.raw.data, 16 );
2808 memcpy( keys + 16, slot->data.raw.data, 8 );
2809 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2810 keys,
2811 192, cipher_operation );
2812 }
2813 else
2814#endif
2815 {
2816 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2817 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002818 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002819 }
Moran Peker41deec42018-04-04 15:43:05 +03002820 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002821 {
2822 psa_cipher_abort( operation );
2823 return( mbedtls_to_psa_error( ret ) );
2824 }
2825
mohammad16038481e742018-03-18 13:57:31 +02002826#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002827 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02002828 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002829 case PSA_ALG_CBC_NO_PADDING:
2830 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2831 MBEDTLS_PADDING_NONE );
2832 break;
2833 case PSA_ALG_CBC_PKCS7:
2834 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2835 MBEDTLS_PADDING_PKCS7 );
2836 break;
2837 default:
2838 /* The algorithm doesn't involve padding. */
2839 ret = 0;
2840 break;
2841 }
2842 if( ret != 0 )
2843 {
2844 psa_cipher_abort( operation );
2845 return( mbedtls_to_psa_error( ret ) );
mohammad16038481e742018-03-18 13:57:31 +02002846 }
2847#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2848
mohammad1603503973b2018-03-12 15:59:30 +02002849 operation->key_set = 1;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002850 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
2851 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
2852 if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
mohammad16038481e742018-03-18 13:57:31 +02002853 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002854 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02002855 }
mohammad1603503973b2018-03-12 15:59:30 +02002856
Moran Peker395db872018-05-31 14:07:14 +03002857 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002858}
2859
Gilles Peskinefe119512018-07-08 21:39:34 +02002860psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002861 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02002862 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002863{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002864 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002865}
2866
Gilles Peskinefe119512018-07-08 21:39:34 +02002867psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002868 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02002869 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002870{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002871 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002872}
2873
Gilles Peskinefe119512018-07-08 21:39:34 +02002874psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
2875 unsigned char *iv,
2876 size_t iv_size,
2877 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002878{
itayzafrir534bd7c2018-08-02 13:56:32 +03002879 psa_status_t status;
2880 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002881 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002882 {
2883 status = PSA_ERROR_BAD_STATE;
2884 goto exit;
2885 }
Moran Peker41deec42018-04-04 15:43:05 +03002886 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002887 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002888 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03002889 goto exit;
2890 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002891 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2892 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002893 if( ret != 0 )
2894 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002895 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002896 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002897 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002898
mohammad16038481e742018-03-18 13:57:31 +02002899 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03002900 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002901
Moran Peker395db872018-05-31 14:07:14 +03002902exit:
itayzafrir534bd7c2018-08-02 13:56:32 +03002903 if( status != PSA_SUCCESS )
Moran Peker395db872018-05-31 14:07:14 +03002904 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002905 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002906}
2907
Gilles Peskinefe119512018-07-08 21:39:34 +02002908psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
2909 const unsigned char *iv,
2910 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002911{
itayzafrir534bd7c2018-08-02 13:56:32 +03002912 psa_status_t status;
2913 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002914 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002915 {
2916 status = PSA_ERROR_BAD_STATE;
2917 goto exit;
2918 }
Moran Pekera28258c2018-05-29 16:25:04 +03002919 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002920 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002921 status = PSA_ERROR_INVALID_ARGUMENT;
2922 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03002923 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002924 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
2925 status = mbedtls_to_psa_error( ret );
2926exit:
2927 if( status == PSA_SUCCESS )
2928 operation->iv_set = 1;
2929 else
mohammad1603503973b2018-03-12 15:59:30 +02002930 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002931 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002932}
2933
Gilles Peskinee553c652018-06-04 16:22:46 +02002934psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2935 const uint8_t *input,
2936 size_t input_length,
2937 unsigned char *output,
2938 size_t output_size,
2939 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002940{
itayzafrir534bd7c2018-08-02 13:56:32 +03002941 psa_status_t status;
2942 int ret;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002943 size_t expected_output_size;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002944 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002945 {
2946 /* Take the unprocessed partial block left over from previous
2947 * update calls, if any, plus the input to this call. Remove
2948 * the last partial block, if any. You get the data that will be
2949 * output in this call. */
2950 expected_output_size =
2951 ( operation->ctx.cipher.unprocessed_len + input_length )
2952 / operation->block_size * operation->block_size;
2953 }
2954 else
2955 {
2956 expected_output_size = input_length;
2957 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002958
Gilles Peskine89d789c2018-06-04 17:17:16 +02002959 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03002960 {
2961 status = PSA_ERROR_BUFFER_TOO_SMALL;
2962 goto exit;
2963 }
mohammad160382759612018-03-12 18:16:40 +02002964
mohammad1603503973b2018-03-12 15:59:30 +02002965 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002966 input_length, output, output_length );
itayzafrir534bd7c2018-08-02 13:56:32 +03002967 status = mbedtls_to_psa_error( ret );
2968exit:
2969 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02002970 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002971 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002972}
2973
Gilles Peskinee553c652018-06-04 16:22:46 +02002974psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2975 uint8_t *output,
2976 size_t output_size,
2977 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002978{
Janos Follath315b51c2018-07-09 16:04:51 +01002979 psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
2980 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002981 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002982
mohammad1603503973b2018-03-12 15:59:30 +02002983 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002984 {
Janos Follath315b51c2018-07-09 16:04:51 +01002985 status = PSA_ERROR_BAD_STATE;
2986 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002987 }
2988 if( operation->iv_required && ! operation->iv_set )
2989 {
Janos Follath315b51c2018-07-09 16:04:51 +01002990 status = PSA_ERROR_BAD_STATE;
2991 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002992 }
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002993
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002994 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002995 operation->alg == PSA_ALG_CBC_NO_PADDING &&
2996 operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03002997 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002998 status = PSA_ERROR_INVALID_ARGUMENT;
Janos Follath315b51c2018-07-09 16:04:51 +01002999 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03003000 }
3001
Janos Follath315b51c2018-07-09 16:04:51 +01003002 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
3003 temp_output_buffer,
3004 output_length );
3005 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02003006 {
Janos Follath315b51c2018-07-09 16:04:51 +01003007 status = mbedtls_to_psa_error( cipher_ret );
3008 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02003009 }
Janos Follath315b51c2018-07-09 16:04:51 +01003010
Gilles Peskine46f1fd72018-06-28 19:31:31 +02003011 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01003012 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02003013 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03003014 memcpy( output, temp_output_buffer, *output_length );
3015 else
3016 {
Janos Follath315b51c2018-07-09 16:04:51 +01003017 status = PSA_ERROR_BUFFER_TOO_SMALL;
3018 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03003019 }
mohammad1603503973b2018-03-12 15:59:30 +02003020
Janos Follath279ab8e2018-07-09 16:13:21 +01003021 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01003022 status = psa_cipher_abort( operation );
3023
3024 return( status );
3025
3026error:
3027
3028 *output_length = 0;
3029
Janos Follath279ab8e2018-07-09 16:13:21 +01003030 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01003031 (void) psa_cipher_abort( operation );
3032
3033 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003034}
3035
Gilles Peskinee553c652018-06-04 16:22:46 +02003036psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
3037{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003038 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02003039 {
3040 /* The object has (apparently) been initialized but it is not
3041 * in use. It's ok to call abort on such an object, and there's
3042 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003043 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02003044 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003045
Gilles Peskinef9c2c092018-06-21 16:57:07 +02003046 /* Sanity check (shouldn't happen: operation->alg should
3047 * always have been initialized to a valid value). */
3048 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
3049 return( PSA_ERROR_BAD_STATE );
3050
mohammad1603503973b2018-03-12 15:59:30 +02003051 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02003052
Moran Peker41deec42018-04-04 15:43:05 +03003053 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03003054 operation->key_set = 0;
3055 operation->iv_set = 0;
3056 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03003057 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03003058 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03003059
Moran Peker395db872018-05-31 14:07:14 +03003060 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02003061}
3062
Gilles Peskinea0655c32018-04-30 17:06:50 +02003063
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003064
mohammad16038cc1cee2018-03-28 01:21:33 +03003065/****************************************************************/
3066/* Key Policy */
3067/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003068
mohammad160327010052018-07-03 13:16:15 +03003069#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02003070void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003071{
Gilles Peskine803ce742018-06-18 16:07:14 +02003072 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03003073}
3074
Gilles Peskine2d277862018-06-18 15:41:12 +02003075void psa_key_policy_set_usage( psa_key_policy_t *policy,
3076 psa_key_usage_t usage,
3077 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03003078{
mohammad16034eed7572018-03-28 05:14:59 -07003079 policy->usage = usage;
3080 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03003081}
3082
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003083psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003084{
mohammad16036df908f2018-04-02 08:34:15 -07003085 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03003086}
3087
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003088psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003089{
mohammad16036df908f2018-04-02 08:34:15 -07003090 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03003091}
mohammad160327010052018-07-03 13:16:15 +03003092#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003093
Gilles Peskinec5487a82018-12-03 18:08:14 +01003094psa_status_t psa_set_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003095 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003096{
3097 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003098 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003099
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003100 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003101 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003102
Gilles Peskinec5487a82018-12-03 18:08:14 +01003103 status = psa_get_empty_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003104 if( status != PSA_SUCCESS )
3105 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03003106
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003107 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
3108 PSA_KEY_USAGE_ENCRYPT |
3109 PSA_KEY_USAGE_DECRYPT |
3110 PSA_KEY_USAGE_SIGN |
Gilles Peskineea0fb492018-07-12 17:17:20 +02003111 PSA_KEY_USAGE_VERIFY |
3112 PSA_KEY_USAGE_DERIVE ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07003113 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03003114
mohammad16036df908f2018-04-02 08:34:15 -07003115 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003116
3117 return( PSA_SUCCESS );
3118}
3119
Gilles Peskinec5487a82018-12-03 18:08:14 +01003120psa_status_t psa_get_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003121 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003122{
3123 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003124 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003125
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003126 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003127 return( PSA_ERROR_INVALID_ARGUMENT );
3128
Gilles Peskinec5487a82018-12-03 18:08:14 +01003129 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003130 if( status != PSA_SUCCESS )
3131 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003132
mohammad16036df908f2018-04-02 08:34:15 -07003133 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003134
3135 return( PSA_SUCCESS );
3136}
Gilles Peskine20035e32018-02-03 22:44:14 +01003137
Gilles Peskinea0655c32018-04-30 17:06:50 +02003138
3139
mohammad1603804cd712018-03-20 22:44:08 +02003140/****************************************************************/
3141/* Key Lifetime */
3142/****************************************************************/
3143
Gilles Peskinec5487a82018-12-03 18:08:14 +01003144psa_status_t psa_get_key_lifetime( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003145 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003146{
3147 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003148 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003149
Gilles Peskinec5487a82018-12-03 18:08:14 +01003150 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003151 if( status != PSA_SUCCESS )
3152 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003153
mohammad1603804cd712018-03-20 22:44:08 +02003154 *lifetime = slot->lifetime;
3155
3156 return( PSA_SUCCESS );
3157}
3158
Gilles Peskine20035e32018-02-03 22:44:14 +01003159
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003160
mohammad16035955c982018-04-26 00:53:03 +03003161/****************************************************************/
3162/* AEAD */
3163/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003164
Gilles Peskineedf9a652018-08-17 18:11:56 +02003165typedef struct
3166{
3167 key_slot_t *slot;
3168 const mbedtls_cipher_info_t *cipher_info;
3169 union
3170 {
3171#if defined(MBEDTLS_CCM_C)
3172 mbedtls_ccm_context ccm;
3173#endif /* MBEDTLS_CCM_C */
3174#if defined(MBEDTLS_GCM_C)
3175 mbedtls_gcm_context gcm;
3176#endif /* MBEDTLS_GCM_C */
3177 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003178 psa_algorithm_t core_alg;
3179 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003180 uint8_t tag_length;
3181} aead_operation_t;
3182
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003183static void psa_aead_abort( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003184{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003185 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003186 {
3187#if defined(MBEDTLS_CCM_C)
3188 case PSA_ALG_CCM:
3189 mbedtls_ccm_free( &operation->ctx.ccm );
3190 break;
3191#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003192#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02003193 case PSA_ALG_GCM:
3194 mbedtls_gcm_free( &operation->ctx.gcm );
3195 break;
3196#endif /* MBEDTLS_GCM_C */
3197 }
3198}
3199
3200static psa_status_t psa_aead_setup( aead_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003201 psa_key_handle_t handle,
Gilles Peskineedf9a652018-08-17 18:11:56 +02003202 psa_key_usage_t usage,
3203 psa_algorithm_t alg )
3204{
3205 psa_status_t status;
3206 size_t key_bits;
3207 mbedtls_cipher_id_t cipher_id;
3208
Gilles Peskinec5487a82018-12-03 18:08:14 +01003209 status = psa_get_key_from_slot( handle, &operation->slot, usage, alg );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003210 if( status != PSA_SUCCESS )
3211 return( status );
3212
3213 key_bits = psa_get_key_bits( operation->slot );
3214
3215 operation->cipher_info =
3216 mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
3217 &cipher_id );
3218 if( operation->cipher_info == NULL )
3219 return( PSA_ERROR_NOT_SUPPORTED );
3220
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003221 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003222 {
3223#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003224 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
3225 operation->core_alg = PSA_ALG_CCM;
3226 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003227 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3228 return( PSA_ERROR_INVALID_ARGUMENT );
3229 mbedtls_ccm_init( &operation->ctx.ccm );
3230 status = mbedtls_to_psa_error(
3231 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
3232 operation->slot->data.raw.data,
3233 (unsigned int) key_bits ) );
3234 if( status != 0 )
3235 goto cleanup;
3236 break;
3237#endif /* MBEDTLS_CCM_C */
3238
3239#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003240 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
3241 operation->core_alg = PSA_ALG_GCM;
3242 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003243 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3244 return( PSA_ERROR_INVALID_ARGUMENT );
3245 mbedtls_gcm_init( &operation->ctx.gcm );
3246 status = mbedtls_to_psa_error(
3247 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
3248 operation->slot->data.raw.data,
3249 (unsigned int) key_bits ) );
3250 break;
3251#endif /* MBEDTLS_GCM_C */
3252
3253 default:
3254 return( PSA_ERROR_NOT_SUPPORTED );
3255 }
3256
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003257 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
3258 {
3259 status = PSA_ERROR_INVALID_ARGUMENT;
3260 goto cleanup;
3261 }
3262 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
3263 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
3264 * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
3265 * In both cases, mbedtls_xxx will validate the tag length below. */
3266
Gilles Peskineedf9a652018-08-17 18:11:56 +02003267 return( PSA_SUCCESS );
3268
3269cleanup:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003270 psa_aead_abort( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003271 return( status );
3272}
3273
Gilles Peskinec5487a82018-12-03 18:08:14 +01003274psa_status_t psa_aead_encrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003275 psa_algorithm_t alg,
3276 const uint8_t *nonce,
3277 size_t nonce_length,
3278 const uint8_t *additional_data,
3279 size_t additional_data_length,
3280 const uint8_t *plaintext,
3281 size_t plaintext_length,
3282 uint8_t *ciphertext,
3283 size_t ciphertext_size,
3284 size_t *ciphertext_length )
3285{
mohammad16035955c982018-04-26 00:53:03 +03003286 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003287 aead_operation_t operation;
mohammad160315223a82018-06-03 17:19:55 +03003288 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02003289
mohammad1603f08a5502018-06-03 15:05:47 +03003290 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07003291
Gilles Peskinec5487a82018-12-03 18:08:14 +01003292 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003293 if( status != PSA_SUCCESS )
3294 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003295
Gilles Peskineedf9a652018-08-17 18:11:56 +02003296 /* For all currently supported modes, the tag is at the end of the
3297 * ciphertext. */
3298 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
3299 {
3300 status = PSA_ERROR_BUFFER_TOO_SMALL;
3301 goto exit;
3302 }
3303 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03003304
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003305#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003306 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003307 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003308 status = mbedtls_to_psa_error(
3309 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
3310 MBEDTLS_GCM_ENCRYPT,
3311 plaintext_length,
3312 nonce, nonce_length,
3313 additional_data, additional_data_length,
3314 plaintext, ciphertext,
3315 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03003316 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003317 else
3318#endif /* MBEDTLS_GCM_C */
3319#if defined(MBEDTLS_CCM_C)
3320 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003321 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003322 status = mbedtls_to_psa_error(
3323 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
3324 plaintext_length,
3325 nonce, nonce_length,
3326 additional_data,
3327 additional_data_length,
3328 plaintext, ciphertext,
3329 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003330 }
mohammad16035c8845f2018-05-09 05:40:09 -07003331 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003332#endif /* MBEDTLS_CCM_C */
mohammad16035c8845f2018-05-09 05:40:09 -07003333 {
mohammad1603554faad2018-06-03 15:07:38 +03003334 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07003335 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003336
Gilles Peskineedf9a652018-08-17 18:11:56 +02003337 if( status != PSA_SUCCESS && ciphertext_size != 0 )
3338 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003339
Gilles Peskineedf9a652018-08-17 18:11:56 +02003340exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003341 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003342 if( status == PSA_SUCCESS )
3343 *ciphertext_length = plaintext_length + operation.tag_length;
3344 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003345}
3346
Gilles Peskineee652a32018-06-01 19:23:52 +02003347/* Locate the tag in a ciphertext buffer containing the encrypted data
3348 * followed by the tag. Return the length of the part preceding the tag in
3349 * *plaintext_length. This is the size of the plaintext in modes where
3350 * the encrypted data has the same size as the plaintext, such as
3351 * CCM and GCM. */
3352static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
3353 const uint8_t *ciphertext,
3354 size_t ciphertext_length,
3355 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02003356 const uint8_t **p_tag )
3357{
3358 size_t payload_length;
3359 if( tag_length > ciphertext_length )
3360 return( PSA_ERROR_INVALID_ARGUMENT );
3361 payload_length = ciphertext_length - tag_length;
3362 if( payload_length > plaintext_size )
3363 return( PSA_ERROR_BUFFER_TOO_SMALL );
3364 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02003365 return( PSA_SUCCESS );
3366}
3367
Gilles Peskinec5487a82018-12-03 18:08:14 +01003368psa_status_t psa_aead_decrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003369 psa_algorithm_t alg,
3370 const uint8_t *nonce,
3371 size_t nonce_length,
3372 const uint8_t *additional_data,
3373 size_t additional_data_length,
3374 const uint8_t *ciphertext,
3375 size_t ciphertext_length,
3376 uint8_t *plaintext,
3377 size_t plaintext_size,
3378 size_t *plaintext_length )
3379{
mohammad16035955c982018-04-26 00:53:03 +03003380 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003381 aead_operation_t operation;
3382 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02003383
Gilles Peskineee652a32018-06-01 19:23:52 +02003384 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03003385
Gilles Peskinec5487a82018-12-03 18:08:14 +01003386 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003387 if( status != PSA_SUCCESS )
3388 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003389
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003390#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003391 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003392 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003393 status = psa_aead_unpadded_locate_tag( operation.tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003394 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003395 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02003396 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003397 goto exit;
Gilles Peskineee652a32018-06-01 19:23:52 +02003398
Gilles Peskineedf9a652018-08-17 18:11:56 +02003399 status = mbedtls_to_psa_error(
3400 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
3401 ciphertext_length - operation.tag_length,
3402 nonce, nonce_length,
3403 additional_data,
3404 additional_data_length,
3405 tag, operation.tag_length,
3406 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03003407 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003408 else
3409#endif /* MBEDTLS_GCM_C */
3410#if defined(MBEDTLS_CCM_C)
3411 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003412 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003413 status = psa_aead_unpadded_locate_tag( operation.tag_length,
mohammad16039375f842018-06-03 14:28:24 +03003414 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003415 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03003416 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003417 goto exit;
mohammad16039375f842018-06-03 14:28:24 +03003418
Gilles Peskineedf9a652018-08-17 18:11:56 +02003419 status = mbedtls_to_psa_error(
3420 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
3421 ciphertext_length - operation.tag_length,
3422 nonce, nonce_length,
3423 additional_data,
3424 additional_data_length,
3425 ciphertext, plaintext,
3426 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003427 }
mohammad160339574652018-06-01 04:39:53 -07003428 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003429#endif /* MBEDTLS_CCM_C */
mohammad160339574652018-06-01 04:39:53 -07003430 {
mohammad1603554faad2018-06-03 15:07:38 +03003431 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07003432 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02003433
Gilles Peskineedf9a652018-08-17 18:11:56 +02003434 if( status != PSA_SUCCESS && plaintext_size != 0 )
3435 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03003436
Gilles Peskineedf9a652018-08-17 18:11:56 +02003437exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003438 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003439 if( status == PSA_SUCCESS )
3440 *plaintext_length = ciphertext_length - operation.tag_length;
3441 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003442}
3443
Gilles Peskinea0655c32018-04-30 17:06:50 +02003444
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003445
Gilles Peskine20035e32018-02-03 22:44:14 +01003446/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003447/* Generators */
3448/****************************************************************/
3449
3450psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
3451{
3452 psa_status_t status = PSA_SUCCESS;
3453 if( generator->alg == 0 )
3454 {
3455 /* The object has (apparently) been initialized but it is not
3456 * in use. It's ok to call abort on such an object, and there's
3457 * nothing to do. */
3458 }
3459 else
Gilles Peskine751d9652018-09-18 12:05:44 +02003460 if( generator->alg == PSA_ALG_SELECT_RAW )
3461 {
3462 if( generator->ctx.buffer.data != NULL )
3463 {
3464 mbedtls_zeroize( generator->ctx.buffer.data,
3465 generator->ctx.buffer.size );
3466 mbedtls_free( generator->ctx.buffer.data );
3467 }
3468 }
3469 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003470#if defined(MBEDTLS_MD_C)
3471 if( PSA_ALG_IS_HKDF( generator->alg ) )
3472 {
3473 mbedtls_free( generator->ctx.hkdf.info );
3474 status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
3475 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003476 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3477 /* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
3478 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003479 {
3480 if( generator->ctx.tls12_prf.key != NULL )
3481 {
3482 mbedtls_zeroize( generator->ctx.tls12_prf.key,
3483 generator->ctx.tls12_prf.key_len );
3484 mbedtls_free( generator->ctx.tls12_prf.key );
3485 }
Hanno Becker580fba12018-11-13 20:50:45 +00003486
3487 if( generator->ctx.tls12_prf.Ai_with_seed != NULL )
3488 {
3489 mbedtls_zeroize( generator->ctx.tls12_prf.Ai_with_seed,
3490 generator->ctx.tls12_prf.Ai_with_seed_len );
3491 mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed );
3492 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003493 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003494 else
3495#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003496 {
3497 status = PSA_ERROR_BAD_STATE;
3498 }
3499 memset( generator, 0, sizeof( *generator ) );
3500 return( status );
3501}
3502
3503
3504psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3505 size_t *capacity)
3506{
3507 *capacity = generator->capacity;
3508 return( PSA_SUCCESS );
3509}
3510
Gilles Peskinebef7f142018-07-12 17:22:21 +02003511#if defined(MBEDTLS_MD_C)
3512/* Read some bytes from an HKDF-based generator. This performs a chunk
3513 * of the expand phase of the HKDF algorithm. */
3514static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
3515 psa_algorithm_t hash_alg,
3516 uint8_t *output,
3517 size_t output_length )
3518{
3519 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3520 psa_status_t status;
3521
3522 while( output_length != 0 )
3523 {
3524 /* Copy what remains of the current block */
3525 uint8_t n = hash_length - hkdf->offset_in_block;
3526 if( n > output_length )
3527 n = (uint8_t) output_length;
3528 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
3529 output += n;
3530 output_length -= n;
3531 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02003532 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003533 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003534 /* We can't be wanting more output after block 0xff, otherwise
3535 * the capacity check in psa_generator_read() would have
3536 * prevented this call. It could happen only if the generator
3537 * object was corrupted or if this function is called directly
3538 * inside the library. */
3539 if( hkdf->block_number == 0xff )
3540 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003541
3542 /* We need a new block */
3543 ++hkdf->block_number;
3544 hkdf->offset_in_block = 0;
3545 status = psa_hmac_setup_internal( &hkdf->hmac,
3546 hkdf->prk, hash_length,
3547 hash_alg );
3548 if( status != PSA_SUCCESS )
3549 return( status );
3550 if( hkdf->block_number != 1 )
3551 {
3552 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3553 hkdf->output_block,
3554 hash_length );
3555 if( status != PSA_SUCCESS )
3556 return( status );
3557 }
3558 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3559 hkdf->info,
3560 hkdf->info_length );
3561 if( status != PSA_SUCCESS )
3562 return( status );
3563 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3564 &hkdf->block_number, 1 );
3565 if( status != PSA_SUCCESS )
3566 return( status );
3567 status = psa_hmac_finish_internal( &hkdf->hmac,
3568 hkdf->output_block,
3569 sizeof( hkdf->output_block ) );
3570 if( status != PSA_SUCCESS )
3571 return( status );
3572 }
3573
3574 return( PSA_SUCCESS );
3575}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003576
3577static psa_status_t psa_generator_tls12_prf_generate_next_block(
3578 psa_tls12_prf_generator_t *tls12_prf,
3579 psa_algorithm_t alg )
3580{
3581 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3582 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3583 psa_hmac_internal_data hmac;
3584 psa_status_t status, cleanup_status;
3585
Hanno Becker3b339e22018-11-13 20:56:14 +00003586 unsigned char *Ai;
3587 size_t Ai_len;
3588
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003589 /* We can't be wanting more output after block 0xff, otherwise
3590 * the capacity check in psa_generator_read() would have
3591 * prevented this call. It could happen only if the generator
3592 * object was corrupted or if this function is called directly
3593 * inside the library. */
3594 if( tls12_prf->block_number == 0xff )
3595 return( PSA_ERROR_BAD_STATE );
3596
3597 /* We need a new block */
3598 ++tls12_prf->block_number;
3599 tls12_prf->offset_in_block = 0;
3600
3601 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
3602 *
3603 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
3604 *
3605 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
3606 * HMAC_hash(secret, A(2) + seed) +
3607 * HMAC_hash(secret, A(3) + seed) + ...
3608 *
3609 * A(0) = seed
3610 * A(i) = HMAC_hash( secret, A(i-1) )
3611 *
3612 * The `psa_tls12_prf_generator` structures saves the block
3613 * `HMAC_hash(secret, A(i) + seed)` from which the output
3614 * is currently extracted as `output_block`, while
3615 * `A(i) + seed` is stored in `Ai_with_seed`.
3616 *
3617 * Generating a new block means recalculating `Ai_with_seed`
3618 * from the A(i)-part of it, and afterwards recalculating
3619 * `output_block`.
3620 *
3621 * A(0) is computed at setup time.
3622 *
3623 */
3624
3625 psa_hmac_init_internal( &hmac );
3626
3627 /* We must distinguish the calculation of A(1) from those
3628 * of A(2) and higher, because A(0)=seed has a different
3629 * length than the other A(i). */
3630 if( tls12_prf->block_number == 1 )
3631 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003632 Ai = tls12_prf->Ai_with_seed + hash_length;
3633 Ai_len = tls12_prf->Ai_with_seed_len - hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003634 }
3635 else
3636 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003637 Ai = tls12_prf->Ai_with_seed;
3638 Ai_len = hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003639 }
3640
Hanno Becker3b339e22018-11-13 20:56:14 +00003641 /* Compute A(i+1) = HMAC_hash(secret, A(i)) */
3642 status = psa_hmac_setup_internal( &hmac,
3643 tls12_prf->key,
3644 tls12_prf->key_len,
3645 hash_alg );
3646 if( status != PSA_SUCCESS )
3647 goto cleanup;
3648
3649 status = psa_hash_update( &hmac.hash_ctx,
3650 Ai, Ai_len );
3651 if( status != PSA_SUCCESS )
3652 goto cleanup;
3653
3654 status = psa_hmac_finish_internal( &hmac,
3655 tls12_prf->Ai_with_seed,
3656 hash_length );
3657 if( status != PSA_SUCCESS )
3658 goto cleanup;
3659
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003660 /* Compute the next block `HMAC_hash(secret, A(i+1) + seed)`. */
3661 status = psa_hmac_setup_internal( &hmac,
3662 tls12_prf->key,
3663 tls12_prf->key_len,
3664 hash_alg );
3665 if( status != PSA_SUCCESS )
3666 goto cleanup;
3667
3668 status = psa_hash_update( &hmac.hash_ctx,
3669 tls12_prf->Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003670 tls12_prf->Ai_with_seed_len );
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003671 if( status != PSA_SUCCESS )
3672 goto cleanup;
3673
3674 status = psa_hmac_finish_internal( &hmac,
3675 tls12_prf->output_block,
3676 hash_length );
3677 if( status != PSA_SUCCESS )
3678 goto cleanup;
3679
3680cleanup:
3681
3682 cleanup_status = psa_hmac_abort_internal( &hmac );
3683 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
3684 status = cleanup_status;
3685
3686 return( status );
3687}
3688
3689/* Read some bytes from an TLS-1.2-PRF-based generator.
3690 * See Section 5 of RFC 5246. */
3691static psa_status_t psa_generator_tls12_prf_read(
3692 psa_tls12_prf_generator_t *tls12_prf,
3693 psa_algorithm_t alg,
3694 uint8_t *output,
3695 size_t output_length )
3696{
3697 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3698 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3699 psa_status_t status;
3700
3701 while( output_length != 0 )
3702 {
3703 /* Copy what remains of the current block */
3704 uint8_t n = hash_length - tls12_prf->offset_in_block;
3705
3706 /* Check if we have fully processed the current block. */
3707 if( n == 0 )
3708 {
3709 status = psa_generator_tls12_prf_generate_next_block( tls12_prf,
3710 alg );
3711 if( status != PSA_SUCCESS )
3712 return( status );
3713
3714 continue;
3715 }
3716
3717 if( n > output_length )
3718 n = (uint8_t) output_length;
3719 memcpy( output, tls12_prf->output_block + tls12_prf->offset_in_block,
3720 n );
3721 output += n;
3722 output_length -= n;
3723 tls12_prf->offset_in_block += n;
3724 }
3725
3726 return( PSA_SUCCESS );
3727}
Gilles Peskinebef7f142018-07-12 17:22:21 +02003728#endif /* MBEDTLS_MD_C */
3729
Gilles Peskineeab56e42018-07-12 17:12:33 +02003730psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
3731 uint8_t *output,
3732 size_t output_length )
3733{
3734 psa_status_t status;
3735
3736 if( output_length > generator->capacity )
3737 {
3738 generator->capacity = 0;
3739 /* Go through the error path to wipe all confidential data now
3740 * that the generator object is useless. */
3741 status = PSA_ERROR_INSUFFICIENT_CAPACITY;
3742 goto exit;
3743 }
3744 if( output_length == 0 &&
3745 generator->capacity == 0 && generator->alg == 0 )
3746 {
3747 /* Edge case: this is a blank or finished generator, and 0
3748 * bytes were requested. The right error in this case could
3749 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3750 * INSUFFICIENT_CAPACITY, which is right for a finished
3751 * generator, for consistency with the case when
3752 * output_length > 0. */
3753 return( PSA_ERROR_INSUFFICIENT_CAPACITY );
3754 }
3755 generator->capacity -= output_length;
3756
Gilles Peskine751d9652018-09-18 12:05:44 +02003757 if( generator->alg == PSA_ALG_SELECT_RAW )
3758 {
Gilles Peskine211a4362018-10-25 22:22:31 +02003759 /* Initially, the capacity of a selection generator is always
3760 * the size of the buffer, i.e. `generator->ctx.buffer.size`,
3761 * abbreviated in this comment as `size`. When the remaining
3762 * capacity is `c`, the next bytes to serve start `c` bytes
3763 * from the end of the buffer, i.e. `size - c` from the
3764 * beginning of the buffer. Since `generator->capacity` was just
3765 * decremented above, we need to serve the bytes from
3766 * `size - generator->capacity - output_length` to
3767 * `size - generator->capacity`. */
Gilles Peskine751d9652018-09-18 12:05:44 +02003768 size_t offset =
3769 generator->ctx.buffer.size - generator->capacity - output_length;
3770 memcpy( output, generator->ctx.buffer.data + offset, output_length );
3771 status = PSA_SUCCESS;
3772 }
3773 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003774#if defined(MBEDTLS_MD_C)
3775 if( PSA_ALG_IS_HKDF( generator->alg ) )
3776 {
3777 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
3778 status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
3779 output, output_length );
3780 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003781 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3782 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003783 {
3784 status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
3785 generator->alg, output,
3786 output_length );
3787 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003788 else
3789#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003790 {
3791 return( PSA_ERROR_BAD_STATE );
3792 }
3793
3794exit:
3795 if( status != PSA_SUCCESS )
3796 {
3797 psa_generator_abort( generator );
3798 memset( output, '!', output_length );
3799 }
3800 return( status );
3801}
3802
Gilles Peskine08542d82018-07-19 17:05:42 +02003803#if defined(MBEDTLS_DES_C)
3804static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
3805{
3806 if( data_size >= 8 )
3807 mbedtls_des_key_set_parity( data );
3808 if( data_size >= 16 )
3809 mbedtls_des_key_set_parity( data + 8 );
3810 if( data_size >= 24 )
3811 mbedtls_des_key_set_parity( data + 16 );
3812}
3813#endif /* MBEDTLS_DES_C */
3814
Gilles Peskinec5487a82018-12-03 18:08:14 +01003815psa_status_t psa_generator_import_key( psa_key_handle_t handle,
Gilles Peskineeab56e42018-07-12 17:12:33 +02003816 psa_key_type_t type,
3817 size_t bits,
3818 psa_crypto_generator_t *generator )
3819{
3820 uint8_t *data = NULL;
3821 size_t bytes = PSA_BITS_TO_BYTES( bits );
3822 psa_status_t status;
3823
3824 if( ! key_type_is_raw_bytes( type ) )
3825 return( PSA_ERROR_INVALID_ARGUMENT );
3826 if( bits % 8 != 0 )
3827 return( PSA_ERROR_INVALID_ARGUMENT );
3828 data = mbedtls_calloc( 1, bytes );
3829 if( data == NULL )
3830 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3831
3832 status = psa_generator_read( generator, data, bytes );
3833 if( status != PSA_SUCCESS )
3834 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02003835#if defined(MBEDTLS_DES_C)
3836 if( type == PSA_KEY_TYPE_DES )
3837 psa_des_set_key_parity( data, bytes );
3838#endif /* MBEDTLS_DES_C */
Gilles Peskinec5487a82018-12-03 18:08:14 +01003839 status = psa_import_key( handle, type, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02003840
3841exit:
3842 mbedtls_free( data );
3843 return( status );
3844}
3845
3846
3847
3848/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003849/* Key derivation */
3850/****************************************************************/
3851
Gilles Peskinea05219c2018-11-16 16:02:56 +01003852#if defined(MBEDTLS_MD_C)
Gilles Peskinebef7f142018-07-12 17:22:21 +02003853/* Set up an HKDF-based generator. This is exactly the extract phase
Gilles Peskine346797d2018-11-16 16:05:06 +01003854 * of the HKDF algorithm.
3855 *
3856 * Note that if this function fails, you must call psa_generator_abort()
3857 * to potentially free embedded data structures and wipe confidential data.
3858 */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003859static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003860 const uint8_t *secret,
3861 size_t secret_length,
Gilles Peskinebef7f142018-07-12 17:22:21 +02003862 psa_algorithm_t hash_alg,
3863 const uint8_t *salt,
3864 size_t salt_length,
3865 const uint8_t *label,
3866 size_t label_length )
3867{
3868 psa_status_t status;
3869 status = psa_hmac_setup_internal( &hkdf->hmac,
3870 salt, salt_length,
Gilles Peskine00709fa2018-08-22 18:25:41 +02003871 PSA_ALG_HMAC_GET_HASH( hash_alg ) );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003872 if( status != PSA_SUCCESS )
3873 return( status );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003874 status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003875 if( status != PSA_SUCCESS )
3876 return( status );
3877 status = psa_hmac_finish_internal( &hkdf->hmac,
3878 hkdf->prk,
3879 sizeof( hkdf->prk ) );
3880 if( status != PSA_SUCCESS )
3881 return( status );
3882 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
3883 hkdf->block_number = 0;
3884 hkdf->info_length = label_length;
3885 if( label_length != 0 )
3886 {
3887 hkdf->info = mbedtls_calloc( 1, label_length );
3888 if( hkdf->info == NULL )
3889 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3890 memcpy( hkdf->info, label, label_length );
3891 }
3892 return( PSA_SUCCESS );
3893}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003894#endif /* MBEDTLS_MD_C */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003895
Gilles Peskinea05219c2018-11-16 16:02:56 +01003896#if defined(MBEDTLS_MD_C)
Gilles Peskine346797d2018-11-16 16:05:06 +01003897/* Set up a TLS-1.2-prf-based generator (see RFC 5246, Section 5).
3898 *
3899 * Note that if this function fails, you must call psa_generator_abort()
3900 * to potentially free embedded data structures and wipe confidential data.
3901 */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003902static psa_status_t psa_generator_tls12_prf_setup(
3903 psa_tls12_prf_generator_t *tls12_prf,
3904 const unsigned char *key,
3905 size_t key_len,
3906 psa_algorithm_t hash_alg,
3907 const uint8_t *salt,
3908 size_t salt_length,
3909 const uint8_t *label,
3910 size_t label_length )
3911{
3912 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Hanno Becker580fba12018-11-13 20:50:45 +00003913 size_t Ai_with_seed_len = hash_length + salt_length + label_length;
3914 int overflow;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003915
3916 tls12_prf->key = mbedtls_calloc( 1, key_len );
3917 if( tls12_prf->key == NULL )
3918 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3919 tls12_prf->key_len = key_len;
3920 memcpy( tls12_prf->key, key, key_len );
3921
Hanno Becker580fba12018-11-13 20:50:45 +00003922 overflow = ( salt_length + label_length < salt_length ) ||
3923 ( salt_length + label_length + hash_length < hash_length );
3924 if( overflow )
3925 return( PSA_ERROR_INVALID_ARGUMENT );
3926
3927 tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len );
3928 if( tls12_prf->Ai_with_seed == NULL )
3929 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3930 tls12_prf->Ai_with_seed_len = Ai_with_seed_len;
3931
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003932 /* Write `label + seed' at the end of the `A(i) + seed` buffer,
3933 * leaving the initial `hash_length` bytes unspecified for now. */
Hanno Becker353e4532018-11-15 09:53:57 +00003934 if( label_length != 0 )
3935 {
3936 memcpy( tls12_prf->Ai_with_seed + hash_length,
3937 label, label_length );
3938 }
3939
3940 if( salt_length != 0 )
3941 {
3942 memcpy( tls12_prf->Ai_with_seed + hash_length + label_length,
3943 salt, salt_length );
3944 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003945
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003946 /* The first block gets generated when
3947 * psa_generator_read() is called. */
3948 tls12_prf->block_number = 0;
3949 tls12_prf->offset_in_block = hash_length;
3950
3951 return( PSA_SUCCESS );
3952}
Hanno Becker1aaedc02018-11-16 11:35:34 +00003953
3954/* Set up a TLS-1.2-PSK-to-MS-based generator. */
3955static psa_status_t psa_generator_tls12_psk_to_ms_setup(
3956 psa_tls12_prf_generator_t *tls12_prf,
3957 const unsigned char *psk,
3958 size_t psk_len,
3959 psa_algorithm_t hash_alg,
3960 const uint8_t *salt,
3961 size_t salt_length,
3962 const uint8_t *label,
3963 size_t label_length )
3964{
3965 psa_status_t status;
3966 unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
3967
3968 if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
3969 return( PSA_ERROR_INVALID_ARGUMENT );
3970
3971 /* Quoting RFC 4279, Section 2:
3972 *
3973 * The premaster secret is formed as follows: if the PSK is N octets
3974 * long, concatenate a uint16 with the value N, N zero octets, a second
3975 * uint16 with the value N, and the PSK itself.
3976 */
3977
3978 pms[0] = ( psk_len >> 8 ) & 0xff;
3979 pms[1] = ( psk_len >> 0 ) & 0xff;
3980 memset( pms + 2, 0, psk_len );
3981 pms[2 + psk_len + 0] = pms[0];
3982 pms[2 + psk_len + 1] = pms[1];
3983 memcpy( pms + 4 + psk_len, psk, psk_len );
3984
3985 status = psa_generator_tls12_prf_setup( tls12_prf,
3986 pms, 4 + 2 * psk_len,
3987 hash_alg,
3988 salt, salt_length,
3989 label, label_length );
3990
3991 mbedtls_zeroize( pms, sizeof( pms ) );
3992 return( status );
3993}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003994#endif /* MBEDTLS_MD_C */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003995
Gilles Peskine346797d2018-11-16 16:05:06 +01003996/* Note that if this function fails, you must call psa_generator_abort()
3997 * to potentially free embedded data structures and wipe confidential data.
3998 */
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003999static psa_status_t psa_key_derivation_internal(
4000 psa_crypto_generator_t *generator,
4001 const uint8_t *secret, size_t secret_length,
4002 psa_algorithm_t alg,
4003 const uint8_t *salt, size_t salt_length,
4004 const uint8_t *label, size_t label_length,
4005 size_t capacity )
4006{
4007 psa_status_t status;
4008 size_t max_capacity;
4009
4010 /* Set generator->alg even on failure so that abort knows what to do. */
4011 generator->alg = alg;
4012
Gilles Peskine751d9652018-09-18 12:05:44 +02004013 if( alg == PSA_ALG_SELECT_RAW )
4014 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01004015 (void) salt;
Gilles Peskine751d9652018-09-18 12:05:44 +02004016 if( salt_length != 0 )
4017 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea05219c2018-11-16 16:02:56 +01004018 (void) label;
Gilles Peskine751d9652018-09-18 12:05:44 +02004019 if( label_length != 0 )
4020 return( PSA_ERROR_INVALID_ARGUMENT );
4021 generator->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
4022 if( generator->ctx.buffer.data == NULL )
4023 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4024 memcpy( generator->ctx.buffer.data, secret, secret_length );
4025 generator->ctx.buffer.size = secret_length;
4026 max_capacity = secret_length;
4027 status = PSA_SUCCESS;
4028 }
4029 else
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004030#if defined(MBEDTLS_MD_C)
4031 if( PSA_ALG_IS_HKDF( alg ) )
4032 {
4033 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
4034 size_t hash_size = PSA_HASH_SIZE( hash_alg );
4035 if( hash_size == 0 )
4036 return( PSA_ERROR_NOT_SUPPORTED );
4037 max_capacity = 255 * hash_size;
4038 status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
4039 secret, secret_length,
4040 hash_alg,
4041 salt, salt_length,
4042 label, label_length );
4043 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00004044 /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
4045 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
4046 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004047 {
4048 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
4049 size_t hash_size = PSA_HASH_SIZE( hash_alg );
4050
4051 /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */
4052 if( hash_alg != PSA_ALG_SHA_256 &&
4053 hash_alg != PSA_ALG_SHA_384 )
4054 {
4055 return( PSA_ERROR_NOT_SUPPORTED );
4056 }
4057
4058 max_capacity = 255 * hash_size;
Hanno Becker1aaedc02018-11-16 11:35:34 +00004059
4060 if( PSA_ALG_IS_TLS12_PRF( alg ) )
4061 {
4062 status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
4063 secret, secret_length,
4064 hash_alg, salt, salt_length,
4065 label, label_length );
4066 }
4067 else
4068 {
4069 status = psa_generator_tls12_psk_to_ms_setup(
4070 &generator->ctx.tls12_prf,
4071 secret, secret_length,
4072 hash_alg, salt, salt_length,
4073 label, label_length );
4074 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004075 }
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004076 else
4077#endif
4078 {
4079 return( PSA_ERROR_NOT_SUPPORTED );
4080 }
4081
4082 if( status != PSA_SUCCESS )
4083 return( status );
4084
4085 if( capacity <= max_capacity )
4086 generator->capacity = capacity;
Gilles Peskine8feb3a82018-09-18 12:06:11 +02004087 else if( capacity == PSA_GENERATOR_UNBRIDLED_CAPACITY )
4088 generator->capacity = max_capacity;
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004089 else
4090 return( PSA_ERROR_INVALID_ARGUMENT );
4091
4092 return( PSA_SUCCESS );
4093}
4094
Gilles Peskineea0fb492018-07-12 17:17:20 +02004095psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
Gilles Peskinec5487a82018-12-03 18:08:14 +01004096 psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02004097 psa_algorithm_t alg,
4098 const uint8_t *salt,
4099 size_t salt_length,
4100 const uint8_t *label,
4101 size_t label_length,
4102 size_t capacity )
4103{
4104 key_slot_t *slot;
4105 psa_status_t status;
4106
4107 if( generator->alg != 0 )
4108 return( PSA_ERROR_BAD_STATE );
4109
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004110 /* Make sure that alg is a key derivation algorithm. This prevents
4111 * key selection algorithms, which psa_key_derivation_internal
4112 * accepts for the sake of key agreement. */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004113 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
4114 return( PSA_ERROR_INVALID_ARGUMENT );
4115
Gilles Peskinec5487a82018-12-03 18:08:14 +01004116 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004117 if( status != PSA_SUCCESS )
4118 return( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004119
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004120 if( slot->type != PSA_KEY_TYPE_DERIVE )
4121 return( PSA_ERROR_INVALID_ARGUMENT );
4122
4123 status = psa_key_derivation_internal( generator,
4124 slot->data.raw.data,
4125 slot->data.raw.bytes,
4126 alg,
4127 salt, salt_length,
4128 label, label_length,
4129 capacity );
4130 if( status != PSA_SUCCESS )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004131 psa_generator_abort( generator );
4132 return( status );
4133}
4134
4135
4136
4137/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02004138/* Key agreement */
4139/****************************************************************/
4140
Gilles Peskinea05219c2018-11-16 16:02:56 +01004141#if defined(MBEDTLS_ECDH_C)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004142static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
4143 size_t peer_key_length,
4144 const mbedtls_ecp_keypair *our_key,
4145 uint8_t *shared_secret,
4146 size_t shared_secret_size,
4147 size_t *shared_secret_length )
4148{
4149 mbedtls_pk_context pk;
4150 mbedtls_ecp_keypair *their_key = NULL;
4151 mbedtls_ecdh_context ecdh;
4152 int ret;
4153 mbedtls_ecdh_init( &ecdh );
4154 mbedtls_pk_init( &pk );
4155
4156 ret = mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length );
4157 if( ret != 0 )
4158 goto exit;
Gilles Peskine88714d72018-10-25 23:07:25 +02004159 switch( mbedtls_pk_get_type( &pk ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004160 {
Gilles Peskine88714d72018-10-25 23:07:25 +02004161 case MBEDTLS_PK_ECKEY:
4162 case MBEDTLS_PK_ECKEY_DH:
4163 break;
4164 default:
4165 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4166 goto exit;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004167 }
4168 their_key = mbedtls_pk_ec( pk );
Gilles Peskineb4086612018-11-14 20:51:23 +01004169 if( their_key->grp.id != our_key->grp.id )
4170 {
4171 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4172 goto exit;
4173 }
4174
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004175 ret = mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS );
4176 if( ret != 0 )
4177 goto exit;
4178 ret = mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS );
4179 if( ret != 0 )
4180 goto exit;
4181
4182 ret = mbedtls_ecdh_calc_secret( &ecdh,
4183 shared_secret_length,
4184 shared_secret, shared_secret_size,
4185 mbedtls_ctr_drbg_random,
4186 &global_data.ctr_drbg );
4187
4188exit:
4189 mbedtls_pk_free( &pk );
4190 mbedtls_ecdh_free( &ecdh );
4191 return( mbedtls_to_psa_error( ret ) );
4192}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004193#endif /* MBEDTLS_ECDH_C */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004194
Gilles Peskine01d718c2018-09-18 12:01:02 +02004195#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
4196
Gilles Peskine346797d2018-11-16 16:05:06 +01004197/* Note that if this function fails, you must call psa_generator_abort()
4198 * to potentially free embedded data structures and wipe confidential data.
4199 */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004200static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
4201 key_slot_t *private_key,
4202 const uint8_t *peer_key,
4203 size_t peer_key_length,
4204 psa_algorithm_t alg )
4205{
4206 psa_status_t status;
4207 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
4208 size_t shared_secret_length = 0;
4209
4210 /* Step 1: run the secret agreement algorithm to generate the shared
4211 * secret. */
4212 switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
4213 {
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004214#if defined(MBEDTLS_ECDH_C)
4215 case PSA_ALG_ECDH_BASE:
4216 if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
4217 return( PSA_ERROR_INVALID_ARGUMENT );
4218 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
4219 private_key->data.ecp,
4220 shared_secret,
4221 sizeof( shared_secret ),
4222 &shared_secret_length );
4223 break;
4224#endif /* MBEDTLS_ECDH_C */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004225 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01004226 (void) private_key;
4227 (void) peer_key;
4228 (void) peer_key_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004229 return( PSA_ERROR_NOT_SUPPORTED );
4230 }
4231 if( status != PSA_SUCCESS )
4232 goto exit;
4233
4234 /* Step 2: set up the key derivation to generate key material from
4235 * the shared secret. */
4236 status = psa_key_derivation_internal( generator,
4237 shared_secret, shared_secret_length,
4238 PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ),
4239 NULL, 0, NULL, 0,
4240 PSA_GENERATOR_UNBRIDLED_CAPACITY );
4241exit:
4242 mbedtls_zeroize( shared_secret, shared_secret_length );
4243 return( status );
4244}
4245
4246psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
Gilles Peskinec5487a82018-12-03 18:08:14 +01004247 psa_key_handle_t private_key,
Gilles Peskine01d718c2018-09-18 12:01:02 +02004248 const uint8_t *peer_key,
4249 size_t peer_key_length,
4250 psa_algorithm_t alg )
4251{
4252 key_slot_t *slot;
4253 psa_status_t status;
4254 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
4255 return( PSA_ERROR_INVALID_ARGUMENT );
4256 status = psa_get_key_from_slot( private_key, &slot,
4257 PSA_KEY_USAGE_DERIVE, alg );
4258 if( status != PSA_SUCCESS )
4259 return( status );
Gilles Peskine346797d2018-11-16 16:05:06 +01004260 status = psa_key_agreement_internal( generator,
4261 slot,
4262 peer_key, peer_key_length,
4263 alg );
4264 if( status != PSA_SUCCESS )
4265 psa_generator_abort( generator );
4266 return( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004267}
4268
4269
4270
4271/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004272/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02004273/****************************************************************/
4274
4275psa_status_t psa_generate_random( uint8_t *output,
4276 size_t output_size )
4277{
itayzafrir0adf0fc2018-09-06 16:24:41 +03004278 int ret;
4279 GUARD_MODULE_INITIALIZED;
4280
4281 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
Gilles Peskine05d69892018-06-19 22:00:52 +02004282 return( mbedtls_to_psa_error( ret ) );
4283}
4284
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004285#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
avolinski13beb102018-11-20 16:51:49 +02004286
4287/* Support function for error conversion between psa_its error codes to psa crypto */
4288static psa_status_t its_to_psa_error( psa_its_status_t ret )
4289{
4290 switch( ret )
4291 {
4292 case PSA_ITS_SUCCESS:
4293 return( PSA_SUCCESS );
4294
4295 case PSA_ITS_ERROR_KEY_NOT_FOUND:
4296 return( PSA_ERROR_EMPTY_SLOT );
4297
4298 case PSA_ITS_ERROR_STORAGE_FAILURE:
4299 return( PSA_ERROR_STORAGE_FAILURE );
4300
4301 case PSA_ITS_ERROR_INSUFFICIENT_SPACE:
4302 return( PSA_ERROR_INSUFFICIENT_STORAGE );
4303
4304 case PSA_ITS_ERROR_INVALID_KEY:
4305 case PSA_PS_ERROR_OFFSET_INVALID:
4306 case PSA_ITS_ERROR_INCORRECT_SIZE:
4307 case PSA_ITS_ERROR_BAD_POINTER:
4308 return( PSA_ERROR_INVALID_ARGUMENT );
4309
4310 case PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED:
4311 return( PSA_ERROR_NOT_SUPPORTED );
4312
4313 case PSA_ITS_ERROR_WRITE_ONCE:
4314 return( PSA_ERROR_OCCUPIED_SLOT );
4315
4316 default:
4317 return( PSA_ERROR_UNKNOWN_ERROR );
4318 }
4319}
4320
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004321psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
4322 size_t seed_size )
4323{
4324 psa_status_t status;
avolinski13beb102018-11-20 16:51:49 +02004325 psa_its_status_t its_status;
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004326 struct psa_its_info_t p_info;
4327 if( global_data.initialized )
4328 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02004329
4330 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
4331 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
4332 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
4333 return( PSA_ERROR_INVALID_ARGUMENT );
4334
avolinski0d2c2662018-11-21 17:31:07 +02004335 its_status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
avolinski13beb102018-11-20 16:51:49 +02004336 status = its_to_psa_error( its_status );
4337
4338 if( PSA_ITS_ERROR_KEY_NOT_FOUND == its_status ) /* No seed exists */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004339 {
avolinski0d2c2662018-11-21 17:31:07 +02004340 its_status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
avolinski13beb102018-11-20 16:51:49 +02004341 status = its_to_psa_error( its_status );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004342 }
avolinski13beb102018-11-20 16:51:49 +02004343 else if( PSA_ITS_SUCCESS == its_status )
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004344 {
4345 /* You should not be here. Seed needs to be injected only once */
4346 status = PSA_ERROR_NOT_PERMITTED;
4347 }
4348 return( status );
4349}
4350#endif
4351
Gilles Peskinec5487a82018-12-03 18:08:14 +01004352psa_status_t psa_generate_key( psa_key_handle_t handle,
Gilles Peskine05d69892018-06-19 22:00:52 +02004353 psa_key_type_t type,
4354 size_t bits,
Gilles Peskine53d991e2018-07-12 01:14:59 +02004355 const void *extra,
4356 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02004357{
Gilles Peskine12313cd2018-06-20 00:20:32 +02004358 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004359 psa_status_t status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004360
Gilles Peskine53d991e2018-07-12 01:14:59 +02004361 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004362 return( PSA_ERROR_INVALID_ARGUMENT );
4363
Gilles Peskinec5487a82018-12-03 18:08:14 +01004364 status = psa_get_empty_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004365 if( status != PSA_SUCCESS )
4366 return( status );
4367
Gilles Peskine48c0ea12018-06-21 14:15:31 +02004368 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004369 {
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004370 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004371 if( status != PSA_SUCCESS )
4372 return( status );
4373 status = psa_generate_random( slot->data.raw.data,
4374 slot->data.raw.bytes );
4375 if( status != PSA_SUCCESS )
4376 {
4377 mbedtls_free( slot->data.raw.data );
4378 return( status );
4379 }
4380#if defined(MBEDTLS_DES_C)
4381 if( type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02004382 psa_des_set_key_parity( slot->data.raw.data,
4383 slot->data.raw.bytes );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004384#endif /* MBEDTLS_DES_C */
4385 }
4386 else
4387
4388#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
4389 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
4390 {
4391 mbedtls_rsa_context *rsa;
4392 int ret;
4393 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02004394 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
4395 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +01004396 /* Accept only byte-aligned keys, for the same reasons as
4397 * in psa_import_rsa_key(). */
4398 if( bits % 8 != 0 )
4399 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02004400 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004401 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02004402 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004403 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004404 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02004405#if INT_MAX < 0xffffffff
4406 /* Check that the uint32_t value passed by the caller fits
4407 * in the range supported by this implementation. */
4408 if( p->e > INT_MAX )
4409 return( PSA_ERROR_NOT_SUPPORTED );
4410#endif
4411 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004412 }
4413 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
4414 if( rsa == NULL )
4415 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4416 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
4417 ret = mbedtls_rsa_gen_key( rsa,
4418 mbedtls_ctr_drbg_random,
4419 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004420 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02004421 exponent );
4422 if( ret != 0 )
4423 {
4424 mbedtls_rsa_free( rsa );
4425 mbedtls_free( rsa );
4426 return( mbedtls_to_psa_error( ret ) );
4427 }
4428 slot->data.rsa = rsa;
4429 }
4430 else
4431#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
4432
4433#if defined(MBEDTLS_ECP_C)
4434 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
4435 {
4436 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
4437 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
4438 const mbedtls_ecp_curve_info *curve_info =
4439 mbedtls_ecp_curve_info_from_grp_id( grp_id );
4440 mbedtls_ecp_keypair *ecp;
4441 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004442 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004443 return( PSA_ERROR_NOT_SUPPORTED );
4444 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
4445 return( PSA_ERROR_NOT_SUPPORTED );
4446 if( curve_info->bit_size != bits )
4447 return( PSA_ERROR_INVALID_ARGUMENT );
4448 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
4449 if( ecp == NULL )
4450 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4451 mbedtls_ecp_keypair_init( ecp );
4452 ret = mbedtls_ecp_gen_key( grp_id, ecp,
4453 mbedtls_ctr_drbg_random,
4454 &global_data.ctr_drbg );
4455 if( ret != 0 )
4456 {
4457 mbedtls_ecp_keypair_free( ecp );
4458 mbedtls_free( ecp );
4459 return( mbedtls_to_psa_error( ret ) );
4460 }
4461 slot->data.ecp = ecp;
4462 }
4463 else
4464#endif /* MBEDTLS_ECP_C */
4465
4466 return( PSA_ERROR_NOT_SUPPORTED );
4467
4468 slot->type = type;
Darryl Green0c6575a2018-11-07 16:05:30 +00004469
4470#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
4471 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
4472 {
Gilles Peskine69f976b2018-11-30 18:46:56 +01004473 return( psa_save_generated_persistent_key( slot, bits ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004474 }
4475#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
4476
4477 return( status );
Gilles Peskine05d69892018-06-19 22:00:52 +02004478}
4479
4480
4481/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01004482/* Module setup */
4483/****************************************************************/
4484
Gilles Peskine5e769522018-11-20 21:59:56 +01004485psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
4486 void (* entropy_init )( mbedtls_entropy_context *ctx ),
4487 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
4488{
4489 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4490 return( PSA_ERROR_BAD_STATE );
4491 global_data.entropy_init = entropy_init;
4492 global_data.entropy_free = entropy_free;
4493 return( PSA_SUCCESS );
4494}
4495
Gilles Peskinee59236f2018-01-27 23:32:46 +01004496void mbedtls_psa_crypto_free( void )
4497{
Gilles Peskinec6b69072018-11-20 21:42:52 +01004498 if( global_data.key_slots_initialized )
Darryl Green40225ba2018-11-15 14:48:15 +00004499 {
Gilles Peskinec5487a82018-12-03 18:08:14 +01004500 psa_key_handle_t key;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004501 for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ )
4502 {
Gilles Peskined7c75702018-12-03 10:36:46 +01004503 key_slot_t *slot = &global_data.key_slots[key - 1];
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01004504 (void) psa_wipe_key_slot( slot );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004505 }
Darryl Green40225ba2018-11-15 14:48:15 +00004506 }
Gilles Peskinec6b69072018-11-20 21:42:52 +01004507 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4508 {
4509 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
Gilles Peskine5e769522018-11-20 21:59:56 +01004510 global_data.entropy_free( &global_data.entropy );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004511 }
4512 /* Wipe all remaining data, including configuration.
4513 * In particular, this sets all state indicator to the value
4514 * indicating "uninitialized". */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004515 mbedtls_zeroize( &global_data, sizeof( global_data ) );
4516}
4517
4518psa_status_t psa_crypto_init( void )
4519{
4520 int ret;
4521 const unsigned char drbg_seed[] = "PSA";
4522
Gilles Peskinec6b69072018-11-20 21:42:52 +01004523 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004524 if( global_data.initialized != 0 )
4525 return( PSA_SUCCESS );
4526
Gilles Peskine5e769522018-11-20 21:59:56 +01004527 /* Set default configuration if
4528 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
4529 if( global_data.entropy_init == NULL )
4530 global_data.entropy_init = mbedtls_entropy_init;
4531 if( global_data.entropy_free == NULL )
4532 global_data.entropy_free = mbedtls_entropy_free;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004533
Gilles Peskinec6b69072018-11-20 21:42:52 +01004534 /* Initialize the random generator. */
Gilles Peskine5e769522018-11-20 21:59:56 +01004535 global_data.entropy_init( &global_data.entropy );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004536 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004537 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004538 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
4539 mbedtls_entropy_func,
4540 &global_data.entropy,
4541 drbg_seed, sizeof( drbg_seed ) - 1 );
4542 if( ret != 0 )
4543 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004544 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004545
Gilles Peskinec6b69072018-11-20 21:42:52 +01004546 /* Initialize the key slots. Zero-initialization has made all key
4547 * slots empty, so there is nothing to do. In a future version we will
4548 * load data from storage. */
4549 global_data.key_slots_initialized = 1;
4550
4551 /* All done. */
Gilles Peskinee4ebc122018-03-07 14:16:44 +01004552 global_data.initialized = 1;
4553
Gilles Peskinee59236f2018-01-27 23:32:46 +01004554exit:
4555 if( ret != 0 )
4556 mbedtls_psa_crypto_free( );
4557 return( mbedtls_to_psa_error( ret ) );
4558}
4559
4560#endif /* MBEDTLS_PSA_CRYPTO_C */