blob: 4f7be40ec082b81be640e5a8498e90ca91358cff [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
Bence Szépkúti86974652020-06-15 11:59:37 +02004/*
Bence Szépkúti1e148272020-08-07 13:07:28 +02005 * Copyright The Mbed TLS Contributors
Gilles Peskinee59236f2018-01-27 23:32:46 +01006 * 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.
Gilles Peskinee59236f2018-01-27 23:32:46 +010019 */
20
Gilles Peskinedb09ef62020-06-03 01:43:33 +020021#include "common.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010022
23#if defined(MBEDTLS_PSA_CRYPTO_C)
mohammad160327010052018-07-03 13:16:15 +030024
John Durkop07cc04a2020-11-16 22:08:34 -080025#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
26#include "check_crypto_config.h"
27#endif
28
itayzafrir7723ab12019-02-14 10:28:02 +020029#include "psa_crypto_service_integration.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010030#include "psa/crypto.h"
31
Gilles Peskine039b90c2018-12-07 18:24:41 +010032#include "psa_crypto_core.h"
Gilles Peskine5e769522018-11-20 21:59:56 +010033#include "psa_crypto_invasive.h"
Steven Cooremancd84cb42020-07-16 20:28:36 +020034#include "psa_crypto_driver_wrappers.h"
Gilles Peskinea8ade162019-06-26 11:24:49 +020035#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined0890212019-06-24 14:34:43 +020036#include "psa_crypto_se.h"
Gilles Peskinea8ade162019-06-26 11:24:49 +020037#endif
Gilles Peskine961849f2018-11-30 18:54:54 +010038#include "psa_crypto_slot_management.h"
Darryl Greend49a4992018-06-18 17:27:26 +010039/* Include internal declarations that are useful for implementing persistently
40 * stored keys. */
41#include "psa_crypto_storage.h"
42
Gilles Peskineb2b64d32020-12-14 16:43:58 +010043#include "psa_crypto_random_impl.h"
Gilles Peskine90edc992020-11-13 15:39:19 +010044
Gilles Peskineb46bef22019-07-30 21:32:04 +020045#include <assert.h>
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010046#include <stdlib.h>
47#include <string.h>
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010048#include "mbedtls/platform.h"
Gilles Peskineff2d2002019-05-06 15:26:23 +020049#if !defined(MBEDTLS_PLATFORM_C)
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010050#define mbedtls_calloc calloc
51#define mbedtls_free free
52#endif
53
Gilles Peskine1c49f1a2020-11-13 18:46:25 +010054#include "mbedtls/aes.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010055#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020056#include "mbedtls/asn1.h"
Jaeden Amero25384a22019-01-10 10:23:21 +000057#include "mbedtls/asn1write.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020058#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010059#include "mbedtls/blowfish.h"
60#include "mbedtls/camellia.h"
Gilles Peskine26869f22019-05-06 15:25:00 +020061#include "mbedtls/chacha20.h"
62#include "mbedtls/chachapoly.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010063#include "mbedtls/cipher.h"
64#include "mbedtls/ccm.h"
65#include "mbedtls/cmac.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010066#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020067#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010068#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010069#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010070#include "mbedtls/error.h"
71#include "mbedtls/gcm.h"
72#include "mbedtls/md2.h"
73#include "mbedtls/md4.h"
74#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010075#include "mbedtls/md.h"
76#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010077#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010078#include "mbedtls/pk_internal.h"
Gilles Peskine3f108122018-12-07 18:14:53 +010079#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000080#include "mbedtls/error.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010081#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010082#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010083#include "mbedtls/sha1.h"
84#include "mbedtls/sha256.h"
85#include "mbedtls/sha512.h"
86#include "mbedtls/xtea.h"
87
Gilles Peskine996deb12018-08-01 15:45:45 +020088#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
89
Gilles Peskine9ef733f2018-02-07 21:05:37 +010090/* constant-time buffer comparison */
91static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
92{
93 size_t i;
94 unsigned char diff = 0;
95
96 for( i = 0; i < n; i++ )
97 diff |= a[i] ^ b[i];
98
99 return( diff );
100}
101
102
103
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100104/****************************************************************/
105/* Global data, support functions and library management */
106/****************************************************************/
107
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200108static int key_type_is_raw_bytes( psa_key_type_t type )
109{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200110 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200111}
112
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100113/* Values for psa_global_data_t::rng_state */
114#define RNG_NOT_INITIALIZED 0
115#define RNG_INITIALIZED 1
116#define RNG_SEEDED 2
Gilles Peskinec6b69072018-11-20 21:42:52 +0100117
Gilles Peskine2d277862018-06-18 15:41:12 +0200118typedef struct
119{
Gilles Peskine30524eb2020-11-13 17:02:26 +0100120 mbedtls_psa_random_context_t rng;
Gilles Peskinec6b69072018-11-20 21:42:52 +0100121 unsigned initialized : 1;
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100122 unsigned rng_state : 2;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100123} psa_global_data_t;
124
125static psa_global_data_t global_data;
126
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100127#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
128mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state =
129 &global_data.rng.drbg;
130#endif
131
itayzafrir0adf0fc2018-09-06 16:24:41 +0300132#define GUARD_MODULE_INITIALIZED \
133 if( global_data.initialized == 0 ) \
134 return( PSA_ERROR_BAD_STATE );
135
Steven Cooreman01164162020-07-20 15:31:37 +0200136psa_status_t mbedtls_to_psa_error( int ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100137{
Gilles Peskinea5905292018-02-07 20:59:33 +0100138 /* If there's both a high-level code and low-level code, dispatch on
139 * the high-level code. */
140 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100141 {
142 case 0:
143 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100144
145 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
146 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
147 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
148 return( PSA_ERROR_NOT_SUPPORTED );
149 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
150 return( PSA_ERROR_HARDWARE_FAILURE );
151
152 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
153 return( PSA_ERROR_HARDWARE_FAILURE );
154
Gilles Peskine9a944802018-06-21 09:35:35 +0200155 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
156 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
157 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
158 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
159 case MBEDTLS_ERR_ASN1_INVALID_DATA:
160 return( PSA_ERROR_INVALID_ARGUMENT );
161 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
162 return( PSA_ERROR_INSUFFICIENT_MEMORY );
163 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
164 return( PSA_ERROR_BUFFER_TOO_SMALL );
165
Jaeden Amero93e21112019-02-20 13:57:28 +0000166#if defined(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA)
Jaeden Amero892cd6d2019-02-11 12:21:12 +0000167 case MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA:
Jaeden Amero93e21112019-02-20 13:57:28 +0000168#elif defined(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH)
169 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
170#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100171 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
172 return( PSA_ERROR_NOT_SUPPORTED );
173 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
174 return( PSA_ERROR_HARDWARE_FAILURE );
175
Jaeden Amero93e21112019-02-20 13:57:28 +0000176#if defined(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
Jaeden Amero892cd6d2019-02-11 12:21:12 +0000177 case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA:
Jaeden Amero93e21112019-02-20 13:57:28 +0000178#elif defined(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH)
179 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
180#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100181 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
182 return( PSA_ERROR_NOT_SUPPORTED );
183 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
186 case MBEDTLS_ERR_CCM_BAD_INPUT:
187 return( PSA_ERROR_INVALID_ARGUMENT );
188 case MBEDTLS_ERR_CCM_AUTH_FAILED:
189 return( PSA_ERROR_INVALID_SIGNATURE );
190 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
191 return( PSA_ERROR_HARDWARE_FAILURE );
192
Gilles Peskine26869f22019-05-06 15:25:00 +0200193 case MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA:
194 return( PSA_ERROR_INVALID_ARGUMENT );
195
196 case MBEDTLS_ERR_CHACHAPOLY_BAD_STATE:
197 return( PSA_ERROR_BAD_STATE );
198 case MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED:
199 return( PSA_ERROR_INVALID_SIGNATURE );
200
Gilles Peskinea5905292018-02-07 20:59:33 +0100201 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
202 return( PSA_ERROR_NOT_SUPPORTED );
203 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
204 return( PSA_ERROR_INVALID_ARGUMENT );
205 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
206 return( PSA_ERROR_INSUFFICIENT_MEMORY );
207 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
208 return( PSA_ERROR_INVALID_PADDING );
209 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
Fredrik Strupef90e3012020-09-28 16:11:33 +0200210 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100211 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
212 return( PSA_ERROR_INVALID_SIGNATURE );
213 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
Gilles Peskine4b3eb692019-05-16 21:35:18 +0200214 return( PSA_ERROR_CORRUPTION_DETECTED );
Gilles Peskinea5905292018-02-07 20:59:33 +0100215 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
216 return( PSA_ERROR_HARDWARE_FAILURE );
217
218 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
219 return( PSA_ERROR_HARDWARE_FAILURE );
220
Gilles Peskine82e57d12020-11-13 21:31:17 +0100221#if !( defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) || \
222 defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE) )
Gilles Peskinebee96c82020-11-23 21:00:09 +0100223 /* Only check CTR_DRBG error codes if underlying mbedtls_xxx
224 * functions are passed a CTR_DRBG instance. */
Gilles Peskinea5905292018-02-07 20:59:33 +0100225 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
226 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
227 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
228 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
229 return( PSA_ERROR_NOT_SUPPORTED );
230 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
231 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskine82e57d12020-11-13 21:31:17 +0100232#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100233
234 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
235 return( PSA_ERROR_NOT_SUPPORTED );
236 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
237 return( PSA_ERROR_HARDWARE_FAILURE );
238
Gilles Peskinee59236f2018-01-27 23:32:46 +0100239 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
240 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
241 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
242 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100243
244 case MBEDTLS_ERR_GCM_AUTH_FAILED:
245 return( PSA_ERROR_INVALID_SIGNATURE );
246 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200247 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100248 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
249 return( PSA_ERROR_HARDWARE_FAILURE );
250
Gilles Peskine82e57d12020-11-13 21:31:17 +0100251#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \
252 defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
Gilles Peskinebee96c82020-11-23 21:00:09 +0100253 /* Only check HMAC_DRBG error codes if underlying mbedtls_xxx
254 * functions are passed a HMAC_DRBG instance. */
Gilles Peskine82e57d12020-11-13 21:31:17 +0100255 case MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED:
256 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
257 case MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG:
258 case MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG:
259 return( PSA_ERROR_NOT_SUPPORTED );
260 case MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR:
261 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
262#endif
263
Gilles Peskinea5905292018-02-07 20:59:33 +0100264 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
265 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
266 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
267 return( PSA_ERROR_HARDWARE_FAILURE );
268
269 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
270 return( PSA_ERROR_NOT_SUPPORTED );
271 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
272 return( PSA_ERROR_INVALID_ARGUMENT );
273 case MBEDTLS_ERR_MD_ALLOC_FAILED:
274 return( PSA_ERROR_INSUFFICIENT_MEMORY );
275 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
276 return( PSA_ERROR_STORAGE_FAILURE );
277 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
278 return( PSA_ERROR_HARDWARE_FAILURE );
279
Gilles Peskinef76aa772018-10-29 19:24:33 +0100280 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
281 return( PSA_ERROR_STORAGE_FAILURE );
282 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
283 return( PSA_ERROR_INVALID_ARGUMENT );
284 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
285 return( PSA_ERROR_INVALID_ARGUMENT );
286 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
287 return( PSA_ERROR_BUFFER_TOO_SMALL );
288 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
289 return( PSA_ERROR_INVALID_ARGUMENT );
290 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
291 return( PSA_ERROR_INVALID_ARGUMENT );
292 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
293 return( PSA_ERROR_INVALID_ARGUMENT );
294 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
295 return( PSA_ERROR_INSUFFICIENT_MEMORY );
296
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100297 case MBEDTLS_ERR_PK_ALLOC_FAILED:
298 return( PSA_ERROR_INSUFFICIENT_MEMORY );
299 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
300 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
301 return( PSA_ERROR_INVALID_ARGUMENT );
302 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100303 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100304 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
305 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
306 return( PSA_ERROR_INVALID_ARGUMENT );
307 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
308 return( PSA_ERROR_NOT_SUPPORTED );
309 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
310 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
311 return( PSA_ERROR_NOT_PERMITTED );
312 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
313 return( PSA_ERROR_INVALID_ARGUMENT );
314 case MBEDTLS_ERR_PK_INVALID_ALG:
315 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
316 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
317 return( PSA_ERROR_NOT_SUPPORTED );
318 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
319 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100320 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
321 return( PSA_ERROR_HARDWARE_FAILURE );
322
Gilles Peskineff2d2002019-05-06 15:26:23 +0200323 case MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED:
324 return( PSA_ERROR_HARDWARE_FAILURE );
325 case MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
326 return( PSA_ERROR_NOT_SUPPORTED );
327
Gilles Peskinea5905292018-02-07 20:59:33 +0100328 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
329 return( PSA_ERROR_HARDWARE_FAILURE );
330
331 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
332 return( PSA_ERROR_INVALID_ARGUMENT );
333 case MBEDTLS_ERR_RSA_INVALID_PADDING:
334 return( PSA_ERROR_INVALID_PADDING );
335 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
336 return( PSA_ERROR_HARDWARE_FAILURE );
337 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
338 return( PSA_ERROR_INVALID_ARGUMENT );
339 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
340 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
Gilles Peskine4b3eb692019-05-16 21:35:18 +0200341 return( PSA_ERROR_CORRUPTION_DETECTED );
Gilles Peskinea5905292018-02-07 20:59:33 +0100342 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
343 return( PSA_ERROR_INVALID_SIGNATURE );
344 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
345 return( PSA_ERROR_BUFFER_TOO_SMALL );
346 case MBEDTLS_ERR_RSA_RNG_FAILED:
347 return( PSA_ERROR_INSUFFICIENT_MEMORY );
348 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
349 return( PSA_ERROR_NOT_SUPPORTED );
350 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
351 return( PSA_ERROR_HARDWARE_FAILURE );
352
353 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
354 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
355 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
356 return( PSA_ERROR_HARDWARE_FAILURE );
357
358 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
359 return( PSA_ERROR_INVALID_ARGUMENT );
360 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
361 return( PSA_ERROR_HARDWARE_FAILURE );
362
itayzafrir5c753392018-05-08 11:18:38 +0300363 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300364 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300365 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300366 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
367 return( PSA_ERROR_BUFFER_TOO_SMALL );
368 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
369 return( PSA_ERROR_NOT_SUPPORTED );
370 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
371 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
372 return( PSA_ERROR_INVALID_SIGNATURE );
373 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
374 return( PSA_ERROR_INSUFFICIENT_MEMORY );
375 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
376 return( PSA_ERROR_HARDWARE_FAILURE );
Janos Follatha13b9052019-11-22 12:48:59 +0000377 case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
378 return( PSA_ERROR_CORRUPTION_DETECTED );
itayzafrir5c753392018-05-08 11:18:38 +0300379
Gilles Peskinee59236f2018-01-27 23:32:46 +0100380 default:
David Saadab4ecc272019-02-14 13:48:10 +0200381 return( PSA_ERROR_GENERIC_ERROR );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100382 }
383}
384
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200385
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200386
387
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100388/****************************************************************/
389/* Key management */
390/****************************************************************/
391
Gilles Peskine73167e12019-07-12 23:44:37 +0200392#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
393static inline int psa_key_slot_is_external( const psa_key_slot_t *slot )
394{
Gilles Peskine8e338702019-07-30 20:06:31 +0200395 return( psa_key_lifetime_is_external( slot->attr.lifetime ) );
Gilles Peskine73167e12019-07-12 23:44:37 +0200396}
397#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
398
John Durkop07cc04a2020-11-16 22:08:34 -0800399/* For now the MBEDTLS_PSA_ACCEL_ guards are also used here since the
400 * current test driver in key_management.c is using this function
401 * when accelerators are used for ECC key pair and public key.
402 * Once that dependency is resolved these guards can be removed.
403 */
John Durkop9814fa22020-11-04 12:28:15 -0800404#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
John Durkop6ba40d12020-11-10 08:50:04 -0800405 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
406 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \
407 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
Paul Elliott8ff510a2020-06-02 17:19:28 +0100408mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_family_t curve,
Gilles Peskine5055b232019-12-12 17:49:31 +0100409 size_t byte_length )
Gilles Peskine12313cd2018-06-20 00:20:32 +0200410{
411 switch( curve )
412 {
Paul Elliott8ff510a2020-06-02 17:19:28 +0100413 case PSA_ECC_FAMILY_SECP_R1:
Gilles Peskine228abc52019-12-03 17:24:19 +0100414 switch( byte_length )
415 {
416 case PSA_BITS_TO_BYTES( 192 ):
417 return( MBEDTLS_ECP_DP_SECP192R1 );
418 case PSA_BITS_TO_BYTES( 224 ):
419 return( MBEDTLS_ECP_DP_SECP224R1 );
420 case PSA_BITS_TO_BYTES( 256 ):
421 return( MBEDTLS_ECP_DP_SECP256R1 );
422 case PSA_BITS_TO_BYTES( 384 ):
423 return( MBEDTLS_ECP_DP_SECP384R1 );
424 case PSA_BITS_TO_BYTES( 521 ):
425 return( MBEDTLS_ECP_DP_SECP521R1 );
426 default:
427 return( MBEDTLS_ECP_DP_NONE );
428 }
429 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100430
Paul Elliott8ff510a2020-06-02 17:19:28 +0100431 case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
Gilles Peskine228abc52019-12-03 17:24:19 +0100432 switch( byte_length )
433 {
434 case PSA_BITS_TO_BYTES( 256 ):
435 return( MBEDTLS_ECP_DP_BP256R1 );
436 case PSA_BITS_TO_BYTES( 384 ):
437 return( MBEDTLS_ECP_DP_BP384R1 );
438 case PSA_BITS_TO_BYTES( 512 ):
439 return( MBEDTLS_ECP_DP_BP512R1 );
440 default:
441 return( MBEDTLS_ECP_DP_NONE );
442 }
443 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100444
Paul Elliott8ff510a2020-06-02 17:19:28 +0100445 case PSA_ECC_FAMILY_MONTGOMERY:
Gilles Peskine228abc52019-12-03 17:24:19 +0100446 switch( byte_length )
447 {
448 case PSA_BITS_TO_BYTES( 255 ):
449 return( MBEDTLS_ECP_DP_CURVE25519 );
450 case PSA_BITS_TO_BYTES( 448 ):
451 return( MBEDTLS_ECP_DP_CURVE448 );
452 default:
453 return( MBEDTLS_ECP_DP_NONE );
454 }
455 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100456
Paul Elliott8ff510a2020-06-02 17:19:28 +0100457 case PSA_ECC_FAMILY_SECP_K1:
Gilles Peskine228abc52019-12-03 17:24:19 +0100458 switch( byte_length )
459 {
460 case PSA_BITS_TO_BYTES( 192 ):
461 return( MBEDTLS_ECP_DP_SECP192K1 );
462 case PSA_BITS_TO_BYTES( 224 ):
463 return( MBEDTLS_ECP_DP_SECP224K1 );
464 case PSA_BITS_TO_BYTES( 256 ):
465 return( MBEDTLS_ECP_DP_SECP256K1 );
466 default:
467 return( MBEDTLS_ECP_DP_NONE );
468 }
469 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100470
Gilles Peskine12313cd2018-06-20 00:20:32 +0200471 default:
472 return( MBEDTLS_ECP_DP_NONE );
473 }
474}
John Durkop9814fa22020-11-04 12:28:15 -0800475#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
John Durkop6ba40d12020-11-10 08:50:04 -0800476 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
477 * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) ||
478 * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200479
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200480static psa_status_t validate_unstructured_key_bit_size( psa_key_type_t type,
481 size_t bits )
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200482{
483 /* Check that the bit size is acceptable for the key type */
484 switch( type )
485 {
486 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200487 case PSA_KEY_TYPE_HMAC:
Gilles Peskineea0fb492018-07-12 17:17:20 +0200488 case PSA_KEY_TYPE_DERIVE:
489 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200490#if defined(MBEDTLS_AES_C)
491 case PSA_KEY_TYPE_AES:
492 if( bits != 128 && bits != 192 && bits != 256 )
493 return( PSA_ERROR_INVALID_ARGUMENT );
494 break;
495#endif
496#if defined(MBEDTLS_CAMELLIA_C)
497 case PSA_KEY_TYPE_CAMELLIA:
498 if( bits != 128 && bits != 192 && bits != 256 )
499 return( PSA_ERROR_INVALID_ARGUMENT );
500 break;
501#endif
502#if defined(MBEDTLS_DES_C)
503 case PSA_KEY_TYPE_DES:
504 if( bits != 64 && bits != 128 && bits != 192 )
505 return( PSA_ERROR_INVALID_ARGUMENT );
506 break;
507#endif
508#if defined(MBEDTLS_ARC4_C)
509 case PSA_KEY_TYPE_ARC4:
510 if( bits < 8 || bits > 2048 )
511 return( PSA_ERROR_INVALID_ARGUMENT );
512 break;
513#endif
Gilles Peskine26869f22019-05-06 15:25:00 +0200514#if defined(MBEDTLS_CHACHA20_C)
515 case PSA_KEY_TYPE_CHACHA20:
516 if( bits != 256 )
517 return( PSA_ERROR_INVALID_ARGUMENT );
518 break;
519#endif
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200520 default:
521 return( PSA_ERROR_NOT_SUPPORTED );
522 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200523 if( bits % 8 != 0 )
524 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200525
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200526 return( PSA_SUCCESS );
527}
528
John Durkop0e005192020-10-31 22:06:54 -0700529#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
530 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
531 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
John Durkop9814fa22020-11-04 12:28:15 -0800532 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
533 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
534 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Steven Cooremana01795d2020-07-24 22:48:15 +0200535
Gilles Peskine86a440b2018-11-12 18:39:40 +0100536/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
537 * that are not a multiple of 8) well. For example, there is only
538 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
539 * way to return the exact bit size of a key.
540 * To keep things simple, reject non-byte-aligned key sizes. */
541static psa_status_t psa_check_rsa_key_byte_aligned(
542 const mbedtls_rsa_context *rsa )
543{
544 mbedtls_mpi n;
545 psa_status_t status;
546 mbedtls_mpi_init( &n );
547 status = mbedtls_to_psa_error(
548 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
549 if( status == PSA_SUCCESS )
550 {
551 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
552 status = PSA_ERROR_NOT_SUPPORTED;
553 }
554 mbedtls_mpi_free( &n );
555 return( status );
556}
557
Steven Cooreman7f391872020-07-30 14:57:44 +0200558/** Load the contents of a key buffer into an internal RSA representation
Steven Cooremana01795d2020-07-24 22:48:15 +0200559 *
Steven Cooreman4fed4552020-08-03 14:46:03 +0200560 * \param[in] type The type of key contained in \p data.
561 * \param[in] data The buffer from which to load the representation.
562 * \param[in] data_length The size in bytes of \p data.
563 * \param[out] p_rsa Returns a pointer to an RSA context on success.
564 * The caller is responsible for freeing both the
565 * contents of the context and the context itself
566 * when done.
Steven Cooremana01795d2020-07-24 22:48:15 +0200567 */
Steven Cooreman4fed4552020-08-03 14:46:03 +0200568static psa_status_t psa_load_rsa_representation( psa_key_type_t type,
569 const uint8_t *data,
570 size_t data_length,
Steven Cooremana2371e52020-07-28 14:30:39 +0200571 mbedtls_rsa_context **p_rsa )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200572{
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000573 psa_status_t status;
Steven Cooremana01795d2020-07-24 22:48:15 +0200574 mbedtls_pk_context ctx;
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000575 size_t bits;
Steven Cooremana01795d2020-07-24 22:48:15 +0200576 mbedtls_pk_init( &ctx );
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000577
578 /* Parse the data. */
Steven Cooreman7f391872020-07-30 14:57:44 +0200579 if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000580 status = mbedtls_to_psa_error(
Steven Cooreman4fed4552020-08-03 14:46:03 +0200581 mbedtls_pk_parse_key( &ctx, data, data_length, NULL, 0 ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200582 else
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000583 status = mbedtls_to_psa_error(
Steven Cooreman4fed4552020-08-03 14:46:03 +0200584 mbedtls_pk_parse_public_key( &ctx, data, data_length ) );
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000585 if( status != PSA_SUCCESS )
586 goto exit;
587
588 /* We have something that the pkparse module recognizes. If it is a
589 * valid RSA key, store it. */
Steven Cooremana01795d2020-07-24 22:48:15 +0200590 if( mbedtls_pk_get_type( &ctx ) != MBEDTLS_PK_RSA )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200591 {
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000592 status = PSA_ERROR_INVALID_ARGUMENT;
593 goto exit;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200594 }
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000595
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000596 /* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
597 * supports non-byte-aligned key sizes, but not well. For example,
598 * mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
Steven Cooremana01795d2020-07-24 22:48:15 +0200599 bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( mbedtls_pk_rsa( ctx ) ) );
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000600 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
601 {
602 status = PSA_ERROR_NOT_SUPPORTED;
603 goto exit;
604 }
Steven Cooremana01795d2020-07-24 22:48:15 +0200605 status = psa_check_rsa_key_byte_aligned( mbedtls_pk_rsa( ctx ) );
Steven Cooremana01795d2020-07-24 22:48:15 +0200606 if( status != PSA_SUCCESS )
607 goto exit;
608
Steven Cooremana2371e52020-07-28 14:30:39 +0200609 /* Copy out the pointer to the RSA context, and reset the PK context
610 * such that pk_free doesn't free the RSA context we just grabbed. */
611 *p_rsa = mbedtls_pk_rsa( ctx );
612 ctx.pk_info = NULL;
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000613
614exit:
Steven Cooremana01795d2020-07-24 22:48:15 +0200615 mbedtls_pk_free( &ctx );
616 return( status );
Steven Cooremana01795d2020-07-24 22:48:15 +0200617}
618
John Durkop6ba40d12020-11-10 08:50:04 -0800619#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
620 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
621 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
622 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
623 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
624 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
625
626#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
627 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
628
Steven Cooremana01795d2020-07-24 22:48:15 +0200629/** Export an RSA key to export representation
630 *
631 * \param[in] type The type of key (public/private) to export
632 * \param[in] rsa The internal RSA representation from which to export
633 * \param[out] data The buffer to export to
634 * \param[in] data_size The length of the buffer to export to
635 * \param[out] data_length The amount of bytes written to \p data
636 */
637static psa_status_t psa_export_rsa_key( psa_key_type_t type,
638 mbedtls_rsa_context *rsa,
639 uint8_t *data,
640 size_t data_size,
641 size_t *data_length )
642{
643#if defined(MBEDTLS_PK_WRITE_C)
644 int ret;
645 mbedtls_pk_context pk;
646 uint8_t *pos = data + data_size;
647
648 mbedtls_pk_init( &pk );
649 pk.pk_info = &mbedtls_rsa_info;
650 pk.pk_ctx = rsa;
651
652 /* PSA Crypto API defines the format of an RSA key as a DER-encoded
Steven Cooreman75b74362020-07-28 14:30:13 +0200653 * representation of the non-encrypted PKCS#1 RSAPrivateKey for a
654 * private key and of the RFC3279 RSAPublicKey for a public key. */
Steven Cooremana01795d2020-07-24 22:48:15 +0200655 if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
656 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
657 else
658 ret = mbedtls_pk_write_pubkey( &pos, data, &pk );
659
660 if( ret < 0 )
Steven Cooreman4fed4552020-08-03 14:46:03 +0200661 {
662 /* Clean up in case pk_write failed halfway through. */
663 memset( data, 0, data_size );
Steven Cooreman29149862020-08-05 15:43:42 +0200664 return( mbedtls_to_psa_error( ret ) );
Steven Cooreman4fed4552020-08-03 14:46:03 +0200665 }
Steven Cooremana01795d2020-07-24 22:48:15 +0200666
667 /* The mbedtls_pk_xxx functions write to the end of the buffer.
668 * Move the data to the beginning and erase remaining data
669 * at the original location. */
670 if( 2 * (size_t) ret <= data_size )
671 {
672 memcpy( data, data + data_size - ret, ret );
673 memset( data + data_size - ret, 0, ret );
674 }
675 else if( (size_t) ret < data_size )
676 {
677 memmove( data, data + data_size - ret, ret );
678 memset( data + ret, 0, data_size - ret );
679 }
680
681 *data_length = ret;
682 return( PSA_SUCCESS );
683#else
684 (void) type;
685 (void) rsa;
686 (void) data;
687 (void) data_size;
688 (void) data_length;
689 return( PSA_ERROR_NOT_SUPPORTED );
690#endif /* MBEDTLS_PK_WRITE_C */
691}
692
693/** Import an RSA key from import representation to a slot
694 *
695 * \param[in,out] slot The slot where to store the export representation to
696 * \param[in] data The buffer containing the import representation
697 * \param[in] data_length The amount of bytes in \p data
698 */
699static psa_status_t psa_import_rsa_key( psa_key_slot_t *slot,
700 const uint8_t *data,
701 size_t data_length )
702{
703 psa_status_t status;
704 uint8_t* output = NULL;
Steven Cooremana2371e52020-07-28 14:30:39 +0200705 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +0200706
Steven Cooremana01795d2020-07-24 22:48:15 +0200707 /* Parse input */
Steven Cooreman4fed4552020-08-03 14:46:03 +0200708 status = psa_load_rsa_representation( slot->attr.type,
709 data,
Steven Cooreman7f391872020-07-30 14:57:44 +0200710 data_length,
Steven Cooreman7f391872020-07-30 14:57:44 +0200711 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +0200712 if( status != PSA_SUCCESS )
713 goto exit;
714
715 slot->attr.bits = (psa_key_bits_t) PSA_BYTES_TO_BITS(
Steven Cooremana2371e52020-07-28 14:30:39 +0200716 mbedtls_rsa_get_len( rsa ) );
Steven Cooremana01795d2020-07-24 22:48:15 +0200717
Steven Cooreman75b74362020-07-28 14:30:13 +0200718 /* Re-export the data to PSA export format, such that we can store export
719 * representation in the key slot. Export representation in case of RSA is
720 * the smallest representation that's allowed as input, so a straight-up
721 * allocation of the same size as the input buffer will be large enough. */
Steven Cooremana01795d2020-07-24 22:48:15 +0200722 output = mbedtls_calloc( 1, data_length );
Steven Cooremana01795d2020-07-24 22:48:15 +0200723 if( output == NULL )
724 {
725 status = PSA_ERROR_INSUFFICIENT_MEMORY;
726 goto exit;
727 }
728
Steven Cooremana01795d2020-07-24 22:48:15 +0200729 status = psa_export_rsa_key( slot->attr.type,
Steven Cooremana2371e52020-07-28 14:30:39 +0200730 rsa,
Steven Cooremana01795d2020-07-24 22:48:15 +0200731 output,
732 data_length,
733 &data_length);
Steven Cooremana01795d2020-07-24 22:48:15 +0200734exit:
735 /* Always free the RSA object */
Steven Cooremana2371e52020-07-28 14:30:39 +0200736 mbedtls_rsa_free( rsa );
Steven Cooreman6d839f02020-07-30 11:36:45 +0200737 mbedtls_free( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +0200738
739 /* Free the allocated buffer only on error. */
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000740 if( status != PSA_SUCCESS )
741 {
Steven Cooremana01795d2020-07-24 22:48:15 +0200742 mbedtls_free( output );
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000743 return( status );
744 }
745
Steven Cooremana01795d2020-07-24 22:48:15 +0200746 /* On success, store the allocated export-formatted key. */
747 slot->data.key.data = output;
748 slot->data.key.bytes = data_length;
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000749
750 return( PSA_SUCCESS );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200751}
John Durkop6ba40d12020-11-10 08:50:04 -0800752
753#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
John Durkop9814fa22020-11-04 12:28:15 -0800754 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200755
John Durkop9814fa22020-11-04 12:28:15 -0800756#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
John Durkop6ba40d12020-11-10 08:50:04 -0800757 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
758 defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
759 defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) || \
760 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Steven Cooreman7f391872020-07-30 14:57:44 +0200761/** Load the contents of a key buffer into an internal ECP representation
Steven Cooremana2371e52020-07-28 14:30:39 +0200762 *
Steven Cooreman4fed4552020-08-03 14:46:03 +0200763 * \param[in] type The type of key contained in \p data.
764 * \param[in] data The buffer from which to load the representation.
765 * \param[in] data_length The size in bytes of \p data.
766 * \param[out] p_ecp Returns a pointer to an ECP context on success.
767 * The caller is responsible for freeing both the
768 * contents of the context and the context itself
769 * when done.
Steven Cooremana2371e52020-07-28 14:30:39 +0200770 */
Steven Cooreman4fed4552020-08-03 14:46:03 +0200771static psa_status_t psa_load_ecp_representation( psa_key_type_t type,
772 const uint8_t *data,
773 size_t data_length,
Steven Cooremana2371e52020-07-28 14:30:39 +0200774 mbedtls_ecp_keypair **p_ecp )
Gilles Peskine4cd32772019-12-02 20:49:42 +0100775{
776 mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
Steven Cooremanacda8342020-07-24 23:09:52 +0200777 psa_status_t status;
Steven Cooreman6d839f02020-07-30 11:36:45 +0200778 mbedtls_ecp_keypair *ecp = NULL;
Steven Cooreman4fed4552020-08-03 14:46:03 +0200779 size_t curve_size = data_length;
Gilles Peskine4cd32772019-12-02 20:49:42 +0100780
Steven Cooreman4fed4552020-08-03 14:46:03 +0200781 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) &&
782 PSA_KEY_TYPE_ECC_GET_FAMILY( type ) != PSA_ECC_FAMILY_MONTGOMERY )
Gilles Peskine4295e8b2019-12-02 21:39:10 +0100783 {
Steven Cooreman4fed4552020-08-03 14:46:03 +0200784 /* A Weierstrass public key is represented as:
785 * - The byte 0x04;
786 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
787 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
Steven Cooreman3ea0ce42020-10-23 11:37:05 +0200788 * So its data length is 2m+1 where m is the curve size in bits.
Steven Cooreman4fed4552020-08-03 14:46:03 +0200789 */
790 if( ( data_length & 1 ) == 0 )
791 return( PSA_ERROR_INVALID_ARGUMENT );
792 curve_size = data_length / 2;
793
794 /* Montgomery public keys are represented in compressed format, meaning
795 * their curve_size is equal to the amount of input. */
796
797 /* Private keys are represented in uncompressed private random integer
798 * format, meaning their curve_size is equal to the amount of input. */
Gilles Peskine4295e8b2019-12-02 21:39:10 +0100799 }
800
Steven Cooreman6d839f02020-07-30 11:36:45 +0200801 /* Allocate and initialize a key representation. */
Steven Cooreman29149862020-08-05 15:43:42 +0200802 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
Steven Cooreman6d839f02020-07-30 11:36:45 +0200803 if( ecp == NULL )
Steven Cooreman29149862020-08-05 15:43:42 +0200804 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Steven Cooremana2371e52020-07-28 14:30:39 +0200805 mbedtls_ecp_keypair_init( ecp );
806
Gilles Peskine4cd32772019-12-02 20:49:42 +0100807 /* Load the group. */
Steven Cooreman7f391872020-07-30 14:57:44 +0200808 grp_id = mbedtls_ecc_group_of_psa( PSA_KEY_TYPE_ECC_GET_FAMILY( type ),
809 curve_size );
Gilles Peskine4295e8b2019-12-02 21:39:10 +0100810 if( grp_id == MBEDTLS_ECP_DP_NONE )
Steven Cooreman6d839f02020-07-30 11:36:45 +0200811 {
812 status = PSA_ERROR_INVALID_ARGUMENT;
813 goto exit;
814 }
815
Steven Cooremanacda8342020-07-24 23:09:52 +0200816 status = mbedtls_to_psa_error(
817 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
818 if( status != PSA_SUCCESS )
Steven Cooreman6d839f02020-07-30 11:36:45 +0200819 goto exit;
Steven Cooremanacda8342020-07-24 23:09:52 +0200820
Steven Cooreman6d839f02020-07-30 11:36:45 +0200821 /* Load the key material. */
Steven Cooreman7f391872020-07-30 14:57:44 +0200822 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
Steven Cooremanacda8342020-07-24 23:09:52 +0200823 {
824 /* Load the public value. */
825 status = mbedtls_to_psa_error(
826 mbedtls_ecp_point_read_binary( &ecp->grp, &ecp->Q,
Steven Cooreman4fed4552020-08-03 14:46:03 +0200827 data,
828 data_length ) );
Steven Cooremanacda8342020-07-24 23:09:52 +0200829 if( status != PSA_SUCCESS )
830 goto exit;
831
832 /* Check that the point is on the curve. */
833 status = mbedtls_to_psa_error(
834 mbedtls_ecp_check_pubkey( &ecp->grp, &ecp->Q ) );
835 if( status != PSA_SUCCESS )
836 goto exit;
837 }
838 else
839 {
Steven Cooreman6d839f02020-07-30 11:36:45 +0200840 /* Load and validate the secret value. */
Steven Cooremanacda8342020-07-24 23:09:52 +0200841 status = mbedtls_to_psa_error(
842 mbedtls_ecp_read_key( ecp->grp.id,
843 ecp,
Steven Cooreman4fed4552020-08-03 14:46:03 +0200844 data,
845 data_length ) );
Steven Cooremanacda8342020-07-24 23:09:52 +0200846 if( status != PSA_SUCCESS )
847 goto exit;
Steven Cooremanacda8342020-07-24 23:09:52 +0200848 }
Steven Cooremana2371e52020-07-28 14:30:39 +0200849
850 *p_ecp = ecp;
Steven Cooremanacda8342020-07-24 23:09:52 +0200851exit:
852 if( status != PSA_SUCCESS )
Steven Cooremana2371e52020-07-28 14:30:39 +0200853 {
Steven Cooremanacda8342020-07-24 23:09:52 +0200854 mbedtls_ecp_keypair_free( ecp );
Steven Cooremana2371e52020-07-28 14:30:39 +0200855 mbedtls_free( ecp );
856 }
857
Steven Cooreman29149862020-08-05 15:43:42 +0200858 return( status );
Gilles Peskine4cd32772019-12-02 20:49:42 +0100859}
John Durkop6ba40d12020-11-10 08:50:04 -0800860#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
861 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
862 * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
863 * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) ||
864 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Jaeden Ameroccdce902019-01-10 11:42:27 +0000865
John Durkop6ba40d12020-11-10 08:50:04 -0800866#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
867 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Steven Cooreman4fed4552020-08-03 14:46:03 +0200868/** Export an ECP key to export representation
869 *
870 * \param[in] type The type of key (public/private) to export
871 * \param[in] ecp The internal ECP representation from which to export
872 * \param[out] data The buffer to export to
873 * \param[in] data_size The length of the buffer to export to
874 * \param[out] data_length The amount of bytes written to \p data
875 */
Steven Cooremanacda8342020-07-24 23:09:52 +0200876static psa_status_t psa_export_ecp_key( psa_key_type_t type,
877 mbedtls_ecp_keypair *ecp,
878 uint8_t *data,
879 size_t data_size,
880 size_t *data_length )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200881{
Steven Cooremanacda8342020-07-24 23:09:52 +0200882 psa_status_t status;
Jaeden Ameroccdce902019-01-10 11:42:27 +0000883
Steven Cooremanacda8342020-07-24 23:09:52 +0200884 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200885 {
Steven Cooremanacda8342020-07-24 23:09:52 +0200886 /* Check whether the public part is loaded */
887 if( mbedtls_ecp_is_zero( &ecp->Q ) )
888 {
889 /* Calculate the public key */
890 status = mbedtls_to_psa_error(
891 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100892 mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
Steven Cooremanacda8342020-07-24 23:09:52 +0200893 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +0200894 return( status );
Steven Cooremanacda8342020-07-24 23:09:52 +0200895 }
896
Steven Cooreman4fed4552020-08-03 14:46:03 +0200897 status = mbedtls_to_psa_error(
Steven Cooremanacda8342020-07-24 23:09:52 +0200898 mbedtls_ecp_point_write_binary( &ecp->grp, &ecp->Q,
899 MBEDTLS_ECP_PF_UNCOMPRESSED,
900 data_length,
901 data,
Steven Cooreman4fed4552020-08-03 14:46:03 +0200902 data_size ) );
Steven Cooreman4fed4552020-08-03 14:46:03 +0200903 if( status != PSA_SUCCESS )
904 memset( data, 0, data_size );
905
Steven Cooreman29149862020-08-05 15:43:42 +0200906 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200907 }
Steven Cooremanacda8342020-07-24 23:09:52 +0200908 else
909 {
Steven Cooreman29149862020-08-05 15:43:42 +0200910 if( data_size < PSA_BITS_TO_BYTES( ecp->grp.nbits ) )
Steven Cooremanacda8342020-07-24 23:09:52 +0200911 return( PSA_ERROR_BUFFER_TOO_SMALL );
912
913 status = mbedtls_to_psa_error(
914 mbedtls_ecp_write_key( ecp,
915 data,
Steven Cooreman29149862020-08-05 15:43:42 +0200916 PSA_BITS_TO_BYTES( ecp->grp.nbits ) ) );
Steven Cooremanacda8342020-07-24 23:09:52 +0200917 if( status == PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +0200918 *data_length = PSA_BITS_TO_BYTES( ecp->grp.nbits );
Steven Cooremanb7f6dea2020-08-05 16:07:20 +0200919 else
920 memset( data, 0, data_size );
Steven Cooremanacda8342020-07-24 23:09:52 +0200921
922 return( status );
923 }
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200924}
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200925
Steven Cooreman4fed4552020-08-03 14:46:03 +0200926/** Import an ECP key from import representation to a slot
927 *
928 * \param[in,out] slot The slot where to store the export representation to
929 * \param[in] data The buffer containing the import representation
930 * \param[in] data_length The amount of bytes in \p data
931 */
Steven Cooremanacda8342020-07-24 23:09:52 +0200932static psa_status_t psa_import_ecp_key( psa_key_slot_t *slot,
933 const uint8_t *data,
934 size_t data_length )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100935{
Steven Cooremanacda8342020-07-24 23:09:52 +0200936 psa_status_t status;
937 uint8_t* output = NULL;
Steven Cooremana2371e52020-07-28 14:30:39 +0200938 mbedtls_ecp_keypair *ecp = NULL;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100939
Steven Cooremanacda8342020-07-24 23:09:52 +0200940 /* Parse input */
Steven Cooreman4fed4552020-08-03 14:46:03 +0200941 status = psa_load_ecp_representation( slot->attr.type,
942 data,
Steven Cooreman7f391872020-07-30 14:57:44 +0200943 data_length,
Steven Cooreman7f391872020-07-30 14:57:44 +0200944 &ecp );
Gilles Peskinef76aa772018-10-29 19:24:33 +0100945 if( status != PSA_SUCCESS )
946 goto exit;
Gilles Peskine4cd32772019-12-02 20:49:42 +0100947
Steven Cooremanacda8342020-07-24 23:09:52 +0200948 if( PSA_KEY_TYPE_ECC_GET_FAMILY( slot->attr.type ) == PSA_ECC_FAMILY_MONTGOMERY)
Steven Cooremana2371e52020-07-28 14:30:39 +0200949 slot->attr.bits = (psa_key_bits_t) ecp->grp.nbits + 1;
Steven Cooremanacda8342020-07-24 23:09:52 +0200950 else
Steven Cooremana2371e52020-07-28 14:30:39 +0200951 slot->attr.bits = (psa_key_bits_t) ecp->grp.nbits;
Steven Cooremane3fd3922020-06-11 16:50:36 +0200952
Steven Cooremanacda8342020-07-24 23:09:52 +0200953 /* Re-export the data to PSA export format. There is currently no support
954 * for other input formats then the export format, so this is a 1-1
955 * copy operation. */
956 output = mbedtls_calloc( 1, data_length );
Steven Cooremanacda8342020-07-24 23:09:52 +0200957 if( output == NULL )
958 {
959 status = PSA_ERROR_INSUFFICIENT_MEMORY;
960 goto exit;
961 }
962
963 status = psa_export_ecp_key( slot->attr.type,
Steven Cooremana2371e52020-07-28 14:30:39 +0200964 ecp,
Steven Cooremanacda8342020-07-24 23:09:52 +0200965 output,
966 data_length,
967 &data_length);
Gilles Peskinef76aa772018-10-29 19:24:33 +0100968exit:
Steven Cooremana2371e52020-07-28 14:30:39 +0200969 /* Always free the PK object (will also free contained ECP context) */
970 mbedtls_ecp_keypair_free( ecp );
Steven Cooreman6d839f02020-07-30 11:36:45 +0200971 mbedtls_free( ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +0200972
973 /* Free the allocated buffer only on error. */
974 if( status != PSA_SUCCESS )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100975 {
Steven Cooremanacda8342020-07-24 23:09:52 +0200976 mbedtls_free( output );
Steven Cooremanacda8342020-07-24 23:09:52 +0200977 return( status );
Gilles Peskinef76aa772018-10-29 19:24:33 +0100978 }
Steven Cooremanacda8342020-07-24 23:09:52 +0200979
980 /* On success, store the allocated export-formatted key. */
981 slot->data.key.data = output;
982 slot->data.key.bytes = data_length;
983
984 return( PSA_SUCCESS );
Gilles Peskinef76aa772018-10-29 19:24:33 +0100985}
John Durkop9814fa22020-11-04 12:28:15 -0800986#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
987 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
Gilles Peskinef76aa772018-10-29 19:24:33 +0100988
Gilles Peskineb46bef22019-07-30 21:32:04 +0200989/** Return the size of the key in the given slot, in bits.
990 *
991 * \param[in] slot A key slot.
992 *
993 * \return The key size in bits, read from the metadata in the slot.
994 */
995static inline size_t psa_get_key_slot_bits( const psa_key_slot_t *slot )
996{
997 return( slot->attr.bits );
998}
999
Steven Cooreman75b74362020-07-28 14:30:13 +02001000/** Try to allocate a buffer to an empty key slot.
1001 *
1002 * \param[in,out] slot Key slot to attach buffer to.
1003 * \param[in] buffer_length Requested size of the buffer.
1004 *
1005 * \retval #PSA_SUCCESS
1006 * The buffer has been successfully allocated.
1007 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
1008 * Not enough memory was available for allocation.
1009 * \retval #PSA_ERROR_ALREADY_EXISTS
1010 * Trying to allocate a buffer to a non-empty key slot.
1011 */
1012static psa_status_t psa_allocate_buffer_to_slot( psa_key_slot_t *slot,
1013 size_t buffer_length )
1014{
1015 if( slot->data.key.data != NULL )
Steven Cooreman29149862020-08-05 15:43:42 +02001016 return( PSA_ERROR_ALREADY_EXISTS );
Steven Cooreman75b74362020-07-28 14:30:13 +02001017
1018 slot->data.key.data = mbedtls_calloc( 1, buffer_length );
1019 if( slot->data.key.data == NULL )
Steven Cooreman29149862020-08-05 15:43:42 +02001020 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Steven Cooreman75b74362020-07-28 14:30:13 +02001021
1022 slot->data.key.bytes = buffer_length;
Steven Cooreman29149862020-08-05 15:43:42 +02001023 return( PSA_SUCCESS );
Steven Cooreman75b74362020-07-28 14:30:13 +02001024}
1025
Steven Cooremanf7cebd42020-10-13 20:27:40 +02001026psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot,
1027 const uint8_t* data,
1028 size_t data_length )
1029{
1030 psa_status_t status = psa_allocate_buffer_to_slot( slot,
1031 data_length );
1032 if( status != PSA_SUCCESS )
1033 return( status );
1034
1035 memcpy( slot->data.key.data, data, data_length );
1036 return( PSA_SUCCESS );
1037}
1038
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001039/** Import key data into a slot.
1040 *
1041 * `slot->type` must have been set previously.
1042 * This function assumes that the slot does not contain any key material yet.
1043 * On failure, the slot content is unchanged.
1044 *
1045 * Persistent storage is not affected.
1046 *
1047 * \param[in,out] slot The key slot to import data into.
1048 * Its `type` field must have previously been set to
1049 * the desired key type.
1050 * It must not contain any key material yet.
1051 * \param[in] data Buffer containing the key material to parse and import.
1052 * \param data_length Size of \p data in bytes.
1053 *
1054 * \retval #PSA_SUCCESS
1055 * \retval #PSA_ERROR_INVALID_ARGUMENT
1056 * \retval #PSA_ERROR_NOT_SUPPORTED
1057 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
1058 */
1059static psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
1060 const uint8_t *data,
1061 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001062{
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001063 psa_status_t status = PSA_SUCCESS;
Steven Cooreman04524762020-10-13 17:43:44 +02001064 size_t bit_size;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001065
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001066 /* zero-length keys are never supported. */
1067 if( data_length == 0 )
1068 return( PSA_ERROR_NOT_SUPPORTED );
1069
Gilles Peskine8e338702019-07-30 20:06:31 +02001070 if( key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001071 {
Steven Cooreman04524762020-10-13 17:43:44 +02001072 bit_size = PSA_BYTES_TO_BITS( data_length );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001073
Steven Cooreman75b74362020-07-28 14:30:13 +02001074 /* Ensure that the bytes-to-bits conversion hasn't overflown. */
1075 if( data_length > SIZE_MAX / 8 )
1076 return( PSA_ERROR_NOT_SUPPORTED );
1077
Gilles Peskine1b9505c2019-08-07 10:59:45 +02001078 /* Enforce a size limit, and in particular ensure that the bit
1079 * size fits in its representation type. */
Gilles Peskinec744d992019-07-30 17:26:54 +02001080 if( bit_size > PSA_MAX_KEY_BITS )
1081 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001082
1083 status = validate_unstructured_key_bit_size( slot->attr.type, bit_size );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +02001084 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02001085 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001086
1087 /* Allocate memory for the key */
Steven Cooremanf7cebd42020-10-13 20:27:40 +02001088 status = psa_copy_key_material_into_slot( slot, data, data_length );
Steven Cooreman75b74362020-07-28 14:30:13 +02001089 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02001090 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001091
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001092 /* Write the actual key size to the slot.
1093 * psa_start_key_creation() wrote the size declared by the
1094 * caller, which may be 0 (meaning unspecified) or wrong. */
1095 slot->attr.bits = (psa_key_bits_t) bit_size;
Steven Cooreman40120f62020-10-29 11:42:22 +01001096
1097 return( PSA_SUCCESS );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001098 }
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001099 else if( PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
Steven Cooreman19fd5742020-07-24 23:31:01 +02001100 {
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001101 /* Try validation through accelerators first. */
1102 bit_size = slot->attr.bits;
1103 psa_key_attributes_t attributes = {
1104 .core = slot->attr
1105 };
1106 status = psa_driver_wrapper_validate_key( &attributes,
1107 data,
1108 data_length,
1109 &bit_size );
1110 if( status == PSA_SUCCESS )
1111 {
1112 /* Key has been validated successfully by an accelerator.
1113 * Copy key material into slot. */
1114 status = psa_copy_key_material_into_slot( slot, data, data_length );
1115 if( status != PSA_SUCCESS )
1116 return( status );
1117
1118 slot->attr.bits = (psa_key_bits_t) bit_size;
1119 return( PSA_SUCCESS );
1120 }
1121 else if( status != PSA_ERROR_NOT_SUPPORTED )
1122 return( status );
1123
1124 /* Key format is not supported by any accelerator, try software fallback
1125 * if present. */
John Durkop9814fa22020-11-04 12:28:15 -08001126#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
1127 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001128 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
1129 {
Steven Cooreman40120f62020-10-29 11:42:22 +01001130 return( psa_import_ecp_key( slot, data, data_length ) );
1131 }
John Durkop9814fa22020-11-04 12:28:15 -08001132#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
1133 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
John Durkop0e005192020-10-31 22:06:54 -07001134#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1135 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Steven Cooreman40120f62020-10-29 11:42:22 +01001136 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001137 {
Steven Cooreman40120f62020-10-29 11:42:22 +01001138 return( psa_import_rsa_key( slot, data, data_length ) );
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001139 }
John Durkop9814fa22020-11-04 12:28:15 -08001140#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1141 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Steven Cooreman40120f62020-10-29 11:42:22 +01001142
1143 /* Fell through the fallback as well, so have nothing else to try. */
1144 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001145 }
1146 else
Gilles Peskinec66ea6a2018-02-03 22:43:28 +01001147 {
Steven Cooreman19fd5742020-07-24 23:31:01 +02001148 /* Unknown key type */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001149 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969ac722018-01-28 18:16:59 +01001150 }
Darryl Green06fd18d2018-07-16 11:21:11 +01001151}
1152
Gilles Peskinef603c712019-01-19 13:40:11 +01001153/** Calculate the intersection of two algorithm usage policies.
1154 *
1155 * Return 0 (which allows no operation) on incompatibility.
1156 */
1157static psa_algorithm_t psa_key_policy_algorithm_intersection(
1158 psa_algorithm_t alg1,
1159 psa_algorithm_t alg2 )
1160{
Gilles Peskine549ea862019-05-22 11:45:59 +02001161 /* Common case: both sides actually specify the same policy. */
Gilles Peskinef603c712019-01-19 13:40:11 +01001162 if( alg1 == alg2 )
1163 return( alg1 );
1164 /* If the policies are from the same hash-and-sign family, check
1165 * if one is a wildcard. If so the other has the specific algorithm. */
1166 if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) &&
1167 PSA_ALG_IS_HASH_AND_SIGN( alg2 ) &&
1168 ( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
1169 {
1170 if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
1171 return( alg2 );
1172 if( PSA_ALG_SIGN_GET_HASH( alg2 ) == PSA_ALG_ANY_HASH )
1173 return( alg1 );
1174 }
1175 /* If the policies are incompatible, allow nothing. */
1176 return( 0 );
1177}
1178
Gilles Peskined6f371b2019-05-10 19:33:38 +02001179static int psa_key_algorithm_permits( psa_algorithm_t policy_alg,
1180 psa_algorithm_t requested_alg )
1181{
Gilles Peskine549ea862019-05-22 11:45:59 +02001182 /* Common case: the policy only allows requested_alg. */
Gilles Peskined6f371b2019-05-10 19:33:38 +02001183 if( requested_alg == policy_alg )
1184 return( 1 );
1185 /* If policy_alg is a hash-and-sign with a wildcard for the hash,
Gilles Peskine549ea862019-05-22 11:45:59 +02001186 * and requested_alg is the same hash-and-sign family with any hash,
1187 * then requested_alg is compliant with policy_alg. */
Gilles Peskined6f371b2019-05-10 19:33:38 +02001188 if( PSA_ALG_IS_HASH_AND_SIGN( requested_alg ) &&
1189 PSA_ALG_SIGN_GET_HASH( policy_alg ) == PSA_ALG_ANY_HASH )
1190 {
1191 return( ( policy_alg & ~PSA_ALG_HASH_MASK ) ==
1192 ( requested_alg & ~PSA_ALG_HASH_MASK ) );
1193 }
Steven Cooremance48e852020-10-05 16:02:45 +02001194 /* If policy_alg is a generic key agreement operation, then using it for
Steven Cooremanfa5e6312020-10-15 17:07:12 +02001195 * a key derivation with that key agreement should also be allowed. This
1196 * behaviour is expected to be defined in a future specification version. */
Steven Cooremance48e852020-10-05 16:02:45 +02001197 if( PSA_ALG_IS_RAW_KEY_AGREEMENT( policy_alg ) &&
1198 PSA_ALG_IS_KEY_AGREEMENT( requested_alg ) )
1199 {
1200 return( PSA_ALG_KEY_AGREEMENT_GET_BASE( requested_alg ) ==
1201 policy_alg );
1202 }
Gilles Peskined6f371b2019-05-10 19:33:38 +02001203 /* If it isn't permitted, it's forbidden. */
1204 return( 0 );
1205}
1206
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001207/** Test whether a policy permits an algorithm.
1208 *
1209 * The caller must test usage flags separately.
1210 */
1211static int psa_key_policy_permits( const psa_key_policy_t *policy,
1212 psa_algorithm_t alg )
1213{
Gilles Peskined6f371b2019-05-10 19:33:38 +02001214 return( psa_key_algorithm_permits( policy->alg, alg ) ||
1215 psa_key_algorithm_permits( policy->alg2, alg ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001216}
1217
Gilles Peskinef603c712019-01-19 13:40:11 +01001218/** Restrict a key policy based on a constraint.
1219 *
1220 * \param[in,out] policy The policy to restrict.
1221 * \param[in] constraint The policy constraint to apply.
1222 *
1223 * \retval #PSA_SUCCESS
1224 * \c *policy contains the intersection of the original value of
1225 * \c *policy and \c *constraint.
1226 * \retval #PSA_ERROR_INVALID_ARGUMENT
1227 * \c *policy and \c *constraint are incompatible.
1228 * \c *policy is unchanged.
1229 */
1230static psa_status_t psa_restrict_key_policy(
1231 psa_key_policy_t *policy,
1232 const psa_key_policy_t *constraint )
1233{
1234 psa_algorithm_t intersection_alg =
1235 psa_key_policy_algorithm_intersection( policy->alg, constraint->alg );
Gilles Peskined6f371b2019-05-10 19:33:38 +02001236 psa_algorithm_t intersection_alg2 =
1237 psa_key_policy_algorithm_intersection( policy->alg2, constraint->alg2 );
Gilles Peskinef603c712019-01-19 13:40:11 +01001238 if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 )
1239 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined6f371b2019-05-10 19:33:38 +02001240 if( intersection_alg2 == 0 && policy->alg2 != 0 && constraint->alg2 != 0 )
1241 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinef603c712019-01-19 13:40:11 +01001242 policy->usage &= constraint->usage;
1243 policy->alg = intersection_alg;
Gilles Peskined6f371b2019-05-10 19:33:38 +02001244 policy->alg2 = intersection_alg2;
Gilles Peskinef603c712019-01-19 13:40:11 +01001245 return( PSA_SUCCESS );
1246}
1247
Ronald Cron5c522922020-11-14 16:35:34 +01001248/** Get the description of a key given its identifier and policy constraints
1249 * and lock it.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001250 *
Ronald Cron5c522922020-11-14 16:35:34 +01001251 * The key must have allow all the usage flags set in \p usage. If \p alg is
1252 * nonzero, the key must allow operations with this algorithm.
Ronald Cron7587ae42020-11-11 15:04:25 +01001253 *
Ronald Cron5c522922020-11-14 16:35:34 +01001254 * In case of a persistent key, the function loads the description of the key
1255 * into a key slot if not already done.
1256 *
1257 * On success, the returned key slot is locked. It is the responsibility of
1258 * the caller to unlock the key slot when it does not access it anymore.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001259 */
Ronald Cron5c522922020-11-14 16:35:34 +01001260static psa_status_t psa_get_and_lock_key_slot_with_policy(
1261 mbedtls_svc_key_id_t key,
1262 psa_key_slot_t **p_slot,
1263 psa_key_usage_t usage,
1264 psa_algorithm_t alg )
Darryl Green06fd18d2018-07-16 11:21:11 +01001265{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001266 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1267 psa_key_slot_t *slot;
Darryl Green06fd18d2018-07-16 11:21:11 +01001268
Ronald Cron5c522922020-11-14 16:35:34 +01001269 status = psa_get_and_lock_key_slot( key, p_slot );
Darryl Green06fd18d2018-07-16 11:21:11 +01001270 if( status != PSA_SUCCESS )
1271 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001272 slot = *p_slot;
Darryl Green06fd18d2018-07-16 11:21:11 +01001273
1274 /* Enforce that usage policy for the key slot contains all the flags
1275 * required by the usage parameter. There is one exception: public
1276 * keys can always be exported, so we treat public key objects as
1277 * if they had the export flag. */
Gilles Peskine8e338702019-07-30 20:06:31 +02001278 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
Darryl Green06fd18d2018-07-16 11:21:11 +01001279 usage &= ~PSA_KEY_USAGE_EXPORT;
Ronald Cronf95a2b12020-10-22 15:24:49 +02001280
1281 status = PSA_ERROR_NOT_PERMITTED;
Gilles Peskine8e338702019-07-30 20:06:31 +02001282 if( ( slot->attr.policy.usage & usage ) != usage )
Ronald Cronf95a2b12020-10-22 15:24:49 +02001283 goto error;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001284
1285 /* Enforce that the usage policy permits the requested algortihm. */
Gilles Peskine8e338702019-07-30 20:06:31 +02001286 if( alg != 0 && ! psa_key_policy_permits( &slot->attr.policy, alg ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02001287 goto error;
Darryl Green06fd18d2018-07-16 11:21:11 +01001288
Darryl Green06fd18d2018-07-16 11:21:11 +01001289 return( PSA_SUCCESS );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001290
1291error:
1292 *p_slot = NULL;
Ronald Cron5c522922020-11-14 16:35:34 +01001293 psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001294
1295 return( status );
Darryl Green06fd18d2018-07-16 11:21:11 +01001296}
Darryl Green940d72c2018-07-13 13:18:51 +01001297
Ronald Cron5c522922020-11-14 16:35:34 +01001298/** Get a key slot containing a transparent key and lock it.
Gilles Peskine28f8f302019-07-24 13:30:31 +02001299 *
1300 * A transparent key is a key for which the key material is directly
1301 * available, as opposed to a key in a secure element.
1302 *
Ronald Cron5c522922020-11-14 16:35:34 +01001303 * This is a temporary function to use instead of
1304 * psa_get_and_lock_key_slot_with_policy() until secure element support is
1305 * fully implemented.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001306 *
Ronald Cron5c522922020-11-14 16:35:34 +01001307 * On success, the returned key slot is locked. It is the responsibility of the
1308 * caller to unlock the key slot when it does not access it anymore.
Gilles Peskine28f8f302019-07-24 13:30:31 +02001309 */
1310#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Ronald Cron5c522922020-11-14 16:35:34 +01001311static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
1312 mbedtls_svc_key_id_t key,
1313 psa_key_slot_t **p_slot,
1314 psa_key_usage_t usage,
1315 psa_algorithm_t alg )
Gilles Peskine28f8f302019-07-24 13:30:31 +02001316{
Ronald Cron5c522922020-11-14 16:35:34 +01001317 psa_status_t status = psa_get_and_lock_key_slot_with_policy( key, p_slot,
1318 usage, alg );
Gilles Peskine28f8f302019-07-24 13:30:31 +02001319 if( status != PSA_SUCCESS )
1320 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001321
Gilles Peskineadad8132019-07-25 11:31:23 +02001322 if( psa_key_slot_is_external( *p_slot ) )
Gilles Peskine28f8f302019-07-24 13:30:31 +02001323 {
Ronald Cron5c522922020-11-14 16:35:34 +01001324 psa_unlock_key_slot( *p_slot );
Gilles Peskine28f8f302019-07-24 13:30:31 +02001325 *p_slot = NULL;
1326 return( PSA_ERROR_NOT_SUPPORTED );
1327 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02001328
Gilles Peskine28f8f302019-07-24 13:30:31 +02001329 return( PSA_SUCCESS );
1330}
1331#else /* MBEDTLS_PSA_CRYPTO_SE_C */
1332/* With no secure element support, all keys are transparent. */
Ronald Cron5c522922020-11-14 16:35:34 +01001333#define psa_get_and_lock_transparent_key_slot_with_policy( key, p_slot, usage, alg ) \
1334 psa_get_and_lock_key_slot_with_policy( key, p_slot, usage, alg )
Gilles Peskine28f8f302019-07-24 13:30:31 +02001335#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1336
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001337/** Wipe key data from a slot. Preserve metadata such as the policy. */
Gilles Peskine2f060a82018-12-04 17:12:32 +01001338static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
Darryl Green40225ba2018-11-15 14:48:15 +00001339{
Gilles Peskine73167e12019-07-12 23:44:37 +02001340#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Fredrik Strupe462aa572020-12-17 10:44:38 +01001341 if( psa_get_se_driver( slot->attr.lifetime, NULL, NULL ) &&
1342 psa_key_slot_is_external( slot ) )
Darryl Green40225ba2018-11-15 14:48:15 +00001343 {
1344 /* No key material to clean. */
1345 }
Gilles Peskine73167e12019-07-12 23:44:37 +02001346 else
1347#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Darryl Green40225ba2018-11-15 14:48:15 +00001348 {
Steven Cooremanfd4d69a2020-08-05 15:46:33 +02001349 /* Data pointer will always be either a valid pointer or NULL in an
1350 * initialized slot, so we can just free it. */
1351 if( slot->data.key.data != NULL )
1352 mbedtls_platform_zeroize( slot->data.key.data, slot->data.key.bytes);
Steven Cooremana01795d2020-07-24 22:48:15 +02001353 mbedtls_free( slot->data.key.data );
1354 slot->data.key.data = NULL;
1355 slot->data.key.bytes = 0;
Darryl Green40225ba2018-11-15 14:48:15 +00001356 }
Darryl Green40225ba2018-11-15 14:48:15 +00001357
1358 return( PSA_SUCCESS );
1359}
1360
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001361/** Completely wipe a slot in memory, including its policy.
1362 * Persistent storage is not affected. */
Gilles Peskine66fb1262018-12-10 16:29:04 +01001363psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot )
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001364{
1365 psa_status_t status = psa_remove_key_data_from_memory( slot );
Ronald Cronddd3d052020-10-30 14:07:07 +01001366
1367 /*
1368 * As the return error code may not be handled in case of multiple errors,
Ronald Cron5c522922020-11-14 16:35:34 +01001369 * do our best to report an unexpected lock counter: if available
Ronald Cronddd3d052020-10-30 14:07:07 +01001370 * call MBEDTLS_PARAM_FAILED that may terminate execution (if called as
1371 * part of the execution of a test suite this will stop the test suite
Ronald Cron4640c152020-11-13 10:11:01 +01001372 * execution).
Ronald Cronddd3d052020-10-30 14:07:07 +01001373 */
Ronald Cron5c522922020-11-14 16:35:34 +01001374 if( slot->lock_count != 1 )
Ronald Cronddd3d052020-10-30 14:07:07 +01001375 {
1376#ifdef MBEDTLS_CHECK_PARAMS
Ronald Cron5c522922020-11-14 16:35:34 +01001377 MBEDTLS_PARAM_FAILED( slot->lock_count == 1 );
Ronald Cronddd3d052020-10-30 14:07:07 +01001378#endif
Ronald Cronddd3d052020-10-30 14:07:07 +01001379 status = PSA_ERROR_CORRUPTION_DETECTED;
1380 }
1381
Gilles Peskine3f7cd622019-08-13 15:01:08 +02001382 /* Multipart operations may still be using the key. This is safe
1383 * because all multipart operation objects are independent from
1384 * the key slot: if they need to access the key after the setup
1385 * phase, they have a copy of the key. Note that this means that
1386 * key material can linger until all operations are completed. */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001387 /* At this point, key material and other type-specific content has
1388 * been wiped. Clear remaining metadata. We can call memset and not
1389 * zeroize because the metadata is not particularly sensitive. */
1390 memset( slot, 0, sizeof( *slot ) );
1391 return( status );
1392}
1393
Ronald Croncf56a0a2020-08-04 09:51:30 +02001394psa_status_t psa_destroy_key( mbedtls_svc_key_id_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001395{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001396 psa_key_slot_t *slot;
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001397 psa_status_t status; /* status of the last operation */
1398 psa_status_t overall_status = PSA_SUCCESS;
Gilles Peskine354f7672019-07-12 23:46:38 +02001399#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1400 psa_se_drv_table_entry_t *driver;
1401#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001402
Ronald Croncf56a0a2020-08-04 09:51:30 +02001403 if( mbedtls_svc_key_id_is_null( key ) )
Gilles Peskine1841cf42019-10-08 15:48:25 +02001404 return( PSA_SUCCESS );
1405
Ronald Cronf2911112020-10-29 17:51:10 +01001406 /*
Ronald Cron19daca92020-11-10 18:08:03 +01001407 * Get the description of the key in a key slot. In case of a persistent
Ronald Cronf2911112020-10-29 17:51:10 +01001408 * key, this will load the key description from persistent memory if not
1409 * done yet. We cannot avoid this loading as without it we don't know if
1410 * the key is operated by an SE or not and this information is needed by
1411 * the current implementation.
1412 */
Ronald Cron5c522922020-11-14 16:35:34 +01001413 status = psa_get_and_lock_key_slot( key, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001414 if( status != PSA_SUCCESS )
1415 return( status );
Gilles Peskine354f7672019-07-12 23:46:38 +02001416
Ronald Cronf2911112020-10-29 17:51:10 +01001417 /*
1418 * If the key slot containing the key description is under access by the
1419 * library (apart from the present access), the key cannot be destroyed
1420 * yet. For the time being, just return in error. Eventually (to be
1421 * implemented), the key should be destroyed when all accesses have
1422 * stopped.
1423 */
Ronald Cron5c522922020-11-14 16:35:34 +01001424 if( slot->lock_count > 1 )
Ronald Cronf2911112020-10-29 17:51:10 +01001425 {
Ronald Cron5c522922020-11-14 16:35:34 +01001426 psa_unlock_key_slot( slot );
Ronald Cronf2911112020-10-29 17:51:10 +01001427 return( PSA_ERROR_GENERIC_ERROR );
1428 }
1429
Gilles Peskine354f7672019-07-12 23:46:38 +02001430#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001431 driver = psa_get_se_driver_entry( slot->attr.lifetime );
Gilles Peskine354f7672019-07-12 23:46:38 +02001432 if( driver != NULL )
Gilles Peskinefc762652019-07-22 19:30:34 +02001433 {
Gilles Peskine60450a42019-07-25 11:32:45 +02001434 /* For a key in a secure element, we need to do three things:
1435 * remove the key file in internal storage, destroy the
1436 * key inside the secure element, and update the driver's
1437 * persistent data. Start a transaction that will encompass these
1438 * three actions. */
Gilles Peskinefc762652019-07-22 19:30:34 +02001439 psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_DESTROY_KEY );
Gilles Peskine8e338702019-07-30 20:06:31 +02001440 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
Gilles Peskinefc762652019-07-22 19:30:34 +02001441 psa_crypto_transaction.key.slot = slot->data.se.slot_number;
Gilles Peskine8e338702019-07-30 20:06:31 +02001442 psa_crypto_transaction.key.id = slot->attr.id;
Gilles Peskinefc762652019-07-22 19:30:34 +02001443 status = psa_crypto_save_transaction( );
1444 if( status != PSA_SUCCESS )
1445 {
Gilles Peskine66be51c2019-07-25 18:02:52 +02001446 (void) psa_crypto_stop_transaction( );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001447 /* We should still try to destroy the key in the secure
1448 * element and the key metadata in storage. This is especially
1449 * important if the error is that the storage is full.
1450 * But how to do it exactly without risking an inconsistent
1451 * state after a reset?
1452 * https://github.com/ARMmbed/mbed-crypto/issues/215
1453 */
1454 overall_status = status;
1455 goto exit;
Gilles Peskinefc762652019-07-22 19:30:34 +02001456 }
1457
Gilles Peskine354f7672019-07-12 23:46:38 +02001458 status = psa_destroy_se_key( driver, slot->data.se.slot_number );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001459 if( overall_status == PSA_SUCCESS )
1460 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001461 }
Gilles Peskine354f7672019-07-12 23:46:38 +02001462#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1463
Darryl Greend49a4992018-06-18 17:27:26 +01001464#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Ronald Crond98059d2020-10-23 18:00:55 +02001465 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
Darryl Greend49a4992018-06-18 17:27:26 +01001466 {
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001467 status = psa_destroy_persistent_key( slot->attr.id );
1468 if( overall_status == PSA_SUCCESS )
1469 overall_status = status;
1470
Gilles Peskine9ce31c42019-08-13 15:14:20 +02001471 /* TODO: other slots may have a copy of the same key. We should
1472 * invalidate them.
1473 * https://github.com/ARMmbed/mbed-crypto/issues/214
1474 */
Darryl Greend49a4992018-06-18 17:27:26 +01001475 }
1476#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskine354f7672019-07-12 23:46:38 +02001477
Gilles Peskinefc762652019-07-22 19:30:34 +02001478#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1479 if( driver != NULL )
1480 {
Gilles Peskine725f22a2019-07-25 11:31:48 +02001481 status = psa_save_se_persistent_data( driver );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001482 if( overall_status == PSA_SUCCESS )
1483 overall_status = status;
1484 status = psa_crypto_stop_transaction( );
1485 if( overall_status == PSA_SUCCESS )
1486 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001487 }
1488#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1489
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001490#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1491exit:
1492#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001493 status = psa_wipe_key_slot( slot );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001494 /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
1495 if( overall_status == PSA_SUCCESS )
1496 overall_status = status;
1497 return( overall_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001498}
1499
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001500void psa_reset_key_attributes( psa_key_attributes_t *attributes )
Gilles Peskineb870b182018-07-06 16:02:09 +02001501{
Gilles Peskineb699f072019-04-26 16:06:02 +02001502 mbedtls_free( attributes->domain_parameters );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001503 memset( attributes, 0, sizeof( *attributes ) );
Gilles Peskineb870b182018-07-06 16:02:09 +02001504}
1505
Gilles Peskineb699f072019-04-26 16:06:02 +02001506psa_status_t psa_set_key_domain_parameters( psa_key_attributes_t *attributes,
1507 psa_key_type_t type,
1508 const uint8_t *data,
1509 size_t data_length )
1510{
1511 uint8_t *copy = NULL;
1512
1513 if( data_length != 0 )
1514 {
1515 copy = mbedtls_calloc( 1, data_length );
1516 if( copy == NULL )
1517 return( PSA_ERROR_INSUFFICIENT_MEMORY );
1518 memcpy( copy, data, data_length );
1519 }
1520 /* After this point, this function is guaranteed to succeed, so it
1521 * can start modifying `*attributes`. */
1522
1523 if( attributes->domain_parameters != NULL )
1524 {
1525 mbedtls_free( attributes->domain_parameters );
1526 attributes->domain_parameters = NULL;
1527 attributes->domain_parameters_size = 0;
1528 }
1529
1530 attributes->domain_parameters = copy;
1531 attributes->domain_parameters_size = data_length;
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001532 attributes->core.type = type;
Gilles Peskineb699f072019-04-26 16:06:02 +02001533 return( PSA_SUCCESS );
1534}
1535
1536psa_status_t psa_get_key_domain_parameters(
1537 const psa_key_attributes_t *attributes,
1538 uint8_t *data, size_t data_size, size_t *data_length )
1539{
1540 if( attributes->domain_parameters_size > data_size )
1541 return( PSA_ERROR_BUFFER_TOO_SMALL );
1542 *data_length = attributes->domain_parameters_size;
1543 if( attributes->domain_parameters_size != 0 )
1544 memcpy( data, attributes->domain_parameters,
1545 attributes->domain_parameters_size );
1546 return( PSA_SUCCESS );
1547}
1548
John Durkop07cc04a2020-11-16 22:08:34 -08001549#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
John Durkop0e005192020-10-31 22:06:54 -07001550 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskineb699f072019-04-26 16:06:02 +02001551static psa_status_t psa_get_rsa_public_exponent(
1552 const mbedtls_rsa_context *rsa,
1553 psa_key_attributes_t *attributes )
1554{
1555 mbedtls_mpi mpi;
Janos Follath24eed8d2019-11-22 13:21:35 +00001556 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb699f072019-04-26 16:06:02 +02001557 uint8_t *buffer = NULL;
1558 size_t buflen;
1559 mbedtls_mpi_init( &mpi );
1560
1561 ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &mpi );
1562 if( ret != 0 )
1563 goto exit;
Gilles Peskine772c8b12019-04-26 17:37:21 +02001564 if( mbedtls_mpi_cmp_int( &mpi, 65537 ) == 0 )
1565 {
1566 /* It's the default value, which is reported as an empty string,
1567 * so there's nothing to do. */
1568 goto exit;
1569 }
Gilles Peskineb699f072019-04-26 16:06:02 +02001570
1571 buflen = mbedtls_mpi_size( &mpi );
1572 buffer = mbedtls_calloc( 1, buflen );
1573 if( buffer == NULL )
1574 {
1575 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
1576 goto exit;
1577 }
1578 ret = mbedtls_mpi_write_binary( &mpi, buffer, buflen );
1579 if( ret != 0 )
1580 goto exit;
1581 attributes->domain_parameters = buffer;
1582 attributes->domain_parameters_size = buflen;
1583
1584exit:
1585 mbedtls_mpi_free( &mpi );
1586 if( ret != 0 )
1587 mbedtls_free( buffer );
1588 return( mbedtls_to_psa_error( ret ) );
1589}
John Durkop07cc04a2020-11-16 22:08:34 -08001590#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
John Durkop9814fa22020-11-04 12:28:15 -08001591 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineb699f072019-04-26 16:06:02 +02001592
Gilles Peskinebfd322f2019-07-23 11:58:03 +02001593/** Retrieve all the publicly-accessible attributes of a key.
1594 */
Ronald Croncf56a0a2020-08-04 09:51:30 +02001595psa_status_t psa_get_key_attributes( mbedtls_svc_key_id_t key,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001596 psa_key_attributes_t *attributes )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001597{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001598 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001599 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001600 psa_key_slot_t *slot;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001601
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001602 psa_reset_key_attributes( attributes );
1603
Ronald Cron5c522922020-11-14 16:35:34 +01001604 status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001605 if( status != PSA_SUCCESS )
1606 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +02001607
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001608 attributes->core = slot->attr;
Gilles Peskinec8000c02019-08-02 20:15:51 +02001609 attributes->core.flags &= ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1610 MBEDTLS_PSA_KA_MASK_DUAL_USE );
1611
1612#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1613 if( psa_key_slot_is_external( slot ) )
1614 psa_set_key_slot_number( attributes, slot->data.se.slot_number );
1615#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineb699f072019-04-26 16:06:02 +02001616
Gilles Peskine8e338702019-07-30 20:06:31 +02001617 switch( slot->attr.type )
Gilles Peskineb699f072019-04-26 16:06:02 +02001618 {
John Durkop07cc04a2020-11-16 22:08:34 -08001619#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
John Durkop0e005192020-10-31 22:06:54 -07001620 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001621 case PSA_KEY_TYPE_RSA_KEY_PAIR:
Gilles Peskineb699f072019-04-26 16:06:02 +02001622 case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001623#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01001624 /* TODO: reporting the public exponent for opaque keys
Gilles Peskinec9d7f942019-08-13 16:17:16 +02001625 * is not yet implemented.
1626 * https://github.com/ARMmbed/mbed-crypto/issues/216
1627 */
Gilles Peskinec8000c02019-08-02 20:15:51 +02001628 if( psa_key_slot_is_external( slot ) )
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001629 break;
1630#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Steven Cooremana01795d2020-07-24 22:48:15 +02001631 {
Steven Cooremana2371e52020-07-28 14:30:39 +02001632 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02001633
Steven Cooreman4fed4552020-08-03 14:46:03 +02001634 status = psa_load_rsa_representation( slot->attr.type,
1635 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02001636 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02001637 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001638 if( status != PSA_SUCCESS )
1639 break;
1640
Steven Cooremana2371e52020-07-28 14:30:39 +02001641 status = psa_get_rsa_public_exponent( rsa,
Steven Cooremana01795d2020-07-24 22:48:15 +02001642 attributes );
Steven Cooremana2371e52020-07-28 14:30:39 +02001643 mbedtls_rsa_free( rsa );
1644 mbedtls_free( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001645 }
Gilles Peskineb699f072019-04-26 16:06:02 +02001646 break;
John Durkop07cc04a2020-11-16 22:08:34 -08001647#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
John Durkop9814fa22020-11-04 12:28:15 -08001648 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineb699f072019-04-26 16:06:02 +02001649 default:
1650 /* Nothing else to do. */
1651 break;
1652 }
1653
1654 if( status != PSA_SUCCESS )
1655 psa_reset_key_attributes( attributes );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001656
Ronald Cron5c522922020-11-14 16:35:34 +01001657 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001658
Ronald Cron5c522922020-11-14 16:35:34 +01001659 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001660}
1661
Gilles Peskinec8000c02019-08-02 20:15:51 +02001662#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1663psa_status_t psa_get_key_slot_number(
1664 const psa_key_attributes_t *attributes,
1665 psa_key_slot_number_t *slot_number )
1666{
1667 if( attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER )
1668 {
1669 *slot_number = attributes->slot_number;
1670 return( PSA_SUCCESS );
1671 }
1672 else
1673 return( PSA_ERROR_INVALID_ARGUMENT );
1674}
1675#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1676
Steven Cooremana01795d2020-07-24 22:48:15 +02001677static psa_status_t psa_internal_export_key_buffer( const psa_key_slot_t *slot,
1678 uint8_t *data,
1679 size_t data_size,
1680 size_t *data_length )
1681{
1682 if( slot->data.key.bytes > data_size )
1683 return( PSA_ERROR_BUFFER_TOO_SMALL );
1684 memcpy( data, slot->data.key.data, slot->data.key.bytes );
1685 memset( data + slot->data.key.bytes, 0,
1686 data_size - slot->data.key.bytes );
1687 *data_length = slot->data.key.bytes;
1688 return( PSA_SUCCESS );
1689}
1690
Gilles Peskinef603c712019-01-19 13:40:11 +01001691static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot,
1692 uint8_t *data,
1693 size_t data_size,
1694 size_t *data_length,
1695 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001696{
Gilles Peskine5d309672019-07-12 23:47:28 +02001697#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1698 const psa_drv_se_t *drv;
1699 psa_drv_se_context_t *drv_context;
1700#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1701
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001702 *data_length = 0;
1703
Gilles Peskine8e338702019-07-30 20:06:31 +02001704 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001705 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +03001706
Gilles Peskinef9168942019-09-12 19:20:29 +02001707 /* Reject a zero-length output buffer now, since this can never be a
1708 * valid key representation. This way we know that data must be a valid
1709 * pointer and we can do things like memset(data, ..., data_size). */
1710 if( data_size == 0 )
1711 return( PSA_ERROR_BUFFER_TOO_SMALL );
1712
Gilles Peskine5d309672019-07-12 23:47:28 +02001713#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001714 if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
Gilles Peskine5d309672019-07-12 23:47:28 +02001715 {
1716 psa_drv_se_export_key_t method;
1717 if( drv->key_management == NULL )
1718 return( PSA_ERROR_NOT_SUPPORTED );
1719 method = ( export_public_key ?
1720 drv->key_management->p_export_public :
1721 drv->key_management->p_export );
1722 if( method == NULL )
1723 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine2e0f3882019-07-25 11:34:33 +02001724 return( method( drv_context,
1725 slot->data.se.slot_number,
1726 data, data_size, data_length ) );
Gilles Peskine5d309672019-07-12 23:47:28 +02001727 }
1728#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1729
Gilles Peskine8e338702019-07-30 20:06:31 +02001730 if( key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001731 {
Steven Cooremanacda8342020-07-24 23:09:52 +02001732 return( psa_internal_export_key_buffer( slot, data, data_size, data_length ) );
Gilles Peskine188c71e2018-10-29 19:26:02 +01001733 }
Steven Cooreman560c28a2020-07-24 23:20:24 +02001734 else if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ||
1735 PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
Moran Peker17e36e12018-05-02 12:55:20 +03001736 {
Steven Cooreman560c28a2020-07-24 23:20:24 +02001737 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +01001738 {
Steven Cooreman560c28a2020-07-24 23:20:24 +02001739 /* Exporting public -> public */
1740 return( psa_internal_export_key_buffer( slot, data, data_size, data_length ) );
1741 }
1742 else if( !export_public_key )
1743 {
1744 /* Exporting private -> private */
1745 return( psa_internal_export_key_buffer( slot, data, data_size, data_length ) );
1746 }
Steven Cooremanb9b84422020-10-14 14:39:20 +02001747
Steven Cooreman560c28a2020-07-24 23:20:24 +02001748 /* Need to export the public part of a private key,
Steven Cooremanb9b84422020-10-14 14:39:20 +02001749 * so conversion is needed. Try the accelerators first. */
1750 psa_status_t status = psa_driver_wrapper_export_public_key( slot,
1751 data,
1752 data_size,
1753 data_length );
1754
1755 if( status != PSA_ERROR_NOT_SUPPORTED ||
1756 psa_key_lifetime_is_external( slot->attr.lifetime ) )
1757 return( status );
1758
Steven Cooreman560c28a2020-07-24 23:20:24 +02001759 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
1760 {
John Durkop0e005192020-10-31 22:06:54 -07001761#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1762 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Steven Cooremana2371e52020-07-28 14:30:39 +02001763 mbedtls_rsa_context *rsa = NULL;
Steven Cooremanb9b84422020-10-14 14:39:20 +02001764 status = psa_load_rsa_representation(
Steven Cooreman4fed4552020-08-03 14:46:03 +02001765 slot->attr.type,
Steven Cooreman7f391872020-07-30 14:57:44 +02001766 slot->data.key.data,
1767 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02001768 &rsa );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001769 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02001770 return( status );
Steven Cooremana01795d2020-07-24 22:48:15 +02001771
Steven Cooreman560c28a2020-07-24 23:20:24 +02001772 status = psa_export_rsa_key( PSA_KEY_TYPE_RSA_PUBLIC_KEY,
Steven Cooremana2371e52020-07-28 14:30:39 +02001773 rsa,
Steven Cooreman560c28a2020-07-24 23:20:24 +02001774 data,
1775 data_size,
1776 data_length );
Steven Cooremana01795d2020-07-24 22:48:15 +02001777
Steven Cooremana2371e52020-07-28 14:30:39 +02001778 mbedtls_rsa_free( rsa );
1779 mbedtls_free( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001780
Steven Cooreman560c28a2020-07-24 23:20:24 +02001781 return( status );
Darryl Green9e2d7a02018-07-24 16:33:30 +01001782#else
Steven Cooreman560c28a2020-07-24 23:20:24 +02001783 /* We don't know how to convert a private RSA key to public. */
1784 return( PSA_ERROR_NOT_SUPPORTED );
John Durkop9814fa22020-11-04 12:28:15 -08001785#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1786 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskine969ac722018-01-28 18:16:59 +01001787 }
1788 else
Moran Pekera998bc62018-04-16 18:16:20 +03001789 {
John Durkop6ba40d12020-11-10 08:50:04 -08001790#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
1791 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Steven Cooremana2371e52020-07-28 14:30:39 +02001792 mbedtls_ecp_keypair *ecp = NULL;
Steven Cooremanb9b84422020-10-14 14:39:20 +02001793 status = psa_load_ecp_representation(
Steven Cooreman4fed4552020-08-03 14:46:03 +02001794 slot->attr.type,
Steven Cooreman7f391872020-07-30 14:57:44 +02001795 slot->data.key.data,
1796 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02001797 &ecp );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001798 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02001799 return( status );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001800
1801 status = psa_export_ecp_key( PSA_KEY_TYPE_ECC_PUBLIC_KEY(
1802 PSA_KEY_TYPE_ECC_GET_FAMILY(
1803 slot->attr.type ) ),
Steven Cooremana2371e52020-07-28 14:30:39 +02001804 ecp,
Steven Cooreman560c28a2020-07-24 23:20:24 +02001805 data,
1806 data_size,
1807 data_length );
1808
Steven Cooremana2371e52020-07-28 14:30:39 +02001809 mbedtls_ecp_keypair_free( ecp );
1810 mbedtls_free( ecp );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001811 return( status );
1812#else
1813 /* We don't know how to convert a private ECC key to public */
Moran Pekera998bc62018-04-16 18:16:20 +03001814 return( PSA_ERROR_NOT_SUPPORTED );
John Durkop9814fa22020-11-04 12:28:15 -08001815#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
1816 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
Moran Pekera998bc62018-04-16 18:16:20 +03001817 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001818 }
Steven Cooreman560c28a2020-07-24 23:20:24 +02001819 else
1820 {
1821 /* This shouldn't happen in the reference implementation, but
1822 it is valid for a special-purpose implementation to omit
1823 support for exporting certain key types. */
1824 return( PSA_ERROR_NOT_SUPPORTED );
1825 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001826}
1827
Ronald Croncf56a0a2020-08-04 09:51:30 +02001828psa_status_t psa_export_key( mbedtls_svc_key_id_t key,
Gilles Peskine2d277862018-06-18 15:41:12 +02001829 uint8_t *data,
1830 size_t data_size,
1831 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001832{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001833 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001834 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001835 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001836
1837 /* Set the key to empty now, so that even when there are errors, we always
1838 * set data_length to a value between 0 and data_size. On error, setting
1839 * the key to empty is a good choice because an empty key representation is
1840 * unlikely to be accepted anywhere. */
1841 *data_length = 0;
1842
1843 /* Export requires the EXPORT flag. There is an exception for public keys,
Ronald Cron5c522922020-11-14 16:35:34 +01001844 * which don't require any flag, but
1845 * psa_get_and_lock_key_slot_with_policy() takes care of this.
1846 */
1847 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
1848 PSA_KEY_USAGE_EXPORT, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001849 if( status != PSA_SUCCESS )
1850 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001851
1852 status = psa_internal_export_key( slot, data, data_size, data_length, 0 );
Ronald Cron5c522922020-11-14 16:35:34 +01001853 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001854
Ronald Cron5c522922020-11-14 16:35:34 +01001855 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001856}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001857
Ronald Croncf56a0a2020-08-04 09:51:30 +02001858psa_status_t psa_export_public_key( mbedtls_svc_key_id_t key,
Gilles Peskine2d277862018-06-18 15:41:12 +02001859 uint8_t *data,
1860 size_t data_size,
1861 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001862{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001863 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001864 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001865 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001866
1867 /* Set the key to empty now, so that even when there are errors, we always
1868 * set data_length to a value between 0 and data_size. On error, setting
1869 * the key to empty is a good choice because an empty key representation is
1870 * unlikely to be accepted anywhere. */
1871 *data_length = 0;
1872
1873 /* Exporting a public key doesn't require a usage flag. */
Ronald Cron5c522922020-11-14 16:35:34 +01001874 status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001875 if( status != PSA_SUCCESS )
1876 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001877
1878 status = psa_internal_export_key( slot, data, data_size, data_length, 1 );
Ronald Cron5c522922020-11-14 16:35:34 +01001879 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001880
Ronald Cron5c522922020-11-14 16:35:34 +01001881 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001882}
1883
Gilles Peskine91e8c332019-08-02 19:19:39 +02001884#if defined(static_assert)
1885static_assert( ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
1886 "One or more key attribute flag is listed as both external-only and dual-use" );
Gilles Peskine5a680562019-08-05 17:32:13 +02001887static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
Gilles Peskine094dac12019-08-07 18:19:46 +02001888 "One or more key attribute flag is listed as both internal-only and dual-use" );
Gilles Peskine5a680562019-08-05 17:32:13 +02001889static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ) == 0,
Gilles Peskine91e8c332019-08-02 19:19:39 +02001890 "One or more key attribute flag is listed as both internal-only and external-only" );
1891#endif
1892
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001893/** Validate that a key policy is internally well-formed.
1894 *
1895 * This function only rejects invalid policies. It does not validate the
1896 * consistency of the policy with respect to other attributes of the key
1897 * such as the key type.
1898 */
1899static psa_status_t psa_validate_key_policy( const psa_key_policy_t *policy )
Gilles Peskine4747d192019-04-17 15:05:45 +02001900{
1901 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
Gilles Peskine8e0206a2019-05-14 14:24:28 +02001902 PSA_KEY_USAGE_COPY |
Gilles Peskine4747d192019-04-17 15:05:45 +02001903 PSA_KEY_USAGE_ENCRYPT |
1904 PSA_KEY_USAGE_DECRYPT |
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01001905 PSA_KEY_USAGE_SIGN_HASH |
1906 PSA_KEY_USAGE_VERIFY_HASH |
Gilles Peskine4747d192019-04-17 15:05:45 +02001907 PSA_KEY_USAGE_DERIVE ) ) != 0 )
1908 return( PSA_ERROR_INVALID_ARGUMENT );
1909
Gilles Peskine4747d192019-04-17 15:05:45 +02001910 return( PSA_SUCCESS );
1911}
1912
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001913/** Validate the internal consistency of key attributes.
1914 *
1915 * This function only rejects invalid attribute values. If does not
1916 * validate the consistency of the attributes with any key data that may
1917 * be involved in the creation of the key.
1918 *
1919 * Call this function early in the key creation process.
1920 *
1921 * \param[in] attributes Key attributes for the new key.
1922 * \param[out] p_drv On any return, the driver for the key, if any.
1923 * NULL for a transparent key.
1924 *
1925 */
1926static psa_status_t psa_validate_key_attributes(
1927 const psa_key_attributes_t *attributes,
1928 psa_se_drv_table_entry_t **p_drv )
Darryl Green0c6575a2018-11-07 16:05:30 +00001929{
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001930 psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
Ronald Crond2ed4812020-07-17 16:11:30 +02001931 psa_key_lifetime_t lifetime = psa_get_key_lifetime( attributes );
Ronald Cron65f38a32020-10-23 17:11:13 +02001932 mbedtls_svc_key_id_t key = psa_get_key_id( attributes );
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001933
Ronald Cron54b90082020-10-29 15:26:43 +01001934 status = psa_validate_key_location( lifetime, p_drv );
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001935 if( status != PSA_SUCCESS )
1936 return( status );
1937
Ronald Crond2ed4812020-07-17 16:11:30 +02001938 status = psa_validate_key_persistence( lifetime );
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001939 if( status != PSA_SUCCESS )
1940 return( status );
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001941
Ronald Cron65f38a32020-10-23 17:11:13 +02001942 if ( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) )
1943 {
1944 if( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key ) != 0 )
1945 return( PSA_ERROR_INVALID_ARGUMENT );
1946 }
1947 else
Ronald Crond2ed4812020-07-17 16:11:30 +02001948 {
Ronald Croncbd7bea2020-11-11 14:57:44 +01001949 status = psa_validate_key_id( psa_get_key_id( attributes ), 0 );
Ronald Crond2ed4812020-07-17 16:11:30 +02001950 if( status != PSA_SUCCESS )
1951 return( status );
1952 }
1953
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001954 status = psa_validate_key_policy( &attributes->core.policy );
Darryl Green0c6575a2018-11-07 16:05:30 +00001955 if( status != PSA_SUCCESS )
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001956 return( status );
1957
1958 /* Refuse to create overly large keys.
1959 * Note that this doesn't trigger on import if the attributes don't
1960 * explicitly specify a size (so psa_get_key_bits returns 0), so
1961 * psa_import_key() needs its own checks. */
1962 if( psa_get_key_bits( attributes ) > PSA_MAX_KEY_BITS )
1963 return( PSA_ERROR_NOT_SUPPORTED );
1964
Gilles Peskine91e8c332019-08-02 19:19:39 +02001965 /* Reject invalid flags. These should not be reachable through the API. */
1966 if( attributes->core.flags & ~ ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1967 MBEDTLS_PSA_KA_MASK_DUAL_USE ) )
1968 return( PSA_ERROR_INVALID_ARGUMENT );
1969
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001970 return( PSA_SUCCESS );
1971}
1972
Gilles Peskine4747d192019-04-17 15:05:45 +02001973/** Prepare a key slot to receive key material.
1974 *
1975 * This function allocates a key slot and sets its metadata.
1976 *
1977 * If this function fails, call psa_fail_key_creation().
1978 *
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001979 * This function is intended to be used as follows:
1980 * -# Call psa_start_key_creation() to allocate a key slot, prepare
Ronald Croncf56a0a2020-08-04 09:51:30 +02001981 * it with the specified attributes, and in case of a volatile key assign it
1982 * a volatile key identifier.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001983 * -# Populate the slot with the key material.
1984 * -# Call psa_finish_key_creation() to finalize the creation of the slot.
1985 * In case of failure at any step, stop the sequence and call
1986 * psa_fail_key_creation().
1987 *
Ronald Cron5c522922020-11-14 16:35:34 +01001988 * On success, the key slot is locked. It is the responsibility of the caller
1989 * to unlock the key slot when it does not access it anymore.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001990 *
Gilles Peskinedf179142019-07-15 22:02:14 +02001991 * \param method An identification of the calling function.
Gilles Peskine011e4282019-06-26 18:34:38 +02001992 * \param[in] attributes Key attributes for the new key.
Gilles Peskine011e4282019-06-26 18:34:38 +02001993 * \param[out] p_slot On success, a pointer to the prepared slot.
1994 * \param[out] p_drv On any return, the driver for the key, if any.
1995 * NULL for a transparent key.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001996 *
1997 * \retval #PSA_SUCCESS
1998 * The key slot is ready to receive key material.
1999 * \return If this function fails, the key slot is an invalid state.
2000 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02002001 */
2002static psa_status_t psa_start_key_creation(
Gilles Peskinedf179142019-07-15 22:02:14 +02002003 psa_key_creation_method_t method,
Gilles Peskine4747d192019-04-17 15:05:45 +02002004 const psa_key_attributes_t *attributes,
Gilles Peskine011e4282019-06-26 18:34:38 +02002005 psa_key_slot_t **p_slot,
Gilles Peskine8abe6a22019-07-12 23:40:35 +02002006 psa_se_drv_table_entry_t **p_drv )
Gilles Peskine4747d192019-04-17 15:05:45 +02002007{
2008 psa_status_t status;
Ronald Cron2a993152020-07-17 14:13:26 +02002009 psa_key_id_t volatile_key_id;
Gilles Peskine4747d192019-04-17 15:05:45 +02002010 psa_key_slot_t *slot;
2011
Gilles Peskinedf179142019-07-15 22:02:14 +02002012 (void) method;
Gilles Peskine011e4282019-06-26 18:34:38 +02002013 *p_drv = NULL;
2014
Gilles Peskine1b8594a2019-07-31 17:21:46 +02002015 status = psa_validate_key_attributes( attributes, p_drv );
2016 if( status != PSA_SUCCESS )
2017 return( status );
2018
Ronald Cronc4d1b512020-07-31 11:26:37 +02002019 status = psa_get_empty_key_slot( &volatile_key_id, p_slot );
Gilles Peskine4747d192019-04-17 15:05:45 +02002020 if( status != PSA_SUCCESS )
2021 return( status );
2022 slot = *p_slot;
2023
Gilles Peskine76aa09c2019-07-31 14:15:34 +02002024 /* We're storing the declared bit-size of the key. It's up to each
2025 * creation mechanism to verify that this information is correct.
2026 * It's automatically correct for mechanisms that use the bit-size as
Gilles Peskineb46bef22019-07-30 21:32:04 +02002027 * an input (generate, device) but not for those where the bit-size
Ronald Cronc4d1b512020-07-31 11:26:37 +02002028 * is optional (import, copy). In case of a volatile key, assign it the
2029 * volatile key identifier associated to the slot returned to contain its
2030 * definition. */
Gilles Peskine76aa09c2019-07-31 14:15:34 +02002031
2032 slot->attr = attributes->core;
Ronald Cronc4d1b512020-07-31 11:26:37 +02002033 if( PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
2034 {
2035#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
2036 slot->attr.id = volatile_key_id;
2037#else
2038 slot->attr.id.key_id = volatile_key_id;
2039#endif
2040 }
Gilles Peskinec744d992019-07-30 17:26:54 +02002041
Gilles Peskine91e8c332019-08-02 19:19:39 +02002042 /* Erase external-only flags from the internal copy. To access
Gilles Peskine013f5472019-08-07 15:42:14 +02002043 * external-only flags, query `attributes`. Thanks to the check
2044 * in psa_validate_key_attributes(), this leaves the dual-use
Gilles Peskineedbed562019-08-07 18:19:59 +02002045 * flags and any internal flag that psa_get_empty_key_slot()
Gilles Peskine013f5472019-08-07 15:42:14 +02002046 * may have set. */
2047 slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
Gilles Peskine91e8c332019-08-02 19:19:39 +02002048
Gilles Peskinecbaff462019-07-12 23:46:04 +02002049#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02002050 /* For a key in a secure element, we need to do three things
Steven Cooremanbbeaf182020-06-08 18:29:44 +02002051 * when creating or registering a persistent key:
Gilles Peskine60450a42019-07-25 11:32:45 +02002052 * create the key file in internal storage, create the
2053 * key inside the secure element, and update the driver's
Steven Cooremanbbeaf182020-06-08 18:29:44 +02002054 * persistent data. This is done by starting a transaction that will
2055 * encompass these three actions.
2056 * For registering a volatile key, we just need to find an appropriate
2057 * slot number inside the SE. Since the key is designated volatile, creating
2058 * a transaction is not required. */
Gilles Peskine60450a42019-07-25 11:32:45 +02002059 /* The first thing to do is to find a slot number for the new key.
2060 * We save the slot number in persistent storage as part of the
2061 * transaction data. It will be needed to recover if the power
2062 * fails during the key creation process, to clean up on the secure
2063 * element side after restarting. Obtaining a slot number from the
2064 * secure element driver updates its persistent state, but we do not yet
2065 * save the driver's persistent state, so that if the power fails,
Gilles Peskinefc762652019-07-22 19:30:34 +02002066 * we can roll back to a state where the key doesn't exist. */
Gilles Peskine3efcebb2019-10-01 14:18:35 +02002067 if( *p_drv != NULL )
Darryl Green0c6575a2018-11-07 16:05:30 +00002068 {
Gilles Peskinee88c2c12019-08-05 16:44:14 +02002069 status = psa_find_se_slot_for_key( attributes, method, *p_drv,
Gilles Peskinecbaff462019-07-12 23:46:04 +02002070 &slot->data.se.slot_number );
2071 if( status != PSA_SUCCESS )
2072 return( status );
Steven Cooremanbbeaf182020-06-08 18:29:44 +02002073
2074 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( attributes->core.lifetime ) )
Gilles Peskine66be51c2019-07-25 18:02:52 +02002075 {
Steven Cooremanbbeaf182020-06-08 18:29:44 +02002076 psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_CREATE_KEY );
2077 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
2078 psa_crypto_transaction.key.slot = slot->data.se.slot_number;
2079 psa_crypto_transaction.key.id = slot->attr.id;
2080 status = psa_crypto_save_transaction( );
2081 if( status != PSA_SUCCESS )
2082 {
2083 (void) psa_crypto_stop_transaction( );
2084 return( status );
2085 }
Gilles Peskine66be51c2019-07-25 18:02:52 +02002086 }
Darryl Green0c6575a2018-11-07 16:05:30 +00002087 }
Gilles Peskine3efcebb2019-10-01 14:18:35 +02002088
2089 if( *p_drv == NULL && method == PSA_KEY_CREATION_REGISTER )
2090 {
2091 /* Key registration only makes sense with a secure element. */
2092 return( PSA_ERROR_INVALID_ARGUMENT );
2093 }
Gilles Peskinecbaff462019-07-12 23:46:04 +02002094#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2095
Ronald Cronc4d1b512020-07-31 11:26:37 +02002096 return( PSA_SUCCESS );
Darryl Green0c6575a2018-11-07 16:05:30 +00002097}
Gilles Peskine4747d192019-04-17 15:05:45 +02002098
2099/** Finalize the creation of a key once its key material has been set.
2100 *
2101 * This entails writing the key to persistent storage.
2102 *
2103 * If this function fails, call psa_fail_key_creation().
Gilles Peskine9bc88c62019-04-28 11:37:03 +02002104 * See the documentation of psa_start_key_creation() for the intended use
2105 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02002106 *
Ronald Cron5c522922020-11-14 16:35:34 +01002107 * If the finalization succeeds, the function unlocks the key slot (it was
2108 * locked by psa_start_key_creation()) and the key slot cannot be accessed
2109 * anymore as part of the key creation process.
Ronald Cron50972942020-11-14 11:28:25 +01002110 *
Gilles Peskine011e4282019-06-26 18:34:38 +02002111 * \param[in,out] slot Pointer to the slot with key material.
2112 * \param[in] driver The secure element driver for the key,
2113 * or NULL for a transparent key.
Ronald Cron81709fc2020-11-14 12:10:32 +01002114 * \param[out] key On success, identifier of the key. Note that the
2115 * key identifier is also stored in the key slot.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02002116 *
2117 * \retval #PSA_SUCCESS
Ronald Croncf56a0a2020-08-04 09:51:30 +02002118 * The key was successfully created.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02002119 * \return If this function fails, the key slot is an invalid state.
2120 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02002121 */
Gilles Peskine011e4282019-06-26 18:34:38 +02002122static psa_status_t psa_finish_key_creation(
2123 psa_key_slot_t *slot,
Ronald Cron81709fc2020-11-14 12:10:32 +01002124 psa_se_drv_table_entry_t *driver,
2125 mbedtls_svc_key_id_t *key)
Gilles Peskine4747d192019-04-17 15:05:45 +02002126{
2127 psa_status_t status = PSA_SUCCESS;
Gilles Peskine30afafd2019-04-25 13:47:40 +02002128 (void) slot;
Gilles Peskine011e4282019-06-26 18:34:38 +02002129 (void) driver;
Gilles Peskine4747d192019-04-17 15:05:45 +02002130
2131#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Steven Cooremanc59de6a2020-06-08 18:28:25 +02002132 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
Gilles Peskine4747d192019-04-17 15:05:45 +02002133 {
Gilles Peskine1df83d42019-07-23 16:13:14 +02002134#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2135 if( driver != NULL )
2136 {
Gilles Peskineb46bef22019-07-30 21:32:04 +02002137 psa_se_key_data_storage_t data;
2138#if defined(static_assert)
2139 static_assert( sizeof( slot->data.se.slot_number ) ==
2140 sizeof( data.slot_number ),
2141 "Slot number size does not match psa_se_key_data_storage_t" );
Gilles Peskineb46bef22019-07-30 21:32:04 +02002142#endif
2143 memcpy( &data.slot_number, &slot->data.se.slot_number,
2144 sizeof( slot->data.se.slot_number ) );
Gilles Peskine76aa09c2019-07-31 14:15:34 +02002145 status = psa_save_persistent_key( &slot->attr,
Gilles Peskineb46bef22019-07-30 21:32:04 +02002146 (uint8_t*) &data,
2147 sizeof( data ) );
Gilles Peskine1df83d42019-07-23 16:13:14 +02002148 }
2149 else
2150#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2151 {
Steven Cooreman40120f62020-10-29 11:42:22 +01002152 /* Key material is saved in export representation in the slot, so
2153 * just pass the slot buffer for storage. */
2154 status = psa_save_persistent_key( &slot->attr,
2155 slot->data.key.data,
2156 slot->data.key.bytes );
Gilles Peskine1df83d42019-07-23 16:13:14 +02002157 }
Gilles Peskine4747d192019-04-17 15:05:45 +02002158 }
Darryl Green0c6575a2018-11-07 16:05:30 +00002159#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
2160
Gilles Peskinecbaff462019-07-12 23:46:04 +02002161#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02002162 /* Finish the transaction for a key creation. This does not
2163 * happen when registering an existing key. Detect this case
2164 * by checking whether a transaction is in progress (actual
Steven Cooremanbbeaf182020-06-08 18:29:44 +02002165 * creation of a persistent key in a secure element requires a transaction,
2166 * but registration or volatile key creation doesn't use one). */
Gilles Peskined7729582019-08-05 15:55:54 +02002167 if( driver != NULL &&
2168 psa_crypto_transaction.unknown.type == PSA_CRYPTO_TRANSACTION_CREATE_KEY )
Gilles Peskinecbaff462019-07-12 23:46:04 +02002169 {
2170 status = psa_save_se_persistent_data( driver );
2171 if( status != PSA_SUCCESS )
2172 {
Gilles Peskine8e338702019-07-30 20:06:31 +02002173 psa_destroy_persistent_key( slot->attr.id );
Gilles Peskinecbaff462019-07-12 23:46:04 +02002174 return( status );
2175 }
Gilles Peskinefc762652019-07-22 19:30:34 +02002176 status = psa_crypto_stop_transaction( );
Gilles Peskinecbaff462019-07-12 23:46:04 +02002177 }
2178#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2179
Ronald Cron50972942020-11-14 11:28:25 +01002180 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01002181 {
2182 *key = slot->attr.id;
Ronald Cron5c522922020-11-14 16:35:34 +01002183 status = psa_unlock_key_slot( slot );
Ronald Cron81709fc2020-11-14 12:10:32 +01002184 if( status != PSA_SUCCESS )
2185 *key = MBEDTLS_SVC_KEY_ID_INIT;
2186 }
Ronald Cron50972942020-11-14 11:28:25 +01002187
Gilles Peskine4747d192019-04-17 15:05:45 +02002188 return( status );
2189}
2190
2191/** Abort the creation of a key.
2192 *
2193 * You may call this function after calling psa_start_key_creation(),
2194 * or after psa_finish_key_creation() fails. In other circumstances, this
2195 * function may not clean up persistent storage.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02002196 * See the documentation of psa_start_key_creation() for the intended use
2197 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02002198 *
Gilles Peskine011e4282019-06-26 18:34:38 +02002199 * \param[in,out] slot Pointer to the slot with key material.
2200 * \param[in] driver The secure element driver for the key,
2201 * or NULL for a transparent key.
Gilles Peskine4747d192019-04-17 15:05:45 +02002202 */
Gilles Peskine011e4282019-06-26 18:34:38 +02002203static void psa_fail_key_creation( psa_key_slot_t *slot,
Gilles Peskine8abe6a22019-07-12 23:40:35 +02002204 psa_se_drv_table_entry_t *driver )
Gilles Peskine4747d192019-04-17 15:05:45 +02002205{
Gilles Peskine011e4282019-06-26 18:34:38 +02002206 (void) driver;
2207
Gilles Peskine4747d192019-04-17 15:05:45 +02002208 if( slot == NULL )
2209 return;
Gilles Peskine011e4282019-06-26 18:34:38 +02002210
2211#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01002212 /* TODO: If the key has already been created in the secure
Gilles Peskine011e4282019-06-26 18:34:38 +02002213 * element, and the failure happened later (when saving metadata
2214 * to internal storage), we need to destroy the key in the secure
Gilles Peskinec9d7f942019-08-13 16:17:16 +02002215 * element.
2216 * https://github.com/ARMmbed/mbed-crypto/issues/217
2217 */
Gilles Peskinefc762652019-07-22 19:30:34 +02002218
Gilles Peskined7729582019-08-05 15:55:54 +02002219 /* Abort the ongoing transaction if any (there may not be one if
2220 * the creation process failed before starting one, or if the
2221 * key creation is a registration of a key in a secure element).
2222 * Earlier functions must already have done what it takes to undo any
2223 * partial creation. All that's left is to update the transaction data
2224 * itself. */
Gilles Peskinefc762652019-07-22 19:30:34 +02002225 (void) psa_crypto_stop_transaction( );
Gilles Peskine011e4282019-06-26 18:34:38 +02002226#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2227
Gilles Peskine4747d192019-04-17 15:05:45 +02002228 psa_wipe_key_slot( slot );
2229}
2230
Gilles Peskine1b8594a2019-07-31 17:21:46 +02002231/** Validate optional attributes during key creation.
2232 *
2233 * Some key attributes are optional during key creation. If they are
2234 * specified in the attributes structure, check that they are consistent
2235 * with the data in the slot.
2236 *
2237 * This function should be called near the end of key creation, after
2238 * the slot in memory is fully populated but before saving persistent data.
2239 */
2240static psa_status_t psa_validate_optional_attributes(
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002241 const psa_key_slot_t *slot,
2242 const psa_key_attributes_t *attributes )
2243{
Gilles Peskine7e0cff92019-07-30 13:48:52 +02002244 if( attributes->core.type != 0 )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002245 {
Gilles Peskine8e338702019-07-30 20:06:31 +02002246 if( attributes->core.type != slot->attr.type )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002247 return( PSA_ERROR_INVALID_ARGUMENT );
2248 }
2249
2250 if( attributes->domain_parameters_size != 0 )
2251 {
John Durkop0e005192020-10-31 22:06:54 -07002252#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
2253 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskine8e338702019-07-30 20:06:31 +02002254 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002255 {
Steven Cooremana2371e52020-07-28 14:30:39 +02002256 mbedtls_rsa_context *rsa = NULL;
Steven Cooreman75b74362020-07-28 14:30:13 +02002257 mbedtls_mpi actual, required;
Steven Cooreman6d839f02020-07-30 11:36:45 +02002258 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooremana01795d2020-07-24 22:48:15 +02002259
Steven Cooreman7f391872020-07-30 14:57:44 +02002260 psa_status_t status = psa_load_rsa_representation(
Steven Cooreman4fed4552020-08-03 14:46:03 +02002261 slot->attr.type,
Steven Cooreman7f391872020-07-30 14:57:44 +02002262 slot->data.key.data,
2263 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02002264 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02002265 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02002266 return( status );
Steven Cooreman75b74362020-07-28 14:30:13 +02002267
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002268 mbedtls_mpi_init( &actual );
2269 mbedtls_mpi_init( &required );
Steven Cooremana2371e52020-07-28 14:30:39 +02002270 ret = mbedtls_rsa_export( rsa,
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002271 NULL, NULL, NULL, NULL, &actual );
Steven Cooremana2371e52020-07-28 14:30:39 +02002272 mbedtls_rsa_free( rsa );
2273 mbedtls_free( rsa );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002274 if( ret != 0 )
2275 goto rsa_exit;
2276 ret = mbedtls_mpi_read_binary( &required,
2277 attributes->domain_parameters,
2278 attributes->domain_parameters_size );
2279 if( ret != 0 )
2280 goto rsa_exit;
2281 if( mbedtls_mpi_cmp_mpi( &actual, &required ) != 0 )
2282 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2283 rsa_exit:
2284 mbedtls_mpi_free( &actual );
2285 mbedtls_mpi_free( &required );
2286 if( ret != 0)
2287 return( mbedtls_to_psa_error( ret ) );
2288 }
2289 else
John Durkop9814fa22020-11-04 12:28:15 -08002290#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
2291 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002292 {
2293 return( PSA_ERROR_INVALID_ARGUMENT );
2294 }
2295 }
2296
Gilles Peskine7e0cff92019-07-30 13:48:52 +02002297 if( attributes->core.bits != 0 )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002298 {
Gilles Peskineb46bef22019-07-30 21:32:04 +02002299 if( attributes->core.bits != slot->attr.bits )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002300 return( PSA_ERROR_INVALID_ARGUMENT );
2301 }
2302
2303 return( PSA_SUCCESS );
2304}
2305
Gilles Peskine4747d192019-04-17 15:05:45 +02002306psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
Gilles Peskine4747d192019-04-17 15:05:45 +02002307 const uint8_t *data,
Gilles Peskine73676cb2019-05-15 20:15:10 +02002308 size_t data_length,
Ronald Croncf56a0a2020-08-04 09:51:30 +02002309 mbedtls_svc_key_id_t *key )
Gilles Peskine4747d192019-04-17 15:05:45 +02002310{
2311 psa_status_t status;
2312 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02002313 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002314
Ronald Cron81709fc2020-11-14 12:10:32 +01002315 *key = MBEDTLS_SVC_KEY_ID_INIT;
2316
Gilles Peskine0f84d622019-09-12 19:03:13 +02002317 /* Reject zero-length symmetric keys (including raw data key objects).
2318 * This also rejects any key which might be encoded as an empty string,
2319 * which is never valid. */
2320 if( data_length == 0 )
2321 return( PSA_ERROR_INVALID_ARGUMENT );
2322
Gilles Peskinedf179142019-07-15 22:02:14 +02002323 status = psa_start_key_creation( PSA_KEY_CREATION_IMPORT, attributes,
Ronald Cron81709fc2020-11-14 12:10:32 +01002324 &slot, &driver );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002325 if( status != PSA_SUCCESS )
2326 goto exit;
2327
Steven Cooreman98435dd2021-01-08 19:19:40 +01002328#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Steven Cooremanac3434f2021-01-15 17:36:02 +01002329 if( driver != NULL )
2330 {
2331 const psa_drv_se_t *drv = psa_get_se_driver_methods( driver );
2332 /* The driver should set the number of key bits, however in
2333 * case it doesn't, we initialize bits to an invalid value. */
2334 size_t bits = PSA_MAX_KEY_BITS + 1;
2335 if( drv->key_management == NULL ||
2336 drv->key_management->p_import == NULL )
Gilles Peskine5d309672019-07-12 23:47:28 +02002337 {
Steven Cooremanac3434f2021-01-15 17:36:02 +01002338 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine5d309672019-07-12 23:47:28 +02002339 goto exit;
2340 }
Steven Cooremanac3434f2021-01-15 17:36:02 +01002341 status = drv->key_management->p_import(
2342 psa_get_se_driver_context( driver ),
2343 slot->data.se.slot_number, attributes, data, data_length,
2344 &bits );
2345 if( status != PSA_SUCCESS )
2346 goto exit;
2347 if( bits > PSA_MAX_KEY_BITS )
2348 {
2349 status = PSA_ERROR_NOT_SUPPORTED;
2350 goto exit;
2351 }
2352 slot->attr.bits = (psa_key_bits_t) bits;
2353 }
2354 else
2355#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2356 if( psa_key_lifetime_is_external( psa_get_key_lifetime( attributes ) ) )
2357 {
2358 /* Importing a key with external lifetime through the driver wrapper
2359 * interface is not yet supported. Return as if this was an invalid
2360 * lifetime. */
2361 status = PSA_ERROR_INVALID_ARGUMENT;
2362 goto exit;
Gilles Peskine5d309672019-07-12 23:47:28 +02002363 }
2364 else
Gilles Peskine5d309672019-07-12 23:47:28 +02002365 {
2366 status = psa_import_key_into_slot( slot, data, data_length );
2367 if( status != PSA_SUCCESS )
2368 goto exit;
Gilles Peskine5d309672019-07-12 23:47:28 +02002369 }
Gilles Peskine1b8594a2019-07-31 17:21:46 +02002370 status = psa_validate_optional_attributes( slot, attributes );
Gilles Peskine18017402019-07-24 20:25:59 +02002371 if( status != PSA_SUCCESS )
2372 goto exit;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002373
Ronald Cron81709fc2020-11-14 12:10:32 +01002374 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002375exit:
Gilles Peskine4747d192019-04-17 15:05:45 +02002376 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02002377 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002378
Gilles Peskine4747d192019-04-17 15:05:45 +02002379 return( status );
2380}
2381
Gilles Peskined7729582019-08-05 15:55:54 +02002382#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2383psa_status_t mbedtls_psa_register_se_key(
2384 const psa_key_attributes_t *attributes )
2385{
2386 psa_status_t status;
2387 psa_key_slot_t *slot = NULL;
2388 psa_se_drv_table_entry_t *driver = NULL;
Ronald Croncf56a0a2020-08-04 09:51:30 +02002389 mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
Gilles Peskined7729582019-08-05 15:55:54 +02002390
2391 /* Leaving attributes unspecified is not currently supported.
2392 * It could make sense to query the key type and size from the
2393 * secure element, but not all secure elements support this
2394 * and the driver HAL doesn't currently support it. */
2395 if( psa_get_key_type( attributes ) == PSA_KEY_TYPE_NONE )
2396 return( PSA_ERROR_NOT_SUPPORTED );
2397 if( psa_get_key_bits( attributes ) == 0 )
2398 return( PSA_ERROR_NOT_SUPPORTED );
2399
2400 status = psa_start_key_creation( PSA_KEY_CREATION_REGISTER, attributes,
Ronald Cron81709fc2020-11-14 12:10:32 +01002401 &slot, &driver );
Gilles Peskined7729582019-08-05 15:55:54 +02002402 if( status != PSA_SUCCESS )
2403 goto exit;
2404
Ronald Cron81709fc2020-11-14 12:10:32 +01002405 status = psa_finish_key_creation( slot, driver, &key );
Gilles Peskined7729582019-08-05 15:55:54 +02002406
2407exit:
2408 if( status != PSA_SUCCESS )
Gilles Peskined7729582019-08-05 15:55:54 +02002409 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002410
Gilles Peskined7729582019-08-05 15:55:54 +02002411 /* Registration doesn't keep the key in RAM. */
Ronald Croncf56a0a2020-08-04 09:51:30 +02002412 psa_close_key( key );
Gilles Peskined7729582019-08-05 15:55:54 +02002413 return( status );
2414}
2415#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2416
Gilles Peskinef603c712019-01-19 13:40:11 +01002417static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002418 psa_key_slot_t *target )
Gilles Peskinef603c712019-01-19 13:40:11 +01002419{
Steven Cooremanf7cebd42020-10-13 20:27:40 +02002420 psa_status_t status = psa_copy_key_material_into_slot( target,
2421 source->data.key.data,
2422 source->data.key.bytes );
Gilles Peskinef603c712019-01-19 13:40:11 +01002423 if( status != PSA_SUCCESS )
Steven Cooreman398aee52020-10-13 14:35:45 +02002424 return( status );
Gilles Peskinef603c712019-01-19 13:40:11 +01002425
Steven Cooreman398aee52020-10-13 14:35:45 +02002426 target->attr.type = source->attr.type;
2427 target->attr.bits = source->attr.bits;
2428
2429 return( PSA_SUCCESS );
Gilles Peskinef603c712019-01-19 13:40:11 +01002430}
2431
Ronald Croncf56a0a2020-08-04 09:51:30 +02002432psa_status_t psa_copy_key( mbedtls_svc_key_id_t source_key,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002433 const psa_key_attributes_t *specified_attributes,
Ronald Croncf56a0a2020-08-04 09:51:30 +02002434 mbedtls_svc_key_id_t *target_key )
Gilles Peskinef603c712019-01-19 13:40:11 +01002435{
Ronald Cronf95a2b12020-10-22 15:24:49 +02002436 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01002437 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskinef603c712019-01-19 13:40:11 +01002438 psa_key_slot_t *source_slot = NULL;
2439 psa_key_slot_t *target_slot = NULL;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002440 psa_key_attributes_t actual_attributes = *specified_attributes;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02002441 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskinef603c712019-01-19 13:40:11 +01002442
Ronald Cron81709fc2020-11-14 12:10:32 +01002443 *target_key = MBEDTLS_SVC_KEY_ID_INIT;
2444
Ronald Cron5c522922020-11-14 16:35:34 +01002445 status = psa_get_and_lock_transparent_key_slot_with_policy(
2446 source_key, &source_slot, PSA_KEY_USAGE_COPY, 0 );
Gilles Peskinef603c712019-01-19 13:40:11 +01002447 if( status != PSA_SUCCESS )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002448 goto exit;
2449
Gilles Peskine1b8594a2019-07-31 17:21:46 +02002450 status = psa_validate_optional_attributes( source_slot,
2451 specified_attributes );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002452 if( status != PSA_SUCCESS )
2453 goto exit;
2454
Gilles Peskine7e0cff92019-07-30 13:48:52 +02002455 status = psa_restrict_key_policy( &actual_attributes.core.policy,
Gilles Peskine8e338702019-07-30 20:06:31 +02002456 &source_slot->attr.policy );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002457 if( status != PSA_SUCCESS )
2458 goto exit;
2459
Ronald Cron81709fc2020-11-14 12:10:32 +01002460 status = psa_start_key_creation( PSA_KEY_CREATION_COPY, &actual_attributes,
2461 &target_slot, &driver );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002462 if( status != PSA_SUCCESS )
2463 goto exit;
2464
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002465#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2466 if( driver != NULL )
Gilles Peskinef603c712019-01-19 13:40:11 +01002467 {
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002468 /* Copying to a secure element is not implemented yet. */
2469 status = PSA_ERROR_NOT_SUPPORTED;
2470 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01002471 }
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002472#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinef603c712019-01-19 13:40:11 +01002473
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002474 status = psa_copy_key_material( source_slot, target_slot );
Gilles Peskinef603c712019-01-19 13:40:11 +01002475 if( status != PSA_SUCCESS )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002476 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01002477
Ronald Cron81709fc2020-11-14 12:10:32 +01002478 status = psa_finish_key_creation( target_slot, driver, target_key );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002479exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002480 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02002481 psa_fail_key_creation( target_slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002482
Ronald Cron5c522922020-11-14 16:35:34 +01002483 unlock_status = psa_unlock_key_slot( source_slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002484
Ronald Cron5c522922020-11-14 16:35:34 +01002485 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskinef603c712019-01-19 13:40:11 +01002486}
2487
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002488
2489
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002490/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01002491/* Message digests */
2492/****************************************************************/
2493
John Durkop07cc04a2020-11-16 22:08:34 -08002494#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
John Durkop0e005192020-10-31 22:06:54 -07002495 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
2496 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
John Durkop9814fa22020-11-04 12:28:15 -08002497 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinedc2fc842018-03-07 16:42:59 +01002498static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01002499{
2500 switch( alg )
2501 {
John Durkopee4e6602020-11-27 08:48:46 -08002502#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine20035e32018-02-03 22:44:14 +01002503 case PSA_ALG_MD2:
2504 return( &mbedtls_md2_info );
2505#endif
John Durkopee4e6602020-11-27 08:48:46 -08002506#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine20035e32018-02-03 22:44:14 +01002507 case PSA_ALG_MD4:
2508 return( &mbedtls_md4_info );
2509#endif
John Durkopee4e6602020-11-27 08:48:46 -08002510#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine20035e32018-02-03 22:44:14 +01002511 case PSA_ALG_MD5:
2512 return( &mbedtls_md5_info );
2513#endif
John Durkopee4e6602020-11-27 08:48:46 -08002514#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine20035e32018-02-03 22:44:14 +01002515 case PSA_ALG_RIPEMD160:
2516 return( &mbedtls_ripemd160_info );
2517#endif
John Durkopee4e6602020-11-27 08:48:46 -08002518#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine20035e32018-02-03 22:44:14 +01002519 case PSA_ALG_SHA_1:
2520 return( &mbedtls_sha1_info );
2521#endif
John Durkopee4e6602020-11-27 08:48:46 -08002522#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine20035e32018-02-03 22:44:14 +01002523 case PSA_ALG_SHA_224:
2524 return( &mbedtls_sha224_info );
John Durkopee4e6602020-11-27 08:48:46 -08002525#endif
2526#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine20035e32018-02-03 22:44:14 +01002527 case PSA_ALG_SHA_256:
2528 return( &mbedtls_sha256_info );
2529#endif
John Durkopee4e6602020-11-27 08:48:46 -08002530#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine20035e32018-02-03 22:44:14 +01002531 case PSA_ALG_SHA_384:
2532 return( &mbedtls_sha384_info );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +02002533#endif
John Durkopee4e6602020-11-27 08:48:46 -08002534#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine20035e32018-02-03 22:44:14 +01002535 case PSA_ALG_SHA_512:
2536 return( &mbedtls_sha512_info );
2537#endif
2538 default:
2539 return( NULL );
2540 }
2541}
John Durkop07cc04a2020-11-16 22:08:34 -08002542#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
John Durkop9814fa22020-11-04 12:28:15 -08002543 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
2544 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
2545 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskine20035e32018-02-03 22:44:14 +01002546
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002547psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
2548{
2549 switch( operation->alg )
2550 {
Gilles Peskine81736312018-06-26 15:04:31 +02002551 case 0:
2552 /* The object has (apparently) been initialized but it is not
2553 * in use. It's ok to call abort on such an object, and there's
2554 * nothing to do. */
2555 break;
John Durkopee4e6602020-11-27 08:48:46 -08002556#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002557 case PSA_ALG_MD2:
2558 mbedtls_md2_free( &operation->ctx.md2 );
2559 break;
2560#endif
John Durkopee4e6602020-11-27 08:48:46 -08002561#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002562 case PSA_ALG_MD4:
2563 mbedtls_md4_free( &operation->ctx.md4 );
2564 break;
2565#endif
John Durkopee4e6602020-11-27 08:48:46 -08002566#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002567 case PSA_ALG_MD5:
2568 mbedtls_md5_free( &operation->ctx.md5 );
2569 break;
2570#endif
John Durkopee4e6602020-11-27 08:48:46 -08002571#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002572 case PSA_ALG_RIPEMD160:
2573 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
2574 break;
2575#endif
John Durkopee4e6602020-11-27 08:48:46 -08002576#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002577 case PSA_ALG_SHA_1:
2578 mbedtls_sha1_free( &operation->ctx.sha1 );
2579 break;
2580#endif
John Durkop6ca23272020-12-03 06:01:32 -08002581#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002582 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002583 mbedtls_sha256_free( &operation->ctx.sha256 );
2584 break;
2585#endif
2586#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002587 case PSA_ALG_SHA_256:
2588 mbedtls_sha256_free( &operation->ctx.sha256 );
2589 break;
2590#endif
John Durkop6ca23272020-12-03 06:01:32 -08002591#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002592 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002593 mbedtls_sha512_free( &operation->ctx.sha512 );
2594 break;
2595#endif
2596#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002597 case PSA_ALG_SHA_512:
2598 mbedtls_sha512_free( &operation->ctx.sha512 );
2599 break;
2600#endif
2601 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002602 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002603 }
2604 operation->alg = 0;
2605 return( PSA_SUCCESS );
2606}
2607
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002608psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002609 psa_algorithm_t alg )
2610{
Janos Follath24eed8d2019-11-22 13:21:35 +00002611 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002612
2613 /* A context must be freshly initialized before it can be set up. */
2614 if( operation->alg != 0 )
2615 {
2616 return( PSA_ERROR_BAD_STATE );
2617 }
2618
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002619 switch( alg )
2620 {
John Durkopee4e6602020-11-27 08:48:46 -08002621#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002622 case PSA_ALG_MD2:
2623 mbedtls_md2_init( &operation->ctx.md2 );
2624 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
2625 break;
2626#endif
John Durkopee4e6602020-11-27 08:48:46 -08002627#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002628 case PSA_ALG_MD4:
2629 mbedtls_md4_init( &operation->ctx.md4 );
2630 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
2631 break;
2632#endif
John Durkopee4e6602020-11-27 08:48:46 -08002633#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002634 case PSA_ALG_MD5:
2635 mbedtls_md5_init( &operation->ctx.md5 );
2636 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
2637 break;
2638#endif
John Durkopee4e6602020-11-27 08:48:46 -08002639#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002640 case PSA_ALG_RIPEMD160:
2641 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
2642 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
2643 break;
2644#endif
John Durkopee4e6602020-11-27 08:48:46 -08002645#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002646 case PSA_ALG_SHA_1:
2647 mbedtls_sha1_init( &operation->ctx.sha1 );
2648 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
2649 break;
2650#endif
John Durkopee4e6602020-11-27 08:48:46 -08002651#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002652 case PSA_ALG_SHA_224:
2653 mbedtls_sha256_init( &operation->ctx.sha256 );
2654 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
2655 break;
John Durkopee4e6602020-11-27 08:48:46 -08002656#endif
2657#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002658 case PSA_ALG_SHA_256:
2659 mbedtls_sha256_init( &operation->ctx.sha256 );
2660 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
2661 break;
2662#endif
John Durkopee4e6602020-11-27 08:48:46 -08002663#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002664 case PSA_ALG_SHA_384:
2665 mbedtls_sha512_init( &operation->ctx.sha512 );
2666 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
2667 break;
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002668#endif
John Durkopee4e6602020-11-27 08:48:46 -08002669#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002670 case PSA_ALG_SHA_512:
2671 mbedtls_sha512_init( &operation->ctx.sha512 );
2672 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
2673 break;
2674#endif
2675 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02002676 return( PSA_ALG_IS_HASH( alg ) ?
2677 PSA_ERROR_NOT_SUPPORTED :
2678 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002679 }
2680 if( ret == 0 )
2681 operation->alg = alg;
2682 else
2683 psa_hash_abort( operation );
2684 return( mbedtls_to_psa_error( ret ) );
2685}
2686
2687psa_status_t psa_hash_update( psa_hash_operation_t *operation,
2688 const uint8_t *input,
2689 size_t input_length )
2690{
Janos Follath24eed8d2019-11-22 13:21:35 +00002691 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine94e44542018-07-12 16:58:43 +02002692
2693 /* Don't require hash implementations to behave correctly on a
2694 * zero-length input, which may have an invalid pointer. */
2695 if( input_length == 0 )
2696 return( PSA_SUCCESS );
2697
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002698 switch( operation->alg )
2699 {
John Durkopee4e6602020-11-27 08:48:46 -08002700#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002701 case PSA_ALG_MD2:
2702 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
2703 input, input_length );
2704 break;
2705#endif
John Durkopee4e6602020-11-27 08:48:46 -08002706#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002707 case PSA_ALG_MD4:
2708 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
2709 input, input_length );
2710 break;
2711#endif
John Durkopee4e6602020-11-27 08:48:46 -08002712#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002713 case PSA_ALG_MD5:
2714 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
2715 input, input_length );
2716 break;
2717#endif
John Durkopee4e6602020-11-27 08:48:46 -08002718#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002719 case PSA_ALG_RIPEMD160:
2720 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
2721 input, input_length );
2722 break;
2723#endif
John Durkopee4e6602020-11-27 08:48:46 -08002724#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002725 case PSA_ALG_SHA_1:
2726 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
2727 input, input_length );
2728 break;
2729#endif
John Durkop6ca23272020-12-03 06:01:32 -08002730#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002731 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002732 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
2733 input, input_length );
2734 break;
2735#endif
2736#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002737 case PSA_ALG_SHA_256:
2738 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
2739 input, input_length );
2740 break;
2741#endif
John Durkop6ca23272020-12-03 06:01:32 -08002742#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002743 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002744 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
2745 input, input_length );
2746 break;
2747#endif
2748#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002749 case PSA_ALG_SHA_512:
2750 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
2751 input, input_length );
2752 break;
2753#endif
2754 default:
John Durkopee4e6602020-11-27 08:48:46 -08002755 (void)input;
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002756 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002757 }
Gilles Peskine94e44542018-07-12 16:58:43 +02002758
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002759 if( ret != 0 )
2760 psa_hash_abort( operation );
2761 return( mbedtls_to_psa_error( ret ) );
2762}
2763
2764psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
2765 uint8_t *hash,
2766 size_t hash_size,
2767 size_t *hash_length )
2768{
itayzafrir40835d42018-08-02 13:14:17 +03002769 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00002770 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02002771 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002772
2773 /* Fill the output buffer with something that isn't a valid hash
2774 * (barring an attack on the hash and deliberately-crafted input),
2775 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02002776 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002777 /* If hash_size is 0 then hash may be NULL and then the
2778 * call to memset would have undefined behavior. */
2779 if( hash_size != 0 )
2780 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002781
2782 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03002783 {
2784 status = PSA_ERROR_BUFFER_TOO_SMALL;
2785 goto exit;
2786 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002787
2788 switch( operation->alg )
2789 {
John Durkopee4e6602020-11-27 08:48:46 -08002790#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002791 case PSA_ALG_MD2:
2792 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
2793 break;
2794#endif
John Durkopee4e6602020-11-27 08:48:46 -08002795#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002796 case PSA_ALG_MD4:
2797 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
2798 break;
2799#endif
John Durkopee4e6602020-11-27 08:48:46 -08002800#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002801 case PSA_ALG_MD5:
2802 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
2803 break;
2804#endif
John Durkopee4e6602020-11-27 08:48:46 -08002805#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002806 case PSA_ALG_RIPEMD160:
2807 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
2808 break;
2809#endif
John Durkopee4e6602020-11-27 08:48:46 -08002810#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002811 case PSA_ALG_SHA_1:
2812 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
2813 break;
2814#endif
John Durkop6ca23272020-12-03 06:01:32 -08002815#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002816 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002817 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
2818 break;
2819#endif
2820#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002821 case PSA_ALG_SHA_256:
2822 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
2823 break;
2824#endif
John Durkop6ca23272020-12-03 06:01:32 -08002825#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002826 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002827 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
2828 break;
2829#endif
2830#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002831 case PSA_ALG_SHA_512:
2832 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
2833 break;
2834#endif
2835 default:
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002836 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002837 }
itayzafrir40835d42018-08-02 13:14:17 +03002838 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002839
itayzafrir40835d42018-08-02 13:14:17 +03002840exit:
2841 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002842 {
Gilles Peskineaee13332018-07-02 12:15:28 +02002843 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002844 return( psa_hash_abort( operation ) );
2845 }
2846 else
2847 {
2848 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03002849 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002850 }
2851}
2852
Gilles Peskine2d277862018-06-18 15:41:12 +02002853psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
2854 const uint8_t *hash,
2855 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002856{
2857 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
2858 size_t actual_hash_length;
2859 psa_status_t status = psa_hash_finish( operation,
2860 actual_hash, sizeof( actual_hash ),
2861 &actual_hash_length );
2862 if( status != PSA_SUCCESS )
2863 return( status );
2864 if( actual_hash_length != hash_length )
2865 return( PSA_ERROR_INVALID_SIGNATURE );
2866 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
2867 return( PSA_ERROR_INVALID_SIGNATURE );
2868 return( PSA_SUCCESS );
2869}
2870
Gilles Peskine0a749c82019-11-28 19:33:58 +01002871psa_status_t psa_hash_compute( psa_algorithm_t alg,
2872 const uint8_t *input, size_t input_length,
2873 uint8_t *hash, size_t hash_size,
2874 size_t *hash_length )
2875{
2876 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
2877 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2878
2879 *hash_length = hash_size;
2880 status = psa_hash_setup( &operation, alg );
2881 if( status != PSA_SUCCESS )
2882 goto exit;
2883 status = psa_hash_update( &operation, input, input_length );
2884 if( status != PSA_SUCCESS )
2885 goto exit;
2886 status = psa_hash_finish( &operation, hash, hash_size, hash_length );
2887 if( status != PSA_SUCCESS )
2888 goto exit;
2889
2890exit:
2891 if( status == PSA_SUCCESS )
2892 status = psa_hash_abort( &operation );
2893 else
2894 psa_hash_abort( &operation );
2895 return( status );
2896}
2897
2898psa_status_t psa_hash_compare( psa_algorithm_t alg,
2899 const uint8_t *input, size_t input_length,
2900 const uint8_t *hash, size_t hash_length )
2901{
2902 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
2903 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2904
2905 status = psa_hash_setup( &operation, alg );
2906 if( status != PSA_SUCCESS )
2907 goto exit;
2908 status = psa_hash_update( &operation, input, input_length );
2909 if( status != PSA_SUCCESS )
2910 goto exit;
2911 status = psa_hash_verify( &operation, hash, hash_length );
2912 if( status != PSA_SUCCESS )
2913 goto exit;
2914
2915exit:
2916 if( status == PSA_SUCCESS )
2917 status = psa_hash_abort( &operation );
2918 else
2919 psa_hash_abort( &operation );
2920 return( status );
2921}
2922
Gilles Peskineeb35d782019-01-22 17:56:16 +01002923psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation,
2924 psa_hash_operation_t *target_operation )
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002925{
2926 if( target_operation->alg != 0 )
2927 return( PSA_ERROR_BAD_STATE );
2928
2929 switch( source_operation->alg )
2930 {
2931 case 0:
2932 return( PSA_ERROR_BAD_STATE );
John Durkopee4e6602020-11-27 08:48:46 -08002933#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002934 case PSA_ALG_MD2:
2935 mbedtls_md2_clone( &target_operation->ctx.md2,
2936 &source_operation->ctx.md2 );
2937 break;
2938#endif
John Durkopee4e6602020-11-27 08:48:46 -08002939#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002940 case PSA_ALG_MD4:
2941 mbedtls_md4_clone( &target_operation->ctx.md4,
2942 &source_operation->ctx.md4 );
2943 break;
2944#endif
John Durkopee4e6602020-11-27 08:48:46 -08002945#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002946 case PSA_ALG_MD5:
2947 mbedtls_md5_clone( &target_operation->ctx.md5,
2948 &source_operation->ctx.md5 );
2949 break;
2950#endif
John Durkopee4e6602020-11-27 08:48:46 -08002951#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002952 case PSA_ALG_RIPEMD160:
2953 mbedtls_ripemd160_clone( &target_operation->ctx.ripemd160,
2954 &source_operation->ctx.ripemd160 );
2955 break;
2956#endif
John Durkopee4e6602020-11-27 08:48:46 -08002957#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002958 case PSA_ALG_SHA_1:
2959 mbedtls_sha1_clone( &target_operation->ctx.sha1,
2960 &source_operation->ctx.sha1 );
2961 break;
2962#endif
John Durkop6ca23272020-12-03 06:01:32 -08002963#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002964 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002965 mbedtls_sha256_clone( &target_operation->ctx.sha256,
2966 &source_operation->ctx.sha256 );
2967 break;
2968#endif
2969#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002970 case PSA_ALG_SHA_256:
2971 mbedtls_sha256_clone( &target_operation->ctx.sha256,
2972 &source_operation->ctx.sha256 );
2973 break;
2974#endif
John Durkop6ca23272020-12-03 06:01:32 -08002975#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002976 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002977 mbedtls_sha512_clone( &target_operation->ctx.sha512,
2978 &source_operation->ctx.sha512 );
2979 break;
2980#endif
2981#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002982 case PSA_ALG_SHA_512:
2983 mbedtls_sha512_clone( &target_operation->ctx.sha512,
2984 &source_operation->ctx.sha512 );
2985 break;
2986#endif
2987 default:
2988 return( PSA_ERROR_NOT_SUPPORTED );
2989 }
2990
2991 target_operation->alg = source_operation->alg;
2992 return( PSA_SUCCESS );
2993}
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002994
2995
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002996/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01002997/* MAC */
2998/****************************************************************/
2999
Gilles Peskinedc2fc842018-03-07 16:42:59 +01003000static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01003001 psa_algorithm_t alg,
3002 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02003003 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03003004 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003005{
Gilles Peskine8c9def32018-02-08 10:02:12 +01003006 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03003007 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003008
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003009 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02003010 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003011
Gilles Peskine8c9def32018-02-08 10:02:12 +01003012 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
3013 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03003014 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003015 {
Bence Szépkúti1de907d2020-12-07 18:20:28 +01003016 case PSA_ALG_STREAM_CIPHER:
Gilles Peskine8c9def32018-02-08 10:02:12 +01003017 mode = MBEDTLS_MODE_STREAM;
3018 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003019 case PSA_ALG_CTR:
3020 mode = MBEDTLS_MODE_CTR;
3021 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003022 case PSA_ALG_CFB:
3023 mode = MBEDTLS_MODE_CFB;
3024 break;
3025 case PSA_ALG_OFB:
3026 mode = MBEDTLS_MODE_OFB;
3027 break;
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003028 case PSA_ALG_ECB_NO_PADDING:
3029 mode = MBEDTLS_MODE_ECB;
3030 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003031 case PSA_ALG_CBC_NO_PADDING:
3032 mode = MBEDTLS_MODE_CBC;
3033 break;
3034 case PSA_ALG_CBC_PKCS7:
3035 mode = MBEDTLS_MODE_CBC;
3036 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02003037 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01003038 mode = MBEDTLS_MODE_CCM;
3039 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02003040 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01003041 mode = MBEDTLS_MODE_GCM;
3042 break;
Gilles Peskine26869f22019-05-06 15:25:00 +02003043 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CHACHA20_POLY1305, 0 ):
3044 mode = MBEDTLS_MODE_CHACHAPOLY;
3045 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003046 default:
3047 return( NULL );
3048 }
3049 }
3050 else if( alg == PSA_ALG_CMAC )
3051 mode = MBEDTLS_MODE_ECB;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003052 else
3053 return( NULL );
3054
3055 switch( key_type )
3056 {
3057 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03003058 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003059 break;
3060 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003061 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
3062 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01003063 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03003064 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003065 else
mohammad1603f4f0d612018-06-03 15:04:51 +03003066 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003067 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
3068 * but two-key Triple-DES is functionally three-key Triple-DES
3069 * with K1=K3, so that's how we present it to mbedtls. */
3070 if( key_bits == 128 )
3071 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003072 break;
3073 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03003074 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003075 break;
3076 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03003077 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003078 break;
Gilles Peskine26869f22019-05-06 15:25:00 +02003079 case PSA_KEY_TYPE_CHACHA20:
3080 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
3081 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003082 default:
3083 return( NULL );
3084 }
mohammad1603f4f0d612018-06-03 15:04:51 +03003085 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03003086 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003087
Jaeden Amero23bbb752018-06-26 14:16:54 +01003088 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
3089 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003090}
3091
John Durkop6ba40d12020-11-10 08:50:04 -08003092#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003093static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03003094{
Gilles Peskine2d277862018-06-18 15:41:12 +02003095 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03003096 {
3097 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003098 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003099 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003100 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003101 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003102 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003103 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003104 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003105 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003106 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003107 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003108 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003109 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003110 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003111 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003112 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003113 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02003114 return( 128 );
3115 default:
3116 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003117 }
3118}
John Durkop07cc04a2020-11-16 22:08:34 -08003119#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03003120
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003121/* Initialize the MAC operation structure. Once this function has been
3122 * called, psa_mac_abort can run and will do the right thing. */
3123static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
3124 psa_algorithm_t alg )
3125{
3126 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
3127
3128 operation->alg = alg;
3129 operation->key_set = 0;
3130 operation->iv_set = 0;
3131 operation->iv_required = 0;
3132 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02003133 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003134
3135#if defined(MBEDTLS_CMAC_C)
3136 if( alg == PSA_ALG_CMAC )
3137 {
3138 operation->iv_required = 0;
3139 mbedtls_cipher_init( &operation->ctx.cmac );
3140 status = PSA_SUCCESS;
3141 }
3142 else
3143#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003144#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003145 if( PSA_ALG_IS_HMAC( operation->alg ) )
3146 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02003147 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
3148 operation->ctx.hmac.hash_ctx.alg = 0;
3149 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003150 }
3151 else
John Durkopd0321952020-10-29 21:37:36 -07003152#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003153 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02003154 if( ! PSA_ALG_IS_MAC( alg ) )
3155 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003156 }
3157
3158 if( status != PSA_SUCCESS )
3159 memset( operation, 0, sizeof( *operation ) );
3160 return( status );
3161}
3162
John Durkop6ba40d12020-11-10 08:50:04 -08003163#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02003164static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
3165{
Gilles Peskine3f108122018-12-07 18:14:53 +01003166 mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003167 return( psa_hash_abort( &hmac->hash_ctx ) );
3168}
John Durkop6ba40d12020-11-10 08:50:04 -08003169#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine01126fa2018-07-12 17:04:55 +02003170
Gilles Peskine8c9def32018-02-08 10:02:12 +01003171psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
3172{
Gilles Peskinefbfac682018-07-08 20:51:54 +02003173 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003174 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02003175 /* The object has (apparently) been initialized but it is not
3176 * in use. It's ok to call abort on such an object, and there's
3177 * nothing to do. */
3178 return( PSA_SUCCESS );
3179 }
3180 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01003181#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003182 if( operation->alg == PSA_ALG_CMAC )
3183 {
3184 mbedtls_cipher_free( &operation->ctx.cmac );
3185 }
3186 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01003187#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003188#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003189 if( PSA_ALG_IS_HMAC( operation->alg ) )
3190 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02003191 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003192 }
3193 else
John Durkopd0321952020-10-29 21:37:36 -07003194#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003195 {
3196 /* Sanity check (shouldn't happen: operation->alg should
3197 * always have been initialized to a valid value). */
3198 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003199 }
Moran Peker41deec42018-04-04 15:43:05 +03003200
Gilles Peskine8c9def32018-02-08 10:02:12 +01003201 operation->alg = 0;
3202 operation->key_set = 0;
3203 operation->iv_set = 0;
3204 operation->iv_required = 0;
3205 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02003206 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03003207
Gilles Peskine8c9def32018-02-08 10:02:12 +01003208 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003209
3210bad_state:
3211 /* If abort is called on an uninitialized object, we can't trust
3212 * anything. Wipe the object in case it contains confidential data.
3213 * This may result in a memory leak if a pointer gets overwritten,
3214 * but it's too late to do anything about this. */
3215 memset( operation, 0, sizeof( *operation ) );
3216 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003217}
3218
Gilles Peskinee3b07d82018-06-19 11:57:35 +02003219#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02003220static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003221 size_t key_bits,
Gilles Peskine2f060a82018-12-04 17:12:32 +01003222 psa_key_slot_t *slot,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003223 const mbedtls_cipher_info_t *cipher_info )
3224{
Janos Follath24eed8d2019-11-22 13:21:35 +00003225 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003226
3227 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003228
3229 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
3230 if( ret != 0 )
3231 return( ret );
3232
3233 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02003234 slot->data.key.data,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003235 key_bits );
3236 return( ret );
3237}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02003238#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003239
John Durkop6ba40d12020-11-10 08:50:04 -08003240#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02003241static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
3242 const uint8_t *key,
3243 size_t key_length,
3244 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003245{
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02003246 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003247 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02003248 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003249 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003250 psa_status_t status;
3251
Gilles Peskine9aa369e2018-07-16 00:36:29 +02003252 /* Sanity checks on block_size, to guarantee that there won't be a buffer
3253 * overflow below. This should never trigger if the hash algorithm
3254 * is implemented correctly. */
3255 /* The size checks against the ipad and opad buffers cannot be written
3256 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
3257 * because that triggers -Wlogical-op on GCC 7.3. */
3258 if( block_size > sizeof( ipad ) )
3259 return( PSA_ERROR_NOT_SUPPORTED );
3260 if( block_size > sizeof( hmac->opad ) )
3261 return( PSA_ERROR_NOT_SUPPORTED );
3262 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003263 return( PSA_ERROR_NOT_SUPPORTED );
3264
Gilles Peskined223b522018-06-11 18:12:58 +02003265 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003266 {
Gilles Peskine84b8fc82019-11-28 20:07:20 +01003267 status = psa_hash_compute( hash_alg, key, key_length,
3268 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003269 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02003270 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003271 }
Gilles Peskine96889972018-07-12 17:07:03 +02003272 /* A 0-length key is not commonly used in HMAC when used as a MAC,
3273 * but it is permitted. It is common when HMAC is used in HKDF, for
3274 * example. Don't call `memcpy` in the 0-length because `key` could be
3275 * an invalid pointer which would make the behavior undefined. */
3276 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02003277 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003278
Gilles Peskined223b522018-06-11 18:12:58 +02003279 /* ipad contains the key followed by garbage. Xor and fill with 0x36
3280 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003281 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02003282 ipad[i] ^= 0x36;
3283 memset( ipad + key_length, 0x36, block_size - key_length );
3284
3285 /* Copy the key material from ipad to opad, flipping the requisite bits,
3286 * and filling the rest of opad with the requisite constant. */
3287 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02003288 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
3289 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003290
Gilles Peskine01126fa2018-07-12 17:04:55 +02003291 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003292 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02003293 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003294
Gilles Peskine01126fa2018-07-12 17:04:55 +02003295 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02003296
3297cleanup:
Steven Cooreman29149862020-08-05 15:43:42 +02003298 mbedtls_platform_zeroize( ipad, sizeof( ipad ) );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02003299
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003300 return( status );
3301}
John Durkop6ba40d12020-11-10 08:50:04 -08003302#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003303
Gilles Peskine89167cb2018-07-08 20:12:23 +02003304static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02003305 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02003306 psa_algorithm_t alg,
3307 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003308{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003309 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003310 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003311 psa_key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003312 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02003313 psa_key_usage_t usage =
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003314 is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH;
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02003315 uint8_t truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02003316 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003317
Jaeden Amero36ee5d02019-02-19 09:25:10 +00003318 /* A context must be freshly initialized before it can be set up. */
3319 if( operation->alg != 0 )
3320 {
3321 return( PSA_ERROR_BAD_STATE );
3322 }
3323
Gilles Peskined911eb72018-08-14 15:18:45 +02003324 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003325 if( status != PSA_SUCCESS )
3326 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003327 if( is_sign )
3328 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003329
Ronald Cron5c522922020-11-14 16:35:34 +01003330 status = psa_get_and_lock_transparent_key_slot_with_policy(
3331 key, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003332 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02003333 goto exit;
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02003334 key_bits = psa_get_key_slot_bits( slot );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02003335
Gilles Peskine8c9def32018-02-08 10:02:12 +01003336#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02003337 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02003338 {
3339 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02003340 mbedtls_cipher_info_from_psa( full_length_alg,
Gilles Peskine8e338702019-07-30 20:06:31 +02003341 slot->attr.type, key_bits, NULL );
Janos Follath24eed8d2019-11-22 13:21:35 +00003342 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinefbfac682018-07-08 20:51:54 +02003343 if( cipher_info == NULL )
3344 {
3345 status = PSA_ERROR_NOT_SUPPORTED;
3346 goto exit;
3347 }
3348 operation->mac_size = cipher_info->block_size;
3349 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
3350 status = mbedtls_to_psa_error( ret );
3351 }
3352 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01003353#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003354#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskined911eb72018-08-14 15:18:45 +02003355 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02003356 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02003357 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003358 if( hash_alg == 0 )
3359 {
3360 status = PSA_ERROR_NOT_SUPPORTED;
3361 goto exit;
3362 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02003363
3364 operation->mac_size = PSA_HASH_SIZE( hash_alg );
3365 /* Sanity check. This shouldn't fail on a valid configuration. */
3366 if( operation->mac_size == 0 ||
3367 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
3368 {
3369 status = PSA_ERROR_NOT_SUPPORTED;
3370 goto exit;
3371 }
3372
Gilles Peskine8e338702019-07-30 20:06:31 +02003373 if( slot->attr.type != PSA_KEY_TYPE_HMAC )
Gilles Peskine01126fa2018-07-12 17:04:55 +02003374 {
3375 status = PSA_ERROR_INVALID_ARGUMENT;
3376 goto exit;
3377 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02003378
Gilles Peskine01126fa2018-07-12 17:04:55 +02003379 status = psa_hmac_setup_internal( &operation->ctx.hmac,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02003380 slot->data.key.data,
3381 slot->data.key.bytes,
Gilles Peskine01126fa2018-07-12 17:04:55 +02003382 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003383 }
3384 else
John Durkopd0321952020-10-29 21:37:36 -07003385#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003386 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00003387 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02003388 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003389 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003390
Gilles Peskined911eb72018-08-14 15:18:45 +02003391 if( truncated == 0 )
3392 {
3393 /* The "normal" case: untruncated algorithm. Nothing to do. */
3394 }
3395 else if( truncated < 4 )
3396 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02003397 /* A very short MAC is too short for security since it can be
3398 * brute-forced. Ancient protocols with 32-bit MACs do exist,
3399 * so we make this our minimum, even though 32 bits is still
3400 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02003401 status = PSA_ERROR_NOT_SUPPORTED;
3402 }
3403 else if( truncated > operation->mac_size )
3404 {
3405 /* It's impossible to "truncate" to a larger length. */
3406 status = PSA_ERROR_INVALID_ARGUMENT;
3407 }
3408 else
3409 operation->mac_size = truncated;
3410
Gilles Peskinefbfac682018-07-08 20:51:54 +02003411exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003412 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003413 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02003414 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003415 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003416 else
3417 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003418 operation->key_set = 1;
3419 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02003420
Ronald Cron5c522922020-11-14 16:35:34 +01003421 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003422
Ronald Cron5c522922020-11-14 16:35:34 +01003423 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003424}
3425
Gilles Peskine89167cb2018-07-08 20:12:23 +02003426psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02003427 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02003428 psa_algorithm_t alg )
3429{
Ronald Croncf56a0a2020-08-04 09:51:30 +02003430 return( psa_mac_setup( operation, key, alg, 1 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003431}
3432
3433psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02003434 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02003435 psa_algorithm_t alg )
3436{
Ronald Croncf56a0a2020-08-04 09:51:30 +02003437 return( psa_mac_setup( operation, key, alg, 0 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003438}
3439
Gilles Peskine8c9def32018-02-08 10:02:12 +01003440psa_status_t psa_mac_update( psa_mac_operation_t *operation,
3441 const uint8_t *input,
3442 size_t input_length )
3443{
Gilles Peskinefbfac682018-07-08 20:51:54 +02003444 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003445 if( ! operation->key_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003446 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003447 if( operation->iv_required && ! operation->iv_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003448 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003449 operation->has_input = 1;
3450
Gilles Peskine8c9def32018-02-08 10:02:12 +01003451#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003452 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03003453 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02003454 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
3455 input, input_length );
3456 status = mbedtls_to_psa_error( ret );
3457 }
3458 else
3459#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003460#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003461 if( PSA_ALG_IS_HMAC( operation->alg ) )
3462 {
3463 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
3464 input_length );
3465 }
3466 else
John Durkopd0321952020-10-29 21:37:36 -07003467#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003468 {
3469 /* This shouldn't happen if `operation` was initialized by
3470 * a setup function. */
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003471 return( PSA_ERROR_BAD_STATE );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03003472 }
3473
Gilles Peskinefbfac682018-07-08 20:51:54 +02003474 if( status != PSA_SUCCESS )
3475 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003476 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003477}
3478
John Durkop6ba40d12020-11-10 08:50:04 -08003479#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02003480static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
3481 uint8_t *mac,
3482 size_t mac_size )
3483{
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02003484 uint8_t tmp[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine01126fa2018-07-12 17:04:55 +02003485 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
3486 size_t hash_size = 0;
3487 size_t block_size = psa_get_hash_block_size( hash_alg );
3488 psa_status_t status;
3489
Gilles Peskine01126fa2018-07-12 17:04:55 +02003490 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
3491 if( status != PSA_SUCCESS )
3492 return( status );
3493 /* From here on, tmp needs to be wiped. */
3494
3495 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
3496 if( status != PSA_SUCCESS )
3497 goto exit;
3498
3499 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
3500 if( status != PSA_SUCCESS )
3501 goto exit;
3502
3503 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
3504 if( status != PSA_SUCCESS )
3505 goto exit;
3506
Gilles Peskined911eb72018-08-14 15:18:45 +02003507 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
3508 if( status != PSA_SUCCESS )
3509 goto exit;
3510
3511 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003512
3513exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01003514 mbedtls_platform_zeroize( tmp, hash_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003515 return( status );
3516}
John Durkop6ba40d12020-11-10 08:50:04 -08003517#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine01126fa2018-07-12 17:04:55 +02003518
mohammad16036df908f2018-04-02 08:34:15 -07003519static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02003520 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003521 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003522{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02003523 if( ! operation->key_set )
3524 return( PSA_ERROR_BAD_STATE );
3525 if( operation->iv_required && ! operation->iv_set )
3526 return( PSA_ERROR_BAD_STATE );
3527
Gilles Peskine8c9def32018-02-08 10:02:12 +01003528 if( mac_size < operation->mac_size )
3529 return( PSA_ERROR_BUFFER_TOO_SMALL );
3530
Gilles Peskine8c9def32018-02-08 10:02:12 +01003531#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003532 if( operation->alg == PSA_ALG_CMAC )
3533 {
Gilles Peskined911eb72018-08-14 15:18:45 +02003534 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
3535 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
3536 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02003537 memcpy( mac, tmp, operation->mac_size );
Gilles Peskine3f108122018-12-07 18:14:53 +01003538 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003539 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003540 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02003541 else
3542#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003543#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003544 if( PSA_ALG_IS_HMAC( operation->alg ) )
3545 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02003546 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02003547 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003548 }
3549 else
John Durkopd0321952020-10-29 21:37:36 -07003550#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003551 {
3552 /* This shouldn't happen if `operation` was initialized by
3553 * a setup function. */
3554 return( PSA_ERROR_BAD_STATE );
3555 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01003556}
3557
Gilles Peskineacd4be32018-07-08 19:56:25 +02003558psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
3559 uint8_t *mac,
3560 size_t mac_size,
3561 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07003562{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003563 psa_status_t status;
3564
Jaeden Amero252ef282019-02-15 14:05:35 +00003565 if( operation->alg == 0 )
3566 {
3567 return( PSA_ERROR_BAD_STATE );
3568 }
3569
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003570 /* Fill the output buffer with something that isn't a valid mac
3571 * (barring an attack on the mac and deliberately-crafted input),
3572 * in case the caller doesn't check the return status properly. */
3573 *mac_length = mac_size;
3574 /* If mac_size is 0 then mac may be NULL and then the
3575 * call to memset would have undefined behavior. */
3576 if( mac_size != 0 )
3577 memset( mac, '!', mac_size );
3578
Gilles Peskine89167cb2018-07-08 20:12:23 +02003579 if( ! operation->is_sign )
3580 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003581 return( PSA_ERROR_BAD_STATE );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003582 }
mohammad16036df908f2018-04-02 08:34:15 -07003583
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003584 status = psa_mac_finish_internal( operation, mac, mac_size );
3585
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003586 if( status == PSA_SUCCESS )
3587 {
3588 status = psa_mac_abort( operation );
3589 if( status == PSA_SUCCESS )
3590 *mac_length = operation->mac_size;
3591 else
3592 memset( mac, '!', mac_size );
3593 }
3594 else
3595 psa_mac_abort( operation );
3596 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07003597}
3598
Gilles Peskineacd4be32018-07-08 19:56:25 +02003599psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
3600 const uint8_t *mac,
3601 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003602{
Gilles Peskine828ed142018-06-18 23:25:51 +02003603 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07003604 psa_status_t status;
3605
Jaeden Amero252ef282019-02-15 14:05:35 +00003606 if( operation->alg == 0 )
3607 {
3608 return( PSA_ERROR_BAD_STATE );
3609 }
3610
Gilles Peskine89167cb2018-07-08 20:12:23 +02003611 if( operation->is_sign )
3612 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003613 return( PSA_ERROR_BAD_STATE );
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003614 }
3615 if( operation->mac_size != mac_length )
3616 {
3617 status = PSA_ERROR_INVALID_SIGNATURE;
3618 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02003619 }
mohammad16036df908f2018-04-02 08:34:15 -07003620
3621 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003622 actual_mac, sizeof( actual_mac ) );
Gilles Peskine28cd4162020-01-20 16:31:06 +01003623 if( status != PSA_SUCCESS )
3624 goto cleanup;
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003625
3626 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
3627 status = PSA_ERROR_INVALID_SIGNATURE;
3628
3629cleanup:
3630 if( status == PSA_SUCCESS )
3631 status = psa_mac_abort( operation );
3632 else
3633 psa_mac_abort( operation );
3634
Gilles Peskine3f108122018-12-07 18:14:53 +01003635 mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02003636
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003637 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003638}
3639
3640
Gilles Peskine20035e32018-02-03 22:44:14 +01003641
Gilles Peskine20035e32018-02-03 22:44:14 +01003642/****************************************************************/
3643/* Asymmetric cryptography */
3644/****************************************************************/
3645
John Durkop6ba40d12020-11-10 08:50:04 -08003646#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3647 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02003648/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003649 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02003650static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
3651 size_t hash_length,
3652 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003653{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02003654 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02003655 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003656 *md_alg = mbedtls_md_get_type( md_info );
3657
3658 /* The Mbed TLS RSA module uses an unsigned int for hash length
3659 * parameters. Validate that it fits so that we don't risk an
3660 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003661#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003662 if( hash_length > UINT_MAX )
3663 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003664#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003665
John Durkop0e005192020-10-31 22:06:54 -07003666#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003667 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
3668 * must be correct. */
3669 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
3670 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003671 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003672 if( md_info == NULL )
3673 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02003674 if( mbedtls_md_get_size( md_info ) != hash_length )
3675 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003676 }
John Durkop0e005192020-10-31 22:06:54 -07003677#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003678
John Durkop0e005192020-10-31 22:06:54 -07003679#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003680 /* PSS requires a hash internally. */
3681 if( PSA_ALG_IS_RSA_PSS( alg ) )
3682 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02003683 if( md_info == NULL )
3684 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003685 }
John Durkop0e005192020-10-31 22:06:54 -07003686#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003687
Gilles Peskine61b91d42018-06-08 16:09:36 +02003688 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003689}
3690
Gilles Peskine2b450e32018-06-27 15:42:46 +02003691static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
3692 psa_algorithm_t alg,
3693 const uint8_t *hash,
3694 size_t hash_length,
3695 uint8_t *signature,
3696 size_t signature_size,
3697 size_t *signature_length )
3698{
3699 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003700 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003701 mbedtls_md_type_t md_alg;
3702
3703 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
3704 if( status != PSA_SUCCESS )
3705 return( status );
3706
Gilles Peskine630a18a2018-06-29 17:49:35 +02003707 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02003708 return( PSA_ERROR_BUFFER_TOO_SMALL );
3709
John Durkop0e005192020-10-31 22:06:54 -07003710#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003711 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
3712 {
3713 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
3714 MBEDTLS_MD_NONE );
3715 ret = mbedtls_rsa_pkcs1_sign( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003716 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003717 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003718 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003719 md_alg,
3720 (unsigned int) hash_length,
3721 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003722 signature );
3723 }
3724 else
John Durkop0e005192020-10-31 22:06:54 -07003725#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
3726#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003727 if( PSA_ALG_IS_RSA_PSS( alg ) )
3728 {
3729 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3730 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003731 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003732 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003733 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003734 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003735 (unsigned int) hash_length,
3736 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003737 signature );
3738 }
3739 else
John Durkop0e005192020-10-31 22:06:54 -07003740#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003741 {
3742 return( PSA_ERROR_INVALID_ARGUMENT );
3743 }
3744
3745 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02003746 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003747 return( mbedtls_to_psa_error( ret ) );
3748}
3749
3750static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
3751 psa_algorithm_t alg,
3752 const uint8_t *hash,
3753 size_t hash_length,
3754 const uint8_t *signature,
3755 size_t signature_length )
3756{
3757 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003758 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003759 mbedtls_md_type_t md_alg;
3760
3761 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
3762 if( status != PSA_SUCCESS )
3763 return( status );
3764
Gilles Peskine89cc74f2019-09-12 22:08:23 +02003765 if( signature_length != mbedtls_rsa_get_len( rsa ) )
3766 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003767
John Durkop0e005192020-10-31 22:06:54 -07003768#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003769 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
3770 {
3771 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
3772 MBEDTLS_MD_NONE );
3773 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003774 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003775 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003776 MBEDTLS_RSA_PUBLIC,
3777 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003778 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003779 hash,
3780 signature );
3781 }
3782 else
John Durkop0e005192020-10-31 22:06:54 -07003783#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
3784#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003785 if( PSA_ALG_IS_RSA_PSS( alg ) )
3786 {
3787 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3788 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003789 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003790 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003791 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003792 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003793 (unsigned int) hash_length,
3794 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003795 signature );
3796 }
3797 else
John Durkop0e005192020-10-31 22:06:54 -07003798#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003799 {
3800 return( PSA_ERROR_INVALID_ARGUMENT );
3801 }
Gilles Peskineef12c632018-09-13 20:37:48 +02003802
3803 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
3804 * the rest of the signature is invalid". This has little use in
3805 * practice and PSA doesn't report this distinction. */
3806 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
3807 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003808 return( mbedtls_to_psa_error( ret ) );
3809}
John Durkop6ba40d12020-11-10 08:50:04 -08003810#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3811 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003812
John Durkop6ba40d12020-11-10 08:50:04 -08003813#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3814 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003815/* `ecp` cannot be const because `ecp->grp` needs to be non-const
3816 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
3817 * (even though these functions don't modify it). */
3818static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
3819 psa_algorithm_t alg,
3820 const uint8_t *hash,
3821 size_t hash_length,
3822 uint8_t *signature,
3823 size_t signature_size,
3824 size_t *signature_length )
3825{
Janos Follath24eed8d2019-11-22 13:21:35 +00003826 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003827 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003828 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003829 mbedtls_mpi_init( &r );
3830 mbedtls_mpi_init( &s );
3831
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003832 if( signature_size < 2 * curve_bytes )
3833 {
3834 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
3835 goto cleanup;
3836 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003837
John Durkop0ea39e02020-10-13 19:58:20 -07003838#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003839 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
3840 {
3841 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
3842 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
3843 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
Darryl Green5e843fa2019-09-05 14:06:34 +01003844 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det_ext( &ecp->grp, &r, &s,
3845 &ecp->d, hash,
3846 hash_length, md_alg,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003847 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003848 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003849 }
3850 else
John Durkop0ea39e02020-10-13 19:58:20 -07003851#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003852 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003853 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003854 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
3855 hash, hash_length,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003856 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003857 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003858 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003859
3860 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
3861 signature,
3862 curve_bytes ) );
3863 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
3864 signature + curve_bytes,
3865 curve_bytes ) );
3866
3867cleanup:
3868 mbedtls_mpi_free( &r );
3869 mbedtls_mpi_free( &s );
3870 if( ret == 0 )
3871 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003872 return( mbedtls_to_psa_error( ret ) );
3873}
3874
3875static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
3876 const uint8_t *hash,
3877 size_t hash_length,
3878 const uint8_t *signature,
3879 size_t signature_length )
3880{
Janos Follath24eed8d2019-11-22 13:21:35 +00003881 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003882 mbedtls_mpi r, s;
3883 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
3884 mbedtls_mpi_init( &r );
3885 mbedtls_mpi_init( &s );
3886
3887 if( signature_length != 2 * curve_bytes )
3888 return( PSA_ERROR_INVALID_SIGNATURE );
3889
3890 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
3891 signature,
3892 curve_bytes ) );
3893 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
3894 signature + curve_bytes,
3895 curve_bytes ) );
3896
Steven Cooremanacda8342020-07-24 23:09:52 +02003897 /* Check whether the public part is loaded. If not, load it. */
3898 if( mbedtls_ecp_is_zero( &ecp->Q ) )
3899 {
3900 MBEDTLS_MPI_CHK(
3901 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003902 mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
Steven Cooremanacda8342020-07-24 23:09:52 +02003903 }
3904
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003905 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
3906 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003907
3908cleanup:
3909 mbedtls_mpi_free( &r );
3910 mbedtls_mpi_free( &s );
3911 return( mbedtls_to_psa_error( ret ) );
3912}
John Durkop6ba40d12020-11-10 08:50:04 -08003913#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3914 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003915
Ronald Croncf56a0a2020-08-04 09:51:30 +02003916psa_status_t psa_sign_hash( mbedtls_svc_key_id_t key,
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003917 psa_algorithm_t alg,
3918 const uint8_t *hash,
3919 size_t hash_length,
3920 uint8_t *signature,
3921 size_t signature_size,
3922 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01003923{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003924 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003925 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003926 psa_key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003927
3928 *signature_length = signature_size;
Gilles Peskine4019f0e2019-09-12 22:05:59 +02003929 /* Immediately reject a zero-length signature buffer. This guarantees
3930 * that signature must be a valid pointer. (On the other hand, the hash
3931 * buffer can in principle be empty since it doesn't actually have
3932 * to be a hash.) */
3933 if( signature_size == 0 )
3934 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003935
Ronald Cron5c522922020-11-14 16:35:34 +01003936 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
3937 PSA_KEY_USAGE_SIGN_HASH,
3938 alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003939 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003940 goto exit;
Gilles Peskine8e338702019-07-30 20:06:31 +02003941 if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003942 {
3943 status = PSA_ERROR_INVALID_ARGUMENT;
3944 goto exit;
3945 }
Gilles Peskine20035e32018-02-03 22:44:14 +01003946
Steven Cooremancd84cb42020-07-16 20:28:36 +02003947 /* Try any of the available accelerators first */
3948 status = psa_driver_wrapper_sign_hash( slot,
3949 alg,
3950 hash,
3951 hash_length,
3952 signature,
3953 signature_size,
3954 signature_length );
Steven Cooreman8d2bde72020-09-04 13:06:39 +02003955 if( status != PSA_ERROR_NOT_SUPPORTED ||
3956 psa_key_lifetime_is_external( slot->attr.lifetime ) )
Steven Cooremancd84cb42020-07-16 20:28:36 +02003957 goto exit;
3958
Steven Cooreman7a250572020-07-17 16:43:05 +02003959 /* If the operation was not supported by any accelerator, try fallback. */
John Durkop6ba40d12020-11-10 08:50:04 -08003960#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3961 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8e338702019-07-30 20:06:31 +02003962 if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskine20035e32018-02-03 22:44:14 +01003963 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003964 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02003965
Steven Cooreman4fed4552020-08-03 14:46:03 +02003966 status = psa_load_rsa_representation( slot->attr.type,
3967 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02003968 slot->data.key.bytes,
Steven Cooremana01795d2020-07-24 22:48:15 +02003969 &rsa );
3970 if( status != PSA_SUCCESS )
3971 goto exit;
3972
Steven Cooremana2371e52020-07-28 14:30:39 +02003973 status = psa_rsa_sign( rsa,
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003974 alg,
3975 hash, hash_length,
3976 signature, signature_size,
3977 signature_length );
Steven Cooremana01795d2020-07-24 22:48:15 +02003978
Steven Cooremana2371e52020-07-28 14:30:39 +02003979 mbedtls_rsa_free( rsa );
3980 mbedtls_free( rsa );
Gilles Peskine20035e32018-02-03 22:44:14 +01003981 }
3982 else
John Durkop6ba40d12020-11-10 08:50:04 -08003983#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3984 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine8e338702019-07-30 20:06:31 +02003985 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01003986 {
John Durkop9814fa22020-11-04 12:28:15 -08003987#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3988 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea05219c2018-11-16 16:02:56 +01003989 if(
John Durkop0ea39e02020-10-13 19:58:20 -07003990#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea05219c2018-11-16 16:02:56 +01003991 PSA_ALG_IS_ECDSA( alg )
3992#else
3993 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
3994#endif
3995 )
Steven Cooremanacda8342020-07-24 23:09:52 +02003996 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003997 mbedtls_ecp_keypair *ecp = NULL;
Steven Cooreman4fed4552020-08-03 14:46:03 +02003998 status = psa_load_ecp_representation( slot->attr.type,
3999 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02004000 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02004001 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02004002 if( status != PSA_SUCCESS )
4003 goto exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02004004 status = psa_ecdsa_sign( ecp,
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02004005 alg,
4006 hash, hash_length,
4007 signature, signature_size,
4008 signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02004009 mbedtls_ecp_keypair_free( ecp );
4010 mbedtls_free( ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02004011 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004012 else
John Durkop9814fa22020-11-04 12:28:15 -08004013#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
4014 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004015 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02004016 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004017 }
itayzafrir5c753392018-05-08 11:18:38 +03004018 }
4019 else
itayzafrir5c753392018-05-08 11:18:38 +03004020 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02004021 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01004022 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02004023
4024exit:
4025 /* Fill the unused part of the output buffer (the whole buffer on error,
4026 * the trailing part on success) with something that isn't a valid mac
4027 * (barring an attack on the mac and deliberately-crafted input),
4028 * in case the caller doesn't check the return status properly. */
4029 if( status == PSA_SUCCESS )
4030 memset( signature + *signature_length, '!',
4031 signature_size - *signature_length );
Gilles Peskine4019f0e2019-09-12 22:05:59 +02004032 else
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02004033 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004034 /* If signature_size is 0 then we have nothing to do. We must not call
4035 * memset because signature may be NULL in this case. */
Ronald Cronf95a2b12020-10-22 15:24:49 +02004036
Ronald Cron5c522922020-11-14 16:35:34 +01004037 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004038
Ronald Cron5c522922020-11-14 16:35:34 +01004039 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
itayzafrir5c753392018-05-08 11:18:38 +03004040}
4041
Ronald Croncf56a0a2020-08-04 09:51:30 +02004042psa_status_t psa_verify_hash( mbedtls_svc_key_id_t key,
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004043 psa_algorithm_t alg,
4044 const uint8_t *hash,
4045 size_t hash_length,
4046 const uint8_t *signature,
4047 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03004048{
Ronald Cronf95a2b12020-10-22 15:24:49 +02004049 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01004050 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01004051 psa_key_slot_t *slot;
Gilles Peskine2b450e32018-06-27 15:42:46 +02004052
Ronald Cron5c522922020-11-14 16:35:34 +01004053 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
4054 PSA_KEY_USAGE_VERIFY_HASH,
4055 alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004056 if( status != PSA_SUCCESS )
4057 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03004058
Steven Cooreman55ae2172020-07-17 19:46:15 +02004059 /* Try any of the available accelerators first */
4060 status = psa_driver_wrapper_verify_hash( slot,
4061 alg,
4062 hash,
4063 hash_length,
4064 signature,
4065 signature_length );
Steven Cooreman8d2bde72020-09-04 13:06:39 +02004066 if( status != PSA_ERROR_NOT_SUPPORTED ||
4067 psa_key_lifetime_is_external( slot->attr.lifetime ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004068 goto exit;
Steven Cooreman55ae2172020-07-17 19:46:15 +02004069
John Durkop6ba40d12020-11-10 08:50:04 -08004070#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
4071 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8e338702019-07-30 20:06:31 +02004072 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004073 {
Steven Cooremana2371e52020-07-28 14:30:39 +02004074 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02004075
Steven Cooreman4fed4552020-08-03 14:46:03 +02004076 status = psa_load_rsa_representation( slot->attr.type,
4077 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02004078 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02004079 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02004080 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004081 goto exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02004082
Steven Cooremana2371e52020-07-28 14:30:39 +02004083 status = psa_rsa_verify( rsa,
Steven Cooremana01795d2020-07-24 22:48:15 +02004084 alg,
4085 hash, hash_length,
4086 signature, signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02004087 mbedtls_rsa_free( rsa );
4088 mbedtls_free( rsa );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004089 goto exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004090 }
4091 else
John Durkop6ba40d12020-11-10 08:50:04 -08004092#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
4093 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine8e338702019-07-30 20:06:31 +02004094 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
itayzafrir5c753392018-05-08 11:18:38 +03004095 {
John Durkop9814fa22020-11-04 12:28:15 -08004096#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
4097 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004098 if( PSA_ALG_IS_ECDSA( alg ) )
Steven Cooremanacda8342020-07-24 23:09:52 +02004099 {
Steven Cooremana2371e52020-07-28 14:30:39 +02004100 mbedtls_ecp_keypair *ecp = NULL;
Steven Cooreman4fed4552020-08-03 14:46:03 +02004101 status = psa_load_ecp_representation( slot->attr.type,
4102 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02004103 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02004104 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02004105 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004106 goto exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02004107 status = psa_ecdsa_verify( ecp,
Steven Cooremanacda8342020-07-24 23:09:52 +02004108 hash, hash_length,
4109 signature, signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02004110 mbedtls_ecp_keypair_free( ecp );
4111 mbedtls_free( ecp );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004112 goto exit;
Steven Cooremanacda8342020-07-24 23:09:52 +02004113 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004114 else
John Durkop9814fa22020-11-04 12:28:15 -08004115#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
4116 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004117 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004118 status = PSA_ERROR_INVALID_ARGUMENT;
4119 goto exit;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004120 }
itayzafrir5c753392018-05-08 11:18:38 +03004121 }
Gilles Peskine20035e32018-02-03 22:44:14 +01004122 else
Gilles Peskine20035e32018-02-03 22:44:14 +01004123 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004124 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01004125 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004126
4127exit:
Ronald Cron5c522922020-11-14 16:35:34 +01004128 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004129
Ronald Cron5c522922020-11-14 16:35:34 +01004130 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine20035e32018-02-03 22:44:14 +01004131}
4132
John Durkop0e005192020-10-31 22:06:54 -07004133#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine072ac562018-06-30 00:21:29 +02004134static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
4135 mbedtls_rsa_context *rsa )
4136{
4137 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
4138 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
4139 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
4140 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
4141}
John Durkop0e005192020-10-31 22:06:54 -07004142#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Gilles Peskine072ac562018-06-30 00:21:29 +02004143
Ronald Croncf56a0a2020-08-04 09:51:30 +02004144psa_status_t psa_asymmetric_encrypt( mbedtls_svc_key_id_t key,
Gilles Peskine61b91d42018-06-08 16:09:36 +02004145 psa_algorithm_t alg,
4146 const uint8_t *input,
4147 size_t input_length,
4148 const uint8_t *salt,
4149 size_t salt_length,
4150 uint8_t *output,
4151 size_t output_size,
4152 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004153{
Ronald Cronf95a2b12020-10-22 15:24:49 +02004154 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01004155 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01004156 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004157
Darryl Green5cc689a2018-07-24 15:34:10 +01004158 (void) input;
4159 (void) input_length;
4160 (void) salt;
4161 (void) output;
4162 (void) output_size;
4163
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03004164 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004165
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02004166 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
4167 return( PSA_ERROR_INVALID_ARGUMENT );
4168
Ronald Cron5c522922020-11-14 16:35:34 +01004169 status = psa_get_and_lock_transparent_key_slot_with_policy(
4170 key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004171 if( status != PSA_SUCCESS )
4172 return( status );
Gilles Peskine8e338702019-07-30 20:06:31 +02004173 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) ||
4174 PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004175 {
4176 status = PSA_ERROR_INVALID_ARGUMENT;
4177 goto exit;
4178 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004179
John Durkop6ba40d12020-11-10 08:50:04 -08004180#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
4181 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine8e338702019-07-30 20:06:31 +02004182 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004183 {
Steven Cooremana2371e52020-07-28 14:30:39 +02004184 mbedtls_rsa_context *rsa = NULL;
Steven Cooreman4fed4552020-08-03 14:46:03 +02004185 status = psa_load_rsa_representation( slot->attr.type,
4186 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02004187 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02004188 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02004189 if( status != PSA_SUCCESS )
Steven Cooreman4fed4552020-08-03 14:46:03 +02004190 goto rsa_exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02004191
4192 if( output_size < mbedtls_rsa_get_len( rsa ) )
Steven Cooremana01795d2020-07-24 22:48:15 +02004193 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004194 status = PSA_ERROR_BUFFER_TOO_SMALL;
4195 goto rsa_exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02004196 }
John Durkop0e005192020-10-31 22:06:54 -07004197#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
Gilles Peskine6afe7892018-05-31 13:16:08 +02004198 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004199 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004200 status = mbedtls_to_psa_error(
4201 mbedtls_rsa_pkcs1_encrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004202 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004203 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02004204 MBEDTLS_RSA_PUBLIC,
4205 input_length,
4206 input,
4207 output ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004208 }
4209 else
John Durkop0e005192020-10-31 22:06:54 -07004210#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
4211#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02004212 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004213 {
Steven Cooremana2371e52020-07-28 14:30:39 +02004214 psa_rsa_oaep_set_padding_mode( alg, rsa );
Steven Cooreman4fed4552020-08-03 14:46:03 +02004215 status = mbedtls_to_psa_error(
4216 mbedtls_rsa_rsaes_oaep_encrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004217 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004218 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02004219 MBEDTLS_RSA_PUBLIC,
4220 salt, salt_length,
4221 input_length,
4222 input,
4223 output ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004224 }
4225 else
John Durkop0e005192020-10-31 22:06:54 -07004226#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004227 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004228 status = PSA_ERROR_INVALID_ARGUMENT;
4229 goto rsa_exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004230 }
Steven Cooreman4fed4552020-08-03 14:46:03 +02004231rsa_exit:
4232 if( status == PSA_SUCCESS )
Steven Cooremana2371e52020-07-28 14:30:39 +02004233 *output_length = mbedtls_rsa_get_len( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02004234
Steven Cooremana2371e52020-07-28 14:30:39 +02004235 mbedtls_rsa_free( rsa );
4236 mbedtls_free( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004237 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004238 else
John Durkop9814fa22020-11-04 12:28:15 -08004239#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
John Durkop6ba40d12020-11-10 08:50:04 -08004240 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004241 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004242 status = PSA_ERROR_NOT_SUPPORTED;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004243 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004244
4245exit:
Ronald Cron5c522922020-11-14 16:35:34 +01004246 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004247
Ronald Cron5c522922020-11-14 16:35:34 +01004248 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004249}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004250
Ronald Croncf56a0a2020-08-04 09:51:30 +02004251psa_status_t psa_asymmetric_decrypt( mbedtls_svc_key_id_t key,
Gilles Peskine61b91d42018-06-08 16:09:36 +02004252 psa_algorithm_t alg,
4253 const uint8_t *input,
4254 size_t input_length,
4255 const uint8_t *salt,
4256 size_t salt_length,
4257 uint8_t *output,
4258 size_t output_size,
4259 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004260{
Ronald Cronf95a2b12020-10-22 15:24:49 +02004261 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01004262 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01004263 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004264
Darryl Green5cc689a2018-07-24 15:34:10 +01004265 (void) input;
4266 (void) input_length;
4267 (void) salt;
4268 (void) output;
4269 (void) output_size;
4270
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03004271 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004272
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02004273 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
4274 return( PSA_ERROR_INVALID_ARGUMENT );
4275
Ronald Cron5c522922020-11-14 16:35:34 +01004276 status = psa_get_and_lock_transparent_key_slot_with_policy(
4277 key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004278 if( status != PSA_SUCCESS )
4279 return( status );
Gilles Peskine8e338702019-07-30 20:06:31 +02004280 if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004281 {
4282 status = PSA_ERROR_INVALID_ARGUMENT;
4283 goto exit;
4284 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004285
John Durkop6ba40d12020-11-10 08:50:04 -08004286#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
4287 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine8e338702019-07-30 20:06:31 +02004288 if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004289 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004290 mbedtls_rsa_context *rsa = NULL;
4291 status = psa_load_rsa_representation( slot->attr.type,
4292 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02004293 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02004294 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02004295 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004296 goto exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004297
Steven Cooremana2371e52020-07-28 14:30:39 +02004298 if( input_length != mbedtls_rsa_get_len( rsa ) )
Steven Cooremana01795d2020-07-24 22:48:15 +02004299 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004300 status = PSA_ERROR_INVALID_ARGUMENT;
4301 goto rsa_exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02004302 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004303
John Durkop0e005192020-10-31 22:06:54 -07004304#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
Gilles Peskine6afe7892018-05-31 13:16:08 +02004305 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004306 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004307 status = mbedtls_to_psa_error(
4308 mbedtls_rsa_pkcs1_decrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004309 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004310 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02004311 MBEDTLS_RSA_PRIVATE,
4312 output_length,
4313 input,
4314 output,
4315 output_size ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004316 }
4317 else
John Durkop0e005192020-10-31 22:06:54 -07004318#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
4319#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02004320 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004321 {
Steven Cooremana2371e52020-07-28 14:30:39 +02004322 psa_rsa_oaep_set_padding_mode( alg, rsa );
Steven Cooreman4fed4552020-08-03 14:46:03 +02004323 status = mbedtls_to_psa_error(
4324 mbedtls_rsa_rsaes_oaep_decrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004325 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004326 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02004327 MBEDTLS_RSA_PRIVATE,
4328 salt, salt_length,
4329 output_length,
4330 input,
4331 output,
4332 output_size ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004333 }
4334 else
John Durkop0e005192020-10-31 22:06:54 -07004335#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004336 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004337 status = PSA_ERROR_INVALID_ARGUMENT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004338 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03004339
Steven Cooreman4fed4552020-08-03 14:46:03 +02004340rsa_exit:
Steven Cooremana2371e52020-07-28 14:30:39 +02004341 mbedtls_rsa_free( rsa );
4342 mbedtls_free( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004343 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004344 else
John Durkop6ba40d12020-11-10 08:50:04 -08004345#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
4346 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004347 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004348 status = PSA_ERROR_NOT_SUPPORTED;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004349 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004350
4351exit:
Ronald Cron5c522922020-11-14 16:35:34 +01004352 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004353
Ronald Cron5c522922020-11-14 16:35:34 +01004354 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004355}
Gilles Peskine20035e32018-02-03 22:44:14 +01004356
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004357
4358
mohammad1603503973b2018-03-12 15:59:30 +02004359/****************************************************************/
4360/* Symmetric cryptography */
4361/****************************************************************/
4362
Gilles Peskinee553c652018-06-04 16:22:46 +02004363static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004364 mbedtls_svc_key_id_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02004365 psa_algorithm_t alg,
4366 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02004367{
Ronald Cronf95a2b12020-10-22 15:24:49 +02004368 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01004369 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004370 int ret = 0;
Gilles Peskine2f060a82018-12-04 17:12:32 +01004371 psa_key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02004372 size_t key_bits;
4373 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004374 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
4375 PSA_KEY_USAGE_ENCRYPT :
4376 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02004377
Steven Cooremand3feccd2020-09-01 15:56:14 +02004378 /* A context must be freshly initialized before it can be set up. */
4379 if( operation->alg != 0 )
4380 return( PSA_ERROR_BAD_STATE );
4381
Steven Cooremana07b9972020-09-10 14:54:14 +02004382 /* The requested algorithm must be one that can be processed by cipher. */
4383 if( ! PSA_ALG_IS_CIPHER( alg ) )
Steven Cooremana07b9972020-09-10 14:54:14 +02004384 return( PSA_ERROR_INVALID_ARGUMENT );
Steven Cooremand3feccd2020-09-01 15:56:14 +02004385
Steven Cooremanef8575e2020-09-11 11:44:50 +02004386 /* Fetch key material from key storage. */
Ronald Cron5c522922020-11-14 16:35:34 +01004387 status = psa_get_and_lock_key_slot_with_policy( key, &slot, usage, alg );
Steven Cooremanef8575e2020-09-11 11:44:50 +02004388 if( status != PSA_SUCCESS )
4389 goto exit;
4390
4391 /* Initialize the operation struct members, except for alg. The alg member
4392 * is used to indicate to psa_cipher_abort that there are resources to free,
4393 * so we only set it after resources have been allocated/initialized. */
Steven Cooremana07b9972020-09-10 14:54:14 +02004394 operation->key_set = 0;
4395 operation->iv_set = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004396 operation->mbedtls_in_use = 0;
Steven Cooremana07b9972020-09-10 14:54:14 +02004397 operation->iv_size = 0;
4398 operation->block_size = 0;
4399 if( alg == PSA_ALG_ECB_NO_PADDING )
4400 operation->iv_required = 0;
4401 else
4402 operation->iv_required = 1;
4403
Steven Cooremana07b9972020-09-10 14:54:14 +02004404 /* Try doing the operation through a driver before using software fallback. */
Steven Cooreman37941cb2020-07-28 18:49:51 +02004405 if( cipher_operation == MBEDTLS_ENCRYPT )
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004406 status = psa_driver_wrapper_cipher_encrypt_setup( &operation->ctx.driver,
Steven Cooreman37941cb2020-07-28 18:49:51 +02004407 slot,
4408 alg );
4409 else
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004410 status = psa_driver_wrapper_cipher_decrypt_setup( &operation->ctx.driver,
Steven Cooreman37941cb2020-07-28 18:49:51 +02004411 slot,
4412 alg );
4413
Steven Cooremanef8575e2020-09-11 11:44:50 +02004414 if( status == PSA_SUCCESS )
Steven Cooreman6d81f7e2020-09-14 13:14:31 +02004415 {
Steven Cooremanef8575e2020-09-11 11:44:50 +02004416 /* Once the driver context is initialised, it needs to be freed using
4417 * psa_cipher_abort. Indicate this through setting alg. */
4418 operation->alg = alg;
Steven Cooreman6d81f7e2020-09-14 13:14:31 +02004419 }
Steven Cooremanef8575e2020-09-11 11:44:50 +02004420
Steven Cooremand3feccd2020-09-01 15:56:14 +02004421 if( status != PSA_ERROR_NOT_SUPPORTED ||
4422 psa_key_lifetime_is_external( slot->attr.lifetime ) )
4423 goto exit;
4424
Steven Cooremana07b9972020-09-10 14:54:14 +02004425 /* Proceed with initializing an mbed TLS cipher context if no driver is
Steven Cooremand3feccd2020-09-01 15:56:14 +02004426 * available for the given algorithm & key. */
4427 mbedtls_cipher_init( &operation->ctx.cipher );
mohammad1603503973b2018-03-12 15:59:30 +02004428
Steven Cooremana07b9972020-09-10 14:54:14 +02004429 /* Once the cipher context is initialised, it needs to be freed using
Steven Cooremanef8575e2020-09-11 11:44:50 +02004430 * psa_cipher_abort. Indicate there is something to be freed through setting
4431 * alg, and indicate the operation is being done using mbedtls crypto through
4432 * setting mbedtls_in_use. */
Steven Cooremana07b9972020-09-10 14:54:14 +02004433 operation->alg = alg;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004434 operation->mbedtls_in_use = 1;
Steven Cooremana07b9972020-09-10 14:54:14 +02004435
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02004436 key_bits = psa_get_key_slot_bits( slot );
Gilles Peskine8e338702019-07-30 20:06:31 +02004437 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->attr.type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02004438 if( cipher_info == NULL )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004439 {
4440 status = PSA_ERROR_NOT_SUPPORTED;
4441 goto exit;
4442 }
mohammad1603503973b2018-03-12 15:59:30 +02004443
mohammad1603503973b2018-03-12 15:59:30 +02004444 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03004445 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004446 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004447
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004448#if defined(MBEDTLS_DES_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02004449 if( slot->attr.type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004450 {
4451 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02004452 uint8_t keys[24];
Steven Cooreman71fd80d2020-07-07 21:12:27 +02004453 memcpy( keys, slot->data.key.data, 16 );
4454 memcpy( keys + 16, slot->data.key.data, 8 );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004455 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
4456 keys,
4457 192, cipher_operation );
4458 }
4459 else
4460#endif
4461 {
4462 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02004463 slot->data.key.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004464 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004465 }
Moran Peker41deec42018-04-04 15:43:05 +03004466 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004467 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004468
mohammad16038481e742018-03-18 13:57:31 +02004469#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004470 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02004471 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004472 case PSA_ALG_CBC_NO_PADDING:
4473 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
4474 MBEDTLS_PADDING_NONE );
4475 break;
4476 case PSA_ALG_CBC_PKCS7:
4477 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
4478 MBEDTLS_PADDING_PKCS7 );
4479 break;
4480 default:
4481 /* The algorithm doesn't involve padding. */
4482 ret = 0;
4483 break;
4484 }
4485 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004486 goto exit;
mohammad16038481e742018-03-18 13:57:31 +02004487#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
4488
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004489 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
Gilles Peskine8e338702019-07-30 20:06:31 +02004490 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ) );
Steven Cooremana6033e92020-08-25 11:47:50 +02004491 if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 &&
4492 alg != PSA_ALG_ECB_NO_PADDING )
mohammad16038481e742018-03-18 13:57:31 +02004493 {
Gilles Peskine8e338702019-07-30 20:06:31 +02004494 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type );
mohammad16038481e742018-03-18 13:57:31 +02004495 }
Gilles Peskine26869f22019-05-06 15:25:00 +02004496#if defined(MBEDTLS_CHACHA20_C)
4497 else
Bence Szépkúticbe39532020-12-08 00:01:31 +01004498 if( alg == PSA_ALG_STREAM_CIPHER && slot->attr.type == PSA_KEY_TYPE_CHACHA20 )
Gilles Peskine26869f22019-05-06 15:25:00 +02004499 operation->iv_size = 12;
4500#endif
mohammad1603503973b2018-03-12 15:59:30 +02004501
Steven Cooreman7df02922020-09-09 15:28:49 +02004502 status = PSA_SUCCESS;
4503
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004504exit:
Steven Cooreman7df02922020-09-09 15:28:49 +02004505 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004506 status = mbedtls_to_psa_error( ret );
Steven Cooreman7df02922020-09-09 15:28:49 +02004507 if( status == PSA_SUCCESS )
4508 {
4509 /* Update operation flags for both driver and software implementations */
4510 operation->key_set = 1;
4511 }
4512 else
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004513 psa_cipher_abort( operation );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004514
Ronald Cron5c522922020-11-14 16:35:34 +01004515 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004516
Ronald Cron5c522922020-11-14 16:35:34 +01004517 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
mohammad1603503973b2018-03-12 15:59:30 +02004518}
4519
Gilles Peskinefe119512018-07-08 21:39:34 +02004520psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004521 mbedtls_svc_key_id_t key,
Gilles Peskinefe119512018-07-08 21:39:34 +02004522 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02004523{
Ronald Croncf56a0a2020-08-04 09:51:30 +02004524 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02004525}
4526
Gilles Peskinefe119512018-07-08 21:39:34 +02004527psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004528 mbedtls_svc_key_id_t key,
Gilles Peskinefe119512018-07-08 21:39:34 +02004529 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02004530{
Ronald Croncf56a0a2020-08-04 09:51:30 +02004531 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02004532}
4533
Gilles Peskinefe119512018-07-08 21:39:34 +02004534psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004535 uint8_t *iv,
Gilles Peskinefe119512018-07-08 21:39:34 +02004536 size_t iv_size,
4537 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02004538{
itayzafrir534bd7c2018-08-02 13:56:32 +03004539 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00004540 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooreman7df02922020-09-09 15:28:49 +02004541 if( operation->iv_set || ! operation->iv_required )
4542 {
4543 return( PSA_ERROR_BAD_STATE );
4544 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004545
Steven Cooremanef8575e2020-09-11 11:44:50 +02004546 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004547 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004548 status = psa_driver_wrapper_cipher_generate_iv( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004549 iv,
4550 iv_size,
4551 iv_length );
4552 goto exit;
4553 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004554
Moran Peker41deec42018-04-04 15:43:05 +03004555 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02004556 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004557 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03004558 goto exit;
4559 }
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004560 ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004561 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03004562 if( ret != 0 )
4563 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004564 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02004565 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004566 }
Gilles Peskinee553c652018-06-04 16:22:46 +02004567
mohammad16038481e742018-03-18 13:57:31 +02004568 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03004569 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03004570
Moran Peker395db872018-05-31 14:07:14 +03004571exit:
Steven Cooreman7df02922020-09-09 15:28:49 +02004572 if( status == PSA_SUCCESS )
4573 operation->iv_set = 1;
4574 else
Moran Peker395db872018-05-31 14:07:14 +03004575 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004576 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004577}
4578
Gilles Peskinefe119512018-07-08 21:39:34 +02004579psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004580 const uint8_t *iv,
Gilles Peskinefe119512018-07-08 21:39:34 +02004581 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02004582{
itayzafrir534bd7c2018-08-02 13:56:32 +03004583 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00004584 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooreman7df02922020-09-09 15:28:49 +02004585 if( operation->iv_set || ! operation->iv_required )
4586 {
4587 return( PSA_ERROR_BAD_STATE );
4588 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004589
Steven Cooremanef8575e2020-09-11 11:44:50 +02004590 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004591 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004592 status = psa_driver_wrapper_cipher_set_iv( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004593 iv,
4594 iv_length );
4595 goto exit;
4596 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004597
Moran Pekera28258c2018-05-29 16:25:04 +03004598 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03004599 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004600 status = PSA_ERROR_INVALID_ARGUMENT;
4601 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03004602 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004603 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
4604 status = mbedtls_to_psa_error( ret );
4605exit:
4606 if( status == PSA_SUCCESS )
4607 operation->iv_set = 1;
4608 else
mohammad1603503973b2018-03-12 15:59:30 +02004609 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004610 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004611}
4612
Steven Cooreman177deba2020-09-07 17:14:14 +02004613/* Process input for which the algorithm is set to ECB mode. This requires
4614 * manual processing, since the PSA API is defined as being able to process
4615 * arbitrary-length calls to psa_cipher_update() with ECB mode, but the
4616 * underlying mbedtls_cipher_update only takes full blocks. */
4617static psa_status_t psa_cipher_update_ecb_internal(
4618 mbedtls_cipher_context_t *ctx,
4619 const uint8_t *input,
4620 size_t input_length,
4621 uint8_t *output,
4622 size_t output_size,
4623 size_t *output_length )
4624{
4625 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4626 size_t block_size = ctx->cipher_info->block_size;
4627 size_t internal_output_length = 0;
4628 *output_length = 0;
4629
4630 if( input_length == 0 )
4631 {
4632 status = PSA_SUCCESS;
4633 goto exit;
4634 }
4635
4636 if( ctx->unprocessed_len > 0 )
4637 {
4638 /* Fill up to block size, and run the block if there's a full one. */
4639 size_t bytes_to_copy = block_size - ctx->unprocessed_len;
4640
4641 if( input_length < bytes_to_copy )
4642 bytes_to_copy = input_length;
4643
4644 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
4645 input, bytes_to_copy );
4646 input_length -= bytes_to_copy;
4647 input += bytes_to_copy;
4648 ctx->unprocessed_len += bytes_to_copy;
4649
4650 if( ctx->unprocessed_len == block_size )
4651 {
4652 status = mbedtls_to_psa_error(
4653 mbedtls_cipher_update( ctx,
4654 ctx->unprocessed_data,
4655 block_size,
4656 output, &internal_output_length ) );
4657
4658 if( status != PSA_SUCCESS )
4659 goto exit;
4660
4661 output += internal_output_length;
4662 output_size -= internal_output_length;
4663 *output_length += internal_output_length;
4664 ctx->unprocessed_len = 0;
4665 }
4666 }
4667
4668 while( input_length >= block_size )
4669 {
4670 /* Run all full blocks we have, one by one */
4671 status = mbedtls_to_psa_error(
4672 mbedtls_cipher_update( ctx, input,
4673 block_size,
4674 output, &internal_output_length ) );
4675
4676 if( status != PSA_SUCCESS )
4677 goto exit;
4678
4679 input_length -= block_size;
4680 input += block_size;
4681
4682 output += internal_output_length;
4683 output_size -= internal_output_length;
4684 *output_length += internal_output_length;
4685 }
4686
4687 if( input_length > 0 )
4688 {
4689 /* Save unprocessed bytes for later processing */
4690 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
4691 input, input_length );
4692 ctx->unprocessed_len += input_length;
4693 }
4694
4695 status = PSA_SUCCESS;
4696
4697exit:
4698 return( status );
4699}
4700
Gilles Peskinee553c652018-06-04 16:22:46 +02004701psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
4702 const uint8_t *input,
4703 size_t input_length,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004704 uint8_t *output,
Gilles Peskinee553c652018-06-04 16:22:46 +02004705 size_t output_size,
4706 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02004707{
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004708 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine89d789c2018-06-04 17:17:16 +02004709 size_t expected_output_size;
Steven Cooreman7df02922020-09-09 15:28:49 +02004710 if( operation->alg == 0 )
4711 {
4712 return( PSA_ERROR_BAD_STATE );
4713 }
4714 if( operation->iv_required && ! operation->iv_set )
4715 {
4716 return( PSA_ERROR_BAD_STATE );
4717 }
Jaeden Ameroab439972019-02-15 14:12:05 +00004718
Steven Cooremanef8575e2020-09-11 11:44:50 +02004719 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004720 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004721 status = psa_driver_wrapper_cipher_update( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004722 input,
4723 input_length,
4724 output,
4725 output_size,
4726 output_length );
4727 goto exit;
4728 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004729
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004730 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02004731 {
4732 /* Take the unprocessed partial block left over from previous
4733 * update calls, if any, plus the input to this call. Remove
4734 * the last partial block, if any. You get the data that will be
4735 * output in this call. */
4736 expected_output_size =
4737 ( operation->ctx.cipher.unprocessed_len + input_length )
4738 / operation->block_size * operation->block_size;
4739 }
4740 else
4741 {
4742 expected_output_size = input_length;
4743 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004744
Gilles Peskine89d789c2018-06-04 17:17:16 +02004745 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03004746 {
4747 status = PSA_ERROR_BUFFER_TOO_SMALL;
4748 goto exit;
4749 }
mohammad160382759612018-03-12 18:16:40 +02004750
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004751 if( operation->alg == PSA_ALG_ECB_NO_PADDING )
4752 {
4753 /* mbedtls_cipher_update has an API inconsistency: it will only
4754 * process a single block at a time in ECB mode. Abstract away that
4755 * inconsistency here to match the PSA API behaviour. */
Steven Cooreman177deba2020-09-07 17:14:14 +02004756 status = psa_cipher_update_ecb_internal( &operation->ctx.cipher,
4757 input,
4758 input_length,
4759 output,
4760 output_size,
4761 output_length );
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004762 }
4763 else
4764 {
4765 status = mbedtls_to_psa_error(
4766 mbedtls_cipher_update( &operation->ctx.cipher, input,
4767 input_length, output, output_length ) );
4768 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004769exit:
4770 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02004771 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004772 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004773}
4774
Gilles Peskinee553c652018-06-04 16:22:46 +02004775psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
4776 uint8_t *output,
4777 size_t output_size,
4778 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02004779{
David Saadab4ecc272019-02-14 13:48:10 +02004780 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskinee553c652018-06-04 16:22:46 +02004781 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Steven Cooreman7df02922020-09-09 15:28:49 +02004782 if( operation->alg == 0 )
4783 {
4784 return( PSA_ERROR_BAD_STATE );
4785 }
4786 if( operation->iv_required && ! operation->iv_set )
4787 {
4788 return( PSA_ERROR_BAD_STATE );
4789 }
Moran Pekerbed71a22018-04-22 20:19:20 +03004790
Steven Cooremanef8575e2020-09-11 11:44:50 +02004791 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004792 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004793 status = psa_driver_wrapper_cipher_finish( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004794 output,
4795 output_size,
4796 output_length );
Steven Cooremanef8575e2020-09-11 11:44:50 +02004797 goto exit;
Steven Cooreman8b122252020-09-03 15:30:32 +02004798 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004799
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004800 if( operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03004801 {
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004802 if( operation->alg == PSA_ALG_ECB_NO_PADDING ||
Fredrik Strupef90e3012020-09-28 16:11:33 +02004803 operation->alg == PSA_ALG_CBC_NO_PADDING )
Steven Cooremana6033e92020-08-25 11:47:50 +02004804 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004805 status = PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004806 goto exit;
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004807 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004808 }
4809
Steven Cooremanef8575e2020-09-11 11:44:50 +02004810 status = mbedtls_to_psa_error(
4811 mbedtls_cipher_finish( &operation->ctx.cipher,
4812 temp_output_buffer,
4813 output_length ) );
4814 if( status != PSA_SUCCESS )
4815 goto exit;
Janos Follath315b51c2018-07-09 16:04:51 +01004816
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004817 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01004818 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004819 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004820 memcpy( output, temp_output_buffer, *output_length );
4821 else
Janos Follath315b51c2018-07-09 16:04:51 +01004822 status = PSA_ERROR_BUFFER_TOO_SMALL;
mohammad1603503973b2018-03-12 15:59:30 +02004823
Steven Cooremanef8575e2020-09-11 11:44:50 +02004824exit:
4825 if( operation->mbedtls_in_use == 1 )
4826 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01004827
Steven Cooremanef8575e2020-09-11 11:44:50 +02004828 if( status == PSA_SUCCESS )
4829 return( psa_cipher_abort( operation ) );
4830 else
4831 {
4832 *output_length = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004833 (void) psa_cipher_abort( operation );
Janos Follath315b51c2018-07-09 16:04:51 +01004834
Steven Cooremanef8575e2020-09-11 11:44:50 +02004835 return( status );
4836 }
mohammad1603503973b2018-03-12 15:59:30 +02004837}
4838
Gilles Peskinee553c652018-06-04 16:22:46 +02004839psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
4840{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004841 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02004842 {
Steven Cooremana07b9972020-09-10 14:54:14 +02004843 /* The object has (apparently) been initialized but it is not (yet)
Gilles Peskine81736312018-06-26 15:04:31 +02004844 * in use. It's ok to call abort on such an object, and there's
4845 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004846 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02004847 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004848
Gilles Peskinef9c2c092018-06-21 16:57:07 +02004849 /* Sanity check (shouldn't happen: operation->alg should
4850 * always have been initialized to a valid value). */
4851 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
4852 return( PSA_ERROR_BAD_STATE );
4853
Steven Cooremanef8575e2020-09-11 11:44:50 +02004854 if( operation->mbedtls_in_use == 0 )
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004855 psa_driver_wrapper_cipher_abort( &operation->ctx.driver );
Steven Cooremand3feccd2020-09-01 15:56:14 +02004856 else
4857 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02004858
Moran Peker41deec42018-04-04 15:43:05 +03004859 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004860 operation->key_set = 0;
4861 operation->iv_set = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004862 operation->mbedtls_in_use = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004863 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03004864 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004865 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03004866
Moran Peker395db872018-05-31 14:07:14 +03004867 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02004868}
4869
Gilles Peskinea0655c32018-04-30 17:06:50 +02004870
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004871
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004872
mohammad16035955c982018-04-26 00:53:03 +03004873/****************************************************************/
4874/* AEAD */
4875/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004876
Gilles Peskineedf9a652018-08-17 18:11:56 +02004877typedef struct
4878{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004879 psa_key_slot_t *slot;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004880 const mbedtls_cipher_info_t *cipher_info;
4881 union
4882 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004883 unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
Gilles Peskineedf9a652018-08-17 18:11:56 +02004884#if defined(MBEDTLS_CCM_C)
4885 mbedtls_ccm_context ccm;
4886#endif /* MBEDTLS_CCM_C */
4887#if defined(MBEDTLS_GCM_C)
4888 mbedtls_gcm_context gcm;
4889#endif /* MBEDTLS_GCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02004890#if defined(MBEDTLS_CHACHAPOLY_C)
4891 mbedtls_chachapoly_context chachapoly;
4892#endif /* MBEDTLS_CHACHAPOLY_C */
Gilles Peskineedf9a652018-08-17 18:11:56 +02004893 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004894 psa_algorithm_t core_alg;
4895 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004896 uint8_t tag_length;
4897} aead_operation_t;
4898
Ronald Cronf95a2b12020-10-22 15:24:49 +02004899#define AEAD_OPERATION_INIT {0, 0, {0}, 0, 0, 0}
4900
Gilles Peskine30a9e412019-01-14 18:36:12 +01004901static void psa_aead_abort_internal( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004902{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02004903 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004904 {
4905#if defined(MBEDTLS_CCM_C)
4906 case PSA_ALG_CCM:
4907 mbedtls_ccm_free( &operation->ctx.ccm );
4908 break;
4909#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004910#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02004911 case PSA_ALG_GCM:
4912 mbedtls_gcm_free( &operation->ctx.gcm );
4913 break;
4914#endif /* MBEDTLS_GCM_C */
4915 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004916
Ronald Cron5c522922020-11-14 16:35:34 +01004917 psa_unlock_key_slot( operation->slot );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004918}
4919
4920static psa_status_t psa_aead_setup( aead_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004921 mbedtls_svc_key_id_t key,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004922 psa_key_usage_t usage,
4923 psa_algorithm_t alg )
4924{
4925 psa_status_t status;
4926 size_t key_bits;
4927 mbedtls_cipher_id_t cipher_id;
4928
Ronald Cron5c522922020-11-14 16:35:34 +01004929 status = psa_get_and_lock_transparent_key_slot_with_policy(
4930 key, &operation->slot, usage, alg );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004931 if( status != PSA_SUCCESS )
4932 return( status );
4933
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02004934 key_bits = psa_get_key_slot_bits( operation->slot );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004935
4936 operation->cipher_info =
Gilles Peskine8e338702019-07-30 20:06:31 +02004937 mbedtls_cipher_info_from_psa( alg, operation->slot->attr.type, key_bits,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004938 &cipher_id );
4939 if( operation->cipher_info == NULL )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004940 {
4941 status = PSA_ERROR_NOT_SUPPORTED;
4942 goto cleanup;
4943 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004944
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004945 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004946 {
4947#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004948 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
4949 operation->core_alg = PSA_ALG_CCM;
4950 operation->full_tag_length = 16;
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004951 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
4952 * The call to mbedtls_ccm_encrypt_and_tag or
4953 * mbedtls_ccm_auth_decrypt will validate the tag length. */
Gilles Peskine8e338702019-07-30 20:06:31 +02004954 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004955 {
4956 status = PSA_ERROR_INVALID_ARGUMENT;
4957 goto cleanup;
4958 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004959 mbedtls_ccm_init( &operation->ctx.ccm );
4960 status = mbedtls_to_psa_error(
4961 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02004962 operation->slot->data.key.data,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004963 (unsigned int) key_bits ) );
4964 if( status != 0 )
4965 goto cleanup;
4966 break;
4967#endif /* MBEDTLS_CCM_C */
4968
4969#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004970 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
4971 operation->core_alg = PSA_ALG_GCM;
4972 operation->full_tag_length = 16;
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004973 /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
4974 * The call to mbedtls_gcm_crypt_and_tag or
4975 * mbedtls_gcm_auth_decrypt will validate the tag length. */
Gilles Peskine8e338702019-07-30 20:06:31 +02004976 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004977 {
4978 status = PSA_ERROR_INVALID_ARGUMENT;
4979 goto cleanup;
4980 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004981 mbedtls_gcm_init( &operation->ctx.gcm );
4982 status = mbedtls_to_psa_error(
4983 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02004984 operation->slot->data.key.data,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004985 (unsigned int) key_bits ) );
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004986 if( status != 0 )
4987 goto cleanup;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004988 break;
4989#endif /* MBEDTLS_GCM_C */
4990
Gilles Peskine26869f22019-05-06 15:25:00 +02004991#if defined(MBEDTLS_CHACHAPOLY_C)
4992 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CHACHA20_POLY1305, 0 ):
4993 operation->core_alg = PSA_ALG_CHACHA20_POLY1305;
4994 operation->full_tag_length = 16;
4995 /* We only support the default tag length. */
4996 if( alg != PSA_ALG_CHACHA20_POLY1305 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004997 {
4998 status = PSA_ERROR_NOT_SUPPORTED;
4999 goto cleanup;
5000 }
Gilles Peskine26869f22019-05-06 15:25:00 +02005001 mbedtls_chachapoly_init( &operation->ctx.chachapoly );
5002 status = mbedtls_to_psa_error(
5003 mbedtls_chachapoly_setkey( &operation->ctx.chachapoly,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02005004 operation->slot->data.key.data ) );
Gilles Peskine26869f22019-05-06 15:25:00 +02005005 if( status != 0 )
5006 goto cleanup;
5007 break;
5008#endif /* MBEDTLS_CHACHAPOLY_C */
5009
Gilles Peskineedf9a652018-08-17 18:11:56 +02005010 default:
Ronald Cronf95a2b12020-10-22 15:24:49 +02005011 status = PSA_ERROR_NOT_SUPPORTED;
5012 goto cleanup;
Gilles Peskineedf9a652018-08-17 18:11:56 +02005013 }
5014
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02005015 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
5016 {
5017 status = PSA_ERROR_INVALID_ARGUMENT;
5018 goto cleanup;
5019 }
5020 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02005021
Gilles Peskineedf9a652018-08-17 18:11:56 +02005022 return( PSA_SUCCESS );
5023
5024cleanup:
Gilles Peskine30a9e412019-01-14 18:36:12 +01005025 psa_aead_abort_internal( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02005026 return( status );
5027}
5028
Ronald Croncf56a0a2020-08-04 09:51:30 +02005029psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key,
mohammad16035955c982018-04-26 00:53:03 +03005030 psa_algorithm_t alg,
5031 const uint8_t *nonce,
5032 size_t nonce_length,
5033 const uint8_t *additional_data,
5034 size_t additional_data_length,
5035 const uint8_t *plaintext,
5036 size_t plaintext_length,
5037 uint8_t *ciphertext,
5038 size_t ciphertext_size,
5039 size_t *ciphertext_length )
5040{
mohammad16035955c982018-04-26 00:53:03 +03005041 psa_status_t status;
Ronald Cronf95a2b12020-10-22 15:24:49 +02005042 aead_operation_t operation = AEAD_OPERATION_INIT;
mohammad160315223a82018-06-03 17:19:55 +03005043 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02005044
mohammad1603f08a5502018-06-03 15:05:47 +03005045 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07005046
Ronald Croncf56a0a2020-08-04 09:51:30 +02005047 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02005048 if( status != PSA_SUCCESS )
5049 return( status );
mohammad16035955c982018-04-26 00:53:03 +03005050
Gilles Peskineedf9a652018-08-17 18:11:56 +02005051 /* For all currently supported modes, the tag is at the end of the
5052 * ciphertext. */
5053 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
5054 {
5055 status = PSA_ERROR_BUFFER_TOO_SMALL;
5056 goto exit;
5057 }
5058 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03005059
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005060#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02005061 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03005062 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02005063 status = mbedtls_to_psa_error(
5064 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
5065 MBEDTLS_GCM_ENCRYPT,
5066 plaintext_length,
5067 nonce, nonce_length,
5068 additional_data, additional_data_length,
5069 plaintext, ciphertext,
5070 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03005071 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005072 else
5073#endif /* MBEDTLS_GCM_C */
5074#if defined(MBEDTLS_CCM_C)
5075 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03005076 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02005077 status = mbedtls_to_psa_error(
5078 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
5079 plaintext_length,
5080 nonce, nonce_length,
5081 additional_data,
5082 additional_data_length,
5083 plaintext, ciphertext,
5084 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03005085 }
mohammad16035c8845f2018-05-09 05:40:09 -07005086 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005087#endif /* MBEDTLS_CCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02005088#if defined(MBEDTLS_CHACHAPOLY_C)
5089 if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
5090 {
5091 if( nonce_length != 12 || operation.tag_length != 16 )
5092 {
5093 status = PSA_ERROR_NOT_SUPPORTED;
5094 goto exit;
5095 }
5096 status = mbedtls_to_psa_error(
5097 mbedtls_chachapoly_encrypt_and_tag( &operation.ctx.chachapoly,
5098 plaintext_length,
5099 nonce,
5100 additional_data,
5101 additional_data_length,
5102 plaintext,
5103 ciphertext,
5104 tag ) );
5105 }
5106 else
5107#endif /* MBEDTLS_CHACHAPOLY_C */
mohammad16035c8845f2018-05-09 05:40:09 -07005108 {
mohammad1603554faad2018-06-03 15:07:38 +03005109 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07005110 }
Gilles Peskine2d277862018-06-18 15:41:12 +02005111
Gilles Peskineedf9a652018-08-17 18:11:56 +02005112 if( status != PSA_SUCCESS && ciphertext_size != 0 )
5113 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02005114
Gilles Peskineedf9a652018-08-17 18:11:56 +02005115exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01005116 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02005117 if( status == PSA_SUCCESS )
5118 *ciphertext_length = plaintext_length + operation.tag_length;
5119 return( status );
mohammad16035955c982018-04-26 00:53:03 +03005120}
5121
Gilles Peskineee652a32018-06-01 19:23:52 +02005122/* Locate the tag in a ciphertext buffer containing the encrypted data
5123 * followed by the tag. Return the length of the part preceding the tag in
5124 * *plaintext_length. This is the size of the plaintext in modes where
5125 * the encrypted data has the same size as the plaintext, such as
5126 * CCM and GCM. */
5127static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
5128 const uint8_t *ciphertext,
5129 size_t ciphertext_length,
5130 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02005131 const uint8_t **p_tag )
5132{
5133 size_t payload_length;
5134 if( tag_length > ciphertext_length )
5135 return( PSA_ERROR_INVALID_ARGUMENT );
5136 payload_length = ciphertext_length - tag_length;
5137 if( payload_length > plaintext_size )
5138 return( PSA_ERROR_BUFFER_TOO_SMALL );
5139 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02005140 return( PSA_SUCCESS );
5141}
5142
Ronald Croncf56a0a2020-08-04 09:51:30 +02005143psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key,
mohammad16035955c982018-04-26 00:53:03 +03005144 psa_algorithm_t alg,
5145 const uint8_t *nonce,
5146 size_t nonce_length,
5147 const uint8_t *additional_data,
5148 size_t additional_data_length,
5149 const uint8_t *ciphertext,
5150 size_t ciphertext_length,
5151 uint8_t *plaintext,
5152 size_t plaintext_size,
5153 size_t *plaintext_length )
5154{
mohammad16035955c982018-04-26 00:53:03 +03005155 psa_status_t status;
Ronald Cronf95a2b12020-10-22 15:24:49 +02005156 aead_operation_t operation = AEAD_OPERATION_INIT;
Gilles Peskineedf9a652018-08-17 18:11:56 +02005157 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02005158
Gilles Peskineee652a32018-06-01 19:23:52 +02005159 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03005160
Ronald Croncf56a0a2020-08-04 09:51:30 +02005161 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02005162 if( status != PSA_SUCCESS )
5163 return( status );
mohammad16035955c982018-04-26 00:53:03 +03005164
Gilles Peskinef7e7b012019-05-06 15:27:16 +02005165 status = psa_aead_unpadded_locate_tag( operation.tag_length,
5166 ciphertext, ciphertext_length,
5167 plaintext_size, &tag );
5168 if( status != PSA_SUCCESS )
5169 goto exit;
5170
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005171#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02005172 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03005173 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02005174 status = mbedtls_to_psa_error(
5175 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
5176 ciphertext_length - operation.tag_length,
5177 nonce, nonce_length,
5178 additional_data,
5179 additional_data_length,
5180 tag, operation.tag_length,
5181 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03005182 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005183 else
5184#endif /* MBEDTLS_GCM_C */
5185#if defined(MBEDTLS_CCM_C)
5186 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03005187 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02005188 status = mbedtls_to_psa_error(
5189 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
5190 ciphertext_length - operation.tag_length,
5191 nonce, nonce_length,
5192 additional_data,
5193 additional_data_length,
5194 ciphertext, plaintext,
5195 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03005196 }
mohammad160339574652018-06-01 04:39:53 -07005197 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005198#endif /* MBEDTLS_CCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02005199#if defined(MBEDTLS_CHACHAPOLY_C)
5200 if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
5201 {
5202 if( nonce_length != 12 || operation.tag_length != 16 )
5203 {
5204 status = PSA_ERROR_NOT_SUPPORTED;
5205 goto exit;
5206 }
5207 status = mbedtls_to_psa_error(
5208 mbedtls_chachapoly_auth_decrypt( &operation.ctx.chachapoly,
5209 ciphertext_length - operation.tag_length,
5210 nonce,
5211 additional_data,
5212 additional_data_length,
5213 tag,
5214 ciphertext,
5215 plaintext ) );
5216 }
5217 else
5218#endif /* MBEDTLS_CHACHAPOLY_C */
mohammad160339574652018-06-01 04:39:53 -07005219 {
mohammad1603554faad2018-06-03 15:07:38 +03005220 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07005221 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02005222
Gilles Peskineedf9a652018-08-17 18:11:56 +02005223 if( status != PSA_SUCCESS && plaintext_size != 0 )
5224 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03005225
Gilles Peskineedf9a652018-08-17 18:11:56 +02005226exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01005227 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02005228 if( status == PSA_SUCCESS )
5229 *plaintext_length = ciphertext_length - operation.tag_length;
5230 return( status );
mohammad16035955c982018-04-26 00:53:03 +03005231}
5232
Gilles Peskinea0655c32018-04-30 17:06:50 +02005233
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02005234
Gilles Peskine20035e32018-02-03 22:44:14 +01005235/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02005236/* Generators */
5237/****************************************************************/
5238
John Durkop07cc04a2020-11-16 22:08:34 -08005239#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
5240 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5241 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5242#define AT_LEAST_ONE_BUILTIN_KDF
5243#endif
5244
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005245#define HKDF_STATE_INIT 0 /* no input yet */
5246#define HKDF_STATE_STARTED 1 /* got salt */
5247#define HKDF_STATE_KEYED 2 /* got key */
5248#define HKDF_STATE_OUTPUT 3 /* output started */
5249
Gilles Peskinecbe66502019-05-16 16:59:18 +02005250static psa_algorithm_t psa_key_derivation_get_kdf_alg(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005251 const psa_key_derivation_operation_t *operation )
Gilles Peskine969c5d62019-01-16 15:53:06 +01005252{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005253 if ( PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
5254 return( PSA_ALG_KEY_AGREEMENT_GET_KDF( operation->alg ) );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005255 else
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005256 return( operation->alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005257}
5258
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005259psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005260{
5261 psa_status_t status = PSA_SUCCESS;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005262 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005263 if( kdf_alg == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005264 {
5265 /* The object has (apparently) been initialized but it is not
5266 * in use. It's ok to call abort on such an object, and there's
5267 * nothing to do. */
5268 }
5269 else
John Durkopd0321952020-10-29 21:37:36 -07005270#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005271 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02005272 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005273 mbedtls_free( operation->ctx.hkdf.info );
5274 status = psa_hmac_abort_internal( &operation->ctx.hkdf.hmac );
Gilles Peskinebef7f142018-07-12 17:22:21 +02005275 }
John Durkop07cc04a2020-11-16 22:08:34 -08005276 else
5277#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF */
5278#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5279 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5280 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005281 /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01005282 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005283 {
Janos Follath6a1d2622019-06-11 10:37:28 +01005284 if( operation->ctx.tls12_prf.seed != NULL )
5285 {
5286 mbedtls_platform_zeroize( operation->ctx.tls12_prf.seed,
5287 operation->ctx.tls12_prf.seed_length );
5288 mbedtls_free( operation->ctx.tls12_prf.seed );
5289 }
5290
5291 if( operation->ctx.tls12_prf.label != NULL )
5292 {
5293 mbedtls_platform_zeroize( operation->ctx.tls12_prf.label,
5294 operation->ctx.tls12_prf.label_length );
5295 mbedtls_free( operation->ctx.tls12_prf.label );
5296 }
5297
5298 status = psa_hmac_abort_internal( &operation->ctx.tls12_prf.hmac );
5299
5300 /* We leave the fields Ai and output_block to be erased safely by the
5301 * mbedtls_platform_zeroize() in the end of this function. */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005302 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02005303 else
John Durkop07cc04a2020-11-16 22:08:34 -08005304#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
5305 * defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) */
Gilles Peskineeab56e42018-07-12 17:12:33 +02005306 {
5307 status = PSA_ERROR_BAD_STATE;
5308 }
Janos Follath083036a2019-06-11 10:22:26 +01005309 mbedtls_platform_zeroize( operation, sizeof( *operation ) );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005310 return( status );
5311}
5312
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005313psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation,
Gilles Peskineeab56e42018-07-12 17:12:33 +02005314 size_t *capacity)
5315{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005316 if( operation->alg == 0 )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005317 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005318 /* This is a blank key derivation operation. */
Steven Cooreman29149862020-08-05 15:43:42 +02005319 return( PSA_ERROR_BAD_STATE );
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005320 }
5321
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005322 *capacity = operation->capacity;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005323 return( PSA_SUCCESS );
5324}
5325
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005326psa_status_t psa_key_derivation_set_capacity( psa_key_derivation_operation_t *operation,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005327 size_t capacity )
5328{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005329 if( operation->alg == 0 )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005330 return( PSA_ERROR_BAD_STATE );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005331 if( capacity > operation->capacity )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005332 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005333 operation->capacity = capacity;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005334 return( PSA_SUCCESS );
5335}
5336
John Durkopd0321952020-10-29 21:37:36 -07005337#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005338/* Read some bytes from an HKDF-based operation. This performs a chunk
Gilles Peskinebef7f142018-07-12 17:22:21 +02005339 * of the expand phase of the HKDF algorithm. */
Gilles Peskinecbe66502019-05-16 16:59:18 +02005340static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkdf,
Gilles Peskinebef7f142018-07-12 17:22:21 +02005341 psa_algorithm_t hash_alg,
5342 uint8_t *output,
5343 size_t output_length )
5344{
5345 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
5346 psa_status_t status;
5347
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005348 if( hkdf->state < HKDF_STATE_KEYED || ! hkdf->info_set )
5349 return( PSA_ERROR_BAD_STATE );
5350 hkdf->state = HKDF_STATE_OUTPUT;
5351
Gilles Peskinebef7f142018-07-12 17:22:21 +02005352 while( output_length != 0 )
5353 {
5354 /* Copy what remains of the current block */
5355 uint8_t n = hash_length - hkdf->offset_in_block;
5356 if( n > output_length )
5357 n = (uint8_t) output_length;
5358 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
5359 output += n;
5360 output_length -= n;
5361 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02005362 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02005363 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02005364 /* We can't be wanting more output after block 0xff, otherwise
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02005365 * the capacity check in psa_key_derivation_output_bytes() would have
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005366 * prevented this call. It could happen only if the operation
Gilles Peskined54931c2018-07-17 21:06:59 +02005367 * object was corrupted or if this function is called directly
5368 * inside the library. */
5369 if( hkdf->block_number == 0xff )
5370 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02005371
5372 /* We need a new block */
5373 ++hkdf->block_number;
5374 hkdf->offset_in_block = 0;
5375 status = psa_hmac_setup_internal( &hkdf->hmac,
5376 hkdf->prk, hash_length,
5377 hash_alg );
5378 if( status != PSA_SUCCESS )
5379 return( status );
5380 if( hkdf->block_number != 1 )
5381 {
5382 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5383 hkdf->output_block,
5384 hash_length );
5385 if( status != PSA_SUCCESS )
5386 return( status );
5387 }
5388 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5389 hkdf->info,
5390 hkdf->info_length );
5391 if( status != PSA_SUCCESS )
5392 return( status );
5393 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5394 &hkdf->block_number, 1 );
5395 if( status != PSA_SUCCESS )
5396 return( status );
5397 status = psa_hmac_finish_internal( &hkdf->hmac,
5398 hkdf->output_block,
5399 sizeof( hkdf->output_block ) );
5400 if( status != PSA_SUCCESS )
5401 return( status );
5402 }
5403
5404 return( PSA_SUCCESS );
5405}
John Durkop07cc04a2020-11-16 22:08:34 -08005406#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005407
John Durkop07cc04a2020-11-16 22:08:34 -08005408#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5409 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follath7742fee2019-06-17 12:58:10 +01005410static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
5411 psa_tls12_prf_key_derivation_t *tls12_prf,
5412 psa_algorithm_t alg )
5413{
5414 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
5415 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Janos Follathea29bfb2019-06-19 12:21:20 +01005416 psa_hash_operation_t backup = PSA_HASH_OPERATION_INIT;
5417 psa_status_t status, cleanup_status;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005418
Janos Follath7742fee2019-06-17 12:58:10 +01005419 /* We can't be wanting more output after block 0xff, otherwise
5420 * the capacity check in psa_key_derivation_output_bytes() would have
5421 * prevented this call. It could happen only if the operation
5422 * object was corrupted or if this function is called directly
5423 * inside the library. */
5424 if( tls12_prf->block_number == 0xff )
Janos Follath30090bc2019-06-25 10:15:04 +01005425 return( PSA_ERROR_CORRUPTION_DETECTED );
Janos Follath7742fee2019-06-17 12:58:10 +01005426
5427 /* We need a new block */
5428 ++tls12_prf->block_number;
Janos Follath844eb0e2019-06-19 12:10:49 +01005429 tls12_prf->left_in_block = hash_length;
Janos Follath7742fee2019-06-17 12:58:10 +01005430
5431 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
5432 *
5433 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
5434 *
5435 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
5436 * HMAC_hash(secret, A(2) + seed) +
5437 * HMAC_hash(secret, A(3) + seed) + ...
5438 *
5439 * A(0) = seed
Janos Follathea29bfb2019-06-19 12:21:20 +01005440 * A(i) = HMAC_hash(secret, A(i-1))
Janos Follath7742fee2019-06-17 12:58:10 +01005441 *
Janos Follathea29bfb2019-06-19 12:21:20 +01005442 * The `psa_tls12_prf_key_derivation` structure saves the block
Janos Follath7742fee2019-06-17 12:58:10 +01005443 * `HMAC_hash(secret, A(i) + seed)` from which the output
Janos Follath76c39842019-06-26 12:50:36 +01005444 * is currently extracted as `output_block` and where i is
5445 * `block_number`.
Janos Follath7742fee2019-06-17 12:58:10 +01005446 */
5447
Janos Follathea29bfb2019-06-19 12:21:20 +01005448 /* Save the hash context before using it, to preserve the hash state with
5449 * only the inner padding in it. We need this, because inner padding depends
5450 * on the key (secret in the RFC's terminology). */
5451 status = psa_hash_clone( &tls12_prf->hmac.hash_ctx, &backup );
5452 if( status != PSA_SUCCESS )
5453 goto cleanup;
5454
5455 /* Calculate A(i) where i = tls12_prf->block_number. */
5456 if( tls12_prf->block_number == 1 )
5457 {
5458 /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads
5459 * the variable seed and in this instance means it in the context of the
5460 * P_hash function, where seed = label + seed.) */
5461 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5462 tls12_prf->label, tls12_prf->label_length );
5463 if( status != PSA_SUCCESS )
5464 goto cleanup;
5465 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5466 tls12_prf->seed, tls12_prf->seed_length );
5467 if( status != PSA_SUCCESS )
5468 goto cleanup;
5469 }
5470 else
5471 {
5472 /* A(i) = HMAC_hash(secret, A(i-1)) */
5473 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5474 tls12_prf->Ai, hash_length );
5475 if( status != PSA_SUCCESS )
5476 goto cleanup;
5477 }
5478
5479 status = psa_hmac_finish_internal( &tls12_prf->hmac,
5480 tls12_prf->Ai, hash_length );
5481 if( status != PSA_SUCCESS )
5482 goto cleanup;
5483 status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
5484 if( status != PSA_SUCCESS )
5485 goto cleanup;
5486
5487 /* Calculate HMAC_hash(secret, A(i) + label + seed). */
5488 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5489 tls12_prf->Ai, hash_length );
5490 if( status != PSA_SUCCESS )
5491 goto cleanup;
5492 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5493 tls12_prf->label, tls12_prf->label_length );
5494 if( status != PSA_SUCCESS )
5495 goto cleanup;
5496 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5497 tls12_prf->seed, tls12_prf->seed_length );
5498 if( status != PSA_SUCCESS )
5499 goto cleanup;
5500 status = psa_hmac_finish_internal( &tls12_prf->hmac,
5501 tls12_prf->output_block, hash_length );
5502 if( status != PSA_SUCCESS )
5503 goto cleanup;
5504 status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
5505 if( status != PSA_SUCCESS )
5506 goto cleanup;
5507
Janos Follath7742fee2019-06-17 12:58:10 +01005508
5509cleanup:
5510
Janos Follathea29bfb2019-06-19 12:21:20 +01005511 cleanup_status = psa_hash_abort( &backup );
5512 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
5513 status = cleanup_status;
5514
5515 return( status );
Janos Follath7742fee2019-06-17 12:58:10 +01005516}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005517
Janos Follath844eb0e2019-06-19 12:10:49 +01005518static psa_status_t psa_key_derivation_tls12_prf_read(
5519 psa_tls12_prf_key_derivation_t *tls12_prf,
5520 psa_algorithm_t alg,
5521 uint8_t *output,
5522 size_t output_length )
5523{
5524 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
5525 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
5526 psa_status_t status;
5527 uint8_t offset, length;
5528
5529 while( output_length != 0 )
5530 {
5531 /* Check if we have fully processed the current block. */
5532 if( tls12_prf->left_in_block == 0 )
5533 {
5534 status = psa_key_derivation_tls12_prf_generate_next_block( tls12_prf,
5535 alg );
5536 if( status != PSA_SUCCESS )
5537 return( status );
5538
5539 continue;
5540 }
5541
5542 if( tls12_prf->left_in_block > output_length )
5543 length = (uint8_t) output_length;
5544 else
5545 length = tls12_prf->left_in_block;
5546
5547 offset = hash_length - tls12_prf->left_in_block;
5548 memcpy( output, tls12_prf->output_block + offset, length );
5549 output += length;
5550 output_length -= length;
5551 tls12_prf->left_in_block -= length;
5552 }
5553
5554 return( PSA_SUCCESS );
5555}
John Durkop07cc04a2020-11-16 22:08:34 -08005556#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
5557 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskinebef7f142018-07-12 17:22:21 +02005558
Janos Follath6c6c8fc2019-06-17 12:38:20 +01005559psa_status_t psa_key_derivation_output_bytes(
5560 psa_key_derivation_operation_t *operation,
5561 uint8_t *output,
5562 size_t output_length )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005563{
5564 psa_status_t status;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005565 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005566
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005567 if( operation->alg == 0 )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005568 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005569 /* This is a blank operation. */
Steven Cooreman29149862020-08-05 15:43:42 +02005570 return( PSA_ERROR_BAD_STATE );
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005571 }
5572
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005573 if( output_length > operation->capacity )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005574 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005575 operation->capacity = 0;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005576 /* Go through the error path to wipe all confidential data now
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005577 * that the operation object is useless. */
David Saadab4ecc272019-02-14 13:48:10 +02005578 status = PSA_ERROR_INSUFFICIENT_DATA;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005579 goto exit;
5580 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005581 if( output_length == 0 && operation->capacity == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005582 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005583 /* Edge case: this is a finished operation, and 0 bytes
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005584 * were requested. The right error in this case could
Gilles Peskineeab56e42018-07-12 17:12:33 +02005585 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
5586 * INSUFFICIENT_CAPACITY, which is right for a finished
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005587 * operation, for consistency with the case when
Gilles Peskineeab56e42018-07-12 17:12:33 +02005588 * output_length > 0. */
David Saadab4ecc272019-02-14 13:48:10 +02005589 return( PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005590 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005591 operation->capacity -= output_length;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005592
John Durkopd0321952020-10-29 21:37:36 -07005593#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005594 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02005595 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01005596 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005597 status = psa_key_derivation_hkdf_read( &operation->ctx.hkdf, hash_alg,
Gilles Peskinebef7f142018-07-12 17:22:21 +02005598 output, output_length );
5599 }
Janos Follathadbec812019-06-14 11:05:39 +01005600 else
John Durkop07cc04a2020-11-16 22:08:34 -08005601#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
5602#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5603 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follathadbec812019-06-14 11:05:39 +01005604 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
John Durkop07cc04a2020-11-16 22:08:34 -08005605 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005606 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005607 status = psa_key_derivation_tls12_prf_read( &operation->ctx.tls12_prf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005608 kdf_alg, output,
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005609 output_length );
5610 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02005611 else
John Durkop07cc04a2020-11-16 22:08:34 -08005612#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
5613 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineeab56e42018-07-12 17:12:33 +02005614 {
5615 return( PSA_ERROR_BAD_STATE );
5616 }
5617
5618exit:
5619 if( status != PSA_SUCCESS )
5620 {
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005621 /* Preserve the algorithm upon errors, but clear all sensitive state.
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005622 * This allows us to differentiate between exhausted operations and
5623 * blank operations, so we can return PSA_ERROR_BAD_STATE on blank
5624 * operations. */
5625 psa_algorithm_t alg = operation->alg;
5626 psa_key_derivation_abort( operation );
5627 operation->alg = alg;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005628 memset( output, '!', output_length );
5629 }
5630 return( status );
5631}
5632
Gilles Peskine08542d82018-07-19 17:05:42 +02005633#if defined(MBEDTLS_DES_C)
5634static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
5635{
5636 if( data_size >= 8 )
5637 mbedtls_des_key_set_parity( data );
5638 if( data_size >= 16 )
5639 mbedtls_des_key_set_parity( data + 8 );
5640 if( data_size >= 24 )
5641 mbedtls_des_key_set_parity( data + 16 );
5642}
5643#endif /* MBEDTLS_DES_C */
5644
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01005645static psa_status_t psa_generate_derived_key_internal(
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005646 psa_key_slot_t *slot,
5647 size_t bits,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005648 psa_key_derivation_operation_t *operation )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005649{
5650 uint8_t *data = NULL;
5651 size_t bytes = PSA_BITS_TO_BYTES( bits );
5652 psa_status_t status;
5653
Gilles Peskine8e338702019-07-30 20:06:31 +02005654 if( ! key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005655 return( PSA_ERROR_INVALID_ARGUMENT );
5656 if( bits % 8 != 0 )
5657 return( PSA_ERROR_INVALID_ARGUMENT );
5658 data = mbedtls_calloc( 1, bytes );
5659 if( data == NULL )
5660 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5661
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005662 status = psa_key_derivation_output_bytes( operation, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005663 if( status != PSA_SUCCESS )
5664 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02005665#if defined(MBEDTLS_DES_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02005666 if( slot->attr.type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02005667 psa_des_set_key_parity( data, bytes );
5668#endif /* MBEDTLS_DES_C */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005669 status = psa_import_key_into_slot( slot, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005670
5671exit:
5672 mbedtls_free( data );
5673 return( status );
5674}
5675
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02005676psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attributes,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005677 psa_key_derivation_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02005678 mbedtls_svc_key_id_t *key )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005679{
5680 psa_status_t status;
5681 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02005682 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine0f84d622019-09-12 19:03:13 +02005683
Ronald Cron81709fc2020-11-14 12:10:32 +01005684 *key = MBEDTLS_SVC_KEY_ID_INIT;
5685
Gilles Peskine0f84d622019-09-12 19:03:13 +02005686 /* Reject any attempt to create a zero-length key so that we don't
5687 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
5688 if( psa_get_key_bits( attributes ) == 0 )
5689 return( PSA_ERROR_INVALID_ARGUMENT );
5690
Gilles Peskine178c9aa2019-09-24 18:21:06 +02005691 if( ! operation->can_output_key )
5692 return( PSA_ERROR_NOT_PERMITTED );
5693
Ronald Cron81709fc2020-11-14 12:10:32 +01005694 status = psa_start_key_creation( PSA_KEY_CREATION_DERIVE, attributes,
5695 &slot, &driver );
Gilles Peskinef4ee6622019-07-24 13:44:30 +02005696#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
5697 if( driver != NULL )
5698 {
5699 /* Deriving a key in a secure element is not implemented yet. */
5700 status = PSA_ERROR_NOT_SUPPORTED;
5701 }
5702#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005703 if( status == PSA_SUCCESS )
5704 {
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01005705 status = psa_generate_derived_key_internal( slot,
Gilles Peskine7e0cff92019-07-30 13:48:52 +02005706 attributes->core.bits,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005707 operation );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005708 }
5709 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01005710 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005711 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02005712 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005713
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005714 return( status );
5715}
5716
Gilles Peskineeab56e42018-07-12 17:12:33 +02005717
5718
5719/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02005720/* Key derivation */
5721/****************************************************************/
5722
John Durkop07cc04a2020-11-16 22:08:34 -08005723#ifdef AT_LEAST_ONE_BUILTIN_KDF
Gilles Peskine969c5d62019-01-16 15:53:06 +01005724static psa_status_t psa_key_derivation_setup_kdf(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005725 psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005726 psa_algorithm_t kdf_alg )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005727{
John Durkop07cc04a2020-11-16 22:08:34 -08005728 int is_kdf_alg_supported;
5729
Janos Follath5fe19732019-06-20 15:09:30 +01005730 /* Make sure that operation->ctx is properly zero-initialised. (Macro
5731 * initialisers for this union leave some bytes unspecified.) */
5732 memset( &operation->ctx, 0, sizeof( operation->ctx ) );
5733
Gilles Peskine969c5d62019-01-16 15:53:06 +01005734 /* Make sure that kdf_alg is a supported key derivation algorithm. */
John Durkopd0321952020-10-29 21:37:36 -07005735#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
John Durkop07cc04a2020-11-16 22:08:34 -08005736 if( PSA_ALG_IS_HKDF( kdf_alg ) )
5737 is_kdf_alg_supported = 1;
5738 else
5739#endif
5740#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
5741 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
5742 is_kdf_alg_supported = 1;
5743 else
5744#endif
5745#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5746 if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
5747 is_kdf_alg_supported = 1;
5748 else
5749#endif
5750 is_kdf_alg_supported = 0;
5751
5752 if( is_kdf_alg_supported )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005753 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01005754 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005755 size_t hash_size = PSA_HASH_SIZE( hash_alg );
5756 if( hash_size == 0 )
5757 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005758 if( ( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
5759 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) &&
Gilles Peskineab4b2012019-04-12 15:06:27 +02005760 ! ( hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384 ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005761 {
5762 return( PSA_ERROR_NOT_SUPPORTED );
5763 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005764 operation->capacity = 255 * hash_size;
Gilles Peskine969c5d62019-01-16 15:53:06 +01005765 return( PSA_SUCCESS );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005766 }
John Durkop07cc04a2020-11-16 22:08:34 -08005767
5768 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005769}
John Durkop07cc04a2020-11-16 22:08:34 -08005770#endif /* AT_LEAST_ONE_BUILTIN_KDF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01005771
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005772psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005773 psa_algorithm_t alg )
5774{
5775 psa_status_t status;
5776
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005777 if( operation->alg != 0 )
Gilles Peskine969c5d62019-01-16 15:53:06 +01005778 return( PSA_ERROR_BAD_STATE );
5779
Gilles Peskine6843c292019-01-18 16:44:49 +01005780 if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
5781 return( PSA_ERROR_INVALID_ARGUMENT );
John Durkop07cc04a2020-11-16 22:08:34 -08005782#ifdef AT_LEAST_ONE_BUILTIN_KDF
Gilles Peskine6843c292019-01-18 16:44:49 +01005783 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskine969c5d62019-01-16 15:53:06 +01005784 {
5785 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005786 status = psa_key_derivation_setup_kdf( operation, kdf_alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005787 }
5788 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
5789 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005790 status = psa_key_derivation_setup_kdf( operation, alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005791 }
John Durkop07cc04a2020-11-16 22:08:34 -08005792#endif
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005793 else
5794 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005795
5796 if( status == PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005797 operation->alg = alg;
Gilles Peskine969c5d62019-01-16 15:53:06 +01005798 return( status );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005799}
5800
John Durkopd0321952020-10-29 21:37:36 -07005801#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskinecbe66502019-05-16 16:59:18 +02005802static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005803 psa_algorithm_t hash_alg,
5804 psa_key_derivation_step_t step,
5805 const uint8_t *data,
5806 size_t data_length )
5807{
5808 psa_status_t status;
5809 switch( step )
5810 {
Gilles Peskine03410b52019-05-16 16:05:19 +02005811 case PSA_KEY_DERIVATION_INPUT_SALT:
Gilles Peskine2b522db2019-04-12 15:11:49 +02005812 if( hkdf->state != HKDF_STATE_INIT )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005813 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005814 status = psa_hmac_setup_internal( &hkdf->hmac,
5815 data, data_length,
5816 hash_alg );
5817 if( status != PSA_SUCCESS )
5818 return( status );
5819 hkdf->state = HKDF_STATE_STARTED;
5820 return( PSA_SUCCESS );
Gilles Peskine03410b52019-05-16 16:05:19 +02005821 case PSA_KEY_DERIVATION_INPUT_SECRET:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005822 /* If no salt was provided, use an empty salt. */
5823 if( hkdf->state == HKDF_STATE_INIT )
5824 {
5825 status = psa_hmac_setup_internal( &hkdf->hmac,
5826 NULL, 0,
Gilles Peskinef9ee6332019-04-11 21:22:52 +02005827 hash_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005828 if( status != PSA_SUCCESS )
5829 return( status );
5830 hkdf->state = HKDF_STATE_STARTED;
5831 }
Gilles Peskine2b522db2019-04-12 15:11:49 +02005832 if( hkdf->state != HKDF_STATE_STARTED )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005833 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005834 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5835 data, data_length );
5836 if( status != PSA_SUCCESS )
5837 return( status );
5838 status = psa_hmac_finish_internal( &hkdf->hmac,
5839 hkdf->prk,
5840 sizeof( hkdf->prk ) );
5841 if( status != PSA_SUCCESS )
5842 return( status );
5843 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
5844 hkdf->block_number = 0;
5845 hkdf->state = HKDF_STATE_KEYED;
5846 return( PSA_SUCCESS );
Gilles Peskine03410b52019-05-16 16:05:19 +02005847 case PSA_KEY_DERIVATION_INPUT_INFO:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005848 if( hkdf->state == HKDF_STATE_OUTPUT )
5849 return( PSA_ERROR_BAD_STATE );
5850 if( hkdf->info_set )
5851 return( PSA_ERROR_BAD_STATE );
5852 hkdf->info_length = data_length;
5853 if( data_length != 0 )
5854 {
5855 hkdf->info = mbedtls_calloc( 1, data_length );
5856 if( hkdf->info == NULL )
5857 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5858 memcpy( hkdf->info, data, data_length );
5859 }
5860 hkdf->info_set = 1;
5861 return( PSA_SUCCESS );
5862 default:
5863 return( PSA_ERROR_INVALID_ARGUMENT );
5864 }
5865}
John Durkop07cc04a2020-11-16 22:08:34 -08005866#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
Janos Follathb03233e2019-06-11 15:30:30 +01005867
John Durkop07cc04a2020-11-16 22:08:34 -08005868#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5869 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follathf08e2652019-06-13 09:05:41 +01005870static psa_status_t psa_tls12_prf_set_seed( psa_tls12_prf_key_derivation_t *prf,
5871 const uint8_t *data,
5872 size_t data_length )
5873{
5874 if( prf->state != TLS12_PRF_STATE_INIT )
5875 return( PSA_ERROR_BAD_STATE );
5876
Janos Follathd6dce9f2019-07-04 09:11:38 +01005877 if( data_length != 0 )
5878 {
5879 prf->seed = mbedtls_calloc( 1, data_length );
5880 if( prf->seed == NULL )
5881 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Janos Follathf08e2652019-06-13 09:05:41 +01005882
Janos Follathd6dce9f2019-07-04 09:11:38 +01005883 memcpy( prf->seed, data, data_length );
5884 prf->seed_length = data_length;
5885 }
Janos Follathf08e2652019-06-13 09:05:41 +01005886
5887 prf->state = TLS12_PRF_STATE_SEED_SET;
5888
5889 return( PSA_SUCCESS );
5890}
5891
Janos Follath81550542019-06-13 14:26:34 +01005892static psa_status_t psa_tls12_prf_set_key( psa_tls12_prf_key_derivation_t *prf,
5893 psa_algorithm_t hash_alg,
5894 const uint8_t *data,
5895 size_t data_length )
5896{
5897 psa_status_t status;
5898 if( prf->state != TLS12_PRF_STATE_SEED_SET )
5899 return( PSA_ERROR_BAD_STATE );
5900
5901 status = psa_hmac_setup_internal( &prf->hmac, data, data_length, hash_alg );
5902 if( status != PSA_SUCCESS )
5903 return( status );
5904
5905 prf->state = TLS12_PRF_STATE_KEY_SET;
5906
5907 return( PSA_SUCCESS );
5908}
5909
Janos Follath63028dd2019-06-13 09:15:47 +01005910static psa_status_t psa_tls12_prf_set_label( psa_tls12_prf_key_derivation_t *prf,
5911 const uint8_t *data,
5912 size_t data_length )
5913{
5914 if( prf->state != TLS12_PRF_STATE_KEY_SET )
5915 return( PSA_ERROR_BAD_STATE );
5916
Janos Follathd6dce9f2019-07-04 09:11:38 +01005917 if( data_length != 0 )
5918 {
5919 prf->label = mbedtls_calloc( 1, data_length );
5920 if( prf->label == NULL )
5921 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Janos Follath63028dd2019-06-13 09:15:47 +01005922
Janos Follathd6dce9f2019-07-04 09:11:38 +01005923 memcpy( prf->label, data, data_length );
5924 prf->label_length = data_length;
5925 }
Janos Follath63028dd2019-06-13 09:15:47 +01005926
5927 prf->state = TLS12_PRF_STATE_LABEL_SET;
5928
5929 return( PSA_SUCCESS );
5930}
5931
Janos Follathb03233e2019-06-11 15:30:30 +01005932static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf,
5933 psa_algorithm_t hash_alg,
5934 psa_key_derivation_step_t step,
5935 const uint8_t *data,
5936 size_t data_length )
5937{
Janos Follathb03233e2019-06-11 15:30:30 +01005938 switch( step )
5939 {
Janos Follathf08e2652019-06-13 09:05:41 +01005940 case PSA_KEY_DERIVATION_INPUT_SEED:
5941 return( psa_tls12_prf_set_seed( prf, data, data_length ) );
Janos Follath81550542019-06-13 14:26:34 +01005942 case PSA_KEY_DERIVATION_INPUT_SECRET:
5943 return( psa_tls12_prf_set_key( prf, hash_alg, data, data_length ) );
Janos Follath63028dd2019-06-13 09:15:47 +01005944 case PSA_KEY_DERIVATION_INPUT_LABEL:
5945 return( psa_tls12_prf_set_label( prf, data, data_length ) );
Janos Follathb03233e2019-06-11 15:30:30 +01005946 default:
5947 return( PSA_ERROR_INVALID_ARGUMENT );
5948 }
5949}
John Durkop07cc04a2020-11-16 22:08:34 -08005950#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
5951 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
5952
5953#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5954static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
5955 psa_tls12_prf_key_derivation_t *prf,
5956 psa_algorithm_t hash_alg,
5957 const uint8_t *data,
5958 size_t data_length )
5959{
5960 psa_status_t status;
5961 uint8_t pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
5962 uint8_t *cur = pms;
5963
5964 if( data_length > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
5965 return( PSA_ERROR_INVALID_ARGUMENT );
5966
5967 /* Quoting RFC 4279, Section 2:
5968 *
5969 * The premaster secret is formed as follows: if the PSK is N octets
5970 * long, concatenate a uint16 with the value N, N zero octets, a second
5971 * uint16 with the value N, and the PSK itself.
5972 */
5973
5974 *cur++ = ( data_length >> 8 ) & 0xff;
5975 *cur++ = ( data_length >> 0 ) & 0xff;
5976 memset( cur, 0, data_length );
5977 cur += data_length;
5978 *cur++ = pms[0];
5979 *cur++ = pms[1];
5980 memcpy( cur, data, data_length );
5981 cur += data_length;
5982
5983 status = psa_tls12_prf_set_key( prf, hash_alg, pms, cur - pms );
5984
5985 mbedtls_platform_zeroize( pms, sizeof( pms ) );
5986 return( status );
5987}
Janos Follath6660f0e2019-06-17 08:44:03 +01005988
5989static psa_status_t psa_tls12_prf_psk_to_ms_input(
5990 psa_tls12_prf_key_derivation_t *prf,
5991 psa_algorithm_t hash_alg,
5992 psa_key_derivation_step_t step,
5993 const uint8_t *data,
5994 size_t data_length )
5995{
5996 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
Janos Follath0c1ed842019-06-28 13:35:36 +01005997 {
Janos Follath6660f0e2019-06-17 08:44:03 +01005998 return( psa_tls12_prf_psk_to_ms_set_key( prf, hash_alg,
5999 data, data_length ) );
Janos Follath0c1ed842019-06-28 13:35:36 +01006000 }
Janos Follath6660f0e2019-06-17 08:44:03 +01006001
6002 return( psa_tls12_prf_input( prf, hash_alg, step, data, data_length ) );
6003}
John Durkop07cc04a2020-11-16 22:08:34 -08006004#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006005
Gilles Peskineb8965192019-09-24 16:21:10 +02006006/** Check whether the given key type is acceptable for the given
6007 * input step of a key derivation.
6008 *
6009 * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE.
6010 * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA.
6011 * Both secret and non-secret inputs can alternatively have the type
6012 * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning
6013 * that the input was passed as a buffer rather than via a key object.
6014 */
Gilles Peskine224b0d62019-09-23 18:13:17 +02006015static int psa_key_derivation_check_input_type(
6016 psa_key_derivation_step_t step,
6017 psa_key_type_t key_type )
6018{
6019 switch( step )
6020 {
6021 case PSA_KEY_DERIVATION_INPUT_SECRET:
Gilles Peskineb8965192019-09-24 16:21:10 +02006022 if( key_type == PSA_KEY_TYPE_DERIVE )
6023 return( PSA_SUCCESS );
6024 if( key_type == PSA_KEY_TYPE_NONE )
Gilles Peskine224b0d62019-09-23 18:13:17 +02006025 return( PSA_SUCCESS );
6026 break;
6027 case PSA_KEY_DERIVATION_INPUT_LABEL:
6028 case PSA_KEY_DERIVATION_INPUT_SALT:
6029 case PSA_KEY_DERIVATION_INPUT_INFO:
6030 case PSA_KEY_DERIVATION_INPUT_SEED:
Gilles Peskineb8965192019-09-24 16:21:10 +02006031 if( key_type == PSA_KEY_TYPE_RAW_DATA )
6032 return( PSA_SUCCESS );
6033 if( key_type == PSA_KEY_TYPE_NONE )
Gilles Peskine224b0d62019-09-23 18:13:17 +02006034 return( PSA_SUCCESS );
6035 break;
6036 }
6037 return( PSA_ERROR_INVALID_ARGUMENT );
6038}
6039
Janos Follathb80a94e2019-06-12 15:54:46 +01006040static psa_status_t psa_key_derivation_input_internal(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006041 psa_key_derivation_operation_t *operation,
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01006042 psa_key_derivation_step_t step,
Gilles Peskine224b0d62019-09-23 18:13:17 +02006043 psa_key_type_t key_type,
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01006044 const uint8_t *data,
6045 size_t data_length )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006046{
Gilles Peskine46d7faf2019-09-23 19:22:55 +02006047 psa_status_t status;
6048 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
6049
6050 status = psa_key_derivation_check_input_type( step, key_type );
Gilles Peskine224b0d62019-09-23 18:13:17 +02006051 if( status != PSA_SUCCESS )
6052 goto exit;
6053
John Durkopd0321952020-10-29 21:37:36 -07006054#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01006055 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006056 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006057 status = psa_hkdf_input( &operation->ctx.hkdf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01006058 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006059 step, data, data_length );
6060 }
John Durkop07cc04a2020-11-16 22:08:34 -08006061 else
6062#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
6063#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
6064 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006065 {
Janos Follathb03233e2019-06-11 15:30:30 +01006066 status = psa_tls12_prf_input( &operation->ctx.tls12_prf,
6067 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
6068 step, data, data_length );
Janos Follath6660f0e2019-06-17 08:44:03 +01006069 }
John Durkop07cc04a2020-11-16 22:08:34 -08006070 else
6071#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF */
6072#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
6073 if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Janos Follath6660f0e2019-06-17 08:44:03 +01006074 {
6075 status = psa_tls12_prf_psk_to_ms_input( &operation->ctx.tls12_prf,
6076 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
6077 step, data, data_length );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006078 }
6079 else
John Durkop07cc04a2020-11-16 22:08:34 -08006080#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006081 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006082 /* This can't happen unless the operation object was not initialized */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006083 return( PSA_ERROR_BAD_STATE );
6084 }
6085
Gilles Peskine224b0d62019-09-23 18:13:17 +02006086exit:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006087 if( status != PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006088 psa_key_derivation_abort( operation );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006089 return( status );
6090}
6091
Janos Follath51f4a0f2019-06-14 11:35:55 +01006092psa_status_t psa_key_derivation_input_bytes(
6093 psa_key_derivation_operation_t *operation,
6094 psa_key_derivation_step_t step,
6095 const uint8_t *data,
6096 size_t data_length )
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01006097{
Gilles Peskineb8965192019-09-24 16:21:10 +02006098 return( psa_key_derivation_input_internal( operation, step,
6099 PSA_KEY_TYPE_NONE,
Janos Follathc5621512019-06-14 11:27:57 +01006100 data, data_length ) );
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01006101}
6102
Janos Follath51f4a0f2019-06-14 11:35:55 +01006103psa_status_t psa_key_derivation_input_key(
6104 psa_key_derivation_operation_t *operation,
6105 psa_key_derivation_step_t step,
Ronald Croncf56a0a2020-08-04 09:51:30 +02006106 mbedtls_svc_key_id_t key )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006107{
Ronald Cronf95a2b12020-10-22 15:24:49 +02006108 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01006109 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006110 psa_key_slot_t *slot;
Gilles Peskine178c9aa2019-09-24 18:21:06 +02006111
Ronald Cron5c522922020-11-14 16:35:34 +01006112 status = psa_get_and_lock_transparent_key_slot_with_policy(
6113 key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006114 if( status != PSA_SUCCESS )
Gilles Peskine593773d2019-09-23 18:17:40 +02006115 {
6116 psa_key_derivation_abort( operation );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006117 return( status );
Gilles Peskine593773d2019-09-23 18:17:40 +02006118 }
Gilles Peskine178c9aa2019-09-24 18:21:06 +02006119
6120 /* Passing a key object as a SECRET input unlocks the permission
6121 * to output to a key object. */
6122 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
6123 operation->can_output_key = 1;
6124
Ronald Cronf95a2b12020-10-22 15:24:49 +02006125 status = psa_key_derivation_input_internal( operation,
6126 step, slot->attr.type,
6127 slot->data.key.data,
6128 slot->data.key.bytes );
6129
Ronald Cron5c522922020-11-14 16:35:34 +01006130 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02006131
Ronald Cron5c522922020-11-14 16:35:34 +01006132 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006133}
Gilles Peskineea0fb492018-07-12 17:17:20 +02006134
6135
6136
6137/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02006138/* Key agreement */
6139/****************************************************************/
6140
John Durkop6ba40d12020-11-10 08:50:04 -08006141#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006142static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
6143 size_t peer_key_length,
6144 const mbedtls_ecp_keypair *our_key,
6145 uint8_t *shared_secret,
6146 size_t shared_secret_size,
6147 size_t *shared_secret_length )
6148{
Steven Cooremand4867872020-08-05 16:31:39 +02006149 mbedtls_ecp_keypair *their_key = NULL;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006150 mbedtls_ecdh_context ecdh;
Jaeden Amero97271b32019-01-10 19:38:51 +00006151 psa_status_t status;
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01006152 size_t bits = 0;
Paul Elliott8ff510a2020-06-02 17:19:28 +01006153 psa_ecc_family_t curve = mbedtls_ecc_group_to_psa( our_key->grp.id, &bits );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006154 mbedtls_ecdh_init( &ecdh );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006155
Steven Cooreman4fed4552020-08-03 14:46:03 +02006156 status = psa_load_ecp_representation( PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
6157 peer_key,
Steven Cooreman7f391872020-07-30 14:57:44 +02006158 peer_key_length,
Steven Cooreman7f391872020-07-30 14:57:44 +02006159 &their_key );
Jaeden Amero97271b32019-01-10 19:38:51 +00006160 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006161 goto exit;
6162
Jaeden Amero97271b32019-01-10 19:38:51 +00006163 status = mbedtls_to_psa_error(
Steven Cooremana2371e52020-07-28 14:30:39 +02006164 mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS ) );
Jaeden Amero97271b32019-01-10 19:38:51 +00006165 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006166 goto exit;
Jaeden Amero97271b32019-01-10 19:38:51 +00006167 status = mbedtls_to_psa_error(
6168 mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS ) );
6169 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006170 goto exit;
6171
Jaeden Amero97271b32019-01-10 19:38:51 +00006172 status = mbedtls_to_psa_error(
6173 mbedtls_ecdh_calc_secret( &ecdh,
6174 shared_secret_length,
6175 shared_secret, shared_secret_size,
Gilles Peskine30524eb2020-11-13 17:02:26 +01006176 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006177 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01006178 if( status != PSA_SUCCESS )
6179 goto exit;
6180 if( PSA_BITS_TO_BYTES( bits ) != *shared_secret_length )
6181 status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006182
6183exit:
Gilles Peskine3e819b72019-12-20 14:09:55 +01006184 if( status != PSA_SUCCESS )
6185 mbedtls_platform_zeroize( shared_secret, shared_secret_size );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006186 mbedtls_ecdh_free( &ecdh );
Steven Cooremana2371e52020-07-28 14:30:39 +02006187 mbedtls_ecp_keypair_free( their_key );
Steven Cooreman6d839f02020-07-30 11:36:45 +02006188 mbedtls_free( their_key );
Steven Cooremana2371e52020-07-28 14:30:39 +02006189
Jaeden Amero97271b32019-01-10 19:38:51 +00006190 return( status );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006191}
John Durkop6ba40d12020-11-10 08:50:04 -08006192#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006193
Gilles Peskine01d718c2018-09-18 12:01:02 +02006194#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
6195
Gilles Peskine0216fe12019-04-11 21:23:21 +02006196static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg,
6197 psa_key_slot_t *private_key,
6198 const uint8_t *peer_key,
6199 size_t peer_key_length,
6200 uint8_t *shared_secret,
6201 size_t shared_secret_size,
6202 size_t *shared_secret_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02006203{
Gilles Peskine0216fe12019-04-11 21:23:21 +02006204 switch( alg )
Gilles Peskine01d718c2018-09-18 12:01:02 +02006205 {
John Durkop6ba40d12020-11-10 08:50:04 -08006206#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
Gilles Peskine0216fe12019-04-11 21:23:21 +02006207 case PSA_ALG_ECDH:
Gilles Peskine8e338702019-07-30 20:06:31 +02006208 if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006209 return( PSA_ERROR_INVALID_ARGUMENT );
Steven Cooremana2371e52020-07-28 14:30:39 +02006210 mbedtls_ecp_keypair *ecp = NULL;
Steven Cooreman7f391872020-07-30 14:57:44 +02006211 psa_status_t status = psa_load_ecp_representation(
Steven Cooreman4fed4552020-08-03 14:46:03 +02006212 private_key->attr.type,
Steven Cooreman7f391872020-07-30 14:57:44 +02006213 private_key->data.key.data,
6214 private_key->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02006215 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02006216 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02006217 return( status );
Steven Cooremanacda8342020-07-24 23:09:52 +02006218 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
Steven Cooremana2371e52020-07-28 14:30:39 +02006219 ecp,
Steven Cooremanacda8342020-07-24 23:09:52 +02006220 shared_secret, shared_secret_size,
6221 shared_secret_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02006222 mbedtls_ecp_keypair_free( ecp );
6223 mbedtls_free( ecp );
Steven Cooreman29149862020-08-05 15:43:42 +02006224 return( status );
John Durkop6ba40d12020-11-10 08:50:04 -08006225#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
Gilles Peskine01d718c2018-09-18 12:01:02 +02006226 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01006227 (void) private_key;
6228 (void) peer_key;
6229 (void) peer_key_length;
Gilles Peskine0216fe12019-04-11 21:23:21 +02006230 (void) shared_secret;
6231 (void) shared_secret_size;
6232 (void) shared_secret_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02006233 return( PSA_ERROR_NOT_SUPPORTED );
6234 }
Gilles Peskine0216fe12019-04-11 21:23:21 +02006235}
6236
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02006237/* Note that if this function fails, you must call psa_key_derivation_abort()
Gilles Peskine01d718c2018-09-18 12:01:02 +02006238 * to potentially free embedded data structures and wipe confidential data.
6239 */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006240static psa_status_t psa_key_agreement_internal( psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01006241 psa_key_derivation_step_t step,
Gilles Peskine01d718c2018-09-18 12:01:02 +02006242 psa_key_slot_t *private_key,
6243 const uint8_t *peer_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01006244 size_t peer_key_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02006245{
6246 psa_status_t status;
6247 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
6248 size_t shared_secret_length = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006249 psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE( operation->alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02006250
6251 /* Step 1: run the secret agreement algorithm to generate the shared
6252 * secret. */
Gilles Peskine0216fe12019-04-11 21:23:21 +02006253 status = psa_key_agreement_raw_internal( ka_alg,
6254 private_key,
6255 peer_key, peer_key_length,
itayzafrir0adf0fc2018-09-06 16:24:41 +03006256 shared_secret,
6257 sizeof( shared_secret ),
Gilles Peskine05d69892018-06-19 22:00:52 +02006258 &shared_secret_length );
Gilles Peskine53d991e2018-07-12 01:14:59 +02006259 if( status != PSA_SUCCESS )
Gilles Peskine12313cd2018-06-20 00:20:32 +02006260 goto exit;
6261
Gilles Peskineb0b255c2018-07-06 17:01:38 +02006262 /* Step 2: set up the key derivation to generate key material from
Gilles Peskine224b0d62019-09-23 18:13:17 +02006263 * the shared secret. A shared secret is permitted wherever a key
6264 * of type DERIVE is permitted. */
Janos Follathb80a94e2019-06-12 15:54:46 +01006265 status = psa_key_derivation_input_internal( operation, step,
Gilles Peskine224b0d62019-09-23 18:13:17 +02006266 PSA_KEY_TYPE_DERIVE,
Janos Follathb80a94e2019-06-12 15:54:46 +01006267 shared_secret,
6268 shared_secret_length );
Gilles Peskine12313cd2018-06-20 00:20:32 +02006269exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01006270 mbedtls_platform_zeroize( shared_secret, shared_secret_length );
Gilles Peskine12313cd2018-06-20 00:20:32 +02006271 return( status );
6272}
6273
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006274psa_status_t psa_key_derivation_key_agreement( psa_key_derivation_operation_t *operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02006275 psa_key_derivation_step_t step,
Ronald Croncf56a0a2020-08-04 09:51:30 +02006276 mbedtls_svc_key_id_t private_key,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02006277 const uint8_t *peer_key,
6278 size_t peer_key_length )
Gilles Peskine12313cd2018-06-20 00:20:32 +02006279{
Ronald Cronf95a2b12020-10-22 15:24:49 +02006280 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01006281 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01006282 psa_key_slot_t *slot;
Ronald Cronf95a2b12020-10-22 15:24:49 +02006283
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006284 if( ! PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02006285 return( PSA_ERROR_INVALID_ARGUMENT );
Ronald Cron5c522922020-11-14 16:35:34 +01006286 status = psa_get_and_lock_transparent_key_slot_with_policy(
6287 private_key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg );
Gilles Peskine12313cd2018-06-20 00:20:32 +02006288 if( status != PSA_SUCCESS )
6289 return( status );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006290 status = psa_key_agreement_internal( operation, step,
Gilles Peskine346797d2018-11-16 16:05:06 +01006291 slot,
Gilles Peskine969c5d62019-01-16 15:53:06 +01006292 peer_key, peer_key_length );
Gilles Peskine346797d2018-11-16 16:05:06 +01006293 if( status != PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006294 psa_key_derivation_abort( operation );
Steven Cooremanfa5e6312020-10-15 17:07:12 +02006295 else
6296 {
6297 /* If a private key has been added as SECRET, we allow the derived
6298 * key material to be used as a key in PSA Crypto. */
6299 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
6300 operation->can_output_key = 1;
6301 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02006302
Ronald Cron5c522922020-11-14 16:35:34 +01006303 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02006304
Ronald Cron5c522922020-11-14 16:35:34 +01006305 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskineaf3baab2018-06-27 22:55:52 +02006306}
6307
Gilles Peskinebe697d82019-05-16 18:00:41 +02006308psa_status_t psa_raw_key_agreement( psa_algorithm_t alg,
Ronald Croncf56a0a2020-08-04 09:51:30 +02006309 mbedtls_svc_key_id_t private_key,
Gilles Peskinebe697d82019-05-16 18:00:41 +02006310 const uint8_t *peer_key,
6311 size_t peer_key_length,
6312 uint8_t *output,
6313 size_t output_size,
6314 size_t *output_length )
Gilles Peskine0216fe12019-04-11 21:23:21 +02006315{
Ronald Cronf95a2b12020-10-22 15:24:49 +02006316 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01006317 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cronf95a2b12020-10-22 15:24:49 +02006318 psa_key_slot_t *slot = NULL;
Gilles Peskine0216fe12019-04-11 21:23:21 +02006319
6320 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
6321 {
6322 status = PSA_ERROR_INVALID_ARGUMENT;
6323 goto exit;
6324 }
Ronald Cron5c522922020-11-14 16:35:34 +01006325 status = psa_get_and_lock_transparent_key_slot_with_policy(
6326 private_key, &slot, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine0216fe12019-04-11 21:23:21 +02006327 if( status != PSA_SUCCESS )
6328 goto exit;
6329
6330 status = psa_key_agreement_raw_internal( alg, slot,
6331 peer_key, peer_key_length,
6332 output, output_size,
6333 output_length );
6334
6335exit:
6336 if( status != PSA_SUCCESS )
6337 {
6338 /* If an error happens and is not handled properly, the output
6339 * may be used as a key to protect sensitive data. Arrange for such
6340 * a key to be random, which is likely to result in decryption or
6341 * verification errors. This is better than filling the buffer with
6342 * some constant data such as zeros, which would result in the data
6343 * being protected with a reproducible, easily knowable key.
6344 */
6345 psa_generate_random( output, output_size );
6346 *output_length = output_size;
6347 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02006348
Ronald Cron5c522922020-11-14 16:35:34 +01006349 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02006350
Ronald Cron5c522922020-11-14 16:35:34 +01006351 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine0216fe12019-04-11 21:23:21 +02006352}
Gilles Peskine86a440b2018-11-12 18:39:40 +01006353
6354
Gilles Peskine30524eb2020-11-13 17:02:26 +01006355
Gilles Peskine86a440b2018-11-12 18:39:40 +01006356/****************************************************************/
6357/* Random generation */
Gilles Peskine53d991e2018-07-12 01:14:59 +02006358/****************************************************************/
Gilles Peskine12313cd2018-06-20 00:20:32 +02006359
Gilles Peskine30524eb2020-11-13 17:02:26 +01006360/** Initialize the PSA random generator.
6361 */
6362static void mbedtls_psa_random_init( mbedtls_psa_random_context_t *rng )
6363{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006364#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6365 memset( rng, 0, sizeof( *rng ) );
6366#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
6367
Gilles Peskine30524eb2020-11-13 17:02:26 +01006368 /* Set default configuration if
6369 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
6370 if( rng->entropy_init == NULL )
6371 rng->entropy_init = mbedtls_entropy_init;
6372 if( rng->entropy_free == NULL )
6373 rng->entropy_free = mbedtls_entropy_free;
6374
6375 rng->entropy_init( &rng->entropy );
6376#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
6377 defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
6378 /* The PSA entropy injection feature depends on using NV seed as an entropy
6379 * source. Add NV seed as an entropy source for PSA entropy injection. */
6380 mbedtls_entropy_add_source( &rng->entropy,
6381 mbedtls_nv_seed_poll, NULL,
6382 MBEDTLS_ENTROPY_BLOCK_SIZE,
6383 MBEDTLS_ENTROPY_SOURCE_STRONG );
6384#endif
6385
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006386 mbedtls_psa_drbg_init( MBEDTLS_PSA_RANDOM_STATE );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006387#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006388}
6389
6390/** Deinitialize the PSA random generator.
6391 */
6392static void mbedtls_psa_random_free( mbedtls_psa_random_context_t *rng )
6393{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006394#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6395 memset( rng, 0, sizeof( *rng ) );
6396#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006397 mbedtls_psa_drbg_free( MBEDTLS_PSA_RANDOM_STATE );
Gilles Peskine30524eb2020-11-13 17:02:26 +01006398 rng->entropy_free( &rng->entropy );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006399#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006400}
6401
6402/** Seed the PSA random generator.
6403 */
6404static psa_status_t mbedtls_psa_random_seed( mbedtls_psa_random_context_t *rng )
6405{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006406#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6407 /* Do nothing: the external RNG seeds itself. */
6408 (void) rng;
6409 return( PSA_SUCCESS );
6410#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006411 const unsigned char drbg_seed[] = "PSA";
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006412 int ret = mbedtls_psa_drbg_seed( &rng->entropy,
6413 drbg_seed, sizeof( drbg_seed ) - 1 );
Gilles Peskine30524eb2020-11-13 17:02:26 +01006414 return mbedtls_to_psa_error( ret );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006415#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006416}
6417
Gilles Peskinee59236f2018-01-27 23:32:46 +01006418psa_status_t psa_generate_random( uint8_t *output,
6419 size_t output_size )
6420{
Gilles Peskinee59236f2018-01-27 23:32:46 +01006421 GUARD_MODULE_INITIALIZED;
6422
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006423#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6424
6425 size_t output_length = 0;
6426 psa_status_t status = mbedtls_psa_external_get_random( &global_data.rng,
6427 output, output_size,
6428 &output_length );
6429 if( status != PSA_SUCCESS )
6430 return( status );
6431 /* Breaking up a request into smaller chunks is currently not supported
6432 * for the extrernal RNG interface. */
6433 if( output_length != output_size )
6434 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
6435 return( PSA_SUCCESS );
6436
6437#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
6438
Gilles Peskine71ddab92021-01-04 21:01:07 +01006439 while( output_size > 0 )
Gilles Peskinef181eca2019-08-07 13:49:00 +02006440 {
Gilles Peskine71ddab92021-01-04 21:01:07 +01006441 size_t request_size =
6442 ( output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ?
6443 MBEDTLS_PSA_RANDOM_MAX_REQUEST :
6444 output_size );
Gilles Peskine0c59ba82021-01-05 14:10:59 +01006445 int ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
6446 output, request_size );
Gilles Peskinef181eca2019-08-07 13:49:00 +02006447 if( ret != 0 )
6448 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine71ddab92021-01-04 21:01:07 +01006449 output_size -= request_size;
6450 output += request_size;
Gilles Peskinef181eca2019-08-07 13:49:00 +02006451 }
Gilles Peskine0c59ba82021-01-05 14:10:59 +01006452 return( PSA_SUCCESS );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006453#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006454}
6455
Gilles Peskine8814fc42020-12-14 15:33:44 +01006456/* Wrapper function allowing the classic API to use the PSA RNG.
Gilles Peskine9c3e0602021-01-05 16:03:55 +01006457 *
6458 * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
6459 * `psa_generate_random(...)`. The state parameter is ignored since the
6460 * PSA API doesn't support passing an explicit state.
6461 *
6462 * In the non-external case, psa_generate_random() calls an
6463 * `mbedtls_xxx_drbg_random` function which has exactly the same signature
6464 * and semantics as mbedtls_psa_get_random(). As an optimization,
6465 * instead of doing this back-and-forth between the PSA API and the
6466 * classic API, psa_crypto_random_impl.h defines `mbedtls_psa_get_random`
6467 * as a constant function pointer to `mbedtls_xxx_drbg_random`.
Gilles Peskine8814fc42020-12-14 15:33:44 +01006468 */
6469#if defined (MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6470int mbedtls_psa_get_random( void *p_rng,
6471 unsigned char *output,
6472 size_t output_size )
6473{
Gilles Peskine9c3e0602021-01-05 16:03:55 +01006474 /* This function takes a pointer to the RNG state because that's what
6475 * classic mbedtls functions using an RNG expect. The PSA RNG manages
6476 * its own state internally and doesn't let the caller access that state.
6477 * So we just ignore the state parameter, and in practice we'll pass
6478 * NULL. */
Gilles Peskine8814fc42020-12-14 15:33:44 +01006479 (void) p_rng;
6480 psa_status_t status = psa_generate_random( output, output_size );
6481 if( status == PSA_SUCCESS )
6482 return( 0 );
6483 else
6484 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
6485}
6486#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
6487
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006488#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
6489#include "mbedtls/entropy_poll.h"
6490
Gilles Peskine7228da22019-07-15 11:06:15 +02006491psa_status_t mbedtls_psa_inject_entropy( const uint8_t *seed,
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006492 size_t seed_size )
6493{
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006494 if( global_data.initialized )
6495 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02006496
6497 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
6498 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
6499 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
6500 return( PSA_ERROR_INVALID_ARGUMENT );
6501
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006502 return( mbedtls_psa_storage_inject_entropy( seed, seed_size ) );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006503}
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006504#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006505
John Durkop07cc04a2020-11-16 22:08:34 -08006506#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
Gilles Peskinee56e8782019-04-26 17:34:02 +02006507static psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters,
6508 size_t domain_parameters_size,
6509 int *exponent )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006510{
Gilles Peskinee56e8782019-04-26 17:34:02 +02006511 size_t i;
6512 uint32_t acc = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006513
Gilles Peskinee56e8782019-04-26 17:34:02 +02006514 if( domain_parameters_size == 0 )
6515 {
6516 *exponent = 65537;
6517 return( PSA_SUCCESS );
6518 }
6519
6520 /* Mbed TLS encodes the public exponent as an int. For simplicity, only
6521 * support values that fit in a 32-bit integer, which is larger than
6522 * int on just about every platform anyway. */
6523 if( domain_parameters_size > sizeof( acc ) )
6524 return( PSA_ERROR_NOT_SUPPORTED );
6525 for( i = 0; i < domain_parameters_size; i++ )
6526 acc = ( acc << 8 ) | domain_parameters[i];
6527 if( acc > INT_MAX )
6528 return( PSA_ERROR_NOT_SUPPORTED );
6529 *exponent = acc;
6530 return( PSA_SUCCESS );
6531}
John Durkop07cc04a2020-11-16 22:08:34 -08006532#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */
Gilles Peskinee56e8782019-04-26 17:34:02 +02006533
Gilles Peskine35ef36b2019-05-16 19:42:05 +02006534static psa_status_t psa_generate_key_internal(
Gilles Peskinee56e8782019-04-26 17:34:02 +02006535 psa_key_slot_t *slot, size_t bits,
6536 const uint8_t *domain_parameters, size_t domain_parameters_size )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006537{
Gilles Peskine8e338702019-07-30 20:06:31 +02006538 psa_key_type_t type = slot->attr.type;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006539
Gilles Peskinee56e8782019-04-26 17:34:02 +02006540 if( domain_parameters == NULL && domain_parameters_size != 0 )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006541 return( PSA_ERROR_INVALID_ARGUMENT );
6542
Gilles Peskinee59236f2018-01-27 23:32:46 +01006543 if( key_type_is_raw_bytes( type ) )
6544 {
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006545 psa_status_t status;
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006546
6547 status = validate_unstructured_key_bit_size( slot->attr.type, bits );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006548 if( status != PSA_SUCCESS )
6549 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006550
6551 /* Allocate memory for the key */
Steven Cooreman75b74362020-07-28 14:30:13 +02006552 status = psa_allocate_buffer_to_slot( slot, PSA_BITS_TO_BYTES( bits ) );
6553 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02006554 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006555
Steven Cooreman71fd80d2020-07-07 21:12:27 +02006556 status = psa_generate_random( slot->data.key.data,
6557 slot->data.key.bytes );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006558 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006559 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006560
6561 slot->attr.bits = (psa_key_bits_t) bits;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006562#if defined(MBEDTLS_DES_C)
6563 if( type == PSA_KEY_TYPE_DES )
Steven Cooreman71fd80d2020-07-07 21:12:27 +02006564 psa_des_set_key_parity( slot->data.key.data,
6565 slot->data.key.bytes );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006566#endif /* MBEDTLS_DES_C */
6567 }
6568 else
6569
John Durkop07cc04a2020-11-16 22:08:34 -08006570#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02006571 if ( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006572 {
Steven Cooremana01795d2020-07-24 22:48:15 +02006573 mbedtls_rsa_context rsa;
Janos Follath24eed8d2019-11-22 13:21:35 +00006574 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinee56e8782019-04-26 17:34:02 +02006575 int exponent;
6576 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006577 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
6578 return( PSA_ERROR_NOT_SUPPORTED );
6579 /* Accept only byte-aligned keys, for the same reasons as
6580 * in psa_import_rsa_key(). */
6581 if( bits % 8 != 0 )
6582 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskinee56e8782019-04-26 17:34:02 +02006583 status = psa_read_rsa_exponent( domain_parameters,
6584 domain_parameters_size,
6585 &exponent );
6586 if( status != PSA_SUCCESS )
6587 return( status );
Steven Cooremana01795d2020-07-24 22:48:15 +02006588 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
6589 ret = mbedtls_rsa_gen_key( &rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01006590 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006591 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskinee59236f2018-01-27 23:32:46 +01006592 (unsigned int) bits,
6593 exponent );
6594 if( ret != 0 )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006595 return( mbedtls_to_psa_error( ret ) );
Steven Cooremana01795d2020-07-24 22:48:15 +02006596
6597 /* Make sure to always have an export representation available */
6598 size_t bytes = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE( bits );
6599
Steven Cooreman75b74362020-07-28 14:30:13 +02006600 status = psa_allocate_buffer_to_slot( slot, bytes );
6601 if( status != PSA_SUCCESS )
Steven Cooremana01795d2020-07-24 22:48:15 +02006602 {
6603 mbedtls_rsa_free( &rsa );
Steven Cooreman29149862020-08-05 15:43:42 +02006604 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006605 }
Steven Cooremana01795d2020-07-24 22:48:15 +02006606
6607 status = psa_export_rsa_key( type,
6608 &rsa,
6609 slot->data.key.data,
6610 bytes,
6611 &slot->data.key.bytes );
6612 mbedtls_rsa_free( &rsa );
6613 if( status != PSA_SUCCESS )
Steven Cooremana01795d2020-07-24 22:48:15 +02006614 psa_remove_key_data_from_memory( slot );
Steven Cooreman560c28a2020-07-24 23:20:24 +02006615 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006616 }
6617 else
John Durkop07cc04a2020-11-16 22:08:34 -08006618#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006619
John Durkop9814fa22020-11-04 12:28:15 -08006620#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02006621 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006622 {
Paul Elliott8ff510a2020-06-02 17:19:28 +01006623 psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( type );
Gilles Peskine4295e8b2019-12-02 21:39:10 +01006624 mbedtls_ecp_group_id grp_id =
6625 mbedtls_ecc_group_of_psa( curve, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006626 const mbedtls_ecp_curve_info *curve_info =
6627 mbedtls_ecp_curve_info_from_grp_id( grp_id );
Steven Cooremanacda8342020-07-24 23:09:52 +02006628 mbedtls_ecp_keypair ecp;
Janos Follath24eed8d2019-11-22 13:21:35 +00006629 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinee56e8782019-04-26 17:34:02 +02006630 if( domain_parameters_size != 0 )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006631 return( PSA_ERROR_NOT_SUPPORTED );
6632 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
6633 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooremanacda8342020-07-24 23:09:52 +02006634 mbedtls_ecp_keypair_init( &ecp );
6635 ret = mbedtls_ecp_gen_key( grp_id, &ecp,
Gilles Peskine30524eb2020-11-13 17:02:26 +01006636 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006637 MBEDTLS_PSA_RANDOM_STATE );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006638 if( ret != 0 )
6639 {
Steven Cooremanacda8342020-07-24 23:09:52 +02006640 mbedtls_ecp_keypair_free( &ecp );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006641 return( mbedtls_to_psa_error( ret ) );
6642 }
Steven Cooremanacda8342020-07-24 23:09:52 +02006643
6644
6645 /* Make sure to always have an export representation available */
6646 size_t bytes = PSA_BITS_TO_BYTES( bits );
Steven Cooreman75b74362020-07-28 14:30:13 +02006647 psa_status_t status = psa_allocate_buffer_to_slot( slot, bytes );
6648 if( status != PSA_SUCCESS )
Steven Cooremanacda8342020-07-24 23:09:52 +02006649 {
6650 mbedtls_ecp_keypair_free( &ecp );
Steven Cooreman29149862020-08-05 15:43:42 +02006651 return( status );
Steven Cooremanacda8342020-07-24 23:09:52 +02006652 }
Steven Cooreman75b74362020-07-28 14:30:13 +02006653
6654 status = mbedtls_to_psa_error(
Steven Cooremanacda8342020-07-24 23:09:52 +02006655 mbedtls_ecp_write_key( &ecp, slot->data.key.data, bytes ) );
6656
6657 mbedtls_ecp_keypair_free( &ecp );
Steven Cooremanb7f6dea2020-08-05 16:07:20 +02006658 if( status != PSA_SUCCESS ) {
6659 memset( slot->data.key.data, 0, bytes );
Steven Cooremanacda8342020-07-24 23:09:52 +02006660 psa_remove_key_data_from_memory( slot );
Steven Cooremanb7f6dea2020-08-05 16:07:20 +02006661 }
Steven Cooreman560c28a2020-07-24 23:20:24 +02006662 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006663 }
6664 else
John Durkop9814fa22020-11-04 12:28:15 -08006665#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
Steven Cooreman29149862020-08-05 15:43:42 +02006666 {
Gilles Peskinee59236f2018-01-27 23:32:46 +01006667 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooreman29149862020-08-05 15:43:42 +02006668 }
Gilles Peskinee59236f2018-01-27 23:32:46 +01006669
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006670 return( PSA_SUCCESS );
6671}
Darryl Green0c6575a2018-11-07 16:05:30 +00006672
Gilles Peskine35ef36b2019-05-16 19:42:05 +02006673psa_status_t psa_generate_key( const psa_key_attributes_t *attributes,
Ronald Croncf56a0a2020-08-04 09:51:30 +02006674 mbedtls_svc_key_id_t *key )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006675{
6676 psa_status_t status;
6677 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02006678 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine11792082019-08-06 18:36:36 +02006679
Ronald Cron81709fc2020-11-14 12:10:32 +01006680 *key = MBEDTLS_SVC_KEY_ID_INIT;
6681
Gilles Peskine0f84d622019-09-12 19:03:13 +02006682 /* Reject any attempt to create a zero-length key so that we don't
6683 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
6684 if( psa_get_key_bits( attributes ) == 0 )
6685 return( PSA_ERROR_INVALID_ARGUMENT );
6686
Ronald Cron81709fc2020-11-14 12:10:32 +01006687 status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE, attributes,
6688 &slot, &driver );
Gilles Peskine11792082019-08-06 18:36:36 +02006689 if( status != PSA_SUCCESS )
6690 goto exit;
6691
Steven Cooreman2a1664c2020-07-20 15:33:08 +02006692 status = psa_driver_wrapper_generate_key( attributes,
6693 slot );
6694 if( status != PSA_ERROR_NOT_SUPPORTED ||
6695 psa_key_lifetime_is_external( attributes->core.lifetime ) )
6696 goto exit;
6697
6698 status = psa_generate_key_internal(
6699 slot, attributes->core.bits,
6700 attributes->domain_parameters, attributes->domain_parameters_size );
Gilles Peskine11792082019-08-06 18:36:36 +02006701
6702exit:
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006703 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01006704 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006705 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02006706 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02006707
Darryl Green0c6575a2018-11-07 16:05:30 +00006708 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006709}
6710
6711
Gilles Peskinee59236f2018-01-27 23:32:46 +01006712
6713/****************************************************************/
6714/* Module setup */
6715/****************************************************************/
6716
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006717#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
Gilles Peskine5e769522018-11-20 21:59:56 +01006718psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
6719 void (* entropy_init )( mbedtls_entropy_context *ctx ),
6720 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
6721{
6722 if( global_data.rng_state != RNG_NOT_INITIALIZED )
6723 return( PSA_ERROR_BAD_STATE );
Gilles Peskine30524eb2020-11-13 17:02:26 +01006724 global_data.rng.entropy_init = entropy_init;
6725 global_data.rng.entropy_free = entropy_free;
Gilles Peskine5e769522018-11-20 21:59:56 +01006726 return( PSA_SUCCESS );
6727}
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006728#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
Gilles Peskine5e769522018-11-20 21:59:56 +01006729
Gilles Peskinee59236f2018-01-27 23:32:46 +01006730void mbedtls_psa_crypto_free( void )
6731{
Gilles Peskine66fb1262018-12-10 16:29:04 +01006732 psa_wipe_all_key_slots( );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006733 if( global_data.rng_state != RNG_NOT_INITIALIZED )
6734 {
Gilles Peskine30524eb2020-11-13 17:02:26 +01006735 mbedtls_psa_random_free( &global_data.rng );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006736 }
6737 /* Wipe all remaining data, including configuration.
6738 * In particular, this sets all state indicator to the value
6739 * indicating "uninitialized". */
Gilles Peskine3f108122018-12-07 18:14:53 +01006740 mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
Gilles Peskinea8ade162019-06-26 11:24:49 +02006741#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined0890212019-06-24 14:34:43 +02006742 /* Unregister all secure element drivers, so that we restart from
6743 * a pristine state. */
6744 psa_unregister_all_se_drivers( );
Gilles Peskinea8ade162019-06-26 11:24:49 +02006745#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006746}
6747
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006748#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
6749/** Recover a transaction that was interrupted by a power failure.
6750 *
6751 * This function is called during initialization, before psa_crypto_init()
6752 * returns. If this function returns a failure status, the initialization
6753 * fails.
6754 */
6755static psa_status_t psa_crypto_recover_transaction(
6756 const psa_crypto_transaction_t *transaction )
6757{
6758 switch( transaction->unknown.type )
6759 {
6760 case PSA_CRYPTO_TRANSACTION_CREATE_KEY:
6761 case PSA_CRYPTO_TRANSACTION_DESTROY_KEY:
Janos Follath1d57a202019-08-13 12:15:34 +01006762 /* TODO - fall through to the failure case until this
Gilles Peskinec9d7f942019-08-13 16:17:16 +02006763 * is implemented.
6764 * https://github.com/ARMmbed/mbed-crypto/issues/218
6765 */
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006766 default:
6767 /* We found an unsupported transaction in the storage.
6768 * We don't know what state the storage is in. Give up. */
6769 return( PSA_ERROR_STORAGE_FAILURE );
6770 }
6771}
6772#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
6773
Gilles Peskinee59236f2018-01-27 23:32:46 +01006774psa_status_t psa_crypto_init( void )
6775{
Gilles Peskine66fb1262018-12-10 16:29:04 +01006776 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006777
Gilles Peskinec6b69072018-11-20 21:42:52 +01006778 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006779 if( global_data.initialized != 0 )
6780 return( PSA_SUCCESS );
6781
Gilles Peskine30524eb2020-11-13 17:02:26 +01006782 /* Initialize and seed the random generator. */
6783 mbedtls_psa_random_init( &global_data.rng );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006784 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskine30524eb2020-11-13 17:02:26 +01006785 status = mbedtls_psa_random_seed( &global_data.rng );
Gilles Peskine66fb1262018-12-10 16:29:04 +01006786 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006787 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01006788 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006789
Gilles Peskine66fb1262018-12-10 16:29:04 +01006790 status = psa_initialize_key_slots( );
6791 if( status != PSA_SUCCESS )
6792 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01006793
Gilles Peskined9348f22019-10-01 15:22:29 +02006794#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
6795 status = psa_init_all_se_drivers( );
6796 if( status != PSA_SUCCESS )
6797 goto exit;
6798#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
6799
Gilles Peskine4b734222019-07-24 15:56:31 +02006800#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
Gilles Peskinefc762652019-07-22 19:30:34 +02006801 status = psa_crypto_load_transaction( );
6802 if( status == PSA_SUCCESS )
6803 {
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006804 status = psa_crypto_recover_transaction( &psa_crypto_transaction );
6805 if( status != PSA_SUCCESS )
6806 goto exit;
6807 status = psa_crypto_stop_transaction( );
Gilles Peskinefc762652019-07-22 19:30:34 +02006808 }
6809 else if( status == PSA_ERROR_DOES_NOT_EXIST )
6810 {
6811 /* There's no transaction to complete. It's all good. */
6812 status = PSA_SUCCESS;
6813 }
Gilles Peskine4b734222019-07-24 15:56:31 +02006814#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
Gilles Peskinefc762652019-07-22 19:30:34 +02006815
Gilles Peskinec6b69072018-11-20 21:42:52 +01006816 /* All done. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006817 global_data.initialized = 1;
6818
6819exit:
Gilles Peskine66fb1262018-12-10 16:29:04 +01006820 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006821 mbedtls_psa_crypto_free( );
Gilles Peskine66fb1262018-12-10 16:29:04 +01006822 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006823}
6824
6825#endif /* MBEDTLS_PSA_CRYPTO_C */