Branch data Line data Source code
1 : : /*
2 : : * PSA crypto layer on top of Mbed TLS crypto
3 : : */
4 : : /*
5 : : * Copyright The Mbed TLS Contributors
6 : : * SPDX-License-Identifier: Apache-2.0
7 : : *
8 : : * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 : : * not use this file except in compliance with the License.
10 : : * You may obtain a copy of the License at
11 : : *
12 : : * http://www.apache.org/licenses/LICENSE-2.0
13 : : *
14 : : * Unless required by applicable law or agreed to in writing, software
15 : : * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 : : * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 : : * See the License for the specific language governing permissions and
18 : : * limitations under the License.
19 : : */
20 : :
21 : : #include "common.h"
22 : :
23 : : #if defined(MBEDTLS_PSA_CRYPTO_C)
24 : :
25 : : #if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
26 : : #include "check_crypto_config.h"
27 : : #endif
28 : :
29 : : #include "psa/crypto.h"
30 : :
31 : : #include "psa_crypto_cipher.h"
32 : : #include "psa_crypto_core.h"
33 : : #include "psa_crypto_invasive.h"
34 : : #include "psa_crypto_driver_wrappers.h"
35 : : #include "psa_crypto_ecp.h"
36 : : #include "psa_crypto_hash.h"
37 : : #include "psa_crypto_mac.h"
38 : : #include "psa_crypto_rsa.h"
39 : : #include "psa_crypto_ecp.h"
40 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
41 : : #include "psa_crypto_se.h"
42 : : #endif
43 : : #include "psa_crypto_slot_management.h"
44 : : /* Include internal declarations that are useful for implementing persistently
45 : : * stored keys. */
46 : : #include "psa_crypto_storage.h"
47 : :
48 : : #include "psa_crypto_random_impl.h"
49 : :
50 : : #include <assert.h>
51 : : #include <stdlib.h>
52 : : #include <string.h>
53 : : #include "mbedtls/platform.h"
54 : : #if !defined(MBEDTLS_PLATFORM_C)
55 : : #define mbedtls_calloc calloc
56 : : #define mbedtls_free free
57 : : #endif
58 : :
59 : : #include "mbedtls/aes.h"
60 : : #include "mbedtls/asn1.h"
61 : : #include "mbedtls/asn1write.h"
62 : : #include "mbedtls/bignum.h"
63 : : #include "mbedtls/camellia.h"
64 : : #include "mbedtls/chacha20.h"
65 : : #include "mbedtls/chachapoly.h"
66 : : #include "mbedtls/cipher.h"
67 : : #include "mbedtls/ccm.h"
68 : : #include "mbedtls/cmac.h"
69 : : #include "mbedtls/des.h"
70 : : #include "mbedtls/ecdh.h"
71 : : #include "mbedtls/ecp.h"
72 : : #include "mbedtls/entropy.h"
73 : : #include "mbedtls/error.h"
74 : : #include "mbedtls/gcm.h"
75 : : #include "mbedtls/md5.h"
76 : : #include "mbedtls/md.h"
77 : : #include "md_wrap.h"
78 : : #include "mbedtls/pk.h"
79 : : #include "pk_wrap.h"
80 : : #include "mbedtls/platform_util.h"
81 : : #include "mbedtls/error.h"
82 : : #include "mbedtls/ripemd160.h"
83 : : #include "mbedtls/rsa.h"
84 : : #include "mbedtls/sha1.h"
85 : : #include "mbedtls/sha256.h"
86 : : #include "mbedtls/sha512.h"
87 : :
88 : : #define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
89 : :
90 : : /****************************************************************/
91 : : /* Global data, support functions and library management */
92 : : /****************************************************************/
93 : :
94 : 172 : static int key_type_is_raw_bytes( psa_key_type_t type )
95 : : {
96 : 172 : return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
97 : : }
98 : :
99 : : /* Values for psa_global_data_t::rng_state */
100 : : #define RNG_NOT_INITIALIZED 0
101 : : #define RNG_INITIALIZED 1
102 : : #define RNG_SEEDED 2
103 : :
104 : : typedef struct
105 : : {
106 : : unsigned initialized : 1;
107 : : unsigned rng_state : 2;
108 : : mbedtls_psa_random_context_t rng;
109 : : } psa_global_data_t;
110 : :
111 : : static psa_global_data_t global_data;
112 : :
113 : : #if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
114 : : mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state =
115 : : &global_data.rng.drbg;
116 : : #endif
117 : :
118 : : #define GUARD_MODULE_INITIALIZED \
119 : : if( global_data.initialized == 0 ) \
120 : : return( PSA_ERROR_BAD_STATE );
121 : :
122 : 1519 : psa_status_t mbedtls_to_psa_error( int ret )
123 : : {
124 : : /* Mbed TLS error codes can combine a high-level error code and a
125 : : * low-level error code. The low-level error usually reflects the
126 : : * root cause better, so dispatch on that preferably. */
127 : 1519 : int low_level_ret = - ( -ret & 0x007f );
128 [ + - - - : 3038 : switch( low_level_ret != 0 ? low_level_ret : ret )
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + ]
129 : : {
130 : : case 0:
131 : : return( PSA_SUCCESS );
132 : :
133 : 0 : case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
134 : : case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
135 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
136 : 0 : case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
137 : : case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
138 : : case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
139 : : case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
140 : : case MBEDTLS_ERR_ASN1_INVALID_DATA:
141 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
142 : 0 : case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
143 : 0 : return( PSA_ERROR_INSUFFICIENT_MEMORY );
144 : 0 : case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
145 : 0 : return( PSA_ERROR_BUFFER_TOO_SMALL );
146 : :
147 : : #if defined(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
148 : 0 : case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA:
149 : : #endif
150 : : case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
151 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
152 : :
153 : 0 : case MBEDTLS_ERR_CCM_BAD_INPUT:
154 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
155 : 0 : case MBEDTLS_ERR_CCM_AUTH_FAILED:
156 : 0 : return( PSA_ERROR_INVALID_SIGNATURE );
157 : :
158 : 0 : case MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA:
159 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
160 : :
161 : 0 : case MBEDTLS_ERR_CHACHAPOLY_BAD_STATE:
162 : 0 : return( PSA_ERROR_BAD_STATE );
163 : 0 : case MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED:
164 : 0 : return( PSA_ERROR_INVALID_SIGNATURE );
165 : :
166 : 0 : case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
167 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
168 : 0 : case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
169 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
170 : 0 : case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
171 : 0 : return( PSA_ERROR_INSUFFICIENT_MEMORY );
172 : 0 : case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
173 : 0 : return( PSA_ERROR_INVALID_PADDING );
174 : 0 : case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
175 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
176 : 0 : case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
177 : 0 : return( PSA_ERROR_INVALID_SIGNATURE );
178 : 0 : case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
179 : 0 : return( PSA_ERROR_CORRUPTION_DETECTED );
180 : :
181 : : #if !( defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) || \
182 : : defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE) )
183 : : /* Only check CTR_DRBG error codes if underlying mbedtls_xxx
184 : : * functions are passed a CTR_DRBG instance. */
185 : : case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
186 : : return( PSA_ERROR_INSUFFICIENT_ENTROPY );
187 : : case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
188 : : case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
189 : : return( PSA_ERROR_NOT_SUPPORTED );
190 : : case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
191 : : return( PSA_ERROR_INSUFFICIENT_ENTROPY );
192 : : #endif
193 : :
194 : 0 : case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
195 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
196 : :
197 : 0 : case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
198 : : case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
199 : : case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
200 : 0 : return( PSA_ERROR_INSUFFICIENT_ENTROPY );
201 : :
202 : 0 : case MBEDTLS_ERR_GCM_AUTH_FAILED:
203 : 0 : return( PSA_ERROR_INVALID_SIGNATURE );
204 : 0 : case MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL:
205 : 0 : return( PSA_ERROR_BUFFER_TOO_SMALL );
206 : 0 : case MBEDTLS_ERR_GCM_BAD_INPUT:
207 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
208 : :
209 : : #if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \
210 : : defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
211 : : /* Only check HMAC_DRBG error codes if underlying mbedtls_xxx
212 : : * functions are passed a HMAC_DRBG instance. */
213 : 0 : case MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED:
214 : 0 : return( PSA_ERROR_INSUFFICIENT_ENTROPY );
215 : 0 : case MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG:
216 : : case MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG:
217 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
218 : 0 : case MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR:
219 : 0 : return( PSA_ERROR_INSUFFICIENT_ENTROPY );
220 : : #endif
221 : :
222 : 0 : case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
223 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
224 : 0 : case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
225 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
226 : 0 : case MBEDTLS_ERR_MD_ALLOC_FAILED:
227 : 0 : return( PSA_ERROR_INSUFFICIENT_MEMORY );
228 : 0 : case MBEDTLS_ERR_MD_FILE_IO_ERROR:
229 : 0 : return( PSA_ERROR_STORAGE_FAILURE );
230 : :
231 : 0 : case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
232 : 0 : return( PSA_ERROR_STORAGE_FAILURE );
233 : 0 : case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
234 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
235 : 0 : case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
236 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
237 : 0 : case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
238 : 0 : return( PSA_ERROR_BUFFER_TOO_SMALL );
239 : 0 : case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
240 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
241 : 0 : case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
242 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
243 : 0 : case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
244 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
245 : 0 : case MBEDTLS_ERR_MPI_ALLOC_FAILED:
246 : 0 : return( PSA_ERROR_INSUFFICIENT_MEMORY );
247 : :
248 : 0 : case MBEDTLS_ERR_PK_ALLOC_FAILED:
249 : 0 : return( PSA_ERROR_INSUFFICIENT_MEMORY );
250 : 0 : case MBEDTLS_ERR_PK_TYPE_MISMATCH:
251 : : case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
252 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
253 : 0 : case MBEDTLS_ERR_PK_FILE_IO_ERROR:
254 : 0 : return( PSA_ERROR_STORAGE_FAILURE );
255 : 0 : case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
256 : : case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
257 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
258 : 0 : case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
259 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
260 : 0 : case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
261 : : case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
262 : 0 : return( PSA_ERROR_NOT_PERMITTED );
263 : 0 : case MBEDTLS_ERR_PK_INVALID_PUBKEY:
264 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
265 : 0 : case MBEDTLS_ERR_PK_INVALID_ALG:
266 : : case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
267 : : case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
268 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
269 : 0 : case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
270 : 0 : return( PSA_ERROR_INVALID_SIGNATURE );
271 : 0 : case MBEDTLS_ERR_PK_BUFFER_TOO_SMALL:
272 : 0 : return( PSA_ERROR_BUFFER_TOO_SMALL );
273 : :
274 : 0 : case MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED:
275 : 0 : return( PSA_ERROR_HARDWARE_FAILURE );
276 : 0 : case MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
277 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
278 : :
279 : 0 : case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
280 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
281 : 0 : case MBEDTLS_ERR_RSA_INVALID_PADDING:
282 : 0 : return( PSA_ERROR_INVALID_PADDING );
283 : 0 : case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
284 : 0 : return( PSA_ERROR_HARDWARE_FAILURE );
285 : 0 : case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
286 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
287 : 0 : case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
288 : : case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
289 : 0 : return( PSA_ERROR_CORRUPTION_DETECTED );
290 : 0 : case MBEDTLS_ERR_RSA_VERIFY_FAILED:
291 : 0 : return( PSA_ERROR_INVALID_SIGNATURE );
292 : 0 : case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
293 : 0 : return( PSA_ERROR_BUFFER_TOO_SMALL );
294 : 0 : case MBEDTLS_ERR_RSA_RNG_FAILED:
295 : 0 : return( PSA_ERROR_INSUFFICIENT_ENTROPY );
296 : :
297 : 0 : case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
298 : : case MBEDTLS_ERR_ECP_INVALID_KEY:
299 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
300 : 0 : case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
301 : 0 : return( PSA_ERROR_BUFFER_TOO_SMALL );
302 : 0 : case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
303 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
304 : 0 : case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
305 : : case MBEDTLS_ERR_ECP_VERIFY_FAILED:
306 : 0 : return( PSA_ERROR_INVALID_SIGNATURE );
307 : 0 : case MBEDTLS_ERR_ECP_ALLOC_FAILED:
308 : 0 : return( PSA_ERROR_INSUFFICIENT_MEMORY );
309 : 0 : case MBEDTLS_ERR_ECP_RANDOM_FAILED:
310 : 0 : return( PSA_ERROR_INSUFFICIENT_ENTROPY );
311 : :
312 : 0 : case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
313 : 0 : return( PSA_ERROR_CORRUPTION_DETECTED );
314 : :
315 : 0 : default:
316 : 0 : return( PSA_ERROR_GENERIC_ERROR );
317 : : }
318 : : }
319 : :
320 : :
321 : :
322 : :
323 : : /****************************************************************/
324 : : /* Key management */
325 : : /****************************************************************/
326 : :
327 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
328 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
329 : : defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
330 : : defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \
331 : : defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
332 : 32 : mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_family_t curve,
333 : : size_t bits,
334 : : int bits_is_sloppy )
335 : : {
336 [ + - ]: 32 : switch( curve )
337 : : {
338 : 32 : case PSA_ECC_FAMILY_SECP_R1:
339 [ - + ]: 32 : switch( bits )
340 : : {
341 : : #if defined(PSA_WANT_ECC_SECP_R1_192)
342 : : case 192:
343 : : return( MBEDTLS_ECP_DP_SECP192R1 );
344 : : #endif
345 : : #if defined(PSA_WANT_ECC_SECP_R1_224)
346 : : case 224:
347 : : return( MBEDTLS_ECP_DP_SECP224R1 );
348 : : #endif
349 : : #if defined(PSA_WANT_ECC_SECP_R1_256)
350 : : case 256:
351 : : return( MBEDTLS_ECP_DP_SECP256R1 );
352 : : #endif
353 : : #if defined(PSA_WANT_ECC_SECP_R1_384)
354 : : case 384:
355 : : return( MBEDTLS_ECP_DP_SECP384R1 );
356 : : #endif
357 : : #if defined(PSA_WANT_ECC_SECP_R1_521)
358 : : case 521:
359 : : return( MBEDTLS_ECP_DP_SECP521R1 );
360 : : case 528:
361 : : if( bits_is_sloppy )
362 : : return( MBEDTLS_ECP_DP_SECP521R1 );
363 : : break;
364 : : #endif
365 : : }
366 : : break;
367 : :
368 : : case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
369 : : switch( bits )
370 : : {
371 : : #if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
372 : : case 256:
373 : : return( MBEDTLS_ECP_DP_BP256R1 );
374 : : #endif
375 : : #if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
376 : : case 384:
377 : : return( MBEDTLS_ECP_DP_BP384R1 );
378 : : #endif
379 : : #if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
380 : : case 512:
381 : : return( MBEDTLS_ECP_DP_BP512R1 );
382 : : #endif
383 : : }
384 : : break;
385 : :
386 : : case PSA_ECC_FAMILY_MONTGOMERY:
387 : : switch( bits )
388 : : {
389 : : #if defined(PSA_WANT_ECC_MONTGOMERY_255)
390 : : case 255:
391 : : return( MBEDTLS_ECP_DP_CURVE25519 );
392 : : case 256:
393 : : if( bits_is_sloppy )
394 : : return( MBEDTLS_ECP_DP_CURVE25519 );
395 : : break;
396 : : #endif
397 : : #if defined(PSA_WANT_ECC_MONTGOMERY_448)
398 : : case 448:
399 : : return( MBEDTLS_ECP_DP_CURVE448 );
400 : : #endif
401 : : }
402 : : break;
403 : :
404 : : case PSA_ECC_FAMILY_SECP_K1:
405 : : switch( bits )
406 : : {
407 : : #if defined(PSA_WANT_ECC_SECP_K1_192)
408 : : case 192:
409 : : return( MBEDTLS_ECP_DP_SECP192K1 );
410 : : #endif
411 : : #if defined(PSA_WANT_ECC_SECP_K1_224)
412 : : case 224:
413 : : return( MBEDTLS_ECP_DP_SECP224K1 );
414 : : #endif
415 : : #if defined(PSA_WANT_ECC_SECP_K1_256)
416 : : case 256:
417 : : return( MBEDTLS_ECP_DP_SECP256K1 );
418 : : #endif
419 : : }
420 : : break;
421 : : }
422 : :
423 : 0 : (void) bits_is_sloppy;
424 : 0 : return( MBEDTLS_ECP_DP_NONE );
425 : : }
426 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
427 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
428 : : defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
429 : : defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) ||
430 : : defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) */
431 : :
432 : 158 : psa_status_t psa_validate_unstructured_key_bit_size( psa_key_type_t type,
433 : : size_t bits )
434 : : {
435 : : /* Check that the bit size is acceptable for the key type */
436 [ + + - ]: 158 : switch( type )
437 : : {
438 : : case PSA_KEY_TYPE_RAW_DATA:
439 : : case PSA_KEY_TYPE_HMAC:
440 : : case PSA_KEY_TYPE_DERIVE:
441 : : break;
442 : : #if defined(PSA_WANT_KEY_TYPE_AES)
443 : 34 : case PSA_KEY_TYPE_AES:
444 [ - + - - ]: 34 : if( bits != 128 && bits != 192 && bits != 256 )
445 : : return( PSA_ERROR_INVALID_ARGUMENT );
446 : : break;
447 : : #endif
448 : : #if defined(PSA_WANT_KEY_TYPE_ARIA)
449 : : case PSA_KEY_TYPE_ARIA:
450 : : if( bits != 128 && bits != 192 && bits != 256 )
451 : : return( PSA_ERROR_INVALID_ARGUMENT );
452 : : break;
453 : : #endif
454 : : #if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
455 : : case PSA_KEY_TYPE_CAMELLIA:
456 : : if( bits != 128 && bits != 192 && bits != 256 )
457 : : return( PSA_ERROR_INVALID_ARGUMENT );
458 : : break;
459 : : #endif
460 : : #if defined(PSA_WANT_KEY_TYPE_DES)
461 : : case PSA_KEY_TYPE_DES:
462 : : if( bits != 64 && bits != 128 && bits != 192 )
463 : : return( PSA_ERROR_INVALID_ARGUMENT );
464 : : break;
465 : : #endif
466 : : #if defined(PSA_WANT_KEY_TYPE_CHACHA20)
467 : : case PSA_KEY_TYPE_CHACHA20:
468 : : if( bits != 256 )
469 : : return( PSA_ERROR_INVALID_ARGUMENT );
470 : : break;
471 : : #endif
472 : : default:
473 : : return( PSA_ERROR_NOT_SUPPORTED );
474 : : }
475 [ - + ]: 158 : if( bits % 8 != 0 )
476 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
477 : :
478 : : return( PSA_SUCCESS );
479 : : }
480 : :
481 : : /** Check whether a given key type is valid for use with a given MAC algorithm
482 : : *
483 : : * Upon successful return of this function, the behavior of #PSA_MAC_LENGTH
484 : : * when called with the validated \p algorithm and \p key_type is well-defined.
485 : : *
486 : : * \param[in] algorithm The specific MAC algorithm (can be wildcard).
487 : : * \param[in] key_type The key type of the key to be used with the
488 : : * \p algorithm.
489 : : *
490 : : * \retval #PSA_SUCCESS
491 : : * The \p key_type is valid for use with the \p algorithm
492 : : * \retval #PSA_ERROR_INVALID_ARGUMENT
493 : : * The \p key_type is not valid for use with the \p algorithm
494 : : */
495 : 154 : MBEDTLS_STATIC_TESTABLE psa_status_t psa_mac_key_can_do(
496 : : psa_algorithm_t algorithm,
497 : : psa_key_type_t key_type )
498 : : {
499 [ + - ]: 154 : if( PSA_ALG_IS_HMAC( algorithm ) )
500 : : {
501 [ - + ]: 154 : if( key_type == PSA_KEY_TYPE_HMAC )
502 : : return( PSA_SUCCESS );
503 : : }
504 : :
505 [ # # ]: 0 : if( PSA_ALG_IS_BLOCK_CIPHER_MAC( algorithm ) )
506 : : {
507 : : /* Check that we're calling PSA_BLOCK_CIPHER_BLOCK_LENGTH with a cipher
508 : : * key. */
509 [ # # ]: 0 : if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) ==
510 : : PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
511 : : {
512 : : /* PSA_BLOCK_CIPHER_BLOCK_LENGTH returns 1 for stream ciphers and
513 : : * the block length (larger than 1) for block ciphers. */
514 [ # # ]: 0 : if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) > 1 )
515 : 0 : return( PSA_SUCCESS );
516 : : }
517 : : }
518 : :
519 : : return( PSA_ERROR_INVALID_ARGUMENT );
520 : : }
521 : :
522 : 172 : psa_status_t psa_allocate_buffer_to_slot( psa_key_slot_t *slot,
523 : : size_t buffer_length )
524 : : {
525 [ + - ]: 172 : if( slot->key.data != NULL )
526 : : return( PSA_ERROR_ALREADY_EXISTS );
527 : :
528 : 172 : slot->key.data = mbedtls_calloc( 1, buffer_length );
529 [ + - ]: 172 : if( slot->key.data == NULL )
530 : : return( PSA_ERROR_INSUFFICIENT_MEMORY );
531 : :
532 : 172 : slot->key.bytes = buffer_length;
533 : 172 : return( PSA_SUCCESS );
534 : : }
535 : :
536 : 0 : psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot,
537 : : const uint8_t* data,
538 : : size_t data_length )
539 : : {
540 : 0 : psa_status_t status = psa_allocate_buffer_to_slot( slot,
541 : : data_length );
542 [ # # ]: 0 : if( status != PSA_SUCCESS )
543 : : return( status );
544 : :
545 : 0 : memcpy( slot->key.data, data, data_length );
546 : 0 : return( PSA_SUCCESS );
547 : : }
548 : :
549 : 172 : psa_status_t psa_import_key_into_slot(
550 : : const psa_key_attributes_t *attributes,
551 : : const uint8_t *data, size_t data_length,
552 : : uint8_t *key_buffer, size_t key_buffer_size,
553 : : size_t *key_buffer_length, size_t *bits )
554 : : {
555 : 172 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
556 : 172 : psa_key_type_t type = attributes->core.type;
557 : :
558 : : /* zero-length keys are never supported. */
559 [ + - ]: 172 : if( data_length == 0 )
560 : : return( PSA_ERROR_NOT_SUPPORTED );
561 : :
562 [ + + ]: 172 : if( key_type_is_raw_bytes( type ) )
563 : : {
564 : 158 : *bits = PSA_BYTES_TO_BITS( data_length );
565 : :
566 : 158 : status = psa_validate_unstructured_key_bit_size( attributes->core.type,
567 : : *bits );
568 [ + - ]: 158 : if( status != PSA_SUCCESS )
569 : : return( status );
570 : :
571 : : /* Copy the key material. */
572 : 158 : memcpy( key_buffer, data, data_length );
573 : 158 : *key_buffer_length = data_length;
574 : 158 : (void)key_buffer_size;
575 : :
576 : 158 : return( PSA_SUCCESS );
577 : : }
578 [ + - ]: 14 : else if( PSA_KEY_TYPE_IS_ASYMMETRIC( type ) )
579 : : {
580 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
581 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
582 [ + - ]: 14 : if( PSA_KEY_TYPE_IS_ECC( type ) )
583 : : {
584 : 14 : return( mbedtls_psa_ecp_import_key( attributes,
585 : : data, data_length,
586 : : key_buffer, key_buffer_size,
587 : : key_buffer_length,
588 : : bits ) );
589 : : }
590 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
591 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
592 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
593 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
594 : : if( PSA_KEY_TYPE_IS_RSA( type ) )
595 : : {
596 : : return( mbedtls_psa_rsa_import_key( attributes,
597 : : data, data_length,
598 : : key_buffer, key_buffer_size,
599 : : key_buffer_length,
600 : : bits ) );
601 : : }
602 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
603 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
604 : : }
605 : :
606 : : return( PSA_ERROR_NOT_SUPPORTED );
607 : : }
608 : :
609 : : /** Calculate the intersection of two algorithm usage policies.
610 : : *
611 : : * Return 0 (which allows no operation) on incompatibility.
612 : : */
613 : 0 : static psa_algorithm_t psa_key_policy_algorithm_intersection(
614 : : psa_key_type_t key_type,
615 : : psa_algorithm_t alg1,
616 : : psa_algorithm_t alg2 )
617 : : {
618 : : /* Common case: both sides actually specify the same policy. */
619 [ # # ]: 0 : if( alg1 == alg2 )
620 : : return( alg1 );
621 : : /* If the policies are from the same hash-and-sign family, check
622 : : * if one is a wildcard. If so the other has the specific algorithm. */
623 [ # # # # : 0 : if( PSA_ALG_IS_SIGN_HASH( alg1 ) &&
# # # # #
# ]
624 [ # # # # : 0 : PSA_ALG_IS_SIGN_HASH( alg2 ) &&
# # # # #
# ]
625 [ # # ]: 0 : ( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
626 : : {
627 [ # # # # : 0 : if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
# # # # #
# # # #
# ]
628 : : return( alg2 );
629 [ # # # # : 0 : if( PSA_ALG_SIGN_GET_HASH( alg2 ) == PSA_ALG_ANY_HASH )
# # # # #
# # # #
# ]
630 : : return( alg1 );
631 : : }
632 : : /* If the policies are from the same AEAD family, check whether
633 : : * one of them is a minimum-tag-length wildcard. Calculate the most
634 : : * restrictive tag length. */
635 [ # # # # ]: 0 : if( PSA_ALG_IS_AEAD( alg1 ) && PSA_ALG_IS_AEAD( alg2 ) &&
636 [ # # ]: 0 : ( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg1, 0 ) ==
637 : : PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg2, 0 ) ) )
638 : : {
639 : 0 : size_t alg1_len = PSA_ALG_AEAD_GET_TAG_LENGTH( alg1 );
640 : 0 : size_t alg2_len = PSA_ALG_AEAD_GET_TAG_LENGTH( alg2 );
641 : 0 : size_t restricted_len = alg1_len > alg2_len ? alg1_len : alg2_len;
642 : :
643 : : /* If both are wildcards, return most restrictive wildcard */
644 [ # # ]: 0 : if( ( ( alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
645 [ # # ]: 0 : ( ( alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) )
646 : : {
647 : 0 : return( PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(
648 : : alg1, restricted_len ) );
649 : : }
650 : : /* If only one is a wildcard, return specific algorithm if compatible. */
651 [ # # # # ]: 0 : if( ( ( alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
652 : : ( alg1_len <= alg2_len ) )
653 : : {
654 : : return( alg2 );
655 : : }
656 [ # # # # ]: 0 : if( ( ( alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
657 : : ( alg2_len <= alg1_len ) )
658 : : {
659 : : return( alg1 );
660 : : }
661 : : }
662 : : /* If the policies are from the same MAC family, check whether one
663 : : * of them is a minimum-MAC-length policy. Calculate the most
664 : : * restrictive tag length. */
665 [ # # # # ]: 0 : if( PSA_ALG_IS_MAC( alg1 ) && PSA_ALG_IS_MAC( alg2 ) &&
666 [ # # ]: 0 : ( PSA_ALG_FULL_LENGTH_MAC( alg1 ) ==
667 : : PSA_ALG_FULL_LENGTH_MAC( alg2 ) ) )
668 : : {
669 : : /* Validate the combination of key type and algorithm. Since the base
670 : : * algorithm of alg1 and alg2 are the same, we only need this once. */
671 [ # # ]: 0 : if( PSA_SUCCESS != psa_mac_key_can_do( alg1, key_type ) )
672 : : return( 0 );
673 : :
674 : : /* Get the (exact or at-least) output lengths for both sides of the
675 : : * requested intersection. None of the currently supported algorithms
676 : : * have an output length dependent on the actual key size, so setting it
677 : : * to a bogus value of 0 is currently OK.
678 : : *
679 : : * Note that for at-least-this-length wildcard algorithms, the output
680 : : * length is set to the shortest allowed length, which allows us to
681 : : * calculate the most restrictive tag length for the intersection. */
682 [ # # # # : 0 : size_t alg1_len = PSA_MAC_LENGTH( key_type, 0, alg1 );
# # # # #
# ]
683 [ # # # # : 0 : size_t alg2_len = PSA_MAC_LENGTH( key_type, 0, alg2 );
# # # # #
# ]
684 : 0 : size_t restricted_len = alg1_len > alg2_len ? alg1_len : alg2_len;
685 : :
686 : : /* If both are wildcards, return most restrictive wildcard */
687 [ # # ]: 0 : if( ( ( alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
688 [ # # ]: 0 : ( ( alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) )
689 : : {
690 : 0 : return( PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( alg1, restricted_len ) );
691 : : }
692 : :
693 : : /* If only one is an at-least-this-length policy, the intersection would
694 : : * be the other (fixed-length) policy as long as said fixed length is
695 : : * equal to or larger than the shortest allowed length. */
696 [ # # ]: 0 : if( ( alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 )
697 : : {
698 [ # # ]: 0 : return( ( alg1_len <= alg2_len ) ? alg2 : 0 );
699 : : }
700 [ # # ]: 0 : if( ( alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 )
701 : : {
702 [ # # ]: 0 : return( ( alg2_len <= alg1_len ) ? alg1 : 0 );
703 : : }
704 : :
705 : : /* If none of them are wildcards, check whether they define the same tag
706 : : * length. This is still possible here when one is default-length and
707 : : * the other specific-length. Ensure to always return the
708 : : * specific-length version for the intersection. */
709 [ # # ]: 0 : if( alg1_len == alg2_len )
710 : 0 : return( PSA_ALG_TRUNCATED_MAC( alg1, alg1_len ) );
711 : : }
712 : : /* If the policies are incompatible, allow nothing. */
713 : : return( 0 );
714 : : }
715 : :
716 : 202 : static int psa_key_algorithm_permits( psa_key_type_t key_type,
717 : : psa_algorithm_t policy_alg,
718 : : psa_algorithm_t requested_alg )
719 : : {
720 : : /* Common case: the policy only allows requested_alg. */
721 [ - + ]: 202 : if( requested_alg == policy_alg )
722 : : return( 1 );
723 : : /* If policy_alg is a hash-and-sign with a wildcard for the hash,
724 : : * and requested_alg is the same hash-and-sign family with any hash,
725 : : * then requested_alg is compliant with policy_alg. */
726 [ # # # # : 0 : if( PSA_ALG_IS_SIGN_HASH( requested_alg ) &&
# # # # #
# ]
727 [ # # # # : 0 : PSA_ALG_SIGN_GET_HASH( policy_alg ) == PSA_ALG_ANY_HASH )
# # # # #
# # # #
# ]
728 : : {
729 : 0 : return( ( policy_alg & ~PSA_ALG_HASH_MASK ) ==
730 : : ( requested_alg & ~PSA_ALG_HASH_MASK ) );
731 : : }
732 : : /* If policy_alg is a wildcard AEAD algorithm of the same base as
733 : : * the requested algorithm, check the requested tag length to be
734 : : * equal-length or longer than the wildcard-specified length. */
735 [ # # ]: 0 : if( PSA_ALG_IS_AEAD( policy_alg ) &&
736 [ # # ]: 0 : PSA_ALG_IS_AEAD( requested_alg ) &&
737 [ # # ]: 0 : ( PSA_ALG_AEAD_WITH_SHORTENED_TAG( policy_alg, 0 ) ==
738 : 0 : PSA_ALG_AEAD_WITH_SHORTENED_TAG( requested_alg, 0 ) ) &&
739 [ # # ]: 0 : ( ( policy_alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) )
740 : : {
741 : 0 : return( PSA_ALG_AEAD_GET_TAG_LENGTH( policy_alg ) <=
742 : 0 : PSA_ALG_AEAD_GET_TAG_LENGTH( requested_alg ) );
743 : : }
744 : : /* If policy_alg is a MAC algorithm of the same base as the requested
745 : : * algorithm, check whether their MAC lengths are compatible. */
746 [ # # ]: 0 : if( PSA_ALG_IS_MAC( policy_alg ) &&
747 [ # # ]: 0 : PSA_ALG_IS_MAC( requested_alg ) &&
748 [ # # ]: 0 : ( PSA_ALG_FULL_LENGTH_MAC( policy_alg ) ==
749 : : PSA_ALG_FULL_LENGTH_MAC( requested_alg ) ) )
750 : : {
751 : : /* Validate the combination of key type and algorithm. Since the policy
752 : : * and requested algorithms are the same, we only need this once. */
753 [ # # ]: 0 : if( PSA_SUCCESS != psa_mac_key_can_do( policy_alg, key_type ) )
754 : : return( 0 );
755 : :
756 : : /* Get both the requested output length for the algorithm which is to be
757 : : * verified, and the default output length for the base algorithm.
758 : : * Note that none of the currently supported algorithms have an output
759 : : * length dependent on actual key size, so setting it to a bogus value
760 : : * of 0 is currently OK. */
761 [ # # # # : 0 : size_t requested_output_length = PSA_MAC_LENGTH(
# # # # #
# ]
762 : : key_type, 0, requested_alg );
763 [ # # # # : 0 : size_t default_output_length = PSA_MAC_LENGTH(
# # # # ]
764 : : key_type, 0,
765 : : PSA_ALG_FULL_LENGTH_MAC( requested_alg ) );
766 : :
767 : : /* If the policy is default-length, only allow an algorithm with
768 : : * a declared exact-length matching the default. */
769 [ # # ]: 0 : if( PSA_MAC_TRUNCATED_LENGTH( policy_alg ) == 0 )
770 : 0 : return( requested_output_length == default_output_length );
771 : :
772 : : /* If the requested algorithm is default-length, allow it if the policy
773 : : * length exactly matches the default length. */
774 [ # # # # ]: 0 : if( PSA_MAC_TRUNCATED_LENGTH( requested_alg ) == 0 &&
775 : : PSA_MAC_TRUNCATED_LENGTH( policy_alg ) == default_output_length )
776 : : {
777 : : return( 1 );
778 : : }
779 : :
780 : : /* If policy_alg is an at-least-this-length wildcard MAC algorithm,
781 : : * check for the requested MAC length to be equal to or longer than the
782 : : * minimum allowed length. */
783 [ # # ]: 0 : if( ( policy_alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 )
784 : : {
785 : 0 : return( PSA_MAC_TRUNCATED_LENGTH( policy_alg ) <=
786 : : requested_output_length );
787 : : }
788 : : }
789 : : /* If policy_alg is a generic key agreement operation, then using it for
790 : : * a key derivation with that key agreement should also be allowed. This
791 : : * behaviour is expected to be defined in a future specification version. */
792 [ # # # # ]: 0 : if( PSA_ALG_IS_RAW_KEY_AGREEMENT( policy_alg ) &&
793 [ # # ]: 0 : PSA_ALG_IS_KEY_AGREEMENT( requested_alg ) )
794 : : {
795 : 0 : return( PSA_ALG_KEY_AGREEMENT_GET_BASE( requested_alg ) ==
796 : : policy_alg );
797 : : }
798 : : /* If it isn't explicitly permitted, it's forbidden. */
799 : : return( 0 );
800 : : }
801 : :
802 : : /** Test whether a policy permits an algorithm.
803 : : *
804 : : * The caller must test usage flags separately.
805 : : *
806 : : * \note This function requires providing the key type for which the policy is
807 : : * being validated, since some algorithm policy definitions (e.g. MAC)
808 : : * have different properties depending on what kind of cipher it is
809 : : * combined with.
810 : : *
811 : : * \retval PSA_SUCCESS When \p alg is a specific algorithm
812 : : * allowed by the \p policy.
813 : : * \retval PSA_ERROR_INVALID_ARGUMENT When \p alg is not a specific algorithm
814 : : * \retval PSA_ERROR_NOT_PERMITTED When \p alg is a specific algorithm, but
815 : : * the \p policy does not allow it.
816 : : */
817 : 202 : static psa_status_t psa_key_policy_permits( const psa_key_policy_t *policy,
818 : : psa_key_type_t key_type,
819 : : psa_algorithm_t alg )
820 : : {
821 : : /* '0' is not a valid algorithm */
822 [ + - ]: 202 : if( alg == 0 )
823 : : return( PSA_ERROR_INVALID_ARGUMENT );
824 : :
825 : : /* A requested algorithm cannot be a wildcard. */
826 [ + - + - : 212 : if( PSA_ALG_IS_WILDCARD( alg ) )
+ + + - -
+ + - + -
+ - - + -
- - - + -
+ + + + +
- ]
827 : : return( PSA_ERROR_INVALID_ARGUMENT );
828 : :
829 [ - + ]: 202 : if( psa_key_algorithm_permits( key_type, policy->alg, alg ) ||
830 [ # # ]: 0 : psa_key_algorithm_permits( key_type, policy->alg2, alg ) )
831 : : return( PSA_SUCCESS );
832 : : else
833 : 0 : return( PSA_ERROR_NOT_PERMITTED );
834 : : }
835 : :
836 : : /** Restrict a key policy based on a constraint.
837 : : *
838 : : * \note This function requires providing the key type for which the policy is
839 : : * being restricted, since some algorithm policy definitions (e.g. MAC)
840 : : * have different properties depending on what kind of cipher it is
841 : : * combined with.
842 : : *
843 : : * \param[in] key_type The key type for which to restrict the policy
844 : : * \param[in,out] policy The policy to restrict.
845 : : * \param[in] constraint The policy constraint to apply.
846 : : *
847 : : * \retval #PSA_SUCCESS
848 : : * \c *policy contains the intersection of the original value of
849 : : * \c *policy and \c *constraint.
850 : : * \retval #PSA_ERROR_INVALID_ARGUMENT
851 : : * \c key_type, \c *policy and \c *constraint are incompatible.
852 : : * \c *policy is unchanged.
853 : : */
854 : 0 : static psa_status_t psa_restrict_key_policy(
855 : : psa_key_type_t key_type,
856 : : psa_key_policy_t *policy,
857 : : const psa_key_policy_t *constraint )
858 : : {
859 : 0 : psa_algorithm_t intersection_alg =
860 : 0 : psa_key_policy_algorithm_intersection( key_type, policy->alg,
861 : 0 : constraint->alg );
862 : 0 : psa_algorithm_t intersection_alg2 =
863 : 0 : psa_key_policy_algorithm_intersection( key_type, policy->alg2,
864 : 0 : constraint->alg2 );
865 [ # # # # : 0 : if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 )
# # ]
866 : : return( PSA_ERROR_INVALID_ARGUMENT );
867 [ # # # # : 0 : if( intersection_alg2 == 0 && policy->alg2 != 0 && constraint->alg2 != 0 )
# # ]
868 : : return( PSA_ERROR_INVALID_ARGUMENT );
869 : 0 : policy->usage &= constraint->usage;
870 : 0 : policy->alg = intersection_alg;
871 : 0 : policy->alg2 = intersection_alg2;
872 : 0 : return( PSA_SUCCESS );
873 : : }
874 : :
875 : : /** Get the description of a key given its identifier and policy constraints
876 : : * and lock it.
877 : : *
878 : : * The key must have allow all the usage flags set in \p usage. If \p alg is
879 : : * nonzero, the key must allow operations with this algorithm. If \p alg is
880 : : * zero, the algorithm is not checked.
881 : : *
882 : : * In case of a persistent key, the function loads the description of the key
883 : : * into a key slot if not already done.
884 : : *
885 : : * On success, the returned key slot is locked. It is the responsibility of
886 : : * the caller to unlock the key slot when it does not access it anymore.
887 : : */
888 : 202 : static psa_status_t psa_get_and_lock_key_slot_with_policy(
889 : : mbedtls_svc_key_id_t key,
890 : : psa_key_slot_t **p_slot,
891 : : psa_key_usage_t usage,
892 : : psa_algorithm_t alg )
893 : : {
894 : 202 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
895 : 202 : psa_key_slot_t *slot;
896 : :
897 : 202 : status = psa_get_and_lock_key_slot( key, p_slot );
898 [ + - ]: 202 : if( status != PSA_SUCCESS )
899 : : return( status );
900 : 202 : slot = *p_slot;
901 : :
902 : : /* Enforce that usage policy for the key slot contains all the flags
903 : : * required by the usage parameter. There is one exception: public
904 : : * keys can always be exported, so we treat public key objects as
905 : : * if they had the export flag. */
906 [ + + ]: 202 : if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
907 : 6 : usage &= ~PSA_KEY_USAGE_EXPORT;
908 : :
909 [ - + ]: 202 : if( ( slot->attr.policy.usage & usage ) != usage )
910 : : {
911 : 0 : status = PSA_ERROR_NOT_PERMITTED;
912 : 0 : goto error;
913 : : }
914 : :
915 : : /* Enforce that the usage policy permits the requested algortihm. */
916 [ + - ]: 202 : if( alg != 0 )
917 : : {
918 : 202 : status = psa_key_policy_permits( &slot->attr.policy,
919 : : slot->attr.type,
920 : : alg );
921 [ - + ]: 202 : if( status != PSA_SUCCESS )
922 : 0 : goto error;
923 : : }
924 : :
925 : : return( PSA_SUCCESS );
926 : :
927 : 0 : error:
928 : 0 : *p_slot = NULL;
929 : 0 : psa_unlock_key_slot( slot );
930 : :
931 : 0 : return( status );
932 : : }
933 : :
934 : : /** Get a key slot containing a transparent key and lock it.
935 : : *
936 : : * A transparent key is a key for which the key material is directly
937 : : * available, as opposed to a key in a secure element and/or to be used
938 : : * by a secure element.
939 : : *
940 : : * This is a temporary function that may be used instead of
941 : : * psa_get_and_lock_key_slot_with_policy() when there is no opaque key support
942 : : * for a cryptographic operation.
943 : : *
944 : : * On success, the returned key slot is locked. It is the responsibility of the
945 : : * caller to unlock the key slot when it does not access it anymore.
946 : : */
947 : 4 : static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
948 : : mbedtls_svc_key_id_t key,
949 : : psa_key_slot_t **p_slot,
950 : : psa_key_usage_t usage,
951 : : psa_algorithm_t alg )
952 : : {
953 : 4 : psa_status_t status = psa_get_and_lock_key_slot_with_policy( key, p_slot,
954 : : usage, alg );
955 [ + - ]: 4 : if( status != PSA_SUCCESS )
956 : : return( status );
957 : :
958 [ - + ]: 4 : if( psa_key_lifetime_is_external( (*p_slot)->attr.lifetime ) )
959 : : {
960 : 0 : psa_unlock_key_slot( *p_slot );
961 : 0 : *p_slot = NULL;
962 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
963 : : }
964 : :
965 : : return( PSA_SUCCESS );
966 : : }
967 : :
968 : 172 : psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
969 : : {
970 : : /* Data pointer will always be either a valid pointer or NULL in an
971 : : * initialized slot, so we can just free it. */
972 [ + - ]: 172 : if( slot->key.data != NULL )
973 : 172 : mbedtls_platform_zeroize( slot->key.data, slot->key.bytes);
974 : :
975 : 172 : mbedtls_free( slot->key.data );
976 : 172 : slot->key.data = NULL;
977 : 172 : slot->key.bytes = 0;
978 : :
979 : 172 : return( PSA_SUCCESS );
980 : : }
981 : :
982 : : /** Completely wipe a slot in memory, including its policy.
983 : : * Persistent storage is not affected. */
984 : 172 : psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot )
985 : : {
986 : 172 : psa_status_t status = psa_remove_key_data_from_memory( slot );
987 : :
988 : : /*
989 : : * As the return error code may not be handled in case of multiple errors,
990 : : * do our best to report an unexpected lock counter. Assert with
991 : : * MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is equal to one:
992 : : * if the MBEDTLS_TEST_HOOKS configuration option is enabled and the
993 : : * function is called as part of the execution of a test suite, the
994 : : * execution of the test suite is stopped in error if the assertion fails.
995 : : */
996 [ - + ]: 172 : if( slot->lock_count != 1 )
997 : : {
998 : 0 : MBEDTLS_TEST_HOOK_TEST_ASSERT( slot->lock_count == 1 );
999 : 0 : status = PSA_ERROR_CORRUPTION_DETECTED;
1000 : : }
1001 : :
1002 : : /* Multipart operations may still be using the key. This is safe
1003 : : * because all multipart operation objects are independent from
1004 : : * the key slot: if they need to access the key after the setup
1005 : : * phase, they have a copy of the key. Note that this means that
1006 : : * key material can linger until all operations are completed. */
1007 : : /* At this point, key material and other type-specific content has
1008 : : * been wiped. Clear remaining metadata. We can call memset and not
1009 : : * zeroize because the metadata is not particularly sensitive. */
1010 : 172 : memset( slot, 0, sizeof( *slot ) );
1011 : 172 : return( status );
1012 : : }
1013 : :
1014 : 172 : psa_status_t psa_destroy_key( mbedtls_svc_key_id_t key )
1015 : : {
1016 : 172 : psa_key_slot_t *slot;
1017 : 172 : psa_status_t status; /* status of the last operation */
1018 : 172 : psa_status_t overall_status = PSA_SUCCESS;
1019 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1020 : : psa_se_drv_table_entry_t *driver;
1021 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1022 : :
1023 [ + - ]: 172 : if( mbedtls_svc_key_id_is_null( key ) )
1024 : : return( PSA_SUCCESS );
1025 : :
1026 : : /*
1027 : : * Get the description of the key in a key slot. In case of a persistent
1028 : : * key, this will load the key description from persistent memory if not
1029 : : * done yet. We cannot avoid this loading as without it we don't know if
1030 : : * the key is operated by an SE or not and this information is needed by
1031 : : * the current implementation.
1032 : : */
1033 : 172 : status = psa_get_and_lock_key_slot( key, &slot );
1034 [ + - ]: 172 : if( status != PSA_SUCCESS )
1035 : : return( status );
1036 : :
1037 : : /*
1038 : : * If the key slot containing the key description is under access by the
1039 : : * library (apart from the present access), the key cannot be destroyed
1040 : : * yet. For the time being, just return in error. Eventually (to be
1041 : : * implemented), the key should be destroyed when all accesses have
1042 : : * stopped.
1043 : : */
1044 [ - + ]: 172 : if( slot->lock_count > 1 )
1045 : : {
1046 : 0 : psa_unlock_key_slot( slot );
1047 : 0 : return( PSA_ERROR_GENERIC_ERROR );
1048 : : }
1049 : :
1050 [ + - ]: 172 : if( PSA_KEY_LIFETIME_IS_READ_ONLY( slot->attr.lifetime ) )
1051 : : {
1052 : : /* Refuse the destruction of a read-only key (which may or may not work
1053 : : * if we attempt it, depending on whether the key is merely read-only
1054 : : * by policy or actually physically read-only).
1055 : : * Just do the best we can, which is to wipe the copy in memory
1056 : : * (done in this function's cleanup code). */
1057 : 0 : overall_status = PSA_ERROR_NOT_PERMITTED;
1058 : 0 : goto exit;
1059 : : }
1060 : :
1061 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1062 : : driver = psa_get_se_driver_entry( slot->attr.lifetime );
1063 : : if( driver != NULL )
1064 : : {
1065 : : /* For a key in a secure element, we need to do three things:
1066 : : * remove the key file in internal storage, destroy the
1067 : : * key inside the secure element, and update the driver's
1068 : : * persistent data. Start a transaction that will encompass these
1069 : : * three actions. */
1070 : : psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_DESTROY_KEY );
1071 : : psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
1072 : : psa_crypto_transaction.key.slot = psa_key_slot_get_slot_number( slot );
1073 : : psa_crypto_transaction.key.id = slot->attr.id;
1074 : : status = psa_crypto_save_transaction( );
1075 : : if( status != PSA_SUCCESS )
1076 : : {
1077 : : (void) psa_crypto_stop_transaction( );
1078 : : /* We should still try to destroy the key in the secure
1079 : : * element and the key metadata in storage. This is especially
1080 : : * important if the error is that the storage is full.
1081 : : * But how to do it exactly without risking an inconsistent
1082 : : * state after a reset?
1083 : : * https://github.com/ARMmbed/mbed-crypto/issues/215
1084 : : */
1085 : : overall_status = status;
1086 : : goto exit;
1087 : : }
1088 : :
1089 : : status = psa_destroy_se_key( driver,
1090 : : psa_key_slot_get_slot_number( slot ) );
1091 : : if( overall_status == PSA_SUCCESS )
1092 : : overall_status = status;
1093 : : }
1094 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1095 : :
1096 : : #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
1097 : : if( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
1098 : : {
1099 : : status = psa_destroy_persistent_key( slot->attr.id );
1100 : : if( overall_status == PSA_SUCCESS )
1101 : : overall_status = status;
1102 : :
1103 : : /* TODO: other slots may have a copy of the same key. We should
1104 : : * invalidate them.
1105 : : * https://github.com/ARMmbed/mbed-crypto/issues/214
1106 : : */
1107 : : }
1108 : : #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1109 : :
1110 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1111 : : if( driver != NULL )
1112 : : {
1113 : : status = psa_save_se_persistent_data( driver );
1114 : : if( overall_status == PSA_SUCCESS )
1115 : : overall_status = status;
1116 : : status = psa_crypto_stop_transaction( );
1117 : : if( overall_status == PSA_SUCCESS )
1118 : : overall_status = status;
1119 : : }
1120 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1121 : :
1122 : 172 : exit:
1123 : 172 : status = psa_wipe_key_slot( slot );
1124 : : /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
1125 [ - + ]: 172 : if( status != PSA_SUCCESS )
1126 : 0 : overall_status = status;
1127 : : return( overall_status );
1128 : : }
1129 : :
1130 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1131 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
1132 : : static psa_status_t psa_get_rsa_public_exponent(
1133 : : const mbedtls_rsa_context *rsa,
1134 : : psa_key_attributes_t *attributes )
1135 : : {
1136 : : mbedtls_mpi mpi;
1137 : : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1138 : : uint8_t *buffer = NULL;
1139 : : size_t buflen;
1140 : : mbedtls_mpi_init( &mpi );
1141 : :
1142 : : ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &mpi );
1143 : : if( ret != 0 )
1144 : : goto exit;
1145 : : if( mbedtls_mpi_cmp_int( &mpi, 65537 ) == 0 )
1146 : : {
1147 : : /* It's the default value, which is reported as an empty string,
1148 : : * so there's nothing to do. */
1149 : : goto exit;
1150 : : }
1151 : :
1152 : : buflen = mbedtls_mpi_size( &mpi );
1153 : : buffer = mbedtls_calloc( 1, buflen );
1154 : : if( buffer == NULL )
1155 : : {
1156 : : ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
1157 : : goto exit;
1158 : : }
1159 : : ret = mbedtls_mpi_write_binary( &mpi, buffer, buflen );
1160 : : if( ret != 0 )
1161 : : goto exit;
1162 : : attributes->domain_parameters = buffer;
1163 : : attributes->domain_parameters_size = buflen;
1164 : :
1165 : : exit:
1166 : : mbedtls_mpi_free( &mpi );
1167 : : if( ret != 0 )
1168 : : mbedtls_free( buffer );
1169 : : return( mbedtls_to_psa_error( ret ) );
1170 : : }
1171 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1172 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
1173 : :
1174 : : /** Retrieve all the publicly-accessible attributes of a key.
1175 : : */
1176 : 0 : psa_status_t psa_get_key_attributes( mbedtls_svc_key_id_t key,
1177 : : psa_key_attributes_t *attributes )
1178 : : {
1179 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1180 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
1181 : 0 : psa_key_slot_t *slot;
1182 : :
1183 : 0 : psa_reset_key_attributes( attributes );
1184 : :
1185 : 0 : status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 );
1186 [ # # ]: 0 : if( status != PSA_SUCCESS )
1187 : : return( status );
1188 : :
1189 : 0 : attributes->core = slot->attr;
1190 : 0 : attributes->core.flags &= ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1191 : : MBEDTLS_PSA_KA_MASK_DUAL_USE );
1192 : :
1193 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1194 : : if( psa_get_se_driver_entry( slot->attr.lifetime ) != NULL )
1195 : : psa_set_key_slot_number( attributes,
1196 : : psa_key_slot_get_slot_number( slot ) );
1197 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1198 : :
1199 : 0 : switch( slot->attr.type )
1200 : : {
1201 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1202 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
1203 : : case PSA_KEY_TYPE_RSA_KEY_PAIR:
1204 : : case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
1205 : : /* TODO: reporting the public exponent for opaque keys
1206 : : * is not yet implemented.
1207 : : * https://github.com/ARMmbed/mbed-crypto/issues/216
1208 : : */
1209 : : if( ! psa_key_lifetime_is_external( slot->attr.lifetime ) )
1210 : : {
1211 : : mbedtls_rsa_context *rsa = NULL;
1212 : :
1213 : : status = mbedtls_psa_rsa_load_representation(
1214 : : slot->attr.type,
1215 : : slot->key.data,
1216 : : slot->key.bytes,
1217 : : &rsa );
1218 : : if( status != PSA_SUCCESS )
1219 : : break;
1220 : :
1221 : : status = psa_get_rsa_public_exponent( rsa,
1222 : : attributes );
1223 : : mbedtls_rsa_free( rsa );
1224 : : mbedtls_free( rsa );
1225 : : }
1226 : : break;
1227 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1228 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
1229 : : default:
1230 : : /* Nothing else to do. */
1231 : 0 : break;
1232 : : }
1233 : :
1234 : 0 : if( status != PSA_SUCCESS )
1235 : : psa_reset_key_attributes( attributes );
1236 : :
1237 : 0 : unlock_status = psa_unlock_key_slot( slot );
1238 : :
1239 : 0 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
1240 : : }
1241 : :
1242 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1243 : : psa_status_t psa_get_key_slot_number(
1244 : : const psa_key_attributes_t *attributes,
1245 : : psa_key_slot_number_t *slot_number )
1246 : : {
1247 : : if( attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER )
1248 : : {
1249 : : *slot_number = attributes->slot_number;
1250 : : return( PSA_SUCCESS );
1251 : : }
1252 : : else
1253 : : return( PSA_ERROR_INVALID_ARGUMENT );
1254 : : }
1255 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1256 : :
1257 : 0 : static psa_status_t psa_export_key_buffer_internal( const uint8_t *key_buffer,
1258 : : size_t key_buffer_size,
1259 : : uint8_t *data,
1260 : : size_t data_size,
1261 : : size_t *data_length )
1262 : : {
1263 [ # # ]: 0 : if( key_buffer_size > data_size )
1264 : : return( PSA_ERROR_BUFFER_TOO_SMALL );
1265 : 0 : memcpy( data, key_buffer, key_buffer_size );
1266 : 0 : memset( data + key_buffer_size, 0,
1267 : : data_size - key_buffer_size );
1268 : 0 : *data_length = key_buffer_size;
1269 : 0 : return( PSA_SUCCESS );
1270 : : }
1271 : :
1272 : 0 : psa_status_t psa_export_key_internal(
1273 : : const psa_key_attributes_t *attributes,
1274 : : const uint8_t *key_buffer, size_t key_buffer_size,
1275 : : uint8_t *data, size_t data_size, size_t *data_length )
1276 : : {
1277 : 0 : psa_key_type_t type = attributes->core.type;
1278 : :
1279 [ # # ]: 0 : if( key_type_is_raw_bytes( type ) ||
1280 [ # # ]: 0 : PSA_KEY_TYPE_IS_RSA( type ) ||
1281 [ # # ]: 0 : PSA_KEY_TYPE_IS_ECC( type ) )
1282 : : {
1283 : 0 : return( psa_export_key_buffer_internal(
1284 : : key_buffer, key_buffer_size,
1285 : : data, data_size, data_length ) );
1286 : : }
1287 : : else
1288 : : {
1289 : : /* This shouldn't happen in the reference implementation, but
1290 : : it is valid for a special-purpose implementation to omit
1291 : : support for exporting certain key types. */
1292 : : return( PSA_ERROR_NOT_SUPPORTED );
1293 : : }
1294 : : }
1295 : :
1296 : 0 : psa_status_t psa_export_key( mbedtls_svc_key_id_t key,
1297 : : uint8_t *data,
1298 : : size_t data_size,
1299 : : size_t *data_length )
1300 : : {
1301 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1302 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
1303 : 0 : psa_key_slot_t *slot;
1304 : :
1305 : : /* Reject a zero-length output buffer now, since this can never be a
1306 : : * valid key representation. This way we know that data must be a valid
1307 : : * pointer and we can do things like memset(data, ..., data_size). */
1308 [ # # ]: 0 : if( data_size == 0 )
1309 : : return( PSA_ERROR_BUFFER_TOO_SMALL );
1310 : :
1311 : : /* Set the key to empty now, so that even when there are errors, we always
1312 : : * set data_length to a value between 0 and data_size. On error, setting
1313 : : * the key to empty is a good choice because an empty key representation is
1314 : : * unlikely to be accepted anywhere. */
1315 : 0 : *data_length = 0;
1316 : :
1317 : : /* Export requires the EXPORT flag. There is an exception for public keys,
1318 : : * which don't require any flag, but
1319 : : * psa_get_and_lock_key_slot_with_policy() takes care of this.
1320 : : */
1321 : 0 : status = psa_get_and_lock_key_slot_with_policy( key, &slot,
1322 : : PSA_KEY_USAGE_EXPORT, 0 );
1323 [ # # ]: 0 : if( status != PSA_SUCCESS )
1324 : : return( status );
1325 : :
1326 : 0 : psa_key_attributes_t attributes = {
1327 : 0 : .core = slot->attr
1328 : : };
1329 : 0 : status = psa_driver_wrapper_export_key( &attributes,
1330 : 0 : slot->key.data, slot->key.bytes,
1331 : : data, data_size, data_length );
1332 : :
1333 : 0 : unlock_status = psa_unlock_key_slot( slot );
1334 : :
1335 [ # # ]: 0 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
1336 : : }
1337 : :
1338 : 0 : psa_status_t psa_export_public_key_internal(
1339 : : const psa_key_attributes_t *attributes,
1340 : : const uint8_t *key_buffer,
1341 : : size_t key_buffer_size,
1342 : : uint8_t *data,
1343 : : size_t data_size,
1344 : : size_t *data_length )
1345 : : {
1346 : 0 : psa_key_type_t type = attributes->core.type;
1347 : :
1348 [ # # # # ]: 0 : if( PSA_KEY_TYPE_IS_RSA( type ) || PSA_KEY_TYPE_IS_ECC( type ) )
1349 : : {
1350 [ # # ]: 0 : if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
1351 : : {
1352 : : /* Exporting public -> public */
1353 : 0 : return( psa_export_key_buffer_internal(
1354 : : key_buffer, key_buffer_size,
1355 : : data, data_size, data_length ) );
1356 : : }
1357 : :
1358 [ # # ]: 0 : if( PSA_KEY_TYPE_IS_RSA( type ) )
1359 : : {
1360 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1361 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
1362 : : return( mbedtls_psa_rsa_export_public_key( attributes,
1363 : : key_buffer,
1364 : : key_buffer_size,
1365 : : data,
1366 : : data_size,
1367 : : data_length ) );
1368 : : #else
1369 : : /* We don't know how to convert a private RSA key to public. */
1370 : : return( PSA_ERROR_NOT_SUPPORTED );
1371 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1372 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
1373 : : }
1374 : : else
1375 : : {
1376 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
1377 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
1378 : 0 : return( mbedtls_psa_ecp_export_public_key( attributes,
1379 : : key_buffer,
1380 : : key_buffer_size,
1381 : : data,
1382 : : data_size,
1383 : : data_length ) );
1384 : : #else
1385 : : /* We don't know how to convert a private ECC key to public */
1386 : : return( PSA_ERROR_NOT_SUPPORTED );
1387 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
1388 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
1389 : : }
1390 : : }
1391 : : else
1392 : : {
1393 : : /* This shouldn't happen in the reference implementation, but
1394 : : it is valid for a special-purpose implementation to omit
1395 : : support for exporting certain key types. */
1396 : : return( PSA_ERROR_NOT_SUPPORTED );
1397 : : }
1398 : : }
1399 : :
1400 : 0 : psa_status_t psa_export_public_key( mbedtls_svc_key_id_t key,
1401 : : uint8_t *data,
1402 : : size_t data_size,
1403 : : size_t *data_length )
1404 : : {
1405 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1406 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
1407 : 0 : psa_key_slot_t *slot;
1408 : :
1409 : : /* Reject a zero-length output buffer now, since this can never be a
1410 : : * valid key representation. This way we know that data must be a valid
1411 : : * pointer and we can do things like memset(data, ..., data_size). */
1412 [ # # ]: 0 : if( data_size == 0 )
1413 : : return( PSA_ERROR_BUFFER_TOO_SMALL );
1414 : :
1415 : : /* Set the key to empty now, so that even when there are errors, we always
1416 : : * set data_length to a value between 0 and data_size. On error, setting
1417 : : * the key to empty is a good choice because an empty key representation is
1418 : : * unlikely to be accepted anywhere. */
1419 : 0 : *data_length = 0;
1420 : :
1421 : : /* Exporting a public key doesn't require a usage flag. */
1422 : 0 : status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 );
1423 [ # # ]: 0 : if( status != PSA_SUCCESS )
1424 : : return( status );
1425 : :
1426 [ # # ]: 0 : if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
1427 : : {
1428 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
1429 : 0 : goto exit;
1430 : : }
1431 : :
1432 : 0 : psa_key_attributes_t attributes = {
1433 : : .core = slot->attr
1434 : : };
1435 : 0 : status = psa_driver_wrapper_export_public_key(
1436 : 0 : &attributes, slot->key.data, slot->key.bytes,
1437 : : data, data_size, data_length );
1438 : :
1439 : 0 : exit:
1440 : 0 : unlock_status = psa_unlock_key_slot( slot );
1441 : :
1442 [ # # ]: 0 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
1443 : : }
1444 : :
1445 : : #if defined(static_assert)
1446 : : static_assert( ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
1447 : : "One or more key attribute flag is listed as both external-only and dual-use" );
1448 : : static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
1449 : : "One or more key attribute flag is listed as both internal-only and dual-use" );
1450 : : static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ) == 0,
1451 : : "One or more key attribute flag is listed as both internal-only and external-only" );
1452 : : #endif
1453 : :
1454 : : /** Validate that a key policy is internally well-formed.
1455 : : *
1456 : : * This function only rejects invalid policies. It does not validate the
1457 : : * consistency of the policy with respect to other attributes of the key
1458 : : * such as the key type.
1459 : : */
1460 : 172 : static psa_status_t psa_validate_key_policy( const psa_key_policy_t *policy )
1461 : : {
1462 [ - + ]: 172 : if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
1463 : : PSA_KEY_USAGE_COPY |
1464 : : PSA_KEY_USAGE_ENCRYPT |
1465 : : PSA_KEY_USAGE_DECRYPT |
1466 : : PSA_KEY_USAGE_SIGN_MESSAGE |
1467 : : PSA_KEY_USAGE_VERIFY_MESSAGE |
1468 : : PSA_KEY_USAGE_SIGN_HASH |
1469 : : PSA_KEY_USAGE_VERIFY_HASH |
1470 : : PSA_KEY_USAGE_VERIFY_DERIVATION |
1471 : : PSA_KEY_USAGE_DERIVE ) ) != 0 )
1472 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
1473 : :
1474 : : return( PSA_SUCCESS );
1475 : : }
1476 : :
1477 : : /** Validate the internal consistency of key attributes.
1478 : : *
1479 : : * This function only rejects invalid attribute values. If does not
1480 : : * validate the consistency of the attributes with any key data that may
1481 : : * be involved in the creation of the key.
1482 : : *
1483 : : * Call this function early in the key creation process.
1484 : : *
1485 : : * \param[in] attributes Key attributes for the new key.
1486 : : * \param[out] p_drv On any return, the driver for the key, if any.
1487 : : * NULL for a transparent key.
1488 : : *
1489 : : */
1490 : 172 : static psa_status_t psa_validate_key_attributes(
1491 : : const psa_key_attributes_t *attributes,
1492 : : psa_se_drv_table_entry_t **p_drv )
1493 : : {
1494 : 172 : psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
1495 : 172 : psa_key_lifetime_t lifetime = psa_get_key_lifetime( attributes );
1496 : 172 : mbedtls_svc_key_id_t key = psa_get_key_id( attributes );
1497 : :
1498 : 172 : status = psa_validate_key_location( lifetime, p_drv );
1499 [ + - ]: 172 : if( status != PSA_SUCCESS )
1500 : : return( status );
1501 : :
1502 : 172 : status = psa_validate_key_persistence( lifetime );
1503 [ + - ]: 172 : if( status != PSA_SUCCESS )
1504 : : return( status );
1505 : :
1506 [ + - ]: 172 : if ( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) )
1507 : : {
1508 [ + - ]: 172 : if( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key ) != 0 )
1509 : : return( PSA_ERROR_INVALID_ARGUMENT );
1510 : : }
1511 : : else
1512 : : {
1513 [ # # ]: 0 : if( !psa_is_valid_key_id( psa_get_key_id( attributes ), 0 ) )
1514 : : return( PSA_ERROR_INVALID_ARGUMENT );
1515 : : }
1516 : :
1517 : 172 : status = psa_validate_key_policy( &attributes->core.policy );
1518 [ + - ]: 172 : if( status != PSA_SUCCESS )
1519 : : return( status );
1520 : :
1521 : : /* Refuse to create overly large keys.
1522 : : * Note that this doesn't trigger on import if the attributes don't
1523 : : * explicitly specify a size (so psa_get_key_bits returns 0), so
1524 : : * psa_import_key() needs its own checks. */
1525 [ + - ]: 172 : if( psa_get_key_bits( attributes ) > PSA_MAX_KEY_BITS )
1526 : : return( PSA_ERROR_NOT_SUPPORTED );
1527 : :
1528 : : /* Reject invalid flags. These should not be reachable through the API. */
1529 [ - + ]: 172 : if( attributes->core.flags & ~ ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1530 : : MBEDTLS_PSA_KA_MASK_DUAL_USE ) )
1531 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
1532 : :
1533 : : return( PSA_SUCCESS );
1534 : : }
1535 : :
1536 : : /** Prepare a key slot to receive key material.
1537 : : *
1538 : : * This function allocates a key slot and sets its metadata.
1539 : : *
1540 : : * If this function fails, call psa_fail_key_creation().
1541 : : *
1542 : : * This function is intended to be used as follows:
1543 : : * -# Call psa_start_key_creation() to allocate a key slot, prepare
1544 : : * it with the specified attributes, and in case of a volatile key assign it
1545 : : * a volatile key identifier.
1546 : : * -# Populate the slot with the key material.
1547 : : * -# Call psa_finish_key_creation() to finalize the creation of the slot.
1548 : : * In case of failure at any step, stop the sequence and call
1549 : : * psa_fail_key_creation().
1550 : : *
1551 : : * On success, the key slot is locked. It is the responsibility of the caller
1552 : : * to unlock the key slot when it does not access it anymore.
1553 : : *
1554 : : * \param method An identification of the calling function.
1555 : : * \param[in] attributes Key attributes for the new key.
1556 : : * \param[out] p_slot On success, a pointer to the prepared slot.
1557 : : * \param[out] p_drv On any return, the driver for the key, if any.
1558 : : * NULL for a transparent key.
1559 : : *
1560 : : * \retval #PSA_SUCCESS
1561 : : * The key slot is ready to receive key material.
1562 : : * \return If this function fails, the key slot is an invalid state.
1563 : : * You must call psa_fail_key_creation() to wipe and free the slot.
1564 : : */
1565 : 172 : static psa_status_t psa_start_key_creation(
1566 : : psa_key_creation_method_t method,
1567 : : const psa_key_attributes_t *attributes,
1568 : : psa_key_slot_t **p_slot,
1569 : : psa_se_drv_table_entry_t **p_drv )
1570 : : {
1571 : 172 : psa_status_t status;
1572 : 172 : psa_key_id_t volatile_key_id;
1573 : 172 : psa_key_slot_t *slot;
1574 : :
1575 : 172 : (void) method;
1576 : 172 : *p_drv = NULL;
1577 : :
1578 : 172 : status = psa_validate_key_attributes( attributes, p_drv );
1579 [ + - ]: 172 : if( status != PSA_SUCCESS )
1580 : : return( status );
1581 : :
1582 : 172 : status = psa_get_empty_key_slot( &volatile_key_id, p_slot );
1583 [ + - ]: 172 : if( status != PSA_SUCCESS )
1584 : : return( status );
1585 : 172 : slot = *p_slot;
1586 : :
1587 : : /* We're storing the declared bit-size of the key. It's up to each
1588 : : * creation mechanism to verify that this information is correct.
1589 : : * It's automatically correct for mechanisms that use the bit-size as
1590 : : * an input (generate, device) but not for those where the bit-size
1591 : : * is optional (import, copy). In case of a volatile key, assign it the
1592 : : * volatile key identifier associated to the slot returned to contain its
1593 : : * definition. */
1594 : :
1595 : 172 : slot->attr = attributes->core;
1596 [ + - ]: 172 : if( PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
1597 : : {
1598 : : #if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
1599 : 172 : slot->attr.id = volatile_key_id;
1600 : : #else
1601 : : slot->attr.id.key_id = volatile_key_id;
1602 : : #endif
1603 : : }
1604 : :
1605 : : /* Erase external-only flags from the internal copy. To access
1606 : : * external-only flags, query `attributes`. Thanks to the check
1607 : : * in psa_validate_key_attributes(), this leaves the dual-use
1608 : : * flags and any internal flag that psa_get_empty_key_slot()
1609 : : * may have set. */
1610 : 172 : slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
1611 : :
1612 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1613 : : /* For a key in a secure element, we need to do three things
1614 : : * when creating or registering a persistent key:
1615 : : * create the key file in internal storage, create the
1616 : : * key inside the secure element, and update the driver's
1617 : : * persistent data. This is done by starting a transaction that will
1618 : : * encompass these three actions.
1619 : : * For registering a volatile key, we just need to find an appropriate
1620 : : * slot number inside the SE. Since the key is designated volatile, creating
1621 : : * a transaction is not required. */
1622 : : /* The first thing to do is to find a slot number for the new key.
1623 : : * We save the slot number in persistent storage as part of the
1624 : : * transaction data. It will be needed to recover if the power
1625 : : * fails during the key creation process, to clean up on the secure
1626 : : * element side after restarting. Obtaining a slot number from the
1627 : : * secure element driver updates its persistent state, but we do not yet
1628 : : * save the driver's persistent state, so that if the power fails,
1629 : : * we can roll back to a state where the key doesn't exist. */
1630 : : if( *p_drv != NULL )
1631 : : {
1632 : : psa_key_slot_number_t slot_number;
1633 : : status = psa_find_se_slot_for_key( attributes, method, *p_drv,
1634 : : &slot_number );
1635 : : if( status != PSA_SUCCESS )
1636 : : return( status );
1637 : :
1638 : : if( ! PSA_KEY_LIFETIME_IS_VOLATILE( attributes->core.lifetime ) )
1639 : : {
1640 : : psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_CREATE_KEY );
1641 : : psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
1642 : : psa_crypto_transaction.key.slot = slot_number;
1643 : : psa_crypto_transaction.key.id = slot->attr.id;
1644 : : status = psa_crypto_save_transaction( );
1645 : : if( status != PSA_SUCCESS )
1646 : : {
1647 : : (void) psa_crypto_stop_transaction( );
1648 : : return( status );
1649 : : }
1650 : : }
1651 : :
1652 : : status = psa_copy_key_material_into_slot(
1653 : : slot, (uint8_t *)( &slot_number ), sizeof( slot_number ) );
1654 : : }
1655 : :
1656 : : if( *p_drv == NULL && method == PSA_KEY_CREATION_REGISTER )
1657 : : {
1658 : : /* Key registration only makes sense with a secure element. */
1659 : : return( PSA_ERROR_INVALID_ARGUMENT );
1660 : : }
1661 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1662 : :
1663 : 172 : return( PSA_SUCCESS );
1664 : : }
1665 : :
1666 : : /** Finalize the creation of a key once its key material has been set.
1667 : : *
1668 : : * This entails writing the key to persistent storage.
1669 : : *
1670 : : * If this function fails, call psa_fail_key_creation().
1671 : : * See the documentation of psa_start_key_creation() for the intended use
1672 : : * of this function.
1673 : : *
1674 : : * If the finalization succeeds, the function unlocks the key slot (it was
1675 : : * locked by psa_start_key_creation()) and the key slot cannot be accessed
1676 : : * anymore as part of the key creation process.
1677 : : *
1678 : : * \param[in,out] slot Pointer to the slot with key material.
1679 : : * \param[in] driver The secure element driver for the key,
1680 : : * or NULL for a transparent key.
1681 : : * \param[out] key On success, identifier of the key. Note that the
1682 : : * key identifier is also stored in the key slot.
1683 : : *
1684 : : * \retval #PSA_SUCCESS
1685 : : * The key was successfully created.
1686 : : * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
1687 : : * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
1688 : : * \retval #PSA_ERROR_ALREADY_EXISTS
1689 : : * \retval #PSA_ERROR_DATA_INVALID
1690 : : * \retval #PSA_ERROR_DATA_CORRUPT
1691 : : * \retval #PSA_ERROR_STORAGE_FAILURE
1692 : : *
1693 : : * \return If this function fails, the key slot is an invalid state.
1694 : : * You must call psa_fail_key_creation() to wipe and free the slot.
1695 : : */
1696 : 172 : static psa_status_t psa_finish_key_creation(
1697 : : psa_key_slot_t *slot,
1698 : : psa_se_drv_table_entry_t *driver,
1699 : : mbedtls_svc_key_id_t *key)
1700 : : {
1701 : 172 : psa_status_t status = PSA_SUCCESS;
1702 : 172 : (void) slot;
1703 : 172 : (void) driver;
1704 : :
1705 : : #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
1706 : : if( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
1707 : : {
1708 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1709 : : if( driver != NULL )
1710 : : {
1711 : : psa_se_key_data_storage_t data;
1712 : : psa_key_slot_number_t slot_number =
1713 : : psa_key_slot_get_slot_number( slot ) ;
1714 : :
1715 : : #if defined(static_assert)
1716 : : static_assert( sizeof( slot_number ) ==
1717 : : sizeof( data.slot_number ),
1718 : : "Slot number size does not match psa_se_key_data_storage_t" );
1719 : : #endif
1720 : : memcpy( &data.slot_number, &slot_number, sizeof( slot_number ) );
1721 : : status = psa_save_persistent_key( &slot->attr,
1722 : : (uint8_t*) &data,
1723 : : sizeof( data ) );
1724 : : }
1725 : : else
1726 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1727 : : {
1728 : : /* Key material is saved in export representation in the slot, so
1729 : : * just pass the slot buffer for storage. */
1730 : : status = psa_save_persistent_key( &slot->attr,
1731 : : slot->key.data,
1732 : : slot->key.bytes );
1733 : : }
1734 : : }
1735 : : #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1736 : :
1737 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1738 : : /* Finish the transaction for a key creation. This does not
1739 : : * happen when registering an existing key. Detect this case
1740 : : * by checking whether a transaction is in progress (actual
1741 : : * creation of a persistent key in a secure element requires a transaction,
1742 : : * but registration or volatile key creation doesn't use one). */
1743 : : if( driver != NULL &&
1744 : : psa_crypto_transaction.unknown.type == PSA_CRYPTO_TRANSACTION_CREATE_KEY )
1745 : : {
1746 : : status = psa_save_se_persistent_data( driver );
1747 : : if( status != PSA_SUCCESS )
1748 : : {
1749 : : psa_destroy_persistent_key( slot->attr.id );
1750 : : return( status );
1751 : : }
1752 : : status = psa_crypto_stop_transaction( );
1753 : : }
1754 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1755 : :
1756 : 172 : if( status == PSA_SUCCESS )
1757 : : {
1758 : 172 : *key = slot->attr.id;
1759 : 172 : status = psa_unlock_key_slot( slot );
1760 [ - + ]: 172 : if( status != PSA_SUCCESS )
1761 : 0 : *key = MBEDTLS_SVC_KEY_ID_INIT;
1762 : : }
1763 : :
1764 : 172 : return( status );
1765 : : }
1766 : :
1767 : : /** Abort the creation of a key.
1768 : : *
1769 : : * You may call this function after calling psa_start_key_creation(),
1770 : : * or after psa_finish_key_creation() fails. In other circumstances, this
1771 : : * function may not clean up persistent storage.
1772 : : * See the documentation of psa_start_key_creation() for the intended use
1773 : : * of this function.
1774 : : *
1775 : : * \param[in,out] slot Pointer to the slot with key material.
1776 : : * \param[in] driver The secure element driver for the key,
1777 : : * or NULL for a transparent key.
1778 : : */
1779 : 0 : static void psa_fail_key_creation( psa_key_slot_t *slot,
1780 : : psa_se_drv_table_entry_t *driver )
1781 : : {
1782 : 0 : (void) driver;
1783 : :
1784 [ # # ]: 0 : if( slot == NULL )
1785 : : return;
1786 : :
1787 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1788 : : /* TODO: If the key has already been created in the secure
1789 : : * element, and the failure happened later (when saving metadata
1790 : : * to internal storage), we need to destroy the key in the secure
1791 : : * element.
1792 : : * https://github.com/ARMmbed/mbed-crypto/issues/217
1793 : : */
1794 : :
1795 : : /* Abort the ongoing transaction if any (there may not be one if
1796 : : * the creation process failed before starting one, or if the
1797 : : * key creation is a registration of a key in a secure element).
1798 : : * Earlier functions must already have done what it takes to undo any
1799 : : * partial creation. All that's left is to update the transaction data
1800 : : * itself. */
1801 : : (void) psa_crypto_stop_transaction( );
1802 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1803 : :
1804 : 0 : psa_wipe_key_slot( slot );
1805 : : }
1806 : :
1807 : : /** Validate optional attributes during key creation.
1808 : : *
1809 : : * Some key attributes are optional during key creation. If they are
1810 : : * specified in the attributes structure, check that they are consistent
1811 : : * with the data in the slot.
1812 : : *
1813 : : * This function should be called near the end of key creation, after
1814 : : * the slot in memory is fully populated but before saving persistent data.
1815 : : */
1816 : 172 : static psa_status_t psa_validate_optional_attributes(
1817 : : const psa_key_slot_t *slot,
1818 : : const psa_key_attributes_t *attributes )
1819 : : {
1820 [ + - ]: 172 : if( attributes->core.type != 0 )
1821 : : {
1822 [ + - ]: 172 : if( attributes->core.type != slot->attr.type )
1823 : : return( PSA_ERROR_INVALID_ARGUMENT );
1824 : : }
1825 : :
1826 [ + - ]: 172 : if( attributes->domain_parameters_size != 0 )
1827 : : {
1828 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1829 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
1830 : : if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
1831 : : {
1832 : : mbedtls_rsa_context *rsa = NULL;
1833 : : mbedtls_mpi actual, required;
1834 : : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1835 : :
1836 : : psa_status_t status = mbedtls_psa_rsa_load_representation(
1837 : : slot->attr.type,
1838 : : slot->key.data,
1839 : : slot->key.bytes,
1840 : : &rsa );
1841 : : if( status != PSA_SUCCESS )
1842 : : return( status );
1843 : :
1844 : : mbedtls_mpi_init( &actual );
1845 : : mbedtls_mpi_init( &required );
1846 : : ret = mbedtls_rsa_export( rsa,
1847 : : NULL, NULL, NULL, NULL, &actual );
1848 : : mbedtls_rsa_free( rsa );
1849 : : mbedtls_free( rsa );
1850 : : if( ret != 0 )
1851 : : goto rsa_exit;
1852 : : ret = mbedtls_mpi_read_binary( &required,
1853 : : attributes->domain_parameters,
1854 : : attributes->domain_parameters_size );
1855 : : if( ret != 0 )
1856 : : goto rsa_exit;
1857 : : if( mbedtls_mpi_cmp_mpi( &actual, &required ) != 0 )
1858 : : ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1859 : : rsa_exit:
1860 : : mbedtls_mpi_free( &actual );
1861 : : mbedtls_mpi_free( &required );
1862 : : if( ret != 0)
1863 : : return( mbedtls_to_psa_error( ret ) );
1864 : : }
1865 : : else
1866 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1867 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
1868 : : {
1869 : : return( PSA_ERROR_INVALID_ARGUMENT );
1870 : : }
1871 : : }
1872 : :
1873 [ + + ]: 172 : if( attributes->core.bits != 0 )
1874 : : {
1875 [ - + ]: 44 : if( attributes->core.bits != slot->attr.bits )
1876 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
1877 : : }
1878 : :
1879 : : return( PSA_SUCCESS );
1880 : : }
1881 : :
1882 : 172 : psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
1883 : : const uint8_t *data,
1884 : : size_t data_length,
1885 : : mbedtls_svc_key_id_t *key )
1886 : : {
1887 : 172 : psa_status_t status;
1888 : 172 : psa_key_slot_t *slot = NULL;
1889 : 172 : psa_se_drv_table_entry_t *driver = NULL;
1890 : 172 : size_t bits;
1891 : 172 : size_t storage_size = data_length;
1892 : :
1893 : 172 : *key = MBEDTLS_SVC_KEY_ID_INIT;
1894 : :
1895 : : /* Reject zero-length symmetric keys (including raw data key objects).
1896 : : * This also rejects any key which might be encoded as an empty string,
1897 : : * which is never valid. */
1898 [ + - ]: 172 : if( data_length == 0 )
1899 : : return( PSA_ERROR_INVALID_ARGUMENT );
1900 : :
1901 : : /* Ensure that the bytes-to-bits conversion cannot overflow. */
1902 [ + - ]: 172 : if( data_length > SIZE_MAX / 8 )
1903 : : return( PSA_ERROR_NOT_SUPPORTED );
1904 : :
1905 : 172 : status = psa_start_key_creation( PSA_KEY_CREATION_IMPORT, attributes,
1906 : : &slot, &driver );
1907 [ - + ]: 172 : if( status != PSA_SUCCESS )
1908 : 0 : goto exit;
1909 : :
1910 : : /* In the case of a transparent key or an opaque key stored in local
1911 : : * storage ( thus not in the case of importing a key in a secure element
1912 : : * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
1913 : : * buffer to hold the imported key material. */
1914 [ + - ]: 172 : if( slot->key.data == NULL )
1915 : : {
1916 [ - + ]: 172 : if( psa_key_lifetime_is_external( attributes->core.lifetime ) )
1917 : : {
1918 : 0 : status = psa_driver_wrapper_get_key_buffer_size_from_key_data(
1919 : : attributes, data, data_length, &storage_size );
1920 [ # # ]: 0 : if( status != PSA_SUCCESS )
1921 : 0 : goto exit;
1922 : : }
1923 : 172 : status = psa_allocate_buffer_to_slot( slot, storage_size );
1924 [ - + ]: 172 : if( status != PSA_SUCCESS )
1925 : 0 : goto exit;
1926 : : }
1927 : :
1928 : 172 : bits = slot->attr.bits;
1929 : 172 : status = psa_driver_wrapper_import_key( attributes,
1930 : : data, data_length,
1931 : : slot->key.data,
1932 : : slot->key.bytes,
1933 : : &slot->key.bytes, &bits );
1934 [ - + ]: 172 : if( status != PSA_SUCCESS )
1935 : 0 : goto exit;
1936 : :
1937 [ + + ]: 172 : if( slot->attr.bits == 0 )
1938 : 128 : slot->attr.bits = (psa_key_bits_t) bits;
1939 [ - + ]: 44 : else if( bits != slot->attr.bits )
1940 : : {
1941 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
1942 : 0 : goto exit;
1943 : : }
1944 : :
1945 : : /* Enforce a size limit, and in particular ensure that the bit
1946 : : * size fits in its representation type.*/
1947 [ - + ]: 172 : if( bits > PSA_MAX_KEY_BITS )
1948 : : {
1949 : 0 : status = PSA_ERROR_NOT_SUPPORTED;
1950 : 0 : goto exit;
1951 : : }
1952 : 172 : status = psa_validate_optional_attributes( slot, attributes );
1953 [ - + ]: 172 : if( status != PSA_SUCCESS )
1954 : 0 : goto exit;
1955 : :
1956 : 172 : status = psa_finish_key_creation( slot, driver, key );
1957 : 172 : exit:
1958 [ - + ]: 172 : if( status != PSA_SUCCESS )
1959 : 0 : psa_fail_key_creation( slot, driver );
1960 : :
1961 : : return( status );
1962 : : }
1963 : :
1964 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1965 : : psa_status_t mbedtls_psa_register_se_key(
1966 : : const psa_key_attributes_t *attributes )
1967 : : {
1968 : : psa_status_t status;
1969 : : psa_key_slot_t *slot = NULL;
1970 : : psa_se_drv_table_entry_t *driver = NULL;
1971 : : mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
1972 : :
1973 : : /* Leaving attributes unspecified is not currently supported.
1974 : : * It could make sense to query the key type and size from the
1975 : : * secure element, but not all secure elements support this
1976 : : * and the driver HAL doesn't currently support it. */
1977 : : if( psa_get_key_type( attributes ) == PSA_KEY_TYPE_NONE )
1978 : : return( PSA_ERROR_NOT_SUPPORTED );
1979 : : if( psa_get_key_bits( attributes ) == 0 )
1980 : : return( PSA_ERROR_NOT_SUPPORTED );
1981 : :
1982 : : status = psa_start_key_creation( PSA_KEY_CREATION_REGISTER, attributes,
1983 : : &slot, &driver );
1984 : : if( status != PSA_SUCCESS )
1985 : : goto exit;
1986 : :
1987 : : status = psa_finish_key_creation( slot, driver, &key );
1988 : :
1989 : : exit:
1990 : : if( status != PSA_SUCCESS )
1991 : : psa_fail_key_creation( slot, driver );
1992 : :
1993 : : /* Registration doesn't keep the key in RAM. */
1994 : : psa_close_key( key );
1995 : : return( status );
1996 : : }
1997 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1998 : :
1999 : 0 : psa_status_t psa_copy_key( mbedtls_svc_key_id_t source_key,
2000 : : const psa_key_attributes_t *specified_attributes,
2001 : : mbedtls_svc_key_id_t *target_key )
2002 : : {
2003 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2004 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2005 : 0 : psa_key_slot_t *source_slot = NULL;
2006 : 0 : psa_key_slot_t *target_slot = NULL;
2007 : 0 : psa_key_attributes_t actual_attributes = *specified_attributes;
2008 : 0 : psa_se_drv_table_entry_t *driver = NULL;
2009 : 0 : size_t storage_size = 0;
2010 : :
2011 : 0 : *target_key = MBEDTLS_SVC_KEY_ID_INIT;
2012 : :
2013 : 0 : status = psa_get_and_lock_key_slot_with_policy(
2014 : : source_key, &source_slot, PSA_KEY_USAGE_COPY, 0 );
2015 [ # # ]: 0 : if( status != PSA_SUCCESS )
2016 : 0 : goto exit;
2017 : :
2018 : 0 : status = psa_validate_optional_attributes( source_slot,
2019 : : specified_attributes );
2020 [ # # ]: 0 : if( status != PSA_SUCCESS )
2021 : 0 : goto exit;
2022 : :
2023 : : /* The target key type and number of bits have been validated by
2024 : : * psa_validate_optional_attributes() to be either equal to zero or
2025 : : * equal to the ones of the source key. So it is safe to inherit
2026 : : * them from the source key now."
2027 : : * */
2028 : 0 : actual_attributes.core.bits = source_slot->attr.bits;
2029 : 0 : actual_attributes.core.type = source_slot->attr.type;
2030 : :
2031 : :
2032 : 0 : status = psa_restrict_key_policy( source_slot->attr.type,
2033 : : &actual_attributes.core.policy,
2034 : 0 : &source_slot->attr.policy );
2035 [ # # ]: 0 : if( status != PSA_SUCCESS )
2036 : 0 : goto exit;
2037 : :
2038 : 0 : status = psa_start_key_creation( PSA_KEY_CREATION_COPY, &actual_attributes,
2039 : : &target_slot, &driver );
2040 [ # # ]: 0 : if( status != PSA_SUCCESS )
2041 : 0 : goto exit;
2042 : 0 : if( PSA_KEY_LIFETIME_GET_LOCATION( target_slot->attr.lifetime ) !=
2043 [ # # ]: 0 : PSA_KEY_LIFETIME_GET_LOCATION( source_slot->attr.lifetime ) )
2044 : : {
2045 : : /*
2046 : : * If the source and target keys are stored in different locations,
2047 : : * the source key would need to be exported as plaintext and re-imported
2048 : : * in the other location. This has security implications which have not
2049 : : * been fully mapped. For now, this can be achieved through
2050 : : * appropriate API invocations from the application, if needed.
2051 : : * */
2052 : 0 : status = PSA_ERROR_NOT_SUPPORTED;
2053 : 0 : goto exit;
2054 : : }
2055 : : /*
2056 : : * When the source and target keys are within the same location,
2057 : : * - For transparent keys it is a blind copy without any driver invocation,
2058 : : * - For opaque keys this translates to an invocation of the drivers'
2059 : : * copy_key entry point through the dispatch layer.
2060 : : * */
2061 [ # # ]: 0 : if( psa_key_lifetime_is_external( actual_attributes.core.lifetime ) )
2062 : : {
2063 : 0 : status = psa_driver_wrapper_get_key_buffer_size( &actual_attributes,
2064 : : &storage_size );
2065 [ # # ]: 0 : if( status != PSA_SUCCESS )
2066 : 0 : goto exit;
2067 : :
2068 : 0 : status = psa_allocate_buffer_to_slot( target_slot, storage_size );
2069 [ # # ]: 0 : if( status != PSA_SUCCESS )
2070 : 0 : goto exit;
2071 : :
2072 : 0 : status = psa_driver_wrapper_copy_key( &actual_attributes,
2073 : 0 : source_slot->key.data,
2074 : 0 : source_slot->key.bytes,
2075 : : target_slot->key.data,
2076 : : target_slot->key.bytes,
2077 : : &target_slot->key.bytes );
2078 [ # # ]: 0 : if( status != PSA_SUCCESS )
2079 : 0 : goto exit;
2080 : : }
2081 : : else
2082 : : {
2083 : 0 : status = psa_copy_key_material_into_slot( target_slot,
2084 : 0 : source_slot->key.data,
2085 : : source_slot->key.bytes );
2086 [ # # ]: 0 : if( status != PSA_SUCCESS )
2087 : 0 : goto exit;
2088 : : }
2089 : 0 : status = psa_finish_key_creation( target_slot, driver, target_key );
2090 : 0 : exit:
2091 [ # # ]: 0 : if( status != PSA_SUCCESS )
2092 : 0 : psa_fail_key_creation( target_slot, driver );
2093 : :
2094 : 0 : unlock_status = psa_unlock_key_slot( source_slot );
2095 : :
2096 [ # # ]: 0 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
2097 : : }
2098 : :
2099 : :
2100 : :
2101 : : /****************************************************************/
2102 : : /* Message digests */
2103 : : /****************************************************************/
2104 : :
2105 : 462 : psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
2106 : : {
2107 : : /* Aborting a non-active operation is allowed */
2108 [ + + ]: 462 : if( operation->id == 0 )
2109 : : return( PSA_SUCCESS );
2110 : :
2111 : 308 : psa_status_t status = psa_driver_wrapper_hash_abort( operation );
2112 : 308 : operation->id = 0;
2113 : :
2114 : 308 : return( status );
2115 : : }
2116 : :
2117 : 308 : psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
2118 : : psa_algorithm_t alg )
2119 : : {
2120 : 308 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2121 : :
2122 : : /* A context must be freshly initialized before it can be set up. */
2123 [ - + ]: 308 : if( operation->id != 0 )
2124 : : {
2125 : 0 : status = PSA_ERROR_BAD_STATE;
2126 : 0 : goto exit;
2127 : : }
2128 : :
2129 [ - + ]: 308 : if( !PSA_ALG_IS_HASH( alg ) )
2130 : : {
2131 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
2132 : 0 : goto exit;
2133 : : }
2134 : :
2135 : : /* Ensure all of the context is zeroized, since PSA_HASH_OPERATION_INIT only
2136 : : * directly zeroes the int-sized dummy member of the context union. */
2137 : 308 : memset( &operation->ctx, 0, sizeof( operation->ctx ) );
2138 : :
2139 : 308 : status = psa_driver_wrapper_hash_setup( operation, alg );
2140 : :
2141 : 308 : exit:
2142 [ - + ]: 308 : if( status != PSA_SUCCESS )
2143 : 0 : psa_hash_abort( operation );
2144 : :
2145 : 308 : return status;
2146 : : }
2147 : :
2148 : 616 : psa_status_t psa_hash_update( psa_hash_operation_t *operation,
2149 : : const uint8_t *input,
2150 : : size_t input_length )
2151 : : {
2152 : 616 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2153 : :
2154 [ - + ]: 616 : if( operation->id == 0 )
2155 : : {
2156 : 0 : status = PSA_ERROR_BAD_STATE;
2157 : 0 : goto exit;
2158 : : }
2159 : :
2160 : : /* Don't require hash implementations to behave correctly on a
2161 : : * zero-length input, which may have an invalid pointer. */
2162 [ + - ]: 616 : if( input_length == 0 )
2163 : : return( PSA_SUCCESS );
2164 : :
2165 : 616 : status = psa_driver_wrapper_hash_update( operation, input, input_length );
2166 : :
2167 : 616 : exit:
2168 [ - + ]: 616 : if( status != PSA_SUCCESS )
2169 : 0 : psa_hash_abort( operation );
2170 : :
2171 : : return( status );
2172 : : }
2173 : :
2174 : 308 : psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
2175 : : uint8_t *hash,
2176 : : size_t hash_size,
2177 : : size_t *hash_length )
2178 : : {
2179 : 308 : *hash_length = 0;
2180 [ + - ]: 308 : if( operation->id == 0 )
2181 : : return( PSA_ERROR_BAD_STATE );
2182 : :
2183 : 308 : psa_status_t status = psa_driver_wrapper_hash_finish(
2184 : : operation, hash, hash_size, hash_length );
2185 : 308 : psa_hash_abort( operation );
2186 : 308 : return( status );
2187 : : }
2188 : :
2189 : 0 : psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
2190 : : const uint8_t *hash,
2191 : : size_t hash_length )
2192 : : {
2193 : 0 : uint8_t actual_hash[PSA_HASH_MAX_SIZE];
2194 : 0 : size_t actual_hash_length;
2195 : 0 : psa_status_t status = psa_hash_finish(
2196 : : operation,
2197 : : actual_hash, sizeof( actual_hash ),
2198 : : &actual_hash_length );
2199 : :
2200 [ # # ]: 0 : if( status != PSA_SUCCESS )
2201 : 0 : goto exit;
2202 : :
2203 [ # # ]: 0 : if( actual_hash_length != hash_length )
2204 : : {
2205 : 0 : status = PSA_ERROR_INVALID_SIGNATURE;
2206 : 0 : goto exit;
2207 : : }
2208 : :
2209 [ # # ]: 0 : if( mbedtls_psa_safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
2210 : 0 : status = PSA_ERROR_INVALID_SIGNATURE;
2211 : :
2212 : 0 : exit:
2213 : 0 : mbedtls_platform_zeroize( actual_hash, sizeof( actual_hash ) );
2214 [ # # ]: 0 : if( status != PSA_SUCCESS )
2215 : 0 : psa_hash_abort(operation);
2216 : :
2217 : 0 : return( status );
2218 : : }
2219 : :
2220 : 24 : psa_status_t psa_hash_compute( psa_algorithm_t alg,
2221 : : const uint8_t *input, size_t input_length,
2222 : : uint8_t *hash, size_t hash_size,
2223 : : size_t *hash_length )
2224 : : {
2225 : 24 : *hash_length = 0;
2226 [ + - ]: 24 : if( !PSA_ALG_IS_HASH( alg ) )
2227 : : return( PSA_ERROR_INVALID_ARGUMENT );
2228 : :
2229 : 24 : return( psa_driver_wrapper_hash_compute( alg, input, input_length,
2230 : : hash, hash_size, hash_length ) );
2231 : : }
2232 : :
2233 : 0 : psa_status_t psa_hash_compare( psa_algorithm_t alg,
2234 : : const uint8_t *input, size_t input_length,
2235 : : const uint8_t *hash, size_t hash_length )
2236 : : {
2237 : 0 : uint8_t actual_hash[PSA_HASH_MAX_SIZE];
2238 : 0 : size_t actual_hash_length;
2239 : :
2240 [ # # ]: 0 : if( !PSA_ALG_IS_HASH( alg ) )
2241 : : return( PSA_ERROR_INVALID_ARGUMENT );
2242 : :
2243 : 0 : psa_status_t status = psa_driver_wrapper_hash_compute(
2244 : : alg, input, input_length,
2245 : : actual_hash, sizeof(actual_hash),
2246 : : &actual_hash_length );
2247 [ # # ]: 0 : if( status != PSA_SUCCESS )
2248 : 0 : goto exit;
2249 [ # # ]: 0 : if( actual_hash_length != hash_length )
2250 : : {
2251 : 0 : status = PSA_ERROR_INVALID_SIGNATURE;
2252 : 0 : goto exit;
2253 : : }
2254 [ # # ]: 0 : if( mbedtls_psa_safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
2255 : 0 : status = PSA_ERROR_INVALID_SIGNATURE;
2256 : :
2257 : 0 : exit:
2258 : 0 : mbedtls_platform_zeroize( actual_hash, sizeof( actual_hash ) );
2259 : 0 : return( status );
2260 : : }
2261 : :
2262 : 0 : psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation,
2263 : : psa_hash_operation_t *target_operation )
2264 : : {
2265 [ # # ]: 0 : if( source_operation->id == 0 ||
2266 [ # # ]: 0 : target_operation->id != 0 )
2267 : : {
2268 : : return( PSA_ERROR_BAD_STATE );
2269 : : }
2270 : :
2271 : 0 : psa_status_t status = psa_driver_wrapper_hash_clone( source_operation,
2272 : : target_operation );
2273 [ # # ]: 0 : if( status != PSA_SUCCESS )
2274 : 0 : psa_hash_abort( target_operation );
2275 : :
2276 : : return( status );
2277 : : }
2278 : :
2279 : :
2280 : : /****************************************************************/
2281 : : /* MAC */
2282 : : /****************************************************************/
2283 : :
2284 : 0 : psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
2285 : : {
2286 : : /* Aborting a non-active operation is allowed */
2287 [ # # ]: 0 : if( operation->id == 0 )
2288 : : return( PSA_SUCCESS );
2289 : :
2290 : 0 : psa_status_t status = psa_driver_wrapper_mac_abort( operation );
2291 : 0 : operation->mac_size = 0;
2292 : 0 : operation->is_sign = 0;
2293 : 0 : operation->id = 0;
2294 : :
2295 : 0 : return( status );
2296 : : }
2297 : :
2298 : 154 : static psa_status_t psa_mac_finalize_alg_and_key_validation(
2299 : : psa_algorithm_t alg,
2300 : : const psa_key_attributes_t *attributes,
2301 : : uint8_t *mac_size )
2302 : : {
2303 : 154 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2304 : 154 : psa_key_type_t key_type = psa_get_key_type( attributes );
2305 : 154 : size_t key_bits = psa_get_key_bits( attributes );
2306 : :
2307 [ + - ]: 154 : if( ! PSA_ALG_IS_MAC( alg ) )
2308 : : return( PSA_ERROR_INVALID_ARGUMENT );
2309 : :
2310 : : /* Validate the combination of key type and algorithm */
2311 : 154 : status = psa_mac_key_can_do( alg, key_type );
2312 [ + - ]: 154 : if( status != PSA_SUCCESS )
2313 : : return( status );
2314 : :
2315 : : /* Get the output length for the algorithm and key combination */
2316 [ - + + - : 154 : *mac_size = PSA_MAC_LENGTH( key_type, key_bits, alg );
+ - - - -
- ]
2317 : :
2318 [ + - ]: 154 : if( *mac_size < 4 )
2319 : : {
2320 : : /* A very short MAC is too short for security since it can be
2321 : : * brute-forced. Ancient protocols with 32-bit MACs do exist,
2322 : : * so we make this our minimum, even though 32 bits is still
2323 : : * too small for security. */
2324 : : return( PSA_ERROR_NOT_SUPPORTED );
2325 : : }
2326 : :
2327 [ + - + - : 308 : if( *mac_size > PSA_MAC_LENGTH( key_type, key_bits,
- - - - -
+ ]
2328 : : PSA_ALG_FULL_LENGTH_MAC( alg ) ) )
2329 : : {
2330 : : /* It's impossible to "truncate" to a larger length than the full length
2331 : : * of the algorithm. */
2332 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
2333 : : }
2334 : :
2335 : : return( PSA_SUCCESS );
2336 : : }
2337 : :
2338 : 0 : static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
2339 : : mbedtls_svc_key_id_t key,
2340 : : psa_algorithm_t alg,
2341 : : int is_sign )
2342 : : {
2343 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2344 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2345 : 0 : psa_key_slot_t *slot = NULL;
2346 : :
2347 : : /* A context must be freshly initialized before it can be set up. */
2348 [ # # ]: 0 : if( operation->id != 0 )
2349 : : {
2350 : 0 : status = PSA_ERROR_BAD_STATE;
2351 : 0 : goto exit;
2352 : : }
2353 : :
2354 [ # # ]: 0 : status = psa_get_and_lock_key_slot_with_policy(
2355 : : key,
2356 : : &slot,
2357 : : is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE,
2358 : : alg );
2359 [ # # ]: 0 : if( status != PSA_SUCCESS )
2360 : 0 : goto exit;
2361 : :
2362 : 0 : psa_key_attributes_t attributes = {
2363 : 0 : .core = slot->attr
2364 : : };
2365 : :
2366 : 0 : status = psa_mac_finalize_alg_and_key_validation( alg, &attributes,
2367 : : &operation->mac_size );
2368 [ # # ]: 0 : if( status != PSA_SUCCESS )
2369 : 0 : goto exit;
2370 : :
2371 : 0 : operation->is_sign = is_sign;
2372 : : /* Dispatch the MAC setup call with validated input */
2373 [ # # ]: 0 : if( is_sign )
2374 : : {
2375 : 0 : status = psa_driver_wrapper_mac_sign_setup( operation,
2376 : : &attributes,
2377 : 0 : slot->key.data,
2378 : : slot->key.bytes,
2379 : : alg );
2380 : : }
2381 : : else
2382 : : {
2383 : 0 : status = psa_driver_wrapper_mac_verify_setup( operation,
2384 : : &attributes,
2385 : 0 : slot->key.data,
2386 : : slot->key.bytes,
2387 : : alg );
2388 : : }
2389 : :
2390 : 0 : exit:
2391 [ # # ]: 0 : if( status != PSA_SUCCESS )
2392 : 0 : psa_mac_abort( operation );
2393 : :
2394 : 0 : unlock_status = psa_unlock_key_slot( slot );
2395 : :
2396 [ # # ]: 0 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
2397 : : }
2398 : :
2399 : 0 : psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
2400 : : mbedtls_svc_key_id_t key,
2401 : : psa_algorithm_t alg )
2402 : : {
2403 : 0 : return( psa_mac_setup( operation, key, alg, 1 ) );
2404 : : }
2405 : :
2406 : 0 : psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
2407 : : mbedtls_svc_key_id_t key,
2408 : : psa_algorithm_t alg )
2409 : : {
2410 : 0 : return( psa_mac_setup( operation, key, alg, 0 ) );
2411 : : }
2412 : :
2413 : 0 : psa_status_t psa_mac_update( psa_mac_operation_t *operation,
2414 : : const uint8_t *input,
2415 : : size_t input_length )
2416 : : {
2417 [ # # ]: 0 : if( operation->id == 0 )
2418 : : return( PSA_ERROR_BAD_STATE );
2419 : :
2420 : : /* Don't require hash implementations to behave correctly on a
2421 : : * zero-length input, which may have an invalid pointer. */
2422 [ # # ]: 0 : if( input_length == 0 )
2423 : : return( PSA_SUCCESS );
2424 : :
2425 : 0 : psa_status_t status = psa_driver_wrapper_mac_update( operation,
2426 : : input, input_length );
2427 [ # # ]: 0 : if( status != PSA_SUCCESS )
2428 : 0 : psa_mac_abort( operation );
2429 : :
2430 : : return( status );
2431 : : }
2432 : :
2433 : 0 : psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
2434 : : uint8_t *mac,
2435 : : size_t mac_size,
2436 : : size_t *mac_length )
2437 : : {
2438 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2439 : 0 : psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
2440 : :
2441 [ # # ]: 0 : if( operation->id == 0 )
2442 : : {
2443 : 0 : status = PSA_ERROR_BAD_STATE;
2444 : 0 : goto exit;
2445 : : }
2446 : :
2447 [ # # ]: 0 : if( ! operation->is_sign )
2448 : : {
2449 : 0 : status = PSA_ERROR_BAD_STATE;
2450 : 0 : goto exit;
2451 : : }
2452 : :
2453 : : /* Sanity check. This will guarantee that mac_size != 0 (and so mac != NULL)
2454 : : * once all the error checks are done. */
2455 [ # # ]: 0 : if( operation->mac_size == 0 )
2456 : : {
2457 : 0 : status = PSA_ERROR_BAD_STATE;
2458 : 0 : goto exit;
2459 : : }
2460 : :
2461 [ # # ]: 0 : if( mac_size < operation->mac_size )
2462 : : {
2463 : 0 : status = PSA_ERROR_BUFFER_TOO_SMALL;
2464 : 0 : goto exit;
2465 : : }
2466 : :
2467 : 0 : status = psa_driver_wrapper_mac_sign_finish( operation,
2468 : : mac, operation->mac_size,
2469 : : mac_length );
2470 : :
2471 : 0 : exit:
2472 : : /* In case of success, set the potential excess room in the output buffer
2473 : : * to an invalid value, to avoid potentially leaking a longer MAC.
2474 : : * In case of error, set the output length and content to a safe default,
2475 : : * such that in case the caller misses an error check, the output would be
2476 : : * an unachievable MAC.
2477 : : */
2478 [ # # ]: 0 : if( status != PSA_SUCCESS )
2479 : : {
2480 : 0 : *mac_length = mac_size;
2481 : 0 : operation->mac_size = 0;
2482 : : }
2483 : :
2484 [ # # ]: 0 : if( mac_size > operation->mac_size )
2485 : 0 : memset( &mac[operation->mac_size], '!',
2486 : : mac_size - operation->mac_size );
2487 : :
2488 : 0 : abort_status = psa_mac_abort( operation );
2489 : :
2490 [ # # ]: 0 : return( status == PSA_SUCCESS ? abort_status : status );
2491 : : }
2492 : :
2493 : 0 : psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
2494 : : const uint8_t *mac,
2495 : : size_t mac_length )
2496 : : {
2497 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2498 : 0 : psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
2499 : :
2500 [ # # ]: 0 : if( operation->id == 0 )
2501 : : {
2502 : 0 : status = PSA_ERROR_BAD_STATE;
2503 : 0 : goto exit;
2504 : : }
2505 : :
2506 [ # # ]: 0 : if( operation->is_sign )
2507 : : {
2508 : 0 : status = PSA_ERROR_BAD_STATE;
2509 : 0 : goto exit;
2510 : : }
2511 : :
2512 [ # # ]: 0 : if( operation->mac_size != mac_length )
2513 : : {
2514 : 0 : status = PSA_ERROR_INVALID_SIGNATURE;
2515 : 0 : goto exit;
2516 : : }
2517 : :
2518 : 0 : status = psa_driver_wrapper_mac_verify_finish( operation,
2519 : : mac, mac_length );
2520 : :
2521 : 0 : exit:
2522 : 0 : abort_status = psa_mac_abort( operation );
2523 : :
2524 [ # # ]: 0 : return( status == PSA_SUCCESS ? abort_status : status );
2525 : : }
2526 : :
2527 : 154 : static psa_status_t psa_mac_compute_internal( mbedtls_svc_key_id_t key,
2528 : : psa_algorithm_t alg,
2529 : : const uint8_t *input,
2530 : : size_t input_length,
2531 : : uint8_t *mac,
2532 : : size_t mac_size,
2533 : : size_t *mac_length,
2534 : : int is_sign )
2535 : : {
2536 : 154 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2537 : 154 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2538 : 154 : psa_key_slot_t *slot;
2539 : 154 : uint8_t operation_mac_size = 0;
2540 : :
2541 [ - + ]: 154 : status = psa_get_and_lock_key_slot_with_policy(
2542 : : key,
2543 : : &slot,
2544 : : is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE,
2545 : : alg );
2546 [ - + ]: 154 : if( status != PSA_SUCCESS )
2547 : 0 : goto exit;
2548 : :
2549 : 154 : psa_key_attributes_t attributes = {
2550 : 154 : .core = slot->attr
2551 : : };
2552 : :
2553 : 154 : status = psa_mac_finalize_alg_and_key_validation( alg, &attributes,
2554 : : &operation_mac_size );
2555 [ - + ]: 154 : if( status != PSA_SUCCESS )
2556 : 0 : goto exit;
2557 : :
2558 [ - + ]: 154 : if( mac_size < operation_mac_size )
2559 : : {
2560 : 0 : status = PSA_ERROR_BUFFER_TOO_SMALL;
2561 : 0 : goto exit;
2562 : : }
2563 : :
2564 : 154 : status = psa_driver_wrapper_mac_compute(
2565 : : &attributes,
2566 : 154 : slot->key.data, slot->key.bytes,
2567 : : alg,
2568 : : input, input_length,
2569 : : mac, operation_mac_size, mac_length );
2570 : :
2571 : 154 : exit:
2572 : : /* In case of success, set the potential excess room in the output buffer
2573 : : * to an invalid value, to avoid potentially leaking a longer MAC.
2574 : : * In case of error, set the output length and content to a safe default,
2575 : : * such that in case the caller misses an error check, the output would be
2576 : : * an unachievable MAC.
2577 : : */
2578 [ - + ]: 154 : if( status != PSA_SUCCESS )
2579 : : {
2580 : 0 : *mac_length = mac_size;
2581 : 0 : operation_mac_size = 0;
2582 : : }
2583 [ - + ]: 154 : if( mac_size > operation_mac_size )
2584 : 0 : memset( &mac[operation_mac_size], '!', mac_size - operation_mac_size );
2585 : :
2586 : 154 : unlock_status = psa_unlock_key_slot( slot );
2587 : :
2588 [ - + ]: 154 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
2589 : : }
2590 : :
2591 : 154 : psa_status_t psa_mac_compute( mbedtls_svc_key_id_t key,
2592 : : psa_algorithm_t alg,
2593 : : const uint8_t *input,
2594 : : size_t input_length,
2595 : : uint8_t *mac,
2596 : : size_t mac_size,
2597 : : size_t *mac_length)
2598 : : {
2599 : 154 : return( psa_mac_compute_internal( key, alg,
2600 : : input, input_length,
2601 : : mac, mac_size, mac_length, 1 ) );
2602 : : }
2603 : :
2604 : 0 : psa_status_t psa_mac_verify( mbedtls_svc_key_id_t key,
2605 : : psa_algorithm_t alg,
2606 : : const uint8_t *input,
2607 : : size_t input_length,
2608 : : const uint8_t *mac,
2609 : : size_t mac_length)
2610 : : {
2611 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2612 : 0 : uint8_t actual_mac[PSA_MAC_MAX_SIZE];
2613 : 0 : size_t actual_mac_length;
2614 : :
2615 : 0 : status = psa_mac_compute_internal( key, alg,
2616 : : input, input_length,
2617 : : actual_mac, sizeof( actual_mac ),
2618 : : &actual_mac_length, 0 );
2619 [ # # ]: 0 : if( status != PSA_SUCCESS )
2620 : 0 : goto exit;
2621 : :
2622 [ # # ]: 0 : if( mac_length != actual_mac_length )
2623 : : {
2624 : 0 : status = PSA_ERROR_INVALID_SIGNATURE;
2625 : 0 : goto exit;
2626 : : }
2627 [ # # ]: 0 : if( mbedtls_psa_safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
2628 : : {
2629 : 0 : status = PSA_ERROR_INVALID_SIGNATURE;
2630 : 0 : goto exit;
2631 : : }
2632 : :
2633 : 0 : exit:
2634 : 0 : mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
2635 : :
2636 : 0 : return ( status );
2637 : : }
2638 : :
2639 : : /****************************************************************/
2640 : : /* Asymmetric cryptography */
2641 : : /****************************************************************/
2642 : :
2643 : 10 : static psa_status_t psa_sign_verify_check_alg( int input_is_message,
2644 : : psa_algorithm_t alg )
2645 : : {
2646 [ + - ]: 10 : if( input_is_message )
2647 : : {
2648 [ + - + - : 10 : if( ! PSA_ALG_IS_SIGN_MESSAGE( alg ) )
- + - - -
- - - ]
2649 : : return( PSA_ERROR_INVALID_ARGUMENT );
2650 : :
2651 [ + - + - : 10 : if ( PSA_ALG_IS_SIGN_HASH( alg ) )
- + - - -
- ]
2652 : : {
2653 [ + - + - : 10 : if( ! PSA_ALG_IS_HASH( PSA_ALG_SIGN_GET_HASH( alg ) ) )
- + - - -
- - + ]
2654 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
2655 : : }
2656 : : }
2657 : : else
2658 : : {
2659 [ # # # # : 0 : if( ! PSA_ALG_IS_SIGN_HASH( alg ) )
# # # # #
# ]
2660 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
2661 : : }
2662 : :
2663 : : return( PSA_SUCCESS );
2664 : : }
2665 : :
2666 : 4 : static psa_status_t psa_sign_internal( mbedtls_svc_key_id_t key,
2667 : : int input_is_message,
2668 : : psa_algorithm_t alg,
2669 : : const uint8_t * input,
2670 : : size_t input_length,
2671 : : uint8_t * signature,
2672 : : size_t signature_size,
2673 : : size_t * signature_length )
2674 : : {
2675 : 4 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2676 : 4 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2677 : 4 : psa_key_slot_t *slot;
2678 : :
2679 : 4 : *signature_length = 0;
2680 : :
2681 : 4 : status = psa_sign_verify_check_alg( input_is_message, alg );
2682 [ + - ]: 4 : if( status != PSA_SUCCESS )
2683 : : return status;
2684 : :
2685 : : /* Immediately reject a zero-length signature buffer. This guarantees
2686 : : * that signature must be a valid pointer. (On the other hand, the input
2687 : : * buffer can in principle be empty since it doesn't actually have
2688 : : * to be a hash.) */
2689 [ + - ]: 4 : if( signature_size == 0 )
2690 : : return( PSA_ERROR_BUFFER_TOO_SMALL );
2691 : :
2692 [ - + ]: 4 : status = psa_get_and_lock_key_slot_with_policy(
2693 : : key, &slot,
2694 : : input_is_message ? PSA_KEY_USAGE_SIGN_MESSAGE :
2695 : : PSA_KEY_USAGE_SIGN_HASH,
2696 : : alg );
2697 : :
2698 [ - + ]: 4 : if( status != PSA_SUCCESS )
2699 : 0 : goto exit;
2700 : :
2701 [ - + ]: 4 : if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
2702 : : {
2703 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
2704 : 0 : goto exit;
2705 : : }
2706 : :
2707 : 4 : psa_key_attributes_t attributes = {
2708 : : .core = slot->attr
2709 : : };
2710 : :
2711 [ + - ]: 4 : if( input_is_message )
2712 : : {
2713 : 4 : status = psa_driver_wrapper_sign_message(
2714 : 4 : &attributes, slot->key.data, slot->key.bytes,
2715 : : alg, input, input_length,
2716 : : signature, signature_size, signature_length );
2717 : : }
2718 : : else
2719 : : {
2720 : :
2721 : 0 : status = psa_driver_wrapper_sign_hash(
2722 : 0 : &attributes, slot->key.data, slot->key.bytes,
2723 : : alg, input, input_length,
2724 : : signature, signature_size, signature_length );
2725 : : }
2726 : :
2727 : :
2728 : 4 : exit:
2729 : : /* Fill the unused part of the output buffer (the whole buffer on error,
2730 : : * the trailing part on success) with something that isn't a valid signature
2731 : : * (barring an attack on the signature and deliberately-crafted input),
2732 : : * in case the caller doesn't check the return status properly. */
2733 [ + - ]: 4 : if( status == PSA_SUCCESS )
2734 : 8 : memset( signature + *signature_length, '!',
2735 : 4 : signature_size - *signature_length );
2736 : : else
2737 : 0 : memset( signature, '!', signature_size );
2738 : : /* If signature_size is 0 then we have nothing to do. We must not call
2739 : : * memset because signature may be NULL in this case. */
2740 : :
2741 : 4 : unlock_status = psa_unlock_key_slot( slot );
2742 : :
2743 [ - + ]: 4 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
2744 : : }
2745 : :
2746 : 6 : static psa_status_t psa_verify_internal( mbedtls_svc_key_id_t key,
2747 : : int input_is_message,
2748 : : psa_algorithm_t alg,
2749 : : const uint8_t * input,
2750 : : size_t input_length,
2751 : : const uint8_t * signature,
2752 : : size_t signature_length )
2753 : : {
2754 : 6 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2755 : 6 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2756 : 6 : psa_key_slot_t *slot;
2757 : :
2758 : 6 : status = psa_sign_verify_check_alg( input_is_message, alg );
2759 [ + - ]: 6 : if( status != PSA_SUCCESS )
2760 : : return status;
2761 : :
2762 [ - + ]: 6 : status = psa_get_and_lock_key_slot_with_policy(
2763 : : key, &slot,
2764 : : input_is_message ? PSA_KEY_USAGE_VERIFY_MESSAGE :
2765 : : PSA_KEY_USAGE_VERIFY_HASH,
2766 : : alg );
2767 : :
2768 [ + - ]: 6 : if( status != PSA_SUCCESS )
2769 : : return( status );
2770 : :
2771 : 6 : psa_key_attributes_t attributes = {
2772 : 6 : .core = slot->attr
2773 : : };
2774 : :
2775 [ + - ]: 6 : if( input_is_message )
2776 : : {
2777 : 6 : status = psa_driver_wrapper_verify_message(
2778 : 6 : &attributes, slot->key.data, slot->key.bytes,
2779 : : alg, input, input_length,
2780 : : signature, signature_length );
2781 : : }
2782 : : else
2783 : : {
2784 : 0 : status = psa_driver_wrapper_verify_hash(
2785 : 0 : &attributes, slot->key.data, slot->key.bytes,
2786 : : alg, input, input_length,
2787 : : signature, signature_length );
2788 : : }
2789 : :
2790 : 6 : unlock_status = psa_unlock_key_slot( slot );
2791 : :
2792 [ - + ]: 6 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
2793 : :
2794 : : }
2795 : :
2796 : 4 : psa_status_t psa_sign_message_builtin(
2797 : : const psa_key_attributes_t *attributes,
2798 : : const uint8_t *key_buffer,
2799 : : size_t key_buffer_size,
2800 : : psa_algorithm_t alg,
2801 : : const uint8_t *input,
2802 : : size_t input_length,
2803 : : uint8_t *signature,
2804 : : size_t signature_size,
2805 : : size_t *signature_length )
2806 : : {
2807 : 4 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2808 : :
2809 [ + - + - : 4 : if ( PSA_ALG_IS_SIGN_HASH( alg ) )
- + - - -
- ]
2810 : : {
2811 : 4 : size_t hash_length;
2812 : 4 : uint8_t hash[PSA_HASH_MAX_SIZE];
2813 : :
2814 [ + - ]: 8 : status = psa_driver_wrapper_hash_compute(
2815 [ + - - + : 4 : PSA_ALG_SIGN_GET_HASH( alg ),
- - - - +
- ]
2816 : : input, input_length,
2817 : : hash, sizeof( hash ), &hash_length );
2818 : :
2819 [ + - ]: 4 : if( status != PSA_SUCCESS )
2820 : : return status;
2821 : :
2822 : 4 : return psa_driver_wrapper_sign_hash(
2823 : : attributes, key_buffer, key_buffer_size,
2824 : : alg, hash, hash_length,
2825 : : signature, signature_size, signature_length );
2826 : : }
2827 : :
2828 : : return( PSA_ERROR_NOT_SUPPORTED );
2829 : : }
2830 : :
2831 : 4 : psa_status_t psa_sign_message( mbedtls_svc_key_id_t key,
2832 : : psa_algorithm_t alg,
2833 : : const uint8_t * input,
2834 : : size_t input_length,
2835 : : uint8_t * signature,
2836 : : size_t signature_size,
2837 : : size_t * signature_length )
2838 : : {
2839 : 4 : return psa_sign_internal(
2840 : : key, 1, alg, input, input_length,
2841 : : signature, signature_size, signature_length );
2842 : : }
2843 : :
2844 : 6 : psa_status_t psa_verify_message_builtin(
2845 : : const psa_key_attributes_t *attributes,
2846 : : const uint8_t *key_buffer,
2847 : : size_t key_buffer_size,
2848 : : psa_algorithm_t alg,
2849 : : const uint8_t *input,
2850 : : size_t input_length,
2851 : : const uint8_t *signature,
2852 : : size_t signature_length )
2853 : : {
2854 : 6 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2855 : :
2856 [ + - + - : 6 : if ( PSA_ALG_IS_SIGN_HASH( alg ) )
- + - - -
- ]
2857 : : {
2858 : 6 : size_t hash_length;
2859 : 6 : uint8_t hash[PSA_HASH_MAX_SIZE];
2860 : :
2861 [ + - ]: 12 : status = psa_driver_wrapper_hash_compute(
2862 [ + - - + : 6 : PSA_ALG_SIGN_GET_HASH( alg ),
- - - - +
- ]
2863 : : input, input_length,
2864 : : hash, sizeof( hash ), &hash_length );
2865 : :
2866 [ + - ]: 6 : if( status != PSA_SUCCESS )
2867 : : return status;
2868 : :
2869 : 6 : return psa_driver_wrapper_verify_hash(
2870 : : attributes, key_buffer, key_buffer_size,
2871 : : alg, hash, hash_length,
2872 : : signature, signature_length );
2873 : : }
2874 : :
2875 : : return( PSA_ERROR_NOT_SUPPORTED );
2876 : : }
2877 : :
2878 : 6 : psa_status_t psa_verify_message( mbedtls_svc_key_id_t key,
2879 : : psa_algorithm_t alg,
2880 : : const uint8_t * input,
2881 : : size_t input_length,
2882 : : const uint8_t * signature,
2883 : : size_t signature_length )
2884 : : {
2885 : 6 : return psa_verify_internal(
2886 : : key, 1, alg, input, input_length,
2887 : : signature, signature_length );
2888 : : }
2889 : :
2890 : 4 : psa_status_t psa_sign_hash_builtin(
2891 : : const psa_key_attributes_t *attributes,
2892 : : const uint8_t *key_buffer, size_t key_buffer_size,
2893 : : psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
2894 : : uint8_t *signature, size_t signature_size, size_t *signature_length )
2895 : : {
2896 [ - + ]: 4 : if( attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
2897 : : {
2898 [ # # ]: 0 : if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) ||
2899 [ # # ]: 0 : PSA_ALG_IS_RSA_PSS( alg) )
2900 : : {
2901 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
2902 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
2903 : : return( mbedtls_psa_rsa_sign_hash(
2904 : : attributes,
2905 : : key_buffer, key_buffer_size,
2906 : : alg, hash, hash_length,
2907 : : signature, signature_size, signature_length ) );
2908 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
2909 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
2910 : : }
2911 : : else
2912 : : {
2913 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
2914 : : }
2915 : : }
2916 [ + - ]: 4 : else if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) )
2917 : : {
2918 [ + - ]: 4 : if( PSA_ALG_IS_ECDSA( alg ) )
2919 : : {
2920 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
2921 : : defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
2922 : 4 : return( mbedtls_psa_ecdsa_sign_hash(
2923 : : attributes,
2924 : : key_buffer, key_buffer_size,
2925 : : alg, hash, hash_length,
2926 : : signature, signature_size, signature_length ) );
2927 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
2928 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
2929 : : }
2930 : : else
2931 : : {
2932 : : return( PSA_ERROR_INVALID_ARGUMENT );
2933 : : }
2934 : : }
2935 : :
2936 : : (void)key_buffer;
2937 : : (void)key_buffer_size;
2938 : : (void)hash;
2939 : : (void)hash_length;
2940 : : (void)signature;
2941 : : (void)signature_size;
2942 : : (void)signature_length;
2943 : :
2944 : : return( PSA_ERROR_NOT_SUPPORTED );
2945 : : }
2946 : :
2947 : 0 : psa_status_t psa_sign_hash( mbedtls_svc_key_id_t key,
2948 : : psa_algorithm_t alg,
2949 : : const uint8_t *hash,
2950 : : size_t hash_length,
2951 : : uint8_t *signature,
2952 : : size_t signature_size,
2953 : : size_t *signature_length )
2954 : : {
2955 : 0 : return psa_sign_internal(
2956 : : key, 0, alg, hash, hash_length,
2957 : : signature, signature_size, signature_length );
2958 : : }
2959 : :
2960 : 6 : psa_status_t psa_verify_hash_builtin(
2961 : : const psa_key_attributes_t *attributes,
2962 : : const uint8_t *key_buffer, size_t key_buffer_size,
2963 : : psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
2964 : : const uint8_t *signature, size_t signature_length )
2965 : : {
2966 [ - + ]: 6 : if( PSA_KEY_TYPE_IS_RSA( attributes->core.type ) )
2967 : : {
2968 [ # # ]: 0 : if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) ||
2969 [ # # ]: 0 : PSA_ALG_IS_RSA_PSS( alg) )
2970 : : {
2971 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
2972 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
2973 : : return( mbedtls_psa_rsa_verify_hash(
2974 : : attributes,
2975 : : key_buffer, key_buffer_size,
2976 : : alg, hash, hash_length,
2977 : : signature, signature_length ) );
2978 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
2979 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
2980 : : }
2981 : : else
2982 : : {
2983 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
2984 : : }
2985 : : }
2986 [ + - ]: 6 : else if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) )
2987 : : {
2988 [ + - ]: 6 : if( PSA_ALG_IS_ECDSA( alg ) )
2989 : : {
2990 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
2991 : : defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
2992 : 6 : return( mbedtls_psa_ecdsa_verify_hash(
2993 : : attributes,
2994 : : key_buffer, key_buffer_size,
2995 : : alg, hash, hash_length,
2996 : : signature, signature_length ) );
2997 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
2998 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
2999 : : }
3000 : : else
3001 : : {
3002 : : return( PSA_ERROR_INVALID_ARGUMENT );
3003 : : }
3004 : : }
3005 : :
3006 : : (void)key_buffer;
3007 : : (void)key_buffer_size;
3008 : : (void)hash;
3009 : : (void)hash_length;
3010 : : (void)signature;
3011 : : (void)signature_length;
3012 : :
3013 : : return( PSA_ERROR_NOT_SUPPORTED );
3014 : : }
3015 : :
3016 : 0 : psa_status_t psa_verify_hash( mbedtls_svc_key_id_t key,
3017 : : psa_algorithm_t alg,
3018 : : const uint8_t *hash,
3019 : : size_t hash_length,
3020 : : const uint8_t *signature,
3021 : : size_t signature_length )
3022 : : {
3023 : 0 : return psa_verify_internal(
3024 : : key, 0, alg, hash, hash_length,
3025 : : signature, signature_length );
3026 : : }
3027 : :
3028 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
3029 : : static int psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
3030 : : mbedtls_rsa_context *rsa )
3031 : : {
3032 : : psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
3033 : : const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
3034 : : mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
3035 : :
3036 : : return( mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg ) );
3037 : : }
3038 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
3039 : :
3040 : 0 : psa_status_t psa_asymmetric_encrypt( mbedtls_svc_key_id_t key,
3041 : : psa_algorithm_t alg,
3042 : : const uint8_t *input,
3043 : : size_t input_length,
3044 : : const uint8_t *salt,
3045 : : size_t salt_length,
3046 : : uint8_t *output,
3047 : : size_t output_size,
3048 : : size_t *output_length )
3049 : : {
3050 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3051 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3052 : 0 : psa_key_slot_t *slot;
3053 : :
3054 : 0 : (void) input;
3055 : 0 : (void) input_length;
3056 : 0 : (void) salt;
3057 : 0 : (void) output;
3058 : 0 : (void) output_size;
3059 : :
3060 : 0 : *output_length = 0;
3061 : :
3062 [ # # # # ]: 0 : if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
3063 : : return( PSA_ERROR_INVALID_ARGUMENT );
3064 : :
3065 : 0 : status = psa_get_and_lock_transparent_key_slot_with_policy(
3066 : : key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
3067 [ # # ]: 0 : if( status != PSA_SUCCESS )
3068 : : return( status );
3069 [ # # ]: 0 : if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) ||
3070 : : PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) )
3071 : : {
3072 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3073 : 0 : goto exit;
3074 : : }
3075 : :
3076 [ # # ]: 0 : if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
3077 : : {
3078 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
3079 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
3080 : : mbedtls_rsa_context *rsa = NULL;
3081 : : status = mbedtls_psa_rsa_load_representation( slot->attr.type,
3082 : : slot->key.data,
3083 : : slot->key.bytes,
3084 : : &rsa );
3085 : : if( status != PSA_SUCCESS )
3086 : : goto rsa_exit;
3087 : :
3088 : : if( output_size < mbedtls_rsa_get_len( rsa ) )
3089 : : {
3090 : : status = PSA_ERROR_BUFFER_TOO_SMALL;
3091 : : goto rsa_exit;
3092 : : }
3093 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
3094 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
3095 [ # # ]: 0 : if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
3096 : : {
3097 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
3098 : : status = mbedtls_to_psa_error(
3099 : : mbedtls_rsa_pkcs1_encrypt( rsa,
3100 : : mbedtls_psa_get_random,
3101 : : MBEDTLS_PSA_RANDOM_STATE,
3102 : : input_length,
3103 : : input,
3104 : : output ) );
3105 : : #else
3106 : : status = PSA_ERROR_NOT_SUPPORTED;
3107 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
3108 : : }
3109 : : else
3110 [ # # ]: 0 : if( PSA_ALG_IS_RSA_OAEP( alg ) )
3111 : : {
3112 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
3113 : : status = mbedtls_to_psa_error(
3114 : : psa_rsa_oaep_set_padding_mode( alg, rsa ) );
3115 : : if( status != PSA_SUCCESS )
3116 : : goto rsa_exit;
3117 : :
3118 : : status = mbedtls_to_psa_error(
3119 : : mbedtls_rsa_rsaes_oaep_encrypt( rsa,
3120 : : mbedtls_psa_get_random,
3121 : : MBEDTLS_PSA_RANDOM_STATE,
3122 : : salt, salt_length,
3123 : : input_length,
3124 : : input,
3125 : : output ) );
3126 : : #else
3127 : : status = PSA_ERROR_NOT_SUPPORTED;
3128 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
3129 : : }
3130 : : else
3131 : : {
3132 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3133 : : }
3134 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
3135 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
3136 : : rsa_exit:
3137 : : if( status == PSA_SUCCESS )
3138 : : *output_length = mbedtls_rsa_get_len( rsa );
3139 : :
3140 : : mbedtls_rsa_free( rsa );
3141 : : mbedtls_free( rsa );
3142 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
3143 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
3144 : : }
3145 : : else
3146 : : {
3147 : : status = PSA_ERROR_NOT_SUPPORTED;
3148 : : }
3149 : :
3150 : 0 : exit:
3151 : 0 : unlock_status = psa_unlock_key_slot( slot );
3152 : :
3153 : 0 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
3154 : : }
3155 : :
3156 : 0 : psa_status_t psa_asymmetric_decrypt( mbedtls_svc_key_id_t key,
3157 : : psa_algorithm_t alg,
3158 : : const uint8_t *input,
3159 : : size_t input_length,
3160 : : const uint8_t *salt,
3161 : : size_t salt_length,
3162 : : uint8_t *output,
3163 : : size_t output_size,
3164 : : size_t *output_length )
3165 : : {
3166 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3167 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3168 : 0 : psa_key_slot_t *slot;
3169 : :
3170 : 0 : (void) input;
3171 : 0 : (void) input_length;
3172 : 0 : (void) salt;
3173 : 0 : (void) output;
3174 : 0 : (void) output_size;
3175 : :
3176 : 0 : *output_length = 0;
3177 : :
3178 [ # # # # ]: 0 : if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
3179 : : return( PSA_ERROR_INVALID_ARGUMENT );
3180 : :
3181 : 0 : status = psa_get_and_lock_transparent_key_slot_with_policy(
3182 : : key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
3183 [ # # ]: 0 : if( status != PSA_SUCCESS )
3184 : : return( status );
3185 [ # # ]: 0 : if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
3186 : : {
3187 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3188 : 0 : goto exit;
3189 : : }
3190 : :
3191 [ # # ]: 0 : if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
3192 : : {
3193 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
3194 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
3195 : : mbedtls_rsa_context *rsa = NULL;
3196 : : status = mbedtls_psa_rsa_load_representation( slot->attr.type,
3197 : : slot->key.data,
3198 : : slot->key.bytes,
3199 : : &rsa );
3200 : : if( status != PSA_SUCCESS )
3201 : : goto exit;
3202 : :
3203 : : if( input_length != mbedtls_rsa_get_len( rsa ) )
3204 : : {
3205 : : status = PSA_ERROR_INVALID_ARGUMENT;
3206 : : goto rsa_exit;
3207 : : }
3208 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
3209 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
3210 : :
3211 [ # # ]: 0 : if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
3212 : : {
3213 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
3214 : : status = mbedtls_to_psa_error(
3215 : : mbedtls_rsa_pkcs1_decrypt( rsa,
3216 : : mbedtls_psa_get_random,
3217 : : MBEDTLS_PSA_RANDOM_STATE,
3218 : : output_length,
3219 : : input,
3220 : : output,
3221 : : output_size ) );
3222 : : #else
3223 : : status = PSA_ERROR_NOT_SUPPORTED;
3224 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
3225 : : }
3226 : : else
3227 [ # # ]: 0 : if( PSA_ALG_IS_RSA_OAEP( alg ) )
3228 : : {
3229 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
3230 : : status = mbedtls_to_psa_error(
3231 : : psa_rsa_oaep_set_padding_mode( alg, rsa ) );
3232 : : if( status != PSA_SUCCESS )
3233 : : goto rsa_exit;
3234 : :
3235 : : status = mbedtls_to_psa_error(
3236 : : mbedtls_rsa_rsaes_oaep_decrypt( rsa,
3237 : : mbedtls_psa_get_random,
3238 : : MBEDTLS_PSA_RANDOM_STATE,
3239 : : salt, salt_length,
3240 : : output_length,
3241 : : input,
3242 : : output,
3243 : : output_size ) );
3244 : : #else
3245 : : status = PSA_ERROR_NOT_SUPPORTED;
3246 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
3247 : : }
3248 : : else
3249 : : {
3250 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3251 : : }
3252 : :
3253 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
3254 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
3255 : : rsa_exit:
3256 : : mbedtls_rsa_free( rsa );
3257 : : mbedtls_free( rsa );
3258 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
3259 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
3260 : : }
3261 : : else
3262 : : {
3263 : : status = PSA_ERROR_NOT_SUPPORTED;
3264 : : }
3265 : :
3266 : 0 : exit:
3267 : 0 : unlock_status = psa_unlock_key_slot( slot );
3268 : :
3269 : 0 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
3270 : : }
3271 : :
3272 : :
3273 : :
3274 : : /****************************************************************/
3275 : : /* Symmetric cryptography */
3276 : : /****************************************************************/
3277 : :
3278 : 0 : static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
3279 : : mbedtls_svc_key_id_t key,
3280 : : psa_algorithm_t alg,
3281 : : mbedtls_operation_t cipher_operation )
3282 : : {
3283 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3284 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3285 : 0 : psa_key_slot_t *slot = NULL;
3286 : 0 : psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
3287 [ # # ]: 0 : PSA_KEY_USAGE_ENCRYPT :
3288 : : PSA_KEY_USAGE_DECRYPT );
3289 : :
3290 : : /* A context must be freshly initialized before it can be set up. */
3291 [ # # ]: 0 : if( operation->id != 0 )
3292 : : {
3293 : 0 : status = PSA_ERROR_BAD_STATE;
3294 : 0 : goto exit;
3295 : : }
3296 : :
3297 [ # # ]: 0 : if( ! PSA_ALG_IS_CIPHER( alg ) )
3298 : : {
3299 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3300 : 0 : goto exit;
3301 : : }
3302 : :
3303 : 0 : status = psa_get_and_lock_key_slot_with_policy( key, &slot, usage, alg );
3304 [ # # ]: 0 : if( status != PSA_SUCCESS )
3305 : 0 : goto exit;
3306 : :
3307 : : /* Initialize the operation struct members, except for id. The id member
3308 : : * is used to indicate to psa_cipher_abort that there are resources to free,
3309 : : * so we only set it (in the driver wrapper) after resources have been
3310 : : * allocated/initialized. */
3311 : 0 : operation->iv_set = 0;
3312 [ # # ]: 0 : if( alg == PSA_ALG_ECB_NO_PADDING )
3313 : 0 : operation->iv_required = 0;
3314 : : else
3315 : 0 : operation->iv_required = 1;
3316 [ # # # # : 0 : operation->default_iv_length = PSA_CIPHER_IV_LENGTH( slot->attr.type, alg );
# # # # #
# # # # #
# # ]
3317 : :
3318 : 0 : psa_key_attributes_t attributes = {
3319 : : .core = slot->attr
3320 : : };
3321 : :
3322 : : /* Try doing the operation through a driver before using software fallback. */
3323 [ # # ]: 0 : if( cipher_operation == MBEDTLS_ENCRYPT )
3324 : 0 : status = psa_driver_wrapper_cipher_encrypt_setup( operation,
3325 : : &attributes,
3326 : 0 : slot->key.data,
3327 : : slot->key.bytes,
3328 : : alg );
3329 : : else
3330 : 0 : status = psa_driver_wrapper_cipher_decrypt_setup( operation,
3331 : : &attributes,
3332 : 0 : slot->key.data,
3333 : : slot->key.bytes,
3334 : : alg );
3335 : :
3336 : 0 : exit:
3337 [ # # ]: 0 : if( status != PSA_SUCCESS )
3338 : 0 : psa_cipher_abort( operation );
3339 : :
3340 : 0 : unlock_status = psa_unlock_key_slot( slot );
3341 : :
3342 [ # # ]: 0 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
3343 : : }
3344 : :
3345 : 0 : psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
3346 : : mbedtls_svc_key_id_t key,
3347 : : psa_algorithm_t alg )
3348 : : {
3349 : 0 : return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
3350 : : }
3351 : :
3352 : 0 : psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
3353 : : mbedtls_svc_key_id_t key,
3354 : : psa_algorithm_t alg )
3355 : : {
3356 : 0 : return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
3357 : : }
3358 : :
3359 : 0 : psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
3360 : : uint8_t *iv,
3361 : : size_t iv_size,
3362 : : size_t *iv_length )
3363 : : {
3364 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3365 : 0 : uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE];
3366 : 0 : size_t default_iv_length;
3367 : :
3368 [ # # ]: 0 : if( operation->id == 0 )
3369 : : {
3370 : 0 : status = PSA_ERROR_BAD_STATE;
3371 : 0 : goto exit;
3372 : : }
3373 : :
3374 [ # # ]: 0 : if( operation->iv_set || ! operation->iv_required )
3375 : : {
3376 : 0 : status = PSA_ERROR_BAD_STATE;
3377 : 0 : goto exit;
3378 : : }
3379 : :
3380 : 0 : default_iv_length = operation->default_iv_length;
3381 [ # # ]: 0 : if( iv_size < default_iv_length )
3382 : : {
3383 : 0 : status = PSA_ERROR_BUFFER_TOO_SMALL;
3384 : 0 : goto exit;
3385 : : }
3386 : :
3387 [ # # ]: 0 : if( default_iv_length > PSA_CIPHER_IV_MAX_SIZE )
3388 : : {
3389 : 0 : status = PSA_ERROR_GENERIC_ERROR;
3390 : 0 : goto exit;
3391 : : }
3392 : :
3393 : 0 : status = psa_generate_random( local_iv, default_iv_length );
3394 [ # # ]: 0 : if( status != PSA_SUCCESS )
3395 : 0 : goto exit;
3396 : :
3397 : 0 : status = psa_driver_wrapper_cipher_set_iv( operation,
3398 : : local_iv, default_iv_length );
3399 : :
3400 : 0 : exit:
3401 [ # # ]: 0 : if( status == PSA_SUCCESS )
3402 : : {
3403 : 0 : memcpy( iv, local_iv, default_iv_length );
3404 : 0 : *iv_length = default_iv_length;
3405 : 0 : operation->iv_set = 1;
3406 : : }
3407 : : else
3408 : : {
3409 : 0 : *iv_length = 0;
3410 : 0 : psa_cipher_abort( operation );
3411 : : }
3412 : :
3413 : 0 : return( status );
3414 : : }
3415 : :
3416 : 0 : psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
3417 : : const uint8_t *iv,
3418 : : size_t iv_length )
3419 : : {
3420 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3421 : :
3422 [ # # ]: 0 : if( operation->id == 0 )
3423 : : {
3424 : 0 : status = PSA_ERROR_BAD_STATE;
3425 : 0 : goto exit;
3426 : : }
3427 : :
3428 [ # # ]: 0 : if( operation->iv_set || ! operation->iv_required )
3429 : : {
3430 : 0 : status = PSA_ERROR_BAD_STATE;
3431 : 0 : goto exit;
3432 : : }
3433 : :
3434 [ # # ]: 0 : if( iv_length > PSA_CIPHER_IV_MAX_SIZE )
3435 : : {
3436 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3437 : 0 : goto exit;
3438 : : }
3439 : :
3440 : 0 : status = psa_driver_wrapper_cipher_set_iv( operation,
3441 : : iv,
3442 : : iv_length );
3443 : :
3444 : 0 : exit:
3445 [ # # ]: 0 : if( status == PSA_SUCCESS )
3446 : 0 : operation->iv_set = 1;
3447 : : else
3448 : 0 : psa_cipher_abort( operation );
3449 : 0 : return( status );
3450 : : }
3451 : :
3452 : 0 : psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
3453 : : const uint8_t *input,
3454 : : size_t input_length,
3455 : : uint8_t *output,
3456 : : size_t output_size,
3457 : : size_t *output_length )
3458 : : {
3459 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3460 : :
3461 [ # # ]: 0 : if( operation->id == 0 )
3462 : : {
3463 : 0 : status = PSA_ERROR_BAD_STATE;
3464 : 0 : goto exit;
3465 : : }
3466 : :
3467 [ # # ]: 0 : if( operation->iv_required && ! operation->iv_set )
3468 : : {
3469 : 0 : status = PSA_ERROR_BAD_STATE;
3470 : 0 : goto exit;
3471 : : }
3472 : :
3473 : 0 : status = psa_driver_wrapper_cipher_update( operation,
3474 : : input,
3475 : : input_length,
3476 : : output,
3477 : : output_size,
3478 : : output_length );
3479 : :
3480 : 0 : exit:
3481 [ # # ]: 0 : if( status != PSA_SUCCESS )
3482 : 0 : psa_cipher_abort( operation );
3483 : :
3484 : 0 : return( status );
3485 : : }
3486 : :
3487 : 0 : psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
3488 : : uint8_t *output,
3489 : : size_t output_size,
3490 : : size_t *output_length )
3491 : : {
3492 : 0 : psa_status_t status = PSA_ERROR_GENERIC_ERROR;
3493 : :
3494 [ # # ]: 0 : if( operation->id == 0 )
3495 : : {
3496 : 0 : status = PSA_ERROR_BAD_STATE;
3497 : 0 : goto exit;
3498 : : }
3499 : :
3500 [ # # ]: 0 : if( operation->iv_required && ! operation->iv_set )
3501 : : {
3502 : 0 : status = PSA_ERROR_BAD_STATE;
3503 : 0 : goto exit;
3504 : : }
3505 : :
3506 : 0 : status = psa_driver_wrapper_cipher_finish( operation,
3507 : : output,
3508 : : output_size,
3509 : : output_length );
3510 : :
3511 : 0 : exit:
3512 [ # # ]: 0 : if( status == PSA_SUCCESS )
3513 : 0 : return( psa_cipher_abort( operation ) );
3514 : : else
3515 : : {
3516 : 0 : *output_length = 0;
3517 : 0 : (void) psa_cipher_abort( operation );
3518 : :
3519 : 0 : return( status );
3520 : : }
3521 : : }
3522 : :
3523 : 0 : psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
3524 : : {
3525 [ # # ]: 0 : if( operation->id == 0 )
3526 : : {
3527 : : /* The object has (apparently) been initialized but it is not (yet)
3528 : : * in use. It's ok to call abort on such an object, and there's
3529 : : * nothing to do. */
3530 : : return( PSA_SUCCESS );
3531 : : }
3532 : :
3533 : 0 : psa_driver_wrapper_cipher_abort( operation );
3534 : :
3535 : 0 : operation->id = 0;
3536 : 0 : operation->iv_set = 0;
3537 : 0 : operation->iv_required = 0;
3538 : :
3539 : 0 : return( PSA_SUCCESS );
3540 : : }
3541 : :
3542 : 0 : psa_status_t psa_cipher_encrypt( mbedtls_svc_key_id_t key,
3543 : : psa_algorithm_t alg,
3544 : : const uint8_t *input,
3545 : : size_t input_length,
3546 : : uint8_t *output,
3547 : : size_t output_size,
3548 : : size_t *output_length )
3549 : : {
3550 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3551 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3552 : 0 : psa_key_slot_t *slot = NULL;
3553 : 0 : uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE];
3554 : 0 : size_t default_iv_length = 0;
3555 : :
3556 [ # # ]: 0 : if( ! PSA_ALG_IS_CIPHER( alg ) )
3557 : : {
3558 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3559 : 0 : goto exit;
3560 : : }
3561 : :
3562 : 0 : status = psa_get_and_lock_key_slot_with_policy( key, &slot,
3563 : : PSA_KEY_USAGE_ENCRYPT,
3564 : : alg );
3565 [ # # ]: 0 : if( status != PSA_SUCCESS )
3566 : 0 : goto exit;
3567 : :
3568 : 0 : psa_key_attributes_t attributes = {
3569 : 0 : .core = slot->attr
3570 : : };
3571 : :
3572 [ # # # # : 0 : default_iv_length = PSA_CIPHER_IV_LENGTH( slot->attr.type, alg );
# # # # #
# # # # #
# # ]
3573 [ # # ]: 0 : if( default_iv_length > PSA_CIPHER_IV_MAX_SIZE )
3574 : : {
3575 : 0 : status = PSA_ERROR_GENERIC_ERROR;
3576 : 0 : goto exit;
3577 : : }
3578 : :
3579 [ # # ]: 0 : if( default_iv_length > 0 )
3580 : : {
3581 [ # # ]: 0 : if( output_size < default_iv_length )
3582 : : {
3583 : 0 : status = PSA_ERROR_BUFFER_TOO_SMALL;
3584 : 0 : goto exit;
3585 : : }
3586 : :
3587 : 0 : status = psa_generate_random( local_iv, default_iv_length );
3588 [ # # ]: 0 : if( status != PSA_SUCCESS )
3589 : 0 : goto exit;
3590 : : }
3591 : :
3592 : 0 : status = psa_driver_wrapper_cipher_encrypt(
3593 : 0 : &attributes, slot->key.data, slot->key.bytes,
3594 : : alg, local_iv, default_iv_length, input, input_length,
3595 : : output + default_iv_length, output_size - default_iv_length,
3596 : : output_length );
3597 : :
3598 : 0 : exit:
3599 : 0 : unlock_status = psa_unlock_key_slot( slot );
3600 [ # # ]: 0 : if( status == PSA_SUCCESS )
3601 : 0 : status = unlock_status;
3602 : :
3603 [ # # ]: 0 : if( status == PSA_SUCCESS )
3604 : : {
3605 [ # # ]: 0 : if( default_iv_length > 0 )
3606 : 0 : memcpy( output, local_iv, default_iv_length );
3607 : 0 : *output_length += default_iv_length;
3608 : : }
3609 : : else
3610 : 0 : *output_length = 0;
3611 : :
3612 : 0 : return( status );
3613 : : }
3614 : :
3615 : 0 : psa_status_t psa_cipher_decrypt( mbedtls_svc_key_id_t key,
3616 : : psa_algorithm_t alg,
3617 : : const uint8_t *input,
3618 : : size_t input_length,
3619 : : uint8_t *output,
3620 : : size_t output_size,
3621 : : size_t *output_length )
3622 : : {
3623 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3624 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3625 : 0 : psa_key_slot_t *slot = NULL;
3626 : :
3627 [ # # ]: 0 : if( ! PSA_ALG_IS_CIPHER( alg ) )
3628 : : {
3629 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3630 : 0 : goto exit;
3631 : : }
3632 : :
3633 : 0 : status = psa_get_and_lock_key_slot_with_policy( key, &slot,
3634 : : PSA_KEY_USAGE_DECRYPT,
3635 : : alg );
3636 [ # # ]: 0 : if( status != PSA_SUCCESS )
3637 : 0 : goto exit;
3638 : :
3639 : 0 : psa_key_attributes_t attributes = {
3640 : 0 : .core = slot->attr
3641 : : };
3642 : :
3643 [ # # # # : 0 : if( alg == PSA_ALG_CCM_STAR_NO_TAG && input_length < PSA_BLOCK_CIPHER_BLOCK_LENGTH( slot->attr.type ) )
# # ]
3644 : : {
3645 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3646 : 0 : goto exit;
3647 : : }
3648 [ # # # # : 0 : else if ( input_length < PSA_CIPHER_IV_LENGTH( slot->attr.type, alg ) )
# # # # #
# # # # #
# # # # ]
3649 : : {
3650 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3651 : 0 : goto exit;
3652 : : }
3653 : :
3654 : 0 : status = psa_driver_wrapper_cipher_decrypt(
3655 : 0 : &attributes, slot->key.data, slot->key.bytes,
3656 : : alg, input, input_length,
3657 : : output, output_size, output_length );
3658 : :
3659 : 0 : exit:
3660 : 0 : unlock_status = psa_unlock_key_slot( slot );
3661 [ # # ]: 0 : if( status == PSA_SUCCESS )
3662 : 0 : status = unlock_status;
3663 : :
3664 [ # # ]: 0 : if( status != PSA_SUCCESS )
3665 : 0 : *output_length = 0;
3666 : :
3667 : 0 : return( status );
3668 : : }
3669 : :
3670 : :
3671 : : /****************************************************************/
3672 : : /* AEAD */
3673 : : /****************************************************************/
3674 : :
3675 : : /* Helper function to get the base algorithm from its variants. */
3676 : 34 : static psa_algorithm_t psa_aead_get_base_algorithm( psa_algorithm_t alg )
3677 : : {
3678 [ - + - - : 34 : return PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG( alg );
- - ]
3679 : : }
3680 : :
3681 : : /* Helper function to perform common nonce length checks. */
3682 : 34 : static psa_status_t psa_aead_check_nonce_length( psa_algorithm_t alg,
3683 : : size_t nonce_length )
3684 : : {
3685 : 34 : psa_algorithm_t base_alg = psa_aead_get_base_algorithm( alg );
3686 : :
3687 [ + - ]: 34 : switch(base_alg)
3688 : : {
3689 : : #if defined(PSA_WANT_ALG_GCM)
3690 : : case PSA_ALG_GCM:
3691 : : /* Not checking max nonce size here as GCM spec allows almost
3692 : : * arbitrarily large nonces. Please note that we do not generally
3693 : : * recommend the usage of nonces of greater length than
3694 : : * PSA_AEAD_NONCE_MAX_SIZE, as large nonces are hashed to a shorter
3695 : : * size, which can then lead to collisions if you encrypt a very
3696 : : * large number of messages.*/
3697 : : if( nonce_length != 0 )
3698 : : return( PSA_SUCCESS );
3699 : : break;
3700 : : #endif /* PSA_WANT_ALG_GCM */
3701 : : #if defined(PSA_WANT_ALG_CCM)
3702 : 34 : case PSA_ALG_CCM:
3703 [ + - ]: 34 : if( nonce_length >= 7 && nonce_length <= 13 )
3704 : 34 : return( PSA_SUCCESS );
3705 : : break;
3706 : : #endif /* PSA_WANT_ALG_CCM */
3707 : : #if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
3708 : : case PSA_ALG_CHACHA20_POLY1305:
3709 : : if( nonce_length == 12 )
3710 : : return( PSA_SUCCESS );
3711 : : else if( nonce_length == 8 )
3712 : : return( PSA_ERROR_NOT_SUPPORTED );
3713 : : break;
3714 : : #endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
3715 : : default:
3716 : : return( PSA_ERROR_NOT_SUPPORTED );
3717 : : }
3718 : :
3719 : : return( PSA_ERROR_INVALID_ARGUMENT );
3720 : : }
3721 : :
3722 : 18 : psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key,
3723 : : psa_algorithm_t alg,
3724 : : const uint8_t *nonce,
3725 : : size_t nonce_length,
3726 : : const uint8_t *additional_data,
3727 : : size_t additional_data_length,
3728 : : const uint8_t *plaintext,
3729 : : size_t plaintext_length,
3730 : : uint8_t *ciphertext,
3731 : : size_t ciphertext_size,
3732 : : size_t *ciphertext_length )
3733 : : {
3734 : 18 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3735 : 18 : psa_key_slot_t *slot;
3736 : :
3737 : 18 : *ciphertext_length = 0;
3738 : :
3739 [ + - + - : 18 : if( !PSA_ALG_IS_AEAD( alg ) || PSA_ALG_IS_WILDCARD( alg ) )
+ - + - +
- - + - -
- - - - -
- - - - -
- - - - +
- ]
3740 : : return( PSA_ERROR_NOT_SUPPORTED );
3741 : :
3742 : 18 : status = psa_get_and_lock_key_slot_with_policy(
3743 : : key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
3744 [ + - ]: 18 : if( status != PSA_SUCCESS )
3745 : : return( status );
3746 : :
3747 : 18 : psa_key_attributes_t attributes = {
3748 : 18 : .core = slot->attr
3749 : : };
3750 : :
3751 : 18 : status = psa_aead_check_nonce_length( alg, nonce_length );
3752 [ - + ]: 18 : if( status != PSA_SUCCESS )
3753 : 0 : goto exit;
3754 : :
3755 : 36 : status = psa_driver_wrapper_aead_encrypt(
3756 : 18 : &attributes, slot->key.data, slot->key.bytes,
3757 : : alg,
3758 : : nonce, nonce_length,
3759 : : additional_data, additional_data_length,
3760 : : plaintext, plaintext_length,
3761 : : ciphertext, ciphertext_size, ciphertext_length );
3762 : :
3763 [ + - ]: 18 : if( status != PSA_SUCCESS && ciphertext_size != 0 )
3764 : 0 : memset( ciphertext, 0, ciphertext_size );
3765 : :
3766 : 18 : exit:
3767 : 18 : psa_unlock_key_slot( slot );
3768 : :
3769 : 18 : return( status );
3770 : : }
3771 : :
3772 : 16 : psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key,
3773 : : psa_algorithm_t alg,
3774 : : const uint8_t *nonce,
3775 : : size_t nonce_length,
3776 : : const uint8_t *additional_data,
3777 : : size_t additional_data_length,
3778 : : const uint8_t *ciphertext,
3779 : : size_t ciphertext_length,
3780 : : uint8_t *plaintext,
3781 : : size_t plaintext_size,
3782 : : size_t *plaintext_length )
3783 : : {
3784 : 16 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3785 : 16 : psa_key_slot_t *slot;
3786 : :
3787 : 16 : *plaintext_length = 0;
3788 : :
3789 [ + - + - : 16 : if( !PSA_ALG_IS_AEAD( alg ) || PSA_ALG_IS_WILDCARD( alg ) )
+ - + - +
- - + - -
- - - - -
- - - - -
- - - - +
- ]
3790 : : return( PSA_ERROR_NOT_SUPPORTED );
3791 : :
3792 : 16 : status = psa_get_and_lock_key_slot_with_policy(
3793 : : key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
3794 [ + - ]: 16 : if( status != PSA_SUCCESS )
3795 : : return( status );
3796 : :
3797 : 16 : psa_key_attributes_t attributes = {
3798 : 16 : .core = slot->attr
3799 : : };
3800 : :
3801 : 16 : status = psa_aead_check_nonce_length( alg, nonce_length );
3802 [ - + ]: 16 : if( status != PSA_SUCCESS )
3803 : 0 : goto exit;
3804 : :
3805 : 32 : status = psa_driver_wrapper_aead_decrypt(
3806 : 16 : &attributes, slot->key.data, slot->key.bytes,
3807 : : alg,
3808 : : nonce, nonce_length,
3809 : : additional_data, additional_data_length,
3810 : : ciphertext, ciphertext_length,
3811 : : plaintext, plaintext_size, plaintext_length );
3812 : :
3813 [ + - ]: 16 : if( status != PSA_SUCCESS && plaintext_size != 0 )
3814 : 0 : memset( plaintext, 0, plaintext_size );
3815 : :
3816 : 16 : exit:
3817 : 16 : psa_unlock_key_slot( slot );
3818 : :
3819 : 16 : return( status );
3820 : : }
3821 : :
3822 : : /* Set the key for a multipart authenticated operation. */
3823 : 0 : static psa_status_t psa_aead_setup( psa_aead_operation_t *operation,
3824 : : int is_encrypt,
3825 : : mbedtls_svc_key_id_t key,
3826 : : psa_algorithm_t alg )
3827 : : {
3828 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3829 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3830 : 0 : psa_key_slot_t *slot = NULL;
3831 : 0 : psa_key_usage_t key_usage = 0;
3832 : :
3833 [ # # # # : 0 : if( !PSA_ALG_IS_AEAD( alg ) || PSA_ALG_IS_WILDCARD( alg ) )
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
3834 : : {
3835 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3836 : 0 : goto exit;
3837 : : }
3838 : :
3839 [ # # ]: 0 : if( operation->id != 0 )
3840 : : {
3841 : 0 : status = PSA_ERROR_BAD_STATE;
3842 : 0 : goto exit;
3843 : : }
3844 : :
3845 : 0 : if( operation->nonce_set || operation->lengths_set ||
3846 [ # # ]: 0 : operation->ad_started || operation->body_started )
3847 : : {
3848 : 0 : status = PSA_ERROR_BAD_STATE;
3849 : 0 : goto exit;
3850 : : }
3851 : :
3852 [ # # ]: 0 : if( is_encrypt )
3853 : : key_usage = PSA_KEY_USAGE_ENCRYPT;
3854 : : else
3855 : 0 : key_usage = PSA_KEY_USAGE_DECRYPT;
3856 : :
3857 : 0 : status = psa_get_and_lock_key_slot_with_policy( key, &slot, key_usage,
3858 : : alg );
3859 [ # # ]: 0 : if( status != PSA_SUCCESS )
3860 : 0 : goto exit;
3861 : :
3862 : 0 : psa_key_attributes_t attributes = {
3863 : 0 : .core = slot->attr
3864 : : };
3865 : :
3866 [ # # ]: 0 : if( is_encrypt )
3867 : 0 : status = psa_driver_wrapper_aead_encrypt_setup( operation,
3868 : : &attributes,
3869 : 0 : slot->key.data,
3870 : : slot->key.bytes,
3871 : : alg );
3872 : : else
3873 : 0 : status = psa_driver_wrapper_aead_decrypt_setup( operation,
3874 : : &attributes,
3875 : 0 : slot->key.data,
3876 : : slot->key.bytes,
3877 : : alg );
3878 [ # # ]: 0 : if( status != PSA_SUCCESS )
3879 : 0 : goto exit;
3880 : :
3881 : 0 : operation->key_type = psa_get_key_type( &attributes );
3882 : :
3883 : 0 : exit:
3884 : 0 : unlock_status = psa_unlock_key_slot( slot );
3885 : :
3886 [ # # ]: 0 : if( status == PSA_SUCCESS )
3887 : : {
3888 : 0 : status = unlock_status;
3889 : 0 : operation->alg = psa_aead_get_base_algorithm( alg );
3890 : 0 : operation->is_encrypt = is_encrypt;
3891 : : }
3892 : : else
3893 : 0 : psa_aead_abort( operation );
3894 : :
3895 : 0 : return( status );
3896 : : }
3897 : :
3898 : : /* Set the key for a multipart authenticated encryption operation. */
3899 : 0 : psa_status_t psa_aead_encrypt_setup( psa_aead_operation_t *operation,
3900 : : mbedtls_svc_key_id_t key,
3901 : : psa_algorithm_t alg )
3902 : : {
3903 : 0 : return( psa_aead_setup( operation, 1, key, alg ) );
3904 : : }
3905 : :
3906 : : /* Set the key for a multipart authenticated decryption operation. */
3907 : 0 : psa_status_t psa_aead_decrypt_setup( psa_aead_operation_t *operation,
3908 : : mbedtls_svc_key_id_t key,
3909 : : psa_algorithm_t alg )
3910 : : {
3911 : 0 : return( psa_aead_setup( operation, 0, key, alg ) );
3912 : : }
3913 : :
3914 : : /* Generate a random nonce / IV for multipart AEAD operation */
3915 : 0 : psa_status_t psa_aead_generate_nonce( psa_aead_operation_t *operation,
3916 : : uint8_t *nonce,
3917 : : size_t nonce_size,
3918 : : size_t *nonce_length )
3919 : : {
3920 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3921 : 0 : uint8_t local_nonce[PSA_AEAD_NONCE_MAX_SIZE];
3922 : 0 : size_t required_nonce_size;
3923 : :
3924 : 0 : *nonce_length = 0;
3925 : :
3926 [ # # ]: 0 : if( operation->id == 0 )
3927 : : {
3928 : 0 : status = PSA_ERROR_BAD_STATE;
3929 : 0 : goto exit;
3930 : : }
3931 : :
3932 [ # # ]: 0 : if( operation->nonce_set || !operation->is_encrypt )
3933 : : {
3934 : 0 : status = PSA_ERROR_BAD_STATE;
3935 : 0 : goto exit;
3936 : : }
3937 : :
3938 : : /* For CCM, this size may not be correct according to the PSA
3939 : : * specification. The PSA Crypto 1.0.1 specification states:
3940 : : *
3941 : : * CCM encodes the plaintext length pLen in L octets, with L the smallest
3942 : : * integer >= 2 where pLen < 2^(8L). The nonce length is then 15 - L bytes.
3943 : : *
3944 : : * However this restriction that L has to be the smallest integer is not
3945 : : * applied in practice, and it is not implementable here since the
3946 : : * plaintext length may or may not be known at this time. */
3947 [ # # # # : 0 : required_nonce_size = PSA_AEAD_NONCE_LENGTH( operation->key_type,
# # # # #
# # # ]
3948 : : operation->alg );
3949 [ # # ]: 0 : if( nonce_size < required_nonce_size )
3950 : : {
3951 : 0 : status = PSA_ERROR_BUFFER_TOO_SMALL;
3952 : 0 : goto exit;
3953 : : }
3954 : :
3955 : 0 : status = psa_generate_random( local_nonce, required_nonce_size );
3956 [ # # ]: 0 : if( status != PSA_SUCCESS )
3957 : 0 : goto exit;
3958 : :
3959 : 0 : status = psa_aead_set_nonce( operation, local_nonce, required_nonce_size );
3960 : :
3961 : 0 : exit:
3962 [ # # ]: 0 : if( status == PSA_SUCCESS )
3963 : : {
3964 : 0 : memcpy( nonce, local_nonce, required_nonce_size );
3965 : 0 : *nonce_length = required_nonce_size;
3966 : : }
3967 : : else
3968 : 0 : psa_aead_abort( operation );
3969 : :
3970 : 0 : return( status );
3971 : : }
3972 : :
3973 : : /* Set the nonce for a multipart authenticated encryption or decryption
3974 : : operation.*/
3975 : 0 : psa_status_t psa_aead_set_nonce( psa_aead_operation_t *operation,
3976 : : const uint8_t *nonce,
3977 : : size_t nonce_length )
3978 : : {
3979 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3980 : :
3981 [ # # ]: 0 : if( operation->id == 0 )
3982 : : {
3983 : 0 : status = PSA_ERROR_BAD_STATE;
3984 : 0 : goto exit;
3985 : : }
3986 : :
3987 [ # # ]: 0 : if( operation->nonce_set )
3988 : : {
3989 : 0 : status = PSA_ERROR_BAD_STATE;
3990 : 0 : goto exit;
3991 : : }
3992 : :
3993 : 0 : status = psa_aead_check_nonce_length( operation->alg, nonce_length );
3994 [ # # ]: 0 : if( status != PSA_SUCCESS )
3995 : : {
3996 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
3997 : 0 : goto exit;
3998 : : }
3999 : :
4000 : 0 : status = psa_driver_wrapper_aead_set_nonce( operation, nonce,
4001 : : nonce_length );
4002 : :
4003 : 0 : exit:
4004 [ # # ]: 0 : if( status == PSA_SUCCESS )
4005 : 0 : operation->nonce_set = 1;
4006 : : else
4007 : 0 : psa_aead_abort( operation );
4008 : :
4009 : 0 : return( status );
4010 : : }
4011 : :
4012 : : /* Declare the lengths of the message and additional data for multipart AEAD. */
4013 : 0 : psa_status_t psa_aead_set_lengths( psa_aead_operation_t *operation,
4014 : : size_t ad_length,
4015 : : size_t plaintext_length )
4016 : : {
4017 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4018 : :
4019 [ # # ]: 0 : if( operation->id == 0 )
4020 : : {
4021 : 0 : status = PSA_ERROR_BAD_STATE;
4022 : 0 : goto exit;
4023 : : }
4024 : :
4025 [ # # ]: 0 : if( operation->lengths_set || operation->ad_started ||
4026 : : operation->body_started )
4027 : : {
4028 : 0 : status = PSA_ERROR_BAD_STATE;
4029 : 0 : goto exit;
4030 : : }
4031 : :
4032 [ # # ]: 0 : switch(operation->alg)
4033 : : {
4034 : : #if defined(PSA_WANT_ALG_GCM)
4035 : : case PSA_ALG_GCM:
4036 : : /* Lengths can only be too large for GCM if size_t is bigger than 32
4037 : : * bits. Without the guard this code will generate warnings on 32bit
4038 : : * builds. */
4039 : : #if SIZE_MAX > UINT32_MAX
4040 : : if( (( uint64_t ) ad_length ) >> 61 != 0 ||
4041 : : (( uint64_t ) plaintext_length ) > 0xFFFFFFFE0ull )
4042 : : {
4043 : : status = PSA_ERROR_INVALID_ARGUMENT;
4044 : : goto exit;
4045 : : }
4046 : : #endif
4047 : : break;
4048 : : #endif /* PSA_WANT_ALG_GCM */
4049 : : #if defined(PSA_WANT_ALG_CCM)
4050 : 0 : case PSA_ALG_CCM:
4051 [ # # ]: 0 : if( ad_length > 0xFF00 )
4052 : : {
4053 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
4054 : 0 : goto exit;
4055 : : }
4056 : : break;
4057 : : #endif /* PSA_WANT_ALG_CCM */
4058 : : #if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
4059 : : case PSA_ALG_CHACHA20_POLY1305:
4060 : : /* No length restrictions for ChaChaPoly. */
4061 : : break;
4062 : : #endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
4063 : : default:
4064 : : break;
4065 : : }
4066 : :
4067 : 0 : status = psa_driver_wrapper_aead_set_lengths( operation, ad_length,
4068 : : plaintext_length );
4069 : :
4070 : 0 : exit:
4071 [ # # ]: 0 : if( status == PSA_SUCCESS )
4072 : : {
4073 : 0 : operation->ad_remaining = ad_length;
4074 : 0 : operation->body_remaining = plaintext_length;
4075 : 0 : operation->lengths_set = 1;
4076 : : }
4077 : : else
4078 : 0 : psa_aead_abort( operation );
4079 : :
4080 : 0 : return( status );
4081 : : }
4082 : :
4083 : : /* Pass additional data to an active multipart AEAD operation. */
4084 : 0 : psa_status_t psa_aead_update_ad( psa_aead_operation_t *operation,
4085 : : const uint8_t *input,
4086 : : size_t input_length )
4087 : : {
4088 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4089 : :
4090 [ # # ]: 0 : if( operation->id == 0 )
4091 : : {
4092 : 0 : status = PSA_ERROR_BAD_STATE;
4093 : 0 : goto exit;
4094 : : }
4095 : :
4096 [ # # ]: 0 : if( !operation->nonce_set || operation->body_started )
4097 : : {
4098 : 0 : status = PSA_ERROR_BAD_STATE;
4099 : 0 : goto exit;
4100 : : }
4101 : :
4102 [ # # ]: 0 : if( operation->lengths_set )
4103 : : {
4104 [ # # ]: 0 : if( operation->ad_remaining < input_length )
4105 : : {
4106 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
4107 : 0 : goto exit;
4108 : : }
4109 : :
4110 : 0 : operation->ad_remaining -= input_length;
4111 : : }
4112 : : #if defined(PSA_WANT_ALG_CCM)
4113 [ # # ]: 0 : else if( operation->alg == PSA_ALG_CCM )
4114 : : {
4115 : 0 : status = PSA_ERROR_BAD_STATE;
4116 : 0 : goto exit;
4117 : : }
4118 : : #endif /* PSA_WANT_ALG_CCM */
4119 : :
4120 : 0 : status = psa_driver_wrapper_aead_update_ad( operation, input,
4121 : : input_length );
4122 : :
4123 : 0 : exit:
4124 [ # # ]: 0 : if( status == PSA_SUCCESS )
4125 : 0 : operation->ad_started = 1;
4126 : : else
4127 : 0 : psa_aead_abort( operation );
4128 : :
4129 : 0 : return( status );
4130 : : }
4131 : :
4132 : : /* Encrypt or decrypt a message fragment in an active multipart AEAD
4133 : : operation.*/
4134 : 0 : psa_status_t psa_aead_update( psa_aead_operation_t *operation,
4135 : : const uint8_t *input,
4136 : : size_t input_length,
4137 : : uint8_t *output,
4138 : : size_t output_size,
4139 : : size_t *output_length )
4140 : : {
4141 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4142 : :
4143 : 0 : *output_length = 0;
4144 : :
4145 [ # # ]: 0 : if( operation->id == 0 )
4146 : : {
4147 : 0 : status = PSA_ERROR_BAD_STATE;
4148 : 0 : goto exit;
4149 : : }
4150 : :
4151 [ # # ]: 0 : if( !operation->nonce_set )
4152 : : {
4153 : 0 : status = PSA_ERROR_BAD_STATE;
4154 : 0 : goto exit;
4155 : : }
4156 : :
4157 [ # # ]: 0 : if( operation->lengths_set )
4158 : : {
4159 : : /* Additional data length was supplied, but not all the additional
4160 : : data was supplied.*/
4161 [ # # ]: 0 : if( operation->ad_remaining != 0 )
4162 : : {
4163 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
4164 : 0 : goto exit;
4165 : : }
4166 : :
4167 : : /* Too much data provided. */
4168 [ # # ]: 0 : if( operation->body_remaining < input_length )
4169 : : {
4170 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
4171 : 0 : goto exit;
4172 : : }
4173 : :
4174 : 0 : operation->body_remaining -= input_length;
4175 : : }
4176 : : #if defined(PSA_WANT_ALG_CCM)
4177 [ # # ]: 0 : else if( operation->alg == PSA_ALG_CCM )
4178 : : {
4179 : 0 : status = PSA_ERROR_BAD_STATE;
4180 : 0 : goto exit;
4181 : : }
4182 : : #endif /* PSA_WANT_ALG_CCM */
4183 : :
4184 : 0 : status = psa_driver_wrapper_aead_update( operation, input, input_length,
4185 : : output, output_size,
4186 : : output_length );
4187 : :
4188 : 0 : exit:
4189 [ # # ]: 0 : if( status == PSA_SUCCESS )
4190 : 0 : operation->body_started = 1;
4191 : : else
4192 : 0 : psa_aead_abort( operation );
4193 : :
4194 : 0 : return( status );
4195 : : }
4196 : :
4197 : 0 : static psa_status_t psa_aead_final_checks( const psa_aead_operation_t *operation )
4198 : : {
4199 [ # # # # ]: 0 : if( operation->id == 0 || !operation->nonce_set )
4200 : : return( PSA_ERROR_BAD_STATE );
4201 : :
4202 [ # # # # ]: 0 : if( operation->lengths_set && ( operation->ad_remaining != 0 ||
4203 [ # # ]: 0 : operation->body_remaining != 0 ) )
4204 : 0 : return( PSA_ERROR_INVALID_ARGUMENT );
4205 : :
4206 : : return( PSA_SUCCESS );
4207 : : }
4208 : :
4209 : : /* Finish encrypting a message in a multipart AEAD operation. */
4210 : 0 : psa_status_t psa_aead_finish( psa_aead_operation_t *operation,
4211 : : uint8_t *ciphertext,
4212 : : size_t ciphertext_size,
4213 : : size_t *ciphertext_length,
4214 : : uint8_t *tag,
4215 : : size_t tag_size,
4216 : : size_t *tag_length )
4217 : : {
4218 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4219 : :
4220 : 0 : *ciphertext_length = 0;
4221 : 0 : *tag_length = tag_size;
4222 : :
4223 : 0 : status = psa_aead_final_checks( operation );
4224 [ # # ]: 0 : if( status != PSA_SUCCESS )
4225 : 0 : goto exit;
4226 : :
4227 [ # # ]: 0 : if( !operation->is_encrypt )
4228 : : {
4229 : 0 : status = PSA_ERROR_BAD_STATE;
4230 : 0 : goto exit;
4231 : : }
4232 : :
4233 : 0 : status = psa_driver_wrapper_aead_finish( operation, ciphertext,
4234 : : ciphertext_size,
4235 : : ciphertext_length,
4236 : : tag, tag_size, tag_length );
4237 : :
4238 : 0 : exit:
4239 : : /* In case the operation fails and the user fails to check for failure or
4240 : : * the zero tag size, make sure the tag is set to something implausible.
4241 : : * Even if the operation succeeds, make sure we clear the rest of the
4242 : : * buffer to prevent potential leakage of anything previously placed in
4243 : : * the same buffer.*/
4244 [ # # ]: 0 : if( tag != NULL )
4245 : : {
4246 [ # # ]: 0 : if( status != PSA_SUCCESS )
4247 : 0 : memset( tag, '!', tag_size );
4248 [ # # ]: 0 : else if( *tag_length < tag_size )
4249 : 0 : memset( tag + *tag_length, '!', ( tag_size - *tag_length ) );
4250 : : }
4251 : :
4252 : 0 : psa_aead_abort( operation );
4253 : :
4254 : 0 : return( status );
4255 : : }
4256 : :
4257 : : /* Finish authenticating and decrypting a message in a multipart AEAD
4258 : : operation.*/
4259 : 0 : psa_status_t psa_aead_verify( psa_aead_operation_t *operation,
4260 : : uint8_t *plaintext,
4261 : : size_t plaintext_size,
4262 : : size_t *plaintext_length,
4263 : : const uint8_t *tag,
4264 : : size_t tag_length )
4265 : : {
4266 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4267 : :
4268 : 0 : *plaintext_length = 0;
4269 : :
4270 : 0 : status = psa_aead_final_checks( operation );
4271 [ # # ]: 0 : if( status != PSA_SUCCESS )
4272 : 0 : goto exit;
4273 : :
4274 [ # # ]: 0 : if( operation->is_encrypt )
4275 : : {
4276 : 0 : status = PSA_ERROR_BAD_STATE;
4277 : 0 : goto exit;
4278 : : }
4279 : :
4280 : 0 : status = psa_driver_wrapper_aead_verify( operation, plaintext,
4281 : : plaintext_size,
4282 : : plaintext_length,
4283 : : tag, tag_length );
4284 : :
4285 : 0 : exit:
4286 : 0 : psa_aead_abort( operation );
4287 : :
4288 : 0 : return( status );
4289 : : }
4290 : :
4291 : : /* Abort an AEAD operation. */
4292 : 0 : psa_status_t psa_aead_abort( psa_aead_operation_t *operation )
4293 : : {
4294 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4295 : :
4296 [ # # ]: 0 : if( operation->id == 0 )
4297 : : {
4298 : : /* The object has (apparently) been initialized but it is not (yet)
4299 : : * in use. It's ok to call abort on such an object, and there's
4300 : : * nothing to do. */
4301 : : return( PSA_SUCCESS );
4302 : : }
4303 : :
4304 : 0 : status = psa_driver_wrapper_aead_abort( operation );
4305 : :
4306 : 0 : memset( operation, 0, sizeof( *operation ) );
4307 : :
4308 : 0 : return( status );
4309 : : }
4310 : :
4311 : : /****************************************************************/
4312 : : /* Generators */
4313 : : /****************************************************************/
4314 : :
4315 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
4316 : : defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4317 : : defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4318 : : #define AT_LEAST_ONE_BUILTIN_KDF
4319 : : #endif /* At least one builtin KDF */
4320 : :
4321 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
4322 : : defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4323 : : defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4324 : 0 : static psa_status_t psa_key_derivation_start_hmac(
4325 : : psa_mac_operation_t *operation,
4326 : : psa_algorithm_t hash_alg,
4327 : : const uint8_t *hmac_key,
4328 : : size_t hmac_key_length )
4329 : : {
4330 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4331 : 0 : psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4332 : 0 : psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC );
4333 : 0 : psa_set_key_bits( &attributes, PSA_BYTES_TO_BITS( hmac_key_length ) );
4334 : 0 : psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
4335 : :
4336 : 0 : operation->is_sign = 1;
4337 [ # # ]: 0 : operation->mac_size = PSA_HASH_LENGTH( hash_alg );
4338 : :
4339 : 0 : status = psa_driver_wrapper_mac_sign_setup( operation,
4340 : : &attributes,
4341 : : hmac_key, hmac_key_length,
4342 : : PSA_ALG_HMAC( hash_alg ) );
4343 : :
4344 : 0 : psa_reset_key_attributes( &attributes );
4345 : 0 : return( status );
4346 : : }
4347 : : #endif /* KDF algorithms reliant on HMAC */
4348 : :
4349 : : #define HKDF_STATE_INIT 0 /* no input yet */
4350 : : #define HKDF_STATE_STARTED 1 /* got salt */
4351 : : #define HKDF_STATE_KEYED 2 /* got key */
4352 : : #define HKDF_STATE_OUTPUT 3 /* output started */
4353 : :
4354 : 0 : static psa_algorithm_t psa_key_derivation_get_kdf_alg(
4355 : : const psa_key_derivation_operation_t *operation )
4356 : : {
4357 [ # # ]: 0 : if ( PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
4358 : 0 : return( PSA_ALG_KEY_AGREEMENT_GET_KDF( operation->alg ) );
4359 : : else
4360 : : return( operation->alg );
4361 : : }
4362 : :
4363 : 0 : psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation )
4364 : : {
4365 : 0 : psa_status_t status = PSA_SUCCESS;
4366 : 0 : psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
4367 [ # # ]: 0 : if( kdf_alg == 0 )
4368 : : {
4369 : : /* The object has (apparently) been initialized but it is not
4370 : : * in use. It's ok to call abort on such an object, and there's
4371 : : * nothing to do. */
4372 : : }
4373 : : else
4374 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
4375 : : if( PSA_ALG_IS_HKDF( kdf_alg ) )
4376 : : {
4377 : : mbedtls_free( operation->ctx.hkdf.info );
4378 : : status = psa_mac_abort( &operation->ctx.hkdf.hmac );
4379 : : }
4380 : : else
4381 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF */
4382 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4383 : : defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4384 [ # # ]: 0 : if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
4385 : : /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */
4386 : : PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
4387 : : {
4388 [ # # ]: 0 : if( operation->ctx.tls12_prf.secret != NULL )
4389 : : {
4390 : 0 : mbedtls_platform_zeroize( operation->ctx.tls12_prf.secret,
4391 : : operation->ctx.tls12_prf.secret_length );
4392 : 0 : mbedtls_free( operation->ctx.tls12_prf.secret );
4393 : : }
4394 : :
4395 [ # # ]: 0 : if( operation->ctx.tls12_prf.seed != NULL )
4396 : : {
4397 : 0 : mbedtls_platform_zeroize( operation->ctx.tls12_prf.seed,
4398 : : operation->ctx.tls12_prf.seed_length );
4399 : 0 : mbedtls_free( operation->ctx.tls12_prf.seed );
4400 : : }
4401 : :
4402 [ # # ]: 0 : if( operation->ctx.tls12_prf.label != NULL )
4403 : : {
4404 : 0 : mbedtls_platform_zeroize( operation->ctx.tls12_prf.label,
4405 : : operation->ctx.tls12_prf.label_length );
4406 : 0 : mbedtls_free( operation->ctx.tls12_prf.label );
4407 : : }
4408 : :
4409 : : status = PSA_SUCCESS;
4410 : :
4411 : : /* We leave the fields Ai and output_block to be erased safely by the
4412 : : * mbedtls_platform_zeroize() in the end of this function. */
4413 : : }
4414 : : else
4415 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
4416 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) */
4417 : : {
4418 : : status = PSA_ERROR_BAD_STATE;
4419 : : }
4420 : 0 : mbedtls_platform_zeroize( operation, sizeof( *operation ) );
4421 : 0 : return( status );
4422 : : }
4423 : :
4424 : 0 : psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation,
4425 : : size_t *capacity)
4426 : : {
4427 [ # # ]: 0 : if( operation->alg == 0 )
4428 : : {
4429 : : /* This is a blank key derivation operation. */
4430 : : return( PSA_ERROR_BAD_STATE );
4431 : : }
4432 : :
4433 : 0 : *capacity = operation->capacity;
4434 : 0 : return( PSA_SUCCESS );
4435 : : }
4436 : :
4437 : 0 : psa_status_t psa_key_derivation_set_capacity( psa_key_derivation_operation_t *operation,
4438 : : size_t capacity )
4439 : : {
4440 [ # # ]: 0 : if( operation->alg == 0 )
4441 : : return( PSA_ERROR_BAD_STATE );
4442 [ # # ]: 0 : if( capacity > operation->capacity )
4443 : : return( PSA_ERROR_INVALID_ARGUMENT );
4444 : 0 : operation->capacity = capacity;
4445 : 0 : return( PSA_SUCCESS );
4446 : : }
4447 : :
4448 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
4449 : : /* Read some bytes from an HKDF-based operation. This performs a chunk
4450 : : * of the expand phase of the HKDF algorithm. */
4451 : : static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkdf,
4452 : : psa_algorithm_t hash_alg,
4453 : : uint8_t *output,
4454 : : size_t output_length )
4455 : : {
4456 : : uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
4457 : : size_t hmac_output_length;
4458 : : psa_status_t status;
4459 : :
4460 : : if( hkdf->state < HKDF_STATE_KEYED || ! hkdf->info_set )
4461 : : return( PSA_ERROR_BAD_STATE );
4462 : : hkdf->state = HKDF_STATE_OUTPUT;
4463 : :
4464 : : while( output_length != 0 )
4465 : : {
4466 : : /* Copy what remains of the current block */
4467 : : uint8_t n = hash_length - hkdf->offset_in_block;
4468 : : if( n > output_length )
4469 : : n = (uint8_t) output_length;
4470 : : memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
4471 : : output += n;
4472 : : output_length -= n;
4473 : : hkdf->offset_in_block += n;
4474 : : if( output_length == 0 )
4475 : : break;
4476 : : /* We can't be wanting more output after block 0xff, otherwise
4477 : : * the capacity check in psa_key_derivation_output_bytes() would have
4478 : : * prevented this call. It could happen only if the operation
4479 : : * object was corrupted or if this function is called directly
4480 : : * inside the library. */
4481 : : if( hkdf->block_number == 0xff )
4482 : : return( PSA_ERROR_BAD_STATE );
4483 : :
4484 : : /* We need a new block */
4485 : : ++hkdf->block_number;
4486 : : hkdf->offset_in_block = 0;
4487 : :
4488 : : status = psa_key_derivation_start_hmac( &hkdf->hmac,
4489 : : hash_alg,
4490 : : hkdf->prk,
4491 : : hash_length );
4492 : : if( status != PSA_SUCCESS )
4493 : : return( status );
4494 : :
4495 : : if( hkdf->block_number != 1 )
4496 : : {
4497 : : status = psa_mac_update( &hkdf->hmac,
4498 : : hkdf->output_block,
4499 : : hash_length );
4500 : : if( status != PSA_SUCCESS )
4501 : : return( status );
4502 : : }
4503 : : status = psa_mac_update( &hkdf->hmac,
4504 : : hkdf->info,
4505 : : hkdf->info_length );
4506 : : if( status != PSA_SUCCESS )
4507 : : return( status );
4508 : : status = psa_mac_update( &hkdf->hmac,
4509 : : &hkdf->block_number, 1 );
4510 : : if( status != PSA_SUCCESS )
4511 : : return( status );
4512 : : status = psa_mac_sign_finish( &hkdf->hmac,
4513 : : hkdf->output_block,
4514 : : sizeof( hkdf->output_block ),
4515 : : &hmac_output_length );
4516 : : if( status != PSA_SUCCESS )
4517 : : return( status );
4518 : : }
4519 : :
4520 : : return( PSA_SUCCESS );
4521 : : }
4522 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
4523 : :
4524 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4525 : : defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4526 : 0 : static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
4527 : : psa_tls12_prf_key_derivation_t *tls12_prf,
4528 : : psa_algorithm_t alg )
4529 : : {
4530 : 0 : psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
4531 [ # # ]: 0 : uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
4532 : 0 : psa_mac_operation_t hmac = PSA_MAC_OPERATION_INIT;
4533 : 0 : size_t hmac_output_length;
4534 : 0 : psa_status_t status, cleanup_status;
4535 : :
4536 : : /* We can't be wanting more output after block 0xff, otherwise
4537 : : * the capacity check in psa_key_derivation_output_bytes() would have
4538 : : * prevented this call. It could happen only if the operation
4539 : : * object was corrupted or if this function is called directly
4540 : : * inside the library. */
4541 [ # # ]: 0 : if( tls12_prf->block_number == 0xff )
4542 : : return( PSA_ERROR_CORRUPTION_DETECTED );
4543 : :
4544 : : /* We need a new block */
4545 : 0 : ++tls12_prf->block_number;
4546 : 0 : tls12_prf->left_in_block = hash_length;
4547 : :
4548 : : /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
4549 : : *
4550 : : * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
4551 : : *
4552 : : * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
4553 : : * HMAC_hash(secret, A(2) + seed) +
4554 : : * HMAC_hash(secret, A(3) + seed) + ...
4555 : : *
4556 : : * A(0) = seed
4557 : : * A(i) = HMAC_hash(secret, A(i-1))
4558 : : *
4559 : : * The `psa_tls12_prf_key_derivation` structure saves the block
4560 : : * `HMAC_hash(secret, A(i) + seed)` from which the output
4561 : : * is currently extracted as `output_block` and where i is
4562 : : * `block_number`.
4563 : : */
4564 : :
4565 : 0 : status = psa_key_derivation_start_hmac( &hmac,
4566 : : hash_alg,
4567 : 0 : tls12_prf->secret,
4568 : : tls12_prf->secret_length );
4569 [ # # ]: 0 : if( status != PSA_SUCCESS )
4570 : 0 : goto cleanup;
4571 : :
4572 : : /* Calculate A(i) where i = tls12_prf->block_number. */
4573 [ # # ]: 0 : if( tls12_prf->block_number == 1 )
4574 : : {
4575 : : /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads
4576 : : * the variable seed and in this instance means it in the context of the
4577 : : * P_hash function, where seed = label + seed.) */
4578 : 0 : status = psa_mac_update( &hmac,
4579 : 0 : tls12_prf->label,
4580 : : tls12_prf->label_length );
4581 [ # # ]: 0 : if( status != PSA_SUCCESS )
4582 : 0 : goto cleanup;
4583 : 0 : status = psa_mac_update( &hmac,
4584 : 0 : tls12_prf->seed,
4585 : : tls12_prf->seed_length );
4586 [ # # ]: 0 : if( status != PSA_SUCCESS )
4587 : 0 : goto cleanup;
4588 : : }
4589 : : else
4590 : : {
4591 : : /* A(i) = HMAC_hash(secret, A(i-1)) */
4592 : 0 : status = psa_mac_update( &hmac, tls12_prf->Ai, hash_length );
4593 [ # # ]: 0 : if( status != PSA_SUCCESS )
4594 : 0 : goto cleanup;
4595 : : }
4596 : :
4597 : 0 : status = psa_mac_sign_finish( &hmac,
4598 : 0 : tls12_prf->Ai, hash_length,
4599 : : &hmac_output_length );
4600 [ # # ]: 0 : if( hmac_output_length != hash_length )
4601 : : status = PSA_ERROR_CORRUPTION_DETECTED;
4602 [ # # ]: 0 : if( status != PSA_SUCCESS )
4603 : 0 : goto cleanup;
4604 : :
4605 : : /* Calculate HMAC_hash(secret, A(i) + label + seed). */
4606 : 0 : status = psa_key_derivation_start_hmac( &hmac,
4607 : : hash_alg,
4608 : 0 : tls12_prf->secret,
4609 : : tls12_prf->secret_length );
4610 [ # # ]: 0 : if( status != PSA_SUCCESS )
4611 : 0 : goto cleanup;
4612 : 0 : status = psa_mac_update( &hmac, tls12_prf->Ai, hash_length );
4613 [ # # ]: 0 : if( status != PSA_SUCCESS )
4614 : 0 : goto cleanup;
4615 : 0 : status = psa_mac_update( &hmac, tls12_prf->label, tls12_prf->label_length );
4616 [ # # ]: 0 : if( status != PSA_SUCCESS )
4617 : 0 : goto cleanup;
4618 : 0 : status = psa_mac_update( &hmac, tls12_prf->seed, tls12_prf->seed_length );
4619 [ # # ]: 0 : if( status != PSA_SUCCESS )
4620 : 0 : goto cleanup;
4621 : 0 : status = psa_mac_sign_finish( &hmac,
4622 : 0 : tls12_prf->output_block, hash_length,
4623 : : &hmac_output_length );
4624 [ # # ]: 0 : if( status != PSA_SUCCESS )
4625 : 0 : goto cleanup;
4626 : :
4627 : :
4628 : 0 : cleanup:
4629 : 0 : cleanup_status = psa_mac_abort( &hmac );
4630 [ # # ]: 0 : if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
4631 : 0 : status = cleanup_status;
4632 : :
4633 : : return( status );
4634 : : }
4635 : :
4636 : 0 : static psa_status_t psa_key_derivation_tls12_prf_read(
4637 : : psa_tls12_prf_key_derivation_t *tls12_prf,
4638 : : psa_algorithm_t alg,
4639 : : uint8_t *output,
4640 : : size_t output_length )
4641 : : {
4642 : 0 : psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
4643 [ # # ]: 0 : uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
4644 : 0 : psa_status_t status;
4645 : 0 : uint8_t offset, length;
4646 : :
4647 [ # # # ]: 0 : switch( tls12_prf->state )
4648 : : {
4649 : 0 : case PSA_TLS12_PRF_STATE_LABEL_SET:
4650 : 0 : tls12_prf->state = PSA_TLS12_PRF_STATE_OUTPUT;
4651 : 0 : break;
4652 : : case PSA_TLS12_PRF_STATE_OUTPUT:
4653 : : break;
4654 : : default:
4655 : : return( PSA_ERROR_BAD_STATE );
4656 : : }
4657 : :
4658 [ # # ]: 0 : while( output_length != 0 )
4659 : : {
4660 : : /* Check if we have fully processed the current block. */
4661 [ # # ]: 0 : if( tls12_prf->left_in_block == 0 )
4662 : : {
4663 : 0 : status = psa_key_derivation_tls12_prf_generate_next_block( tls12_prf,
4664 : : alg );
4665 [ # # ]: 0 : if( status != PSA_SUCCESS )
4666 : 0 : return( status );
4667 : :
4668 : 0 : continue;
4669 : : }
4670 : :
4671 [ # # ]: 0 : if( tls12_prf->left_in_block > output_length )
4672 : 0 : length = (uint8_t) output_length;
4673 : : else
4674 : : length = tls12_prf->left_in_block;
4675 : :
4676 : 0 : offset = hash_length - tls12_prf->left_in_block;
4677 : 0 : memcpy( output, tls12_prf->output_block + offset, length );
4678 : 0 : output += length;
4679 : 0 : output_length -= length;
4680 : 0 : tls12_prf->left_in_block -= length;
4681 : : }
4682 : :
4683 : : return( PSA_SUCCESS );
4684 : : }
4685 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
4686 : : * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
4687 : :
4688 : 0 : psa_status_t psa_key_derivation_output_bytes(
4689 : : psa_key_derivation_operation_t *operation,
4690 : : uint8_t *output,
4691 : : size_t output_length )
4692 : : {
4693 : 0 : psa_status_t status;
4694 : 0 : psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
4695 : :
4696 [ # # ]: 0 : if( operation->alg == 0 )
4697 : : {
4698 : : /* This is a blank operation. */
4699 : : return( PSA_ERROR_BAD_STATE );
4700 : : }
4701 : :
4702 [ # # ]: 0 : if( output_length > operation->capacity )
4703 : : {
4704 : 0 : operation->capacity = 0;
4705 : : /* Go through the error path to wipe all confidential data now
4706 : : * that the operation object is useless. */
4707 : 0 : status = PSA_ERROR_INSUFFICIENT_DATA;
4708 : 0 : goto exit;
4709 : : }
4710 [ # # # # ]: 0 : if( output_length == 0 && operation->capacity == 0 )
4711 : : {
4712 : : /* Edge case: this is a finished operation, and 0 bytes
4713 : : * were requested. The right error in this case could
4714 : : * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
4715 : : * INSUFFICIENT_CAPACITY, which is right for a finished
4716 : : * operation, for consistency with the case when
4717 : : * output_length > 0. */
4718 : : return( PSA_ERROR_INSUFFICIENT_DATA );
4719 : : }
4720 : 0 : operation->capacity -= output_length;
4721 : :
4722 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
4723 : : if( PSA_ALG_IS_HKDF( kdf_alg ) )
4724 : : {
4725 : : psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
4726 : : status = psa_key_derivation_hkdf_read( &operation->ctx.hkdf, hash_alg,
4727 : : output, output_length );
4728 : : }
4729 : : else
4730 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
4731 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4732 : : defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4733 [ # # ]: 0 : if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
4734 : : PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
4735 : : {
4736 : 0 : status = psa_key_derivation_tls12_prf_read( &operation->ctx.tls12_prf,
4737 : : kdf_alg, output,
4738 : : output_length );
4739 : : }
4740 : : else
4741 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
4742 : : * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
4743 : : {
4744 : : (void) kdf_alg;
4745 : : return( PSA_ERROR_BAD_STATE );
4746 : : }
4747 : :
4748 : 0 : exit:
4749 [ # # ]: 0 : if( status != PSA_SUCCESS )
4750 : : {
4751 : : /* Preserve the algorithm upon errors, but clear all sensitive state.
4752 : : * This allows us to differentiate between exhausted operations and
4753 : : * blank operations, so we can return PSA_ERROR_BAD_STATE on blank
4754 : : * operations. */
4755 : 0 : psa_algorithm_t alg = operation->alg;
4756 : 0 : psa_key_derivation_abort( operation );
4757 : 0 : operation->alg = alg;
4758 : 0 : memset( output, '!', output_length );
4759 : : }
4760 : : return( status );
4761 : : }
4762 : :
4763 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
4764 : : static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
4765 : : {
4766 : : if( data_size >= 8 )
4767 : : mbedtls_des_key_set_parity( data );
4768 : : if( data_size >= 16 )
4769 : : mbedtls_des_key_set_parity( data + 8 );
4770 : : if( data_size >= 24 )
4771 : : mbedtls_des_key_set_parity( data + 16 );
4772 : : }
4773 : : #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
4774 : :
4775 : 0 : static psa_status_t psa_generate_derived_key_internal(
4776 : : psa_key_slot_t *slot,
4777 : : size_t bits,
4778 : : psa_key_derivation_operation_t *operation )
4779 : : {
4780 : 0 : uint8_t *data = NULL;
4781 : 0 : size_t bytes = PSA_BITS_TO_BYTES( bits );
4782 : 0 : size_t storage_size = bytes;
4783 : 0 : psa_status_t status;
4784 : :
4785 [ # # ]: 0 : if( ! key_type_is_raw_bytes( slot->attr.type ) )
4786 : : return( PSA_ERROR_INVALID_ARGUMENT );
4787 [ # # ]: 0 : if( bits % 8 != 0 )
4788 : : return( PSA_ERROR_INVALID_ARGUMENT );
4789 : 0 : data = mbedtls_calloc( 1, bytes );
4790 [ # # ]: 0 : if( data == NULL )
4791 : : return( PSA_ERROR_INSUFFICIENT_MEMORY );
4792 : :
4793 : 0 : status = psa_key_derivation_output_bytes( operation, data, bytes );
4794 [ # # ]: 0 : if( status != PSA_SUCCESS )
4795 : 0 : goto exit;
4796 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
4797 : : if( slot->attr.type == PSA_KEY_TYPE_DES )
4798 : : psa_des_set_key_parity( data, bytes );
4799 : : #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
4800 : :
4801 : 0 : slot->attr.bits = (psa_key_bits_t) bits;
4802 : 0 : psa_key_attributes_t attributes = {
4803 : : .core = slot->attr
4804 : : };
4805 : :
4806 [ # # ]: 0 : if( psa_key_lifetime_is_external( attributes.core.lifetime ) )
4807 : : {
4808 : 0 : status = psa_driver_wrapper_get_key_buffer_size( &attributes,
4809 : : &storage_size );
4810 [ # # ]: 0 : if( status != PSA_SUCCESS )
4811 : 0 : goto exit;
4812 : : }
4813 : 0 : status = psa_allocate_buffer_to_slot( slot, storage_size );
4814 [ # # ]: 0 : if( status != PSA_SUCCESS )
4815 : 0 : goto exit;
4816 : :
4817 : 0 : status = psa_driver_wrapper_import_key( &attributes,
4818 : : data, bytes,
4819 : : slot->key.data,
4820 : : slot->key.bytes,
4821 : : &slot->key.bytes, &bits );
4822 [ # # ]: 0 : if( bits != slot->attr.bits )
4823 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
4824 : :
4825 : 0 : exit:
4826 : 0 : mbedtls_free( data );
4827 : 0 : return( status );
4828 : : }
4829 : :
4830 : 0 : psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attributes,
4831 : : psa_key_derivation_operation_t *operation,
4832 : : mbedtls_svc_key_id_t *key )
4833 : : {
4834 : 0 : psa_status_t status;
4835 : 0 : psa_key_slot_t *slot = NULL;
4836 : 0 : psa_se_drv_table_entry_t *driver = NULL;
4837 : :
4838 : 0 : *key = MBEDTLS_SVC_KEY_ID_INIT;
4839 : :
4840 : : /* Reject any attempt to create a zero-length key so that we don't
4841 : : * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
4842 [ # # ]: 0 : if( psa_get_key_bits( attributes ) == 0 )
4843 : : return( PSA_ERROR_INVALID_ARGUMENT );
4844 : :
4845 [ # # ]: 0 : if( operation->alg == PSA_ALG_NONE )
4846 : : return( PSA_ERROR_BAD_STATE );
4847 : :
4848 [ # # ]: 0 : if( ! operation->can_output_key )
4849 : : return( PSA_ERROR_NOT_PERMITTED );
4850 : :
4851 : 0 : status = psa_start_key_creation( PSA_KEY_CREATION_DERIVE, attributes,
4852 : : &slot, &driver );
4853 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
4854 : : if( driver != NULL )
4855 : : {
4856 : : /* Deriving a key in a secure element is not implemented yet. */
4857 : : status = PSA_ERROR_NOT_SUPPORTED;
4858 : : }
4859 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
4860 [ # # ]: 0 : if( status == PSA_SUCCESS )
4861 : : {
4862 : 0 : status = psa_generate_derived_key_internal( slot,
4863 : 0 : attributes->core.bits,
4864 : : operation );
4865 : : }
4866 [ # # ]: 0 : if( status == PSA_SUCCESS )
4867 : 0 : status = psa_finish_key_creation( slot, driver, key );
4868 [ # # ]: 0 : if( status != PSA_SUCCESS )
4869 : 0 : psa_fail_key_creation( slot, driver );
4870 : :
4871 : : return( status );
4872 : : }
4873 : :
4874 : :
4875 : :
4876 : : /****************************************************************/
4877 : : /* Key derivation */
4878 : : /****************************************************************/
4879 : :
4880 : : #if defined(AT_LEAST_ONE_BUILTIN_KDF)
4881 : 0 : static psa_status_t psa_key_derivation_setup_kdf(
4882 : : psa_key_derivation_operation_t *operation,
4883 : : psa_algorithm_t kdf_alg )
4884 : : {
4885 : 0 : int is_kdf_alg_supported;
4886 : :
4887 : : /* Make sure that operation->ctx is properly zero-initialised. (Macro
4888 : : * initialisers for this union leave some bytes unspecified.) */
4889 [ # # ]: 0 : memset( &operation->ctx, 0, sizeof( operation->ctx ) );
4890 : :
4891 : : /* Make sure that kdf_alg is a supported key derivation algorithm. */
4892 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
4893 : : if( PSA_ALG_IS_HKDF( kdf_alg ) )
4894 : : is_kdf_alg_supported = 1;
4895 : : else
4896 : : #endif
4897 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
4898 [ # # ]: 0 : if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
4899 : : is_kdf_alg_supported = 1;
4900 : : else
4901 : : #endif
4902 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4903 [ # # ]: 0 : if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
4904 : : is_kdf_alg_supported = 1;
4905 : : else
4906 : : #endif
4907 : : is_kdf_alg_supported = 0;
4908 : :
4909 : : if( is_kdf_alg_supported )
4910 : : {
4911 : 0 : psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
4912 [ # # ]: 0 : size_t hash_size = PSA_HASH_LENGTH( hash_alg );
4913 [ # # ]: 0 : if( hash_size == 0 )
4914 : : return( PSA_ERROR_NOT_SUPPORTED );
4915 [ # # ]: 0 : if( ( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
4916 : 0 : PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) &&
4917 [ # # ]: 0 : ! ( hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384 ) )
4918 : : {
4919 : : return( PSA_ERROR_NOT_SUPPORTED );
4920 : : }
4921 : 0 : operation->capacity = 255 * hash_size;
4922 : 0 : return( PSA_SUCCESS );
4923 : : }
4924 : :
4925 : : return( PSA_ERROR_NOT_SUPPORTED );
4926 : : }
4927 : : #endif /* AT_LEAST_ONE_BUILTIN_KDF */
4928 : :
4929 : 0 : psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation,
4930 : : psa_algorithm_t alg )
4931 : : {
4932 : 0 : psa_status_t status;
4933 : :
4934 [ # # ]: 0 : if( operation->alg != 0 )
4935 : : return( PSA_ERROR_BAD_STATE );
4936 : :
4937 [ # # # # ]: 0 : if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
4938 : : return( PSA_ERROR_INVALID_ARGUMENT );
4939 [ # # ]: 0 : else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
4940 : : {
4941 : : #if defined(AT_LEAST_ONE_BUILTIN_KDF)
4942 : 0 : psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
4943 : 0 : status = psa_key_derivation_setup_kdf( operation, kdf_alg );
4944 : : #else
4945 : : return( PSA_ERROR_NOT_SUPPORTED );
4946 : : #endif /* AT_LEAST_ONE_BUILTIN_KDF */
4947 : : }
4948 [ # # ]: 0 : else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
4949 : : {
4950 : : #if defined(AT_LEAST_ONE_BUILTIN_KDF)
4951 : 0 : status = psa_key_derivation_setup_kdf( operation, alg );
4952 : : #else
4953 : : return( PSA_ERROR_NOT_SUPPORTED );
4954 : : #endif /* AT_LEAST_ONE_BUILTIN_KDF */
4955 : : }
4956 : : else
4957 : : return( PSA_ERROR_INVALID_ARGUMENT );
4958 : :
4959 [ # # ]: 0 : if( status == PSA_SUCCESS )
4960 : 0 : operation->alg = alg;
4961 : : return( status );
4962 : : }
4963 : :
4964 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
4965 : : static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf,
4966 : : psa_algorithm_t hash_alg,
4967 : : psa_key_derivation_step_t step,
4968 : : const uint8_t *data,
4969 : : size_t data_length )
4970 : : {
4971 : : psa_status_t status;
4972 : : switch( step )
4973 : : {
4974 : : case PSA_KEY_DERIVATION_INPUT_SALT:
4975 : : if( hkdf->state != HKDF_STATE_INIT )
4976 : : return( PSA_ERROR_BAD_STATE );
4977 : : else
4978 : : {
4979 : : status = psa_key_derivation_start_hmac( &hkdf->hmac,
4980 : : hash_alg,
4981 : : data, data_length );
4982 : : if( status != PSA_SUCCESS )
4983 : : return( status );
4984 : : hkdf->state = HKDF_STATE_STARTED;
4985 : : return( PSA_SUCCESS );
4986 : : }
4987 : : case PSA_KEY_DERIVATION_INPUT_SECRET:
4988 : : /* If no salt was provided, use an empty salt. */
4989 : : if( hkdf->state == HKDF_STATE_INIT )
4990 : : {
4991 : : status = psa_key_derivation_start_hmac( &hkdf->hmac,
4992 : : hash_alg,
4993 : : NULL, 0 );
4994 : : if( status != PSA_SUCCESS )
4995 : : return( status );
4996 : : hkdf->state = HKDF_STATE_STARTED;
4997 : : }
4998 : : if( hkdf->state != HKDF_STATE_STARTED )
4999 : : return( PSA_ERROR_BAD_STATE );
5000 : : status = psa_mac_update( &hkdf->hmac,
5001 : : data, data_length );
5002 : : if( status != PSA_SUCCESS )
5003 : : return( status );
5004 : : status = psa_mac_sign_finish( &hkdf->hmac,
5005 : : hkdf->prk,
5006 : : sizeof( hkdf->prk ),
5007 : : &data_length );
5008 : : if( status != PSA_SUCCESS )
5009 : : return( status );
5010 : : hkdf->offset_in_block = PSA_HASH_LENGTH( hash_alg );
5011 : : hkdf->block_number = 0;
5012 : : hkdf->state = HKDF_STATE_KEYED;
5013 : : return( PSA_SUCCESS );
5014 : : case PSA_KEY_DERIVATION_INPUT_INFO:
5015 : : if( hkdf->state == HKDF_STATE_OUTPUT )
5016 : : return( PSA_ERROR_BAD_STATE );
5017 : : if( hkdf->info_set )
5018 : : return( PSA_ERROR_BAD_STATE );
5019 : : hkdf->info_length = data_length;
5020 : : if( data_length != 0 )
5021 : : {
5022 : : hkdf->info = mbedtls_calloc( 1, data_length );
5023 : : if( hkdf->info == NULL )
5024 : : return( PSA_ERROR_INSUFFICIENT_MEMORY );
5025 : : memcpy( hkdf->info, data, data_length );
5026 : : }
5027 : : hkdf->info_set = 1;
5028 : : return( PSA_SUCCESS );
5029 : : default:
5030 : : return( PSA_ERROR_INVALID_ARGUMENT );
5031 : : }
5032 : : }
5033 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
5034 : :
5035 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5036 : : defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5037 : 0 : static psa_status_t psa_tls12_prf_set_seed( psa_tls12_prf_key_derivation_t *prf,
5038 : : const uint8_t *data,
5039 : : size_t data_length )
5040 : : {
5041 [ # # ]: 0 : if( prf->state != PSA_TLS12_PRF_STATE_INIT )
5042 : : return( PSA_ERROR_BAD_STATE );
5043 : :
5044 [ # # ]: 0 : if( data_length != 0 )
5045 : : {
5046 : 0 : prf->seed = mbedtls_calloc( 1, data_length );
5047 [ # # ]: 0 : if( prf->seed == NULL )
5048 : : return( PSA_ERROR_INSUFFICIENT_MEMORY );
5049 : :
5050 : 0 : memcpy( prf->seed, data, data_length );
5051 : 0 : prf->seed_length = data_length;
5052 : : }
5053 : :
5054 : 0 : prf->state = PSA_TLS12_PRF_STATE_SEED_SET;
5055 : :
5056 : 0 : return( PSA_SUCCESS );
5057 : : }
5058 : :
5059 : 0 : static psa_status_t psa_tls12_prf_set_key( psa_tls12_prf_key_derivation_t *prf,
5060 : : const uint8_t *data,
5061 : : size_t data_length )
5062 : : {
5063 [ # # ]: 0 : if( prf->state != PSA_TLS12_PRF_STATE_SEED_SET )
5064 : : return( PSA_ERROR_BAD_STATE );
5065 : :
5066 [ # # ]: 0 : if( data_length != 0 )
5067 : : {
5068 : 0 : prf->secret = mbedtls_calloc( 1, data_length );
5069 [ # # ]: 0 : if( prf->secret == NULL )
5070 : : return( PSA_ERROR_INSUFFICIENT_MEMORY );
5071 : :
5072 : 0 : memcpy( prf->secret, data, data_length );
5073 : 0 : prf->secret_length = data_length;
5074 : : }
5075 : :
5076 : 0 : prf->state = PSA_TLS12_PRF_STATE_KEY_SET;
5077 : :
5078 : 0 : return( PSA_SUCCESS );
5079 : : }
5080 : :
5081 : 0 : static psa_status_t psa_tls12_prf_set_label( psa_tls12_prf_key_derivation_t *prf,
5082 : : const uint8_t *data,
5083 : : size_t data_length )
5084 : : {
5085 [ # # ]: 0 : if( prf->state != PSA_TLS12_PRF_STATE_KEY_SET )
5086 : : return( PSA_ERROR_BAD_STATE );
5087 : :
5088 [ # # ]: 0 : if( data_length != 0 )
5089 : : {
5090 : 0 : prf->label = mbedtls_calloc( 1, data_length );
5091 [ # # ]: 0 : if( prf->label == NULL )
5092 : : return( PSA_ERROR_INSUFFICIENT_MEMORY );
5093 : :
5094 : 0 : memcpy( prf->label, data, data_length );
5095 : 0 : prf->label_length = data_length;
5096 : : }
5097 : :
5098 : 0 : prf->state = PSA_TLS12_PRF_STATE_LABEL_SET;
5099 : :
5100 : 0 : return( PSA_SUCCESS );
5101 : : }
5102 : :
5103 : 0 : static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf,
5104 : : psa_key_derivation_step_t step,
5105 : : const uint8_t *data,
5106 : : size_t data_length )
5107 : : {
5108 [ # # # # ]: 0 : switch( step )
5109 : : {
5110 : 0 : case PSA_KEY_DERIVATION_INPUT_SEED:
5111 : 0 : return( psa_tls12_prf_set_seed( prf, data, data_length ) );
5112 : 0 : case PSA_KEY_DERIVATION_INPUT_SECRET:
5113 : 0 : return( psa_tls12_prf_set_key( prf, data, data_length ) );
5114 : 0 : case PSA_KEY_DERIVATION_INPUT_LABEL:
5115 : 0 : return( psa_tls12_prf_set_label( prf, data, data_length ) );
5116 : : default:
5117 : : return( PSA_ERROR_INVALID_ARGUMENT );
5118 : : }
5119 : : }
5120 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
5121 : : * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
5122 : :
5123 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5124 : 0 : static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
5125 : : psa_tls12_prf_key_derivation_t *prf,
5126 : : const uint8_t *data,
5127 : : size_t data_length )
5128 : : {
5129 : 0 : psa_status_t status;
5130 : 0 : uint8_t pms[ 4 + 2 * PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE ];
5131 : 0 : uint8_t *cur = pms;
5132 : :
5133 [ # # ]: 0 : if( data_length > PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE )
5134 : : return( PSA_ERROR_INVALID_ARGUMENT );
5135 : :
5136 : : /* Quoting RFC 4279, Section 2:
5137 : : *
5138 : : * The premaster secret is formed as follows: if the PSK is N octets
5139 : : * long, concatenate a uint16 with the value N, N zero octets, a second
5140 : : * uint16 with the value N, and the PSK itself.
5141 : : */
5142 : :
5143 : 0 : *cur++ = MBEDTLS_BYTE_1( data_length );
5144 : 0 : *cur++ = MBEDTLS_BYTE_0( data_length );
5145 : 0 : memset( cur, 0, data_length );
5146 : 0 : cur += data_length;
5147 : 0 : *cur++ = pms[0];
5148 : 0 : *cur++ = pms[1];
5149 : 0 : memcpy( cur, data, data_length );
5150 : 0 : cur += data_length;
5151 : :
5152 : 0 : status = psa_tls12_prf_set_key( prf, pms, cur - pms );
5153 : :
5154 : 0 : mbedtls_platform_zeroize( pms, sizeof( pms ) );
5155 : 0 : return( status );
5156 : : }
5157 : :
5158 : 0 : static psa_status_t psa_tls12_prf_psk_to_ms_input(
5159 : : psa_tls12_prf_key_derivation_t *prf,
5160 : : psa_key_derivation_step_t step,
5161 : : const uint8_t *data,
5162 : : size_t data_length )
5163 : : {
5164 [ # # ]: 0 : if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
5165 : : {
5166 : 0 : return( psa_tls12_prf_psk_to_ms_set_key( prf,
5167 : : data, data_length ) );
5168 : : }
5169 : :
5170 : 0 : return( psa_tls12_prf_input( prf, step, data, data_length ) );
5171 : : }
5172 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
5173 : :
5174 : : /** Check whether the given key type is acceptable for the given
5175 : : * input step of a key derivation.
5176 : : *
5177 : : * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE.
5178 : : * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA.
5179 : : * Both secret and non-secret inputs can alternatively have the type
5180 : : * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning
5181 : : * that the input was passed as a buffer rather than via a key object.
5182 : : */
5183 : 0 : static int psa_key_derivation_check_input_type(
5184 : : psa_key_derivation_step_t step,
5185 : : psa_key_type_t key_type )
5186 : : {
5187 [ # # # ]: 0 : switch( step )
5188 : : {
5189 : 0 : case PSA_KEY_DERIVATION_INPUT_SECRET:
5190 [ # # ]: 0 : if( key_type == PSA_KEY_TYPE_DERIVE )
5191 : : return( PSA_SUCCESS );
5192 [ # # ]: 0 : if( key_type == PSA_KEY_TYPE_NONE )
5193 : 0 : return( PSA_SUCCESS );
5194 : : break;
5195 : 0 : case PSA_KEY_DERIVATION_INPUT_LABEL:
5196 : : case PSA_KEY_DERIVATION_INPUT_SALT:
5197 : : case PSA_KEY_DERIVATION_INPUT_INFO:
5198 : : case PSA_KEY_DERIVATION_INPUT_SEED:
5199 [ # # ]: 0 : if( key_type == PSA_KEY_TYPE_RAW_DATA )
5200 : : return( PSA_SUCCESS );
5201 [ # # ]: 0 : if( key_type == PSA_KEY_TYPE_NONE )
5202 : 0 : return( PSA_SUCCESS );
5203 : : break;
5204 : : }
5205 : : return( PSA_ERROR_INVALID_ARGUMENT );
5206 : : }
5207 : :
5208 : 0 : static psa_status_t psa_key_derivation_input_internal(
5209 : : psa_key_derivation_operation_t *operation,
5210 : : psa_key_derivation_step_t step,
5211 : : psa_key_type_t key_type,
5212 : : const uint8_t *data,
5213 : : size_t data_length )
5214 : : {
5215 : 0 : psa_status_t status;
5216 : 0 : psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
5217 : :
5218 : 0 : status = psa_key_derivation_check_input_type( step, key_type );
5219 [ # # ]: 0 : if( status != PSA_SUCCESS )
5220 : 0 : goto exit;
5221 : :
5222 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
5223 : : if( PSA_ALG_IS_HKDF( kdf_alg ) )
5224 : : {
5225 : : status = psa_hkdf_input( &operation->ctx.hkdf,
5226 : : PSA_ALG_HKDF_GET_HASH( kdf_alg ),
5227 : : step, data, data_length );
5228 : : }
5229 : : else
5230 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
5231 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
5232 [ # # ]: 0 : if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
5233 : : {
5234 : 0 : status = psa_tls12_prf_input( &operation->ctx.tls12_prf,
5235 : : step, data, data_length );
5236 : : }
5237 : : else
5238 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF */
5239 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5240 [ # # ]: 0 : if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
5241 : : {
5242 : 0 : status = psa_tls12_prf_psk_to_ms_input( &operation->ctx.tls12_prf,
5243 : : step, data, data_length );
5244 : : }
5245 : : else
5246 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
5247 : : {
5248 : : /* This can't happen unless the operation object was not initialized */
5249 : : (void) data;
5250 : : (void) data_length;
5251 : : (void) kdf_alg;
5252 : : return( PSA_ERROR_BAD_STATE );
5253 : : }
5254 : :
5255 : 0 : exit:
5256 [ # # ]: 0 : if( status != PSA_SUCCESS )
5257 : 0 : psa_key_derivation_abort( operation );
5258 : : return( status );
5259 : : }
5260 : :
5261 : 0 : psa_status_t psa_key_derivation_input_bytes(
5262 : : psa_key_derivation_operation_t *operation,
5263 : : psa_key_derivation_step_t step,
5264 : : const uint8_t *data,
5265 : : size_t data_length )
5266 : : {
5267 : 0 : return( psa_key_derivation_input_internal( operation, step,
5268 : : PSA_KEY_TYPE_NONE,
5269 : : data, data_length ) );
5270 : : }
5271 : :
5272 : 0 : psa_status_t psa_key_derivation_input_key(
5273 : : psa_key_derivation_operation_t *operation,
5274 : : psa_key_derivation_step_t step,
5275 : : mbedtls_svc_key_id_t key )
5276 : : {
5277 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5278 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
5279 : 0 : psa_key_slot_t *slot;
5280 : :
5281 : 0 : status = psa_get_and_lock_transparent_key_slot_with_policy(
5282 : : key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg );
5283 [ # # ]: 0 : if( status != PSA_SUCCESS )
5284 : : {
5285 : 0 : psa_key_derivation_abort( operation );
5286 : 0 : return( status );
5287 : : }
5288 : :
5289 : : /* Passing a key object as a SECRET input unlocks the permission
5290 : : * to output to a key object. */
5291 [ # # ]: 0 : if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
5292 : 0 : operation->can_output_key = 1;
5293 : :
5294 : 0 : status = psa_key_derivation_input_internal( operation,
5295 : 0 : step, slot->attr.type,
5296 : 0 : slot->key.data,
5297 : 0 : slot->key.bytes );
5298 : :
5299 : 0 : unlock_status = psa_unlock_key_slot( slot );
5300 : :
5301 [ # # ]: 0 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
5302 : : }
5303 : :
5304 : :
5305 : :
5306 : : /****************************************************************/
5307 : : /* Key agreement */
5308 : : /****************************************************************/
5309 : :
5310 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
5311 : 4 : static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
5312 : : size_t peer_key_length,
5313 : : const mbedtls_ecp_keypair *our_key,
5314 : : uint8_t *shared_secret,
5315 : : size_t shared_secret_size,
5316 : : size_t *shared_secret_length )
5317 : : {
5318 : 4 : mbedtls_ecp_keypair *their_key = NULL;
5319 : 4 : mbedtls_ecdh_context ecdh;
5320 : 4 : psa_status_t status;
5321 : 4 : size_t bits = 0;
5322 : 4 : psa_ecc_family_t curve = mbedtls_ecc_group_to_psa( our_key->grp.id, &bits );
5323 : 4 : mbedtls_ecdh_init( &ecdh );
5324 : :
5325 : 8 : status = mbedtls_psa_ecp_load_representation(
5326 : 4 : PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
5327 : : bits,
5328 : : peer_key,
5329 : : peer_key_length,
5330 : : &their_key );
5331 [ - + ]: 4 : if( status != PSA_SUCCESS )
5332 : 0 : goto exit;
5333 : :
5334 : 4 : status = mbedtls_to_psa_error(
5335 : : mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS ) );
5336 [ - + ]: 4 : if( status != PSA_SUCCESS )
5337 : 0 : goto exit;
5338 : 4 : status = mbedtls_to_psa_error(
5339 : : mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS ) );
5340 [ - + ]: 4 : if( status != PSA_SUCCESS )
5341 : 0 : goto exit;
5342 : :
5343 : 4 : status = mbedtls_to_psa_error(
5344 : : mbedtls_ecdh_calc_secret( &ecdh,
5345 : : shared_secret_length,
5346 : : shared_secret, shared_secret_size,
5347 : : mbedtls_psa_get_random,
5348 : : MBEDTLS_PSA_RANDOM_STATE ) );
5349 [ - + ]: 4 : if( status != PSA_SUCCESS )
5350 : 0 : goto exit;
5351 [ + - ]: 4 : if( PSA_BITS_TO_BYTES( bits ) != *shared_secret_length )
5352 : : status = PSA_ERROR_CORRUPTION_DETECTED;
5353 : :
5354 : 4 : exit:
5355 [ - + ]: 4 : if( status != PSA_SUCCESS )
5356 : 0 : mbedtls_platform_zeroize( shared_secret, shared_secret_size );
5357 : 4 : mbedtls_ecdh_free( &ecdh );
5358 : 4 : mbedtls_ecp_keypair_free( their_key );
5359 : 4 : mbedtls_free( their_key );
5360 : :
5361 : 4 : return( status );
5362 : : }
5363 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
5364 : :
5365 : : #define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
5366 : :
5367 : 4 : static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg,
5368 : : psa_key_slot_t *private_key,
5369 : : const uint8_t *peer_key,
5370 : : size_t peer_key_length,
5371 : : uint8_t *shared_secret,
5372 : : size_t shared_secret_size,
5373 : : size_t *shared_secret_length )
5374 : : {
5375 [ + - ]: 4 : switch( alg )
5376 : : {
5377 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
5378 : 4 : case PSA_ALG_ECDH:
5379 [ + - ]: 4 : if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) )
5380 : : return( PSA_ERROR_INVALID_ARGUMENT );
5381 : 4 : mbedtls_ecp_keypair *ecp = NULL;
5382 : 8 : psa_status_t status = mbedtls_psa_ecp_load_representation(
5383 : : private_key->attr.type,
5384 : 4 : private_key->attr.bits,
5385 : 4 : private_key->key.data,
5386 : : private_key->key.bytes,
5387 : : &ecp );
5388 [ + - ]: 4 : if( status != PSA_SUCCESS )
5389 : : return( status );
5390 : 4 : status = psa_key_agreement_ecdh( peer_key, peer_key_length,
5391 : : ecp,
5392 : : shared_secret, shared_secret_size,
5393 : : shared_secret_length );
5394 : 4 : mbedtls_ecp_keypair_free( ecp );
5395 : 4 : mbedtls_free( ecp );
5396 : 4 : return( status );
5397 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
5398 : : default:
5399 : : (void) private_key;
5400 : : (void) peer_key;
5401 : : (void) peer_key_length;
5402 : : (void) shared_secret;
5403 : : (void) shared_secret_size;
5404 : : (void) shared_secret_length;
5405 : : return( PSA_ERROR_NOT_SUPPORTED );
5406 : : }
5407 : : }
5408 : :
5409 : : /* Note that if this function fails, you must call psa_key_derivation_abort()
5410 : : * to potentially free embedded data structures and wipe confidential data.
5411 : : */
5412 : 0 : static psa_status_t psa_key_agreement_internal( psa_key_derivation_operation_t *operation,
5413 : : psa_key_derivation_step_t step,
5414 : : psa_key_slot_t *private_key,
5415 : : const uint8_t *peer_key,
5416 : : size_t peer_key_length )
5417 : : {
5418 : 0 : psa_status_t status;
5419 : 0 : uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
5420 : 0 : size_t shared_secret_length = 0;
5421 : 0 : psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE( operation->alg );
5422 : :
5423 : : /* Step 1: run the secret agreement algorithm to generate the shared
5424 : : * secret. */
5425 : 0 : status = psa_key_agreement_raw_internal( ka_alg,
5426 : : private_key,
5427 : : peer_key, peer_key_length,
5428 : : shared_secret,
5429 : : sizeof( shared_secret ),
5430 : : &shared_secret_length );
5431 [ # # ]: 0 : if( status != PSA_SUCCESS )
5432 : 0 : goto exit;
5433 : :
5434 : : /* Step 2: set up the key derivation to generate key material from
5435 : : * the shared secret. A shared secret is permitted wherever a key
5436 : : * of type DERIVE is permitted. */
5437 : 0 : status = psa_key_derivation_input_internal( operation, step,
5438 : : PSA_KEY_TYPE_DERIVE,
5439 : : shared_secret,
5440 : : shared_secret_length );
5441 : 0 : exit:
5442 : 0 : mbedtls_platform_zeroize( shared_secret, shared_secret_length );
5443 : 0 : return( status );
5444 : : }
5445 : :
5446 : 0 : psa_status_t psa_key_derivation_key_agreement( psa_key_derivation_operation_t *operation,
5447 : : psa_key_derivation_step_t step,
5448 : : mbedtls_svc_key_id_t private_key,
5449 : : const uint8_t *peer_key,
5450 : : size_t peer_key_length )
5451 : : {
5452 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5453 : 0 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
5454 : 0 : psa_key_slot_t *slot;
5455 : :
5456 [ # # ]: 0 : if( ! PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
5457 : : return( PSA_ERROR_INVALID_ARGUMENT );
5458 : 0 : status = psa_get_and_lock_transparent_key_slot_with_policy(
5459 : : private_key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg );
5460 [ # # ]: 0 : if( status != PSA_SUCCESS )
5461 : : return( status );
5462 : 0 : status = psa_key_agreement_internal( operation, step,
5463 : : slot,
5464 : : peer_key, peer_key_length );
5465 [ # # ]: 0 : if( status != PSA_SUCCESS )
5466 : 0 : psa_key_derivation_abort( operation );
5467 : : else
5468 : : {
5469 : : /* If a private key has been added as SECRET, we allow the derived
5470 : : * key material to be used as a key in PSA Crypto. */
5471 [ # # ]: 0 : if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
5472 : 0 : operation->can_output_key = 1;
5473 : : }
5474 : :
5475 : 0 : unlock_status = psa_unlock_key_slot( slot );
5476 : :
5477 [ # # ]: 0 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
5478 : : }
5479 : :
5480 : 4 : psa_status_t psa_raw_key_agreement( psa_algorithm_t alg,
5481 : : mbedtls_svc_key_id_t private_key,
5482 : : const uint8_t *peer_key,
5483 : : size_t peer_key_length,
5484 : : uint8_t *output,
5485 : : size_t output_size,
5486 : : size_t *output_length )
5487 : : {
5488 : 4 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5489 : 4 : psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
5490 : 4 : psa_key_slot_t *slot = NULL;
5491 : :
5492 [ - + ]: 4 : if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
5493 : : {
5494 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
5495 : 0 : goto exit;
5496 : : }
5497 : 4 : status = psa_get_and_lock_transparent_key_slot_with_policy(
5498 : : private_key, &slot, PSA_KEY_USAGE_DERIVE, alg );
5499 [ - + ]: 4 : if( status != PSA_SUCCESS )
5500 : 0 : goto exit;
5501 : :
5502 : 4 : status = psa_key_agreement_raw_internal( alg, slot,
5503 : : peer_key, peer_key_length,
5504 : : output, output_size,
5505 : : output_length );
5506 : :
5507 : 4 : exit:
5508 [ - + ]: 4 : if( status != PSA_SUCCESS )
5509 : : {
5510 : : /* If an error happens and is not handled properly, the output
5511 : : * may be used as a key to protect sensitive data. Arrange for such
5512 : : * a key to be random, which is likely to result in decryption or
5513 : : * verification errors. This is better than filling the buffer with
5514 : : * some constant data such as zeros, which would result in the data
5515 : : * being protected with a reproducible, easily knowable key.
5516 : : */
5517 : 0 : psa_generate_random( output, output_size );
5518 : 0 : *output_length = output_size;
5519 : : }
5520 : :
5521 : 4 : unlock_status = psa_unlock_key_slot( slot );
5522 : :
5523 [ - + ]: 4 : return( ( status == PSA_SUCCESS ) ? unlock_status : status );
5524 : : }
5525 : :
5526 : :
5527 : :
5528 : : /****************************************************************/
5529 : : /* Random generation */
5530 : : /****************************************************************/
5531 : :
5532 : : /** Initialize the PSA random generator.
5533 : : */
5534 : 1 : static void mbedtls_psa_random_init( mbedtls_psa_random_context_t *rng )
5535 : : {
5536 : : #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
5537 : : memset( rng, 0, sizeof( *rng ) );
5538 : : #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
5539 : :
5540 : : /* Set default configuration if
5541 : : * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
5542 [ + - ]: 1 : if( rng->entropy_init == NULL )
5543 : 1 : rng->entropy_init = mbedtls_entropy_init;
5544 [ + - ]: 1 : if( rng->entropy_free == NULL )
5545 : 1 : rng->entropy_free = mbedtls_entropy_free;
5546 : :
5547 : 1 : rng->entropy_init( &rng->entropy );
5548 : : #if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
5549 : : defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
5550 : : /* The PSA entropy injection feature depends on using NV seed as an entropy
5551 : : * source. Add NV seed as an entropy source for PSA entropy injection. */
5552 : : mbedtls_entropy_add_source( &rng->entropy,
5553 : : mbedtls_nv_seed_poll, NULL,
5554 : : MBEDTLS_ENTROPY_BLOCK_SIZE,
5555 : : MBEDTLS_ENTROPY_SOURCE_STRONG );
5556 : : #endif
5557 : :
5558 : 1 : mbedtls_psa_drbg_init( MBEDTLS_PSA_RANDOM_STATE );
5559 : : #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
5560 : 1 : }
5561 : :
5562 : : /** Deinitialize the PSA random generator.
5563 : : */
5564 : 0 : static void mbedtls_psa_random_free( mbedtls_psa_random_context_t *rng )
5565 : : {
5566 : : #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
5567 : : memset( rng, 0, sizeof( *rng ) );
5568 : : #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
5569 : 0 : mbedtls_psa_drbg_free( MBEDTLS_PSA_RANDOM_STATE );
5570 : 0 : rng->entropy_free( &rng->entropy );
5571 : : #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
5572 : 0 : }
5573 : :
5574 : : /** Seed the PSA random generator.
5575 : : */
5576 : 1 : static psa_status_t mbedtls_psa_random_seed( mbedtls_psa_random_context_t *rng )
5577 : : {
5578 : : #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
5579 : : /* Do nothing: the external RNG seeds itself. */
5580 : : (void) rng;
5581 : : return( PSA_SUCCESS );
5582 : : #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
5583 : 1 : const unsigned char drbg_seed[] = "PSA";
5584 : 1 : int ret = mbedtls_psa_drbg_seed( &rng->entropy,
5585 : : drbg_seed, sizeof( drbg_seed ) - 1 );
5586 : 1 : return mbedtls_to_psa_error( ret );
5587 : : #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
5588 : : }
5589 : :
5590 : 0 : psa_status_t psa_generate_random( uint8_t *output,
5591 : : size_t output_size )
5592 : : {
5593 [ # # ]: 0 : GUARD_MODULE_INITIALIZED;
5594 : :
5595 : : #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
5596 : :
5597 : : size_t output_length = 0;
5598 : : psa_status_t status = mbedtls_psa_external_get_random( &global_data.rng,
5599 : : output, output_size,
5600 : : &output_length );
5601 : : if( status != PSA_SUCCESS )
5602 : : return( status );
5603 : : /* Breaking up a request into smaller chunks is currently not supported
5604 : : * for the extrernal RNG interface. */
5605 : : if( output_length != output_size )
5606 : : return( PSA_ERROR_INSUFFICIENT_ENTROPY );
5607 : : return( PSA_SUCCESS );
5608 : :
5609 : : #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
5610 : :
5611 [ # # ]: 0 : while( output_size > 0 )
5612 : : {
5613 : 0 : size_t request_size =
5614 : : ( output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ?
5615 : : MBEDTLS_PSA_RANDOM_MAX_REQUEST :
5616 : : output_size );
5617 : 0 : int ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
5618 : : output, request_size );
5619 [ # # ]: 0 : if( ret != 0 )
5620 : 0 : return( mbedtls_to_psa_error( ret ) );
5621 : 0 : output_size -= request_size;
5622 : 0 : output += request_size;
5623 : : }
5624 : : return( PSA_SUCCESS );
5625 : : #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
5626 : : }
5627 : :
5628 : : /* Wrapper function allowing the classic API to use the PSA RNG.
5629 : : *
5630 : : * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
5631 : : * `psa_generate_random(...)`. The state parameter is ignored since the
5632 : : * PSA API doesn't support passing an explicit state.
5633 : : *
5634 : : * In the non-external case, psa_generate_random() calls an
5635 : : * `mbedtls_xxx_drbg_random` function which has exactly the same signature
5636 : : * and semantics as mbedtls_psa_get_random(). As an optimization,
5637 : : * instead of doing this back-and-forth between the PSA API and the
5638 : : * classic API, psa_crypto_random_impl.h defines `mbedtls_psa_get_random`
5639 : : * as a constant function pointer to `mbedtls_xxx_drbg_random`.
5640 : : */
5641 : : #if defined (MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
5642 : : int mbedtls_psa_get_random( void *p_rng,
5643 : : unsigned char *output,
5644 : : size_t output_size )
5645 : : {
5646 : : /* This function takes a pointer to the RNG state because that's what
5647 : : * classic mbedtls functions using an RNG expect. The PSA RNG manages
5648 : : * its own state internally and doesn't let the caller access that state.
5649 : : * So we just ignore the state parameter, and in practice we'll pass
5650 : : * NULL. */
5651 : : (void) p_rng;
5652 : : psa_status_t status = psa_generate_random( output, output_size );
5653 : : if( status == PSA_SUCCESS )
5654 : : return( 0 );
5655 : : else
5656 : : return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
5657 : : }
5658 : : #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
5659 : :
5660 : : #if defined(MBEDTLS_PSA_INJECT_ENTROPY)
5661 : : #include "entropy_poll.h"
5662 : :
5663 : : psa_status_t mbedtls_psa_inject_entropy( const uint8_t *seed,
5664 : : size_t seed_size )
5665 : : {
5666 : : if( global_data.initialized )
5667 : : return( PSA_ERROR_NOT_PERMITTED );
5668 : :
5669 : : if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
5670 : : ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
5671 : : ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
5672 : : return( PSA_ERROR_INVALID_ARGUMENT );
5673 : :
5674 : : return( mbedtls_psa_storage_inject_entropy( seed, seed_size ) );
5675 : : }
5676 : : #endif /* MBEDTLS_PSA_INJECT_ENTROPY */
5677 : :
5678 : : /** Validate the key type and size for key generation
5679 : : *
5680 : : * \param type The key type
5681 : : * \param bits The number of bits of the key
5682 : : *
5683 : : * \retval #PSA_SUCCESS
5684 : : * The key type and size are valid.
5685 : : * \retval #PSA_ERROR_INVALID_ARGUMENT
5686 : : * The size in bits of the key is not valid.
5687 : : * \retval #PSA_ERROR_NOT_SUPPORTED
5688 : : * The type and/or the size in bits of the key or the combination of
5689 : : * the two is not supported.
5690 : : */
5691 : 0 : static psa_status_t psa_validate_key_type_and_size_for_key_generation(
5692 : : psa_key_type_t type, size_t bits )
5693 : : {
5694 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5695 : :
5696 [ # # ]: 0 : if( key_type_is_raw_bytes( type ) )
5697 : : {
5698 : 0 : status = psa_validate_unstructured_key_bit_size( type, bits );
5699 [ # # ]: 0 : if( status != PSA_SUCCESS )
5700 : 0 : return( status );
5701 : : }
5702 : : else
5703 : : #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
5704 : : if( PSA_KEY_TYPE_IS_RSA( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
5705 : : {
5706 : : if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
5707 : : return( PSA_ERROR_NOT_SUPPORTED );
5708 : :
5709 : : /* Accept only byte-aligned keys, for the same reasons as
5710 : : * in psa_import_rsa_key(). */
5711 : : if( bits % 8 != 0 )
5712 : : return( PSA_ERROR_NOT_SUPPORTED );
5713 : : }
5714 : : else
5715 : : #endif /* defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) */
5716 : :
5717 : : #if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
5718 [ # # ]: 0 : if( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
5719 : : {
5720 : : /* To avoid empty block, return successfully here. */
5721 : : return( PSA_SUCCESS );
5722 : : }
5723 : : else
5724 : : #endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) */
5725 : : {
5726 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
5727 : : }
5728 : :
5729 : : return( PSA_SUCCESS );
5730 : : }
5731 : :
5732 : 0 : psa_status_t psa_generate_key_internal(
5733 : : const psa_key_attributes_t *attributes,
5734 : : uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
5735 : : {
5736 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
5737 : 0 : psa_key_type_t type = attributes->core.type;
5738 : :
5739 [ # # ]: 0 : if( ( attributes->domain_parameters == NULL ) &&
5740 [ # # ]: 0 : ( attributes->domain_parameters_size != 0 ) )
5741 : : return( PSA_ERROR_INVALID_ARGUMENT );
5742 : :
5743 [ # # ]: 0 : if( key_type_is_raw_bytes( type ) )
5744 : : {
5745 : 0 : status = psa_generate_random( key_buffer, key_buffer_size );
5746 [ # # ]: 0 : if( status != PSA_SUCCESS )
5747 : 0 : return( status );
5748 : :
5749 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
5750 : : if( type == PSA_KEY_TYPE_DES )
5751 : : psa_des_set_key_parity( key_buffer, key_buffer_size );
5752 : : #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
5753 : : }
5754 : : else
5755 : :
5756 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) && \
5757 : : defined(MBEDTLS_GENPRIME)
5758 : : if ( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
5759 : : {
5760 : : return( mbedtls_psa_rsa_generate_key( attributes,
5761 : : key_buffer,
5762 : : key_buffer_size,
5763 : : key_buffer_length ) );
5764 : : }
5765 : : else
5766 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
5767 : : * defined(MBEDTLS_GENPRIME) */
5768 : :
5769 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
5770 [ # # ]: 0 : if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
5771 : : {
5772 : 0 : return( mbedtls_psa_ecp_generate_key( attributes,
5773 : : key_buffer,
5774 : : key_buffer_size,
5775 : : key_buffer_length ) );
5776 : : }
5777 : : else
5778 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
5779 : : {
5780 : : (void)key_buffer_length;
5781 : : return( PSA_ERROR_NOT_SUPPORTED );
5782 : : }
5783 : :
5784 : : return( PSA_SUCCESS );
5785 : : }
5786 : :
5787 : 0 : psa_status_t psa_generate_key( const psa_key_attributes_t *attributes,
5788 : : mbedtls_svc_key_id_t *key )
5789 : : {
5790 : 0 : psa_status_t status;
5791 : 0 : psa_key_slot_t *slot = NULL;
5792 : 0 : psa_se_drv_table_entry_t *driver = NULL;
5793 : 0 : size_t key_buffer_size;
5794 : :
5795 : 0 : *key = MBEDTLS_SVC_KEY_ID_INIT;
5796 : :
5797 : : /* Reject any attempt to create a zero-length key so that we don't
5798 : : * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
5799 [ # # ]: 0 : if( psa_get_key_bits( attributes ) == 0 )
5800 : : return( PSA_ERROR_INVALID_ARGUMENT );
5801 : :
5802 : : /* Reject any attempt to create a public key. */
5803 [ # # ]: 0 : if( PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->core.type) )
5804 : : return( PSA_ERROR_INVALID_ARGUMENT );
5805 : :
5806 : 0 : status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE, attributes,
5807 : : &slot, &driver );
5808 [ # # ]: 0 : if( status != PSA_SUCCESS )
5809 : 0 : goto exit;
5810 : :
5811 : : /* In the case of a transparent key or an opaque key stored in local
5812 : : * storage ( thus not in the case of generating a key in a secure element
5813 : : * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
5814 : : * buffer to hold the generated key material. */
5815 [ # # ]: 0 : if( slot->key.data == NULL )
5816 : : {
5817 [ # # ]: 0 : if ( PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ) ==
5818 : : PSA_KEY_LOCATION_LOCAL_STORAGE )
5819 : : {
5820 : 0 : status = psa_validate_key_type_and_size_for_key_generation(
5821 : 0 : attributes->core.type, attributes->core.bits );
5822 [ # # ]: 0 : if( status != PSA_SUCCESS )
5823 : 0 : goto exit;
5824 : :
5825 [ # # # # : 0 : key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
# # # # #
# # # #
# ]
5826 : : attributes->core.type,
5827 : : attributes->core.bits );
5828 : : }
5829 : : else
5830 : : {
5831 : 0 : status = psa_driver_wrapper_get_key_buffer_size(
5832 : : attributes, &key_buffer_size );
5833 [ # # ]: 0 : if( status != PSA_SUCCESS )
5834 : 0 : goto exit;
5835 : : }
5836 : :
5837 : 0 : status = psa_allocate_buffer_to_slot( slot, key_buffer_size );
5838 [ # # ]: 0 : if( status != PSA_SUCCESS )
5839 : 0 : goto exit;
5840 : : }
5841 : :
5842 : 0 : status = psa_driver_wrapper_generate_key( attributes,
5843 : 0 : slot->key.data, slot->key.bytes, &slot->key.bytes );
5844 : :
5845 [ # # ]: 0 : if( status != PSA_SUCCESS )
5846 : 0 : psa_remove_key_data_from_memory( slot );
5847 : :
5848 : 0 : exit:
5849 [ # # ]: 0 : if( status == PSA_SUCCESS )
5850 : 0 : status = psa_finish_key_creation( slot, driver, key );
5851 [ # # ]: 0 : if( status != PSA_SUCCESS )
5852 : 0 : psa_fail_key_creation( slot, driver );
5853 : :
5854 : : return( status );
5855 : : }
5856 : :
5857 : : /****************************************************************/
5858 : : /* Module setup */
5859 : : /****************************************************************/
5860 : :
5861 : : #if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
5862 : 0 : psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
5863 : : void (* entropy_init )( mbedtls_entropy_context *ctx ),
5864 : : void (* entropy_free )( mbedtls_entropy_context *ctx ) )
5865 : : {
5866 [ # # ]: 0 : if( global_data.rng_state != RNG_NOT_INITIALIZED )
5867 : : return( PSA_ERROR_BAD_STATE );
5868 : 0 : global_data.rng.entropy_init = entropy_init;
5869 : 0 : global_data.rng.entropy_free = entropy_free;
5870 : 0 : return( PSA_SUCCESS );
5871 : : }
5872 : : #endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
5873 : :
5874 : 0 : void mbedtls_psa_crypto_free( void )
5875 : : {
5876 : 0 : psa_wipe_all_key_slots( );
5877 [ # # ]: 0 : if( global_data.rng_state != RNG_NOT_INITIALIZED )
5878 : : {
5879 : 0 : mbedtls_psa_random_free( &global_data.rng );
5880 : : }
5881 : : /* Wipe all remaining data, including configuration.
5882 : : * In particular, this sets all state indicator to the value
5883 : : * indicating "uninitialized". */
5884 : 0 : mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
5885 : :
5886 : : /* Terminate drivers */
5887 : 0 : psa_driver_wrapper_free( );
5888 : 0 : }
5889 : :
5890 : : #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
5891 : : /** Recover a transaction that was interrupted by a power failure.
5892 : : *
5893 : : * This function is called during initialization, before psa_crypto_init()
5894 : : * returns. If this function returns a failure status, the initialization
5895 : : * fails.
5896 : : */
5897 : : static psa_status_t psa_crypto_recover_transaction(
5898 : : const psa_crypto_transaction_t *transaction )
5899 : : {
5900 : : switch( transaction->unknown.type )
5901 : : {
5902 : : case PSA_CRYPTO_TRANSACTION_CREATE_KEY:
5903 : : case PSA_CRYPTO_TRANSACTION_DESTROY_KEY:
5904 : : /* TODO - fall through to the failure case until this
5905 : : * is implemented.
5906 : : * https://github.com/ARMmbed/mbed-crypto/issues/218
5907 : : */
5908 : : default:
5909 : : /* We found an unsupported transaction in the storage.
5910 : : * We don't know what state the storage is in. Give up. */
5911 : : return( PSA_ERROR_DATA_INVALID );
5912 : : }
5913 : : }
5914 : : #endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
5915 : :
5916 : 172 : psa_status_t psa_crypto_init( void )
5917 : : {
5918 : 172 : psa_status_t status;
5919 : :
5920 : : /* Double initialization is explicitly allowed. */
5921 [ + + ]: 172 : if( global_data.initialized != 0 )
5922 : : return( PSA_SUCCESS );
5923 : :
5924 : : /* Initialize and seed the random generator. */
5925 : 1 : mbedtls_psa_random_init( &global_data.rng );
5926 : 1 : global_data.rng_state = RNG_INITIALIZED;
5927 : 1 : status = mbedtls_psa_random_seed( &global_data.rng );
5928 [ - + ]: 1 : if( status != PSA_SUCCESS )
5929 : 0 : goto exit;
5930 : 1 : global_data.rng_state = RNG_SEEDED;
5931 : :
5932 : 1 : status = psa_initialize_key_slots( );
5933 [ - + ]: 1 : if( status != PSA_SUCCESS )
5934 : 0 : goto exit;
5935 : :
5936 : : /* Init drivers */
5937 : 1 : status = psa_driver_wrapper_init( );
5938 [ - + ]: 1 : if( status != PSA_SUCCESS )
5939 : 0 : goto exit;
5940 : :
5941 : : #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
5942 : : status = psa_crypto_load_transaction( );
5943 : : if( status == PSA_SUCCESS )
5944 : : {
5945 : : status = psa_crypto_recover_transaction( &psa_crypto_transaction );
5946 : : if( status != PSA_SUCCESS )
5947 : : goto exit;
5948 : : status = psa_crypto_stop_transaction( );
5949 : : }
5950 : : else if( status == PSA_ERROR_DOES_NOT_EXIST )
5951 : : {
5952 : : /* There's no transaction to complete. It's all good. */
5953 : : status = PSA_SUCCESS;
5954 : : }
5955 : : #endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
5956 : :
5957 : : /* All done. */
5958 : 1 : global_data.initialized = 1;
5959 : :
5960 : 1 : exit:
5961 [ - + ]: 1 : if( status != PSA_SUCCESS )
5962 : 0 : mbedtls_psa_crypto_free( );
5963 : : return( status );
5964 : : }
5965 : :
5966 : : #endif /* MBEDTLS_PSA_CRYPTO_C */
|