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