blob: c4f41db10b60b26972394d633327d13829ee6c6f [file] [log] [blame]
Tom Van Eyckb0563632024-06-13 16:20:14 +02001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
4/*
5 * Copyright The Mbed TLS Contributors
6 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7 */
8
9#include "common.h"
10#include "psa_crypto_core_common.h"
11
12#if defined(MBEDTLS_PSA_CRYPTO_C)
13
14#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
15#include "check_crypto_config.h"
16#endif
17
18#include "psa/crypto.h"
19#include "psa/crypto_values.h"
20
21#include "psa_crypto_cipher.h"
22#include "psa_crypto_core.h"
23#include "psa_crypto_invasive.h"
24#include "psa_crypto_driver_wrappers.h"
25#include "psa_crypto_driver_wrappers_no_static.h"
26#include "psa_crypto_ecp.h"
27#include "psa_crypto_ffdh.h"
28#include "psa_crypto_hash.h"
29#include "psa_crypto_mac.h"
30#include "psa_crypto_rsa.h"
31#include "psa_crypto_ecp.h"
32#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
33#include "psa_crypto_se.h"
34#endif
35#include "psa_crypto_slot_management.h"
36/* Include internal declarations that are useful for implementing persistently
37 * stored keys. */
38#include "psa_crypto_storage.h"
39
40#include "psa_crypto_random_impl.h"
41
42#include <stdlib.h>
43#include <string.h>
44#include "mbedtls/platform.h"
45
46#include "mbedtls/aes.h"
47#include "mbedtls/asn1.h"
48#include "mbedtls/asn1write.h"
49#include "mbedtls/bignum.h"
50#include "mbedtls/camellia.h"
51#include "mbedtls/chacha20.h"
52#include "mbedtls/chachapoly.h"
53#include "mbedtls/cipher.h"
54#include "mbedtls/ccm.h"
55#include "mbedtls/cmac.h"
56#include "mbedtls/constant_time.h"
57#include "mbedtls/des.h"
58#include "mbedtls/ecdh.h"
59#include "mbedtls/ecp.h"
60#include "mbedtls/entropy.h"
61#include "mbedtls/error.h"
62#include "mbedtls/gcm.h"
63#include "mbedtls/md5.h"
64#include "mbedtls/pk.h"
65#include "pk_wrap.h"
66#include "mbedtls/platform_util.h"
67#include "mbedtls/error.h"
68#include "mbedtls/ripemd160.h"
69#include "mbedtls/rsa.h"
70#include "mbedtls/sha1.h"
71#include "mbedtls/sha256.h"
72#include "mbedtls/sha512.h"
73#include "mbedtls/psa_util.h"
74#include "mbedtls/threading.h"
75
76#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
77 defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \
78 defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND)
79#define BUILTIN_ALG_ANY_HKDF 1
80#endif
81
82/****************************************************************/
83/* Global data, support functions and library management */
84/****************************************************************/
85
86static int key_type_is_raw_bytes(psa_key_type_t type)
87{
88 return PSA_KEY_TYPE_IS_UNSTRUCTURED(type);
89}
90
91/* Values for psa_global_data_t::rng_state */
92#define RNG_NOT_INITIALIZED 0
93#define RNG_INITIALIZED 1
94#define RNG_SEEDED 2
95
96/* IDs for PSA crypto subsystems. Starts at 1 to catch potential uninitialized
97 * variables as arguments. */
98typedef enum {
99 PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS = 1,
100 PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS,
101 PSA_CRYPTO_SUBSYSTEM_RNG,
102 PSA_CRYPTO_SUBSYSTEM_TRANSACTION,
103} mbedtls_psa_crypto_subsystem;
104
105/* Initialization flags for global_data::initialized */
106#define PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED 0x01
107#define PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED 0x02
108#define PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED 0x04
109
110#define PSA_CRYPTO_SUBSYSTEM_ALL_INITIALISED ( \
111 PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED | \
112 PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED | \
113 PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED)
114
115typedef struct {
116 uint8_t initialized;
117 uint8_t rng_state;
118 mbedtls_psa_random_context_t rng;
119} psa_global_data_t;
120
121static psa_global_data_t global_data;
122
123static uint8_t psa_get_initialized(void)
124{
125 uint8_t initialized;
126
127#if defined(MBEDTLS_THREADING_C)
128 mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex);
129#endif /* defined(MBEDTLS_THREADING_C) */
130
131 initialized = global_data.rng_state == RNG_SEEDED;
132
133#if defined(MBEDTLS_THREADING_C)
134 mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex);
135#endif /* defined(MBEDTLS_THREADING_C) */
136
137#if defined(MBEDTLS_THREADING_C)
138 mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex);
139#endif /* defined(MBEDTLS_THREADING_C) */
140
141 initialized =
142 (initialized && (global_data.initialized == PSA_CRYPTO_SUBSYSTEM_ALL_INITIALISED));
143
144#if defined(MBEDTLS_THREADING_C)
145 mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex);
146#endif /* defined(MBEDTLS_THREADING_C) */
147
148 return initialized;
149}
150
151static uint8_t psa_get_drivers_initialized(void)
152{
153 uint8_t initialized;
154
155#if defined(MBEDTLS_THREADING_C)
156 mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex);
157#endif /* defined(MBEDTLS_THREADING_C) */
158
159 initialized = (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED) != 0;
160
161#if defined(MBEDTLS_THREADING_C)
162 mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex);
163#endif /* defined(MBEDTLS_THREADING_C) */
164
165 return initialized;
166}
167
168#define GUARD_MODULE_INITIALIZED \
169 if (psa_get_initialized() == 0) \
170 return PSA_ERROR_BAD_STATE;
171
172#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
173
174/* Declare a local copy of an input buffer and a variable that will be used
175 * to store a pointer to the start of the buffer.
176 *
177 * Note: This macro must be called before any operations which may jump to
178 * the exit label, so that the local input copy object is safe to be freed.
179 *
180 * Assumptions:
181 * - input is the name of a pointer to the buffer to be copied
182 * - The name LOCAL_INPUT_COPY_OF_input is unused in the current scope
183 * - input_copy_name is a name that is unused in the current scope
184 */
185#define LOCAL_INPUT_DECLARE(input, input_copy_name) \
186 psa_crypto_local_input_t LOCAL_INPUT_COPY_OF_##input = PSA_CRYPTO_LOCAL_INPUT_INIT; \
187 const uint8_t *input_copy_name = NULL;
188
189/* Allocate a copy of the buffer input and set the pointer input_copy to
190 * point to the start of the copy.
191 *
192 * Assumptions:
193 * - psa_status_t status exists
194 * - An exit label is declared
195 * - input is the name of a pointer to the buffer to be copied
196 * - LOCAL_INPUT_DECLARE(input, input_copy) has previously been called
197 */
198#define LOCAL_INPUT_ALLOC(input, length, input_copy) \
199 status = psa_crypto_local_input_alloc(input, length, \
200 &LOCAL_INPUT_COPY_OF_##input); \
201 if (status != PSA_SUCCESS) { \
202 goto exit; \
203 } \
204 input_copy = LOCAL_INPUT_COPY_OF_##input.buffer;
205
206/* Free the local input copy allocated previously by LOCAL_INPUT_ALLOC()
207 *
208 * Assumptions:
209 * - input_copy is the name of the input copy pointer set by LOCAL_INPUT_ALLOC()
210 * - input is the name of the original buffer that was copied
211 */
212#define LOCAL_INPUT_FREE(input, input_copy) \
213 input_copy = NULL; \
214 psa_crypto_local_input_free(&LOCAL_INPUT_COPY_OF_##input);
215
216/* Declare a local copy of an output buffer and a variable that will be used
217 * to store a pointer to the start of the buffer.
218 *
219 * Note: This macro must be called before any operations which may jump to
220 * the exit label, so that the local output copy object is safe to be freed.
221 *
222 * Assumptions:
223 * - output is the name of a pointer to the buffer to be copied
224 * - The name LOCAL_OUTPUT_COPY_OF_output is unused in the current scope
225 * - output_copy_name is a name that is unused in the current scope
226 */
227#define LOCAL_OUTPUT_DECLARE(output, output_copy_name) \
228 psa_crypto_local_output_t LOCAL_OUTPUT_COPY_OF_##output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; \
229 uint8_t *output_copy_name = NULL;
230
231/* Allocate a copy of the buffer output and set the pointer output_copy to
232 * point to the start of the copy.
233 *
234 * Assumptions:
235 * - psa_status_t status exists
236 * - An exit label is declared
237 * - output is the name of a pointer to the buffer to be copied
238 * - LOCAL_OUTPUT_DECLARE(output, output_copy) has previously been called
239 */
240#define LOCAL_OUTPUT_ALLOC(output, length, output_copy) \
241 status = psa_crypto_local_output_alloc(output, length, \
242 &LOCAL_OUTPUT_COPY_OF_##output); \
243 if (status != PSA_SUCCESS) { \
244 goto exit; \
245 } \
246 output_copy = LOCAL_OUTPUT_COPY_OF_##output.buffer;
247
248/* Free the local output copy allocated previously by LOCAL_OUTPUT_ALLOC()
249 * after first copying back its contents to the original buffer.
250 *
251 * Assumptions:
252 * - psa_status_t status exists
253 * - output_copy is the name of the output copy pointer set by LOCAL_OUTPUT_ALLOC()
254 * - output is the name of the original buffer that was copied
255 */
256#define LOCAL_OUTPUT_FREE(output, output_copy) \
257 output_copy = NULL; \
258 do { \
259 psa_status_t local_output_status; \
260 local_output_status = psa_crypto_local_output_free(&LOCAL_OUTPUT_COPY_OF_##output); \
261 if (local_output_status != PSA_SUCCESS) { \
262 /* Since this error case is an internal error, it's more serious than \
263 * any existing error code and so it's fine to overwrite the existing \
264 * status. */ \
265 status = local_output_status; \
266 } \
267 } while (0)
268#else /* !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */
269#define LOCAL_INPUT_DECLARE(input, input_copy_name) \
270 const uint8_t *input_copy_name = NULL;
271#define LOCAL_INPUT_ALLOC(input, length, input_copy) \
272 input_copy = input;
273#define LOCAL_INPUT_FREE(input, input_copy) \
274 input_copy = NULL;
275#define LOCAL_OUTPUT_DECLARE(output, output_copy_name) \
276 uint8_t *output_copy_name = NULL;
277#define LOCAL_OUTPUT_ALLOC(output, length, output_copy) \
278 output_copy = output;
279#define LOCAL_OUTPUT_FREE(output, output_copy) \
280 output_copy = NULL;
281#endif /* !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */
282
283
284int psa_can_do_hash(psa_algorithm_t hash_alg)
285{
286 (void) hash_alg;
287 return psa_get_drivers_initialized();
288}
289
290int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg)
291{
292 (void) key_type;
293 (void) cipher_alg;
294 return psa_get_drivers_initialized();
295}
296
297
298#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \
299 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \
300 defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
301static int psa_is_dh_key_size_valid(size_t bits)
302{
303 switch (bits) {
304#if defined(PSA_WANT_DH_RFC7919_2048)
305 case 2048:
306 return 1;
307#endif /* PSA_WANT_DH_RFC7919_2048 */
308#if defined(PSA_WANT_DH_RFC7919_3072)
309 case 3072:
310 return 1;
311#endif /* PSA_WANT_DH_RFC7919_3072 */
312#if defined(PSA_WANT_DH_RFC7919_4096)
313 case 4096:
314 return 1;
315#endif /* PSA_WANT_DH_RFC7919_4096 */
316#if defined(PSA_WANT_DH_RFC7919_6144)
317 case 6144:
318 return 1;
319#endif /* PSA_WANT_DH_RFC7919_6144 */
320#if defined(PSA_WANT_DH_RFC7919_8192)
321 case 8192:
322 return 1;
323#endif /* PSA_WANT_DH_RFC7919_8192 */
324 default:
325 return 0;
326 }
327}
328#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT ||
329 MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY ||
330 PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */
331
332psa_status_t mbedtls_to_psa_error(int ret)
333{
334 /* Mbed TLS error codes can combine a high-level error code and a
335 * low-level error code. The low-level error usually reflects the
336 * root cause better, so dispatch on that preferably. */
337 int low_level_ret = -(-ret & 0x007f);
338 switch (low_level_ret != 0 ? low_level_ret : ret) {
339 case 0:
340 return PSA_SUCCESS;
341
342#if defined(MBEDTLS_AES_C)
343 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
344 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
345 return PSA_ERROR_NOT_SUPPORTED;
346 case MBEDTLS_ERR_AES_BAD_INPUT_DATA:
347 return PSA_ERROR_INVALID_ARGUMENT;
348#endif
349
350#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_ASN1_WRITE_C)
351 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
352 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
353 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
354 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
355 case MBEDTLS_ERR_ASN1_INVALID_DATA:
356 return PSA_ERROR_INVALID_ARGUMENT;
357 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
358 return PSA_ERROR_INSUFFICIENT_MEMORY;
359 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
360 return PSA_ERROR_BUFFER_TOO_SMALL;
361#endif
362
363#if defined(MBEDTLS_CAMELLIA_C)
364 case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA:
365 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
366 return PSA_ERROR_NOT_SUPPORTED;
367#endif
368
369#if defined(MBEDTLS_CCM_C)
370 case MBEDTLS_ERR_CCM_BAD_INPUT:
371 return PSA_ERROR_INVALID_ARGUMENT;
372 case MBEDTLS_ERR_CCM_AUTH_FAILED:
373 return PSA_ERROR_INVALID_SIGNATURE;
374#endif
375
376#if defined(MBEDTLS_CHACHA20_C)
377 case MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA:
378 return PSA_ERROR_INVALID_ARGUMENT;
379#endif
380
381#if defined(MBEDTLS_CHACHAPOLY_C)
382 case MBEDTLS_ERR_CHACHAPOLY_BAD_STATE:
383 return PSA_ERROR_BAD_STATE;
384 case MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED:
385 return PSA_ERROR_INVALID_SIGNATURE;
386#endif
387
388#if defined(MBEDTLS_CIPHER_C)
389 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
390 return PSA_ERROR_NOT_SUPPORTED;
391 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
392 return PSA_ERROR_INVALID_ARGUMENT;
393 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
394 return PSA_ERROR_INSUFFICIENT_MEMORY;
395 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
396 return PSA_ERROR_INVALID_PADDING;
397 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
398 return PSA_ERROR_INVALID_ARGUMENT;
399 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
400 return PSA_ERROR_INVALID_SIGNATURE;
401 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
402 return PSA_ERROR_CORRUPTION_DETECTED;
403#endif
404
405#if !(defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) || \
406 defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE))
407 /* Only check CTR_DRBG error codes if underlying mbedtls_xxx
408 * functions are passed a CTR_DRBG instance. */
409 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
410 return PSA_ERROR_INSUFFICIENT_ENTROPY;
411 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
412 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
413 return PSA_ERROR_NOT_SUPPORTED;
414 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
415 return PSA_ERROR_INSUFFICIENT_ENTROPY;
416#endif
417
418#if defined(MBEDTLS_DES_C)
419 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
420 return PSA_ERROR_NOT_SUPPORTED;
421#endif
422
423 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
424 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
425 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
426 return PSA_ERROR_INSUFFICIENT_ENTROPY;
427
428#if defined(MBEDTLS_GCM_C)
429 case MBEDTLS_ERR_GCM_AUTH_FAILED:
430 return PSA_ERROR_INVALID_SIGNATURE;
431 case MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL:
432 return PSA_ERROR_BUFFER_TOO_SMALL;
433 case MBEDTLS_ERR_GCM_BAD_INPUT:
434 return PSA_ERROR_INVALID_ARGUMENT;
435#endif
436
437#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \
438 defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
439 /* Only check HMAC_DRBG error codes if underlying mbedtls_xxx
440 * functions are passed a HMAC_DRBG instance. */
441 case MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED:
442 return PSA_ERROR_INSUFFICIENT_ENTROPY;
443 case MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG:
444 case MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG:
445 return PSA_ERROR_NOT_SUPPORTED;
446 case MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR:
447 return PSA_ERROR_INSUFFICIENT_ENTROPY;
448#endif
449
450#if defined(MBEDTLS_MD_LIGHT)
451 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
452 return PSA_ERROR_NOT_SUPPORTED;
453 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
454 return PSA_ERROR_INVALID_ARGUMENT;
455 case MBEDTLS_ERR_MD_ALLOC_FAILED:
456 return PSA_ERROR_INSUFFICIENT_MEMORY;
457#if defined(MBEDTLS_FS_IO)
458 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
459 return PSA_ERROR_STORAGE_FAILURE;
460#endif
461#endif
462
463#if defined(MBEDTLS_BIGNUM_C)
464#if defined(MBEDTLS_FS_IO)
465 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
466 return PSA_ERROR_STORAGE_FAILURE;
467#endif
468 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
469 return PSA_ERROR_INVALID_ARGUMENT;
470 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
471 return PSA_ERROR_INVALID_ARGUMENT;
472 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
473 return PSA_ERROR_BUFFER_TOO_SMALL;
474 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
475 return PSA_ERROR_INVALID_ARGUMENT;
476 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
477 return PSA_ERROR_INVALID_ARGUMENT;
478 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
479 return PSA_ERROR_INVALID_ARGUMENT;
480 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
481 return PSA_ERROR_INSUFFICIENT_MEMORY;
482#endif
483
484#if defined(MBEDTLS_PK_C)
485 case MBEDTLS_ERR_PK_ALLOC_FAILED:
486 return PSA_ERROR_INSUFFICIENT_MEMORY;
487 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
488 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
489 return PSA_ERROR_INVALID_ARGUMENT;
490#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || defined(MBEDTLS_FS_IO) || \
491 defined(MBEDTLS_PSA_ITS_FILE_C)
492 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
493 return PSA_ERROR_STORAGE_FAILURE;
494#endif
495 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
496 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
497 return PSA_ERROR_INVALID_ARGUMENT;
498 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
499 return PSA_ERROR_NOT_SUPPORTED;
500 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
501 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
502 return PSA_ERROR_NOT_PERMITTED;
503 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
504 return PSA_ERROR_INVALID_ARGUMENT;
505 case MBEDTLS_ERR_PK_INVALID_ALG:
506 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
507 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
508 return PSA_ERROR_NOT_SUPPORTED;
509 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
510 return PSA_ERROR_INVALID_SIGNATURE;
511 case MBEDTLS_ERR_PK_BUFFER_TOO_SMALL:
512 return PSA_ERROR_BUFFER_TOO_SMALL;
513#endif
514
515 case MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED:
516 return PSA_ERROR_HARDWARE_FAILURE;
517 case MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
518 return PSA_ERROR_NOT_SUPPORTED;
519
520#if defined(MBEDTLS_RSA_C)
521 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
522 return PSA_ERROR_INVALID_ARGUMENT;
523 case MBEDTLS_ERR_RSA_INVALID_PADDING:
524 return PSA_ERROR_INVALID_PADDING;
525 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
526 return PSA_ERROR_HARDWARE_FAILURE;
527 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
528 return PSA_ERROR_INVALID_ARGUMENT;
529 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
530 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
531 return PSA_ERROR_CORRUPTION_DETECTED;
532 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
533 return PSA_ERROR_INVALID_SIGNATURE;
534 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
535 return PSA_ERROR_BUFFER_TOO_SMALL;
536 case MBEDTLS_ERR_RSA_RNG_FAILED:
537 return PSA_ERROR_INSUFFICIENT_ENTROPY;
538#endif
539
540#if defined(MBEDTLS_ECP_LIGHT)
541 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
542 case MBEDTLS_ERR_ECP_INVALID_KEY:
543 return PSA_ERROR_INVALID_ARGUMENT;
544 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
545 return PSA_ERROR_BUFFER_TOO_SMALL;
546 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
547 return PSA_ERROR_NOT_SUPPORTED;
548 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
549 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
550 return PSA_ERROR_INVALID_SIGNATURE;
551 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
552 return PSA_ERROR_INSUFFICIENT_MEMORY;
553 case MBEDTLS_ERR_ECP_RANDOM_FAILED:
554 return PSA_ERROR_INSUFFICIENT_ENTROPY;
555
556#if defined(MBEDTLS_ECP_RESTARTABLE)
557 case MBEDTLS_ERR_ECP_IN_PROGRESS:
558 return PSA_OPERATION_INCOMPLETE;
559#endif
560#endif
561
562 case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
563 return PSA_ERROR_CORRUPTION_DETECTED;
564
565 default:
566 return PSA_ERROR_GENERIC_ERROR;
567 }
568}
569
570/**
571 * \brief For output buffers which contain "tags"
572 * (outputs that may be checked for validity like
573 * hashes, MACs and signatures), fill the unused
574 * part of the output buffer (the whole buffer on
575 * error, the trailing part on success) with
576 * something that isn't a valid tag (barring an
577 * attack on the tag and deliberately-crafted
578 * input), in case the caller doesn't check the
579 * return status properly.
580 *
581 * \param output_buffer Pointer to buffer to wipe. May not be NULL
582 * unless \p output_buffer_size is zero.
583 * \param status Status of function called to generate
584 * output_buffer originally
585 * \param output_buffer_size Size of output buffer. If zero, \p output_buffer
586 * could be NULL.
587 * \param output_buffer_length Length of data written to output_buffer, must be
588 * less than \p output_buffer_size
589 */
590static void psa_wipe_tag_output_buffer(uint8_t *output_buffer, psa_status_t status,
591 size_t output_buffer_size, size_t output_buffer_length)
592{
593 size_t offset = 0;
594
595 if (output_buffer_size == 0) {
596 /* If output_buffer_size is 0 then we have nothing to do. We must not
597 call memset because output_buffer may be NULL in this case */
598 return;
599 }
600
601 if (status == PSA_SUCCESS) {
602 offset = output_buffer_length;
603 }
604
605 memset(output_buffer + offset, '!', output_buffer_size - offset);
606}
607
608
609psa_status_t psa_validate_unstructured_key_bit_size(psa_key_type_t type,
610 size_t bits)
611{
612 /* Check that the bit size is acceptable for the key type */
613 switch (type) {
614 case PSA_KEY_TYPE_RAW_DATA:
615 case PSA_KEY_TYPE_HMAC:
616 case PSA_KEY_TYPE_DERIVE:
617 case PSA_KEY_TYPE_PASSWORD:
618 case PSA_KEY_TYPE_PASSWORD_HASH:
619 break;
620#if defined(PSA_WANT_KEY_TYPE_AES)
621 case PSA_KEY_TYPE_AES:
622 if (bits != 128 && bits != 192 && bits != 256) {
623 return PSA_ERROR_INVALID_ARGUMENT;
624 }
625 break;
626#endif
627#if defined(PSA_WANT_KEY_TYPE_ARIA)
628 case PSA_KEY_TYPE_ARIA:
629 if (bits != 128 && bits != 192 && bits != 256) {
630 return PSA_ERROR_INVALID_ARGUMENT;
631 }
632 break;
633#endif
634#if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
635 case PSA_KEY_TYPE_CAMELLIA:
636 if (bits != 128 && bits != 192 && bits != 256) {
637 return PSA_ERROR_INVALID_ARGUMENT;
638 }
639 break;
640#endif
641#if defined(PSA_WANT_KEY_TYPE_DES)
642 case PSA_KEY_TYPE_DES:
643 if (bits != 64 && bits != 128 && bits != 192) {
644 return PSA_ERROR_INVALID_ARGUMENT;
645 }
646 break;
647#endif
648#if defined(PSA_WANT_KEY_TYPE_CHACHA20)
649 case PSA_KEY_TYPE_CHACHA20:
650 if (bits != 256) {
651 return PSA_ERROR_INVALID_ARGUMENT;
652 }
653 break;
654#endif
655 default:
656 return PSA_ERROR_NOT_SUPPORTED;
657 }
658 if (bits % 8 != 0) {
659 return PSA_ERROR_INVALID_ARGUMENT;
660 }
661
662 return PSA_SUCCESS;
663}
664
665/** Check whether a given key type is valid for use with a given MAC algorithm
666 *
667 * Upon successful return of this function, the behavior of #PSA_MAC_LENGTH
668 * when called with the validated \p algorithm and \p key_type is well-defined.
669 *
670 * \param[in] algorithm The specific MAC algorithm (can be wildcard).
671 * \param[in] key_type The key type of the key to be used with the
672 * \p algorithm.
673 *
674 * \retval #PSA_SUCCESS
675 * The \p key_type is valid for use with the \p algorithm
676 * \retval #PSA_ERROR_INVALID_ARGUMENT
677 * The \p key_type is not valid for use with the \p algorithm
678 */
679MBEDTLS_STATIC_TESTABLE psa_status_t psa_mac_key_can_do(
680 psa_algorithm_t algorithm,
681 psa_key_type_t key_type)
682{
683 if (PSA_ALG_IS_HMAC(algorithm)) {
684 if (key_type == PSA_KEY_TYPE_HMAC) {
685 return PSA_SUCCESS;
686 }
687 }
688
689 if (PSA_ALG_IS_BLOCK_CIPHER_MAC(algorithm)) {
690 /* Check that we're calling PSA_BLOCK_CIPHER_BLOCK_LENGTH with a cipher
691 * key. */
692 if ((key_type & PSA_KEY_TYPE_CATEGORY_MASK) ==
693 PSA_KEY_TYPE_CATEGORY_SYMMETRIC) {
694 /* PSA_BLOCK_CIPHER_BLOCK_LENGTH returns 1 for stream ciphers and
695 * the block length (larger than 1) for block ciphers. */
696 if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1) {
697 return PSA_SUCCESS;
698 }
699 }
700 }
701
702 return PSA_ERROR_INVALID_ARGUMENT;
703}
704
705psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot,
706 size_t buffer_length)
707{
708 if (slot->key.data != NULL) {
709 return PSA_ERROR_ALREADY_EXISTS;
710 }
711
712 slot->key.data = mbedtls_calloc(1, buffer_length);
713 if (slot->key.data == NULL) {
714 return PSA_ERROR_INSUFFICIENT_MEMORY;
715 }
716
717 slot->key.bytes = buffer_length;
718 return PSA_SUCCESS;
719}
720
721psa_status_t psa_copy_key_material_into_slot(psa_key_slot_t *slot,
722 const uint8_t *data,
723 size_t data_length)
724{
725 psa_status_t status = psa_allocate_buffer_to_slot(slot,
726 data_length);
727 if (status != PSA_SUCCESS) {
728 return status;
729 }
730
731 memcpy(slot->key.data, data, data_length);
732 return PSA_SUCCESS;
733}
734
735psa_status_t psa_import_key_into_slot(
736 const psa_key_attributes_t *attributes,
737 const uint8_t *data, size_t data_length,
738 uint8_t *key_buffer, size_t key_buffer_size,
739 size_t *key_buffer_length, size_t *bits)
740{
741 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
742 psa_key_type_t type = attributes->type;
743
744 /* zero-length keys are never supported. */
745 if (data_length == 0) {
746 return PSA_ERROR_NOT_SUPPORTED;
747 }
748
749 if (key_type_is_raw_bytes(type)) {
750 *bits = PSA_BYTES_TO_BITS(data_length);
751
752 status = psa_validate_unstructured_key_bit_size(attributes->type,
753 *bits);
754 if (status != PSA_SUCCESS) {
755 return status;
756 }
757
758 /* Copy the key material. */
759 memcpy(key_buffer, data, data_length);
760 *key_buffer_length = data_length;
761 (void) key_buffer_size;
762
763 return PSA_SUCCESS;
764 } else if (PSA_KEY_TYPE_IS_ASYMMETRIC(type)) {
765#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \
766 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
767 if (PSA_KEY_TYPE_IS_DH(type)) {
768 if (psa_is_dh_key_size_valid(PSA_BYTES_TO_BITS(data_length)) == 0) {
769 return PSA_ERROR_NOT_SUPPORTED;
770 }
771 return mbedtls_psa_ffdh_import_key(attributes,
772 data, data_length,
773 key_buffer, key_buffer_size,
774 key_buffer_length,
775 bits);
776 }
777#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) ||
778 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */
779#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
780 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
781 if (PSA_KEY_TYPE_IS_ECC(type)) {
782 return mbedtls_psa_ecp_import_key(attributes,
783 data, data_length,
784 key_buffer, key_buffer_size,
785 key_buffer_length,
786 bits);
787 }
788#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) ||
789 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
790#if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && \
791 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || \
792 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
793 if (PSA_KEY_TYPE_IS_RSA(type)) {
794 return mbedtls_psa_rsa_import_key(attributes,
795 data, data_length,
796 key_buffer, key_buffer_size,
797 key_buffer_length,
798 bits);
799 }
800#endif /* (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) &&
801 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) ||
802 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
803 }
804
805 return PSA_ERROR_NOT_SUPPORTED;
806}
807
808/** Calculate the intersection of two algorithm usage policies.
809 *
810 * Return 0 (which allows no operation) on incompatibility.
811 */
812static psa_algorithm_t psa_key_policy_algorithm_intersection(
813 psa_key_type_t key_type,
814 psa_algorithm_t alg1,
815 psa_algorithm_t alg2)
816{
817 /* Common case: both sides actually specify the same policy. */
818 if (alg1 == alg2) {
819 return alg1;
820 }
821 /* If the policies are from the same hash-and-sign family, check
822 * if one is a wildcard. If so the other has the specific algorithm. */
823 if (PSA_ALG_IS_SIGN_HASH(alg1) &&
824 PSA_ALG_IS_SIGN_HASH(alg2) &&
825 (alg1 & ~PSA_ALG_HASH_MASK) == (alg2 & ~PSA_ALG_HASH_MASK)) {
826 if (PSA_ALG_SIGN_GET_HASH(alg1) == PSA_ALG_ANY_HASH) {
827 return alg2;
828 }
829 if (PSA_ALG_SIGN_GET_HASH(alg2) == PSA_ALG_ANY_HASH) {
830 return alg1;
831 }
832 }
833 /* If the policies are from the same AEAD family, check whether
834 * one of them is a minimum-tag-length wildcard. Calculate the most
835 * restrictive tag length. */
836 if (PSA_ALG_IS_AEAD(alg1) && PSA_ALG_IS_AEAD(alg2) &&
837 (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg1, 0) ==
838 PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg2, 0))) {
839 size_t alg1_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg1);
840 size_t alg2_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg2);
841 size_t restricted_len = alg1_len > alg2_len ? alg1_len : alg2_len;
842
843 /* If both are wildcards, return most restrictive wildcard */
844 if (((alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) &&
845 ((alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0)) {
846 return PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(
847 alg1, restricted_len);
848 }
849 /* If only one is a wildcard, return specific algorithm if compatible. */
850 if (((alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) &&
851 (alg1_len <= alg2_len)) {
852 return alg2;
853 }
854 if (((alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) &&
855 (alg2_len <= alg1_len)) {
856 return alg1;
857 }
858 }
859 /* If the policies are from the same MAC family, check whether one
860 * of them is a minimum-MAC-length policy. Calculate the most
861 * restrictive tag length. */
862 if (PSA_ALG_IS_MAC(alg1) && PSA_ALG_IS_MAC(alg2) &&
863 (PSA_ALG_FULL_LENGTH_MAC(alg1) ==
864 PSA_ALG_FULL_LENGTH_MAC(alg2))) {
865 /* Validate the combination of key type and algorithm. Since the base
866 * algorithm of alg1 and alg2 are the same, we only need this once. */
867 if (PSA_SUCCESS != psa_mac_key_can_do(alg1, key_type)) {
868 return 0;
869 }
870
871 /* Get the (exact or at-least) output lengths for both sides of the
872 * requested intersection. None of the currently supported algorithms
873 * have an output length dependent on the actual key size, so setting it
874 * to a bogus value of 0 is currently OK.
875 *
876 * Note that for at-least-this-length wildcard algorithms, the output
877 * length is set to the shortest allowed length, which allows us to
878 * calculate the most restrictive tag length for the intersection. */
879 size_t alg1_len = PSA_MAC_LENGTH(key_type, 0, alg1);
880 size_t alg2_len = PSA_MAC_LENGTH(key_type, 0, alg2);
881 size_t restricted_len = alg1_len > alg2_len ? alg1_len : alg2_len;
882
883 /* If both are wildcards, return most restrictive wildcard */
884 if (((alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) &&
885 ((alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0)) {
886 return PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(alg1, restricted_len);
887 }
888
889 /* If only one is an at-least-this-length policy, the intersection would
890 * be the other (fixed-length) policy as long as said fixed length is
891 * equal to or larger than the shortest allowed length. */
892 if ((alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) {
893 return (alg1_len <= alg2_len) ? alg2 : 0;
894 }
895 if ((alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) {
896 return (alg2_len <= alg1_len) ? alg1 : 0;
897 }
898
899 /* If none of them are wildcards, check whether they define the same tag
900 * length. This is still possible here when one is default-length and
901 * the other specific-length. Ensure to always return the
902 * specific-length version for the intersection. */
903 if (alg1_len == alg2_len) {
904 return PSA_ALG_TRUNCATED_MAC(alg1, alg1_len);
905 }
906 }
907 /* If the policies are incompatible, allow nothing. */
908 return 0;
909}
910
911static int psa_key_algorithm_permits(psa_key_type_t key_type,
912 psa_algorithm_t policy_alg,
913 psa_algorithm_t requested_alg)
914{
915 /* Common case: the policy only allows requested_alg. */
916 if (requested_alg == policy_alg) {
917 return 1;
918 }
919 /* If policy_alg is a hash-and-sign with a wildcard for the hash,
920 * and requested_alg is the same hash-and-sign family with any hash,
921 * then requested_alg is compliant with policy_alg. */
922 if (PSA_ALG_IS_SIGN_HASH(requested_alg) &&
923 PSA_ALG_SIGN_GET_HASH(policy_alg) == PSA_ALG_ANY_HASH) {
924 return (policy_alg & ~PSA_ALG_HASH_MASK) ==
925 (requested_alg & ~PSA_ALG_HASH_MASK);
926 }
927 /* If policy_alg is a wildcard AEAD algorithm of the same base as
928 * the requested algorithm, check the requested tag length to be
929 * equal-length or longer than the wildcard-specified length. */
930 if (PSA_ALG_IS_AEAD(policy_alg) &&
931 PSA_ALG_IS_AEAD(requested_alg) &&
932 (PSA_ALG_AEAD_WITH_SHORTENED_TAG(policy_alg, 0) ==
933 PSA_ALG_AEAD_WITH_SHORTENED_TAG(requested_alg, 0)) &&
934 ((policy_alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0)) {
935 return PSA_ALG_AEAD_GET_TAG_LENGTH(policy_alg) <=
936 PSA_ALG_AEAD_GET_TAG_LENGTH(requested_alg);
937 }
938 /* If policy_alg is a MAC algorithm of the same base as the requested
939 * algorithm, check whether their MAC lengths are compatible. */
940 if (PSA_ALG_IS_MAC(policy_alg) &&
941 PSA_ALG_IS_MAC(requested_alg) &&
942 (PSA_ALG_FULL_LENGTH_MAC(policy_alg) ==
943 PSA_ALG_FULL_LENGTH_MAC(requested_alg))) {
944 /* Validate the combination of key type and algorithm. Since the policy
945 * and requested algorithms are the same, we only need this once. */
946 if (PSA_SUCCESS != psa_mac_key_can_do(policy_alg, key_type)) {
947 return 0;
948 }
949
950 /* Get both the requested output length for the algorithm which is to be
951 * verified, and the default output length for the base algorithm.
952 * Note that none of the currently supported algorithms have an output
953 * length dependent on actual key size, so setting it to a bogus value
954 * of 0 is currently OK. */
955 size_t requested_output_length = PSA_MAC_LENGTH(
956 key_type, 0, requested_alg);
957 size_t default_output_length = PSA_MAC_LENGTH(
958 key_type, 0,
959 PSA_ALG_FULL_LENGTH_MAC(requested_alg));
960
961 /* If the policy is default-length, only allow an algorithm with
962 * a declared exact-length matching the default. */
963 if (PSA_MAC_TRUNCATED_LENGTH(policy_alg) == 0) {
964 return requested_output_length == default_output_length;
965 }
966
967 /* If the requested algorithm is default-length, allow it if the policy
968 * length exactly matches the default length. */
969 if (PSA_MAC_TRUNCATED_LENGTH(requested_alg) == 0 &&
970 PSA_MAC_TRUNCATED_LENGTH(policy_alg) == default_output_length) {
971 return 1;
972 }
973
974 /* If policy_alg is an at-least-this-length wildcard MAC algorithm,
975 * check for the requested MAC length to be equal to or longer than the
976 * minimum allowed length. */
977 if ((policy_alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) {
978 return PSA_MAC_TRUNCATED_LENGTH(policy_alg) <=
979 requested_output_length;
980 }
981 }
982 /* If policy_alg is a generic key agreement operation, then using it for
983 * a key derivation with that key agreement should also be allowed. This
984 * behaviour is expected to be defined in a future specification version. */
985 if (PSA_ALG_IS_RAW_KEY_AGREEMENT(policy_alg) &&
986 PSA_ALG_IS_KEY_AGREEMENT(requested_alg)) {
987 return PSA_ALG_KEY_AGREEMENT_GET_BASE(requested_alg) ==
988 policy_alg;
989 }
990 /* If it isn't explicitly permitted, it's forbidden. */
991 return 0;
992}
993
994/** Test whether a policy permits an algorithm.
995 *
996 * The caller must test usage flags separately.
997 *
998 * \note This function requires providing the key type for which the policy is
999 * being validated, since some algorithm policy definitions (e.g. MAC)
1000 * have different properties depending on what kind of cipher it is
1001 * combined with.
1002 *
1003 * \retval PSA_SUCCESS When \p alg is a specific algorithm
1004 * allowed by the \p policy.
1005 * \retval PSA_ERROR_INVALID_ARGUMENT When \p alg is not a specific algorithm
1006 * \retval PSA_ERROR_NOT_PERMITTED When \p alg is a specific algorithm, but
1007 * the \p policy does not allow it.
1008 */
1009static psa_status_t psa_key_policy_permits(const psa_key_policy_t *policy,
1010 psa_key_type_t key_type,
1011 psa_algorithm_t alg)
1012{
1013 /* '0' is not a valid algorithm */
1014 if (alg == 0) {
1015 return PSA_ERROR_INVALID_ARGUMENT;
1016 }
1017
1018 /* A requested algorithm cannot be a wildcard. */
1019 if (PSA_ALG_IS_WILDCARD(alg)) {
1020 return PSA_ERROR_INVALID_ARGUMENT;
1021 }
1022
1023 if (psa_key_algorithm_permits(key_type, policy->alg, alg) ||
1024 psa_key_algorithm_permits(key_type, policy->alg2, alg)) {
1025 return PSA_SUCCESS;
1026 } else {
1027 return PSA_ERROR_NOT_PERMITTED;
1028 }
1029}
1030
1031/** Restrict a key policy based on a constraint.
1032 *
1033 * \note This function requires providing the key type for which the policy is
1034 * being restricted, since some algorithm policy definitions (e.g. MAC)
1035 * have different properties depending on what kind of cipher it is
1036 * combined with.
1037 *
1038 * \param[in] key_type The key type for which to restrict the policy
1039 * \param[in,out] policy The policy to restrict.
1040 * \param[in] constraint The policy constraint to apply.
1041 *
1042 * \retval #PSA_SUCCESS
1043 * \c *policy contains the intersection of the original value of
1044 * \c *policy and \c *constraint.
1045 * \retval #PSA_ERROR_INVALID_ARGUMENT
1046 * \c key_type, \c *policy and \c *constraint are incompatible.
1047 * \c *policy is unchanged.
1048 */
1049static psa_status_t psa_restrict_key_policy(
1050 psa_key_type_t key_type,
1051 psa_key_policy_t *policy,
1052 const psa_key_policy_t *constraint)
1053{
1054 psa_algorithm_t intersection_alg =
1055 psa_key_policy_algorithm_intersection(key_type, policy->alg,
1056 constraint->alg);
1057 psa_algorithm_t intersection_alg2 =
1058 psa_key_policy_algorithm_intersection(key_type, policy->alg2,
1059 constraint->alg2);
1060 if (intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0) {
1061 return PSA_ERROR_INVALID_ARGUMENT;
1062 }
1063 if (intersection_alg2 == 0 && policy->alg2 != 0 && constraint->alg2 != 0) {
1064 return PSA_ERROR_INVALID_ARGUMENT;
1065 }
1066 policy->usage &= constraint->usage;
1067 policy->alg = intersection_alg;
1068 policy->alg2 = intersection_alg2;
1069 return PSA_SUCCESS;
1070}
1071
1072/** Get the description of a key given its identifier and policy constraints
1073 * and lock it.
1074 *
1075 * The key must have allow all the usage flags set in \p usage. If \p alg is
1076 * nonzero, the key must allow operations with this algorithm. If \p alg is
1077 * zero, the algorithm is not checked.
1078 *
1079 * In case of a persistent key, the function loads the description of the key
1080 * into a key slot if not already done.
1081 *
1082 * On success, the returned key slot has been registered for reading.
1083 * It is the responsibility of the caller to then unregister
1084 * once they have finished reading the contents of the slot.
1085 * The caller unregisters by calling psa_unregister_read() or
1086 * psa_unregister_read_under_mutex(). psa_unregister_read() must be called
1087 * if and only if the caller already holds the global key slot mutex
1088 * (when mutexes are enabled). psa_unregister_read_under_mutex() encapsulates
1089 * the unregister with mutex lock and unlock operations.
1090 */
1091static psa_status_t psa_get_and_lock_key_slot_with_policy(
1092 mbedtls_svc_key_id_t key,
1093 psa_key_slot_t **p_slot,
1094 psa_key_usage_t usage,
1095 psa_algorithm_t alg)
1096{
1097 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1098 psa_key_slot_t *slot = NULL;
1099
1100 status = psa_get_and_lock_key_slot(key, p_slot);
1101 if (status != PSA_SUCCESS) {
1102 return status;
1103 }
1104 slot = *p_slot;
1105
1106 /* Enforce that usage policy for the key slot contains all the flags
1107 * required by the usage parameter. There is one exception: public
1108 * keys can always be exported, so we treat public key objects as
1109 * if they had the export flag. */
1110 if (PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type)) {
1111 usage &= ~PSA_KEY_USAGE_EXPORT;
1112 }
1113
1114 if ((slot->attr.policy.usage & usage) != usage) {
1115 status = PSA_ERROR_NOT_PERMITTED;
1116 goto error;
1117 }
1118
1119 /* Enforce that the usage policy permits the requested algorithm. */
1120 if (alg != 0) {
1121 status = psa_key_policy_permits(&slot->attr.policy,
1122 slot->attr.type,
1123 alg);
1124 if (status != PSA_SUCCESS) {
1125 goto error;
1126 }
1127 }
1128
1129 return PSA_SUCCESS;
1130
1131error:
1132 *p_slot = NULL;
1133 psa_unregister_read_under_mutex(slot);
1134
1135 return status;
1136}
1137
1138/** Get a key slot containing a transparent key and lock it.
1139 *
1140 * A transparent key is a key for which the key material is directly
1141 * available, as opposed to a key in a secure element and/or to be used
1142 * by a secure element.
1143 *
1144 * This is a temporary function that may be used instead of
1145 * psa_get_and_lock_key_slot_with_policy() when there is no opaque key support
1146 * for a cryptographic operation.
1147 *
1148 * On success, the returned key slot has been registered for reading.
1149 * It is the responsibility of the caller to then unregister
1150 * once they have finished reading the contents of the slot.
1151 * The caller unregisters by calling psa_unregister_read() or
1152 * psa_unregister_read_under_mutex(). psa_unregister_read() must be called
1153 * if and only if the caller already holds the global key slot mutex
1154 * (when mutexes are enabled). psa_unregister_read_under_mutex() encapsulates
1155 * psa_unregister_read() with mutex lock and unlock operations.
1156 */
1157static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
1158 mbedtls_svc_key_id_t key,
1159 psa_key_slot_t **p_slot,
1160 psa_key_usage_t usage,
1161 psa_algorithm_t alg)
1162{
1163 psa_status_t status = psa_get_and_lock_key_slot_with_policy(key, p_slot,
1164 usage, alg);
1165 if (status != PSA_SUCCESS) {
1166 return status;
1167 }
1168
1169 if (psa_key_lifetime_is_external((*p_slot)->attr.lifetime)) {
1170 psa_unregister_read_under_mutex(*p_slot);
1171 *p_slot = NULL;
1172 return PSA_ERROR_NOT_SUPPORTED;
1173 }
1174
1175 return PSA_SUCCESS;
1176}
1177
1178psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot)
1179{
1180 if (slot->key.data != NULL) {
1181 mbedtls_zeroize_and_free(slot->key.data, slot->key.bytes);
1182 }
1183
1184 slot->key.data = NULL;
1185 slot->key.bytes = 0;
1186
1187 return PSA_SUCCESS;
1188}
1189
1190/** Completely wipe a slot in memory, including its policy.
1191 * Persistent storage is not affected. */
1192psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot)
1193{
1194 psa_status_t status = psa_remove_key_data_from_memory(slot);
1195
1196 /*
1197 * As the return error code may not be handled in case of multiple errors,
1198 * do our best to report an unexpected amount of registered readers or
1199 * an unexpected state.
1200 * Assert with MBEDTLS_TEST_HOOK_TEST_ASSERT that the slot is valid for
1201 * wiping.
1202 * if the MBEDTLS_TEST_HOOKS configuration option is enabled and the
1203 * function is called as part of the execution of a test suite, the
1204 * execution of the test suite is stopped in error if the assertion fails.
1205 */
1206 switch (slot->state) {
1207 case PSA_SLOT_FULL:
1208 /* In this state psa_wipe_key_slot() must only be called if the
1209 * caller is the last reader. */
1210 case PSA_SLOT_PENDING_DELETION:
1211 /* In this state psa_wipe_key_slot() must only be called if the
1212 * caller is the last reader. */
Sungbae Yoo4d211f32024-11-19 02:47:55 +00001213 if (slot->var.occupied.registered_readers != 1) {
1214 MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->var.occupied.registered_readers == 1);
Tom Van Eyckb0563632024-06-13 16:20:14 +02001215 status = PSA_ERROR_CORRUPTION_DETECTED;
1216 }
1217 break;
1218 case PSA_SLOT_FILLING:
1219 /* In this state registered_readers must be 0. */
Sungbae Yoo4d211f32024-11-19 02:47:55 +00001220 if (slot->var.occupied.registered_readers != 0) {
1221 MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->var.occupied.registered_readers == 0);
Tom Van Eyckb0563632024-06-13 16:20:14 +02001222 status = PSA_ERROR_CORRUPTION_DETECTED;
1223 }
1224 break;
1225 case PSA_SLOT_EMPTY:
1226 /* The slot is already empty, it cannot be wiped. */
1227 MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->state != PSA_SLOT_EMPTY);
1228 status = PSA_ERROR_CORRUPTION_DETECTED;
1229 break;
1230 default:
1231 /* The slot's state is invalid. */
1232 status = PSA_ERROR_CORRUPTION_DETECTED;
1233 }
1234
Sungbae Yoo4d211f32024-11-19 02:47:55 +00001235#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
1236 size_t slice_index = slot->slice_index;
1237#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
1238
1239
Tom Van Eyckb0563632024-06-13 16:20:14 +02001240 /* Multipart operations may still be using the key. This is safe
1241 * because all multipart operation objects are independent from
1242 * the key slot: if they need to access the key after the setup
1243 * phase, they have a copy of the key. Note that this means that
1244 * key material can linger until all operations are completed. */
1245 /* At this point, key material and other type-specific content has
1246 * been wiped. Clear remaining metadata. We can call memset and not
1247 * zeroize because the metadata is not particularly sensitive.
1248 * This memset also sets the slot's state to PSA_SLOT_EMPTY. */
1249 memset(slot, 0, sizeof(*slot));
Sungbae Yoo4d211f32024-11-19 02:47:55 +00001250
1251#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
1252 /* If the slot is already corrupted, something went deeply wrong,
1253 * like a thread still using the slot or a stray pointer leading
1254 * to the slot's memory being used for another object. Let the slot
1255 * leak rather than make the corruption worse. */
1256 if (status == PSA_SUCCESS) {
1257 status = psa_free_key_slot(slice_index, slot);
1258 }
1259#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
1260
Tom Van Eyckb0563632024-06-13 16:20:14 +02001261 return status;
1262}
1263
1264psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
1265{
1266 psa_key_slot_t *slot;
1267 psa_status_t status; /* status of the last operation */
1268 psa_status_t overall_status = PSA_SUCCESS;
1269#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1270 psa_se_drv_table_entry_t *driver;
1271#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1272
1273 if (mbedtls_svc_key_id_is_null(key)) {
1274 return PSA_SUCCESS;
1275 }
1276
1277 /*
1278 * Get the description of the key in a key slot, and register to read it.
1279 * In the case of a persistent key, this will load the key description
1280 * from persistent memory if not done yet.
1281 * We cannot avoid this loading as without it we don't know if
1282 * the key is operated by an SE or not and this information is needed by
1283 * the current implementation. */
1284 status = psa_get_and_lock_key_slot(key, &slot);
1285 if (status != PSA_SUCCESS) {
1286 return status;
1287 }
1288
1289#if defined(MBEDTLS_THREADING_C)
1290 /* We cannot unlock between setting the state to PENDING_DELETION
1291 * and destroying the key in storage, as otherwise another thread
1292 * could load the key into a new slot and the key will not be
1293 * fully destroyed. */
1294 PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(
1295 &mbedtls_threading_key_slot_mutex));
1296
1297 if (slot->state == PSA_SLOT_PENDING_DELETION) {
1298 /* Another thread has destroyed the key between us locking the slot
1299 * and us gaining the mutex. Unregister from the slot,
1300 * and report that the key does not exist. */
1301 status = psa_unregister_read(slot);
1302
1303 PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
1304 &mbedtls_threading_key_slot_mutex));
1305 return (status == PSA_SUCCESS) ? PSA_ERROR_INVALID_HANDLE : status;
1306 }
1307#endif
1308 /* Set the key slot containing the key description's state to
1309 * PENDING_DELETION. This stops new operations from registering
1310 * to read the slot. Current readers can safely continue to access
1311 * the key within the slot; the last registered reader will
1312 * automatically wipe the slot when they call psa_unregister_read().
1313 * If the key is persistent, we can now delete the copy of the key
1314 * from memory. If the key is opaque, we require the driver to
1315 * deal with the deletion. */
1316 overall_status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL,
1317 PSA_SLOT_PENDING_DELETION);
1318
1319 if (overall_status != PSA_SUCCESS) {
1320 goto exit;
1321 }
1322
1323 if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) {
1324 /* Refuse the destruction of a read-only key (which may or may not work
1325 * if we attempt it, depending on whether the key is merely read-only
1326 * by policy or actually physically read-only).
1327 * Just do the best we can, which is to wipe the copy in memory
1328 * (done in this function's cleanup code). */
1329 overall_status = PSA_ERROR_NOT_PERMITTED;
1330 goto exit;
1331 }
1332
1333#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1334 driver = psa_get_se_driver_entry(slot->attr.lifetime);
1335 if (driver != NULL) {
1336 /* For a key in a secure element, we need to do three things:
1337 * remove the key file in internal storage, destroy the
1338 * key inside the secure element, and update the driver's
1339 * persistent data. Start a transaction that will encompass these
1340 * three actions. */
1341 psa_crypto_prepare_transaction(PSA_CRYPTO_TRANSACTION_DESTROY_KEY);
1342 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
1343 psa_crypto_transaction.key.slot = psa_key_slot_get_slot_number(slot);
1344 psa_crypto_transaction.key.id = slot->attr.id;
1345 status = psa_crypto_save_transaction();
1346 if (status != PSA_SUCCESS) {
1347 (void) psa_crypto_stop_transaction();
1348 /* We should still try to destroy the key in the secure
1349 * element and the key metadata in storage. This is especially
1350 * important if the error is that the storage is full.
1351 * But how to do it exactly without risking an inconsistent
1352 * state after a reset?
1353 * https://github.com/ARMmbed/mbed-crypto/issues/215
1354 */
1355 overall_status = status;
1356 goto exit;
1357 }
1358
1359 status = psa_destroy_se_key(driver,
1360 psa_key_slot_get_slot_number(slot));
1361 if (overall_status == PSA_SUCCESS) {
1362 overall_status = status;
1363 }
1364 }
1365#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1366
1367#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
1368 if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
1369 /* Destroy the copy of the persistent key from storage.
1370 * The slot will still hold a copy of the key until the last reader
1371 * unregisters. */
1372 status = psa_destroy_persistent_key(slot->attr.id);
1373 if (overall_status == PSA_SUCCESS) {
1374 overall_status = status;
1375 }
1376 }
1377#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1378
1379#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1380 if (driver != NULL) {
1381 status = psa_save_se_persistent_data(driver);
1382 if (overall_status == PSA_SUCCESS) {
1383 overall_status = status;
1384 }
1385 status = psa_crypto_stop_transaction();
1386 if (overall_status == PSA_SUCCESS) {
1387 overall_status = status;
1388 }
1389 }
1390#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1391
1392exit:
1393 /* Unregister from reading the slot. If we are the last active reader
1394 * then this will wipe the slot. */
1395 status = psa_unregister_read(slot);
1396 /* Prioritize CORRUPTION_DETECTED from unregistering over
1397 * a storage error. */
1398 if (status != PSA_SUCCESS) {
1399 overall_status = status;
1400 }
1401
1402#if defined(MBEDTLS_THREADING_C)
1403 /* Don't overwrite existing errors if the unlock fails. */
1404 status = overall_status;
1405 PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
1406 &mbedtls_threading_key_slot_mutex));
1407#endif
1408
1409 return overall_status;
1410}
1411
1412/** Retrieve all the publicly-accessible attributes of a key.
1413 */
1414psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key,
1415 psa_key_attributes_t *attributes)
1416{
1417 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1418 psa_key_slot_t *slot;
1419
1420 psa_reset_key_attributes(attributes);
1421
1422 status = psa_get_and_lock_key_slot_with_policy(key, &slot, 0, 0);
1423 if (status != PSA_SUCCESS) {
1424 return status;
1425 }
1426
1427 *attributes = slot->attr;
1428
1429#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1430 if (psa_get_se_driver_entry(slot->attr.lifetime) != NULL) {
1431 psa_set_key_slot_number(attributes,
1432 psa_key_slot_get_slot_number(slot));
1433 }
1434#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1435
1436 return psa_unregister_read_under_mutex(slot);
1437}
1438
1439#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1440psa_status_t psa_get_key_slot_number(
1441 const psa_key_attributes_t *attributes,
1442 psa_key_slot_number_t *slot_number)
1443{
1444 if (attributes->has_slot_number) {
1445 *slot_number = attributes->slot_number;
1446 return PSA_SUCCESS;
1447 } else {
1448 return PSA_ERROR_INVALID_ARGUMENT;
1449 }
1450}
1451#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1452
1453static psa_status_t psa_export_key_buffer_internal(const uint8_t *key_buffer,
1454 size_t key_buffer_size,
1455 uint8_t *data,
1456 size_t data_size,
1457 size_t *data_length)
1458{
1459 if (key_buffer_size > data_size) {
1460 return PSA_ERROR_BUFFER_TOO_SMALL;
1461 }
1462 memcpy(data, key_buffer, key_buffer_size);
1463 memset(data + key_buffer_size, 0,
1464 data_size - key_buffer_size);
1465 *data_length = key_buffer_size;
1466 return PSA_SUCCESS;
1467}
1468
1469psa_status_t psa_export_key_internal(
1470 const psa_key_attributes_t *attributes,
1471 const uint8_t *key_buffer, size_t key_buffer_size,
1472 uint8_t *data, size_t data_size, size_t *data_length)
1473{
1474 psa_key_type_t type = attributes->type;
1475
1476 if (key_type_is_raw_bytes(type) ||
1477 PSA_KEY_TYPE_IS_RSA(type) ||
1478 PSA_KEY_TYPE_IS_ECC(type) ||
1479 PSA_KEY_TYPE_IS_DH(type)) {
1480 return psa_export_key_buffer_internal(
1481 key_buffer, key_buffer_size,
1482 data, data_size, data_length);
1483 } else {
1484 /* This shouldn't happen in the reference implementation, but
1485 it is valid for a special-purpose implementation to omit
1486 support for exporting certain key types. */
1487 return PSA_ERROR_NOT_SUPPORTED;
1488 }
1489}
1490
1491psa_status_t psa_export_key(mbedtls_svc_key_id_t key,
1492 uint8_t *data_external,
1493 size_t data_size,
1494 size_t *data_length)
1495{
1496 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1497 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
1498 psa_key_slot_t *slot;
1499 LOCAL_OUTPUT_DECLARE(data_external, data);
1500
1501 /* Reject a zero-length output buffer now, since this can never be a
1502 * valid key representation. This way we know that data must be a valid
1503 * pointer and we can do things like memset(data, ..., data_size). */
1504 if (data_size == 0) {
1505 return PSA_ERROR_BUFFER_TOO_SMALL;
1506 }
1507
1508 /* Set the key to empty now, so that even when there are errors, we always
1509 * set data_length to a value between 0 and data_size. On error, setting
1510 * the key to empty is a good choice because an empty key representation is
1511 * unlikely to be accepted anywhere. */
1512 *data_length = 0;
1513
1514 /* Export requires the EXPORT flag. There is an exception for public keys,
1515 * which don't require any flag, but
1516 * psa_get_and_lock_key_slot_with_policy() takes care of this.
1517 */
1518 status = psa_get_and_lock_key_slot_with_policy(key, &slot,
1519 PSA_KEY_USAGE_EXPORT, 0);
1520 if (status != PSA_SUCCESS) {
1521 return status;
1522 }
1523
1524 LOCAL_OUTPUT_ALLOC(data_external, data_size, data);
1525
1526 status = psa_driver_wrapper_export_key(&slot->attr,
1527 slot->key.data, slot->key.bytes,
1528 data, data_size, data_length);
1529
1530#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
1531exit:
1532#endif
1533 unlock_status = psa_unregister_read_under_mutex(slot);
1534
1535 LOCAL_OUTPUT_FREE(data_external, data);
1536 return (status == PSA_SUCCESS) ? unlock_status : status;
1537}
1538
1539psa_status_t psa_export_public_key_internal(
1540 const psa_key_attributes_t *attributes,
1541 const uint8_t *key_buffer,
1542 size_t key_buffer_size,
1543 uint8_t *data,
1544 size_t data_size,
1545 size_t *data_length)
1546{
1547 psa_key_type_t type = attributes->type;
1548
1549 if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) &&
1550 (PSA_KEY_TYPE_IS_RSA(type) || PSA_KEY_TYPE_IS_ECC(type) ||
1551 PSA_KEY_TYPE_IS_DH(type))) {
1552 /* Exporting public -> public */
1553 return psa_export_key_buffer_internal(
1554 key_buffer, key_buffer_size,
1555 data, data_size, data_length);
1556 } else if (PSA_KEY_TYPE_IS_RSA(type)) {
1557#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
1558 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
1559 return mbedtls_psa_rsa_export_public_key(attributes,
1560 key_buffer,
1561 key_buffer_size,
1562 data,
1563 data_size,
1564 data_length);
1565#else
1566 /* We don't know how to convert a private RSA key to public. */
1567 return PSA_ERROR_NOT_SUPPORTED;
1568#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
1569 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
1570 } else if (PSA_KEY_TYPE_IS_ECC(type)) {
1571#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
1572 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
1573 return mbedtls_psa_ecp_export_public_key(attributes,
1574 key_buffer,
1575 key_buffer_size,
1576 data,
1577 data_size,
1578 data_length);
1579#else
1580 /* We don't know how to convert a private ECC key to public */
1581 return PSA_ERROR_NOT_SUPPORTED;
1582#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) ||
1583 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
1584 } else if (PSA_KEY_TYPE_IS_DH(type)) {
1585#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
1586 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
1587 return mbedtls_psa_ffdh_export_public_key(attributes,
1588 key_buffer,
1589 key_buffer_size,
1590 data, data_size,
1591 data_length);
1592#else
1593 return PSA_ERROR_NOT_SUPPORTED;
1594#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) ||
1595 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */
1596 } else {
1597 (void) key_buffer;
1598 (void) key_buffer_size;
1599 (void) data;
1600 (void) data_size;
1601 (void) data_length;
1602 return PSA_ERROR_NOT_SUPPORTED;
1603 }
1604}
1605
1606psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key,
1607 uint8_t *data_external,
1608 size_t data_size,
1609 size_t *data_length)
1610{
1611 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1612 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
1613 psa_key_slot_t *slot;
1614
1615 LOCAL_OUTPUT_DECLARE(data_external, data);
1616
1617 /* Reject a zero-length output buffer now, since this can never be a
1618 * valid key representation. This way we know that data must be a valid
1619 * pointer and we can do things like memset(data, ..., data_size). */
1620 if (data_size == 0) {
1621 return PSA_ERROR_BUFFER_TOO_SMALL;
1622 }
1623
1624 /* Set the key to empty now, so that even when there are errors, we always
1625 * set data_length to a value between 0 and data_size. On error, setting
1626 * the key to empty is a good choice because an empty key representation is
1627 * unlikely to be accepted anywhere. */
1628 *data_length = 0;
1629
1630 /* Exporting a public key doesn't require a usage flag. */
1631 status = psa_get_and_lock_key_slot_with_policy(key, &slot, 0, 0);
1632 if (status != PSA_SUCCESS) {
1633 return status;
1634 }
1635
1636 LOCAL_OUTPUT_ALLOC(data_external, data_size, data);
1637
1638 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(slot->attr.type)) {
1639 status = PSA_ERROR_INVALID_ARGUMENT;
1640 goto exit;
1641 }
1642
1643 status = psa_driver_wrapper_export_public_key(
1644 &slot->attr, slot->key.data, slot->key.bytes,
1645 data, data_size, data_length);
1646
1647exit:
1648 unlock_status = psa_unregister_read_under_mutex(slot);
1649
1650 LOCAL_OUTPUT_FREE(data_external, data);
1651 return (status == PSA_SUCCESS) ? unlock_status : status;
1652}
1653
1654/** Validate that a key policy is internally well-formed.
1655 *
1656 * This function only rejects invalid policies. It does not validate the
1657 * consistency of the policy with respect to other attributes of the key
1658 * such as the key type.
1659 */
1660static psa_status_t psa_validate_key_policy(const psa_key_policy_t *policy)
1661{
1662 if ((policy->usage & ~(PSA_KEY_USAGE_EXPORT |
1663 PSA_KEY_USAGE_COPY |
1664 PSA_KEY_USAGE_ENCRYPT |
1665 PSA_KEY_USAGE_DECRYPT |
1666 PSA_KEY_USAGE_SIGN_MESSAGE |
1667 PSA_KEY_USAGE_VERIFY_MESSAGE |
1668 PSA_KEY_USAGE_SIGN_HASH |
1669 PSA_KEY_USAGE_VERIFY_HASH |
1670 PSA_KEY_USAGE_VERIFY_DERIVATION |
1671 PSA_KEY_USAGE_DERIVE)) != 0) {
1672 return PSA_ERROR_INVALID_ARGUMENT;
1673 }
1674
1675 return PSA_SUCCESS;
1676}
1677
1678/** Validate the internal consistency of key attributes.
1679 *
1680 * This function only rejects invalid attribute values. If does not
1681 * validate the consistency of the attributes with any key data that may
1682 * be involved in the creation of the key.
1683 *
1684 * Call this function early in the key creation process.
1685 *
1686 * \param[in] attributes Key attributes for the new key.
1687 * \param[out] p_drv On any return, the driver for the key, if any.
1688 * NULL for a transparent key.
1689 *
1690 */
1691static psa_status_t psa_validate_key_attributes(
1692 const psa_key_attributes_t *attributes,
1693 psa_se_drv_table_entry_t **p_drv)
1694{
1695 psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
1696 psa_key_lifetime_t lifetime = psa_get_key_lifetime(attributes);
1697 mbedtls_svc_key_id_t key = psa_get_key_id(attributes);
1698
1699 status = psa_validate_key_location(lifetime, p_drv);
1700 if (status != PSA_SUCCESS) {
1701 return status;
1702 }
1703
1704 status = psa_validate_key_persistence(lifetime);
1705 if (status != PSA_SUCCESS) {
1706 return status;
1707 }
1708
1709 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
1710 if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key) != 0) {
1711 return PSA_ERROR_INVALID_ARGUMENT;
1712 }
1713 } else {
1714 if (!psa_is_valid_key_id(psa_get_key_id(attributes), 0)) {
1715 return PSA_ERROR_INVALID_ARGUMENT;
1716 }
1717 }
1718
1719 status = psa_validate_key_policy(&attributes->policy);
1720 if (status != PSA_SUCCESS) {
1721 return status;
1722 }
1723
1724 /* Refuse to create overly large keys.
1725 * Note that this doesn't trigger on import if the attributes don't
1726 * explicitly specify a size (so psa_get_key_bits returns 0), so
1727 * psa_import_key() needs its own checks. */
1728 if (psa_get_key_bits(attributes) > PSA_MAX_KEY_BITS) {
1729 return PSA_ERROR_NOT_SUPPORTED;
1730 }
1731
1732 return PSA_SUCCESS;
1733}
1734
1735/** Prepare a key slot to receive key material.
1736 *
1737 * This function allocates a key slot and sets its metadata.
1738 *
1739 * If this function fails, call psa_fail_key_creation().
1740 *
1741 * This function is intended to be used as follows:
1742 * -# Call psa_start_key_creation() to allocate a key slot, prepare
1743 * it with the specified attributes, and in case of a volatile key assign it
1744 * a volatile key identifier.
1745 * -# Populate the slot with the key material.
1746 * -# Call psa_finish_key_creation() to finalize the creation of the slot.
1747 * In case of failure at any step, stop the sequence and call
1748 * psa_fail_key_creation().
1749 *
1750 * On success, the key slot's state is PSA_SLOT_FILLING.
1751 * It is the responsibility of the caller to change the slot's state to
1752 * PSA_SLOT_EMPTY/FULL once key creation has finished.
1753 *
1754 * \param method An identification of the calling function.
1755 * \param[in] attributes Key attributes for the new key.
1756 * \param[out] p_slot On success, a pointer to the prepared slot.
1757 * \param[out] p_drv On any return, the driver for the key, if any.
1758 * NULL for a transparent key.
1759 *
1760 * \retval #PSA_SUCCESS
1761 * The key slot is ready to receive key material.
1762 * \return If this function fails, the key slot is an invalid state.
1763 * You must call psa_fail_key_creation() to wipe and free the slot.
1764 */
1765static psa_status_t psa_start_key_creation(
1766 psa_key_creation_method_t method,
1767 const psa_key_attributes_t *attributes,
1768 psa_key_slot_t **p_slot,
1769 psa_se_drv_table_entry_t **p_drv)
1770{
1771 psa_status_t status;
Tom Van Eyckb0563632024-06-13 16:20:14 +02001772
1773 (void) method;
1774 *p_drv = NULL;
1775
1776 status = psa_validate_key_attributes(attributes, p_drv);
1777 if (status != PSA_SUCCESS) {
1778 return status;
1779 }
1780
Sungbae Yoo4d211f32024-11-19 02:47:55 +00001781 int key_is_volatile = PSA_KEY_LIFETIME_IS_VOLATILE(attributes->lifetime);
1782 psa_key_id_t volatile_key_id;
1783
Tom Van Eyckb0563632024-06-13 16:20:14 +02001784#if defined(MBEDTLS_THREADING_C)
1785 PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
1786 &mbedtls_threading_key_slot_mutex));
1787#endif
Sungbae Yoo4d211f32024-11-19 02:47:55 +00001788 status = psa_reserve_free_key_slot(
1789 key_is_volatile ? &volatile_key_id : NULL,
1790 p_slot);
Tom Van Eyckb0563632024-06-13 16:20:14 +02001791#if defined(MBEDTLS_THREADING_C)
1792 PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
1793 &mbedtls_threading_key_slot_mutex));
1794#endif
1795 if (status != PSA_SUCCESS) {
1796 return status;
1797 }
Sungbae Yoo4d211f32024-11-19 02:47:55 +00001798 psa_key_slot_t *slot = *p_slot;
Tom Van Eyckb0563632024-06-13 16:20:14 +02001799
1800 /* We're storing the declared bit-size of the key. It's up to each
1801 * creation mechanism to verify that this information is correct.
1802 * It's automatically correct for mechanisms that use the bit-size as
1803 * an input (generate, device) but not for those where the bit-size
1804 * is optional (import, copy). In case of a volatile key, assign it the
1805 * volatile key identifier associated to the slot returned to contain its
1806 * definition. */
1807
1808 slot->attr = *attributes;
Sungbae Yoo4d211f32024-11-19 02:47:55 +00001809 if (key_is_volatile) {
Tom Van Eyckb0563632024-06-13 16:20:14 +02001810#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
1811 slot->attr.id = volatile_key_id;
1812#else
1813 slot->attr.id.key_id = volatile_key_id;
1814#endif
1815 }
1816
1817#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1818 /* For a key in a secure element, we need to do three things
1819 * when creating or registering a persistent key:
1820 * create the key file in internal storage, create the
1821 * key inside the secure element, and update the driver's
1822 * persistent data. This is done by starting a transaction that will
1823 * encompass these three actions.
1824 * For registering a volatile key, we just need to find an appropriate
1825 * slot number inside the SE. Since the key is designated volatile, creating
1826 * a transaction is not required. */
1827 /* The first thing to do is to find a slot number for the new key.
1828 * We save the slot number in persistent storage as part of the
1829 * transaction data. It will be needed to recover if the power
1830 * fails during the key creation process, to clean up on the secure
1831 * element side after restarting. Obtaining a slot number from the
1832 * secure element driver updates its persistent state, but we do not yet
1833 * save the driver's persistent state, so that if the power fails,
1834 * we can roll back to a state where the key doesn't exist. */
1835 if (*p_drv != NULL) {
1836 psa_key_slot_number_t slot_number;
1837 status = psa_find_se_slot_for_key(attributes, method, *p_drv,
1838 &slot_number);
1839 if (status != PSA_SUCCESS) {
1840 return status;
1841 }
1842
1843 if (!PSA_KEY_LIFETIME_IS_VOLATILE(attributes->lifetime)) {
1844 psa_crypto_prepare_transaction(PSA_CRYPTO_TRANSACTION_CREATE_KEY);
1845 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
1846 psa_crypto_transaction.key.slot = slot_number;
1847 psa_crypto_transaction.key.id = slot->attr.id;
1848 status = psa_crypto_save_transaction();
1849 if (status != PSA_SUCCESS) {
1850 (void) psa_crypto_stop_transaction();
1851 return status;
1852 }
1853 }
1854
1855 status = psa_copy_key_material_into_slot(
1856 slot, (uint8_t *) (&slot_number), sizeof(slot_number));
Sungbae Yoo4d211f32024-11-19 02:47:55 +00001857 if (status != PSA_SUCCESS) {
1858 return status;
1859 }
Tom Van Eyckb0563632024-06-13 16:20:14 +02001860 }
1861
1862 if (*p_drv == NULL && method == PSA_KEY_CREATION_REGISTER) {
1863 /* Key registration only makes sense with a secure element. */
1864 return PSA_ERROR_INVALID_ARGUMENT;
1865 }
1866#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1867
1868 return PSA_SUCCESS;
1869}
1870
1871/** Finalize the creation of a key once its key material has been set.
1872 *
1873 * This entails writing the key to persistent storage.
1874 *
1875 * If this function fails, call psa_fail_key_creation().
1876 * See the documentation of psa_start_key_creation() for the intended use
1877 * of this function.
1878 *
1879 * If the finalization succeeds, the function sets the key slot's state to
1880 * PSA_SLOT_FULL, and the key slot can no longer be accessed as part of the
1881 * key creation process.
1882 *
1883 * \param[in,out] slot Pointer to the slot with key material.
1884 * \param[in] driver The secure element driver for the key,
1885 * or NULL for a transparent key.
1886 * \param[out] key On success, identifier of the key. Note that the
1887 * key identifier is also stored in the key slot.
1888 *
1889 * \retval #PSA_SUCCESS
1890 * The key was successfully created.
1891 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
1892 * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
1893 * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
1894 * \retval #PSA_ERROR_DATA_INVALID \emptydescription
1895 * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
1896 * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
1897 *
1898 * \return If this function fails, the key slot is an invalid state.
1899 * You must call psa_fail_key_creation() to wipe and free the slot.
1900 */
1901static psa_status_t psa_finish_key_creation(
1902 psa_key_slot_t *slot,
1903 psa_se_drv_table_entry_t *driver,
1904 mbedtls_svc_key_id_t *key)
1905{
1906 psa_status_t status = PSA_SUCCESS;
1907 (void) slot;
1908 (void) driver;
1909
1910#if defined(MBEDTLS_THREADING_C)
1911 PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
1912 &mbedtls_threading_key_slot_mutex));
1913#endif
1914
1915#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
1916 if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
1917#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1918 if (driver != NULL) {
1919 psa_se_key_data_storage_t data;
1920 psa_key_slot_number_t slot_number =
1921 psa_key_slot_get_slot_number(slot);
1922
1923 MBEDTLS_STATIC_ASSERT(sizeof(slot_number) ==
1924 sizeof(data.slot_number),
1925 "Slot number size does not match psa_se_key_data_storage_t");
1926
1927 memcpy(&data.slot_number, &slot_number, sizeof(slot_number));
1928 status = psa_save_persistent_key(&slot->attr,
1929 (uint8_t *) &data,
1930 sizeof(data));
1931 } else
1932#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1933 {
1934 /* Key material is saved in export representation in the slot, so
1935 * just pass the slot buffer for storage. */
1936 status = psa_save_persistent_key(&slot->attr,
1937 slot->key.data,
1938 slot->key.bytes);
1939 }
1940 }
1941#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1942
1943#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1944 /* Finish the transaction for a key creation. This does not
1945 * happen when registering an existing key. Detect this case
1946 * by checking whether a transaction is in progress (actual
1947 * creation of a persistent key in a secure element requires a transaction,
1948 * but registration or volatile key creation doesn't use one). */
1949 if (driver != NULL &&
1950 psa_crypto_transaction.unknown.type == PSA_CRYPTO_TRANSACTION_CREATE_KEY) {
1951 status = psa_save_se_persistent_data(driver);
1952 if (status != PSA_SUCCESS) {
1953 psa_destroy_persistent_key(slot->attr.id);
1954
1955#if defined(MBEDTLS_THREADING_C)
1956 PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
1957 &mbedtls_threading_key_slot_mutex));
1958#endif
1959 return status;
1960 }
1961 status = psa_crypto_stop_transaction();
1962 }
1963#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1964
1965 if (status == PSA_SUCCESS) {
1966 *key = slot->attr.id;
1967 status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
1968 PSA_SLOT_FULL);
1969 if (status != PSA_SUCCESS) {
1970 *key = MBEDTLS_SVC_KEY_ID_INIT;
1971 }
1972 }
1973
1974#if defined(MBEDTLS_THREADING_C)
1975 PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
1976 &mbedtls_threading_key_slot_mutex));
1977#endif
1978 return status;
1979}
1980
1981/** Abort the creation of a key.
1982 *
1983 * You may call this function after calling psa_start_key_creation(),
1984 * or after psa_finish_key_creation() fails. In other circumstances, this
1985 * function may not clean up persistent storage.
1986 * See the documentation of psa_start_key_creation() for the intended use
1987 * of this function. Sets the slot's state to PSA_SLOT_EMPTY.
1988 *
1989 * \param[in,out] slot Pointer to the slot with key material.
1990 * \param[in] driver The secure element driver for the key,
1991 * or NULL for a transparent key.
1992 */
1993static void psa_fail_key_creation(psa_key_slot_t *slot,
1994 psa_se_drv_table_entry_t *driver)
1995{
1996 (void) driver;
1997
1998 if (slot == NULL) {
1999 return;
2000 }
2001
2002#if defined(MBEDTLS_THREADING_C)
2003 /* If the lock operation fails we still wipe the slot.
2004 * Operations will no longer work after a failed lock,
2005 * but we still need to wipe the slot of confidential data. */
2006 mbedtls_mutex_lock(&mbedtls_threading_key_slot_mutex);
2007#endif
2008
2009#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2010 /* TODO: If the key has already been created in the secure
2011 * element, and the failure happened later (when saving metadata
2012 * to internal storage), we need to destroy the key in the secure
2013 * element.
2014 * https://github.com/ARMmbed/mbed-crypto/issues/217
2015 */
2016
2017 /* Abort the ongoing transaction if any (there may not be one if
2018 * the creation process failed before starting one, or if the
2019 * key creation is a registration of a key in a secure element).
2020 * Earlier functions must already have done what it takes to undo any
2021 * partial creation. All that's left is to update the transaction data
2022 * itself. */
2023 (void) psa_crypto_stop_transaction();
2024#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2025
2026 psa_wipe_key_slot(slot);
2027
2028#if defined(MBEDTLS_THREADING_C)
2029 mbedtls_mutex_unlock(&mbedtls_threading_key_slot_mutex);
2030#endif
2031}
2032
2033/** Validate optional attributes during key creation.
2034 *
2035 * Some key attributes are optional during key creation. If they are
2036 * specified in the attributes structure, check that they are consistent
2037 * with the data in the slot.
2038 *
2039 * This function should be called near the end of key creation, after
2040 * the slot in memory is fully populated but before saving persistent data.
2041 */
2042static psa_status_t psa_validate_optional_attributes(
2043 const psa_key_slot_t *slot,
2044 const psa_key_attributes_t *attributes)
2045{
2046 if (attributes->type != 0) {
2047 if (attributes->type != slot->attr.type) {
2048 return PSA_ERROR_INVALID_ARGUMENT;
2049 }
2050 }
2051
2052 if (attributes->bits != 0) {
2053 if (attributes->bits != slot->attr.bits) {
2054 return PSA_ERROR_INVALID_ARGUMENT;
2055 }
2056 }
2057
2058 return PSA_SUCCESS;
2059}
2060
2061psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
2062 const uint8_t *data_external,
2063 size_t data_length,
2064 mbedtls_svc_key_id_t *key)
2065{
2066 psa_status_t status;
2067 LOCAL_INPUT_DECLARE(data_external, data);
2068 psa_key_slot_t *slot = NULL;
2069 psa_se_drv_table_entry_t *driver = NULL;
2070 size_t bits;
2071 size_t storage_size = data_length;
2072
2073 *key = MBEDTLS_SVC_KEY_ID_INIT;
2074
2075 /* Reject zero-length symmetric keys (including raw data key objects).
2076 * This also rejects any key which might be encoded as an empty string,
2077 * which is never valid. */
2078 if (data_length == 0) {
2079 return PSA_ERROR_INVALID_ARGUMENT;
2080 }
2081
2082 /* Ensure that the bytes-to-bits conversion cannot overflow. */
2083 if (data_length > SIZE_MAX / 8) {
2084 return PSA_ERROR_NOT_SUPPORTED;
2085 }
2086
2087 LOCAL_INPUT_ALLOC(data_external, data_length, data);
2088
2089 status = psa_start_key_creation(PSA_KEY_CREATION_IMPORT, attributes,
2090 &slot, &driver);
2091 if (status != PSA_SUCCESS) {
2092 goto exit;
2093 }
2094
2095 /* In the case of a transparent key or an opaque key stored in local
2096 * storage ( thus not in the case of importing a key in a secure element
2097 * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
2098 * buffer to hold the imported key material. */
2099 if (slot->key.data == NULL) {
2100 if (psa_key_lifetime_is_external(attributes->lifetime)) {
2101 status = psa_driver_wrapper_get_key_buffer_size_from_key_data(
2102 attributes, data, data_length, &storage_size);
2103 if (status != PSA_SUCCESS) {
2104 goto exit;
2105 }
2106 }
2107 status = psa_allocate_buffer_to_slot(slot, storage_size);
2108 if (status != PSA_SUCCESS) {
2109 goto exit;
2110 }
2111 }
2112
2113 bits = slot->attr.bits;
2114 status = psa_driver_wrapper_import_key(attributes,
2115 data, data_length,
2116 slot->key.data,
2117 slot->key.bytes,
2118 &slot->key.bytes, &bits);
2119 if (status != PSA_SUCCESS) {
2120 goto exit;
2121 }
2122
2123 if (slot->attr.bits == 0) {
2124 slot->attr.bits = (psa_key_bits_t) bits;
2125 } else if (bits != slot->attr.bits) {
2126 status = PSA_ERROR_INVALID_ARGUMENT;
2127 goto exit;
2128 }
2129
2130 /* Enforce a size limit, and in particular ensure that the bit
2131 * size fits in its representation type.*/
2132 if (bits > PSA_MAX_KEY_BITS) {
2133 status = PSA_ERROR_NOT_SUPPORTED;
2134 goto exit;
2135 }
2136 status = psa_validate_optional_attributes(slot, attributes);
2137 if (status != PSA_SUCCESS) {
2138 goto exit;
2139 }
2140
2141 status = psa_finish_key_creation(slot, driver, key);
2142exit:
2143 LOCAL_INPUT_FREE(data_external, data);
2144 if (status != PSA_SUCCESS) {
2145 psa_fail_key_creation(slot, driver);
2146 }
2147
2148 return status;
2149}
2150
2151#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2152psa_status_t mbedtls_psa_register_se_key(
2153 const psa_key_attributes_t *attributes)
2154{
2155 psa_status_t status;
2156 psa_key_slot_t *slot = NULL;
2157 psa_se_drv_table_entry_t *driver = NULL;
2158 mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
2159
2160 /* Leaving attributes unspecified is not currently supported.
2161 * It could make sense to query the key type and size from the
2162 * secure element, but not all secure elements support this
2163 * and the driver HAL doesn't currently support it. */
2164 if (psa_get_key_type(attributes) == PSA_KEY_TYPE_NONE) {
2165 return PSA_ERROR_NOT_SUPPORTED;
2166 }
2167 if (psa_get_key_bits(attributes) == 0) {
2168 return PSA_ERROR_NOT_SUPPORTED;
2169 }
2170
Sungbae Yoo4d211f32024-11-19 02:47:55 +00002171 /* Not usable with volatile keys, even with an appropriate location,
2172 * due to the API design.
2173 * https://github.com/Mbed-TLS/mbedtls/issues/9253
2174 */
2175 if (PSA_KEY_LIFETIME_IS_VOLATILE(psa_get_key_lifetime(attributes))) {
2176 return PSA_ERROR_INVALID_ARGUMENT;
2177 }
2178
Tom Van Eyckb0563632024-06-13 16:20:14 +02002179 status = psa_start_key_creation(PSA_KEY_CREATION_REGISTER, attributes,
2180 &slot, &driver);
2181 if (status != PSA_SUCCESS) {
2182 goto exit;
2183 }
2184
2185 status = psa_finish_key_creation(slot, driver, &key);
2186
2187exit:
2188 if (status != PSA_SUCCESS) {
2189 psa_fail_key_creation(slot, driver);
2190 }
2191
2192 /* Registration doesn't keep the key in RAM. */
2193 psa_close_key(key);
2194 return status;
2195}
2196#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2197
2198psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key,
2199 const psa_key_attributes_t *specified_attributes,
2200 mbedtls_svc_key_id_t *target_key)
2201{
2202 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2203 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2204 psa_key_slot_t *source_slot = NULL;
2205 psa_key_slot_t *target_slot = NULL;
2206 psa_key_attributes_t actual_attributes = *specified_attributes;
2207 psa_se_drv_table_entry_t *driver = NULL;
2208 size_t storage_size = 0;
2209
2210 *target_key = MBEDTLS_SVC_KEY_ID_INIT;
2211
2212 status = psa_get_and_lock_key_slot_with_policy(
2213 source_key, &source_slot, PSA_KEY_USAGE_COPY, 0);
2214 if (status != PSA_SUCCESS) {
2215 goto exit;
2216 }
2217
2218 status = psa_validate_optional_attributes(source_slot,
2219 specified_attributes);
2220 if (status != PSA_SUCCESS) {
2221 goto exit;
2222 }
2223
2224 /* The target key type and number of bits have been validated by
2225 * psa_validate_optional_attributes() to be either equal to zero or
2226 * equal to the ones of the source key. So it is safe to inherit
2227 * them from the source key now."
2228 * */
2229 actual_attributes.bits = source_slot->attr.bits;
2230 actual_attributes.type = source_slot->attr.type;
2231
2232
2233 status = psa_restrict_key_policy(source_slot->attr.type,
2234 &actual_attributes.policy,
2235 &source_slot->attr.policy);
2236 if (status != PSA_SUCCESS) {
2237 goto exit;
2238 }
2239
2240 status = psa_start_key_creation(PSA_KEY_CREATION_COPY, &actual_attributes,
2241 &target_slot, &driver);
2242 if (status != PSA_SUCCESS) {
2243 goto exit;
2244 }
2245 if (PSA_KEY_LIFETIME_GET_LOCATION(target_slot->attr.lifetime) !=
2246 PSA_KEY_LIFETIME_GET_LOCATION(source_slot->attr.lifetime)) {
2247 /*
2248 * If the source and target keys are stored in different locations,
2249 * the source key would need to be exported as plaintext and re-imported
2250 * in the other location. This has security implications which have not
2251 * been fully mapped. For now, this can be achieved through
2252 * appropriate API invocations from the application, if needed.
2253 * */
2254 status = PSA_ERROR_NOT_SUPPORTED;
2255 goto exit;
2256 }
2257 /*
2258 * When the source and target keys are within the same location,
2259 * - For transparent keys it is a blind copy without any driver invocation,
2260 * - For opaque keys this translates to an invocation of the drivers'
2261 * copy_key entry point through the dispatch layer.
2262 * */
2263 if (psa_key_lifetime_is_external(actual_attributes.lifetime)) {
2264 status = psa_driver_wrapper_get_key_buffer_size(&actual_attributes,
2265 &storage_size);
2266 if (status != PSA_SUCCESS) {
2267 goto exit;
2268 }
2269
2270 status = psa_allocate_buffer_to_slot(target_slot, storage_size);
2271 if (status != PSA_SUCCESS) {
2272 goto exit;
2273 }
2274
2275 status = psa_driver_wrapper_copy_key(&actual_attributes,
2276 source_slot->key.data,
2277 source_slot->key.bytes,
2278 target_slot->key.data,
2279 target_slot->key.bytes,
2280 &target_slot->key.bytes);
2281 if (status != PSA_SUCCESS) {
2282 goto exit;
2283 }
2284 } else {
2285 status = psa_copy_key_material_into_slot(target_slot,
2286 source_slot->key.data,
2287 source_slot->key.bytes);
2288 if (status != PSA_SUCCESS) {
2289 goto exit;
2290 }
2291 }
2292 status = psa_finish_key_creation(target_slot, driver, target_key);
2293exit:
2294 if (status != PSA_SUCCESS) {
2295 psa_fail_key_creation(target_slot, driver);
2296 }
2297
2298 unlock_status = psa_unregister_read_under_mutex(source_slot);
2299
2300 return (status == PSA_SUCCESS) ? unlock_status : status;
2301}
2302
2303
2304
2305/****************************************************************/
2306/* Message digests */
2307/****************************************************************/
2308
2309psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
2310{
2311 /* Aborting a non-active operation is allowed */
2312 if (operation->id == 0) {
2313 return PSA_SUCCESS;
2314 }
2315
2316 psa_status_t status = psa_driver_wrapper_hash_abort(operation);
2317 operation->id = 0;
2318
2319 return status;
2320}
2321
2322psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
2323 psa_algorithm_t alg)
2324{
2325 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2326
2327 /* A context must be freshly initialized before it can be set up. */
2328 if (operation->id != 0) {
2329 status = PSA_ERROR_BAD_STATE;
2330 goto exit;
2331 }
2332
2333 if (!PSA_ALG_IS_HASH(alg)) {
2334 status = PSA_ERROR_INVALID_ARGUMENT;
2335 goto exit;
2336 }
2337
2338 /* Ensure all of the context is zeroized, since PSA_HASH_OPERATION_INIT only
2339 * directly zeroes the int-sized dummy member of the context union. */
2340 memset(&operation->ctx, 0, sizeof(operation->ctx));
2341
2342 status = psa_driver_wrapper_hash_setup(operation, alg);
2343
2344exit:
2345 if (status != PSA_SUCCESS) {
2346 psa_hash_abort(operation);
2347 }
2348
2349 return status;
2350}
2351
2352psa_status_t psa_hash_update(psa_hash_operation_t *operation,
2353 const uint8_t *input_external,
2354 size_t input_length)
2355{
2356 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2357 LOCAL_INPUT_DECLARE(input_external, input);
2358
2359 if (operation->id == 0) {
2360 status = PSA_ERROR_BAD_STATE;
2361 goto exit;
2362 }
2363
2364 /* Don't require hash implementations to behave correctly on a
2365 * zero-length input, which may have an invalid pointer. */
2366 if (input_length == 0) {
2367 return PSA_SUCCESS;
2368 }
2369
2370 LOCAL_INPUT_ALLOC(input_external, input_length, input);
2371 status = psa_driver_wrapper_hash_update(operation, input, input_length);
2372
2373exit:
2374 if (status != PSA_SUCCESS) {
2375 psa_hash_abort(operation);
2376 }
2377
2378 LOCAL_INPUT_FREE(input_external, input);
2379 return status;
2380}
2381
2382static psa_status_t psa_hash_finish_internal(psa_hash_operation_t *operation,
2383 uint8_t *hash,
2384 size_t hash_size,
2385 size_t *hash_length)
2386{
2387 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2388
2389 *hash_length = 0;
2390 if (operation->id == 0) {
2391 return PSA_ERROR_BAD_STATE;
2392 }
2393
2394 status = psa_driver_wrapper_hash_finish(
2395 operation, hash, hash_size, hash_length);
2396 psa_hash_abort(operation);
2397
2398 return status;
2399}
2400
2401psa_status_t psa_hash_finish(psa_hash_operation_t *operation,
2402 uint8_t *hash_external,
2403 size_t hash_size,
2404 size_t *hash_length)
2405{
2406 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2407 LOCAL_OUTPUT_DECLARE(hash_external, hash);
2408
2409 LOCAL_OUTPUT_ALLOC(hash_external, hash_size, hash);
2410 status = psa_hash_finish_internal(operation, hash, hash_size, hash_length);
2411
2412#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
2413exit:
2414#endif
2415 LOCAL_OUTPUT_FREE(hash_external, hash);
2416 return status;
2417}
2418
2419psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
2420 const uint8_t *hash_external,
2421 size_t hash_length)
2422{
2423 uint8_t actual_hash[PSA_HASH_MAX_SIZE];
2424 size_t actual_hash_length;
2425 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2426 LOCAL_INPUT_DECLARE(hash_external, hash);
2427
2428 status = psa_hash_finish_internal(
2429 operation,
2430 actual_hash, sizeof(actual_hash),
2431 &actual_hash_length);
2432
2433 if (status != PSA_SUCCESS) {
2434 goto exit;
2435 }
2436
2437 if (actual_hash_length != hash_length) {
2438 status = PSA_ERROR_INVALID_SIGNATURE;
2439 goto exit;
2440 }
2441
2442 LOCAL_INPUT_ALLOC(hash_external, hash_length, hash);
2443 if (mbedtls_ct_memcmp(hash, actual_hash, actual_hash_length) != 0) {
2444 status = PSA_ERROR_INVALID_SIGNATURE;
2445 }
2446
2447exit:
2448 mbedtls_platform_zeroize(actual_hash, sizeof(actual_hash));
2449 if (status != PSA_SUCCESS) {
2450 psa_hash_abort(operation);
2451 }
2452 LOCAL_INPUT_FREE(hash_external, hash);
2453 return status;
2454}
2455
2456psa_status_t psa_hash_compute(psa_algorithm_t alg,
2457 const uint8_t *input_external, size_t input_length,
2458 uint8_t *hash_external, size_t hash_size,
2459 size_t *hash_length)
2460{
2461 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2462 LOCAL_INPUT_DECLARE(input_external, input);
2463 LOCAL_OUTPUT_DECLARE(hash_external, hash);
2464
2465 *hash_length = 0;
2466 if (!PSA_ALG_IS_HASH(alg)) {
2467 return PSA_ERROR_INVALID_ARGUMENT;
2468 }
2469
2470 LOCAL_INPUT_ALLOC(input_external, input_length, input);
2471 LOCAL_OUTPUT_ALLOC(hash_external, hash_size, hash);
2472 status = psa_driver_wrapper_hash_compute(alg, input, input_length,
2473 hash, hash_size, hash_length);
2474
2475#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
2476exit:
2477#endif
2478 LOCAL_INPUT_FREE(input_external, input);
2479 LOCAL_OUTPUT_FREE(hash_external, hash);
2480 return status;
2481}
2482
2483psa_status_t psa_hash_compare(psa_algorithm_t alg,
2484 const uint8_t *input_external, size_t input_length,
2485 const uint8_t *hash_external, size_t hash_length)
2486{
2487 uint8_t actual_hash[PSA_HASH_MAX_SIZE];
2488 size_t actual_hash_length;
2489 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2490
2491 LOCAL_INPUT_DECLARE(input_external, input);
2492 LOCAL_INPUT_DECLARE(hash_external, hash);
2493
2494 if (!PSA_ALG_IS_HASH(alg)) {
2495 status = PSA_ERROR_INVALID_ARGUMENT;
2496 return status;
2497 }
2498
2499 LOCAL_INPUT_ALLOC(input_external, input_length, input);
2500 status = psa_driver_wrapper_hash_compute(
2501 alg, input, input_length,
2502 actual_hash, sizeof(actual_hash),
2503 &actual_hash_length);
2504 if (status != PSA_SUCCESS) {
2505 goto exit;
2506 }
2507 if (actual_hash_length != hash_length) {
2508 status = PSA_ERROR_INVALID_SIGNATURE;
2509 goto exit;
2510 }
2511
2512 LOCAL_INPUT_ALLOC(hash_external, hash_length, hash);
2513 if (mbedtls_ct_memcmp(hash, actual_hash, actual_hash_length) != 0) {
2514 status = PSA_ERROR_INVALID_SIGNATURE;
2515 }
2516
2517exit:
2518 mbedtls_platform_zeroize(actual_hash, sizeof(actual_hash));
2519
2520 LOCAL_INPUT_FREE(input_external, input);
2521 LOCAL_INPUT_FREE(hash_external, hash);
2522
2523 return status;
2524}
2525
2526psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
2527 psa_hash_operation_t *target_operation)
2528{
2529 if (source_operation->id == 0 ||
2530 target_operation->id != 0) {
2531 return PSA_ERROR_BAD_STATE;
2532 }
2533
2534 psa_status_t status = psa_driver_wrapper_hash_clone(source_operation,
2535 target_operation);
2536 if (status != PSA_SUCCESS) {
2537 psa_hash_abort(target_operation);
2538 }
2539
2540 return status;
2541}
2542
2543
2544/****************************************************************/
2545/* MAC */
2546/****************************************************************/
2547
2548psa_status_t psa_mac_abort(psa_mac_operation_t *operation)
2549{
2550 /* Aborting a non-active operation is allowed */
2551 if (operation->id == 0) {
2552 return PSA_SUCCESS;
2553 }
2554
2555 psa_status_t status = psa_driver_wrapper_mac_abort(operation);
2556 operation->mac_size = 0;
2557 operation->is_sign = 0;
2558 operation->id = 0;
2559
2560 return status;
2561}
2562
2563static psa_status_t psa_mac_finalize_alg_and_key_validation(
2564 psa_algorithm_t alg,
2565 const psa_key_attributes_t *attributes,
2566 uint8_t *mac_size)
2567{
2568 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2569 psa_key_type_t key_type = psa_get_key_type(attributes);
2570 size_t key_bits = psa_get_key_bits(attributes);
2571
2572 if (!PSA_ALG_IS_MAC(alg)) {
2573 return PSA_ERROR_INVALID_ARGUMENT;
2574 }
2575
2576 /* Validate the combination of key type and algorithm */
2577 status = psa_mac_key_can_do(alg, key_type);
2578 if (status != PSA_SUCCESS) {
2579 return status;
2580 }
2581
2582 /* Get the output length for the algorithm and key combination */
2583 *mac_size = PSA_MAC_LENGTH(key_type, key_bits, alg);
2584
2585 if (*mac_size < 4) {
2586 /* A very short MAC is too short for security since it can be
2587 * brute-forced. Ancient protocols with 32-bit MACs do exist,
2588 * so we make this our minimum, even though 32 bits is still
2589 * too small for security. */
2590 return PSA_ERROR_NOT_SUPPORTED;
2591 }
2592
2593 if (*mac_size > PSA_MAC_LENGTH(key_type, key_bits,
2594 PSA_ALG_FULL_LENGTH_MAC(alg))) {
2595 /* It's impossible to "truncate" to a larger length than the full length
2596 * of the algorithm. */
2597 return PSA_ERROR_INVALID_ARGUMENT;
2598 }
2599
2600 if (*mac_size > PSA_MAC_MAX_SIZE) {
2601 /* PSA_MAC_LENGTH returns the correct length even for a MAC algorithm
2602 * that is disabled in the compile-time configuration. The result can
2603 * therefore be larger than PSA_MAC_MAX_SIZE, which does take the
2604 * configuration into account. In this case, force a return of
2605 * PSA_ERROR_NOT_SUPPORTED here. Otherwise psa_mac_verify(), or
2606 * psa_mac_compute(mac_size=PSA_MAC_MAX_SIZE), would return
2607 * PSA_ERROR_BUFFER_TOO_SMALL for an unsupported algorithm whose MAC size
2608 * is larger than PSA_MAC_MAX_SIZE, which is misleading and which breaks
2609 * systematically generated tests. */
2610 return PSA_ERROR_NOT_SUPPORTED;
2611 }
2612
2613 return PSA_SUCCESS;
2614}
2615
2616static psa_status_t psa_mac_setup(psa_mac_operation_t *operation,
2617 mbedtls_svc_key_id_t key,
2618 psa_algorithm_t alg,
2619 int is_sign)
2620{
2621 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2622 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2623 psa_key_slot_t *slot = NULL;
2624
2625 /* A context must be freshly initialized before it can be set up. */
2626 if (operation->id != 0) {
2627 status = PSA_ERROR_BAD_STATE;
2628 goto exit;
2629 }
2630
2631 status = psa_get_and_lock_key_slot_with_policy(
2632 key,
2633 &slot,
2634 is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE,
2635 alg);
2636 if (status != PSA_SUCCESS) {
2637 goto exit;
2638 }
2639
2640 status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr,
2641 &operation->mac_size);
2642 if (status != PSA_SUCCESS) {
2643 goto exit;
2644 }
2645
2646 operation->is_sign = is_sign;
2647 /* Dispatch the MAC setup call with validated input */
2648 if (is_sign) {
2649 status = psa_driver_wrapper_mac_sign_setup(operation,
2650 &slot->attr,
2651 slot->key.data,
2652 slot->key.bytes,
2653 alg);
2654 } else {
2655 status = psa_driver_wrapper_mac_verify_setup(operation,
2656 &slot->attr,
2657 slot->key.data,
2658 slot->key.bytes,
2659 alg);
2660 }
2661
2662exit:
2663 if (status != PSA_SUCCESS) {
2664 psa_mac_abort(operation);
2665 }
2666
2667 unlock_status = psa_unregister_read_under_mutex(slot);
2668
2669 return (status == PSA_SUCCESS) ? unlock_status : status;
2670}
2671
2672psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
2673 mbedtls_svc_key_id_t key,
2674 psa_algorithm_t alg)
2675{
2676 return psa_mac_setup(operation, key, alg, 1);
2677}
2678
2679psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
2680 mbedtls_svc_key_id_t key,
2681 psa_algorithm_t alg)
2682{
2683 return psa_mac_setup(operation, key, alg, 0);
2684}
2685
2686psa_status_t psa_mac_update(psa_mac_operation_t *operation,
2687 const uint8_t *input_external,
2688 size_t input_length)
2689{
2690 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2691 LOCAL_INPUT_DECLARE(input_external, input);
2692
2693 if (operation->id == 0) {
2694 status = PSA_ERROR_BAD_STATE;
2695 return status;
2696 }
2697
2698 /* Don't require hash implementations to behave correctly on a
2699 * zero-length input, which may have an invalid pointer. */
2700 if (input_length == 0) {
2701 status = PSA_SUCCESS;
2702 return status;
2703 }
2704
2705 LOCAL_INPUT_ALLOC(input_external, input_length, input);
2706 status = psa_driver_wrapper_mac_update(operation, input, input_length);
2707
2708 if (status != PSA_SUCCESS) {
2709 psa_mac_abort(operation);
2710 }
2711
2712#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
2713exit:
2714#endif
2715 LOCAL_INPUT_FREE(input_external, input);
2716
2717 return status;
2718}
2719
2720psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,
2721 uint8_t *mac_external,
2722 size_t mac_size,
2723 size_t *mac_length)
2724{
2725 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2726 psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
2727 LOCAL_OUTPUT_DECLARE(mac_external, mac);
2728 LOCAL_OUTPUT_ALLOC(mac_external, mac_size, mac);
2729
2730 if (operation->id == 0) {
2731 status = PSA_ERROR_BAD_STATE;
2732 goto exit;
2733 }
2734
2735 if (!operation->is_sign) {
2736 status = PSA_ERROR_BAD_STATE;
2737 goto exit;
2738 }
2739
2740 /* Sanity check. This will guarantee that mac_size != 0 (and so mac != NULL)
2741 * once all the error checks are done. */
2742 if (operation->mac_size == 0) {
2743 status = PSA_ERROR_BAD_STATE;
2744 goto exit;
2745 }
2746
2747 if (mac_size < operation->mac_size) {
2748 status = PSA_ERROR_BUFFER_TOO_SMALL;
2749 goto exit;
2750 }
2751
2752
2753 status = psa_driver_wrapper_mac_sign_finish(operation,
2754 mac, operation->mac_size,
2755 mac_length);
2756
2757exit:
2758 /* In case of success, set the potential excess room in the output buffer
2759 * to an invalid value, to avoid potentially leaking a longer MAC.
2760 * In case of error, set the output length and content to a safe default,
2761 * such that in case the caller misses an error check, the output would be
2762 * an unachievable MAC.
2763 */
2764 if (status != PSA_SUCCESS) {
2765 *mac_length = mac_size;
2766 operation->mac_size = 0;
2767 }
2768
2769 if (mac != NULL) {
2770 psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length);
2771 }
2772
2773 abort_status = psa_mac_abort(operation);
2774 LOCAL_OUTPUT_FREE(mac_external, mac);
2775
2776 return status == PSA_SUCCESS ? abort_status : status;
2777}
2778
2779psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
2780 const uint8_t *mac_external,
2781 size_t mac_length)
2782{
2783 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2784 psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
2785 LOCAL_INPUT_DECLARE(mac_external, mac);
2786
2787 if (operation->id == 0) {
2788 status = PSA_ERROR_BAD_STATE;
2789 goto exit;
2790 }
2791
2792 if (operation->is_sign) {
2793 status = PSA_ERROR_BAD_STATE;
2794 goto exit;
2795 }
2796
2797 if (operation->mac_size != mac_length) {
2798 status = PSA_ERROR_INVALID_SIGNATURE;
2799 goto exit;
2800 }
2801
2802 LOCAL_INPUT_ALLOC(mac_external, mac_length, mac);
2803 status = psa_driver_wrapper_mac_verify_finish(operation,
2804 mac, mac_length);
2805
2806exit:
2807 abort_status = psa_mac_abort(operation);
2808 LOCAL_INPUT_FREE(mac_external, mac);
2809
2810 return status == PSA_SUCCESS ? abort_status : status;
2811}
2812
2813static psa_status_t psa_mac_compute_internal(mbedtls_svc_key_id_t key,
2814 psa_algorithm_t alg,
2815 const uint8_t *input,
2816 size_t input_length,
2817 uint8_t *mac,
2818 size_t mac_size,
2819 size_t *mac_length,
2820 int is_sign)
2821{
2822 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2823 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2824 psa_key_slot_t *slot;
2825 uint8_t operation_mac_size = 0;
2826
2827 status = psa_get_and_lock_key_slot_with_policy(
2828 key,
2829 &slot,
2830 is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE,
2831 alg);
2832 if (status != PSA_SUCCESS) {
2833 goto exit;
2834 }
2835
2836 status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr,
2837 &operation_mac_size);
2838 if (status != PSA_SUCCESS) {
2839 goto exit;
2840 }
2841
2842 if (mac_size < operation_mac_size) {
2843 status = PSA_ERROR_BUFFER_TOO_SMALL;
2844 goto exit;
2845 }
2846
2847 status = psa_driver_wrapper_mac_compute(
2848 &slot->attr,
2849 slot->key.data, slot->key.bytes,
2850 alg,
2851 input, input_length,
2852 mac, operation_mac_size, mac_length);
2853
2854exit:
2855 /* In case of success, set the potential excess room in the output buffer
2856 * to an invalid value, to avoid potentially leaking a longer MAC.
2857 * In case of error, set the output length and content to a safe default,
2858 * such that in case the caller misses an error check, the output would be
2859 * an unachievable MAC.
2860 */
2861 if (status != PSA_SUCCESS) {
2862 *mac_length = mac_size;
2863 operation_mac_size = 0;
2864 }
2865
2866 psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length);
2867
2868 unlock_status = psa_unregister_read_under_mutex(slot);
2869
2870 return (status == PSA_SUCCESS) ? unlock_status : status;
2871}
2872
2873psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key,
2874 psa_algorithm_t alg,
2875 const uint8_t *input_external,
2876 size_t input_length,
2877 uint8_t *mac_external,
2878 size_t mac_size,
2879 size_t *mac_length)
2880{
2881 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2882 LOCAL_INPUT_DECLARE(input_external, input);
2883 LOCAL_OUTPUT_DECLARE(mac_external, mac);
2884
2885 LOCAL_INPUT_ALLOC(input_external, input_length, input);
2886 LOCAL_OUTPUT_ALLOC(mac_external, mac_size, mac);
2887 status = psa_mac_compute_internal(key, alg,
2888 input, input_length,
2889 mac, mac_size, mac_length, 1);
2890
2891#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
2892exit:
2893#endif
2894 LOCAL_INPUT_FREE(input_external, input);
2895 LOCAL_OUTPUT_FREE(mac_external, mac);
2896
2897 return status;
2898}
2899
2900psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key,
2901 psa_algorithm_t alg,
2902 const uint8_t *input_external,
2903 size_t input_length,
2904 const uint8_t *mac_external,
2905 size_t mac_length)
2906{
2907 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2908 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
2909 size_t actual_mac_length;
2910 LOCAL_INPUT_DECLARE(input_external, input);
2911 LOCAL_INPUT_DECLARE(mac_external, mac);
2912
2913 LOCAL_INPUT_ALLOC(input_external, input_length, input);
2914 status = psa_mac_compute_internal(key, alg,
2915 input, input_length,
2916 actual_mac, sizeof(actual_mac),
2917 &actual_mac_length, 0);
2918 if (status != PSA_SUCCESS) {
2919 goto exit;
2920 }
2921
2922 if (mac_length != actual_mac_length) {
2923 status = PSA_ERROR_INVALID_SIGNATURE;
2924 goto exit;
2925 }
2926
2927 LOCAL_INPUT_ALLOC(mac_external, mac_length, mac);
2928 if (mbedtls_ct_memcmp(mac, actual_mac, actual_mac_length) != 0) {
2929 status = PSA_ERROR_INVALID_SIGNATURE;
2930 goto exit;
2931 }
2932
2933exit:
2934 mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac));
2935 LOCAL_INPUT_FREE(input_external, input);
2936 LOCAL_INPUT_FREE(mac_external, mac);
2937
2938 return status;
2939}
2940
2941/****************************************************************/
2942/* Asymmetric cryptography */
2943/****************************************************************/
2944
2945static psa_status_t psa_sign_verify_check_alg(int input_is_message,
2946 psa_algorithm_t alg)
2947{
2948 if (input_is_message) {
2949 if (!PSA_ALG_IS_SIGN_MESSAGE(alg)) {
2950 return PSA_ERROR_INVALID_ARGUMENT;
2951 }
2952
2953 if (PSA_ALG_IS_SIGN_HASH(alg)) {
2954 if (!PSA_ALG_IS_HASH(PSA_ALG_SIGN_GET_HASH(alg))) {
2955 return PSA_ERROR_INVALID_ARGUMENT;
2956 }
2957 }
2958 } else {
2959 if (!PSA_ALG_IS_SIGN_HASH(alg)) {
2960 return PSA_ERROR_INVALID_ARGUMENT;
2961 }
2962 }
2963
2964 return PSA_SUCCESS;
2965}
2966
2967static psa_status_t psa_sign_internal(mbedtls_svc_key_id_t key,
2968 int input_is_message,
2969 psa_algorithm_t alg,
2970 const uint8_t *input,
2971 size_t input_length,
2972 uint8_t *signature,
2973 size_t signature_size,
2974 size_t *signature_length)
2975{
2976 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2977 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2978 psa_key_slot_t *slot;
2979
2980 *signature_length = 0;
2981
2982 status = psa_sign_verify_check_alg(input_is_message, alg);
2983 if (status != PSA_SUCCESS) {
2984 return status;
2985 }
2986
2987 /* Immediately reject a zero-length signature buffer. This guarantees
2988 * that signature must be a valid pointer. (On the other hand, the input
2989 * buffer can in principle be empty since it doesn't actually have
2990 * to be a hash.) */
2991 if (signature_size == 0) {
2992 return PSA_ERROR_BUFFER_TOO_SMALL;
2993 }
2994
2995 status = psa_get_and_lock_key_slot_with_policy(
2996 key, &slot,
2997 input_is_message ? PSA_KEY_USAGE_SIGN_MESSAGE :
2998 PSA_KEY_USAGE_SIGN_HASH,
2999 alg);
3000
3001 if (status != PSA_SUCCESS) {
3002 goto exit;
3003 }
3004
3005 if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) {
3006 status = PSA_ERROR_INVALID_ARGUMENT;
3007 goto exit;
3008 }
3009
3010 if (input_is_message) {
3011 status = psa_driver_wrapper_sign_message(
3012 &slot->attr, slot->key.data, slot->key.bytes,
3013 alg, input, input_length,
3014 signature, signature_size, signature_length);
3015 } else {
3016
3017 status = psa_driver_wrapper_sign_hash(
3018 &slot->attr, slot->key.data, slot->key.bytes,
3019 alg, input, input_length,
3020 signature, signature_size, signature_length);
3021 }
3022
3023
3024exit:
3025 psa_wipe_tag_output_buffer(signature, status, signature_size,
3026 *signature_length);
3027
3028 unlock_status = psa_unregister_read_under_mutex(slot);
3029
3030 return (status == PSA_SUCCESS) ? unlock_status : status;
3031}
3032
3033static psa_status_t psa_verify_internal(mbedtls_svc_key_id_t key,
3034 int input_is_message,
3035 psa_algorithm_t alg,
3036 const uint8_t *input,
3037 size_t input_length,
3038 const uint8_t *signature,
3039 size_t signature_length)
3040{
3041 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3042 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3043 psa_key_slot_t *slot;
3044
3045 status = psa_sign_verify_check_alg(input_is_message, alg);
3046 if (status != PSA_SUCCESS) {
3047 return status;
3048 }
3049
3050 status = psa_get_and_lock_key_slot_with_policy(
3051 key, &slot,
3052 input_is_message ? PSA_KEY_USAGE_VERIFY_MESSAGE :
3053 PSA_KEY_USAGE_VERIFY_HASH,
3054 alg);
3055
3056 if (status != PSA_SUCCESS) {
3057 return status;
3058 }
3059
3060 if (input_is_message) {
3061 status = psa_driver_wrapper_verify_message(
3062 &slot->attr, slot->key.data, slot->key.bytes,
3063 alg, input, input_length,
3064 signature, signature_length);
3065 } else {
3066 status = psa_driver_wrapper_verify_hash(
3067 &slot->attr, slot->key.data, slot->key.bytes,
3068 alg, input, input_length,
3069 signature, signature_length);
3070 }
3071
3072 unlock_status = psa_unregister_read_under_mutex(slot);
3073
3074 return (status == PSA_SUCCESS) ? unlock_status : status;
3075
3076}
3077
3078psa_status_t psa_sign_message_builtin(
3079 const psa_key_attributes_t *attributes,
3080 const uint8_t *key_buffer,
3081 size_t key_buffer_size,
3082 psa_algorithm_t alg,
3083 const uint8_t *input,
3084 size_t input_length,
3085 uint8_t *signature,
3086 size_t signature_size,
3087 size_t *signature_length)
3088{
3089 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3090
3091 if (PSA_ALG_IS_SIGN_HASH(alg)) {
3092 size_t hash_length;
3093 uint8_t hash[PSA_HASH_MAX_SIZE];
3094
3095 status = psa_driver_wrapper_hash_compute(
3096 PSA_ALG_SIGN_GET_HASH(alg),
3097 input, input_length,
3098 hash, sizeof(hash), &hash_length);
3099
3100 if (status != PSA_SUCCESS) {
3101 return status;
3102 }
3103
3104 return psa_driver_wrapper_sign_hash(
3105 attributes, key_buffer, key_buffer_size,
3106 alg, hash, hash_length,
3107 signature, signature_size, signature_length);
3108 }
3109
3110 return PSA_ERROR_NOT_SUPPORTED;
3111}
3112
3113psa_status_t psa_sign_message(mbedtls_svc_key_id_t key,
3114 psa_algorithm_t alg,
3115 const uint8_t *input_external,
3116 size_t input_length,
3117 uint8_t *signature_external,
3118 size_t signature_size,
3119 size_t *signature_length)
3120{
3121 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3122 LOCAL_INPUT_DECLARE(input_external, input);
3123 LOCAL_OUTPUT_DECLARE(signature_external, signature);
3124
3125 LOCAL_INPUT_ALLOC(input_external, input_length, input);
3126 LOCAL_OUTPUT_ALLOC(signature_external, signature_size, signature);
3127 status = psa_sign_internal(key, 1, alg, input, input_length, signature,
3128 signature_size, signature_length);
3129
3130#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
3131exit:
3132#endif
3133 LOCAL_INPUT_FREE(input_external, input);
3134 LOCAL_OUTPUT_FREE(signature_external, signature);
3135 return status;
3136}
3137
3138psa_status_t psa_verify_message_builtin(
3139 const psa_key_attributes_t *attributes,
3140 const uint8_t *key_buffer,
3141 size_t key_buffer_size,
3142 psa_algorithm_t alg,
3143 const uint8_t *input,
3144 size_t input_length,
3145 const uint8_t *signature,
3146 size_t signature_length)
3147{
3148 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3149
3150 if (PSA_ALG_IS_SIGN_HASH(alg)) {
3151 size_t hash_length;
3152 uint8_t hash[PSA_HASH_MAX_SIZE];
3153
3154 status = psa_driver_wrapper_hash_compute(
3155 PSA_ALG_SIGN_GET_HASH(alg),
3156 input, input_length,
3157 hash, sizeof(hash), &hash_length);
3158
3159 if (status != PSA_SUCCESS) {
3160 return status;
3161 }
3162
3163 return psa_driver_wrapper_verify_hash(
3164 attributes, key_buffer, key_buffer_size,
3165 alg, hash, hash_length,
3166 signature, signature_length);
3167 }
3168
3169 return PSA_ERROR_NOT_SUPPORTED;
3170}
3171
3172psa_status_t psa_verify_message(mbedtls_svc_key_id_t key,
3173 psa_algorithm_t alg,
3174 const uint8_t *input_external,
3175 size_t input_length,
3176 const uint8_t *signature_external,
3177 size_t signature_length)
3178{
3179 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3180 LOCAL_INPUT_DECLARE(input_external, input);
3181 LOCAL_INPUT_DECLARE(signature_external, signature);
3182
3183 LOCAL_INPUT_ALLOC(input_external, input_length, input);
3184 LOCAL_INPUT_ALLOC(signature_external, signature_length, signature);
3185 status = psa_verify_internal(key, 1, alg, input, input_length, signature,
3186 signature_length);
3187
3188#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
3189exit:
3190#endif
3191 LOCAL_INPUT_FREE(input_external, input);
3192 LOCAL_INPUT_FREE(signature_external, signature);
3193
3194 return status;
3195}
3196
3197psa_status_t psa_sign_hash_builtin(
3198 const psa_key_attributes_t *attributes,
3199 const uint8_t *key_buffer, size_t key_buffer_size,
3200 psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
3201 uint8_t *signature, size_t signature_size, size_t *signature_length)
3202{
3203 if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
3204 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
3205 PSA_ALG_IS_RSA_PSS(alg)) {
3206#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3207 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
3208 return mbedtls_psa_rsa_sign_hash(
3209 attributes,
3210 key_buffer, key_buffer_size,
3211 alg, hash, hash_length,
3212 signature, signature_size, signature_length);
3213#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3214 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
3215 } else {
3216 return PSA_ERROR_INVALID_ARGUMENT;
3217 }
3218 } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
3219 if (PSA_ALG_IS_ECDSA(alg)) {
3220#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3221 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
3222 return mbedtls_psa_ecdsa_sign_hash(
3223 attributes,
3224 key_buffer, key_buffer_size,
3225 alg, hash, hash_length,
3226 signature, signature_size, signature_length);
3227#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3228 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
3229 } else {
3230 return PSA_ERROR_INVALID_ARGUMENT;
3231 }
3232 }
3233
3234 (void) key_buffer;
3235 (void) key_buffer_size;
3236 (void) hash;
3237 (void) hash_length;
3238 (void) signature;
3239 (void) signature_size;
3240 (void) signature_length;
3241
3242 return PSA_ERROR_NOT_SUPPORTED;
3243}
3244
3245psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key,
3246 psa_algorithm_t alg,
3247 const uint8_t *hash_external,
3248 size_t hash_length,
3249 uint8_t *signature_external,
3250 size_t signature_size,
3251 size_t *signature_length)
3252{
3253 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3254 LOCAL_INPUT_DECLARE(hash_external, hash);
3255 LOCAL_OUTPUT_DECLARE(signature_external, signature);
3256
3257 LOCAL_INPUT_ALLOC(hash_external, hash_length, hash);
3258 LOCAL_OUTPUT_ALLOC(signature_external, signature_size, signature);
3259 status = psa_sign_internal(key, 0, alg, hash, hash_length, signature,
3260 signature_size, signature_length);
3261
3262#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
3263exit:
3264#endif
3265 LOCAL_INPUT_FREE(hash_external, hash);
3266 LOCAL_OUTPUT_FREE(signature_external, signature);
3267
3268 return status;
3269}
3270
3271psa_status_t psa_verify_hash_builtin(
3272 const psa_key_attributes_t *attributes,
3273 const uint8_t *key_buffer, size_t key_buffer_size,
3274 psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
3275 const uint8_t *signature, size_t signature_length)
3276{
3277 if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
3278 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
3279 PSA_ALG_IS_RSA_PSS(alg)) {
3280#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3281 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
3282 return mbedtls_psa_rsa_verify_hash(
3283 attributes,
3284 key_buffer, key_buffer_size,
3285 alg, hash, hash_length,
3286 signature, signature_length);
3287#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3288 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
3289 } else {
3290 return PSA_ERROR_INVALID_ARGUMENT;
3291 }
3292 } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
3293 if (PSA_ALG_IS_ECDSA(alg)) {
3294#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3295 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
3296 return mbedtls_psa_ecdsa_verify_hash(
3297 attributes,
3298 key_buffer, key_buffer_size,
3299 alg, hash, hash_length,
3300 signature, signature_length);
3301#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3302 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
3303 } else {
3304 return PSA_ERROR_INVALID_ARGUMENT;
3305 }
3306 }
3307
3308 (void) key_buffer;
3309 (void) key_buffer_size;
3310 (void) hash;
3311 (void) hash_length;
3312 (void) signature;
3313 (void) signature_length;
3314
3315 return PSA_ERROR_NOT_SUPPORTED;
3316}
3317
3318psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key,
3319 psa_algorithm_t alg,
3320 const uint8_t *hash_external,
3321 size_t hash_length,
3322 const uint8_t *signature_external,
3323 size_t signature_length)
3324{
3325 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3326 LOCAL_INPUT_DECLARE(hash_external, hash);
3327 LOCAL_INPUT_DECLARE(signature_external, signature);
3328
3329 LOCAL_INPUT_ALLOC(hash_external, hash_length, hash);
3330 LOCAL_INPUT_ALLOC(signature_external, signature_length, signature);
3331 status = psa_verify_internal(key, 0, alg, hash, hash_length, signature,
3332 signature_length);
3333
3334#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
3335exit:
3336#endif
3337 LOCAL_INPUT_FREE(hash_external, hash);
3338 LOCAL_INPUT_FREE(signature_external, signature);
3339
3340 return status;
3341}
3342
3343psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key,
3344 psa_algorithm_t alg,
3345 const uint8_t *input_external,
3346 size_t input_length,
3347 const uint8_t *salt_external,
3348 size_t salt_length,
3349 uint8_t *output_external,
3350 size_t output_size,
3351 size_t *output_length)
3352{
3353 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3354 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3355 psa_key_slot_t *slot;
3356
3357 LOCAL_INPUT_DECLARE(input_external, input);
3358 LOCAL_INPUT_DECLARE(salt_external, salt);
3359 LOCAL_OUTPUT_DECLARE(output_external, output);
3360
3361 (void) input;
3362 (void) input_length;
3363 (void) salt;
3364 (void) output;
3365 (void) output_size;
3366
3367 *output_length = 0;
3368
3369 if (!PSA_ALG_IS_RSA_OAEP(alg) && salt_length != 0) {
3370 return PSA_ERROR_INVALID_ARGUMENT;
3371 }
3372
3373 status = psa_get_and_lock_key_slot_with_policy(
3374 key, &slot, PSA_KEY_USAGE_ENCRYPT, alg);
3375 if (status != PSA_SUCCESS) {
3376 return status;
3377 }
3378 if (!(PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type) ||
3379 PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type))) {
3380 status = PSA_ERROR_INVALID_ARGUMENT;
3381 goto exit;
3382 }
3383
3384 LOCAL_INPUT_ALLOC(input_external, input_length, input);
3385 LOCAL_INPUT_ALLOC(salt_external, salt_length, salt);
3386 LOCAL_OUTPUT_ALLOC(output_external, output_size, output);
3387
3388 status = psa_driver_wrapper_asymmetric_encrypt(
3389 &slot->attr, slot->key.data, slot->key.bytes,
3390 alg, input, input_length, salt, salt_length,
3391 output, output_size, output_length);
3392exit:
3393 unlock_status = psa_unregister_read_under_mutex(slot);
3394
3395 LOCAL_INPUT_FREE(input_external, input);
3396 LOCAL_INPUT_FREE(salt_external, salt);
3397 LOCAL_OUTPUT_FREE(output_external, output);
3398
3399 return (status == PSA_SUCCESS) ? unlock_status : status;
3400}
3401
3402psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key,
3403 psa_algorithm_t alg,
3404 const uint8_t *input_external,
3405 size_t input_length,
3406 const uint8_t *salt_external,
3407 size_t salt_length,
3408 uint8_t *output_external,
3409 size_t output_size,
3410 size_t *output_length)
3411{
3412 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3413 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3414 psa_key_slot_t *slot;
3415
3416 LOCAL_INPUT_DECLARE(input_external, input);
3417 LOCAL_INPUT_DECLARE(salt_external, salt);
3418 LOCAL_OUTPUT_DECLARE(output_external, output);
3419
3420 (void) input;
3421 (void) input_length;
3422 (void) salt;
3423 (void) output;
3424 (void) output_size;
3425
3426 *output_length = 0;
3427
3428 if (!PSA_ALG_IS_RSA_OAEP(alg) && salt_length != 0) {
3429 return PSA_ERROR_INVALID_ARGUMENT;
3430 }
3431
3432 status = psa_get_and_lock_key_slot_with_policy(
3433 key, &slot, PSA_KEY_USAGE_DECRYPT, alg);
3434 if (status != PSA_SUCCESS) {
3435 return status;
3436 }
3437 if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) {
3438 status = PSA_ERROR_INVALID_ARGUMENT;
3439 goto exit;
3440 }
3441
3442 LOCAL_INPUT_ALLOC(input_external, input_length, input);
3443 LOCAL_INPUT_ALLOC(salt_external, salt_length, salt);
3444 LOCAL_OUTPUT_ALLOC(output_external, output_size, output);
3445
3446 status = psa_driver_wrapper_asymmetric_decrypt(
3447 &slot->attr, slot->key.data, slot->key.bytes,
3448 alg, input, input_length, salt, salt_length,
3449 output, output_size, output_length);
3450
3451exit:
3452 unlock_status = psa_unregister_read_under_mutex(slot);
3453
3454 LOCAL_INPUT_FREE(input_external, input);
3455 LOCAL_INPUT_FREE(salt_external, salt);
3456 LOCAL_OUTPUT_FREE(output_external, output);
3457
3458 return (status == PSA_SUCCESS) ? unlock_status : status;
3459}
3460
3461/****************************************************************/
3462/* Asymmetric interruptible cryptography */
3463/****************************************************************/
3464
3465static uint32_t psa_interruptible_max_ops = PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED;
3466
3467void psa_interruptible_set_max_ops(uint32_t max_ops)
3468{
3469 psa_interruptible_max_ops = max_ops;
3470}
3471
3472uint32_t psa_interruptible_get_max_ops(void)
3473{
3474 return psa_interruptible_max_ops;
3475}
3476
3477uint32_t psa_sign_hash_get_num_ops(
3478 const psa_sign_hash_interruptible_operation_t *operation)
3479{
3480 return operation->num_ops;
3481}
3482
3483uint32_t psa_verify_hash_get_num_ops(
3484 const psa_verify_hash_interruptible_operation_t *operation)
3485{
3486 return operation->num_ops;
3487}
3488
3489static psa_status_t psa_sign_hash_abort_internal(
3490 psa_sign_hash_interruptible_operation_t *operation)
3491{
3492 if (operation->id == 0) {
3493 /* The object has (apparently) been initialized but it is not (yet)
3494 * in use. It's ok to call abort on such an object, and there's
3495 * nothing to do. */
3496 return PSA_SUCCESS;
3497 }
3498
3499 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3500
3501 status = psa_driver_wrapper_sign_hash_abort(operation);
3502
3503 operation->id = 0;
3504
3505 /* Do not clear either the error_occurred or num_ops elements here as they
3506 * only want to be cleared by the application calling abort, not by abort
3507 * being called at completion of an operation. */
3508
3509 return status;
3510}
3511
3512psa_status_t psa_sign_hash_start(
3513 psa_sign_hash_interruptible_operation_t *operation,
3514 mbedtls_svc_key_id_t key, psa_algorithm_t alg,
3515 const uint8_t *hash_external, size_t hash_length)
3516{
3517 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3518 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3519 psa_key_slot_t *slot;
3520
3521 LOCAL_INPUT_DECLARE(hash_external, hash);
3522
3523 /* Check that start has not been previously called, or operation has not
3524 * previously errored. */
3525 if (operation->id != 0 || operation->error_occurred) {
3526 return PSA_ERROR_BAD_STATE;
3527 }
3528
3529 status = psa_sign_verify_check_alg(0, alg);
3530 if (status != PSA_SUCCESS) {
3531 operation->error_occurred = 1;
3532 return status;
3533 }
3534
3535 status = psa_get_and_lock_key_slot_with_policy(key, &slot,
3536 PSA_KEY_USAGE_SIGN_HASH,
3537 alg);
3538
3539 if (status != PSA_SUCCESS) {
3540 goto exit;
3541 }
3542
3543 if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) {
3544 status = PSA_ERROR_INVALID_ARGUMENT;
3545 goto exit;
3546 }
3547
3548 LOCAL_INPUT_ALLOC(hash_external, hash_length, hash);
3549
3550 /* Ensure ops count gets reset, in case of operation re-use. */
3551 operation->num_ops = 0;
3552
3553 status = psa_driver_wrapper_sign_hash_start(operation, &slot->attr,
3554 slot->key.data,
3555 slot->key.bytes, alg,
3556 hash, hash_length);
3557exit:
3558
3559 if (status != PSA_SUCCESS) {
3560 operation->error_occurred = 1;
3561 psa_sign_hash_abort_internal(operation);
3562 }
3563
3564 unlock_status = psa_unregister_read_under_mutex(slot);
3565
3566 if (unlock_status != PSA_SUCCESS) {
3567 operation->error_occurred = 1;
3568 }
3569
3570 LOCAL_INPUT_FREE(hash_external, hash);
3571
3572 return (status == PSA_SUCCESS) ? unlock_status : status;
3573}
3574
3575
3576psa_status_t psa_sign_hash_complete(
3577 psa_sign_hash_interruptible_operation_t *operation,
3578 uint8_t *signature_external, size_t signature_size,
3579 size_t *signature_length)
3580{
3581 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3582
3583 LOCAL_OUTPUT_DECLARE(signature_external, signature);
3584
3585 *signature_length = 0;
3586
3587 /* Check that start has been called first, and that operation has not
3588 * previously errored. */
3589 if (operation->id == 0 || operation->error_occurred) {
3590 status = PSA_ERROR_BAD_STATE;
3591 goto exit;
3592 }
3593
3594 /* Immediately reject a zero-length signature buffer. This guarantees that
3595 * signature must be a valid pointer. */
3596 if (signature_size == 0) {
3597 status = PSA_ERROR_BUFFER_TOO_SMALL;
3598 goto exit;
3599 }
3600
3601 LOCAL_OUTPUT_ALLOC(signature_external, signature_size, signature);
3602
3603 status = psa_driver_wrapper_sign_hash_complete(operation, signature,
3604 signature_size,
3605 signature_length);
3606
3607 /* Update ops count with work done. */
3608 operation->num_ops = psa_driver_wrapper_sign_hash_get_num_ops(operation);
3609
3610exit:
3611
3612 if (signature != NULL) {
3613 psa_wipe_tag_output_buffer(signature, status, signature_size,
3614 *signature_length);
3615 }
3616
3617 if (status != PSA_OPERATION_INCOMPLETE) {
3618 if (status != PSA_SUCCESS) {
3619 operation->error_occurred = 1;
3620 }
3621
3622 psa_sign_hash_abort_internal(operation);
3623 }
3624
3625 LOCAL_OUTPUT_FREE(signature_external, signature);
3626
3627 return status;
3628}
3629
3630psa_status_t psa_sign_hash_abort(
3631 psa_sign_hash_interruptible_operation_t *operation)
3632{
3633 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3634
3635 status = psa_sign_hash_abort_internal(operation);
3636
3637 /* We clear the number of ops done here, so that it is not cleared when
3638 * the operation fails or succeeds, only on manual abort. */
3639 operation->num_ops = 0;
3640
3641 /* Likewise, failure state. */
3642 operation->error_occurred = 0;
3643
3644 return status;
3645}
3646
3647static psa_status_t psa_verify_hash_abort_internal(
3648 psa_verify_hash_interruptible_operation_t *operation)
3649{
3650 if (operation->id == 0) {
3651 /* The object has (apparently) been initialized but it is not (yet)
3652 * in use. It's ok to call abort on such an object, and there's
3653 * nothing to do. */
3654 return PSA_SUCCESS;
3655 }
3656
3657 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3658
3659 status = psa_driver_wrapper_verify_hash_abort(operation);
3660
3661 operation->id = 0;
3662
3663 /* Do not clear either the error_occurred or num_ops elements here as they
3664 * only want to be cleared by the application calling abort, not by abort
3665 * being called at completion of an operation. */
3666
3667 return status;
3668}
3669
3670psa_status_t psa_verify_hash_start(
3671 psa_verify_hash_interruptible_operation_t *operation,
3672 mbedtls_svc_key_id_t key, psa_algorithm_t alg,
3673 const uint8_t *hash_external, size_t hash_length,
3674 const uint8_t *signature_external, size_t signature_length)
3675{
3676 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3677 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3678 psa_key_slot_t *slot;
3679
3680 LOCAL_INPUT_DECLARE(hash_external, hash);
3681 LOCAL_INPUT_DECLARE(signature_external, signature);
3682
3683 /* Check that start has not been previously called, or operation has not
3684 * previously errored. */
3685 if (operation->id != 0 || operation->error_occurred) {
3686 return PSA_ERROR_BAD_STATE;
3687 }
3688
3689 status = psa_sign_verify_check_alg(0, alg);
3690 if (status != PSA_SUCCESS) {
3691 operation->error_occurred = 1;
3692 return status;
3693 }
3694
3695 status = psa_get_and_lock_key_slot_with_policy(key, &slot,
3696 PSA_KEY_USAGE_VERIFY_HASH,
3697 alg);
3698
3699 if (status != PSA_SUCCESS) {
3700 operation->error_occurred = 1;
3701 return status;
3702 }
3703
3704 LOCAL_INPUT_ALLOC(hash_external, hash_length, hash);
3705 LOCAL_INPUT_ALLOC(signature_external, signature_length, signature);
3706
3707 /* Ensure ops count gets reset, in case of operation re-use. */
3708 operation->num_ops = 0;
3709
3710 status = psa_driver_wrapper_verify_hash_start(operation, &slot->attr,
3711 slot->key.data,
3712 slot->key.bytes,
3713 alg, hash, hash_length,
3714 signature, signature_length);
3715#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
3716exit:
3717#endif
3718
3719 if (status != PSA_SUCCESS) {
3720 operation->error_occurred = 1;
3721 psa_verify_hash_abort_internal(operation);
3722 }
3723
3724 unlock_status = psa_unregister_read_under_mutex(slot);
3725
3726 if (unlock_status != PSA_SUCCESS) {
3727 operation->error_occurred = 1;
3728 }
3729
3730 LOCAL_INPUT_FREE(hash_external, hash);
3731 LOCAL_INPUT_FREE(signature_external, signature);
3732
3733 return (status == PSA_SUCCESS) ? unlock_status : status;
3734}
3735
3736psa_status_t psa_verify_hash_complete(
3737 psa_verify_hash_interruptible_operation_t *operation)
3738{
3739 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3740
3741 /* Check that start has been called first, and that operation has not
3742 * previously errored. */
3743 if (operation->id == 0 || operation->error_occurred) {
3744 status = PSA_ERROR_BAD_STATE;
3745 goto exit;
3746 }
3747
3748 status = psa_driver_wrapper_verify_hash_complete(operation);
3749
3750 /* Update ops count with work done. */
3751 operation->num_ops = psa_driver_wrapper_verify_hash_get_num_ops(
3752 operation);
3753
3754exit:
3755
3756 if (status != PSA_OPERATION_INCOMPLETE) {
3757 if (status != PSA_SUCCESS) {
3758 operation->error_occurred = 1;
3759 }
3760
3761 psa_verify_hash_abort_internal(operation);
3762 }
3763
3764 return status;
3765}
3766
3767psa_status_t psa_verify_hash_abort(
3768 psa_verify_hash_interruptible_operation_t *operation)
3769{
3770 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3771
3772 status = psa_verify_hash_abort_internal(operation);
3773
3774 /* We clear the number of ops done here, so that it is not cleared when
3775 * the operation fails or succeeds, only on manual abort. */
3776 operation->num_ops = 0;
3777
3778 /* Likewise, failure state. */
3779 operation->error_occurred = 0;
3780
3781 return status;
3782}
3783
3784/****************************************************************/
3785/* Asymmetric interruptible cryptography internal */
3786/* implementations */
3787/****************************************************************/
3788
3789void mbedtls_psa_interruptible_set_max_ops(uint32_t max_ops)
3790{
3791
3792#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3793 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
3794 defined(MBEDTLS_ECP_RESTARTABLE)
3795
3796 /* Internal implementation uses zero to indicate infinite number max ops,
3797 * therefore avoid this value, and set to minimum possible. */
3798 if (max_ops == 0) {
3799 max_ops = 1;
3800 }
3801
3802 mbedtls_ecp_set_max_ops(max_ops);
3803#else
3804 (void) max_ops;
3805#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3806 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
3807 * defined( MBEDTLS_ECP_RESTARTABLE ) */
3808}
3809
3810uint32_t mbedtls_psa_sign_hash_get_num_ops(
3811 const mbedtls_psa_sign_hash_interruptible_operation_t *operation)
3812{
3813#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3814 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
3815 defined(MBEDTLS_ECP_RESTARTABLE)
3816
3817 return operation->num_ops;
3818#else
3819 (void) operation;
3820 return 0;
3821#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3822 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
3823 * defined( MBEDTLS_ECP_RESTARTABLE ) */
3824}
3825
3826uint32_t mbedtls_psa_verify_hash_get_num_ops(
3827 const mbedtls_psa_verify_hash_interruptible_operation_t *operation)
3828{
3829 #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3830 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
3831 defined(MBEDTLS_ECP_RESTARTABLE)
3832
3833 return operation->num_ops;
3834#else
3835 (void) operation;
3836 return 0;
3837#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3838 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
3839 * defined( MBEDTLS_ECP_RESTARTABLE ) */
3840}
3841
3842psa_status_t mbedtls_psa_sign_hash_start(
3843 mbedtls_psa_sign_hash_interruptible_operation_t *operation,
3844 const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
3845 size_t key_buffer_size, psa_algorithm_t alg,
3846 const uint8_t *hash, size_t hash_length)
3847{
3848 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3849 size_t required_hash_length;
3850
3851 if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) {
3852 return PSA_ERROR_NOT_SUPPORTED;
3853 }
3854
3855 if (!PSA_ALG_IS_ECDSA(alg)) {
3856 return PSA_ERROR_NOT_SUPPORTED;
3857 }
3858
3859#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3860 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
3861 defined(MBEDTLS_ECP_RESTARTABLE)
3862
3863 mbedtls_ecdsa_restart_init(&operation->restart_ctx);
3864
3865 /* Ensure num_ops is zero'ed in case of context re-use. */
3866 operation->num_ops = 0;
3867
3868 status = mbedtls_psa_ecp_load_representation(attributes->type,
3869 attributes->bits,
3870 key_buffer,
3871 key_buffer_size,
3872 &operation->ctx);
3873
3874 if (status != PSA_SUCCESS) {
3875 return status;
3876 }
3877
3878 operation->coordinate_bytes = PSA_BITS_TO_BYTES(
3879 operation->ctx->grp.nbits);
3880
3881 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
3882 operation->md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
3883 operation->alg = alg;
3884
3885 /* We only need to store the same length of hash as the private key size
3886 * here, it would be truncated by the internal implementation anyway. */
3887 required_hash_length = (hash_length < operation->coordinate_bytes ?
3888 hash_length : operation->coordinate_bytes);
3889
3890 if (required_hash_length > sizeof(operation->hash)) {
3891 /* Shouldn't happen, but better safe than sorry. */
3892 return PSA_ERROR_CORRUPTION_DETECTED;
3893 }
3894
3895 memcpy(operation->hash, hash, required_hash_length);
3896 operation->hash_length = required_hash_length;
3897
3898 return PSA_SUCCESS;
3899
3900#else
3901 (void) operation;
3902 (void) key_buffer;
3903 (void) key_buffer_size;
3904 (void) alg;
3905 (void) hash;
3906 (void) hash_length;
3907 (void) status;
3908 (void) required_hash_length;
3909
3910 return PSA_ERROR_NOT_SUPPORTED;
3911#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3912 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
3913 * defined( MBEDTLS_ECP_RESTARTABLE ) */
3914}
3915
3916psa_status_t mbedtls_psa_sign_hash_complete(
3917 mbedtls_psa_sign_hash_interruptible_operation_t *operation,
3918 uint8_t *signature, size_t signature_size,
3919 size_t *signature_length)
3920{
3921#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3922 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
3923 defined(MBEDTLS_ECP_RESTARTABLE)
3924
3925 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3926 mbedtls_mpi r;
3927 mbedtls_mpi s;
3928
3929 mbedtls_mpi_init(&r);
3930 mbedtls_mpi_init(&s);
3931
3932 /* Ensure max_ops is set to the current value (or default). */
3933 mbedtls_psa_interruptible_set_max_ops(psa_interruptible_get_max_ops());
3934
3935 if (signature_size < 2 * operation->coordinate_bytes) {
3936 status = PSA_ERROR_BUFFER_TOO_SMALL;
3937 goto exit;
3938 }
3939
3940 if (PSA_ALG_ECDSA_IS_DETERMINISTIC(operation->alg)) {
3941
3942#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
3943 status = mbedtls_to_psa_error(
3944 mbedtls_ecdsa_sign_det_restartable(&operation->ctx->grp,
3945 &r,
3946 &s,
3947 &operation->ctx->d,
3948 operation->hash,
3949 operation->hash_length,
3950 operation->md_alg,
3951 mbedtls_psa_get_random,
3952 MBEDTLS_PSA_RANDOM_STATE,
3953 &operation->restart_ctx));
3954#else /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
3955 status = PSA_ERROR_NOT_SUPPORTED;
3956 goto exit;
3957#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
3958 } else {
3959 status = mbedtls_to_psa_error(
3960 mbedtls_ecdsa_sign_restartable(&operation->ctx->grp,
3961 &r,
3962 &s,
3963 &operation->ctx->d,
3964 operation->hash,
3965 operation->hash_length,
3966 mbedtls_psa_get_random,
3967 MBEDTLS_PSA_RANDOM_STATE,
3968 mbedtls_psa_get_random,
3969 MBEDTLS_PSA_RANDOM_STATE,
3970 &operation->restart_ctx));
3971 }
3972
3973 /* Hide the fact that the restart context only holds a delta of number of
3974 * ops done during the last operation, not an absolute value. */
3975 operation->num_ops += operation->restart_ctx.ecp.ops_done;
3976
3977 if (status == PSA_SUCCESS) {
3978 status = mbedtls_to_psa_error(
3979 mbedtls_mpi_write_binary(&r,
3980 signature,
3981 operation->coordinate_bytes)
3982 );
3983
3984 if (status != PSA_SUCCESS) {
3985 goto exit;
3986 }
3987
3988 status = mbedtls_to_psa_error(
3989 mbedtls_mpi_write_binary(&s,
3990 signature +
3991 operation->coordinate_bytes,
3992 operation->coordinate_bytes)
3993 );
3994
3995 if (status != PSA_SUCCESS) {
3996 goto exit;
3997 }
3998
3999 *signature_length = operation->coordinate_bytes * 2;
4000
4001 status = PSA_SUCCESS;
4002 }
4003
4004exit:
4005
4006 mbedtls_mpi_free(&r);
4007 mbedtls_mpi_free(&s);
4008 return status;
4009
4010 #else
4011
4012 (void) operation;
4013 (void) signature;
4014 (void) signature_size;
4015 (void) signature_length;
4016
4017 return PSA_ERROR_NOT_SUPPORTED;
4018
4019#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
4020 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
4021 * defined( MBEDTLS_ECP_RESTARTABLE ) */
4022}
4023
4024psa_status_t mbedtls_psa_sign_hash_abort(
4025 mbedtls_psa_sign_hash_interruptible_operation_t *operation)
4026{
4027
4028#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
4029 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
4030 defined(MBEDTLS_ECP_RESTARTABLE)
4031
4032 if (operation->ctx) {
4033 mbedtls_ecdsa_free(operation->ctx);
4034 mbedtls_free(operation->ctx);
4035 operation->ctx = NULL;
4036 }
4037
4038 mbedtls_ecdsa_restart_free(&operation->restart_ctx);
4039
4040 operation->num_ops = 0;
4041
4042 return PSA_SUCCESS;
4043
4044#else
4045
4046 (void) operation;
4047
4048 return PSA_ERROR_NOT_SUPPORTED;
4049
4050#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
4051 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
4052 * defined( MBEDTLS_ECP_RESTARTABLE ) */
4053}
4054
4055psa_status_t mbedtls_psa_verify_hash_start(
4056 mbedtls_psa_verify_hash_interruptible_operation_t *operation,
4057 const psa_key_attributes_t *attributes,
4058 const uint8_t *key_buffer, size_t key_buffer_size,
4059 psa_algorithm_t alg,
4060 const uint8_t *hash, size_t hash_length,
4061 const uint8_t *signature, size_t signature_length)
4062{
4063 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4064 size_t coordinate_bytes = 0;
4065 size_t required_hash_length = 0;
4066
4067 if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) {
4068 return PSA_ERROR_NOT_SUPPORTED;
4069 }
4070
4071 if (!PSA_ALG_IS_ECDSA(alg)) {
4072 return PSA_ERROR_NOT_SUPPORTED;
4073 }
4074
4075#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
4076 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
4077 defined(MBEDTLS_ECP_RESTARTABLE)
4078
4079 mbedtls_ecdsa_restart_init(&operation->restart_ctx);
4080 mbedtls_mpi_init(&operation->r);
4081 mbedtls_mpi_init(&operation->s);
4082
4083 /* Ensure num_ops is zero'ed in case of context re-use. */
4084 operation->num_ops = 0;
4085
4086 status = mbedtls_psa_ecp_load_representation(attributes->type,
4087 attributes->bits,
4088 key_buffer,
4089 key_buffer_size,
4090 &operation->ctx);
4091
4092 if (status != PSA_SUCCESS) {
4093 return status;
4094 }
4095
4096 coordinate_bytes = PSA_BITS_TO_BYTES(operation->ctx->grp.nbits);
4097
4098 if (signature_length != 2 * coordinate_bytes) {
4099 return PSA_ERROR_INVALID_SIGNATURE;
4100 }
4101
4102 status = mbedtls_to_psa_error(
4103 mbedtls_mpi_read_binary(&operation->r,
4104 signature,
4105 coordinate_bytes));
4106
4107 if (status != PSA_SUCCESS) {
4108 return status;
4109 }
4110
4111 status = mbedtls_to_psa_error(
4112 mbedtls_mpi_read_binary(&operation->s,
4113 signature +
4114 coordinate_bytes,
4115 coordinate_bytes));
4116
4117 if (status != PSA_SUCCESS) {
4118 return status;
4119 }
4120
4121 status = mbedtls_psa_ecp_load_public_part(operation->ctx);
4122
4123 if (status != PSA_SUCCESS) {
4124 return status;
4125 }
4126
4127 /* We only need to store the same length of hash as the private key size
4128 * here, it would be truncated by the internal implementation anyway. */
4129 required_hash_length = (hash_length < coordinate_bytes ? hash_length :
4130 coordinate_bytes);
4131
4132 if (required_hash_length > sizeof(operation->hash)) {
4133 /* Shouldn't happen, but better safe than sorry. */
4134 return PSA_ERROR_CORRUPTION_DETECTED;
4135 }
4136
4137 memcpy(operation->hash, hash, required_hash_length);
4138 operation->hash_length = required_hash_length;
4139
4140 return PSA_SUCCESS;
4141#else
4142 (void) operation;
4143 (void) key_buffer;
4144 (void) key_buffer_size;
4145 (void) alg;
4146 (void) hash;
4147 (void) hash_length;
4148 (void) signature;
4149 (void) signature_length;
4150 (void) status;
4151 (void) coordinate_bytes;
4152 (void) required_hash_length;
4153
4154 return PSA_ERROR_NOT_SUPPORTED;
4155#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
4156 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
4157 * defined( MBEDTLS_ECP_RESTARTABLE ) */
4158}
4159
4160psa_status_t mbedtls_psa_verify_hash_complete(
4161 mbedtls_psa_verify_hash_interruptible_operation_t *operation)
4162{
4163
4164#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
4165 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
4166 defined(MBEDTLS_ECP_RESTARTABLE)
4167
4168 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4169
4170 /* Ensure max_ops is set to the current value (or default). */
4171 mbedtls_psa_interruptible_set_max_ops(psa_interruptible_get_max_ops());
4172
4173 status = mbedtls_to_psa_error(
4174 mbedtls_ecdsa_verify_restartable(&operation->ctx->grp,
4175 operation->hash,
4176 operation->hash_length,
4177 &operation->ctx->Q,
4178 &operation->r,
4179 &operation->s,
4180 &operation->restart_ctx));
4181
4182 /* Hide the fact that the restart context only holds a delta of number of
4183 * ops done during the last operation, not an absolute value. */
4184 operation->num_ops += operation->restart_ctx.ecp.ops_done;
4185
4186 return status;
4187#else
4188 (void) operation;
4189
4190 return PSA_ERROR_NOT_SUPPORTED;
4191
4192#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
4193 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
4194 * defined( MBEDTLS_ECP_RESTARTABLE ) */
4195}
4196
4197psa_status_t mbedtls_psa_verify_hash_abort(
4198 mbedtls_psa_verify_hash_interruptible_operation_t *operation)
4199{
4200
4201#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
4202 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
4203 defined(MBEDTLS_ECP_RESTARTABLE)
4204
4205 if (operation->ctx) {
4206 mbedtls_ecdsa_free(operation->ctx);
4207 mbedtls_free(operation->ctx);
4208 operation->ctx = NULL;
4209 }
4210
4211 mbedtls_ecdsa_restart_free(&operation->restart_ctx);
4212
4213 operation->num_ops = 0;
4214
4215 mbedtls_mpi_free(&operation->r);
4216 mbedtls_mpi_free(&operation->s);
4217
4218 return PSA_SUCCESS;
4219
4220#else
4221 (void) operation;
4222
4223 return PSA_ERROR_NOT_SUPPORTED;
4224
4225#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
4226 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
4227 * defined( MBEDTLS_ECP_RESTARTABLE ) */
4228}
4229
4230static psa_status_t psa_generate_random_internal(uint8_t *output,
4231 size_t output_size)
4232{
4233 GUARD_MODULE_INITIALIZED;
4234
4235#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
4236
4237 psa_status_t status;
4238 size_t output_length = 0;
4239 status = mbedtls_psa_external_get_random(&global_data.rng,
4240 output, output_size,
4241 &output_length);
4242 if (status != PSA_SUCCESS) {
4243 return status;
4244 }
4245 /* Breaking up a request into smaller chunks is currently not supported
4246 * for the external RNG interface. */
4247 if (output_length != output_size) {
4248 return PSA_ERROR_INSUFFICIENT_ENTROPY;
4249 }
4250 return PSA_SUCCESS;
4251
4252#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
4253
4254 while (output_size > 0) {
4255 int ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
4256 size_t request_size =
4257 (output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ?
4258 MBEDTLS_PSA_RANDOM_MAX_REQUEST :
4259 output_size);
4260#if defined(MBEDTLS_CTR_DRBG_C)
4261 ret = mbedtls_ctr_drbg_random(&global_data.rng.drbg, output, request_size);
4262#elif defined(MBEDTLS_HMAC_DRBG_C)
4263 ret = mbedtls_hmac_drbg_random(&global_data.rng.drbg, output, request_size);
4264#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
4265 if (ret != 0) {
4266 return mbedtls_to_psa_error(ret);
4267 }
4268 output_size -= request_size;
4269 output += request_size;
4270 }
4271 return PSA_SUCCESS;
4272#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
4273}
4274
4275
4276/****************************************************************/
4277/* Symmetric cryptography */
4278/****************************************************************/
4279
4280static psa_status_t psa_cipher_setup(psa_cipher_operation_t *operation,
4281 mbedtls_svc_key_id_t key,
4282 psa_algorithm_t alg,
4283 mbedtls_operation_t cipher_operation)
4284{
4285 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4286 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
4287 psa_key_slot_t *slot = NULL;
4288 psa_key_usage_t usage = (cipher_operation == MBEDTLS_ENCRYPT ?
4289 PSA_KEY_USAGE_ENCRYPT :
4290 PSA_KEY_USAGE_DECRYPT);
4291
4292 /* A context must be freshly initialized before it can be set up. */
4293 if (operation->id != 0) {
4294 status = PSA_ERROR_BAD_STATE;
4295 goto exit;
4296 }
4297
4298 if (!PSA_ALG_IS_CIPHER(alg)) {
4299 status = PSA_ERROR_INVALID_ARGUMENT;
4300 goto exit;
4301 }
4302
4303 status = psa_get_and_lock_key_slot_with_policy(key, &slot, usage, alg);
4304 if (status != PSA_SUCCESS) {
4305 goto exit;
4306 }
4307
4308 /* Initialize the operation struct members, except for id. The id member
4309 * is used to indicate to psa_cipher_abort that there are resources to free,
4310 * so we only set it (in the driver wrapper) after resources have been
4311 * allocated/initialized. */
4312 operation->iv_set = 0;
4313 if (alg == PSA_ALG_ECB_NO_PADDING) {
4314 operation->iv_required = 0;
4315 } else {
4316 operation->iv_required = 1;
4317 }
4318 operation->default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg);
4319
4320 /* Try doing the operation through a driver before using software fallback. */
4321 if (cipher_operation == MBEDTLS_ENCRYPT) {
4322 status = psa_driver_wrapper_cipher_encrypt_setup(operation,
4323 &slot->attr,
4324 slot->key.data,
4325 slot->key.bytes,
4326 alg);
4327 } else {
4328 status = psa_driver_wrapper_cipher_decrypt_setup(operation,
4329 &slot->attr,
4330 slot->key.data,
4331 slot->key.bytes,
4332 alg);
4333 }
4334
4335exit:
4336 if (status != PSA_SUCCESS) {
4337 psa_cipher_abort(operation);
4338 }
4339
4340 unlock_status = psa_unregister_read_under_mutex(slot);
4341
4342 return (status == PSA_SUCCESS) ? unlock_status : status;
4343}
4344
4345psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
4346 mbedtls_svc_key_id_t key,
4347 psa_algorithm_t alg)
4348{
4349 return psa_cipher_setup(operation, key, alg, MBEDTLS_ENCRYPT);
4350}
4351
4352psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
4353 mbedtls_svc_key_id_t key,
4354 psa_algorithm_t alg)
4355{
4356 return psa_cipher_setup(operation, key, alg, MBEDTLS_DECRYPT);
4357}
4358
4359psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
4360 uint8_t *iv_external,
4361 size_t iv_size,
4362 size_t *iv_length)
4363{
4364 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4365 size_t default_iv_length = 0;
4366
4367 LOCAL_OUTPUT_DECLARE(iv_external, iv);
4368
4369 if (operation->id == 0) {
4370 status = PSA_ERROR_BAD_STATE;
4371 goto exit;
4372 }
4373
4374 if (operation->iv_set || !operation->iv_required) {
4375 status = PSA_ERROR_BAD_STATE;
4376 goto exit;
4377 }
4378
4379 default_iv_length = operation->default_iv_length;
4380 if (iv_size < default_iv_length) {
4381 status = PSA_ERROR_BUFFER_TOO_SMALL;
4382 goto exit;
4383 }
4384
4385 if (default_iv_length > PSA_CIPHER_IV_MAX_SIZE) {
4386 status = PSA_ERROR_GENERIC_ERROR;
4387 goto exit;
4388 }
4389
4390 LOCAL_OUTPUT_ALLOC(iv_external, default_iv_length, iv);
4391
4392 status = psa_generate_random_internal(iv, default_iv_length);
4393 if (status != PSA_SUCCESS) {
4394 goto exit;
4395 }
4396
4397 status = psa_driver_wrapper_cipher_set_iv(operation,
4398 iv, default_iv_length);
4399
4400exit:
4401 if (status == PSA_SUCCESS) {
4402 *iv_length = default_iv_length;
4403 operation->iv_set = 1;
4404 } else {
4405 *iv_length = 0;
4406 psa_cipher_abort(operation);
4407 if (iv != NULL) {
4408 mbedtls_platform_zeroize(iv, default_iv_length);
4409 }
4410 }
4411
4412 LOCAL_OUTPUT_FREE(iv_external, iv);
4413 return status;
4414}
4415
4416psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
4417 const uint8_t *iv_external,
4418 size_t iv_length)
4419{
4420 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4421
4422 LOCAL_INPUT_DECLARE(iv_external, iv);
4423
4424 if (operation->id == 0) {
4425 status = PSA_ERROR_BAD_STATE;
4426 goto exit;
4427 }
4428
4429 if (operation->iv_set || !operation->iv_required) {
4430 status = PSA_ERROR_BAD_STATE;
4431 goto exit;
4432 }
4433
4434 if (iv_length > PSA_CIPHER_IV_MAX_SIZE) {
4435 status = PSA_ERROR_INVALID_ARGUMENT;
4436 goto exit;
4437 }
4438
4439 LOCAL_INPUT_ALLOC(iv_external, iv_length, iv);
4440
4441 status = psa_driver_wrapper_cipher_set_iv(operation,
4442 iv,
4443 iv_length);
4444
4445exit:
4446 if (status == PSA_SUCCESS) {
4447 operation->iv_set = 1;
4448 } else {
4449 psa_cipher_abort(operation);
4450 }
4451
4452 LOCAL_INPUT_FREE(iv_external, iv);
4453
4454 return status;
4455}
4456
4457psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
4458 const uint8_t *input_external,
4459 size_t input_length,
4460 uint8_t *output_external,
4461 size_t output_size,
4462 size_t *output_length)
4463{
4464 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4465
4466 LOCAL_INPUT_DECLARE(input_external, input);
4467 LOCAL_OUTPUT_DECLARE(output_external, output);
4468
4469 if (operation->id == 0) {
4470 status = PSA_ERROR_BAD_STATE;
4471 goto exit;
4472 }
4473
4474 if (operation->iv_required && !operation->iv_set) {
4475 status = PSA_ERROR_BAD_STATE;
4476 goto exit;
4477 }
4478
4479 LOCAL_INPUT_ALLOC(input_external, input_length, input);
4480 LOCAL_OUTPUT_ALLOC(output_external, output_size, output);
4481
4482 status = psa_driver_wrapper_cipher_update(operation,
4483 input,
4484 input_length,
4485 output,
4486 output_size,
4487 output_length);
4488
4489exit:
4490 if (status != PSA_SUCCESS) {
4491 psa_cipher_abort(operation);
4492 }
4493
4494 LOCAL_INPUT_FREE(input_external, input);
4495 LOCAL_OUTPUT_FREE(output_external, output);
4496
4497 return status;
4498}
4499
4500psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
4501 uint8_t *output_external,
4502 size_t output_size,
4503 size_t *output_length)
4504{
4505 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
4506
4507 LOCAL_OUTPUT_DECLARE(output_external, output);
4508
4509 if (operation->id == 0) {
4510 status = PSA_ERROR_BAD_STATE;
4511 goto exit;
4512 }
4513
4514 if (operation->iv_required && !operation->iv_set) {
4515 status = PSA_ERROR_BAD_STATE;
4516 goto exit;
4517 }
4518
4519 LOCAL_OUTPUT_ALLOC(output_external, output_size, output);
4520
4521 status = psa_driver_wrapper_cipher_finish(operation,
4522 output,
4523 output_size,
4524 output_length);
4525
4526exit:
4527 if (status == PSA_SUCCESS) {
4528 status = psa_cipher_abort(operation);
4529 } else {
4530 *output_length = 0;
4531 (void) psa_cipher_abort(operation);
4532 }
4533
4534 LOCAL_OUTPUT_FREE(output_external, output);
4535
4536 return status;
4537}
4538
4539psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
4540{
4541 if (operation->id == 0) {
4542 /* The object has (apparently) been initialized but it is not (yet)
4543 * in use. It's ok to call abort on such an object, and there's
4544 * nothing to do. */
4545 return PSA_SUCCESS;
4546 }
4547
4548 psa_driver_wrapper_cipher_abort(operation);
4549
4550 operation->id = 0;
4551 operation->iv_set = 0;
4552 operation->iv_required = 0;
4553
4554 return PSA_SUCCESS;
4555}
4556
4557psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key,
4558 psa_algorithm_t alg,
4559 const uint8_t *input_external,
4560 size_t input_length,
4561 uint8_t *output_external,
4562 size_t output_size,
4563 size_t *output_length)
4564{
4565 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4566 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
4567 psa_key_slot_t *slot = NULL;
4568 uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE];
4569 size_t default_iv_length = 0;
4570
4571 LOCAL_INPUT_DECLARE(input_external, input);
4572 LOCAL_OUTPUT_DECLARE(output_external, output);
4573
4574 if (!PSA_ALG_IS_CIPHER(alg)) {
4575 status = PSA_ERROR_INVALID_ARGUMENT;
4576 goto exit;
4577 }
4578
4579 status = psa_get_and_lock_key_slot_with_policy(key, &slot,
4580 PSA_KEY_USAGE_ENCRYPT,
4581 alg);
4582 if (status != PSA_SUCCESS) {
4583 goto exit;
4584 }
4585
4586 default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg);
4587 if (default_iv_length > PSA_CIPHER_IV_MAX_SIZE) {
4588 status = PSA_ERROR_GENERIC_ERROR;
4589 goto exit;
4590 }
4591
4592 if (default_iv_length > 0) {
4593 if (output_size < default_iv_length) {
4594 status = PSA_ERROR_BUFFER_TOO_SMALL;
4595 goto exit;
4596 }
4597
4598 status = psa_generate_random_internal(local_iv, default_iv_length);
4599 if (status != PSA_SUCCESS) {
4600 goto exit;
4601 }
4602 }
4603
4604 LOCAL_INPUT_ALLOC(input_external, input_length, input);
4605 LOCAL_OUTPUT_ALLOC(output_external, output_size, output);
4606
4607 status = psa_driver_wrapper_cipher_encrypt(
4608 &slot->attr, slot->key.data, slot->key.bytes,
4609 alg, local_iv, default_iv_length, input, input_length,
4610 psa_crypto_buffer_offset(output, default_iv_length),
4611 output_size - default_iv_length, output_length);
4612
4613exit:
4614 unlock_status = psa_unregister_read_under_mutex(slot);
4615 if (status == PSA_SUCCESS) {
4616 status = unlock_status;
4617 }
4618
4619 if (status == PSA_SUCCESS) {
4620 if (default_iv_length > 0) {
4621 memcpy(output, local_iv, default_iv_length);
4622 }
4623 *output_length += default_iv_length;
4624 } else {
4625 *output_length = 0;
4626 }
4627
4628 LOCAL_INPUT_FREE(input_external, input);
4629 LOCAL_OUTPUT_FREE(output_external, output);
4630
4631 return status;
4632}
4633
4634psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key,
4635 psa_algorithm_t alg,
4636 const uint8_t *input_external,
4637 size_t input_length,
4638 uint8_t *output_external,
4639 size_t output_size,
4640 size_t *output_length)
4641{
4642 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4643 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
4644 psa_key_slot_t *slot = NULL;
4645
4646 LOCAL_INPUT_DECLARE(input_external, input);
4647 LOCAL_OUTPUT_DECLARE(output_external, output);
4648
4649 if (!PSA_ALG_IS_CIPHER(alg)) {
4650 status = PSA_ERROR_INVALID_ARGUMENT;
4651 goto exit;
4652 }
4653
4654 status = psa_get_and_lock_key_slot_with_policy(key, &slot,
4655 PSA_KEY_USAGE_DECRYPT,
4656 alg);
4657 if (status != PSA_SUCCESS) {
4658 goto exit;
4659 }
4660
Sungbae Yoo4d211f32024-11-19 02:47:55 +00004661 if (input_length < PSA_CIPHER_IV_LENGTH(slot->attr.type, alg)) {
Tom Van Eyckb0563632024-06-13 16:20:14 +02004662 status = PSA_ERROR_INVALID_ARGUMENT;
4663 goto exit;
4664 }
4665
4666 LOCAL_INPUT_ALLOC(input_external, input_length, input);
4667 LOCAL_OUTPUT_ALLOC(output_external, output_size, output);
4668
4669 status = psa_driver_wrapper_cipher_decrypt(
4670 &slot->attr, slot->key.data, slot->key.bytes,
4671 alg, input, input_length,
4672 output, output_size, output_length);
4673
4674exit:
4675 unlock_status = psa_unregister_read_under_mutex(slot);
4676 if (status == PSA_SUCCESS) {
4677 status = unlock_status;
4678 }
4679
4680 if (status != PSA_SUCCESS) {
4681 *output_length = 0;
4682 }
4683
4684 LOCAL_INPUT_FREE(input_external, input);
4685 LOCAL_OUTPUT_FREE(output_external, output);
4686
4687 return status;
4688}
4689
4690
4691/****************************************************************/
4692/* AEAD */
4693/****************************************************************/
4694
4695/* Helper function to get the base algorithm from its variants. */
4696static psa_algorithm_t psa_aead_get_base_algorithm(psa_algorithm_t alg)
4697{
4698 return PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg);
4699}
4700
4701/* Helper function to perform common nonce length checks. */
4702static psa_status_t psa_aead_check_nonce_length(psa_algorithm_t alg,
4703 size_t nonce_length)
4704{
4705 psa_algorithm_t base_alg = psa_aead_get_base_algorithm(alg);
4706
4707 switch (base_alg) {
4708#if defined(PSA_WANT_ALG_GCM)
4709 case PSA_ALG_GCM:
4710 /* Not checking max nonce size here as GCM spec allows almost
4711 * arbitrarily large nonces. Please note that we do not generally
4712 * recommend the usage of nonces of greater length than
4713 * PSA_AEAD_NONCE_MAX_SIZE, as large nonces are hashed to a shorter
4714 * size, which can then lead to collisions if you encrypt a very
4715 * large number of messages.*/
4716 if (nonce_length != 0) {
4717 return PSA_SUCCESS;
4718 }
4719 break;
4720#endif /* PSA_WANT_ALG_GCM */
4721#if defined(PSA_WANT_ALG_CCM)
4722 case PSA_ALG_CCM:
4723 if (nonce_length >= 7 && nonce_length <= 13) {
4724 return PSA_SUCCESS;
4725 }
4726 break;
4727#endif /* PSA_WANT_ALG_CCM */
4728#if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
4729 case PSA_ALG_CHACHA20_POLY1305:
4730 if (nonce_length == 12) {
4731 return PSA_SUCCESS;
4732 } else if (nonce_length == 8) {
4733 return PSA_ERROR_NOT_SUPPORTED;
4734 }
4735 break;
4736#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
4737 default:
4738 (void) nonce_length;
4739 return PSA_ERROR_NOT_SUPPORTED;
4740 }
4741
4742 return PSA_ERROR_INVALID_ARGUMENT;
4743}
4744
4745static psa_status_t psa_aead_check_algorithm(psa_algorithm_t alg)
4746{
4747 if (!PSA_ALG_IS_AEAD(alg) || PSA_ALG_IS_WILDCARD(alg)) {
4748 return PSA_ERROR_INVALID_ARGUMENT;
4749 }
4750
4751 return PSA_SUCCESS;
4752}
4753
4754psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key,
4755 psa_algorithm_t alg,
4756 const uint8_t *nonce_external,
4757 size_t nonce_length,
4758 const uint8_t *additional_data_external,
4759 size_t additional_data_length,
4760 const uint8_t *plaintext_external,
4761 size_t plaintext_length,
4762 uint8_t *ciphertext_external,
4763 size_t ciphertext_size,
4764 size_t *ciphertext_length)
4765{
4766 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4767 psa_key_slot_t *slot;
4768
4769 LOCAL_INPUT_DECLARE(nonce_external, nonce);
4770 LOCAL_INPUT_DECLARE(additional_data_external, additional_data);
4771 LOCAL_INPUT_DECLARE(plaintext_external, plaintext);
4772 LOCAL_OUTPUT_DECLARE(ciphertext_external, ciphertext);
4773
4774 *ciphertext_length = 0;
4775
4776 status = psa_aead_check_algorithm(alg);
4777 if (status != PSA_SUCCESS) {
4778 return status;
4779 }
4780
4781 status = psa_get_and_lock_key_slot_with_policy(
4782 key, &slot, PSA_KEY_USAGE_ENCRYPT, alg);
4783 if (status != PSA_SUCCESS) {
4784 return status;
4785 }
4786
4787 LOCAL_INPUT_ALLOC(nonce_external, nonce_length, nonce);
4788 LOCAL_INPUT_ALLOC(additional_data_external, additional_data_length, additional_data);
4789 LOCAL_INPUT_ALLOC(plaintext_external, plaintext_length, plaintext);
4790 LOCAL_OUTPUT_ALLOC(ciphertext_external, ciphertext_size, ciphertext);
4791
4792 status = psa_aead_check_nonce_length(alg, nonce_length);
4793 if (status != PSA_SUCCESS) {
4794 goto exit;
4795 }
4796
4797 status = psa_driver_wrapper_aead_encrypt(
4798 &slot->attr, slot->key.data, slot->key.bytes,
4799 alg,
4800 nonce, nonce_length,
4801 additional_data, additional_data_length,
4802 plaintext, plaintext_length,
4803 ciphertext, ciphertext_size, ciphertext_length);
4804
4805 if (status != PSA_SUCCESS && ciphertext_size != 0) {
4806 memset(ciphertext, 0, ciphertext_size);
4807 }
4808
4809exit:
4810 LOCAL_INPUT_FREE(nonce_external, nonce);
4811 LOCAL_INPUT_FREE(additional_data_external, additional_data);
4812 LOCAL_INPUT_FREE(plaintext_external, plaintext);
4813 LOCAL_OUTPUT_FREE(ciphertext_external, ciphertext);
4814
4815 psa_unregister_read_under_mutex(slot);
4816
4817 return status;
4818}
4819
4820psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key,
4821 psa_algorithm_t alg,
4822 const uint8_t *nonce_external,
4823 size_t nonce_length,
4824 const uint8_t *additional_data_external,
4825 size_t additional_data_length,
4826 const uint8_t *ciphertext_external,
4827 size_t ciphertext_length,
4828 uint8_t *plaintext_external,
4829 size_t plaintext_size,
4830 size_t *plaintext_length)
4831{
4832 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4833 psa_key_slot_t *slot;
4834
4835 LOCAL_INPUT_DECLARE(nonce_external, nonce);
4836 LOCAL_INPUT_DECLARE(additional_data_external, additional_data);
4837 LOCAL_INPUT_DECLARE(ciphertext_external, ciphertext);
4838 LOCAL_OUTPUT_DECLARE(plaintext_external, plaintext);
4839
4840 *plaintext_length = 0;
4841
4842 status = psa_aead_check_algorithm(alg);
4843 if (status != PSA_SUCCESS) {
4844 return status;
4845 }
4846
4847 status = psa_get_and_lock_key_slot_with_policy(
4848 key, &slot, PSA_KEY_USAGE_DECRYPT, alg);
4849 if (status != PSA_SUCCESS) {
4850 return status;
4851 }
4852
4853 LOCAL_INPUT_ALLOC(nonce_external, nonce_length, nonce);
4854 LOCAL_INPUT_ALLOC(additional_data_external, additional_data_length,
4855 additional_data);
4856 LOCAL_INPUT_ALLOC(ciphertext_external, ciphertext_length, ciphertext);
4857 LOCAL_OUTPUT_ALLOC(plaintext_external, plaintext_size, plaintext);
4858
4859 status = psa_aead_check_nonce_length(alg, nonce_length);
4860 if (status != PSA_SUCCESS) {
4861 goto exit;
4862 }
4863
4864 status = psa_driver_wrapper_aead_decrypt(
4865 &slot->attr, slot->key.data, slot->key.bytes,
4866 alg,
4867 nonce, nonce_length,
4868 additional_data, additional_data_length,
4869 ciphertext, ciphertext_length,
4870 plaintext, plaintext_size, plaintext_length);
4871
4872 if (status != PSA_SUCCESS && plaintext_size != 0) {
4873 memset(plaintext, 0, plaintext_size);
4874 }
4875
4876exit:
4877 LOCAL_INPUT_FREE(nonce_external, nonce);
4878 LOCAL_INPUT_FREE(additional_data_external, additional_data);
4879 LOCAL_INPUT_FREE(ciphertext_external, ciphertext);
4880 LOCAL_OUTPUT_FREE(plaintext_external, plaintext);
4881
4882 psa_unregister_read_under_mutex(slot);
4883
4884 return status;
4885}
4886
4887static psa_status_t psa_validate_tag_length(psa_algorithm_t alg)
4888{
4889 const uint8_t tag_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg);
4890
4891 switch (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0)) {
4892#if defined(PSA_WANT_ALG_CCM)
4893 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
4894 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.*/
4895 if (tag_len < 4 || tag_len > 16 || tag_len % 2) {
4896 return PSA_ERROR_INVALID_ARGUMENT;
4897 }
4898 break;
4899#endif /* PSA_WANT_ALG_CCM */
4900
4901#if defined(PSA_WANT_ALG_GCM)
4902 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
4903 /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. */
4904 if (tag_len != 4 && tag_len != 8 && (tag_len < 12 || tag_len > 16)) {
4905 return PSA_ERROR_INVALID_ARGUMENT;
4906 }
4907 break;
4908#endif /* PSA_WANT_ALG_GCM */
4909
4910#if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
4911 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
4912 /* We only support the default tag length. */
4913 if (tag_len != 16) {
4914 return PSA_ERROR_INVALID_ARGUMENT;
4915 }
4916 break;
4917#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
4918
4919 default:
4920 (void) tag_len;
4921 return PSA_ERROR_NOT_SUPPORTED;
4922 }
4923 return PSA_SUCCESS;
4924}
4925
4926/* Set the key for a multipart authenticated operation. */
4927static psa_status_t psa_aead_setup(psa_aead_operation_t *operation,
4928 int is_encrypt,
4929 mbedtls_svc_key_id_t key,
4930 psa_algorithm_t alg)
4931{
4932 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4933 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
4934 psa_key_slot_t *slot = NULL;
4935 psa_key_usage_t key_usage = 0;
4936
4937 status = psa_aead_check_algorithm(alg);
4938 if (status != PSA_SUCCESS) {
4939 goto exit;
4940 }
4941
4942 if (operation->id != 0) {
4943 status = PSA_ERROR_BAD_STATE;
4944 goto exit;
4945 }
4946
4947 if (operation->nonce_set || operation->lengths_set ||
4948 operation->ad_started || operation->body_started) {
4949 status = PSA_ERROR_BAD_STATE;
4950 goto exit;
4951 }
4952
4953 if (is_encrypt) {
4954 key_usage = PSA_KEY_USAGE_ENCRYPT;
4955 } else {
4956 key_usage = PSA_KEY_USAGE_DECRYPT;
4957 }
4958
4959 status = psa_get_and_lock_key_slot_with_policy(key, &slot, key_usage,
4960 alg);
4961 if (status != PSA_SUCCESS) {
4962 goto exit;
4963 }
4964
4965 if ((status = psa_validate_tag_length(alg)) != PSA_SUCCESS) {
4966 goto exit;
4967 }
4968
4969 if (is_encrypt) {
4970 status = psa_driver_wrapper_aead_encrypt_setup(operation,
4971 &slot->attr,
4972 slot->key.data,
4973 slot->key.bytes,
4974 alg);
4975 } else {
4976 status = psa_driver_wrapper_aead_decrypt_setup(operation,
4977 &slot->attr,
4978 slot->key.data,
4979 slot->key.bytes,
4980 alg);
4981 }
4982 if (status != PSA_SUCCESS) {
4983 goto exit;
4984 }
4985
4986 operation->key_type = psa_get_key_type(&slot->attr);
4987
4988exit:
4989 unlock_status = psa_unregister_read_under_mutex(slot);
4990
4991 if (status == PSA_SUCCESS) {
4992 status = unlock_status;
4993 operation->alg = psa_aead_get_base_algorithm(alg);
4994 operation->is_encrypt = is_encrypt;
4995 } else {
4996 psa_aead_abort(operation);
4997 }
4998
4999 return status;
5000}
5001
5002/* Set the key for a multipart authenticated encryption operation. */
5003psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
5004 mbedtls_svc_key_id_t key,
5005 psa_algorithm_t alg)
5006{
5007 return psa_aead_setup(operation, 1, key, alg);
5008}
5009
5010/* Set the key for a multipart authenticated decryption operation. */
5011psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
5012 mbedtls_svc_key_id_t key,
5013 psa_algorithm_t alg)
5014{
5015 return psa_aead_setup(operation, 0, key, alg);
5016}
5017
5018static psa_status_t psa_aead_set_nonce_internal(psa_aead_operation_t *operation,
5019 const uint8_t *nonce,
5020 size_t nonce_length)
5021{
5022 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5023
5024 if (operation->id == 0) {
5025 status = PSA_ERROR_BAD_STATE;
5026 goto exit;
5027 }
5028
5029 if (operation->nonce_set) {
5030 status = PSA_ERROR_BAD_STATE;
5031 goto exit;
5032 }
5033
5034 status = psa_aead_check_nonce_length(operation->alg, nonce_length);
5035 if (status != PSA_SUCCESS) {
5036 status = PSA_ERROR_INVALID_ARGUMENT;
5037 goto exit;
5038 }
5039
5040 status = psa_driver_wrapper_aead_set_nonce(operation, nonce,
5041 nonce_length);
5042
5043exit:
5044 if (status == PSA_SUCCESS) {
5045 operation->nonce_set = 1;
5046 } else {
5047 psa_aead_abort(operation);
5048 }
5049
5050 return status;
5051}
5052
5053/* Generate a random nonce / IV for multipart AEAD operation */
5054psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation,
5055 uint8_t *nonce_external,
5056 size_t nonce_size,
5057 size_t *nonce_length)
5058{
5059 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5060 uint8_t local_nonce[PSA_AEAD_NONCE_MAX_SIZE];
5061 size_t required_nonce_size = 0;
5062
5063 LOCAL_OUTPUT_DECLARE(nonce_external, nonce);
5064 LOCAL_OUTPUT_ALLOC(nonce_external, nonce_size, nonce);
5065
5066 *nonce_length = 0;
5067
5068 if (operation->id == 0) {
5069 status = PSA_ERROR_BAD_STATE;
5070 goto exit;
5071 }
5072
5073 if (operation->nonce_set || !operation->is_encrypt) {
5074 status = PSA_ERROR_BAD_STATE;
5075 goto exit;
5076 }
5077
5078 /* For CCM, this size may not be correct according to the PSA
5079 * specification. The PSA Crypto 1.0.1 specification states:
5080 *
5081 * CCM encodes the plaintext length pLen in L octets, with L the smallest
5082 * integer >= 2 where pLen < 2^(8L). The nonce length is then 15 - L bytes.
5083 *
5084 * However this restriction that L has to be the smallest integer is not
5085 * applied in practice, and it is not implementable here since the
5086 * plaintext length may or may not be known at this time. */
5087 required_nonce_size = PSA_AEAD_NONCE_LENGTH(operation->key_type,
5088 operation->alg);
5089 if (nonce_size < required_nonce_size) {
5090 status = PSA_ERROR_BUFFER_TOO_SMALL;
5091 goto exit;
5092 }
5093
5094 status = psa_generate_random_internal(local_nonce, required_nonce_size);
5095 if (status != PSA_SUCCESS) {
5096 goto exit;
5097 }
5098
5099 status = psa_aead_set_nonce_internal(operation, local_nonce,
5100 required_nonce_size);
5101
5102exit:
5103 if (status == PSA_SUCCESS) {
5104 memcpy(nonce, local_nonce, required_nonce_size);
5105 *nonce_length = required_nonce_size;
5106 } else {
5107 psa_aead_abort(operation);
5108 }
5109
5110 LOCAL_OUTPUT_FREE(nonce_external, nonce);
5111
5112 return status;
5113}
5114
5115/* Set the nonce for a multipart authenticated encryption or decryption
5116 operation.*/
5117psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation,
5118 const uint8_t *nonce_external,
5119 size_t nonce_length)
5120{
5121 psa_status_t status;
5122
5123 LOCAL_INPUT_DECLARE(nonce_external, nonce);
5124 LOCAL_INPUT_ALLOC(nonce_external, nonce_length, nonce);
5125
5126 status = psa_aead_set_nonce_internal(operation, nonce, nonce_length);
5127
5128/* Exit label is only needed for buffer copying, prevent unused warnings. */
5129#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
5130exit:
5131#endif
5132
5133 LOCAL_INPUT_FREE(nonce_external, nonce);
5134
5135 return status;
5136}
5137
5138/* Declare the lengths of the message and additional data for multipart AEAD. */
5139psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation,
5140 size_t ad_length,
5141 size_t plaintext_length)
5142{
5143 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5144
5145 if (operation->id == 0) {
5146 status = PSA_ERROR_BAD_STATE;
5147 goto exit;
5148 }
5149
5150 if (operation->lengths_set || operation->ad_started ||
5151 operation->body_started) {
5152 status = PSA_ERROR_BAD_STATE;
5153 goto exit;
5154 }
5155
5156 switch (operation->alg) {
5157#if defined(PSA_WANT_ALG_GCM)
5158 case PSA_ALG_GCM:
5159 /* Lengths can only be too large for GCM if size_t is bigger than 32
5160 * bits. Without the guard this code will generate warnings on 32bit
5161 * builds. */
5162#if SIZE_MAX > UINT32_MAX
5163 if (((uint64_t) ad_length) >> 61 != 0 ||
5164 ((uint64_t) plaintext_length) > 0xFFFFFFFE0ull) {
5165 status = PSA_ERROR_INVALID_ARGUMENT;
5166 goto exit;
5167 }
5168#endif
5169 break;
5170#endif /* PSA_WANT_ALG_GCM */
5171#if defined(PSA_WANT_ALG_CCM)
5172 case PSA_ALG_CCM:
5173 if (ad_length > 0xFF00) {
5174 status = PSA_ERROR_INVALID_ARGUMENT;
5175 goto exit;
5176 }
5177 break;
5178#endif /* PSA_WANT_ALG_CCM */
5179#if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
5180 case PSA_ALG_CHACHA20_POLY1305:
5181 /* No length restrictions for ChaChaPoly. */
5182 break;
5183#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
5184 default:
5185 break;
5186 }
5187
5188 status = psa_driver_wrapper_aead_set_lengths(operation, ad_length,
5189 plaintext_length);
5190
5191exit:
5192 if (status == PSA_SUCCESS) {
5193 operation->ad_remaining = ad_length;
5194 operation->body_remaining = plaintext_length;
5195 operation->lengths_set = 1;
5196 } else {
5197 psa_aead_abort(operation);
5198 }
5199
5200 return status;
5201}
5202
5203/* Pass additional data to an active multipart AEAD operation. */
5204psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation,
5205 const uint8_t *input_external,
5206 size_t input_length)
5207{
5208 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5209
5210 LOCAL_INPUT_DECLARE(input_external, input);
5211 LOCAL_INPUT_ALLOC(input_external, input_length, input);
5212
5213 if (operation->id == 0) {
5214 status = PSA_ERROR_BAD_STATE;
5215 goto exit;
5216 }
5217
5218 if (!operation->nonce_set || operation->body_started) {
5219 status = PSA_ERROR_BAD_STATE;
5220 goto exit;
5221 }
5222
Sungbae Yoo4d211f32024-11-19 02:47:55 +00005223 /* No input to add (zero length), nothing to do. */
5224 if (input_length == 0) {
5225 status = PSA_SUCCESS;
5226 goto exit;
5227 }
5228
Tom Van Eyckb0563632024-06-13 16:20:14 +02005229 if (operation->lengths_set) {
5230 if (operation->ad_remaining < input_length) {
5231 status = PSA_ERROR_INVALID_ARGUMENT;
5232 goto exit;
5233 }
5234
5235 operation->ad_remaining -= input_length;
5236 }
5237#if defined(PSA_WANT_ALG_CCM)
5238 else if (operation->alg == PSA_ALG_CCM) {
5239 status = PSA_ERROR_BAD_STATE;
5240 goto exit;
5241 }
5242#endif /* PSA_WANT_ALG_CCM */
5243
5244 status = psa_driver_wrapper_aead_update_ad(operation, input,
5245 input_length);
5246
5247exit:
5248 if (status == PSA_SUCCESS) {
5249 operation->ad_started = 1;
5250 } else {
5251 psa_aead_abort(operation);
5252 }
5253
5254 LOCAL_INPUT_FREE(input_external, input);
5255
5256 return status;
5257}
5258
5259/* Encrypt or decrypt a message fragment in an active multipart AEAD
5260 operation.*/
5261psa_status_t psa_aead_update(psa_aead_operation_t *operation,
5262 const uint8_t *input_external,
5263 size_t input_length,
5264 uint8_t *output_external,
5265 size_t output_size,
5266 size_t *output_length)
5267{
5268 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5269
5270
5271 LOCAL_INPUT_DECLARE(input_external, input);
5272 LOCAL_OUTPUT_DECLARE(output_external, output);
5273
5274 LOCAL_INPUT_ALLOC(input_external, input_length, input);
5275 LOCAL_OUTPUT_ALLOC(output_external, output_size, output);
5276
5277 *output_length = 0;
5278
5279 if (operation->id == 0) {
5280 status = PSA_ERROR_BAD_STATE;
5281 goto exit;
5282 }
5283
5284 if (!operation->nonce_set) {
5285 status = PSA_ERROR_BAD_STATE;
5286 goto exit;
5287 }
5288
5289 if (operation->lengths_set) {
5290 /* Additional data length was supplied, but not all the additional
5291 data was supplied.*/
5292 if (operation->ad_remaining != 0) {
5293 status = PSA_ERROR_INVALID_ARGUMENT;
5294 goto exit;
5295 }
5296
5297 /* Too much data provided. */
5298 if (operation->body_remaining < input_length) {
5299 status = PSA_ERROR_INVALID_ARGUMENT;
5300 goto exit;
5301 }
5302
5303 operation->body_remaining -= input_length;
5304 }
5305#if defined(PSA_WANT_ALG_CCM)
5306 else if (operation->alg == PSA_ALG_CCM) {
5307 status = PSA_ERROR_BAD_STATE;
5308 goto exit;
5309 }
5310#endif /* PSA_WANT_ALG_CCM */
5311
5312 status = psa_driver_wrapper_aead_update(operation, input, input_length,
5313 output, output_size,
5314 output_length);
5315
5316exit:
5317 if (status == PSA_SUCCESS) {
5318 operation->body_started = 1;
5319 } else {
5320 psa_aead_abort(operation);
5321 }
5322
5323 LOCAL_INPUT_FREE(input_external, input);
5324 LOCAL_OUTPUT_FREE(output_external, output);
5325
5326 return status;
5327}
5328
5329static psa_status_t psa_aead_final_checks(const psa_aead_operation_t *operation)
5330{
5331 if (operation->id == 0 || !operation->nonce_set) {
5332 return PSA_ERROR_BAD_STATE;
5333 }
5334
5335 if (operation->lengths_set && (operation->ad_remaining != 0 ||
5336 operation->body_remaining != 0)) {
5337 return PSA_ERROR_INVALID_ARGUMENT;
5338 }
5339
5340 return PSA_SUCCESS;
5341}
5342
5343/* Finish encrypting a message in a multipart AEAD operation. */
5344psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
5345 uint8_t *ciphertext_external,
5346 size_t ciphertext_size,
5347 size_t *ciphertext_length,
5348 uint8_t *tag_external,
5349 size_t tag_size,
5350 size_t *tag_length)
5351{
5352 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5353
5354 LOCAL_OUTPUT_DECLARE(ciphertext_external, ciphertext);
5355 LOCAL_OUTPUT_DECLARE(tag_external, tag);
5356
5357 LOCAL_OUTPUT_ALLOC(ciphertext_external, ciphertext_size, ciphertext);
5358 LOCAL_OUTPUT_ALLOC(tag_external, tag_size, tag);
5359
5360 *ciphertext_length = 0;
5361 *tag_length = tag_size;
5362
5363 status = psa_aead_final_checks(operation);
5364 if (status != PSA_SUCCESS) {
5365 goto exit;
5366 }
5367
5368 if (!operation->is_encrypt) {
5369 status = PSA_ERROR_BAD_STATE;
5370 goto exit;
5371 }
5372
5373 status = psa_driver_wrapper_aead_finish(operation, ciphertext,
5374 ciphertext_size,
5375 ciphertext_length,
5376 tag, tag_size, tag_length);
5377
5378exit:
5379
5380
5381 /* In case the operation fails and the user fails to check for failure or
5382 * the zero tag size, make sure the tag is set to something implausible.
5383 * Even if the operation succeeds, make sure we clear the rest of the
5384 * buffer to prevent potential leakage of anything previously placed in
5385 * the same buffer.*/
5386 psa_wipe_tag_output_buffer(tag, status, tag_size, *tag_length);
5387
5388 psa_aead_abort(operation);
5389
5390 LOCAL_OUTPUT_FREE(ciphertext_external, ciphertext);
5391 LOCAL_OUTPUT_FREE(tag_external, tag);
5392
5393 return status;
5394}
5395
5396/* Finish authenticating and decrypting a message in a multipart AEAD
5397 operation.*/
5398psa_status_t psa_aead_verify(psa_aead_operation_t *operation,
5399 uint8_t *plaintext_external,
5400 size_t plaintext_size,
5401 size_t *plaintext_length,
5402 const uint8_t *tag_external,
5403 size_t tag_length)
5404{
5405 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5406
5407 LOCAL_OUTPUT_DECLARE(plaintext_external, plaintext);
5408 LOCAL_INPUT_DECLARE(tag_external, tag);
5409
5410 LOCAL_OUTPUT_ALLOC(plaintext_external, plaintext_size, plaintext);
5411 LOCAL_INPUT_ALLOC(tag_external, tag_length, tag);
5412
5413 *plaintext_length = 0;
5414
5415 status = psa_aead_final_checks(operation);
5416 if (status != PSA_SUCCESS) {
5417 goto exit;
5418 }
5419
5420 if (operation->is_encrypt) {
5421 status = PSA_ERROR_BAD_STATE;
5422 goto exit;
5423 }
5424
5425 status = psa_driver_wrapper_aead_verify(operation, plaintext,
5426 plaintext_size,
5427 plaintext_length,
5428 tag, tag_length);
5429
5430exit:
5431 psa_aead_abort(operation);
5432
5433 LOCAL_OUTPUT_FREE(plaintext_external, plaintext);
5434 LOCAL_INPUT_FREE(tag_external, tag);
5435
5436 return status;
5437}
5438
5439/* Abort an AEAD operation. */
5440psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
5441{
5442 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5443
5444 if (operation->id == 0) {
5445 /* The object has (apparently) been initialized but it is not (yet)
5446 * in use. It's ok to call abort on such an object, and there's
5447 * nothing to do. */
5448 return PSA_SUCCESS;
5449 }
5450
5451 status = psa_driver_wrapper_aead_abort(operation);
5452
5453 memset(operation, 0, sizeof(*operation));
5454
5455 return status;
5456}
5457
5458/****************************************************************/
5459/* Generators */
5460/****************************************************************/
5461
5462#if defined(BUILTIN_ALG_ANY_HKDF) || \
5463 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5464 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) || \
5465 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) || \
5466 defined(PSA_HAVE_SOFT_PBKDF2)
5467#define AT_LEAST_ONE_BUILTIN_KDF
5468#endif /* At least one builtin KDF */
5469
5470#if defined(BUILTIN_ALG_ANY_HKDF) || \
5471 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5472 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5473static psa_status_t psa_key_derivation_start_hmac(
5474 psa_mac_operation_t *operation,
5475 psa_algorithm_t hash_alg,
5476 const uint8_t *hmac_key,
5477 size_t hmac_key_length)
5478{
5479 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5480 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
5481 psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
5482 psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(hmac_key_length));
5483 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
5484
5485 operation->is_sign = 1;
5486 operation->mac_size = PSA_HASH_LENGTH(hash_alg);
5487
5488 status = psa_driver_wrapper_mac_sign_setup(operation,
5489 &attributes,
5490 hmac_key, hmac_key_length,
5491 PSA_ALG_HMAC(hash_alg));
5492
5493 psa_reset_key_attributes(&attributes);
5494 return status;
5495}
5496#endif /* KDF algorithms reliant on HMAC */
5497
5498#define HKDF_STATE_INIT 0 /* no input yet */
5499#define HKDF_STATE_STARTED 1 /* got salt */
5500#define HKDF_STATE_KEYED 2 /* got key */
5501#define HKDF_STATE_OUTPUT 3 /* output started */
5502
5503static psa_algorithm_t psa_key_derivation_get_kdf_alg(
5504 const psa_key_derivation_operation_t *operation)
5505{
5506 if (PSA_ALG_IS_KEY_AGREEMENT(operation->alg)) {
5507 return PSA_ALG_KEY_AGREEMENT_GET_KDF(operation->alg);
5508 } else {
5509 return operation->alg;
5510 }
5511}
5512
5513psa_status_t psa_key_derivation_abort(psa_key_derivation_operation_t *operation)
5514{
5515 psa_status_t status = PSA_SUCCESS;
5516 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
5517 if (kdf_alg == 0) {
5518 /* The object has (apparently) been initialized but it is not
5519 * in use. It's ok to call abort on such an object, and there's
5520 * nothing to do. */
5521 } else
5522#if defined(BUILTIN_ALG_ANY_HKDF)
5523 if (PSA_ALG_IS_ANY_HKDF(kdf_alg)) {
5524 mbedtls_free(operation->ctx.hkdf.info);
5525 status = psa_mac_abort(&operation->ctx.hkdf.hmac);
5526 } else
5527#endif /* BUILTIN_ALG_ANY_HKDF */
5528#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5529 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5530 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
5531 /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */
5532 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
5533 if (operation->ctx.tls12_prf.secret != NULL) {
5534 mbedtls_zeroize_and_free(operation->ctx.tls12_prf.secret,
5535 operation->ctx.tls12_prf.secret_length);
5536 }
5537
5538 if (operation->ctx.tls12_prf.seed != NULL) {
5539 mbedtls_zeroize_and_free(operation->ctx.tls12_prf.seed,
5540 operation->ctx.tls12_prf.seed_length);
5541 }
5542
5543 if (operation->ctx.tls12_prf.label != NULL) {
5544 mbedtls_zeroize_and_free(operation->ctx.tls12_prf.label,
5545 operation->ctx.tls12_prf.label_length);
5546 }
5547#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5548 if (operation->ctx.tls12_prf.other_secret != NULL) {
5549 mbedtls_zeroize_and_free(operation->ctx.tls12_prf.other_secret,
5550 operation->ctx.tls12_prf.other_secret_length);
5551 }
5552#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
5553 status = PSA_SUCCESS;
5554
5555 /* We leave the fields Ai and output_block to be erased safely by the
5556 * mbedtls_platform_zeroize() in the end of this function. */
5557 } else
5558#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
5559 * defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) */
5560#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
5561 if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
5562 mbedtls_platform_zeroize(operation->ctx.tls12_ecjpake_to_pms.data,
5563 sizeof(operation->ctx.tls12_ecjpake_to_pms.data));
5564 } else
5565#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) */
5566#if defined(PSA_HAVE_SOFT_PBKDF2)
5567 if (PSA_ALG_IS_PBKDF2(kdf_alg)) {
5568 if (operation->ctx.pbkdf2.salt != NULL) {
5569 mbedtls_zeroize_and_free(operation->ctx.pbkdf2.salt,
5570 operation->ctx.pbkdf2.salt_length);
5571 }
5572
5573 status = PSA_SUCCESS;
5574 } else
5575#endif /* defined(PSA_HAVE_SOFT_PBKDF2) */
5576 {
5577 status = PSA_ERROR_BAD_STATE;
5578 }
5579 mbedtls_platform_zeroize(operation, sizeof(*operation));
5580 return status;
5581}
5582
5583psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation,
5584 size_t *capacity)
5585{
5586 if (operation->alg == 0) {
5587 /* This is a blank key derivation operation. */
5588 return PSA_ERROR_BAD_STATE;
5589 }
5590
5591 *capacity = operation->capacity;
5592 return PSA_SUCCESS;
5593}
5594
5595psa_status_t psa_key_derivation_set_capacity(psa_key_derivation_operation_t *operation,
5596 size_t capacity)
5597{
5598 if (operation->alg == 0) {
5599 return PSA_ERROR_BAD_STATE;
5600 }
5601 if (capacity > operation->capacity) {
5602 return PSA_ERROR_INVALID_ARGUMENT;
5603 }
5604 operation->capacity = capacity;
5605 return PSA_SUCCESS;
5606}
5607
5608#if defined(BUILTIN_ALG_ANY_HKDF)
5609/* Read some bytes from an HKDF-based operation. */
5610static psa_status_t psa_key_derivation_hkdf_read(psa_hkdf_key_derivation_t *hkdf,
5611 psa_algorithm_t kdf_alg,
5612 uint8_t *output,
5613 size_t output_length)
5614{
5615 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
5616 uint8_t hash_length = PSA_HASH_LENGTH(hash_alg);
5617 size_t hmac_output_length;
5618 psa_status_t status;
5619#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT)
5620 const uint8_t last_block = PSA_ALG_IS_HKDF_EXTRACT(kdf_alg) ? 0 : 0xff;
5621#else
5622 const uint8_t last_block = 0xff;
5623#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */
5624
5625 if (hkdf->state < HKDF_STATE_KEYED ||
5626 (!hkdf->info_set
5627#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT)
5628 && !PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)
5629#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */
5630 )) {
5631 return PSA_ERROR_BAD_STATE;
5632 }
5633 hkdf->state = HKDF_STATE_OUTPUT;
5634
5635 while (output_length != 0) {
5636 /* Copy what remains of the current block */
5637 uint8_t n = hash_length - hkdf->offset_in_block;
5638 if (n > output_length) {
5639 n = (uint8_t) output_length;
5640 }
5641 memcpy(output, hkdf->output_block + hkdf->offset_in_block, n);
5642 output += n;
5643 output_length -= n;
5644 hkdf->offset_in_block += n;
5645 if (output_length == 0) {
5646 break;
5647 }
5648 /* We can't be wanting more output after the last block, otherwise
5649 * the capacity check in psa_key_derivation_output_bytes() would have
5650 * prevented this call. It could happen only if the operation
5651 * object was corrupted or if this function is called directly
5652 * inside the library. */
5653 if (hkdf->block_number == last_block) {
5654 return PSA_ERROR_BAD_STATE;
5655 }
5656
5657 /* We need a new block */
5658 ++hkdf->block_number;
5659 hkdf->offset_in_block = 0;
5660
5661 status = psa_key_derivation_start_hmac(&hkdf->hmac,
5662 hash_alg,
5663 hkdf->prk,
5664 hash_length);
5665 if (status != PSA_SUCCESS) {
5666 return status;
5667 }
5668
5669 if (hkdf->block_number != 1) {
5670 status = psa_mac_update(&hkdf->hmac,
5671 hkdf->output_block,
5672 hash_length);
5673 if (status != PSA_SUCCESS) {
5674 return status;
5675 }
5676 }
5677 status = psa_mac_update(&hkdf->hmac,
5678 hkdf->info,
5679 hkdf->info_length);
5680 if (status != PSA_SUCCESS) {
5681 return status;
5682 }
5683 status = psa_mac_update(&hkdf->hmac,
5684 &hkdf->block_number, 1);
5685 if (status != PSA_SUCCESS) {
5686 return status;
5687 }
5688 status = psa_mac_sign_finish(&hkdf->hmac,
5689 hkdf->output_block,
5690 sizeof(hkdf->output_block),
5691 &hmac_output_length);
5692 if (status != PSA_SUCCESS) {
5693 return status;
5694 }
5695 }
5696
5697 return PSA_SUCCESS;
5698}
5699#endif /* BUILTIN_ALG_ANY_HKDF */
5700
5701#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5702 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5703static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
5704 psa_tls12_prf_key_derivation_t *tls12_prf,
5705 psa_algorithm_t alg)
5706{
5707 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(alg);
5708 uint8_t hash_length = PSA_HASH_LENGTH(hash_alg);
5709 psa_mac_operation_t hmac = PSA_MAC_OPERATION_INIT;
5710 size_t hmac_output_length;
5711 psa_status_t status, cleanup_status;
5712
5713 /* We can't be wanting more output after block 0xff, otherwise
5714 * the capacity check in psa_key_derivation_output_bytes() would have
5715 * prevented this call. It could happen only if the operation
5716 * object was corrupted or if this function is called directly
5717 * inside the library. */
5718 if (tls12_prf->block_number == 0xff) {
5719 return PSA_ERROR_CORRUPTION_DETECTED;
5720 }
5721
5722 /* We need a new block */
5723 ++tls12_prf->block_number;
5724 tls12_prf->left_in_block = hash_length;
5725
5726 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
5727 *
5728 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
5729 *
5730 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
5731 * HMAC_hash(secret, A(2) + seed) +
5732 * HMAC_hash(secret, A(3) + seed) + ...
5733 *
5734 * A(0) = seed
5735 * A(i) = HMAC_hash(secret, A(i-1))
5736 *
5737 * The `psa_tls12_prf_key_derivation` structure saves the block
5738 * `HMAC_hash(secret, A(i) + seed)` from which the output
5739 * is currently extracted as `output_block` and where i is
5740 * `block_number`.
5741 */
5742
5743 status = psa_key_derivation_start_hmac(&hmac,
5744 hash_alg,
5745 tls12_prf->secret,
5746 tls12_prf->secret_length);
5747 if (status != PSA_SUCCESS) {
5748 goto cleanup;
5749 }
5750
5751 /* Calculate A(i) where i = tls12_prf->block_number. */
5752 if (tls12_prf->block_number == 1) {
5753 /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads
5754 * the variable seed and in this instance means it in the context of the
5755 * P_hash function, where seed = label + seed.) */
5756 status = psa_mac_update(&hmac,
5757 tls12_prf->label,
5758 tls12_prf->label_length);
5759 if (status != PSA_SUCCESS) {
5760 goto cleanup;
5761 }
5762 status = psa_mac_update(&hmac,
5763 tls12_prf->seed,
5764 tls12_prf->seed_length);
5765 if (status != PSA_SUCCESS) {
5766 goto cleanup;
5767 }
5768 } else {
5769 /* A(i) = HMAC_hash(secret, A(i-1)) */
5770 status = psa_mac_update(&hmac, tls12_prf->Ai, hash_length);
5771 if (status != PSA_SUCCESS) {
5772 goto cleanup;
5773 }
5774 }
5775
5776 status = psa_mac_sign_finish(&hmac,
5777 tls12_prf->Ai, hash_length,
5778 &hmac_output_length);
5779 if (hmac_output_length != hash_length) {
5780 status = PSA_ERROR_CORRUPTION_DETECTED;
5781 }
5782 if (status != PSA_SUCCESS) {
5783 goto cleanup;
5784 }
5785
5786 /* Calculate HMAC_hash(secret, A(i) + label + seed). */
5787 status = psa_key_derivation_start_hmac(&hmac,
5788 hash_alg,
5789 tls12_prf->secret,
5790 tls12_prf->secret_length);
5791 if (status != PSA_SUCCESS) {
5792 goto cleanup;
5793 }
5794 status = psa_mac_update(&hmac, tls12_prf->Ai, hash_length);
5795 if (status != PSA_SUCCESS) {
5796 goto cleanup;
5797 }
5798 status = psa_mac_update(&hmac, tls12_prf->label, tls12_prf->label_length);
5799 if (status != PSA_SUCCESS) {
5800 goto cleanup;
5801 }
5802 status = psa_mac_update(&hmac, tls12_prf->seed, tls12_prf->seed_length);
5803 if (status != PSA_SUCCESS) {
5804 goto cleanup;
5805 }
5806 status = psa_mac_sign_finish(&hmac,
5807 tls12_prf->output_block, hash_length,
5808 &hmac_output_length);
5809 if (status != PSA_SUCCESS) {
5810 goto cleanup;
5811 }
5812
5813
5814cleanup:
5815 cleanup_status = psa_mac_abort(&hmac);
5816 if (status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS) {
5817 status = cleanup_status;
5818 }
5819
5820 return status;
5821}
5822
5823static psa_status_t psa_key_derivation_tls12_prf_read(
5824 psa_tls12_prf_key_derivation_t *tls12_prf,
5825 psa_algorithm_t alg,
5826 uint8_t *output,
5827 size_t output_length)
5828{
5829 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH(alg);
5830 uint8_t hash_length = PSA_HASH_LENGTH(hash_alg);
5831 psa_status_t status;
5832 uint8_t offset, length;
5833
5834 switch (tls12_prf->state) {
5835 case PSA_TLS12_PRF_STATE_LABEL_SET:
5836 tls12_prf->state = PSA_TLS12_PRF_STATE_OUTPUT;
5837 break;
5838 case PSA_TLS12_PRF_STATE_OUTPUT:
5839 break;
5840 default:
5841 return PSA_ERROR_BAD_STATE;
5842 }
5843
5844 while (output_length != 0) {
5845 /* Check if we have fully processed the current block. */
5846 if (tls12_prf->left_in_block == 0) {
5847 status = psa_key_derivation_tls12_prf_generate_next_block(tls12_prf,
5848 alg);
5849 if (status != PSA_SUCCESS) {
5850 return status;
5851 }
5852
5853 continue;
5854 }
5855
5856 if (tls12_prf->left_in_block > output_length) {
5857 length = (uint8_t) output_length;
5858 } else {
5859 length = tls12_prf->left_in_block;
5860 }
5861
5862 offset = hash_length - tls12_prf->left_in_block;
5863 memcpy(output, tls12_prf->output_block + offset, length);
5864 output += length;
5865 output_length -= length;
5866 tls12_prf->left_in_block -= length;
5867 }
5868
5869 return PSA_SUCCESS;
5870}
5871#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
5872 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
5873
5874#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
5875static psa_status_t psa_key_derivation_tls12_ecjpake_to_pms_read(
5876 psa_tls12_ecjpake_to_pms_t *ecjpake,
5877 uint8_t *output,
5878 size_t output_length)
5879{
5880 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5881 size_t output_size = 0;
5882
5883 if (output_length != 32) {
5884 return PSA_ERROR_INVALID_ARGUMENT;
5885 }
5886
5887 status = psa_hash_compute(PSA_ALG_SHA_256, ecjpake->data,
5888 PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE, output, output_length,
5889 &output_size);
5890 if (status != PSA_SUCCESS) {
5891 return status;
5892 }
5893
5894 if (output_size != output_length) {
5895 return PSA_ERROR_GENERIC_ERROR;
5896 }
5897
5898 return PSA_SUCCESS;
5899}
5900#endif
5901
5902#if defined(PSA_HAVE_SOFT_PBKDF2)
5903static psa_status_t psa_key_derivation_pbkdf2_generate_block(
5904 psa_pbkdf2_key_derivation_t *pbkdf2,
5905 psa_algorithm_t prf_alg,
5906 uint8_t prf_output_length,
5907 psa_key_attributes_t *attributes)
5908{
5909 psa_status_t status;
5910 psa_mac_operation_t mac_operation = PSA_MAC_OPERATION_INIT;
5911 size_t mac_output_length;
5912 uint8_t U_i[PSA_MAC_MAX_SIZE];
5913 uint8_t *U_accumulator = pbkdf2->output_block;
5914 uint64_t i;
5915 uint8_t block_counter[4];
5916
5917 mac_operation.is_sign = 1;
5918 mac_operation.mac_size = prf_output_length;
5919 MBEDTLS_PUT_UINT32_BE(pbkdf2->block_number, block_counter, 0);
5920
5921 status = psa_driver_wrapper_mac_sign_setup(&mac_operation,
5922 attributes,
5923 pbkdf2->password,
5924 pbkdf2->password_length,
5925 prf_alg);
5926 if (status != PSA_SUCCESS) {
5927 goto cleanup;
5928 }
5929 status = psa_mac_update(&mac_operation, pbkdf2->salt, pbkdf2->salt_length);
5930 if (status != PSA_SUCCESS) {
5931 goto cleanup;
5932 }
5933 status = psa_mac_update(&mac_operation, block_counter, sizeof(block_counter));
5934 if (status != PSA_SUCCESS) {
5935 goto cleanup;
5936 }
5937 status = psa_mac_sign_finish(&mac_operation, U_i, sizeof(U_i),
5938 &mac_output_length);
5939 if (status != PSA_SUCCESS) {
5940 goto cleanup;
5941 }
5942
5943 if (mac_output_length != prf_output_length) {
5944 status = PSA_ERROR_CORRUPTION_DETECTED;
5945 goto cleanup;
5946 }
5947
5948 memcpy(U_accumulator, U_i, prf_output_length);
5949
5950 for (i = 1; i < pbkdf2->input_cost; i++) {
5951 /* We are passing prf_output_length as mac_size because the driver
5952 * function directly sets mac_output_length as mac_size upon success.
5953 * See https://github.com/Mbed-TLS/mbedtls/issues/7801 */
5954 status = psa_driver_wrapper_mac_compute(attributes,
5955 pbkdf2->password,
5956 pbkdf2->password_length,
5957 prf_alg, U_i, prf_output_length,
5958 U_i, prf_output_length,
5959 &mac_output_length);
5960 if (status != PSA_SUCCESS) {
5961 goto cleanup;
5962 }
5963
5964 mbedtls_xor(U_accumulator, U_accumulator, U_i, prf_output_length);
5965 }
5966
5967cleanup:
5968 /* Zeroise buffers to clear sensitive data from memory. */
5969 mbedtls_platform_zeroize(U_i, PSA_MAC_MAX_SIZE);
5970 return status;
5971}
5972
5973static psa_status_t psa_key_derivation_pbkdf2_read(
5974 psa_pbkdf2_key_derivation_t *pbkdf2,
5975 psa_algorithm_t kdf_alg,
5976 uint8_t *output,
5977 size_t output_length)
5978{
5979 psa_status_t status;
5980 psa_algorithm_t prf_alg;
5981 uint8_t prf_output_length;
5982 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
5983 psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(pbkdf2->password_length));
5984 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
5985
5986 if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
5987 prf_alg = PSA_ALG_HMAC(PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg));
5988 prf_output_length = PSA_HASH_LENGTH(prf_alg);
5989 psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
5990 } else if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
5991 prf_alg = PSA_ALG_CMAC;
5992 prf_output_length = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC);
5993 psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
5994 } else {
5995 return PSA_ERROR_INVALID_ARGUMENT;
5996 }
5997
5998 switch (pbkdf2->state) {
5999 case PSA_PBKDF2_STATE_PASSWORD_SET:
6000 /* Initially we need a new block so bytes_used is equal to block size*/
6001 pbkdf2->bytes_used = prf_output_length;
6002 pbkdf2->state = PSA_PBKDF2_STATE_OUTPUT;
6003 break;
6004 case PSA_PBKDF2_STATE_OUTPUT:
6005 break;
6006 default:
6007 return PSA_ERROR_BAD_STATE;
6008 }
6009
6010 while (output_length != 0) {
6011 uint8_t n = prf_output_length - pbkdf2->bytes_used;
6012 if (n > output_length) {
6013 n = (uint8_t) output_length;
6014 }
6015 memcpy(output, pbkdf2->output_block + pbkdf2->bytes_used, n);
6016 output += n;
6017 output_length -= n;
6018 pbkdf2->bytes_used += n;
6019
6020 if (output_length == 0) {
6021 break;
6022 }
6023
6024 /* We need a new block */
6025 pbkdf2->bytes_used = 0;
6026 pbkdf2->block_number++;
6027
6028 status = psa_key_derivation_pbkdf2_generate_block(pbkdf2, prf_alg,
6029 prf_output_length,
6030 &attributes);
6031 if (status != PSA_SUCCESS) {
6032 return status;
6033 }
6034 }
6035
6036 return PSA_SUCCESS;
6037}
6038#endif /* PSA_HAVE_SOFT_PBKDF2 */
6039
6040psa_status_t psa_key_derivation_output_bytes(
6041 psa_key_derivation_operation_t *operation,
6042 uint8_t *output_external,
6043 size_t output_length)
6044{
6045 psa_status_t status;
6046 LOCAL_OUTPUT_DECLARE(output_external, output);
6047
6048 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
6049
6050 if (operation->alg == 0) {
6051 /* This is a blank operation. */
6052 return PSA_ERROR_BAD_STATE;
6053 }
6054
6055 if (output_length == 0 && operation->capacity == 0) {
6056 /* Edge case: this is a finished operation, and 0 bytes
6057 * were requested. The right error in this case could
6058 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
6059 * INSUFFICIENT_CAPACITY, which is right for a finished
6060 * operation, for consistency with the case when
6061 * output_length > 0. */
6062 return PSA_ERROR_INSUFFICIENT_DATA;
6063 }
6064
6065 LOCAL_OUTPUT_ALLOC(output_external, output_length, output);
6066 if (output_length > operation->capacity) {
6067 operation->capacity = 0;
6068 /* Go through the error path to wipe all confidential data now
6069 * that the operation object is useless. */
6070 status = PSA_ERROR_INSUFFICIENT_DATA;
6071 goto exit;
6072 }
6073
6074 operation->capacity -= output_length;
6075
6076#if defined(BUILTIN_ALG_ANY_HKDF)
6077 if (PSA_ALG_IS_ANY_HKDF(kdf_alg)) {
6078 status = psa_key_derivation_hkdf_read(&operation->ctx.hkdf, kdf_alg,
6079 output, output_length);
6080 } else
6081#endif /* BUILTIN_ALG_ANY_HKDF */
6082#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
6083 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
6084 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
6085 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
6086 status = psa_key_derivation_tls12_prf_read(&operation->ctx.tls12_prf,
6087 kdf_alg, output,
6088 output_length);
6089 } else
6090#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
6091 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
6092#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
6093 if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
6094 status = psa_key_derivation_tls12_ecjpake_to_pms_read(
6095 &operation->ctx.tls12_ecjpake_to_pms, output, output_length);
6096 } else
6097#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
6098#if defined(PSA_HAVE_SOFT_PBKDF2)
6099 if (PSA_ALG_IS_PBKDF2(kdf_alg)) {
6100 status = psa_key_derivation_pbkdf2_read(&operation->ctx.pbkdf2, kdf_alg,
6101 output, output_length);
6102 } else
6103#endif /* PSA_HAVE_SOFT_PBKDF2 */
6104
6105 {
6106 (void) kdf_alg;
6107 status = PSA_ERROR_BAD_STATE;
6108 LOCAL_OUTPUT_FREE(output_external, output);
6109
6110 return status;
6111 }
6112
6113exit:
6114 if (status != PSA_SUCCESS) {
6115 /* Preserve the algorithm upon errors, but clear all sensitive state.
6116 * This allows us to differentiate between exhausted operations and
6117 * blank operations, so we can return PSA_ERROR_BAD_STATE on blank
6118 * operations. */
6119 psa_algorithm_t alg = operation->alg;
6120 psa_key_derivation_abort(operation);
6121 operation->alg = alg;
6122 if (output != NULL) {
6123 memset(output, '!', output_length);
6124 }
6125 }
6126
6127 LOCAL_OUTPUT_FREE(output_external, output);
6128 return status;
6129}
6130
6131#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
6132static void psa_des_set_key_parity(uint8_t *data, size_t data_size)
6133{
6134 if (data_size >= 8) {
6135 mbedtls_des_key_set_parity(data);
6136 }
6137 if (data_size >= 16) {
6138 mbedtls_des_key_set_parity(data + 8);
6139 }
6140 if (data_size >= 24) {
6141 mbedtls_des_key_set_parity(data + 16);
6142 }
6143}
6144#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
6145
6146/*
6147 * ECC keys on a Weierstrass elliptic curve require the generation
6148 * of a private key which is an integer
6149 * in the range [1, N - 1], where N is the boundary of the private key domain:
6150 * N is the prime p for Diffie-Hellman, or the order of the
6151 * curve’s base point for ECC.
6152 *
6153 * Let m be the bit size of N, such that 2^m > N >= 2^(m-1).
6154 * This function generates the private key using the following process:
6155 *
6156 * 1. Draw a byte string of length ceiling(m/8) bytes.
6157 * 2. If m is not a multiple of 8, set the most significant
6158 * (8 * ceiling(m/8) - m) bits of the first byte in the string to zero.
6159 * 3. Convert the string to integer k by decoding it as a big-endian byte string.
6160 * 4. If k > N - 2, discard the result and return to step 1.
6161 * 5. Output k + 1 as the private key.
6162 *
6163 * This method allows compliance to NIST standards, specifically the methods titled
6164 * Key-Pair Generation by Testing Candidates in the following publications:
6165 * - NIST Special Publication 800-56A: Recommendation for Pair-Wise Key-Establishment
6166 * Schemes Using Discrete Logarithm Cryptography [SP800-56A] §5.6.1.1.4 for
6167 * Diffie-Hellman keys.
6168 *
6169 * - [SP800-56A] §5.6.1.2.2 or FIPS Publication 186-4: Digital Signature
6170 * Standard (DSS) [FIPS186-4] §B.4.2 for elliptic curve keys.
6171 *
6172 * Note: Function allocates memory for *data buffer, so given *data should be
6173 * always NULL.
6174 */
6175#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
6176#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
6177static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper(
6178 psa_key_slot_t *slot,
6179 size_t bits,
6180 psa_key_derivation_operation_t *operation,
6181 uint8_t **data
6182 )
6183{
6184 unsigned key_out_of_range = 1;
6185 mbedtls_mpi k;
6186 mbedtls_mpi diff_N_2;
6187 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
6188 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
6189 size_t m;
6190 size_t m_bytes;
6191
6192 mbedtls_mpi_init(&k);
6193 mbedtls_mpi_init(&diff_N_2);
6194
6195 psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
6196 slot->attr.type);
6197 mbedtls_ecp_group_id grp_id =
6198 mbedtls_ecc_group_from_psa(curve, bits);
6199
6200 if (grp_id == MBEDTLS_ECP_DP_NONE) {
6201 ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
6202 goto cleanup;
6203 }
6204
6205 mbedtls_ecp_group ecp_group;
6206 mbedtls_ecp_group_init(&ecp_group);
6207
6208 MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&ecp_group, grp_id));
6209
6210 /* N is the boundary of the private key domain (ecp_group.N). */
6211 /* Let m be the bit size of N. */
6212 m = ecp_group.nbits;
6213
6214 m_bytes = PSA_BITS_TO_BYTES(m);
6215
6216 /* Calculate N - 2 - it will be needed later. */
6217 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&diff_N_2, &ecp_group.N, 2));
6218
6219 /* Note: This function is always called with *data == NULL and it
6220 * allocates memory for the data buffer. */
6221 *data = mbedtls_calloc(1, m_bytes);
6222 if (*data == NULL) {
6223 ret = MBEDTLS_ERR_ASN1_ALLOC_FAILED;
6224 goto cleanup;
6225 }
6226
6227 while (key_out_of_range) {
6228 /* 1. Draw a byte string of length ceiling(m/8) bytes. */
6229 if ((status = psa_key_derivation_output_bytes(operation, *data, m_bytes)) != 0) {
6230 goto cleanup;
6231 }
6232
6233 /* 2. If m is not a multiple of 8 */
6234 if (m % 8 != 0) {
6235 /* Set the most significant
6236 * (8 * ceiling(m/8) - m) bits of the first byte in
6237 * the string to zero.
6238 */
6239 uint8_t clear_bit_mask = (1 << (m % 8)) - 1;
6240 (*data)[0] &= clear_bit_mask;
6241 }
6242
6243 /* 3. Convert the string to integer k by decoding it as a
6244 * big-endian byte string.
6245 */
6246 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&k, *data, m_bytes));
6247
6248 /* 4. If k > N - 2, discard the result and return to step 1.
6249 * Result of comparison is returned. When it indicates error
6250 * then this function is called again.
6251 */
6252 MBEDTLS_MPI_CHK(mbedtls_mpi_lt_mpi_ct(&diff_N_2, &k, &key_out_of_range));
6253 }
6254
6255 /* 5. Output k + 1 as the private key. */
6256 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&k, &k, 1));
6257 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&k, *data, m_bytes));
6258cleanup:
6259 if (ret != 0) {
6260 status = mbedtls_to_psa_error(ret);
6261 }
6262 if (status != PSA_SUCCESS) {
6263 mbedtls_free(*data);
6264 *data = NULL;
6265 }
6266 mbedtls_mpi_free(&k);
6267 mbedtls_mpi_free(&diff_N_2);
6268 return status;
6269}
6270
6271/* ECC keys on a Montgomery elliptic curve draws a byte string whose length
6272 * is determined by the curve, and sets the mandatory bits accordingly. That is:
6273 *
6274 * - Curve25519 (PSA_ECC_FAMILY_MONTGOMERY, 255 bits):
6275 * draw a 32-byte string and process it as specified in
6276 * Elliptic Curves for Security [RFC7748] §5.
6277 *
6278 * - Curve448 (PSA_ECC_FAMILY_MONTGOMERY, 448 bits):
6279 * draw a 56-byte string and process it as specified in [RFC7748] §5.
6280 *
6281 * Note: Function allocates memory for *data buffer, so given *data should be
6282 * always NULL.
6283 */
6284
6285static psa_status_t psa_generate_derived_ecc_key_montgomery_helper(
6286 size_t bits,
6287 psa_key_derivation_operation_t *operation,
6288 uint8_t **data
6289 )
6290{
6291 size_t output_length;
6292 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
6293
6294 switch (bits) {
6295 case 255:
6296 output_length = 32;
6297 break;
6298 case 448:
6299 output_length = 56;
6300 break;
6301 default:
6302 return PSA_ERROR_INVALID_ARGUMENT;
6303 break;
6304 }
6305
6306 *data = mbedtls_calloc(1, output_length);
6307
6308 if (*data == NULL) {
6309 return PSA_ERROR_INSUFFICIENT_MEMORY;
6310 }
6311
6312 status = psa_key_derivation_output_bytes(operation, *data, output_length);
6313
6314 if (status != PSA_SUCCESS) {
6315 return status;
6316 }
6317
6318 switch (bits) {
6319 case 255:
6320 (*data)[0] &= 248;
6321 (*data)[31] &= 127;
6322 (*data)[31] |= 64;
6323 break;
6324 case 448:
6325 (*data)[0] &= 252;
6326 (*data)[55] |= 128;
6327 break;
6328 default:
6329 return PSA_ERROR_CORRUPTION_DETECTED;
6330 break;
6331 }
6332
6333 return status;
6334}
6335#else /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE */
6336static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper(
6337 psa_key_slot_t *slot, size_t bits,
6338 psa_key_derivation_operation_t *operation, uint8_t **data)
6339{
6340 (void) slot;
6341 (void) bits;
6342 (void) operation;
6343 (void) data;
6344 return PSA_ERROR_NOT_SUPPORTED;
6345}
6346
6347static psa_status_t psa_generate_derived_ecc_key_montgomery_helper(
6348 size_t bits, psa_key_derivation_operation_t *operation, uint8_t **data)
6349{
6350 (void) bits;
6351 (void) operation;
6352 (void) data;
6353 return PSA_ERROR_NOT_SUPPORTED;
6354}
6355#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE */
6356#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE */
6357
6358static psa_status_t psa_generate_derived_key_internal(
6359 psa_key_slot_t *slot,
6360 size_t bits,
6361 psa_key_derivation_operation_t *operation)
6362{
6363 uint8_t *data = NULL;
6364 size_t bytes = PSA_BITS_TO_BYTES(bits);
6365 size_t storage_size = bytes;
6366 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
6367
6368 if (PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type)) {
6369 return PSA_ERROR_INVALID_ARGUMENT;
6370 }
6371
6372#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) || \
6373 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
6374 if (PSA_KEY_TYPE_IS_ECC(slot->attr.type)) {
6375 psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(slot->attr.type);
6376 if (PSA_ECC_FAMILY_IS_WEIERSTRASS(curve)) {
6377 /* Weierstrass elliptic curve */
6378 status = psa_generate_derived_ecc_key_weierstrass_helper(slot, bits, operation, &data);
6379 if (status != PSA_SUCCESS) {
6380 goto exit;
6381 }
6382 } else {
6383 /* Montgomery elliptic curve */
6384 status = psa_generate_derived_ecc_key_montgomery_helper(bits, operation, &data);
6385 if (status != PSA_SUCCESS) {
6386 goto exit;
6387 }
6388 }
6389 } else
6390#endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) ||
6391 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE) */
6392 if (key_type_is_raw_bytes(slot->attr.type)) {
6393 if (bits % 8 != 0) {
6394 return PSA_ERROR_INVALID_ARGUMENT;
6395 }
6396 data = mbedtls_calloc(1, bytes);
6397 if (data == NULL) {
6398 return PSA_ERROR_INSUFFICIENT_MEMORY;
6399 }
6400
6401 status = psa_key_derivation_output_bytes(operation, data, bytes);
6402 if (status != PSA_SUCCESS) {
6403 goto exit;
6404 }
6405#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
6406 if (slot->attr.type == PSA_KEY_TYPE_DES) {
6407 psa_des_set_key_parity(data, bytes);
6408 }
6409#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) */
6410 } else {
6411 return PSA_ERROR_NOT_SUPPORTED;
6412 }
6413
6414 slot->attr.bits = (psa_key_bits_t) bits;
6415
6416 if (psa_key_lifetime_is_external(slot->attr.lifetime)) {
6417 status = psa_driver_wrapper_get_key_buffer_size(&slot->attr,
6418 &storage_size);
6419 if (status != PSA_SUCCESS) {
6420 goto exit;
6421 }
6422 }
6423 status = psa_allocate_buffer_to_slot(slot, storage_size);
6424 if (status != PSA_SUCCESS) {
6425 goto exit;
6426 }
6427
6428 status = psa_driver_wrapper_import_key(&slot->attr,
6429 data, bytes,
6430 slot->key.data,
6431 slot->key.bytes,
6432 &slot->key.bytes, &bits);
6433 if (bits != slot->attr.bits) {
6434 status = PSA_ERROR_INVALID_ARGUMENT;
6435 }
6436
6437exit:
6438 mbedtls_free(data);
6439 return status;
6440}
6441
Sungbae Yoo4d211f32024-11-19 02:47:55 +00006442static const psa_custom_key_parameters_t default_custom_production =
6443 PSA_CUSTOM_KEY_PARAMETERS_INIT;
Tom Van Eyckb0563632024-06-13 16:20:14 +02006444
Sungbae Yoo4d211f32024-11-19 02:47:55 +00006445int psa_custom_key_parameters_are_default(
6446 const psa_custom_key_parameters_t *custom,
6447 size_t custom_data_length)
Tom Van Eyckb0563632024-06-13 16:20:14 +02006448{
Sungbae Yoo4d211f32024-11-19 02:47:55 +00006449 if (custom->flags != 0) {
Tom Van Eyckb0563632024-06-13 16:20:14 +02006450 return 0;
6451 }
Sungbae Yoo4d211f32024-11-19 02:47:55 +00006452 if (custom_data_length != 0) {
Tom Van Eyckb0563632024-06-13 16:20:14 +02006453 return 0;
6454 }
6455 return 1;
6456}
6457
Sungbae Yoo4d211f32024-11-19 02:47:55 +00006458psa_status_t psa_key_derivation_output_key_custom(
Tom Van Eyckb0563632024-06-13 16:20:14 +02006459 const psa_key_attributes_t *attributes,
6460 psa_key_derivation_operation_t *operation,
Sungbae Yoo4d211f32024-11-19 02:47:55 +00006461 const psa_custom_key_parameters_t *custom,
6462 const uint8_t *custom_data,
6463 size_t custom_data_length,
Tom Van Eyckb0563632024-06-13 16:20:14 +02006464 mbedtls_svc_key_id_t *key)
6465{
6466 psa_status_t status;
6467 psa_key_slot_t *slot = NULL;
6468 psa_se_drv_table_entry_t *driver = NULL;
6469
6470 *key = MBEDTLS_SVC_KEY_ID_INIT;
6471
6472 /* Reject any attempt to create a zero-length key so that we don't
6473 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
6474 if (psa_get_key_bits(attributes) == 0) {
6475 return PSA_ERROR_INVALID_ARGUMENT;
6476 }
6477
Sungbae Yoo4d211f32024-11-19 02:47:55 +00006478 (void) custom_data; /* We only accept 0-length data */
6479 if (!psa_custom_key_parameters_are_default(custom, custom_data_length)) {
Tom Van Eyckb0563632024-06-13 16:20:14 +02006480 return PSA_ERROR_INVALID_ARGUMENT;
6481 }
6482
6483 if (operation->alg == PSA_ALG_NONE) {
6484 return PSA_ERROR_BAD_STATE;
6485 }
6486
6487 if (!operation->can_output_key) {
6488 return PSA_ERROR_NOT_PERMITTED;
6489 }
6490
6491 status = psa_start_key_creation(PSA_KEY_CREATION_DERIVE, attributes,
6492 &slot, &driver);
6493#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
6494 if (driver != NULL) {
6495 /* Deriving a key in a secure element is not implemented yet. */
6496 status = PSA_ERROR_NOT_SUPPORTED;
6497 }
6498#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
6499 if (status == PSA_SUCCESS) {
6500 status = psa_generate_derived_key_internal(slot,
6501 attributes->bits,
6502 operation);
6503 }
6504 if (status == PSA_SUCCESS) {
6505 status = psa_finish_key_creation(slot, driver, key);
6506 }
6507 if (status != PSA_SUCCESS) {
6508 psa_fail_key_creation(slot, driver);
6509 }
6510
6511 return status;
6512}
6513
Sungbae Yoo4d211f32024-11-19 02:47:55 +00006514psa_status_t psa_key_derivation_output_key_ext(
6515 const psa_key_attributes_t *attributes,
6516 psa_key_derivation_operation_t *operation,
6517 const psa_key_production_parameters_t *params,
6518 size_t params_data_length,
6519 mbedtls_svc_key_id_t *key)
6520{
6521 return psa_key_derivation_output_key_custom(
6522 attributes, operation,
6523 (const psa_custom_key_parameters_t *) params,
6524 params->data, params_data_length,
6525 key);
6526}
6527
Tom Van Eyckb0563632024-06-13 16:20:14 +02006528psa_status_t psa_key_derivation_output_key(
6529 const psa_key_attributes_t *attributes,
6530 psa_key_derivation_operation_t *operation,
6531 mbedtls_svc_key_id_t *key)
6532{
Sungbae Yoo4d211f32024-11-19 02:47:55 +00006533 return psa_key_derivation_output_key_custom(attributes, operation,
6534 &default_custom_production,
6535 NULL, 0,
6536 key);
Tom Van Eyckb0563632024-06-13 16:20:14 +02006537}
6538
6539
6540/****************************************************************/
6541/* Key derivation */
6542/****************************************************************/
6543
6544#if defined(AT_LEAST_ONE_BUILTIN_KDF)
6545static int is_kdf_alg_supported(psa_algorithm_t kdf_alg)
6546{
6547#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
6548 if (PSA_ALG_IS_HKDF(kdf_alg)) {
6549 return 1;
6550 }
6551#endif
6552#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT)
6553 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
6554 return 1;
6555 }
6556#endif
6557#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND)
6558 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
6559 return 1;
6560 }
6561#endif
6562#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
6563 if (PSA_ALG_IS_TLS12_PRF(kdf_alg)) {
6564 return 1;
6565 }
6566#endif
6567#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
6568 if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
6569 return 1;
6570 }
6571#endif
6572#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
6573 if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
6574 return 1;
6575 }
6576#endif
6577#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
6578 if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
6579 return 1;
6580 }
6581#endif
6582#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128)
6583 if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
6584 return 1;
6585 }
6586#endif
6587 return 0;
6588}
6589
6590static psa_status_t psa_hash_try_support(psa_algorithm_t alg)
6591{
6592 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
6593 psa_status_t status = psa_hash_setup(&operation, alg);
6594 psa_hash_abort(&operation);
6595 return status;
6596}
6597
6598static psa_status_t psa_key_derivation_set_maximum_capacity(
6599 psa_key_derivation_operation_t *operation,
6600 psa_algorithm_t kdf_alg)
6601{
6602#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS)
6603 if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
6604 operation->capacity = PSA_HASH_LENGTH(PSA_ALG_SHA_256);
6605 return PSA_SUCCESS;
6606 }
6607#endif
6608#if defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128)
6609 if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
6610#if (SIZE_MAX > UINT32_MAX)
6611 operation->capacity = UINT32_MAX * (size_t) PSA_MAC_LENGTH(
6612 PSA_KEY_TYPE_AES,
6613 128U,
6614 PSA_ALG_CMAC);
6615#else
6616 operation->capacity = SIZE_MAX;
6617#endif
6618 return PSA_SUCCESS;
6619 }
6620#endif /* PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 */
6621
6622 /* After this point, if kdf_alg is not valid then value of hash_alg may be
6623 * invalid or meaningless but it does not affect this function */
6624 psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(kdf_alg);
6625 size_t hash_size = PSA_HASH_LENGTH(hash_alg);
6626 if (hash_size == 0) {
6627 return PSA_ERROR_NOT_SUPPORTED;
6628 }
6629
6630 /* Make sure that hash_alg is a supported hash algorithm. Otherwise
6631 * we might fail later, which is somewhat unfriendly and potentially
6632 * risk-prone. */
6633 psa_status_t status = psa_hash_try_support(hash_alg);
6634 if (status != PSA_SUCCESS) {
6635 return status;
6636 }
6637
6638#if defined(PSA_WANT_ALG_HKDF)
6639 if (PSA_ALG_IS_HKDF(kdf_alg)) {
6640 operation->capacity = 255 * hash_size;
6641 } else
6642#endif
6643#if defined(PSA_WANT_ALG_HKDF_EXTRACT)
6644 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
6645 operation->capacity = hash_size;
6646 } else
6647#endif
6648#if defined(PSA_WANT_ALG_HKDF_EXPAND)
6649 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
6650 operation->capacity = 255 * hash_size;
6651 } else
6652#endif
6653#if defined(PSA_WANT_ALG_TLS12_PRF)
6654 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) &&
6655 (hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384)) {
6656 operation->capacity = SIZE_MAX;
6657 } else
6658#endif
6659#if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS)
6660 if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg) &&
6661 (hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384)) {
6662 /* Master Secret is always 48 bytes
6663 * https://datatracker.ietf.org/doc/html/rfc5246.html#section-8.1 */
6664 operation->capacity = 48U;
6665 } else
6666#endif
6667#if defined(PSA_WANT_ALG_PBKDF2_HMAC)
6668 if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
6669#if (SIZE_MAX > UINT32_MAX)
6670 operation->capacity = UINT32_MAX * hash_size;
6671#else
6672 operation->capacity = SIZE_MAX;
6673#endif
6674 } else
6675#endif /* PSA_WANT_ALG_PBKDF2_HMAC */
6676 {
6677 (void) hash_size;
6678 status = PSA_ERROR_NOT_SUPPORTED;
6679 }
6680 return status;
6681}
6682
6683static psa_status_t psa_key_derivation_setup_kdf(
6684 psa_key_derivation_operation_t *operation,
6685 psa_algorithm_t kdf_alg)
6686{
6687 /* Make sure that operation->ctx is properly zero-initialised. (Macro
6688 * initialisers for this union leave some bytes unspecified.) */
6689 memset(&operation->ctx, 0, sizeof(operation->ctx));
6690
6691 /* Make sure that kdf_alg is a supported key derivation algorithm. */
6692 if (!is_kdf_alg_supported(kdf_alg)) {
6693 return PSA_ERROR_NOT_SUPPORTED;
6694 }
6695
6696 psa_status_t status = psa_key_derivation_set_maximum_capacity(operation,
6697 kdf_alg);
6698 return status;
6699}
6700
6701static psa_status_t psa_key_agreement_try_support(psa_algorithm_t alg)
6702{
6703#if defined(PSA_WANT_ALG_ECDH)
6704 if (alg == PSA_ALG_ECDH) {
6705 return PSA_SUCCESS;
6706 }
6707#endif
6708#if defined(PSA_WANT_ALG_FFDH)
6709 if (alg == PSA_ALG_FFDH) {
6710 return PSA_SUCCESS;
6711 }
6712#endif
6713 (void) alg;
6714 return PSA_ERROR_NOT_SUPPORTED;
6715}
6716
6717static int psa_key_derivation_allows_free_form_secret_input(
6718 psa_algorithm_t kdf_alg)
6719{
6720#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS)
6721 if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
6722 return 0;
6723 }
6724#endif
6725 (void) kdf_alg;
6726 return 1;
6727}
6728#endif /* AT_LEAST_ONE_BUILTIN_KDF */
6729
6730psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation,
6731 psa_algorithm_t alg)
6732{
6733 psa_status_t status;
6734
6735 if (operation->alg != 0) {
6736 return PSA_ERROR_BAD_STATE;
6737 }
6738
6739 if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
6740 return PSA_ERROR_INVALID_ARGUMENT;
6741 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
6742#if defined(AT_LEAST_ONE_BUILTIN_KDF)
6743 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
6744 psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE(alg);
6745 status = psa_key_agreement_try_support(ka_alg);
6746 if (status != PSA_SUCCESS) {
6747 return status;
6748 }
6749 if (!psa_key_derivation_allows_free_form_secret_input(kdf_alg)) {
6750 return PSA_ERROR_INVALID_ARGUMENT;
6751 }
6752 status = psa_key_derivation_setup_kdf(operation, kdf_alg);
6753#else
6754 return PSA_ERROR_NOT_SUPPORTED;
6755#endif /* AT_LEAST_ONE_BUILTIN_KDF */
6756 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
6757#if defined(AT_LEAST_ONE_BUILTIN_KDF)
6758 status = psa_key_derivation_setup_kdf(operation, alg);
6759#else
6760 return PSA_ERROR_NOT_SUPPORTED;
6761#endif /* AT_LEAST_ONE_BUILTIN_KDF */
6762 } else {
6763 return PSA_ERROR_INVALID_ARGUMENT;
6764 }
6765
6766 if (status == PSA_SUCCESS) {
6767 operation->alg = alg;
6768 }
6769 return status;
6770}
6771
6772#if defined(BUILTIN_ALG_ANY_HKDF)
6773static psa_status_t psa_hkdf_input(psa_hkdf_key_derivation_t *hkdf,
6774 psa_algorithm_t kdf_alg,
6775 psa_key_derivation_step_t step,
6776 const uint8_t *data,
6777 size_t data_length)
6778{
6779 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
6780 psa_status_t status;
6781 switch (step) {
6782 case PSA_KEY_DERIVATION_INPUT_SALT:
6783#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND)
6784 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
6785 return PSA_ERROR_INVALID_ARGUMENT;
6786 }
6787#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND */
6788 if (hkdf->state != HKDF_STATE_INIT) {
6789 return PSA_ERROR_BAD_STATE;
6790 } else {
6791 status = psa_key_derivation_start_hmac(&hkdf->hmac,
6792 hash_alg,
6793 data, data_length);
6794 if (status != PSA_SUCCESS) {
6795 return status;
6796 }
6797 hkdf->state = HKDF_STATE_STARTED;
6798 return PSA_SUCCESS;
6799 }
6800 case PSA_KEY_DERIVATION_INPUT_SECRET:
6801#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND)
6802 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
6803 /* We shouldn't be in different state as HKDF_EXPAND only allows
6804 * two inputs: SECRET (this case) and INFO which does not modify
6805 * the state. It could happen only if the hkdf
6806 * object was corrupted. */
6807 if (hkdf->state != HKDF_STATE_INIT) {
6808 return PSA_ERROR_BAD_STATE;
6809 }
6810
6811 /* Allow only input that fits expected prk size */
6812 if (data_length != PSA_HASH_LENGTH(hash_alg)) {
6813 return PSA_ERROR_INVALID_ARGUMENT;
6814 }
6815
6816 memcpy(hkdf->prk, data, data_length);
6817 } else
6818#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND */
6819 {
6820 /* HKDF: If no salt was provided, use an empty salt.
6821 * HKDF-EXTRACT: salt is mandatory. */
6822 if (hkdf->state == HKDF_STATE_INIT) {
6823#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT)
6824 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
6825 return PSA_ERROR_BAD_STATE;
6826 }
6827#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */
6828 status = psa_key_derivation_start_hmac(&hkdf->hmac,
6829 hash_alg,
6830 NULL, 0);
6831 if (status != PSA_SUCCESS) {
6832 return status;
6833 }
6834 hkdf->state = HKDF_STATE_STARTED;
6835 }
6836 if (hkdf->state != HKDF_STATE_STARTED) {
6837 return PSA_ERROR_BAD_STATE;
6838 }
6839 status = psa_mac_update(&hkdf->hmac,
6840 data, data_length);
6841 if (status != PSA_SUCCESS) {
6842 return status;
6843 }
6844 status = psa_mac_sign_finish(&hkdf->hmac,
6845 hkdf->prk,
6846 sizeof(hkdf->prk),
6847 &data_length);
6848 if (status != PSA_SUCCESS) {
6849 return status;
6850 }
6851 }
6852
6853 hkdf->state = HKDF_STATE_KEYED;
6854 hkdf->block_number = 0;
6855#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT)
6856 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
6857 /* The only block of output is the PRK. */
6858 memcpy(hkdf->output_block, hkdf->prk, PSA_HASH_LENGTH(hash_alg));
6859 hkdf->offset_in_block = 0;
6860 } else
6861#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */
6862 {
6863 /* Block 0 is empty, and the next block will be
6864 * generated by psa_key_derivation_hkdf_read(). */
6865 hkdf->offset_in_block = PSA_HASH_LENGTH(hash_alg);
6866 }
6867
6868 return PSA_SUCCESS;
6869 case PSA_KEY_DERIVATION_INPUT_INFO:
6870#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT)
6871 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
6872 return PSA_ERROR_INVALID_ARGUMENT;
6873 }
6874#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */
6875#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND)
6876 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg) &&
6877 hkdf->state == HKDF_STATE_INIT) {
6878 return PSA_ERROR_BAD_STATE;
6879 }
6880#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */
6881 if (hkdf->state == HKDF_STATE_OUTPUT) {
6882 return PSA_ERROR_BAD_STATE;
6883 }
6884 if (hkdf->info_set) {
6885 return PSA_ERROR_BAD_STATE;
6886 }
6887 hkdf->info_length = data_length;
6888 if (data_length != 0) {
6889 hkdf->info = mbedtls_calloc(1, data_length);
6890 if (hkdf->info == NULL) {
6891 return PSA_ERROR_INSUFFICIENT_MEMORY;
6892 }
6893 memcpy(hkdf->info, data, data_length);
6894 }
6895 hkdf->info_set = 1;
6896 return PSA_SUCCESS;
6897 default:
6898 return PSA_ERROR_INVALID_ARGUMENT;
6899 }
6900}
6901#endif /* BUILTIN_ALG_ANY_HKDF */
6902
6903#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
6904 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
6905static psa_status_t psa_tls12_prf_set_seed(psa_tls12_prf_key_derivation_t *prf,
6906 const uint8_t *data,
6907 size_t data_length)
6908{
6909 if (prf->state != PSA_TLS12_PRF_STATE_INIT) {
6910 return PSA_ERROR_BAD_STATE;
6911 }
6912
6913 if (data_length != 0) {
6914 prf->seed = mbedtls_calloc(1, data_length);
6915 if (prf->seed == NULL) {
6916 return PSA_ERROR_INSUFFICIENT_MEMORY;
6917 }
6918
6919 memcpy(prf->seed, data, data_length);
6920 prf->seed_length = data_length;
6921 }
6922
6923 prf->state = PSA_TLS12_PRF_STATE_SEED_SET;
6924
6925 return PSA_SUCCESS;
6926}
6927
6928static psa_status_t psa_tls12_prf_set_key(psa_tls12_prf_key_derivation_t *prf,
6929 const uint8_t *data,
6930 size_t data_length)
6931{
6932 if (prf->state != PSA_TLS12_PRF_STATE_SEED_SET &&
6933 prf->state != PSA_TLS12_PRF_STATE_OTHER_KEY_SET) {
6934 return PSA_ERROR_BAD_STATE;
6935 }
6936
6937 if (data_length != 0) {
6938 prf->secret = mbedtls_calloc(1, data_length);
6939 if (prf->secret == NULL) {
6940 return PSA_ERROR_INSUFFICIENT_MEMORY;
6941 }
6942
6943 memcpy(prf->secret, data, data_length);
6944 prf->secret_length = data_length;
6945 }
6946
6947 prf->state = PSA_TLS12_PRF_STATE_KEY_SET;
6948
6949 return PSA_SUCCESS;
6950}
6951
6952static psa_status_t psa_tls12_prf_set_label(psa_tls12_prf_key_derivation_t *prf,
6953 const uint8_t *data,
6954 size_t data_length)
6955{
6956 if (prf->state != PSA_TLS12_PRF_STATE_KEY_SET) {
6957 return PSA_ERROR_BAD_STATE;
6958 }
6959
6960 if (data_length != 0) {
6961 prf->label = mbedtls_calloc(1, data_length);
6962 if (prf->label == NULL) {
6963 return PSA_ERROR_INSUFFICIENT_MEMORY;
6964 }
6965
6966 memcpy(prf->label, data, data_length);
6967 prf->label_length = data_length;
6968 }
6969
6970 prf->state = PSA_TLS12_PRF_STATE_LABEL_SET;
6971
6972 return PSA_SUCCESS;
6973}
6974
6975static psa_status_t psa_tls12_prf_input(psa_tls12_prf_key_derivation_t *prf,
6976 psa_key_derivation_step_t step,
6977 const uint8_t *data,
6978 size_t data_length)
6979{
6980 switch (step) {
6981 case PSA_KEY_DERIVATION_INPUT_SEED:
6982 return psa_tls12_prf_set_seed(prf, data, data_length);
6983 case PSA_KEY_DERIVATION_INPUT_SECRET:
6984 return psa_tls12_prf_set_key(prf, data, data_length);
6985 case PSA_KEY_DERIVATION_INPUT_LABEL:
6986 return psa_tls12_prf_set_label(prf, data, data_length);
6987 default:
6988 return PSA_ERROR_INVALID_ARGUMENT;
6989 }
6990}
6991#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
6992 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
6993
6994#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
6995static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
6996 psa_tls12_prf_key_derivation_t *prf,
6997 const uint8_t *data,
6998 size_t data_length)
6999{
7000 psa_status_t status;
7001 const size_t pms_len = (prf->state == PSA_TLS12_PRF_STATE_OTHER_KEY_SET ?
7002 4 + data_length + prf->other_secret_length :
7003 4 + 2 * data_length);
7004
7005 if (data_length > PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE) {
7006 return PSA_ERROR_INVALID_ARGUMENT;
7007 }
7008
7009 uint8_t *pms = mbedtls_calloc(1, pms_len);
7010 if (pms == NULL) {
7011 return PSA_ERROR_INSUFFICIENT_MEMORY;
7012 }
7013 uint8_t *cur = pms;
7014
7015 /* pure-PSK:
7016 * Quoting RFC 4279, Section 2:
7017 *
7018 * The premaster secret is formed as follows: if the PSK is N octets
7019 * long, concatenate a uint16 with the value N, N zero octets, a second
7020 * uint16 with the value N, and the PSK itself.
7021 *
7022 * mixed-PSK:
7023 * In a DHE-PSK, RSA-PSK, ECDHE-PSK the premaster secret is formed as
7024 * follows: concatenate a uint16 with the length of the other secret,
7025 * the other secret itself, uint16 with the length of PSK, and the
7026 * PSK itself.
7027 * For details please check:
7028 * - RFC 4279, Section 4 for the definition of RSA-PSK,
7029 * - RFC 4279, Section 3 for the definition of DHE-PSK,
7030 * - RFC 5489 for the definition of ECDHE-PSK.
7031 */
7032
7033 if (prf->state == PSA_TLS12_PRF_STATE_OTHER_KEY_SET) {
7034 *cur++ = MBEDTLS_BYTE_1(prf->other_secret_length);
7035 *cur++ = MBEDTLS_BYTE_0(prf->other_secret_length);
7036 if (prf->other_secret_length != 0) {
7037 memcpy(cur, prf->other_secret, prf->other_secret_length);
7038 mbedtls_platform_zeroize(prf->other_secret, prf->other_secret_length);
7039 cur += prf->other_secret_length;
7040 }
7041 } else {
7042 *cur++ = MBEDTLS_BYTE_1(data_length);
7043 *cur++ = MBEDTLS_BYTE_0(data_length);
7044 memset(cur, 0, data_length);
7045 cur += data_length;
7046 }
7047
7048 *cur++ = MBEDTLS_BYTE_1(data_length);
7049 *cur++ = MBEDTLS_BYTE_0(data_length);
7050 memcpy(cur, data, data_length);
7051 cur += data_length;
7052
7053 status = psa_tls12_prf_set_key(prf, pms, (size_t) (cur - pms));
7054
7055 mbedtls_zeroize_and_free(pms, pms_len);
7056 return status;
7057}
7058
7059static psa_status_t psa_tls12_prf_psk_to_ms_set_other_key(
7060 psa_tls12_prf_key_derivation_t *prf,
7061 const uint8_t *data,
7062 size_t data_length)
7063{
7064 if (prf->state != PSA_TLS12_PRF_STATE_SEED_SET) {
7065 return PSA_ERROR_BAD_STATE;
7066 }
7067
7068 if (data_length != 0) {
7069 prf->other_secret = mbedtls_calloc(1, data_length);
7070 if (prf->other_secret == NULL) {
7071 return PSA_ERROR_INSUFFICIENT_MEMORY;
7072 }
7073
7074 memcpy(prf->other_secret, data, data_length);
7075 prf->other_secret_length = data_length;
7076 } else {
7077 prf->other_secret_length = 0;
7078 }
7079
7080 prf->state = PSA_TLS12_PRF_STATE_OTHER_KEY_SET;
7081
7082 return PSA_SUCCESS;
7083}
7084
7085static psa_status_t psa_tls12_prf_psk_to_ms_input(
7086 psa_tls12_prf_key_derivation_t *prf,
7087 psa_key_derivation_step_t step,
7088 const uint8_t *data,
7089 size_t data_length)
7090{
7091 switch (step) {
7092 case PSA_KEY_DERIVATION_INPUT_SECRET:
7093 return psa_tls12_prf_psk_to_ms_set_key(prf,
7094 data, data_length);
7095 break;
7096 case PSA_KEY_DERIVATION_INPUT_OTHER_SECRET:
7097 return psa_tls12_prf_psk_to_ms_set_other_key(prf,
7098 data,
7099 data_length);
7100 break;
7101 default:
7102 return psa_tls12_prf_input(prf, step, data, data_length);
7103 break;
7104
7105 }
7106}
7107#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
7108
7109#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
7110static psa_status_t psa_tls12_ecjpake_to_pms_input(
7111 psa_tls12_ecjpake_to_pms_t *ecjpake,
7112 psa_key_derivation_step_t step,
7113 const uint8_t *data,
7114 size_t data_length)
7115{
7116 if (data_length != PSA_TLS12_ECJPAKE_TO_PMS_INPUT_SIZE ||
7117 step != PSA_KEY_DERIVATION_INPUT_SECRET) {
7118 return PSA_ERROR_INVALID_ARGUMENT;
7119 }
7120
7121 /* Check if the passed point is in an uncompressed form */
7122 if (data[0] != 0x04) {
7123 return PSA_ERROR_INVALID_ARGUMENT;
7124 }
7125
7126 /* Only K.X has to be extracted - bytes 1 to 32 inclusive. */
7127 memcpy(ecjpake->data, data + 1, PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE);
7128
7129 return PSA_SUCCESS;
7130}
7131#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
7132
7133#if defined(PSA_HAVE_SOFT_PBKDF2)
7134static psa_status_t psa_pbkdf2_set_input_cost(
7135 psa_pbkdf2_key_derivation_t *pbkdf2,
7136 psa_key_derivation_step_t step,
7137 uint64_t data)
7138{
7139 if (step != PSA_KEY_DERIVATION_INPUT_COST) {
7140 return PSA_ERROR_INVALID_ARGUMENT;
7141 }
7142
7143 if (pbkdf2->state != PSA_PBKDF2_STATE_INIT) {
7144 return PSA_ERROR_BAD_STATE;
7145 }
7146
7147 if (data > PSA_VENDOR_PBKDF2_MAX_ITERATIONS) {
7148 return PSA_ERROR_NOT_SUPPORTED;
7149 }
7150
7151 if (data == 0) {
7152 return PSA_ERROR_INVALID_ARGUMENT;
7153 }
7154
7155 pbkdf2->input_cost = data;
7156 pbkdf2->state = PSA_PBKDF2_STATE_INPUT_COST_SET;
7157
7158 return PSA_SUCCESS;
7159}
7160
7161static psa_status_t psa_pbkdf2_set_salt(psa_pbkdf2_key_derivation_t *pbkdf2,
7162 const uint8_t *data,
7163 size_t data_length)
7164{
7165 if (pbkdf2->state == PSA_PBKDF2_STATE_INPUT_COST_SET) {
7166 pbkdf2->state = PSA_PBKDF2_STATE_SALT_SET;
7167 } else if (pbkdf2->state == PSA_PBKDF2_STATE_SALT_SET) {
7168 /* Appending to existing salt. No state change. */
7169 } else {
7170 return PSA_ERROR_BAD_STATE;
7171 }
7172
7173 if (data_length == 0) {
7174 /* Appending an empty string, nothing to do. */
7175 } else {
7176 uint8_t *next_salt;
7177
7178 next_salt = mbedtls_calloc(1, data_length + pbkdf2->salt_length);
7179 if (next_salt == NULL) {
7180 return PSA_ERROR_INSUFFICIENT_MEMORY;
7181 }
7182
7183 if (pbkdf2->salt_length != 0) {
7184 memcpy(next_salt, pbkdf2->salt, pbkdf2->salt_length);
7185 }
7186 memcpy(next_salt + pbkdf2->salt_length, data, data_length);
7187 pbkdf2->salt_length += data_length;
7188 mbedtls_free(pbkdf2->salt);
7189 pbkdf2->salt = next_salt;
7190 }
7191 return PSA_SUCCESS;
7192}
7193
7194#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
7195static psa_status_t psa_pbkdf2_hmac_set_password(psa_algorithm_t hash_alg,
7196 const uint8_t *input,
7197 size_t input_len,
7198 uint8_t *output,
7199 size_t *output_len)
7200{
7201 psa_status_t status = PSA_SUCCESS;
7202 if (input_len > PSA_HASH_BLOCK_LENGTH(hash_alg)) {
7203 return psa_hash_compute(hash_alg, input, input_len, output,
7204 PSA_HMAC_MAX_HASH_BLOCK_SIZE, output_len);
7205 } else if (input_len > 0) {
7206 memcpy(output, input, input_len);
7207 }
7208 *output_len = PSA_HASH_BLOCK_LENGTH(hash_alg);
7209 return status;
7210}
7211#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
7212
7213#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128)
7214static psa_status_t psa_pbkdf2_cmac_set_password(const uint8_t *input,
7215 size_t input_len,
7216 uint8_t *output,
7217 size_t *output_len)
7218{
7219 psa_status_t status = PSA_SUCCESS;
7220 if (input_len != PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC)) {
7221 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
7222 uint8_t zeros[16] = { 0 };
7223 psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
7224 psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(sizeof(zeros)));
7225 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
7226 /* Passing PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC) as
7227 * mac_size as the driver function sets mac_output_length = mac_size
7228 * on success. See https://github.com/Mbed-TLS/mbedtls/issues/7801 */
7229 status = psa_driver_wrapper_mac_compute(&attributes,
7230 zeros, sizeof(zeros),
7231 PSA_ALG_CMAC, input, input_len,
7232 output,
7233 PSA_MAC_LENGTH(PSA_KEY_TYPE_AES,
7234 128U,
7235 PSA_ALG_CMAC),
7236 output_len);
7237 } else {
7238 memcpy(output, input, input_len);
7239 *output_len = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC);
7240 }
7241 return status;
7242}
7243#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 */
7244
7245static psa_status_t psa_pbkdf2_set_password(psa_pbkdf2_key_derivation_t *pbkdf2,
7246 psa_algorithm_t kdf_alg,
7247 const uint8_t *data,
7248 size_t data_length)
7249{
7250 psa_status_t status = PSA_SUCCESS;
7251 if (pbkdf2->state != PSA_PBKDF2_STATE_SALT_SET) {
7252 return PSA_ERROR_BAD_STATE;
7253 }
7254
7255#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
7256 if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
7257 psa_algorithm_t hash_alg = PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg);
7258 status = psa_pbkdf2_hmac_set_password(hash_alg, data, data_length,
7259 pbkdf2->password,
7260 &pbkdf2->password_length);
7261 } else
7262#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
7263#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128)
7264 if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
7265 status = psa_pbkdf2_cmac_set_password(data, data_length,
7266 pbkdf2->password,
7267 &pbkdf2->password_length);
7268 } else
7269#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 */
7270 {
7271 return PSA_ERROR_INVALID_ARGUMENT;
7272 }
7273
7274 pbkdf2->state = PSA_PBKDF2_STATE_PASSWORD_SET;
7275
7276 return status;
7277}
7278
7279static psa_status_t psa_pbkdf2_input(psa_pbkdf2_key_derivation_t *pbkdf2,
7280 psa_algorithm_t kdf_alg,
7281 psa_key_derivation_step_t step,
7282 const uint8_t *data,
7283 size_t data_length)
7284{
7285 switch (step) {
7286 case PSA_KEY_DERIVATION_INPUT_SALT:
7287 return psa_pbkdf2_set_salt(pbkdf2, data, data_length);
7288 case PSA_KEY_DERIVATION_INPUT_PASSWORD:
7289 return psa_pbkdf2_set_password(pbkdf2, kdf_alg, data, data_length);
7290 default:
7291 return PSA_ERROR_INVALID_ARGUMENT;
7292 }
7293}
7294#endif /* PSA_HAVE_SOFT_PBKDF2 */
7295
7296/** Check whether the given key type is acceptable for the given
7297 * input step of a key derivation.
7298 *
7299 * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE.
7300 * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA.
7301 * Both secret and non-secret inputs can alternatively have the type
7302 * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning
7303 * that the input was passed as a buffer rather than via a key object.
7304 */
7305static int psa_key_derivation_check_input_type(
7306 psa_key_derivation_step_t step,
7307 psa_key_type_t key_type)
7308{
7309 switch (step) {
7310 case PSA_KEY_DERIVATION_INPUT_SECRET:
7311 if (key_type == PSA_KEY_TYPE_DERIVE) {
7312 return PSA_SUCCESS;
7313 }
7314 if (key_type == PSA_KEY_TYPE_NONE) {
7315 return PSA_SUCCESS;
7316 }
7317 break;
7318 case PSA_KEY_DERIVATION_INPUT_OTHER_SECRET:
7319 if (key_type == PSA_KEY_TYPE_DERIVE) {
7320 return PSA_SUCCESS;
7321 }
7322 if (key_type == PSA_KEY_TYPE_NONE) {
7323 return PSA_SUCCESS;
7324 }
7325 break;
7326 case PSA_KEY_DERIVATION_INPUT_LABEL:
7327 case PSA_KEY_DERIVATION_INPUT_SALT:
7328 case PSA_KEY_DERIVATION_INPUT_INFO:
7329 case PSA_KEY_DERIVATION_INPUT_SEED:
7330 if (key_type == PSA_KEY_TYPE_RAW_DATA) {
7331 return PSA_SUCCESS;
7332 }
7333 if (key_type == PSA_KEY_TYPE_NONE) {
7334 return PSA_SUCCESS;
7335 }
7336 break;
7337 case PSA_KEY_DERIVATION_INPUT_PASSWORD:
7338 if (key_type == PSA_KEY_TYPE_PASSWORD) {
7339 return PSA_SUCCESS;
7340 }
7341 if (key_type == PSA_KEY_TYPE_DERIVE) {
7342 return PSA_SUCCESS;
7343 }
7344 if (key_type == PSA_KEY_TYPE_NONE) {
7345 return PSA_SUCCESS;
7346 }
7347 break;
7348 }
7349 return PSA_ERROR_INVALID_ARGUMENT;
7350}
7351
7352static psa_status_t psa_key_derivation_input_internal(
7353 psa_key_derivation_operation_t *operation,
7354 psa_key_derivation_step_t step,
7355 psa_key_type_t key_type,
7356 const uint8_t *data,
7357 size_t data_length)
7358{
7359 psa_status_t status;
7360 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
7361
7362 status = psa_key_derivation_check_input_type(step, key_type);
7363 if (status != PSA_SUCCESS) {
7364 goto exit;
7365 }
7366
7367#if defined(BUILTIN_ALG_ANY_HKDF)
7368 if (PSA_ALG_IS_ANY_HKDF(kdf_alg)) {
7369 status = psa_hkdf_input(&operation->ctx.hkdf, kdf_alg,
7370 step, data, data_length);
7371 } else
7372#endif /* BUILTIN_ALG_ANY_HKDF */
7373#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
7374 if (PSA_ALG_IS_TLS12_PRF(kdf_alg)) {
7375 status = psa_tls12_prf_input(&operation->ctx.tls12_prf,
7376 step, data, data_length);
7377 } else
7378#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF */
7379#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
7380 if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
7381 status = psa_tls12_prf_psk_to_ms_input(&operation->ctx.tls12_prf,
7382 step, data, data_length);
7383 } else
7384#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
7385#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
7386 if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
7387 status = psa_tls12_ecjpake_to_pms_input(
7388 &operation->ctx.tls12_ecjpake_to_pms, step, data, data_length);
7389 } else
7390#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
7391#if defined(PSA_HAVE_SOFT_PBKDF2)
7392 if (PSA_ALG_IS_PBKDF2(kdf_alg)) {
7393 status = psa_pbkdf2_input(&operation->ctx.pbkdf2, kdf_alg,
7394 step, data, data_length);
7395 } else
7396#endif /* PSA_HAVE_SOFT_PBKDF2 */
7397 {
7398 /* This can't happen unless the operation object was not initialized */
7399 (void) data;
7400 (void) data_length;
7401 (void) kdf_alg;
7402 return PSA_ERROR_BAD_STATE;
7403 }
7404
7405exit:
7406 if (status != PSA_SUCCESS) {
7407 psa_key_derivation_abort(operation);
7408 }
7409 return status;
7410}
7411
7412static psa_status_t psa_key_derivation_input_integer_internal(
7413 psa_key_derivation_operation_t *operation,
7414 psa_key_derivation_step_t step,
7415 uint64_t value)
7416{
7417 psa_status_t status;
7418 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
7419
7420#if defined(PSA_HAVE_SOFT_PBKDF2)
7421 if (PSA_ALG_IS_PBKDF2(kdf_alg)) {
7422 status = psa_pbkdf2_set_input_cost(
7423 &operation->ctx.pbkdf2, step, value);
7424 } else
7425#endif /* PSA_HAVE_SOFT_PBKDF2 */
7426 {
7427 (void) step;
7428 (void) value;
7429 (void) kdf_alg;
7430 status = PSA_ERROR_INVALID_ARGUMENT;
7431 }
7432
7433 if (status != PSA_SUCCESS) {
7434 psa_key_derivation_abort(operation);
7435 }
7436 return status;
7437}
7438
7439psa_status_t psa_key_derivation_input_bytes(
7440 psa_key_derivation_operation_t *operation,
7441 psa_key_derivation_step_t step,
7442 const uint8_t *data_external,
7443 size_t data_length)
7444{
7445 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
7446 LOCAL_INPUT_DECLARE(data_external, data);
7447
7448 LOCAL_INPUT_ALLOC(data_external, data_length, data);
7449
7450 status = psa_key_derivation_input_internal(operation, step,
7451 PSA_KEY_TYPE_NONE,
7452 data, data_length);
7453#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
7454exit:
7455#endif
7456 LOCAL_INPUT_FREE(data_external, data);
7457 return status;
7458}
7459
7460psa_status_t psa_key_derivation_input_integer(
7461 psa_key_derivation_operation_t *operation,
7462 psa_key_derivation_step_t step,
7463 uint64_t value)
7464{
7465 return psa_key_derivation_input_integer_internal(operation, step, value);
7466}
7467
7468psa_status_t psa_key_derivation_input_key(
7469 psa_key_derivation_operation_t *operation,
7470 psa_key_derivation_step_t step,
7471 mbedtls_svc_key_id_t key)
7472{
7473 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
7474 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
7475 psa_key_slot_t *slot;
7476
7477 status = psa_get_and_lock_transparent_key_slot_with_policy(
7478 key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg);
7479 if (status != PSA_SUCCESS) {
7480 psa_key_derivation_abort(operation);
7481 return status;
7482 }
7483
7484 /* Passing a key object as a SECRET or PASSWORD input unlocks the
7485 * permission to output to a key object. */
7486 if (step == PSA_KEY_DERIVATION_INPUT_SECRET ||
7487 step == PSA_KEY_DERIVATION_INPUT_PASSWORD) {
7488 operation->can_output_key = 1;
7489 }
7490
7491 status = psa_key_derivation_input_internal(operation,
7492 step, slot->attr.type,
7493 slot->key.data,
7494 slot->key.bytes);
7495
7496 unlock_status = psa_unregister_read_under_mutex(slot);
7497
7498 return (status == PSA_SUCCESS) ? unlock_status : status;
7499}
7500
7501
7502
7503/****************************************************************/
7504/* Key agreement */
7505/****************************************************************/
7506
7507psa_status_t psa_key_agreement_raw_builtin(const psa_key_attributes_t *attributes,
7508 const uint8_t *key_buffer,
7509 size_t key_buffer_size,
7510 psa_algorithm_t alg,
7511 const uint8_t *peer_key,
7512 size_t peer_key_length,
7513 uint8_t *shared_secret,
7514 size_t shared_secret_size,
7515 size_t *shared_secret_length)
7516{
7517 switch (alg) {
7518#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
7519 case PSA_ALG_ECDH:
7520 return mbedtls_psa_key_agreement_ecdh(attributes, key_buffer,
7521 key_buffer_size, alg,
7522 peer_key, peer_key_length,
7523 shared_secret,
7524 shared_secret_size,
7525 shared_secret_length);
7526#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
7527
7528#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
7529 case PSA_ALG_FFDH:
7530 return mbedtls_psa_ffdh_key_agreement(attributes,
7531 peer_key,
7532 peer_key_length,
7533 key_buffer,
7534 key_buffer_size,
7535 shared_secret,
7536 shared_secret_size,
7537 shared_secret_length);
7538#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */
7539
7540 default:
7541 (void) attributes;
7542 (void) key_buffer;
7543 (void) key_buffer_size;
7544 (void) peer_key;
7545 (void) peer_key_length;
7546 (void) shared_secret;
7547 (void) shared_secret_size;
7548 (void) shared_secret_length;
7549 return PSA_ERROR_NOT_SUPPORTED;
7550 }
7551}
7552
7553/** Internal function for raw key agreement
7554 * Calls the driver wrapper which will hand off key agreement task
7555 * to the driver's implementation if a driver is present.
7556 * Fallback specified in the driver wrapper is built-in raw key agreement
7557 * (psa_key_agreement_raw_builtin).
7558 */
7559static psa_status_t psa_key_agreement_raw_internal(psa_algorithm_t alg,
7560 psa_key_slot_t *private_key,
7561 const uint8_t *peer_key,
7562 size_t peer_key_length,
7563 uint8_t *shared_secret,
7564 size_t shared_secret_size,
7565 size_t *shared_secret_length)
7566{
7567 if (!PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
7568 return PSA_ERROR_NOT_SUPPORTED;
7569 }
7570
7571 return psa_driver_wrapper_key_agreement(&private_key->attr,
7572 private_key->key.data,
7573 private_key->key.bytes, alg,
7574 peer_key, peer_key_length,
7575 shared_secret,
7576 shared_secret_size,
7577 shared_secret_length);
7578}
7579
7580/* Note that if this function fails, you must call psa_key_derivation_abort()
7581 * to potentially free embedded data structures and wipe confidential data.
7582 */
7583static psa_status_t psa_key_agreement_internal(psa_key_derivation_operation_t *operation,
7584 psa_key_derivation_step_t step,
7585 psa_key_slot_t *private_key,
7586 const uint8_t *peer_key,
7587 size_t peer_key_length)
7588{
7589 psa_status_t status;
7590 uint8_t shared_secret[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE] = { 0 };
7591 size_t shared_secret_length = 0;
7592 psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE(operation->alg);
7593
7594 /* Step 1: run the secret agreement algorithm to generate the shared
7595 * secret. */
7596 status = psa_key_agreement_raw_internal(ka_alg,
7597 private_key,
7598 peer_key, peer_key_length,
7599 shared_secret,
7600 sizeof(shared_secret),
7601 &shared_secret_length);
7602 if (status != PSA_SUCCESS) {
7603 goto exit;
7604 }
7605
7606 /* Step 2: set up the key derivation to generate key material from
7607 * the shared secret. A shared secret is permitted wherever a key
7608 * of type DERIVE is permitted. */
7609 status = psa_key_derivation_input_internal(operation, step,
7610 PSA_KEY_TYPE_DERIVE,
7611 shared_secret,
7612 shared_secret_length);
7613exit:
7614 mbedtls_platform_zeroize(shared_secret, shared_secret_length);
7615 return status;
7616}
7617
7618psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *operation,
7619 psa_key_derivation_step_t step,
7620 mbedtls_svc_key_id_t private_key,
7621 const uint8_t *peer_key_external,
7622 size_t peer_key_length)
7623{
7624 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
7625 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
7626 psa_key_slot_t *slot;
7627 LOCAL_INPUT_DECLARE(peer_key_external, peer_key);
7628
7629 if (!PSA_ALG_IS_KEY_AGREEMENT(operation->alg)) {
7630 return PSA_ERROR_INVALID_ARGUMENT;
7631 }
7632 status = psa_get_and_lock_transparent_key_slot_with_policy(
7633 private_key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg);
7634 if (status != PSA_SUCCESS) {
7635 return status;
7636 }
7637
7638 LOCAL_INPUT_ALLOC(peer_key_external, peer_key_length, peer_key);
7639 status = psa_key_agreement_internal(operation, step,
7640 slot,
7641 peer_key, peer_key_length);
7642
7643#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
7644exit:
7645#endif
7646 if (status != PSA_SUCCESS) {
7647 psa_key_derivation_abort(operation);
7648 } else {
7649 /* If a private key has been added as SECRET, we allow the derived
7650 * key material to be used as a key in PSA Crypto. */
7651 if (step == PSA_KEY_DERIVATION_INPUT_SECRET) {
7652 operation->can_output_key = 1;
7653 }
7654 }
7655
7656 unlock_status = psa_unregister_read_under_mutex(slot);
7657 LOCAL_INPUT_FREE(peer_key_external, peer_key);
7658
7659 return (status == PSA_SUCCESS) ? unlock_status : status;
7660}
7661
7662psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
7663 mbedtls_svc_key_id_t private_key,
7664 const uint8_t *peer_key_external,
7665 size_t peer_key_length,
7666 uint8_t *output_external,
7667 size_t output_size,
7668 size_t *output_length)
7669{
7670 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
7671 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
7672 psa_key_slot_t *slot = NULL;
7673 size_t expected_length;
7674 LOCAL_INPUT_DECLARE(peer_key_external, peer_key);
7675 LOCAL_OUTPUT_DECLARE(output_external, output);
7676 LOCAL_OUTPUT_ALLOC(output_external, output_size, output);
7677
7678 if (!PSA_ALG_IS_KEY_AGREEMENT(alg)) {
7679 status = PSA_ERROR_INVALID_ARGUMENT;
7680 goto exit;
7681 }
7682 status = psa_get_and_lock_transparent_key_slot_with_policy(
7683 private_key, &slot, PSA_KEY_USAGE_DERIVE, alg);
7684 if (status != PSA_SUCCESS) {
7685 goto exit;
7686 }
7687
7688 /* PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is in general an upper bound
7689 * for the output size. The PSA specification only guarantees that this
7690 * function works if output_size >= PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(...),
7691 * but it might be nice to allow smaller buffers if the output fits.
7692 * At the time of writing this comment, with only ECDH implemented,
7693 * PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is exact so the point is moot.
7694 * If FFDH is implemented, PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() can easily
7695 * be exact for it as well. */
7696 expected_length =
7697 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(slot->attr.type, slot->attr.bits);
7698 if (output_size < expected_length) {
7699 status = PSA_ERROR_BUFFER_TOO_SMALL;
7700 goto exit;
7701 }
7702
7703 LOCAL_INPUT_ALLOC(peer_key_external, peer_key_length, peer_key);
7704 status = psa_key_agreement_raw_internal(alg, slot,
7705 peer_key, peer_key_length,
7706 output, output_size,
7707 output_length);
7708
7709exit:
7710 /* Check for successful allocation of output,
7711 * with an unsuccessful status. */
7712 if (output != NULL && status != PSA_SUCCESS) {
7713 /* If an error happens and is not handled properly, the output
7714 * may be used as a key to protect sensitive data. Arrange for such
7715 * a key to be random, which is likely to result in decryption or
7716 * verification errors. This is better than filling the buffer with
7717 * some constant data such as zeros, which would result in the data
7718 * being protected with a reproducible, easily knowable key.
7719 */
7720 psa_generate_random_internal(output, output_size);
7721 *output_length = output_size;
7722 }
7723
7724 if (output == NULL) {
7725 /* output allocation failed. */
7726 *output_length = 0;
7727 }
7728
7729 unlock_status = psa_unregister_read_under_mutex(slot);
7730
7731 LOCAL_INPUT_FREE(peer_key_external, peer_key);
7732 LOCAL_OUTPUT_FREE(output_external, output);
7733 return (status == PSA_SUCCESS) ? unlock_status : status;
7734}
7735
7736
7737/****************************************************************/
7738/* Random generation */
7739/****************************************************************/
7740
7741#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
7742#include "entropy_poll.h"
7743#endif
7744
7745/** Initialize the PSA random generator.
7746 *
7747 * Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling
7748 * this function if mutexes are enabled.
7749 */
7750static void mbedtls_psa_random_init(mbedtls_psa_random_context_t *rng)
7751{
7752#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
7753 memset(rng, 0, sizeof(*rng));
7754#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
7755
7756 /* Set default configuration if
7757 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
7758 if (rng->entropy_init == NULL) {
7759 rng->entropy_init = mbedtls_entropy_init;
7760 }
7761 if (rng->entropy_free == NULL) {
7762 rng->entropy_free = mbedtls_entropy_free;
7763 }
7764
7765 rng->entropy_init(&rng->entropy);
7766#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
7767 defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
7768 /* The PSA entropy injection feature depends on using NV seed as an entropy
7769 * source. Add NV seed as an entropy source for PSA entropy injection. */
7770 mbedtls_entropy_add_source(&rng->entropy,
7771 mbedtls_nv_seed_poll, NULL,
7772 MBEDTLS_ENTROPY_BLOCK_SIZE,
7773 MBEDTLS_ENTROPY_SOURCE_STRONG);
7774#endif
7775
7776 mbedtls_psa_drbg_init(&rng->drbg);
7777#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
7778}
7779
7780/** Deinitialize the PSA random generator.
7781 *
7782 * Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling
7783 * this function if mutexes are enabled.
7784 */
7785static void mbedtls_psa_random_free(mbedtls_psa_random_context_t *rng)
7786{
7787#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
7788 memset(rng, 0, sizeof(*rng));
7789#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
7790 mbedtls_psa_drbg_free(&rng->drbg);
7791 rng->entropy_free(&rng->entropy);
7792#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
7793}
7794
7795/** Seed the PSA random generator.
7796 */
7797static psa_status_t mbedtls_psa_random_seed(mbedtls_psa_random_context_t *rng)
7798{
7799#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
7800 /* Do nothing: the external RNG seeds itself. */
7801 (void) rng;
7802 return PSA_SUCCESS;
7803#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
7804 const unsigned char drbg_seed[] = "PSA";
7805 int ret = mbedtls_psa_drbg_seed(&rng->drbg, &rng->entropy,
7806 drbg_seed, sizeof(drbg_seed) - 1);
7807 return mbedtls_to_psa_error(ret);
7808#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
7809}
7810
7811psa_status_t psa_generate_random(uint8_t *output_external,
7812 size_t output_size)
7813{
7814 psa_status_t status;
7815
7816 LOCAL_OUTPUT_DECLARE(output_external, output);
7817 LOCAL_OUTPUT_ALLOC(output_external, output_size, output);
7818
7819 status = psa_generate_random_internal(output, output_size);
7820
7821#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
7822exit:
7823#endif
7824 LOCAL_OUTPUT_FREE(output_external, output);
7825 return status;
7826}
7827
7828#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
7829psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
7830 size_t seed_size)
7831{
7832 if (psa_get_initialized()) {
7833 return PSA_ERROR_NOT_PERMITTED;
7834 }
7835
7836 if (((seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM) ||
7837 (seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE)) ||
7838 (seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE)) {
7839 return PSA_ERROR_INVALID_ARGUMENT;
7840 }
7841
7842 return mbedtls_psa_storage_inject_entropy(seed, seed_size);
7843}
7844#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
7845
7846/** Validate the key type and size for key generation
7847 *
7848 * \param type The key type
7849 * \param bits The number of bits of the key
7850 *
7851 * \retval #PSA_SUCCESS
7852 * The key type and size are valid.
7853 * \retval #PSA_ERROR_INVALID_ARGUMENT
7854 * The size in bits of the key is not valid.
7855 * \retval #PSA_ERROR_NOT_SUPPORTED
7856 * The type and/or the size in bits of the key or the combination of
7857 * the two is not supported.
7858 */
7859static psa_status_t psa_validate_key_type_and_size_for_key_generation(
7860 psa_key_type_t type, size_t bits)
7861{
7862 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
7863
7864 if (key_type_is_raw_bytes(type)) {
7865 status = psa_validate_unstructured_key_bit_size(type, bits);
7866 if (status != PSA_SUCCESS) {
7867 return status;
7868 }
7869 } else
7870#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
7871 if (PSA_KEY_TYPE_IS_RSA(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
7872 if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) {
7873 return PSA_ERROR_NOT_SUPPORTED;
7874 }
7875 if (bits < PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS) {
7876 return PSA_ERROR_NOT_SUPPORTED;
7877 }
7878
7879 /* Accept only byte-aligned keys, for the same reasons as
7880 * in psa_import_rsa_key(). */
7881 if (bits % 8 != 0) {
7882 return PSA_ERROR_NOT_SUPPORTED;
7883 }
7884 } else
7885#endif /* defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */
7886
7887#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
7888 if (PSA_KEY_TYPE_IS_ECC(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
7889 /* To avoid empty block, return successfully here. */
7890 return PSA_SUCCESS;
7891 } else
7892#endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) */
7893
7894#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
7895 if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
7896 if (psa_is_dh_key_size_valid(bits) == 0) {
7897 return PSA_ERROR_NOT_SUPPORTED;
7898 }
7899 } else
7900#endif /* defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) */
7901 {
7902 return PSA_ERROR_NOT_SUPPORTED;
7903 }
7904
7905 return PSA_SUCCESS;
7906}
7907
7908psa_status_t psa_generate_key_internal(
7909 const psa_key_attributes_t *attributes,
Sungbae Yoo4d211f32024-11-19 02:47:55 +00007910 const psa_custom_key_parameters_t *custom,
7911 const uint8_t *custom_data,
7912 size_t custom_data_length,
Tom Van Eyckb0563632024-06-13 16:20:14 +02007913 uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
7914{
7915 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
7916 psa_key_type_t type = attributes->type;
7917
7918 /* Only used for RSA */
Sungbae Yoo4d211f32024-11-19 02:47:55 +00007919 (void) custom;
7920 (void) custom_data;
7921 (void) custom_data_length;
Tom Van Eyckb0563632024-06-13 16:20:14 +02007922
7923 if (key_type_is_raw_bytes(type)) {
7924 status = psa_generate_random_internal(key_buffer, key_buffer_size);
7925 if (status != PSA_SUCCESS) {
7926 return status;
7927 }
7928
7929#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
7930 if (type == PSA_KEY_TYPE_DES) {
7931 psa_des_set_key_parity(key_buffer, key_buffer_size);
7932 }
7933#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
7934 } else
7935
7936#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
7937 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
7938 return mbedtls_psa_rsa_generate_key(attributes,
Sungbae Yoo4d211f32024-11-19 02:47:55 +00007939 custom_data, custom_data_length,
Tom Van Eyckb0563632024-06-13 16:20:14 +02007940 key_buffer,
7941 key_buffer_size,
7942 key_buffer_length);
7943 } else
7944#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */
7945
7946#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
7947 if (PSA_KEY_TYPE_IS_ECC(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
7948 return mbedtls_psa_ecp_generate_key(attributes,
7949 key_buffer,
7950 key_buffer_size,
7951 key_buffer_length);
7952 } else
7953#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE) */
7954
7955#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE)
7956 if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
7957 return mbedtls_psa_ffdh_generate_key(attributes,
7958 key_buffer,
7959 key_buffer_size,
7960 key_buffer_length);
7961 } else
7962#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE) */
7963 {
7964 (void) key_buffer_length;
7965 return PSA_ERROR_NOT_SUPPORTED;
7966 }
7967
7968 return PSA_SUCCESS;
7969}
7970
Sungbae Yoo4d211f32024-11-19 02:47:55 +00007971psa_status_t psa_generate_key_custom(const psa_key_attributes_t *attributes,
7972 const psa_custom_key_parameters_t *custom,
7973 const uint8_t *custom_data,
7974 size_t custom_data_length,
7975 mbedtls_svc_key_id_t *key)
Tom Van Eyckb0563632024-06-13 16:20:14 +02007976{
7977 psa_status_t status;
7978 psa_key_slot_t *slot = NULL;
7979 psa_se_drv_table_entry_t *driver = NULL;
7980 size_t key_buffer_size;
7981
7982 *key = MBEDTLS_SVC_KEY_ID_INIT;
7983
7984 /* Reject any attempt to create a zero-length key so that we don't
7985 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
7986 if (psa_get_key_bits(attributes) == 0) {
7987 return PSA_ERROR_INVALID_ARGUMENT;
7988 }
7989
7990 /* Reject any attempt to create a public key. */
7991 if (PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->type)) {
7992 return PSA_ERROR_INVALID_ARGUMENT;
7993 }
7994
7995#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
7996 if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
Sungbae Yoo4d211f32024-11-19 02:47:55 +00007997 if (custom->flags != 0) {
Tom Van Eyckb0563632024-06-13 16:20:14 +02007998 return PSA_ERROR_INVALID_ARGUMENT;
7999 }
8000 } else
8001#endif
Sungbae Yoo4d211f32024-11-19 02:47:55 +00008002 if (!psa_custom_key_parameters_are_default(custom, custom_data_length)) {
Tom Van Eyckb0563632024-06-13 16:20:14 +02008003 return PSA_ERROR_INVALID_ARGUMENT;
8004 }
8005
8006 status = psa_start_key_creation(PSA_KEY_CREATION_GENERATE, attributes,
8007 &slot, &driver);
8008 if (status != PSA_SUCCESS) {
8009 goto exit;
8010 }
8011
8012 /* In the case of a transparent key or an opaque key stored in local
8013 * storage ( thus not in the case of generating a key in a secure element
8014 * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
8015 * buffer to hold the generated key material. */
8016 if (slot->key.data == NULL) {
8017 if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->lifetime) ==
8018 PSA_KEY_LOCATION_LOCAL_STORAGE) {
8019 status = psa_validate_key_type_and_size_for_key_generation(
8020 attributes->type, attributes->bits);
8021 if (status != PSA_SUCCESS) {
8022 goto exit;
8023 }
8024
8025 key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
8026 attributes->type,
8027 attributes->bits);
8028 } else {
8029 status = psa_driver_wrapper_get_key_buffer_size(
8030 attributes, &key_buffer_size);
8031 if (status != PSA_SUCCESS) {
8032 goto exit;
8033 }
8034 }
8035
8036 status = psa_allocate_buffer_to_slot(slot, key_buffer_size);
8037 if (status != PSA_SUCCESS) {
8038 goto exit;
8039 }
8040 }
8041
8042 status = psa_driver_wrapper_generate_key(attributes,
Sungbae Yoo4d211f32024-11-19 02:47:55 +00008043 custom,
8044 custom_data, custom_data_length,
Tom Van Eyckb0563632024-06-13 16:20:14 +02008045 slot->key.data, slot->key.bytes,
8046 &slot->key.bytes);
8047 if (status != PSA_SUCCESS) {
8048 psa_remove_key_data_from_memory(slot);
8049 }
8050
8051exit:
8052 if (status == PSA_SUCCESS) {
8053 status = psa_finish_key_creation(slot, driver, key);
8054 }
8055 if (status != PSA_SUCCESS) {
8056 psa_fail_key_creation(slot, driver);
8057 }
8058
8059 return status;
8060}
8061
Sungbae Yoo4d211f32024-11-19 02:47:55 +00008062psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes,
8063 const psa_key_production_parameters_t *params,
8064 size_t params_data_length,
8065 mbedtls_svc_key_id_t *key)
8066{
8067 return psa_generate_key_custom(
8068 attributes,
8069 (const psa_custom_key_parameters_t *) params,
8070 params->data, params_data_length,
8071 key);
8072}
8073
Tom Van Eyckb0563632024-06-13 16:20:14 +02008074psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
8075 mbedtls_svc_key_id_t *key)
8076{
Sungbae Yoo4d211f32024-11-19 02:47:55 +00008077 return psa_generate_key_custom(attributes,
8078 &default_custom_production,
8079 NULL, 0,
8080 key);
Tom Van Eyckb0563632024-06-13 16:20:14 +02008081}
8082
8083/****************************************************************/
8084/* Module setup */
8085/****************************************************************/
8086
8087#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
8088psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
8089 void (* entropy_init)(mbedtls_entropy_context *ctx),
8090 void (* entropy_free)(mbedtls_entropy_context *ctx))
8091{
8092 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
8093
8094#if defined(MBEDTLS_THREADING_C)
8095 mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex);
8096#endif /* defined(MBEDTLS_THREADING_C) */
8097
8098 if (global_data.rng_state != RNG_NOT_INITIALIZED) {
8099 status = PSA_ERROR_BAD_STATE;
8100 } else {
8101 global_data.rng.entropy_init = entropy_init;
8102 global_data.rng.entropy_free = entropy_free;
8103 status = PSA_SUCCESS;
8104 }
8105
8106#if defined(MBEDTLS_THREADING_C)
8107 mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex);
8108#endif /* defined(MBEDTLS_THREADING_C) */
8109
8110 return status;
8111}
8112#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
8113
8114void mbedtls_psa_crypto_free(void)
8115{
8116
8117#if defined(MBEDTLS_THREADING_C)
8118 mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex);
8119#endif /* defined(MBEDTLS_THREADING_C) */
8120
8121 /* Nothing to do to free transaction. */
8122 if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED) {
8123 global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED;
8124 }
8125
8126 if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED) {
8127 psa_wipe_all_key_slots();
8128 global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED;
8129 }
8130
8131#if defined(MBEDTLS_THREADING_C)
8132 mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex);
8133#endif /* defined(MBEDTLS_THREADING_C) */
8134
8135#if defined(MBEDTLS_THREADING_C)
8136 mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex);
8137#endif /* defined(MBEDTLS_THREADING_C) */
8138
8139 if (global_data.rng_state != RNG_NOT_INITIALIZED) {
8140 mbedtls_psa_random_free(&global_data.rng);
8141 }
8142 global_data.rng_state = RNG_NOT_INITIALIZED;
8143 mbedtls_platform_zeroize(&global_data.rng, sizeof(global_data.rng));
8144
8145#if defined(MBEDTLS_THREADING_C)
8146 mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex);
8147#endif /* defined(MBEDTLS_THREADING_C) */
8148
8149#if defined(MBEDTLS_THREADING_C)
8150 mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex);
8151#endif /* defined(MBEDTLS_THREADING_C) */
8152
8153 /* Terminate drivers */
8154 if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED) {
8155 psa_driver_wrapper_free();
8156 global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED;
8157 }
8158
8159#if defined(MBEDTLS_THREADING_C)
8160 mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex);
8161#endif /* defined(MBEDTLS_THREADING_C) */
8162
8163}
8164
8165#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
8166/** Recover a transaction that was interrupted by a power failure.
8167 *
8168 * This function is called during initialization, before psa_crypto_init()
8169 * returns. If this function returns a failure status, the initialization
8170 * fails.
8171 */
8172static psa_status_t psa_crypto_recover_transaction(
8173 const psa_crypto_transaction_t *transaction)
8174{
8175 switch (transaction->unknown.type) {
8176 case PSA_CRYPTO_TRANSACTION_CREATE_KEY:
8177 case PSA_CRYPTO_TRANSACTION_DESTROY_KEY:
8178 /* TODO - fall through to the failure case until this
8179 * is implemented.
8180 * https://github.com/ARMmbed/mbed-crypto/issues/218
8181 */
8182 default:
8183 /* We found an unsupported transaction in the storage.
8184 * We don't know what state the storage is in. Give up. */
8185 return PSA_ERROR_DATA_INVALID;
8186 }
8187}
8188#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
8189
8190static psa_status_t mbedtls_psa_crypto_init_subsystem(mbedtls_psa_crypto_subsystem subsystem)
8191{
8192 psa_status_t status = PSA_SUCCESS;
8193 uint8_t driver_wrappers_initialized = 0;
8194
8195 switch (subsystem) {
8196 case PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS:
8197
8198#if defined(MBEDTLS_THREADING_C)
8199 PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex));
8200#endif /* defined(MBEDTLS_THREADING_C) */
8201
8202 if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED)) {
8203 /* Init drivers */
8204 status = psa_driver_wrapper_init();
8205
8206 /* Drivers need shutdown regardless of startup errors. */
8207 global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED;
8208
8209
8210 }
8211#if defined(MBEDTLS_THREADING_C)
8212 PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock(
8213 &mbedtls_threading_psa_globaldata_mutex));
8214#endif /* defined(MBEDTLS_THREADING_C) */
8215
8216 break;
8217
8218 case PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS:
8219
8220#if defined(MBEDTLS_THREADING_C)
8221 PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex));
8222#endif /* defined(MBEDTLS_THREADING_C) */
8223
8224 if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED)) {
8225 status = psa_initialize_key_slots();
8226
8227 /* Need to wipe keys even if initialization fails. */
8228 global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED;
8229
8230 }
8231#if defined(MBEDTLS_THREADING_C)
8232 PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock(
8233 &mbedtls_threading_psa_globaldata_mutex));
8234#endif /* defined(MBEDTLS_THREADING_C) */
8235
8236 break;
8237
8238 case PSA_CRYPTO_SUBSYSTEM_RNG:
8239
8240#if defined(MBEDTLS_THREADING_C)
8241 PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex));
8242#endif /* defined(MBEDTLS_THREADING_C) */
8243
8244 driver_wrappers_initialized =
8245 (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED);
8246
8247#if defined(MBEDTLS_THREADING_C)
8248 PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock(
8249 &mbedtls_threading_psa_globaldata_mutex));
8250#endif /* defined(MBEDTLS_THREADING_C) */
8251
8252 /* Need to use separate mutex here, as initialisation can require
8253 * testing of init flags, which requires locking the global data
8254 * mutex. */
8255#if defined(MBEDTLS_THREADING_C)
8256 PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex));
8257#endif /* defined(MBEDTLS_THREADING_C) */
8258
8259 /* Initialize and seed the random generator. */
8260 if (global_data.rng_state == RNG_NOT_INITIALIZED && driver_wrappers_initialized) {
8261 mbedtls_psa_random_init(&global_data.rng);
8262 global_data.rng_state = RNG_INITIALIZED;
8263
8264 status = mbedtls_psa_random_seed(&global_data.rng);
8265 if (status == PSA_SUCCESS) {
8266 global_data.rng_state = RNG_SEEDED;
8267 }
8268 }
8269
8270#if defined(MBEDTLS_THREADING_C)
8271 PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock(
8272 &mbedtls_threading_psa_rngdata_mutex));
8273#endif /* defined(MBEDTLS_THREADING_C) */
8274
8275 break;
8276
8277 case PSA_CRYPTO_SUBSYSTEM_TRANSACTION:
8278
8279#if defined(MBEDTLS_THREADING_C)
8280 PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex));
8281#endif /* defined(MBEDTLS_THREADING_C) */
8282
8283 if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED)) {
8284#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
8285 status = psa_crypto_load_transaction();
8286 if (status == PSA_SUCCESS) {
8287 status = psa_crypto_recover_transaction(&psa_crypto_transaction);
8288 if (status == PSA_SUCCESS) {
8289 global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED;
8290 }
8291 status = psa_crypto_stop_transaction();
8292 } else if (status == PSA_ERROR_DOES_NOT_EXIST) {
8293 /* There's no transaction to complete. It's all good. */
8294 global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED;
8295 status = PSA_SUCCESS;
8296 }
8297#else /* defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) */
8298 global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED;
8299 status = PSA_SUCCESS;
8300#endif /* defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) */
8301 }
8302
8303#if defined(MBEDTLS_THREADING_C)
8304 PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock(
8305 &mbedtls_threading_psa_globaldata_mutex));
8306#endif /* defined(MBEDTLS_THREADING_C) */
8307
8308 break;
8309
8310 default:
8311 status = PSA_ERROR_CORRUPTION_DETECTED;
8312 }
8313
8314 /* Exit label only required when using threading macros. */
8315#if defined(MBEDTLS_THREADING_C)
8316exit:
8317#endif /* defined(MBEDTLS_THREADING_C) */
8318
8319 return status;
8320}
8321
8322psa_status_t psa_crypto_init(void)
8323{
8324 psa_status_t status;
8325
8326 /* Double initialization is explicitly allowed. Early out if everything is
8327 * done. */
8328 if (psa_get_initialized()) {
8329 return PSA_SUCCESS;
8330 }
8331
8332 status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS);
8333 if (status != PSA_SUCCESS) {
8334 goto exit;
8335 }
8336
8337 status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS);
8338 if (status != PSA_SUCCESS) {
8339 goto exit;
8340 }
8341
8342 status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_RNG);
8343 if (status != PSA_SUCCESS) {
8344 goto exit;
8345 }
8346
8347 status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_TRANSACTION);
8348
8349exit:
8350
8351 if (status != PSA_SUCCESS) {
8352 mbedtls_psa_crypto_free();
8353 }
8354
8355 return status;
8356}
8357
8358#if defined(PSA_WANT_ALG_SOME_PAKE)
8359psa_status_t psa_crypto_driver_pake_get_password_len(
8360 const psa_crypto_driver_pake_inputs_t *inputs,
8361 size_t *password_len)
8362{
8363 if (inputs->password_len == 0) {
8364 return PSA_ERROR_BAD_STATE;
8365 }
8366
8367 *password_len = inputs->password_len;
8368
8369 return PSA_SUCCESS;
8370}
8371
8372psa_status_t psa_crypto_driver_pake_get_password(
8373 const psa_crypto_driver_pake_inputs_t *inputs,
8374 uint8_t *buffer, size_t buffer_size, size_t *buffer_length)
8375{
8376 if (inputs->password_len == 0) {
8377 return PSA_ERROR_BAD_STATE;
8378 }
8379
8380 if (buffer_size < inputs->password_len) {
8381 return PSA_ERROR_BUFFER_TOO_SMALL;
8382 }
8383
8384 memcpy(buffer, inputs->password, inputs->password_len);
8385 *buffer_length = inputs->password_len;
8386
8387 return PSA_SUCCESS;
8388}
8389
8390psa_status_t psa_crypto_driver_pake_get_user_len(
8391 const psa_crypto_driver_pake_inputs_t *inputs,
8392 size_t *user_len)
8393{
8394 if (inputs->user_len == 0) {
8395 return PSA_ERROR_BAD_STATE;
8396 }
8397
8398 *user_len = inputs->user_len;
8399
8400 return PSA_SUCCESS;
8401}
8402
8403psa_status_t psa_crypto_driver_pake_get_user(
8404 const psa_crypto_driver_pake_inputs_t *inputs,
8405 uint8_t *user_id, size_t user_id_size, size_t *user_id_len)
8406{
8407 if (inputs->user_len == 0) {
8408 return PSA_ERROR_BAD_STATE;
8409 }
8410
8411 if (user_id_size < inputs->user_len) {
8412 return PSA_ERROR_BUFFER_TOO_SMALL;
8413 }
8414
8415 memcpy(user_id, inputs->user, inputs->user_len);
8416 *user_id_len = inputs->user_len;
8417
8418 return PSA_SUCCESS;
8419}
8420
8421psa_status_t psa_crypto_driver_pake_get_peer_len(
8422 const psa_crypto_driver_pake_inputs_t *inputs,
8423 size_t *peer_len)
8424{
8425 if (inputs->peer_len == 0) {
8426 return PSA_ERROR_BAD_STATE;
8427 }
8428
8429 *peer_len = inputs->peer_len;
8430
8431 return PSA_SUCCESS;
8432}
8433
8434psa_status_t psa_crypto_driver_pake_get_peer(
8435 const psa_crypto_driver_pake_inputs_t *inputs,
8436 uint8_t *peer_id, size_t peer_id_size, size_t *peer_id_length)
8437{
8438 if (inputs->peer_len == 0) {
8439 return PSA_ERROR_BAD_STATE;
8440 }
8441
8442 if (peer_id_size < inputs->peer_len) {
8443 return PSA_ERROR_BUFFER_TOO_SMALL;
8444 }
8445
8446 memcpy(peer_id, inputs->peer, inputs->peer_len);
8447 *peer_id_length = inputs->peer_len;
8448
8449 return PSA_SUCCESS;
8450}
8451
8452psa_status_t psa_crypto_driver_pake_get_cipher_suite(
8453 const psa_crypto_driver_pake_inputs_t *inputs,
8454 psa_pake_cipher_suite_t *cipher_suite)
8455{
8456 if (inputs->cipher_suite.algorithm == PSA_ALG_NONE) {
8457 return PSA_ERROR_BAD_STATE;
8458 }
8459
8460 *cipher_suite = inputs->cipher_suite;
8461
8462 return PSA_SUCCESS;
8463}
8464
8465psa_status_t psa_pake_setup(
8466 psa_pake_operation_t *operation,
8467 const psa_pake_cipher_suite_t *cipher_suite)
8468{
8469 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
8470
8471 if (operation->stage != PSA_PAKE_OPERATION_STAGE_SETUP) {
8472 status = PSA_ERROR_BAD_STATE;
8473 goto exit;
8474 }
8475
8476 if (PSA_ALG_IS_PAKE(cipher_suite->algorithm) == 0 ||
8477 PSA_ALG_IS_HASH(cipher_suite->hash) == 0) {
8478 status = PSA_ERROR_INVALID_ARGUMENT;
8479 goto exit;
8480 }
8481
8482 memset(&operation->data.inputs, 0, sizeof(operation->data.inputs));
8483
8484 operation->alg = cipher_suite->algorithm;
8485 operation->primitive = PSA_PAKE_PRIMITIVE(cipher_suite->type,
8486 cipher_suite->family, cipher_suite->bits);
8487 operation->data.inputs.cipher_suite = *cipher_suite;
8488
8489#if defined(PSA_WANT_ALG_JPAKE)
8490 if (operation->alg == PSA_ALG_JPAKE) {
8491 psa_jpake_computation_stage_t *computation_stage =
8492 &operation->computation_stage.jpake;
8493
8494 memset(computation_stage, 0, sizeof(*computation_stage));
8495 computation_stage->step = PSA_PAKE_STEP_KEY_SHARE;
8496 } else
8497#endif /* PSA_WANT_ALG_JPAKE */
8498 {
8499 status = PSA_ERROR_NOT_SUPPORTED;
8500 goto exit;
8501 }
8502
8503 operation->stage = PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS;
8504
8505 return PSA_SUCCESS;
8506exit:
8507 psa_pake_abort(operation);
8508 return status;
8509}
8510
8511psa_status_t psa_pake_set_password_key(
8512 psa_pake_operation_t *operation,
8513 mbedtls_svc_key_id_t password)
8514{
8515 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
8516 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
8517 psa_key_slot_t *slot = NULL;
8518 psa_key_type_t type;
8519
8520 if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
8521 status = PSA_ERROR_BAD_STATE;
8522 goto exit;
8523 }
8524
8525 status = psa_get_and_lock_key_slot_with_policy(password, &slot,
8526 PSA_KEY_USAGE_DERIVE,
8527 operation->alg);
8528 if (status != PSA_SUCCESS) {
8529 goto exit;
8530 }
8531
8532 type = psa_get_key_type(&slot->attr);
8533
8534 if (type != PSA_KEY_TYPE_PASSWORD &&
8535 type != PSA_KEY_TYPE_PASSWORD_HASH) {
8536 status = PSA_ERROR_INVALID_ARGUMENT;
8537 goto exit;
8538 }
8539
8540 operation->data.inputs.password = mbedtls_calloc(1, slot->key.bytes);
8541 if (operation->data.inputs.password == NULL) {
8542 status = PSA_ERROR_INSUFFICIENT_MEMORY;
8543 goto exit;
8544 }
8545
8546 memcpy(operation->data.inputs.password, slot->key.data, slot->key.bytes);
8547 operation->data.inputs.password_len = slot->key.bytes;
8548 operation->data.inputs.attributes = slot->attr;
8549
8550exit:
8551 if (status != PSA_SUCCESS) {
8552 psa_pake_abort(operation);
8553 }
8554 unlock_status = psa_unregister_read_under_mutex(slot);
8555 return (status == PSA_SUCCESS) ? unlock_status : status;
8556}
8557
8558psa_status_t psa_pake_set_user(
8559 psa_pake_operation_t *operation,
8560 const uint8_t *user_id_external,
8561 size_t user_id_len)
8562{
8563 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
8564 LOCAL_INPUT_DECLARE(user_id_external, user_id);
8565
8566 if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
8567 status = PSA_ERROR_BAD_STATE;
8568 goto exit;
8569 }
8570
8571 if (user_id_len == 0) {
8572 status = PSA_ERROR_INVALID_ARGUMENT;
8573 goto exit;
8574 }
8575
8576 if (operation->data.inputs.user_len != 0) {
8577 status = PSA_ERROR_BAD_STATE;
8578 goto exit;
8579 }
8580
8581 operation->data.inputs.user = mbedtls_calloc(1, user_id_len);
8582 if (operation->data.inputs.user == NULL) {
8583 status = PSA_ERROR_INSUFFICIENT_MEMORY;
8584 goto exit;
8585 }
8586
8587 LOCAL_INPUT_ALLOC(user_id_external, user_id_len, user_id);
8588
8589 memcpy(operation->data.inputs.user, user_id, user_id_len);
8590 operation->data.inputs.user_len = user_id_len;
8591
8592 status = PSA_SUCCESS;
8593
8594exit:
8595 LOCAL_INPUT_FREE(user_id_external, user_id);
8596 if (status != PSA_SUCCESS) {
8597 psa_pake_abort(operation);
8598 }
8599 return status;
8600}
8601
8602psa_status_t psa_pake_set_peer(
8603 psa_pake_operation_t *operation,
8604 const uint8_t *peer_id_external,
8605 size_t peer_id_len)
8606{
8607 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
8608 LOCAL_INPUT_DECLARE(peer_id_external, peer_id);
8609
8610 if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
8611 status = PSA_ERROR_BAD_STATE;
8612 goto exit;
8613 }
8614
8615 if (peer_id_len == 0) {
8616 status = PSA_ERROR_INVALID_ARGUMENT;
8617 goto exit;
8618 }
8619
8620 if (operation->data.inputs.peer_len != 0) {
8621 status = PSA_ERROR_BAD_STATE;
8622 goto exit;
8623 }
8624
8625 operation->data.inputs.peer = mbedtls_calloc(1, peer_id_len);
8626 if (operation->data.inputs.peer == NULL) {
8627 status = PSA_ERROR_INSUFFICIENT_MEMORY;
8628 goto exit;
8629 }
8630
8631 LOCAL_INPUT_ALLOC(peer_id_external, peer_id_len, peer_id);
8632
8633 memcpy(operation->data.inputs.peer, peer_id, peer_id_len);
8634 operation->data.inputs.peer_len = peer_id_len;
8635
8636 status = PSA_SUCCESS;
8637
8638exit:
8639 LOCAL_INPUT_FREE(peer_id_external, peer_id);
8640 if (status != PSA_SUCCESS) {
8641 psa_pake_abort(operation);
8642 }
8643 return status;
8644}
8645
8646psa_status_t psa_pake_set_role(
8647 psa_pake_operation_t *operation,
8648 psa_pake_role_t role)
8649{
8650 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
8651
8652 if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
8653 status = PSA_ERROR_BAD_STATE;
8654 goto exit;
8655 }
8656
8657 switch (operation->alg) {
8658#if defined(PSA_WANT_ALG_JPAKE)
8659 case PSA_ALG_JPAKE:
8660 if (role == PSA_PAKE_ROLE_NONE) {
8661 return PSA_SUCCESS;
8662 }
8663 status = PSA_ERROR_INVALID_ARGUMENT;
8664 break;
8665#endif
8666 default:
8667 (void) role;
8668 status = PSA_ERROR_NOT_SUPPORTED;
8669 goto exit;
8670 }
8671exit:
8672 psa_pake_abort(operation);
8673 return status;
8674}
8675
8676/* Auxiliary function to convert core computation stage to single driver step. */
8677#if defined(PSA_WANT_ALG_JPAKE)
8678static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_step(
8679 psa_jpake_computation_stage_t *stage)
8680{
8681 psa_crypto_driver_pake_step_t key_share_step;
8682 if (stage->round == PSA_JPAKE_FIRST) {
8683 int is_x1;
8684
8685 if (stage->io_mode == PSA_JPAKE_OUTPUT) {
8686 is_x1 = (stage->outputs < 1);
8687 } else {
8688 is_x1 = (stage->inputs < 1);
8689 }
8690
8691 key_share_step = is_x1 ?
8692 PSA_JPAKE_X1_STEP_KEY_SHARE :
8693 PSA_JPAKE_X2_STEP_KEY_SHARE;
8694 } else if (stage->round == PSA_JPAKE_SECOND) {
8695 key_share_step = (stage->io_mode == PSA_JPAKE_OUTPUT) ?
8696 PSA_JPAKE_X2S_STEP_KEY_SHARE :
8697 PSA_JPAKE_X4S_STEP_KEY_SHARE;
8698 } else {
8699 return PSA_JPAKE_STEP_INVALID;
8700 }
8701 return (psa_crypto_driver_pake_step_t) (key_share_step + stage->step - PSA_PAKE_STEP_KEY_SHARE);
8702}
8703#endif /* PSA_WANT_ALG_JPAKE */
8704
8705static psa_status_t psa_pake_complete_inputs(
8706 psa_pake_operation_t *operation)
8707{
8708 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
8709 /* Create copy of the inputs on stack as inputs share memory
8710 with the driver context which will be setup by the driver. */
8711 psa_crypto_driver_pake_inputs_t inputs = operation->data.inputs;
8712
8713 if (inputs.password_len == 0) {
8714 return PSA_ERROR_BAD_STATE;
8715 }
8716
8717 if (operation->alg == PSA_ALG_JPAKE) {
8718 if (inputs.user_len == 0 || inputs.peer_len == 0) {
8719 return PSA_ERROR_BAD_STATE;
8720 }
8721 }
8722
8723 /* Clear driver context */
8724 mbedtls_platform_zeroize(&operation->data, sizeof(operation->data));
8725
8726 status = psa_driver_wrapper_pake_setup(operation, &inputs);
8727
8728 /* Driver is responsible for creating its own copy of the password. */
8729 mbedtls_zeroize_and_free(inputs.password, inputs.password_len);
8730
8731 /* User and peer are translated to role. */
8732 mbedtls_free(inputs.user);
8733 mbedtls_free(inputs.peer);
8734
8735 if (status == PSA_SUCCESS) {
8736#if defined(PSA_WANT_ALG_JPAKE)
8737 if (operation->alg == PSA_ALG_JPAKE) {
8738 operation->stage = PSA_PAKE_OPERATION_STAGE_COMPUTATION;
8739 } else
8740#endif /* PSA_WANT_ALG_JPAKE */
8741 {
8742 status = PSA_ERROR_NOT_SUPPORTED;
8743 }
8744 }
8745 return status;
8746}
8747
8748#if defined(PSA_WANT_ALG_JPAKE)
8749static psa_status_t psa_jpake_prologue(
8750 psa_pake_operation_t *operation,
8751 psa_pake_step_t step,
8752 psa_jpake_io_mode_t io_mode)
8753{
8754 if (step != PSA_PAKE_STEP_KEY_SHARE &&
8755 step != PSA_PAKE_STEP_ZK_PUBLIC &&
8756 step != PSA_PAKE_STEP_ZK_PROOF) {
8757 return PSA_ERROR_INVALID_ARGUMENT;
8758 }
8759
8760 psa_jpake_computation_stage_t *computation_stage =
8761 &operation->computation_stage.jpake;
8762
8763 if (computation_stage->round != PSA_JPAKE_FIRST &&
8764 computation_stage->round != PSA_JPAKE_SECOND) {
8765 return PSA_ERROR_BAD_STATE;
8766 }
8767
8768 /* Check that the step we are given is the one we were expecting */
8769 if (step != computation_stage->step) {
8770 return PSA_ERROR_BAD_STATE;
8771 }
8772
8773 if (step == PSA_PAKE_STEP_KEY_SHARE &&
8774 computation_stage->inputs == 0 &&
8775 computation_stage->outputs == 0) {
8776 /* Start of the round, so function decides whether we are inputting
8777 * or outputting */
8778 computation_stage->io_mode = io_mode;
8779 } else if (computation_stage->io_mode != io_mode) {
8780 /* Middle of the round so the mode we are in must match the function
8781 * called by the user */
8782 return PSA_ERROR_BAD_STATE;
8783 }
8784
8785 return PSA_SUCCESS;
8786}
8787
8788static psa_status_t psa_jpake_epilogue(
8789 psa_pake_operation_t *operation,
8790 psa_jpake_io_mode_t io_mode)
8791{
8792 psa_jpake_computation_stage_t *stage =
8793 &operation->computation_stage.jpake;
8794
8795 if (stage->step == PSA_PAKE_STEP_ZK_PROOF) {
8796 /* End of an input/output */
8797 if (io_mode == PSA_JPAKE_INPUT) {
8798 stage->inputs++;
8799 if (stage->inputs == PSA_JPAKE_EXPECTED_INPUTS(stage->round)) {
8800 stage->io_mode = PSA_JPAKE_OUTPUT;
8801 }
8802 }
8803 if (io_mode == PSA_JPAKE_OUTPUT) {
8804 stage->outputs++;
8805 if (stage->outputs == PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) {
8806 stage->io_mode = PSA_JPAKE_INPUT;
8807 }
8808 }
8809 if (stage->inputs == PSA_JPAKE_EXPECTED_INPUTS(stage->round) &&
8810 stage->outputs == PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) {
8811 /* End of a round, move to the next round */
8812 stage->inputs = 0;
8813 stage->outputs = 0;
8814 stage->round++;
8815 }
8816 stage->step = PSA_PAKE_STEP_KEY_SHARE;
8817 } else {
8818 stage->step++;
8819 }
8820 return PSA_SUCCESS;
8821}
8822
8823#endif /* PSA_WANT_ALG_JPAKE */
8824
8825psa_status_t psa_pake_output(
8826 psa_pake_operation_t *operation,
8827 psa_pake_step_t step,
8828 uint8_t *output_external,
8829 size_t output_size,
8830 size_t *output_length)
8831{
8832 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
8833 psa_crypto_driver_pake_step_t driver_step = PSA_JPAKE_STEP_INVALID;
8834 LOCAL_OUTPUT_DECLARE(output_external, output);
8835 *output_length = 0;
8836
8837 if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
8838 status = psa_pake_complete_inputs(operation);
8839 if (status != PSA_SUCCESS) {
8840 goto exit;
8841 }
8842 }
8843
8844 if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) {
8845 status = PSA_ERROR_BAD_STATE;
8846 goto exit;
8847 }
8848
8849 if (output_size == 0) {
8850 status = PSA_ERROR_INVALID_ARGUMENT;
8851 goto exit;
8852 }
8853
8854 switch (operation->alg) {
8855#if defined(PSA_WANT_ALG_JPAKE)
8856 case PSA_ALG_JPAKE:
8857 status = psa_jpake_prologue(operation, step, PSA_JPAKE_OUTPUT);
8858 if (status != PSA_SUCCESS) {
8859 goto exit;
8860 }
8861 driver_step = convert_jpake_computation_stage_to_driver_step(
8862 &operation->computation_stage.jpake);
8863 break;
8864#endif /* PSA_WANT_ALG_JPAKE */
8865 default:
8866 (void) step;
8867 status = PSA_ERROR_NOT_SUPPORTED;
8868 goto exit;
8869 }
8870
8871 LOCAL_OUTPUT_ALLOC(output_external, output_size, output);
8872
8873 status = psa_driver_wrapper_pake_output(operation, driver_step,
8874 output, output_size, output_length);
8875
8876 if (status != PSA_SUCCESS) {
8877 goto exit;
8878 }
8879
8880 switch (operation->alg) {
8881#if defined(PSA_WANT_ALG_JPAKE)
8882 case PSA_ALG_JPAKE:
8883 status = psa_jpake_epilogue(operation, PSA_JPAKE_OUTPUT);
8884 if (status != PSA_SUCCESS) {
8885 goto exit;
8886 }
8887 break;
8888#endif /* PSA_WANT_ALG_JPAKE */
8889 default:
8890 status = PSA_ERROR_NOT_SUPPORTED;
8891 goto exit;
8892 }
8893
8894exit:
8895 LOCAL_OUTPUT_FREE(output_external, output);
8896 if (status != PSA_SUCCESS) {
8897 psa_pake_abort(operation);
8898 }
8899 return status;
8900}
8901
8902psa_status_t psa_pake_input(
8903 psa_pake_operation_t *operation,
8904 psa_pake_step_t step,
8905 const uint8_t *input_external,
8906 size_t input_length)
8907{
8908 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
8909 psa_crypto_driver_pake_step_t driver_step = PSA_JPAKE_STEP_INVALID;
8910 const size_t max_input_length = (size_t) PSA_PAKE_INPUT_SIZE(operation->alg,
8911 operation->primitive,
8912 step);
8913 LOCAL_INPUT_DECLARE(input_external, input);
8914
8915 if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
8916 status = psa_pake_complete_inputs(operation);
8917 if (status != PSA_SUCCESS) {
8918 goto exit;
8919 }
8920 }
8921
8922 if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) {
8923 status = PSA_ERROR_BAD_STATE;
8924 goto exit;
8925 }
8926
8927 if (input_length == 0 || input_length > max_input_length) {
8928 status = PSA_ERROR_INVALID_ARGUMENT;
8929 goto exit;
8930 }
8931
8932 switch (operation->alg) {
8933#if defined(PSA_WANT_ALG_JPAKE)
8934 case PSA_ALG_JPAKE:
8935 status = psa_jpake_prologue(operation, step, PSA_JPAKE_INPUT);
8936 if (status != PSA_SUCCESS) {
8937 goto exit;
8938 }
8939 driver_step = convert_jpake_computation_stage_to_driver_step(
8940 &operation->computation_stage.jpake);
8941 break;
8942#endif /* PSA_WANT_ALG_JPAKE */
8943 default:
8944 (void) step;
8945 status = PSA_ERROR_NOT_SUPPORTED;
8946 goto exit;
8947 }
8948
8949 LOCAL_INPUT_ALLOC(input_external, input_length, input);
8950 status = psa_driver_wrapper_pake_input(operation, driver_step,
8951 input, input_length);
8952
8953 if (status != PSA_SUCCESS) {
8954 goto exit;
8955 }
8956
8957 switch (operation->alg) {
8958#if defined(PSA_WANT_ALG_JPAKE)
8959 case PSA_ALG_JPAKE:
8960 status = psa_jpake_epilogue(operation, PSA_JPAKE_INPUT);
8961 if (status != PSA_SUCCESS) {
8962 goto exit;
8963 }
8964 break;
8965#endif /* PSA_WANT_ALG_JPAKE */
8966 default:
8967 status = PSA_ERROR_NOT_SUPPORTED;
8968 goto exit;
8969 }
8970
8971exit:
8972 LOCAL_INPUT_FREE(input_external, input);
8973 if (status != PSA_SUCCESS) {
8974 psa_pake_abort(operation);
8975 }
8976 return status;
8977}
8978
8979psa_status_t psa_pake_get_implicit_key(
8980 psa_pake_operation_t *operation,
8981 psa_key_derivation_operation_t *output)
8982{
8983 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
8984 psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
8985 uint8_t shared_key[MBEDTLS_PSA_JPAKE_BUFFER_SIZE];
8986 size_t shared_key_len = 0;
8987
8988 if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) {
8989 status = PSA_ERROR_BAD_STATE;
8990 goto exit;
8991 }
8992
8993#if defined(PSA_WANT_ALG_JPAKE)
8994 if (operation->alg == PSA_ALG_JPAKE) {
8995 psa_jpake_computation_stage_t *computation_stage =
8996 &operation->computation_stage.jpake;
8997 if (computation_stage->round != PSA_JPAKE_FINISHED) {
8998 status = PSA_ERROR_BAD_STATE;
8999 goto exit;
9000 }
9001 } else
9002#endif /* PSA_WANT_ALG_JPAKE */
9003 {
9004 status = PSA_ERROR_NOT_SUPPORTED;
9005 goto exit;
9006 }
9007
9008 status = psa_driver_wrapper_pake_get_implicit_key(operation,
9009 shared_key,
9010 sizeof(shared_key),
9011 &shared_key_len);
9012
9013 if (status != PSA_SUCCESS) {
9014 goto exit;
9015 }
9016
9017 status = psa_key_derivation_input_bytes(output,
9018 PSA_KEY_DERIVATION_INPUT_SECRET,
9019 shared_key,
9020 shared_key_len);
9021
9022 mbedtls_platform_zeroize(shared_key, sizeof(shared_key));
9023exit:
9024 abort_status = psa_pake_abort(operation);
9025 return status == PSA_SUCCESS ? abort_status : status;
9026}
9027
9028psa_status_t psa_pake_abort(
9029 psa_pake_operation_t *operation)
9030{
9031 psa_status_t status = PSA_SUCCESS;
9032
9033 if (operation->stage == PSA_PAKE_OPERATION_STAGE_COMPUTATION) {
9034 status = psa_driver_wrapper_pake_abort(operation);
9035 }
9036
9037 if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
9038 if (operation->data.inputs.password != NULL) {
9039 mbedtls_zeroize_and_free(operation->data.inputs.password,
9040 operation->data.inputs.password_len);
9041 }
9042 if (operation->data.inputs.user != NULL) {
9043 mbedtls_free(operation->data.inputs.user);
9044 }
9045 if (operation->data.inputs.peer != NULL) {
9046 mbedtls_free(operation->data.inputs.peer);
9047 }
9048 }
9049 memset(operation, 0, sizeof(psa_pake_operation_t));
9050
9051 return status;
9052}
9053#endif /* PSA_WANT_ALG_SOME_PAKE */
9054
9055/* Memory copying test hooks. These are called before input copy, after input
9056 * copy, before output copy and after output copy, respectively.
9057 * They are used by memory-poisoning tests to temporarily unpoison buffers
9058 * while they are copied. */
9059#if defined(MBEDTLS_TEST_HOOKS)
9060void (*psa_input_pre_copy_hook)(const uint8_t *input, size_t input_len) = NULL;
9061void (*psa_input_post_copy_hook)(const uint8_t *input, size_t input_len) = NULL;
9062void (*psa_output_pre_copy_hook)(const uint8_t *output, size_t output_len) = NULL;
9063void (*psa_output_post_copy_hook)(const uint8_t *output, size_t output_len) = NULL;
9064#endif
9065
9066/** Copy from an input buffer to a local copy.
9067 *
9068 * \param[in] input Pointer to input buffer.
9069 * \param[in] input_len Length of the input buffer.
9070 * \param[out] input_copy Pointer to a local copy in which to store the input data.
9071 * \param[out] input_copy_len Length of the local copy buffer.
9072 * \return #PSA_SUCCESS, if the buffer was successfully
9073 * copied.
9074 * \return #PSA_ERROR_CORRUPTION_DETECTED, if the local
9075 * copy is too small to hold contents of the
9076 * input buffer.
9077 */
9078MBEDTLS_STATIC_TESTABLE
9079psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len,
9080 uint8_t *input_copy, size_t input_copy_len)
9081{
9082 if (input_len > input_copy_len) {
9083 return PSA_ERROR_CORRUPTION_DETECTED;
9084 }
9085
9086#if defined(MBEDTLS_TEST_HOOKS)
9087 if (psa_input_pre_copy_hook != NULL) {
9088 psa_input_pre_copy_hook(input, input_len);
9089 }
9090#endif
9091
9092 if (input_len > 0) {
9093 memcpy(input_copy, input, input_len);
9094 }
9095
9096#if defined(MBEDTLS_TEST_HOOKS)
9097 if (psa_input_post_copy_hook != NULL) {
9098 psa_input_post_copy_hook(input, input_len);
9099 }
9100#endif
9101
9102 return PSA_SUCCESS;
9103}
9104
9105/** Copy from a local output buffer into a user-supplied one.
9106 *
9107 * \param[in] output_copy Pointer to a local buffer containing the output.
9108 * \param[in] output_copy_len Length of the local buffer.
9109 * \param[out] output Pointer to user-supplied output buffer.
9110 * \param[out] output_len Length of the user-supplied output buffer.
9111 * \return #PSA_SUCCESS, if the buffer was successfully
9112 * copied.
9113 * \return #PSA_ERROR_BUFFER_TOO_SMALL, if the
9114 * user-supplied output buffer is too small to
9115 * hold the contents of the local buffer.
9116 */
9117MBEDTLS_STATIC_TESTABLE
9118psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len,
9119 uint8_t *output, size_t output_len)
9120{
9121 if (output_len < output_copy_len) {
9122 return PSA_ERROR_BUFFER_TOO_SMALL;
9123 }
9124
9125#if defined(MBEDTLS_TEST_HOOKS)
9126 if (psa_output_pre_copy_hook != NULL) {
9127 psa_output_pre_copy_hook(output, output_len);
9128 }
9129#endif
9130
9131 if (output_copy_len > 0) {
9132 memcpy(output, output_copy, output_copy_len);
9133 }
9134
9135#if defined(MBEDTLS_TEST_HOOKS)
9136 if (psa_output_post_copy_hook != NULL) {
9137 psa_output_post_copy_hook(output, output_len);
9138 }
9139#endif
9140
9141 return PSA_SUCCESS;
9142}
9143
9144psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len,
9145 psa_crypto_local_input_t *local_input)
9146{
9147 psa_status_t status;
9148
9149 *local_input = PSA_CRYPTO_LOCAL_INPUT_INIT;
9150
9151 if (input_len == 0) {
9152 return PSA_SUCCESS;
9153 }
9154
9155 local_input->buffer = mbedtls_calloc(input_len, 1);
9156 if (local_input->buffer == NULL) {
9157 /* Since we dealt with the zero-length case above, we know that
9158 * a NULL return value means a failure of allocation. */
9159 return PSA_ERROR_INSUFFICIENT_MEMORY;
9160 }
9161 /* From now on, we must free local_input->buffer on error. */
9162
9163 local_input->length = input_len;
9164
9165 status = psa_crypto_copy_input(input, input_len,
9166 local_input->buffer, local_input->length);
9167 if (status != PSA_SUCCESS) {
9168 goto error;
9169 }
9170
9171 return PSA_SUCCESS;
9172
9173error:
9174 mbedtls_free(local_input->buffer);
9175 local_input->buffer = NULL;
9176 local_input->length = 0;
9177 return status;
9178}
9179
9180void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input)
9181{
9182 mbedtls_free(local_input->buffer);
9183 local_input->buffer = NULL;
9184 local_input->length = 0;
9185}
9186
9187psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len,
9188 psa_crypto_local_output_t *local_output)
9189{
9190 *local_output = PSA_CRYPTO_LOCAL_OUTPUT_INIT;
9191
9192 if (output_len == 0) {
9193 return PSA_SUCCESS;
9194 }
9195 local_output->buffer = mbedtls_calloc(output_len, 1);
9196 if (local_output->buffer == NULL) {
9197 /* Since we dealt with the zero-length case above, we know that
9198 * a NULL return value means a failure of allocation. */
9199 return PSA_ERROR_INSUFFICIENT_MEMORY;
9200 }
9201 local_output->length = output_len;
9202 local_output->original = output;
9203
9204 return PSA_SUCCESS;
9205}
9206
9207psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_output)
9208{
9209 psa_status_t status;
9210
9211 if (local_output->buffer == NULL) {
9212 local_output->length = 0;
9213 return PSA_SUCCESS;
9214 }
9215 if (local_output->original == NULL) {
9216 /* We have an internal copy but nothing to copy back to. */
9217 return PSA_ERROR_CORRUPTION_DETECTED;
9218 }
9219
9220 status = psa_crypto_copy_output(local_output->buffer, local_output->length,
9221 local_output->original, local_output->length);
9222 if (status != PSA_SUCCESS) {
9223 return status;
9224 }
9225
9226 mbedtls_free(local_output->buffer);
9227 local_output->buffer = NULL;
9228 local_output->length = 0;
9229
9230 return PSA_SUCCESS;
9231}
9232
9233#endif /* MBEDTLS_PSA_CRYPTO_C */