blob: fbde52bd338ef5ecc00e6337f62666cea670db84 [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"
Ronald Cron00b7bfc2020-11-25 15:25:26 +010035#include "psa_crypto_ecp.h"
36#include "psa_crypto_rsa.h"
Ronald Cron7023db52020-11-20 18:17:42 +010037#include "psa_crypto_ecp.h"
Gilles Peskinea8ade162019-06-26 11:24:49 +020038#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined0890212019-06-24 14:34:43 +020039#include "psa_crypto_se.h"
Gilles Peskinea8ade162019-06-26 11:24:49 +020040#endif
Gilles Peskine961849f2018-11-30 18:54:54 +010041#include "psa_crypto_slot_management.h"
Darryl Greend49a4992018-06-18 17:27:26 +010042/* Include internal declarations that are useful for implementing persistently
43 * stored keys. */
44#include "psa_crypto_storage.h"
45
Gilles Peskineb2b64d32020-12-14 16:43:58 +010046#include "psa_crypto_random_impl.h"
Gilles Peskine90edc992020-11-13 15:39:19 +010047
Gilles Peskineb46bef22019-07-30 21:32:04 +020048#include <assert.h>
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010049#include <stdlib.h>
50#include <string.h>
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010051#include "mbedtls/platform.h"
Gilles Peskineff2d2002019-05-06 15:26:23 +020052#if !defined(MBEDTLS_PLATFORM_C)
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010053#define mbedtls_calloc calloc
54#define mbedtls_free free
55#endif
56
Gilles Peskine1c49f1a2020-11-13 18:46:25 +010057#include "mbedtls/aes.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010058#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020059#include "mbedtls/asn1.h"
Jaeden Amero25384a22019-01-10 10:23:21 +000060#include "mbedtls/asn1write.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020061#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010062#include "mbedtls/blowfish.h"
63#include "mbedtls/camellia.h"
Gilles Peskine26869f22019-05-06 15:25:00 +020064#include "mbedtls/chacha20.h"
65#include "mbedtls/chachapoly.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010066#include "mbedtls/cipher.h"
67#include "mbedtls/ccm.h"
68#include "mbedtls/cmac.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010069#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020070#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010071#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010072#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010073#include "mbedtls/error.h"
74#include "mbedtls/gcm.h"
75#include "mbedtls/md2.h"
76#include "mbedtls/md4.h"
77#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010078#include "mbedtls/md.h"
79#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010080#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010081#include "mbedtls/pk_internal.h"
Gilles Peskine3f108122018-12-07 18:14:53 +010082#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000083#include "mbedtls/error.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010084#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010085#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010086#include "mbedtls/sha1.h"
87#include "mbedtls/sha256.h"
88#include "mbedtls/sha512.h"
89#include "mbedtls/xtea.h"
90
Gilles Peskine996deb12018-08-01 15:45:45 +020091#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
92
Gilles Peskine9ef733f2018-02-07 21:05:37 +010093/* constant-time buffer comparison */
94static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
95{
96 size_t i;
97 unsigned char diff = 0;
98
99 for( i = 0; i < n; i++ )
100 diff |= a[i] ^ b[i];
101
102 return( diff );
103}
104
105
106
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100107/****************************************************************/
108/* Global data, support functions and library management */
109/****************************************************************/
110
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200111static int key_type_is_raw_bytes( psa_key_type_t type )
112{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200113 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200114}
115
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100116/* Values for psa_global_data_t::rng_state */
117#define RNG_NOT_INITIALIZED 0
118#define RNG_INITIALIZED 1
119#define RNG_SEEDED 2
Gilles Peskinec6b69072018-11-20 21:42:52 +0100120
Gilles Peskine2d277862018-06-18 15:41:12 +0200121typedef struct
122{
Gilles Peskine30524eb2020-11-13 17:02:26 +0100123 mbedtls_psa_random_context_t rng;
Gilles Peskinec6b69072018-11-20 21:42:52 +0100124 unsigned initialized : 1;
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100125 unsigned rng_state : 2;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100126} psa_global_data_t;
127
128static psa_global_data_t global_data;
129
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100130#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
131mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state =
132 &global_data.rng.drbg;
133#endif
134
itayzafrir0adf0fc2018-09-06 16:24:41 +0300135#define GUARD_MODULE_INITIALIZED \
136 if( global_data.initialized == 0 ) \
137 return( PSA_ERROR_BAD_STATE );
138
Steven Cooreman01164162020-07-20 15:31:37 +0200139psa_status_t mbedtls_to_psa_error( int ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100140{
Gilles Peskinedbf68962021-01-06 20:04:23 +0100141 /* Mbed TLS error codes can combine a high-level error code and a
142 * low-level error code. The low-level error usually reflects the
143 * root cause better, so dispatch on that preferably. */
144 int low_level_ret = - ( -ret & 0x007f );
145 switch( low_level_ret != 0 ? low_level_ret : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100146 {
147 case 0:
148 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100149
150 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
151 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
152 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
153 return( PSA_ERROR_NOT_SUPPORTED );
154 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
155 return( PSA_ERROR_HARDWARE_FAILURE );
156
157 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
158 return( PSA_ERROR_HARDWARE_FAILURE );
159
Gilles Peskine9a944802018-06-21 09:35:35 +0200160 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
161 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
162 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
163 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
164 case MBEDTLS_ERR_ASN1_INVALID_DATA:
165 return( PSA_ERROR_INVALID_ARGUMENT );
166 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
167 return( PSA_ERROR_INSUFFICIENT_MEMORY );
168 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
169 return( PSA_ERROR_BUFFER_TOO_SMALL );
170
Jaeden Amero93e21112019-02-20 13:57:28 +0000171#if defined(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA)
Jaeden Amero892cd6d2019-02-11 12:21:12 +0000172 case MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA:
Jaeden Amero93e21112019-02-20 13:57:28 +0000173#elif defined(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH)
174 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
175#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100176 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
177 return( PSA_ERROR_NOT_SUPPORTED );
178 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
179 return( PSA_ERROR_HARDWARE_FAILURE );
180
Jaeden Amero93e21112019-02-20 13:57:28 +0000181#if defined(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
Jaeden Amero892cd6d2019-02-11 12:21:12 +0000182 case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA:
Jaeden Amero93e21112019-02-20 13:57:28 +0000183#elif defined(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH)
184 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
185#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100186 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
187 return( PSA_ERROR_NOT_SUPPORTED );
188 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
189 return( PSA_ERROR_HARDWARE_FAILURE );
190
191 case MBEDTLS_ERR_CCM_BAD_INPUT:
192 return( PSA_ERROR_INVALID_ARGUMENT );
193 case MBEDTLS_ERR_CCM_AUTH_FAILED:
194 return( PSA_ERROR_INVALID_SIGNATURE );
195 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
196 return( PSA_ERROR_HARDWARE_FAILURE );
197
Gilles Peskine26869f22019-05-06 15:25:00 +0200198 case MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA:
199 return( PSA_ERROR_INVALID_ARGUMENT );
200
201 case MBEDTLS_ERR_CHACHAPOLY_BAD_STATE:
202 return( PSA_ERROR_BAD_STATE );
203 case MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED:
204 return( PSA_ERROR_INVALID_SIGNATURE );
205
Gilles Peskinea5905292018-02-07 20:59:33 +0100206 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
207 return( PSA_ERROR_NOT_SUPPORTED );
208 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
209 return( PSA_ERROR_INVALID_ARGUMENT );
210 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
211 return( PSA_ERROR_INSUFFICIENT_MEMORY );
212 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
213 return( PSA_ERROR_INVALID_PADDING );
214 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
Fredrik Strupef90e3012020-09-28 16:11:33 +0200215 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100216 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
217 return( PSA_ERROR_INVALID_SIGNATURE );
218 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
Gilles Peskine4b3eb692019-05-16 21:35:18 +0200219 return( PSA_ERROR_CORRUPTION_DETECTED );
Gilles Peskinea5905292018-02-07 20:59:33 +0100220 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
221 return( PSA_ERROR_HARDWARE_FAILURE );
222
223 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
224 return( PSA_ERROR_HARDWARE_FAILURE );
225
Gilles Peskine82e57d12020-11-13 21:31:17 +0100226#if !( defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) || \
227 defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE) )
Gilles Peskinebee96c82020-11-23 21:00:09 +0100228 /* Only check CTR_DRBG error codes if underlying mbedtls_xxx
229 * functions are passed a CTR_DRBG instance. */
Gilles Peskinea5905292018-02-07 20:59:33 +0100230 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
231 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
232 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
233 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
234 return( PSA_ERROR_NOT_SUPPORTED );
235 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
236 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskine82e57d12020-11-13 21:31:17 +0100237#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100238
239 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
240 return( PSA_ERROR_NOT_SUPPORTED );
241 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
242 return( PSA_ERROR_HARDWARE_FAILURE );
243
Gilles Peskinee59236f2018-01-27 23:32:46 +0100244 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
245 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
246 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
247 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100248
249 case MBEDTLS_ERR_GCM_AUTH_FAILED:
250 return( PSA_ERROR_INVALID_SIGNATURE );
251 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200252 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100253 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
254 return( PSA_ERROR_HARDWARE_FAILURE );
255
Gilles Peskine82e57d12020-11-13 21:31:17 +0100256#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \
257 defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
Gilles Peskinebee96c82020-11-23 21:00:09 +0100258 /* Only check HMAC_DRBG error codes if underlying mbedtls_xxx
259 * functions are passed a HMAC_DRBG instance. */
Gilles Peskine82e57d12020-11-13 21:31:17 +0100260 case MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED:
261 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
262 case MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG:
263 case MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG:
264 return( PSA_ERROR_NOT_SUPPORTED );
265 case MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR:
266 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
267#endif
268
Gilles Peskinea5905292018-02-07 20:59:33 +0100269 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
270 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
271 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
272 return( PSA_ERROR_HARDWARE_FAILURE );
273
274 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
275 return( PSA_ERROR_NOT_SUPPORTED );
276 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
277 return( PSA_ERROR_INVALID_ARGUMENT );
278 case MBEDTLS_ERR_MD_ALLOC_FAILED:
279 return( PSA_ERROR_INSUFFICIENT_MEMORY );
280 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
281 return( PSA_ERROR_STORAGE_FAILURE );
282 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
283 return( PSA_ERROR_HARDWARE_FAILURE );
284
Gilles Peskinef76aa772018-10-29 19:24:33 +0100285 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
286 return( PSA_ERROR_STORAGE_FAILURE );
287 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
288 return( PSA_ERROR_INVALID_ARGUMENT );
289 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
290 return( PSA_ERROR_INVALID_ARGUMENT );
291 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
292 return( PSA_ERROR_BUFFER_TOO_SMALL );
293 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
294 return( PSA_ERROR_INVALID_ARGUMENT );
295 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
296 return( PSA_ERROR_INVALID_ARGUMENT );
297 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
298 return( PSA_ERROR_INVALID_ARGUMENT );
299 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
300 return( PSA_ERROR_INSUFFICIENT_MEMORY );
301
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100302 case MBEDTLS_ERR_PK_ALLOC_FAILED:
303 return( PSA_ERROR_INSUFFICIENT_MEMORY );
304 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
305 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
306 return( PSA_ERROR_INVALID_ARGUMENT );
307 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100308 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100309 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
310 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
311 return( PSA_ERROR_INVALID_ARGUMENT );
312 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
313 return( PSA_ERROR_NOT_SUPPORTED );
314 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
315 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
316 return( PSA_ERROR_NOT_PERMITTED );
317 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
318 return( PSA_ERROR_INVALID_ARGUMENT );
319 case MBEDTLS_ERR_PK_INVALID_ALG:
320 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
321 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
322 return( PSA_ERROR_NOT_SUPPORTED );
323 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
324 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100325 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
326 return( PSA_ERROR_HARDWARE_FAILURE );
327
Gilles Peskineff2d2002019-05-06 15:26:23 +0200328 case MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED:
329 return( PSA_ERROR_HARDWARE_FAILURE );
330 case MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
331 return( PSA_ERROR_NOT_SUPPORTED );
332
Gilles Peskinea5905292018-02-07 20:59:33 +0100333 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
334 return( PSA_ERROR_HARDWARE_FAILURE );
335
336 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
337 return( PSA_ERROR_INVALID_ARGUMENT );
338 case MBEDTLS_ERR_RSA_INVALID_PADDING:
339 return( PSA_ERROR_INVALID_PADDING );
340 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
341 return( PSA_ERROR_HARDWARE_FAILURE );
342 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
343 return( PSA_ERROR_INVALID_ARGUMENT );
344 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
345 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
Gilles Peskine4b3eb692019-05-16 21:35:18 +0200346 return( PSA_ERROR_CORRUPTION_DETECTED );
Gilles Peskinea5905292018-02-07 20:59:33 +0100347 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
348 return( PSA_ERROR_INVALID_SIGNATURE );
349 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
350 return( PSA_ERROR_BUFFER_TOO_SMALL );
351 case MBEDTLS_ERR_RSA_RNG_FAILED:
Gilles Peskine40d81602020-11-25 00:09:47 +0100352 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100353 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
354 return( PSA_ERROR_NOT_SUPPORTED );
355 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
356 return( PSA_ERROR_HARDWARE_FAILURE );
357
358 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
359 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
360 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
361 return( PSA_ERROR_HARDWARE_FAILURE );
362
363 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
364 return( PSA_ERROR_INVALID_ARGUMENT );
365 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
366 return( PSA_ERROR_HARDWARE_FAILURE );
367
itayzafrir5c753392018-05-08 11:18:38 +0300368 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300369 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300370 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300371 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
372 return( PSA_ERROR_BUFFER_TOO_SMALL );
373 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
374 return( PSA_ERROR_NOT_SUPPORTED );
375 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
376 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
377 return( PSA_ERROR_INVALID_SIGNATURE );
378 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
379 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Gilles Peskine40d81602020-11-25 00:09:47 +0100380 case MBEDTLS_ERR_ECP_RANDOM_FAILED:
381 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300382 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
383 return( PSA_ERROR_HARDWARE_FAILURE );
Gilles Peskine40d81602020-11-25 00:09:47 +0100384
Janos Follatha13b9052019-11-22 12:48:59 +0000385 case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
386 return( PSA_ERROR_CORRUPTION_DETECTED );
itayzafrir5c753392018-05-08 11:18:38 +0300387
Gilles Peskinee59236f2018-01-27 23:32:46 +0100388 default:
David Saadab4ecc272019-02-14 13:48:10 +0200389 return( PSA_ERROR_GENERIC_ERROR );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100390 }
391}
392
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200393
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200394
395
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100396/****************************************************************/
397/* Key management */
398/****************************************************************/
399
Gilles Peskine73167e12019-07-12 23:44:37 +0200400#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
401static inline int psa_key_slot_is_external( const psa_key_slot_t *slot )
402{
Gilles Peskine8e338702019-07-30 20:06:31 +0200403 return( psa_key_lifetime_is_external( slot->attr.lifetime ) );
Gilles Peskine73167e12019-07-12 23:44:37 +0200404}
405#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
406
John Durkop07cc04a2020-11-16 22:08:34 -0800407/* For now the MBEDTLS_PSA_ACCEL_ guards are also used here since the
408 * current test driver in key_management.c is using this function
409 * when accelerators are used for ECC key pair and public key.
410 * Once that dependency is resolved these guards can be removed.
411 */
John Durkop9814fa22020-11-04 12:28:15 -0800412#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
John Durkop6ba40d12020-11-10 08:50:04 -0800413 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
414 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \
415 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
Paul Elliott8ff510a2020-06-02 17:19:28 +0100416mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_family_t curve,
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100417 size_t bits,
418 int bits_is_sloppy )
Gilles Peskine12313cd2018-06-20 00:20:32 +0200419{
420 switch( curve )
421 {
Paul Elliott8ff510a2020-06-02 17:19:28 +0100422 case PSA_ECC_FAMILY_SECP_R1:
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100423 switch( bits )
Gilles Peskine228abc52019-12-03 17:24:19 +0100424 {
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100425 case 192:
Gilles Peskine228abc52019-12-03 17:24:19 +0100426 return( MBEDTLS_ECP_DP_SECP192R1 );
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100427 case 224:
Gilles Peskine228abc52019-12-03 17:24:19 +0100428 return( MBEDTLS_ECP_DP_SECP224R1 );
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100429 case 256:
Gilles Peskine228abc52019-12-03 17:24:19 +0100430 return( MBEDTLS_ECP_DP_SECP256R1 );
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100431 case 384:
Gilles Peskine228abc52019-12-03 17:24:19 +0100432 return( MBEDTLS_ECP_DP_SECP384R1 );
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100433 case 521:
Gilles Peskine228abc52019-12-03 17:24:19 +0100434 return( MBEDTLS_ECP_DP_SECP521R1 );
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100435 case 528:
436 if( bits_is_sloppy )
437 return( MBEDTLS_ECP_DP_SECP521R1 );
438 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100439 }
440 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100441
Paul Elliott8ff510a2020-06-02 17:19:28 +0100442 case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100443 switch( bits )
Gilles Peskine228abc52019-12-03 17:24:19 +0100444 {
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100445 case 256:
Gilles Peskine228abc52019-12-03 17:24:19 +0100446 return( MBEDTLS_ECP_DP_BP256R1 );
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100447 case 384:
Gilles Peskine228abc52019-12-03 17:24:19 +0100448 return( MBEDTLS_ECP_DP_BP384R1 );
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100449 case 512:
Gilles Peskine228abc52019-12-03 17:24:19 +0100450 return( MBEDTLS_ECP_DP_BP512R1 );
Gilles Peskine228abc52019-12-03 17:24:19 +0100451 }
452 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100453
Paul Elliott8ff510a2020-06-02 17:19:28 +0100454 case PSA_ECC_FAMILY_MONTGOMERY:
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100455 switch( bits )
Gilles Peskine228abc52019-12-03 17:24:19 +0100456 {
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100457 case 255:
Gilles Peskine228abc52019-12-03 17:24:19 +0100458 return( MBEDTLS_ECP_DP_CURVE25519 );
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100459 case 256:
460 if( bits_is_sloppy )
461 return( MBEDTLS_ECP_DP_CURVE25519 );
462 break;
463 case 448:
Gilles Peskine228abc52019-12-03 17:24:19 +0100464 return( MBEDTLS_ECP_DP_CURVE448 );
Gilles Peskine228abc52019-12-03 17:24:19 +0100465 }
466 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100467
Paul Elliott8ff510a2020-06-02 17:19:28 +0100468 case PSA_ECC_FAMILY_SECP_K1:
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100469 switch( bits )
Gilles Peskine228abc52019-12-03 17:24:19 +0100470 {
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100471 case 192:
Gilles Peskine228abc52019-12-03 17:24:19 +0100472 return( MBEDTLS_ECP_DP_SECP192K1 );
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100473 case 224:
Gilles Peskine228abc52019-12-03 17:24:19 +0100474 return( MBEDTLS_ECP_DP_SECP224K1 );
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100475 case 256:
Gilles Peskine228abc52019-12-03 17:24:19 +0100476 return( MBEDTLS_ECP_DP_SECP256K1 );
Gilles Peskine228abc52019-12-03 17:24:19 +0100477 }
478 break;
Gilles Peskine12313cd2018-06-20 00:20:32 +0200479 }
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100480
481 return( MBEDTLS_ECP_DP_NONE );
Gilles Peskine12313cd2018-06-20 00:20:32 +0200482}
John Durkop9814fa22020-11-04 12:28:15 -0800483#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
John Durkop6ba40d12020-11-10 08:50:04 -0800484 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
485 * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) ||
486 * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200487
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200488static psa_status_t validate_unstructured_key_bit_size( psa_key_type_t type,
489 size_t bits )
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200490{
491 /* Check that the bit size is acceptable for the key type */
492 switch( type )
493 {
494 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200495 case PSA_KEY_TYPE_HMAC:
Gilles Peskineea0fb492018-07-12 17:17:20 +0200496 case PSA_KEY_TYPE_DERIVE:
497 break;
David Browne04acc22021-01-26 11:39:16 -0700498#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200499 case PSA_KEY_TYPE_AES:
500 if( bits != 128 && bits != 192 && bits != 256 )
501 return( PSA_ERROR_INVALID_ARGUMENT );
502 break;
503#endif
David Browne04acc22021-01-26 11:39:16 -0700504#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200505 case PSA_KEY_TYPE_CAMELLIA:
506 if( bits != 128 && bits != 192 && bits != 256 )
507 return( PSA_ERROR_INVALID_ARGUMENT );
508 break;
509#endif
David Browne04acc22021-01-26 11:39:16 -0700510#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200511 case PSA_KEY_TYPE_DES:
512 if( bits != 64 && bits != 128 && bits != 192 )
513 return( PSA_ERROR_INVALID_ARGUMENT );
514 break;
515#endif
David Browne04acc22021-01-26 11:39:16 -0700516#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARC4)
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200517 case PSA_KEY_TYPE_ARC4:
518 if( bits < 8 || bits > 2048 )
519 return( PSA_ERROR_INVALID_ARGUMENT );
520 break;
521#endif
David Brown1bfe4d72021-02-16 12:54:35 -0700522#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
Gilles Peskine26869f22019-05-06 15:25:00 +0200523 case PSA_KEY_TYPE_CHACHA20:
524 if( bits != 256 )
525 return( PSA_ERROR_INVALID_ARGUMENT );
526 break;
527#endif
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200528 default:
529 return( PSA_ERROR_NOT_SUPPORTED );
530 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200531 if( bits % 8 != 0 )
532 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200533
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200534 return( PSA_SUCCESS );
535}
536
Gilles Peskineb46bef22019-07-30 21:32:04 +0200537/** Return the size of the key in the given slot, in bits.
538 *
539 * \param[in] slot A key slot.
540 *
541 * \return The key size in bits, read from the metadata in the slot.
542 */
543static inline size_t psa_get_key_slot_bits( const psa_key_slot_t *slot )
544{
545 return( slot->attr.bits );
546}
547
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100548/** Return the output MAC length of a MAC algorithm, in bytes
549 *
550 * \param[in] algorithm The specific MAC algorithm
551 * \param[in] key_type The key type of the key to be used with the
552 * \p algorithm.
553 * \param[out] length The calculated output length of the given MAC
554 * \p algorithm when used with a key corresponding to
555 * the given \p key_type
556 *
557 * \retval #PSA_SUCCESS
558 * The \p length has been successfully calculated
559 * \retval #PSA_ERROR_NOT_SUPPORTED
560 * \p algorithm is a MAC algorithm, but ubsupported by this PSA core.
561 * \retval #PSA_ERROR_INVALID_ARGUMENT
562 * \p algorithm is not a valid, specific MAC algorithm or \p key_type
563 * describes a key incompatible with the specified \p algorithm.
564 */
565static psa_status_t psa_get_mac_output_length( psa_algorithm_t algorithm,
566 psa_key_type_t key_type,
567 size_t *length )
568{
569 if( !PSA_ALG_IS_MAC( algorithm ) || PSA_ALG_IS_WILDCARD( algorithm ) )
570 return( PSA_ERROR_INVALID_ARGUMENT );
571
572 size_t default_length = 0;
573
574 if( PSA_ALG_FULL_LENGTH_MAC( algorithm ) == PSA_ALG_CMAC ||
575 PSA_ALG_FULL_LENGTH_MAC( algorithm ) == PSA_ALG_CBC_MAC )
576 {
577 default_length = PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type );
578 /* CMAC and CBC-MAC are only defined on block ciphers */
579 if( default_length == 0 )
580 return( PSA_ERROR_INVALID_ARGUMENT );
581 }
582 else if( PSA_ALG_IS_HMAC( algorithm ) )
583 {
584 /* HMAC output length is dictated by the underlying hash operation */
585 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( algorithm );
586 default_length = PSA_HASH_LENGTH( hash_alg );
587
588 if( hash_alg == 0 || default_length == 0 )
589 return( PSA_ERROR_INVALID_ARGUMENT );
590 }
591 else
592 return( PSA_ERROR_NOT_SUPPORTED );
593
594 /* Output the expected (potentially truncated) length as long as it can
595 * actually be output by the algorithm */
596 if( PSA_ALG_FULL_LENGTH_MAC( algorithm ) == algorithm )
597 {
598 *length = default_length;
599 return( PSA_SUCCESS );
600 }
601 else if( PSA_MAC_TRUNCATED_LENGTH( algorithm ) <= default_length )
602 {
603 *length = PSA_MAC_TRUNCATED_LENGTH( algorithm );
604 return( PSA_SUCCESS );
605 }
606 else
607 return( PSA_ERROR_INVALID_ARGUMENT );
608}
609
Steven Cooreman75b74362020-07-28 14:30:13 +0200610/** Try to allocate a buffer to an empty key slot.
611 *
612 * \param[in,out] slot Key slot to attach buffer to.
613 * \param[in] buffer_length Requested size of the buffer.
614 *
615 * \retval #PSA_SUCCESS
616 * The buffer has been successfully allocated.
617 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
618 * Not enough memory was available for allocation.
619 * \retval #PSA_ERROR_ALREADY_EXISTS
620 * Trying to allocate a buffer to a non-empty key slot.
621 */
622static psa_status_t psa_allocate_buffer_to_slot( psa_key_slot_t *slot,
623 size_t buffer_length )
624{
Ronald Cronea0f8a62020-11-25 17:52:23 +0100625 if( slot->key.data != NULL )
Steven Cooreman29149862020-08-05 15:43:42 +0200626 return( PSA_ERROR_ALREADY_EXISTS );
Steven Cooreman75b74362020-07-28 14:30:13 +0200627
Ronald Cronea0f8a62020-11-25 17:52:23 +0100628 slot->key.data = mbedtls_calloc( 1, buffer_length );
629 if( slot->key.data == NULL )
Steven Cooreman29149862020-08-05 15:43:42 +0200630 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Steven Cooreman75b74362020-07-28 14:30:13 +0200631
Ronald Cronea0f8a62020-11-25 17:52:23 +0100632 slot->key.bytes = buffer_length;
Steven Cooreman29149862020-08-05 15:43:42 +0200633 return( PSA_SUCCESS );
Steven Cooreman75b74362020-07-28 14:30:13 +0200634}
635
Steven Cooremanf7cebd42020-10-13 20:27:40 +0200636psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot,
637 const uint8_t* data,
638 size_t data_length )
639{
640 psa_status_t status = psa_allocate_buffer_to_slot( slot,
641 data_length );
642 if( status != PSA_SUCCESS )
643 return( status );
644
Ronald Cronea0f8a62020-11-25 17:52:23 +0100645 memcpy( slot->key.data, data, data_length );
Steven Cooremanf7cebd42020-10-13 20:27:40 +0200646 return( PSA_SUCCESS );
647}
648
Ronald Crona0fe59f2020-11-29 11:14:53 +0100649psa_status_t psa_import_key_into_slot(
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100650 const psa_key_attributes_t *attributes,
651 const uint8_t *data, size_t data_length,
652 uint8_t *key_buffer, size_t key_buffer_size,
653 size_t *key_buffer_length, size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100654{
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100655 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
656 psa_key_type_t type = attributes->core.type;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100657
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200658 /* zero-length keys are never supported. */
659 if( data_length == 0 )
660 return( PSA_ERROR_NOT_SUPPORTED );
661
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100662 if( key_type_is_raw_bytes( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100663 {
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100664 *bits = PSA_BYTES_TO_BITS( data_length );
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200665
Steven Cooreman75b74362020-07-28 14:30:13 +0200666 /* Ensure that the bytes-to-bits conversion hasn't overflown. */
667 if( data_length > SIZE_MAX / 8 )
668 return( PSA_ERROR_NOT_SUPPORTED );
669
Gilles Peskine1b9505c2019-08-07 10:59:45 +0200670 /* Enforce a size limit, and in particular ensure that the bit
671 * size fits in its representation type. */
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100672 if( ( *bits ) > PSA_MAX_KEY_BITS )
Gilles Peskinec744d992019-07-30 17:26:54 +0200673 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200674
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100675 status = validate_unstructured_key_bit_size( type, *bits );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200676 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +0200677 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200678
Ronald Crondd04d422020-11-28 15:14:42 +0100679 /* Copy the key material. */
680 memcpy( key_buffer, data, data_length );
681 *key_buffer_length = data_length;
682 (void)key_buffer_size;
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200683
Steven Cooreman40120f62020-10-29 11:42:22 +0100684 return( PSA_SUCCESS );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100685 }
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100686 else if( PSA_KEY_TYPE_IS_ASYMMETRIC( type ) )
Steven Cooreman19fd5742020-07-24 23:31:01 +0200687 {
John Durkop9814fa22020-11-04 12:28:15 -0800688#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
689 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100690 if( PSA_KEY_TYPE_IS_ECC( type ) )
Steven Cooreman3ea0ce42020-10-23 11:37:05 +0200691 {
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100692 return( mbedtls_psa_ecp_import_key( attributes,
693 data, data_length,
694 key_buffer, key_buffer_size,
695 key_buffer_length,
696 bits ) );
Steven Cooreman40120f62020-10-29 11:42:22 +0100697 }
John Durkop9814fa22020-11-04 12:28:15 -0800698#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
699 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
John Durkop0e005192020-10-31 22:06:54 -0700700#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
701 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100702 if( PSA_KEY_TYPE_IS_RSA( type ) )
Steven Cooreman3ea0ce42020-10-23 11:37:05 +0200703 {
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100704 return( mbedtls_psa_rsa_import_key( attributes,
705 data, data_length,
706 key_buffer, key_buffer_size,
707 key_buffer_length,
708 bits ) );
Steven Cooreman3ea0ce42020-10-23 11:37:05 +0200709 }
John Durkop9814fa22020-11-04 12:28:15 -0800710#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
711 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100712 }
Steven Cooreman40120f62020-10-29 11:42:22 +0100713
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100714 return( PSA_ERROR_NOT_SUPPORTED );
Darryl Green06fd18d2018-07-16 11:21:11 +0100715}
716
Gilles Peskinef603c712019-01-19 13:40:11 +0100717/** Calculate the intersection of two algorithm usage policies.
718 *
719 * Return 0 (which allows no operation) on incompatibility.
720 */
721static psa_algorithm_t psa_key_policy_algorithm_intersection(
722 psa_algorithm_t alg1,
723 psa_algorithm_t alg2 )
724{
Gilles Peskine549ea862019-05-22 11:45:59 +0200725 /* Common case: both sides actually specify the same policy. */
Gilles Peskinef603c712019-01-19 13:40:11 +0100726 if( alg1 == alg2 )
727 return( alg1 );
Steven Cooreman03488022021-02-18 12:07:20 +0100728 /* If the policies are from the same hash-and-sign family, check
729 * if one is a wildcard. If so the other has the specific algorithm. */
730 if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) &&
731 PSA_ALG_IS_HASH_AND_SIGN( alg2 ) &&
732 ( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
Gilles Peskinef603c712019-01-19 13:40:11 +0100733 {
Steven Cooreman03488022021-02-18 12:07:20 +0100734 if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
735 return( alg2 );
736 if( PSA_ALG_SIGN_GET_HASH( alg2 ) == PSA_ALG_ANY_HASH )
737 return( alg1 );
738 }
739 /* If the policies are from the same AEAD family, check whether
Steven Cooreman7de9e2d2021-02-22 17:05:56 +0100740 * one of them is a minimum-tag-length wildcard. Calculate the most
Steven Cooreman03488022021-02-18 12:07:20 +0100741 * restrictive tag length. */
742 if( PSA_ALG_IS_AEAD( alg1 ) && PSA_ALG_IS_AEAD( alg2 ) &&
743 ( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg1, 0 ) ==
744 PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg2, 0 ) ) )
745 {
746 size_t alg1_len = PSA_ALG_AEAD_GET_TAG_LENGTH( alg1 );
747 size_t alg2_len = PSA_ALG_AEAD_GET_TAG_LENGTH( alg2 );
748 size_t max_len = alg1_len > alg2_len ? alg1_len : alg2_len;
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100749
Steven Cooreman7de9e2d2021-02-22 17:05:56 +0100750 /* If both are wildcards, return most restrictive wildcard */
Steven Cooremand927ed72021-02-22 19:59:35 +0100751 if( ( ( alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
752 ( ( alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) )
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100753 {
Steven Cooreman5d814812021-02-18 12:11:39 +0100754 return( PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( alg1, max_len ) );
Steven Cooreman03488022021-02-18 12:07:20 +0100755 }
756 /* If only one is a wildcard, return specific algorithm if compatible. */
Steven Cooremand927ed72021-02-22 19:59:35 +0100757 if( ( ( alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
Steven Cooreman03488022021-02-18 12:07:20 +0100758 ( alg1_len <= alg2_len ) )
759 {
760 return( alg2 );
761 }
Steven Cooremand927ed72021-02-22 19:59:35 +0100762 if( ( ( alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
Steven Cooreman03488022021-02-18 12:07:20 +0100763 ( alg2_len <= alg1_len ) )
764 {
765 return( alg1 );
766 }
767 }
768 /* If the policies are from the same MAC family, check whether one
769 * of them is a minimum-MAC-length policy. Calculate the most
770 * restrictive tag length. */
771 if( PSA_ALG_IS_MAC( alg1 ) && PSA_ALG_IS_MAC( alg2 ) &&
772 ( PSA_ALG_FULL_LENGTH_MAC( alg1 ) ==
773 PSA_ALG_FULL_LENGTH_MAC( alg2 ) ) )
774 {
775 size_t alg1_len = PSA_MAC_TRUNCATED_LENGTH( alg1 );
776 size_t alg2_len = PSA_MAC_TRUNCATED_LENGTH( alg2 );
777 size_t max_len = alg1_len > alg2_len ? alg1_len : alg2_len;
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100778
Steven Cooremana1d83222021-02-25 10:20:29 +0100779 /* If both are wildcards, return most restrictive wildcard */
Steven Cooremand927ed72021-02-22 19:59:35 +0100780 if( ( ( alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
781 ( ( alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) )
Steven Cooreman03488022021-02-18 12:07:20 +0100782 {
Steven Cooremancaad4932021-02-18 11:28:17 +0100783 return( PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( alg1, max_len ) );
Steven Cooreman03488022021-02-18 12:07:20 +0100784 }
785 /* If only one is a wildcard, return specific algorithm if compatible.
786 * Special case: specific MAC algorithm with '0' as length means full-
787 * length MAC, which is always allowed by a wildcard with the same
788 * base algorithm. */
Steven Cooremand927ed72021-02-22 19:59:35 +0100789 if( ( ( alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
Steven Cooreman03488022021-02-18 12:07:20 +0100790 ( ( alg1_len <= alg2_len ) ||
791 ( alg2 == PSA_ALG_FULL_LENGTH_MAC( alg1 ) ) ) )
792 {
793 return( alg2 );
794 }
Steven Cooremand927ed72021-02-22 19:59:35 +0100795 if( ( ( alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
Steven Cooreman03488022021-02-18 12:07:20 +0100796 ( ( alg2_len <= alg1_len ) ||
797 ( alg1 == PSA_ALG_FULL_LENGTH_MAC( alg2 ) ) ) )
798 {
799 return( alg1 );
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100800 }
Gilles Peskinef603c712019-01-19 13:40:11 +0100801 }
802 /* If the policies are incompatible, allow nothing. */
803 return( 0 );
804}
805
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100806static int psa_key_algorithm_permits( psa_key_type_t key_type,
807 psa_algorithm_t policy_alg,
Gilles Peskined6f371b2019-05-10 19:33:38 +0200808 psa_algorithm_t requested_alg )
809{
Gilles Peskine549ea862019-05-22 11:45:59 +0200810 /* Common case: the policy only allows requested_alg. */
Gilles Peskined6f371b2019-05-10 19:33:38 +0200811 if( requested_alg == policy_alg )
812 return( 1 );
Steven Cooreman03488022021-02-18 12:07:20 +0100813 /* If policy_alg is a hash-and-sign with a wildcard for the hash,
814 * and requested_alg is the same hash-and-sign family with any hash,
815 * then requested_alg is compliant with policy_alg. */
816 if( PSA_ALG_IS_HASH_AND_SIGN( requested_alg ) &&
817 PSA_ALG_SIGN_GET_HASH( policy_alg ) == PSA_ALG_ANY_HASH )
Gilles Peskined6f371b2019-05-10 19:33:38 +0200818 {
Steven Cooreman03488022021-02-18 12:07:20 +0100819 return( ( policy_alg & ~PSA_ALG_HASH_MASK ) ==
820 ( requested_alg & ~PSA_ALG_HASH_MASK ) );
821 }
822 /* If policy_alg is a wildcard AEAD algorithm of the same base as
823 * the requested algorithm, check the requested tag length to be
824 * equal-length or longer than the wildcard-specified length. */
825 if( PSA_ALG_IS_AEAD( policy_alg ) &&
826 PSA_ALG_IS_AEAD( requested_alg ) &&
827 ( PSA_ALG_AEAD_WITH_SHORTENED_TAG( policy_alg, 0 ) ==
828 PSA_ALG_AEAD_WITH_SHORTENED_TAG( requested_alg, 0 ) ) &&
Steven Cooremand927ed72021-02-22 19:59:35 +0100829 ( ( policy_alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) )
Steven Cooreman03488022021-02-18 12:07:20 +0100830 {
831 return( PSA_ALG_AEAD_GET_TAG_LENGTH( policy_alg ) <=
832 PSA_ALG_AEAD_GET_TAG_LENGTH( requested_alg ) );
833 }
Steven Cooreman03488022021-02-18 12:07:20 +0100834 if( PSA_ALG_IS_MAC( policy_alg ) &&
835 PSA_ALG_IS_MAC( requested_alg ) &&
836 ( PSA_ALG_FULL_LENGTH_MAC( policy_alg ) ==
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100837 PSA_ALG_FULL_LENGTH_MAC( requested_alg ) ) )
Steven Cooreman03488022021-02-18 12:07:20 +0100838 {
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100839 size_t actual_output_length;
840 size_t default_output_length;
841 if( PSA_SUCCESS != psa_get_mac_output_length(
842 requested_alg,
843 key_type,
844 &actual_output_length ) )
845 {
846 return( 0 );
847 }
848 if( PSA_SUCCESS != psa_get_mac_output_length(
849 PSA_ALG_FULL_LENGTH_MAC( requested_alg ),
850 key_type,
851 &default_output_length ) )
852 {
853 return( 0 );
854 }
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100855
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100856 /* If the policy is default-length, only allow an algorithm with
857 * a declared exact-length matching the default. */
858 if( PSA_MAC_TRUNCATED_LENGTH( policy_alg ) == 0 )
859 return( actual_output_length == default_output_length );
860
861 /* If the requested algorithm is default-length, allow it if the policy
862 * is exactly the default length. */
863 if( PSA_MAC_TRUNCATED_LENGTH( requested_alg ) == 0 &&
864 PSA_MAC_TRUNCATED_LENGTH( policy_alg ) == default_output_length )
865 {
866 return( 1 );
867 }
868
869 /* If policy_alg is a wildcard MAC algorithm of the same base as
870 * the requested algorithm, check the requested tag length to be
871 * equal-length or longer than the wildcard-specified length. */
872 if( ( policy_alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 )
873 {
874 return( PSA_MAC_TRUNCATED_LENGTH( policy_alg ) <=
875 actual_output_length );
876 }
Gilles Peskined6f371b2019-05-10 19:33:38 +0200877 }
Steven Cooremance48e852020-10-05 16:02:45 +0200878 /* If policy_alg is a generic key agreement operation, then using it for
Steven Cooremanfa5e6312020-10-15 17:07:12 +0200879 * a key derivation with that key agreement should also be allowed. This
880 * behaviour is expected to be defined in a future specification version. */
Steven Cooremance48e852020-10-05 16:02:45 +0200881 if( PSA_ALG_IS_RAW_KEY_AGREEMENT( policy_alg ) &&
882 PSA_ALG_IS_KEY_AGREEMENT( requested_alg ) )
883 {
884 return( PSA_ALG_KEY_AGREEMENT_GET_BASE( requested_alg ) ==
885 policy_alg );
886 }
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100887 /* If it isn't explicitly permitted, it's forbidden. */
Gilles Peskined6f371b2019-05-10 19:33:38 +0200888 return( 0 );
889}
890
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100891/** Test whether a policy permits an algorithm.
892 *
893 * The caller must test usage flags separately.
Steven Cooreman7e39f052021-02-23 14:18:32 +0100894 *
895 * \retval PSA_SUCCESS When \p alg is a specific algorithm
896 * allowed by the \p policy.
897 * \retval PSA_ERROR_INVALID_ARGUMENT When \p alg is not a specific algorithm
898 * \retval PSA_ERROR_NOT_PERMITTED When \p alg is a specific algorithm, but
899 * the \p policy does not allow it.
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100900 */
Steven Cooreman7e39f052021-02-23 14:18:32 +0100901static psa_status_t psa_key_policy_permits( const psa_key_policy_t *policy,
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100902 psa_key_type_t key_type,
Steven Cooreman7e39f052021-02-23 14:18:32 +0100903 psa_algorithm_t alg )
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100904{
Steven Cooremand788fab2021-02-25 11:29:17 +0100905 /* '0' is not a valid algorithm */
906 if( alg == 0 )
907 return( PSA_ERROR_INVALID_ARGUMENT );
908
Steven Cooreman7e39f052021-02-23 14:18:32 +0100909 /* A requested algorithm cannot be a wildcard. */
910 if( PSA_ALG_IS_WILDCARD( alg ) )
911 return( PSA_ERROR_INVALID_ARGUMENT );
912
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100913 if( psa_key_algorithm_permits( key_type, policy->alg, alg ) ||
914 psa_key_algorithm_permits( key_type, policy->alg2, alg ) )
Steven Cooreman7e39f052021-02-23 14:18:32 +0100915 return( PSA_SUCCESS );
916 else
917 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100918}
919
Gilles Peskinef603c712019-01-19 13:40:11 +0100920/** Restrict a key policy based on a constraint.
921 *
922 * \param[in,out] policy The policy to restrict.
923 * \param[in] constraint The policy constraint to apply.
924 *
925 * \retval #PSA_SUCCESS
926 * \c *policy contains the intersection of the original value of
927 * \c *policy and \c *constraint.
928 * \retval #PSA_ERROR_INVALID_ARGUMENT
929 * \c *policy and \c *constraint are incompatible.
930 * \c *policy is unchanged.
931 */
932static psa_status_t psa_restrict_key_policy(
933 psa_key_policy_t *policy,
934 const psa_key_policy_t *constraint )
935{
936 psa_algorithm_t intersection_alg =
937 psa_key_policy_algorithm_intersection( policy->alg, constraint->alg );
Gilles Peskined6f371b2019-05-10 19:33:38 +0200938 psa_algorithm_t intersection_alg2 =
939 psa_key_policy_algorithm_intersection( policy->alg2, constraint->alg2 );
Gilles Peskinef603c712019-01-19 13:40:11 +0100940 if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 )
941 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined6f371b2019-05-10 19:33:38 +0200942 if( intersection_alg2 == 0 && policy->alg2 != 0 && constraint->alg2 != 0 )
943 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinef603c712019-01-19 13:40:11 +0100944 policy->usage &= constraint->usage;
945 policy->alg = intersection_alg;
Gilles Peskined6f371b2019-05-10 19:33:38 +0200946 policy->alg2 = intersection_alg2;
Gilles Peskinef603c712019-01-19 13:40:11 +0100947 return( PSA_SUCCESS );
948}
949
Ronald Cron5c522922020-11-14 16:35:34 +0100950/** Get the description of a key given its identifier and policy constraints
951 * and lock it.
Ronald Cronf95a2b12020-10-22 15:24:49 +0200952 *
Ronald Cron5c522922020-11-14 16:35:34 +0100953 * The key must have allow all the usage flags set in \p usage. If \p alg is
Steven Cooremand788fab2021-02-25 11:29:17 +0100954 * nonzero, the key must allow operations with this algorithm. If \p alg is
955 * zero, the algorithm is not checked.
Ronald Cron7587ae42020-11-11 15:04:25 +0100956 *
Ronald Cron5c522922020-11-14 16:35:34 +0100957 * In case of a persistent key, the function loads the description of the key
958 * into a key slot if not already done.
959 *
960 * On success, the returned key slot is locked. It is the responsibility of
961 * the caller to unlock the key slot when it does not access it anymore.
Ronald Cronf95a2b12020-10-22 15:24:49 +0200962 */
Ronald Cron5c522922020-11-14 16:35:34 +0100963static psa_status_t psa_get_and_lock_key_slot_with_policy(
964 mbedtls_svc_key_id_t key,
965 psa_key_slot_t **p_slot,
966 psa_key_usage_t usage,
967 psa_algorithm_t alg )
Darryl Green06fd18d2018-07-16 11:21:11 +0100968{
Ronald Cronf95a2b12020-10-22 15:24:49 +0200969 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
970 psa_key_slot_t *slot;
Darryl Green06fd18d2018-07-16 11:21:11 +0100971
Ronald Cron5c522922020-11-14 16:35:34 +0100972 status = psa_get_and_lock_key_slot( key, p_slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100973 if( status != PSA_SUCCESS )
974 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +0200975 slot = *p_slot;
Darryl Green06fd18d2018-07-16 11:21:11 +0100976
977 /* Enforce that usage policy for the key slot contains all the flags
978 * required by the usage parameter. There is one exception: public
979 * keys can always be exported, so we treat public key objects as
980 * if they had the export flag. */
Gilles Peskine8e338702019-07-30 20:06:31 +0200981 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
Darryl Green06fd18d2018-07-16 11:21:11 +0100982 usage &= ~PSA_KEY_USAGE_EXPORT;
Ronald Cronf95a2b12020-10-22 15:24:49 +0200983
Gilles Peskine8e338702019-07-30 20:06:31 +0200984 if( ( slot->attr.policy.usage & usage ) != usage )
Steven Cooreman328f11c2021-03-02 11:44:51 +0100985 {
986 status = PSA_ERROR_NOT_PERMITTED;
Ronald Cronf95a2b12020-10-22 15:24:49 +0200987 goto error;
Steven Cooreman328f11c2021-03-02 11:44:51 +0100988 }
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100989
990 /* Enforce that the usage policy permits the requested algortihm. */
Steven Cooreman7e39f052021-02-23 14:18:32 +0100991 if( alg != 0 )
992 {
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100993 status = psa_key_policy_permits( &slot->attr.policy,
994 slot->attr.type,
995 alg );
Steven Cooreman7e39f052021-02-23 14:18:32 +0100996 if( status != PSA_SUCCESS )
997 goto error;
998 }
Darryl Green06fd18d2018-07-16 11:21:11 +0100999
Darryl Green06fd18d2018-07-16 11:21:11 +01001000 return( PSA_SUCCESS );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001001
1002error:
1003 *p_slot = NULL;
Ronald Cron5c522922020-11-14 16:35:34 +01001004 psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001005
1006 return( status );
Darryl Green06fd18d2018-07-16 11:21:11 +01001007}
Darryl Green940d72c2018-07-13 13:18:51 +01001008
Ronald Cron5c522922020-11-14 16:35:34 +01001009/** Get a key slot containing a transparent key and lock it.
Gilles Peskine28f8f302019-07-24 13:30:31 +02001010 *
1011 * A transparent key is a key for which the key material is directly
1012 * available, as opposed to a key in a secure element.
1013 *
Ronald Cron5c522922020-11-14 16:35:34 +01001014 * This is a temporary function to use instead of
1015 * psa_get_and_lock_key_slot_with_policy() until secure element support is
1016 * fully implemented.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001017 *
Ronald Cron5c522922020-11-14 16:35:34 +01001018 * On success, the returned key slot is locked. It is the responsibility of the
1019 * caller to unlock the key slot when it does not access it anymore.
Gilles Peskine28f8f302019-07-24 13:30:31 +02001020 */
1021#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Ronald Cron5c522922020-11-14 16:35:34 +01001022static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
1023 mbedtls_svc_key_id_t key,
1024 psa_key_slot_t **p_slot,
1025 psa_key_usage_t usage,
1026 psa_algorithm_t alg )
Gilles Peskine28f8f302019-07-24 13:30:31 +02001027{
Ronald Cron5c522922020-11-14 16:35:34 +01001028 psa_status_t status = psa_get_and_lock_key_slot_with_policy( key, p_slot,
1029 usage, alg );
Gilles Peskine28f8f302019-07-24 13:30:31 +02001030 if( status != PSA_SUCCESS )
1031 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001032
Gilles Peskineadad8132019-07-25 11:31:23 +02001033 if( psa_key_slot_is_external( *p_slot ) )
Gilles Peskine28f8f302019-07-24 13:30:31 +02001034 {
Ronald Cron5c522922020-11-14 16:35:34 +01001035 psa_unlock_key_slot( *p_slot );
Gilles Peskine28f8f302019-07-24 13:30:31 +02001036 *p_slot = NULL;
1037 return( PSA_ERROR_NOT_SUPPORTED );
1038 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02001039
Gilles Peskine28f8f302019-07-24 13:30:31 +02001040 return( PSA_SUCCESS );
1041}
1042#else /* MBEDTLS_PSA_CRYPTO_SE_C */
1043/* With no secure element support, all keys are transparent. */
Ronald Cron5c522922020-11-14 16:35:34 +01001044#define psa_get_and_lock_transparent_key_slot_with_policy( key, p_slot, usage, alg ) \
1045 psa_get_and_lock_key_slot_with_policy( key, p_slot, usage, alg )
Gilles Peskine28f8f302019-07-24 13:30:31 +02001046#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1047
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001048/** Wipe key data from a slot. Preserve metadata such as the policy. */
Gilles Peskine2f060a82018-12-04 17:12:32 +01001049static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
Darryl Green40225ba2018-11-15 14:48:15 +00001050{
Ronald Cronea0f8a62020-11-25 17:52:23 +01001051 /* Data pointer will always be either a valid pointer or NULL in an
1052 * initialized slot, so we can just free it. */
1053 if( slot->key.data != NULL )
1054 mbedtls_platform_zeroize( slot->key.data, slot->key.bytes);
1055
1056 mbedtls_free( slot->key.data );
1057 slot->key.data = NULL;
1058 slot->key.bytes = 0;
Darryl Green40225ba2018-11-15 14:48:15 +00001059
1060 return( PSA_SUCCESS );
1061}
1062
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001063/** Completely wipe a slot in memory, including its policy.
1064 * Persistent storage is not affected. */
Gilles Peskine66fb1262018-12-10 16:29:04 +01001065psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot )
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001066{
1067 psa_status_t status = psa_remove_key_data_from_memory( slot );
Ronald Cronddd3d052020-10-30 14:07:07 +01001068
1069 /*
1070 * As the return error code may not be handled in case of multiple errors,
Ronald Cron5c522922020-11-14 16:35:34 +01001071 * do our best to report an unexpected lock counter: if available
Ronald Cronddd3d052020-10-30 14:07:07 +01001072 * call MBEDTLS_PARAM_FAILED that may terminate execution (if called as
1073 * part of the execution of a test suite this will stop the test suite
Ronald Cron4640c152020-11-13 10:11:01 +01001074 * execution).
Ronald Cronddd3d052020-10-30 14:07:07 +01001075 */
Ronald Cron5c522922020-11-14 16:35:34 +01001076 if( slot->lock_count != 1 )
Ronald Cronddd3d052020-10-30 14:07:07 +01001077 {
1078#ifdef MBEDTLS_CHECK_PARAMS
Ronald Cron5c522922020-11-14 16:35:34 +01001079 MBEDTLS_PARAM_FAILED( slot->lock_count == 1 );
Ronald Cronddd3d052020-10-30 14:07:07 +01001080#endif
Ronald Cronddd3d052020-10-30 14:07:07 +01001081 status = PSA_ERROR_CORRUPTION_DETECTED;
1082 }
1083
Gilles Peskine3f7cd622019-08-13 15:01:08 +02001084 /* Multipart operations may still be using the key. This is safe
1085 * because all multipart operation objects are independent from
1086 * the key slot: if they need to access the key after the setup
1087 * phase, they have a copy of the key. Note that this means that
1088 * key material can linger until all operations are completed. */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001089 /* At this point, key material and other type-specific content has
1090 * been wiped. Clear remaining metadata. We can call memset and not
1091 * zeroize because the metadata is not particularly sensitive. */
1092 memset( slot, 0, sizeof( *slot ) );
1093 return( status );
1094}
1095
Ronald Croncf56a0a2020-08-04 09:51:30 +02001096psa_status_t psa_destroy_key( mbedtls_svc_key_id_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001097{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001098 psa_key_slot_t *slot;
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001099 psa_status_t status; /* status of the last operation */
1100 psa_status_t overall_status = PSA_SUCCESS;
Gilles Peskine354f7672019-07-12 23:46:38 +02001101#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1102 psa_se_drv_table_entry_t *driver;
1103#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001104
Ronald Croncf56a0a2020-08-04 09:51:30 +02001105 if( mbedtls_svc_key_id_is_null( key ) )
Gilles Peskine1841cf42019-10-08 15:48:25 +02001106 return( PSA_SUCCESS );
1107
Ronald Cronf2911112020-10-29 17:51:10 +01001108 /*
Ronald Cron19daca92020-11-10 18:08:03 +01001109 * Get the description of the key in a key slot. In case of a persistent
Ronald Cronf2911112020-10-29 17:51:10 +01001110 * key, this will load the key description from persistent memory if not
1111 * done yet. We cannot avoid this loading as without it we don't know if
1112 * the key is operated by an SE or not and this information is needed by
1113 * the current implementation.
1114 */
Ronald Cron5c522922020-11-14 16:35:34 +01001115 status = psa_get_and_lock_key_slot( key, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001116 if( status != PSA_SUCCESS )
1117 return( status );
Gilles Peskine354f7672019-07-12 23:46:38 +02001118
Ronald Cronf2911112020-10-29 17:51:10 +01001119 /*
1120 * If the key slot containing the key description is under access by the
1121 * library (apart from the present access), the key cannot be destroyed
1122 * yet. For the time being, just return in error. Eventually (to be
1123 * implemented), the key should be destroyed when all accesses have
1124 * stopped.
1125 */
Ronald Cron5c522922020-11-14 16:35:34 +01001126 if( slot->lock_count > 1 )
Ronald Cronf2911112020-10-29 17:51:10 +01001127 {
Ronald Cron5c522922020-11-14 16:35:34 +01001128 psa_unlock_key_slot( slot );
Ronald Cronf2911112020-10-29 17:51:10 +01001129 return( PSA_ERROR_GENERIC_ERROR );
1130 }
1131
Gilles Peskine354f7672019-07-12 23:46:38 +02001132#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001133 driver = psa_get_se_driver_entry( slot->attr.lifetime );
Gilles Peskine354f7672019-07-12 23:46:38 +02001134 if( driver != NULL )
Gilles Peskinefc762652019-07-22 19:30:34 +02001135 {
Gilles Peskine60450a42019-07-25 11:32:45 +02001136 /* For a key in a secure element, we need to do three things:
1137 * remove the key file in internal storage, destroy the
1138 * key inside the secure element, and update the driver's
1139 * persistent data. Start a transaction that will encompass these
1140 * three actions. */
Gilles Peskinefc762652019-07-22 19:30:34 +02001141 psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_DESTROY_KEY );
Gilles Peskine8e338702019-07-30 20:06:31 +02001142 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
Ronald Cronea0f8a62020-11-25 17:52:23 +01001143 psa_crypto_transaction.key.slot = psa_key_slot_get_slot_number( slot );
Gilles Peskine8e338702019-07-30 20:06:31 +02001144 psa_crypto_transaction.key.id = slot->attr.id;
Gilles Peskinefc762652019-07-22 19:30:34 +02001145 status = psa_crypto_save_transaction( );
1146 if( status != PSA_SUCCESS )
1147 {
Gilles Peskine66be51c2019-07-25 18:02:52 +02001148 (void) psa_crypto_stop_transaction( );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001149 /* We should still try to destroy the key in the secure
1150 * element and the key metadata in storage. This is especially
1151 * important if the error is that the storage is full.
1152 * But how to do it exactly without risking an inconsistent
1153 * state after a reset?
1154 * https://github.com/ARMmbed/mbed-crypto/issues/215
1155 */
1156 overall_status = status;
1157 goto exit;
Gilles Peskinefc762652019-07-22 19:30:34 +02001158 }
1159
Ronald Cronea0f8a62020-11-25 17:52:23 +01001160 status = psa_destroy_se_key( driver,
1161 psa_key_slot_get_slot_number( slot ) );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001162 if( overall_status == PSA_SUCCESS )
1163 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001164 }
Gilles Peskine354f7672019-07-12 23:46:38 +02001165#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1166
Darryl Greend49a4992018-06-18 17:27:26 +01001167#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Ronald Crond98059d2020-10-23 18:00:55 +02001168 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
Darryl Greend49a4992018-06-18 17:27:26 +01001169 {
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001170 status = psa_destroy_persistent_key( slot->attr.id );
1171 if( overall_status == PSA_SUCCESS )
1172 overall_status = status;
1173
Gilles Peskine9ce31c42019-08-13 15:14:20 +02001174 /* TODO: other slots may have a copy of the same key. We should
1175 * invalidate them.
1176 * https://github.com/ARMmbed/mbed-crypto/issues/214
1177 */
Darryl Greend49a4992018-06-18 17:27:26 +01001178 }
1179#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskine354f7672019-07-12 23:46:38 +02001180
Gilles Peskinefc762652019-07-22 19:30:34 +02001181#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1182 if( driver != NULL )
1183 {
Gilles Peskine725f22a2019-07-25 11:31:48 +02001184 status = psa_save_se_persistent_data( driver );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001185 if( overall_status == PSA_SUCCESS )
1186 overall_status = status;
1187 status = psa_crypto_stop_transaction( );
1188 if( overall_status == PSA_SUCCESS )
1189 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001190 }
1191#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1192
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001193#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1194exit:
1195#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001196 status = psa_wipe_key_slot( slot );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001197 /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
1198 if( overall_status == PSA_SUCCESS )
1199 overall_status = status;
1200 return( overall_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001201}
1202
John Durkop07cc04a2020-11-16 22:08:34 -08001203#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
John Durkop0e005192020-10-31 22:06:54 -07001204 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskineb699f072019-04-26 16:06:02 +02001205static psa_status_t psa_get_rsa_public_exponent(
1206 const mbedtls_rsa_context *rsa,
1207 psa_key_attributes_t *attributes )
1208{
1209 mbedtls_mpi mpi;
Janos Follath24eed8d2019-11-22 13:21:35 +00001210 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb699f072019-04-26 16:06:02 +02001211 uint8_t *buffer = NULL;
1212 size_t buflen;
1213 mbedtls_mpi_init( &mpi );
1214
1215 ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &mpi );
1216 if( ret != 0 )
1217 goto exit;
Gilles Peskine772c8b12019-04-26 17:37:21 +02001218 if( mbedtls_mpi_cmp_int( &mpi, 65537 ) == 0 )
1219 {
1220 /* It's the default value, which is reported as an empty string,
1221 * so there's nothing to do. */
1222 goto exit;
1223 }
Gilles Peskineb699f072019-04-26 16:06:02 +02001224
1225 buflen = mbedtls_mpi_size( &mpi );
1226 buffer = mbedtls_calloc( 1, buflen );
1227 if( buffer == NULL )
1228 {
1229 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
1230 goto exit;
1231 }
1232 ret = mbedtls_mpi_write_binary( &mpi, buffer, buflen );
1233 if( ret != 0 )
1234 goto exit;
1235 attributes->domain_parameters = buffer;
1236 attributes->domain_parameters_size = buflen;
1237
1238exit:
1239 mbedtls_mpi_free( &mpi );
1240 if( ret != 0 )
1241 mbedtls_free( buffer );
1242 return( mbedtls_to_psa_error( ret ) );
1243}
John Durkop07cc04a2020-11-16 22:08:34 -08001244#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
John Durkop9814fa22020-11-04 12:28:15 -08001245 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineb699f072019-04-26 16:06:02 +02001246
Gilles Peskinebfd322f2019-07-23 11:58:03 +02001247/** Retrieve all the publicly-accessible attributes of a key.
1248 */
Ronald Croncf56a0a2020-08-04 09:51:30 +02001249psa_status_t psa_get_key_attributes( mbedtls_svc_key_id_t key,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001250 psa_key_attributes_t *attributes )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001251{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001252 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001253 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001254 psa_key_slot_t *slot;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001255
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001256 psa_reset_key_attributes( attributes );
1257
Ronald Cron5c522922020-11-14 16:35:34 +01001258 status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001259 if( status != PSA_SUCCESS )
1260 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +02001261
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001262 attributes->core = slot->attr;
Gilles Peskinec8000c02019-08-02 20:15:51 +02001263 attributes->core.flags &= ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1264 MBEDTLS_PSA_KA_MASK_DUAL_USE );
1265
1266#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1267 if( psa_key_slot_is_external( slot ) )
Ronald Cronea0f8a62020-11-25 17:52:23 +01001268 psa_set_key_slot_number( attributes,
1269 psa_key_slot_get_slot_number( slot ) );
Gilles Peskinec8000c02019-08-02 20:15:51 +02001270#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineb699f072019-04-26 16:06:02 +02001271
Gilles Peskine8e338702019-07-30 20:06:31 +02001272 switch( slot->attr.type )
Gilles Peskineb699f072019-04-26 16:06:02 +02001273 {
John Durkop07cc04a2020-11-16 22:08:34 -08001274#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
John Durkop0e005192020-10-31 22:06:54 -07001275 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001276 case PSA_KEY_TYPE_RSA_KEY_PAIR:
Gilles Peskineb699f072019-04-26 16:06:02 +02001277 case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001278#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01001279 /* TODO: reporting the public exponent for opaque keys
Gilles Peskinec9d7f942019-08-13 16:17:16 +02001280 * is not yet implemented.
1281 * https://github.com/ARMmbed/mbed-crypto/issues/216
1282 */
Gilles Peskinec8000c02019-08-02 20:15:51 +02001283 if( psa_key_slot_is_external( slot ) )
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001284 break;
1285#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Steven Cooremana01795d2020-07-24 22:48:15 +02001286 {
Steven Cooremana2371e52020-07-28 14:30:39 +02001287 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02001288
Ronald Cron90857082020-11-25 14:58:33 +01001289 status = mbedtls_psa_rsa_load_representation(
1290 slot->attr.type,
1291 slot->key.data,
1292 slot->key.bytes,
1293 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001294 if( status != PSA_SUCCESS )
1295 break;
1296
Steven Cooremana2371e52020-07-28 14:30:39 +02001297 status = psa_get_rsa_public_exponent( rsa,
Steven Cooremana01795d2020-07-24 22:48:15 +02001298 attributes );
Steven Cooremana2371e52020-07-28 14:30:39 +02001299 mbedtls_rsa_free( rsa );
1300 mbedtls_free( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001301 }
Gilles Peskineb699f072019-04-26 16:06:02 +02001302 break;
John Durkop07cc04a2020-11-16 22:08:34 -08001303#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
John Durkop9814fa22020-11-04 12:28:15 -08001304 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineb699f072019-04-26 16:06:02 +02001305 default:
1306 /* Nothing else to do. */
1307 break;
1308 }
1309
1310 if( status != PSA_SUCCESS )
1311 psa_reset_key_attributes( attributes );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001312
Ronald Cron5c522922020-11-14 16:35:34 +01001313 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001314
Ronald Cron5c522922020-11-14 16:35:34 +01001315 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001316}
1317
Gilles Peskinec8000c02019-08-02 20:15:51 +02001318#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1319psa_status_t psa_get_key_slot_number(
1320 const psa_key_attributes_t *attributes,
1321 psa_key_slot_number_t *slot_number )
1322{
1323 if( attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER )
1324 {
1325 *slot_number = attributes->slot_number;
1326 return( PSA_SUCCESS );
1327 }
1328 else
1329 return( PSA_ERROR_INVALID_ARGUMENT );
1330}
1331#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1332
Ronald Crond18b5f82020-11-25 16:46:05 +01001333static psa_status_t psa_export_key_buffer_internal( const uint8_t *key_buffer,
1334 size_t key_buffer_size,
Steven Cooremana01795d2020-07-24 22:48:15 +02001335 uint8_t *data,
1336 size_t data_size,
1337 size_t *data_length )
1338{
Ronald Crond18b5f82020-11-25 16:46:05 +01001339 if( key_buffer_size > data_size )
Steven Cooremana01795d2020-07-24 22:48:15 +02001340 return( PSA_ERROR_BUFFER_TOO_SMALL );
Ronald Crond18b5f82020-11-25 16:46:05 +01001341 memcpy( data, key_buffer, key_buffer_size );
1342 memset( data + key_buffer_size, 0,
1343 data_size - key_buffer_size );
1344 *data_length = key_buffer_size;
Steven Cooremana01795d2020-07-24 22:48:15 +02001345 return( PSA_SUCCESS );
1346}
1347
Ronald Cron7285cda2020-11-26 14:46:37 +01001348psa_status_t psa_export_key_internal(
Ronald Crond18b5f82020-11-25 16:46:05 +01001349 const psa_key_attributes_t *attributes,
1350 const uint8_t *key_buffer, size_t key_buffer_size,
1351 uint8_t *data, size_t data_size, size_t *data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001352{
Ronald Crond18b5f82020-11-25 16:46:05 +01001353 psa_key_type_t type = attributes->core.type;
1354
Ronald Crond18b5f82020-11-25 16:46:05 +01001355 if( key_type_is_raw_bytes( type ) ||
1356 PSA_KEY_TYPE_IS_RSA( type ) ||
1357 PSA_KEY_TYPE_IS_ECC( type ) )
Ronald Cron9486f9d2020-11-26 13:36:23 +01001358 {
1359 return( psa_export_key_buffer_internal(
Ronald Crond18b5f82020-11-25 16:46:05 +01001360 key_buffer, key_buffer_size,
1361 data, data_size, data_length ) );
Ronald Cron9486f9d2020-11-26 13:36:23 +01001362 }
1363 else
1364 {
1365 /* This shouldn't happen in the reference implementation, but
1366 it is valid for a special-purpose implementation to omit
1367 support for exporting certain key types. */
1368 return( PSA_ERROR_NOT_SUPPORTED );
1369 }
1370}
1371
1372psa_status_t psa_export_key( mbedtls_svc_key_id_t key,
1373 uint8_t *data,
1374 size_t data_size,
1375 size_t *data_length )
1376{
1377 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1378 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
1379 psa_key_slot_t *slot;
1380
Ronald Crone907e552021-01-18 13:22:38 +01001381 /* Reject a zero-length output buffer now, since this can never be a
1382 * valid key representation. This way we know that data must be a valid
1383 * pointer and we can do things like memset(data, ..., data_size). */
1384 if( data_size == 0 )
1385 return( PSA_ERROR_BUFFER_TOO_SMALL );
1386
Ronald Cron9486f9d2020-11-26 13:36:23 +01001387 /* Set the key to empty now, so that even when there are errors, we always
1388 * set data_length to a value between 0 and data_size. On error, setting
1389 * the key to empty is a good choice because an empty key representation is
1390 * unlikely to be accepted anywhere. */
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001391 *data_length = 0;
1392
Ronald Cron9486f9d2020-11-26 13:36:23 +01001393 /* Export requires the EXPORT flag. There is an exception for public keys,
1394 * which don't require any flag, but
1395 * psa_get_and_lock_key_slot_with_policy() takes care of this.
1396 */
1397 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
1398 PSA_KEY_USAGE_EXPORT, 0 );
1399 if( status != PSA_SUCCESS )
1400 return( status );
mohammad160306e79202018-03-28 13:17:44 +03001401
Ronald Crond18b5f82020-11-25 16:46:05 +01001402 psa_key_attributes_t attributes = {
1403 .core = slot->attr
1404 };
Ronald Cron67227982020-11-26 15:16:05 +01001405 status = psa_driver_wrapper_export_key( &attributes,
Ronald Crond18b5f82020-11-25 16:46:05 +01001406 slot->key.data, slot->key.bytes,
1407 data, data_size, data_length );
Ronald Cron9486f9d2020-11-26 13:36:23 +01001408
Ronald Cron9486f9d2020-11-26 13:36:23 +01001409 unlock_status = psa_unlock_key_slot( slot );
1410
1411 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
1412}
1413
Ronald Cron7285cda2020-11-26 14:46:37 +01001414psa_status_t psa_export_public_key_internal(
Ronald Crond18b5f82020-11-25 16:46:05 +01001415 const psa_key_attributes_t *attributes,
1416 const uint8_t *key_buffer,
1417 size_t key_buffer_size,
1418 uint8_t *data,
1419 size_t data_size,
1420 size_t *data_length )
Ronald Cron9486f9d2020-11-26 13:36:23 +01001421{
Ronald Crond18b5f82020-11-25 16:46:05 +01001422 psa_key_type_t type = attributes->core.type;
Ronald Crond18b5f82020-11-25 16:46:05 +01001423
Ronald Crond18b5f82020-11-25 16:46:05 +01001424 if( PSA_KEY_TYPE_IS_RSA( type ) || PSA_KEY_TYPE_IS_ECC( type ) )
Moran Peker17e36e12018-05-02 12:55:20 +03001425 {
Ronald Crond18b5f82020-11-25 16:46:05 +01001426 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +01001427 {
Steven Cooreman560c28a2020-07-24 23:20:24 +02001428 /* Exporting public -> public */
Ronald Cron9486f9d2020-11-26 13:36:23 +01001429 return( psa_export_key_buffer_internal(
Ronald Crond18b5f82020-11-25 16:46:05 +01001430 key_buffer, key_buffer_size,
1431 data, data_size, data_length ) );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001432 }
Steven Cooremanb9b84422020-10-14 14:39:20 +02001433
Ronald Crond18b5f82020-11-25 16:46:05 +01001434 if( PSA_KEY_TYPE_IS_RSA( type ) )
Steven Cooreman560c28a2020-07-24 23:20:24 +02001435 {
John Durkop0e005192020-10-31 22:06:54 -07001436#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1437 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Ronald Crone5ca3d82020-11-26 16:36:16 +01001438 return( mbedtls_psa_rsa_export_public_key( attributes,
1439 key_buffer,
1440 key_buffer_size,
1441 data,
1442 data_size,
1443 data_length ) );
Darryl Green9e2d7a02018-07-24 16:33:30 +01001444#else
Steven Cooreman560c28a2020-07-24 23:20:24 +02001445 /* We don't know how to convert a private RSA key to public. */
1446 return( PSA_ERROR_NOT_SUPPORTED );
John Durkop9814fa22020-11-04 12:28:15 -08001447#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1448 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskine969ac722018-01-28 18:16:59 +01001449 }
1450 else
Moran Pekera998bc62018-04-16 18:16:20 +03001451 {
John Durkop6ba40d12020-11-10 08:50:04 -08001452#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
1453 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Ronald Crone5ca3d82020-11-26 16:36:16 +01001454 return( mbedtls_psa_ecp_export_public_key( attributes,
1455 key_buffer,
1456 key_buffer_size,
1457 data,
1458 data_size,
1459 data_length ) );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001460#else
1461 /* We don't know how to convert a private ECC key to public */
Moran Pekera998bc62018-04-16 18:16:20 +03001462 return( PSA_ERROR_NOT_SUPPORTED );
John Durkop9814fa22020-11-04 12:28:15 -08001463#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
1464 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
Moran Pekera998bc62018-04-16 18:16:20 +03001465 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001466 }
Steven Cooreman560c28a2020-07-24 23:20:24 +02001467 else
1468 {
1469 /* This shouldn't happen in the reference implementation, but
1470 it is valid for a special-purpose implementation to omit
1471 support for exporting certain key types. */
1472 return( PSA_ERROR_NOT_SUPPORTED );
1473 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001474}
Ronald Crond18b5f82020-11-25 16:46:05 +01001475
Ronald Croncf56a0a2020-08-04 09:51:30 +02001476psa_status_t psa_export_public_key( mbedtls_svc_key_id_t key,
Gilles Peskine2d277862018-06-18 15:41:12 +02001477 uint8_t *data,
1478 size_t data_size,
1479 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001480{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001481 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001482 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001483 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001484
Ronald Crone907e552021-01-18 13:22:38 +01001485 /* Reject a zero-length output buffer now, since this can never be a
1486 * valid key representation. This way we know that data must be a valid
1487 * pointer and we can do things like memset(data, ..., data_size). */
1488 if( data_size == 0 )
1489 return( PSA_ERROR_BUFFER_TOO_SMALL );
1490
Darryl Greendd8fb772018-11-07 16:00:44 +00001491 /* Set the key to empty now, so that even when there are errors, we always
1492 * set data_length to a value between 0 and data_size. On error, setting
1493 * the key to empty is a good choice because an empty key representation is
1494 * unlikely to be accepted anywhere. */
1495 *data_length = 0;
1496
1497 /* Exporting a public key doesn't require a usage flag. */
Ronald Cron5c522922020-11-14 16:35:34 +01001498 status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001499 if( status != PSA_SUCCESS )
1500 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001501
Ronald Cron9486f9d2020-11-26 13:36:23 +01001502 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
1503 {
1504 status = PSA_ERROR_INVALID_ARGUMENT;
1505 goto exit;
1506 }
1507
Ronald Crond18b5f82020-11-25 16:46:05 +01001508 psa_key_attributes_t attributes = {
1509 .core = slot->attr
1510 };
Ronald Cron67227982020-11-26 15:16:05 +01001511 status = psa_driver_wrapper_export_public_key(
Ronald Crond18b5f82020-11-25 16:46:05 +01001512 &attributes, slot->key.data, slot->key.bytes,
1513 data, data_size, data_length );
Ronald Cron9486f9d2020-11-26 13:36:23 +01001514
1515exit:
Ronald Cron5c522922020-11-14 16:35:34 +01001516 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001517
Ronald Cron5c522922020-11-14 16:35:34 +01001518 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001519}
1520
Gilles Peskine91e8c332019-08-02 19:19:39 +02001521#if defined(static_assert)
1522static_assert( ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
1523 "One or more key attribute flag is listed as both external-only and dual-use" );
Gilles Peskine5a680562019-08-05 17:32:13 +02001524static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
Gilles Peskine094dac12019-08-07 18:19:46 +02001525 "One or more key attribute flag is listed as both internal-only and dual-use" );
Gilles Peskine5a680562019-08-05 17:32:13 +02001526static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ) == 0,
Gilles Peskine91e8c332019-08-02 19:19:39 +02001527 "One or more key attribute flag is listed as both internal-only and external-only" );
1528#endif
1529
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001530/** Validate that a key policy is internally well-formed.
1531 *
1532 * This function only rejects invalid policies. It does not validate the
1533 * consistency of the policy with respect to other attributes of the key
1534 * such as the key type.
1535 */
1536static psa_status_t psa_validate_key_policy( const psa_key_policy_t *policy )
Gilles Peskine4747d192019-04-17 15:05:45 +02001537{
1538 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
Gilles Peskine8e0206a2019-05-14 14:24:28 +02001539 PSA_KEY_USAGE_COPY |
Gilles Peskine4747d192019-04-17 15:05:45 +02001540 PSA_KEY_USAGE_ENCRYPT |
1541 PSA_KEY_USAGE_DECRYPT |
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01001542 PSA_KEY_USAGE_SIGN_HASH |
1543 PSA_KEY_USAGE_VERIFY_HASH |
Gilles Peskine4747d192019-04-17 15:05:45 +02001544 PSA_KEY_USAGE_DERIVE ) ) != 0 )
1545 return( PSA_ERROR_INVALID_ARGUMENT );
1546
Gilles Peskine4747d192019-04-17 15:05:45 +02001547 return( PSA_SUCCESS );
1548}
1549
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001550/** Validate the internal consistency of key attributes.
1551 *
1552 * This function only rejects invalid attribute values. If does not
1553 * validate the consistency of the attributes with any key data that may
1554 * be involved in the creation of the key.
1555 *
1556 * Call this function early in the key creation process.
1557 *
1558 * \param[in] attributes Key attributes for the new key.
1559 * \param[out] p_drv On any return, the driver for the key, if any.
1560 * NULL for a transparent key.
1561 *
1562 */
1563static psa_status_t psa_validate_key_attributes(
1564 const psa_key_attributes_t *attributes,
1565 psa_se_drv_table_entry_t **p_drv )
Darryl Green0c6575a2018-11-07 16:05:30 +00001566{
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001567 psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
Ronald Crond2ed4812020-07-17 16:11:30 +02001568 psa_key_lifetime_t lifetime = psa_get_key_lifetime( attributes );
Ronald Cron65f38a32020-10-23 17:11:13 +02001569 mbedtls_svc_key_id_t key = psa_get_key_id( attributes );
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001570
Ronald Cron54b90082020-10-29 15:26:43 +01001571 status = psa_validate_key_location( lifetime, p_drv );
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001572 if( status != PSA_SUCCESS )
1573 return( status );
1574
Ronald Crond2ed4812020-07-17 16:11:30 +02001575 status = psa_validate_key_persistence( lifetime );
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001576 if( status != PSA_SUCCESS )
1577 return( status );
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001578
Ronald Cron65f38a32020-10-23 17:11:13 +02001579 if ( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) )
1580 {
1581 if( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key ) != 0 )
1582 return( PSA_ERROR_INVALID_ARGUMENT );
1583 }
1584 else
Ronald Crond2ed4812020-07-17 16:11:30 +02001585 {
Ronald Croncbd7bea2020-11-11 14:57:44 +01001586 status = psa_validate_key_id( psa_get_key_id( attributes ), 0 );
Ronald Crond2ed4812020-07-17 16:11:30 +02001587 if( status != PSA_SUCCESS )
1588 return( status );
1589 }
1590
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001591 status = psa_validate_key_policy( &attributes->core.policy );
Darryl Green0c6575a2018-11-07 16:05:30 +00001592 if( status != PSA_SUCCESS )
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001593 return( status );
1594
1595 /* Refuse to create overly large keys.
1596 * Note that this doesn't trigger on import if the attributes don't
1597 * explicitly specify a size (so psa_get_key_bits returns 0), so
1598 * psa_import_key() needs its own checks. */
1599 if( psa_get_key_bits( attributes ) > PSA_MAX_KEY_BITS )
1600 return( PSA_ERROR_NOT_SUPPORTED );
1601
Gilles Peskine91e8c332019-08-02 19:19:39 +02001602 /* Reject invalid flags. These should not be reachable through the API. */
1603 if( attributes->core.flags & ~ ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1604 MBEDTLS_PSA_KA_MASK_DUAL_USE ) )
1605 return( PSA_ERROR_INVALID_ARGUMENT );
1606
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001607 return( PSA_SUCCESS );
1608}
1609
Gilles Peskine4747d192019-04-17 15:05:45 +02001610/** Prepare a key slot to receive key material.
1611 *
1612 * This function allocates a key slot and sets its metadata.
1613 *
1614 * If this function fails, call psa_fail_key_creation().
1615 *
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001616 * This function is intended to be used as follows:
1617 * -# Call psa_start_key_creation() to allocate a key slot, prepare
Ronald Croncf56a0a2020-08-04 09:51:30 +02001618 * it with the specified attributes, and in case of a volatile key assign it
1619 * a volatile key identifier.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001620 * -# Populate the slot with the key material.
1621 * -# Call psa_finish_key_creation() to finalize the creation of the slot.
1622 * In case of failure at any step, stop the sequence and call
1623 * psa_fail_key_creation().
1624 *
Ronald Cron5c522922020-11-14 16:35:34 +01001625 * On success, the key slot is locked. It is the responsibility of the caller
1626 * to unlock the key slot when it does not access it anymore.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001627 *
Gilles Peskinedf179142019-07-15 22:02:14 +02001628 * \param method An identification of the calling function.
Gilles Peskine011e4282019-06-26 18:34:38 +02001629 * \param[in] attributes Key attributes for the new key.
Gilles Peskine011e4282019-06-26 18:34:38 +02001630 * \param[out] p_slot On success, a pointer to the prepared slot.
1631 * \param[out] p_drv On any return, the driver for the key, if any.
1632 * NULL for a transparent key.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001633 *
1634 * \retval #PSA_SUCCESS
1635 * The key slot is ready to receive key material.
1636 * \return If this function fails, the key slot is an invalid state.
1637 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02001638 */
1639static psa_status_t psa_start_key_creation(
Gilles Peskinedf179142019-07-15 22:02:14 +02001640 psa_key_creation_method_t method,
Gilles Peskine4747d192019-04-17 15:05:45 +02001641 const psa_key_attributes_t *attributes,
Gilles Peskine011e4282019-06-26 18:34:38 +02001642 psa_key_slot_t **p_slot,
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001643 psa_se_drv_table_entry_t **p_drv )
Gilles Peskine4747d192019-04-17 15:05:45 +02001644{
1645 psa_status_t status;
Ronald Cron2a993152020-07-17 14:13:26 +02001646 psa_key_id_t volatile_key_id;
Gilles Peskine4747d192019-04-17 15:05:45 +02001647 psa_key_slot_t *slot;
1648
Gilles Peskinedf179142019-07-15 22:02:14 +02001649 (void) method;
Gilles Peskine011e4282019-06-26 18:34:38 +02001650 *p_drv = NULL;
1651
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001652 status = psa_validate_key_attributes( attributes, p_drv );
1653 if( status != PSA_SUCCESS )
1654 return( status );
1655
Ronald Cronc4d1b512020-07-31 11:26:37 +02001656 status = psa_get_empty_key_slot( &volatile_key_id, p_slot );
Gilles Peskine4747d192019-04-17 15:05:45 +02001657 if( status != PSA_SUCCESS )
1658 return( status );
1659 slot = *p_slot;
1660
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001661 /* We're storing the declared bit-size of the key. It's up to each
1662 * creation mechanism to verify that this information is correct.
1663 * It's automatically correct for mechanisms that use the bit-size as
Gilles Peskineb46bef22019-07-30 21:32:04 +02001664 * an input (generate, device) but not for those where the bit-size
Ronald Cronc4d1b512020-07-31 11:26:37 +02001665 * is optional (import, copy). In case of a volatile key, assign it the
1666 * volatile key identifier associated to the slot returned to contain its
1667 * definition. */
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001668
1669 slot->attr = attributes->core;
Ronald Cronc4d1b512020-07-31 11:26:37 +02001670 if( PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
1671 {
1672#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
1673 slot->attr.id = volatile_key_id;
1674#else
1675 slot->attr.id.key_id = volatile_key_id;
1676#endif
1677 }
Gilles Peskinec744d992019-07-30 17:26:54 +02001678
Gilles Peskine91e8c332019-08-02 19:19:39 +02001679 /* Erase external-only flags from the internal copy. To access
Gilles Peskine013f5472019-08-07 15:42:14 +02001680 * external-only flags, query `attributes`. Thanks to the check
1681 * in psa_validate_key_attributes(), this leaves the dual-use
Gilles Peskineedbed562019-08-07 18:19:59 +02001682 * flags and any internal flag that psa_get_empty_key_slot()
Gilles Peskine013f5472019-08-07 15:42:14 +02001683 * may have set. */
1684 slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
Gilles Peskine91e8c332019-08-02 19:19:39 +02001685
Gilles Peskinecbaff462019-07-12 23:46:04 +02001686#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02001687 /* For a key in a secure element, we need to do three things
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001688 * when creating or registering a persistent key:
Gilles Peskine60450a42019-07-25 11:32:45 +02001689 * create the key file in internal storage, create the
1690 * key inside the secure element, and update the driver's
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001691 * persistent data. This is done by starting a transaction that will
1692 * encompass these three actions.
1693 * For registering a volatile key, we just need to find an appropriate
1694 * slot number inside the SE. Since the key is designated volatile, creating
1695 * a transaction is not required. */
Gilles Peskine60450a42019-07-25 11:32:45 +02001696 /* The first thing to do is to find a slot number for the new key.
1697 * We save the slot number in persistent storage as part of the
1698 * transaction data. It will be needed to recover if the power
1699 * fails during the key creation process, to clean up on the secure
1700 * element side after restarting. Obtaining a slot number from the
1701 * secure element driver updates its persistent state, but we do not yet
1702 * save the driver's persistent state, so that if the power fails,
Gilles Peskinefc762652019-07-22 19:30:34 +02001703 * we can roll back to a state where the key doesn't exist. */
Gilles Peskine3efcebb2019-10-01 14:18:35 +02001704 if( *p_drv != NULL )
Darryl Green0c6575a2018-11-07 16:05:30 +00001705 {
Ronald Cronea0f8a62020-11-25 17:52:23 +01001706 psa_key_slot_number_t slot_number;
Gilles Peskinee88c2c12019-08-05 16:44:14 +02001707 status = psa_find_se_slot_for_key( attributes, method, *p_drv,
Ronald Cronea0f8a62020-11-25 17:52:23 +01001708 &slot_number );
Gilles Peskinecbaff462019-07-12 23:46:04 +02001709 if( status != PSA_SUCCESS )
1710 return( status );
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001711
1712 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( attributes->core.lifetime ) )
Gilles Peskine66be51c2019-07-25 18:02:52 +02001713 {
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001714 psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_CREATE_KEY );
1715 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
Ronald Cronea0f8a62020-11-25 17:52:23 +01001716 psa_crypto_transaction.key.slot = slot_number;
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001717 psa_crypto_transaction.key.id = slot->attr.id;
1718 status = psa_crypto_save_transaction( );
1719 if( status != PSA_SUCCESS )
1720 {
1721 (void) psa_crypto_stop_transaction( );
1722 return( status );
1723 }
Gilles Peskine66be51c2019-07-25 18:02:52 +02001724 }
Ronald Cronea0f8a62020-11-25 17:52:23 +01001725
1726 status = psa_copy_key_material_into_slot(
1727 slot, (uint8_t *)( &slot_number ), sizeof( slot_number ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00001728 }
Gilles Peskine3efcebb2019-10-01 14:18:35 +02001729
1730 if( *p_drv == NULL && method == PSA_KEY_CREATION_REGISTER )
1731 {
1732 /* Key registration only makes sense with a secure element. */
1733 return( PSA_ERROR_INVALID_ARGUMENT );
1734 }
Gilles Peskinecbaff462019-07-12 23:46:04 +02001735#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1736
Ronald Cronc4d1b512020-07-31 11:26:37 +02001737 return( PSA_SUCCESS );
Darryl Green0c6575a2018-11-07 16:05:30 +00001738}
Gilles Peskine4747d192019-04-17 15:05:45 +02001739
1740/** Finalize the creation of a key once its key material has been set.
1741 *
1742 * This entails writing the key to persistent storage.
1743 *
1744 * If this function fails, call psa_fail_key_creation().
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001745 * See the documentation of psa_start_key_creation() for the intended use
1746 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02001747 *
Ronald Cron5c522922020-11-14 16:35:34 +01001748 * If the finalization succeeds, the function unlocks the key slot (it was
1749 * locked by psa_start_key_creation()) and the key slot cannot be accessed
1750 * anymore as part of the key creation process.
Ronald Cron50972942020-11-14 11:28:25 +01001751 *
Gilles Peskine011e4282019-06-26 18:34:38 +02001752 * \param[in,out] slot Pointer to the slot with key material.
1753 * \param[in] driver The secure element driver for the key,
1754 * or NULL for a transparent key.
Ronald Cron81709fc2020-11-14 12:10:32 +01001755 * \param[out] key On success, identifier of the key. Note that the
1756 * key identifier is also stored in the key slot.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001757 *
1758 * \retval #PSA_SUCCESS
Ronald Croncf56a0a2020-08-04 09:51:30 +02001759 * The key was successfully created.
gabor-mezei-arm452b0a32020-11-09 17:42:55 +01001760 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
1761 * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
1762 * \retval #PSA_ERROR_ALREADY_EXISTS
1763 * \retval #PSA_ERROR_DATA_INVALID
1764 * \retval #PSA_ERROR_DATA_CORRUPT
gabor-mezei-arm86326a92020-11-30 16:50:34 +01001765 * \retval #PSA_ERROR_STORAGE_FAILURE
gabor-mezei-arm452b0a32020-11-09 17:42:55 +01001766 *
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001767 * \return If this function fails, the key slot is an invalid state.
1768 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02001769 */
Gilles Peskine011e4282019-06-26 18:34:38 +02001770static psa_status_t psa_finish_key_creation(
1771 psa_key_slot_t *slot,
Ronald Cron81709fc2020-11-14 12:10:32 +01001772 psa_se_drv_table_entry_t *driver,
1773 mbedtls_svc_key_id_t *key)
Gilles Peskine4747d192019-04-17 15:05:45 +02001774{
1775 psa_status_t status = PSA_SUCCESS;
Gilles Peskine30afafd2019-04-25 13:47:40 +02001776 (void) slot;
Gilles Peskine011e4282019-06-26 18:34:38 +02001777 (void) driver;
Gilles Peskine4747d192019-04-17 15:05:45 +02001778
1779#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Steven Cooremanc59de6a2020-06-08 18:28:25 +02001780 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
Gilles Peskine4747d192019-04-17 15:05:45 +02001781 {
Gilles Peskine1df83d42019-07-23 16:13:14 +02001782#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1783 if( driver != NULL )
1784 {
Gilles Peskineb46bef22019-07-30 21:32:04 +02001785 psa_se_key_data_storage_t data;
Ronald Cronea0f8a62020-11-25 17:52:23 +01001786 psa_key_slot_number_t slot_number =
1787 psa_key_slot_get_slot_number( slot ) ;
1788
Gilles Peskineb46bef22019-07-30 21:32:04 +02001789#if defined(static_assert)
Ronald Cronea0f8a62020-11-25 17:52:23 +01001790 static_assert( sizeof( slot_number ) ==
Gilles Peskineb46bef22019-07-30 21:32:04 +02001791 sizeof( data.slot_number ),
1792 "Slot number size does not match psa_se_key_data_storage_t" );
Gilles Peskineb46bef22019-07-30 21:32:04 +02001793#endif
Ronald Cronea0f8a62020-11-25 17:52:23 +01001794 memcpy( &data.slot_number, &slot_number, sizeof( slot_number ) );
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001795 status = psa_save_persistent_key( &slot->attr,
Gilles Peskineb46bef22019-07-30 21:32:04 +02001796 (uint8_t*) &data,
1797 sizeof( data ) );
Gilles Peskine1df83d42019-07-23 16:13:14 +02001798 }
1799 else
1800#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1801 {
Steven Cooreman40120f62020-10-29 11:42:22 +01001802 /* Key material is saved in export representation in the slot, so
1803 * just pass the slot buffer for storage. */
1804 status = psa_save_persistent_key( &slot->attr,
Ronald Cronea0f8a62020-11-25 17:52:23 +01001805 slot->key.data,
1806 slot->key.bytes );
Gilles Peskine1df83d42019-07-23 16:13:14 +02001807 }
Gilles Peskine4747d192019-04-17 15:05:45 +02001808 }
Darryl Green0c6575a2018-11-07 16:05:30 +00001809#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1810
Gilles Peskinecbaff462019-07-12 23:46:04 +02001811#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02001812 /* Finish the transaction for a key creation. This does not
1813 * happen when registering an existing key. Detect this case
1814 * by checking whether a transaction is in progress (actual
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001815 * creation of a persistent key in a secure element requires a transaction,
1816 * but registration or volatile key creation doesn't use one). */
Gilles Peskined7729582019-08-05 15:55:54 +02001817 if( driver != NULL &&
1818 psa_crypto_transaction.unknown.type == PSA_CRYPTO_TRANSACTION_CREATE_KEY )
Gilles Peskinecbaff462019-07-12 23:46:04 +02001819 {
1820 status = psa_save_se_persistent_data( driver );
1821 if( status != PSA_SUCCESS )
1822 {
Gilles Peskine8e338702019-07-30 20:06:31 +02001823 psa_destroy_persistent_key( slot->attr.id );
Gilles Peskinecbaff462019-07-12 23:46:04 +02001824 return( status );
1825 }
Gilles Peskinefc762652019-07-22 19:30:34 +02001826 status = psa_crypto_stop_transaction( );
Gilles Peskinecbaff462019-07-12 23:46:04 +02001827 }
1828#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1829
Ronald Cron50972942020-11-14 11:28:25 +01001830 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01001831 {
1832 *key = slot->attr.id;
Ronald Cron5c522922020-11-14 16:35:34 +01001833 status = psa_unlock_key_slot( slot );
Ronald Cron81709fc2020-11-14 12:10:32 +01001834 if( status != PSA_SUCCESS )
1835 *key = MBEDTLS_SVC_KEY_ID_INIT;
1836 }
Ronald Cron50972942020-11-14 11:28:25 +01001837
Gilles Peskine4747d192019-04-17 15:05:45 +02001838 return( status );
1839}
1840
1841/** Abort the creation of a key.
1842 *
1843 * You may call this function after calling psa_start_key_creation(),
1844 * or after psa_finish_key_creation() fails. In other circumstances, this
1845 * function may not clean up persistent storage.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001846 * See the documentation of psa_start_key_creation() for the intended use
1847 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02001848 *
Gilles Peskine011e4282019-06-26 18:34:38 +02001849 * \param[in,out] slot Pointer to the slot with key material.
1850 * \param[in] driver The secure element driver for the key,
1851 * or NULL for a transparent key.
Gilles Peskine4747d192019-04-17 15:05:45 +02001852 */
Gilles Peskine011e4282019-06-26 18:34:38 +02001853static void psa_fail_key_creation( psa_key_slot_t *slot,
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001854 psa_se_drv_table_entry_t *driver )
Gilles Peskine4747d192019-04-17 15:05:45 +02001855{
Gilles Peskine011e4282019-06-26 18:34:38 +02001856 (void) driver;
1857
Gilles Peskine4747d192019-04-17 15:05:45 +02001858 if( slot == NULL )
1859 return;
Gilles Peskine011e4282019-06-26 18:34:38 +02001860
1861#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01001862 /* TODO: If the key has already been created in the secure
Gilles Peskine011e4282019-06-26 18:34:38 +02001863 * element, and the failure happened later (when saving metadata
1864 * to internal storage), we need to destroy the key in the secure
Gilles Peskinec9d7f942019-08-13 16:17:16 +02001865 * element.
1866 * https://github.com/ARMmbed/mbed-crypto/issues/217
1867 */
Gilles Peskinefc762652019-07-22 19:30:34 +02001868
Gilles Peskined7729582019-08-05 15:55:54 +02001869 /* Abort the ongoing transaction if any (there may not be one if
1870 * the creation process failed before starting one, or if the
1871 * key creation is a registration of a key in a secure element).
1872 * Earlier functions must already have done what it takes to undo any
1873 * partial creation. All that's left is to update the transaction data
1874 * itself. */
Gilles Peskinefc762652019-07-22 19:30:34 +02001875 (void) psa_crypto_stop_transaction( );
Gilles Peskine011e4282019-06-26 18:34:38 +02001876#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1877
Gilles Peskine4747d192019-04-17 15:05:45 +02001878 psa_wipe_key_slot( slot );
1879}
1880
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001881/** Validate optional attributes during key creation.
1882 *
1883 * Some key attributes are optional during key creation. If they are
1884 * specified in the attributes structure, check that they are consistent
1885 * with the data in the slot.
1886 *
1887 * This function should be called near the end of key creation, after
1888 * the slot in memory is fully populated but before saving persistent data.
1889 */
1890static psa_status_t psa_validate_optional_attributes(
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001891 const psa_key_slot_t *slot,
1892 const psa_key_attributes_t *attributes )
1893{
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001894 if( attributes->core.type != 0 )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001895 {
Gilles Peskine8e338702019-07-30 20:06:31 +02001896 if( attributes->core.type != slot->attr.type )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001897 return( PSA_ERROR_INVALID_ARGUMENT );
1898 }
1899
1900 if( attributes->domain_parameters_size != 0 )
1901 {
John Durkop0e005192020-10-31 22:06:54 -07001902#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1903 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskine8e338702019-07-30 20:06:31 +02001904 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001905 {
Steven Cooremana2371e52020-07-28 14:30:39 +02001906 mbedtls_rsa_context *rsa = NULL;
Steven Cooreman75b74362020-07-28 14:30:13 +02001907 mbedtls_mpi actual, required;
Steven Cooreman6d839f02020-07-30 11:36:45 +02001908 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooremana01795d2020-07-24 22:48:15 +02001909
Ronald Cron90857082020-11-25 14:58:33 +01001910 psa_status_t status = mbedtls_psa_rsa_load_representation(
1911 slot->attr.type,
1912 slot->key.data,
1913 slot->key.bytes,
1914 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001915 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02001916 return( status );
Steven Cooreman75b74362020-07-28 14:30:13 +02001917
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001918 mbedtls_mpi_init( &actual );
1919 mbedtls_mpi_init( &required );
Steven Cooremana2371e52020-07-28 14:30:39 +02001920 ret = mbedtls_rsa_export( rsa,
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001921 NULL, NULL, NULL, NULL, &actual );
Steven Cooremana2371e52020-07-28 14:30:39 +02001922 mbedtls_rsa_free( rsa );
1923 mbedtls_free( rsa );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001924 if( ret != 0 )
1925 goto rsa_exit;
1926 ret = mbedtls_mpi_read_binary( &required,
1927 attributes->domain_parameters,
1928 attributes->domain_parameters_size );
1929 if( ret != 0 )
1930 goto rsa_exit;
1931 if( mbedtls_mpi_cmp_mpi( &actual, &required ) != 0 )
1932 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1933 rsa_exit:
1934 mbedtls_mpi_free( &actual );
1935 mbedtls_mpi_free( &required );
1936 if( ret != 0)
1937 return( mbedtls_to_psa_error( ret ) );
1938 }
1939 else
John Durkop9814fa22020-11-04 12:28:15 -08001940#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1941 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001942 {
1943 return( PSA_ERROR_INVALID_ARGUMENT );
1944 }
1945 }
1946
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001947 if( attributes->core.bits != 0 )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001948 {
Gilles Peskineb46bef22019-07-30 21:32:04 +02001949 if( attributes->core.bits != slot->attr.bits )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001950 return( PSA_ERROR_INVALID_ARGUMENT );
1951 }
1952
1953 return( PSA_SUCCESS );
1954}
1955
Gilles Peskine4747d192019-04-17 15:05:45 +02001956psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
Gilles Peskine4747d192019-04-17 15:05:45 +02001957 const uint8_t *data,
Gilles Peskine73676cb2019-05-15 20:15:10 +02001958 size_t data_length,
Ronald Croncf56a0a2020-08-04 09:51:30 +02001959 mbedtls_svc_key_id_t *key )
Gilles Peskine4747d192019-04-17 15:05:45 +02001960{
1961 psa_status_t status;
1962 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001963 psa_se_drv_table_entry_t *driver = NULL;
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001964 size_t bits;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001965
Ronald Cron81709fc2020-11-14 12:10:32 +01001966 *key = MBEDTLS_SVC_KEY_ID_INIT;
1967
Gilles Peskine0f84d622019-09-12 19:03:13 +02001968 /* Reject zero-length symmetric keys (including raw data key objects).
1969 * This also rejects any key which might be encoded as an empty string,
1970 * which is never valid. */
1971 if( data_length == 0 )
1972 return( PSA_ERROR_INVALID_ARGUMENT );
1973
Gilles Peskinedf179142019-07-15 22:02:14 +02001974 status = psa_start_key_creation( PSA_KEY_CREATION_IMPORT, attributes,
Ronald Cron81709fc2020-11-14 12:10:32 +01001975 &slot, &driver );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001976 if( status != PSA_SUCCESS )
1977 goto exit;
1978
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001979 /* In the case of a transparent key or an opaque key stored in local
1980 * storage (thus not in the case of generating a key in a secure element
1981 * or cryptoprocessor with storage), we have to allocate a buffer to
1982 * hold the generated key material. */
1983 if( slot->key.data == NULL )
Gilles Peskine5d309672019-07-12 23:47:28 +02001984 {
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001985 status = psa_allocate_buffer_to_slot( slot, data_length );
Gilles Peskineb46bef22019-07-30 21:32:04 +02001986 if( status != PSA_SUCCESS )
1987 goto exit;
Gilles Peskine5d309672019-07-12 23:47:28 +02001988 }
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001989
1990 bits = slot->attr.bits;
1991 status = psa_driver_wrapper_import_key( attributes,
1992 data, data_length,
1993 slot->key.data,
1994 slot->key.bytes,
1995 &slot->key.bytes, &bits );
1996 if( status != PSA_SUCCESS )
1997 goto exit;
1998
1999 if( slot->attr.bits == 0 )
2000 slot->attr.bits = (psa_key_bits_t) bits;
2001 else if( bits != slot->attr.bits )
Steven Cooremanac3434f2021-01-15 17:36:02 +01002002 {
Steven Cooremanac3434f2021-01-15 17:36:02 +01002003 status = PSA_ERROR_INVALID_ARGUMENT;
2004 goto exit;
Gilles Peskine5d309672019-07-12 23:47:28 +02002005 }
Ronald Cron2ebfdcc2020-11-28 15:54:54 +01002006
Gilles Peskine1b8594a2019-07-31 17:21:46 +02002007 status = psa_validate_optional_attributes( slot, attributes );
Gilles Peskine18017402019-07-24 20:25:59 +02002008 if( status != PSA_SUCCESS )
2009 goto exit;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002010
Ronald Cron81709fc2020-11-14 12:10:32 +01002011 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002012exit:
Gilles Peskine4747d192019-04-17 15:05:45 +02002013 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02002014 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002015
Gilles Peskine4747d192019-04-17 15:05:45 +02002016 return( status );
2017}
2018
Gilles Peskined7729582019-08-05 15:55:54 +02002019#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2020psa_status_t mbedtls_psa_register_se_key(
2021 const psa_key_attributes_t *attributes )
2022{
2023 psa_status_t status;
2024 psa_key_slot_t *slot = NULL;
2025 psa_se_drv_table_entry_t *driver = NULL;
Ronald Croncf56a0a2020-08-04 09:51:30 +02002026 mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
Gilles Peskined7729582019-08-05 15:55:54 +02002027
2028 /* Leaving attributes unspecified is not currently supported.
2029 * It could make sense to query the key type and size from the
2030 * secure element, but not all secure elements support this
2031 * and the driver HAL doesn't currently support it. */
2032 if( psa_get_key_type( attributes ) == PSA_KEY_TYPE_NONE )
2033 return( PSA_ERROR_NOT_SUPPORTED );
2034 if( psa_get_key_bits( attributes ) == 0 )
2035 return( PSA_ERROR_NOT_SUPPORTED );
2036
2037 status = psa_start_key_creation( PSA_KEY_CREATION_REGISTER, attributes,
Ronald Cron81709fc2020-11-14 12:10:32 +01002038 &slot, &driver );
Gilles Peskined7729582019-08-05 15:55:54 +02002039 if( status != PSA_SUCCESS )
2040 goto exit;
2041
Ronald Cron81709fc2020-11-14 12:10:32 +01002042 status = psa_finish_key_creation( slot, driver, &key );
Gilles Peskined7729582019-08-05 15:55:54 +02002043
2044exit:
2045 if( status != PSA_SUCCESS )
Gilles Peskined7729582019-08-05 15:55:54 +02002046 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002047
Gilles Peskined7729582019-08-05 15:55:54 +02002048 /* Registration doesn't keep the key in RAM. */
Ronald Croncf56a0a2020-08-04 09:51:30 +02002049 psa_close_key( key );
Gilles Peskined7729582019-08-05 15:55:54 +02002050 return( status );
2051}
2052#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2053
Gilles Peskinef603c712019-01-19 13:40:11 +01002054static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002055 psa_key_slot_t *target )
Gilles Peskinef603c712019-01-19 13:40:11 +01002056{
Steven Cooremanf7cebd42020-10-13 20:27:40 +02002057 psa_status_t status = psa_copy_key_material_into_slot( target,
Ronald Cronea0f8a62020-11-25 17:52:23 +01002058 source->key.data,
2059 source->key.bytes );
Gilles Peskinef603c712019-01-19 13:40:11 +01002060 if( status != PSA_SUCCESS )
Steven Cooreman398aee52020-10-13 14:35:45 +02002061 return( status );
Gilles Peskinef603c712019-01-19 13:40:11 +01002062
Steven Cooreman398aee52020-10-13 14:35:45 +02002063 target->attr.type = source->attr.type;
2064 target->attr.bits = source->attr.bits;
2065
2066 return( PSA_SUCCESS );
Gilles Peskinef603c712019-01-19 13:40:11 +01002067}
2068
Ronald Croncf56a0a2020-08-04 09:51:30 +02002069psa_status_t psa_copy_key( mbedtls_svc_key_id_t source_key,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002070 const psa_key_attributes_t *specified_attributes,
Ronald Croncf56a0a2020-08-04 09:51:30 +02002071 mbedtls_svc_key_id_t *target_key )
Gilles Peskinef603c712019-01-19 13:40:11 +01002072{
Ronald Cronf95a2b12020-10-22 15:24:49 +02002073 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01002074 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskinef603c712019-01-19 13:40:11 +01002075 psa_key_slot_t *source_slot = NULL;
2076 psa_key_slot_t *target_slot = NULL;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002077 psa_key_attributes_t actual_attributes = *specified_attributes;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02002078 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskinef603c712019-01-19 13:40:11 +01002079
Ronald Cron81709fc2020-11-14 12:10:32 +01002080 *target_key = MBEDTLS_SVC_KEY_ID_INIT;
2081
Ronald Cron5c522922020-11-14 16:35:34 +01002082 status = psa_get_and_lock_transparent_key_slot_with_policy(
2083 source_key, &source_slot, PSA_KEY_USAGE_COPY, 0 );
Gilles Peskinef603c712019-01-19 13:40:11 +01002084 if( status != PSA_SUCCESS )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002085 goto exit;
2086
Gilles Peskine1b8594a2019-07-31 17:21:46 +02002087 status = psa_validate_optional_attributes( source_slot,
2088 specified_attributes );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002089 if( status != PSA_SUCCESS )
2090 goto exit;
2091
Gilles Peskine7e0cff92019-07-30 13:48:52 +02002092 status = psa_restrict_key_policy( &actual_attributes.core.policy,
Gilles Peskine8e338702019-07-30 20:06:31 +02002093 &source_slot->attr.policy );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002094 if( status != PSA_SUCCESS )
2095 goto exit;
2096
Ronald Cron81709fc2020-11-14 12:10:32 +01002097 status = psa_start_key_creation( PSA_KEY_CREATION_COPY, &actual_attributes,
2098 &target_slot, &driver );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002099 if( status != PSA_SUCCESS )
2100 goto exit;
2101
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002102#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2103 if( driver != NULL )
Gilles Peskinef603c712019-01-19 13:40:11 +01002104 {
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002105 /* Copying to a secure element is not implemented yet. */
2106 status = PSA_ERROR_NOT_SUPPORTED;
2107 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01002108 }
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002109#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinef603c712019-01-19 13:40:11 +01002110
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002111 status = psa_copy_key_material( source_slot, target_slot );
Gilles Peskinef603c712019-01-19 13:40:11 +01002112 if( status != PSA_SUCCESS )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002113 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01002114
Ronald Cron81709fc2020-11-14 12:10:32 +01002115 status = psa_finish_key_creation( target_slot, driver, target_key );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002116exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002117 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02002118 psa_fail_key_creation( target_slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002119
Ronald Cron5c522922020-11-14 16:35:34 +01002120 unlock_status = psa_unlock_key_slot( source_slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002121
Ronald Cron5c522922020-11-14 16:35:34 +01002122 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskinef603c712019-01-19 13:40:11 +01002123}
2124
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002125
2126
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002127/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01002128/* Message digests */
2129/****************************************************************/
2130
John Durkop07cc04a2020-11-16 22:08:34 -08002131#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
John Durkop0e005192020-10-31 22:06:54 -07002132 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
2133 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
John Durkop9814fa22020-11-04 12:28:15 -08002134 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinedc2fc842018-03-07 16:42:59 +01002135static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01002136{
2137 switch( alg )
2138 {
John Durkopee4e6602020-11-27 08:48:46 -08002139#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine20035e32018-02-03 22:44:14 +01002140 case PSA_ALG_MD2:
2141 return( &mbedtls_md2_info );
2142#endif
John Durkopee4e6602020-11-27 08:48:46 -08002143#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine20035e32018-02-03 22:44:14 +01002144 case PSA_ALG_MD4:
2145 return( &mbedtls_md4_info );
2146#endif
John Durkopee4e6602020-11-27 08:48:46 -08002147#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine20035e32018-02-03 22:44:14 +01002148 case PSA_ALG_MD5:
2149 return( &mbedtls_md5_info );
2150#endif
John Durkopee4e6602020-11-27 08:48:46 -08002151#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine20035e32018-02-03 22:44:14 +01002152 case PSA_ALG_RIPEMD160:
2153 return( &mbedtls_ripemd160_info );
2154#endif
John Durkopee4e6602020-11-27 08:48:46 -08002155#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine20035e32018-02-03 22:44:14 +01002156 case PSA_ALG_SHA_1:
2157 return( &mbedtls_sha1_info );
2158#endif
John Durkopee4e6602020-11-27 08:48:46 -08002159#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine20035e32018-02-03 22:44:14 +01002160 case PSA_ALG_SHA_224:
2161 return( &mbedtls_sha224_info );
John Durkopee4e6602020-11-27 08:48:46 -08002162#endif
2163#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine20035e32018-02-03 22:44:14 +01002164 case PSA_ALG_SHA_256:
2165 return( &mbedtls_sha256_info );
2166#endif
John Durkopee4e6602020-11-27 08:48:46 -08002167#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine20035e32018-02-03 22:44:14 +01002168 case PSA_ALG_SHA_384:
2169 return( &mbedtls_sha384_info );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +02002170#endif
John Durkopee4e6602020-11-27 08:48:46 -08002171#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine20035e32018-02-03 22:44:14 +01002172 case PSA_ALG_SHA_512:
2173 return( &mbedtls_sha512_info );
2174#endif
2175 default:
2176 return( NULL );
2177 }
2178}
John Durkop07cc04a2020-11-16 22:08:34 -08002179#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
John Durkop9814fa22020-11-04 12:28:15 -08002180 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
2181 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
2182 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskine20035e32018-02-03 22:44:14 +01002183
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002184psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
2185{
2186 switch( operation->alg )
2187 {
Gilles Peskine81736312018-06-26 15:04:31 +02002188 case 0:
2189 /* The object has (apparently) been initialized but it is not
2190 * in use. It's ok to call abort on such an object, and there's
2191 * nothing to do. */
2192 break;
John Durkopee4e6602020-11-27 08:48:46 -08002193#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002194 case PSA_ALG_MD2:
2195 mbedtls_md2_free( &operation->ctx.md2 );
2196 break;
2197#endif
John Durkopee4e6602020-11-27 08:48:46 -08002198#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002199 case PSA_ALG_MD4:
2200 mbedtls_md4_free( &operation->ctx.md4 );
2201 break;
2202#endif
John Durkopee4e6602020-11-27 08:48:46 -08002203#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002204 case PSA_ALG_MD5:
2205 mbedtls_md5_free( &operation->ctx.md5 );
2206 break;
2207#endif
John Durkopee4e6602020-11-27 08:48:46 -08002208#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002209 case PSA_ALG_RIPEMD160:
2210 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
2211 break;
2212#endif
John Durkopee4e6602020-11-27 08:48:46 -08002213#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002214 case PSA_ALG_SHA_1:
2215 mbedtls_sha1_free( &operation->ctx.sha1 );
2216 break;
2217#endif
John Durkop6ca23272020-12-03 06:01:32 -08002218#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002219 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002220 mbedtls_sha256_free( &operation->ctx.sha256 );
2221 break;
2222#endif
2223#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002224 case PSA_ALG_SHA_256:
2225 mbedtls_sha256_free( &operation->ctx.sha256 );
2226 break;
2227#endif
John Durkop6ca23272020-12-03 06:01:32 -08002228#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002229 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002230 mbedtls_sha512_free( &operation->ctx.sha512 );
2231 break;
2232#endif
2233#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002234 case PSA_ALG_SHA_512:
2235 mbedtls_sha512_free( &operation->ctx.sha512 );
2236 break;
2237#endif
2238 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002239 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002240 }
2241 operation->alg = 0;
2242 return( PSA_SUCCESS );
2243}
2244
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002245psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002246 psa_algorithm_t alg )
2247{
Janos Follath24eed8d2019-11-22 13:21:35 +00002248 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002249
2250 /* A context must be freshly initialized before it can be set up. */
2251 if( operation->alg != 0 )
2252 {
2253 return( PSA_ERROR_BAD_STATE );
2254 }
2255
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002256 switch( alg )
2257 {
John Durkopee4e6602020-11-27 08:48:46 -08002258#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002259 case PSA_ALG_MD2:
2260 mbedtls_md2_init( &operation->ctx.md2 );
2261 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
2262 break;
2263#endif
John Durkopee4e6602020-11-27 08:48:46 -08002264#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002265 case PSA_ALG_MD4:
2266 mbedtls_md4_init( &operation->ctx.md4 );
2267 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
2268 break;
2269#endif
John Durkopee4e6602020-11-27 08:48:46 -08002270#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002271 case PSA_ALG_MD5:
2272 mbedtls_md5_init( &operation->ctx.md5 );
2273 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
2274 break;
2275#endif
John Durkopee4e6602020-11-27 08:48:46 -08002276#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002277 case PSA_ALG_RIPEMD160:
2278 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
2279 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
2280 break;
2281#endif
John Durkopee4e6602020-11-27 08:48:46 -08002282#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002283 case PSA_ALG_SHA_1:
2284 mbedtls_sha1_init( &operation->ctx.sha1 );
2285 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
2286 break;
2287#endif
John Durkopee4e6602020-11-27 08:48:46 -08002288#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002289 case PSA_ALG_SHA_224:
2290 mbedtls_sha256_init( &operation->ctx.sha256 );
2291 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
2292 break;
John Durkopee4e6602020-11-27 08:48:46 -08002293#endif
2294#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002295 case PSA_ALG_SHA_256:
2296 mbedtls_sha256_init( &operation->ctx.sha256 );
2297 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
2298 break;
2299#endif
John Durkopee4e6602020-11-27 08:48:46 -08002300#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002301 case PSA_ALG_SHA_384:
2302 mbedtls_sha512_init( &operation->ctx.sha512 );
2303 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
2304 break;
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002305#endif
John Durkopee4e6602020-11-27 08:48:46 -08002306#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002307 case PSA_ALG_SHA_512:
2308 mbedtls_sha512_init( &operation->ctx.sha512 );
2309 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
2310 break;
2311#endif
2312 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02002313 return( PSA_ALG_IS_HASH( alg ) ?
2314 PSA_ERROR_NOT_SUPPORTED :
2315 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002316 }
2317 if( ret == 0 )
2318 operation->alg = alg;
2319 else
2320 psa_hash_abort( operation );
2321 return( mbedtls_to_psa_error( ret ) );
2322}
2323
2324psa_status_t psa_hash_update( psa_hash_operation_t *operation,
2325 const uint8_t *input,
2326 size_t input_length )
2327{
Janos Follath24eed8d2019-11-22 13:21:35 +00002328 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine94e44542018-07-12 16:58:43 +02002329
2330 /* Don't require hash implementations to behave correctly on a
2331 * zero-length input, which may have an invalid pointer. */
2332 if( input_length == 0 )
2333 return( PSA_SUCCESS );
2334
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002335 switch( operation->alg )
2336 {
John Durkopee4e6602020-11-27 08:48:46 -08002337#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002338 case PSA_ALG_MD2:
2339 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
2340 input, input_length );
2341 break;
2342#endif
John Durkopee4e6602020-11-27 08:48:46 -08002343#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002344 case PSA_ALG_MD4:
2345 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
2346 input, input_length );
2347 break;
2348#endif
John Durkopee4e6602020-11-27 08:48:46 -08002349#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002350 case PSA_ALG_MD5:
2351 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
2352 input, input_length );
2353 break;
2354#endif
John Durkopee4e6602020-11-27 08:48:46 -08002355#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002356 case PSA_ALG_RIPEMD160:
2357 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
2358 input, input_length );
2359 break;
2360#endif
John Durkopee4e6602020-11-27 08:48:46 -08002361#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002362 case PSA_ALG_SHA_1:
2363 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
2364 input, input_length );
2365 break;
2366#endif
John Durkop6ca23272020-12-03 06:01:32 -08002367#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002368 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002369 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
2370 input, input_length );
2371 break;
2372#endif
2373#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002374 case PSA_ALG_SHA_256:
2375 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
2376 input, input_length );
2377 break;
2378#endif
John Durkop6ca23272020-12-03 06:01:32 -08002379#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002380 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002381 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
2382 input, input_length );
2383 break;
2384#endif
2385#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002386 case PSA_ALG_SHA_512:
2387 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
2388 input, input_length );
2389 break;
2390#endif
2391 default:
John Durkopee4e6602020-11-27 08:48:46 -08002392 (void)input;
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002393 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002394 }
Gilles Peskine94e44542018-07-12 16:58:43 +02002395
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002396 if( ret != 0 )
2397 psa_hash_abort( operation );
2398 return( mbedtls_to_psa_error( ret ) );
2399}
2400
2401psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
2402 uint8_t *hash,
2403 size_t hash_size,
2404 size_t *hash_length )
2405{
itayzafrir40835d42018-08-02 13:14:17 +03002406 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00002407 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
gabor-mezei-armcbcec212020-12-18 14:23:51 +01002408 size_t actual_hash_length = PSA_HASH_LENGTH( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002409
2410 /* Fill the output buffer with something that isn't a valid hash
2411 * (barring an attack on the hash and deliberately-crafted input),
2412 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02002413 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002414 /* If hash_size is 0 then hash may be NULL and then the
2415 * call to memset would have undefined behavior. */
2416 if( hash_size != 0 )
2417 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002418
2419 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03002420 {
2421 status = PSA_ERROR_BUFFER_TOO_SMALL;
2422 goto exit;
2423 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002424
2425 switch( operation->alg )
2426 {
John Durkopee4e6602020-11-27 08:48:46 -08002427#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002428 case PSA_ALG_MD2:
2429 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
2430 break;
2431#endif
John Durkopee4e6602020-11-27 08:48:46 -08002432#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002433 case PSA_ALG_MD4:
2434 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
2435 break;
2436#endif
John Durkopee4e6602020-11-27 08:48:46 -08002437#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002438 case PSA_ALG_MD5:
2439 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
2440 break;
2441#endif
John Durkopee4e6602020-11-27 08:48:46 -08002442#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002443 case PSA_ALG_RIPEMD160:
2444 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
2445 break;
2446#endif
John Durkopee4e6602020-11-27 08:48:46 -08002447#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002448 case PSA_ALG_SHA_1:
2449 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
2450 break;
2451#endif
John Durkop6ca23272020-12-03 06:01:32 -08002452#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002453 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002454 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
2455 break;
2456#endif
2457#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002458 case PSA_ALG_SHA_256:
2459 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
2460 break;
2461#endif
John Durkop6ca23272020-12-03 06:01:32 -08002462#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002463 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002464 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
2465 break;
2466#endif
2467#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002468 case PSA_ALG_SHA_512:
2469 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
2470 break;
2471#endif
2472 default:
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002473 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002474 }
itayzafrir40835d42018-08-02 13:14:17 +03002475 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002476
itayzafrir40835d42018-08-02 13:14:17 +03002477exit:
2478 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002479 {
Gilles Peskineaee13332018-07-02 12:15:28 +02002480 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002481 return( psa_hash_abort( operation ) );
2482 }
2483 else
2484 {
2485 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03002486 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002487 }
2488}
2489
Gilles Peskine2d277862018-06-18 15:41:12 +02002490psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
2491 const uint8_t *hash,
2492 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002493{
2494 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
2495 size_t actual_hash_length;
2496 psa_status_t status = psa_hash_finish( operation,
2497 actual_hash, sizeof( actual_hash ),
2498 &actual_hash_length );
2499 if( status != PSA_SUCCESS )
2500 return( status );
2501 if( actual_hash_length != hash_length )
2502 return( PSA_ERROR_INVALID_SIGNATURE );
2503 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
2504 return( PSA_ERROR_INVALID_SIGNATURE );
2505 return( PSA_SUCCESS );
2506}
2507
Gilles Peskine0a749c82019-11-28 19:33:58 +01002508psa_status_t psa_hash_compute( psa_algorithm_t alg,
2509 const uint8_t *input, size_t input_length,
2510 uint8_t *hash, size_t hash_size,
2511 size_t *hash_length )
2512{
2513 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
2514 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2515
2516 *hash_length = hash_size;
2517 status = psa_hash_setup( &operation, alg );
2518 if( status != PSA_SUCCESS )
2519 goto exit;
2520 status = psa_hash_update( &operation, input, input_length );
2521 if( status != PSA_SUCCESS )
2522 goto exit;
2523 status = psa_hash_finish( &operation, hash, hash_size, hash_length );
2524 if( status != PSA_SUCCESS )
2525 goto exit;
2526
2527exit:
2528 if( status == PSA_SUCCESS )
2529 status = psa_hash_abort( &operation );
2530 else
2531 psa_hash_abort( &operation );
2532 return( status );
2533}
2534
2535psa_status_t psa_hash_compare( psa_algorithm_t alg,
2536 const uint8_t *input, size_t input_length,
2537 const uint8_t *hash, size_t hash_length )
2538{
2539 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
2540 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2541
2542 status = psa_hash_setup( &operation, alg );
2543 if( status != PSA_SUCCESS )
2544 goto exit;
2545 status = psa_hash_update( &operation, input, input_length );
2546 if( status != PSA_SUCCESS )
2547 goto exit;
2548 status = psa_hash_verify( &operation, hash, hash_length );
2549 if( status != PSA_SUCCESS )
2550 goto exit;
2551
2552exit:
2553 if( status == PSA_SUCCESS )
2554 status = psa_hash_abort( &operation );
2555 else
2556 psa_hash_abort( &operation );
2557 return( status );
2558}
2559
Gilles Peskineeb35d782019-01-22 17:56:16 +01002560psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation,
2561 psa_hash_operation_t *target_operation )
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002562{
2563 if( target_operation->alg != 0 )
2564 return( PSA_ERROR_BAD_STATE );
2565
2566 switch( source_operation->alg )
2567 {
2568 case 0:
2569 return( PSA_ERROR_BAD_STATE );
John Durkopee4e6602020-11-27 08:48:46 -08002570#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002571 case PSA_ALG_MD2:
2572 mbedtls_md2_clone( &target_operation->ctx.md2,
2573 &source_operation->ctx.md2 );
2574 break;
2575#endif
John Durkopee4e6602020-11-27 08:48:46 -08002576#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002577 case PSA_ALG_MD4:
2578 mbedtls_md4_clone( &target_operation->ctx.md4,
2579 &source_operation->ctx.md4 );
2580 break;
2581#endif
John Durkopee4e6602020-11-27 08:48:46 -08002582#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002583 case PSA_ALG_MD5:
2584 mbedtls_md5_clone( &target_operation->ctx.md5,
2585 &source_operation->ctx.md5 );
2586 break;
2587#endif
John Durkopee4e6602020-11-27 08:48:46 -08002588#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002589 case PSA_ALG_RIPEMD160:
2590 mbedtls_ripemd160_clone( &target_operation->ctx.ripemd160,
2591 &source_operation->ctx.ripemd160 );
2592 break;
2593#endif
John Durkopee4e6602020-11-27 08:48:46 -08002594#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002595 case PSA_ALG_SHA_1:
2596 mbedtls_sha1_clone( &target_operation->ctx.sha1,
2597 &source_operation->ctx.sha1 );
2598 break;
2599#endif
John Durkop6ca23272020-12-03 06:01:32 -08002600#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002601 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002602 mbedtls_sha256_clone( &target_operation->ctx.sha256,
2603 &source_operation->ctx.sha256 );
2604 break;
2605#endif
2606#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002607 case PSA_ALG_SHA_256:
2608 mbedtls_sha256_clone( &target_operation->ctx.sha256,
2609 &source_operation->ctx.sha256 );
2610 break;
2611#endif
John Durkop6ca23272020-12-03 06:01:32 -08002612#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002613 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002614 mbedtls_sha512_clone( &target_operation->ctx.sha512,
2615 &source_operation->ctx.sha512 );
2616 break;
2617#endif
2618#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002619 case PSA_ALG_SHA_512:
2620 mbedtls_sha512_clone( &target_operation->ctx.sha512,
2621 &source_operation->ctx.sha512 );
2622 break;
2623#endif
2624 default:
2625 return( PSA_ERROR_NOT_SUPPORTED );
2626 }
2627
2628 target_operation->alg = source_operation->alg;
2629 return( PSA_SUCCESS );
2630}
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002631
2632
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002633/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01002634/* MAC */
2635/****************************************************************/
2636
Gilles Peskinedc2fc842018-03-07 16:42:59 +01002637static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01002638 psa_algorithm_t alg,
2639 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02002640 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03002641 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002642{
Gilles Peskine8c9def32018-02-08 10:02:12 +01002643 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03002644 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002645
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02002646 if( PSA_ALG_IS_AEAD( alg ) )
Bence Szépkútia63b20d2020-12-16 11:36:46 +01002647 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02002648
Gilles Peskine8c9def32018-02-08 10:02:12 +01002649 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
2650 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03002651 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002652 {
Bence Szépkúti1de907d2020-12-07 18:20:28 +01002653 case PSA_ALG_STREAM_CIPHER:
Gilles Peskine8c9def32018-02-08 10:02:12 +01002654 mode = MBEDTLS_MODE_STREAM;
2655 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002656 case PSA_ALG_CTR:
2657 mode = MBEDTLS_MODE_CTR;
2658 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002659 case PSA_ALG_CFB:
2660 mode = MBEDTLS_MODE_CFB;
2661 break;
2662 case PSA_ALG_OFB:
2663 mode = MBEDTLS_MODE_OFB;
2664 break;
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02002665 case PSA_ALG_ECB_NO_PADDING:
2666 mode = MBEDTLS_MODE_ECB;
2667 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002668 case PSA_ALG_CBC_NO_PADDING:
2669 mode = MBEDTLS_MODE_CBC;
2670 break;
2671 case PSA_ALG_CBC_PKCS7:
2672 mode = MBEDTLS_MODE_CBC;
2673 break;
Bence Szépkútia63b20d2020-12-16 11:36:46 +01002674 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01002675 mode = MBEDTLS_MODE_CCM;
2676 break;
Bence Szépkútia63b20d2020-12-16 11:36:46 +01002677 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01002678 mode = MBEDTLS_MODE_GCM;
2679 break;
Bence Szépkútia63b20d2020-12-16 11:36:46 +01002680 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
Gilles Peskine26869f22019-05-06 15:25:00 +02002681 mode = MBEDTLS_MODE_CHACHAPOLY;
2682 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002683 default:
2684 return( NULL );
2685 }
2686 }
2687 else if( alg == PSA_ALG_CMAC )
2688 mode = MBEDTLS_MODE_ECB;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002689 else
2690 return( NULL );
2691
2692 switch( key_type )
2693 {
2694 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03002695 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002696 break;
2697 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002698 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
2699 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01002700 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03002701 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002702 else
mohammad1603f4f0d612018-06-03 15:04:51 +03002703 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002704 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
2705 * but two-key Triple-DES is functionally three-key Triple-DES
2706 * with K1=K3, so that's how we present it to mbedtls. */
2707 if( key_bits == 128 )
2708 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002709 break;
2710 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03002711 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002712 break;
2713 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03002714 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002715 break;
Gilles Peskine26869f22019-05-06 15:25:00 +02002716 case PSA_KEY_TYPE_CHACHA20:
2717 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
2718 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002719 default:
2720 return( NULL );
2721 }
mohammad1603f4f0d612018-06-03 15:04:51 +03002722 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03002723 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002724
Jaeden Amero23bbb752018-06-26 14:16:54 +01002725 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
2726 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002727}
2728
John Durkop6ba40d12020-11-10 08:50:04 -08002729#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002730static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03002731{
Gilles Peskine2d277862018-06-18 15:41:12 +02002732 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03002733 {
2734 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002735 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002736 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002737 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002738 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002739 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002740 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002741 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002742 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002743 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002744 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002745 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002746 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002747 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002748 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002749 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002750 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02002751 return( 128 );
2752 default:
2753 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002754 }
2755}
John Durkop07cc04a2020-11-16 22:08:34 -08002756#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03002757
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002758/* Initialize the MAC operation structure. Once this function has been
2759 * called, psa_mac_abort can run and will do the right thing. */
2760static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
2761 psa_algorithm_t alg )
2762{
2763 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
2764
Steven Cooreman15472f82021-03-02 16:16:22 +01002765 operation->alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002766 operation->key_set = 0;
2767 operation->iv_set = 0;
2768 operation->iv_required = 0;
2769 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002770 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002771
2772#if defined(MBEDTLS_CMAC_C)
Steven Cooreman15472f82021-03-02 16:16:22 +01002773 if( operation->alg == PSA_ALG_CMAC )
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002774 {
2775 operation->iv_required = 0;
2776 mbedtls_cipher_init( &operation->ctx.cmac );
2777 status = PSA_SUCCESS;
2778 }
2779 else
2780#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07002781#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002782 if( PSA_ALG_IS_HMAC( operation->alg ) )
2783 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02002784 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
2785 operation->ctx.hmac.hash_ctx.alg = 0;
2786 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002787 }
2788 else
John Durkopd0321952020-10-29 21:37:36 -07002789#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002790 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02002791 if( ! PSA_ALG_IS_MAC( alg ) )
2792 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002793 }
2794
2795 if( status != PSA_SUCCESS )
2796 memset( operation, 0, sizeof( *operation ) );
2797 return( status );
2798}
2799
John Durkop6ba40d12020-11-10 08:50:04 -08002800#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02002801static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
2802{
Gilles Peskine3f108122018-12-07 18:14:53 +01002803 mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002804 return( psa_hash_abort( &hmac->hash_ctx ) );
2805}
John Durkop6ba40d12020-11-10 08:50:04 -08002806#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine01126fa2018-07-12 17:04:55 +02002807
Gilles Peskine8c9def32018-02-08 10:02:12 +01002808psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
2809{
Gilles Peskinefbfac682018-07-08 20:51:54 +02002810 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002811 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02002812 /* The object has (apparently) been initialized but it is not
2813 * in use. It's ok to call abort on such an object, and there's
2814 * nothing to do. */
2815 return( PSA_SUCCESS );
2816 }
2817 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002818#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002819 if( operation->alg == PSA_ALG_CMAC )
2820 {
2821 mbedtls_cipher_free( &operation->ctx.cmac );
2822 }
2823 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002824#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07002825#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002826 if( PSA_ALG_IS_HMAC( operation->alg ) )
2827 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002828 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002829 }
2830 else
John Durkopd0321952020-10-29 21:37:36 -07002831#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02002832 {
2833 /* Sanity check (shouldn't happen: operation->alg should
2834 * always have been initialized to a valid value). */
2835 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002836 }
Moran Peker41deec42018-04-04 15:43:05 +03002837
Gilles Peskine8c9def32018-02-08 10:02:12 +01002838 operation->alg = 0;
2839 operation->key_set = 0;
2840 operation->iv_set = 0;
2841 operation->iv_required = 0;
2842 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002843 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002844
Gilles Peskine8c9def32018-02-08 10:02:12 +01002845 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002846
2847bad_state:
2848 /* If abort is called on an uninitialized object, we can't trust
2849 * anything. Wipe the object in case it contains confidential data.
2850 * This may result in a memory leak if a pointer gets overwritten,
2851 * but it's too late to do anything about this. */
2852 memset( operation, 0, sizeof( *operation ) );
2853 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002854}
2855
Gilles Peskinee3b07d82018-06-19 11:57:35 +02002856#if defined(MBEDTLS_CMAC_C)
Steven Cooreman15472f82021-03-02 16:16:22 +01002857static psa_status_t psa_cmac_setup( psa_mac_operation_t *operation,
2858 psa_key_slot_t *slot )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002859{
Janos Follath24eed8d2019-11-22 13:21:35 +00002860 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooreman15472f82021-03-02 16:16:22 +01002861 const mbedtls_cipher_info_t *cipher_info =
2862 mbedtls_cipher_info_from_psa( PSA_ALG_CMAC,
2863 slot->attr.type, slot->attr.bits,
2864 NULL );
2865 if( cipher_info == NULL )
2866 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002867
2868 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
2869 if( ret != 0 )
Steven Cooreman15472f82021-03-02 16:16:22 +01002870 goto exit;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002871
2872 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
Ronald Cronea0f8a62020-11-25 17:52:23 +01002873 slot->key.data,
Steven Cooreman15472f82021-03-02 16:16:22 +01002874 slot->attr.bits );
2875exit:
2876 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002877}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02002878#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002879
John Durkop6ba40d12020-11-10 08:50:04 -08002880#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02002881static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
2882 const uint8_t *key,
2883 size_t key_length,
2884 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002885{
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02002886 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002887 size_t i;
gabor-mezei-armcbcec212020-12-18 14:23:51 +01002888 size_t hash_size = PSA_HASH_LENGTH( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002889 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002890 psa_status_t status;
2891
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002892 /* Sanity checks on block_size, to guarantee that there won't be a buffer
2893 * overflow below. This should never trigger if the hash algorithm
2894 * is implemented correctly. */
2895 /* The size checks against the ipad and opad buffers cannot be written
2896 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
2897 * because that triggers -Wlogical-op on GCC 7.3. */
2898 if( block_size > sizeof( ipad ) )
2899 return( PSA_ERROR_NOT_SUPPORTED );
2900 if( block_size > sizeof( hmac->opad ) )
2901 return( PSA_ERROR_NOT_SUPPORTED );
2902 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002903 return( PSA_ERROR_NOT_SUPPORTED );
2904
Gilles Peskined223b522018-06-11 18:12:58 +02002905 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002906 {
Gilles Peskine84b8fc82019-11-28 20:07:20 +01002907 status = psa_hash_compute( hash_alg, key, key_length,
2908 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002909 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02002910 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002911 }
Gilles Peskine96889972018-07-12 17:07:03 +02002912 /* A 0-length key is not commonly used in HMAC when used as a MAC,
2913 * but it is permitted. It is common when HMAC is used in HKDF, for
2914 * example. Don't call `memcpy` in the 0-length because `key` could be
2915 * an invalid pointer which would make the behavior undefined. */
2916 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02002917 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002918
Gilles Peskined223b522018-06-11 18:12:58 +02002919 /* ipad contains the key followed by garbage. Xor and fill with 0x36
2920 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002921 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02002922 ipad[i] ^= 0x36;
2923 memset( ipad + key_length, 0x36, block_size - key_length );
2924
2925 /* Copy the key material from ipad to opad, flipping the requisite bits,
2926 * and filling the rest of opad with the requisite constant. */
2927 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02002928 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
2929 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002930
Gilles Peskine01126fa2018-07-12 17:04:55 +02002931 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002932 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002933 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002934
Gilles Peskine01126fa2018-07-12 17:04:55 +02002935 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002936
2937cleanup:
Steven Cooreman29149862020-08-05 15:43:42 +02002938 mbedtls_platform_zeroize( ipad, sizeof( ipad ) );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002939
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002940 return( status );
2941}
John Durkop6ba40d12020-11-10 08:50:04 -08002942#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002943
Gilles Peskine89167cb2018-07-08 20:12:23 +02002944static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02002945 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02002946 psa_algorithm_t alg,
2947 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002948{
Ronald Cronf95a2b12020-10-22 15:24:49 +02002949 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01002950 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01002951 psa_key_slot_t *slot;
Steven Cooreman15472f82021-03-02 16:16:22 +01002952 size_t output_length = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002953 psa_key_usage_t usage =
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01002954 is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002955
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002956 /* A context must be freshly initialized before it can be set up. */
2957 if( operation->alg != 0 )
2958 {
2959 return( PSA_ERROR_BAD_STATE );
2960 }
2961
Steven Cooreman15472f82021-03-02 16:16:22 +01002962 status = psa_mac_init( operation, alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002963 if( status != PSA_SUCCESS )
2964 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02002965 if( is_sign )
2966 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002967
Ronald Cron5c522922020-11-14 16:35:34 +01002968 status = psa_get_and_lock_transparent_key_slot_with_policy(
2969 key, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002970 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002971 goto exit;
Steven Cooreman15472f82021-03-02 16:16:22 +01002972
2973 status = psa_get_mac_output_length( alg, slot->attr.type,
2974 &output_length );
2975 if( status != PSA_SUCCESS )
2976 goto exit;
2977
2978 operation->mac_size = (uint8_t) output_length;
2979
2980 if( operation->mac_size < 4 )
2981 {
2982 /* A very short MAC is too short for security since it can be
2983 * brute-forced. Ancient protocols with 32-bit MACs do exist,
2984 * so we make this our minimum, even though 32 bits is still
2985 * too small for security. */
2986 status = PSA_ERROR_NOT_SUPPORTED;
2987 goto exit;
2988 }
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002989
Gilles Peskine8c9def32018-02-08 10:02:12 +01002990#if defined(MBEDTLS_CMAC_C)
Steven Cooreman15472f82021-03-02 16:16:22 +01002991 if( PSA_ALG_FULL_LENGTH_MAC( alg ) == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002992 {
Steven Cooreman15472f82021-03-02 16:16:22 +01002993 status = psa_cmac_setup( operation, slot );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002994 }
2995 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002996#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07002997#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Steven Cooreman15472f82021-03-02 16:16:22 +01002998 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002999 {
Gilles Peskine9aa369e2018-07-16 00:36:29 +02003000 /* Sanity check. This shouldn't fail on a valid configuration. */
3001 if( operation->mac_size == 0 ||
3002 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
3003 {
3004 status = PSA_ERROR_NOT_SUPPORTED;
3005 goto exit;
3006 }
3007
Gilles Peskine8e338702019-07-30 20:06:31 +02003008 if( slot->attr.type != PSA_KEY_TYPE_HMAC )
Gilles Peskine01126fa2018-07-12 17:04:55 +02003009 {
3010 status = PSA_ERROR_INVALID_ARGUMENT;
3011 goto exit;
3012 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02003013
Gilles Peskine01126fa2018-07-12 17:04:55 +02003014 status = psa_hmac_setup_internal( &operation->ctx.hmac,
Ronald Cronea0f8a62020-11-25 17:52:23 +01003015 slot->key.data,
3016 slot->key.bytes,
Steven Cooreman15472f82021-03-02 16:16:22 +01003017 PSA_ALG_HMAC_GET_HASH( alg ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003018 }
3019 else
John Durkopd0321952020-10-29 21:37:36 -07003020#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003021 {
3022 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003023 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003024
Gilles Peskinefbfac682018-07-08 20:51:54 +02003025exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003026 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003027 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02003028 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003029 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003030 else
3031 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003032 operation->key_set = 1;
3033 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02003034
Ronald Cron5c522922020-11-14 16:35:34 +01003035 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003036
Ronald Cron5c522922020-11-14 16:35:34 +01003037 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003038}
3039
Gilles Peskine89167cb2018-07-08 20:12:23 +02003040psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02003041 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02003042 psa_algorithm_t alg )
3043{
Ronald Croncf56a0a2020-08-04 09:51:30 +02003044 return( psa_mac_setup( operation, key, alg, 1 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003045}
3046
3047psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02003048 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02003049 psa_algorithm_t alg )
3050{
Ronald Croncf56a0a2020-08-04 09:51:30 +02003051 return( psa_mac_setup( operation, key, alg, 0 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003052}
3053
Gilles Peskine8c9def32018-02-08 10:02:12 +01003054psa_status_t psa_mac_update( psa_mac_operation_t *operation,
3055 const uint8_t *input,
3056 size_t input_length )
3057{
Gilles Peskinefbfac682018-07-08 20:51:54 +02003058 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003059 if( ! operation->key_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003060 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003061 if( operation->iv_required && ! operation->iv_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003062 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003063 operation->has_input = 1;
3064
Gilles Peskine8c9def32018-02-08 10:02:12 +01003065#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003066 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03003067 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02003068 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
3069 input, input_length );
3070 status = mbedtls_to_psa_error( ret );
3071 }
3072 else
3073#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003074#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003075 if( PSA_ALG_IS_HMAC( operation->alg ) )
3076 {
3077 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
3078 input_length );
3079 }
3080 else
John Durkopd0321952020-10-29 21:37:36 -07003081#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003082 {
3083 /* This shouldn't happen if `operation` was initialized by
3084 * a setup function. */
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003085 return( PSA_ERROR_BAD_STATE );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03003086 }
3087
Gilles Peskinefbfac682018-07-08 20:51:54 +02003088 if( status != PSA_SUCCESS )
3089 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003090 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003091}
3092
John Durkop6ba40d12020-11-10 08:50:04 -08003093#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02003094static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
3095 uint8_t *mac,
3096 size_t mac_size )
3097{
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02003098 uint8_t tmp[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine01126fa2018-07-12 17:04:55 +02003099 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
3100 size_t hash_size = 0;
3101 size_t block_size = psa_get_hash_block_size( hash_alg );
3102 psa_status_t status;
3103
Gilles Peskine01126fa2018-07-12 17:04:55 +02003104 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
3105 if( status != PSA_SUCCESS )
3106 return( status );
3107 /* From here on, tmp needs to be wiped. */
3108
3109 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
3110 if( status != PSA_SUCCESS )
3111 goto exit;
3112
3113 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
3114 if( status != PSA_SUCCESS )
3115 goto exit;
3116
3117 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
3118 if( status != PSA_SUCCESS )
3119 goto exit;
3120
Gilles Peskined911eb72018-08-14 15:18:45 +02003121 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
3122 if( status != PSA_SUCCESS )
3123 goto exit;
3124
3125 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003126
3127exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01003128 mbedtls_platform_zeroize( tmp, hash_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003129 return( status );
3130}
John Durkop6ba40d12020-11-10 08:50:04 -08003131#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine01126fa2018-07-12 17:04:55 +02003132
mohammad16036df908f2018-04-02 08:34:15 -07003133static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02003134 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003135 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003136{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02003137 if( ! operation->key_set )
3138 return( PSA_ERROR_BAD_STATE );
3139 if( operation->iv_required && ! operation->iv_set )
3140 return( PSA_ERROR_BAD_STATE );
3141
Gilles Peskine8c9def32018-02-08 10:02:12 +01003142 if( mac_size < operation->mac_size )
3143 return( PSA_ERROR_BUFFER_TOO_SMALL );
3144
Gilles Peskine8c9def32018-02-08 10:02:12 +01003145#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003146 if( operation->alg == PSA_ALG_CMAC )
3147 {
gabor-mezei-armcbcec212020-12-18 14:23:51 +01003148 uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE];
Gilles Peskined911eb72018-08-14 15:18:45 +02003149 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
3150 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02003151 memcpy( mac, tmp, operation->mac_size );
Gilles Peskine3f108122018-12-07 18:14:53 +01003152 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003153 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003154 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02003155 else
3156#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003157#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003158 if( PSA_ALG_IS_HMAC( operation->alg ) )
3159 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02003160 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02003161 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003162 }
3163 else
John Durkopd0321952020-10-29 21:37:36 -07003164#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003165 {
3166 /* This shouldn't happen if `operation` was initialized by
3167 * a setup function. */
3168 return( PSA_ERROR_BAD_STATE );
3169 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01003170}
3171
Gilles Peskineacd4be32018-07-08 19:56:25 +02003172psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
3173 uint8_t *mac,
3174 size_t mac_size,
3175 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07003176{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003177 psa_status_t status;
3178
Jaeden Amero252ef282019-02-15 14:05:35 +00003179 if( operation->alg == 0 )
3180 {
3181 return( PSA_ERROR_BAD_STATE );
3182 }
3183
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003184 /* Fill the output buffer with something that isn't a valid mac
3185 * (barring an attack on the mac and deliberately-crafted input),
3186 * in case the caller doesn't check the return status properly. */
3187 *mac_length = mac_size;
3188 /* If mac_size is 0 then mac may be NULL and then the
3189 * call to memset would have undefined behavior. */
3190 if( mac_size != 0 )
3191 memset( mac, '!', mac_size );
3192
Gilles Peskine89167cb2018-07-08 20:12:23 +02003193 if( ! operation->is_sign )
3194 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003195 return( PSA_ERROR_BAD_STATE );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003196 }
mohammad16036df908f2018-04-02 08:34:15 -07003197
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003198 status = psa_mac_finish_internal( operation, mac, mac_size );
3199
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003200 if( status == PSA_SUCCESS )
3201 {
3202 status = psa_mac_abort( operation );
3203 if( status == PSA_SUCCESS )
3204 *mac_length = operation->mac_size;
3205 else
3206 memset( mac, '!', mac_size );
3207 }
3208 else
3209 psa_mac_abort( operation );
3210 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07003211}
3212
Gilles Peskineacd4be32018-07-08 19:56:25 +02003213psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
3214 const uint8_t *mac,
3215 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003216{
Gilles Peskine828ed142018-06-18 23:25:51 +02003217 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07003218 psa_status_t status;
3219
Jaeden Amero252ef282019-02-15 14:05:35 +00003220 if( operation->alg == 0 )
3221 {
3222 return( PSA_ERROR_BAD_STATE );
3223 }
3224
Gilles Peskine89167cb2018-07-08 20:12:23 +02003225 if( operation->is_sign )
3226 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003227 return( PSA_ERROR_BAD_STATE );
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003228 }
3229 if( operation->mac_size != mac_length )
3230 {
3231 status = PSA_ERROR_INVALID_SIGNATURE;
3232 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02003233 }
mohammad16036df908f2018-04-02 08:34:15 -07003234
3235 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003236 actual_mac, sizeof( actual_mac ) );
Gilles Peskine28cd4162020-01-20 16:31:06 +01003237 if( status != PSA_SUCCESS )
3238 goto cleanup;
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003239
3240 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
3241 status = PSA_ERROR_INVALID_SIGNATURE;
3242
3243cleanup:
3244 if( status == PSA_SUCCESS )
3245 status = psa_mac_abort( operation );
3246 else
3247 psa_mac_abort( operation );
3248
Gilles Peskine3f108122018-12-07 18:14:53 +01003249 mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02003250
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003251 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003252}
3253
3254
Gilles Peskine20035e32018-02-03 22:44:14 +01003255
Gilles Peskine20035e32018-02-03 22:44:14 +01003256/****************************************************************/
3257/* Asymmetric cryptography */
3258/****************************************************************/
3259
John Durkop6ba40d12020-11-10 08:50:04 -08003260#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3261 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02003262/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003263 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02003264static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
3265 size_t hash_length,
3266 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003267{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02003268 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02003269 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003270 *md_alg = mbedtls_md_get_type( md_info );
3271
3272 /* The Mbed TLS RSA module uses an unsigned int for hash length
3273 * parameters. Validate that it fits so that we don't risk an
3274 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003275#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003276 if( hash_length > UINT_MAX )
3277 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003278#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003279
John Durkop0e005192020-10-31 22:06:54 -07003280#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003281 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
3282 * must be correct. */
3283 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
3284 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003285 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003286 if( md_info == NULL )
3287 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02003288 if( mbedtls_md_get_size( md_info ) != hash_length )
3289 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003290 }
John Durkop0e005192020-10-31 22:06:54 -07003291#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003292
John Durkop0e005192020-10-31 22:06:54 -07003293#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003294 /* PSS requires a hash internally. */
3295 if( PSA_ALG_IS_RSA_PSS( alg ) )
3296 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02003297 if( md_info == NULL )
3298 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003299 }
John Durkop0e005192020-10-31 22:06:54 -07003300#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003301
Gilles Peskine61b91d42018-06-08 16:09:36 +02003302 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003303}
3304
Gilles Peskine2b450e32018-06-27 15:42:46 +02003305static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
3306 psa_algorithm_t alg,
3307 const uint8_t *hash,
3308 size_t hash_length,
3309 uint8_t *signature,
3310 size_t signature_size,
3311 size_t *signature_length )
3312{
3313 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003314 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003315 mbedtls_md_type_t md_alg;
3316
3317 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
3318 if( status != PSA_SUCCESS )
3319 return( status );
3320
Gilles Peskine630a18a2018-06-29 17:49:35 +02003321 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02003322 return( PSA_ERROR_BUFFER_TOO_SMALL );
3323
John Durkop0e005192020-10-31 22:06:54 -07003324#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003325 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
3326 {
3327 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
3328 MBEDTLS_MD_NONE );
3329 ret = mbedtls_rsa_pkcs1_sign( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003330 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003331 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003332 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003333 md_alg,
3334 (unsigned int) hash_length,
3335 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003336 signature );
3337 }
3338 else
John Durkop0e005192020-10-31 22:06:54 -07003339#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
3340#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003341 if( PSA_ALG_IS_RSA_PSS( alg ) )
3342 {
3343 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3344 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003345 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003346 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003347 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003348 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003349 (unsigned int) hash_length,
3350 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003351 signature );
3352 }
3353 else
John Durkop0e005192020-10-31 22:06:54 -07003354#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003355 {
3356 return( PSA_ERROR_INVALID_ARGUMENT );
3357 }
3358
3359 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02003360 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003361 return( mbedtls_to_psa_error( ret ) );
3362}
3363
3364static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
3365 psa_algorithm_t alg,
3366 const uint8_t *hash,
3367 size_t hash_length,
3368 const uint8_t *signature,
3369 size_t signature_length )
3370{
3371 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003372 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003373 mbedtls_md_type_t md_alg;
3374
3375 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
3376 if( status != PSA_SUCCESS )
3377 return( status );
3378
Gilles Peskine89cc74f2019-09-12 22:08:23 +02003379 if( signature_length != mbedtls_rsa_get_len( rsa ) )
3380 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003381
John Durkop0e005192020-10-31 22:06:54 -07003382#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003383 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
3384 {
3385 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
3386 MBEDTLS_MD_NONE );
3387 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003388 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003389 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003390 MBEDTLS_RSA_PUBLIC,
3391 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003392 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003393 hash,
3394 signature );
3395 }
3396 else
John Durkop0e005192020-10-31 22:06:54 -07003397#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
3398#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003399 if( PSA_ALG_IS_RSA_PSS( alg ) )
3400 {
3401 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3402 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003403 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003404 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003405 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003406 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003407 (unsigned int) hash_length,
3408 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003409 signature );
3410 }
3411 else
John Durkop0e005192020-10-31 22:06:54 -07003412#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003413 {
3414 return( PSA_ERROR_INVALID_ARGUMENT );
3415 }
Gilles Peskineef12c632018-09-13 20:37:48 +02003416
3417 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
3418 * the rest of the signature is invalid". This has little use in
3419 * practice and PSA doesn't report this distinction. */
3420 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
3421 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003422 return( mbedtls_to_psa_error( ret ) );
3423}
John Durkop6ba40d12020-11-10 08:50:04 -08003424#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3425 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003426
John Durkop6ba40d12020-11-10 08:50:04 -08003427#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3428 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003429/* `ecp` cannot be const because `ecp->grp` needs to be non-const
3430 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
3431 * (even though these functions don't modify it). */
3432static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
3433 psa_algorithm_t alg,
3434 const uint8_t *hash,
3435 size_t hash_length,
3436 uint8_t *signature,
3437 size_t signature_size,
3438 size_t *signature_length )
3439{
Janos Follath24eed8d2019-11-22 13:21:35 +00003440 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003441 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003442 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003443 mbedtls_mpi_init( &r );
3444 mbedtls_mpi_init( &s );
3445
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003446 if( signature_size < 2 * curve_bytes )
3447 {
3448 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
3449 goto cleanup;
3450 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003451
John Durkop0ea39e02020-10-13 19:58:20 -07003452#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003453 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
3454 {
3455 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
3456 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
3457 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
Darryl Green5e843fa2019-09-05 14:06:34 +01003458 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det_ext( &ecp->grp, &r, &s,
3459 &ecp->d, hash,
3460 hash_length, md_alg,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003461 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003462 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003463 }
3464 else
John Durkop0ea39e02020-10-13 19:58:20 -07003465#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003466 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003467 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003468 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
3469 hash, hash_length,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003470 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003471 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003472 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003473
3474 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
3475 signature,
3476 curve_bytes ) );
3477 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
3478 signature + curve_bytes,
3479 curve_bytes ) );
3480
3481cleanup:
3482 mbedtls_mpi_free( &r );
3483 mbedtls_mpi_free( &s );
3484 if( ret == 0 )
3485 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003486 return( mbedtls_to_psa_error( ret ) );
3487}
3488
3489static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
3490 const uint8_t *hash,
3491 size_t hash_length,
3492 const uint8_t *signature,
3493 size_t signature_length )
3494{
Janos Follath24eed8d2019-11-22 13:21:35 +00003495 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003496 mbedtls_mpi r, s;
3497 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
3498 mbedtls_mpi_init( &r );
3499 mbedtls_mpi_init( &s );
3500
3501 if( signature_length != 2 * curve_bytes )
3502 return( PSA_ERROR_INVALID_SIGNATURE );
3503
3504 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
3505 signature,
3506 curve_bytes ) );
3507 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
3508 signature + curve_bytes,
3509 curve_bytes ) );
3510
Steven Cooremanacda8342020-07-24 23:09:52 +02003511 /* Check whether the public part is loaded. If not, load it. */
3512 if( mbedtls_ecp_is_zero( &ecp->Q ) )
3513 {
3514 MBEDTLS_MPI_CHK(
3515 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003516 mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
Steven Cooremanacda8342020-07-24 23:09:52 +02003517 }
3518
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003519 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
3520 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003521
3522cleanup:
3523 mbedtls_mpi_free( &r );
3524 mbedtls_mpi_free( &s );
3525 return( mbedtls_to_psa_error( ret ) );
3526}
John Durkop6ba40d12020-11-10 08:50:04 -08003527#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3528 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003529
Ronald Croncf56a0a2020-08-04 09:51:30 +02003530psa_status_t psa_sign_hash( mbedtls_svc_key_id_t key,
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003531 psa_algorithm_t alg,
3532 const uint8_t *hash,
3533 size_t hash_length,
3534 uint8_t *signature,
3535 size_t signature_size,
3536 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01003537{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003538 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003539 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003540 psa_key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003541
3542 *signature_length = signature_size;
Gilles Peskine4019f0e2019-09-12 22:05:59 +02003543 /* Immediately reject a zero-length signature buffer. This guarantees
3544 * that signature must be a valid pointer. (On the other hand, the hash
3545 * buffer can in principle be empty since it doesn't actually have
3546 * to be a hash.) */
3547 if( signature_size == 0 )
3548 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003549
Ronald Cron5c522922020-11-14 16:35:34 +01003550 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
3551 PSA_KEY_USAGE_SIGN_HASH,
3552 alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003553 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003554 goto exit;
Gilles Peskine8e338702019-07-30 20:06:31 +02003555 if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003556 {
3557 status = PSA_ERROR_INVALID_ARGUMENT;
3558 goto exit;
3559 }
Gilles Peskine20035e32018-02-03 22:44:14 +01003560
Steven Cooremancd84cb42020-07-16 20:28:36 +02003561 /* Try any of the available accelerators first */
3562 status = psa_driver_wrapper_sign_hash( slot,
3563 alg,
3564 hash,
3565 hash_length,
3566 signature,
3567 signature_size,
3568 signature_length );
Steven Cooreman8d2bde72020-09-04 13:06:39 +02003569 if( status != PSA_ERROR_NOT_SUPPORTED ||
3570 psa_key_lifetime_is_external( slot->attr.lifetime ) )
Steven Cooremancd84cb42020-07-16 20:28:36 +02003571 goto exit;
3572
Steven Cooreman7a250572020-07-17 16:43:05 +02003573 /* If the operation was not supported by any accelerator, try fallback. */
John Durkop6ba40d12020-11-10 08:50:04 -08003574#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3575 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8e338702019-07-30 20:06:31 +02003576 if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskine20035e32018-02-03 22:44:14 +01003577 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003578 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02003579
Ronald Cron90857082020-11-25 14:58:33 +01003580 status = mbedtls_psa_rsa_load_representation( slot->attr.type,
3581 slot->key.data,
3582 slot->key.bytes,
3583 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02003584 if( status != PSA_SUCCESS )
3585 goto exit;
3586
Steven Cooremana2371e52020-07-28 14:30:39 +02003587 status = psa_rsa_sign( rsa,
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003588 alg,
3589 hash, hash_length,
3590 signature, signature_size,
3591 signature_length );
Steven Cooremana01795d2020-07-24 22:48:15 +02003592
Steven Cooremana2371e52020-07-28 14:30:39 +02003593 mbedtls_rsa_free( rsa );
3594 mbedtls_free( rsa );
Gilles Peskine20035e32018-02-03 22:44:14 +01003595 }
3596 else
John Durkop6ba40d12020-11-10 08:50:04 -08003597#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3598 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine8e338702019-07-30 20:06:31 +02003599 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01003600 {
John Durkop9814fa22020-11-04 12:28:15 -08003601#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3602 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea05219c2018-11-16 16:02:56 +01003603 if(
John Durkop0ea39e02020-10-13 19:58:20 -07003604#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea05219c2018-11-16 16:02:56 +01003605 PSA_ALG_IS_ECDSA( alg )
3606#else
3607 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
3608#endif
3609 )
Steven Cooremanacda8342020-07-24 23:09:52 +02003610 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003611 mbedtls_ecp_keypair *ecp = NULL;
Ronald Cron90857082020-11-25 14:58:33 +01003612 status = mbedtls_psa_ecp_load_representation( slot->attr.type,
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +01003613 slot->attr.bits,
Ronald Cron90857082020-11-25 14:58:33 +01003614 slot->key.data,
3615 slot->key.bytes,
3616 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02003617 if( status != PSA_SUCCESS )
3618 goto exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02003619 status = psa_ecdsa_sign( ecp,
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003620 alg,
3621 hash, hash_length,
3622 signature, signature_size,
3623 signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02003624 mbedtls_ecp_keypair_free( ecp );
3625 mbedtls_free( ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02003626 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003627 else
John Durkop9814fa22020-11-04 12:28:15 -08003628#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3629 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003630 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003631 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003632 }
itayzafrir5c753392018-05-08 11:18:38 +03003633 }
3634 else
itayzafrir5c753392018-05-08 11:18:38 +03003635 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003636 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01003637 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003638
3639exit:
3640 /* Fill the unused part of the output buffer (the whole buffer on error,
3641 * the trailing part on success) with something that isn't a valid mac
3642 * (barring an attack on the mac and deliberately-crafted input),
3643 * in case the caller doesn't check the return status properly. */
3644 if( status == PSA_SUCCESS )
3645 memset( signature + *signature_length, '!',
3646 signature_size - *signature_length );
Gilles Peskine4019f0e2019-09-12 22:05:59 +02003647 else
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003648 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02003649 /* If signature_size is 0 then we have nothing to do. We must not call
3650 * memset because signature may be NULL in this case. */
Ronald Cronf95a2b12020-10-22 15:24:49 +02003651
Ronald Cron5c522922020-11-14 16:35:34 +01003652 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003653
Ronald Cron5c522922020-11-14 16:35:34 +01003654 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
itayzafrir5c753392018-05-08 11:18:38 +03003655}
3656
Ronald Croncf56a0a2020-08-04 09:51:30 +02003657psa_status_t psa_verify_hash( mbedtls_svc_key_id_t key,
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003658 psa_algorithm_t alg,
3659 const uint8_t *hash,
3660 size_t hash_length,
3661 const uint8_t *signature,
3662 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03003663{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003664 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003665 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003666 psa_key_slot_t *slot;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003667
Ronald Cron5c522922020-11-14 16:35:34 +01003668 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
3669 PSA_KEY_USAGE_VERIFY_HASH,
3670 alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003671 if( status != PSA_SUCCESS )
3672 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03003673
Steven Cooreman55ae2172020-07-17 19:46:15 +02003674 /* Try any of the available accelerators first */
3675 status = psa_driver_wrapper_verify_hash( slot,
3676 alg,
3677 hash,
3678 hash_length,
3679 signature,
3680 signature_length );
Steven Cooreman8d2bde72020-09-04 13:06:39 +02003681 if( status != PSA_ERROR_NOT_SUPPORTED ||
3682 psa_key_lifetime_is_external( slot->attr.lifetime ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003683 goto exit;
Steven Cooreman55ae2172020-07-17 19:46:15 +02003684
John Durkop6ba40d12020-11-10 08:50:04 -08003685#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3686 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8e338702019-07-30 20:06:31 +02003687 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003688 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003689 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02003690
Ronald Cron90857082020-11-25 14:58:33 +01003691 status = mbedtls_psa_rsa_load_representation( slot->attr.type,
3692 slot->key.data,
3693 slot->key.bytes,
3694 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02003695 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003696 goto exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02003697
Steven Cooremana2371e52020-07-28 14:30:39 +02003698 status = psa_rsa_verify( rsa,
Steven Cooremana01795d2020-07-24 22:48:15 +02003699 alg,
3700 hash, hash_length,
3701 signature, signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02003702 mbedtls_rsa_free( rsa );
3703 mbedtls_free( rsa );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003704 goto exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003705 }
3706 else
John Durkop6ba40d12020-11-10 08:50:04 -08003707#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3708 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine8e338702019-07-30 20:06:31 +02003709 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
itayzafrir5c753392018-05-08 11:18:38 +03003710 {
John Durkop9814fa22020-11-04 12:28:15 -08003711#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3712 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003713 if( PSA_ALG_IS_ECDSA( alg ) )
Steven Cooremanacda8342020-07-24 23:09:52 +02003714 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003715 mbedtls_ecp_keypair *ecp = NULL;
Ronald Cron90857082020-11-25 14:58:33 +01003716 status = mbedtls_psa_ecp_load_representation( slot->attr.type,
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +01003717 slot->attr.bits,
Ronald Cron90857082020-11-25 14:58:33 +01003718 slot->key.data,
3719 slot->key.bytes,
3720 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02003721 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003722 goto exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02003723 status = psa_ecdsa_verify( ecp,
Steven Cooremanacda8342020-07-24 23:09:52 +02003724 hash, hash_length,
3725 signature, signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02003726 mbedtls_ecp_keypair_free( ecp );
3727 mbedtls_free( ecp );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003728 goto exit;
Steven Cooremanacda8342020-07-24 23:09:52 +02003729 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003730 else
John Durkop9814fa22020-11-04 12:28:15 -08003731#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3732 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003733 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02003734 status = PSA_ERROR_INVALID_ARGUMENT;
3735 goto exit;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003736 }
itayzafrir5c753392018-05-08 11:18:38 +03003737 }
Gilles Peskine20035e32018-02-03 22:44:14 +01003738 else
Gilles Peskine20035e32018-02-03 22:44:14 +01003739 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02003740 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01003741 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02003742
3743exit:
Ronald Cron5c522922020-11-14 16:35:34 +01003744 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003745
Ronald Cron5c522922020-11-14 16:35:34 +01003746 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine20035e32018-02-03 22:44:14 +01003747}
3748
John Durkop0e005192020-10-31 22:06:54 -07003749#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine072ac562018-06-30 00:21:29 +02003750static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
3751 mbedtls_rsa_context *rsa )
3752{
3753 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
3754 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
3755 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
3756 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3757}
John Durkop0e005192020-10-31 22:06:54 -07003758#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Gilles Peskine072ac562018-06-30 00:21:29 +02003759
Ronald Croncf56a0a2020-08-04 09:51:30 +02003760psa_status_t psa_asymmetric_encrypt( mbedtls_svc_key_id_t key,
Gilles Peskine61b91d42018-06-08 16:09:36 +02003761 psa_algorithm_t alg,
3762 const uint8_t *input,
3763 size_t input_length,
3764 const uint8_t *salt,
3765 size_t salt_length,
3766 uint8_t *output,
3767 size_t output_size,
3768 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003769{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003770 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003771 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003772 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003773
Darryl Green5cc689a2018-07-24 15:34:10 +01003774 (void) input;
3775 (void) input_length;
3776 (void) salt;
3777 (void) output;
3778 (void) output_size;
3779
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03003780 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003781
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02003782 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
3783 return( PSA_ERROR_INVALID_ARGUMENT );
3784
Ronald Cron5c522922020-11-14 16:35:34 +01003785 status = psa_get_and_lock_transparent_key_slot_with_policy(
3786 key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003787 if( status != PSA_SUCCESS )
3788 return( status );
Gilles Peskine8e338702019-07-30 20:06:31 +02003789 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) ||
3790 PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003791 {
3792 status = PSA_ERROR_INVALID_ARGUMENT;
3793 goto exit;
3794 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003795
John Durkop6ba40d12020-11-10 08:50:04 -08003796#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
3797 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine8e338702019-07-30 20:06:31 +02003798 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003799 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003800 mbedtls_rsa_context *rsa = NULL;
Ronald Cron90857082020-11-25 14:58:33 +01003801 status = mbedtls_psa_rsa_load_representation( slot->attr.type,
3802 slot->key.data,
3803 slot->key.bytes,
3804 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02003805 if( status != PSA_SUCCESS )
Steven Cooreman4fed4552020-08-03 14:46:03 +02003806 goto rsa_exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02003807
3808 if( output_size < mbedtls_rsa_get_len( rsa ) )
Steven Cooremana01795d2020-07-24 22:48:15 +02003809 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003810 status = PSA_ERROR_BUFFER_TOO_SMALL;
3811 goto rsa_exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02003812 }
John Durkop0e005192020-10-31 22:06:54 -07003813#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
Gilles Peskine6afe7892018-05-31 13:16:08 +02003814 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003815 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003816 status = mbedtls_to_psa_error(
3817 mbedtls_rsa_pkcs1_encrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003818 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003819 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02003820 MBEDTLS_RSA_PUBLIC,
3821 input_length,
3822 input,
3823 output ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003824 }
3825 else
John Durkop0e005192020-10-31 22:06:54 -07003826#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
3827#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02003828 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003829 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003830 psa_rsa_oaep_set_padding_mode( alg, rsa );
Steven Cooreman4fed4552020-08-03 14:46:03 +02003831 status = mbedtls_to_psa_error(
3832 mbedtls_rsa_rsaes_oaep_encrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003833 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003834 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02003835 MBEDTLS_RSA_PUBLIC,
3836 salt, salt_length,
3837 input_length,
3838 input,
3839 output ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003840 }
3841 else
John Durkop0e005192020-10-31 22:06:54 -07003842#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003843 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003844 status = PSA_ERROR_INVALID_ARGUMENT;
3845 goto rsa_exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003846 }
Steven Cooreman4fed4552020-08-03 14:46:03 +02003847rsa_exit:
3848 if( status == PSA_SUCCESS )
Steven Cooremana2371e52020-07-28 14:30:39 +02003849 *output_length = mbedtls_rsa_get_len( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02003850
Steven Cooremana2371e52020-07-28 14:30:39 +02003851 mbedtls_rsa_free( rsa );
3852 mbedtls_free( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003853 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003854 else
John Durkop9814fa22020-11-04 12:28:15 -08003855#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
John Durkop6ba40d12020-11-10 08:50:04 -08003856 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003857 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02003858 status = PSA_ERROR_NOT_SUPPORTED;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003859 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02003860
3861exit:
Ronald Cron5c522922020-11-14 16:35:34 +01003862 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003863
Ronald Cron5c522922020-11-14 16:35:34 +01003864 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003865}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003866
Ronald Croncf56a0a2020-08-04 09:51:30 +02003867psa_status_t psa_asymmetric_decrypt( mbedtls_svc_key_id_t key,
Gilles Peskine61b91d42018-06-08 16:09:36 +02003868 psa_algorithm_t alg,
3869 const uint8_t *input,
3870 size_t input_length,
3871 const uint8_t *salt,
3872 size_t salt_length,
3873 uint8_t *output,
3874 size_t output_size,
3875 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003876{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003877 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003878 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003879 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003880
Darryl Green5cc689a2018-07-24 15:34:10 +01003881 (void) input;
3882 (void) input_length;
3883 (void) salt;
3884 (void) output;
3885 (void) output_size;
3886
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03003887 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003888
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02003889 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
3890 return( PSA_ERROR_INVALID_ARGUMENT );
3891
Ronald Cron5c522922020-11-14 16:35:34 +01003892 status = psa_get_and_lock_transparent_key_slot_with_policy(
3893 key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003894 if( status != PSA_SUCCESS )
3895 return( status );
Gilles Peskine8e338702019-07-30 20:06:31 +02003896 if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003897 {
3898 status = PSA_ERROR_INVALID_ARGUMENT;
3899 goto exit;
3900 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003901
John Durkop6ba40d12020-11-10 08:50:04 -08003902#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
3903 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine8e338702019-07-30 20:06:31 +02003904 if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003905 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003906 mbedtls_rsa_context *rsa = NULL;
Ronald Cron90857082020-11-25 14:58:33 +01003907 status = mbedtls_psa_rsa_load_representation( slot->attr.type,
3908 slot->key.data,
3909 slot->key.bytes,
3910 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02003911 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003912 goto exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003913
Steven Cooremana2371e52020-07-28 14:30:39 +02003914 if( input_length != mbedtls_rsa_get_len( rsa ) )
Steven Cooremana01795d2020-07-24 22:48:15 +02003915 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003916 status = PSA_ERROR_INVALID_ARGUMENT;
3917 goto rsa_exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02003918 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003919
John Durkop0e005192020-10-31 22:06:54 -07003920#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
Gilles Peskine6afe7892018-05-31 13:16:08 +02003921 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003922 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003923 status = mbedtls_to_psa_error(
3924 mbedtls_rsa_pkcs1_decrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003925 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003926 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02003927 MBEDTLS_RSA_PRIVATE,
3928 output_length,
3929 input,
3930 output,
3931 output_size ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003932 }
3933 else
John Durkop0e005192020-10-31 22:06:54 -07003934#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
3935#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02003936 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003937 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003938 psa_rsa_oaep_set_padding_mode( alg, rsa );
Steven Cooreman4fed4552020-08-03 14:46:03 +02003939 status = mbedtls_to_psa_error(
3940 mbedtls_rsa_rsaes_oaep_decrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003941 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003942 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02003943 MBEDTLS_RSA_PRIVATE,
3944 salt, salt_length,
3945 output_length,
3946 input,
3947 output,
3948 output_size ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003949 }
3950 else
John Durkop0e005192020-10-31 22:06:54 -07003951#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003952 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003953 status = PSA_ERROR_INVALID_ARGUMENT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003954 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03003955
Steven Cooreman4fed4552020-08-03 14:46:03 +02003956rsa_exit:
Steven Cooremana2371e52020-07-28 14:30:39 +02003957 mbedtls_rsa_free( rsa );
3958 mbedtls_free( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003959 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003960 else
John Durkop6ba40d12020-11-10 08:50:04 -08003961#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
3962 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003963 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02003964 status = PSA_ERROR_NOT_SUPPORTED;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003965 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02003966
3967exit:
Ronald Cron5c522922020-11-14 16:35:34 +01003968 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003969
Ronald Cron5c522922020-11-14 16:35:34 +01003970 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003971}
Gilles Peskine20035e32018-02-03 22:44:14 +01003972
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003973
3974
mohammad1603503973b2018-03-12 15:59:30 +02003975/****************************************************************/
3976/* Symmetric cryptography */
3977/****************************************************************/
3978
Gilles Peskinee553c652018-06-04 16:22:46 +02003979static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02003980 mbedtls_svc_key_id_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02003981 psa_algorithm_t alg,
3982 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02003983{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003984 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003985 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003986 int ret = 0;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003987 psa_key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02003988 size_t key_bits;
3989 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003990 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
3991 PSA_KEY_USAGE_ENCRYPT :
3992 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02003993
Steven Cooremand3feccd2020-09-01 15:56:14 +02003994 /* A context must be freshly initialized before it can be set up. */
3995 if( operation->alg != 0 )
3996 return( PSA_ERROR_BAD_STATE );
3997
Steven Cooremana07b9972020-09-10 14:54:14 +02003998 /* The requested algorithm must be one that can be processed by cipher. */
3999 if( ! PSA_ALG_IS_CIPHER( alg ) )
Steven Cooremana07b9972020-09-10 14:54:14 +02004000 return( PSA_ERROR_INVALID_ARGUMENT );
Steven Cooremand3feccd2020-09-01 15:56:14 +02004001
Steven Cooremanef8575e2020-09-11 11:44:50 +02004002 /* Fetch key material from key storage. */
Ronald Cron5c522922020-11-14 16:35:34 +01004003 status = psa_get_and_lock_key_slot_with_policy( key, &slot, usage, alg );
Steven Cooremanef8575e2020-09-11 11:44:50 +02004004 if( status != PSA_SUCCESS )
4005 goto exit;
4006
4007 /* Initialize the operation struct members, except for alg. The alg member
4008 * is used to indicate to psa_cipher_abort that there are resources to free,
4009 * so we only set it after resources have been allocated/initialized. */
Steven Cooremana07b9972020-09-10 14:54:14 +02004010 operation->key_set = 0;
4011 operation->iv_set = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004012 operation->mbedtls_in_use = 0;
Steven Cooremana07b9972020-09-10 14:54:14 +02004013 operation->iv_size = 0;
4014 operation->block_size = 0;
4015 if( alg == PSA_ALG_ECB_NO_PADDING )
4016 operation->iv_required = 0;
4017 else
4018 operation->iv_required = 1;
4019
Steven Cooremana07b9972020-09-10 14:54:14 +02004020 /* Try doing the operation through a driver before using software fallback. */
Steven Cooreman37941cb2020-07-28 18:49:51 +02004021 if( cipher_operation == MBEDTLS_ENCRYPT )
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004022 status = psa_driver_wrapper_cipher_encrypt_setup( &operation->ctx.driver,
Steven Cooreman37941cb2020-07-28 18:49:51 +02004023 slot,
4024 alg );
4025 else
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004026 status = psa_driver_wrapper_cipher_decrypt_setup( &operation->ctx.driver,
Steven Cooreman37941cb2020-07-28 18:49:51 +02004027 slot,
4028 alg );
4029
Steven Cooremanef8575e2020-09-11 11:44:50 +02004030 if( status == PSA_SUCCESS )
Steven Cooreman6d81f7e2020-09-14 13:14:31 +02004031 {
Steven Cooremanef8575e2020-09-11 11:44:50 +02004032 /* Once the driver context is initialised, it needs to be freed using
4033 * psa_cipher_abort. Indicate this through setting alg. */
4034 operation->alg = alg;
Steven Cooreman6d81f7e2020-09-14 13:14:31 +02004035 }
Steven Cooremanef8575e2020-09-11 11:44:50 +02004036
Steven Cooremand3feccd2020-09-01 15:56:14 +02004037 if( status != PSA_ERROR_NOT_SUPPORTED ||
4038 psa_key_lifetime_is_external( slot->attr.lifetime ) )
4039 goto exit;
4040
Steven Cooremana07b9972020-09-10 14:54:14 +02004041 /* Proceed with initializing an mbed TLS cipher context if no driver is
Steven Cooremand3feccd2020-09-01 15:56:14 +02004042 * available for the given algorithm & key. */
4043 mbedtls_cipher_init( &operation->ctx.cipher );
mohammad1603503973b2018-03-12 15:59:30 +02004044
Steven Cooremana07b9972020-09-10 14:54:14 +02004045 /* Once the cipher context is initialised, it needs to be freed using
Steven Cooremanef8575e2020-09-11 11:44:50 +02004046 * psa_cipher_abort. Indicate there is something to be freed through setting
4047 * alg, and indicate the operation is being done using mbedtls crypto through
4048 * setting mbedtls_in_use. */
Steven Cooremana07b9972020-09-10 14:54:14 +02004049 operation->alg = alg;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004050 operation->mbedtls_in_use = 1;
Steven Cooremana07b9972020-09-10 14:54:14 +02004051
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02004052 key_bits = psa_get_key_slot_bits( slot );
Gilles Peskine8e338702019-07-30 20:06:31 +02004053 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->attr.type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02004054 if( cipher_info == NULL )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004055 {
4056 status = PSA_ERROR_NOT_SUPPORTED;
4057 goto exit;
4058 }
mohammad1603503973b2018-03-12 15:59:30 +02004059
mohammad1603503973b2018-03-12 15:59:30 +02004060 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03004061 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004062 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004063
David Brown12ca5032021-02-11 11:02:00 -07004064#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskine8e338702019-07-30 20:06:31 +02004065 if( slot->attr.type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004066 {
4067 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02004068 uint8_t keys[24];
Ronald Cronea0f8a62020-11-25 17:52:23 +01004069 memcpy( keys, slot->key.data, 16 );
4070 memcpy( keys + 16, slot->key.data, 8 );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004071 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
4072 keys,
4073 192, cipher_operation );
4074 }
4075 else
4076#endif
4077 {
4078 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
Ronald Cronea0f8a62020-11-25 17:52:23 +01004079 slot->key.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004080 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004081 }
Moran Peker41deec42018-04-04 15:43:05 +03004082 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004083 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004084
David Brown63ca2602021-01-26 11:51:12 -07004085#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
4086 defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004087 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02004088 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004089 case PSA_ALG_CBC_NO_PADDING:
4090 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
4091 MBEDTLS_PADDING_NONE );
4092 break;
4093 case PSA_ALG_CBC_PKCS7:
4094 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
4095 MBEDTLS_PADDING_PKCS7 );
4096 break;
4097 default:
4098 /* The algorithm doesn't involve padding. */
4099 ret = 0;
4100 break;
4101 }
4102 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004103 goto exit;
David Brown288a96e2021-02-09 16:27:55 -07004104#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING || MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
mohammad16038481e742018-03-18 13:57:31 +02004105
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004106 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
gabor-mezei-armcbcec212020-12-18 14:23:51 +01004107 PSA_BLOCK_CIPHER_BLOCK_LENGTH( slot->attr.type ) );
Steven Cooremana6033e92020-08-25 11:47:50 +02004108 if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 &&
4109 alg != PSA_ALG_ECB_NO_PADDING )
mohammad16038481e742018-03-18 13:57:31 +02004110 {
gabor-mezei-armcbcec212020-12-18 14:23:51 +01004111 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( slot->attr.type );
mohammad16038481e742018-03-18 13:57:31 +02004112 }
David Brown1bfe4d72021-02-16 12:54:35 -07004113#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
Gilles Peskine26869f22019-05-06 15:25:00 +02004114 else
Bence Szépkúticbe39532020-12-08 00:01:31 +01004115 if( alg == PSA_ALG_STREAM_CIPHER && slot->attr.type == PSA_KEY_TYPE_CHACHA20 )
Gilles Peskine26869f22019-05-06 15:25:00 +02004116 operation->iv_size = 12;
4117#endif
mohammad1603503973b2018-03-12 15:59:30 +02004118
Steven Cooreman7df02922020-09-09 15:28:49 +02004119 status = PSA_SUCCESS;
4120
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004121exit:
Steven Cooreman7df02922020-09-09 15:28:49 +02004122 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004123 status = mbedtls_to_psa_error( ret );
Steven Cooreman7df02922020-09-09 15:28:49 +02004124 if( status == PSA_SUCCESS )
4125 {
4126 /* Update operation flags for both driver and software implementations */
4127 operation->key_set = 1;
4128 }
4129 else
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004130 psa_cipher_abort( operation );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004131
Ronald Cron5c522922020-11-14 16:35:34 +01004132 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004133
Ronald Cron5c522922020-11-14 16:35:34 +01004134 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
mohammad1603503973b2018-03-12 15:59:30 +02004135}
4136
Gilles Peskinefe119512018-07-08 21:39:34 +02004137psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004138 mbedtls_svc_key_id_t key,
Gilles Peskinefe119512018-07-08 21:39:34 +02004139 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02004140{
Ronald Croncf56a0a2020-08-04 09:51:30 +02004141 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02004142}
4143
Gilles Peskinefe119512018-07-08 21:39:34 +02004144psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004145 mbedtls_svc_key_id_t key,
Gilles Peskinefe119512018-07-08 21:39:34 +02004146 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02004147{
Ronald Croncf56a0a2020-08-04 09:51:30 +02004148 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02004149}
4150
Gilles Peskinefe119512018-07-08 21:39:34 +02004151psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004152 uint8_t *iv,
Gilles Peskinefe119512018-07-08 21:39:34 +02004153 size_t iv_size,
4154 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02004155{
itayzafrir534bd7c2018-08-02 13:56:32 +03004156 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00004157 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooreman7df02922020-09-09 15:28:49 +02004158 if( operation->iv_set || ! operation->iv_required )
4159 {
4160 return( PSA_ERROR_BAD_STATE );
4161 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004162
Steven Cooremanef8575e2020-09-11 11:44:50 +02004163 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004164 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004165 status = psa_driver_wrapper_cipher_generate_iv( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004166 iv,
4167 iv_size,
4168 iv_length );
4169 goto exit;
4170 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004171
Moran Peker41deec42018-04-04 15:43:05 +03004172 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02004173 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004174 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03004175 goto exit;
4176 }
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004177 ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004178 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03004179 if( ret != 0 )
4180 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004181 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02004182 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004183 }
Gilles Peskinee553c652018-06-04 16:22:46 +02004184
mohammad16038481e742018-03-18 13:57:31 +02004185 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03004186 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03004187
Moran Peker395db872018-05-31 14:07:14 +03004188exit:
Steven Cooreman7df02922020-09-09 15:28:49 +02004189 if( status == PSA_SUCCESS )
4190 operation->iv_set = 1;
4191 else
Moran Peker395db872018-05-31 14:07:14 +03004192 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004193 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004194}
4195
Gilles Peskinefe119512018-07-08 21:39:34 +02004196psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004197 const uint8_t *iv,
Gilles Peskinefe119512018-07-08 21:39:34 +02004198 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02004199{
itayzafrir534bd7c2018-08-02 13:56:32 +03004200 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00004201 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooreman7df02922020-09-09 15:28:49 +02004202 if( operation->iv_set || ! operation->iv_required )
4203 {
4204 return( PSA_ERROR_BAD_STATE );
4205 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004206
Steven Cooremanef8575e2020-09-11 11:44:50 +02004207 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004208 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004209 status = psa_driver_wrapper_cipher_set_iv( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004210 iv,
4211 iv_length );
4212 goto exit;
4213 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004214
Moran Pekera28258c2018-05-29 16:25:04 +03004215 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03004216 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004217 status = PSA_ERROR_INVALID_ARGUMENT;
4218 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03004219 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004220 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
4221 status = mbedtls_to_psa_error( ret );
4222exit:
4223 if( status == PSA_SUCCESS )
4224 operation->iv_set = 1;
4225 else
mohammad1603503973b2018-03-12 15:59:30 +02004226 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004227 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004228}
4229
Steven Cooreman177deba2020-09-07 17:14:14 +02004230/* Process input for which the algorithm is set to ECB mode. This requires
4231 * manual processing, since the PSA API is defined as being able to process
4232 * arbitrary-length calls to psa_cipher_update() with ECB mode, but the
4233 * underlying mbedtls_cipher_update only takes full blocks. */
4234static psa_status_t psa_cipher_update_ecb_internal(
4235 mbedtls_cipher_context_t *ctx,
4236 const uint8_t *input,
4237 size_t input_length,
4238 uint8_t *output,
4239 size_t output_size,
4240 size_t *output_length )
4241{
4242 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4243 size_t block_size = ctx->cipher_info->block_size;
4244 size_t internal_output_length = 0;
4245 *output_length = 0;
4246
4247 if( input_length == 0 )
4248 {
4249 status = PSA_SUCCESS;
4250 goto exit;
4251 }
4252
4253 if( ctx->unprocessed_len > 0 )
4254 {
4255 /* Fill up to block size, and run the block if there's a full one. */
4256 size_t bytes_to_copy = block_size - ctx->unprocessed_len;
4257
4258 if( input_length < bytes_to_copy )
4259 bytes_to_copy = input_length;
4260
4261 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
4262 input, bytes_to_copy );
4263 input_length -= bytes_to_copy;
4264 input += bytes_to_copy;
4265 ctx->unprocessed_len += bytes_to_copy;
4266
4267 if( ctx->unprocessed_len == block_size )
4268 {
4269 status = mbedtls_to_psa_error(
4270 mbedtls_cipher_update( ctx,
4271 ctx->unprocessed_data,
4272 block_size,
4273 output, &internal_output_length ) );
4274
4275 if( status != PSA_SUCCESS )
4276 goto exit;
4277
4278 output += internal_output_length;
4279 output_size -= internal_output_length;
4280 *output_length += internal_output_length;
4281 ctx->unprocessed_len = 0;
4282 }
4283 }
4284
4285 while( input_length >= block_size )
4286 {
4287 /* Run all full blocks we have, one by one */
4288 status = mbedtls_to_psa_error(
4289 mbedtls_cipher_update( ctx, input,
4290 block_size,
4291 output, &internal_output_length ) );
4292
4293 if( status != PSA_SUCCESS )
4294 goto exit;
4295
4296 input_length -= block_size;
4297 input += block_size;
4298
4299 output += internal_output_length;
4300 output_size -= internal_output_length;
4301 *output_length += internal_output_length;
4302 }
4303
4304 if( input_length > 0 )
4305 {
4306 /* Save unprocessed bytes for later processing */
4307 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
4308 input, input_length );
4309 ctx->unprocessed_len += input_length;
4310 }
4311
4312 status = PSA_SUCCESS;
4313
4314exit:
4315 return( status );
4316}
4317
Gilles Peskinee553c652018-06-04 16:22:46 +02004318psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
4319 const uint8_t *input,
4320 size_t input_length,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004321 uint8_t *output,
Gilles Peskinee553c652018-06-04 16:22:46 +02004322 size_t output_size,
4323 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02004324{
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004325 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine89d789c2018-06-04 17:17:16 +02004326 size_t expected_output_size;
Steven Cooreman7df02922020-09-09 15:28:49 +02004327 if( operation->alg == 0 )
4328 {
4329 return( PSA_ERROR_BAD_STATE );
4330 }
4331 if( operation->iv_required && ! operation->iv_set )
4332 {
4333 return( PSA_ERROR_BAD_STATE );
4334 }
Jaeden Ameroab439972019-02-15 14:12:05 +00004335
Steven Cooremanef8575e2020-09-11 11:44:50 +02004336 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004337 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004338 status = psa_driver_wrapper_cipher_update( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004339 input,
4340 input_length,
4341 output,
4342 output_size,
4343 output_length );
4344 goto exit;
4345 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004346
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004347 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02004348 {
4349 /* Take the unprocessed partial block left over from previous
4350 * update calls, if any, plus the input to this call. Remove
4351 * the last partial block, if any. You get the data that will be
4352 * output in this call. */
4353 expected_output_size =
4354 ( operation->ctx.cipher.unprocessed_len + input_length )
4355 / operation->block_size * operation->block_size;
4356 }
4357 else
4358 {
4359 expected_output_size = input_length;
4360 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004361
Gilles Peskine89d789c2018-06-04 17:17:16 +02004362 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03004363 {
4364 status = PSA_ERROR_BUFFER_TOO_SMALL;
4365 goto exit;
4366 }
mohammad160382759612018-03-12 18:16:40 +02004367
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004368 if( operation->alg == PSA_ALG_ECB_NO_PADDING )
4369 {
4370 /* mbedtls_cipher_update has an API inconsistency: it will only
4371 * process a single block at a time in ECB mode. Abstract away that
4372 * inconsistency here to match the PSA API behaviour. */
Steven Cooreman177deba2020-09-07 17:14:14 +02004373 status = psa_cipher_update_ecb_internal( &operation->ctx.cipher,
4374 input,
4375 input_length,
4376 output,
4377 output_size,
4378 output_length );
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004379 }
4380 else
4381 {
4382 status = mbedtls_to_psa_error(
4383 mbedtls_cipher_update( &operation->ctx.cipher, input,
4384 input_length, output, output_length ) );
4385 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004386exit:
4387 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02004388 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004389 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004390}
4391
Gilles Peskinee553c652018-06-04 16:22:46 +02004392psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
4393 uint8_t *output,
4394 size_t output_size,
4395 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02004396{
David Saadab4ecc272019-02-14 13:48:10 +02004397 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskinee553c652018-06-04 16:22:46 +02004398 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Steven Cooreman7df02922020-09-09 15:28:49 +02004399 if( operation->alg == 0 )
4400 {
4401 return( PSA_ERROR_BAD_STATE );
4402 }
4403 if( operation->iv_required && ! operation->iv_set )
4404 {
4405 return( PSA_ERROR_BAD_STATE );
4406 }
Moran Pekerbed71a22018-04-22 20:19:20 +03004407
Steven Cooremanef8575e2020-09-11 11:44:50 +02004408 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004409 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004410 status = psa_driver_wrapper_cipher_finish( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004411 output,
4412 output_size,
4413 output_length );
Steven Cooremanef8575e2020-09-11 11:44:50 +02004414 goto exit;
Steven Cooreman8b122252020-09-03 15:30:32 +02004415 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004416
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004417 if( operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03004418 {
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004419 if( operation->alg == PSA_ALG_ECB_NO_PADDING ||
Fredrik Strupef90e3012020-09-28 16:11:33 +02004420 operation->alg == PSA_ALG_CBC_NO_PADDING )
Steven Cooremana6033e92020-08-25 11:47:50 +02004421 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004422 status = PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004423 goto exit;
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004424 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004425 }
4426
Steven Cooremanef8575e2020-09-11 11:44:50 +02004427 status = mbedtls_to_psa_error(
4428 mbedtls_cipher_finish( &operation->ctx.cipher,
4429 temp_output_buffer,
4430 output_length ) );
4431 if( status != PSA_SUCCESS )
4432 goto exit;
Janos Follath315b51c2018-07-09 16:04:51 +01004433
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004434 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01004435 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004436 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004437 memcpy( output, temp_output_buffer, *output_length );
4438 else
Janos Follath315b51c2018-07-09 16:04:51 +01004439 status = PSA_ERROR_BUFFER_TOO_SMALL;
mohammad1603503973b2018-03-12 15:59:30 +02004440
Steven Cooremanef8575e2020-09-11 11:44:50 +02004441exit:
4442 if( operation->mbedtls_in_use == 1 )
4443 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01004444
Steven Cooremanef8575e2020-09-11 11:44:50 +02004445 if( status == PSA_SUCCESS )
4446 return( psa_cipher_abort( operation ) );
4447 else
4448 {
4449 *output_length = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004450 (void) psa_cipher_abort( operation );
Janos Follath315b51c2018-07-09 16:04:51 +01004451
Steven Cooremanef8575e2020-09-11 11:44:50 +02004452 return( status );
4453 }
mohammad1603503973b2018-03-12 15:59:30 +02004454}
4455
Gilles Peskinee553c652018-06-04 16:22:46 +02004456psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
4457{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004458 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02004459 {
Steven Cooremana07b9972020-09-10 14:54:14 +02004460 /* The object has (apparently) been initialized but it is not (yet)
Gilles Peskine81736312018-06-26 15:04:31 +02004461 * in use. It's ok to call abort on such an object, and there's
4462 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004463 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02004464 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004465
Gilles Peskinef9c2c092018-06-21 16:57:07 +02004466 /* Sanity check (shouldn't happen: operation->alg should
4467 * always have been initialized to a valid value). */
4468 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
4469 return( PSA_ERROR_BAD_STATE );
4470
Steven Cooremanef8575e2020-09-11 11:44:50 +02004471 if( operation->mbedtls_in_use == 0 )
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004472 psa_driver_wrapper_cipher_abort( &operation->ctx.driver );
Steven Cooremand3feccd2020-09-01 15:56:14 +02004473 else
4474 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02004475
Moran Peker41deec42018-04-04 15:43:05 +03004476 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004477 operation->key_set = 0;
4478 operation->iv_set = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004479 operation->mbedtls_in_use = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004480 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03004481 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004482 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03004483
Moran Peker395db872018-05-31 14:07:14 +03004484 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02004485}
4486
Gilles Peskinea0655c32018-04-30 17:06:50 +02004487
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004488
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004489
mohammad16035955c982018-04-26 00:53:03 +03004490/****************************************************************/
4491/* AEAD */
4492/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004493
Gilles Peskineedf9a652018-08-17 18:11:56 +02004494typedef struct
4495{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004496 psa_key_slot_t *slot;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004497 const mbedtls_cipher_info_t *cipher_info;
4498 union
4499 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004500 unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
Gilles Peskineedf9a652018-08-17 18:11:56 +02004501#if defined(MBEDTLS_CCM_C)
4502 mbedtls_ccm_context ccm;
4503#endif /* MBEDTLS_CCM_C */
4504#if defined(MBEDTLS_GCM_C)
4505 mbedtls_gcm_context gcm;
4506#endif /* MBEDTLS_GCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02004507#if defined(MBEDTLS_CHACHAPOLY_C)
4508 mbedtls_chachapoly_context chachapoly;
4509#endif /* MBEDTLS_CHACHAPOLY_C */
Gilles Peskineedf9a652018-08-17 18:11:56 +02004510 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004511 psa_algorithm_t core_alg;
4512 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004513 uint8_t tag_length;
4514} aead_operation_t;
4515
Ronald Cronf95a2b12020-10-22 15:24:49 +02004516#define AEAD_OPERATION_INIT {0, 0, {0}, 0, 0, 0}
4517
Gilles Peskine30a9e412019-01-14 18:36:12 +01004518static void psa_aead_abort_internal( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004519{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02004520 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004521 {
4522#if defined(MBEDTLS_CCM_C)
4523 case PSA_ALG_CCM:
4524 mbedtls_ccm_free( &operation->ctx.ccm );
4525 break;
4526#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004527#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02004528 case PSA_ALG_GCM:
4529 mbedtls_gcm_free( &operation->ctx.gcm );
4530 break;
4531#endif /* MBEDTLS_GCM_C */
4532 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004533
Ronald Cron5c522922020-11-14 16:35:34 +01004534 psa_unlock_key_slot( operation->slot );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004535}
4536
4537static psa_status_t psa_aead_setup( aead_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004538 mbedtls_svc_key_id_t key,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004539 psa_key_usage_t usage,
4540 psa_algorithm_t alg )
4541{
4542 psa_status_t status;
4543 size_t key_bits;
4544 mbedtls_cipher_id_t cipher_id;
4545
Ronald Cron5c522922020-11-14 16:35:34 +01004546 status = psa_get_and_lock_transparent_key_slot_with_policy(
4547 key, &operation->slot, usage, alg );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004548 if( status != PSA_SUCCESS )
4549 return( status );
4550
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02004551 key_bits = psa_get_key_slot_bits( operation->slot );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004552
4553 operation->cipher_info =
Gilles Peskine8e338702019-07-30 20:06:31 +02004554 mbedtls_cipher_info_from_psa( alg, operation->slot->attr.type, key_bits,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004555 &cipher_id );
4556 if( operation->cipher_info == NULL )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004557 {
4558 status = PSA_ERROR_NOT_SUPPORTED;
4559 goto cleanup;
4560 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004561
Bence Szépkútia63b20d2020-12-16 11:36:46 +01004562 switch( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004563 {
4564#if defined(MBEDTLS_CCM_C)
Bence Szépkútia63b20d2020-12-16 11:36:46 +01004565 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004566 operation->core_alg = PSA_ALG_CCM;
4567 operation->full_tag_length = 16;
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004568 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
4569 * The call to mbedtls_ccm_encrypt_and_tag or
4570 * mbedtls_ccm_auth_decrypt will validate the tag length. */
gabor-mezei-armcbcec212020-12-18 14:23:51 +01004571 if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( operation->slot->attr.type ) != 16 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004572 {
4573 status = PSA_ERROR_INVALID_ARGUMENT;
4574 goto cleanup;
4575 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004576 mbedtls_ccm_init( &operation->ctx.ccm );
4577 status = mbedtls_to_psa_error(
4578 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
Ronald Cronea0f8a62020-11-25 17:52:23 +01004579 operation->slot->key.data,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004580 (unsigned int) key_bits ) );
4581 if( status != 0 )
4582 goto cleanup;
4583 break;
4584#endif /* MBEDTLS_CCM_C */
4585
4586#if defined(MBEDTLS_GCM_C)
Bence Szépkútia63b20d2020-12-16 11:36:46 +01004587 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004588 operation->core_alg = PSA_ALG_GCM;
4589 operation->full_tag_length = 16;
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004590 /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
4591 * The call to mbedtls_gcm_crypt_and_tag or
4592 * mbedtls_gcm_auth_decrypt will validate the tag length. */
gabor-mezei-armcbcec212020-12-18 14:23:51 +01004593 if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( operation->slot->attr.type ) != 16 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004594 {
4595 status = PSA_ERROR_INVALID_ARGUMENT;
4596 goto cleanup;
4597 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004598 mbedtls_gcm_init( &operation->ctx.gcm );
4599 status = mbedtls_to_psa_error(
4600 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
Ronald Cronea0f8a62020-11-25 17:52:23 +01004601 operation->slot->key.data,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004602 (unsigned int) key_bits ) );
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004603 if( status != 0 )
4604 goto cleanup;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004605 break;
4606#endif /* MBEDTLS_GCM_C */
4607
Gilles Peskine26869f22019-05-06 15:25:00 +02004608#if defined(MBEDTLS_CHACHAPOLY_C)
Bence Szépkútia63b20d2020-12-16 11:36:46 +01004609 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
Gilles Peskine26869f22019-05-06 15:25:00 +02004610 operation->core_alg = PSA_ALG_CHACHA20_POLY1305;
4611 operation->full_tag_length = 16;
4612 /* We only support the default tag length. */
4613 if( alg != PSA_ALG_CHACHA20_POLY1305 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004614 {
4615 status = PSA_ERROR_NOT_SUPPORTED;
4616 goto cleanup;
4617 }
Gilles Peskine26869f22019-05-06 15:25:00 +02004618 mbedtls_chachapoly_init( &operation->ctx.chachapoly );
4619 status = mbedtls_to_psa_error(
4620 mbedtls_chachapoly_setkey( &operation->ctx.chachapoly,
Ronald Cronea0f8a62020-11-25 17:52:23 +01004621 operation->slot->key.data ) );
Gilles Peskine26869f22019-05-06 15:25:00 +02004622 if( status != 0 )
4623 goto cleanup;
4624 break;
4625#endif /* MBEDTLS_CHACHAPOLY_C */
4626
Gilles Peskineedf9a652018-08-17 18:11:56 +02004627 default:
Ronald Cronf95a2b12020-10-22 15:24:49 +02004628 status = PSA_ERROR_NOT_SUPPORTED;
4629 goto cleanup;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004630 }
4631
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004632 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
4633 {
4634 status = PSA_ERROR_INVALID_ARGUMENT;
4635 goto cleanup;
4636 }
4637 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004638
Gilles Peskineedf9a652018-08-17 18:11:56 +02004639 return( PSA_SUCCESS );
4640
4641cleanup:
Gilles Peskine30a9e412019-01-14 18:36:12 +01004642 psa_aead_abort_internal( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004643 return( status );
4644}
4645
Ronald Croncf56a0a2020-08-04 09:51:30 +02004646psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key,
mohammad16035955c982018-04-26 00:53:03 +03004647 psa_algorithm_t alg,
4648 const uint8_t *nonce,
4649 size_t nonce_length,
4650 const uint8_t *additional_data,
4651 size_t additional_data_length,
4652 const uint8_t *plaintext,
4653 size_t plaintext_length,
4654 uint8_t *ciphertext,
4655 size_t ciphertext_size,
4656 size_t *ciphertext_length )
4657{
mohammad16035955c982018-04-26 00:53:03 +03004658 psa_status_t status;
Ronald Cronf95a2b12020-10-22 15:24:49 +02004659 aead_operation_t operation = AEAD_OPERATION_INIT;
mohammad160315223a82018-06-03 17:19:55 +03004660 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02004661
mohammad1603f08a5502018-06-03 15:05:47 +03004662 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07004663
Ronald Croncf56a0a2020-08-04 09:51:30 +02004664 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004665 if( status != PSA_SUCCESS )
4666 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004667
Gilles Peskineedf9a652018-08-17 18:11:56 +02004668 /* For all currently supported modes, the tag is at the end of the
4669 * ciphertext. */
4670 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
4671 {
4672 status = PSA_ERROR_BUFFER_TOO_SMALL;
4673 goto exit;
4674 }
4675 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03004676
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004677#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004678 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03004679 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004680 status = mbedtls_to_psa_error(
4681 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
4682 MBEDTLS_GCM_ENCRYPT,
4683 plaintext_length,
4684 nonce, nonce_length,
4685 additional_data, additional_data_length,
4686 plaintext, ciphertext,
4687 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03004688 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004689 else
4690#endif /* MBEDTLS_GCM_C */
4691#if defined(MBEDTLS_CCM_C)
4692 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03004693 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004694 status = mbedtls_to_psa_error(
4695 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
4696 plaintext_length,
4697 nonce, nonce_length,
4698 additional_data,
4699 additional_data_length,
4700 plaintext, ciphertext,
4701 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03004702 }
mohammad16035c8845f2018-05-09 05:40:09 -07004703 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004704#endif /* MBEDTLS_CCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02004705#if defined(MBEDTLS_CHACHAPOLY_C)
4706 if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
4707 {
4708 if( nonce_length != 12 || operation.tag_length != 16 )
4709 {
4710 status = PSA_ERROR_NOT_SUPPORTED;
4711 goto exit;
4712 }
4713 status = mbedtls_to_psa_error(
4714 mbedtls_chachapoly_encrypt_and_tag( &operation.ctx.chachapoly,
4715 plaintext_length,
4716 nonce,
4717 additional_data,
4718 additional_data_length,
4719 plaintext,
4720 ciphertext,
4721 tag ) );
4722 }
4723 else
4724#endif /* MBEDTLS_CHACHAPOLY_C */
mohammad16035c8845f2018-05-09 05:40:09 -07004725 {
Steven Cooreman7196fef2021-02-10 17:13:28 +01004726 (void) tag;
mohammad1603554faad2018-06-03 15:07:38 +03004727 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07004728 }
Gilles Peskine2d277862018-06-18 15:41:12 +02004729
Gilles Peskineedf9a652018-08-17 18:11:56 +02004730 if( status != PSA_SUCCESS && ciphertext_size != 0 )
4731 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02004732
Gilles Peskineedf9a652018-08-17 18:11:56 +02004733exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01004734 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004735 if( status == PSA_SUCCESS )
4736 *ciphertext_length = plaintext_length + operation.tag_length;
4737 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004738}
4739
Gilles Peskineee652a32018-06-01 19:23:52 +02004740/* Locate the tag in a ciphertext buffer containing the encrypted data
4741 * followed by the tag. Return the length of the part preceding the tag in
4742 * *plaintext_length. This is the size of the plaintext in modes where
4743 * the encrypted data has the same size as the plaintext, such as
4744 * CCM and GCM. */
4745static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
4746 const uint8_t *ciphertext,
4747 size_t ciphertext_length,
4748 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02004749 const uint8_t **p_tag )
4750{
4751 size_t payload_length;
4752 if( tag_length > ciphertext_length )
4753 return( PSA_ERROR_INVALID_ARGUMENT );
4754 payload_length = ciphertext_length - tag_length;
4755 if( payload_length > plaintext_size )
4756 return( PSA_ERROR_BUFFER_TOO_SMALL );
4757 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02004758 return( PSA_SUCCESS );
4759}
4760
Ronald Croncf56a0a2020-08-04 09:51:30 +02004761psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key,
mohammad16035955c982018-04-26 00:53:03 +03004762 psa_algorithm_t alg,
4763 const uint8_t *nonce,
4764 size_t nonce_length,
4765 const uint8_t *additional_data,
4766 size_t additional_data_length,
4767 const uint8_t *ciphertext,
4768 size_t ciphertext_length,
4769 uint8_t *plaintext,
4770 size_t plaintext_size,
4771 size_t *plaintext_length )
4772{
mohammad16035955c982018-04-26 00:53:03 +03004773 psa_status_t status;
Ronald Cronf95a2b12020-10-22 15:24:49 +02004774 aead_operation_t operation = AEAD_OPERATION_INIT;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004775 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02004776
Gilles Peskineee652a32018-06-01 19:23:52 +02004777 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03004778
Ronald Croncf56a0a2020-08-04 09:51:30 +02004779 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004780 if( status != PSA_SUCCESS )
4781 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004782
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004783 status = psa_aead_unpadded_locate_tag( operation.tag_length,
4784 ciphertext, ciphertext_length,
4785 plaintext_size, &tag );
4786 if( status != PSA_SUCCESS )
4787 goto exit;
4788
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004789#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004790 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03004791 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004792 status = mbedtls_to_psa_error(
4793 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
4794 ciphertext_length - operation.tag_length,
4795 nonce, nonce_length,
4796 additional_data,
4797 additional_data_length,
4798 tag, operation.tag_length,
4799 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03004800 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004801 else
4802#endif /* MBEDTLS_GCM_C */
4803#if defined(MBEDTLS_CCM_C)
4804 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03004805 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004806 status = mbedtls_to_psa_error(
4807 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
4808 ciphertext_length - operation.tag_length,
4809 nonce, nonce_length,
4810 additional_data,
4811 additional_data_length,
4812 ciphertext, plaintext,
4813 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03004814 }
mohammad160339574652018-06-01 04:39:53 -07004815 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004816#endif /* MBEDTLS_CCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02004817#if defined(MBEDTLS_CHACHAPOLY_C)
4818 if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
4819 {
4820 if( nonce_length != 12 || operation.tag_length != 16 )
4821 {
4822 status = PSA_ERROR_NOT_SUPPORTED;
4823 goto exit;
4824 }
4825 status = mbedtls_to_psa_error(
4826 mbedtls_chachapoly_auth_decrypt( &operation.ctx.chachapoly,
4827 ciphertext_length - operation.tag_length,
4828 nonce,
4829 additional_data,
4830 additional_data_length,
4831 tag,
4832 ciphertext,
4833 plaintext ) );
4834 }
4835 else
4836#endif /* MBEDTLS_CHACHAPOLY_C */
mohammad160339574652018-06-01 04:39:53 -07004837 {
mohammad1603554faad2018-06-03 15:07:38 +03004838 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07004839 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02004840
Gilles Peskineedf9a652018-08-17 18:11:56 +02004841 if( status != PSA_SUCCESS && plaintext_size != 0 )
4842 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03004843
Gilles Peskineedf9a652018-08-17 18:11:56 +02004844exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01004845 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004846 if( status == PSA_SUCCESS )
4847 *plaintext_length = ciphertext_length - operation.tag_length;
4848 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004849}
4850
Gilles Peskinea0655c32018-04-30 17:06:50 +02004851
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004852
Gilles Peskine20035e32018-02-03 22:44:14 +01004853/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004854/* Generators */
4855/****************************************************************/
4856
John Durkop07cc04a2020-11-16 22:08:34 -08004857#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
4858 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4859 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4860#define AT_LEAST_ONE_BUILTIN_KDF
4861#endif
4862
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004863#define HKDF_STATE_INIT 0 /* no input yet */
4864#define HKDF_STATE_STARTED 1 /* got salt */
4865#define HKDF_STATE_KEYED 2 /* got key */
4866#define HKDF_STATE_OUTPUT 3 /* output started */
4867
Gilles Peskinecbe66502019-05-16 16:59:18 +02004868static psa_algorithm_t psa_key_derivation_get_kdf_alg(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004869 const psa_key_derivation_operation_t *operation )
Gilles Peskine969c5d62019-01-16 15:53:06 +01004870{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004871 if ( PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
4872 return( PSA_ALG_KEY_AGREEMENT_GET_KDF( operation->alg ) );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004873 else
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004874 return( operation->alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004875}
4876
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004877psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004878{
4879 psa_status_t status = PSA_SUCCESS;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004880 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004881 if( kdf_alg == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004882 {
4883 /* The object has (apparently) been initialized but it is not
4884 * in use. It's ok to call abort on such an object, and there's
4885 * nothing to do. */
4886 }
4887 else
John Durkopd0321952020-10-29 21:37:36 -07004888#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01004889 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02004890 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004891 mbedtls_free( operation->ctx.hkdf.info );
4892 status = psa_hmac_abort_internal( &operation->ctx.hkdf.hmac );
Gilles Peskinebef7f142018-07-12 17:22:21 +02004893 }
John Durkop07cc04a2020-11-16 22:08:34 -08004894 else
4895#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF */
4896#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4897 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4898 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004899 /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01004900 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004901 {
Janos Follath6a1d2622019-06-11 10:37:28 +01004902 if( operation->ctx.tls12_prf.seed != NULL )
4903 {
4904 mbedtls_platform_zeroize( operation->ctx.tls12_prf.seed,
4905 operation->ctx.tls12_prf.seed_length );
4906 mbedtls_free( operation->ctx.tls12_prf.seed );
4907 }
4908
4909 if( operation->ctx.tls12_prf.label != NULL )
4910 {
4911 mbedtls_platform_zeroize( operation->ctx.tls12_prf.label,
4912 operation->ctx.tls12_prf.label_length );
4913 mbedtls_free( operation->ctx.tls12_prf.label );
4914 }
4915
4916 status = psa_hmac_abort_internal( &operation->ctx.tls12_prf.hmac );
4917
4918 /* We leave the fields Ai and output_block to be erased safely by the
4919 * mbedtls_platform_zeroize() in the end of this function. */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004920 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02004921 else
John Durkop07cc04a2020-11-16 22:08:34 -08004922#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
4923 * defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) */
Gilles Peskineeab56e42018-07-12 17:12:33 +02004924 {
4925 status = PSA_ERROR_BAD_STATE;
4926 }
Janos Follath083036a2019-06-11 10:22:26 +01004927 mbedtls_platform_zeroize( operation, sizeof( *operation ) );
Gilles Peskineeab56e42018-07-12 17:12:33 +02004928 return( status );
4929}
4930
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004931psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation,
Gilles Peskineeab56e42018-07-12 17:12:33 +02004932 size_t *capacity)
4933{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004934 if( operation->alg == 0 )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004935 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004936 /* This is a blank key derivation operation. */
Steven Cooreman29149862020-08-05 15:43:42 +02004937 return( PSA_ERROR_BAD_STATE );
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004938 }
4939
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004940 *capacity = operation->capacity;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004941 return( PSA_SUCCESS );
4942}
4943
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004944psa_status_t psa_key_derivation_set_capacity( psa_key_derivation_operation_t *operation,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004945 size_t capacity )
4946{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004947 if( operation->alg == 0 )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004948 return( PSA_ERROR_BAD_STATE );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004949 if( capacity > operation->capacity )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004950 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004951 operation->capacity = capacity;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004952 return( PSA_SUCCESS );
4953}
4954
John Durkopd0321952020-10-29 21:37:36 -07004955#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004956/* Read some bytes from an HKDF-based operation. This performs a chunk
Gilles Peskinebef7f142018-07-12 17:22:21 +02004957 * of the expand phase of the HKDF algorithm. */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004958static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkdf,
Gilles Peskinebef7f142018-07-12 17:22:21 +02004959 psa_algorithm_t hash_alg,
4960 uint8_t *output,
4961 size_t output_length )
4962{
gabor-mezei-armcbcec212020-12-18 14:23:51 +01004963 uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
Gilles Peskinebef7f142018-07-12 17:22:21 +02004964 psa_status_t status;
4965
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004966 if( hkdf->state < HKDF_STATE_KEYED || ! hkdf->info_set )
4967 return( PSA_ERROR_BAD_STATE );
4968 hkdf->state = HKDF_STATE_OUTPUT;
4969
Gilles Peskinebef7f142018-07-12 17:22:21 +02004970 while( output_length != 0 )
4971 {
4972 /* Copy what remains of the current block */
4973 uint8_t n = hash_length - hkdf->offset_in_block;
4974 if( n > output_length )
4975 n = (uint8_t) output_length;
4976 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
4977 output += n;
4978 output_length -= n;
4979 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02004980 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02004981 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02004982 /* We can't be wanting more output after block 0xff, otherwise
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004983 * the capacity check in psa_key_derivation_output_bytes() would have
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004984 * prevented this call. It could happen only if the operation
Gilles Peskined54931c2018-07-17 21:06:59 +02004985 * object was corrupted or if this function is called directly
4986 * inside the library. */
4987 if( hkdf->block_number == 0xff )
4988 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02004989
4990 /* We need a new block */
4991 ++hkdf->block_number;
4992 hkdf->offset_in_block = 0;
4993 status = psa_hmac_setup_internal( &hkdf->hmac,
4994 hkdf->prk, hash_length,
4995 hash_alg );
4996 if( status != PSA_SUCCESS )
4997 return( status );
4998 if( hkdf->block_number != 1 )
4999 {
5000 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5001 hkdf->output_block,
5002 hash_length );
5003 if( status != PSA_SUCCESS )
5004 return( status );
5005 }
5006 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5007 hkdf->info,
5008 hkdf->info_length );
5009 if( status != PSA_SUCCESS )
5010 return( status );
5011 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5012 &hkdf->block_number, 1 );
5013 if( status != PSA_SUCCESS )
5014 return( status );
5015 status = psa_hmac_finish_internal( &hkdf->hmac,
5016 hkdf->output_block,
5017 sizeof( hkdf->output_block ) );
5018 if( status != PSA_SUCCESS )
5019 return( status );
5020 }
5021
5022 return( PSA_SUCCESS );
5023}
John Durkop07cc04a2020-11-16 22:08:34 -08005024#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005025
John Durkop07cc04a2020-11-16 22:08:34 -08005026#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5027 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follath7742fee2019-06-17 12:58:10 +01005028static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
5029 psa_tls12_prf_key_derivation_t *tls12_prf,
5030 psa_algorithm_t alg )
5031{
5032 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
gabor-mezei-armcbcec212020-12-18 14:23:51 +01005033 uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
Janos Follathea29bfb2019-06-19 12:21:20 +01005034 psa_hash_operation_t backup = PSA_HASH_OPERATION_INIT;
5035 psa_status_t status, cleanup_status;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005036
Janos Follath7742fee2019-06-17 12:58:10 +01005037 /* We can't be wanting more output after block 0xff, otherwise
5038 * the capacity check in psa_key_derivation_output_bytes() would have
5039 * prevented this call. It could happen only if the operation
5040 * object was corrupted or if this function is called directly
5041 * inside the library. */
5042 if( tls12_prf->block_number == 0xff )
Janos Follath30090bc2019-06-25 10:15:04 +01005043 return( PSA_ERROR_CORRUPTION_DETECTED );
Janos Follath7742fee2019-06-17 12:58:10 +01005044
5045 /* We need a new block */
5046 ++tls12_prf->block_number;
Janos Follath844eb0e2019-06-19 12:10:49 +01005047 tls12_prf->left_in_block = hash_length;
Janos Follath7742fee2019-06-17 12:58:10 +01005048
5049 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
5050 *
5051 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
5052 *
5053 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
5054 * HMAC_hash(secret, A(2) + seed) +
5055 * HMAC_hash(secret, A(3) + seed) + ...
5056 *
5057 * A(0) = seed
Janos Follathea29bfb2019-06-19 12:21:20 +01005058 * A(i) = HMAC_hash(secret, A(i-1))
Janos Follath7742fee2019-06-17 12:58:10 +01005059 *
Janos Follathea29bfb2019-06-19 12:21:20 +01005060 * The `psa_tls12_prf_key_derivation` structure saves the block
Janos Follath7742fee2019-06-17 12:58:10 +01005061 * `HMAC_hash(secret, A(i) + seed)` from which the output
Janos Follath76c39842019-06-26 12:50:36 +01005062 * is currently extracted as `output_block` and where i is
5063 * `block_number`.
Janos Follath7742fee2019-06-17 12:58:10 +01005064 */
5065
Janos Follathea29bfb2019-06-19 12:21:20 +01005066 /* Save the hash context before using it, to preserve the hash state with
5067 * only the inner padding in it. We need this, because inner padding depends
5068 * on the key (secret in the RFC's terminology). */
5069 status = psa_hash_clone( &tls12_prf->hmac.hash_ctx, &backup );
5070 if( status != PSA_SUCCESS )
5071 goto cleanup;
5072
5073 /* Calculate A(i) where i = tls12_prf->block_number. */
5074 if( tls12_prf->block_number == 1 )
5075 {
5076 /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads
5077 * the variable seed and in this instance means it in the context of the
5078 * P_hash function, where seed = label + seed.) */
5079 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5080 tls12_prf->label, tls12_prf->label_length );
5081 if( status != PSA_SUCCESS )
5082 goto cleanup;
5083 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5084 tls12_prf->seed, tls12_prf->seed_length );
5085 if( status != PSA_SUCCESS )
5086 goto cleanup;
5087 }
5088 else
5089 {
5090 /* A(i) = HMAC_hash(secret, A(i-1)) */
5091 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5092 tls12_prf->Ai, hash_length );
5093 if( status != PSA_SUCCESS )
5094 goto cleanup;
5095 }
5096
5097 status = psa_hmac_finish_internal( &tls12_prf->hmac,
5098 tls12_prf->Ai, hash_length );
5099 if( status != PSA_SUCCESS )
5100 goto cleanup;
5101 status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
5102 if( status != PSA_SUCCESS )
5103 goto cleanup;
5104
5105 /* Calculate HMAC_hash(secret, A(i) + label + seed). */
5106 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5107 tls12_prf->Ai, hash_length );
5108 if( status != PSA_SUCCESS )
5109 goto cleanup;
5110 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5111 tls12_prf->label, tls12_prf->label_length );
5112 if( status != PSA_SUCCESS )
5113 goto cleanup;
5114 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5115 tls12_prf->seed, tls12_prf->seed_length );
5116 if( status != PSA_SUCCESS )
5117 goto cleanup;
5118 status = psa_hmac_finish_internal( &tls12_prf->hmac,
5119 tls12_prf->output_block, hash_length );
5120 if( status != PSA_SUCCESS )
5121 goto cleanup;
5122 status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
5123 if( status != PSA_SUCCESS )
5124 goto cleanup;
5125
Janos Follath7742fee2019-06-17 12:58:10 +01005126
5127cleanup:
5128
Janos Follathea29bfb2019-06-19 12:21:20 +01005129 cleanup_status = psa_hash_abort( &backup );
5130 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
5131 status = cleanup_status;
5132
5133 return( status );
Janos Follath7742fee2019-06-17 12:58:10 +01005134}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005135
Janos Follath844eb0e2019-06-19 12:10:49 +01005136static psa_status_t psa_key_derivation_tls12_prf_read(
5137 psa_tls12_prf_key_derivation_t *tls12_prf,
5138 psa_algorithm_t alg,
5139 uint8_t *output,
5140 size_t output_length )
5141{
5142 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
gabor-mezei-armcbcec212020-12-18 14:23:51 +01005143 uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
Janos Follath844eb0e2019-06-19 12:10:49 +01005144 psa_status_t status;
5145 uint8_t offset, length;
5146
5147 while( output_length != 0 )
5148 {
5149 /* Check if we have fully processed the current block. */
5150 if( tls12_prf->left_in_block == 0 )
5151 {
5152 status = psa_key_derivation_tls12_prf_generate_next_block( tls12_prf,
5153 alg );
5154 if( status != PSA_SUCCESS )
5155 return( status );
5156
5157 continue;
5158 }
5159
5160 if( tls12_prf->left_in_block > output_length )
5161 length = (uint8_t) output_length;
5162 else
5163 length = tls12_prf->left_in_block;
5164
5165 offset = hash_length - tls12_prf->left_in_block;
5166 memcpy( output, tls12_prf->output_block + offset, length );
5167 output += length;
5168 output_length -= length;
5169 tls12_prf->left_in_block -= length;
5170 }
5171
5172 return( PSA_SUCCESS );
5173}
John Durkop07cc04a2020-11-16 22:08:34 -08005174#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
5175 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskinebef7f142018-07-12 17:22:21 +02005176
Janos Follath6c6c8fc2019-06-17 12:38:20 +01005177psa_status_t psa_key_derivation_output_bytes(
5178 psa_key_derivation_operation_t *operation,
5179 uint8_t *output,
5180 size_t output_length )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005181{
5182 psa_status_t status;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005183 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005184
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005185 if( operation->alg == 0 )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005186 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005187 /* This is a blank operation. */
Steven Cooreman29149862020-08-05 15:43:42 +02005188 return( PSA_ERROR_BAD_STATE );
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005189 }
5190
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005191 if( output_length > operation->capacity )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005192 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005193 operation->capacity = 0;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005194 /* Go through the error path to wipe all confidential data now
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005195 * that the operation object is useless. */
David Saadab4ecc272019-02-14 13:48:10 +02005196 status = PSA_ERROR_INSUFFICIENT_DATA;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005197 goto exit;
5198 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005199 if( output_length == 0 && operation->capacity == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005200 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005201 /* Edge case: this is a finished operation, and 0 bytes
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005202 * were requested. The right error in this case could
Gilles Peskineeab56e42018-07-12 17:12:33 +02005203 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
5204 * INSUFFICIENT_CAPACITY, which is right for a finished
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005205 * operation, for consistency with the case when
Gilles Peskineeab56e42018-07-12 17:12:33 +02005206 * output_length > 0. */
David Saadab4ecc272019-02-14 13:48:10 +02005207 return( PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005208 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005209 operation->capacity -= output_length;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005210
John Durkopd0321952020-10-29 21:37:36 -07005211#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005212 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02005213 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01005214 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005215 status = psa_key_derivation_hkdf_read( &operation->ctx.hkdf, hash_alg,
Gilles Peskinebef7f142018-07-12 17:22:21 +02005216 output, output_length );
5217 }
Janos Follathadbec812019-06-14 11:05:39 +01005218 else
John Durkop07cc04a2020-11-16 22:08:34 -08005219#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
5220#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5221 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follathadbec812019-06-14 11:05:39 +01005222 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
John Durkop07cc04a2020-11-16 22:08:34 -08005223 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005224 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005225 status = psa_key_derivation_tls12_prf_read( &operation->ctx.tls12_prf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005226 kdf_alg, output,
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005227 output_length );
5228 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02005229 else
John Durkop07cc04a2020-11-16 22:08:34 -08005230#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
5231 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineeab56e42018-07-12 17:12:33 +02005232 {
Steven Cooreman74afe472021-02-10 17:19:22 +01005233 (void) kdf_alg;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005234 return( PSA_ERROR_BAD_STATE );
5235 }
5236
5237exit:
5238 if( status != PSA_SUCCESS )
5239 {
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005240 /* Preserve the algorithm upon errors, but clear all sensitive state.
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005241 * This allows us to differentiate between exhausted operations and
5242 * blank operations, so we can return PSA_ERROR_BAD_STATE on blank
5243 * operations. */
5244 psa_algorithm_t alg = operation->alg;
5245 psa_key_derivation_abort( operation );
5246 operation->alg = alg;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005247 memset( output, '!', output_length );
5248 }
5249 return( status );
5250}
5251
David Brown7807bf72021-02-09 16:28:23 -07005252#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskine08542d82018-07-19 17:05:42 +02005253static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
5254{
5255 if( data_size >= 8 )
5256 mbedtls_des_key_set_parity( data );
5257 if( data_size >= 16 )
5258 mbedtls_des_key_set_parity( data + 8 );
5259 if( data_size >= 24 )
5260 mbedtls_des_key_set_parity( data + 16 );
5261}
David Brown7807bf72021-02-09 16:28:23 -07005262#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
Gilles Peskine08542d82018-07-19 17:05:42 +02005263
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01005264static psa_status_t psa_generate_derived_key_internal(
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005265 psa_key_slot_t *slot,
5266 size_t bits,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005267 psa_key_derivation_operation_t *operation )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005268{
5269 uint8_t *data = NULL;
5270 size_t bytes = PSA_BITS_TO_BYTES( bits );
5271 psa_status_t status;
5272
Gilles Peskine8e338702019-07-30 20:06:31 +02005273 if( ! key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005274 return( PSA_ERROR_INVALID_ARGUMENT );
5275 if( bits % 8 != 0 )
5276 return( PSA_ERROR_INVALID_ARGUMENT );
5277 data = mbedtls_calloc( 1, bytes );
5278 if( data == NULL )
5279 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5280
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005281 status = psa_key_derivation_output_bytes( operation, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005282 if( status != PSA_SUCCESS )
5283 goto exit;
David Brown12ca5032021-02-11 11:02:00 -07005284#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskine8e338702019-07-30 20:06:31 +02005285 if( slot->attr.type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02005286 psa_des_set_key_parity( data, bytes );
David Brown8107e312021-02-12 08:08:46 -07005287#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
Ronald Crondd04d422020-11-28 15:14:42 +01005288
5289 status = psa_allocate_buffer_to_slot( slot, bytes );
5290 if( status != PSA_SUCCESS )
Paul Elliottda3e7db2021-02-09 18:58:20 +00005291 goto exit;
Ronald Crondd04d422020-11-28 15:14:42 +01005292
Ronald Cronbf33c932020-11-28 18:06:53 +01005293 slot->attr.bits = (psa_key_bits_t) bits;
Ronald Cron2ebfdcc2020-11-28 15:54:54 +01005294 psa_key_attributes_t attributes = {
5295 .core = slot->attr
5296 };
5297
Ronald Cronbf33c932020-11-28 18:06:53 +01005298 status = psa_driver_wrapper_import_key( &attributes,
5299 data, bytes,
5300 slot->key.data,
5301 slot->key.bytes,
5302 &slot->key.bytes, &bits );
5303 if( bits != slot->attr.bits )
5304 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005305
5306exit:
5307 mbedtls_free( data );
5308 return( status );
5309}
5310
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02005311psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attributes,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005312 psa_key_derivation_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02005313 mbedtls_svc_key_id_t *key )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005314{
5315 psa_status_t status;
5316 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02005317 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine0f84d622019-09-12 19:03:13 +02005318
Ronald Cron81709fc2020-11-14 12:10:32 +01005319 *key = MBEDTLS_SVC_KEY_ID_INIT;
5320
Gilles Peskine0f84d622019-09-12 19:03:13 +02005321 /* Reject any attempt to create a zero-length key so that we don't
5322 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
5323 if( psa_get_key_bits( attributes ) == 0 )
5324 return( PSA_ERROR_INVALID_ARGUMENT );
5325
Gilles Peskine178c9aa2019-09-24 18:21:06 +02005326 if( ! operation->can_output_key )
5327 return( PSA_ERROR_NOT_PERMITTED );
5328
Ronald Cron81709fc2020-11-14 12:10:32 +01005329 status = psa_start_key_creation( PSA_KEY_CREATION_DERIVE, attributes,
5330 &slot, &driver );
Gilles Peskinef4ee6622019-07-24 13:44:30 +02005331#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
5332 if( driver != NULL )
5333 {
5334 /* Deriving a key in a secure element is not implemented yet. */
5335 status = PSA_ERROR_NOT_SUPPORTED;
5336 }
5337#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005338 if( status == PSA_SUCCESS )
5339 {
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01005340 status = psa_generate_derived_key_internal( slot,
Gilles Peskine7e0cff92019-07-30 13:48:52 +02005341 attributes->core.bits,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005342 operation );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005343 }
5344 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01005345 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005346 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02005347 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005348
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005349 return( status );
5350}
5351
Gilles Peskineeab56e42018-07-12 17:12:33 +02005352
5353
5354/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02005355/* Key derivation */
5356/****************************************************************/
5357
Steven Cooreman932ffb72021-02-15 12:14:32 +01005358#if defined(AT_LEAST_ONE_BUILTIN_KDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005359static psa_status_t psa_key_derivation_setup_kdf(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005360 psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005361 psa_algorithm_t kdf_alg )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005362{
John Durkop07cc04a2020-11-16 22:08:34 -08005363 int is_kdf_alg_supported;
5364
Janos Follath5fe19732019-06-20 15:09:30 +01005365 /* Make sure that operation->ctx is properly zero-initialised. (Macro
5366 * initialisers for this union leave some bytes unspecified.) */
5367 memset( &operation->ctx, 0, sizeof( operation->ctx ) );
5368
Gilles Peskine969c5d62019-01-16 15:53:06 +01005369 /* Make sure that kdf_alg is a supported key derivation algorithm. */
John Durkopd0321952020-10-29 21:37:36 -07005370#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
John Durkop07cc04a2020-11-16 22:08:34 -08005371 if( PSA_ALG_IS_HKDF( kdf_alg ) )
5372 is_kdf_alg_supported = 1;
5373 else
5374#endif
5375#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
5376 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
5377 is_kdf_alg_supported = 1;
5378 else
5379#endif
5380#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5381 if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
5382 is_kdf_alg_supported = 1;
5383 else
5384#endif
5385 is_kdf_alg_supported = 0;
5386
5387 if( is_kdf_alg_supported )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005388 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01005389 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
gabor-mezei-armcbcec212020-12-18 14:23:51 +01005390 size_t hash_size = PSA_HASH_LENGTH( hash_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005391 if( hash_size == 0 )
5392 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005393 if( ( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
5394 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) &&
Gilles Peskineab4b2012019-04-12 15:06:27 +02005395 ! ( hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384 ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005396 {
5397 return( PSA_ERROR_NOT_SUPPORTED );
5398 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005399 operation->capacity = 255 * hash_size;
Gilles Peskine969c5d62019-01-16 15:53:06 +01005400 return( PSA_SUCCESS );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005401 }
John Durkop07cc04a2020-11-16 22:08:34 -08005402
5403 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005404}
John Durkop07cc04a2020-11-16 22:08:34 -08005405#endif /* AT_LEAST_ONE_BUILTIN_KDF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01005406
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005407psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005408 psa_algorithm_t alg )
5409{
5410 psa_status_t status;
5411
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005412 if( operation->alg != 0 )
Gilles Peskine969c5d62019-01-16 15:53:06 +01005413 return( PSA_ERROR_BAD_STATE );
5414
Gilles Peskine6843c292019-01-18 16:44:49 +01005415 if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
5416 return( PSA_ERROR_INVALID_ARGUMENT );
5417 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskine969c5d62019-01-16 15:53:06 +01005418 {
Steven Cooreman932ffb72021-02-15 12:14:32 +01005419#if defined(AT_LEAST_ONE_BUILTIN_KDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005420 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005421 status = psa_key_derivation_setup_kdf( operation, kdf_alg );
Steven Cooreman932ffb72021-02-15 12:14:32 +01005422#else
5423 return( PSA_ERROR_NOT_SUPPORTED );
5424#endif /* AT_LEAST_ONE_BUILTIN_KDF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01005425 }
5426 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
5427 {
Steven Cooreman932ffb72021-02-15 12:14:32 +01005428#if defined(AT_LEAST_ONE_BUILTIN_KDF)
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005429 status = psa_key_derivation_setup_kdf( operation, alg );
Steven Cooreman932ffb72021-02-15 12:14:32 +01005430#else
5431 return( PSA_ERROR_NOT_SUPPORTED );
5432#endif /* AT_LEAST_ONE_BUILTIN_KDF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01005433 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005434 else
5435 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005436
5437 if( status == PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005438 operation->alg = alg;
Gilles Peskine969c5d62019-01-16 15:53:06 +01005439 return( status );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005440}
5441
John Durkopd0321952020-10-29 21:37:36 -07005442#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskinecbe66502019-05-16 16:59:18 +02005443static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005444 psa_algorithm_t hash_alg,
5445 psa_key_derivation_step_t step,
5446 const uint8_t *data,
5447 size_t data_length )
5448{
5449 psa_status_t status;
5450 switch( step )
5451 {
Gilles Peskine03410b52019-05-16 16:05:19 +02005452 case PSA_KEY_DERIVATION_INPUT_SALT:
Gilles Peskine2b522db2019-04-12 15:11:49 +02005453 if( hkdf->state != HKDF_STATE_INIT )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005454 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005455 status = psa_hmac_setup_internal( &hkdf->hmac,
5456 data, data_length,
5457 hash_alg );
5458 if( status != PSA_SUCCESS )
5459 return( status );
5460 hkdf->state = HKDF_STATE_STARTED;
5461 return( PSA_SUCCESS );
Gilles Peskine03410b52019-05-16 16:05:19 +02005462 case PSA_KEY_DERIVATION_INPUT_SECRET:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005463 /* If no salt was provided, use an empty salt. */
5464 if( hkdf->state == HKDF_STATE_INIT )
5465 {
5466 status = psa_hmac_setup_internal( &hkdf->hmac,
5467 NULL, 0,
Gilles Peskinef9ee6332019-04-11 21:22:52 +02005468 hash_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005469 if( status != PSA_SUCCESS )
5470 return( status );
5471 hkdf->state = HKDF_STATE_STARTED;
5472 }
Gilles Peskine2b522db2019-04-12 15:11:49 +02005473 if( hkdf->state != HKDF_STATE_STARTED )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005474 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005475 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5476 data, data_length );
5477 if( status != PSA_SUCCESS )
5478 return( status );
5479 status = psa_hmac_finish_internal( &hkdf->hmac,
5480 hkdf->prk,
5481 sizeof( hkdf->prk ) );
5482 if( status != PSA_SUCCESS )
5483 return( status );
gabor-mezei-armcbcec212020-12-18 14:23:51 +01005484 hkdf->offset_in_block = PSA_HASH_LENGTH( hash_alg );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005485 hkdf->block_number = 0;
5486 hkdf->state = HKDF_STATE_KEYED;
5487 return( PSA_SUCCESS );
Gilles Peskine03410b52019-05-16 16:05:19 +02005488 case PSA_KEY_DERIVATION_INPUT_INFO:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005489 if( hkdf->state == HKDF_STATE_OUTPUT )
5490 return( PSA_ERROR_BAD_STATE );
5491 if( hkdf->info_set )
5492 return( PSA_ERROR_BAD_STATE );
5493 hkdf->info_length = data_length;
5494 if( data_length != 0 )
5495 {
5496 hkdf->info = mbedtls_calloc( 1, data_length );
5497 if( hkdf->info == NULL )
5498 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5499 memcpy( hkdf->info, data, data_length );
5500 }
5501 hkdf->info_set = 1;
5502 return( PSA_SUCCESS );
5503 default:
5504 return( PSA_ERROR_INVALID_ARGUMENT );
5505 }
5506}
John Durkop07cc04a2020-11-16 22:08:34 -08005507#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
Janos Follathb03233e2019-06-11 15:30:30 +01005508
John Durkop07cc04a2020-11-16 22:08:34 -08005509#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5510 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follathf08e2652019-06-13 09:05:41 +01005511static psa_status_t psa_tls12_prf_set_seed( psa_tls12_prf_key_derivation_t *prf,
5512 const uint8_t *data,
5513 size_t data_length )
5514{
Gilles Peskine43f958b2020-12-13 14:55:14 +01005515 if( prf->state != PSA_TLS12_PRF_STATE_INIT )
Janos Follathf08e2652019-06-13 09:05:41 +01005516 return( PSA_ERROR_BAD_STATE );
5517
Janos Follathd6dce9f2019-07-04 09:11:38 +01005518 if( data_length != 0 )
5519 {
5520 prf->seed = mbedtls_calloc( 1, data_length );
5521 if( prf->seed == NULL )
5522 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Janos Follathf08e2652019-06-13 09:05:41 +01005523
Janos Follathd6dce9f2019-07-04 09:11:38 +01005524 memcpy( prf->seed, data, data_length );
5525 prf->seed_length = data_length;
5526 }
Janos Follathf08e2652019-06-13 09:05:41 +01005527
Gilles Peskine43f958b2020-12-13 14:55:14 +01005528 prf->state = PSA_TLS12_PRF_STATE_SEED_SET;
Janos Follathf08e2652019-06-13 09:05:41 +01005529
5530 return( PSA_SUCCESS );
5531}
5532
Janos Follath81550542019-06-13 14:26:34 +01005533static psa_status_t psa_tls12_prf_set_key( psa_tls12_prf_key_derivation_t *prf,
5534 psa_algorithm_t hash_alg,
5535 const uint8_t *data,
5536 size_t data_length )
5537{
5538 psa_status_t status;
Gilles Peskine43f958b2020-12-13 14:55:14 +01005539 if( prf->state != PSA_TLS12_PRF_STATE_SEED_SET )
Janos Follath81550542019-06-13 14:26:34 +01005540 return( PSA_ERROR_BAD_STATE );
5541
5542 status = psa_hmac_setup_internal( &prf->hmac, data, data_length, hash_alg );
5543 if( status != PSA_SUCCESS )
5544 return( status );
5545
Gilles Peskine43f958b2020-12-13 14:55:14 +01005546 prf->state = PSA_TLS12_PRF_STATE_KEY_SET;
Janos Follath81550542019-06-13 14:26:34 +01005547
5548 return( PSA_SUCCESS );
5549}
5550
Janos Follath63028dd2019-06-13 09:15:47 +01005551static psa_status_t psa_tls12_prf_set_label( psa_tls12_prf_key_derivation_t *prf,
5552 const uint8_t *data,
5553 size_t data_length )
5554{
Gilles Peskine43f958b2020-12-13 14:55:14 +01005555 if( prf->state != PSA_TLS12_PRF_STATE_KEY_SET )
Janos Follath63028dd2019-06-13 09:15:47 +01005556 return( PSA_ERROR_BAD_STATE );
5557
Janos Follathd6dce9f2019-07-04 09:11:38 +01005558 if( data_length != 0 )
5559 {
5560 prf->label = mbedtls_calloc( 1, data_length );
5561 if( prf->label == NULL )
5562 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Janos Follath63028dd2019-06-13 09:15:47 +01005563
Janos Follathd6dce9f2019-07-04 09:11:38 +01005564 memcpy( prf->label, data, data_length );
5565 prf->label_length = data_length;
5566 }
Janos Follath63028dd2019-06-13 09:15:47 +01005567
Gilles Peskine43f958b2020-12-13 14:55:14 +01005568 prf->state = PSA_TLS12_PRF_STATE_LABEL_SET;
Janos Follath63028dd2019-06-13 09:15:47 +01005569
5570 return( PSA_SUCCESS );
5571}
5572
Janos Follathb03233e2019-06-11 15:30:30 +01005573static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf,
5574 psa_algorithm_t hash_alg,
5575 psa_key_derivation_step_t step,
5576 const uint8_t *data,
5577 size_t data_length )
5578{
Janos Follathb03233e2019-06-11 15:30:30 +01005579 switch( step )
5580 {
Janos Follathf08e2652019-06-13 09:05:41 +01005581 case PSA_KEY_DERIVATION_INPUT_SEED:
5582 return( psa_tls12_prf_set_seed( prf, data, data_length ) );
Janos Follath81550542019-06-13 14:26:34 +01005583 case PSA_KEY_DERIVATION_INPUT_SECRET:
5584 return( psa_tls12_prf_set_key( prf, hash_alg, data, data_length ) );
Janos Follath63028dd2019-06-13 09:15:47 +01005585 case PSA_KEY_DERIVATION_INPUT_LABEL:
5586 return( psa_tls12_prf_set_label( prf, data, data_length ) );
Janos Follathb03233e2019-06-11 15:30:30 +01005587 default:
5588 return( PSA_ERROR_INVALID_ARGUMENT );
5589 }
5590}
John Durkop07cc04a2020-11-16 22:08:34 -08005591#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
5592 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
5593
5594#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5595static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
5596 psa_tls12_prf_key_derivation_t *prf,
5597 psa_algorithm_t hash_alg,
5598 const uint8_t *data,
5599 size_t data_length )
5600{
5601 psa_status_t status;
gabor-mezei-armcbcec212020-12-18 14:23:51 +01005602 uint8_t pms[ 4 + 2 * PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE ];
John Durkop07cc04a2020-11-16 22:08:34 -08005603 uint8_t *cur = pms;
5604
gabor-mezei-armcbcec212020-12-18 14:23:51 +01005605 if( data_length > PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE )
John Durkop07cc04a2020-11-16 22:08:34 -08005606 return( PSA_ERROR_INVALID_ARGUMENT );
5607
5608 /* Quoting RFC 4279, Section 2:
5609 *
5610 * The premaster secret is formed as follows: if the PSK is N octets
5611 * long, concatenate a uint16 with the value N, N zero octets, a second
5612 * uint16 with the value N, and the PSK itself.
5613 */
5614
5615 *cur++ = ( data_length >> 8 ) & 0xff;
5616 *cur++ = ( data_length >> 0 ) & 0xff;
5617 memset( cur, 0, data_length );
5618 cur += data_length;
5619 *cur++ = pms[0];
5620 *cur++ = pms[1];
5621 memcpy( cur, data, data_length );
5622 cur += data_length;
5623
5624 status = psa_tls12_prf_set_key( prf, hash_alg, pms, cur - pms );
5625
5626 mbedtls_platform_zeroize( pms, sizeof( pms ) );
5627 return( status );
5628}
Janos Follath6660f0e2019-06-17 08:44:03 +01005629
5630static psa_status_t psa_tls12_prf_psk_to_ms_input(
5631 psa_tls12_prf_key_derivation_t *prf,
5632 psa_algorithm_t hash_alg,
5633 psa_key_derivation_step_t step,
5634 const uint8_t *data,
5635 size_t data_length )
5636{
5637 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
Janos Follath0c1ed842019-06-28 13:35:36 +01005638 {
Janos Follath6660f0e2019-06-17 08:44:03 +01005639 return( psa_tls12_prf_psk_to_ms_set_key( prf, hash_alg,
5640 data, data_length ) );
Janos Follath0c1ed842019-06-28 13:35:36 +01005641 }
Janos Follath6660f0e2019-06-17 08:44:03 +01005642
5643 return( psa_tls12_prf_input( prf, hash_alg, step, data, data_length ) );
5644}
John Durkop07cc04a2020-11-16 22:08:34 -08005645#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005646
Gilles Peskineb8965192019-09-24 16:21:10 +02005647/** Check whether the given key type is acceptable for the given
5648 * input step of a key derivation.
5649 *
5650 * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE.
5651 * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA.
5652 * Both secret and non-secret inputs can alternatively have the type
5653 * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning
5654 * that the input was passed as a buffer rather than via a key object.
5655 */
Gilles Peskine224b0d62019-09-23 18:13:17 +02005656static int psa_key_derivation_check_input_type(
5657 psa_key_derivation_step_t step,
5658 psa_key_type_t key_type )
5659{
5660 switch( step )
5661 {
5662 case PSA_KEY_DERIVATION_INPUT_SECRET:
Gilles Peskineb8965192019-09-24 16:21:10 +02005663 if( key_type == PSA_KEY_TYPE_DERIVE )
5664 return( PSA_SUCCESS );
5665 if( key_type == PSA_KEY_TYPE_NONE )
Gilles Peskine224b0d62019-09-23 18:13:17 +02005666 return( PSA_SUCCESS );
5667 break;
5668 case PSA_KEY_DERIVATION_INPUT_LABEL:
5669 case PSA_KEY_DERIVATION_INPUT_SALT:
5670 case PSA_KEY_DERIVATION_INPUT_INFO:
5671 case PSA_KEY_DERIVATION_INPUT_SEED:
Gilles Peskineb8965192019-09-24 16:21:10 +02005672 if( key_type == PSA_KEY_TYPE_RAW_DATA )
5673 return( PSA_SUCCESS );
5674 if( key_type == PSA_KEY_TYPE_NONE )
Gilles Peskine224b0d62019-09-23 18:13:17 +02005675 return( PSA_SUCCESS );
5676 break;
5677 }
5678 return( PSA_ERROR_INVALID_ARGUMENT );
5679}
5680
Janos Follathb80a94e2019-06-12 15:54:46 +01005681static psa_status_t psa_key_derivation_input_internal(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005682 psa_key_derivation_operation_t *operation,
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005683 psa_key_derivation_step_t step,
Gilles Peskine224b0d62019-09-23 18:13:17 +02005684 psa_key_type_t key_type,
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005685 const uint8_t *data,
5686 size_t data_length )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005687{
Gilles Peskine46d7faf2019-09-23 19:22:55 +02005688 psa_status_t status;
5689 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
5690
5691 status = psa_key_derivation_check_input_type( step, key_type );
Gilles Peskine224b0d62019-09-23 18:13:17 +02005692 if( status != PSA_SUCCESS )
5693 goto exit;
5694
John Durkopd0321952020-10-29 21:37:36 -07005695#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005696 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005697 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005698 status = psa_hkdf_input( &operation->ctx.hkdf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005699 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005700 step, data, data_length );
5701 }
John Durkop07cc04a2020-11-16 22:08:34 -08005702 else
5703#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
5704#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
5705 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005706 {
Janos Follathb03233e2019-06-11 15:30:30 +01005707 status = psa_tls12_prf_input( &operation->ctx.tls12_prf,
5708 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
5709 step, data, data_length );
Janos Follath6660f0e2019-06-17 08:44:03 +01005710 }
John Durkop07cc04a2020-11-16 22:08:34 -08005711 else
5712#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF */
5713#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5714 if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Janos Follath6660f0e2019-06-17 08:44:03 +01005715 {
5716 status = psa_tls12_prf_psk_to_ms_input( &operation->ctx.tls12_prf,
5717 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
5718 step, data, data_length );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005719 }
5720 else
John Durkop07cc04a2020-11-16 22:08:34 -08005721#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005722 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005723 /* This can't happen unless the operation object was not initialized */
Steven Cooreman74afe472021-02-10 17:19:22 +01005724 (void) data;
5725 (void) data_length;
5726 (void) kdf_alg;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005727 return( PSA_ERROR_BAD_STATE );
5728 }
5729
Gilles Peskine224b0d62019-09-23 18:13:17 +02005730exit:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005731 if( status != PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005732 psa_key_derivation_abort( operation );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005733 return( status );
5734}
5735
Janos Follath51f4a0f2019-06-14 11:35:55 +01005736psa_status_t psa_key_derivation_input_bytes(
5737 psa_key_derivation_operation_t *operation,
5738 psa_key_derivation_step_t step,
5739 const uint8_t *data,
5740 size_t data_length )
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005741{
Gilles Peskineb8965192019-09-24 16:21:10 +02005742 return( psa_key_derivation_input_internal( operation, step,
5743 PSA_KEY_TYPE_NONE,
Janos Follathc5621512019-06-14 11:27:57 +01005744 data, data_length ) );
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005745}
5746
Janos Follath51f4a0f2019-06-14 11:35:55 +01005747psa_status_t psa_key_derivation_input_key(
5748 psa_key_derivation_operation_t *operation,
5749 psa_key_derivation_step_t step,
Ronald Croncf56a0a2020-08-04 09:51:30 +02005750 mbedtls_svc_key_id_t key )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005751{
Ronald Cronf95a2b12020-10-22 15:24:49 +02005752 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01005753 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005754 psa_key_slot_t *slot;
Gilles Peskine178c9aa2019-09-24 18:21:06 +02005755
Ronald Cron5c522922020-11-14 16:35:34 +01005756 status = psa_get_and_lock_transparent_key_slot_with_policy(
5757 key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005758 if( status != PSA_SUCCESS )
Gilles Peskine593773d2019-09-23 18:17:40 +02005759 {
5760 psa_key_derivation_abort( operation );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005761 return( status );
Gilles Peskine593773d2019-09-23 18:17:40 +02005762 }
Gilles Peskine178c9aa2019-09-24 18:21:06 +02005763
5764 /* Passing a key object as a SECRET input unlocks the permission
5765 * to output to a key object. */
5766 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
5767 operation->can_output_key = 1;
5768
Ronald Cronf95a2b12020-10-22 15:24:49 +02005769 status = psa_key_derivation_input_internal( operation,
5770 step, slot->attr.type,
Ronald Cronea0f8a62020-11-25 17:52:23 +01005771 slot->key.data,
5772 slot->key.bytes );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005773
Ronald Cron5c522922020-11-14 16:35:34 +01005774 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005775
Ronald Cron5c522922020-11-14 16:35:34 +01005776 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005777}
Gilles Peskineea0fb492018-07-12 17:17:20 +02005778
5779
5780
5781/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02005782/* Key agreement */
5783/****************************************************************/
5784
John Durkop6ba40d12020-11-10 08:50:04 -08005785#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005786static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
5787 size_t peer_key_length,
5788 const mbedtls_ecp_keypair *our_key,
5789 uint8_t *shared_secret,
5790 size_t shared_secret_size,
5791 size_t *shared_secret_length )
5792{
Steven Cooremand4867872020-08-05 16:31:39 +02005793 mbedtls_ecp_keypair *their_key = NULL;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005794 mbedtls_ecdh_context ecdh;
Jaeden Amero97271b32019-01-10 19:38:51 +00005795 psa_status_t status;
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01005796 size_t bits = 0;
Paul Elliott8ff510a2020-06-02 17:19:28 +01005797 psa_ecc_family_t curve = mbedtls_ecc_group_to_psa( our_key->grp.id, &bits );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005798 mbedtls_ecdh_init( &ecdh );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005799
Ronald Cron90857082020-11-25 14:58:33 +01005800 status = mbedtls_psa_ecp_load_representation(
5801 PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +01005802 bits,
Ronald Cron90857082020-11-25 14:58:33 +01005803 peer_key,
5804 peer_key_length,
5805 &their_key );
Jaeden Amero97271b32019-01-10 19:38:51 +00005806 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005807 goto exit;
5808
Jaeden Amero97271b32019-01-10 19:38:51 +00005809 status = mbedtls_to_psa_error(
Steven Cooremana2371e52020-07-28 14:30:39 +02005810 mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS ) );
Jaeden Amero97271b32019-01-10 19:38:51 +00005811 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005812 goto exit;
Jaeden Amero97271b32019-01-10 19:38:51 +00005813 status = mbedtls_to_psa_error(
5814 mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS ) );
5815 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005816 goto exit;
5817
Jaeden Amero97271b32019-01-10 19:38:51 +00005818 status = mbedtls_to_psa_error(
5819 mbedtls_ecdh_calc_secret( &ecdh,
5820 shared_secret_length,
5821 shared_secret, shared_secret_size,
Gilles Peskine30524eb2020-11-13 17:02:26 +01005822 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01005823 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01005824 if( status != PSA_SUCCESS )
5825 goto exit;
5826 if( PSA_BITS_TO_BYTES( bits ) != *shared_secret_length )
5827 status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005828
5829exit:
Gilles Peskine3e819b72019-12-20 14:09:55 +01005830 if( status != PSA_SUCCESS )
5831 mbedtls_platform_zeroize( shared_secret, shared_secret_size );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005832 mbedtls_ecdh_free( &ecdh );
Steven Cooremana2371e52020-07-28 14:30:39 +02005833 mbedtls_ecp_keypair_free( their_key );
Steven Cooreman6d839f02020-07-30 11:36:45 +02005834 mbedtls_free( their_key );
Steven Cooremana2371e52020-07-28 14:30:39 +02005835
Jaeden Amero97271b32019-01-10 19:38:51 +00005836 return( status );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005837}
John Durkop6ba40d12020-11-10 08:50:04 -08005838#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005839
Gilles Peskine01d718c2018-09-18 12:01:02 +02005840#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
5841
Gilles Peskine0216fe12019-04-11 21:23:21 +02005842static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg,
5843 psa_key_slot_t *private_key,
5844 const uint8_t *peer_key,
5845 size_t peer_key_length,
5846 uint8_t *shared_secret,
5847 size_t shared_secret_size,
5848 size_t *shared_secret_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02005849{
Gilles Peskine0216fe12019-04-11 21:23:21 +02005850 switch( alg )
Gilles Peskine01d718c2018-09-18 12:01:02 +02005851 {
John Durkop6ba40d12020-11-10 08:50:04 -08005852#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
Gilles Peskine0216fe12019-04-11 21:23:21 +02005853 case PSA_ALG_ECDH:
Gilles Peskine8e338702019-07-30 20:06:31 +02005854 if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005855 return( PSA_ERROR_INVALID_ARGUMENT );
Steven Cooremana2371e52020-07-28 14:30:39 +02005856 mbedtls_ecp_keypair *ecp = NULL;
Ronald Cron90857082020-11-25 14:58:33 +01005857 psa_status_t status = mbedtls_psa_ecp_load_representation(
5858 private_key->attr.type,
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +01005859 private_key->attr.bits,
Ronald Cron90857082020-11-25 14:58:33 +01005860 private_key->key.data,
5861 private_key->key.bytes,
5862 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02005863 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02005864 return( status );
Steven Cooremanacda8342020-07-24 23:09:52 +02005865 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
Steven Cooremana2371e52020-07-28 14:30:39 +02005866 ecp,
Steven Cooremanacda8342020-07-24 23:09:52 +02005867 shared_secret, shared_secret_size,
5868 shared_secret_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02005869 mbedtls_ecp_keypair_free( ecp );
5870 mbedtls_free( ecp );
Steven Cooreman29149862020-08-05 15:43:42 +02005871 return( status );
John Durkop6ba40d12020-11-10 08:50:04 -08005872#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
Gilles Peskine01d718c2018-09-18 12:01:02 +02005873 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01005874 (void) private_key;
5875 (void) peer_key;
5876 (void) peer_key_length;
Gilles Peskine0216fe12019-04-11 21:23:21 +02005877 (void) shared_secret;
5878 (void) shared_secret_size;
5879 (void) shared_secret_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02005880 return( PSA_ERROR_NOT_SUPPORTED );
5881 }
Gilles Peskine0216fe12019-04-11 21:23:21 +02005882}
5883
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02005884/* Note that if this function fails, you must call psa_key_derivation_abort()
Gilles Peskine01d718c2018-09-18 12:01:02 +02005885 * to potentially free embedded data structures and wipe confidential data.
5886 */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005887static psa_status_t psa_key_agreement_internal( psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005888 psa_key_derivation_step_t step,
Gilles Peskine01d718c2018-09-18 12:01:02 +02005889 psa_key_slot_t *private_key,
5890 const uint8_t *peer_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005891 size_t peer_key_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02005892{
5893 psa_status_t status;
5894 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
5895 size_t shared_secret_length = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005896 psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE( operation->alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02005897
5898 /* Step 1: run the secret agreement algorithm to generate the shared
5899 * secret. */
Gilles Peskine0216fe12019-04-11 21:23:21 +02005900 status = psa_key_agreement_raw_internal( ka_alg,
5901 private_key,
5902 peer_key, peer_key_length,
itayzafrir0adf0fc2018-09-06 16:24:41 +03005903 shared_secret,
5904 sizeof( shared_secret ),
Gilles Peskine05d69892018-06-19 22:00:52 +02005905 &shared_secret_length );
Gilles Peskine53d991e2018-07-12 01:14:59 +02005906 if( status != PSA_SUCCESS )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005907 goto exit;
5908
Gilles Peskineb0b255c2018-07-06 17:01:38 +02005909 /* Step 2: set up the key derivation to generate key material from
Gilles Peskine224b0d62019-09-23 18:13:17 +02005910 * the shared secret. A shared secret is permitted wherever a key
5911 * of type DERIVE is permitted. */
Janos Follathb80a94e2019-06-12 15:54:46 +01005912 status = psa_key_derivation_input_internal( operation, step,
Gilles Peskine224b0d62019-09-23 18:13:17 +02005913 PSA_KEY_TYPE_DERIVE,
Janos Follathb80a94e2019-06-12 15:54:46 +01005914 shared_secret,
5915 shared_secret_length );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005916exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01005917 mbedtls_platform_zeroize( shared_secret, shared_secret_length );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005918 return( status );
5919}
5920
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005921psa_status_t psa_key_derivation_key_agreement( psa_key_derivation_operation_t *operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005922 psa_key_derivation_step_t step,
Ronald Croncf56a0a2020-08-04 09:51:30 +02005923 mbedtls_svc_key_id_t private_key,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005924 const uint8_t *peer_key,
5925 size_t peer_key_length )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005926{
Ronald Cronf95a2b12020-10-22 15:24:49 +02005927 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01005928 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01005929 psa_key_slot_t *slot;
Ronald Cronf95a2b12020-10-22 15:24:49 +02005930
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005931 if( ! PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005932 return( PSA_ERROR_INVALID_ARGUMENT );
Ronald Cron5c522922020-11-14 16:35:34 +01005933 status = psa_get_and_lock_transparent_key_slot_with_policy(
5934 private_key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005935 if( status != PSA_SUCCESS )
5936 return( status );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005937 status = psa_key_agreement_internal( operation, step,
Gilles Peskine346797d2018-11-16 16:05:06 +01005938 slot,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005939 peer_key, peer_key_length );
Gilles Peskine346797d2018-11-16 16:05:06 +01005940 if( status != PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005941 psa_key_derivation_abort( operation );
Steven Cooremanfa5e6312020-10-15 17:07:12 +02005942 else
5943 {
5944 /* If a private key has been added as SECRET, we allow the derived
5945 * key material to be used as a key in PSA Crypto. */
5946 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
5947 operation->can_output_key = 1;
5948 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02005949
Ronald Cron5c522922020-11-14 16:35:34 +01005950 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005951
Ronald Cron5c522922020-11-14 16:35:34 +01005952 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskineaf3baab2018-06-27 22:55:52 +02005953}
5954
Gilles Peskinebe697d82019-05-16 18:00:41 +02005955psa_status_t psa_raw_key_agreement( psa_algorithm_t alg,
Ronald Croncf56a0a2020-08-04 09:51:30 +02005956 mbedtls_svc_key_id_t private_key,
Gilles Peskinebe697d82019-05-16 18:00:41 +02005957 const uint8_t *peer_key,
5958 size_t peer_key_length,
5959 uint8_t *output,
5960 size_t output_size,
5961 size_t *output_length )
Gilles Peskine0216fe12019-04-11 21:23:21 +02005962{
Ronald Cronf95a2b12020-10-22 15:24:49 +02005963 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01005964 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cronf95a2b12020-10-22 15:24:49 +02005965 psa_key_slot_t *slot = NULL;
Gilles Peskine0216fe12019-04-11 21:23:21 +02005966
5967 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
5968 {
5969 status = PSA_ERROR_INVALID_ARGUMENT;
5970 goto exit;
5971 }
Ronald Cron5c522922020-11-14 16:35:34 +01005972 status = psa_get_and_lock_transparent_key_slot_with_policy(
5973 private_key, &slot, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine0216fe12019-04-11 21:23:21 +02005974 if( status != PSA_SUCCESS )
5975 goto exit;
5976
5977 status = psa_key_agreement_raw_internal( alg, slot,
5978 peer_key, peer_key_length,
5979 output, output_size,
5980 output_length );
5981
5982exit:
5983 if( status != PSA_SUCCESS )
5984 {
5985 /* If an error happens and is not handled properly, the output
5986 * may be used as a key to protect sensitive data. Arrange for such
5987 * a key to be random, which is likely to result in decryption or
5988 * verification errors. This is better than filling the buffer with
5989 * some constant data such as zeros, which would result in the data
5990 * being protected with a reproducible, easily knowable key.
5991 */
5992 psa_generate_random( output, output_size );
5993 *output_length = output_size;
5994 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02005995
Ronald Cron5c522922020-11-14 16:35:34 +01005996 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005997
Ronald Cron5c522922020-11-14 16:35:34 +01005998 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine0216fe12019-04-11 21:23:21 +02005999}
Gilles Peskine86a440b2018-11-12 18:39:40 +01006000
6001
Gilles Peskine30524eb2020-11-13 17:02:26 +01006002
Gilles Peskine86a440b2018-11-12 18:39:40 +01006003/****************************************************************/
6004/* Random generation */
Gilles Peskine53d991e2018-07-12 01:14:59 +02006005/****************************************************************/
Gilles Peskine12313cd2018-06-20 00:20:32 +02006006
Gilles Peskine30524eb2020-11-13 17:02:26 +01006007/** Initialize the PSA random generator.
6008 */
6009static void mbedtls_psa_random_init( mbedtls_psa_random_context_t *rng )
6010{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006011#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6012 memset( rng, 0, sizeof( *rng ) );
6013#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
6014
Gilles Peskine30524eb2020-11-13 17:02:26 +01006015 /* Set default configuration if
6016 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
6017 if( rng->entropy_init == NULL )
6018 rng->entropy_init = mbedtls_entropy_init;
6019 if( rng->entropy_free == NULL )
6020 rng->entropy_free = mbedtls_entropy_free;
6021
6022 rng->entropy_init( &rng->entropy );
6023#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
6024 defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
6025 /* The PSA entropy injection feature depends on using NV seed as an entropy
6026 * source. Add NV seed as an entropy source for PSA entropy injection. */
6027 mbedtls_entropy_add_source( &rng->entropy,
6028 mbedtls_nv_seed_poll, NULL,
6029 MBEDTLS_ENTROPY_BLOCK_SIZE,
6030 MBEDTLS_ENTROPY_SOURCE_STRONG );
6031#endif
6032
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006033 mbedtls_psa_drbg_init( MBEDTLS_PSA_RANDOM_STATE );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006034#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006035}
6036
6037/** Deinitialize the PSA random generator.
6038 */
6039static void mbedtls_psa_random_free( mbedtls_psa_random_context_t *rng )
6040{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006041#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6042 memset( rng, 0, sizeof( *rng ) );
6043#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006044 mbedtls_psa_drbg_free( MBEDTLS_PSA_RANDOM_STATE );
Gilles Peskine30524eb2020-11-13 17:02:26 +01006045 rng->entropy_free( &rng->entropy );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006046#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006047}
6048
6049/** Seed the PSA random generator.
6050 */
6051static psa_status_t mbedtls_psa_random_seed( mbedtls_psa_random_context_t *rng )
6052{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006053#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6054 /* Do nothing: the external RNG seeds itself. */
6055 (void) rng;
6056 return( PSA_SUCCESS );
6057#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006058 const unsigned char drbg_seed[] = "PSA";
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006059 int ret = mbedtls_psa_drbg_seed( &rng->entropy,
6060 drbg_seed, sizeof( drbg_seed ) - 1 );
Gilles Peskine30524eb2020-11-13 17:02:26 +01006061 return mbedtls_to_psa_error( ret );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006062#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006063}
6064
Gilles Peskinee59236f2018-01-27 23:32:46 +01006065psa_status_t psa_generate_random( uint8_t *output,
6066 size_t output_size )
6067{
Gilles Peskinee59236f2018-01-27 23:32:46 +01006068 GUARD_MODULE_INITIALIZED;
6069
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006070#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6071
6072 size_t output_length = 0;
6073 psa_status_t status = mbedtls_psa_external_get_random( &global_data.rng,
6074 output, output_size,
6075 &output_length );
6076 if( status != PSA_SUCCESS )
6077 return( status );
6078 /* Breaking up a request into smaller chunks is currently not supported
6079 * for the extrernal RNG interface. */
6080 if( output_length != output_size )
6081 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
6082 return( PSA_SUCCESS );
6083
6084#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
6085
Gilles Peskine71ddab92021-01-04 21:01:07 +01006086 while( output_size > 0 )
Gilles Peskinef181eca2019-08-07 13:49:00 +02006087 {
Gilles Peskine71ddab92021-01-04 21:01:07 +01006088 size_t request_size =
6089 ( output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ?
6090 MBEDTLS_PSA_RANDOM_MAX_REQUEST :
6091 output_size );
Gilles Peskine0c59ba82021-01-05 14:10:59 +01006092 int ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
6093 output, request_size );
Gilles Peskinef181eca2019-08-07 13:49:00 +02006094 if( ret != 0 )
6095 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine71ddab92021-01-04 21:01:07 +01006096 output_size -= request_size;
6097 output += request_size;
Gilles Peskinef181eca2019-08-07 13:49:00 +02006098 }
Gilles Peskine0c59ba82021-01-05 14:10:59 +01006099 return( PSA_SUCCESS );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006100#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006101}
6102
Gilles Peskine8814fc42020-12-14 15:33:44 +01006103/* Wrapper function allowing the classic API to use the PSA RNG.
Gilles Peskine9c3e0602021-01-05 16:03:55 +01006104 *
6105 * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
6106 * `psa_generate_random(...)`. The state parameter is ignored since the
6107 * PSA API doesn't support passing an explicit state.
6108 *
6109 * In the non-external case, psa_generate_random() calls an
6110 * `mbedtls_xxx_drbg_random` function which has exactly the same signature
6111 * and semantics as mbedtls_psa_get_random(). As an optimization,
6112 * instead of doing this back-and-forth between the PSA API and the
6113 * classic API, psa_crypto_random_impl.h defines `mbedtls_psa_get_random`
6114 * as a constant function pointer to `mbedtls_xxx_drbg_random`.
Gilles Peskine8814fc42020-12-14 15:33:44 +01006115 */
6116#if defined (MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6117int mbedtls_psa_get_random( void *p_rng,
6118 unsigned char *output,
6119 size_t output_size )
6120{
Gilles Peskine9c3e0602021-01-05 16:03:55 +01006121 /* This function takes a pointer to the RNG state because that's what
6122 * classic mbedtls functions using an RNG expect. The PSA RNG manages
6123 * its own state internally and doesn't let the caller access that state.
6124 * So we just ignore the state parameter, and in practice we'll pass
6125 * NULL. */
Gilles Peskine8814fc42020-12-14 15:33:44 +01006126 (void) p_rng;
6127 psa_status_t status = psa_generate_random( output, output_size );
6128 if( status == PSA_SUCCESS )
6129 return( 0 );
6130 else
6131 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
6132}
6133#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
6134
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006135#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
6136#include "mbedtls/entropy_poll.h"
6137
Gilles Peskine7228da22019-07-15 11:06:15 +02006138psa_status_t mbedtls_psa_inject_entropy( const uint8_t *seed,
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006139 size_t seed_size )
6140{
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006141 if( global_data.initialized )
6142 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02006143
6144 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
6145 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
6146 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
6147 return( PSA_ERROR_INVALID_ARGUMENT );
6148
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006149 return( mbedtls_psa_storage_inject_entropy( seed, seed_size ) );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006150}
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006151#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006152
Ronald Cron3772afe2021-02-08 16:10:05 +01006153/** Validate the key type and size for key generation
Ronald Cron01b2aba2020-10-05 09:42:02 +02006154 *
Ronald Cron3772afe2021-02-08 16:10:05 +01006155 * \param type The key type
6156 * \param bits The number of bits of the key
Ronald Cron01b2aba2020-10-05 09:42:02 +02006157 *
6158 * \retval #PSA_SUCCESS
Ronald Cron3772afe2021-02-08 16:10:05 +01006159 * The key type and size are valid.
Ronald Cron01b2aba2020-10-05 09:42:02 +02006160 * \retval #PSA_ERROR_INVALID_ARGUMENT
6161 * The size in bits of the key is not valid.
6162 * \retval #PSA_ERROR_NOT_SUPPORTED
6163 * The type and/or the size in bits of the key or the combination of
6164 * the two is not supported.
6165 */
Ronald Cron3772afe2021-02-08 16:10:05 +01006166static psa_status_t psa_validate_key_type_and_size_for_key_generation(
6167 psa_key_type_t type, size_t bits )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006168{
Ronald Cronf3bb7612020-10-02 20:11:59 +02006169 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006170
Gilles Peskinee59236f2018-01-27 23:32:46 +01006171 if( key_type_is_raw_bytes( type ) )
6172 {
Ronald Cronf3bb7612020-10-02 20:11:59 +02006173 status = validate_unstructured_key_bit_size( type, bits );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006174 if( status != PSA_SUCCESS )
6175 return( status );
Ronald Cron01b2aba2020-10-05 09:42:02 +02006176 }
6177 else
Ronald Cron5c4d3862020-12-07 11:07:24 +01006178#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
Ronald Cron01b2aba2020-10-05 09:42:02 +02006179 if( PSA_KEY_TYPE_IS_RSA( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
6180 {
6181 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
6182 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006183
Ronald Cron01b2aba2020-10-05 09:42:02 +02006184 /* Accept only byte-aligned keys, for the same reasons as
6185 * in psa_import_rsa_key(). */
6186 if( bits % 8 != 0 )
6187 return( PSA_ERROR_NOT_SUPPORTED );
Ronald Cron01b2aba2020-10-05 09:42:02 +02006188 }
6189 else
Ronald Cron5c4d3862020-12-07 11:07:24 +01006190#endif /* defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) */
Ronald Cron01b2aba2020-10-05 09:42:02 +02006191
Ronald Cron5c4d3862020-12-07 11:07:24 +01006192#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
Ronald Cron01b2aba2020-10-05 09:42:02 +02006193 if( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
6194 {
Ronald Crond81ab562021-02-16 09:01:16 +01006195 /* To avoid empty block, return successfully here. */
6196 return( PSA_SUCCESS );
Ronald Cron01b2aba2020-10-05 09:42:02 +02006197 }
6198 else
Ronald Cron5c4d3862020-12-07 11:07:24 +01006199#endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) */
Ronald Cron01b2aba2020-10-05 09:42:02 +02006200 {
6201 return( PSA_ERROR_NOT_SUPPORTED );
6202 }
6203
6204 return( PSA_SUCCESS );
6205}
6206
Ronald Cron55ed0592020-10-05 10:30:40 +02006207psa_status_t psa_generate_key_internal(
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006208 const psa_key_attributes_t *attributes,
6209 uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
Ronald Cron01b2aba2020-10-05 09:42:02 +02006210{
6211 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006212 psa_key_type_t type = attributes->core.type;
Ronald Cron01b2aba2020-10-05 09:42:02 +02006213
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006214 if( ( attributes->domain_parameters == NULL ) &&
6215 ( attributes->domain_parameters_size != 0 ) )
Ronald Cron01b2aba2020-10-05 09:42:02 +02006216 return( PSA_ERROR_INVALID_ARGUMENT );
6217
Ronald Cron01b2aba2020-10-05 09:42:02 +02006218 if( key_type_is_raw_bytes( type ) )
6219 {
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006220 status = psa_generate_random( key_buffer, key_buffer_size );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006221 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006222 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006223
David Brown12ca5032021-02-11 11:02:00 -07006224#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskinee59236f2018-01-27 23:32:46 +01006225 if( type == PSA_KEY_TYPE_DES )
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006226 psa_des_set_key_parity( key_buffer, key_buffer_size );
David Brown8107e312021-02-12 08:08:46 -07006227#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006228 }
6229 else
6230
John Durkop07cc04a2020-11-16 22:08:34 -08006231#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02006232 if ( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006233 {
Ronald Cron9e18fc12020-11-05 17:36:40 +01006234 return( mbedtls_psa_rsa_generate_key( attributes,
6235 key_buffer,
6236 key_buffer_size,
6237 key_buffer_length ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006238 }
6239 else
John Durkop07cc04a2020-11-16 22:08:34 -08006240#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006241
John Durkop9814fa22020-11-04 12:28:15 -08006242#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02006243 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006244 {
Ronald Cron7023db52020-11-20 18:17:42 +01006245 return( mbedtls_psa_ecp_generate_key( attributes,
6246 key_buffer,
6247 key_buffer_size,
6248 key_buffer_length ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006249 }
6250 else
John Durkop9814fa22020-11-04 12:28:15 -08006251#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
Steven Cooreman29149862020-08-05 15:43:42 +02006252 {
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006253 (void)key_buffer_length;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006254 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooreman29149862020-08-05 15:43:42 +02006255 }
Gilles Peskinee59236f2018-01-27 23:32:46 +01006256
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006257 return( PSA_SUCCESS );
6258}
Darryl Green0c6575a2018-11-07 16:05:30 +00006259
Gilles Peskine35ef36b2019-05-16 19:42:05 +02006260psa_status_t psa_generate_key( const psa_key_attributes_t *attributes,
Ronald Croncf56a0a2020-08-04 09:51:30 +02006261 mbedtls_svc_key_id_t *key )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006262{
6263 psa_status_t status;
6264 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02006265 psa_se_drv_table_entry_t *driver = NULL;
Ronald Cron2b56bc82020-10-05 10:02:26 +02006266 size_t key_buffer_size;
Gilles Peskine11792082019-08-06 18:36:36 +02006267
Ronald Cron81709fc2020-11-14 12:10:32 +01006268 *key = MBEDTLS_SVC_KEY_ID_INIT;
6269
Gilles Peskine0f84d622019-09-12 19:03:13 +02006270 /* Reject any attempt to create a zero-length key so that we don't
6271 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
6272 if( psa_get_key_bits( attributes ) == 0 )
6273 return( PSA_ERROR_INVALID_ARGUMENT );
6274
Ronald Cron81709fc2020-11-14 12:10:32 +01006275 status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE, attributes,
6276 &slot, &driver );
Gilles Peskine11792082019-08-06 18:36:36 +02006277 if( status != PSA_SUCCESS )
6278 goto exit;
6279
Ronald Cron977c2472020-10-13 08:32:21 +02006280 /* In the case of a transparent key or an opaque key stored in local
6281 * storage (thus not in the case of generating a key in a secure element
6282 * or cryptoprocessor with storage), we have to allocate a buffer to
6283 * hold the generated key material. */
6284 if( slot->key.data == NULL )
6285 {
6286 if ( PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ) ==
6287 PSA_KEY_LOCATION_LOCAL_STORAGE )
6288 {
Ronald Cron3772afe2021-02-08 16:10:05 +01006289 status = psa_validate_key_type_and_size_for_key_generation(
6290 attributes->core.type, attributes->core.bits );
6291 if( status != PSA_SUCCESS )
6292 goto exit;
6293
6294 key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
6295 attributes->core.type,
6296 attributes->core.bits );
Ronald Cron977c2472020-10-13 08:32:21 +02006297 }
6298 else
6299 {
6300 status = psa_driver_wrapper_get_key_buffer_size(
6301 attributes, &key_buffer_size );
Ronald Cron3772afe2021-02-08 16:10:05 +01006302 if( status != PSA_SUCCESS )
6303 goto exit;
Ronald Cron977c2472020-10-13 08:32:21 +02006304 }
Ronald Cron977c2472020-10-13 08:32:21 +02006305
6306 status = psa_allocate_buffer_to_slot( slot, key_buffer_size );
6307 if( status != PSA_SUCCESS )
6308 goto exit;
6309 }
6310
Steven Cooreman2a1664c2020-07-20 15:33:08 +02006311 status = psa_driver_wrapper_generate_key( attributes,
Ronald Cron977c2472020-10-13 08:32:21 +02006312 slot->key.data, slot->key.bytes, &slot->key.bytes );
Gilles Peskine11792082019-08-06 18:36:36 +02006313
Ronald Cron2b56bc82020-10-05 10:02:26 +02006314 if( status != PSA_SUCCESS )
6315 psa_remove_key_data_from_memory( slot );
6316
Gilles Peskine11792082019-08-06 18:36:36 +02006317exit:
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006318 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01006319 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006320 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02006321 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02006322
Darryl Green0c6575a2018-11-07 16:05:30 +00006323 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006324}
6325
Gilles Peskinee59236f2018-01-27 23:32:46 +01006326/****************************************************************/
6327/* Module setup */
6328/****************************************************************/
6329
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006330#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
Gilles Peskine5e769522018-11-20 21:59:56 +01006331psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
6332 void (* entropy_init )( mbedtls_entropy_context *ctx ),
6333 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
6334{
6335 if( global_data.rng_state != RNG_NOT_INITIALIZED )
6336 return( PSA_ERROR_BAD_STATE );
Gilles Peskine30524eb2020-11-13 17:02:26 +01006337 global_data.rng.entropy_init = entropy_init;
6338 global_data.rng.entropy_free = entropy_free;
Gilles Peskine5e769522018-11-20 21:59:56 +01006339 return( PSA_SUCCESS );
6340}
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006341#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
Gilles Peskine5e769522018-11-20 21:59:56 +01006342
Gilles Peskinee59236f2018-01-27 23:32:46 +01006343void mbedtls_psa_crypto_free( void )
6344{
Gilles Peskine66fb1262018-12-10 16:29:04 +01006345 psa_wipe_all_key_slots( );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006346 if( global_data.rng_state != RNG_NOT_INITIALIZED )
6347 {
Gilles Peskine30524eb2020-11-13 17:02:26 +01006348 mbedtls_psa_random_free( &global_data.rng );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006349 }
6350 /* Wipe all remaining data, including configuration.
6351 * In particular, this sets all state indicator to the value
6352 * indicating "uninitialized". */
Gilles Peskine3f108122018-12-07 18:14:53 +01006353 mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
Gilles Peskinea8ade162019-06-26 11:24:49 +02006354#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined0890212019-06-24 14:34:43 +02006355 /* Unregister all secure element drivers, so that we restart from
6356 * a pristine state. */
6357 psa_unregister_all_se_drivers( );
Gilles Peskinea8ade162019-06-26 11:24:49 +02006358#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006359}
6360
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006361#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
6362/** Recover a transaction that was interrupted by a power failure.
6363 *
6364 * This function is called during initialization, before psa_crypto_init()
6365 * returns. If this function returns a failure status, the initialization
6366 * fails.
6367 */
6368static psa_status_t psa_crypto_recover_transaction(
6369 const psa_crypto_transaction_t *transaction )
6370{
6371 switch( transaction->unknown.type )
6372 {
6373 case PSA_CRYPTO_TRANSACTION_CREATE_KEY:
6374 case PSA_CRYPTO_TRANSACTION_DESTROY_KEY:
Janos Follath1d57a202019-08-13 12:15:34 +01006375 /* TODO - fall through to the failure case until this
Gilles Peskinec9d7f942019-08-13 16:17:16 +02006376 * is implemented.
6377 * https://github.com/ARMmbed/mbed-crypto/issues/218
6378 */
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006379 default:
6380 /* We found an unsupported transaction in the storage.
6381 * We don't know what state the storage is in. Give up. */
gabor-mezei-armfe309242020-11-09 17:39:56 +01006382 return( PSA_ERROR_DATA_INVALID );
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006383 }
6384}
6385#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
6386
Gilles Peskinee59236f2018-01-27 23:32:46 +01006387psa_status_t psa_crypto_init( void )
6388{
Gilles Peskine66fb1262018-12-10 16:29:04 +01006389 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006390
Gilles Peskinec6b69072018-11-20 21:42:52 +01006391 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006392 if( global_data.initialized != 0 )
6393 return( PSA_SUCCESS );
6394
Gilles Peskine30524eb2020-11-13 17:02:26 +01006395 /* Initialize and seed the random generator. */
6396 mbedtls_psa_random_init( &global_data.rng );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006397 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskine30524eb2020-11-13 17:02:26 +01006398 status = mbedtls_psa_random_seed( &global_data.rng );
Gilles Peskine66fb1262018-12-10 16:29:04 +01006399 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006400 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01006401 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006402
Gilles Peskine66fb1262018-12-10 16:29:04 +01006403 status = psa_initialize_key_slots( );
6404 if( status != PSA_SUCCESS )
6405 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01006406
Gilles Peskined9348f22019-10-01 15:22:29 +02006407#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
6408 status = psa_init_all_se_drivers( );
6409 if( status != PSA_SUCCESS )
6410 goto exit;
6411#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
6412
Gilles Peskine4b734222019-07-24 15:56:31 +02006413#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
Gilles Peskinefc762652019-07-22 19:30:34 +02006414 status = psa_crypto_load_transaction( );
6415 if( status == PSA_SUCCESS )
6416 {
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006417 status = psa_crypto_recover_transaction( &psa_crypto_transaction );
6418 if( status != PSA_SUCCESS )
6419 goto exit;
6420 status = psa_crypto_stop_transaction( );
Gilles Peskinefc762652019-07-22 19:30:34 +02006421 }
6422 else if( status == PSA_ERROR_DOES_NOT_EXIST )
6423 {
6424 /* There's no transaction to complete. It's all good. */
6425 status = PSA_SUCCESS;
6426 }
Gilles Peskine4b734222019-07-24 15:56:31 +02006427#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
Gilles Peskinefc762652019-07-22 19:30:34 +02006428
Gilles Peskinec6b69072018-11-20 21:42:52 +01006429 /* All done. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006430 global_data.initialized = 1;
6431
6432exit:
Gilles Peskine66fb1262018-12-10 16:29:04 +01006433 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006434 mbedtls_psa_crypto_free( );
Gilles Peskine66fb1262018-12-10 16:29:04 +01006435 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006436}
6437
6438#endif /* MBEDTLS_PSA_CRYPTO_C */