blob: 24ad06d389136f31d70d7adf24c1b20268462209 [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"
Darryl Greend49a4992018-06-18 17:27:26 +010047/* Include internal declarations that are useful for implementing persistently
48 * stored keys. */
49#include "psa_crypto_storage.h"
50
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010051#include <stdlib.h>
52#include <string.h>
53#if defined(MBEDTLS_PLATFORM_C)
54#include "mbedtls/platform.h"
55#else
56#define mbedtls_calloc calloc
57#define mbedtls_free free
58#endif
59
Gilles Peskinea5905292018-02-07 20:59:33 +010060#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020061#include "mbedtls/asn1.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020062#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010063#include "mbedtls/blowfish.h"
64#include "mbedtls/camellia.h"
65#include "mbedtls/cipher.h"
66#include "mbedtls/ccm.h"
67#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010068#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010069#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020070#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010071#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010072#include "mbedtls/entropy.h"
Netanel Gonen2bcd3122018-11-19 11:53:02 +020073#include "mbedtls/entropy_poll.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010074#include "mbedtls/error.h"
75#include "mbedtls/gcm.h"
76#include "mbedtls/md2.h"
77#include "mbedtls/md4.h"
78#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010079#include "mbedtls/md.h"
80#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010081#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010082#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010083#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010084#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010085#include "mbedtls/sha1.h"
86#include "mbedtls/sha256.h"
87#include "mbedtls/sha512.h"
88#include "mbedtls/xtea.h"
89
Netanel Gonen2bcd3122018-11-19 11:53:02 +020090#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
91#include "psa_prot_internal_storage.h"
92#endif
Gilles Peskinee59236f2018-01-27 23:32:46 +010093
Gilles Peskine996deb12018-08-01 15:45:45 +020094#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
95
Gilles Peskinee59236f2018-01-27 23:32:46 +010096/* Implementation that should never be optimized out by the compiler */
97static void mbedtls_zeroize( void *v, size_t n )
98{
99 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
100}
101
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100102/* constant-time buffer comparison */
103static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
104{
105 size_t i;
106 unsigned char diff = 0;
107
108 for( i = 0; i < n; i++ )
109 diff |= a[i] ^ b[i];
110
111 return( diff );
112}
113
114
115
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100116/****************************************************************/
117/* Global data, support functions and library management */
118/****************************************************************/
119
120/* Number of key slots (plus one because 0 is not used).
121 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +0200122#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100123
Gilles Peskine2d277862018-06-18 15:41:12 +0200124typedef struct
125{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100126 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300127 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200128 psa_key_lifetime_t lifetime;
Gilles Peskine69f976b2018-11-30 18:46:56 +0100129 psa_key_id_t persistent_storage_id;
Gilles Peskine2d277862018-06-18 15:41:12 +0200130 union
131 {
132 struct raw_data
133 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100134 uint8_t *data;
135 size_t bytes;
136 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100137#if defined(MBEDTLS_RSA_C)
138 mbedtls_rsa_context *rsa;
139#endif /* MBEDTLS_RSA_C */
140#if defined(MBEDTLS_ECP_C)
141 mbedtls_ecp_keypair *ecp;
142#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100143 } data;
144} key_slot_t;
145
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200146static int key_type_is_raw_bytes( psa_key_type_t type )
147{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200148 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200149}
150
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100151/* Values for psa_global_data_t::rng_state */
152#define RNG_NOT_INITIALIZED 0
153#define RNG_INITIALIZED 1
154#define RNG_SEEDED 2
Gilles Peskinec6b69072018-11-20 21:42:52 +0100155
Gilles Peskine2d277862018-06-18 15:41:12 +0200156typedef struct
157{
Gilles Peskine5e769522018-11-20 21:59:56 +0100158 void (* entropy_init )( mbedtls_entropy_context *ctx );
159 void (* entropy_free )( mbedtls_entropy_context *ctx );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100160 mbedtls_entropy_context entropy;
161 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200162 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinec6b69072018-11-20 21:42:52 +0100163 unsigned initialized : 1;
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100164 unsigned rng_state : 2;
Gilles Peskinec6b69072018-11-20 21:42:52 +0100165 unsigned key_slots_initialized : 1;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100166} psa_global_data_t;
167
168static psa_global_data_t global_data;
169
itayzafrir0adf0fc2018-09-06 16:24:41 +0300170#define GUARD_MODULE_INITIALIZED \
171 if( global_data.initialized == 0 ) \
172 return( PSA_ERROR_BAD_STATE );
173
Gilles Peskinee59236f2018-01-27 23:32:46 +0100174static psa_status_t mbedtls_to_psa_error( int ret )
175{
Gilles Peskinea5905292018-02-07 20:59:33 +0100176 /* If there's both a high-level code and low-level code, dispatch on
177 * the high-level code. */
178 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100179 {
180 case 0:
181 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100182
183 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
184 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
185 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
186 return( PSA_ERROR_NOT_SUPPORTED );
187 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
188 return( PSA_ERROR_HARDWARE_FAILURE );
189
190 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
191 return( PSA_ERROR_HARDWARE_FAILURE );
192
Gilles Peskine9a944802018-06-21 09:35:35 +0200193 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
194 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
195 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
196 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
197 case MBEDTLS_ERR_ASN1_INVALID_DATA:
198 return( PSA_ERROR_INVALID_ARGUMENT );
199 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
200 return( PSA_ERROR_INSUFFICIENT_MEMORY );
201 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
202 return( PSA_ERROR_BUFFER_TOO_SMALL );
203
Gilles Peskinea5905292018-02-07 20:59:33 +0100204 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
205 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
206 return( PSA_ERROR_NOT_SUPPORTED );
207 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
208 return( PSA_ERROR_HARDWARE_FAILURE );
209
210 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
211 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
212 return( PSA_ERROR_NOT_SUPPORTED );
213 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
214 return( PSA_ERROR_HARDWARE_FAILURE );
215
216 case MBEDTLS_ERR_CCM_BAD_INPUT:
217 return( PSA_ERROR_INVALID_ARGUMENT );
218 case MBEDTLS_ERR_CCM_AUTH_FAILED:
219 return( PSA_ERROR_INVALID_SIGNATURE );
220 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
221 return( PSA_ERROR_HARDWARE_FAILURE );
222
223 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
224 return( PSA_ERROR_NOT_SUPPORTED );
225 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
226 return( PSA_ERROR_INVALID_ARGUMENT );
227 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
228 return( PSA_ERROR_INSUFFICIENT_MEMORY );
229 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
230 return( PSA_ERROR_INVALID_PADDING );
231 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
232 return( PSA_ERROR_BAD_STATE );
233 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
234 return( PSA_ERROR_INVALID_SIGNATURE );
235 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
236 return( PSA_ERROR_TAMPERING_DETECTED );
237 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
238 return( PSA_ERROR_HARDWARE_FAILURE );
239
240 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
241 return( PSA_ERROR_HARDWARE_FAILURE );
242
243 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
244 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
245 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
246 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
247 return( PSA_ERROR_NOT_SUPPORTED );
248 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
249 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
250
251 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
252 return( PSA_ERROR_NOT_SUPPORTED );
253 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
254 return( PSA_ERROR_HARDWARE_FAILURE );
255
Gilles Peskinee59236f2018-01-27 23:32:46 +0100256 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
257 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
258 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
259 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100260
261 case MBEDTLS_ERR_GCM_AUTH_FAILED:
262 return( PSA_ERROR_INVALID_SIGNATURE );
263 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200264 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100265 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
266 return( PSA_ERROR_HARDWARE_FAILURE );
267
268 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
269 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
270 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
271 return( PSA_ERROR_HARDWARE_FAILURE );
272
273 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
274 return( PSA_ERROR_NOT_SUPPORTED );
275 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
276 return( PSA_ERROR_INVALID_ARGUMENT );
277 case MBEDTLS_ERR_MD_ALLOC_FAILED:
278 return( PSA_ERROR_INSUFFICIENT_MEMORY );
279 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
280 return( PSA_ERROR_STORAGE_FAILURE );
281 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
282 return( PSA_ERROR_HARDWARE_FAILURE );
283
Gilles Peskinef76aa772018-10-29 19:24:33 +0100284 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
285 return( PSA_ERROR_STORAGE_FAILURE );
286 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
287 return( PSA_ERROR_INVALID_ARGUMENT );
288 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
289 return( PSA_ERROR_INVALID_ARGUMENT );
290 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
291 return( PSA_ERROR_BUFFER_TOO_SMALL );
292 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
293 return( PSA_ERROR_INVALID_ARGUMENT );
294 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
295 return( PSA_ERROR_INVALID_ARGUMENT );
296 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
297 return( PSA_ERROR_INVALID_ARGUMENT );
298 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
299 return( PSA_ERROR_INSUFFICIENT_MEMORY );
300
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100301 case MBEDTLS_ERR_PK_ALLOC_FAILED:
302 return( PSA_ERROR_INSUFFICIENT_MEMORY );
303 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
304 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
305 return( PSA_ERROR_INVALID_ARGUMENT );
306 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100307 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100308 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
309 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
310 return( PSA_ERROR_INVALID_ARGUMENT );
311 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
312 return( PSA_ERROR_NOT_SUPPORTED );
313 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
314 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
315 return( PSA_ERROR_NOT_PERMITTED );
316 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
317 return( PSA_ERROR_INVALID_ARGUMENT );
318 case MBEDTLS_ERR_PK_INVALID_ALG:
319 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
320 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
321 return( PSA_ERROR_NOT_SUPPORTED );
322 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
323 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100324 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
325 return( PSA_ERROR_HARDWARE_FAILURE );
326
327 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
328 return( PSA_ERROR_HARDWARE_FAILURE );
329
330 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
331 return( PSA_ERROR_INVALID_ARGUMENT );
332 case MBEDTLS_ERR_RSA_INVALID_PADDING:
333 return( PSA_ERROR_INVALID_PADDING );
334 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
335 return( PSA_ERROR_HARDWARE_FAILURE );
336 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
337 return( PSA_ERROR_INVALID_ARGUMENT );
338 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
339 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
340 return( PSA_ERROR_TAMPERING_DETECTED );
341 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
342 return( PSA_ERROR_INVALID_SIGNATURE );
343 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
344 return( PSA_ERROR_BUFFER_TOO_SMALL );
345 case MBEDTLS_ERR_RSA_RNG_FAILED:
346 return( PSA_ERROR_INSUFFICIENT_MEMORY );
347 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
348 return( PSA_ERROR_NOT_SUPPORTED );
349 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
350 return( PSA_ERROR_HARDWARE_FAILURE );
351
352 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
353 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
354 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
355 return( PSA_ERROR_HARDWARE_FAILURE );
356
357 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
358 return( PSA_ERROR_INVALID_ARGUMENT );
359 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
360 return( PSA_ERROR_HARDWARE_FAILURE );
361
itayzafrir5c753392018-05-08 11:18:38 +0300362 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300363 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300364 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300365 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
366 return( PSA_ERROR_BUFFER_TOO_SMALL );
367 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
368 return( PSA_ERROR_NOT_SUPPORTED );
369 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
370 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
371 return( PSA_ERROR_INVALID_SIGNATURE );
372 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
373 return( PSA_ERROR_INSUFFICIENT_MEMORY );
374 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
375 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300376
Gilles Peskinee59236f2018-01-27 23:32:46 +0100377 default:
378 return( PSA_ERROR_UNKNOWN_ERROR );
379 }
380}
381
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200382
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200383
384
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100385/****************************************************************/
386/* Key management */
387/****************************************************************/
388
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100389#if defined(MBEDTLS_ECP_C)
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200390static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
391{
392 switch( grpid )
393 {
394 case MBEDTLS_ECP_DP_SECP192R1:
395 return( PSA_ECC_CURVE_SECP192R1 );
396 case MBEDTLS_ECP_DP_SECP224R1:
397 return( PSA_ECC_CURVE_SECP224R1 );
398 case MBEDTLS_ECP_DP_SECP256R1:
399 return( PSA_ECC_CURVE_SECP256R1 );
400 case MBEDTLS_ECP_DP_SECP384R1:
401 return( PSA_ECC_CURVE_SECP384R1 );
402 case MBEDTLS_ECP_DP_SECP521R1:
403 return( PSA_ECC_CURVE_SECP521R1 );
404 case MBEDTLS_ECP_DP_BP256R1:
405 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
406 case MBEDTLS_ECP_DP_BP384R1:
407 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
408 case MBEDTLS_ECP_DP_BP512R1:
409 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
410 case MBEDTLS_ECP_DP_CURVE25519:
411 return( PSA_ECC_CURVE_CURVE25519 );
412 case MBEDTLS_ECP_DP_SECP192K1:
413 return( PSA_ECC_CURVE_SECP192K1 );
414 case MBEDTLS_ECP_DP_SECP224K1:
415 return( PSA_ECC_CURVE_SECP224K1 );
416 case MBEDTLS_ECP_DP_SECP256K1:
417 return( PSA_ECC_CURVE_SECP256K1 );
418 case MBEDTLS_ECP_DP_CURVE448:
419 return( PSA_ECC_CURVE_CURVE448 );
420 default:
421 return( 0 );
422 }
423}
424
Gilles Peskine12313cd2018-06-20 00:20:32 +0200425static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
426{
427 switch( curve )
428 {
429 case PSA_ECC_CURVE_SECP192R1:
430 return( MBEDTLS_ECP_DP_SECP192R1 );
431 case PSA_ECC_CURVE_SECP224R1:
432 return( MBEDTLS_ECP_DP_SECP224R1 );
433 case PSA_ECC_CURVE_SECP256R1:
434 return( MBEDTLS_ECP_DP_SECP256R1 );
435 case PSA_ECC_CURVE_SECP384R1:
436 return( MBEDTLS_ECP_DP_SECP384R1 );
437 case PSA_ECC_CURVE_SECP521R1:
438 return( MBEDTLS_ECP_DP_SECP521R1 );
439 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
440 return( MBEDTLS_ECP_DP_BP256R1 );
441 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
442 return( MBEDTLS_ECP_DP_BP384R1 );
443 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
444 return( MBEDTLS_ECP_DP_BP512R1 );
445 case PSA_ECC_CURVE_CURVE25519:
446 return( MBEDTLS_ECP_DP_CURVE25519 );
447 case PSA_ECC_CURVE_SECP192K1:
448 return( MBEDTLS_ECP_DP_SECP192K1 );
449 case PSA_ECC_CURVE_SECP224K1:
450 return( MBEDTLS_ECP_DP_SECP224K1 );
451 case PSA_ECC_CURVE_SECP256K1:
452 return( MBEDTLS_ECP_DP_SECP256K1 );
453 case PSA_ECC_CURVE_CURVE448:
454 return( MBEDTLS_ECP_DP_CURVE448 );
455 default:
456 return( MBEDTLS_ECP_DP_NONE );
457 }
458}
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100459#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200460
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200461static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
462 size_t bits,
463 struct raw_data *raw )
464{
465 /* Check that the bit size is acceptable for the key type */
466 switch( type )
467 {
468 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200469 if( bits == 0 )
470 {
471 raw->bytes = 0;
472 raw->data = NULL;
473 return( PSA_SUCCESS );
474 }
475 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200476#if defined(MBEDTLS_MD_C)
477 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200478#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200479 case PSA_KEY_TYPE_DERIVE:
480 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200481#if defined(MBEDTLS_AES_C)
482 case PSA_KEY_TYPE_AES:
483 if( bits != 128 && bits != 192 && bits != 256 )
484 return( PSA_ERROR_INVALID_ARGUMENT );
485 break;
486#endif
487#if defined(MBEDTLS_CAMELLIA_C)
488 case PSA_KEY_TYPE_CAMELLIA:
489 if( bits != 128 && bits != 192 && bits != 256 )
490 return( PSA_ERROR_INVALID_ARGUMENT );
491 break;
492#endif
493#if defined(MBEDTLS_DES_C)
494 case PSA_KEY_TYPE_DES:
495 if( bits != 64 && bits != 128 && bits != 192 )
496 return( PSA_ERROR_INVALID_ARGUMENT );
497 break;
498#endif
499#if defined(MBEDTLS_ARC4_C)
500 case PSA_KEY_TYPE_ARC4:
501 if( bits < 8 || bits > 2048 )
502 return( PSA_ERROR_INVALID_ARGUMENT );
503 break;
504#endif
505 default:
506 return( PSA_ERROR_NOT_SUPPORTED );
507 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200508 if( bits % 8 != 0 )
509 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200510
511 /* Allocate memory for the key */
512 raw->bytes = PSA_BITS_TO_BYTES( bits );
513 raw->data = mbedtls_calloc( 1, raw->bytes );
514 if( raw->data == NULL )
515 {
516 raw->bytes = 0;
517 return( PSA_ERROR_INSUFFICIENT_MEMORY );
518 }
519 return( PSA_SUCCESS );
520}
521
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200522#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine86a440b2018-11-12 18:39:40 +0100523/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
524 * that are not a multiple of 8) well. For example, there is only
525 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
526 * way to return the exact bit size of a key.
527 * To keep things simple, reject non-byte-aligned key sizes. */
528static psa_status_t psa_check_rsa_key_byte_aligned(
529 const mbedtls_rsa_context *rsa )
530{
531 mbedtls_mpi n;
532 psa_status_t status;
533 mbedtls_mpi_init( &n );
534 status = mbedtls_to_psa_error(
535 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
536 if( status == PSA_SUCCESS )
537 {
538 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
539 status = PSA_ERROR_NOT_SUPPORTED;
540 }
541 mbedtls_mpi_free( &n );
542 return( status );
543}
544
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200545static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
546 mbedtls_rsa_context **p_rsa )
547{
548 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_RSA )
549 return( PSA_ERROR_INVALID_ARGUMENT );
550 else
551 {
552 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *pk );
Gilles Peskineaac64a22018-11-12 18:37:42 +0100553 /* The size of an RSA key doesn't have to be a multiple of 8.
554 * Mbed TLS supports non-byte-aligned key sizes, but not well.
555 * For example, mbedtls_rsa_get_len() returns the key size in
556 * bytes, not in bits. */
557 size_t bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100558 psa_status_t status;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200559 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
560 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100561 status = psa_check_rsa_key_byte_aligned( rsa );
562 if( status != PSA_SUCCESS )
563 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200564 *p_rsa = rsa;
565 return( PSA_SUCCESS );
566 }
567}
568#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
569
570#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinef76aa772018-10-29 19:24:33 +0100571/* Import an elliptic curve parsed by the mbedtls pk module. */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200572static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
573 mbedtls_pk_context *pk,
574 mbedtls_ecp_keypair **p_ecp )
575{
576 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
577 return( PSA_ERROR_INVALID_ARGUMENT );
578 else
579 {
580 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
581 psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
582 if( actual_curve != expected_curve )
583 return( PSA_ERROR_INVALID_ARGUMENT );
584 *p_ecp = ecp;
585 return( PSA_SUCCESS );
586 }
587}
588#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
589
Gilles Peskinef76aa772018-10-29 19:24:33 +0100590#if defined(MBEDTLS_ECP_C)
591/* Import a private key given as a byte string which is the private value
592 * in big-endian order. */
593static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
594 const uint8_t *data,
595 size_t data_length,
596 mbedtls_ecp_keypair **p_ecp )
597{
598 psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
599 mbedtls_ecp_keypair *ecp = NULL;
600 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
601
602 *p_ecp = NULL;
603 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
604 if( ecp == NULL )
605 return( PSA_ERROR_INSUFFICIENT_MEMORY );
606
607 /* Load the group. */
608 status = mbedtls_to_psa_error(
609 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
610 if( status != PSA_SUCCESS )
611 goto exit;
612 /* Load the secret value. */
613 status = mbedtls_to_psa_error(
614 mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
615 if( status != PSA_SUCCESS )
616 goto exit;
617 /* Validate the private key. */
618 status = mbedtls_to_psa_error(
619 mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
620 if( status != PSA_SUCCESS )
621 goto exit;
622 /* Calculate the public key from the private key. */
623 status = mbedtls_to_psa_error(
624 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
625 mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
626 if( status != PSA_SUCCESS )
627 goto exit;
628
629 *p_ecp = ecp;
630 return( PSA_SUCCESS );
631
632exit:
633 if( ecp != NULL )
634 {
635 mbedtls_ecp_keypair_free( ecp );
636 mbedtls_free( ecp );
637 }
638 return( status );
639}
640#endif /* defined(MBEDTLS_ECP_C) */
641
Darryl Green940d72c2018-07-13 13:18:51 +0100642static psa_status_t psa_import_key_into_slot( key_slot_t *slot,
643 const uint8_t *data,
644 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100645{
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200646 psa_status_t status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100647
Darryl Green940d72c2018-07-13 13:18:51 +0100648 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100649 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100650 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100651 if( data_length > SIZE_MAX / 8 )
652 return( PSA_ERROR_NOT_SUPPORTED );
Darryl Green940d72c2018-07-13 13:18:51 +0100653 status = prepare_raw_data_slot( slot->type,
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200654 PSA_BYTES_TO_BITS( data_length ),
655 &slot->data.raw );
656 if( status != PSA_SUCCESS )
657 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200658 if( data_length != 0 )
659 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100660 }
661 else
Gilles Peskinef76aa772018-10-29 19:24:33 +0100662#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100663 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100664 {
Darryl Green940d72c2018-07-13 13:18:51 +0100665 status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskinef76aa772018-10-29 19:24:33 +0100666 data, data_length,
667 &slot->data.ecp );
668 if( status != PSA_SUCCESS )
669 return( status );
670 }
671 else
672#endif /* MBEDTLS_ECP_C */
Gilles Peskine969ac722018-01-28 18:16:59 +0100673#if defined(MBEDTLS_PK_PARSE_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100674 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
675 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100676 {
677 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100678 mbedtls_pk_context pk;
679 mbedtls_pk_init( &pk );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200680
681 /* Parse the data. */
Darryl Green940d72c2018-07-13 13:18:51 +0100682 if( PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100683 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
684 else
685 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100686 if( ret != 0 )
687 return( mbedtls_to_psa_error( ret ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200688
689 /* We have something that the pkparse module recognizes.
690 * If it has the expected type and passes any type-specific
691 * checks, store it. */
Gilles Peskine969ac722018-01-28 18:16:59 +0100692#if defined(MBEDTLS_RSA_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100693 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200694 status = psa_import_rsa_key( &pk, &slot->data.rsa );
695 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100696#endif /* MBEDTLS_RSA_C */
697#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100698 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
699 status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200700 &pk, &slot->data.ecp );
701 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100702#endif /* MBEDTLS_ECP_C */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200703 {
704 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinec648d692018-06-28 08:46:13 +0200705 }
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200706
Gilles Peskinec648d692018-06-28 08:46:13 +0200707 /* Free the content of the pk object only on error. On success,
708 * the content of the object has been stored in the slot. */
709 if( status != PSA_SUCCESS )
710 {
711 mbedtls_pk_free( &pk );
712 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100713 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100714 }
715 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100716#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100717 {
718 return( PSA_ERROR_NOT_SUPPORTED );
719 }
Darryl Green940d72c2018-07-13 13:18:51 +0100720 return( PSA_SUCCESS );
721}
722
Darryl Greend49a4992018-06-18 17:27:26 +0100723#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine69f976b2018-11-30 18:46:56 +0100724static psa_status_t psa_load_persistent_key_into_slot( key_slot_t *p_slot )
Darryl Greend49a4992018-06-18 17:27:26 +0100725{
726 psa_status_t status = PSA_SUCCESS;
727 uint8_t *key_data = NULL;
728 size_t key_data_length = 0;
729
Gilles Peskine69f976b2018-11-30 18:46:56 +0100730 status = psa_load_persistent_key( p_slot->persistent_storage_id,
731 &( p_slot )->type,
Darryl Greend49a4992018-06-18 17:27:26 +0100732 &( p_slot )->policy, &key_data,
733 &key_data_length );
734 if( status != PSA_SUCCESS )
735 goto exit;
736 status = psa_import_key_into_slot( p_slot,
737 key_data, key_data_length );
738exit:
739 psa_free_persistent_key_data( key_data, key_data_length );
740 return( status );
741}
742#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
743
Darryl Green06fd18d2018-07-16 11:21:11 +0100744/* Retrieve a key slot, occupied or not. */
745static psa_status_t psa_get_key_slot( psa_key_slot_t key,
746 key_slot_t **p_slot )
747{
748 GUARD_MODULE_INITIALIZED;
749
750 /* 0 is not a valid slot number under any circumstance. This
751 * implementation provides slots number 1 to N where N is the
752 * number of available slots. */
753 if( key == 0 || key > ARRAY_LENGTH( global_data.key_slots ) )
754 return( PSA_ERROR_INVALID_ARGUMENT );
755
756 *p_slot = &global_data.key_slots[key - 1];
Darryl Greend49a4992018-06-18 17:27:26 +0100757
758#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
759 if( ( *p_slot )->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
760 {
761 /* There are two circumstances this can occur: the key material has
762 * not yet been created, or the key exists in storage but has not yet
763 * been loaded into memory. */
764 if( ( *p_slot )->type == PSA_KEY_TYPE_NONE )
765 {
766 psa_status_t status = PSA_SUCCESS;
Gilles Peskine69f976b2018-11-30 18:46:56 +0100767 status = psa_load_persistent_key_into_slot( *p_slot );
Darryl Greend49a4992018-06-18 17:27:26 +0100768 if( status != PSA_ERROR_EMPTY_SLOT )
769 return( status );
770 }
771 }
772#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
773
Darryl Green06fd18d2018-07-16 11:21:11 +0100774 return( PSA_SUCCESS );
775}
776
777/* Retrieve an empty key slot (slot with no key data, but possibly
778 * with some metadata such as a policy). */
779static psa_status_t psa_get_empty_key_slot( psa_key_slot_t key,
780 key_slot_t **p_slot )
781{
782 psa_status_t status;
783 key_slot_t *slot = NULL;
784
785 *p_slot = NULL;
786
787 status = psa_get_key_slot( key, &slot );
788 if( status != PSA_SUCCESS )
789 return( status );
790
791 if( slot->type != PSA_KEY_TYPE_NONE )
792 return( PSA_ERROR_OCCUPIED_SLOT );
793
794 *p_slot = slot;
795 return( status );
796}
797
798/** Retrieve a slot which must contain a key. The key must have allow all the
799 * usage flags set in \p usage. If \p alg is nonzero, the key must allow
800 * operations with this algorithm. */
801static psa_status_t psa_get_key_from_slot( psa_key_slot_t key,
802 key_slot_t **p_slot,
803 psa_key_usage_t usage,
804 psa_algorithm_t alg )
805{
806 psa_status_t status;
807 key_slot_t *slot = NULL;
808
809 *p_slot = NULL;
810
811 status = psa_get_key_slot( key, &slot );
812 if( status != PSA_SUCCESS )
813 return( status );
814 if( slot->type == PSA_KEY_TYPE_NONE )
815 return( PSA_ERROR_EMPTY_SLOT );
816
817 /* Enforce that usage policy for the key slot contains all the flags
818 * required by the usage parameter. There is one exception: public
819 * keys can always be exported, so we treat public key objects as
820 * if they had the export flag. */
821 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
822 usage &= ~PSA_KEY_USAGE_EXPORT;
823 if( ( slot->policy.usage & usage ) != usage )
824 return( PSA_ERROR_NOT_PERMITTED );
825 if( alg != 0 && ( alg != slot->policy.alg ) )
826 return( PSA_ERROR_NOT_PERMITTED );
827
828 *p_slot = slot;
829 return( PSA_SUCCESS );
830}
Darryl Green940d72c2018-07-13 13:18:51 +0100831
Darryl Green40225ba2018-11-15 14:48:15 +0000832static psa_status_t psa_remove_key_data_from_memory( key_slot_t *slot )
833{
834 if( slot->type == PSA_KEY_TYPE_NONE )
835 {
836 /* No key material to clean. */
837 }
838 else if( key_type_is_raw_bytes( slot->type ) )
839 {
840 mbedtls_free( slot->data.raw.data );
841 }
842 else
843#if defined(MBEDTLS_RSA_C)
844 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
845 {
846 mbedtls_rsa_free( slot->data.rsa );
847 mbedtls_free( slot->data.rsa );
848 }
849 else
850#endif /* defined(MBEDTLS_RSA_C) */
851#if defined(MBEDTLS_ECP_C)
852 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
853 {
854 mbedtls_ecp_keypair_free( slot->data.ecp );
855 mbedtls_free( slot->data.ecp );
856 }
857 else
858#endif /* defined(MBEDTLS_ECP_C) */
859 {
860 /* Shouldn't happen: the key type is not any type that we
861 * put in. */
862 return( PSA_ERROR_TAMPERING_DETECTED );
863 }
864
865 return( PSA_SUCCESS );
866}
867
Darryl Green940d72c2018-07-13 13:18:51 +0100868psa_status_t psa_import_key( psa_key_slot_t key,
869 psa_key_type_t type,
870 const uint8_t *data,
871 size_t data_length )
872{
873 key_slot_t *slot;
874 psa_status_t status;
875
876 status = psa_get_empty_key_slot( key, &slot );
877 if( status != PSA_SUCCESS )
878 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100879
880 slot->type = type;
Darryl Green940d72c2018-07-13 13:18:51 +0100881
882 status = psa_import_key_into_slot( slot, data, data_length );
883 if( status != PSA_SUCCESS )
884 {
885 slot->type = PSA_KEY_TYPE_NONE;
886 return( status );
887 }
888
Darryl Greend49a4992018-06-18 17:27:26 +0100889#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
890 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
891 {
892 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +0100893 status = psa_save_persistent_key( slot->persistent_storage_id,
894 slot->type, &slot->policy, data,
Darryl Greend49a4992018-06-18 17:27:26 +0100895 data_length );
896 if( status != PSA_SUCCESS )
897 {
898 (void) psa_remove_key_data_from_memory( slot );
899 slot->type = PSA_KEY_TYPE_NONE;
900 }
901 }
902#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
903
904 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100905}
906
Gilles Peskine2d277862018-06-18 15:41:12 +0200907psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100908{
909 key_slot_t *slot;
Darryl Greend49a4992018-06-18 17:27:26 +0100910 psa_status_t status = PSA_SUCCESS;
911 psa_status_t storage_status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100912
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200913 status = psa_get_key_slot( key, &slot );
914 if( status != PSA_SUCCESS )
915 return( status );
Darryl Greend49a4992018-06-18 17:27:26 +0100916#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
917 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
918 {
Gilles Peskine69f976b2018-11-30 18:46:56 +0100919 storage_status =
920 psa_destroy_persistent_key( slot->persistent_storage_id );
Darryl Greend49a4992018-06-18 17:27:26 +0100921 }
922#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
923 status = psa_remove_key_data_from_memory( slot );
924 /* Zeroize the slot to wipe metadata such as policies. */
925 mbedtls_zeroize( slot, sizeof( *slot ) );
926 if( status != PSA_SUCCESS )
927 return( status );
928 return( storage_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100929}
930
Gilles Peskineb870b182018-07-06 16:02:09 +0200931/* Return the size of the key in the given slot, in bits. */
932static size_t psa_get_key_bits( const key_slot_t *slot )
933{
934 if( key_type_is_raw_bytes( slot->type ) )
935 return( slot->data.raw.bytes * 8 );
936#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200937 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaac64a22018-11-12 18:37:42 +0100938 return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
Gilles Peskineb870b182018-07-06 16:02:09 +0200939#endif /* defined(MBEDTLS_RSA_C) */
940#if defined(MBEDTLS_ECP_C)
941 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
942 return( slot->data.ecp->grp.pbits );
943#endif /* defined(MBEDTLS_ECP_C) */
944 /* Shouldn't happen except on an empty slot. */
945 return( 0 );
946}
947
Gilles Peskine2d277862018-06-18 15:41:12 +0200948psa_status_t psa_get_key_information( psa_key_slot_t key,
949 psa_key_type_t *type,
950 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100951{
952 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200953 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100954
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100955 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200956 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100957 if( bits != NULL )
958 *bits = 0;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200959 status = psa_get_key_slot( key, &slot );
960 if( status != PSA_SUCCESS )
961 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +0200962
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100963 if( slot->type == PSA_KEY_TYPE_NONE )
964 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200965 if( type != NULL )
966 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +0200967 if( bits != NULL )
968 *bits = psa_get_key_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100969 return( PSA_SUCCESS );
970}
971
Darryl Greendd8fb772018-11-07 16:00:44 +0000972static psa_status_t psa_internal_export_key( key_slot_t *slot,
Gilles Peskine2d277862018-06-18 15:41:12 +0200973 uint8_t *data,
974 size_t data_size,
975 size_t *data_length,
976 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100977{
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100978 *data_length = 0;
979
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200980 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300981 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300982
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200983 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100984 {
985 if( slot->data.raw.bytes > data_size )
986 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine52b90182018-10-29 19:26:27 +0100987 if( data_size != 0 )
988 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200989 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine52b90182018-10-29 19:26:27 +0100990 memset( data + slot->data.raw.bytes, 0,
991 data_size - slot->data.raw.bytes );
992 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100993 *data_length = slot->data.raw.bytes;
994 return( PSA_SUCCESS );
995 }
Gilles Peskine188c71e2018-10-29 19:26:02 +0100996#if defined(MBEDTLS_ECP_C)
997 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) && !export_public_key )
998 {
Darryl Greendd8fb772018-11-07 16:00:44 +0000999 psa_status_t status;
1000
Gilles Peskine188c71e2018-10-29 19:26:02 +01001001 size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( slot ) );
1002 if( bytes > data_size )
1003 return( PSA_ERROR_BUFFER_TOO_SMALL );
1004 status = mbedtls_to_psa_error(
1005 mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
1006 if( status != PSA_SUCCESS )
1007 return( status );
1008 memset( data + bytes, 0, data_size - bytes );
1009 *data_length = bytes;
1010 return( PSA_SUCCESS );
1011 }
1012#endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001013 else
Moran Peker17e36e12018-05-02 12:55:20 +03001014 {
Gilles Peskine969ac722018-01-28 18:16:59 +01001015#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02001016 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
Moran Pekera998bc62018-04-16 18:16:20 +03001017 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +01001018 {
Moran Pekera998bc62018-04-16 18:16:20 +03001019 mbedtls_pk_context pk;
1020 int ret;
Gilles Peskined8008d62018-06-29 19:51:51 +02001021 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001022 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001023#if defined(MBEDTLS_RSA_C)
1024 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001025 pk.pk_info = &mbedtls_rsa_info;
1026 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001027#else
1028 return( PSA_ERROR_NOT_SUPPORTED );
1029#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001030 }
1031 else
1032 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001033#if defined(MBEDTLS_ECP_C)
1034 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001035 pk.pk_info = &mbedtls_eckey_info;
1036 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001037#else
1038 return( PSA_ERROR_NOT_SUPPORTED );
1039#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001040 }
Moran Pekerd7326592018-05-29 16:56:39 +03001041 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001042 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +03001043 else
1044 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +03001045 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001046 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001047 /* If data_size is 0 then data may be NULL and then the
1048 * call to memset would have undefined behavior. */
1049 if( data_size != 0 )
1050 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +03001051 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001052 }
Gilles Peskine0e231582018-06-20 00:11:07 +02001053 /* The mbedtls_pk_xxx functions write to the end of the buffer.
1054 * Move the data to the beginning and erase remaining data
1055 * at the original location. */
1056 if( 2 * (size_t) ret <= data_size )
1057 {
1058 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001059 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001060 }
1061 else if( (size_t) ret < data_size )
1062 {
1063 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001064 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001065 }
Moran Pekera998bc62018-04-16 18:16:20 +03001066 *data_length = ret;
1067 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +01001068 }
1069 else
Gilles Peskine6d912132018-03-07 16:41:37 +01001070#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +03001071 {
1072 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +02001073 it is valid for a special-purpose implementation to omit
1074 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +03001075 return( PSA_ERROR_NOT_SUPPORTED );
1076 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001077 }
1078}
1079
Gilles Peskine2d277862018-06-18 15:41:12 +02001080psa_status_t psa_export_key( psa_key_slot_t key,
1081 uint8_t *data,
1082 size_t data_size,
1083 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001084{
Darryl Greendd8fb772018-11-07 16:00:44 +00001085 key_slot_t *slot;
1086 psa_status_t status;
1087
1088 /* Set the key to empty now, so that even when there are errors, we always
1089 * set data_length to a value between 0 and data_size. On error, setting
1090 * the key to empty is a good choice because an empty key representation is
1091 * unlikely to be accepted anywhere. */
1092 *data_length = 0;
1093
1094 /* Export requires the EXPORT flag. There is an exception for public keys,
1095 * which don't require any flag, but psa_get_key_from_slot takes
1096 * care of this. */
1097 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_EXPORT, 0 );
1098 if( status != PSA_SUCCESS )
1099 return( status );
1100 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001101 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001102}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001103
Gilles Peskine2d277862018-06-18 15:41:12 +02001104psa_status_t psa_export_public_key( psa_key_slot_t key,
1105 uint8_t *data,
1106 size_t data_size,
1107 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001108{
Darryl Greendd8fb772018-11-07 16:00:44 +00001109 key_slot_t *slot;
1110 psa_status_t status;
1111
1112 /* Set the key to empty now, so that even when there are errors, we always
1113 * set data_length to a value between 0 and data_size. On error, setting
1114 * the key to empty is a good choice because an empty key representation is
1115 * unlikely to be accepted anywhere. */
1116 *data_length = 0;
1117
1118 /* Exporting a public key doesn't require a usage flag. */
1119 status = psa_get_key_from_slot( key, &slot, 0, 0 );
1120 if( status != PSA_SUCCESS )
1121 return( status );
1122 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001123 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001124}
1125
Darryl Green0c6575a2018-11-07 16:05:30 +00001126#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine69f976b2018-11-30 18:46:56 +01001127static psa_status_t psa_save_generated_persistent_key( key_slot_t *slot,
Darryl Green0c6575a2018-11-07 16:05:30 +00001128 size_t bits )
1129{
1130 psa_status_t status;
1131 uint8_t *data;
1132 size_t key_length;
1133 size_t data_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type, bits );
1134 data = mbedtls_calloc( 1, data_size );
itayzafrir910c76b2018-11-21 16:03:21 +02001135 if( data == NULL )
1136 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Darryl Green0c6575a2018-11-07 16:05:30 +00001137 /* Get key data in export format */
1138 status = psa_internal_export_key( slot, data, data_size, &key_length, 0 );
1139 if( status != PSA_SUCCESS )
1140 {
1141 slot->type = PSA_KEY_TYPE_NONE;
1142 goto exit;
1143 }
1144 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +01001145 status = psa_save_persistent_key( slot->persistent_storage_id,
1146 slot->type, &slot->policy,
Darryl Green0c6575a2018-11-07 16:05:30 +00001147 data, key_length );
1148 if( status != PSA_SUCCESS )
1149 {
1150 slot->type = PSA_KEY_TYPE_NONE;
1151 }
1152exit:
1153 mbedtls_zeroize( data, key_length );
1154 mbedtls_free( data );
1155 return( status );
1156}
1157#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1158
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001159
1160
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001161/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01001162/* Message digests */
1163/****************************************************************/
1164
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001165static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01001166{
1167 switch( alg )
1168 {
1169#if defined(MBEDTLS_MD2_C)
1170 case PSA_ALG_MD2:
1171 return( &mbedtls_md2_info );
1172#endif
1173#if defined(MBEDTLS_MD4_C)
1174 case PSA_ALG_MD4:
1175 return( &mbedtls_md4_info );
1176#endif
1177#if defined(MBEDTLS_MD5_C)
1178 case PSA_ALG_MD5:
1179 return( &mbedtls_md5_info );
1180#endif
1181#if defined(MBEDTLS_RIPEMD160_C)
1182 case PSA_ALG_RIPEMD160:
1183 return( &mbedtls_ripemd160_info );
1184#endif
1185#if defined(MBEDTLS_SHA1_C)
1186 case PSA_ALG_SHA_1:
1187 return( &mbedtls_sha1_info );
1188#endif
1189#if defined(MBEDTLS_SHA256_C)
1190 case PSA_ALG_SHA_224:
1191 return( &mbedtls_sha224_info );
1192 case PSA_ALG_SHA_256:
1193 return( &mbedtls_sha256_info );
1194#endif
1195#if defined(MBEDTLS_SHA512_C)
1196 case PSA_ALG_SHA_384:
1197 return( &mbedtls_sha384_info );
1198 case PSA_ALG_SHA_512:
1199 return( &mbedtls_sha512_info );
1200#endif
1201 default:
1202 return( NULL );
1203 }
1204}
1205
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001206psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
1207{
1208 switch( operation->alg )
1209 {
Gilles Peskine81736312018-06-26 15:04:31 +02001210 case 0:
1211 /* The object has (apparently) been initialized but it is not
1212 * in use. It's ok to call abort on such an object, and there's
1213 * nothing to do. */
1214 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001215#if defined(MBEDTLS_MD2_C)
1216 case PSA_ALG_MD2:
1217 mbedtls_md2_free( &operation->ctx.md2 );
1218 break;
1219#endif
1220#if defined(MBEDTLS_MD4_C)
1221 case PSA_ALG_MD4:
1222 mbedtls_md4_free( &operation->ctx.md4 );
1223 break;
1224#endif
1225#if defined(MBEDTLS_MD5_C)
1226 case PSA_ALG_MD5:
1227 mbedtls_md5_free( &operation->ctx.md5 );
1228 break;
1229#endif
1230#if defined(MBEDTLS_RIPEMD160_C)
1231 case PSA_ALG_RIPEMD160:
1232 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
1233 break;
1234#endif
1235#if defined(MBEDTLS_SHA1_C)
1236 case PSA_ALG_SHA_1:
1237 mbedtls_sha1_free( &operation->ctx.sha1 );
1238 break;
1239#endif
1240#if defined(MBEDTLS_SHA256_C)
1241 case PSA_ALG_SHA_224:
1242 case PSA_ALG_SHA_256:
1243 mbedtls_sha256_free( &operation->ctx.sha256 );
1244 break;
1245#endif
1246#if defined(MBEDTLS_SHA512_C)
1247 case PSA_ALG_SHA_384:
1248 case PSA_ALG_SHA_512:
1249 mbedtls_sha512_free( &operation->ctx.sha512 );
1250 break;
1251#endif
1252 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001253 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001254 }
1255 operation->alg = 0;
1256 return( PSA_SUCCESS );
1257}
1258
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02001259psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001260 psa_algorithm_t alg )
1261{
1262 int ret;
1263 operation->alg = 0;
1264 switch( alg )
1265 {
1266#if defined(MBEDTLS_MD2_C)
1267 case PSA_ALG_MD2:
1268 mbedtls_md2_init( &operation->ctx.md2 );
1269 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
1270 break;
1271#endif
1272#if defined(MBEDTLS_MD4_C)
1273 case PSA_ALG_MD4:
1274 mbedtls_md4_init( &operation->ctx.md4 );
1275 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
1276 break;
1277#endif
1278#if defined(MBEDTLS_MD5_C)
1279 case PSA_ALG_MD5:
1280 mbedtls_md5_init( &operation->ctx.md5 );
1281 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
1282 break;
1283#endif
1284#if defined(MBEDTLS_RIPEMD160_C)
1285 case PSA_ALG_RIPEMD160:
1286 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
1287 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
1288 break;
1289#endif
1290#if defined(MBEDTLS_SHA1_C)
1291 case PSA_ALG_SHA_1:
1292 mbedtls_sha1_init( &operation->ctx.sha1 );
1293 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
1294 break;
1295#endif
1296#if defined(MBEDTLS_SHA256_C)
1297 case PSA_ALG_SHA_224:
1298 mbedtls_sha256_init( &operation->ctx.sha256 );
1299 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
1300 break;
1301 case PSA_ALG_SHA_256:
1302 mbedtls_sha256_init( &operation->ctx.sha256 );
1303 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
1304 break;
1305#endif
1306#if defined(MBEDTLS_SHA512_C)
1307 case PSA_ALG_SHA_384:
1308 mbedtls_sha512_init( &operation->ctx.sha512 );
1309 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
1310 break;
1311 case PSA_ALG_SHA_512:
1312 mbedtls_sha512_init( &operation->ctx.sha512 );
1313 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1314 break;
1315#endif
1316 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001317 return( PSA_ALG_IS_HASH( alg ) ?
1318 PSA_ERROR_NOT_SUPPORTED :
1319 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001320 }
1321 if( ret == 0 )
1322 operation->alg = alg;
1323 else
1324 psa_hash_abort( operation );
1325 return( mbedtls_to_psa_error( ret ) );
1326}
1327
1328psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1329 const uint8_t *input,
1330 size_t input_length )
1331{
1332 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001333
1334 /* Don't require hash implementations to behave correctly on a
1335 * zero-length input, which may have an invalid pointer. */
1336 if( input_length == 0 )
1337 return( PSA_SUCCESS );
1338
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001339 switch( operation->alg )
1340 {
1341#if defined(MBEDTLS_MD2_C)
1342 case PSA_ALG_MD2:
1343 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1344 input, input_length );
1345 break;
1346#endif
1347#if defined(MBEDTLS_MD4_C)
1348 case PSA_ALG_MD4:
1349 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1350 input, input_length );
1351 break;
1352#endif
1353#if defined(MBEDTLS_MD5_C)
1354 case PSA_ALG_MD5:
1355 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1356 input, input_length );
1357 break;
1358#endif
1359#if defined(MBEDTLS_RIPEMD160_C)
1360 case PSA_ALG_RIPEMD160:
1361 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1362 input, input_length );
1363 break;
1364#endif
1365#if defined(MBEDTLS_SHA1_C)
1366 case PSA_ALG_SHA_1:
1367 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1368 input, input_length );
1369 break;
1370#endif
1371#if defined(MBEDTLS_SHA256_C)
1372 case PSA_ALG_SHA_224:
1373 case PSA_ALG_SHA_256:
1374 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1375 input, input_length );
1376 break;
1377#endif
1378#if defined(MBEDTLS_SHA512_C)
1379 case PSA_ALG_SHA_384:
1380 case PSA_ALG_SHA_512:
1381 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1382 input, input_length );
1383 break;
1384#endif
1385 default:
1386 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1387 break;
1388 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001389
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001390 if( ret != 0 )
1391 psa_hash_abort( operation );
1392 return( mbedtls_to_psa_error( ret ) );
1393}
1394
1395psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1396 uint8_t *hash,
1397 size_t hash_size,
1398 size_t *hash_length )
1399{
itayzafrir40835d42018-08-02 13:14:17 +03001400 psa_status_t status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001401 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001402 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001403
1404 /* Fill the output buffer with something that isn't a valid hash
1405 * (barring an attack on the hash and deliberately-crafted input),
1406 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001407 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001408 /* If hash_size is 0 then hash may be NULL and then the
1409 * call to memset would have undefined behavior. */
1410 if( hash_size != 0 )
1411 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001412
1413 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03001414 {
1415 status = PSA_ERROR_BUFFER_TOO_SMALL;
1416 goto exit;
1417 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001418
1419 switch( operation->alg )
1420 {
1421#if defined(MBEDTLS_MD2_C)
1422 case PSA_ALG_MD2:
1423 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1424 break;
1425#endif
1426#if defined(MBEDTLS_MD4_C)
1427 case PSA_ALG_MD4:
1428 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1429 break;
1430#endif
1431#if defined(MBEDTLS_MD5_C)
1432 case PSA_ALG_MD5:
1433 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1434 break;
1435#endif
1436#if defined(MBEDTLS_RIPEMD160_C)
1437 case PSA_ALG_RIPEMD160:
1438 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1439 break;
1440#endif
1441#if defined(MBEDTLS_SHA1_C)
1442 case PSA_ALG_SHA_1:
1443 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1444 break;
1445#endif
1446#if defined(MBEDTLS_SHA256_C)
1447 case PSA_ALG_SHA_224:
1448 case PSA_ALG_SHA_256:
1449 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1450 break;
1451#endif
1452#if defined(MBEDTLS_SHA512_C)
1453 case PSA_ALG_SHA_384:
1454 case PSA_ALG_SHA_512:
1455 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1456 break;
1457#endif
1458 default:
1459 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1460 break;
1461 }
itayzafrir40835d42018-08-02 13:14:17 +03001462 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001463
itayzafrir40835d42018-08-02 13:14:17 +03001464exit:
1465 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001466 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001467 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001468 return( psa_hash_abort( operation ) );
1469 }
1470 else
1471 {
1472 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03001473 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001474 }
1475}
1476
Gilles Peskine2d277862018-06-18 15:41:12 +02001477psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1478 const uint8_t *hash,
1479 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001480{
1481 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1482 size_t actual_hash_length;
1483 psa_status_t status = psa_hash_finish( operation,
1484 actual_hash, sizeof( actual_hash ),
1485 &actual_hash_length );
1486 if( status != PSA_SUCCESS )
1487 return( status );
1488 if( actual_hash_length != hash_length )
1489 return( PSA_ERROR_INVALID_SIGNATURE );
1490 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1491 return( PSA_ERROR_INVALID_SIGNATURE );
1492 return( PSA_SUCCESS );
1493}
1494
1495
1496
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001497/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001498/* MAC */
1499/****************************************************************/
1500
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001501static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001502 psa_algorithm_t alg,
1503 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001504 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001505 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001506{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001507 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001508 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001509
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001510 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001511 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001512
Gilles Peskine8c9def32018-02-08 10:02:12 +01001513 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1514 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001515 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001516 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001517 case PSA_ALG_ARC4:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001518 mode = MBEDTLS_MODE_STREAM;
1519 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001520 case PSA_ALG_CTR:
1521 mode = MBEDTLS_MODE_CTR;
1522 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001523 case PSA_ALG_CFB:
1524 mode = MBEDTLS_MODE_CFB;
1525 break;
1526 case PSA_ALG_OFB:
1527 mode = MBEDTLS_MODE_OFB;
1528 break;
1529 case PSA_ALG_CBC_NO_PADDING:
1530 mode = MBEDTLS_MODE_CBC;
1531 break;
1532 case PSA_ALG_CBC_PKCS7:
1533 mode = MBEDTLS_MODE_CBC;
1534 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001535 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001536 mode = MBEDTLS_MODE_CCM;
1537 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001538 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001539 mode = MBEDTLS_MODE_GCM;
1540 break;
1541 default:
1542 return( NULL );
1543 }
1544 }
1545 else if( alg == PSA_ALG_CMAC )
1546 mode = MBEDTLS_MODE_ECB;
1547 else if( alg == PSA_ALG_GMAC )
1548 mode = MBEDTLS_MODE_GCM;
1549 else
1550 return( NULL );
1551
1552 switch( key_type )
1553 {
1554 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001555 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001556 break;
1557 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001558 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1559 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001560 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001561 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001562 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001563 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001564 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1565 * but two-key Triple-DES is functionally three-key Triple-DES
1566 * with K1=K3, so that's how we present it to mbedtls. */
1567 if( key_bits == 128 )
1568 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001569 break;
1570 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001571 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001572 break;
1573 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001574 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001575 break;
1576 default:
1577 return( NULL );
1578 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001579 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001580 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001581
Jaeden Amero23bbb752018-06-26 14:16:54 +01001582 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1583 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001584}
1585
Gilles Peskinea05219c2018-11-16 16:02:56 +01001586#if defined(MBEDTLS_MD_C)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001587static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001588{
Gilles Peskine2d277862018-06-18 15:41:12 +02001589 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001590 {
1591 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001592 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001593 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001594 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001595 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001596 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001597 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001598 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001599 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001600 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001601 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001602 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001603 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001604 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001605 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001606 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001607 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001608 return( 128 );
1609 default:
1610 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001611 }
1612}
Gilles Peskinea05219c2018-11-16 16:02:56 +01001613#endif /* MBEDTLS_MD_C */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001614
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001615/* Initialize the MAC operation structure. Once this function has been
1616 * called, psa_mac_abort can run and will do the right thing. */
1617static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1618 psa_algorithm_t alg )
1619{
1620 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1621
1622 operation->alg = alg;
1623 operation->key_set = 0;
1624 operation->iv_set = 0;
1625 operation->iv_required = 0;
1626 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001627 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001628
1629#if defined(MBEDTLS_CMAC_C)
1630 if( alg == PSA_ALG_CMAC )
1631 {
1632 operation->iv_required = 0;
1633 mbedtls_cipher_init( &operation->ctx.cmac );
1634 status = PSA_SUCCESS;
1635 }
1636 else
1637#endif /* MBEDTLS_CMAC_C */
1638#if defined(MBEDTLS_MD_C)
1639 if( PSA_ALG_IS_HMAC( operation->alg ) )
1640 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02001641 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
1642 operation->ctx.hmac.hash_ctx.alg = 0;
1643 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001644 }
1645 else
1646#endif /* MBEDTLS_MD_C */
1647 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001648 if( ! PSA_ALG_IS_MAC( alg ) )
1649 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001650 }
1651
1652 if( status != PSA_SUCCESS )
1653 memset( operation, 0, sizeof( *operation ) );
1654 return( status );
1655}
1656
Gilles Peskine01126fa2018-07-12 17:04:55 +02001657#if defined(MBEDTLS_MD_C)
1658static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
1659{
1660 mbedtls_zeroize( hmac->opad, sizeof( hmac->opad ) );
1661 return( psa_hash_abort( &hmac->hash_ctx ) );
1662}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01001663
1664static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
1665{
1666 /* Instances of psa_hash_operation_s can be initialized by zeroization. */
1667 memset( hmac, 0, sizeof( *hmac ) );
1668}
Gilles Peskine01126fa2018-07-12 17:04:55 +02001669#endif /* MBEDTLS_MD_C */
1670
Gilles Peskine8c9def32018-02-08 10:02:12 +01001671psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1672{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001673 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001674 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001675 /* The object has (apparently) been initialized but it is not
1676 * in use. It's ok to call abort on such an object, and there's
1677 * nothing to do. */
1678 return( PSA_SUCCESS );
1679 }
1680 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001681#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001682 if( operation->alg == PSA_ALG_CMAC )
1683 {
1684 mbedtls_cipher_free( &operation->ctx.cmac );
1685 }
1686 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001687#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001688#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001689 if( PSA_ALG_IS_HMAC( operation->alg ) )
1690 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001691 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001692 }
1693 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001694#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001695 {
1696 /* Sanity check (shouldn't happen: operation->alg should
1697 * always have been initialized to a valid value). */
1698 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001699 }
Moran Peker41deec42018-04-04 15:43:05 +03001700
Gilles Peskine8c9def32018-02-08 10:02:12 +01001701 operation->alg = 0;
1702 operation->key_set = 0;
1703 operation->iv_set = 0;
1704 operation->iv_required = 0;
1705 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001706 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001707
Gilles Peskine8c9def32018-02-08 10:02:12 +01001708 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001709
1710bad_state:
1711 /* If abort is called on an uninitialized object, we can't trust
1712 * anything. Wipe the object in case it contains confidential data.
1713 * This may result in a memory leak if a pointer gets overwritten,
1714 * but it's too late to do anything about this. */
1715 memset( operation, 0, sizeof( *operation ) );
1716 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001717}
1718
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001719#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02001720static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001721 size_t key_bits,
1722 key_slot_t *slot,
1723 const mbedtls_cipher_info_t *cipher_info )
1724{
1725 int ret;
1726
1727 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001728
1729 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1730 if( ret != 0 )
1731 return( ret );
1732
1733 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1734 slot->data.raw.data,
1735 key_bits );
1736 return( ret );
1737}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001738#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001739
Gilles Peskine248051a2018-06-20 16:09:38 +02001740#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02001741static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
1742 const uint8_t *key,
1743 size_t key_length,
1744 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001745{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001746 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001747 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001748 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001749 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001750 psa_status_t status;
1751
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001752 /* Sanity checks on block_size, to guarantee that there won't be a buffer
1753 * overflow below. This should never trigger if the hash algorithm
1754 * is implemented correctly. */
1755 /* The size checks against the ipad and opad buffers cannot be written
1756 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
1757 * because that triggers -Wlogical-op on GCC 7.3. */
1758 if( block_size > sizeof( ipad ) )
1759 return( PSA_ERROR_NOT_SUPPORTED );
1760 if( block_size > sizeof( hmac->opad ) )
1761 return( PSA_ERROR_NOT_SUPPORTED );
1762 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001763 return( PSA_ERROR_NOT_SUPPORTED );
1764
Gilles Peskined223b522018-06-11 18:12:58 +02001765 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001766 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001767 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001768 if( status != PSA_SUCCESS )
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001769 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001770 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001771 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001772 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001773 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001774 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001775 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001776 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001777 }
Gilles Peskine96889972018-07-12 17:07:03 +02001778 /* A 0-length key is not commonly used in HMAC when used as a MAC,
1779 * but it is permitted. It is common when HMAC is used in HKDF, for
1780 * example. Don't call `memcpy` in the 0-length because `key` could be
1781 * an invalid pointer which would make the behavior undefined. */
1782 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001783 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001784
Gilles Peskined223b522018-06-11 18:12:58 +02001785 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1786 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001787 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001788 ipad[i] ^= 0x36;
1789 memset( ipad + key_length, 0x36, block_size - key_length );
1790
1791 /* Copy the key material from ipad to opad, flipping the requisite bits,
1792 * and filling the rest of opad with the requisite constant. */
1793 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001794 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1795 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001796
Gilles Peskine01126fa2018-07-12 17:04:55 +02001797 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001798 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001799 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001800
Gilles Peskine01126fa2018-07-12 17:04:55 +02001801 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001802
1803cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001804 mbedtls_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001805
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001806 return( status );
1807}
Gilles Peskine248051a2018-06-20 16:09:38 +02001808#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001809
Gilles Peskine89167cb2018-07-08 20:12:23 +02001810static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
1811 psa_key_slot_t key,
1812 psa_algorithm_t alg,
1813 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001814{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001815 psa_status_t status;
1816 key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001817 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001818 psa_key_usage_t usage =
1819 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskined911eb72018-08-14 15:18:45 +02001820 unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02001821 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001822
Gilles Peskined911eb72018-08-14 15:18:45 +02001823 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001824 if( status != PSA_SUCCESS )
1825 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001826 if( is_sign )
1827 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001828
Gilles Peskine89167cb2018-07-08 20:12:23 +02001829 status = psa_get_key_from_slot( key, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001830 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001831 goto exit;
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02001832 key_bits = psa_get_key_bits( slot );
1833
Gilles Peskine8c9def32018-02-08 10:02:12 +01001834#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001835 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001836 {
1837 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02001838 mbedtls_cipher_info_from_psa( full_length_alg,
1839 slot->type, key_bits, NULL );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001840 int ret;
1841 if( cipher_info == NULL )
1842 {
1843 status = PSA_ERROR_NOT_SUPPORTED;
1844 goto exit;
1845 }
1846 operation->mac_size = cipher_info->block_size;
1847 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
1848 status = mbedtls_to_psa_error( ret );
1849 }
1850 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001851#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001852#if defined(MBEDTLS_MD_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001853 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001854 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02001855 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001856 if( hash_alg == 0 )
1857 {
1858 status = PSA_ERROR_NOT_SUPPORTED;
1859 goto exit;
1860 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001861
1862 operation->mac_size = PSA_HASH_SIZE( hash_alg );
1863 /* Sanity check. This shouldn't fail on a valid configuration. */
1864 if( operation->mac_size == 0 ||
1865 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
1866 {
1867 status = PSA_ERROR_NOT_SUPPORTED;
1868 goto exit;
1869 }
1870
Gilles Peskine01126fa2018-07-12 17:04:55 +02001871 if( slot->type != PSA_KEY_TYPE_HMAC )
1872 {
1873 status = PSA_ERROR_INVALID_ARGUMENT;
1874 goto exit;
1875 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001876
Gilles Peskine01126fa2018-07-12 17:04:55 +02001877 status = psa_hmac_setup_internal( &operation->ctx.hmac,
1878 slot->data.raw.data,
1879 slot->data.raw.bytes,
1880 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001881 }
1882 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001883#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001884 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00001885 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02001886 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001887 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001888
Gilles Peskined911eb72018-08-14 15:18:45 +02001889 if( truncated == 0 )
1890 {
1891 /* The "normal" case: untruncated algorithm. Nothing to do. */
1892 }
1893 else if( truncated < 4 )
1894 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02001895 /* A very short MAC is too short for security since it can be
1896 * brute-forced. Ancient protocols with 32-bit MACs do exist,
1897 * so we make this our minimum, even though 32 bits is still
1898 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02001899 status = PSA_ERROR_NOT_SUPPORTED;
1900 }
1901 else if( truncated > operation->mac_size )
1902 {
1903 /* It's impossible to "truncate" to a larger length. */
1904 status = PSA_ERROR_INVALID_ARGUMENT;
1905 }
1906 else
1907 operation->mac_size = truncated;
1908
Gilles Peskinefbfac682018-07-08 20:51:54 +02001909exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001910 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001911 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001912 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001913 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001914 else
1915 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001916 operation->key_set = 1;
1917 }
1918 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001919}
1920
Gilles Peskine89167cb2018-07-08 20:12:23 +02001921psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
1922 psa_key_slot_t key,
1923 psa_algorithm_t alg )
1924{
1925 return( psa_mac_setup( operation, key, alg, 1 ) );
1926}
1927
1928psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
1929 psa_key_slot_t key,
1930 psa_algorithm_t alg )
1931{
1932 return( psa_mac_setup( operation, key, alg, 0 ) );
1933}
1934
Gilles Peskine8c9def32018-02-08 10:02:12 +01001935psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1936 const uint8_t *input,
1937 size_t input_length )
1938{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001939 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001940 if( ! operation->key_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001941 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001942 if( operation->iv_required && ! operation->iv_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001943 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001944 operation->has_input = 1;
1945
Gilles Peskine8c9def32018-02-08 10:02:12 +01001946#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001947 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001948 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001949 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1950 input, input_length );
1951 status = mbedtls_to_psa_error( ret );
1952 }
1953 else
1954#endif /* MBEDTLS_CMAC_C */
1955#if defined(MBEDTLS_MD_C)
1956 if( PSA_ALG_IS_HMAC( operation->alg ) )
1957 {
1958 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
1959 input_length );
1960 }
1961 else
1962#endif /* MBEDTLS_MD_C */
1963 {
1964 /* This shouldn't happen if `operation` was initialized by
1965 * a setup function. */
1966 status = PSA_ERROR_BAD_STATE;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001967 }
1968
Gilles Peskinefbfac682018-07-08 20:51:54 +02001969cleanup:
1970 if( status != PSA_SUCCESS )
1971 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001972 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001973}
1974
Gilles Peskine01126fa2018-07-12 17:04:55 +02001975#if defined(MBEDTLS_MD_C)
1976static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
1977 uint8_t *mac,
1978 size_t mac_size )
1979{
1980 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
1981 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
1982 size_t hash_size = 0;
1983 size_t block_size = psa_get_hash_block_size( hash_alg );
1984 psa_status_t status;
1985
Gilles Peskine01126fa2018-07-12 17:04:55 +02001986 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1987 if( status != PSA_SUCCESS )
1988 return( status );
1989 /* From here on, tmp needs to be wiped. */
1990
1991 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
1992 if( status != PSA_SUCCESS )
1993 goto exit;
1994
1995 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
1996 if( status != PSA_SUCCESS )
1997 goto exit;
1998
1999 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
2000 if( status != PSA_SUCCESS )
2001 goto exit;
2002
Gilles Peskined911eb72018-08-14 15:18:45 +02002003 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
2004 if( status != PSA_SUCCESS )
2005 goto exit;
2006
2007 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002008
2009exit:
2010 mbedtls_zeroize( tmp, hash_size );
2011 return( status );
2012}
2013#endif /* MBEDTLS_MD_C */
2014
mohammad16036df908f2018-04-02 08:34:15 -07002015static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02002016 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002017 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002018{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02002019 if( ! operation->key_set )
2020 return( PSA_ERROR_BAD_STATE );
2021 if( operation->iv_required && ! operation->iv_set )
2022 return( PSA_ERROR_BAD_STATE );
2023
Gilles Peskine8c9def32018-02-08 10:02:12 +01002024 if( mac_size < operation->mac_size )
2025 return( PSA_ERROR_BUFFER_TOO_SMALL );
2026
Gilles Peskine8c9def32018-02-08 10:02:12 +01002027#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002028 if( operation->alg == PSA_ALG_CMAC )
2029 {
Gilles Peskined911eb72018-08-14 15:18:45 +02002030 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
2031 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
2032 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02002033 memcpy( mac, tmp, operation->mac_size );
Gilles Peskined911eb72018-08-14 15:18:45 +02002034 mbedtls_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002035 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002036 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02002037 else
2038#endif /* MBEDTLS_CMAC_C */
2039#if defined(MBEDTLS_MD_C)
2040 if( PSA_ALG_IS_HMAC( operation->alg ) )
2041 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002042 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02002043 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002044 }
2045 else
2046#endif /* MBEDTLS_MD_C */
2047 {
2048 /* This shouldn't happen if `operation` was initialized by
2049 * a setup function. */
2050 return( PSA_ERROR_BAD_STATE );
2051 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01002052}
2053
Gilles Peskineacd4be32018-07-08 19:56:25 +02002054psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
2055 uint8_t *mac,
2056 size_t mac_size,
2057 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07002058{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002059 psa_status_t status;
2060
2061 /* Fill the output buffer with something that isn't a valid mac
2062 * (barring an attack on the mac and deliberately-crafted input),
2063 * in case the caller doesn't check the return status properly. */
2064 *mac_length = mac_size;
2065 /* If mac_size is 0 then mac may be NULL and then the
2066 * call to memset would have undefined behavior. */
2067 if( mac_size != 0 )
2068 memset( mac, '!', mac_size );
2069
Gilles Peskine89167cb2018-07-08 20:12:23 +02002070 if( ! operation->is_sign )
2071 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002072 status = PSA_ERROR_BAD_STATE;
2073 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002074 }
mohammad16036df908f2018-04-02 08:34:15 -07002075
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002076 status = psa_mac_finish_internal( operation, mac, mac_size );
2077
2078cleanup:
2079 if( status == PSA_SUCCESS )
2080 {
2081 status = psa_mac_abort( operation );
2082 if( status == PSA_SUCCESS )
2083 *mac_length = operation->mac_size;
2084 else
2085 memset( mac, '!', mac_size );
2086 }
2087 else
2088 psa_mac_abort( operation );
2089 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07002090}
2091
Gilles Peskineacd4be32018-07-08 19:56:25 +02002092psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
2093 const uint8_t *mac,
2094 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002095{
Gilles Peskine828ed142018-06-18 23:25:51 +02002096 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07002097 psa_status_t status;
2098
Gilles Peskine89167cb2018-07-08 20:12:23 +02002099 if( operation->is_sign )
2100 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002101 status = PSA_ERROR_BAD_STATE;
2102 goto cleanup;
2103 }
2104 if( operation->mac_size != mac_length )
2105 {
2106 status = PSA_ERROR_INVALID_SIGNATURE;
2107 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002108 }
mohammad16036df908f2018-04-02 08:34:15 -07002109
2110 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002111 actual_mac, sizeof( actual_mac ) );
2112
2113 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
2114 status = PSA_ERROR_INVALID_SIGNATURE;
2115
2116cleanup:
2117 if( status == PSA_SUCCESS )
2118 status = psa_mac_abort( operation );
2119 else
2120 psa_mac_abort( operation );
2121
Gilles Peskine99b7d6b2018-08-21 14:56:19 +02002122 mbedtls_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02002123
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002124 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002125}
2126
2127
Gilles Peskine20035e32018-02-03 22:44:14 +01002128
Gilles Peskine20035e32018-02-03 22:44:14 +01002129/****************************************************************/
2130/* Asymmetric cryptography */
2131/****************************************************************/
2132
Gilles Peskine2b450e32018-06-27 15:42:46 +02002133#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002134/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002135 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002136static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
2137 size_t hash_length,
2138 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002139{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02002140 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002141 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002142 *md_alg = mbedtls_md_get_type( md_info );
2143
2144 /* The Mbed TLS RSA module uses an unsigned int for hash length
2145 * parameters. Validate that it fits so that we don't risk an
2146 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002147#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002148 if( hash_length > UINT_MAX )
2149 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002150#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002151
2152#if defined(MBEDTLS_PKCS1_V15)
2153 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
2154 * must be correct. */
2155 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
2156 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002157 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002158 if( md_info == NULL )
2159 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002160 if( mbedtls_md_get_size( md_info ) != hash_length )
2161 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002162 }
2163#endif /* MBEDTLS_PKCS1_V15 */
2164
2165#if defined(MBEDTLS_PKCS1_V21)
2166 /* PSS requires a hash internally. */
2167 if( PSA_ALG_IS_RSA_PSS( alg ) )
2168 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002169 if( md_info == NULL )
2170 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002171 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002172#endif /* MBEDTLS_PKCS1_V21 */
2173
Gilles Peskine61b91d42018-06-08 16:09:36 +02002174 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002175}
2176
Gilles Peskine2b450e32018-06-27 15:42:46 +02002177static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
2178 psa_algorithm_t alg,
2179 const uint8_t *hash,
2180 size_t hash_length,
2181 uint8_t *signature,
2182 size_t signature_size,
2183 size_t *signature_length )
2184{
2185 psa_status_t status;
2186 int ret;
2187 mbedtls_md_type_t md_alg;
2188
2189 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2190 if( status != PSA_SUCCESS )
2191 return( status );
2192
Gilles Peskine630a18a2018-06-29 17:49:35 +02002193 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002194 return( PSA_ERROR_BUFFER_TOO_SMALL );
2195
2196#if defined(MBEDTLS_PKCS1_V15)
2197 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2198 {
2199 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2200 MBEDTLS_MD_NONE );
2201 ret = mbedtls_rsa_pkcs1_sign( rsa,
2202 mbedtls_ctr_drbg_random,
2203 &global_data.ctr_drbg,
2204 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002205 md_alg,
2206 (unsigned int) hash_length,
2207 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002208 signature );
2209 }
2210 else
2211#endif /* MBEDTLS_PKCS1_V15 */
2212#if defined(MBEDTLS_PKCS1_V21)
2213 if( PSA_ALG_IS_RSA_PSS( alg ) )
2214 {
2215 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2216 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
2217 mbedtls_ctr_drbg_random,
2218 &global_data.ctr_drbg,
2219 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002220 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002221 (unsigned int) hash_length,
2222 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002223 signature );
2224 }
2225 else
2226#endif /* MBEDTLS_PKCS1_V21 */
2227 {
2228 return( PSA_ERROR_INVALID_ARGUMENT );
2229 }
2230
2231 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002232 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002233 return( mbedtls_to_psa_error( ret ) );
2234}
2235
2236static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
2237 psa_algorithm_t alg,
2238 const uint8_t *hash,
2239 size_t hash_length,
2240 const uint8_t *signature,
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_length < 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_verify( rsa,
2260 mbedtls_ctr_drbg_random,
2261 &global_data.ctr_drbg,
2262 MBEDTLS_RSA_PUBLIC,
2263 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002264 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002265 hash,
2266 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_verify( rsa,
2275 mbedtls_ctr_drbg_random,
2276 &global_data.ctr_drbg,
2277 MBEDTLS_RSA_PUBLIC,
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 }
Gilles Peskineef12c632018-09-13 20:37:48 +02002288
2289 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
2290 * the rest of the signature is invalid". This has little use in
2291 * practice and PSA doesn't report this distinction. */
2292 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
2293 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002294 return( mbedtls_to_psa_error( ret ) );
2295}
2296#endif /* MBEDTLS_RSA_C */
2297
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002298#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002299/* `ecp` cannot be const because `ecp->grp` needs to be non-const
2300 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
2301 * (even though these functions don't modify it). */
2302static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
2303 psa_algorithm_t alg,
2304 const uint8_t *hash,
2305 size_t hash_length,
2306 uint8_t *signature,
2307 size_t signature_size,
2308 size_t *signature_length )
2309{
2310 int ret;
2311 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002312 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002313 mbedtls_mpi_init( &r );
2314 mbedtls_mpi_init( &s );
2315
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002316 if( signature_size < 2 * curve_bytes )
2317 {
2318 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
2319 goto cleanup;
2320 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002321
Gilles Peskinea05219c2018-11-16 16:02:56 +01002322#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002323 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
2324 {
2325 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
2326 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2327 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2328 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
2329 hash, hash_length,
2330 md_alg ) );
2331 }
2332 else
Gilles Peskinea05219c2018-11-16 16:02:56 +01002333#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002334 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01002335 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002336 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
2337 hash, hash_length,
2338 mbedtls_ctr_drbg_random,
2339 &global_data.ctr_drbg ) );
2340 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002341
2342 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
2343 signature,
2344 curve_bytes ) );
2345 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
2346 signature + curve_bytes,
2347 curve_bytes ) );
2348
2349cleanup:
2350 mbedtls_mpi_free( &r );
2351 mbedtls_mpi_free( &s );
2352 if( ret == 0 )
2353 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002354 return( mbedtls_to_psa_error( ret ) );
2355}
2356
2357static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
2358 const uint8_t *hash,
2359 size_t hash_length,
2360 const uint8_t *signature,
2361 size_t signature_length )
2362{
2363 int ret;
2364 mbedtls_mpi r, s;
2365 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
2366 mbedtls_mpi_init( &r );
2367 mbedtls_mpi_init( &s );
2368
2369 if( signature_length != 2 * curve_bytes )
2370 return( PSA_ERROR_INVALID_SIGNATURE );
2371
2372 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2373 signature,
2374 curve_bytes ) );
2375 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2376 signature + curve_bytes,
2377 curve_bytes ) );
2378
2379 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2380 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002381
2382cleanup:
2383 mbedtls_mpi_free( &r );
2384 mbedtls_mpi_free( &s );
2385 return( mbedtls_to_psa_error( ret ) );
2386}
2387#endif /* MBEDTLS_ECDSA_C */
2388
Gilles Peskine61b91d42018-06-08 16:09:36 +02002389psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
2390 psa_algorithm_t alg,
2391 const uint8_t *hash,
2392 size_t hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002393 uint8_t *signature,
2394 size_t signature_size,
2395 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002396{
2397 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002398 psa_status_t status;
2399
2400 *signature_length = signature_size;
2401
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002402 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_SIGN, alg );
2403 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002404 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002405 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002406 {
2407 status = PSA_ERROR_INVALID_ARGUMENT;
2408 goto exit;
2409 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002410
Gilles Peskine20035e32018-02-03 22:44:14 +01002411#if defined(MBEDTLS_RSA_C)
2412 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2413 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002414 status = psa_rsa_sign( slot->data.rsa,
2415 alg,
2416 hash, hash_length,
2417 signature, signature_size,
2418 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002419 }
2420 else
2421#endif /* defined(MBEDTLS_RSA_C) */
2422#if defined(MBEDTLS_ECP_C)
2423 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2424 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002425#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea05219c2018-11-16 16:02:56 +01002426 if(
2427#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
2428 PSA_ALG_IS_ECDSA( alg )
2429#else
2430 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
2431#endif
2432 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002433 status = psa_ecdsa_sign( slot->data.ecp,
2434 alg,
2435 hash, hash_length,
2436 signature, signature_size,
2437 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002438 else
2439#endif /* defined(MBEDTLS_ECDSA_C) */
2440 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002441 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002442 }
itayzafrir5c753392018-05-08 11:18:38 +03002443 }
2444 else
2445#endif /* defined(MBEDTLS_ECP_C) */
2446 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002447 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002448 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002449
2450exit:
2451 /* Fill the unused part of the output buffer (the whole buffer on error,
2452 * the trailing part on success) with something that isn't a valid mac
2453 * (barring an attack on the mac and deliberately-crafted input),
2454 * in case the caller doesn't check the return status properly. */
2455 if( status == PSA_SUCCESS )
2456 memset( signature + *signature_length, '!',
2457 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002458 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002459 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002460 /* If signature_size is 0 then we have nothing to do. We must not call
2461 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002462 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002463}
2464
2465psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
2466 psa_algorithm_t alg,
2467 const uint8_t *hash,
2468 size_t hash_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002469 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002470 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002471{
2472 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002473 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002474
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002475 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_VERIFY, alg );
2476 if( status != PSA_SUCCESS )
2477 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002478
Gilles Peskine61b91d42018-06-08 16:09:36 +02002479#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002480 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002481 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002482 return( psa_rsa_verify( slot->data.rsa,
2483 alg,
2484 hash, hash_length,
2485 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002486 }
2487 else
2488#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002489#if defined(MBEDTLS_ECP_C)
2490 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2491 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002492#if defined(MBEDTLS_ECDSA_C)
2493 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002494 return( psa_ecdsa_verify( slot->data.ecp,
2495 hash, hash_length,
2496 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002497 else
2498#endif /* defined(MBEDTLS_ECDSA_C) */
2499 {
2500 return( PSA_ERROR_INVALID_ARGUMENT );
2501 }
itayzafrir5c753392018-05-08 11:18:38 +03002502 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002503 else
2504#endif /* defined(MBEDTLS_ECP_C) */
2505 {
2506 return( PSA_ERROR_NOT_SUPPORTED );
2507 }
2508}
2509
Gilles Peskine072ac562018-06-30 00:21:29 +02002510#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
2511static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
2512 mbedtls_rsa_context *rsa )
2513{
2514 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
2515 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2516 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2517 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2518}
2519#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
2520
Gilles Peskine61b91d42018-06-08 16:09:36 +02002521psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
2522 psa_algorithm_t alg,
2523 const uint8_t *input,
2524 size_t input_length,
2525 const uint8_t *salt,
2526 size_t salt_length,
2527 uint8_t *output,
2528 size_t output_size,
2529 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002530{
2531 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002532 psa_status_t status;
2533
Darryl Green5cc689a2018-07-24 15:34:10 +01002534 (void) input;
2535 (void) input_length;
2536 (void) salt;
2537 (void) output;
2538 (void) output_size;
2539
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002540 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002541
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002542 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2543 return( PSA_ERROR_INVALID_ARGUMENT );
2544
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002545 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
2546 if( status != PSA_SUCCESS )
2547 return( status );
Gilles Peskine35da9a22018-06-29 19:17:49 +02002548 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
2549 PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002550 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002551
2552#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002553 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002554 {
2555 mbedtls_rsa_context *rsa = slot->data.rsa;
2556 int ret;
Gilles Peskine630a18a2018-06-29 17:49:35 +02002557 if( output_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002558 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002559#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002560 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002561 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002562 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2563 mbedtls_ctr_drbg_random,
2564 &global_data.ctr_drbg,
2565 MBEDTLS_RSA_PUBLIC,
2566 input_length,
2567 input,
2568 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002569 }
2570 else
2571#endif /* MBEDTLS_PKCS1_V15 */
2572#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002573 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002574 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002575 psa_rsa_oaep_set_padding_mode( alg, rsa );
2576 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
2577 mbedtls_ctr_drbg_random,
2578 &global_data.ctr_drbg,
2579 MBEDTLS_RSA_PUBLIC,
2580 salt, salt_length,
2581 input_length,
2582 input,
2583 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002584 }
2585 else
2586#endif /* MBEDTLS_PKCS1_V21 */
2587 {
2588 return( PSA_ERROR_INVALID_ARGUMENT );
2589 }
2590 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002591 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002592 return( mbedtls_to_psa_error( ret ) );
2593 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002594 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002595#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002596 {
2597 return( PSA_ERROR_NOT_SUPPORTED );
2598 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002599}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002600
Gilles Peskine61b91d42018-06-08 16:09:36 +02002601psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2602 psa_algorithm_t alg,
2603 const uint8_t *input,
2604 size_t input_length,
2605 const uint8_t *salt,
2606 size_t salt_length,
2607 uint8_t *output,
2608 size_t output_size,
2609 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002610{
2611 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002612 psa_status_t status;
2613
Darryl Green5cc689a2018-07-24 15:34:10 +01002614 (void) input;
2615 (void) input_length;
2616 (void) salt;
2617 (void) output;
2618 (void) output_size;
2619
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002620 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002621
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002622 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2623 return( PSA_ERROR_INVALID_ARGUMENT );
2624
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002625 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
2626 if( status != PSA_SUCCESS )
2627 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002628 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2629 return( PSA_ERROR_INVALID_ARGUMENT );
2630
2631#if defined(MBEDTLS_RSA_C)
2632 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2633 {
2634 mbedtls_rsa_context *rsa = slot->data.rsa;
2635 int ret;
2636
Gilles Peskine630a18a2018-06-29 17:49:35 +02002637 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002638 return( PSA_ERROR_INVALID_ARGUMENT );
2639
2640#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002641 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002642 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002643 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2644 mbedtls_ctr_drbg_random,
2645 &global_data.ctr_drbg,
2646 MBEDTLS_RSA_PRIVATE,
2647 output_length,
2648 input,
2649 output,
2650 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002651 }
2652 else
2653#endif /* MBEDTLS_PKCS1_V15 */
2654#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002655 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002656 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002657 psa_rsa_oaep_set_padding_mode( alg, rsa );
2658 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
2659 mbedtls_ctr_drbg_random,
2660 &global_data.ctr_drbg,
2661 MBEDTLS_RSA_PRIVATE,
2662 salt, salt_length,
2663 output_length,
2664 input,
2665 output,
2666 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002667 }
2668 else
2669#endif /* MBEDTLS_PKCS1_V21 */
2670 {
2671 return( PSA_ERROR_INVALID_ARGUMENT );
2672 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002673
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002674 return( mbedtls_to_psa_error( ret ) );
2675 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002676 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002677#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002678 {
2679 return( PSA_ERROR_NOT_SUPPORTED );
2680 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002681}
Gilles Peskine20035e32018-02-03 22:44:14 +01002682
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002683
2684
mohammad1603503973b2018-03-12 15:59:30 +02002685/****************************************************************/
2686/* Symmetric cryptography */
2687/****************************************************************/
2688
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002689/* Initialize the cipher operation structure. Once this function has been
2690 * called, psa_cipher_abort can run and will do the right thing. */
2691static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2692 psa_algorithm_t alg )
2693{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002694 if( ! PSA_ALG_IS_CIPHER( alg ) )
2695 {
2696 memset( operation, 0, sizeof( *operation ) );
2697 return( PSA_ERROR_INVALID_ARGUMENT );
2698 }
2699
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002700 operation->alg = alg;
2701 operation->key_set = 0;
2702 operation->iv_set = 0;
2703 operation->iv_required = 1;
2704 operation->iv_size = 0;
2705 operation->block_size = 0;
2706 mbedtls_cipher_init( &operation->ctx.cipher );
2707 return( PSA_SUCCESS );
2708}
2709
Gilles Peskinee553c652018-06-04 16:22:46 +02002710static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2711 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002712 psa_algorithm_t alg,
2713 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002714{
2715 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2716 psa_status_t status;
2717 key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02002718 size_t key_bits;
2719 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002720 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
2721 PSA_KEY_USAGE_ENCRYPT :
2722 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02002723
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002724 status = psa_cipher_init( operation, alg );
2725 if( status != PSA_SUCCESS )
2726 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002727
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002728 status = psa_get_key_from_slot( key, &slot, usage, alg);
2729 if( status != PSA_SUCCESS )
2730 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002731 key_bits = psa_get_key_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02002732
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002733 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002734 if( cipher_info == NULL )
2735 return( PSA_ERROR_NOT_SUPPORTED );
2736
mohammad1603503973b2018-03-12 15:59:30 +02002737 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002738 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002739 {
2740 psa_cipher_abort( operation );
2741 return( mbedtls_to_psa_error( ret ) );
2742 }
2743
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002744#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002745 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002746 {
2747 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2748 unsigned char keys[24];
2749 memcpy( keys, slot->data.raw.data, 16 );
2750 memcpy( keys + 16, slot->data.raw.data, 8 );
2751 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2752 keys,
2753 192, cipher_operation );
2754 }
2755 else
2756#endif
2757 {
2758 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2759 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002760 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002761 }
Moran Peker41deec42018-04-04 15:43:05 +03002762 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002763 {
2764 psa_cipher_abort( operation );
2765 return( mbedtls_to_psa_error( ret ) );
2766 }
2767
mohammad16038481e742018-03-18 13:57:31 +02002768#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002769 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02002770 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002771 case PSA_ALG_CBC_NO_PADDING:
2772 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2773 MBEDTLS_PADDING_NONE );
2774 break;
2775 case PSA_ALG_CBC_PKCS7:
2776 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2777 MBEDTLS_PADDING_PKCS7 );
2778 break;
2779 default:
2780 /* The algorithm doesn't involve padding. */
2781 ret = 0;
2782 break;
2783 }
2784 if( ret != 0 )
2785 {
2786 psa_cipher_abort( operation );
2787 return( mbedtls_to_psa_error( ret ) );
mohammad16038481e742018-03-18 13:57:31 +02002788 }
2789#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2790
mohammad1603503973b2018-03-12 15:59:30 +02002791 operation->key_set = 1;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002792 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
2793 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
2794 if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
mohammad16038481e742018-03-18 13:57:31 +02002795 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002796 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02002797 }
mohammad1603503973b2018-03-12 15:59:30 +02002798
Moran Peker395db872018-05-31 14:07:14 +03002799 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002800}
2801
Gilles Peskinefe119512018-07-08 21:39:34 +02002802psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
2803 psa_key_slot_t key,
2804 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002805{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002806 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002807}
2808
Gilles Peskinefe119512018-07-08 21:39:34 +02002809psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
2810 psa_key_slot_t key,
2811 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002812{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002813 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002814}
2815
Gilles Peskinefe119512018-07-08 21:39:34 +02002816psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
2817 unsigned char *iv,
2818 size_t iv_size,
2819 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002820{
itayzafrir534bd7c2018-08-02 13:56:32 +03002821 psa_status_t status;
2822 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002823 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002824 {
2825 status = PSA_ERROR_BAD_STATE;
2826 goto exit;
2827 }
Moran Peker41deec42018-04-04 15:43:05 +03002828 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002829 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002830 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03002831 goto exit;
2832 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002833 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2834 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002835 if( ret != 0 )
2836 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002837 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002838 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002839 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002840
mohammad16038481e742018-03-18 13:57:31 +02002841 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03002842 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002843
Moran Peker395db872018-05-31 14:07:14 +03002844exit:
itayzafrir534bd7c2018-08-02 13:56:32 +03002845 if( status != PSA_SUCCESS )
Moran Peker395db872018-05-31 14:07:14 +03002846 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002847 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002848}
2849
Gilles Peskinefe119512018-07-08 21:39:34 +02002850psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
2851 const unsigned char *iv,
2852 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002853{
itayzafrir534bd7c2018-08-02 13:56:32 +03002854 psa_status_t status;
2855 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002856 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002857 {
2858 status = PSA_ERROR_BAD_STATE;
2859 goto exit;
2860 }
Moran Pekera28258c2018-05-29 16:25:04 +03002861 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002862 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002863 status = PSA_ERROR_INVALID_ARGUMENT;
2864 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03002865 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002866 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
2867 status = mbedtls_to_psa_error( ret );
2868exit:
2869 if( status == PSA_SUCCESS )
2870 operation->iv_set = 1;
2871 else
mohammad1603503973b2018-03-12 15:59:30 +02002872 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002873 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002874}
2875
Gilles Peskinee553c652018-06-04 16:22:46 +02002876psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2877 const uint8_t *input,
2878 size_t input_length,
2879 unsigned char *output,
2880 size_t output_size,
2881 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002882{
itayzafrir534bd7c2018-08-02 13:56:32 +03002883 psa_status_t status;
2884 int ret;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002885 size_t expected_output_size;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002886 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002887 {
2888 /* Take the unprocessed partial block left over from previous
2889 * update calls, if any, plus the input to this call. Remove
2890 * the last partial block, if any. You get the data that will be
2891 * output in this call. */
2892 expected_output_size =
2893 ( operation->ctx.cipher.unprocessed_len + input_length )
2894 / operation->block_size * operation->block_size;
2895 }
2896 else
2897 {
2898 expected_output_size = input_length;
2899 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002900
Gilles Peskine89d789c2018-06-04 17:17:16 +02002901 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03002902 {
2903 status = PSA_ERROR_BUFFER_TOO_SMALL;
2904 goto exit;
2905 }
mohammad160382759612018-03-12 18:16:40 +02002906
mohammad1603503973b2018-03-12 15:59:30 +02002907 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002908 input_length, output, output_length );
itayzafrir534bd7c2018-08-02 13:56:32 +03002909 status = mbedtls_to_psa_error( ret );
2910exit:
2911 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02002912 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002913 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002914}
2915
Gilles Peskinee553c652018-06-04 16:22:46 +02002916psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2917 uint8_t *output,
2918 size_t output_size,
2919 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002920{
Janos Follath315b51c2018-07-09 16:04:51 +01002921 psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
2922 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002923 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002924
mohammad1603503973b2018-03-12 15:59:30 +02002925 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002926 {
Janos Follath315b51c2018-07-09 16:04:51 +01002927 status = PSA_ERROR_BAD_STATE;
2928 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002929 }
2930 if( operation->iv_required && ! operation->iv_set )
2931 {
Janos Follath315b51c2018-07-09 16:04:51 +01002932 status = PSA_ERROR_BAD_STATE;
2933 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002934 }
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002935
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002936 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002937 operation->alg == PSA_ALG_CBC_NO_PADDING &&
2938 operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03002939 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002940 status = PSA_ERROR_INVALID_ARGUMENT;
Janos Follath315b51c2018-07-09 16:04:51 +01002941 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002942 }
2943
Janos Follath315b51c2018-07-09 16:04:51 +01002944 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
2945 temp_output_buffer,
2946 output_length );
2947 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002948 {
Janos Follath315b51c2018-07-09 16:04:51 +01002949 status = mbedtls_to_psa_error( cipher_ret );
2950 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02002951 }
Janos Follath315b51c2018-07-09 16:04:51 +01002952
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002953 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01002954 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002955 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002956 memcpy( output, temp_output_buffer, *output_length );
2957 else
2958 {
Janos Follath315b51c2018-07-09 16:04:51 +01002959 status = PSA_ERROR_BUFFER_TOO_SMALL;
2960 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002961 }
mohammad1603503973b2018-03-12 15:59:30 +02002962
Janos Follath279ab8e2018-07-09 16:13:21 +01002963 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002964 status = psa_cipher_abort( operation );
2965
2966 return( status );
2967
2968error:
2969
2970 *output_length = 0;
2971
Janos Follath279ab8e2018-07-09 16:13:21 +01002972 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002973 (void) psa_cipher_abort( operation );
2974
2975 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002976}
2977
Gilles Peskinee553c652018-06-04 16:22:46 +02002978psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2979{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002980 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002981 {
2982 /* The object has (apparently) been initialized but it is not
2983 * in use. It's ok to call abort on such an object, and there's
2984 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002985 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002986 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002987
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002988 /* Sanity check (shouldn't happen: operation->alg should
2989 * always have been initialized to a valid value). */
2990 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2991 return( PSA_ERROR_BAD_STATE );
2992
mohammad1603503973b2018-03-12 15:59:30 +02002993 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002994
Moran Peker41deec42018-04-04 15:43:05 +03002995 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002996 operation->key_set = 0;
2997 operation->iv_set = 0;
2998 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002999 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03003000 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03003001
Moran Peker395db872018-05-31 14:07:14 +03003002 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02003003}
3004
Gilles Peskinea0655c32018-04-30 17:06:50 +02003005
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003006
mohammad16038cc1cee2018-03-28 01:21:33 +03003007/****************************************************************/
3008/* Key Policy */
3009/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003010
mohammad160327010052018-07-03 13:16:15 +03003011#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02003012void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003013{
Gilles Peskine803ce742018-06-18 16:07:14 +02003014 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03003015}
3016
Gilles Peskine2d277862018-06-18 15:41:12 +02003017void psa_key_policy_set_usage( psa_key_policy_t *policy,
3018 psa_key_usage_t usage,
3019 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03003020{
mohammad16034eed7572018-03-28 05:14:59 -07003021 policy->usage = usage;
3022 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03003023}
3024
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003025psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003026{
mohammad16036df908f2018-04-02 08:34:15 -07003027 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03003028}
3029
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003030psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003031{
mohammad16036df908f2018-04-02 08:34:15 -07003032 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03003033}
mohammad160327010052018-07-03 13:16:15 +03003034#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003035
Gilles Peskine2d277862018-06-18 15:41:12 +02003036psa_status_t psa_set_key_policy( psa_key_slot_t key,
3037 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003038{
3039 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003040 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003041
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003042 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003043 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003044
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003045 status = psa_get_empty_key_slot( key, &slot );
3046 if( status != PSA_SUCCESS )
3047 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03003048
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003049 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
3050 PSA_KEY_USAGE_ENCRYPT |
3051 PSA_KEY_USAGE_DECRYPT |
3052 PSA_KEY_USAGE_SIGN |
Gilles Peskineea0fb492018-07-12 17:17:20 +02003053 PSA_KEY_USAGE_VERIFY |
3054 PSA_KEY_USAGE_DERIVE ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07003055 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03003056
mohammad16036df908f2018-04-02 08:34:15 -07003057 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003058
3059 return( PSA_SUCCESS );
3060}
3061
Gilles Peskine2d277862018-06-18 15:41:12 +02003062psa_status_t psa_get_key_policy( psa_key_slot_t key,
3063 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003064{
3065 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003066 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003067
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003068 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003069 return( PSA_ERROR_INVALID_ARGUMENT );
3070
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003071 status = psa_get_key_slot( key, &slot );
3072 if( status != PSA_SUCCESS )
3073 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003074
mohammad16036df908f2018-04-02 08:34:15 -07003075 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003076
3077 return( PSA_SUCCESS );
3078}
Gilles Peskine20035e32018-02-03 22:44:14 +01003079
Gilles Peskinea0655c32018-04-30 17:06:50 +02003080
3081
mohammad1603804cd712018-03-20 22:44:08 +02003082/****************************************************************/
3083/* Key Lifetime */
3084/****************************************************************/
3085
Gilles Peskine2d277862018-06-18 15:41:12 +02003086psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
3087 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003088{
3089 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003090 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003091
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003092 status = psa_get_key_slot( key, &slot );
3093 if( status != PSA_SUCCESS )
3094 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003095
mohammad1603804cd712018-03-20 22:44:08 +02003096 *lifetime = slot->lifetime;
3097
3098 return( PSA_SUCCESS );
3099}
3100
Gilles Peskine2d277862018-06-18 15:41:12 +02003101psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
Jaeden Amero65fb2362018-06-26 13:55:30 +01003102 psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003103{
3104 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003105 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003106
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003107 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
3108 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
Darryl Greend49a4992018-06-18 17:27:26 +01003109 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE )
mohammad1603ba178512018-03-21 04:35:20 -07003110 return( PSA_ERROR_INVALID_ARGUMENT );
3111
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003112 status = psa_get_empty_key_slot( key, &slot );
3113 if( status != PSA_SUCCESS )
3114 return( status );
mohammad1603804cd712018-03-20 22:44:08 +02003115
Darryl Greend49a4992018-06-18 17:27:26 +01003116 if( lifetime == PSA_KEY_LIFETIME_WRITE_ONCE )
mohammad1603ba178512018-03-21 04:35:20 -07003117 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003118
Darryl Greend49a4992018-06-18 17:27:26 +01003119#if !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
3120 if( lifetime == PSA_KEY_LIFETIME_PERSISTENT )
3121 return( PSA_ERROR_NOT_SUPPORTED );
3122#endif
3123
mohammad1603060ad8a2018-03-20 14:28:38 -07003124 slot->lifetime = lifetime;
Gilles Peskine69f976b2018-11-30 18:46:56 +01003125 slot->persistent_storage_id = key;
mohammad1603804cd712018-03-20 22:44:08 +02003126
3127 return( PSA_SUCCESS );
3128}
3129
Gilles Peskine20035e32018-02-03 22:44:14 +01003130
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003131
mohammad16035955c982018-04-26 00:53:03 +03003132/****************************************************************/
3133/* AEAD */
3134/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003135
Gilles Peskineedf9a652018-08-17 18:11:56 +02003136typedef struct
3137{
3138 key_slot_t *slot;
3139 const mbedtls_cipher_info_t *cipher_info;
3140 union
3141 {
3142#if defined(MBEDTLS_CCM_C)
3143 mbedtls_ccm_context ccm;
3144#endif /* MBEDTLS_CCM_C */
3145#if defined(MBEDTLS_GCM_C)
3146 mbedtls_gcm_context gcm;
3147#endif /* MBEDTLS_GCM_C */
3148 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003149 psa_algorithm_t core_alg;
3150 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003151 uint8_t tag_length;
3152} aead_operation_t;
3153
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003154static void psa_aead_abort( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003155{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003156 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003157 {
3158#if defined(MBEDTLS_CCM_C)
3159 case PSA_ALG_CCM:
3160 mbedtls_ccm_free( &operation->ctx.ccm );
3161 break;
3162#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003163#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02003164 case PSA_ALG_GCM:
3165 mbedtls_gcm_free( &operation->ctx.gcm );
3166 break;
3167#endif /* MBEDTLS_GCM_C */
3168 }
3169}
3170
3171static psa_status_t psa_aead_setup( aead_operation_t *operation,
3172 psa_key_slot_t key,
3173 psa_key_usage_t usage,
3174 psa_algorithm_t alg )
3175{
3176 psa_status_t status;
3177 size_t key_bits;
3178 mbedtls_cipher_id_t cipher_id;
3179
3180 status = psa_get_key_from_slot( key, &operation->slot, usage, alg );
3181 if( status != PSA_SUCCESS )
3182 return( status );
3183
3184 key_bits = psa_get_key_bits( operation->slot );
3185
3186 operation->cipher_info =
3187 mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
3188 &cipher_id );
3189 if( operation->cipher_info == NULL )
3190 return( PSA_ERROR_NOT_SUPPORTED );
3191
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003192 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003193 {
3194#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003195 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
3196 operation->core_alg = PSA_ALG_CCM;
3197 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003198 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3199 return( PSA_ERROR_INVALID_ARGUMENT );
3200 mbedtls_ccm_init( &operation->ctx.ccm );
3201 status = mbedtls_to_psa_error(
3202 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
3203 operation->slot->data.raw.data,
3204 (unsigned int) key_bits ) );
3205 if( status != 0 )
3206 goto cleanup;
3207 break;
3208#endif /* MBEDTLS_CCM_C */
3209
3210#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003211 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
3212 operation->core_alg = PSA_ALG_GCM;
3213 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003214 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3215 return( PSA_ERROR_INVALID_ARGUMENT );
3216 mbedtls_gcm_init( &operation->ctx.gcm );
3217 status = mbedtls_to_psa_error(
3218 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
3219 operation->slot->data.raw.data,
3220 (unsigned int) key_bits ) );
3221 break;
3222#endif /* MBEDTLS_GCM_C */
3223
3224 default:
3225 return( PSA_ERROR_NOT_SUPPORTED );
3226 }
3227
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003228 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
3229 {
3230 status = PSA_ERROR_INVALID_ARGUMENT;
3231 goto cleanup;
3232 }
3233 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
3234 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
3235 * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
3236 * In both cases, mbedtls_xxx will validate the tag length below. */
3237
Gilles Peskineedf9a652018-08-17 18:11:56 +02003238 return( PSA_SUCCESS );
3239
3240cleanup:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003241 psa_aead_abort( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003242 return( status );
3243}
3244
mohammad16035955c982018-04-26 00:53:03 +03003245psa_status_t psa_aead_encrypt( psa_key_slot_t key,
3246 psa_algorithm_t alg,
3247 const uint8_t *nonce,
3248 size_t nonce_length,
3249 const uint8_t *additional_data,
3250 size_t additional_data_length,
3251 const uint8_t *plaintext,
3252 size_t plaintext_length,
3253 uint8_t *ciphertext,
3254 size_t ciphertext_size,
3255 size_t *ciphertext_length )
3256{
mohammad16035955c982018-04-26 00:53:03 +03003257 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003258 aead_operation_t operation;
mohammad160315223a82018-06-03 17:19:55 +03003259 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02003260
mohammad1603f08a5502018-06-03 15:05:47 +03003261 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07003262
Gilles Peskineedf9a652018-08-17 18:11:56 +02003263 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003264 if( status != PSA_SUCCESS )
3265 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003266
Gilles Peskineedf9a652018-08-17 18:11:56 +02003267 /* For all currently supported modes, the tag is at the end of the
3268 * ciphertext. */
3269 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
3270 {
3271 status = PSA_ERROR_BUFFER_TOO_SMALL;
3272 goto exit;
3273 }
3274 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03003275
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003276#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003277 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003278 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003279 status = mbedtls_to_psa_error(
3280 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
3281 MBEDTLS_GCM_ENCRYPT,
3282 plaintext_length,
3283 nonce, nonce_length,
3284 additional_data, additional_data_length,
3285 plaintext, ciphertext,
3286 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03003287 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003288 else
3289#endif /* MBEDTLS_GCM_C */
3290#if defined(MBEDTLS_CCM_C)
3291 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003292 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003293 status = mbedtls_to_psa_error(
3294 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
3295 plaintext_length,
3296 nonce, nonce_length,
3297 additional_data,
3298 additional_data_length,
3299 plaintext, ciphertext,
3300 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003301 }
mohammad16035c8845f2018-05-09 05:40:09 -07003302 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003303#endif /* MBEDTLS_CCM_C */
mohammad16035c8845f2018-05-09 05:40:09 -07003304 {
mohammad1603554faad2018-06-03 15:07:38 +03003305 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07003306 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003307
Gilles Peskineedf9a652018-08-17 18:11:56 +02003308 if( status != PSA_SUCCESS && ciphertext_size != 0 )
3309 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003310
Gilles Peskineedf9a652018-08-17 18:11:56 +02003311exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003312 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003313 if( status == PSA_SUCCESS )
3314 *ciphertext_length = plaintext_length + operation.tag_length;
3315 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003316}
3317
Gilles Peskineee652a32018-06-01 19:23:52 +02003318/* Locate the tag in a ciphertext buffer containing the encrypted data
3319 * followed by the tag. Return the length of the part preceding the tag in
3320 * *plaintext_length. This is the size of the plaintext in modes where
3321 * the encrypted data has the same size as the plaintext, such as
3322 * CCM and GCM. */
3323static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
3324 const uint8_t *ciphertext,
3325 size_t ciphertext_length,
3326 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02003327 const uint8_t **p_tag )
3328{
3329 size_t payload_length;
3330 if( tag_length > ciphertext_length )
3331 return( PSA_ERROR_INVALID_ARGUMENT );
3332 payload_length = ciphertext_length - tag_length;
3333 if( payload_length > plaintext_size )
3334 return( PSA_ERROR_BUFFER_TOO_SMALL );
3335 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02003336 return( PSA_SUCCESS );
3337}
3338
mohammad16035955c982018-04-26 00:53:03 +03003339psa_status_t psa_aead_decrypt( psa_key_slot_t key,
3340 psa_algorithm_t alg,
3341 const uint8_t *nonce,
3342 size_t nonce_length,
3343 const uint8_t *additional_data,
3344 size_t additional_data_length,
3345 const uint8_t *ciphertext,
3346 size_t ciphertext_length,
3347 uint8_t *plaintext,
3348 size_t plaintext_size,
3349 size_t *plaintext_length )
3350{
mohammad16035955c982018-04-26 00:53:03 +03003351 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003352 aead_operation_t operation;
3353 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02003354
Gilles Peskineee652a32018-06-01 19:23:52 +02003355 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03003356
Gilles Peskineedf9a652018-08-17 18:11:56 +02003357 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003358 if( status != PSA_SUCCESS )
3359 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003360
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003361#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003362 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003363 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003364 status = psa_aead_unpadded_locate_tag( operation.tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003365 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003366 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02003367 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003368 goto exit;
Gilles Peskineee652a32018-06-01 19:23:52 +02003369
Gilles Peskineedf9a652018-08-17 18:11:56 +02003370 status = mbedtls_to_psa_error(
3371 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
3372 ciphertext_length - operation.tag_length,
3373 nonce, nonce_length,
3374 additional_data,
3375 additional_data_length,
3376 tag, operation.tag_length,
3377 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03003378 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003379 else
3380#endif /* MBEDTLS_GCM_C */
3381#if defined(MBEDTLS_CCM_C)
3382 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003383 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003384 status = psa_aead_unpadded_locate_tag( operation.tag_length,
mohammad16039375f842018-06-03 14:28:24 +03003385 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003386 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03003387 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003388 goto exit;
mohammad16039375f842018-06-03 14:28:24 +03003389
Gilles Peskineedf9a652018-08-17 18:11:56 +02003390 status = mbedtls_to_psa_error(
3391 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
3392 ciphertext_length - operation.tag_length,
3393 nonce, nonce_length,
3394 additional_data,
3395 additional_data_length,
3396 ciphertext, plaintext,
3397 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003398 }
mohammad160339574652018-06-01 04:39:53 -07003399 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003400#endif /* MBEDTLS_CCM_C */
mohammad160339574652018-06-01 04:39:53 -07003401 {
mohammad1603554faad2018-06-03 15:07:38 +03003402 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07003403 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02003404
Gilles Peskineedf9a652018-08-17 18:11:56 +02003405 if( status != PSA_SUCCESS && plaintext_size != 0 )
3406 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03003407
Gilles Peskineedf9a652018-08-17 18:11:56 +02003408exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003409 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003410 if( status == PSA_SUCCESS )
3411 *plaintext_length = ciphertext_length - operation.tag_length;
3412 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003413}
3414
Gilles Peskinea0655c32018-04-30 17:06:50 +02003415
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003416
Gilles Peskine20035e32018-02-03 22:44:14 +01003417/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003418/* Generators */
3419/****************************************************************/
3420
3421psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
3422{
3423 psa_status_t status = PSA_SUCCESS;
3424 if( generator->alg == 0 )
3425 {
3426 /* The object has (apparently) been initialized but it is not
3427 * in use. It's ok to call abort on such an object, and there's
3428 * nothing to do. */
3429 }
3430 else
Gilles Peskine751d9652018-09-18 12:05:44 +02003431 if( generator->alg == PSA_ALG_SELECT_RAW )
3432 {
3433 if( generator->ctx.buffer.data != NULL )
3434 {
3435 mbedtls_zeroize( generator->ctx.buffer.data,
3436 generator->ctx.buffer.size );
3437 mbedtls_free( generator->ctx.buffer.data );
3438 }
3439 }
3440 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003441#if defined(MBEDTLS_MD_C)
3442 if( PSA_ALG_IS_HKDF( generator->alg ) )
3443 {
3444 mbedtls_free( generator->ctx.hkdf.info );
3445 status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
3446 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003447 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3448 /* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
3449 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003450 {
3451 if( generator->ctx.tls12_prf.key != NULL )
3452 {
3453 mbedtls_zeroize( generator->ctx.tls12_prf.key,
3454 generator->ctx.tls12_prf.key_len );
3455 mbedtls_free( generator->ctx.tls12_prf.key );
3456 }
Hanno Becker580fba12018-11-13 20:50:45 +00003457
3458 if( generator->ctx.tls12_prf.Ai_with_seed != NULL )
3459 {
3460 mbedtls_zeroize( generator->ctx.tls12_prf.Ai_with_seed,
3461 generator->ctx.tls12_prf.Ai_with_seed_len );
3462 mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed );
3463 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003464 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003465 else
3466#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003467 {
3468 status = PSA_ERROR_BAD_STATE;
3469 }
3470 memset( generator, 0, sizeof( *generator ) );
3471 return( status );
3472}
3473
3474
3475psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3476 size_t *capacity)
3477{
3478 *capacity = generator->capacity;
3479 return( PSA_SUCCESS );
3480}
3481
Gilles Peskinebef7f142018-07-12 17:22:21 +02003482#if defined(MBEDTLS_MD_C)
3483/* Read some bytes from an HKDF-based generator. This performs a chunk
3484 * of the expand phase of the HKDF algorithm. */
3485static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
3486 psa_algorithm_t hash_alg,
3487 uint8_t *output,
3488 size_t output_length )
3489{
3490 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3491 psa_status_t status;
3492
3493 while( output_length != 0 )
3494 {
3495 /* Copy what remains of the current block */
3496 uint8_t n = hash_length - hkdf->offset_in_block;
3497 if( n > output_length )
3498 n = (uint8_t) output_length;
3499 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
3500 output += n;
3501 output_length -= n;
3502 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02003503 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003504 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003505 /* We can't be wanting more output after block 0xff, otherwise
3506 * the capacity check in psa_generator_read() would have
3507 * prevented this call. It could happen only if the generator
3508 * object was corrupted or if this function is called directly
3509 * inside the library. */
3510 if( hkdf->block_number == 0xff )
3511 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003512
3513 /* We need a new block */
3514 ++hkdf->block_number;
3515 hkdf->offset_in_block = 0;
3516 status = psa_hmac_setup_internal( &hkdf->hmac,
3517 hkdf->prk, hash_length,
3518 hash_alg );
3519 if( status != PSA_SUCCESS )
3520 return( status );
3521 if( hkdf->block_number != 1 )
3522 {
3523 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3524 hkdf->output_block,
3525 hash_length );
3526 if( status != PSA_SUCCESS )
3527 return( status );
3528 }
3529 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3530 hkdf->info,
3531 hkdf->info_length );
3532 if( status != PSA_SUCCESS )
3533 return( status );
3534 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3535 &hkdf->block_number, 1 );
3536 if( status != PSA_SUCCESS )
3537 return( status );
3538 status = psa_hmac_finish_internal( &hkdf->hmac,
3539 hkdf->output_block,
3540 sizeof( hkdf->output_block ) );
3541 if( status != PSA_SUCCESS )
3542 return( status );
3543 }
3544
3545 return( PSA_SUCCESS );
3546}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003547
3548static psa_status_t psa_generator_tls12_prf_generate_next_block(
3549 psa_tls12_prf_generator_t *tls12_prf,
3550 psa_algorithm_t alg )
3551{
3552 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3553 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3554 psa_hmac_internal_data hmac;
3555 psa_status_t status, cleanup_status;
3556
Hanno Becker3b339e22018-11-13 20:56:14 +00003557 unsigned char *Ai;
3558 size_t Ai_len;
3559
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003560 /* We can't be wanting more output after block 0xff, otherwise
3561 * the capacity check in psa_generator_read() would have
3562 * prevented this call. It could happen only if the generator
3563 * object was corrupted or if this function is called directly
3564 * inside the library. */
3565 if( tls12_prf->block_number == 0xff )
3566 return( PSA_ERROR_BAD_STATE );
3567
3568 /* We need a new block */
3569 ++tls12_prf->block_number;
3570 tls12_prf->offset_in_block = 0;
3571
3572 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
3573 *
3574 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
3575 *
3576 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
3577 * HMAC_hash(secret, A(2) + seed) +
3578 * HMAC_hash(secret, A(3) + seed) + ...
3579 *
3580 * A(0) = seed
3581 * A(i) = HMAC_hash( secret, A(i-1) )
3582 *
3583 * The `psa_tls12_prf_generator` structures saves the block
3584 * `HMAC_hash(secret, A(i) + seed)` from which the output
3585 * is currently extracted as `output_block`, while
3586 * `A(i) + seed` is stored in `Ai_with_seed`.
3587 *
3588 * Generating a new block means recalculating `Ai_with_seed`
3589 * from the A(i)-part of it, and afterwards recalculating
3590 * `output_block`.
3591 *
3592 * A(0) is computed at setup time.
3593 *
3594 */
3595
3596 psa_hmac_init_internal( &hmac );
3597
3598 /* We must distinguish the calculation of A(1) from those
3599 * of A(2) and higher, because A(0)=seed has a different
3600 * length than the other A(i). */
3601 if( tls12_prf->block_number == 1 )
3602 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003603 Ai = tls12_prf->Ai_with_seed + hash_length;
3604 Ai_len = tls12_prf->Ai_with_seed_len - hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003605 }
3606 else
3607 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003608 Ai = tls12_prf->Ai_with_seed;
3609 Ai_len = hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003610 }
3611
Hanno Becker3b339e22018-11-13 20:56:14 +00003612 /* Compute A(i+1) = HMAC_hash(secret, A(i)) */
3613 status = psa_hmac_setup_internal( &hmac,
3614 tls12_prf->key,
3615 tls12_prf->key_len,
3616 hash_alg );
3617 if( status != PSA_SUCCESS )
3618 goto cleanup;
3619
3620 status = psa_hash_update( &hmac.hash_ctx,
3621 Ai, Ai_len );
3622 if( status != PSA_SUCCESS )
3623 goto cleanup;
3624
3625 status = psa_hmac_finish_internal( &hmac,
3626 tls12_prf->Ai_with_seed,
3627 hash_length );
3628 if( status != PSA_SUCCESS )
3629 goto cleanup;
3630
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003631 /* Compute the next block `HMAC_hash(secret, A(i+1) + seed)`. */
3632 status = psa_hmac_setup_internal( &hmac,
3633 tls12_prf->key,
3634 tls12_prf->key_len,
3635 hash_alg );
3636 if( status != PSA_SUCCESS )
3637 goto cleanup;
3638
3639 status = psa_hash_update( &hmac.hash_ctx,
3640 tls12_prf->Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003641 tls12_prf->Ai_with_seed_len );
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003642 if( status != PSA_SUCCESS )
3643 goto cleanup;
3644
3645 status = psa_hmac_finish_internal( &hmac,
3646 tls12_prf->output_block,
3647 hash_length );
3648 if( status != PSA_SUCCESS )
3649 goto cleanup;
3650
3651cleanup:
3652
3653 cleanup_status = psa_hmac_abort_internal( &hmac );
3654 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
3655 status = cleanup_status;
3656
3657 return( status );
3658}
3659
3660/* Read some bytes from an TLS-1.2-PRF-based generator.
3661 * See Section 5 of RFC 5246. */
3662static psa_status_t psa_generator_tls12_prf_read(
3663 psa_tls12_prf_generator_t *tls12_prf,
3664 psa_algorithm_t alg,
3665 uint8_t *output,
3666 size_t output_length )
3667{
3668 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3669 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3670 psa_status_t status;
3671
3672 while( output_length != 0 )
3673 {
3674 /* Copy what remains of the current block */
3675 uint8_t n = hash_length - tls12_prf->offset_in_block;
3676
3677 /* Check if we have fully processed the current block. */
3678 if( n == 0 )
3679 {
3680 status = psa_generator_tls12_prf_generate_next_block( tls12_prf,
3681 alg );
3682 if( status != PSA_SUCCESS )
3683 return( status );
3684
3685 continue;
3686 }
3687
3688 if( n > output_length )
3689 n = (uint8_t) output_length;
3690 memcpy( output, tls12_prf->output_block + tls12_prf->offset_in_block,
3691 n );
3692 output += n;
3693 output_length -= n;
3694 tls12_prf->offset_in_block += n;
3695 }
3696
3697 return( PSA_SUCCESS );
3698}
Gilles Peskinebef7f142018-07-12 17:22:21 +02003699#endif /* MBEDTLS_MD_C */
3700
Gilles Peskineeab56e42018-07-12 17:12:33 +02003701psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
3702 uint8_t *output,
3703 size_t output_length )
3704{
3705 psa_status_t status;
3706
3707 if( output_length > generator->capacity )
3708 {
3709 generator->capacity = 0;
3710 /* Go through the error path to wipe all confidential data now
3711 * that the generator object is useless. */
3712 status = PSA_ERROR_INSUFFICIENT_CAPACITY;
3713 goto exit;
3714 }
3715 if( output_length == 0 &&
3716 generator->capacity == 0 && generator->alg == 0 )
3717 {
3718 /* Edge case: this is a blank or finished generator, and 0
3719 * bytes were requested. The right error in this case could
3720 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3721 * INSUFFICIENT_CAPACITY, which is right for a finished
3722 * generator, for consistency with the case when
3723 * output_length > 0. */
3724 return( PSA_ERROR_INSUFFICIENT_CAPACITY );
3725 }
3726 generator->capacity -= output_length;
3727
Gilles Peskine751d9652018-09-18 12:05:44 +02003728 if( generator->alg == PSA_ALG_SELECT_RAW )
3729 {
Gilles Peskine211a4362018-10-25 22:22:31 +02003730 /* Initially, the capacity of a selection generator is always
3731 * the size of the buffer, i.e. `generator->ctx.buffer.size`,
3732 * abbreviated in this comment as `size`. When the remaining
3733 * capacity is `c`, the next bytes to serve start `c` bytes
3734 * from the end of the buffer, i.e. `size - c` from the
3735 * beginning of the buffer. Since `generator->capacity` was just
3736 * decremented above, we need to serve the bytes from
3737 * `size - generator->capacity - output_length` to
3738 * `size - generator->capacity`. */
Gilles Peskine751d9652018-09-18 12:05:44 +02003739 size_t offset =
3740 generator->ctx.buffer.size - generator->capacity - output_length;
3741 memcpy( output, generator->ctx.buffer.data + offset, output_length );
3742 status = PSA_SUCCESS;
3743 }
3744 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003745#if defined(MBEDTLS_MD_C)
3746 if( PSA_ALG_IS_HKDF( generator->alg ) )
3747 {
3748 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
3749 status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
3750 output, output_length );
3751 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003752 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3753 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003754 {
3755 status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
3756 generator->alg, output,
3757 output_length );
3758 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003759 else
3760#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003761 {
3762 return( PSA_ERROR_BAD_STATE );
3763 }
3764
3765exit:
3766 if( status != PSA_SUCCESS )
3767 {
3768 psa_generator_abort( generator );
3769 memset( output, '!', output_length );
3770 }
3771 return( status );
3772}
3773
Gilles Peskine08542d82018-07-19 17:05:42 +02003774#if defined(MBEDTLS_DES_C)
3775static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
3776{
3777 if( data_size >= 8 )
3778 mbedtls_des_key_set_parity( data );
3779 if( data_size >= 16 )
3780 mbedtls_des_key_set_parity( data + 8 );
3781 if( data_size >= 24 )
3782 mbedtls_des_key_set_parity( data + 16 );
3783}
3784#endif /* MBEDTLS_DES_C */
3785
Gilles Peskineeab56e42018-07-12 17:12:33 +02003786psa_status_t psa_generator_import_key( psa_key_slot_t key,
3787 psa_key_type_t type,
3788 size_t bits,
3789 psa_crypto_generator_t *generator )
3790{
3791 uint8_t *data = NULL;
3792 size_t bytes = PSA_BITS_TO_BYTES( bits );
3793 psa_status_t status;
3794
3795 if( ! key_type_is_raw_bytes( type ) )
3796 return( PSA_ERROR_INVALID_ARGUMENT );
3797 if( bits % 8 != 0 )
3798 return( PSA_ERROR_INVALID_ARGUMENT );
3799 data = mbedtls_calloc( 1, bytes );
3800 if( data == NULL )
3801 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3802
3803 status = psa_generator_read( generator, data, bytes );
3804 if( status != PSA_SUCCESS )
3805 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02003806#if defined(MBEDTLS_DES_C)
3807 if( type == PSA_KEY_TYPE_DES )
3808 psa_des_set_key_parity( data, bytes );
3809#endif /* MBEDTLS_DES_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003810 status = psa_import_key( key, type, data, bytes );
3811
3812exit:
3813 mbedtls_free( data );
3814 return( status );
3815}
3816
3817
3818
3819/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003820/* Key derivation */
3821/****************************************************************/
3822
Gilles Peskinea05219c2018-11-16 16:02:56 +01003823#if defined(MBEDTLS_MD_C)
Gilles Peskinebef7f142018-07-12 17:22:21 +02003824/* Set up an HKDF-based generator. This is exactly the extract phase
Gilles Peskine346797d2018-11-16 16:05:06 +01003825 * of the HKDF algorithm.
3826 *
3827 * Note that if this function fails, you must call psa_generator_abort()
3828 * to potentially free embedded data structures and wipe confidential data.
3829 */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003830static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003831 const uint8_t *secret,
3832 size_t secret_length,
Gilles Peskinebef7f142018-07-12 17:22:21 +02003833 psa_algorithm_t hash_alg,
3834 const uint8_t *salt,
3835 size_t salt_length,
3836 const uint8_t *label,
3837 size_t label_length )
3838{
3839 psa_status_t status;
3840 status = psa_hmac_setup_internal( &hkdf->hmac,
3841 salt, salt_length,
Gilles Peskine00709fa2018-08-22 18:25:41 +02003842 PSA_ALG_HMAC_GET_HASH( hash_alg ) );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003843 if( status != PSA_SUCCESS )
3844 return( status );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003845 status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003846 if( status != PSA_SUCCESS )
3847 return( status );
3848 status = psa_hmac_finish_internal( &hkdf->hmac,
3849 hkdf->prk,
3850 sizeof( hkdf->prk ) );
3851 if( status != PSA_SUCCESS )
3852 return( status );
3853 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
3854 hkdf->block_number = 0;
3855 hkdf->info_length = label_length;
3856 if( label_length != 0 )
3857 {
3858 hkdf->info = mbedtls_calloc( 1, label_length );
3859 if( hkdf->info == NULL )
3860 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3861 memcpy( hkdf->info, label, label_length );
3862 }
3863 return( PSA_SUCCESS );
3864}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003865#endif /* MBEDTLS_MD_C */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003866
Gilles Peskinea05219c2018-11-16 16:02:56 +01003867#if defined(MBEDTLS_MD_C)
Gilles Peskine346797d2018-11-16 16:05:06 +01003868/* Set up a TLS-1.2-prf-based generator (see RFC 5246, Section 5).
3869 *
3870 * Note that if this function fails, you must call psa_generator_abort()
3871 * to potentially free embedded data structures and wipe confidential data.
3872 */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003873static psa_status_t psa_generator_tls12_prf_setup(
3874 psa_tls12_prf_generator_t *tls12_prf,
3875 const unsigned char *key,
3876 size_t key_len,
3877 psa_algorithm_t hash_alg,
3878 const uint8_t *salt,
3879 size_t salt_length,
3880 const uint8_t *label,
3881 size_t label_length )
3882{
3883 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Hanno Becker580fba12018-11-13 20:50:45 +00003884 size_t Ai_with_seed_len = hash_length + salt_length + label_length;
3885 int overflow;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003886
3887 tls12_prf->key = mbedtls_calloc( 1, key_len );
3888 if( tls12_prf->key == NULL )
3889 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3890 tls12_prf->key_len = key_len;
3891 memcpy( tls12_prf->key, key, key_len );
3892
Hanno Becker580fba12018-11-13 20:50:45 +00003893 overflow = ( salt_length + label_length < salt_length ) ||
3894 ( salt_length + label_length + hash_length < hash_length );
3895 if( overflow )
3896 return( PSA_ERROR_INVALID_ARGUMENT );
3897
3898 tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len );
3899 if( tls12_prf->Ai_with_seed == NULL )
3900 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3901 tls12_prf->Ai_with_seed_len = Ai_with_seed_len;
3902
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003903 /* Write `label + seed' at the end of the `A(i) + seed` buffer,
3904 * leaving the initial `hash_length` bytes unspecified for now. */
Hanno Becker353e4532018-11-15 09:53:57 +00003905 if( label_length != 0 )
3906 {
3907 memcpy( tls12_prf->Ai_with_seed + hash_length,
3908 label, label_length );
3909 }
3910
3911 if( salt_length != 0 )
3912 {
3913 memcpy( tls12_prf->Ai_with_seed + hash_length + label_length,
3914 salt, salt_length );
3915 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003916
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003917 /* The first block gets generated when
3918 * psa_generator_read() is called. */
3919 tls12_prf->block_number = 0;
3920 tls12_prf->offset_in_block = hash_length;
3921
3922 return( PSA_SUCCESS );
3923}
Hanno Becker1aaedc02018-11-16 11:35:34 +00003924
3925/* Set up a TLS-1.2-PSK-to-MS-based generator. */
3926static psa_status_t psa_generator_tls12_psk_to_ms_setup(
3927 psa_tls12_prf_generator_t *tls12_prf,
3928 const unsigned char *psk,
3929 size_t psk_len,
3930 psa_algorithm_t hash_alg,
3931 const uint8_t *salt,
3932 size_t salt_length,
3933 const uint8_t *label,
3934 size_t label_length )
3935{
3936 psa_status_t status;
3937 unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
3938
3939 if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
3940 return( PSA_ERROR_INVALID_ARGUMENT );
3941
3942 /* Quoting RFC 4279, Section 2:
3943 *
3944 * The premaster secret is formed as follows: if the PSK is N octets
3945 * long, concatenate a uint16 with the value N, N zero octets, a second
3946 * uint16 with the value N, and the PSK itself.
3947 */
3948
3949 pms[0] = ( psk_len >> 8 ) & 0xff;
3950 pms[1] = ( psk_len >> 0 ) & 0xff;
3951 memset( pms + 2, 0, psk_len );
3952 pms[2 + psk_len + 0] = pms[0];
3953 pms[2 + psk_len + 1] = pms[1];
3954 memcpy( pms + 4 + psk_len, psk, psk_len );
3955
3956 status = psa_generator_tls12_prf_setup( tls12_prf,
3957 pms, 4 + 2 * psk_len,
3958 hash_alg,
3959 salt, salt_length,
3960 label, label_length );
3961
3962 mbedtls_zeroize( pms, sizeof( pms ) );
3963 return( status );
3964}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003965#endif /* MBEDTLS_MD_C */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003966
Gilles Peskine346797d2018-11-16 16:05:06 +01003967/* Note that if this function fails, you must call psa_generator_abort()
3968 * to potentially free embedded data structures and wipe confidential data.
3969 */
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003970static psa_status_t psa_key_derivation_internal(
3971 psa_crypto_generator_t *generator,
3972 const uint8_t *secret, size_t secret_length,
3973 psa_algorithm_t alg,
3974 const uint8_t *salt, size_t salt_length,
3975 const uint8_t *label, size_t label_length,
3976 size_t capacity )
3977{
3978 psa_status_t status;
3979 size_t max_capacity;
3980
3981 /* Set generator->alg even on failure so that abort knows what to do. */
3982 generator->alg = alg;
3983
Gilles Peskine751d9652018-09-18 12:05:44 +02003984 if( alg == PSA_ALG_SELECT_RAW )
3985 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003986 (void) salt;
Gilles Peskine751d9652018-09-18 12:05:44 +02003987 if( salt_length != 0 )
3988 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea05219c2018-11-16 16:02:56 +01003989 (void) label;
Gilles Peskine751d9652018-09-18 12:05:44 +02003990 if( label_length != 0 )
3991 return( PSA_ERROR_INVALID_ARGUMENT );
3992 generator->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
3993 if( generator->ctx.buffer.data == NULL )
3994 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3995 memcpy( generator->ctx.buffer.data, secret, secret_length );
3996 generator->ctx.buffer.size = secret_length;
3997 max_capacity = secret_length;
3998 status = PSA_SUCCESS;
3999 }
4000 else
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004001#if defined(MBEDTLS_MD_C)
4002 if( PSA_ALG_IS_HKDF( alg ) )
4003 {
4004 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
4005 size_t hash_size = PSA_HASH_SIZE( hash_alg );
4006 if( hash_size == 0 )
4007 return( PSA_ERROR_NOT_SUPPORTED );
4008 max_capacity = 255 * hash_size;
4009 status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
4010 secret, secret_length,
4011 hash_alg,
4012 salt, salt_length,
4013 label, label_length );
4014 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00004015 /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
4016 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
4017 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004018 {
4019 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
4020 size_t hash_size = PSA_HASH_SIZE( hash_alg );
4021
4022 /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */
4023 if( hash_alg != PSA_ALG_SHA_256 &&
4024 hash_alg != PSA_ALG_SHA_384 )
4025 {
4026 return( PSA_ERROR_NOT_SUPPORTED );
4027 }
4028
4029 max_capacity = 255 * hash_size;
Hanno Becker1aaedc02018-11-16 11:35:34 +00004030
4031 if( PSA_ALG_IS_TLS12_PRF( alg ) )
4032 {
4033 status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
4034 secret, secret_length,
4035 hash_alg, salt, salt_length,
4036 label, label_length );
4037 }
4038 else
4039 {
4040 status = psa_generator_tls12_psk_to_ms_setup(
4041 &generator->ctx.tls12_prf,
4042 secret, secret_length,
4043 hash_alg, salt, salt_length,
4044 label, label_length );
4045 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004046 }
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004047 else
4048#endif
4049 {
4050 return( PSA_ERROR_NOT_SUPPORTED );
4051 }
4052
4053 if( status != PSA_SUCCESS )
4054 return( status );
4055
4056 if( capacity <= max_capacity )
4057 generator->capacity = capacity;
Gilles Peskine8feb3a82018-09-18 12:06:11 +02004058 else if( capacity == PSA_GENERATOR_UNBRIDLED_CAPACITY )
4059 generator->capacity = max_capacity;
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004060 else
4061 return( PSA_ERROR_INVALID_ARGUMENT );
4062
4063 return( PSA_SUCCESS );
4064}
4065
Gilles Peskineea0fb492018-07-12 17:17:20 +02004066psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
Darryl Green88001362018-07-26 13:59:04 +01004067 psa_key_slot_t key,
Gilles Peskineea0fb492018-07-12 17:17:20 +02004068 psa_algorithm_t alg,
4069 const uint8_t *salt,
4070 size_t salt_length,
4071 const uint8_t *label,
4072 size_t label_length,
4073 size_t capacity )
4074{
4075 key_slot_t *slot;
4076 psa_status_t status;
4077
4078 if( generator->alg != 0 )
4079 return( PSA_ERROR_BAD_STATE );
4080
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004081 /* Make sure that alg is a key derivation algorithm. This prevents
4082 * key selection algorithms, which psa_key_derivation_internal
4083 * accepts for the sake of key agreement. */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004084 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
4085 return( PSA_ERROR_INVALID_ARGUMENT );
4086
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004087 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DERIVE, alg );
4088 if( status != PSA_SUCCESS )
4089 return( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004090
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004091 if( slot->type != PSA_KEY_TYPE_DERIVE )
4092 return( PSA_ERROR_INVALID_ARGUMENT );
4093
4094 status = psa_key_derivation_internal( generator,
4095 slot->data.raw.data,
4096 slot->data.raw.bytes,
4097 alg,
4098 salt, salt_length,
4099 label, label_length,
4100 capacity );
4101 if( status != PSA_SUCCESS )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004102 psa_generator_abort( generator );
4103 return( status );
4104}
4105
4106
4107
4108/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02004109/* Key agreement */
4110/****************************************************************/
4111
Gilles Peskinea05219c2018-11-16 16:02:56 +01004112#if defined(MBEDTLS_ECDH_C)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004113static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
4114 size_t peer_key_length,
4115 const mbedtls_ecp_keypair *our_key,
4116 uint8_t *shared_secret,
4117 size_t shared_secret_size,
4118 size_t *shared_secret_length )
4119{
4120 mbedtls_pk_context pk;
4121 mbedtls_ecp_keypair *their_key = NULL;
4122 mbedtls_ecdh_context ecdh;
4123 int ret;
4124 mbedtls_ecdh_init( &ecdh );
4125 mbedtls_pk_init( &pk );
4126
4127 ret = mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length );
4128 if( ret != 0 )
4129 goto exit;
Gilles Peskine88714d72018-10-25 23:07:25 +02004130 switch( mbedtls_pk_get_type( &pk ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004131 {
Gilles Peskine88714d72018-10-25 23:07:25 +02004132 case MBEDTLS_PK_ECKEY:
4133 case MBEDTLS_PK_ECKEY_DH:
4134 break;
4135 default:
4136 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4137 goto exit;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004138 }
4139 their_key = mbedtls_pk_ec( pk );
Gilles Peskineb4086612018-11-14 20:51:23 +01004140 if( their_key->grp.id != our_key->grp.id )
4141 {
4142 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4143 goto exit;
4144 }
4145
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004146 ret = mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS );
4147 if( ret != 0 )
4148 goto exit;
4149 ret = mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS );
4150 if( ret != 0 )
4151 goto exit;
4152
4153 ret = mbedtls_ecdh_calc_secret( &ecdh,
4154 shared_secret_length,
4155 shared_secret, shared_secret_size,
4156 mbedtls_ctr_drbg_random,
4157 &global_data.ctr_drbg );
4158
4159exit:
4160 mbedtls_pk_free( &pk );
4161 mbedtls_ecdh_free( &ecdh );
4162 return( mbedtls_to_psa_error( ret ) );
4163}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004164#endif /* MBEDTLS_ECDH_C */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004165
Gilles Peskine01d718c2018-09-18 12:01:02 +02004166#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
4167
Gilles Peskine346797d2018-11-16 16:05:06 +01004168/* Note that if this function fails, you must call psa_generator_abort()
4169 * to potentially free embedded data structures and wipe confidential data.
4170 */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004171static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
4172 key_slot_t *private_key,
4173 const uint8_t *peer_key,
4174 size_t peer_key_length,
4175 psa_algorithm_t alg )
4176{
4177 psa_status_t status;
4178 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
4179 size_t shared_secret_length = 0;
4180
4181 /* Step 1: run the secret agreement algorithm to generate the shared
4182 * secret. */
4183 switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
4184 {
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004185#if defined(MBEDTLS_ECDH_C)
4186 case PSA_ALG_ECDH_BASE:
4187 if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
4188 return( PSA_ERROR_INVALID_ARGUMENT );
4189 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
4190 private_key->data.ecp,
4191 shared_secret,
4192 sizeof( shared_secret ),
4193 &shared_secret_length );
4194 break;
4195#endif /* MBEDTLS_ECDH_C */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004196 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01004197 (void) private_key;
4198 (void) peer_key;
4199 (void) peer_key_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004200 return( PSA_ERROR_NOT_SUPPORTED );
4201 }
4202 if( status != PSA_SUCCESS )
4203 goto exit;
4204
4205 /* Step 2: set up the key derivation to generate key material from
4206 * the shared secret. */
4207 status = psa_key_derivation_internal( generator,
4208 shared_secret, shared_secret_length,
4209 PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ),
4210 NULL, 0, NULL, 0,
4211 PSA_GENERATOR_UNBRIDLED_CAPACITY );
4212exit:
4213 mbedtls_zeroize( shared_secret, shared_secret_length );
4214 return( status );
4215}
4216
4217psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
4218 psa_key_slot_t private_key,
4219 const uint8_t *peer_key,
4220 size_t peer_key_length,
4221 psa_algorithm_t alg )
4222{
4223 key_slot_t *slot;
4224 psa_status_t status;
4225 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
4226 return( PSA_ERROR_INVALID_ARGUMENT );
4227 status = psa_get_key_from_slot( private_key, &slot,
4228 PSA_KEY_USAGE_DERIVE, alg );
4229 if( status != PSA_SUCCESS )
4230 return( status );
Gilles Peskine346797d2018-11-16 16:05:06 +01004231 status = psa_key_agreement_internal( generator,
4232 slot,
4233 peer_key, peer_key_length,
4234 alg );
4235 if( status != PSA_SUCCESS )
4236 psa_generator_abort( generator );
4237 return( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004238}
4239
4240
4241
4242/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004243/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02004244/****************************************************************/
4245
4246psa_status_t psa_generate_random( uint8_t *output,
4247 size_t output_size )
4248{
itayzafrir0adf0fc2018-09-06 16:24:41 +03004249 int ret;
4250 GUARD_MODULE_INITIALIZED;
4251
4252 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
Gilles Peskine05d69892018-06-19 22:00:52 +02004253 return( mbedtls_to_psa_error( ret ) );
4254}
4255
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004256#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
avolinski13beb102018-11-20 16:51:49 +02004257
4258/* Support function for error conversion between psa_its error codes to psa crypto */
4259static psa_status_t its_to_psa_error( psa_its_status_t ret )
4260{
4261 switch( ret )
4262 {
4263 case PSA_ITS_SUCCESS:
4264 return( PSA_SUCCESS );
4265
4266 case PSA_ITS_ERROR_KEY_NOT_FOUND:
4267 return( PSA_ERROR_EMPTY_SLOT );
4268
4269 case PSA_ITS_ERROR_STORAGE_FAILURE:
4270 return( PSA_ERROR_STORAGE_FAILURE );
4271
4272 case PSA_ITS_ERROR_INSUFFICIENT_SPACE:
4273 return( PSA_ERROR_INSUFFICIENT_STORAGE );
4274
4275 case PSA_ITS_ERROR_INVALID_KEY:
4276 case PSA_PS_ERROR_OFFSET_INVALID:
4277 case PSA_ITS_ERROR_INCORRECT_SIZE:
4278 case PSA_ITS_ERROR_BAD_POINTER:
4279 return( PSA_ERROR_INVALID_ARGUMENT );
4280
4281 case PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED:
4282 return( PSA_ERROR_NOT_SUPPORTED );
4283
4284 case PSA_ITS_ERROR_WRITE_ONCE:
4285 return( PSA_ERROR_OCCUPIED_SLOT );
4286
4287 default:
4288 return( PSA_ERROR_UNKNOWN_ERROR );
4289 }
4290}
4291
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004292psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
4293 size_t seed_size )
4294{
4295 psa_status_t status;
avolinski13beb102018-11-20 16:51:49 +02004296 psa_its_status_t its_status;
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004297 struct psa_its_info_t p_info;
4298 if( global_data.initialized )
4299 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02004300
4301 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
4302 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
4303 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
4304 return( PSA_ERROR_INVALID_ARGUMENT );
4305
avolinski0d2c2662018-11-21 17:31:07 +02004306 its_status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
avolinski13beb102018-11-20 16:51:49 +02004307 status = its_to_psa_error( its_status );
4308
4309 if( PSA_ITS_ERROR_KEY_NOT_FOUND == its_status ) /* No seed exists */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004310 {
avolinski0d2c2662018-11-21 17:31:07 +02004311 its_status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
avolinski13beb102018-11-20 16:51:49 +02004312 status = its_to_psa_error( its_status );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004313 }
avolinski13beb102018-11-20 16:51:49 +02004314 else if( PSA_ITS_SUCCESS == its_status )
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004315 {
4316 /* You should not be here. Seed needs to be injected only once */
4317 status = PSA_ERROR_NOT_PERMITTED;
4318 }
4319 return( status );
4320}
4321#endif
4322
Gilles Peskine05d69892018-06-19 22:00:52 +02004323psa_status_t psa_generate_key( psa_key_slot_t key,
4324 psa_key_type_t type,
4325 size_t bits,
Gilles Peskine53d991e2018-07-12 01:14:59 +02004326 const void *extra,
4327 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02004328{
Gilles Peskine12313cd2018-06-20 00:20:32 +02004329 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004330 psa_status_t status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004331
Gilles Peskine53d991e2018-07-12 01:14:59 +02004332 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004333 return( PSA_ERROR_INVALID_ARGUMENT );
4334
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004335 status = psa_get_empty_key_slot( key, &slot );
4336 if( status != PSA_SUCCESS )
4337 return( status );
4338
Gilles Peskine48c0ea12018-06-21 14:15:31 +02004339 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004340 {
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004341 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004342 if( status != PSA_SUCCESS )
4343 return( status );
4344 status = psa_generate_random( slot->data.raw.data,
4345 slot->data.raw.bytes );
4346 if( status != PSA_SUCCESS )
4347 {
4348 mbedtls_free( slot->data.raw.data );
4349 return( status );
4350 }
4351#if defined(MBEDTLS_DES_C)
4352 if( type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02004353 psa_des_set_key_parity( slot->data.raw.data,
4354 slot->data.raw.bytes );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004355#endif /* MBEDTLS_DES_C */
4356 }
4357 else
4358
4359#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
4360 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
4361 {
4362 mbedtls_rsa_context *rsa;
4363 int ret;
4364 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02004365 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
4366 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +01004367 /* Accept only byte-aligned keys, for the same reasons as
4368 * in psa_import_rsa_key(). */
4369 if( bits % 8 != 0 )
4370 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02004371 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004372 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02004373 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004374 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004375 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02004376#if INT_MAX < 0xffffffff
4377 /* Check that the uint32_t value passed by the caller fits
4378 * in the range supported by this implementation. */
4379 if( p->e > INT_MAX )
4380 return( PSA_ERROR_NOT_SUPPORTED );
4381#endif
4382 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004383 }
4384 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
4385 if( rsa == NULL )
4386 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4387 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
4388 ret = mbedtls_rsa_gen_key( rsa,
4389 mbedtls_ctr_drbg_random,
4390 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004391 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02004392 exponent );
4393 if( ret != 0 )
4394 {
4395 mbedtls_rsa_free( rsa );
4396 mbedtls_free( rsa );
4397 return( mbedtls_to_psa_error( ret ) );
4398 }
4399 slot->data.rsa = rsa;
4400 }
4401 else
4402#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
4403
4404#if defined(MBEDTLS_ECP_C)
4405 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
4406 {
4407 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
4408 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
4409 const mbedtls_ecp_curve_info *curve_info =
4410 mbedtls_ecp_curve_info_from_grp_id( grp_id );
4411 mbedtls_ecp_keypair *ecp;
4412 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004413 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004414 return( PSA_ERROR_NOT_SUPPORTED );
4415 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
4416 return( PSA_ERROR_NOT_SUPPORTED );
4417 if( curve_info->bit_size != bits )
4418 return( PSA_ERROR_INVALID_ARGUMENT );
4419 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
4420 if( ecp == NULL )
4421 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4422 mbedtls_ecp_keypair_init( ecp );
4423 ret = mbedtls_ecp_gen_key( grp_id, ecp,
4424 mbedtls_ctr_drbg_random,
4425 &global_data.ctr_drbg );
4426 if( ret != 0 )
4427 {
4428 mbedtls_ecp_keypair_free( ecp );
4429 mbedtls_free( ecp );
4430 return( mbedtls_to_psa_error( ret ) );
4431 }
4432 slot->data.ecp = ecp;
4433 }
4434 else
4435#endif /* MBEDTLS_ECP_C */
4436
4437 return( PSA_ERROR_NOT_SUPPORTED );
4438
4439 slot->type = type;
Darryl Green0c6575a2018-11-07 16:05:30 +00004440
4441#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
4442 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
4443 {
Gilles Peskine69f976b2018-11-30 18:46:56 +01004444 return( psa_save_generated_persistent_key( slot, bits ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004445 }
4446#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
4447
4448 return( status );
Gilles Peskine05d69892018-06-19 22:00:52 +02004449}
4450
4451
4452/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01004453/* Module setup */
4454/****************************************************************/
4455
Gilles Peskine5e769522018-11-20 21:59:56 +01004456psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
4457 void (* entropy_init )( mbedtls_entropy_context *ctx ),
4458 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
4459{
4460 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4461 return( PSA_ERROR_BAD_STATE );
4462 global_data.entropy_init = entropy_init;
4463 global_data.entropy_free = entropy_free;
4464 return( PSA_SUCCESS );
4465}
4466
Gilles Peskinee59236f2018-01-27 23:32:46 +01004467void mbedtls_psa_crypto_free( void )
4468{
Jaeden Amero045bd502018-06-26 14:00:08 +01004469 psa_key_slot_t key;
Darryl Green40225ba2018-11-15 14:48:15 +00004470 key_slot_t *slot;
4471 psa_status_t status;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004472 if( global_data.key_slots_initialized )
Darryl Green40225ba2018-11-15 14:48:15 +00004473 {
Gilles Peskinec6b69072018-11-20 21:42:52 +01004474 for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ )
4475 {
4476 status = psa_get_key_slot( key, &slot );
4477 if( status != PSA_SUCCESS )
4478 continue;
4479 psa_remove_key_data_from_memory( slot );
4480 /* Zeroize the slot to wipe metadata such as policies. */
4481 mbedtls_zeroize( slot, sizeof( *slot ) );
4482 }
Darryl Green40225ba2018-11-15 14:48:15 +00004483 }
Gilles Peskinec6b69072018-11-20 21:42:52 +01004484 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4485 {
4486 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
Gilles Peskine5e769522018-11-20 21:59:56 +01004487 global_data.entropy_free( &global_data.entropy );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004488 }
4489 /* Wipe all remaining data, including configuration.
4490 * In particular, this sets all state indicator to the value
4491 * indicating "uninitialized". */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004492 mbedtls_zeroize( &global_data, sizeof( global_data ) );
4493}
4494
4495psa_status_t psa_crypto_init( void )
4496{
4497 int ret;
4498 const unsigned char drbg_seed[] = "PSA";
4499
Gilles Peskinec6b69072018-11-20 21:42:52 +01004500 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004501 if( global_data.initialized != 0 )
4502 return( PSA_SUCCESS );
4503
Gilles Peskine5e769522018-11-20 21:59:56 +01004504 /* Set default configuration if
4505 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
4506 if( global_data.entropy_init == NULL )
4507 global_data.entropy_init = mbedtls_entropy_init;
4508 if( global_data.entropy_free == NULL )
4509 global_data.entropy_free = mbedtls_entropy_free;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004510
Gilles Peskinec6b69072018-11-20 21:42:52 +01004511 /* Initialize the random generator. */
Gilles Peskine5e769522018-11-20 21:59:56 +01004512 global_data.entropy_init( &global_data.entropy );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004513 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004514 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004515 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
4516 mbedtls_entropy_func,
4517 &global_data.entropy,
4518 drbg_seed, sizeof( drbg_seed ) - 1 );
4519 if( ret != 0 )
4520 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004521 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004522
Gilles Peskinec6b69072018-11-20 21:42:52 +01004523 /* Initialize the key slots. Zero-initialization has made all key
4524 * slots empty, so there is nothing to do. In a future version we will
4525 * load data from storage. */
4526 global_data.key_slots_initialized = 1;
4527
4528 /* All done. */
Gilles Peskinee4ebc122018-03-07 14:16:44 +01004529 global_data.initialized = 1;
4530
Gilles Peskinee59236f2018-01-27 23:32:46 +01004531exit:
4532 if( ret != 0 )
4533 mbedtls_psa_crypto_free( );
4534 return( mbedtls_to_psa_error( ret ) );
4535}
4536
4537#endif /* MBEDTLS_PSA_CRYPTO_C */