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