blob: 40a0db373246cf3260eba5c216450503b5ddfe6f [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 Cooreman75b74362020-07-28 14:30:13 +0200548/** Try to allocate a buffer to an empty key slot.
549 *
550 * \param[in,out] slot Key slot to attach buffer to.
551 * \param[in] buffer_length Requested size of the buffer.
552 *
553 * \retval #PSA_SUCCESS
554 * The buffer has been successfully allocated.
555 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
556 * Not enough memory was available for allocation.
557 * \retval #PSA_ERROR_ALREADY_EXISTS
558 * Trying to allocate a buffer to a non-empty key slot.
559 */
560static psa_status_t psa_allocate_buffer_to_slot( psa_key_slot_t *slot,
561 size_t buffer_length )
562{
Ronald Cronea0f8a62020-11-25 17:52:23 +0100563 if( slot->key.data != NULL )
Steven Cooreman29149862020-08-05 15:43:42 +0200564 return( PSA_ERROR_ALREADY_EXISTS );
Steven Cooreman75b74362020-07-28 14:30:13 +0200565
Ronald Cronea0f8a62020-11-25 17:52:23 +0100566 slot->key.data = mbedtls_calloc( 1, buffer_length );
567 if( slot->key.data == NULL )
Steven Cooreman29149862020-08-05 15:43:42 +0200568 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Steven Cooreman75b74362020-07-28 14:30:13 +0200569
Ronald Cronea0f8a62020-11-25 17:52:23 +0100570 slot->key.bytes = buffer_length;
Steven Cooreman29149862020-08-05 15:43:42 +0200571 return( PSA_SUCCESS );
Steven Cooreman75b74362020-07-28 14:30:13 +0200572}
573
Steven Cooremanf7cebd42020-10-13 20:27:40 +0200574psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot,
575 const uint8_t* data,
576 size_t data_length )
577{
578 psa_status_t status = psa_allocate_buffer_to_slot( slot,
579 data_length );
580 if( status != PSA_SUCCESS )
581 return( status );
582
Ronald Cronea0f8a62020-11-25 17:52:23 +0100583 memcpy( slot->key.data, data, data_length );
Steven Cooremanf7cebd42020-10-13 20:27:40 +0200584 return( PSA_SUCCESS );
585}
586
Ronald Crona0fe59f2020-11-29 11:14:53 +0100587psa_status_t psa_import_key_into_slot(
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100588 const psa_key_attributes_t *attributes,
589 const uint8_t *data, size_t data_length,
590 uint8_t *key_buffer, size_t key_buffer_size,
591 size_t *key_buffer_length, size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100592{
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100593 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
594 psa_key_type_t type = attributes->core.type;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100595
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200596 /* zero-length keys are never supported. */
597 if( data_length == 0 )
598 return( PSA_ERROR_NOT_SUPPORTED );
599
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100600 if( key_type_is_raw_bytes( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100601 {
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100602 *bits = PSA_BYTES_TO_BITS( data_length );
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200603
Steven Cooreman75b74362020-07-28 14:30:13 +0200604 /* Ensure that the bytes-to-bits conversion hasn't overflown. */
605 if( data_length > SIZE_MAX / 8 )
606 return( PSA_ERROR_NOT_SUPPORTED );
607
Gilles Peskine1b9505c2019-08-07 10:59:45 +0200608 /* Enforce a size limit, and in particular ensure that the bit
609 * size fits in its representation type. */
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100610 if( ( *bits ) > PSA_MAX_KEY_BITS )
Gilles Peskinec744d992019-07-30 17:26:54 +0200611 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200612
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100613 status = validate_unstructured_key_bit_size( type, *bits );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200614 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +0200615 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200616
Ronald Crondd04d422020-11-28 15:14:42 +0100617 /* Copy the key material. */
618 memcpy( key_buffer, data, data_length );
619 *key_buffer_length = data_length;
620 (void)key_buffer_size;
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200621
Steven Cooreman40120f62020-10-29 11:42:22 +0100622 return( PSA_SUCCESS );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100623 }
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100624 else if( PSA_KEY_TYPE_IS_ASYMMETRIC( type ) )
Steven Cooreman19fd5742020-07-24 23:31:01 +0200625 {
John Durkop9814fa22020-11-04 12:28:15 -0800626#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
627 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100628 if( PSA_KEY_TYPE_IS_ECC( type ) )
Steven Cooreman3ea0ce42020-10-23 11:37:05 +0200629 {
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100630 return( mbedtls_psa_ecp_import_key( attributes,
631 data, data_length,
632 key_buffer, key_buffer_size,
633 key_buffer_length,
634 bits ) );
Steven Cooreman40120f62020-10-29 11:42:22 +0100635 }
John Durkop9814fa22020-11-04 12:28:15 -0800636#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
637 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
John Durkop0e005192020-10-31 22:06:54 -0700638#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
639 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100640 if( PSA_KEY_TYPE_IS_RSA( type ) )
Steven Cooreman3ea0ce42020-10-23 11:37:05 +0200641 {
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100642 return( mbedtls_psa_rsa_import_key( attributes,
643 data, data_length,
644 key_buffer, key_buffer_size,
645 key_buffer_length,
646 bits ) );
Steven Cooreman3ea0ce42020-10-23 11:37:05 +0200647 }
John Durkop9814fa22020-11-04 12:28:15 -0800648#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
649 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100650 }
Steven Cooreman40120f62020-10-29 11:42:22 +0100651
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100652 return( PSA_ERROR_NOT_SUPPORTED );
Darryl Green06fd18d2018-07-16 11:21:11 +0100653}
654
Gilles Peskinef603c712019-01-19 13:40:11 +0100655/** Calculate the intersection of two algorithm usage policies.
656 *
657 * Return 0 (which allows no operation) on incompatibility.
658 */
659static psa_algorithm_t psa_key_policy_algorithm_intersection(
660 psa_algorithm_t alg1,
661 psa_algorithm_t alg2 )
662{
Gilles Peskine549ea862019-05-22 11:45:59 +0200663 /* Common case: both sides actually specify the same policy. */
Gilles Peskinef603c712019-01-19 13:40:11 +0100664 if( alg1 == alg2 )
665 return( alg1 );
Steven Cooreman03488022021-02-18 12:07:20 +0100666 /* If the policies are from the same hash-and-sign family, check
667 * if one is a wildcard. If so the other has the specific algorithm. */
668 if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) &&
669 PSA_ALG_IS_HASH_AND_SIGN( alg2 ) &&
670 ( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
Gilles Peskinef603c712019-01-19 13:40:11 +0100671 {
Steven Cooreman03488022021-02-18 12:07:20 +0100672 if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
673 return( alg2 );
674 if( PSA_ALG_SIGN_GET_HASH( alg2 ) == PSA_ALG_ANY_HASH )
675 return( alg1 );
676 }
677 /* If the policies are from the same AEAD family, check whether
Steven Cooreman7de9e2d2021-02-22 17:05:56 +0100678 * one of them is a minimum-tag-length wildcard. Calculate the most
Steven Cooreman03488022021-02-18 12:07:20 +0100679 * restrictive tag length. */
680 if( PSA_ALG_IS_AEAD( alg1 ) && PSA_ALG_IS_AEAD( alg2 ) &&
681 ( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg1, 0 ) ==
682 PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg2, 0 ) ) )
683 {
684 size_t alg1_len = PSA_ALG_AEAD_GET_TAG_LENGTH( alg1 );
685 size_t alg2_len = PSA_ALG_AEAD_GET_TAG_LENGTH( alg2 );
686 size_t max_len = alg1_len > alg2_len ? alg1_len : alg2_len;
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100687
Steven Cooreman7de9e2d2021-02-22 17:05:56 +0100688 /* If both are wildcards, return most restrictive wildcard */
Steven Cooremand927ed72021-02-22 19:59:35 +0100689 if( ( ( alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
690 ( ( alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) )
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100691 {
Steven Cooreman5d814812021-02-18 12:11:39 +0100692 return( PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( alg1, max_len ) );
Steven Cooreman03488022021-02-18 12:07:20 +0100693 }
694 /* If only one is a wildcard, return specific algorithm if compatible. */
Steven Cooremand927ed72021-02-22 19:59:35 +0100695 if( ( ( alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
Steven Cooreman03488022021-02-18 12:07:20 +0100696 ( alg1_len <= alg2_len ) )
697 {
698 return( alg2 );
699 }
Steven Cooremand927ed72021-02-22 19:59:35 +0100700 if( ( ( alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
Steven Cooreman03488022021-02-18 12:07:20 +0100701 ( alg2_len <= alg1_len ) )
702 {
703 return( alg1 );
704 }
705 }
706 /* If the policies are from the same MAC family, check whether one
707 * of them is a minimum-MAC-length policy. Calculate the most
708 * restrictive tag length. */
709 if( PSA_ALG_IS_MAC( alg1 ) && PSA_ALG_IS_MAC( alg2 ) &&
710 ( PSA_ALG_FULL_LENGTH_MAC( alg1 ) ==
711 PSA_ALG_FULL_LENGTH_MAC( alg2 ) ) )
712 {
713 size_t alg1_len = PSA_MAC_TRUNCATED_LENGTH( alg1 );
714 size_t alg2_len = PSA_MAC_TRUNCATED_LENGTH( alg2 );
715 size_t max_len = alg1_len > alg2_len ? alg1_len : alg2_len;
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100716
Steven Cooreman03488022021-02-18 12:07:20 +0100717 /* If both are wildcards, return most restricitve wildcard */
Steven Cooremand927ed72021-02-22 19:59:35 +0100718 if( ( ( alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
719 ( ( alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) )
Steven Cooreman03488022021-02-18 12:07:20 +0100720 {
Steven Cooremancaad4932021-02-18 11:28:17 +0100721 return( PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( alg1, max_len ) );
Steven Cooreman03488022021-02-18 12:07:20 +0100722 }
723 /* If only one is a wildcard, return specific algorithm if compatible.
724 * Special case: specific MAC algorithm with '0' as length means full-
725 * length MAC, which is always allowed by a wildcard with the same
726 * base algorithm. */
Steven Cooremand927ed72021-02-22 19:59:35 +0100727 if( ( ( alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
Steven Cooreman03488022021-02-18 12:07:20 +0100728 ( ( alg1_len <= alg2_len ) ||
729 ( alg2 == PSA_ALG_FULL_LENGTH_MAC( alg1 ) ) ) )
730 {
731 return( alg2 );
732 }
Steven Cooremand927ed72021-02-22 19:59:35 +0100733 if( ( ( alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) &&
Steven Cooreman03488022021-02-18 12:07:20 +0100734 ( ( alg2_len <= alg1_len ) ||
735 ( alg1 == PSA_ALG_FULL_LENGTH_MAC( alg2 ) ) ) )
736 {
737 return( alg1 );
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100738 }
Gilles Peskinef603c712019-01-19 13:40:11 +0100739 }
740 /* If the policies are incompatible, allow nothing. */
741 return( 0 );
742}
743
Gilles Peskined6f371b2019-05-10 19:33:38 +0200744static int psa_key_algorithm_permits( psa_algorithm_t policy_alg,
745 psa_algorithm_t requested_alg )
746{
Gilles Peskine549ea862019-05-22 11:45:59 +0200747 /* Common case: the policy only allows requested_alg. */
Gilles Peskined6f371b2019-05-10 19:33:38 +0200748 if( requested_alg == policy_alg )
749 return( 1 );
Steven Cooreman03488022021-02-18 12:07:20 +0100750 /* If policy_alg is a hash-and-sign with a wildcard for the hash,
751 * and requested_alg is the same hash-and-sign family with any hash,
752 * then requested_alg is compliant with policy_alg. */
753 if( PSA_ALG_IS_HASH_AND_SIGN( requested_alg ) &&
754 PSA_ALG_SIGN_GET_HASH( policy_alg ) == PSA_ALG_ANY_HASH )
Gilles Peskined6f371b2019-05-10 19:33:38 +0200755 {
Steven Cooreman03488022021-02-18 12:07:20 +0100756 return( ( policy_alg & ~PSA_ALG_HASH_MASK ) ==
757 ( requested_alg & ~PSA_ALG_HASH_MASK ) );
758 }
759 /* If policy_alg is a wildcard AEAD algorithm of the same base as
760 * the requested algorithm, check the requested tag length to be
761 * equal-length or longer than the wildcard-specified length. */
762 if( PSA_ALG_IS_AEAD( policy_alg ) &&
763 PSA_ALG_IS_AEAD( requested_alg ) &&
764 ( PSA_ALG_AEAD_WITH_SHORTENED_TAG( policy_alg, 0 ) ==
765 PSA_ALG_AEAD_WITH_SHORTENED_TAG( requested_alg, 0 ) ) &&
Steven Cooremand927ed72021-02-22 19:59:35 +0100766 ( ( policy_alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) )
Steven Cooreman03488022021-02-18 12:07:20 +0100767 {
768 return( PSA_ALG_AEAD_GET_TAG_LENGTH( policy_alg ) <=
769 PSA_ALG_AEAD_GET_TAG_LENGTH( requested_alg ) );
770 }
771 /* If policy_alg is a wildcard MAC algorithm of the same base as
772 * the requested algorithm, check the requested tag length to be
773 * equal-length or longer than the wildcard-specified length. */
774 if( PSA_ALG_IS_MAC( policy_alg ) &&
775 PSA_ALG_IS_MAC( requested_alg ) &&
776 ( PSA_ALG_FULL_LENGTH_MAC( policy_alg ) ==
777 PSA_ALG_FULL_LENGTH_MAC( requested_alg ) ) &&
Steven Cooremand927ed72021-02-22 19:59:35 +0100778 ( ( policy_alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) )
Steven Cooreman03488022021-02-18 12:07:20 +0100779 {
780 /* Special case: full-length MAC is encoded with 0-length.
781 * A minimum-length policy will always allow a full-length MAC. */
782 if( PSA_ALG_FULL_LENGTH_MAC( requested_alg ) == requested_alg )
783 return( 1 );
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100784
Steven Cooreman03488022021-02-18 12:07:20 +0100785 return( PSA_MAC_TRUNCATED_LENGTH( policy_alg ) <=
786 PSA_MAC_TRUNCATED_LENGTH( requested_alg ) );
Gilles Peskined6f371b2019-05-10 19:33:38 +0200787 }
Steven Cooremance48e852020-10-05 16:02:45 +0200788 /* If policy_alg is a generic key agreement operation, then using it for
Steven Cooremanfa5e6312020-10-15 17:07:12 +0200789 * a key derivation with that key agreement should also be allowed. This
790 * behaviour is expected to be defined in a future specification version. */
Steven Cooremance48e852020-10-05 16:02:45 +0200791 if( PSA_ALG_IS_RAW_KEY_AGREEMENT( policy_alg ) &&
792 PSA_ALG_IS_KEY_AGREEMENT( requested_alg ) )
793 {
794 return( PSA_ALG_KEY_AGREEMENT_GET_BASE( requested_alg ) ==
795 policy_alg );
796 }
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100797 /* If it isn't explicitly permitted, it's forbidden. */
Gilles Peskined6f371b2019-05-10 19:33:38 +0200798 return( 0 );
799}
800
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100801/** Test whether a policy permits an algorithm.
802 *
803 * The caller must test usage flags separately.
Steven Cooreman7e39f052021-02-23 14:18:32 +0100804 *
805 * \retval PSA_SUCCESS When \p alg is a specific algorithm
806 * allowed by the \p policy.
807 * \retval PSA_ERROR_INVALID_ARGUMENT When \p alg is not a specific algorithm
808 * \retval PSA_ERROR_NOT_PERMITTED When \p alg is a specific algorithm, but
809 * the \p policy does not allow it.
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100810 */
Steven Cooreman7e39f052021-02-23 14:18:32 +0100811static psa_status_t psa_key_policy_permits( const psa_key_policy_t *policy,
812 psa_algorithm_t alg )
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100813{
Steven Cooreman7e39f052021-02-23 14:18:32 +0100814 /* A requested algorithm cannot be a wildcard. */
815 if( PSA_ALG_IS_WILDCARD( alg ) )
816 return( PSA_ERROR_INVALID_ARGUMENT );
817
818 if( psa_key_algorithm_permits( policy->alg, alg ) ||
819 psa_key_algorithm_permits( policy->alg2, alg ) )
820 return( PSA_SUCCESS );
821 else
822 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100823}
824
Gilles Peskinef603c712019-01-19 13:40:11 +0100825/** Restrict a key policy based on a constraint.
826 *
827 * \param[in,out] policy The policy to restrict.
828 * \param[in] constraint The policy constraint to apply.
829 *
830 * \retval #PSA_SUCCESS
831 * \c *policy contains the intersection of the original value of
832 * \c *policy and \c *constraint.
833 * \retval #PSA_ERROR_INVALID_ARGUMENT
834 * \c *policy and \c *constraint are incompatible.
835 * \c *policy is unchanged.
836 */
837static psa_status_t psa_restrict_key_policy(
838 psa_key_policy_t *policy,
839 const psa_key_policy_t *constraint )
840{
841 psa_algorithm_t intersection_alg =
842 psa_key_policy_algorithm_intersection( policy->alg, constraint->alg );
Gilles Peskined6f371b2019-05-10 19:33:38 +0200843 psa_algorithm_t intersection_alg2 =
844 psa_key_policy_algorithm_intersection( policy->alg2, constraint->alg2 );
Gilles Peskinef603c712019-01-19 13:40:11 +0100845 if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 )
846 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined6f371b2019-05-10 19:33:38 +0200847 if( intersection_alg2 == 0 && policy->alg2 != 0 && constraint->alg2 != 0 )
848 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinef603c712019-01-19 13:40:11 +0100849 policy->usage &= constraint->usage;
850 policy->alg = intersection_alg;
Gilles Peskined6f371b2019-05-10 19:33:38 +0200851 policy->alg2 = intersection_alg2;
Gilles Peskinef603c712019-01-19 13:40:11 +0100852 return( PSA_SUCCESS );
853}
854
Ronald Cron5c522922020-11-14 16:35:34 +0100855/** Get the description of a key given its identifier and policy constraints
856 * and lock it.
Ronald Cronf95a2b12020-10-22 15:24:49 +0200857 *
Ronald Cron5c522922020-11-14 16:35:34 +0100858 * The key must have allow all the usage flags set in \p usage. If \p alg is
859 * nonzero, the key must allow operations with this algorithm.
Ronald Cron7587ae42020-11-11 15:04:25 +0100860 *
Ronald Cron5c522922020-11-14 16:35:34 +0100861 * In case of a persistent key, the function loads the description of the key
862 * into a key slot if not already done.
863 *
864 * On success, the returned key slot is locked. It is the responsibility of
865 * the caller to unlock the key slot when it does not access it anymore.
Ronald Cronf95a2b12020-10-22 15:24:49 +0200866 */
Ronald Cron5c522922020-11-14 16:35:34 +0100867static psa_status_t psa_get_and_lock_key_slot_with_policy(
868 mbedtls_svc_key_id_t key,
869 psa_key_slot_t **p_slot,
870 psa_key_usage_t usage,
871 psa_algorithm_t alg )
Darryl Green06fd18d2018-07-16 11:21:11 +0100872{
Ronald Cronf95a2b12020-10-22 15:24:49 +0200873 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
874 psa_key_slot_t *slot;
Darryl Green06fd18d2018-07-16 11:21:11 +0100875
Ronald Cron5c522922020-11-14 16:35:34 +0100876 status = psa_get_and_lock_key_slot( key, p_slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100877 if( status != PSA_SUCCESS )
878 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +0200879 slot = *p_slot;
Darryl Green06fd18d2018-07-16 11:21:11 +0100880
881 /* Enforce that usage policy for the key slot contains all the flags
882 * required by the usage parameter. There is one exception: public
883 * keys can always be exported, so we treat public key objects as
884 * if they had the export flag. */
Gilles Peskine8e338702019-07-30 20:06:31 +0200885 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
Darryl Green06fd18d2018-07-16 11:21:11 +0100886 usage &= ~PSA_KEY_USAGE_EXPORT;
Ronald Cronf95a2b12020-10-22 15:24:49 +0200887
888 status = PSA_ERROR_NOT_PERMITTED;
Gilles Peskine8e338702019-07-30 20:06:31 +0200889 if( ( slot->attr.policy.usage & usage ) != usage )
Ronald Cronf95a2b12020-10-22 15:24:49 +0200890 goto error;
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100891
892 /* Enforce that the usage policy permits the requested algortihm. */
Steven Cooreman7e39f052021-02-23 14:18:32 +0100893 if( alg != 0 )
894 {
895 status = psa_key_policy_permits( &slot->attr.policy, alg );
896 if( status != PSA_SUCCESS )
897 goto error;
898 }
Darryl Green06fd18d2018-07-16 11:21:11 +0100899
Darryl Green06fd18d2018-07-16 11:21:11 +0100900 return( PSA_SUCCESS );
Ronald Cronf95a2b12020-10-22 15:24:49 +0200901
902error:
903 *p_slot = NULL;
Ronald Cron5c522922020-11-14 16:35:34 +0100904 psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +0200905
906 return( status );
Darryl Green06fd18d2018-07-16 11:21:11 +0100907}
Darryl Green940d72c2018-07-13 13:18:51 +0100908
Ronald Cron5c522922020-11-14 16:35:34 +0100909/** Get a key slot containing a transparent key and lock it.
Gilles Peskine28f8f302019-07-24 13:30:31 +0200910 *
911 * A transparent key is a key for which the key material is directly
912 * available, as opposed to a key in a secure element.
913 *
Ronald Cron5c522922020-11-14 16:35:34 +0100914 * This is a temporary function to use instead of
915 * psa_get_and_lock_key_slot_with_policy() until secure element support is
916 * fully implemented.
Ronald Cronf95a2b12020-10-22 15:24:49 +0200917 *
Ronald Cron5c522922020-11-14 16:35:34 +0100918 * On success, the returned key slot is locked. It is the responsibility of the
919 * caller to unlock the key slot when it does not access it anymore.
Gilles Peskine28f8f302019-07-24 13:30:31 +0200920 */
921#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Ronald Cron5c522922020-11-14 16:35:34 +0100922static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
923 mbedtls_svc_key_id_t key,
924 psa_key_slot_t **p_slot,
925 psa_key_usage_t usage,
926 psa_algorithm_t alg )
Gilles Peskine28f8f302019-07-24 13:30:31 +0200927{
Ronald Cron5c522922020-11-14 16:35:34 +0100928 psa_status_t status = psa_get_and_lock_key_slot_with_policy( key, p_slot,
929 usage, alg );
Gilles Peskine28f8f302019-07-24 13:30:31 +0200930 if( status != PSA_SUCCESS )
931 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +0200932
Gilles Peskineadad8132019-07-25 11:31:23 +0200933 if( psa_key_slot_is_external( *p_slot ) )
Gilles Peskine28f8f302019-07-24 13:30:31 +0200934 {
Ronald Cron5c522922020-11-14 16:35:34 +0100935 psa_unlock_key_slot( *p_slot );
Gilles Peskine28f8f302019-07-24 13:30:31 +0200936 *p_slot = NULL;
937 return( PSA_ERROR_NOT_SUPPORTED );
938 }
Ronald Cronf95a2b12020-10-22 15:24:49 +0200939
Gilles Peskine28f8f302019-07-24 13:30:31 +0200940 return( PSA_SUCCESS );
941}
942#else /* MBEDTLS_PSA_CRYPTO_SE_C */
943/* With no secure element support, all keys are transparent. */
Ronald Cron5c522922020-11-14 16:35:34 +0100944#define psa_get_and_lock_transparent_key_slot_with_policy( key, p_slot, usage, alg ) \
945 psa_get_and_lock_key_slot_with_policy( key, p_slot, usage, alg )
Gilles Peskine28f8f302019-07-24 13:30:31 +0200946#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
947
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100948/** Wipe key data from a slot. Preserve metadata such as the policy. */
Gilles Peskine2f060a82018-12-04 17:12:32 +0100949static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
Darryl Green40225ba2018-11-15 14:48:15 +0000950{
Ronald Cronea0f8a62020-11-25 17:52:23 +0100951 /* Data pointer will always be either a valid pointer or NULL in an
952 * initialized slot, so we can just free it. */
953 if( slot->key.data != NULL )
954 mbedtls_platform_zeroize( slot->key.data, slot->key.bytes);
955
956 mbedtls_free( slot->key.data );
957 slot->key.data = NULL;
958 slot->key.bytes = 0;
Darryl Green40225ba2018-11-15 14:48:15 +0000959
960 return( PSA_SUCCESS );
961}
962
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100963/** Completely wipe a slot in memory, including its policy.
964 * Persistent storage is not affected. */
Gilles Peskine66fb1262018-12-10 16:29:04 +0100965psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot )
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100966{
967 psa_status_t status = psa_remove_key_data_from_memory( slot );
Ronald Cronddd3d052020-10-30 14:07:07 +0100968
969 /*
970 * As the return error code may not be handled in case of multiple errors,
Ronald Cron5c522922020-11-14 16:35:34 +0100971 * do our best to report an unexpected lock counter: if available
Ronald Cronddd3d052020-10-30 14:07:07 +0100972 * call MBEDTLS_PARAM_FAILED that may terminate execution (if called as
973 * part of the execution of a test suite this will stop the test suite
Ronald Cron4640c152020-11-13 10:11:01 +0100974 * execution).
Ronald Cronddd3d052020-10-30 14:07:07 +0100975 */
Ronald Cron5c522922020-11-14 16:35:34 +0100976 if( slot->lock_count != 1 )
Ronald Cronddd3d052020-10-30 14:07:07 +0100977 {
978#ifdef MBEDTLS_CHECK_PARAMS
Ronald Cron5c522922020-11-14 16:35:34 +0100979 MBEDTLS_PARAM_FAILED( slot->lock_count == 1 );
Ronald Cronddd3d052020-10-30 14:07:07 +0100980#endif
Ronald Cronddd3d052020-10-30 14:07:07 +0100981 status = PSA_ERROR_CORRUPTION_DETECTED;
982 }
983
Gilles Peskine3f7cd622019-08-13 15:01:08 +0200984 /* Multipart operations may still be using the key. This is safe
985 * because all multipart operation objects are independent from
986 * the key slot: if they need to access the key after the setup
987 * phase, they have a copy of the key. Note that this means that
988 * key material can linger until all operations are completed. */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100989 /* At this point, key material and other type-specific content has
990 * been wiped. Clear remaining metadata. We can call memset and not
991 * zeroize because the metadata is not particularly sensitive. */
992 memset( slot, 0, sizeof( *slot ) );
993 return( status );
994}
995
Ronald Croncf56a0a2020-08-04 09:51:30 +0200996psa_status_t psa_destroy_key( mbedtls_svc_key_id_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100997{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100998 psa_key_slot_t *slot;
Gilles Peskine4b7f3402019-08-13 15:58:36 +0200999 psa_status_t status; /* status of the last operation */
1000 psa_status_t overall_status = PSA_SUCCESS;
Gilles Peskine354f7672019-07-12 23:46:38 +02001001#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1002 psa_se_drv_table_entry_t *driver;
1003#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001004
Ronald Croncf56a0a2020-08-04 09:51:30 +02001005 if( mbedtls_svc_key_id_is_null( key ) )
Gilles Peskine1841cf42019-10-08 15:48:25 +02001006 return( PSA_SUCCESS );
1007
Ronald Cronf2911112020-10-29 17:51:10 +01001008 /*
Ronald Cron19daca92020-11-10 18:08:03 +01001009 * Get the description of the key in a key slot. In case of a persistent
Ronald Cronf2911112020-10-29 17:51:10 +01001010 * key, this will load the key description from persistent memory if not
1011 * done yet. We cannot avoid this loading as without it we don't know if
1012 * the key is operated by an SE or not and this information is needed by
1013 * the current implementation.
1014 */
Ronald Cron5c522922020-11-14 16:35:34 +01001015 status = psa_get_and_lock_key_slot( key, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001016 if( status != PSA_SUCCESS )
1017 return( status );
Gilles Peskine354f7672019-07-12 23:46:38 +02001018
Ronald Cronf2911112020-10-29 17:51:10 +01001019 /*
1020 * If the key slot containing the key description is under access by the
1021 * library (apart from the present access), the key cannot be destroyed
1022 * yet. For the time being, just return in error. Eventually (to be
1023 * implemented), the key should be destroyed when all accesses have
1024 * stopped.
1025 */
Ronald Cron5c522922020-11-14 16:35:34 +01001026 if( slot->lock_count > 1 )
Ronald Cronf2911112020-10-29 17:51:10 +01001027 {
Ronald Cron5c522922020-11-14 16:35:34 +01001028 psa_unlock_key_slot( slot );
Ronald Cronf2911112020-10-29 17:51:10 +01001029 return( PSA_ERROR_GENERIC_ERROR );
1030 }
1031
Gilles Peskine354f7672019-07-12 23:46:38 +02001032#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001033 driver = psa_get_se_driver_entry( slot->attr.lifetime );
Gilles Peskine354f7672019-07-12 23:46:38 +02001034 if( driver != NULL )
Gilles Peskinefc762652019-07-22 19:30:34 +02001035 {
Gilles Peskine60450a42019-07-25 11:32:45 +02001036 /* For a key in a secure element, we need to do three things:
1037 * remove the key file in internal storage, destroy the
1038 * key inside the secure element, and update the driver's
1039 * persistent data. Start a transaction that will encompass these
1040 * three actions. */
Gilles Peskinefc762652019-07-22 19:30:34 +02001041 psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_DESTROY_KEY );
Gilles Peskine8e338702019-07-30 20:06:31 +02001042 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
Ronald Cronea0f8a62020-11-25 17:52:23 +01001043 psa_crypto_transaction.key.slot = psa_key_slot_get_slot_number( slot );
Gilles Peskine8e338702019-07-30 20:06:31 +02001044 psa_crypto_transaction.key.id = slot->attr.id;
Gilles Peskinefc762652019-07-22 19:30:34 +02001045 status = psa_crypto_save_transaction( );
1046 if( status != PSA_SUCCESS )
1047 {
Gilles Peskine66be51c2019-07-25 18:02:52 +02001048 (void) psa_crypto_stop_transaction( );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001049 /* We should still try to destroy the key in the secure
1050 * element and the key metadata in storage. This is especially
1051 * important if the error is that the storage is full.
1052 * But how to do it exactly without risking an inconsistent
1053 * state after a reset?
1054 * https://github.com/ARMmbed/mbed-crypto/issues/215
1055 */
1056 overall_status = status;
1057 goto exit;
Gilles Peskinefc762652019-07-22 19:30:34 +02001058 }
1059
Ronald Cronea0f8a62020-11-25 17:52:23 +01001060 status = psa_destroy_se_key( driver,
1061 psa_key_slot_get_slot_number( slot ) );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001062 if( overall_status == PSA_SUCCESS )
1063 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001064 }
Gilles Peskine354f7672019-07-12 23:46:38 +02001065#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1066
Darryl Greend49a4992018-06-18 17:27:26 +01001067#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Ronald Crond98059d2020-10-23 18:00:55 +02001068 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
Darryl Greend49a4992018-06-18 17:27:26 +01001069 {
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001070 status = psa_destroy_persistent_key( slot->attr.id );
1071 if( overall_status == PSA_SUCCESS )
1072 overall_status = status;
1073
Gilles Peskine9ce31c42019-08-13 15:14:20 +02001074 /* TODO: other slots may have a copy of the same key. We should
1075 * invalidate them.
1076 * https://github.com/ARMmbed/mbed-crypto/issues/214
1077 */
Darryl Greend49a4992018-06-18 17:27:26 +01001078 }
1079#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskine354f7672019-07-12 23:46:38 +02001080
Gilles Peskinefc762652019-07-22 19:30:34 +02001081#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1082 if( driver != NULL )
1083 {
Gilles Peskine725f22a2019-07-25 11:31:48 +02001084 status = psa_save_se_persistent_data( driver );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001085 if( overall_status == PSA_SUCCESS )
1086 overall_status = status;
1087 status = psa_crypto_stop_transaction( );
1088 if( overall_status == PSA_SUCCESS )
1089 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001090 }
1091#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1092
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001093#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1094exit:
1095#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001096 status = psa_wipe_key_slot( slot );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001097 /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
1098 if( overall_status == PSA_SUCCESS )
1099 overall_status = status;
1100 return( overall_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001101}
1102
John Durkop07cc04a2020-11-16 22:08:34 -08001103#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
John Durkop0e005192020-10-31 22:06:54 -07001104 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskineb699f072019-04-26 16:06:02 +02001105static psa_status_t psa_get_rsa_public_exponent(
1106 const mbedtls_rsa_context *rsa,
1107 psa_key_attributes_t *attributes )
1108{
1109 mbedtls_mpi mpi;
Janos Follath24eed8d2019-11-22 13:21:35 +00001110 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb699f072019-04-26 16:06:02 +02001111 uint8_t *buffer = NULL;
1112 size_t buflen;
1113 mbedtls_mpi_init( &mpi );
1114
1115 ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &mpi );
1116 if( ret != 0 )
1117 goto exit;
Gilles Peskine772c8b12019-04-26 17:37:21 +02001118 if( mbedtls_mpi_cmp_int( &mpi, 65537 ) == 0 )
1119 {
1120 /* It's the default value, which is reported as an empty string,
1121 * so there's nothing to do. */
1122 goto exit;
1123 }
Gilles Peskineb699f072019-04-26 16:06:02 +02001124
1125 buflen = mbedtls_mpi_size( &mpi );
1126 buffer = mbedtls_calloc( 1, buflen );
1127 if( buffer == NULL )
1128 {
1129 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
1130 goto exit;
1131 }
1132 ret = mbedtls_mpi_write_binary( &mpi, buffer, buflen );
1133 if( ret != 0 )
1134 goto exit;
1135 attributes->domain_parameters = buffer;
1136 attributes->domain_parameters_size = buflen;
1137
1138exit:
1139 mbedtls_mpi_free( &mpi );
1140 if( ret != 0 )
1141 mbedtls_free( buffer );
1142 return( mbedtls_to_psa_error( ret ) );
1143}
John Durkop07cc04a2020-11-16 22:08:34 -08001144#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
John Durkop9814fa22020-11-04 12:28:15 -08001145 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineb699f072019-04-26 16:06:02 +02001146
Gilles Peskinebfd322f2019-07-23 11:58:03 +02001147/** Retrieve all the publicly-accessible attributes of a key.
1148 */
Ronald Croncf56a0a2020-08-04 09:51:30 +02001149psa_status_t psa_get_key_attributes( mbedtls_svc_key_id_t key,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001150 psa_key_attributes_t *attributes )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001151{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001152 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001153 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001154 psa_key_slot_t *slot;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001155
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001156 psa_reset_key_attributes( attributes );
1157
Ronald Cron5c522922020-11-14 16:35:34 +01001158 status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001159 if( status != PSA_SUCCESS )
1160 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +02001161
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001162 attributes->core = slot->attr;
Gilles Peskinec8000c02019-08-02 20:15:51 +02001163 attributes->core.flags &= ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1164 MBEDTLS_PSA_KA_MASK_DUAL_USE );
1165
1166#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1167 if( psa_key_slot_is_external( slot ) )
Ronald Cronea0f8a62020-11-25 17:52:23 +01001168 psa_set_key_slot_number( attributes,
1169 psa_key_slot_get_slot_number( slot ) );
Gilles Peskinec8000c02019-08-02 20:15:51 +02001170#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineb699f072019-04-26 16:06:02 +02001171
Gilles Peskine8e338702019-07-30 20:06:31 +02001172 switch( slot->attr.type )
Gilles Peskineb699f072019-04-26 16:06:02 +02001173 {
John Durkop07cc04a2020-11-16 22:08:34 -08001174#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
John Durkop0e005192020-10-31 22:06:54 -07001175 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001176 case PSA_KEY_TYPE_RSA_KEY_PAIR:
Gilles Peskineb699f072019-04-26 16:06:02 +02001177 case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001178#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01001179 /* TODO: reporting the public exponent for opaque keys
Gilles Peskinec9d7f942019-08-13 16:17:16 +02001180 * is not yet implemented.
1181 * https://github.com/ARMmbed/mbed-crypto/issues/216
1182 */
Gilles Peskinec8000c02019-08-02 20:15:51 +02001183 if( psa_key_slot_is_external( slot ) )
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001184 break;
1185#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Steven Cooremana01795d2020-07-24 22:48:15 +02001186 {
Steven Cooremana2371e52020-07-28 14:30:39 +02001187 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02001188
Ronald Cron90857082020-11-25 14:58:33 +01001189 status = mbedtls_psa_rsa_load_representation(
1190 slot->attr.type,
1191 slot->key.data,
1192 slot->key.bytes,
1193 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001194 if( status != PSA_SUCCESS )
1195 break;
1196
Steven Cooremana2371e52020-07-28 14:30:39 +02001197 status = psa_get_rsa_public_exponent( rsa,
Steven Cooremana01795d2020-07-24 22:48:15 +02001198 attributes );
Steven Cooremana2371e52020-07-28 14:30:39 +02001199 mbedtls_rsa_free( rsa );
1200 mbedtls_free( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001201 }
Gilles Peskineb699f072019-04-26 16:06:02 +02001202 break;
John Durkop07cc04a2020-11-16 22:08:34 -08001203#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
John Durkop9814fa22020-11-04 12:28:15 -08001204 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineb699f072019-04-26 16:06:02 +02001205 default:
1206 /* Nothing else to do. */
1207 break;
1208 }
1209
1210 if( status != PSA_SUCCESS )
1211 psa_reset_key_attributes( attributes );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001212
Ronald Cron5c522922020-11-14 16:35:34 +01001213 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001214
Ronald Cron5c522922020-11-14 16:35:34 +01001215 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001216}
1217
Gilles Peskinec8000c02019-08-02 20:15:51 +02001218#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1219psa_status_t psa_get_key_slot_number(
1220 const psa_key_attributes_t *attributes,
1221 psa_key_slot_number_t *slot_number )
1222{
1223 if( attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER )
1224 {
1225 *slot_number = attributes->slot_number;
1226 return( PSA_SUCCESS );
1227 }
1228 else
1229 return( PSA_ERROR_INVALID_ARGUMENT );
1230}
1231#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1232
Ronald Crond18b5f82020-11-25 16:46:05 +01001233static psa_status_t psa_export_key_buffer_internal( const uint8_t *key_buffer,
1234 size_t key_buffer_size,
Steven Cooremana01795d2020-07-24 22:48:15 +02001235 uint8_t *data,
1236 size_t data_size,
1237 size_t *data_length )
1238{
Ronald Crond18b5f82020-11-25 16:46:05 +01001239 if( key_buffer_size > data_size )
Steven Cooremana01795d2020-07-24 22:48:15 +02001240 return( PSA_ERROR_BUFFER_TOO_SMALL );
Ronald Crond18b5f82020-11-25 16:46:05 +01001241 memcpy( data, key_buffer, key_buffer_size );
1242 memset( data + key_buffer_size, 0,
1243 data_size - key_buffer_size );
1244 *data_length = key_buffer_size;
Steven Cooremana01795d2020-07-24 22:48:15 +02001245 return( PSA_SUCCESS );
1246}
1247
Ronald Cron7285cda2020-11-26 14:46:37 +01001248psa_status_t psa_export_key_internal(
Ronald Crond18b5f82020-11-25 16:46:05 +01001249 const psa_key_attributes_t *attributes,
1250 const uint8_t *key_buffer, size_t key_buffer_size,
1251 uint8_t *data, size_t data_size, size_t *data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001252{
Ronald Crond18b5f82020-11-25 16:46:05 +01001253 psa_key_type_t type = attributes->core.type;
1254
Ronald Crond18b5f82020-11-25 16:46:05 +01001255 if( key_type_is_raw_bytes( type ) ||
1256 PSA_KEY_TYPE_IS_RSA( type ) ||
1257 PSA_KEY_TYPE_IS_ECC( type ) )
Ronald Cron9486f9d2020-11-26 13:36:23 +01001258 {
1259 return( psa_export_key_buffer_internal(
Ronald Crond18b5f82020-11-25 16:46:05 +01001260 key_buffer, key_buffer_size,
1261 data, data_size, data_length ) );
Ronald Cron9486f9d2020-11-26 13:36:23 +01001262 }
1263 else
1264 {
1265 /* This shouldn't happen in the reference implementation, but
1266 it is valid for a special-purpose implementation to omit
1267 support for exporting certain key types. */
1268 return( PSA_ERROR_NOT_SUPPORTED );
1269 }
1270}
1271
1272psa_status_t psa_export_key( mbedtls_svc_key_id_t key,
1273 uint8_t *data,
1274 size_t data_size,
1275 size_t *data_length )
1276{
1277 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1278 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
1279 psa_key_slot_t *slot;
1280
Ronald Crone907e552021-01-18 13:22:38 +01001281 /* Reject a zero-length output buffer now, since this can never be a
1282 * valid key representation. This way we know that data must be a valid
1283 * pointer and we can do things like memset(data, ..., data_size). */
1284 if( data_size == 0 )
1285 return( PSA_ERROR_BUFFER_TOO_SMALL );
1286
Ronald Cron9486f9d2020-11-26 13:36:23 +01001287 /* Set the key to empty now, so that even when there are errors, we always
1288 * set data_length to a value between 0 and data_size. On error, setting
1289 * the key to empty is a good choice because an empty key representation is
1290 * unlikely to be accepted anywhere. */
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001291 *data_length = 0;
1292
Ronald Cron9486f9d2020-11-26 13:36:23 +01001293 /* Export requires the EXPORT flag. There is an exception for public keys,
1294 * which don't require any flag, but
1295 * psa_get_and_lock_key_slot_with_policy() takes care of this.
1296 */
1297 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
1298 PSA_KEY_USAGE_EXPORT, 0 );
1299 if( status != PSA_SUCCESS )
1300 return( status );
mohammad160306e79202018-03-28 13:17:44 +03001301
Ronald Crond18b5f82020-11-25 16:46:05 +01001302 psa_key_attributes_t attributes = {
1303 .core = slot->attr
1304 };
Ronald Cron67227982020-11-26 15:16:05 +01001305 status = psa_driver_wrapper_export_key( &attributes,
Ronald Crond18b5f82020-11-25 16:46:05 +01001306 slot->key.data, slot->key.bytes,
1307 data, data_size, data_length );
Ronald Cron9486f9d2020-11-26 13:36:23 +01001308
Ronald Cron9486f9d2020-11-26 13:36:23 +01001309 unlock_status = psa_unlock_key_slot( slot );
1310
1311 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
1312}
1313
Ronald Cron7285cda2020-11-26 14:46:37 +01001314psa_status_t psa_export_public_key_internal(
Ronald Crond18b5f82020-11-25 16:46:05 +01001315 const psa_key_attributes_t *attributes,
1316 const uint8_t *key_buffer,
1317 size_t key_buffer_size,
1318 uint8_t *data,
1319 size_t data_size,
1320 size_t *data_length )
Ronald Cron9486f9d2020-11-26 13:36:23 +01001321{
Ronald Crond18b5f82020-11-25 16:46:05 +01001322 psa_key_type_t type = attributes->core.type;
Ronald Crond18b5f82020-11-25 16:46:05 +01001323
Ronald Crond18b5f82020-11-25 16:46:05 +01001324 if( PSA_KEY_TYPE_IS_RSA( type ) || PSA_KEY_TYPE_IS_ECC( type ) )
Moran Peker17e36e12018-05-02 12:55:20 +03001325 {
Ronald Crond18b5f82020-11-25 16:46:05 +01001326 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +01001327 {
Steven Cooreman560c28a2020-07-24 23:20:24 +02001328 /* Exporting public -> public */
Ronald Cron9486f9d2020-11-26 13:36:23 +01001329 return( psa_export_key_buffer_internal(
Ronald Crond18b5f82020-11-25 16:46:05 +01001330 key_buffer, key_buffer_size,
1331 data, data_size, data_length ) );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001332 }
Steven Cooremanb9b84422020-10-14 14:39:20 +02001333
Ronald Crond18b5f82020-11-25 16:46:05 +01001334 if( PSA_KEY_TYPE_IS_RSA( type ) )
Steven Cooreman560c28a2020-07-24 23:20:24 +02001335 {
John Durkop0e005192020-10-31 22:06:54 -07001336#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1337 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Ronald Crone5ca3d82020-11-26 16:36:16 +01001338 return( mbedtls_psa_rsa_export_public_key( attributes,
1339 key_buffer,
1340 key_buffer_size,
1341 data,
1342 data_size,
1343 data_length ) );
Darryl Green9e2d7a02018-07-24 16:33:30 +01001344#else
Steven Cooreman560c28a2020-07-24 23:20:24 +02001345 /* We don't know how to convert a private RSA key to public. */
1346 return( PSA_ERROR_NOT_SUPPORTED );
John Durkop9814fa22020-11-04 12:28:15 -08001347#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1348 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskine969ac722018-01-28 18:16:59 +01001349 }
1350 else
Moran Pekera998bc62018-04-16 18:16:20 +03001351 {
John Durkop6ba40d12020-11-10 08:50:04 -08001352#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
1353 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Ronald Crone5ca3d82020-11-26 16:36:16 +01001354 return( mbedtls_psa_ecp_export_public_key( attributes,
1355 key_buffer,
1356 key_buffer_size,
1357 data,
1358 data_size,
1359 data_length ) );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001360#else
1361 /* We don't know how to convert a private ECC key to public */
Moran Pekera998bc62018-04-16 18:16:20 +03001362 return( PSA_ERROR_NOT_SUPPORTED );
John Durkop9814fa22020-11-04 12:28:15 -08001363#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
1364 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
Moran Pekera998bc62018-04-16 18:16:20 +03001365 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001366 }
Steven Cooreman560c28a2020-07-24 23:20:24 +02001367 else
1368 {
1369 /* This shouldn't happen in the reference implementation, but
1370 it is valid for a special-purpose implementation to omit
1371 support for exporting certain key types. */
1372 return( PSA_ERROR_NOT_SUPPORTED );
1373 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001374}
Ronald Crond18b5f82020-11-25 16:46:05 +01001375
Ronald Croncf56a0a2020-08-04 09:51:30 +02001376psa_status_t psa_export_public_key( mbedtls_svc_key_id_t key,
Gilles Peskine2d277862018-06-18 15:41:12 +02001377 uint8_t *data,
1378 size_t data_size,
1379 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001380{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001381 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001382 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001383 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001384
Ronald Crone907e552021-01-18 13:22:38 +01001385 /* Reject a zero-length output buffer now, since this can never be a
1386 * valid key representation. This way we know that data must be a valid
1387 * pointer and we can do things like memset(data, ..., data_size). */
1388 if( data_size == 0 )
1389 return( PSA_ERROR_BUFFER_TOO_SMALL );
1390
Darryl Greendd8fb772018-11-07 16:00:44 +00001391 /* Set the key to empty now, so that even when there are errors, we always
1392 * set data_length to a value between 0 and data_size. On error, setting
1393 * the key to empty is a good choice because an empty key representation is
1394 * unlikely to be accepted anywhere. */
1395 *data_length = 0;
1396
1397 /* Exporting a public key doesn't require a usage flag. */
Ronald Cron5c522922020-11-14 16:35:34 +01001398 status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001399 if( status != PSA_SUCCESS )
1400 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001401
Ronald Cron9486f9d2020-11-26 13:36:23 +01001402 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
1403 {
1404 status = PSA_ERROR_INVALID_ARGUMENT;
1405 goto exit;
1406 }
1407
Ronald Crond18b5f82020-11-25 16:46:05 +01001408 psa_key_attributes_t attributes = {
1409 .core = slot->attr
1410 };
Ronald Cron67227982020-11-26 15:16:05 +01001411 status = psa_driver_wrapper_export_public_key(
Ronald Crond18b5f82020-11-25 16:46:05 +01001412 &attributes, slot->key.data, slot->key.bytes,
1413 data, data_size, data_length );
Ronald Cron9486f9d2020-11-26 13:36:23 +01001414
1415exit:
Ronald Cron5c522922020-11-14 16:35:34 +01001416 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001417
Ronald Cron5c522922020-11-14 16:35:34 +01001418 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001419}
1420
Gilles Peskine91e8c332019-08-02 19:19:39 +02001421#if defined(static_assert)
1422static_assert( ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
1423 "One or more key attribute flag is listed as both external-only and dual-use" );
Gilles Peskine5a680562019-08-05 17:32:13 +02001424static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
Gilles Peskine094dac12019-08-07 18:19:46 +02001425 "One or more key attribute flag is listed as both internal-only and dual-use" );
Gilles Peskine5a680562019-08-05 17:32:13 +02001426static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ) == 0,
Gilles Peskine91e8c332019-08-02 19:19:39 +02001427 "One or more key attribute flag is listed as both internal-only and external-only" );
1428#endif
1429
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001430/** Validate that a key policy is internally well-formed.
1431 *
1432 * This function only rejects invalid policies. It does not validate the
1433 * consistency of the policy with respect to other attributes of the key
1434 * such as the key type.
1435 */
1436static psa_status_t psa_validate_key_policy( const psa_key_policy_t *policy )
Gilles Peskine4747d192019-04-17 15:05:45 +02001437{
1438 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
Gilles Peskine8e0206a2019-05-14 14:24:28 +02001439 PSA_KEY_USAGE_COPY |
Gilles Peskine4747d192019-04-17 15:05:45 +02001440 PSA_KEY_USAGE_ENCRYPT |
1441 PSA_KEY_USAGE_DECRYPT |
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01001442 PSA_KEY_USAGE_SIGN_HASH |
1443 PSA_KEY_USAGE_VERIFY_HASH |
Gilles Peskine4747d192019-04-17 15:05:45 +02001444 PSA_KEY_USAGE_DERIVE ) ) != 0 )
1445 return( PSA_ERROR_INVALID_ARGUMENT );
1446
Gilles Peskine4747d192019-04-17 15:05:45 +02001447 return( PSA_SUCCESS );
1448}
1449
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001450/** Validate the internal consistency of key attributes.
1451 *
1452 * This function only rejects invalid attribute values. If does not
1453 * validate the consistency of the attributes with any key data that may
1454 * be involved in the creation of the key.
1455 *
1456 * Call this function early in the key creation process.
1457 *
1458 * \param[in] attributes Key attributes for the new key.
1459 * \param[out] p_drv On any return, the driver for the key, if any.
1460 * NULL for a transparent key.
1461 *
1462 */
1463static psa_status_t psa_validate_key_attributes(
1464 const psa_key_attributes_t *attributes,
1465 psa_se_drv_table_entry_t **p_drv )
Darryl Green0c6575a2018-11-07 16:05:30 +00001466{
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001467 psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
Ronald Crond2ed4812020-07-17 16:11:30 +02001468 psa_key_lifetime_t lifetime = psa_get_key_lifetime( attributes );
Ronald Cron65f38a32020-10-23 17:11:13 +02001469 mbedtls_svc_key_id_t key = psa_get_key_id( attributes );
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001470
Ronald Cron54b90082020-10-29 15:26:43 +01001471 status = psa_validate_key_location( lifetime, p_drv );
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001472 if( status != PSA_SUCCESS )
1473 return( status );
1474
Ronald Crond2ed4812020-07-17 16:11:30 +02001475 status = psa_validate_key_persistence( lifetime );
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001476 if( status != PSA_SUCCESS )
1477 return( status );
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001478
Ronald Cron65f38a32020-10-23 17:11:13 +02001479 if ( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) )
1480 {
1481 if( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key ) != 0 )
1482 return( PSA_ERROR_INVALID_ARGUMENT );
1483 }
1484 else
Ronald Crond2ed4812020-07-17 16:11:30 +02001485 {
Ronald Croncbd7bea2020-11-11 14:57:44 +01001486 status = psa_validate_key_id( psa_get_key_id( attributes ), 0 );
Ronald Crond2ed4812020-07-17 16:11:30 +02001487 if( status != PSA_SUCCESS )
1488 return( status );
1489 }
1490
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001491 status = psa_validate_key_policy( &attributes->core.policy );
Darryl Green0c6575a2018-11-07 16:05:30 +00001492 if( status != PSA_SUCCESS )
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001493 return( status );
1494
1495 /* Refuse to create overly large keys.
1496 * Note that this doesn't trigger on import if the attributes don't
1497 * explicitly specify a size (so psa_get_key_bits returns 0), so
1498 * psa_import_key() needs its own checks. */
1499 if( psa_get_key_bits( attributes ) > PSA_MAX_KEY_BITS )
1500 return( PSA_ERROR_NOT_SUPPORTED );
1501
Gilles Peskine91e8c332019-08-02 19:19:39 +02001502 /* Reject invalid flags. These should not be reachable through the API. */
1503 if( attributes->core.flags & ~ ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1504 MBEDTLS_PSA_KA_MASK_DUAL_USE ) )
1505 return( PSA_ERROR_INVALID_ARGUMENT );
1506
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001507 return( PSA_SUCCESS );
1508}
1509
Gilles Peskine4747d192019-04-17 15:05:45 +02001510/** Prepare a key slot to receive key material.
1511 *
1512 * This function allocates a key slot and sets its metadata.
1513 *
1514 * If this function fails, call psa_fail_key_creation().
1515 *
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001516 * This function is intended to be used as follows:
1517 * -# Call psa_start_key_creation() to allocate a key slot, prepare
Ronald Croncf56a0a2020-08-04 09:51:30 +02001518 * it with the specified attributes, and in case of a volatile key assign it
1519 * a volatile key identifier.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001520 * -# Populate the slot with the key material.
1521 * -# Call psa_finish_key_creation() to finalize the creation of the slot.
1522 * In case of failure at any step, stop the sequence and call
1523 * psa_fail_key_creation().
1524 *
Ronald Cron5c522922020-11-14 16:35:34 +01001525 * On success, the key slot is locked. It is the responsibility of the caller
1526 * to unlock the key slot when it does not access it anymore.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001527 *
Gilles Peskinedf179142019-07-15 22:02:14 +02001528 * \param method An identification of the calling function.
Gilles Peskine011e4282019-06-26 18:34:38 +02001529 * \param[in] attributes Key attributes for the new key.
Gilles Peskine011e4282019-06-26 18:34:38 +02001530 * \param[out] p_slot On success, a pointer to the prepared slot.
1531 * \param[out] p_drv On any return, the driver for the key, if any.
1532 * NULL for a transparent key.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001533 *
1534 * \retval #PSA_SUCCESS
1535 * The key slot is ready to receive key material.
1536 * \return If this function fails, the key slot is an invalid state.
1537 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02001538 */
1539static psa_status_t psa_start_key_creation(
Gilles Peskinedf179142019-07-15 22:02:14 +02001540 psa_key_creation_method_t method,
Gilles Peskine4747d192019-04-17 15:05:45 +02001541 const psa_key_attributes_t *attributes,
Gilles Peskine011e4282019-06-26 18:34:38 +02001542 psa_key_slot_t **p_slot,
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001543 psa_se_drv_table_entry_t **p_drv )
Gilles Peskine4747d192019-04-17 15:05:45 +02001544{
1545 psa_status_t status;
Ronald Cron2a993152020-07-17 14:13:26 +02001546 psa_key_id_t volatile_key_id;
Gilles Peskine4747d192019-04-17 15:05:45 +02001547 psa_key_slot_t *slot;
1548
Gilles Peskinedf179142019-07-15 22:02:14 +02001549 (void) method;
Gilles Peskine011e4282019-06-26 18:34:38 +02001550 *p_drv = NULL;
1551
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001552 status = psa_validate_key_attributes( attributes, p_drv );
1553 if( status != PSA_SUCCESS )
1554 return( status );
1555
Ronald Cronc4d1b512020-07-31 11:26:37 +02001556 status = psa_get_empty_key_slot( &volatile_key_id, p_slot );
Gilles Peskine4747d192019-04-17 15:05:45 +02001557 if( status != PSA_SUCCESS )
1558 return( status );
1559 slot = *p_slot;
1560
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001561 /* We're storing the declared bit-size of the key. It's up to each
1562 * creation mechanism to verify that this information is correct.
1563 * It's automatically correct for mechanisms that use the bit-size as
Gilles Peskineb46bef22019-07-30 21:32:04 +02001564 * an input (generate, device) but not for those where the bit-size
Ronald Cronc4d1b512020-07-31 11:26:37 +02001565 * is optional (import, copy). In case of a volatile key, assign it the
1566 * volatile key identifier associated to the slot returned to contain its
1567 * definition. */
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001568
1569 slot->attr = attributes->core;
Ronald Cronc4d1b512020-07-31 11:26:37 +02001570 if( PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
1571 {
1572#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
1573 slot->attr.id = volatile_key_id;
1574#else
1575 slot->attr.id.key_id = volatile_key_id;
1576#endif
1577 }
Gilles Peskinec744d992019-07-30 17:26:54 +02001578
Gilles Peskine91e8c332019-08-02 19:19:39 +02001579 /* Erase external-only flags from the internal copy. To access
Gilles Peskine013f5472019-08-07 15:42:14 +02001580 * external-only flags, query `attributes`. Thanks to the check
1581 * in psa_validate_key_attributes(), this leaves the dual-use
Gilles Peskineedbed562019-08-07 18:19:59 +02001582 * flags and any internal flag that psa_get_empty_key_slot()
Gilles Peskine013f5472019-08-07 15:42:14 +02001583 * may have set. */
1584 slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
Gilles Peskine91e8c332019-08-02 19:19:39 +02001585
Gilles Peskinecbaff462019-07-12 23:46:04 +02001586#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02001587 /* For a key in a secure element, we need to do three things
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001588 * when creating or registering a persistent key:
Gilles Peskine60450a42019-07-25 11:32:45 +02001589 * create the key file in internal storage, create the
1590 * key inside the secure element, and update the driver's
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001591 * persistent data. This is done by starting a transaction that will
1592 * encompass these three actions.
1593 * For registering a volatile key, we just need to find an appropriate
1594 * slot number inside the SE. Since the key is designated volatile, creating
1595 * a transaction is not required. */
Gilles Peskine60450a42019-07-25 11:32:45 +02001596 /* The first thing to do is to find a slot number for the new key.
1597 * We save the slot number in persistent storage as part of the
1598 * transaction data. It will be needed to recover if the power
1599 * fails during the key creation process, to clean up on the secure
1600 * element side after restarting. Obtaining a slot number from the
1601 * secure element driver updates its persistent state, but we do not yet
1602 * save the driver's persistent state, so that if the power fails,
Gilles Peskinefc762652019-07-22 19:30:34 +02001603 * we can roll back to a state where the key doesn't exist. */
Gilles Peskine3efcebb2019-10-01 14:18:35 +02001604 if( *p_drv != NULL )
Darryl Green0c6575a2018-11-07 16:05:30 +00001605 {
Ronald Cronea0f8a62020-11-25 17:52:23 +01001606 psa_key_slot_number_t slot_number;
Gilles Peskinee88c2c12019-08-05 16:44:14 +02001607 status = psa_find_se_slot_for_key( attributes, method, *p_drv,
Ronald Cronea0f8a62020-11-25 17:52:23 +01001608 &slot_number );
Gilles Peskinecbaff462019-07-12 23:46:04 +02001609 if( status != PSA_SUCCESS )
1610 return( status );
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001611
1612 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( attributes->core.lifetime ) )
Gilles Peskine66be51c2019-07-25 18:02:52 +02001613 {
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001614 psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_CREATE_KEY );
1615 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
Ronald Cronea0f8a62020-11-25 17:52:23 +01001616 psa_crypto_transaction.key.slot = slot_number;
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001617 psa_crypto_transaction.key.id = slot->attr.id;
1618 status = psa_crypto_save_transaction( );
1619 if( status != PSA_SUCCESS )
1620 {
1621 (void) psa_crypto_stop_transaction( );
1622 return( status );
1623 }
Gilles Peskine66be51c2019-07-25 18:02:52 +02001624 }
Ronald Cronea0f8a62020-11-25 17:52:23 +01001625
1626 status = psa_copy_key_material_into_slot(
1627 slot, (uint8_t *)( &slot_number ), sizeof( slot_number ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00001628 }
Gilles Peskine3efcebb2019-10-01 14:18:35 +02001629
1630 if( *p_drv == NULL && method == PSA_KEY_CREATION_REGISTER )
1631 {
1632 /* Key registration only makes sense with a secure element. */
1633 return( PSA_ERROR_INVALID_ARGUMENT );
1634 }
Gilles Peskinecbaff462019-07-12 23:46:04 +02001635#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1636
Ronald Cronc4d1b512020-07-31 11:26:37 +02001637 return( PSA_SUCCESS );
Darryl Green0c6575a2018-11-07 16:05:30 +00001638}
Gilles Peskine4747d192019-04-17 15:05:45 +02001639
1640/** Finalize the creation of a key once its key material has been set.
1641 *
1642 * This entails writing the key to persistent storage.
1643 *
1644 * If this function fails, call psa_fail_key_creation().
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001645 * See the documentation of psa_start_key_creation() for the intended use
1646 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02001647 *
Ronald Cron5c522922020-11-14 16:35:34 +01001648 * If the finalization succeeds, the function unlocks the key slot (it was
1649 * locked by psa_start_key_creation()) and the key slot cannot be accessed
1650 * anymore as part of the key creation process.
Ronald Cron50972942020-11-14 11:28:25 +01001651 *
Gilles Peskine011e4282019-06-26 18:34:38 +02001652 * \param[in,out] slot Pointer to the slot with key material.
1653 * \param[in] driver The secure element driver for the key,
1654 * or NULL for a transparent key.
Ronald Cron81709fc2020-11-14 12:10:32 +01001655 * \param[out] key On success, identifier of the key. Note that the
1656 * key identifier is also stored in the key slot.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001657 *
1658 * \retval #PSA_SUCCESS
Ronald Croncf56a0a2020-08-04 09:51:30 +02001659 * The key was successfully created.
gabor-mezei-arm452b0a32020-11-09 17:42:55 +01001660 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
1661 * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
1662 * \retval #PSA_ERROR_ALREADY_EXISTS
1663 * \retval #PSA_ERROR_DATA_INVALID
1664 * \retval #PSA_ERROR_DATA_CORRUPT
gabor-mezei-arm86326a92020-11-30 16:50:34 +01001665 * \retval #PSA_ERROR_STORAGE_FAILURE
gabor-mezei-arm452b0a32020-11-09 17:42:55 +01001666 *
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001667 * \return If this function fails, the key slot is an invalid state.
1668 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02001669 */
Gilles Peskine011e4282019-06-26 18:34:38 +02001670static psa_status_t psa_finish_key_creation(
1671 psa_key_slot_t *slot,
Ronald Cron81709fc2020-11-14 12:10:32 +01001672 psa_se_drv_table_entry_t *driver,
1673 mbedtls_svc_key_id_t *key)
Gilles Peskine4747d192019-04-17 15:05:45 +02001674{
1675 psa_status_t status = PSA_SUCCESS;
Gilles Peskine30afafd2019-04-25 13:47:40 +02001676 (void) slot;
Gilles Peskine011e4282019-06-26 18:34:38 +02001677 (void) driver;
Gilles Peskine4747d192019-04-17 15:05:45 +02001678
1679#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Steven Cooremanc59de6a2020-06-08 18:28:25 +02001680 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
Gilles Peskine4747d192019-04-17 15:05:45 +02001681 {
Gilles Peskine1df83d42019-07-23 16:13:14 +02001682#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1683 if( driver != NULL )
1684 {
Gilles Peskineb46bef22019-07-30 21:32:04 +02001685 psa_se_key_data_storage_t data;
Ronald Cronea0f8a62020-11-25 17:52:23 +01001686 psa_key_slot_number_t slot_number =
1687 psa_key_slot_get_slot_number( slot ) ;
1688
Gilles Peskineb46bef22019-07-30 21:32:04 +02001689#if defined(static_assert)
Ronald Cronea0f8a62020-11-25 17:52:23 +01001690 static_assert( sizeof( slot_number ) ==
Gilles Peskineb46bef22019-07-30 21:32:04 +02001691 sizeof( data.slot_number ),
1692 "Slot number size does not match psa_se_key_data_storage_t" );
Gilles Peskineb46bef22019-07-30 21:32:04 +02001693#endif
Ronald Cronea0f8a62020-11-25 17:52:23 +01001694 memcpy( &data.slot_number, &slot_number, sizeof( slot_number ) );
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001695 status = psa_save_persistent_key( &slot->attr,
Gilles Peskineb46bef22019-07-30 21:32:04 +02001696 (uint8_t*) &data,
1697 sizeof( data ) );
Gilles Peskine1df83d42019-07-23 16:13:14 +02001698 }
1699 else
1700#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1701 {
Steven Cooreman40120f62020-10-29 11:42:22 +01001702 /* Key material is saved in export representation in the slot, so
1703 * just pass the slot buffer for storage. */
1704 status = psa_save_persistent_key( &slot->attr,
Ronald Cronea0f8a62020-11-25 17:52:23 +01001705 slot->key.data,
1706 slot->key.bytes );
Gilles Peskine1df83d42019-07-23 16:13:14 +02001707 }
Gilles Peskine4747d192019-04-17 15:05:45 +02001708 }
Darryl Green0c6575a2018-11-07 16:05:30 +00001709#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1710
Gilles Peskinecbaff462019-07-12 23:46:04 +02001711#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02001712 /* Finish the transaction for a key creation. This does not
1713 * happen when registering an existing key. Detect this case
1714 * by checking whether a transaction is in progress (actual
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001715 * creation of a persistent key in a secure element requires a transaction,
1716 * but registration or volatile key creation doesn't use one). */
Gilles Peskined7729582019-08-05 15:55:54 +02001717 if( driver != NULL &&
1718 psa_crypto_transaction.unknown.type == PSA_CRYPTO_TRANSACTION_CREATE_KEY )
Gilles Peskinecbaff462019-07-12 23:46:04 +02001719 {
1720 status = psa_save_se_persistent_data( driver );
1721 if( status != PSA_SUCCESS )
1722 {
Gilles Peskine8e338702019-07-30 20:06:31 +02001723 psa_destroy_persistent_key( slot->attr.id );
Gilles Peskinecbaff462019-07-12 23:46:04 +02001724 return( status );
1725 }
Gilles Peskinefc762652019-07-22 19:30:34 +02001726 status = psa_crypto_stop_transaction( );
Gilles Peskinecbaff462019-07-12 23:46:04 +02001727 }
1728#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1729
Ronald Cron50972942020-11-14 11:28:25 +01001730 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01001731 {
1732 *key = slot->attr.id;
Ronald Cron5c522922020-11-14 16:35:34 +01001733 status = psa_unlock_key_slot( slot );
Ronald Cron81709fc2020-11-14 12:10:32 +01001734 if( status != PSA_SUCCESS )
1735 *key = MBEDTLS_SVC_KEY_ID_INIT;
1736 }
Ronald Cron50972942020-11-14 11:28:25 +01001737
Gilles Peskine4747d192019-04-17 15:05:45 +02001738 return( status );
1739}
1740
1741/** Abort the creation of a key.
1742 *
1743 * You may call this function after calling psa_start_key_creation(),
1744 * or after psa_finish_key_creation() fails. In other circumstances, this
1745 * function may not clean up persistent storage.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001746 * See the documentation of psa_start_key_creation() for the intended use
1747 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02001748 *
Gilles Peskine011e4282019-06-26 18:34:38 +02001749 * \param[in,out] slot Pointer to the slot with key material.
1750 * \param[in] driver The secure element driver for the key,
1751 * or NULL for a transparent key.
Gilles Peskine4747d192019-04-17 15:05:45 +02001752 */
Gilles Peskine011e4282019-06-26 18:34:38 +02001753static void psa_fail_key_creation( psa_key_slot_t *slot,
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001754 psa_se_drv_table_entry_t *driver )
Gilles Peskine4747d192019-04-17 15:05:45 +02001755{
Gilles Peskine011e4282019-06-26 18:34:38 +02001756 (void) driver;
1757
Gilles Peskine4747d192019-04-17 15:05:45 +02001758 if( slot == NULL )
1759 return;
Gilles Peskine011e4282019-06-26 18:34:38 +02001760
1761#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01001762 /* TODO: If the key has already been created in the secure
Gilles Peskine011e4282019-06-26 18:34:38 +02001763 * element, and the failure happened later (when saving metadata
1764 * to internal storage), we need to destroy the key in the secure
Gilles Peskinec9d7f942019-08-13 16:17:16 +02001765 * element.
1766 * https://github.com/ARMmbed/mbed-crypto/issues/217
1767 */
Gilles Peskinefc762652019-07-22 19:30:34 +02001768
Gilles Peskined7729582019-08-05 15:55:54 +02001769 /* Abort the ongoing transaction if any (there may not be one if
1770 * the creation process failed before starting one, or if the
1771 * key creation is a registration of a key in a secure element).
1772 * Earlier functions must already have done what it takes to undo any
1773 * partial creation. All that's left is to update the transaction data
1774 * itself. */
Gilles Peskinefc762652019-07-22 19:30:34 +02001775 (void) psa_crypto_stop_transaction( );
Gilles Peskine011e4282019-06-26 18:34:38 +02001776#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1777
Gilles Peskine4747d192019-04-17 15:05:45 +02001778 psa_wipe_key_slot( slot );
1779}
1780
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001781/** Validate optional attributes during key creation.
1782 *
1783 * Some key attributes are optional during key creation. If they are
1784 * specified in the attributes structure, check that they are consistent
1785 * with the data in the slot.
1786 *
1787 * This function should be called near the end of key creation, after
1788 * the slot in memory is fully populated but before saving persistent data.
1789 */
1790static psa_status_t psa_validate_optional_attributes(
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001791 const psa_key_slot_t *slot,
1792 const psa_key_attributes_t *attributes )
1793{
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001794 if( attributes->core.type != 0 )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001795 {
Gilles Peskine8e338702019-07-30 20:06:31 +02001796 if( attributes->core.type != slot->attr.type )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001797 return( PSA_ERROR_INVALID_ARGUMENT );
1798 }
1799
1800 if( attributes->domain_parameters_size != 0 )
1801 {
John Durkop0e005192020-10-31 22:06:54 -07001802#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1803 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskine8e338702019-07-30 20:06:31 +02001804 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001805 {
Steven Cooremana2371e52020-07-28 14:30:39 +02001806 mbedtls_rsa_context *rsa = NULL;
Steven Cooreman75b74362020-07-28 14:30:13 +02001807 mbedtls_mpi actual, required;
Steven Cooreman6d839f02020-07-30 11:36:45 +02001808 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooremana01795d2020-07-24 22:48:15 +02001809
Ronald Cron90857082020-11-25 14:58:33 +01001810 psa_status_t status = mbedtls_psa_rsa_load_representation(
1811 slot->attr.type,
1812 slot->key.data,
1813 slot->key.bytes,
1814 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001815 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02001816 return( status );
Steven Cooreman75b74362020-07-28 14:30:13 +02001817
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001818 mbedtls_mpi_init( &actual );
1819 mbedtls_mpi_init( &required );
Steven Cooremana2371e52020-07-28 14:30:39 +02001820 ret = mbedtls_rsa_export( rsa,
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001821 NULL, NULL, NULL, NULL, &actual );
Steven Cooremana2371e52020-07-28 14:30:39 +02001822 mbedtls_rsa_free( rsa );
1823 mbedtls_free( rsa );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001824 if( ret != 0 )
1825 goto rsa_exit;
1826 ret = mbedtls_mpi_read_binary( &required,
1827 attributes->domain_parameters,
1828 attributes->domain_parameters_size );
1829 if( ret != 0 )
1830 goto rsa_exit;
1831 if( mbedtls_mpi_cmp_mpi( &actual, &required ) != 0 )
1832 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1833 rsa_exit:
1834 mbedtls_mpi_free( &actual );
1835 mbedtls_mpi_free( &required );
1836 if( ret != 0)
1837 return( mbedtls_to_psa_error( ret ) );
1838 }
1839 else
John Durkop9814fa22020-11-04 12:28:15 -08001840#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1841 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001842 {
1843 return( PSA_ERROR_INVALID_ARGUMENT );
1844 }
1845 }
1846
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001847 if( attributes->core.bits != 0 )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001848 {
Gilles Peskineb46bef22019-07-30 21:32:04 +02001849 if( attributes->core.bits != slot->attr.bits )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001850 return( PSA_ERROR_INVALID_ARGUMENT );
1851 }
1852
1853 return( PSA_SUCCESS );
1854}
1855
Gilles Peskine4747d192019-04-17 15:05:45 +02001856psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
Gilles Peskine4747d192019-04-17 15:05:45 +02001857 const uint8_t *data,
Gilles Peskine73676cb2019-05-15 20:15:10 +02001858 size_t data_length,
Ronald Croncf56a0a2020-08-04 09:51:30 +02001859 mbedtls_svc_key_id_t *key )
Gilles Peskine4747d192019-04-17 15:05:45 +02001860{
1861 psa_status_t status;
1862 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001863 psa_se_drv_table_entry_t *driver = NULL;
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001864 size_t bits;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001865
Ronald Cron81709fc2020-11-14 12:10:32 +01001866 *key = MBEDTLS_SVC_KEY_ID_INIT;
1867
Gilles Peskine0f84d622019-09-12 19:03:13 +02001868 /* Reject zero-length symmetric keys (including raw data key objects).
1869 * This also rejects any key which might be encoded as an empty string,
1870 * which is never valid. */
1871 if( data_length == 0 )
1872 return( PSA_ERROR_INVALID_ARGUMENT );
1873
Gilles Peskinedf179142019-07-15 22:02:14 +02001874 status = psa_start_key_creation( PSA_KEY_CREATION_IMPORT, attributes,
Ronald Cron81709fc2020-11-14 12:10:32 +01001875 &slot, &driver );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001876 if( status != PSA_SUCCESS )
1877 goto exit;
1878
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001879 /* In the case of a transparent key or an opaque key stored in local
1880 * storage (thus not in the case of generating a key in a secure element
1881 * or cryptoprocessor with storage), we have to allocate a buffer to
1882 * hold the generated key material. */
1883 if( slot->key.data == NULL )
Gilles Peskine5d309672019-07-12 23:47:28 +02001884 {
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001885 status = psa_allocate_buffer_to_slot( slot, data_length );
Gilles Peskineb46bef22019-07-30 21:32:04 +02001886 if( status != PSA_SUCCESS )
1887 goto exit;
Gilles Peskine5d309672019-07-12 23:47:28 +02001888 }
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001889
1890 bits = slot->attr.bits;
1891 status = psa_driver_wrapper_import_key( attributes,
1892 data, data_length,
1893 slot->key.data,
1894 slot->key.bytes,
1895 &slot->key.bytes, &bits );
1896 if( status != PSA_SUCCESS )
1897 goto exit;
1898
1899 if( slot->attr.bits == 0 )
1900 slot->attr.bits = (psa_key_bits_t) bits;
1901 else if( bits != slot->attr.bits )
Steven Cooremanac3434f2021-01-15 17:36:02 +01001902 {
Steven Cooremanac3434f2021-01-15 17:36:02 +01001903 status = PSA_ERROR_INVALID_ARGUMENT;
1904 goto exit;
Gilles Peskine5d309672019-07-12 23:47:28 +02001905 }
Ronald Cron2ebfdcc2020-11-28 15:54:54 +01001906
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001907 status = psa_validate_optional_attributes( slot, attributes );
Gilles Peskine18017402019-07-24 20:25:59 +02001908 if( status != PSA_SUCCESS )
1909 goto exit;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001910
Ronald Cron81709fc2020-11-14 12:10:32 +01001911 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001912exit:
Gilles Peskine4747d192019-04-17 15:05:45 +02001913 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02001914 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001915
Gilles Peskine4747d192019-04-17 15:05:45 +02001916 return( status );
1917}
1918
Gilles Peskined7729582019-08-05 15:55:54 +02001919#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1920psa_status_t mbedtls_psa_register_se_key(
1921 const psa_key_attributes_t *attributes )
1922{
1923 psa_status_t status;
1924 psa_key_slot_t *slot = NULL;
1925 psa_se_drv_table_entry_t *driver = NULL;
Ronald Croncf56a0a2020-08-04 09:51:30 +02001926 mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
Gilles Peskined7729582019-08-05 15:55:54 +02001927
1928 /* Leaving attributes unspecified is not currently supported.
1929 * It could make sense to query the key type and size from the
1930 * secure element, but not all secure elements support this
1931 * and the driver HAL doesn't currently support it. */
1932 if( psa_get_key_type( attributes ) == PSA_KEY_TYPE_NONE )
1933 return( PSA_ERROR_NOT_SUPPORTED );
1934 if( psa_get_key_bits( attributes ) == 0 )
1935 return( PSA_ERROR_NOT_SUPPORTED );
1936
1937 status = psa_start_key_creation( PSA_KEY_CREATION_REGISTER, attributes,
Ronald Cron81709fc2020-11-14 12:10:32 +01001938 &slot, &driver );
Gilles Peskined7729582019-08-05 15:55:54 +02001939 if( status != PSA_SUCCESS )
1940 goto exit;
1941
Ronald Cron81709fc2020-11-14 12:10:32 +01001942 status = psa_finish_key_creation( slot, driver, &key );
Gilles Peskined7729582019-08-05 15:55:54 +02001943
1944exit:
1945 if( status != PSA_SUCCESS )
Gilles Peskined7729582019-08-05 15:55:54 +02001946 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001947
Gilles Peskined7729582019-08-05 15:55:54 +02001948 /* Registration doesn't keep the key in RAM. */
Ronald Croncf56a0a2020-08-04 09:51:30 +02001949 psa_close_key( key );
Gilles Peskined7729582019-08-05 15:55:54 +02001950 return( status );
1951}
1952#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1953
Gilles Peskinef603c712019-01-19 13:40:11 +01001954static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001955 psa_key_slot_t *target )
Gilles Peskinef603c712019-01-19 13:40:11 +01001956{
Steven Cooremanf7cebd42020-10-13 20:27:40 +02001957 psa_status_t status = psa_copy_key_material_into_slot( target,
Ronald Cronea0f8a62020-11-25 17:52:23 +01001958 source->key.data,
1959 source->key.bytes );
Gilles Peskinef603c712019-01-19 13:40:11 +01001960 if( status != PSA_SUCCESS )
Steven Cooreman398aee52020-10-13 14:35:45 +02001961 return( status );
Gilles Peskinef603c712019-01-19 13:40:11 +01001962
Steven Cooreman398aee52020-10-13 14:35:45 +02001963 target->attr.type = source->attr.type;
1964 target->attr.bits = source->attr.bits;
1965
1966 return( PSA_SUCCESS );
Gilles Peskinef603c712019-01-19 13:40:11 +01001967}
1968
Ronald Croncf56a0a2020-08-04 09:51:30 +02001969psa_status_t psa_copy_key( mbedtls_svc_key_id_t source_key,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001970 const psa_key_attributes_t *specified_attributes,
Ronald Croncf56a0a2020-08-04 09:51:30 +02001971 mbedtls_svc_key_id_t *target_key )
Gilles Peskinef603c712019-01-19 13:40:11 +01001972{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001973 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001974 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskinef603c712019-01-19 13:40:11 +01001975 psa_key_slot_t *source_slot = NULL;
1976 psa_key_slot_t *target_slot = NULL;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001977 psa_key_attributes_t actual_attributes = *specified_attributes;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001978 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskinef603c712019-01-19 13:40:11 +01001979
Ronald Cron81709fc2020-11-14 12:10:32 +01001980 *target_key = MBEDTLS_SVC_KEY_ID_INIT;
1981
Ronald Cron5c522922020-11-14 16:35:34 +01001982 status = psa_get_and_lock_transparent_key_slot_with_policy(
1983 source_key, &source_slot, PSA_KEY_USAGE_COPY, 0 );
Gilles Peskinef603c712019-01-19 13:40:11 +01001984 if( status != PSA_SUCCESS )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001985 goto exit;
1986
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001987 status = psa_validate_optional_attributes( source_slot,
1988 specified_attributes );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001989 if( status != PSA_SUCCESS )
1990 goto exit;
1991
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001992 status = psa_restrict_key_policy( &actual_attributes.core.policy,
Gilles Peskine8e338702019-07-30 20:06:31 +02001993 &source_slot->attr.policy );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001994 if( status != PSA_SUCCESS )
1995 goto exit;
1996
Ronald Cron81709fc2020-11-14 12:10:32 +01001997 status = psa_start_key_creation( PSA_KEY_CREATION_COPY, &actual_attributes,
1998 &target_slot, &driver );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001999 if( status != PSA_SUCCESS )
2000 goto exit;
2001
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002002#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2003 if( driver != NULL )
Gilles Peskinef603c712019-01-19 13:40:11 +01002004 {
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002005 /* Copying to a secure element is not implemented yet. */
2006 status = PSA_ERROR_NOT_SUPPORTED;
2007 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01002008 }
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002009#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinef603c712019-01-19 13:40:11 +01002010
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002011 status = psa_copy_key_material( source_slot, target_slot );
Gilles Peskinef603c712019-01-19 13:40:11 +01002012 if( status != PSA_SUCCESS )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002013 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01002014
Ronald Cron81709fc2020-11-14 12:10:32 +01002015 status = psa_finish_key_creation( target_slot, driver, target_key );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002016exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002017 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02002018 psa_fail_key_creation( target_slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002019
Ronald Cron5c522922020-11-14 16:35:34 +01002020 unlock_status = psa_unlock_key_slot( source_slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002021
Ronald Cron5c522922020-11-14 16:35:34 +01002022 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskinef603c712019-01-19 13:40:11 +01002023}
2024
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002025
2026
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002027/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01002028/* Message digests */
2029/****************************************************************/
2030
John Durkop07cc04a2020-11-16 22:08:34 -08002031#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
John Durkop0e005192020-10-31 22:06:54 -07002032 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
2033 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
John Durkop9814fa22020-11-04 12:28:15 -08002034 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinedc2fc842018-03-07 16:42:59 +01002035static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01002036{
2037 switch( alg )
2038 {
John Durkopee4e6602020-11-27 08:48:46 -08002039#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine20035e32018-02-03 22:44:14 +01002040 case PSA_ALG_MD2:
2041 return( &mbedtls_md2_info );
2042#endif
John Durkopee4e6602020-11-27 08:48:46 -08002043#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine20035e32018-02-03 22:44:14 +01002044 case PSA_ALG_MD4:
2045 return( &mbedtls_md4_info );
2046#endif
John Durkopee4e6602020-11-27 08:48:46 -08002047#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine20035e32018-02-03 22:44:14 +01002048 case PSA_ALG_MD5:
2049 return( &mbedtls_md5_info );
2050#endif
John Durkopee4e6602020-11-27 08:48:46 -08002051#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine20035e32018-02-03 22:44:14 +01002052 case PSA_ALG_RIPEMD160:
2053 return( &mbedtls_ripemd160_info );
2054#endif
John Durkopee4e6602020-11-27 08:48:46 -08002055#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine20035e32018-02-03 22:44:14 +01002056 case PSA_ALG_SHA_1:
2057 return( &mbedtls_sha1_info );
2058#endif
John Durkopee4e6602020-11-27 08:48:46 -08002059#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine20035e32018-02-03 22:44:14 +01002060 case PSA_ALG_SHA_224:
2061 return( &mbedtls_sha224_info );
John Durkopee4e6602020-11-27 08:48:46 -08002062#endif
2063#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine20035e32018-02-03 22:44:14 +01002064 case PSA_ALG_SHA_256:
2065 return( &mbedtls_sha256_info );
2066#endif
John Durkopee4e6602020-11-27 08:48:46 -08002067#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine20035e32018-02-03 22:44:14 +01002068 case PSA_ALG_SHA_384:
2069 return( &mbedtls_sha384_info );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +02002070#endif
John Durkopee4e6602020-11-27 08:48:46 -08002071#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine20035e32018-02-03 22:44:14 +01002072 case PSA_ALG_SHA_512:
2073 return( &mbedtls_sha512_info );
2074#endif
2075 default:
2076 return( NULL );
2077 }
2078}
John Durkop07cc04a2020-11-16 22:08:34 -08002079#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
John Durkop9814fa22020-11-04 12:28:15 -08002080 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
2081 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
2082 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskine20035e32018-02-03 22:44:14 +01002083
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002084psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
2085{
2086 switch( operation->alg )
2087 {
Gilles Peskine81736312018-06-26 15:04:31 +02002088 case 0:
2089 /* The object has (apparently) been initialized but it is not
2090 * in use. It's ok to call abort on such an object, and there's
2091 * nothing to do. */
2092 break;
John Durkopee4e6602020-11-27 08:48:46 -08002093#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002094 case PSA_ALG_MD2:
2095 mbedtls_md2_free( &operation->ctx.md2 );
2096 break;
2097#endif
John Durkopee4e6602020-11-27 08:48:46 -08002098#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002099 case PSA_ALG_MD4:
2100 mbedtls_md4_free( &operation->ctx.md4 );
2101 break;
2102#endif
John Durkopee4e6602020-11-27 08:48:46 -08002103#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002104 case PSA_ALG_MD5:
2105 mbedtls_md5_free( &operation->ctx.md5 );
2106 break;
2107#endif
John Durkopee4e6602020-11-27 08:48:46 -08002108#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002109 case PSA_ALG_RIPEMD160:
2110 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
2111 break;
2112#endif
John Durkopee4e6602020-11-27 08:48:46 -08002113#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002114 case PSA_ALG_SHA_1:
2115 mbedtls_sha1_free( &operation->ctx.sha1 );
2116 break;
2117#endif
John Durkop6ca23272020-12-03 06:01:32 -08002118#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002119 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002120 mbedtls_sha256_free( &operation->ctx.sha256 );
2121 break;
2122#endif
2123#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002124 case PSA_ALG_SHA_256:
2125 mbedtls_sha256_free( &operation->ctx.sha256 );
2126 break;
2127#endif
John Durkop6ca23272020-12-03 06:01:32 -08002128#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002129 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002130 mbedtls_sha512_free( &operation->ctx.sha512 );
2131 break;
2132#endif
2133#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002134 case PSA_ALG_SHA_512:
2135 mbedtls_sha512_free( &operation->ctx.sha512 );
2136 break;
2137#endif
2138 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002139 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002140 }
2141 operation->alg = 0;
2142 return( PSA_SUCCESS );
2143}
2144
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002145psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002146 psa_algorithm_t alg )
2147{
Janos Follath24eed8d2019-11-22 13:21:35 +00002148 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002149
2150 /* A context must be freshly initialized before it can be set up. */
2151 if( operation->alg != 0 )
2152 {
2153 return( PSA_ERROR_BAD_STATE );
2154 }
2155
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002156 switch( alg )
2157 {
John Durkopee4e6602020-11-27 08:48:46 -08002158#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002159 case PSA_ALG_MD2:
2160 mbedtls_md2_init( &operation->ctx.md2 );
2161 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
2162 break;
2163#endif
John Durkopee4e6602020-11-27 08:48:46 -08002164#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002165 case PSA_ALG_MD4:
2166 mbedtls_md4_init( &operation->ctx.md4 );
2167 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
2168 break;
2169#endif
John Durkopee4e6602020-11-27 08:48:46 -08002170#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002171 case PSA_ALG_MD5:
2172 mbedtls_md5_init( &operation->ctx.md5 );
2173 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
2174 break;
2175#endif
John Durkopee4e6602020-11-27 08:48:46 -08002176#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002177 case PSA_ALG_RIPEMD160:
2178 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
2179 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
2180 break;
2181#endif
John Durkopee4e6602020-11-27 08:48:46 -08002182#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002183 case PSA_ALG_SHA_1:
2184 mbedtls_sha1_init( &operation->ctx.sha1 );
2185 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
2186 break;
2187#endif
John Durkopee4e6602020-11-27 08:48:46 -08002188#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002189 case PSA_ALG_SHA_224:
2190 mbedtls_sha256_init( &operation->ctx.sha256 );
2191 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
2192 break;
John Durkopee4e6602020-11-27 08:48:46 -08002193#endif
2194#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002195 case PSA_ALG_SHA_256:
2196 mbedtls_sha256_init( &operation->ctx.sha256 );
2197 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
2198 break;
2199#endif
John Durkopee4e6602020-11-27 08:48:46 -08002200#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002201 case PSA_ALG_SHA_384:
2202 mbedtls_sha512_init( &operation->ctx.sha512 );
2203 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
2204 break;
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002205#endif
John Durkopee4e6602020-11-27 08:48:46 -08002206#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002207 case PSA_ALG_SHA_512:
2208 mbedtls_sha512_init( &operation->ctx.sha512 );
2209 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
2210 break;
2211#endif
2212 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02002213 return( PSA_ALG_IS_HASH( alg ) ?
2214 PSA_ERROR_NOT_SUPPORTED :
2215 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002216 }
2217 if( ret == 0 )
2218 operation->alg = alg;
2219 else
2220 psa_hash_abort( operation );
2221 return( mbedtls_to_psa_error( ret ) );
2222}
2223
2224psa_status_t psa_hash_update( psa_hash_operation_t *operation,
2225 const uint8_t *input,
2226 size_t input_length )
2227{
Janos Follath24eed8d2019-11-22 13:21:35 +00002228 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine94e44542018-07-12 16:58:43 +02002229
2230 /* Don't require hash implementations to behave correctly on a
2231 * zero-length input, which may have an invalid pointer. */
2232 if( input_length == 0 )
2233 return( PSA_SUCCESS );
2234
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002235 switch( operation->alg )
2236 {
John Durkopee4e6602020-11-27 08:48:46 -08002237#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002238 case PSA_ALG_MD2:
2239 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
2240 input, input_length );
2241 break;
2242#endif
John Durkopee4e6602020-11-27 08:48:46 -08002243#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002244 case PSA_ALG_MD4:
2245 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
2246 input, input_length );
2247 break;
2248#endif
John Durkopee4e6602020-11-27 08:48:46 -08002249#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002250 case PSA_ALG_MD5:
2251 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
2252 input, input_length );
2253 break;
2254#endif
John Durkopee4e6602020-11-27 08:48:46 -08002255#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002256 case PSA_ALG_RIPEMD160:
2257 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
2258 input, input_length );
2259 break;
2260#endif
John Durkopee4e6602020-11-27 08:48:46 -08002261#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002262 case PSA_ALG_SHA_1:
2263 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
2264 input, input_length );
2265 break;
2266#endif
John Durkop6ca23272020-12-03 06:01:32 -08002267#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002268 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002269 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
2270 input, input_length );
2271 break;
2272#endif
2273#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002274 case PSA_ALG_SHA_256:
2275 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
2276 input, input_length );
2277 break;
2278#endif
John Durkop6ca23272020-12-03 06:01:32 -08002279#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002280 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002281 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
2282 input, input_length );
2283 break;
2284#endif
2285#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002286 case PSA_ALG_SHA_512:
2287 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
2288 input, input_length );
2289 break;
2290#endif
2291 default:
John Durkopee4e6602020-11-27 08:48:46 -08002292 (void)input;
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002293 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002294 }
Gilles Peskine94e44542018-07-12 16:58:43 +02002295
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002296 if( ret != 0 )
2297 psa_hash_abort( operation );
2298 return( mbedtls_to_psa_error( ret ) );
2299}
2300
2301psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
2302 uint8_t *hash,
2303 size_t hash_size,
2304 size_t *hash_length )
2305{
itayzafrir40835d42018-08-02 13:14:17 +03002306 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00002307 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
gabor-mezei-armcbcec212020-12-18 14:23:51 +01002308 size_t actual_hash_length = PSA_HASH_LENGTH( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002309
2310 /* Fill the output buffer with something that isn't a valid hash
2311 * (barring an attack on the hash and deliberately-crafted input),
2312 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02002313 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002314 /* If hash_size is 0 then hash may be NULL and then the
2315 * call to memset would have undefined behavior. */
2316 if( hash_size != 0 )
2317 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002318
2319 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03002320 {
2321 status = PSA_ERROR_BUFFER_TOO_SMALL;
2322 goto exit;
2323 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002324
2325 switch( operation->alg )
2326 {
John Durkopee4e6602020-11-27 08:48:46 -08002327#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002328 case PSA_ALG_MD2:
2329 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
2330 break;
2331#endif
John Durkopee4e6602020-11-27 08:48:46 -08002332#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002333 case PSA_ALG_MD4:
2334 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
2335 break;
2336#endif
John Durkopee4e6602020-11-27 08:48:46 -08002337#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002338 case PSA_ALG_MD5:
2339 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
2340 break;
2341#endif
John Durkopee4e6602020-11-27 08:48:46 -08002342#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002343 case PSA_ALG_RIPEMD160:
2344 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
2345 break;
2346#endif
John Durkopee4e6602020-11-27 08:48:46 -08002347#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002348 case PSA_ALG_SHA_1:
2349 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
2350 break;
2351#endif
John Durkop6ca23272020-12-03 06:01:32 -08002352#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002353 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002354 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
2355 break;
2356#endif
2357#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002358 case PSA_ALG_SHA_256:
2359 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
2360 break;
2361#endif
John Durkop6ca23272020-12-03 06:01:32 -08002362#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002363 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002364 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
2365 break;
2366#endif
2367#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002368 case PSA_ALG_SHA_512:
2369 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
2370 break;
2371#endif
2372 default:
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002373 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002374 }
itayzafrir40835d42018-08-02 13:14:17 +03002375 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002376
itayzafrir40835d42018-08-02 13:14:17 +03002377exit:
2378 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002379 {
Gilles Peskineaee13332018-07-02 12:15:28 +02002380 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002381 return( psa_hash_abort( operation ) );
2382 }
2383 else
2384 {
2385 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03002386 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002387 }
2388}
2389
Gilles Peskine2d277862018-06-18 15:41:12 +02002390psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
2391 const uint8_t *hash,
2392 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002393{
2394 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
2395 size_t actual_hash_length;
2396 psa_status_t status = psa_hash_finish( operation,
2397 actual_hash, sizeof( actual_hash ),
2398 &actual_hash_length );
2399 if( status != PSA_SUCCESS )
2400 return( status );
2401 if( actual_hash_length != hash_length )
2402 return( PSA_ERROR_INVALID_SIGNATURE );
2403 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
2404 return( PSA_ERROR_INVALID_SIGNATURE );
2405 return( PSA_SUCCESS );
2406}
2407
Gilles Peskine0a749c82019-11-28 19:33:58 +01002408psa_status_t psa_hash_compute( psa_algorithm_t alg,
2409 const uint8_t *input, size_t input_length,
2410 uint8_t *hash, size_t hash_size,
2411 size_t *hash_length )
2412{
2413 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
2414 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2415
2416 *hash_length = hash_size;
2417 status = psa_hash_setup( &operation, alg );
2418 if( status != PSA_SUCCESS )
2419 goto exit;
2420 status = psa_hash_update( &operation, input, input_length );
2421 if( status != PSA_SUCCESS )
2422 goto exit;
2423 status = psa_hash_finish( &operation, hash, hash_size, hash_length );
2424 if( status != PSA_SUCCESS )
2425 goto exit;
2426
2427exit:
2428 if( status == PSA_SUCCESS )
2429 status = psa_hash_abort( &operation );
2430 else
2431 psa_hash_abort( &operation );
2432 return( status );
2433}
2434
2435psa_status_t psa_hash_compare( psa_algorithm_t alg,
2436 const uint8_t *input, size_t input_length,
2437 const uint8_t *hash, size_t hash_length )
2438{
2439 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
2440 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2441
2442 status = psa_hash_setup( &operation, alg );
2443 if( status != PSA_SUCCESS )
2444 goto exit;
2445 status = psa_hash_update( &operation, input, input_length );
2446 if( status != PSA_SUCCESS )
2447 goto exit;
2448 status = psa_hash_verify( &operation, hash, hash_length );
2449 if( status != PSA_SUCCESS )
2450 goto exit;
2451
2452exit:
2453 if( status == PSA_SUCCESS )
2454 status = psa_hash_abort( &operation );
2455 else
2456 psa_hash_abort( &operation );
2457 return( status );
2458}
2459
Gilles Peskineeb35d782019-01-22 17:56:16 +01002460psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation,
2461 psa_hash_operation_t *target_operation )
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002462{
2463 if( target_operation->alg != 0 )
2464 return( PSA_ERROR_BAD_STATE );
2465
2466 switch( source_operation->alg )
2467 {
2468 case 0:
2469 return( PSA_ERROR_BAD_STATE );
John Durkopee4e6602020-11-27 08:48:46 -08002470#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002471 case PSA_ALG_MD2:
2472 mbedtls_md2_clone( &target_operation->ctx.md2,
2473 &source_operation->ctx.md2 );
2474 break;
2475#endif
John Durkopee4e6602020-11-27 08:48:46 -08002476#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002477 case PSA_ALG_MD4:
2478 mbedtls_md4_clone( &target_operation->ctx.md4,
2479 &source_operation->ctx.md4 );
2480 break;
2481#endif
John Durkopee4e6602020-11-27 08:48:46 -08002482#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002483 case PSA_ALG_MD5:
2484 mbedtls_md5_clone( &target_operation->ctx.md5,
2485 &source_operation->ctx.md5 );
2486 break;
2487#endif
John Durkopee4e6602020-11-27 08:48:46 -08002488#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002489 case PSA_ALG_RIPEMD160:
2490 mbedtls_ripemd160_clone( &target_operation->ctx.ripemd160,
2491 &source_operation->ctx.ripemd160 );
2492 break;
2493#endif
John Durkopee4e6602020-11-27 08:48:46 -08002494#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002495 case PSA_ALG_SHA_1:
2496 mbedtls_sha1_clone( &target_operation->ctx.sha1,
2497 &source_operation->ctx.sha1 );
2498 break;
2499#endif
John Durkop6ca23272020-12-03 06:01:32 -08002500#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002501 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002502 mbedtls_sha256_clone( &target_operation->ctx.sha256,
2503 &source_operation->ctx.sha256 );
2504 break;
2505#endif
2506#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002507 case PSA_ALG_SHA_256:
2508 mbedtls_sha256_clone( &target_operation->ctx.sha256,
2509 &source_operation->ctx.sha256 );
2510 break;
2511#endif
John Durkop6ca23272020-12-03 06:01:32 -08002512#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002513 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002514 mbedtls_sha512_clone( &target_operation->ctx.sha512,
2515 &source_operation->ctx.sha512 );
2516 break;
2517#endif
2518#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002519 case PSA_ALG_SHA_512:
2520 mbedtls_sha512_clone( &target_operation->ctx.sha512,
2521 &source_operation->ctx.sha512 );
2522 break;
2523#endif
2524 default:
2525 return( PSA_ERROR_NOT_SUPPORTED );
2526 }
2527
2528 target_operation->alg = source_operation->alg;
2529 return( PSA_SUCCESS );
2530}
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002531
2532
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002533/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01002534/* MAC */
2535/****************************************************************/
2536
Gilles Peskinedc2fc842018-03-07 16:42:59 +01002537static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01002538 psa_algorithm_t alg,
2539 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02002540 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03002541 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002542{
Gilles Peskine8c9def32018-02-08 10:02:12 +01002543 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03002544 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002545
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02002546 if( PSA_ALG_IS_AEAD( alg ) )
Bence Szépkútia63b20d2020-12-16 11:36:46 +01002547 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02002548
Gilles Peskine8c9def32018-02-08 10:02:12 +01002549 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
2550 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03002551 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002552 {
Bence Szépkúti1de907d2020-12-07 18:20:28 +01002553 case PSA_ALG_STREAM_CIPHER:
Gilles Peskine8c9def32018-02-08 10:02:12 +01002554 mode = MBEDTLS_MODE_STREAM;
2555 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002556 case PSA_ALG_CTR:
2557 mode = MBEDTLS_MODE_CTR;
2558 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002559 case PSA_ALG_CFB:
2560 mode = MBEDTLS_MODE_CFB;
2561 break;
2562 case PSA_ALG_OFB:
2563 mode = MBEDTLS_MODE_OFB;
2564 break;
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02002565 case PSA_ALG_ECB_NO_PADDING:
2566 mode = MBEDTLS_MODE_ECB;
2567 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002568 case PSA_ALG_CBC_NO_PADDING:
2569 mode = MBEDTLS_MODE_CBC;
2570 break;
2571 case PSA_ALG_CBC_PKCS7:
2572 mode = MBEDTLS_MODE_CBC;
2573 break;
Bence Szépkútia63b20d2020-12-16 11:36:46 +01002574 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01002575 mode = MBEDTLS_MODE_CCM;
2576 break;
Bence Szépkútia63b20d2020-12-16 11:36:46 +01002577 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01002578 mode = MBEDTLS_MODE_GCM;
2579 break;
Bence Szépkútia63b20d2020-12-16 11:36:46 +01002580 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
Gilles Peskine26869f22019-05-06 15:25:00 +02002581 mode = MBEDTLS_MODE_CHACHAPOLY;
2582 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002583 default:
2584 return( NULL );
2585 }
2586 }
2587 else if( alg == PSA_ALG_CMAC )
2588 mode = MBEDTLS_MODE_ECB;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002589 else
2590 return( NULL );
2591
2592 switch( key_type )
2593 {
2594 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03002595 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002596 break;
2597 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002598 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
2599 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01002600 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03002601 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002602 else
mohammad1603f4f0d612018-06-03 15:04:51 +03002603 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002604 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
2605 * but two-key Triple-DES is functionally three-key Triple-DES
2606 * with K1=K3, so that's how we present it to mbedtls. */
2607 if( key_bits == 128 )
2608 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002609 break;
2610 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03002611 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002612 break;
2613 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03002614 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002615 break;
Gilles Peskine26869f22019-05-06 15:25:00 +02002616 case PSA_KEY_TYPE_CHACHA20:
2617 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
2618 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002619 default:
2620 return( NULL );
2621 }
mohammad1603f4f0d612018-06-03 15:04:51 +03002622 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03002623 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002624
Jaeden Amero23bbb752018-06-26 14:16:54 +01002625 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
2626 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002627}
2628
John Durkop6ba40d12020-11-10 08:50:04 -08002629#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002630static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03002631{
Gilles Peskine2d277862018-06-18 15:41:12 +02002632 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03002633 {
2634 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002635 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002636 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002637 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002638 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002639 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002640 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002641 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002642 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002643 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002644 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002645 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002646 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002647 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002648 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002649 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002650 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02002651 return( 128 );
2652 default:
2653 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002654 }
2655}
John Durkop07cc04a2020-11-16 22:08:34 -08002656#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03002657
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002658/* Initialize the MAC operation structure. Once this function has been
2659 * called, psa_mac_abort can run and will do the right thing. */
2660static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
2661 psa_algorithm_t alg )
2662{
2663 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
2664
2665 operation->alg = alg;
2666 operation->key_set = 0;
2667 operation->iv_set = 0;
2668 operation->iv_required = 0;
2669 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002670 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002671
2672#if defined(MBEDTLS_CMAC_C)
2673 if( alg == PSA_ALG_CMAC )
2674 {
2675 operation->iv_required = 0;
2676 mbedtls_cipher_init( &operation->ctx.cmac );
2677 status = PSA_SUCCESS;
2678 }
2679 else
2680#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07002681#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002682 if( PSA_ALG_IS_HMAC( operation->alg ) )
2683 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02002684 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
2685 operation->ctx.hmac.hash_ctx.alg = 0;
2686 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002687 }
2688 else
John Durkopd0321952020-10-29 21:37:36 -07002689#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002690 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02002691 if( ! PSA_ALG_IS_MAC( alg ) )
2692 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002693 }
2694
2695 if( status != PSA_SUCCESS )
2696 memset( operation, 0, sizeof( *operation ) );
2697 return( status );
2698}
2699
John Durkop6ba40d12020-11-10 08:50:04 -08002700#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02002701static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
2702{
Gilles Peskine3f108122018-12-07 18:14:53 +01002703 mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002704 return( psa_hash_abort( &hmac->hash_ctx ) );
2705}
John Durkop6ba40d12020-11-10 08:50:04 -08002706#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine01126fa2018-07-12 17:04:55 +02002707
Gilles Peskine8c9def32018-02-08 10:02:12 +01002708psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
2709{
Gilles Peskinefbfac682018-07-08 20:51:54 +02002710 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002711 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02002712 /* The object has (apparently) been initialized but it is not
2713 * in use. It's ok to call abort on such an object, and there's
2714 * nothing to do. */
2715 return( PSA_SUCCESS );
2716 }
2717 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002718#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002719 if( operation->alg == PSA_ALG_CMAC )
2720 {
2721 mbedtls_cipher_free( &operation->ctx.cmac );
2722 }
2723 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002724#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07002725#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002726 if( PSA_ALG_IS_HMAC( operation->alg ) )
2727 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002728 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002729 }
2730 else
John Durkopd0321952020-10-29 21:37:36 -07002731#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02002732 {
2733 /* Sanity check (shouldn't happen: operation->alg should
2734 * always have been initialized to a valid value). */
2735 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002736 }
Moran Peker41deec42018-04-04 15:43:05 +03002737
Gilles Peskine8c9def32018-02-08 10:02:12 +01002738 operation->alg = 0;
2739 operation->key_set = 0;
2740 operation->iv_set = 0;
2741 operation->iv_required = 0;
2742 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002743 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002744
Gilles Peskine8c9def32018-02-08 10:02:12 +01002745 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002746
2747bad_state:
2748 /* If abort is called on an uninitialized object, we can't trust
2749 * anything. Wipe the object in case it contains confidential data.
2750 * This may result in a memory leak if a pointer gets overwritten,
2751 * but it's too late to do anything about this. */
2752 memset( operation, 0, sizeof( *operation ) );
2753 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002754}
2755
Gilles Peskinee3b07d82018-06-19 11:57:35 +02002756#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02002757static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002758 size_t key_bits,
Gilles Peskine2f060a82018-12-04 17:12:32 +01002759 psa_key_slot_t *slot,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002760 const mbedtls_cipher_info_t *cipher_info )
2761{
Janos Follath24eed8d2019-11-22 13:21:35 +00002762 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002763
2764 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002765
2766 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
2767 if( ret != 0 )
2768 return( ret );
2769
2770 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
Ronald Cronea0f8a62020-11-25 17:52:23 +01002771 slot->key.data,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002772 key_bits );
2773 return( ret );
2774}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02002775#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002776
John Durkop6ba40d12020-11-10 08:50:04 -08002777#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02002778static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
2779 const uint8_t *key,
2780 size_t key_length,
2781 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002782{
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02002783 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002784 size_t i;
gabor-mezei-armcbcec212020-12-18 14:23:51 +01002785 size_t hash_size = PSA_HASH_LENGTH( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002786 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002787 psa_status_t status;
2788
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002789 /* Sanity checks on block_size, to guarantee that there won't be a buffer
2790 * overflow below. This should never trigger if the hash algorithm
2791 * is implemented correctly. */
2792 /* The size checks against the ipad and opad buffers cannot be written
2793 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
2794 * because that triggers -Wlogical-op on GCC 7.3. */
2795 if( block_size > sizeof( ipad ) )
2796 return( PSA_ERROR_NOT_SUPPORTED );
2797 if( block_size > sizeof( hmac->opad ) )
2798 return( PSA_ERROR_NOT_SUPPORTED );
2799 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002800 return( PSA_ERROR_NOT_SUPPORTED );
2801
Gilles Peskined223b522018-06-11 18:12:58 +02002802 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002803 {
Gilles Peskine84b8fc82019-11-28 20:07:20 +01002804 status = psa_hash_compute( hash_alg, key, key_length,
2805 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002806 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02002807 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002808 }
Gilles Peskine96889972018-07-12 17:07:03 +02002809 /* A 0-length key is not commonly used in HMAC when used as a MAC,
2810 * but it is permitted. It is common when HMAC is used in HKDF, for
2811 * example. Don't call `memcpy` in the 0-length because `key` could be
2812 * an invalid pointer which would make the behavior undefined. */
2813 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02002814 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002815
Gilles Peskined223b522018-06-11 18:12:58 +02002816 /* ipad contains the key followed by garbage. Xor and fill with 0x36
2817 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002818 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02002819 ipad[i] ^= 0x36;
2820 memset( ipad + key_length, 0x36, block_size - key_length );
2821
2822 /* Copy the key material from ipad to opad, flipping the requisite bits,
2823 * and filling the rest of opad with the requisite constant. */
2824 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02002825 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
2826 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002827
Gilles Peskine01126fa2018-07-12 17:04:55 +02002828 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002829 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002830 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002831
Gilles Peskine01126fa2018-07-12 17:04:55 +02002832 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002833
2834cleanup:
Steven Cooreman29149862020-08-05 15:43:42 +02002835 mbedtls_platform_zeroize( ipad, sizeof( ipad ) );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002836
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002837 return( status );
2838}
John Durkop6ba40d12020-11-10 08:50:04 -08002839#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002840
Gilles Peskine89167cb2018-07-08 20:12:23 +02002841static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02002842 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02002843 psa_algorithm_t alg,
2844 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002845{
Ronald Cronf95a2b12020-10-22 15:24:49 +02002846 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01002847 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01002848 psa_key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002849 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002850 psa_key_usage_t usage =
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01002851 is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH;
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02002852 uint8_t truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02002853 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002854
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002855 /* A context must be freshly initialized before it can be set up. */
2856 if( operation->alg != 0 )
2857 {
2858 return( PSA_ERROR_BAD_STATE );
2859 }
2860
Gilles Peskined911eb72018-08-14 15:18:45 +02002861 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002862 if( status != PSA_SUCCESS )
2863 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02002864 if( is_sign )
2865 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002866
Ronald Cron5c522922020-11-14 16:35:34 +01002867 status = psa_get_and_lock_transparent_key_slot_with_policy(
2868 key, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002869 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002870 goto exit;
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02002871 key_bits = psa_get_key_slot_bits( slot );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002872
Gilles Peskine8c9def32018-02-08 10:02:12 +01002873#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02002874 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002875 {
2876 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02002877 mbedtls_cipher_info_from_psa( full_length_alg,
Gilles Peskine8e338702019-07-30 20:06:31 +02002878 slot->attr.type, key_bits, NULL );
Janos Follath24eed8d2019-11-22 13:21:35 +00002879 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinefbfac682018-07-08 20:51:54 +02002880 if( cipher_info == NULL )
2881 {
2882 status = PSA_ERROR_NOT_SUPPORTED;
2883 goto exit;
2884 }
2885 operation->mac_size = cipher_info->block_size;
2886 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
2887 status = mbedtls_to_psa_error( ret );
2888 }
2889 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002890#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07002891#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskined911eb72018-08-14 15:18:45 +02002892 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002893 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02002894 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002895 if( hash_alg == 0 )
2896 {
2897 status = PSA_ERROR_NOT_SUPPORTED;
2898 goto exit;
2899 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002900
gabor-mezei-armcbcec212020-12-18 14:23:51 +01002901 operation->mac_size = PSA_HASH_LENGTH( hash_alg );
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002902 /* Sanity check. This shouldn't fail on a valid configuration. */
2903 if( operation->mac_size == 0 ||
2904 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
2905 {
2906 status = PSA_ERROR_NOT_SUPPORTED;
2907 goto exit;
2908 }
2909
Gilles Peskine8e338702019-07-30 20:06:31 +02002910 if( slot->attr.type != PSA_KEY_TYPE_HMAC )
Gilles Peskine01126fa2018-07-12 17:04:55 +02002911 {
2912 status = PSA_ERROR_INVALID_ARGUMENT;
2913 goto exit;
2914 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002915
Gilles Peskine01126fa2018-07-12 17:04:55 +02002916 status = psa_hmac_setup_internal( &operation->ctx.hmac,
Ronald Cronea0f8a62020-11-25 17:52:23 +01002917 slot->key.data,
2918 slot->key.bytes,
Gilles Peskine01126fa2018-07-12 17:04:55 +02002919 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002920 }
2921 else
John Durkopd0321952020-10-29 21:37:36 -07002922#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02002923 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00002924 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02002925 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002926 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002927
Gilles Peskined911eb72018-08-14 15:18:45 +02002928 if( truncated == 0 )
2929 {
Steven Cooremanae3f13b2021-02-23 12:19:42 +01002930 /* The "normal" case: untruncated algorithm. Re-validate the
2931 * key policy with explicit MAC length set in the algorithm
2932 * when the algorithm policy is at-least-this-length to catch
2933 * a corner case due to the default MAC length being unknown
2934 * at key loading time. */
2935 if( PSA_ALG_IS_MAC( slot->attr.policy.alg ) &&
2936 ( PSA_ALG_FULL_LENGTH_MAC( slot->attr.policy.alg ) == full_length_alg ) &&
2937 ( slot->attr.policy.alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) )
2938 {
2939 /* validate policy length */
2940 if( PSA_MAC_TRUNCATED_LENGTH( slot->attr.policy.alg ) > operation->mac_size )
2941 status = PSA_ERROR_NOT_PERMITTED;
2942 }
2943
2944 if( PSA_ALG_IS_MAC( slot->attr.policy.alg2 ) &&
2945 ( PSA_ALG_FULL_LENGTH_MAC( slot->attr.policy.alg2 ) == full_length_alg ) &&
2946 ( slot->attr.policy.alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) )
2947 {
2948 /* validate policy length */
2949 if( PSA_MAC_TRUNCATED_LENGTH( slot->attr.policy.alg2 ) > operation->mac_size )
2950 status = PSA_ERROR_NOT_PERMITTED;
2951 }
Gilles Peskined911eb72018-08-14 15:18:45 +02002952 }
2953 else if( truncated < 4 )
2954 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02002955 /* A very short MAC is too short for security since it can be
2956 * brute-forced. Ancient protocols with 32-bit MACs do exist,
2957 * so we make this our minimum, even though 32 bits is still
2958 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02002959 status = PSA_ERROR_NOT_SUPPORTED;
2960 }
2961 else if( truncated > operation->mac_size )
2962 {
2963 /* It's impossible to "truncate" to a larger length. */
2964 status = PSA_ERROR_INVALID_ARGUMENT;
2965 }
2966 else
2967 operation->mac_size = truncated;
2968
Gilles Peskinefbfac682018-07-08 20:51:54 +02002969exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002970 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002971 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002972 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002973 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002974 else
2975 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002976 operation->key_set = 1;
2977 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02002978
Ronald Cron5c522922020-11-14 16:35:34 +01002979 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002980
Ronald Cron5c522922020-11-14 16:35:34 +01002981 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002982}
2983
Gilles Peskine89167cb2018-07-08 20:12:23 +02002984psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02002985 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02002986 psa_algorithm_t alg )
2987{
Ronald Croncf56a0a2020-08-04 09:51:30 +02002988 return( psa_mac_setup( operation, key, alg, 1 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02002989}
2990
2991psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02002992 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02002993 psa_algorithm_t alg )
2994{
Ronald Croncf56a0a2020-08-04 09:51:30 +02002995 return( psa_mac_setup( operation, key, alg, 0 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02002996}
2997
Gilles Peskine8c9def32018-02-08 10:02:12 +01002998psa_status_t psa_mac_update( psa_mac_operation_t *operation,
2999 const uint8_t *input,
3000 size_t input_length )
3001{
Gilles Peskinefbfac682018-07-08 20:51:54 +02003002 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003003 if( ! operation->key_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003004 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003005 if( operation->iv_required && ! operation->iv_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003006 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003007 operation->has_input = 1;
3008
Gilles Peskine8c9def32018-02-08 10:02:12 +01003009#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003010 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03003011 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02003012 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
3013 input, input_length );
3014 status = mbedtls_to_psa_error( ret );
3015 }
3016 else
3017#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003018#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003019 if( PSA_ALG_IS_HMAC( operation->alg ) )
3020 {
3021 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
3022 input_length );
3023 }
3024 else
John Durkopd0321952020-10-29 21:37:36 -07003025#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003026 {
3027 /* This shouldn't happen if `operation` was initialized by
3028 * a setup function. */
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003029 return( PSA_ERROR_BAD_STATE );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03003030 }
3031
Gilles Peskinefbfac682018-07-08 20:51:54 +02003032 if( status != PSA_SUCCESS )
3033 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003034 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003035}
3036
John Durkop6ba40d12020-11-10 08:50:04 -08003037#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02003038static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
3039 uint8_t *mac,
3040 size_t mac_size )
3041{
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02003042 uint8_t tmp[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine01126fa2018-07-12 17:04:55 +02003043 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
3044 size_t hash_size = 0;
3045 size_t block_size = psa_get_hash_block_size( hash_alg );
3046 psa_status_t status;
3047
Gilles Peskine01126fa2018-07-12 17:04:55 +02003048 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
3049 if( status != PSA_SUCCESS )
3050 return( status );
3051 /* From here on, tmp needs to be wiped. */
3052
3053 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
3054 if( status != PSA_SUCCESS )
3055 goto exit;
3056
3057 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
3058 if( status != PSA_SUCCESS )
3059 goto exit;
3060
3061 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
3062 if( status != PSA_SUCCESS )
3063 goto exit;
3064
Gilles Peskined911eb72018-08-14 15:18:45 +02003065 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
3066 if( status != PSA_SUCCESS )
3067 goto exit;
3068
3069 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003070
3071exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01003072 mbedtls_platform_zeroize( tmp, hash_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003073 return( status );
3074}
John Durkop6ba40d12020-11-10 08:50:04 -08003075#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine01126fa2018-07-12 17:04:55 +02003076
mohammad16036df908f2018-04-02 08:34:15 -07003077static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02003078 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003079 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003080{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02003081 if( ! operation->key_set )
3082 return( PSA_ERROR_BAD_STATE );
3083 if( operation->iv_required && ! operation->iv_set )
3084 return( PSA_ERROR_BAD_STATE );
3085
Gilles Peskine8c9def32018-02-08 10:02:12 +01003086 if( mac_size < operation->mac_size )
3087 return( PSA_ERROR_BUFFER_TOO_SMALL );
3088
Gilles Peskine8c9def32018-02-08 10:02:12 +01003089#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003090 if( operation->alg == PSA_ALG_CMAC )
3091 {
gabor-mezei-armcbcec212020-12-18 14:23:51 +01003092 uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE];
Gilles Peskined911eb72018-08-14 15:18:45 +02003093 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
3094 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02003095 memcpy( mac, tmp, operation->mac_size );
Gilles Peskine3f108122018-12-07 18:14:53 +01003096 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003097 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003098 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02003099 else
3100#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003101#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003102 if( PSA_ALG_IS_HMAC( operation->alg ) )
3103 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02003104 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02003105 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003106 }
3107 else
John Durkopd0321952020-10-29 21:37:36 -07003108#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003109 {
3110 /* This shouldn't happen if `operation` was initialized by
3111 * a setup function. */
3112 return( PSA_ERROR_BAD_STATE );
3113 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01003114}
3115
Gilles Peskineacd4be32018-07-08 19:56:25 +02003116psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
3117 uint8_t *mac,
3118 size_t mac_size,
3119 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07003120{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003121 psa_status_t status;
3122
Jaeden Amero252ef282019-02-15 14:05:35 +00003123 if( operation->alg == 0 )
3124 {
3125 return( PSA_ERROR_BAD_STATE );
3126 }
3127
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003128 /* Fill the output buffer with something that isn't a valid mac
3129 * (barring an attack on the mac and deliberately-crafted input),
3130 * in case the caller doesn't check the return status properly. */
3131 *mac_length = mac_size;
3132 /* If mac_size is 0 then mac may be NULL and then the
3133 * call to memset would have undefined behavior. */
3134 if( mac_size != 0 )
3135 memset( mac, '!', mac_size );
3136
Gilles Peskine89167cb2018-07-08 20:12:23 +02003137 if( ! operation->is_sign )
3138 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003139 return( PSA_ERROR_BAD_STATE );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003140 }
mohammad16036df908f2018-04-02 08:34:15 -07003141
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003142 status = psa_mac_finish_internal( operation, mac, mac_size );
3143
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003144 if( status == PSA_SUCCESS )
3145 {
3146 status = psa_mac_abort( operation );
3147 if( status == PSA_SUCCESS )
3148 *mac_length = operation->mac_size;
3149 else
3150 memset( mac, '!', mac_size );
3151 }
3152 else
3153 psa_mac_abort( operation );
3154 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07003155}
3156
Gilles Peskineacd4be32018-07-08 19:56:25 +02003157psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
3158 const uint8_t *mac,
3159 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003160{
Gilles Peskine828ed142018-06-18 23:25:51 +02003161 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07003162 psa_status_t status;
3163
Jaeden Amero252ef282019-02-15 14:05:35 +00003164 if( operation->alg == 0 )
3165 {
3166 return( PSA_ERROR_BAD_STATE );
3167 }
3168
Gilles Peskine89167cb2018-07-08 20:12:23 +02003169 if( operation->is_sign )
3170 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003171 return( PSA_ERROR_BAD_STATE );
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003172 }
3173 if( operation->mac_size != mac_length )
3174 {
3175 status = PSA_ERROR_INVALID_SIGNATURE;
3176 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02003177 }
mohammad16036df908f2018-04-02 08:34:15 -07003178
3179 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003180 actual_mac, sizeof( actual_mac ) );
Gilles Peskine28cd4162020-01-20 16:31:06 +01003181 if( status != PSA_SUCCESS )
3182 goto cleanup;
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003183
3184 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
3185 status = PSA_ERROR_INVALID_SIGNATURE;
3186
3187cleanup:
3188 if( status == PSA_SUCCESS )
3189 status = psa_mac_abort( operation );
3190 else
3191 psa_mac_abort( operation );
3192
Gilles Peskine3f108122018-12-07 18:14:53 +01003193 mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02003194
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003195 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003196}
3197
3198
Gilles Peskine20035e32018-02-03 22:44:14 +01003199
Gilles Peskine20035e32018-02-03 22:44:14 +01003200/****************************************************************/
3201/* Asymmetric cryptography */
3202/****************************************************************/
3203
John Durkop6ba40d12020-11-10 08:50:04 -08003204#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3205 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02003206/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003207 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02003208static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
3209 size_t hash_length,
3210 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003211{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02003212 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02003213 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003214 *md_alg = mbedtls_md_get_type( md_info );
3215
3216 /* The Mbed TLS RSA module uses an unsigned int for hash length
3217 * parameters. Validate that it fits so that we don't risk an
3218 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003219#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003220 if( hash_length > UINT_MAX )
3221 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003222#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003223
John Durkop0e005192020-10-31 22:06:54 -07003224#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003225 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
3226 * must be correct. */
3227 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
3228 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003229 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003230 if( md_info == NULL )
3231 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02003232 if( mbedtls_md_get_size( md_info ) != hash_length )
3233 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003234 }
John Durkop0e005192020-10-31 22:06:54 -07003235#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003236
John Durkop0e005192020-10-31 22:06:54 -07003237#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003238 /* PSS requires a hash internally. */
3239 if( PSA_ALG_IS_RSA_PSS( alg ) )
3240 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02003241 if( md_info == NULL )
3242 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003243 }
John Durkop0e005192020-10-31 22:06:54 -07003244#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003245
Gilles Peskine61b91d42018-06-08 16:09:36 +02003246 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003247}
3248
Gilles Peskine2b450e32018-06-27 15:42:46 +02003249static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
3250 psa_algorithm_t alg,
3251 const uint8_t *hash,
3252 size_t hash_length,
3253 uint8_t *signature,
3254 size_t signature_size,
3255 size_t *signature_length )
3256{
3257 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003258 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003259 mbedtls_md_type_t md_alg;
3260
3261 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
3262 if( status != PSA_SUCCESS )
3263 return( status );
3264
Gilles Peskine630a18a2018-06-29 17:49:35 +02003265 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02003266 return( PSA_ERROR_BUFFER_TOO_SMALL );
3267
John Durkop0e005192020-10-31 22:06:54 -07003268#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003269 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
3270 {
3271 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
3272 MBEDTLS_MD_NONE );
3273 ret = mbedtls_rsa_pkcs1_sign( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003274 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003275 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003276 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003277 md_alg,
3278 (unsigned int) hash_length,
3279 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003280 signature );
3281 }
3282 else
John Durkop0e005192020-10-31 22:06:54 -07003283#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
3284#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003285 if( PSA_ALG_IS_RSA_PSS( alg ) )
3286 {
3287 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3288 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003289 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003290 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003291 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003292 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003293 (unsigned int) hash_length,
3294 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003295 signature );
3296 }
3297 else
John Durkop0e005192020-10-31 22:06:54 -07003298#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003299 {
3300 return( PSA_ERROR_INVALID_ARGUMENT );
3301 }
3302
3303 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02003304 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003305 return( mbedtls_to_psa_error( ret ) );
3306}
3307
3308static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
3309 psa_algorithm_t alg,
3310 const uint8_t *hash,
3311 size_t hash_length,
3312 const uint8_t *signature,
3313 size_t signature_length )
3314{
3315 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003316 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003317 mbedtls_md_type_t md_alg;
3318
3319 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
3320 if( status != PSA_SUCCESS )
3321 return( status );
3322
Gilles Peskine89cc74f2019-09-12 22:08:23 +02003323 if( signature_length != mbedtls_rsa_get_len( rsa ) )
3324 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003325
John Durkop0e005192020-10-31 22:06:54 -07003326#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003327 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
3328 {
3329 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
3330 MBEDTLS_MD_NONE );
3331 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003332 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003333 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003334 MBEDTLS_RSA_PUBLIC,
3335 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003336 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003337 hash,
3338 signature );
3339 }
3340 else
John Durkop0e005192020-10-31 22:06:54 -07003341#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
3342#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003343 if( PSA_ALG_IS_RSA_PSS( alg ) )
3344 {
3345 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3346 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003347 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003348 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003349 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003350 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003351 (unsigned int) hash_length,
3352 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003353 signature );
3354 }
3355 else
John Durkop0e005192020-10-31 22:06:54 -07003356#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003357 {
3358 return( PSA_ERROR_INVALID_ARGUMENT );
3359 }
Gilles Peskineef12c632018-09-13 20:37:48 +02003360
3361 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
3362 * the rest of the signature is invalid". This has little use in
3363 * practice and PSA doesn't report this distinction. */
3364 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
3365 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003366 return( mbedtls_to_psa_error( ret ) );
3367}
John Durkop6ba40d12020-11-10 08:50:04 -08003368#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3369 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003370
John Durkop6ba40d12020-11-10 08:50:04 -08003371#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3372 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003373/* `ecp` cannot be const because `ecp->grp` needs to be non-const
3374 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
3375 * (even though these functions don't modify it). */
3376static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
3377 psa_algorithm_t alg,
3378 const uint8_t *hash,
3379 size_t hash_length,
3380 uint8_t *signature,
3381 size_t signature_size,
3382 size_t *signature_length )
3383{
Janos Follath24eed8d2019-11-22 13:21:35 +00003384 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003385 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003386 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003387 mbedtls_mpi_init( &r );
3388 mbedtls_mpi_init( &s );
3389
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003390 if( signature_size < 2 * curve_bytes )
3391 {
3392 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
3393 goto cleanup;
3394 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003395
John Durkop0ea39e02020-10-13 19:58:20 -07003396#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003397 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
3398 {
3399 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
3400 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
3401 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
Darryl Green5e843fa2019-09-05 14:06:34 +01003402 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det_ext( &ecp->grp, &r, &s,
3403 &ecp->d, hash,
3404 hash_length, md_alg,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003405 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003406 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003407 }
3408 else
John Durkop0ea39e02020-10-13 19:58:20 -07003409#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003410 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003411 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003412 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
3413 hash, hash_length,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003414 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003415 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003416 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003417
3418 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
3419 signature,
3420 curve_bytes ) );
3421 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
3422 signature + curve_bytes,
3423 curve_bytes ) );
3424
3425cleanup:
3426 mbedtls_mpi_free( &r );
3427 mbedtls_mpi_free( &s );
3428 if( ret == 0 )
3429 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003430 return( mbedtls_to_psa_error( ret ) );
3431}
3432
3433static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
3434 const uint8_t *hash,
3435 size_t hash_length,
3436 const uint8_t *signature,
3437 size_t signature_length )
3438{
Janos Follath24eed8d2019-11-22 13:21:35 +00003439 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003440 mbedtls_mpi r, s;
3441 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
3442 mbedtls_mpi_init( &r );
3443 mbedtls_mpi_init( &s );
3444
3445 if( signature_length != 2 * curve_bytes )
3446 return( PSA_ERROR_INVALID_SIGNATURE );
3447
3448 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
3449 signature,
3450 curve_bytes ) );
3451 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
3452 signature + curve_bytes,
3453 curve_bytes ) );
3454
Steven Cooremanacda8342020-07-24 23:09:52 +02003455 /* Check whether the public part is loaded. If not, load it. */
3456 if( mbedtls_ecp_is_zero( &ecp->Q ) )
3457 {
3458 MBEDTLS_MPI_CHK(
3459 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003460 mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
Steven Cooremanacda8342020-07-24 23:09:52 +02003461 }
3462
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003463 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
3464 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003465
3466cleanup:
3467 mbedtls_mpi_free( &r );
3468 mbedtls_mpi_free( &s );
3469 return( mbedtls_to_psa_error( ret ) );
3470}
John Durkop6ba40d12020-11-10 08:50:04 -08003471#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3472 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003473
Ronald Croncf56a0a2020-08-04 09:51:30 +02003474psa_status_t psa_sign_hash( mbedtls_svc_key_id_t key,
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003475 psa_algorithm_t alg,
3476 const uint8_t *hash,
3477 size_t hash_length,
3478 uint8_t *signature,
3479 size_t signature_size,
3480 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01003481{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003482 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003483 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003484 psa_key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003485
3486 *signature_length = signature_size;
Gilles Peskine4019f0e2019-09-12 22:05:59 +02003487 /* Immediately reject a zero-length signature buffer. This guarantees
3488 * that signature must be a valid pointer. (On the other hand, the hash
3489 * buffer can in principle be empty since it doesn't actually have
3490 * to be a hash.) */
3491 if( signature_size == 0 )
3492 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003493
Ronald Cron5c522922020-11-14 16:35:34 +01003494 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
3495 PSA_KEY_USAGE_SIGN_HASH,
3496 alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003497 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003498 goto exit;
Gilles Peskine8e338702019-07-30 20:06:31 +02003499 if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003500 {
3501 status = PSA_ERROR_INVALID_ARGUMENT;
3502 goto exit;
3503 }
Gilles Peskine20035e32018-02-03 22:44:14 +01003504
Steven Cooremancd84cb42020-07-16 20:28:36 +02003505 /* Try any of the available accelerators first */
3506 status = psa_driver_wrapper_sign_hash( slot,
3507 alg,
3508 hash,
3509 hash_length,
3510 signature,
3511 signature_size,
3512 signature_length );
Steven Cooreman8d2bde72020-09-04 13:06:39 +02003513 if( status != PSA_ERROR_NOT_SUPPORTED ||
3514 psa_key_lifetime_is_external( slot->attr.lifetime ) )
Steven Cooremancd84cb42020-07-16 20:28:36 +02003515 goto exit;
3516
Steven Cooreman7a250572020-07-17 16:43:05 +02003517 /* If the operation was not supported by any accelerator, try fallback. */
John Durkop6ba40d12020-11-10 08:50:04 -08003518#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3519 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8e338702019-07-30 20:06:31 +02003520 if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskine20035e32018-02-03 22:44:14 +01003521 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003522 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02003523
Ronald Cron90857082020-11-25 14:58:33 +01003524 status = mbedtls_psa_rsa_load_representation( slot->attr.type,
3525 slot->key.data,
3526 slot->key.bytes,
3527 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02003528 if( status != PSA_SUCCESS )
3529 goto exit;
3530
Steven Cooremana2371e52020-07-28 14:30:39 +02003531 status = psa_rsa_sign( rsa,
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003532 alg,
3533 hash, hash_length,
3534 signature, signature_size,
3535 signature_length );
Steven Cooremana01795d2020-07-24 22:48:15 +02003536
Steven Cooremana2371e52020-07-28 14:30:39 +02003537 mbedtls_rsa_free( rsa );
3538 mbedtls_free( rsa );
Gilles Peskine20035e32018-02-03 22:44:14 +01003539 }
3540 else
John Durkop6ba40d12020-11-10 08:50:04 -08003541#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3542 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine8e338702019-07-30 20:06:31 +02003543 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01003544 {
John Durkop9814fa22020-11-04 12:28:15 -08003545#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3546 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea05219c2018-11-16 16:02:56 +01003547 if(
John Durkop0ea39e02020-10-13 19:58:20 -07003548#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea05219c2018-11-16 16:02:56 +01003549 PSA_ALG_IS_ECDSA( alg )
3550#else
3551 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
3552#endif
3553 )
Steven Cooremanacda8342020-07-24 23:09:52 +02003554 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003555 mbedtls_ecp_keypair *ecp = NULL;
Ronald Cron90857082020-11-25 14:58:33 +01003556 status = mbedtls_psa_ecp_load_representation( slot->attr.type,
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +01003557 slot->attr.bits,
Ronald Cron90857082020-11-25 14:58:33 +01003558 slot->key.data,
3559 slot->key.bytes,
3560 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02003561 if( status != PSA_SUCCESS )
3562 goto exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02003563 status = psa_ecdsa_sign( ecp,
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003564 alg,
3565 hash, hash_length,
3566 signature, signature_size,
3567 signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02003568 mbedtls_ecp_keypair_free( ecp );
3569 mbedtls_free( ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02003570 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003571 else
John Durkop9814fa22020-11-04 12:28:15 -08003572#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3573 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003574 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003575 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003576 }
itayzafrir5c753392018-05-08 11:18:38 +03003577 }
3578 else
itayzafrir5c753392018-05-08 11:18:38 +03003579 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003580 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01003581 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003582
3583exit:
3584 /* Fill the unused part of the output buffer (the whole buffer on error,
3585 * the trailing part on success) with something that isn't a valid mac
3586 * (barring an attack on the mac and deliberately-crafted input),
3587 * in case the caller doesn't check the return status properly. */
3588 if( status == PSA_SUCCESS )
3589 memset( signature + *signature_length, '!',
3590 signature_size - *signature_length );
Gilles Peskine4019f0e2019-09-12 22:05:59 +02003591 else
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003592 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02003593 /* If signature_size is 0 then we have nothing to do. We must not call
3594 * memset because signature may be NULL in this case. */
Ronald Cronf95a2b12020-10-22 15:24:49 +02003595
Ronald Cron5c522922020-11-14 16:35:34 +01003596 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003597
Ronald Cron5c522922020-11-14 16:35:34 +01003598 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
itayzafrir5c753392018-05-08 11:18:38 +03003599}
3600
Ronald Croncf56a0a2020-08-04 09:51:30 +02003601psa_status_t psa_verify_hash( mbedtls_svc_key_id_t key,
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003602 psa_algorithm_t alg,
3603 const uint8_t *hash,
3604 size_t hash_length,
3605 const uint8_t *signature,
3606 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03003607{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003608 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003609 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003610 psa_key_slot_t *slot;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003611
Ronald Cron5c522922020-11-14 16:35:34 +01003612 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
3613 PSA_KEY_USAGE_VERIFY_HASH,
3614 alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003615 if( status != PSA_SUCCESS )
3616 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03003617
Steven Cooreman55ae2172020-07-17 19:46:15 +02003618 /* Try any of the available accelerators first */
3619 status = psa_driver_wrapper_verify_hash( slot,
3620 alg,
3621 hash,
3622 hash_length,
3623 signature,
3624 signature_length );
Steven Cooreman8d2bde72020-09-04 13:06:39 +02003625 if( status != PSA_ERROR_NOT_SUPPORTED ||
3626 psa_key_lifetime_is_external( slot->attr.lifetime ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003627 goto exit;
Steven Cooreman55ae2172020-07-17 19:46:15 +02003628
John Durkop6ba40d12020-11-10 08:50:04 -08003629#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3630 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8e338702019-07-30 20:06:31 +02003631 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003632 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003633 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02003634
Ronald Cron90857082020-11-25 14:58:33 +01003635 status = mbedtls_psa_rsa_load_representation( slot->attr.type,
3636 slot->key.data,
3637 slot->key.bytes,
3638 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02003639 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003640 goto exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02003641
Steven Cooremana2371e52020-07-28 14:30:39 +02003642 status = psa_rsa_verify( rsa,
Steven Cooremana01795d2020-07-24 22:48:15 +02003643 alg,
3644 hash, hash_length,
3645 signature, signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02003646 mbedtls_rsa_free( rsa );
3647 mbedtls_free( rsa );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003648 goto exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003649 }
3650 else
John Durkop6ba40d12020-11-10 08:50:04 -08003651#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3652 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine8e338702019-07-30 20:06:31 +02003653 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
itayzafrir5c753392018-05-08 11:18:38 +03003654 {
John Durkop9814fa22020-11-04 12:28:15 -08003655#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3656 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003657 if( PSA_ALG_IS_ECDSA( alg ) )
Steven Cooremanacda8342020-07-24 23:09:52 +02003658 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003659 mbedtls_ecp_keypair *ecp = NULL;
Ronald Cron90857082020-11-25 14:58:33 +01003660 status = mbedtls_psa_ecp_load_representation( slot->attr.type,
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +01003661 slot->attr.bits,
Ronald Cron90857082020-11-25 14:58:33 +01003662 slot->key.data,
3663 slot->key.bytes,
3664 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02003665 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003666 goto exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02003667 status = psa_ecdsa_verify( ecp,
Steven Cooremanacda8342020-07-24 23:09:52 +02003668 hash, hash_length,
3669 signature, signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02003670 mbedtls_ecp_keypair_free( ecp );
3671 mbedtls_free( ecp );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003672 goto exit;
Steven Cooremanacda8342020-07-24 23:09:52 +02003673 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003674 else
John Durkop9814fa22020-11-04 12:28:15 -08003675#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3676 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003677 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02003678 status = PSA_ERROR_INVALID_ARGUMENT;
3679 goto exit;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003680 }
itayzafrir5c753392018-05-08 11:18:38 +03003681 }
Gilles Peskine20035e32018-02-03 22:44:14 +01003682 else
Gilles Peskine20035e32018-02-03 22:44:14 +01003683 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02003684 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01003685 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02003686
3687exit:
Ronald Cron5c522922020-11-14 16:35:34 +01003688 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003689
Ronald Cron5c522922020-11-14 16:35:34 +01003690 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine20035e32018-02-03 22:44:14 +01003691}
3692
John Durkop0e005192020-10-31 22:06:54 -07003693#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine072ac562018-06-30 00:21:29 +02003694static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
3695 mbedtls_rsa_context *rsa )
3696{
3697 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
3698 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
3699 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
3700 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3701}
John Durkop0e005192020-10-31 22:06:54 -07003702#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Gilles Peskine072ac562018-06-30 00:21:29 +02003703
Ronald Croncf56a0a2020-08-04 09:51:30 +02003704psa_status_t psa_asymmetric_encrypt( mbedtls_svc_key_id_t key,
Gilles Peskine61b91d42018-06-08 16:09:36 +02003705 psa_algorithm_t alg,
3706 const uint8_t *input,
3707 size_t input_length,
3708 const uint8_t *salt,
3709 size_t salt_length,
3710 uint8_t *output,
3711 size_t output_size,
3712 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003713{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003714 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003715 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003716 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003717
Darryl Green5cc689a2018-07-24 15:34:10 +01003718 (void) input;
3719 (void) input_length;
3720 (void) salt;
3721 (void) output;
3722 (void) output_size;
3723
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03003724 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003725
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02003726 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
3727 return( PSA_ERROR_INVALID_ARGUMENT );
3728
Ronald Cron5c522922020-11-14 16:35:34 +01003729 status = psa_get_and_lock_transparent_key_slot_with_policy(
3730 key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003731 if( status != PSA_SUCCESS )
3732 return( status );
Gilles Peskine8e338702019-07-30 20:06:31 +02003733 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) ||
3734 PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003735 {
3736 status = PSA_ERROR_INVALID_ARGUMENT;
3737 goto exit;
3738 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003739
John Durkop6ba40d12020-11-10 08:50:04 -08003740#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
3741 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine8e338702019-07-30 20:06:31 +02003742 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003743 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003744 mbedtls_rsa_context *rsa = NULL;
Ronald Cron90857082020-11-25 14:58:33 +01003745 status = mbedtls_psa_rsa_load_representation( slot->attr.type,
3746 slot->key.data,
3747 slot->key.bytes,
3748 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02003749 if( status != PSA_SUCCESS )
Steven Cooreman4fed4552020-08-03 14:46:03 +02003750 goto rsa_exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02003751
3752 if( output_size < mbedtls_rsa_get_len( rsa ) )
Steven Cooremana01795d2020-07-24 22:48:15 +02003753 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003754 status = PSA_ERROR_BUFFER_TOO_SMALL;
3755 goto rsa_exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02003756 }
John Durkop0e005192020-10-31 22:06:54 -07003757#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
Gilles Peskine6afe7892018-05-31 13:16:08 +02003758 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003759 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003760 status = mbedtls_to_psa_error(
3761 mbedtls_rsa_pkcs1_encrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003762 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003763 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02003764 MBEDTLS_RSA_PUBLIC,
3765 input_length,
3766 input,
3767 output ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003768 }
3769 else
John Durkop0e005192020-10-31 22:06:54 -07003770#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
3771#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02003772 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003773 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003774 psa_rsa_oaep_set_padding_mode( alg, rsa );
Steven Cooreman4fed4552020-08-03 14:46:03 +02003775 status = mbedtls_to_psa_error(
3776 mbedtls_rsa_rsaes_oaep_encrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003777 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003778 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02003779 MBEDTLS_RSA_PUBLIC,
3780 salt, salt_length,
3781 input_length,
3782 input,
3783 output ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003784 }
3785 else
John Durkop0e005192020-10-31 22:06:54 -07003786#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003787 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003788 status = PSA_ERROR_INVALID_ARGUMENT;
3789 goto rsa_exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003790 }
Steven Cooreman4fed4552020-08-03 14:46:03 +02003791rsa_exit:
3792 if( status == PSA_SUCCESS )
Steven Cooremana2371e52020-07-28 14:30:39 +02003793 *output_length = mbedtls_rsa_get_len( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02003794
Steven Cooremana2371e52020-07-28 14:30:39 +02003795 mbedtls_rsa_free( rsa );
3796 mbedtls_free( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003797 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003798 else
John Durkop9814fa22020-11-04 12:28:15 -08003799#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
John Durkop6ba40d12020-11-10 08:50:04 -08003800 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003801 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02003802 status = PSA_ERROR_NOT_SUPPORTED;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003803 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02003804
3805exit:
Ronald Cron5c522922020-11-14 16:35:34 +01003806 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003807
Ronald Cron5c522922020-11-14 16:35:34 +01003808 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003809}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003810
Ronald Croncf56a0a2020-08-04 09:51:30 +02003811psa_status_t psa_asymmetric_decrypt( mbedtls_svc_key_id_t key,
Gilles Peskine61b91d42018-06-08 16:09:36 +02003812 psa_algorithm_t alg,
3813 const uint8_t *input,
3814 size_t input_length,
3815 const uint8_t *salt,
3816 size_t salt_length,
3817 uint8_t *output,
3818 size_t output_size,
3819 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003820{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003821 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003822 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003823 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003824
Darryl Green5cc689a2018-07-24 15:34:10 +01003825 (void) input;
3826 (void) input_length;
3827 (void) salt;
3828 (void) output;
3829 (void) output_size;
3830
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03003831 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003832
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02003833 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
3834 return( PSA_ERROR_INVALID_ARGUMENT );
3835
Ronald Cron5c522922020-11-14 16:35:34 +01003836 status = psa_get_and_lock_transparent_key_slot_with_policy(
3837 key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003838 if( status != PSA_SUCCESS )
3839 return( status );
Gilles Peskine8e338702019-07-30 20:06:31 +02003840 if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003841 {
3842 status = PSA_ERROR_INVALID_ARGUMENT;
3843 goto exit;
3844 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003845
John Durkop6ba40d12020-11-10 08:50:04 -08003846#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
3847 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine8e338702019-07-30 20:06:31 +02003848 if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003849 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003850 mbedtls_rsa_context *rsa = NULL;
Ronald Cron90857082020-11-25 14:58:33 +01003851 status = mbedtls_psa_rsa_load_representation( slot->attr.type,
3852 slot->key.data,
3853 slot->key.bytes,
3854 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02003855 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02003856 goto exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003857
Steven Cooremana2371e52020-07-28 14:30:39 +02003858 if( input_length != mbedtls_rsa_get_len( rsa ) )
Steven Cooremana01795d2020-07-24 22:48:15 +02003859 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003860 status = PSA_ERROR_INVALID_ARGUMENT;
3861 goto rsa_exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02003862 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003863
John Durkop0e005192020-10-31 22:06:54 -07003864#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
Gilles Peskine6afe7892018-05-31 13:16:08 +02003865 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003866 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003867 status = mbedtls_to_psa_error(
3868 mbedtls_rsa_pkcs1_decrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003869 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003870 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02003871 MBEDTLS_RSA_PRIVATE,
3872 output_length,
3873 input,
3874 output,
3875 output_size ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003876 }
3877 else
John Durkop0e005192020-10-31 22:06:54 -07003878#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
3879#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02003880 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003881 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003882 psa_rsa_oaep_set_padding_mode( alg, rsa );
Steven Cooreman4fed4552020-08-03 14:46:03 +02003883 status = mbedtls_to_psa_error(
3884 mbedtls_rsa_rsaes_oaep_decrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003885 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003886 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02003887 MBEDTLS_RSA_PRIVATE,
3888 salt, salt_length,
3889 output_length,
3890 input,
3891 output,
3892 output_size ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003893 }
3894 else
John Durkop0e005192020-10-31 22:06:54 -07003895#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003896 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02003897 status = PSA_ERROR_INVALID_ARGUMENT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003898 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03003899
Steven Cooreman4fed4552020-08-03 14:46:03 +02003900rsa_exit:
Steven Cooremana2371e52020-07-28 14:30:39 +02003901 mbedtls_rsa_free( rsa );
3902 mbedtls_free( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003903 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003904 else
John Durkop6ba40d12020-11-10 08:50:04 -08003905#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
3906 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003907 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02003908 status = PSA_ERROR_NOT_SUPPORTED;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003909 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02003910
3911exit:
Ronald Cron5c522922020-11-14 16:35:34 +01003912 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003913
Ronald Cron5c522922020-11-14 16:35:34 +01003914 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003915}
Gilles Peskine20035e32018-02-03 22:44:14 +01003916
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003917
3918
mohammad1603503973b2018-03-12 15:59:30 +02003919/****************************************************************/
3920/* Symmetric cryptography */
3921/****************************************************************/
3922
Gilles Peskinee553c652018-06-04 16:22:46 +02003923static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02003924 mbedtls_svc_key_id_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02003925 psa_algorithm_t alg,
3926 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02003927{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003928 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003929 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003930 int ret = 0;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003931 psa_key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02003932 size_t key_bits;
3933 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003934 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
3935 PSA_KEY_USAGE_ENCRYPT :
3936 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02003937
Steven Cooremand3feccd2020-09-01 15:56:14 +02003938 /* A context must be freshly initialized before it can be set up. */
3939 if( operation->alg != 0 )
3940 return( PSA_ERROR_BAD_STATE );
3941
Steven Cooremana07b9972020-09-10 14:54:14 +02003942 /* The requested algorithm must be one that can be processed by cipher. */
3943 if( ! PSA_ALG_IS_CIPHER( alg ) )
Steven Cooremana07b9972020-09-10 14:54:14 +02003944 return( PSA_ERROR_INVALID_ARGUMENT );
Steven Cooremand3feccd2020-09-01 15:56:14 +02003945
Steven Cooremanef8575e2020-09-11 11:44:50 +02003946 /* Fetch key material from key storage. */
Ronald Cron5c522922020-11-14 16:35:34 +01003947 status = psa_get_and_lock_key_slot_with_policy( key, &slot, usage, alg );
Steven Cooremanef8575e2020-09-11 11:44:50 +02003948 if( status != PSA_SUCCESS )
3949 goto exit;
3950
3951 /* Initialize the operation struct members, except for alg. The alg member
3952 * is used to indicate to psa_cipher_abort that there are resources to free,
3953 * so we only set it after resources have been allocated/initialized. */
Steven Cooremana07b9972020-09-10 14:54:14 +02003954 operation->key_set = 0;
3955 operation->iv_set = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02003956 operation->mbedtls_in_use = 0;
Steven Cooremana07b9972020-09-10 14:54:14 +02003957 operation->iv_size = 0;
3958 operation->block_size = 0;
3959 if( alg == PSA_ALG_ECB_NO_PADDING )
3960 operation->iv_required = 0;
3961 else
3962 operation->iv_required = 1;
3963
Steven Cooremana07b9972020-09-10 14:54:14 +02003964 /* Try doing the operation through a driver before using software fallback. */
Steven Cooreman37941cb2020-07-28 18:49:51 +02003965 if( cipher_operation == MBEDTLS_ENCRYPT )
Steven Cooremanfb81aa52020-09-09 12:01:43 +02003966 status = psa_driver_wrapper_cipher_encrypt_setup( &operation->ctx.driver,
Steven Cooreman37941cb2020-07-28 18:49:51 +02003967 slot,
3968 alg );
3969 else
Steven Cooremanfb81aa52020-09-09 12:01:43 +02003970 status = psa_driver_wrapper_cipher_decrypt_setup( &operation->ctx.driver,
Steven Cooreman37941cb2020-07-28 18:49:51 +02003971 slot,
3972 alg );
3973
Steven Cooremanef8575e2020-09-11 11:44:50 +02003974 if( status == PSA_SUCCESS )
Steven Cooreman6d81f7e2020-09-14 13:14:31 +02003975 {
Steven Cooremanef8575e2020-09-11 11:44:50 +02003976 /* Once the driver context is initialised, it needs to be freed using
3977 * psa_cipher_abort. Indicate this through setting alg. */
3978 operation->alg = alg;
Steven Cooreman6d81f7e2020-09-14 13:14:31 +02003979 }
Steven Cooremanef8575e2020-09-11 11:44:50 +02003980
Steven Cooremand3feccd2020-09-01 15:56:14 +02003981 if( status != PSA_ERROR_NOT_SUPPORTED ||
3982 psa_key_lifetime_is_external( slot->attr.lifetime ) )
3983 goto exit;
3984
Steven Cooremana07b9972020-09-10 14:54:14 +02003985 /* Proceed with initializing an mbed TLS cipher context if no driver is
Steven Cooremand3feccd2020-09-01 15:56:14 +02003986 * available for the given algorithm & key. */
3987 mbedtls_cipher_init( &operation->ctx.cipher );
mohammad1603503973b2018-03-12 15:59:30 +02003988
Steven Cooremana07b9972020-09-10 14:54:14 +02003989 /* Once the cipher context is initialised, it needs to be freed using
Steven Cooremanef8575e2020-09-11 11:44:50 +02003990 * psa_cipher_abort. Indicate there is something to be freed through setting
3991 * alg, and indicate the operation is being done using mbedtls crypto through
3992 * setting mbedtls_in_use. */
Steven Cooremana07b9972020-09-10 14:54:14 +02003993 operation->alg = alg;
Steven Cooremanef8575e2020-09-11 11:44:50 +02003994 operation->mbedtls_in_use = 1;
Steven Cooremana07b9972020-09-10 14:54:14 +02003995
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02003996 key_bits = psa_get_key_slot_bits( slot );
Gilles Peskine8e338702019-07-30 20:06:31 +02003997 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->attr.type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02003998 if( cipher_info == NULL )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003999 {
4000 status = PSA_ERROR_NOT_SUPPORTED;
4001 goto exit;
4002 }
mohammad1603503973b2018-03-12 15:59:30 +02004003
mohammad1603503973b2018-03-12 15:59:30 +02004004 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03004005 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004006 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004007
David Brown12ca5032021-02-11 11:02:00 -07004008#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskine8e338702019-07-30 20:06:31 +02004009 if( slot->attr.type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004010 {
4011 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02004012 uint8_t keys[24];
Ronald Cronea0f8a62020-11-25 17:52:23 +01004013 memcpy( keys, slot->key.data, 16 );
4014 memcpy( keys + 16, slot->key.data, 8 );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004015 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
4016 keys,
4017 192, cipher_operation );
4018 }
4019 else
4020#endif
4021 {
4022 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
Ronald Cronea0f8a62020-11-25 17:52:23 +01004023 slot->key.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004024 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004025 }
Moran Peker41deec42018-04-04 15:43:05 +03004026 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004027 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004028
David Brown63ca2602021-01-26 11:51:12 -07004029#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
4030 defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004031 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02004032 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004033 case PSA_ALG_CBC_NO_PADDING:
4034 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
4035 MBEDTLS_PADDING_NONE );
4036 break;
4037 case PSA_ALG_CBC_PKCS7:
4038 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
4039 MBEDTLS_PADDING_PKCS7 );
4040 break;
4041 default:
4042 /* The algorithm doesn't involve padding. */
4043 ret = 0;
4044 break;
4045 }
4046 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004047 goto exit;
David Brown288a96e2021-02-09 16:27:55 -07004048#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING || MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
mohammad16038481e742018-03-18 13:57:31 +02004049
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004050 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
gabor-mezei-armcbcec212020-12-18 14:23:51 +01004051 PSA_BLOCK_CIPHER_BLOCK_LENGTH( slot->attr.type ) );
Steven Cooremana6033e92020-08-25 11:47:50 +02004052 if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 &&
4053 alg != PSA_ALG_ECB_NO_PADDING )
mohammad16038481e742018-03-18 13:57:31 +02004054 {
gabor-mezei-armcbcec212020-12-18 14:23:51 +01004055 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( slot->attr.type );
mohammad16038481e742018-03-18 13:57:31 +02004056 }
David Brown1bfe4d72021-02-16 12:54:35 -07004057#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
Gilles Peskine26869f22019-05-06 15:25:00 +02004058 else
Bence Szépkúticbe39532020-12-08 00:01:31 +01004059 if( alg == PSA_ALG_STREAM_CIPHER && slot->attr.type == PSA_KEY_TYPE_CHACHA20 )
Gilles Peskine26869f22019-05-06 15:25:00 +02004060 operation->iv_size = 12;
4061#endif
mohammad1603503973b2018-03-12 15:59:30 +02004062
Steven Cooreman7df02922020-09-09 15:28:49 +02004063 status = PSA_SUCCESS;
4064
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004065exit:
Steven Cooreman7df02922020-09-09 15:28:49 +02004066 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004067 status = mbedtls_to_psa_error( ret );
Steven Cooreman7df02922020-09-09 15:28:49 +02004068 if( status == PSA_SUCCESS )
4069 {
4070 /* Update operation flags for both driver and software implementations */
4071 operation->key_set = 1;
4072 }
4073 else
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004074 psa_cipher_abort( operation );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004075
Ronald Cron5c522922020-11-14 16:35:34 +01004076 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004077
Ronald Cron5c522922020-11-14 16:35:34 +01004078 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
mohammad1603503973b2018-03-12 15:59:30 +02004079}
4080
Gilles Peskinefe119512018-07-08 21:39:34 +02004081psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004082 mbedtls_svc_key_id_t key,
Gilles Peskinefe119512018-07-08 21:39:34 +02004083 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02004084{
Ronald Croncf56a0a2020-08-04 09:51:30 +02004085 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02004086}
4087
Gilles Peskinefe119512018-07-08 21:39:34 +02004088psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004089 mbedtls_svc_key_id_t key,
Gilles Peskinefe119512018-07-08 21:39:34 +02004090 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02004091{
Ronald Croncf56a0a2020-08-04 09:51:30 +02004092 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02004093}
4094
Gilles Peskinefe119512018-07-08 21:39:34 +02004095psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004096 uint8_t *iv,
Gilles Peskinefe119512018-07-08 21:39:34 +02004097 size_t iv_size,
4098 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02004099{
itayzafrir534bd7c2018-08-02 13:56:32 +03004100 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00004101 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooreman7df02922020-09-09 15:28:49 +02004102 if( operation->iv_set || ! operation->iv_required )
4103 {
4104 return( PSA_ERROR_BAD_STATE );
4105 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004106
Steven Cooremanef8575e2020-09-11 11:44:50 +02004107 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004108 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004109 status = psa_driver_wrapper_cipher_generate_iv( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004110 iv,
4111 iv_size,
4112 iv_length );
4113 goto exit;
4114 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004115
Moran Peker41deec42018-04-04 15:43:05 +03004116 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02004117 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004118 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03004119 goto exit;
4120 }
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004121 ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004122 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03004123 if( ret != 0 )
4124 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004125 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02004126 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004127 }
Gilles Peskinee553c652018-06-04 16:22:46 +02004128
mohammad16038481e742018-03-18 13:57:31 +02004129 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03004130 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03004131
Moran Peker395db872018-05-31 14:07:14 +03004132exit:
Steven Cooreman7df02922020-09-09 15:28:49 +02004133 if( status == PSA_SUCCESS )
4134 operation->iv_set = 1;
4135 else
Moran Peker395db872018-05-31 14:07:14 +03004136 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004137 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004138}
4139
Gilles Peskinefe119512018-07-08 21:39:34 +02004140psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004141 const uint8_t *iv,
Gilles Peskinefe119512018-07-08 21:39:34 +02004142 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02004143{
itayzafrir534bd7c2018-08-02 13:56:32 +03004144 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00004145 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooreman7df02922020-09-09 15:28:49 +02004146 if( operation->iv_set || ! operation->iv_required )
4147 {
4148 return( PSA_ERROR_BAD_STATE );
4149 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004150
Steven Cooremanef8575e2020-09-11 11:44:50 +02004151 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004152 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004153 status = psa_driver_wrapper_cipher_set_iv( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004154 iv,
4155 iv_length );
4156 goto exit;
4157 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004158
Moran Pekera28258c2018-05-29 16:25:04 +03004159 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03004160 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004161 status = PSA_ERROR_INVALID_ARGUMENT;
4162 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03004163 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004164 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
4165 status = mbedtls_to_psa_error( ret );
4166exit:
4167 if( status == PSA_SUCCESS )
4168 operation->iv_set = 1;
4169 else
mohammad1603503973b2018-03-12 15:59:30 +02004170 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004171 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004172}
4173
Steven Cooreman177deba2020-09-07 17:14:14 +02004174/* Process input for which the algorithm is set to ECB mode. This requires
4175 * manual processing, since the PSA API is defined as being able to process
4176 * arbitrary-length calls to psa_cipher_update() with ECB mode, but the
4177 * underlying mbedtls_cipher_update only takes full blocks. */
4178static psa_status_t psa_cipher_update_ecb_internal(
4179 mbedtls_cipher_context_t *ctx,
4180 const uint8_t *input,
4181 size_t input_length,
4182 uint8_t *output,
4183 size_t output_size,
4184 size_t *output_length )
4185{
4186 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4187 size_t block_size = ctx->cipher_info->block_size;
4188 size_t internal_output_length = 0;
4189 *output_length = 0;
4190
4191 if( input_length == 0 )
4192 {
4193 status = PSA_SUCCESS;
4194 goto exit;
4195 }
4196
4197 if( ctx->unprocessed_len > 0 )
4198 {
4199 /* Fill up to block size, and run the block if there's a full one. */
4200 size_t bytes_to_copy = block_size - ctx->unprocessed_len;
4201
4202 if( input_length < bytes_to_copy )
4203 bytes_to_copy = input_length;
4204
4205 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
4206 input, bytes_to_copy );
4207 input_length -= bytes_to_copy;
4208 input += bytes_to_copy;
4209 ctx->unprocessed_len += bytes_to_copy;
4210
4211 if( ctx->unprocessed_len == block_size )
4212 {
4213 status = mbedtls_to_psa_error(
4214 mbedtls_cipher_update( ctx,
4215 ctx->unprocessed_data,
4216 block_size,
4217 output, &internal_output_length ) );
4218
4219 if( status != PSA_SUCCESS )
4220 goto exit;
4221
4222 output += internal_output_length;
4223 output_size -= internal_output_length;
4224 *output_length += internal_output_length;
4225 ctx->unprocessed_len = 0;
4226 }
4227 }
4228
4229 while( input_length >= block_size )
4230 {
4231 /* Run all full blocks we have, one by one */
4232 status = mbedtls_to_psa_error(
4233 mbedtls_cipher_update( ctx, input,
4234 block_size,
4235 output, &internal_output_length ) );
4236
4237 if( status != PSA_SUCCESS )
4238 goto exit;
4239
4240 input_length -= block_size;
4241 input += block_size;
4242
4243 output += internal_output_length;
4244 output_size -= internal_output_length;
4245 *output_length += internal_output_length;
4246 }
4247
4248 if( input_length > 0 )
4249 {
4250 /* Save unprocessed bytes for later processing */
4251 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
4252 input, input_length );
4253 ctx->unprocessed_len += input_length;
4254 }
4255
4256 status = PSA_SUCCESS;
4257
4258exit:
4259 return( status );
4260}
4261
Gilles Peskinee553c652018-06-04 16:22:46 +02004262psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
4263 const uint8_t *input,
4264 size_t input_length,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004265 uint8_t *output,
Gilles Peskinee553c652018-06-04 16:22:46 +02004266 size_t output_size,
4267 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02004268{
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004269 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine89d789c2018-06-04 17:17:16 +02004270 size_t expected_output_size;
Steven Cooreman7df02922020-09-09 15:28:49 +02004271 if( operation->alg == 0 )
4272 {
4273 return( PSA_ERROR_BAD_STATE );
4274 }
4275 if( operation->iv_required && ! operation->iv_set )
4276 {
4277 return( PSA_ERROR_BAD_STATE );
4278 }
Jaeden Ameroab439972019-02-15 14:12:05 +00004279
Steven Cooremanef8575e2020-09-11 11:44:50 +02004280 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004281 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004282 status = psa_driver_wrapper_cipher_update( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004283 input,
4284 input_length,
4285 output,
4286 output_size,
4287 output_length );
4288 goto exit;
4289 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004290
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004291 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02004292 {
4293 /* Take the unprocessed partial block left over from previous
4294 * update calls, if any, plus the input to this call. Remove
4295 * the last partial block, if any. You get the data that will be
4296 * output in this call. */
4297 expected_output_size =
4298 ( operation->ctx.cipher.unprocessed_len + input_length )
4299 / operation->block_size * operation->block_size;
4300 }
4301 else
4302 {
4303 expected_output_size = input_length;
4304 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004305
Gilles Peskine89d789c2018-06-04 17:17:16 +02004306 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03004307 {
4308 status = PSA_ERROR_BUFFER_TOO_SMALL;
4309 goto exit;
4310 }
mohammad160382759612018-03-12 18:16:40 +02004311
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004312 if( operation->alg == PSA_ALG_ECB_NO_PADDING )
4313 {
4314 /* mbedtls_cipher_update has an API inconsistency: it will only
4315 * process a single block at a time in ECB mode. Abstract away that
4316 * inconsistency here to match the PSA API behaviour. */
Steven Cooreman177deba2020-09-07 17:14:14 +02004317 status = psa_cipher_update_ecb_internal( &operation->ctx.cipher,
4318 input,
4319 input_length,
4320 output,
4321 output_size,
4322 output_length );
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004323 }
4324 else
4325 {
4326 status = mbedtls_to_psa_error(
4327 mbedtls_cipher_update( &operation->ctx.cipher, input,
4328 input_length, output, output_length ) );
4329 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004330exit:
4331 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02004332 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004333 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004334}
4335
Gilles Peskinee553c652018-06-04 16:22:46 +02004336psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
4337 uint8_t *output,
4338 size_t output_size,
4339 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02004340{
David Saadab4ecc272019-02-14 13:48:10 +02004341 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskinee553c652018-06-04 16:22:46 +02004342 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Steven Cooreman7df02922020-09-09 15:28:49 +02004343 if( operation->alg == 0 )
4344 {
4345 return( PSA_ERROR_BAD_STATE );
4346 }
4347 if( operation->iv_required && ! operation->iv_set )
4348 {
4349 return( PSA_ERROR_BAD_STATE );
4350 }
Moran Pekerbed71a22018-04-22 20:19:20 +03004351
Steven Cooremanef8575e2020-09-11 11:44:50 +02004352 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004353 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004354 status = psa_driver_wrapper_cipher_finish( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004355 output,
4356 output_size,
4357 output_length );
Steven Cooremanef8575e2020-09-11 11:44:50 +02004358 goto exit;
Steven Cooreman8b122252020-09-03 15:30:32 +02004359 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004360
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004361 if( operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03004362 {
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004363 if( operation->alg == PSA_ALG_ECB_NO_PADDING ||
Fredrik Strupef90e3012020-09-28 16:11:33 +02004364 operation->alg == PSA_ALG_CBC_NO_PADDING )
Steven Cooremana6033e92020-08-25 11:47:50 +02004365 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004366 status = PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004367 goto exit;
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004368 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004369 }
4370
Steven Cooremanef8575e2020-09-11 11:44:50 +02004371 status = mbedtls_to_psa_error(
4372 mbedtls_cipher_finish( &operation->ctx.cipher,
4373 temp_output_buffer,
4374 output_length ) );
4375 if( status != PSA_SUCCESS )
4376 goto exit;
Janos Follath315b51c2018-07-09 16:04:51 +01004377
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004378 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01004379 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004380 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004381 memcpy( output, temp_output_buffer, *output_length );
4382 else
Janos Follath315b51c2018-07-09 16:04:51 +01004383 status = PSA_ERROR_BUFFER_TOO_SMALL;
mohammad1603503973b2018-03-12 15:59:30 +02004384
Steven Cooremanef8575e2020-09-11 11:44:50 +02004385exit:
4386 if( operation->mbedtls_in_use == 1 )
4387 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01004388
Steven Cooremanef8575e2020-09-11 11:44:50 +02004389 if( status == PSA_SUCCESS )
4390 return( psa_cipher_abort( operation ) );
4391 else
4392 {
4393 *output_length = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004394 (void) psa_cipher_abort( operation );
Janos Follath315b51c2018-07-09 16:04:51 +01004395
Steven Cooremanef8575e2020-09-11 11:44:50 +02004396 return( status );
4397 }
mohammad1603503973b2018-03-12 15:59:30 +02004398}
4399
Gilles Peskinee553c652018-06-04 16:22:46 +02004400psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
4401{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004402 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02004403 {
Steven Cooremana07b9972020-09-10 14:54:14 +02004404 /* The object has (apparently) been initialized but it is not (yet)
Gilles Peskine81736312018-06-26 15:04:31 +02004405 * in use. It's ok to call abort on such an object, and there's
4406 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004407 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02004408 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004409
Gilles Peskinef9c2c092018-06-21 16:57:07 +02004410 /* Sanity check (shouldn't happen: operation->alg should
4411 * always have been initialized to a valid value). */
4412 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
4413 return( PSA_ERROR_BAD_STATE );
4414
Steven Cooremanef8575e2020-09-11 11:44:50 +02004415 if( operation->mbedtls_in_use == 0 )
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004416 psa_driver_wrapper_cipher_abort( &operation->ctx.driver );
Steven Cooremand3feccd2020-09-01 15:56:14 +02004417 else
4418 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02004419
Moran Peker41deec42018-04-04 15:43:05 +03004420 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004421 operation->key_set = 0;
4422 operation->iv_set = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004423 operation->mbedtls_in_use = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004424 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03004425 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004426 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03004427
Moran Peker395db872018-05-31 14:07:14 +03004428 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02004429}
4430
Gilles Peskinea0655c32018-04-30 17:06:50 +02004431
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004432
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004433
mohammad16035955c982018-04-26 00:53:03 +03004434/****************************************************************/
4435/* AEAD */
4436/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004437
Gilles Peskineedf9a652018-08-17 18:11:56 +02004438typedef struct
4439{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004440 psa_key_slot_t *slot;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004441 const mbedtls_cipher_info_t *cipher_info;
4442 union
4443 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004444 unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
Gilles Peskineedf9a652018-08-17 18:11:56 +02004445#if defined(MBEDTLS_CCM_C)
4446 mbedtls_ccm_context ccm;
4447#endif /* MBEDTLS_CCM_C */
4448#if defined(MBEDTLS_GCM_C)
4449 mbedtls_gcm_context gcm;
4450#endif /* MBEDTLS_GCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02004451#if defined(MBEDTLS_CHACHAPOLY_C)
4452 mbedtls_chachapoly_context chachapoly;
4453#endif /* MBEDTLS_CHACHAPOLY_C */
Gilles Peskineedf9a652018-08-17 18:11:56 +02004454 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004455 psa_algorithm_t core_alg;
4456 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004457 uint8_t tag_length;
4458} aead_operation_t;
4459
Ronald Cronf95a2b12020-10-22 15:24:49 +02004460#define AEAD_OPERATION_INIT {0, 0, {0}, 0, 0, 0}
4461
Gilles Peskine30a9e412019-01-14 18:36:12 +01004462static void psa_aead_abort_internal( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004463{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02004464 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004465 {
4466#if defined(MBEDTLS_CCM_C)
4467 case PSA_ALG_CCM:
4468 mbedtls_ccm_free( &operation->ctx.ccm );
4469 break;
4470#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004471#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02004472 case PSA_ALG_GCM:
4473 mbedtls_gcm_free( &operation->ctx.gcm );
4474 break;
4475#endif /* MBEDTLS_GCM_C */
4476 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004477
Ronald Cron5c522922020-11-14 16:35:34 +01004478 psa_unlock_key_slot( operation->slot );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004479}
4480
4481static psa_status_t psa_aead_setup( aead_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004482 mbedtls_svc_key_id_t key,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004483 psa_key_usage_t usage,
4484 psa_algorithm_t alg )
4485{
4486 psa_status_t status;
4487 size_t key_bits;
4488 mbedtls_cipher_id_t cipher_id;
4489
Ronald Cron5c522922020-11-14 16:35:34 +01004490 status = psa_get_and_lock_transparent_key_slot_with_policy(
4491 key, &operation->slot, usage, alg );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004492 if( status != PSA_SUCCESS )
4493 return( status );
4494
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02004495 key_bits = psa_get_key_slot_bits( operation->slot );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004496
4497 operation->cipher_info =
Gilles Peskine8e338702019-07-30 20:06:31 +02004498 mbedtls_cipher_info_from_psa( alg, operation->slot->attr.type, key_bits,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004499 &cipher_id );
4500 if( operation->cipher_info == NULL )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004501 {
4502 status = PSA_ERROR_NOT_SUPPORTED;
4503 goto cleanup;
4504 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004505
Bence Szépkútia63b20d2020-12-16 11:36:46 +01004506 switch( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004507 {
4508#if defined(MBEDTLS_CCM_C)
Bence Szépkútia63b20d2020-12-16 11:36:46 +01004509 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004510 operation->core_alg = PSA_ALG_CCM;
4511 operation->full_tag_length = 16;
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004512 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
4513 * The call to mbedtls_ccm_encrypt_and_tag or
4514 * mbedtls_ccm_auth_decrypt will validate the tag length. */
gabor-mezei-armcbcec212020-12-18 14:23:51 +01004515 if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( operation->slot->attr.type ) != 16 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004516 {
4517 status = PSA_ERROR_INVALID_ARGUMENT;
4518 goto cleanup;
4519 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004520 mbedtls_ccm_init( &operation->ctx.ccm );
4521 status = mbedtls_to_psa_error(
4522 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
Ronald Cronea0f8a62020-11-25 17:52:23 +01004523 operation->slot->key.data,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004524 (unsigned int) key_bits ) );
4525 if( status != 0 )
4526 goto cleanup;
4527 break;
4528#endif /* MBEDTLS_CCM_C */
4529
4530#if defined(MBEDTLS_GCM_C)
Bence Szépkútia63b20d2020-12-16 11:36:46 +01004531 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004532 operation->core_alg = PSA_ALG_GCM;
4533 operation->full_tag_length = 16;
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004534 /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
4535 * The call to mbedtls_gcm_crypt_and_tag or
4536 * mbedtls_gcm_auth_decrypt will validate the tag length. */
gabor-mezei-armcbcec212020-12-18 14:23:51 +01004537 if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( operation->slot->attr.type ) != 16 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004538 {
4539 status = PSA_ERROR_INVALID_ARGUMENT;
4540 goto cleanup;
4541 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004542 mbedtls_gcm_init( &operation->ctx.gcm );
4543 status = mbedtls_to_psa_error(
4544 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
Ronald Cronea0f8a62020-11-25 17:52:23 +01004545 operation->slot->key.data,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004546 (unsigned int) key_bits ) );
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004547 if( status != 0 )
4548 goto cleanup;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004549 break;
4550#endif /* MBEDTLS_GCM_C */
4551
Gilles Peskine26869f22019-05-06 15:25:00 +02004552#if defined(MBEDTLS_CHACHAPOLY_C)
Bence Szépkútia63b20d2020-12-16 11:36:46 +01004553 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
Gilles Peskine26869f22019-05-06 15:25:00 +02004554 operation->core_alg = PSA_ALG_CHACHA20_POLY1305;
4555 operation->full_tag_length = 16;
4556 /* We only support the default tag length. */
4557 if( alg != PSA_ALG_CHACHA20_POLY1305 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004558 {
4559 status = PSA_ERROR_NOT_SUPPORTED;
4560 goto cleanup;
4561 }
Gilles Peskine26869f22019-05-06 15:25:00 +02004562 mbedtls_chachapoly_init( &operation->ctx.chachapoly );
4563 status = mbedtls_to_psa_error(
4564 mbedtls_chachapoly_setkey( &operation->ctx.chachapoly,
Ronald Cronea0f8a62020-11-25 17:52:23 +01004565 operation->slot->key.data ) );
Gilles Peskine26869f22019-05-06 15:25:00 +02004566 if( status != 0 )
4567 goto cleanup;
4568 break;
4569#endif /* MBEDTLS_CHACHAPOLY_C */
4570
Gilles Peskineedf9a652018-08-17 18:11:56 +02004571 default:
Ronald Cronf95a2b12020-10-22 15:24:49 +02004572 status = PSA_ERROR_NOT_SUPPORTED;
4573 goto cleanup;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004574 }
4575
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004576 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
4577 {
4578 status = PSA_ERROR_INVALID_ARGUMENT;
4579 goto cleanup;
4580 }
4581 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004582
Gilles Peskineedf9a652018-08-17 18:11:56 +02004583 return( PSA_SUCCESS );
4584
4585cleanup:
Gilles Peskine30a9e412019-01-14 18:36:12 +01004586 psa_aead_abort_internal( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004587 return( status );
4588}
4589
Ronald Croncf56a0a2020-08-04 09:51:30 +02004590psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key,
mohammad16035955c982018-04-26 00:53:03 +03004591 psa_algorithm_t alg,
4592 const uint8_t *nonce,
4593 size_t nonce_length,
4594 const uint8_t *additional_data,
4595 size_t additional_data_length,
4596 const uint8_t *plaintext,
4597 size_t plaintext_length,
4598 uint8_t *ciphertext,
4599 size_t ciphertext_size,
4600 size_t *ciphertext_length )
4601{
mohammad16035955c982018-04-26 00:53:03 +03004602 psa_status_t status;
Ronald Cronf95a2b12020-10-22 15:24:49 +02004603 aead_operation_t operation = AEAD_OPERATION_INIT;
mohammad160315223a82018-06-03 17:19:55 +03004604 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02004605
mohammad1603f08a5502018-06-03 15:05:47 +03004606 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07004607
Ronald Croncf56a0a2020-08-04 09:51:30 +02004608 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004609 if( status != PSA_SUCCESS )
4610 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004611
Gilles Peskineedf9a652018-08-17 18:11:56 +02004612 /* For all currently supported modes, the tag is at the end of the
4613 * ciphertext. */
4614 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
4615 {
4616 status = PSA_ERROR_BUFFER_TOO_SMALL;
4617 goto exit;
4618 }
4619 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03004620
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004621#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004622 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03004623 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004624 status = mbedtls_to_psa_error(
4625 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
4626 MBEDTLS_GCM_ENCRYPT,
4627 plaintext_length,
4628 nonce, nonce_length,
4629 additional_data, additional_data_length,
4630 plaintext, ciphertext,
4631 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03004632 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004633 else
4634#endif /* MBEDTLS_GCM_C */
4635#if defined(MBEDTLS_CCM_C)
4636 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03004637 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004638 status = mbedtls_to_psa_error(
4639 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
4640 plaintext_length,
4641 nonce, nonce_length,
4642 additional_data,
4643 additional_data_length,
4644 plaintext, ciphertext,
4645 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03004646 }
mohammad16035c8845f2018-05-09 05:40:09 -07004647 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004648#endif /* MBEDTLS_CCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02004649#if defined(MBEDTLS_CHACHAPOLY_C)
4650 if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
4651 {
4652 if( nonce_length != 12 || operation.tag_length != 16 )
4653 {
4654 status = PSA_ERROR_NOT_SUPPORTED;
4655 goto exit;
4656 }
4657 status = mbedtls_to_psa_error(
4658 mbedtls_chachapoly_encrypt_and_tag( &operation.ctx.chachapoly,
4659 plaintext_length,
4660 nonce,
4661 additional_data,
4662 additional_data_length,
4663 plaintext,
4664 ciphertext,
4665 tag ) );
4666 }
4667 else
4668#endif /* MBEDTLS_CHACHAPOLY_C */
mohammad16035c8845f2018-05-09 05:40:09 -07004669 {
Steven Cooreman7196fef2021-02-10 17:13:28 +01004670 (void) tag;
mohammad1603554faad2018-06-03 15:07:38 +03004671 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07004672 }
Gilles Peskine2d277862018-06-18 15:41:12 +02004673
Gilles Peskineedf9a652018-08-17 18:11:56 +02004674 if( status != PSA_SUCCESS && ciphertext_size != 0 )
4675 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02004676
Gilles Peskineedf9a652018-08-17 18:11:56 +02004677exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01004678 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004679 if( status == PSA_SUCCESS )
4680 *ciphertext_length = plaintext_length + operation.tag_length;
4681 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004682}
4683
Gilles Peskineee652a32018-06-01 19:23:52 +02004684/* Locate the tag in a ciphertext buffer containing the encrypted data
4685 * followed by the tag. Return the length of the part preceding the tag in
4686 * *plaintext_length. This is the size of the plaintext in modes where
4687 * the encrypted data has the same size as the plaintext, such as
4688 * CCM and GCM. */
4689static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
4690 const uint8_t *ciphertext,
4691 size_t ciphertext_length,
4692 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02004693 const uint8_t **p_tag )
4694{
4695 size_t payload_length;
4696 if( tag_length > ciphertext_length )
4697 return( PSA_ERROR_INVALID_ARGUMENT );
4698 payload_length = ciphertext_length - tag_length;
4699 if( payload_length > plaintext_size )
4700 return( PSA_ERROR_BUFFER_TOO_SMALL );
4701 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02004702 return( PSA_SUCCESS );
4703}
4704
Ronald Croncf56a0a2020-08-04 09:51:30 +02004705psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key,
mohammad16035955c982018-04-26 00:53:03 +03004706 psa_algorithm_t alg,
4707 const uint8_t *nonce,
4708 size_t nonce_length,
4709 const uint8_t *additional_data,
4710 size_t additional_data_length,
4711 const uint8_t *ciphertext,
4712 size_t ciphertext_length,
4713 uint8_t *plaintext,
4714 size_t plaintext_size,
4715 size_t *plaintext_length )
4716{
mohammad16035955c982018-04-26 00:53:03 +03004717 psa_status_t status;
Ronald Cronf95a2b12020-10-22 15:24:49 +02004718 aead_operation_t operation = AEAD_OPERATION_INIT;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004719 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02004720
Gilles Peskineee652a32018-06-01 19:23:52 +02004721 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03004722
Ronald Croncf56a0a2020-08-04 09:51:30 +02004723 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004724 if( status != PSA_SUCCESS )
4725 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004726
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004727 status = psa_aead_unpadded_locate_tag( operation.tag_length,
4728 ciphertext, ciphertext_length,
4729 plaintext_size, &tag );
4730 if( status != PSA_SUCCESS )
4731 goto exit;
4732
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004733#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004734 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03004735 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004736 status = mbedtls_to_psa_error(
4737 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
4738 ciphertext_length - operation.tag_length,
4739 nonce, nonce_length,
4740 additional_data,
4741 additional_data_length,
4742 tag, operation.tag_length,
4743 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03004744 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004745 else
4746#endif /* MBEDTLS_GCM_C */
4747#if defined(MBEDTLS_CCM_C)
4748 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03004749 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004750 status = mbedtls_to_psa_error(
4751 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
4752 ciphertext_length - operation.tag_length,
4753 nonce, nonce_length,
4754 additional_data,
4755 additional_data_length,
4756 ciphertext, plaintext,
4757 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03004758 }
mohammad160339574652018-06-01 04:39:53 -07004759 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004760#endif /* MBEDTLS_CCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02004761#if defined(MBEDTLS_CHACHAPOLY_C)
4762 if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
4763 {
4764 if( nonce_length != 12 || operation.tag_length != 16 )
4765 {
4766 status = PSA_ERROR_NOT_SUPPORTED;
4767 goto exit;
4768 }
4769 status = mbedtls_to_psa_error(
4770 mbedtls_chachapoly_auth_decrypt( &operation.ctx.chachapoly,
4771 ciphertext_length - operation.tag_length,
4772 nonce,
4773 additional_data,
4774 additional_data_length,
4775 tag,
4776 ciphertext,
4777 plaintext ) );
4778 }
4779 else
4780#endif /* MBEDTLS_CHACHAPOLY_C */
mohammad160339574652018-06-01 04:39:53 -07004781 {
mohammad1603554faad2018-06-03 15:07:38 +03004782 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07004783 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02004784
Gilles Peskineedf9a652018-08-17 18:11:56 +02004785 if( status != PSA_SUCCESS && plaintext_size != 0 )
4786 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03004787
Gilles Peskineedf9a652018-08-17 18:11:56 +02004788exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01004789 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004790 if( status == PSA_SUCCESS )
4791 *plaintext_length = ciphertext_length - operation.tag_length;
4792 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004793}
4794
Gilles Peskinea0655c32018-04-30 17:06:50 +02004795
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004796
Gilles Peskine20035e32018-02-03 22:44:14 +01004797/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004798/* Generators */
4799/****************************************************************/
4800
John Durkop07cc04a2020-11-16 22:08:34 -08004801#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
4802 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4803 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4804#define AT_LEAST_ONE_BUILTIN_KDF
4805#endif
4806
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004807#define HKDF_STATE_INIT 0 /* no input yet */
4808#define HKDF_STATE_STARTED 1 /* got salt */
4809#define HKDF_STATE_KEYED 2 /* got key */
4810#define HKDF_STATE_OUTPUT 3 /* output started */
4811
Gilles Peskinecbe66502019-05-16 16:59:18 +02004812static psa_algorithm_t psa_key_derivation_get_kdf_alg(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004813 const psa_key_derivation_operation_t *operation )
Gilles Peskine969c5d62019-01-16 15:53:06 +01004814{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004815 if ( PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
4816 return( PSA_ALG_KEY_AGREEMENT_GET_KDF( operation->alg ) );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004817 else
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004818 return( operation->alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004819}
4820
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004821psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004822{
4823 psa_status_t status = PSA_SUCCESS;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004824 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004825 if( kdf_alg == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004826 {
4827 /* The object has (apparently) been initialized but it is not
4828 * in use. It's ok to call abort on such an object, and there's
4829 * nothing to do. */
4830 }
4831 else
John Durkopd0321952020-10-29 21:37:36 -07004832#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01004833 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02004834 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004835 mbedtls_free( operation->ctx.hkdf.info );
4836 status = psa_hmac_abort_internal( &operation->ctx.hkdf.hmac );
Gilles Peskinebef7f142018-07-12 17:22:21 +02004837 }
John Durkop07cc04a2020-11-16 22:08:34 -08004838 else
4839#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF */
4840#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4841 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4842 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004843 /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01004844 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004845 {
Janos Follath6a1d2622019-06-11 10:37:28 +01004846 if( operation->ctx.tls12_prf.seed != NULL )
4847 {
4848 mbedtls_platform_zeroize( operation->ctx.tls12_prf.seed,
4849 operation->ctx.tls12_prf.seed_length );
4850 mbedtls_free( operation->ctx.tls12_prf.seed );
4851 }
4852
4853 if( operation->ctx.tls12_prf.label != NULL )
4854 {
4855 mbedtls_platform_zeroize( operation->ctx.tls12_prf.label,
4856 operation->ctx.tls12_prf.label_length );
4857 mbedtls_free( operation->ctx.tls12_prf.label );
4858 }
4859
4860 status = psa_hmac_abort_internal( &operation->ctx.tls12_prf.hmac );
4861
4862 /* We leave the fields Ai and output_block to be erased safely by the
4863 * mbedtls_platform_zeroize() in the end of this function. */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004864 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02004865 else
John Durkop07cc04a2020-11-16 22:08:34 -08004866#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
4867 * defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) */
Gilles Peskineeab56e42018-07-12 17:12:33 +02004868 {
4869 status = PSA_ERROR_BAD_STATE;
4870 }
Janos Follath083036a2019-06-11 10:22:26 +01004871 mbedtls_platform_zeroize( operation, sizeof( *operation ) );
Gilles Peskineeab56e42018-07-12 17:12:33 +02004872 return( status );
4873}
4874
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004875psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation,
Gilles Peskineeab56e42018-07-12 17:12:33 +02004876 size_t *capacity)
4877{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004878 if( operation->alg == 0 )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004879 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004880 /* This is a blank key derivation operation. */
Steven Cooreman29149862020-08-05 15:43:42 +02004881 return( PSA_ERROR_BAD_STATE );
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004882 }
4883
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004884 *capacity = operation->capacity;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004885 return( PSA_SUCCESS );
4886}
4887
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004888psa_status_t psa_key_derivation_set_capacity( psa_key_derivation_operation_t *operation,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004889 size_t capacity )
4890{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004891 if( operation->alg == 0 )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004892 return( PSA_ERROR_BAD_STATE );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004893 if( capacity > operation->capacity )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004894 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004895 operation->capacity = capacity;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004896 return( PSA_SUCCESS );
4897}
4898
John Durkopd0321952020-10-29 21:37:36 -07004899#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004900/* Read some bytes from an HKDF-based operation. This performs a chunk
Gilles Peskinebef7f142018-07-12 17:22:21 +02004901 * of the expand phase of the HKDF algorithm. */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004902static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkdf,
Gilles Peskinebef7f142018-07-12 17:22:21 +02004903 psa_algorithm_t hash_alg,
4904 uint8_t *output,
4905 size_t output_length )
4906{
gabor-mezei-armcbcec212020-12-18 14:23:51 +01004907 uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
Gilles Peskinebef7f142018-07-12 17:22:21 +02004908 psa_status_t status;
4909
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004910 if( hkdf->state < HKDF_STATE_KEYED || ! hkdf->info_set )
4911 return( PSA_ERROR_BAD_STATE );
4912 hkdf->state = HKDF_STATE_OUTPUT;
4913
Gilles Peskinebef7f142018-07-12 17:22:21 +02004914 while( output_length != 0 )
4915 {
4916 /* Copy what remains of the current block */
4917 uint8_t n = hash_length - hkdf->offset_in_block;
4918 if( n > output_length )
4919 n = (uint8_t) output_length;
4920 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
4921 output += n;
4922 output_length -= n;
4923 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02004924 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02004925 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02004926 /* We can't be wanting more output after block 0xff, otherwise
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004927 * the capacity check in psa_key_derivation_output_bytes() would have
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004928 * prevented this call. It could happen only if the operation
Gilles Peskined54931c2018-07-17 21:06:59 +02004929 * object was corrupted or if this function is called directly
4930 * inside the library. */
4931 if( hkdf->block_number == 0xff )
4932 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02004933
4934 /* We need a new block */
4935 ++hkdf->block_number;
4936 hkdf->offset_in_block = 0;
4937 status = psa_hmac_setup_internal( &hkdf->hmac,
4938 hkdf->prk, hash_length,
4939 hash_alg );
4940 if( status != PSA_SUCCESS )
4941 return( status );
4942 if( hkdf->block_number != 1 )
4943 {
4944 status = psa_hash_update( &hkdf->hmac.hash_ctx,
4945 hkdf->output_block,
4946 hash_length );
4947 if( status != PSA_SUCCESS )
4948 return( status );
4949 }
4950 status = psa_hash_update( &hkdf->hmac.hash_ctx,
4951 hkdf->info,
4952 hkdf->info_length );
4953 if( status != PSA_SUCCESS )
4954 return( status );
4955 status = psa_hash_update( &hkdf->hmac.hash_ctx,
4956 &hkdf->block_number, 1 );
4957 if( status != PSA_SUCCESS )
4958 return( status );
4959 status = psa_hmac_finish_internal( &hkdf->hmac,
4960 hkdf->output_block,
4961 sizeof( hkdf->output_block ) );
4962 if( status != PSA_SUCCESS )
4963 return( status );
4964 }
4965
4966 return( PSA_SUCCESS );
4967}
John Durkop07cc04a2020-11-16 22:08:34 -08004968#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004969
John Durkop07cc04a2020-11-16 22:08:34 -08004970#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4971 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follath7742fee2019-06-17 12:58:10 +01004972static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
4973 psa_tls12_prf_key_derivation_t *tls12_prf,
4974 psa_algorithm_t alg )
4975{
4976 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
gabor-mezei-armcbcec212020-12-18 14:23:51 +01004977 uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
Janos Follathea29bfb2019-06-19 12:21:20 +01004978 psa_hash_operation_t backup = PSA_HASH_OPERATION_INIT;
4979 psa_status_t status, cleanup_status;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004980
Janos Follath7742fee2019-06-17 12:58:10 +01004981 /* We can't be wanting more output after block 0xff, otherwise
4982 * the capacity check in psa_key_derivation_output_bytes() would have
4983 * prevented this call. It could happen only if the operation
4984 * object was corrupted or if this function is called directly
4985 * inside the library. */
4986 if( tls12_prf->block_number == 0xff )
Janos Follath30090bc2019-06-25 10:15:04 +01004987 return( PSA_ERROR_CORRUPTION_DETECTED );
Janos Follath7742fee2019-06-17 12:58:10 +01004988
4989 /* We need a new block */
4990 ++tls12_prf->block_number;
Janos Follath844eb0e2019-06-19 12:10:49 +01004991 tls12_prf->left_in_block = hash_length;
Janos Follath7742fee2019-06-17 12:58:10 +01004992
4993 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
4994 *
4995 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
4996 *
4997 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
4998 * HMAC_hash(secret, A(2) + seed) +
4999 * HMAC_hash(secret, A(3) + seed) + ...
5000 *
5001 * A(0) = seed
Janos Follathea29bfb2019-06-19 12:21:20 +01005002 * A(i) = HMAC_hash(secret, A(i-1))
Janos Follath7742fee2019-06-17 12:58:10 +01005003 *
Janos Follathea29bfb2019-06-19 12:21:20 +01005004 * The `psa_tls12_prf_key_derivation` structure saves the block
Janos Follath7742fee2019-06-17 12:58:10 +01005005 * `HMAC_hash(secret, A(i) + seed)` from which the output
Janos Follath76c39842019-06-26 12:50:36 +01005006 * is currently extracted as `output_block` and where i is
5007 * `block_number`.
Janos Follath7742fee2019-06-17 12:58:10 +01005008 */
5009
Janos Follathea29bfb2019-06-19 12:21:20 +01005010 /* Save the hash context before using it, to preserve the hash state with
5011 * only the inner padding in it. We need this, because inner padding depends
5012 * on the key (secret in the RFC's terminology). */
5013 status = psa_hash_clone( &tls12_prf->hmac.hash_ctx, &backup );
5014 if( status != PSA_SUCCESS )
5015 goto cleanup;
5016
5017 /* Calculate A(i) where i = tls12_prf->block_number. */
5018 if( tls12_prf->block_number == 1 )
5019 {
5020 /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads
5021 * the variable seed and in this instance means it in the context of the
5022 * P_hash function, where seed = label + seed.) */
5023 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5024 tls12_prf->label, tls12_prf->label_length );
5025 if( status != PSA_SUCCESS )
5026 goto cleanup;
5027 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5028 tls12_prf->seed, tls12_prf->seed_length );
5029 if( status != PSA_SUCCESS )
5030 goto cleanup;
5031 }
5032 else
5033 {
5034 /* A(i) = HMAC_hash(secret, A(i-1)) */
5035 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5036 tls12_prf->Ai, hash_length );
5037 if( status != PSA_SUCCESS )
5038 goto cleanup;
5039 }
5040
5041 status = psa_hmac_finish_internal( &tls12_prf->hmac,
5042 tls12_prf->Ai, hash_length );
5043 if( status != PSA_SUCCESS )
5044 goto cleanup;
5045 status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
5046 if( status != PSA_SUCCESS )
5047 goto cleanup;
5048
5049 /* Calculate HMAC_hash(secret, A(i) + label + seed). */
5050 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5051 tls12_prf->Ai, hash_length );
5052 if( status != PSA_SUCCESS )
5053 goto cleanup;
5054 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5055 tls12_prf->label, tls12_prf->label_length );
5056 if( status != PSA_SUCCESS )
5057 goto cleanup;
5058 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5059 tls12_prf->seed, tls12_prf->seed_length );
5060 if( status != PSA_SUCCESS )
5061 goto cleanup;
5062 status = psa_hmac_finish_internal( &tls12_prf->hmac,
5063 tls12_prf->output_block, hash_length );
5064 if( status != PSA_SUCCESS )
5065 goto cleanup;
5066 status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
5067 if( status != PSA_SUCCESS )
5068 goto cleanup;
5069
Janos Follath7742fee2019-06-17 12:58:10 +01005070
5071cleanup:
5072
Janos Follathea29bfb2019-06-19 12:21:20 +01005073 cleanup_status = psa_hash_abort( &backup );
5074 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
5075 status = cleanup_status;
5076
5077 return( status );
Janos Follath7742fee2019-06-17 12:58:10 +01005078}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005079
Janos Follath844eb0e2019-06-19 12:10:49 +01005080static psa_status_t psa_key_derivation_tls12_prf_read(
5081 psa_tls12_prf_key_derivation_t *tls12_prf,
5082 psa_algorithm_t alg,
5083 uint8_t *output,
5084 size_t output_length )
5085{
5086 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
gabor-mezei-armcbcec212020-12-18 14:23:51 +01005087 uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
Janos Follath844eb0e2019-06-19 12:10:49 +01005088 psa_status_t status;
5089 uint8_t offset, length;
5090
5091 while( output_length != 0 )
5092 {
5093 /* Check if we have fully processed the current block. */
5094 if( tls12_prf->left_in_block == 0 )
5095 {
5096 status = psa_key_derivation_tls12_prf_generate_next_block( tls12_prf,
5097 alg );
5098 if( status != PSA_SUCCESS )
5099 return( status );
5100
5101 continue;
5102 }
5103
5104 if( tls12_prf->left_in_block > output_length )
5105 length = (uint8_t) output_length;
5106 else
5107 length = tls12_prf->left_in_block;
5108
5109 offset = hash_length - tls12_prf->left_in_block;
5110 memcpy( output, tls12_prf->output_block + offset, length );
5111 output += length;
5112 output_length -= length;
5113 tls12_prf->left_in_block -= length;
5114 }
5115
5116 return( PSA_SUCCESS );
5117}
John Durkop07cc04a2020-11-16 22:08:34 -08005118#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
5119 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskinebef7f142018-07-12 17:22:21 +02005120
Janos Follath6c6c8fc2019-06-17 12:38:20 +01005121psa_status_t psa_key_derivation_output_bytes(
5122 psa_key_derivation_operation_t *operation,
5123 uint8_t *output,
5124 size_t output_length )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005125{
5126 psa_status_t status;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005127 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005128
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005129 if( operation->alg == 0 )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005130 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005131 /* This is a blank operation. */
Steven Cooreman29149862020-08-05 15:43:42 +02005132 return( PSA_ERROR_BAD_STATE );
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005133 }
5134
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005135 if( output_length > operation->capacity )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005136 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005137 operation->capacity = 0;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005138 /* Go through the error path to wipe all confidential data now
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005139 * that the operation object is useless. */
David Saadab4ecc272019-02-14 13:48:10 +02005140 status = PSA_ERROR_INSUFFICIENT_DATA;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005141 goto exit;
5142 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005143 if( output_length == 0 && operation->capacity == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005144 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005145 /* Edge case: this is a finished operation, and 0 bytes
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005146 * were requested. The right error in this case could
Gilles Peskineeab56e42018-07-12 17:12:33 +02005147 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
5148 * INSUFFICIENT_CAPACITY, which is right for a finished
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005149 * operation, for consistency with the case when
Gilles Peskineeab56e42018-07-12 17:12:33 +02005150 * output_length > 0. */
David Saadab4ecc272019-02-14 13:48:10 +02005151 return( PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005152 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005153 operation->capacity -= output_length;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005154
John Durkopd0321952020-10-29 21:37:36 -07005155#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005156 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02005157 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01005158 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005159 status = psa_key_derivation_hkdf_read( &operation->ctx.hkdf, hash_alg,
Gilles Peskinebef7f142018-07-12 17:22:21 +02005160 output, output_length );
5161 }
Janos Follathadbec812019-06-14 11:05:39 +01005162 else
John Durkop07cc04a2020-11-16 22:08:34 -08005163#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
5164#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5165 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follathadbec812019-06-14 11:05:39 +01005166 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
John Durkop07cc04a2020-11-16 22:08:34 -08005167 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005168 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005169 status = psa_key_derivation_tls12_prf_read( &operation->ctx.tls12_prf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005170 kdf_alg, output,
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005171 output_length );
5172 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02005173 else
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 Peskineeab56e42018-07-12 17:12:33 +02005176 {
Steven Cooreman74afe472021-02-10 17:19:22 +01005177 (void) kdf_alg;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005178 return( PSA_ERROR_BAD_STATE );
5179 }
5180
5181exit:
5182 if( status != PSA_SUCCESS )
5183 {
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005184 /* Preserve the algorithm upon errors, but clear all sensitive state.
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005185 * This allows us to differentiate between exhausted operations and
5186 * blank operations, so we can return PSA_ERROR_BAD_STATE on blank
5187 * operations. */
5188 psa_algorithm_t alg = operation->alg;
5189 psa_key_derivation_abort( operation );
5190 operation->alg = alg;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005191 memset( output, '!', output_length );
5192 }
5193 return( status );
5194}
5195
David Brown7807bf72021-02-09 16:28:23 -07005196#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskine08542d82018-07-19 17:05:42 +02005197static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
5198{
5199 if( data_size >= 8 )
5200 mbedtls_des_key_set_parity( data );
5201 if( data_size >= 16 )
5202 mbedtls_des_key_set_parity( data + 8 );
5203 if( data_size >= 24 )
5204 mbedtls_des_key_set_parity( data + 16 );
5205}
David Brown7807bf72021-02-09 16:28:23 -07005206#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
Gilles Peskine08542d82018-07-19 17:05:42 +02005207
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01005208static psa_status_t psa_generate_derived_key_internal(
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005209 psa_key_slot_t *slot,
5210 size_t bits,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005211 psa_key_derivation_operation_t *operation )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005212{
5213 uint8_t *data = NULL;
5214 size_t bytes = PSA_BITS_TO_BYTES( bits );
5215 psa_status_t status;
5216
Gilles Peskine8e338702019-07-30 20:06:31 +02005217 if( ! key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005218 return( PSA_ERROR_INVALID_ARGUMENT );
5219 if( bits % 8 != 0 )
5220 return( PSA_ERROR_INVALID_ARGUMENT );
5221 data = mbedtls_calloc( 1, bytes );
5222 if( data == NULL )
5223 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5224
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005225 status = psa_key_derivation_output_bytes( operation, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005226 if( status != PSA_SUCCESS )
5227 goto exit;
David Brown12ca5032021-02-11 11:02:00 -07005228#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskine8e338702019-07-30 20:06:31 +02005229 if( slot->attr.type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02005230 psa_des_set_key_parity( data, bytes );
David Brown8107e312021-02-12 08:08:46 -07005231#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
Ronald Crondd04d422020-11-28 15:14:42 +01005232
5233 status = psa_allocate_buffer_to_slot( slot, bytes );
5234 if( status != PSA_SUCCESS )
Paul Elliottda3e7db2021-02-09 18:58:20 +00005235 goto exit;
Ronald Crondd04d422020-11-28 15:14:42 +01005236
Ronald Cronbf33c932020-11-28 18:06:53 +01005237 slot->attr.bits = (psa_key_bits_t) bits;
Ronald Cron2ebfdcc2020-11-28 15:54:54 +01005238 psa_key_attributes_t attributes = {
5239 .core = slot->attr
5240 };
5241
Ronald Cronbf33c932020-11-28 18:06:53 +01005242 status = psa_driver_wrapper_import_key( &attributes,
5243 data, bytes,
5244 slot->key.data,
5245 slot->key.bytes,
5246 &slot->key.bytes, &bits );
5247 if( bits != slot->attr.bits )
5248 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005249
5250exit:
5251 mbedtls_free( data );
5252 return( status );
5253}
5254
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02005255psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attributes,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005256 psa_key_derivation_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02005257 mbedtls_svc_key_id_t *key )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005258{
5259 psa_status_t status;
5260 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02005261 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine0f84d622019-09-12 19:03:13 +02005262
Ronald Cron81709fc2020-11-14 12:10:32 +01005263 *key = MBEDTLS_SVC_KEY_ID_INIT;
5264
Gilles Peskine0f84d622019-09-12 19:03:13 +02005265 /* Reject any attempt to create a zero-length key so that we don't
5266 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
5267 if( psa_get_key_bits( attributes ) == 0 )
5268 return( PSA_ERROR_INVALID_ARGUMENT );
5269
Gilles Peskine178c9aa2019-09-24 18:21:06 +02005270 if( ! operation->can_output_key )
5271 return( PSA_ERROR_NOT_PERMITTED );
5272
Ronald Cron81709fc2020-11-14 12:10:32 +01005273 status = psa_start_key_creation( PSA_KEY_CREATION_DERIVE, attributes,
5274 &slot, &driver );
Gilles Peskinef4ee6622019-07-24 13:44:30 +02005275#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
5276 if( driver != NULL )
5277 {
5278 /* Deriving a key in a secure element is not implemented yet. */
5279 status = PSA_ERROR_NOT_SUPPORTED;
5280 }
5281#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005282 if( status == PSA_SUCCESS )
5283 {
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01005284 status = psa_generate_derived_key_internal( slot,
Gilles Peskine7e0cff92019-07-30 13:48:52 +02005285 attributes->core.bits,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005286 operation );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005287 }
5288 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01005289 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005290 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02005291 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005292
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005293 return( status );
5294}
5295
Gilles Peskineeab56e42018-07-12 17:12:33 +02005296
5297
5298/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02005299/* Key derivation */
5300/****************************************************************/
5301
Steven Cooreman932ffb72021-02-15 12:14:32 +01005302#if defined(AT_LEAST_ONE_BUILTIN_KDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005303static psa_status_t psa_key_derivation_setup_kdf(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005304 psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005305 psa_algorithm_t kdf_alg )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005306{
John Durkop07cc04a2020-11-16 22:08:34 -08005307 int is_kdf_alg_supported;
5308
Janos Follath5fe19732019-06-20 15:09:30 +01005309 /* Make sure that operation->ctx is properly zero-initialised. (Macro
5310 * initialisers for this union leave some bytes unspecified.) */
5311 memset( &operation->ctx, 0, sizeof( operation->ctx ) );
5312
Gilles Peskine969c5d62019-01-16 15:53:06 +01005313 /* Make sure that kdf_alg is a supported key derivation algorithm. */
John Durkopd0321952020-10-29 21:37:36 -07005314#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
John Durkop07cc04a2020-11-16 22:08:34 -08005315 if( PSA_ALG_IS_HKDF( kdf_alg ) )
5316 is_kdf_alg_supported = 1;
5317 else
5318#endif
5319#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
5320 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
5321 is_kdf_alg_supported = 1;
5322 else
5323#endif
5324#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5325 if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
5326 is_kdf_alg_supported = 1;
5327 else
5328#endif
5329 is_kdf_alg_supported = 0;
5330
5331 if( is_kdf_alg_supported )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005332 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01005333 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
gabor-mezei-armcbcec212020-12-18 14:23:51 +01005334 size_t hash_size = PSA_HASH_LENGTH( hash_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005335 if( hash_size == 0 )
5336 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005337 if( ( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
5338 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) &&
Gilles Peskineab4b2012019-04-12 15:06:27 +02005339 ! ( hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384 ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005340 {
5341 return( PSA_ERROR_NOT_SUPPORTED );
5342 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005343 operation->capacity = 255 * hash_size;
Gilles Peskine969c5d62019-01-16 15:53:06 +01005344 return( PSA_SUCCESS );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005345 }
John Durkop07cc04a2020-11-16 22:08:34 -08005346
5347 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005348}
John Durkop07cc04a2020-11-16 22:08:34 -08005349#endif /* AT_LEAST_ONE_BUILTIN_KDF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01005350
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005351psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005352 psa_algorithm_t alg )
5353{
5354 psa_status_t status;
5355
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005356 if( operation->alg != 0 )
Gilles Peskine969c5d62019-01-16 15:53:06 +01005357 return( PSA_ERROR_BAD_STATE );
5358
Gilles Peskine6843c292019-01-18 16:44:49 +01005359 if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
5360 return( PSA_ERROR_INVALID_ARGUMENT );
5361 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskine969c5d62019-01-16 15:53:06 +01005362 {
Steven Cooreman932ffb72021-02-15 12:14:32 +01005363#if defined(AT_LEAST_ONE_BUILTIN_KDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005364 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005365 status = psa_key_derivation_setup_kdf( operation, kdf_alg );
Steven Cooreman932ffb72021-02-15 12:14:32 +01005366#else
5367 return( PSA_ERROR_NOT_SUPPORTED );
5368#endif /* AT_LEAST_ONE_BUILTIN_KDF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01005369 }
5370 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
5371 {
Steven Cooreman932ffb72021-02-15 12:14:32 +01005372#if defined(AT_LEAST_ONE_BUILTIN_KDF)
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005373 status = psa_key_derivation_setup_kdf( operation, alg );
Steven Cooreman932ffb72021-02-15 12:14:32 +01005374#else
5375 return( PSA_ERROR_NOT_SUPPORTED );
5376#endif /* AT_LEAST_ONE_BUILTIN_KDF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01005377 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005378 else
5379 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005380
5381 if( status == PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005382 operation->alg = alg;
Gilles Peskine969c5d62019-01-16 15:53:06 +01005383 return( status );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005384}
5385
John Durkopd0321952020-10-29 21:37:36 -07005386#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskinecbe66502019-05-16 16:59:18 +02005387static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005388 psa_algorithm_t hash_alg,
5389 psa_key_derivation_step_t step,
5390 const uint8_t *data,
5391 size_t data_length )
5392{
5393 psa_status_t status;
5394 switch( step )
5395 {
Gilles Peskine03410b52019-05-16 16:05:19 +02005396 case PSA_KEY_DERIVATION_INPUT_SALT:
Gilles Peskine2b522db2019-04-12 15:11:49 +02005397 if( hkdf->state != HKDF_STATE_INIT )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005398 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005399 status = psa_hmac_setup_internal( &hkdf->hmac,
5400 data, data_length,
5401 hash_alg );
5402 if( status != PSA_SUCCESS )
5403 return( status );
5404 hkdf->state = HKDF_STATE_STARTED;
5405 return( PSA_SUCCESS );
Gilles Peskine03410b52019-05-16 16:05:19 +02005406 case PSA_KEY_DERIVATION_INPUT_SECRET:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005407 /* If no salt was provided, use an empty salt. */
5408 if( hkdf->state == HKDF_STATE_INIT )
5409 {
5410 status = psa_hmac_setup_internal( &hkdf->hmac,
5411 NULL, 0,
Gilles Peskinef9ee6332019-04-11 21:22:52 +02005412 hash_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005413 if( status != PSA_SUCCESS )
5414 return( status );
5415 hkdf->state = HKDF_STATE_STARTED;
5416 }
Gilles Peskine2b522db2019-04-12 15:11:49 +02005417 if( hkdf->state != HKDF_STATE_STARTED )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005418 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005419 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5420 data, data_length );
5421 if( status != PSA_SUCCESS )
5422 return( status );
5423 status = psa_hmac_finish_internal( &hkdf->hmac,
5424 hkdf->prk,
5425 sizeof( hkdf->prk ) );
5426 if( status != PSA_SUCCESS )
5427 return( status );
gabor-mezei-armcbcec212020-12-18 14:23:51 +01005428 hkdf->offset_in_block = PSA_HASH_LENGTH( hash_alg );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005429 hkdf->block_number = 0;
5430 hkdf->state = HKDF_STATE_KEYED;
5431 return( PSA_SUCCESS );
Gilles Peskine03410b52019-05-16 16:05:19 +02005432 case PSA_KEY_DERIVATION_INPUT_INFO:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005433 if( hkdf->state == HKDF_STATE_OUTPUT )
5434 return( PSA_ERROR_BAD_STATE );
5435 if( hkdf->info_set )
5436 return( PSA_ERROR_BAD_STATE );
5437 hkdf->info_length = data_length;
5438 if( data_length != 0 )
5439 {
5440 hkdf->info = mbedtls_calloc( 1, data_length );
5441 if( hkdf->info == NULL )
5442 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5443 memcpy( hkdf->info, data, data_length );
5444 }
5445 hkdf->info_set = 1;
5446 return( PSA_SUCCESS );
5447 default:
5448 return( PSA_ERROR_INVALID_ARGUMENT );
5449 }
5450}
John Durkop07cc04a2020-11-16 22:08:34 -08005451#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
Janos Follathb03233e2019-06-11 15:30:30 +01005452
John Durkop07cc04a2020-11-16 22:08:34 -08005453#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5454 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follathf08e2652019-06-13 09:05:41 +01005455static psa_status_t psa_tls12_prf_set_seed( psa_tls12_prf_key_derivation_t *prf,
5456 const uint8_t *data,
5457 size_t data_length )
5458{
Gilles Peskine43f958b2020-12-13 14:55:14 +01005459 if( prf->state != PSA_TLS12_PRF_STATE_INIT )
Janos Follathf08e2652019-06-13 09:05:41 +01005460 return( PSA_ERROR_BAD_STATE );
5461
Janos Follathd6dce9f2019-07-04 09:11:38 +01005462 if( data_length != 0 )
5463 {
5464 prf->seed = mbedtls_calloc( 1, data_length );
5465 if( prf->seed == NULL )
5466 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Janos Follathf08e2652019-06-13 09:05:41 +01005467
Janos Follathd6dce9f2019-07-04 09:11:38 +01005468 memcpy( prf->seed, data, data_length );
5469 prf->seed_length = data_length;
5470 }
Janos Follathf08e2652019-06-13 09:05:41 +01005471
Gilles Peskine43f958b2020-12-13 14:55:14 +01005472 prf->state = PSA_TLS12_PRF_STATE_SEED_SET;
Janos Follathf08e2652019-06-13 09:05:41 +01005473
5474 return( PSA_SUCCESS );
5475}
5476
Janos Follath81550542019-06-13 14:26:34 +01005477static psa_status_t psa_tls12_prf_set_key( psa_tls12_prf_key_derivation_t *prf,
5478 psa_algorithm_t hash_alg,
5479 const uint8_t *data,
5480 size_t data_length )
5481{
5482 psa_status_t status;
Gilles Peskine43f958b2020-12-13 14:55:14 +01005483 if( prf->state != PSA_TLS12_PRF_STATE_SEED_SET )
Janos Follath81550542019-06-13 14:26:34 +01005484 return( PSA_ERROR_BAD_STATE );
5485
5486 status = psa_hmac_setup_internal( &prf->hmac, data, data_length, hash_alg );
5487 if( status != PSA_SUCCESS )
5488 return( status );
5489
Gilles Peskine43f958b2020-12-13 14:55:14 +01005490 prf->state = PSA_TLS12_PRF_STATE_KEY_SET;
Janos Follath81550542019-06-13 14:26:34 +01005491
5492 return( PSA_SUCCESS );
5493}
5494
Janos Follath63028dd2019-06-13 09:15:47 +01005495static psa_status_t psa_tls12_prf_set_label( psa_tls12_prf_key_derivation_t *prf,
5496 const uint8_t *data,
5497 size_t data_length )
5498{
Gilles Peskine43f958b2020-12-13 14:55:14 +01005499 if( prf->state != PSA_TLS12_PRF_STATE_KEY_SET )
Janos Follath63028dd2019-06-13 09:15:47 +01005500 return( PSA_ERROR_BAD_STATE );
5501
Janos Follathd6dce9f2019-07-04 09:11:38 +01005502 if( data_length != 0 )
5503 {
5504 prf->label = mbedtls_calloc( 1, data_length );
5505 if( prf->label == NULL )
5506 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Janos Follath63028dd2019-06-13 09:15:47 +01005507
Janos Follathd6dce9f2019-07-04 09:11:38 +01005508 memcpy( prf->label, data, data_length );
5509 prf->label_length = data_length;
5510 }
Janos Follath63028dd2019-06-13 09:15:47 +01005511
Gilles Peskine43f958b2020-12-13 14:55:14 +01005512 prf->state = PSA_TLS12_PRF_STATE_LABEL_SET;
Janos Follath63028dd2019-06-13 09:15:47 +01005513
5514 return( PSA_SUCCESS );
5515}
5516
Janos Follathb03233e2019-06-11 15:30:30 +01005517static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf,
5518 psa_algorithm_t hash_alg,
5519 psa_key_derivation_step_t step,
5520 const uint8_t *data,
5521 size_t data_length )
5522{
Janos Follathb03233e2019-06-11 15:30:30 +01005523 switch( step )
5524 {
Janos Follathf08e2652019-06-13 09:05:41 +01005525 case PSA_KEY_DERIVATION_INPUT_SEED:
5526 return( psa_tls12_prf_set_seed( prf, data, data_length ) );
Janos Follath81550542019-06-13 14:26:34 +01005527 case PSA_KEY_DERIVATION_INPUT_SECRET:
5528 return( psa_tls12_prf_set_key( prf, hash_alg, data, data_length ) );
Janos Follath63028dd2019-06-13 09:15:47 +01005529 case PSA_KEY_DERIVATION_INPUT_LABEL:
5530 return( psa_tls12_prf_set_label( prf, data, data_length ) );
Janos Follathb03233e2019-06-11 15:30:30 +01005531 default:
5532 return( PSA_ERROR_INVALID_ARGUMENT );
5533 }
5534}
John Durkop07cc04a2020-11-16 22:08:34 -08005535#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
5536 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
5537
5538#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5539static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
5540 psa_tls12_prf_key_derivation_t *prf,
5541 psa_algorithm_t hash_alg,
5542 const uint8_t *data,
5543 size_t data_length )
5544{
5545 psa_status_t status;
gabor-mezei-armcbcec212020-12-18 14:23:51 +01005546 uint8_t pms[ 4 + 2 * PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE ];
John Durkop07cc04a2020-11-16 22:08:34 -08005547 uint8_t *cur = pms;
5548
gabor-mezei-armcbcec212020-12-18 14:23:51 +01005549 if( data_length > PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE )
John Durkop07cc04a2020-11-16 22:08:34 -08005550 return( PSA_ERROR_INVALID_ARGUMENT );
5551
5552 /* Quoting RFC 4279, Section 2:
5553 *
5554 * The premaster secret is formed as follows: if the PSK is N octets
5555 * long, concatenate a uint16 with the value N, N zero octets, a second
5556 * uint16 with the value N, and the PSK itself.
5557 */
5558
5559 *cur++ = ( data_length >> 8 ) & 0xff;
5560 *cur++ = ( data_length >> 0 ) & 0xff;
5561 memset( cur, 0, data_length );
5562 cur += data_length;
5563 *cur++ = pms[0];
5564 *cur++ = pms[1];
5565 memcpy( cur, data, data_length );
5566 cur += data_length;
5567
5568 status = psa_tls12_prf_set_key( prf, hash_alg, pms, cur - pms );
5569
5570 mbedtls_platform_zeroize( pms, sizeof( pms ) );
5571 return( status );
5572}
Janos Follath6660f0e2019-06-17 08:44:03 +01005573
5574static psa_status_t psa_tls12_prf_psk_to_ms_input(
5575 psa_tls12_prf_key_derivation_t *prf,
5576 psa_algorithm_t hash_alg,
5577 psa_key_derivation_step_t step,
5578 const uint8_t *data,
5579 size_t data_length )
5580{
5581 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
Janos Follath0c1ed842019-06-28 13:35:36 +01005582 {
Janos Follath6660f0e2019-06-17 08:44:03 +01005583 return( psa_tls12_prf_psk_to_ms_set_key( prf, hash_alg,
5584 data, data_length ) );
Janos Follath0c1ed842019-06-28 13:35:36 +01005585 }
Janos Follath6660f0e2019-06-17 08:44:03 +01005586
5587 return( psa_tls12_prf_input( prf, hash_alg, step, data, data_length ) );
5588}
John Durkop07cc04a2020-11-16 22:08:34 -08005589#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005590
Gilles Peskineb8965192019-09-24 16:21:10 +02005591/** Check whether the given key type is acceptable for the given
5592 * input step of a key derivation.
5593 *
5594 * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE.
5595 * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA.
5596 * Both secret and non-secret inputs can alternatively have the type
5597 * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning
5598 * that the input was passed as a buffer rather than via a key object.
5599 */
Gilles Peskine224b0d62019-09-23 18:13:17 +02005600static int psa_key_derivation_check_input_type(
5601 psa_key_derivation_step_t step,
5602 psa_key_type_t key_type )
5603{
5604 switch( step )
5605 {
5606 case PSA_KEY_DERIVATION_INPUT_SECRET:
Gilles Peskineb8965192019-09-24 16:21:10 +02005607 if( key_type == PSA_KEY_TYPE_DERIVE )
5608 return( PSA_SUCCESS );
5609 if( key_type == PSA_KEY_TYPE_NONE )
Gilles Peskine224b0d62019-09-23 18:13:17 +02005610 return( PSA_SUCCESS );
5611 break;
5612 case PSA_KEY_DERIVATION_INPUT_LABEL:
5613 case PSA_KEY_DERIVATION_INPUT_SALT:
5614 case PSA_KEY_DERIVATION_INPUT_INFO:
5615 case PSA_KEY_DERIVATION_INPUT_SEED:
Gilles Peskineb8965192019-09-24 16:21:10 +02005616 if( key_type == PSA_KEY_TYPE_RAW_DATA )
5617 return( PSA_SUCCESS );
5618 if( key_type == PSA_KEY_TYPE_NONE )
Gilles Peskine224b0d62019-09-23 18:13:17 +02005619 return( PSA_SUCCESS );
5620 break;
5621 }
5622 return( PSA_ERROR_INVALID_ARGUMENT );
5623}
5624
Janos Follathb80a94e2019-06-12 15:54:46 +01005625static psa_status_t psa_key_derivation_input_internal(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005626 psa_key_derivation_operation_t *operation,
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005627 psa_key_derivation_step_t step,
Gilles Peskine224b0d62019-09-23 18:13:17 +02005628 psa_key_type_t key_type,
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005629 const uint8_t *data,
5630 size_t data_length )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005631{
Gilles Peskine46d7faf2019-09-23 19:22:55 +02005632 psa_status_t status;
5633 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
5634
5635 status = psa_key_derivation_check_input_type( step, key_type );
Gilles Peskine224b0d62019-09-23 18:13:17 +02005636 if( status != PSA_SUCCESS )
5637 goto exit;
5638
John Durkopd0321952020-10-29 21:37:36 -07005639#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005640 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005641 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005642 status = psa_hkdf_input( &operation->ctx.hkdf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005643 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005644 step, data, data_length );
5645 }
John Durkop07cc04a2020-11-16 22:08:34 -08005646 else
5647#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
5648#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
5649 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005650 {
Janos Follathb03233e2019-06-11 15:30:30 +01005651 status = psa_tls12_prf_input( &operation->ctx.tls12_prf,
5652 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
5653 step, data, data_length );
Janos Follath6660f0e2019-06-17 08:44:03 +01005654 }
John Durkop07cc04a2020-11-16 22:08:34 -08005655 else
5656#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF */
5657#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5658 if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Janos Follath6660f0e2019-06-17 08:44:03 +01005659 {
5660 status = psa_tls12_prf_psk_to_ms_input( &operation->ctx.tls12_prf,
5661 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
5662 step, data, data_length );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005663 }
5664 else
John Durkop07cc04a2020-11-16 22:08:34 -08005665#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005666 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005667 /* This can't happen unless the operation object was not initialized */
Steven Cooreman74afe472021-02-10 17:19:22 +01005668 (void) data;
5669 (void) data_length;
5670 (void) kdf_alg;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005671 return( PSA_ERROR_BAD_STATE );
5672 }
5673
Gilles Peskine224b0d62019-09-23 18:13:17 +02005674exit:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005675 if( status != PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005676 psa_key_derivation_abort( operation );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005677 return( status );
5678}
5679
Janos Follath51f4a0f2019-06-14 11:35:55 +01005680psa_status_t psa_key_derivation_input_bytes(
5681 psa_key_derivation_operation_t *operation,
5682 psa_key_derivation_step_t step,
5683 const uint8_t *data,
5684 size_t data_length )
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005685{
Gilles Peskineb8965192019-09-24 16:21:10 +02005686 return( psa_key_derivation_input_internal( operation, step,
5687 PSA_KEY_TYPE_NONE,
Janos Follathc5621512019-06-14 11:27:57 +01005688 data, data_length ) );
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005689}
5690
Janos Follath51f4a0f2019-06-14 11:35:55 +01005691psa_status_t psa_key_derivation_input_key(
5692 psa_key_derivation_operation_t *operation,
5693 psa_key_derivation_step_t step,
Ronald Croncf56a0a2020-08-04 09:51:30 +02005694 mbedtls_svc_key_id_t key )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005695{
Ronald Cronf95a2b12020-10-22 15:24:49 +02005696 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01005697 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005698 psa_key_slot_t *slot;
Gilles Peskine178c9aa2019-09-24 18:21:06 +02005699
Ronald Cron5c522922020-11-14 16:35:34 +01005700 status = psa_get_and_lock_transparent_key_slot_with_policy(
5701 key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005702 if( status != PSA_SUCCESS )
Gilles Peskine593773d2019-09-23 18:17:40 +02005703 {
5704 psa_key_derivation_abort( operation );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005705 return( status );
Gilles Peskine593773d2019-09-23 18:17:40 +02005706 }
Gilles Peskine178c9aa2019-09-24 18:21:06 +02005707
5708 /* Passing a key object as a SECRET input unlocks the permission
5709 * to output to a key object. */
5710 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
5711 operation->can_output_key = 1;
5712
Ronald Cronf95a2b12020-10-22 15:24:49 +02005713 status = psa_key_derivation_input_internal( operation,
5714 step, slot->attr.type,
Ronald Cronea0f8a62020-11-25 17:52:23 +01005715 slot->key.data,
5716 slot->key.bytes );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005717
Ronald Cron5c522922020-11-14 16:35:34 +01005718 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005719
Ronald Cron5c522922020-11-14 16:35:34 +01005720 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005721}
Gilles Peskineea0fb492018-07-12 17:17:20 +02005722
5723
5724
5725/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02005726/* Key agreement */
5727/****************************************************************/
5728
John Durkop6ba40d12020-11-10 08:50:04 -08005729#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005730static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
5731 size_t peer_key_length,
5732 const mbedtls_ecp_keypair *our_key,
5733 uint8_t *shared_secret,
5734 size_t shared_secret_size,
5735 size_t *shared_secret_length )
5736{
Steven Cooremand4867872020-08-05 16:31:39 +02005737 mbedtls_ecp_keypair *their_key = NULL;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005738 mbedtls_ecdh_context ecdh;
Jaeden Amero97271b32019-01-10 19:38:51 +00005739 psa_status_t status;
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01005740 size_t bits = 0;
Paul Elliott8ff510a2020-06-02 17:19:28 +01005741 psa_ecc_family_t curve = mbedtls_ecc_group_to_psa( our_key->grp.id, &bits );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005742 mbedtls_ecdh_init( &ecdh );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005743
Ronald Cron90857082020-11-25 14:58:33 +01005744 status = mbedtls_psa_ecp_load_representation(
5745 PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +01005746 bits,
Ronald Cron90857082020-11-25 14:58:33 +01005747 peer_key,
5748 peer_key_length,
5749 &their_key );
Jaeden Amero97271b32019-01-10 19:38:51 +00005750 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005751 goto exit;
5752
Jaeden Amero97271b32019-01-10 19:38:51 +00005753 status = mbedtls_to_psa_error(
Steven Cooremana2371e52020-07-28 14:30:39 +02005754 mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS ) );
Jaeden Amero97271b32019-01-10 19:38:51 +00005755 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005756 goto exit;
Jaeden Amero97271b32019-01-10 19:38:51 +00005757 status = mbedtls_to_psa_error(
5758 mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS ) );
5759 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005760 goto exit;
5761
Jaeden Amero97271b32019-01-10 19:38:51 +00005762 status = mbedtls_to_psa_error(
5763 mbedtls_ecdh_calc_secret( &ecdh,
5764 shared_secret_length,
5765 shared_secret, shared_secret_size,
Gilles Peskine30524eb2020-11-13 17:02:26 +01005766 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01005767 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01005768 if( status != PSA_SUCCESS )
5769 goto exit;
5770 if( PSA_BITS_TO_BYTES( bits ) != *shared_secret_length )
5771 status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005772
5773exit:
Gilles Peskine3e819b72019-12-20 14:09:55 +01005774 if( status != PSA_SUCCESS )
5775 mbedtls_platform_zeroize( shared_secret, shared_secret_size );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005776 mbedtls_ecdh_free( &ecdh );
Steven Cooremana2371e52020-07-28 14:30:39 +02005777 mbedtls_ecp_keypair_free( their_key );
Steven Cooreman6d839f02020-07-30 11:36:45 +02005778 mbedtls_free( their_key );
Steven Cooremana2371e52020-07-28 14:30:39 +02005779
Jaeden Amero97271b32019-01-10 19:38:51 +00005780 return( status );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005781}
John Durkop6ba40d12020-11-10 08:50:04 -08005782#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005783
Gilles Peskine01d718c2018-09-18 12:01:02 +02005784#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
5785
Gilles Peskine0216fe12019-04-11 21:23:21 +02005786static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg,
5787 psa_key_slot_t *private_key,
5788 const uint8_t *peer_key,
5789 size_t peer_key_length,
5790 uint8_t *shared_secret,
5791 size_t shared_secret_size,
5792 size_t *shared_secret_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02005793{
Gilles Peskine0216fe12019-04-11 21:23:21 +02005794 switch( alg )
Gilles Peskine01d718c2018-09-18 12:01:02 +02005795 {
John Durkop6ba40d12020-11-10 08:50:04 -08005796#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
Gilles Peskine0216fe12019-04-11 21:23:21 +02005797 case PSA_ALG_ECDH:
Gilles Peskine8e338702019-07-30 20:06:31 +02005798 if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005799 return( PSA_ERROR_INVALID_ARGUMENT );
Steven Cooremana2371e52020-07-28 14:30:39 +02005800 mbedtls_ecp_keypair *ecp = NULL;
Ronald Cron90857082020-11-25 14:58:33 +01005801 psa_status_t status = mbedtls_psa_ecp_load_representation(
5802 private_key->attr.type,
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +01005803 private_key->attr.bits,
Ronald Cron90857082020-11-25 14:58:33 +01005804 private_key->key.data,
5805 private_key->key.bytes,
5806 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02005807 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02005808 return( status );
Steven Cooremanacda8342020-07-24 23:09:52 +02005809 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
Steven Cooremana2371e52020-07-28 14:30:39 +02005810 ecp,
Steven Cooremanacda8342020-07-24 23:09:52 +02005811 shared_secret, shared_secret_size,
5812 shared_secret_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02005813 mbedtls_ecp_keypair_free( ecp );
5814 mbedtls_free( ecp );
Steven Cooreman29149862020-08-05 15:43:42 +02005815 return( status );
John Durkop6ba40d12020-11-10 08:50:04 -08005816#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
Gilles Peskine01d718c2018-09-18 12:01:02 +02005817 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01005818 (void) private_key;
5819 (void) peer_key;
5820 (void) peer_key_length;
Gilles Peskine0216fe12019-04-11 21:23:21 +02005821 (void) shared_secret;
5822 (void) shared_secret_size;
5823 (void) shared_secret_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02005824 return( PSA_ERROR_NOT_SUPPORTED );
5825 }
Gilles Peskine0216fe12019-04-11 21:23:21 +02005826}
5827
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02005828/* Note that if this function fails, you must call psa_key_derivation_abort()
Gilles Peskine01d718c2018-09-18 12:01:02 +02005829 * to potentially free embedded data structures and wipe confidential data.
5830 */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005831static psa_status_t psa_key_agreement_internal( psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005832 psa_key_derivation_step_t step,
Gilles Peskine01d718c2018-09-18 12:01:02 +02005833 psa_key_slot_t *private_key,
5834 const uint8_t *peer_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005835 size_t peer_key_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02005836{
5837 psa_status_t status;
5838 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
5839 size_t shared_secret_length = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005840 psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE( operation->alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02005841
5842 /* Step 1: run the secret agreement algorithm to generate the shared
5843 * secret. */
Gilles Peskine0216fe12019-04-11 21:23:21 +02005844 status = psa_key_agreement_raw_internal( ka_alg,
5845 private_key,
5846 peer_key, peer_key_length,
itayzafrir0adf0fc2018-09-06 16:24:41 +03005847 shared_secret,
5848 sizeof( shared_secret ),
Gilles Peskine05d69892018-06-19 22:00:52 +02005849 &shared_secret_length );
Gilles Peskine53d991e2018-07-12 01:14:59 +02005850 if( status != PSA_SUCCESS )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005851 goto exit;
5852
Gilles Peskineb0b255c2018-07-06 17:01:38 +02005853 /* Step 2: set up the key derivation to generate key material from
Gilles Peskine224b0d62019-09-23 18:13:17 +02005854 * the shared secret. A shared secret is permitted wherever a key
5855 * of type DERIVE is permitted. */
Janos Follathb80a94e2019-06-12 15:54:46 +01005856 status = psa_key_derivation_input_internal( operation, step,
Gilles Peskine224b0d62019-09-23 18:13:17 +02005857 PSA_KEY_TYPE_DERIVE,
Janos Follathb80a94e2019-06-12 15:54:46 +01005858 shared_secret,
5859 shared_secret_length );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005860exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01005861 mbedtls_platform_zeroize( shared_secret, shared_secret_length );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005862 return( status );
5863}
5864
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005865psa_status_t psa_key_derivation_key_agreement( psa_key_derivation_operation_t *operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005866 psa_key_derivation_step_t step,
Ronald Croncf56a0a2020-08-04 09:51:30 +02005867 mbedtls_svc_key_id_t private_key,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005868 const uint8_t *peer_key,
5869 size_t peer_key_length )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005870{
Ronald Cronf95a2b12020-10-22 15:24:49 +02005871 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01005872 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01005873 psa_key_slot_t *slot;
Ronald Cronf95a2b12020-10-22 15:24:49 +02005874
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005875 if( ! PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005876 return( PSA_ERROR_INVALID_ARGUMENT );
Ronald Cron5c522922020-11-14 16:35:34 +01005877 status = psa_get_and_lock_transparent_key_slot_with_policy(
5878 private_key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005879 if( status != PSA_SUCCESS )
5880 return( status );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005881 status = psa_key_agreement_internal( operation, step,
Gilles Peskine346797d2018-11-16 16:05:06 +01005882 slot,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005883 peer_key, peer_key_length );
Gilles Peskine346797d2018-11-16 16:05:06 +01005884 if( status != PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005885 psa_key_derivation_abort( operation );
Steven Cooremanfa5e6312020-10-15 17:07:12 +02005886 else
5887 {
5888 /* If a private key has been added as SECRET, we allow the derived
5889 * key material to be used as a key in PSA Crypto. */
5890 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
5891 operation->can_output_key = 1;
5892 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02005893
Ronald Cron5c522922020-11-14 16:35:34 +01005894 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005895
Ronald Cron5c522922020-11-14 16:35:34 +01005896 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskineaf3baab2018-06-27 22:55:52 +02005897}
5898
Gilles Peskinebe697d82019-05-16 18:00:41 +02005899psa_status_t psa_raw_key_agreement( psa_algorithm_t alg,
Ronald Croncf56a0a2020-08-04 09:51:30 +02005900 mbedtls_svc_key_id_t private_key,
Gilles Peskinebe697d82019-05-16 18:00:41 +02005901 const uint8_t *peer_key,
5902 size_t peer_key_length,
5903 uint8_t *output,
5904 size_t output_size,
5905 size_t *output_length )
Gilles Peskine0216fe12019-04-11 21:23:21 +02005906{
Ronald Cronf95a2b12020-10-22 15:24:49 +02005907 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01005908 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cronf95a2b12020-10-22 15:24:49 +02005909 psa_key_slot_t *slot = NULL;
Gilles Peskine0216fe12019-04-11 21:23:21 +02005910
5911 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
5912 {
5913 status = PSA_ERROR_INVALID_ARGUMENT;
5914 goto exit;
5915 }
Ronald Cron5c522922020-11-14 16:35:34 +01005916 status = psa_get_and_lock_transparent_key_slot_with_policy(
5917 private_key, &slot, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine0216fe12019-04-11 21:23:21 +02005918 if( status != PSA_SUCCESS )
5919 goto exit;
5920
5921 status = psa_key_agreement_raw_internal( alg, slot,
5922 peer_key, peer_key_length,
5923 output, output_size,
5924 output_length );
5925
5926exit:
5927 if( status != PSA_SUCCESS )
5928 {
5929 /* If an error happens and is not handled properly, the output
5930 * may be used as a key to protect sensitive data. Arrange for such
5931 * a key to be random, which is likely to result in decryption or
5932 * verification errors. This is better than filling the buffer with
5933 * some constant data such as zeros, which would result in the data
5934 * being protected with a reproducible, easily knowable key.
5935 */
5936 psa_generate_random( output, output_size );
5937 *output_length = output_size;
5938 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02005939
Ronald Cron5c522922020-11-14 16:35:34 +01005940 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005941
Ronald Cron5c522922020-11-14 16:35:34 +01005942 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine0216fe12019-04-11 21:23:21 +02005943}
Gilles Peskine86a440b2018-11-12 18:39:40 +01005944
5945
Gilles Peskine30524eb2020-11-13 17:02:26 +01005946
Gilles Peskine86a440b2018-11-12 18:39:40 +01005947/****************************************************************/
5948/* Random generation */
Gilles Peskine53d991e2018-07-12 01:14:59 +02005949/****************************************************************/
Gilles Peskine12313cd2018-06-20 00:20:32 +02005950
Gilles Peskine30524eb2020-11-13 17:02:26 +01005951/** Initialize the PSA random generator.
5952 */
5953static void mbedtls_psa_random_init( mbedtls_psa_random_context_t *rng )
5954{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01005955#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
5956 memset( rng, 0, sizeof( *rng ) );
5957#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
5958
Gilles Peskine30524eb2020-11-13 17:02:26 +01005959 /* Set default configuration if
5960 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
5961 if( rng->entropy_init == NULL )
5962 rng->entropy_init = mbedtls_entropy_init;
5963 if( rng->entropy_free == NULL )
5964 rng->entropy_free = mbedtls_entropy_free;
5965
5966 rng->entropy_init( &rng->entropy );
5967#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
5968 defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
5969 /* The PSA entropy injection feature depends on using NV seed as an entropy
5970 * source. Add NV seed as an entropy source for PSA entropy injection. */
5971 mbedtls_entropy_add_source( &rng->entropy,
5972 mbedtls_nv_seed_poll, NULL,
5973 MBEDTLS_ENTROPY_BLOCK_SIZE,
5974 MBEDTLS_ENTROPY_SOURCE_STRONG );
5975#endif
5976
Gilles Peskine5894e8e2020-12-14 14:54:06 +01005977 mbedtls_psa_drbg_init( MBEDTLS_PSA_RANDOM_STATE );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01005978#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01005979}
5980
5981/** Deinitialize the PSA random generator.
5982 */
5983static void mbedtls_psa_random_free( mbedtls_psa_random_context_t *rng )
5984{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01005985#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
5986 memset( rng, 0, sizeof( *rng ) );
5987#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine5894e8e2020-12-14 14:54:06 +01005988 mbedtls_psa_drbg_free( MBEDTLS_PSA_RANDOM_STATE );
Gilles Peskine30524eb2020-11-13 17:02:26 +01005989 rng->entropy_free( &rng->entropy );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01005990#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01005991}
5992
5993/** Seed the PSA random generator.
5994 */
5995static psa_status_t mbedtls_psa_random_seed( mbedtls_psa_random_context_t *rng )
5996{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01005997#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
5998 /* Do nothing: the external RNG seeds itself. */
5999 (void) rng;
6000 return( PSA_SUCCESS );
6001#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006002 const unsigned char drbg_seed[] = "PSA";
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006003 int ret = mbedtls_psa_drbg_seed( &rng->entropy,
6004 drbg_seed, sizeof( drbg_seed ) - 1 );
Gilles Peskine30524eb2020-11-13 17:02:26 +01006005 return mbedtls_to_psa_error( ret );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006006#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006007}
6008
Gilles Peskinee59236f2018-01-27 23:32:46 +01006009psa_status_t psa_generate_random( uint8_t *output,
6010 size_t output_size )
6011{
Gilles Peskinee59236f2018-01-27 23:32:46 +01006012 GUARD_MODULE_INITIALIZED;
6013
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006014#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6015
6016 size_t output_length = 0;
6017 psa_status_t status = mbedtls_psa_external_get_random( &global_data.rng,
6018 output, output_size,
6019 &output_length );
6020 if( status != PSA_SUCCESS )
6021 return( status );
6022 /* Breaking up a request into smaller chunks is currently not supported
6023 * for the extrernal RNG interface. */
6024 if( output_length != output_size )
6025 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
6026 return( PSA_SUCCESS );
6027
6028#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
6029
Gilles Peskine71ddab92021-01-04 21:01:07 +01006030 while( output_size > 0 )
Gilles Peskinef181eca2019-08-07 13:49:00 +02006031 {
Gilles Peskine71ddab92021-01-04 21:01:07 +01006032 size_t request_size =
6033 ( output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ?
6034 MBEDTLS_PSA_RANDOM_MAX_REQUEST :
6035 output_size );
Gilles Peskine0c59ba82021-01-05 14:10:59 +01006036 int ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
6037 output, request_size );
Gilles Peskinef181eca2019-08-07 13:49:00 +02006038 if( ret != 0 )
6039 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine71ddab92021-01-04 21:01:07 +01006040 output_size -= request_size;
6041 output += request_size;
Gilles Peskinef181eca2019-08-07 13:49:00 +02006042 }
Gilles Peskine0c59ba82021-01-05 14:10:59 +01006043 return( PSA_SUCCESS );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006044#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006045}
6046
Gilles Peskine8814fc42020-12-14 15:33:44 +01006047/* Wrapper function allowing the classic API to use the PSA RNG.
Gilles Peskine9c3e0602021-01-05 16:03:55 +01006048 *
6049 * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
6050 * `psa_generate_random(...)`. The state parameter is ignored since the
6051 * PSA API doesn't support passing an explicit state.
6052 *
6053 * In the non-external case, psa_generate_random() calls an
6054 * `mbedtls_xxx_drbg_random` function which has exactly the same signature
6055 * and semantics as mbedtls_psa_get_random(). As an optimization,
6056 * instead of doing this back-and-forth between the PSA API and the
6057 * classic API, psa_crypto_random_impl.h defines `mbedtls_psa_get_random`
6058 * as a constant function pointer to `mbedtls_xxx_drbg_random`.
Gilles Peskine8814fc42020-12-14 15:33:44 +01006059 */
6060#if defined (MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6061int mbedtls_psa_get_random( void *p_rng,
6062 unsigned char *output,
6063 size_t output_size )
6064{
Gilles Peskine9c3e0602021-01-05 16:03:55 +01006065 /* This function takes a pointer to the RNG state because that's what
6066 * classic mbedtls functions using an RNG expect. The PSA RNG manages
6067 * its own state internally and doesn't let the caller access that state.
6068 * So we just ignore the state parameter, and in practice we'll pass
6069 * NULL. */
Gilles Peskine8814fc42020-12-14 15:33:44 +01006070 (void) p_rng;
6071 psa_status_t status = psa_generate_random( output, output_size );
6072 if( status == PSA_SUCCESS )
6073 return( 0 );
6074 else
6075 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
6076}
6077#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
6078
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006079#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
6080#include "mbedtls/entropy_poll.h"
6081
Gilles Peskine7228da22019-07-15 11:06:15 +02006082psa_status_t mbedtls_psa_inject_entropy( const uint8_t *seed,
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006083 size_t seed_size )
6084{
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006085 if( global_data.initialized )
6086 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02006087
6088 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
6089 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
6090 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
6091 return( PSA_ERROR_INVALID_ARGUMENT );
6092
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006093 return( mbedtls_psa_storage_inject_entropy( seed, seed_size ) );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006094}
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006095#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006096
Ronald Cron3772afe2021-02-08 16:10:05 +01006097/** Validate the key type and size for key generation
Ronald Cron01b2aba2020-10-05 09:42:02 +02006098 *
Ronald Cron3772afe2021-02-08 16:10:05 +01006099 * \param type The key type
6100 * \param bits The number of bits of the key
Ronald Cron01b2aba2020-10-05 09:42:02 +02006101 *
6102 * \retval #PSA_SUCCESS
Ronald Cron3772afe2021-02-08 16:10:05 +01006103 * The key type and size are valid.
Ronald Cron01b2aba2020-10-05 09:42:02 +02006104 * \retval #PSA_ERROR_INVALID_ARGUMENT
6105 * The size in bits of the key is not valid.
6106 * \retval #PSA_ERROR_NOT_SUPPORTED
6107 * The type and/or the size in bits of the key or the combination of
6108 * the two is not supported.
6109 */
Ronald Cron3772afe2021-02-08 16:10:05 +01006110static psa_status_t psa_validate_key_type_and_size_for_key_generation(
6111 psa_key_type_t type, size_t bits )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006112{
Ronald Cronf3bb7612020-10-02 20:11:59 +02006113 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006114
Gilles Peskinee59236f2018-01-27 23:32:46 +01006115 if( key_type_is_raw_bytes( type ) )
6116 {
Ronald Cronf3bb7612020-10-02 20:11:59 +02006117 status = validate_unstructured_key_bit_size( type, bits );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006118 if( status != PSA_SUCCESS )
6119 return( status );
Ronald Cron01b2aba2020-10-05 09:42:02 +02006120 }
6121 else
Ronald Cron5c4d3862020-12-07 11:07:24 +01006122#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
Ronald Cron01b2aba2020-10-05 09:42:02 +02006123 if( PSA_KEY_TYPE_IS_RSA( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
6124 {
6125 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
6126 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006127
Ronald Cron01b2aba2020-10-05 09:42:02 +02006128 /* Accept only byte-aligned keys, for the same reasons as
6129 * in psa_import_rsa_key(). */
6130 if( bits % 8 != 0 )
6131 return( PSA_ERROR_NOT_SUPPORTED );
Ronald Cron01b2aba2020-10-05 09:42:02 +02006132 }
6133 else
Ronald Cron5c4d3862020-12-07 11:07:24 +01006134#endif /* defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) */
Ronald Cron01b2aba2020-10-05 09:42:02 +02006135
Ronald Cron5c4d3862020-12-07 11:07:24 +01006136#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
Ronald Cron01b2aba2020-10-05 09:42:02 +02006137 if( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
6138 {
Ronald Crond81ab562021-02-16 09:01:16 +01006139 /* To avoid empty block, return successfully here. */
6140 return( PSA_SUCCESS );
Ronald Cron01b2aba2020-10-05 09:42:02 +02006141 }
6142 else
Ronald Cron5c4d3862020-12-07 11:07:24 +01006143#endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) */
Ronald Cron01b2aba2020-10-05 09:42:02 +02006144 {
6145 return( PSA_ERROR_NOT_SUPPORTED );
6146 }
6147
6148 return( PSA_SUCCESS );
6149}
6150
Ronald Cron55ed0592020-10-05 10:30:40 +02006151psa_status_t psa_generate_key_internal(
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006152 const psa_key_attributes_t *attributes,
6153 uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
Ronald Cron01b2aba2020-10-05 09:42:02 +02006154{
6155 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006156 psa_key_type_t type = attributes->core.type;
Ronald Cron01b2aba2020-10-05 09:42:02 +02006157
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006158 if( ( attributes->domain_parameters == NULL ) &&
6159 ( attributes->domain_parameters_size != 0 ) )
Ronald Cron01b2aba2020-10-05 09:42:02 +02006160 return( PSA_ERROR_INVALID_ARGUMENT );
6161
Ronald Cron01b2aba2020-10-05 09:42:02 +02006162 if( key_type_is_raw_bytes( type ) )
6163 {
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006164 status = psa_generate_random( key_buffer, key_buffer_size );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006165 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006166 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006167
David Brown12ca5032021-02-11 11:02:00 -07006168#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskinee59236f2018-01-27 23:32:46 +01006169 if( type == PSA_KEY_TYPE_DES )
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006170 psa_des_set_key_parity( key_buffer, key_buffer_size );
David Brown8107e312021-02-12 08:08:46 -07006171#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006172 }
6173 else
6174
John Durkop07cc04a2020-11-16 22:08:34 -08006175#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02006176 if ( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006177 {
Ronald Cron9e18fc12020-11-05 17:36:40 +01006178 return( mbedtls_psa_rsa_generate_key( attributes,
6179 key_buffer,
6180 key_buffer_size,
6181 key_buffer_length ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006182 }
6183 else
John Durkop07cc04a2020-11-16 22:08:34 -08006184#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006185
John Durkop9814fa22020-11-04 12:28:15 -08006186#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02006187 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006188 {
Ronald Cron7023db52020-11-20 18:17:42 +01006189 return( mbedtls_psa_ecp_generate_key( attributes,
6190 key_buffer,
6191 key_buffer_size,
6192 key_buffer_length ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006193 }
6194 else
John Durkop9814fa22020-11-04 12:28:15 -08006195#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
Steven Cooreman29149862020-08-05 15:43:42 +02006196 {
Ronald Cron2a38a6b2020-10-02 20:02:04 +02006197 (void)key_buffer_length;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006198 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooreman29149862020-08-05 15:43:42 +02006199 }
Gilles Peskinee59236f2018-01-27 23:32:46 +01006200
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006201 return( PSA_SUCCESS );
6202}
Darryl Green0c6575a2018-11-07 16:05:30 +00006203
Gilles Peskine35ef36b2019-05-16 19:42:05 +02006204psa_status_t psa_generate_key( const psa_key_attributes_t *attributes,
Ronald Croncf56a0a2020-08-04 09:51:30 +02006205 mbedtls_svc_key_id_t *key )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006206{
6207 psa_status_t status;
6208 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02006209 psa_se_drv_table_entry_t *driver = NULL;
Ronald Cron2b56bc82020-10-05 10:02:26 +02006210 size_t key_buffer_size;
Gilles Peskine11792082019-08-06 18:36:36 +02006211
Ronald Cron81709fc2020-11-14 12:10:32 +01006212 *key = MBEDTLS_SVC_KEY_ID_INIT;
6213
Gilles Peskine0f84d622019-09-12 19:03:13 +02006214 /* Reject any attempt to create a zero-length key so that we don't
6215 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
6216 if( psa_get_key_bits( attributes ) == 0 )
6217 return( PSA_ERROR_INVALID_ARGUMENT );
6218
Ronald Cron81709fc2020-11-14 12:10:32 +01006219 status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE, attributes,
6220 &slot, &driver );
Gilles Peskine11792082019-08-06 18:36:36 +02006221 if( status != PSA_SUCCESS )
6222 goto exit;
6223
Ronald Cron977c2472020-10-13 08:32:21 +02006224 /* In the case of a transparent key or an opaque key stored in local
6225 * storage (thus not in the case of generating a key in a secure element
6226 * or cryptoprocessor with storage), we have to allocate a buffer to
6227 * hold the generated key material. */
6228 if( slot->key.data == NULL )
6229 {
6230 if ( PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ) ==
6231 PSA_KEY_LOCATION_LOCAL_STORAGE )
6232 {
Ronald Cron3772afe2021-02-08 16:10:05 +01006233 status = psa_validate_key_type_and_size_for_key_generation(
6234 attributes->core.type, attributes->core.bits );
6235 if( status != PSA_SUCCESS )
6236 goto exit;
6237
6238 key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
6239 attributes->core.type,
6240 attributes->core.bits );
Ronald Cron977c2472020-10-13 08:32:21 +02006241 }
6242 else
6243 {
6244 status = psa_driver_wrapper_get_key_buffer_size(
6245 attributes, &key_buffer_size );
Ronald Cron3772afe2021-02-08 16:10:05 +01006246 if( status != PSA_SUCCESS )
6247 goto exit;
Ronald Cron977c2472020-10-13 08:32:21 +02006248 }
Ronald Cron977c2472020-10-13 08:32:21 +02006249
6250 status = psa_allocate_buffer_to_slot( slot, key_buffer_size );
6251 if( status != PSA_SUCCESS )
6252 goto exit;
6253 }
6254
Steven Cooreman2a1664c2020-07-20 15:33:08 +02006255 status = psa_driver_wrapper_generate_key( attributes,
Ronald Cron977c2472020-10-13 08:32:21 +02006256 slot->key.data, slot->key.bytes, &slot->key.bytes );
Gilles Peskine11792082019-08-06 18:36:36 +02006257
Ronald Cron2b56bc82020-10-05 10:02:26 +02006258 if( status != PSA_SUCCESS )
6259 psa_remove_key_data_from_memory( slot );
6260
Gilles Peskine11792082019-08-06 18:36:36 +02006261exit:
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006262 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01006263 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006264 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02006265 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02006266
Darryl Green0c6575a2018-11-07 16:05:30 +00006267 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006268}
6269
Gilles Peskinee59236f2018-01-27 23:32:46 +01006270/****************************************************************/
6271/* Module setup */
6272/****************************************************************/
6273
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006274#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
Gilles Peskine5e769522018-11-20 21:59:56 +01006275psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
6276 void (* entropy_init )( mbedtls_entropy_context *ctx ),
6277 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
6278{
6279 if( global_data.rng_state != RNG_NOT_INITIALIZED )
6280 return( PSA_ERROR_BAD_STATE );
Gilles Peskine30524eb2020-11-13 17:02:26 +01006281 global_data.rng.entropy_init = entropy_init;
6282 global_data.rng.entropy_free = entropy_free;
Gilles Peskine5e769522018-11-20 21:59:56 +01006283 return( PSA_SUCCESS );
6284}
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006285#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
Gilles Peskine5e769522018-11-20 21:59:56 +01006286
Gilles Peskinee59236f2018-01-27 23:32:46 +01006287void mbedtls_psa_crypto_free( void )
6288{
Gilles Peskine66fb1262018-12-10 16:29:04 +01006289 psa_wipe_all_key_slots( );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006290 if( global_data.rng_state != RNG_NOT_INITIALIZED )
6291 {
Gilles Peskine30524eb2020-11-13 17:02:26 +01006292 mbedtls_psa_random_free( &global_data.rng );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006293 }
6294 /* Wipe all remaining data, including configuration.
6295 * In particular, this sets all state indicator to the value
6296 * indicating "uninitialized". */
Gilles Peskine3f108122018-12-07 18:14:53 +01006297 mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
Gilles Peskinea8ade162019-06-26 11:24:49 +02006298#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined0890212019-06-24 14:34:43 +02006299 /* Unregister all secure element drivers, so that we restart from
6300 * a pristine state. */
6301 psa_unregister_all_se_drivers( );
Gilles Peskinea8ade162019-06-26 11:24:49 +02006302#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006303}
6304
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006305#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
6306/** Recover a transaction that was interrupted by a power failure.
6307 *
6308 * This function is called during initialization, before psa_crypto_init()
6309 * returns. If this function returns a failure status, the initialization
6310 * fails.
6311 */
6312static psa_status_t psa_crypto_recover_transaction(
6313 const psa_crypto_transaction_t *transaction )
6314{
6315 switch( transaction->unknown.type )
6316 {
6317 case PSA_CRYPTO_TRANSACTION_CREATE_KEY:
6318 case PSA_CRYPTO_TRANSACTION_DESTROY_KEY:
Janos Follath1d57a202019-08-13 12:15:34 +01006319 /* TODO - fall through to the failure case until this
Gilles Peskinec9d7f942019-08-13 16:17:16 +02006320 * is implemented.
6321 * https://github.com/ARMmbed/mbed-crypto/issues/218
6322 */
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006323 default:
6324 /* We found an unsupported transaction in the storage.
6325 * We don't know what state the storage is in. Give up. */
gabor-mezei-armfe309242020-11-09 17:39:56 +01006326 return( PSA_ERROR_DATA_INVALID );
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006327 }
6328}
6329#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
6330
Gilles Peskinee59236f2018-01-27 23:32:46 +01006331psa_status_t psa_crypto_init( void )
6332{
Gilles Peskine66fb1262018-12-10 16:29:04 +01006333 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006334
Gilles Peskinec6b69072018-11-20 21:42:52 +01006335 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006336 if( global_data.initialized != 0 )
6337 return( PSA_SUCCESS );
6338
Gilles Peskine30524eb2020-11-13 17:02:26 +01006339 /* Initialize and seed the random generator. */
6340 mbedtls_psa_random_init( &global_data.rng );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006341 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskine30524eb2020-11-13 17:02:26 +01006342 status = mbedtls_psa_random_seed( &global_data.rng );
Gilles Peskine66fb1262018-12-10 16:29:04 +01006343 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006344 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01006345 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006346
Gilles Peskine66fb1262018-12-10 16:29:04 +01006347 status = psa_initialize_key_slots( );
6348 if( status != PSA_SUCCESS )
6349 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01006350
Gilles Peskined9348f22019-10-01 15:22:29 +02006351#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
6352 status = psa_init_all_se_drivers( );
6353 if( status != PSA_SUCCESS )
6354 goto exit;
6355#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
6356
Gilles Peskine4b734222019-07-24 15:56:31 +02006357#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
Gilles Peskinefc762652019-07-22 19:30:34 +02006358 status = psa_crypto_load_transaction( );
6359 if( status == PSA_SUCCESS )
6360 {
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006361 status = psa_crypto_recover_transaction( &psa_crypto_transaction );
6362 if( status != PSA_SUCCESS )
6363 goto exit;
6364 status = psa_crypto_stop_transaction( );
Gilles Peskinefc762652019-07-22 19:30:34 +02006365 }
6366 else if( status == PSA_ERROR_DOES_NOT_EXIST )
6367 {
6368 /* There's no transaction to complete. It's all good. */
6369 status = PSA_SUCCESS;
6370 }
Gilles Peskine4b734222019-07-24 15:56:31 +02006371#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
Gilles Peskinefc762652019-07-22 19:30:34 +02006372
Gilles Peskinec6b69072018-11-20 21:42:52 +01006373 /* All done. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006374 global_data.initialized = 1;
6375
6376exit:
Gilles Peskine66fb1262018-12-10 16:29:04 +01006377 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006378 mbedtls_psa_crypto_free( );
Gilles Peskine66fb1262018-12-10 16:29:04 +01006379 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006380}
6381
6382#endif /* MBEDTLS_PSA_CRYPTO_C */