blob: 73f5a6e726b3fc197933ff92cc65bf5b09f82db4 [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
Bence Szépkúti86974652020-06-15 11:59:37 +02004/*
Bence Szépkúti1e148272020-08-07 13:07:28 +02005 * Copyright The Mbed TLS Contributors
Gilles Peskinee59236f2018-01-27 23:32:46 +01006 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
Gilles Peskinee59236f2018-01-27 23:32:46 +010019 */
20
Gilles Peskinedb09ef62020-06-03 01:43:33 +020021#include "common.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010022
23#if defined(MBEDTLS_PSA_CRYPTO_C)
mohammad160327010052018-07-03 13:16:15 +030024
John Durkop07cc04a2020-11-16 22:08:34 -080025#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
26#include "check_crypto_config.h"
27#endif
28
itayzafrir7723ab12019-02-14 10:28:02 +020029#include "psa_crypto_service_integration.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010030#include "psa/crypto.h"
31
Gilles Peskine039b90c2018-12-07 18:24:41 +010032#include "psa_crypto_core.h"
Gilles Peskine5e769522018-11-20 21:59:56 +010033#include "psa_crypto_invasive.h"
Steven Cooremancd84cb42020-07-16 20:28:36 +020034#include "psa_crypto_driver_wrappers.h"
Gilles Peskinea8ade162019-06-26 11:24:49 +020035#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined0890212019-06-24 14:34:43 +020036#include "psa_crypto_se.h"
Gilles Peskinea8ade162019-06-26 11:24:49 +020037#endif
Gilles Peskine961849f2018-11-30 18:54:54 +010038#include "psa_crypto_slot_management.h"
Darryl Greend49a4992018-06-18 17:27:26 +010039/* Include internal declarations that are useful for implementing persistently
40 * stored keys. */
41#include "psa_crypto_storage.h"
42
Gilles Peskineb2b64d32020-12-14 16:43:58 +010043#include "psa_crypto_random_impl.h"
Gilles Peskine90edc992020-11-13 15:39:19 +010044
Gilles Peskineb46bef22019-07-30 21:32:04 +020045#include <assert.h>
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010046#include <stdlib.h>
47#include <string.h>
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010048#include "mbedtls/platform.h"
Gilles Peskineff2d2002019-05-06 15:26:23 +020049#if !defined(MBEDTLS_PLATFORM_C)
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010050#define mbedtls_calloc calloc
51#define mbedtls_free free
52#endif
53
Gilles Peskine1c49f1a2020-11-13 18:46:25 +010054#include "mbedtls/aes.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010055#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020056#include "mbedtls/asn1.h"
Jaeden Amero25384a22019-01-10 10:23:21 +000057#include "mbedtls/asn1write.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020058#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010059#include "mbedtls/blowfish.h"
60#include "mbedtls/camellia.h"
Gilles Peskine26869f22019-05-06 15:25:00 +020061#include "mbedtls/chacha20.h"
62#include "mbedtls/chachapoly.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010063#include "mbedtls/cipher.h"
64#include "mbedtls/ccm.h"
65#include "mbedtls/cmac.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010066#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020067#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010068#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010069#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010070#include "mbedtls/error.h"
71#include "mbedtls/gcm.h"
72#include "mbedtls/md2.h"
73#include "mbedtls/md4.h"
74#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010075#include "mbedtls/md.h"
76#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010077#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010078#include "mbedtls/pk_internal.h"
Gilles Peskine3f108122018-12-07 18:14:53 +010079#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000080#include "mbedtls/error.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010081#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010082#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010083#include "mbedtls/sha1.h"
84#include "mbedtls/sha256.h"
85#include "mbedtls/sha512.h"
86#include "mbedtls/xtea.h"
87
Gilles Peskine996deb12018-08-01 15:45:45 +020088#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
89
Gilles Peskine9ef733f2018-02-07 21:05:37 +010090/* constant-time buffer comparison */
91static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
92{
93 size_t i;
94 unsigned char diff = 0;
95
96 for( i = 0; i < n; i++ )
97 diff |= a[i] ^ b[i];
98
99 return( diff );
100}
101
102
103
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100104/****************************************************************/
105/* Global data, support functions and library management */
106/****************************************************************/
107
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200108static int key_type_is_raw_bytes( psa_key_type_t type )
109{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200110 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200111}
112
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100113/* Values for psa_global_data_t::rng_state */
114#define RNG_NOT_INITIALIZED 0
115#define RNG_INITIALIZED 1
116#define RNG_SEEDED 2
Gilles Peskinec6b69072018-11-20 21:42:52 +0100117
Gilles Peskine2d277862018-06-18 15:41:12 +0200118typedef struct
119{
Gilles Peskine30524eb2020-11-13 17:02:26 +0100120 mbedtls_psa_random_context_t rng;
Gilles Peskinec6b69072018-11-20 21:42:52 +0100121 unsigned initialized : 1;
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100122 unsigned rng_state : 2;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100123} psa_global_data_t;
124
125static psa_global_data_t global_data;
126
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100127#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
128mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state =
129 &global_data.rng.drbg;
130#endif
131
itayzafrir0adf0fc2018-09-06 16:24:41 +0300132#define GUARD_MODULE_INITIALIZED \
133 if( global_data.initialized == 0 ) \
134 return( PSA_ERROR_BAD_STATE );
135
Steven Cooreman01164162020-07-20 15:31:37 +0200136psa_status_t mbedtls_to_psa_error( int ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100137{
Gilles Peskinea5905292018-02-07 20:59:33 +0100138 /* If there's both a high-level code and low-level code, dispatch on
139 * the high-level code. */
140 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100141 {
142 case 0:
143 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100144
145 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
146 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
147 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
148 return( PSA_ERROR_NOT_SUPPORTED );
149 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
150 return( PSA_ERROR_HARDWARE_FAILURE );
151
152 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
153 return( PSA_ERROR_HARDWARE_FAILURE );
154
Gilles Peskine9a944802018-06-21 09:35:35 +0200155 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
156 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
157 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
158 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
159 case MBEDTLS_ERR_ASN1_INVALID_DATA:
160 return( PSA_ERROR_INVALID_ARGUMENT );
161 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
162 return( PSA_ERROR_INSUFFICIENT_MEMORY );
163 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
164 return( PSA_ERROR_BUFFER_TOO_SMALL );
165
Jaeden Amero93e21112019-02-20 13:57:28 +0000166#if defined(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA)
Jaeden Amero892cd6d2019-02-11 12:21:12 +0000167 case MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA:
Jaeden Amero93e21112019-02-20 13:57:28 +0000168#elif defined(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH)
169 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
170#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100171 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
172 return( PSA_ERROR_NOT_SUPPORTED );
173 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
174 return( PSA_ERROR_HARDWARE_FAILURE );
175
Jaeden Amero93e21112019-02-20 13:57:28 +0000176#if defined(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
Jaeden Amero892cd6d2019-02-11 12:21:12 +0000177 case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA:
Jaeden Amero93e21112019-02-20 13:57:28 +0000178#elif defined(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH)
179 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
180#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100181 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
182 return( PSA_ERROR_NOT_SUPPORTED );
183 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
186 case MBEDTLS_ERR_CCM_BAD_INPUT:
187 return( PSA_ERROR_INVALID_ARGUMENT );
188 case MBEDTLS_ERR_CCM_AUTH_FAILED:
189 return( PSA_ERROR_INVALID_SIGNATURE );
190 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
191 return( PSA_ERROR_HARDWARE_FAILURE );
192
Gilles Peskine26869f22019-05-06 15:25:00 +0200193 case MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA:
194 return( PSA_ERROR_INVALID_ARGUMENT );
195
196 case MBEDTLS_ERR_CHACHAPOLY_BAD_STATE:
197 return( PSA_ERROR_BAD_STATE );
198 case MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED:
199 return( PSA_ERROR_INVALID_SIGNATURE );
200
Gilles Peskinea5905292018-02-07 20:59:33 +0100201 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
202 return( PSA_ERROR_NOT_SUPPORTED );
203 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
204 return( PSA_ERROR_INVALID_ARGUMENT );
205 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
206 return( PSA_ERROR_INSUFFICIENT_MEMORY );
207 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
208 return( PSA_ERROR_INVALID_PADDING );
209 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
Fredrik Strupef90e3012020-09-28 16:11:33 +0200210 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100211 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
212 return( PSA_ERROR_INVALID_SIGNATURE );
213 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
Gilles Peskine4b3eb692019-05-16 21:35:18 +0200214 return( PSA_ERROR_CORRUPTION_DETECTED );
Gilles Peskinea5905292018-02-07 20:59:33 +0100215 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
216 return( PSA_ERROR_HARDWARE_FAILURE );
217
218 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
219 return( PSA_ERROR_HARDWARE_FAILURE );
220
Gilles Peskine82e57d12020-11-13 21:31:17 +0100221#if !( defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) || \
222 defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE) )
Gilles Peskinebee96c82020-11-23 21:00:09 +0100223 /* Only check CTR_DRBG error codes if underlying mbedtls_xxx
224 * functions are passed a CTR_DRBG instance. */
Gilles Peskinea5905292018-02-07 20:59:33 +0100225 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
226 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
227 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
228 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
229 return( PSA_ERROR_NOT_SUPPORTED );
230 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
231 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskine82e57d12020-11-13 21:31:17 +0100232#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100233
234 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
235 return( PSA_ERROR_NOT_SUPPORTED );
236 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
237 return( PSA_ERROR_HARDWARE_FAILURE );
238
Gilles Peskinee59236f2018-01-27 23:32:46 +0100239 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
240 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
241 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
242 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100243
244 case MBEDTLS_ERR_GCM_AUTH_FAILED:
245 return( PSA_ERROR_INVALID_SIGNATURE );
246 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200247 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100248 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
249 return( PSA_ERROR_HARDWARE_FAILURE );
250
Gilles Peskine82e57d12020-11-13 21:31:17 +0100251#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \
252 defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
Gilles Peskinebee96c82020-11-23 21:00:09 +0100253 /* Only check HMAC_DRBG error codes if underlying mbedtls_xxx
254 * functions are passed a HMAC_DRBG instance. */
Gilles Peskine82e57d12020-11-13 21:31:17 +0100255 case MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED:
256 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
257 case MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG:
258 case MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG:
259 return( PSA_ERROR_NOT_SUPPORTED );
260 case MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR:
261 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
262#endif
263
Gilles Peskinea5905292018-02-07 20:59:33 +0100264 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
265 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
266 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
267 return( PSA_ERROR_HARDWARE_FAILURE );
268
269 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
270 return( PSA_ERROR_NOT_SUPPORTED );
271 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
272 return( PSA_ERROR_INVALID_ARGUMENT );
273 case MBEDTLS_ERR_MD_ALLOC_FAILED:
274 return( PSA_ERROR_INSUFFICIENT_MEMORY );
275 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
276 return( PSA_ERROR_STORAGE_FAILURE );
277 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
278 return( PSA_ERROR_HARDWARE_FAILURE );
279
Gilles Peskinef76aa772018-10-29 19:24:33 +0100280 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
281 return( PSA_ERROR_STORAGE_FAILURE );
282 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
283 return( PSA_ERROR_INVALID_ARGUMENT );
284 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
285 return( PSA_ERROR_INVALID_ARGUMENT );
286 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
287 return( PSA_ERROR_BUFFER_TOO_SMALL );
288 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
289 return( PSA_ERROR_INVALID_ARGUMENT );
290 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
291 return( PSA_ERROR_INVALID_ARGUMENT );
292 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
293 return( PSA_ERROR_INVALID_ARGUMENT );
294 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
295 return( PSA_ERROR_INSUFFICIENT_MEMORY );
296
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100297 case MBEDTLS_ERR_PK_ALLOC_FAILED:
298 return( PSA_ERROR_INSUFFICIENT_MEMORY );
299 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
300 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
301 return( PSA_ERROR_INVALID_ARGUMENT );
302 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100303 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100304 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
305 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
306 return( PSA_ERROR_INVALID_ARGUMENT );
307 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
308 return( PSA_ERROR_NOT_SUPPORTED );
309 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
310 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
311 return( PSA_ERROR_NOT_PERMITTED );
312 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
313 return( PSA_ERROR_INVALID_ARGUMENT );
314 case MBEDTLS_ERR_PK_INVALID_ALG:
315 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
316 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
317 return( PSA_ERROR_NOT_SUPPORTED );
318 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
319 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100320 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
321 return( PSA_ERROR_HARDWARE_FAILURE );
322
Gilles Peskineff2d2002019-05-06 15:26:23 +0200323 case MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED:
324 return( PSA_ERROR_HARDWARE_FAILURE );
325 case MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
326 return( PSA_ERROR_NOT_SUPPORTED );
327
Gilles Peskinea5905292018-02-07 20:59:33 +0100328 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
329 return( PSA_ERROR_HARDWARE_FAILURE );
330
331 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
332 return( PSA_ERROR_INVALID_ARGUMENT );
333 case MBEDTLS_ERR_RSA_INVALID_PADDING:
334 return( PSA_ERROR_INVALID_PADDING );
335 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
336 return( PSA_ERROR_HARDWARE_FAILURE );
337 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
338 return( PSA_ERROR_INVALID_ARGUMENT );
339 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
340 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
Gilles Peskine4b3eb692019-05-16 21:35:18 +0200341 return( PSA_ERROR_CORRUPTION_DETECTED );
Gilles Peskinea5905292018-02-07 20:59:33 +0100342 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
343 return( PSA_ERROR_INVALID_SIGNATURE );
344 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
345 return( PSA_ERROR_BUFFER_TOO_SMALL );
346 case MBEDTLS_ERR_RSA_RNG_FAILED:
Gilles Peskine40d81602020-11-25 00:09:47 +0100347 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100348 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
349 return( PSA_ERROR_NOT_SUPPORTED );
350 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
351 return( PSA_ERROR_HARDWARE_FAILURE );
352
353 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
354 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
355 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
356 return( PSA_ERROR_HARDWARE_FAILURE );
357
358 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
359 return( PSA_ERROR_INVALID_ARGUMENT );
360 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
361 return( PSA_ERROR_HARDWARE_FAILURE );
362
itayzafrir5c753392018-05-08 11:18:38 +0300363 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300364 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300365 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300366 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
367 return( PSA_ERROR_BUFFER_TOO_SMALL );
368 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
369 return( PSA_ERROR_NOT_SUPPORTED );
370 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
371 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
372 return( PSA_ERROR_INVALID_SIGNATURE );
373 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
374 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Gilles Peskine40d81602020-11-25 00:09:47 +0100375 case MBEDTLS_ERR_ECP_RANDOM_FAILED:
376 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300377 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
378 return( PSA_ERROR_HARDWARE_FAILURE );
Gilles Peskine40d81602020-11-25 00:09:47 +0100379
Janos Follatha13b9052019-11-22 12:48:59 +0000380 case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
381 return( PSA_ERROR_CORRUPTION_DETECTED );
itayzafrir5c753392018-05-08 11:18:38 +0300382
Gilles Peskinee59236f2018-01-27 23:32:46 +0100383 default:
David Saadab4ecc272019-02-14 13:48:10 +0200384 return( PSA_ERROR_GENERIC_ERROR );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100385 }
386}
387
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200388
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200389
390
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100391/****************************************************************/
392/* Key management */
393/****************************************************************/
394
Gilles Peskine73167e12019-07-12 23:44:37 +0200395#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
396static inline int psa_key_slot_is_external( const psa_key_slot_t *slot )
397{
Gilles Peskine8e338702019-07-30 20:06:31 +0200398 return( psa_key_lifetime_is_external( slot->attr.lifetime ) );
Gilles Peskine73167e12019-07-12 23:44:37 +0200399}
400#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
401
John Durkop07cc04a2020-11-16 22:08:34 -0800402/* For now the MBEDTLS_PSA_ACCEL_ guards are also used here since the
403 * current test driver in key_management.c is using this function
404 * when accelerators are used for ECC key pair and public key.
405 * Once that dependency is resolved these guards can be removed.
406 */
John Durkop9814fa22020-11-04 12:28:15 -0800407#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
John Durkop6ba40d12020-11-10 08:50:04 -0800408 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
409 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \
410 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
Paul Elliott8ff510a2020-06-02 17:19:28 +0100411mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_family_t curve,
Gilles Peskine5055b232019-12-12 17:49:31 +0100412 size_t byte_length )
Gilles Peskine12313cd2018-06-20 00:20:32 +0200413{
414 switch( curve )
415 {
Paul Elliott8ff510a2020-06-02 17:19:28 +0100416 case PSA_ECC_FAMILY_SECP_R1:
Gilles Peskine228abc52019-12-03 17:24:19 +0100417 switch( byte_length )
418 {
419 case PSA_BITS_TO_BYTES( 192 ):
420 return( MBEDTLS_ECP_DP_SECP192R1 );
421 case PSA_BITS_TO_BYTES( 224 ):
422 return( MBEDTLS_ECP_DP_SECP224R1 );
423 case PSA_BITS_TO_BYTES( 256 ):
424 return( MBEDTLS_ECP_DP_SECP256R1 );
425 case PSA_BITS_TO_BYTES( 384 ):
426 return( MBEDTLS_ECP_DP_SECP384R1 );
427 case PSA_BITS_TO_BYTES( 521 ):
428 return( MBEDTLS_ECP_DP_SECP521R1 );
429 default:
430 return( MBEDTLS_ECP_DP_NONE );
431 }
432 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100433
Paul Elliott8ff510a2020-06-02 17:19:28 +0100434 case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
Gilles Peskine228abc52019-12-03 17:24:19 +0100435 switch( byte_length )
436 {
437 case PSA_BITS_TO_BYTES( 256 ):
438 return( MBEDTLS_ECP_DP_BP256R1 );
439 case PSA_BITS_TO_BYTES( 384 ):
440 return( MBEDTLS_ECP_DP_BP384R1 );
441 case PSA_BITS_TO_BYTES( 512 ):
442 return( MBEDTLS_ECP_DP_BP512R1 );
443 default:
444 return( MBEDTLS_ECP_DP_NONE );
445 }
446 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100447
Paul Elliott8ff510a2020-06-02 17:19:28 +0100448 case PSA_ECC_FAMILY_MONTGOMERY:
Gilles Peskine228abc52019-12-03 17:24:19 +0100449 switch( byte_length )
450 {
451 case PSA_BITS_TO_BYTES( 255 ):
452 return( MBEDTLS_ECP_DP_CURVE25519 );
453 case PSA_BITS_TO_BYTES( 448 ):
454 return( MBEDTLS_ECP_DP_CURVE448 );
455 default:
456 return( MBEDTLS_ECP_DP_NONE );
457 }
458 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100459
Paul Elliott8ff510a2020-06-02 17:19:28 +0100460 case PSA_ECC_FAMILY_SECP_K1:
Gilles Peskine228abc52019-12-03 17:24:19 +0100461 switch( byte_length )
462 {
463 case PSA_BITS_TO_BYTES( 192 ):
464 return( MBEDTLS_ECP_DP_SECP192K1 );
465 case PSA_BITS_TO_BYTES( 224 ):
466 return( MBEDTLS_ECP_DP_SECP224K1 );
467 case PSA_BITS_TO_BYTES( 256 ):
468 return( MBEDTLS_ECP_DP_SECP256K1 );
469 default:
470 return( MBEDTLS_ECP_DP_NONE );
471 }
472 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100473
Gilles Peskine12313cd2018-06-20 00:20:32 +0200474 default:
475 return( MBEDTLS_ECP_DP_NONE );
476 }
477}
John Durkop9814fa22020-11-04 12:28:15 -0800478#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
John Durkop6ba40d12020-11-10 08:50:04 -0800479 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
480 * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) ||
481 * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200482
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200483static psa_status_t validate_unstructured_key_bit_size( psa_key_type_t type,
484 size_t bits )
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200485{
486 /* Check that the bit size is acceptable for the key type */
487 switch( type )
488 {
489 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200490 case PSA_KEY_TYPE_HMAC:
Gilles Peskineea0fb492018-07-12 17:17:20 +0200491 case PSA_KEY_TYPE_DERIVE:
492 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200493#if defined(MBEDTLS_AES_C)
494 case PSA_KEY_TYPE_AES:
495 if( bits != 128 && bits != 192 && bits != 256 )
496 return( PSA_ERROR_INVALID_ARGUMENT );
497 break;
498#endif
499#if defined(MBEDTLS_CAMELLIA_C)
500 case PSA_KEY_TYPE_CAMELLIA:
501 if( bits != 128 && bits != 192 && bits != 256 )
502 return( PSA_ERROR_INVALID_ARGUMENT );
503 break;
504#endif
505#if defined(MBEDTLS_DES_C)
506 case PSA_KEY_TYPE_DES:
507 if( bits != 64 && bits != 128 && bits != 192 )
508 return( PSA_ERROR_INVALID_ARGUMENT );
509 break;
510#endif
511#if defined(MBEDTLS_ARC4_C)
512 case PSA_KEY_TYPE_ARC4:
513 if( bits < 8 || bits > 2048 )
514 return( PSA_ERROR_INVALID_ARGUMENT );
515 break;
516#endif
Gilles Peskine26869f22019-05-06 15:25:00 +0200517#if defined(MBEDTLS_CHACHA20_C)
518 case PSA_KEY_TYPE_CHACHA20:
519 if( bits != 256 )
520 return( PSA_ERROR_INVALID_ARGUMENT );
521 break;
522#endif
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200523 default:
524 return( PSA_ERROR_NOT_SUPPORTED );
525 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200526 if( bits % 8 != 0 )
527 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200528
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200529 return( PSA_SUCCESS );
530}
531
John Durkop0e005192020-10-31 22:06:54 -0700532#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
533 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
534 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
John Durkop9814fa22020-11-04 12:28:15 -0800535 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
536 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
537 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Steven Cooremana01795d2020-07-24 22:48:15 +0200538
Gilles Peskine86a440b2018-11-12 18:39:40 +0100539/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
540 * that are not a multiple of 8) well. For example, there is only
541 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
542 * way to return the exact bit size of a key.
543 * To keep things simple, reject non-byte-aligned key sizes. */
544static psa_status_t psa_check_rsa_key_byte_aligned(
545 const mbedtls_rsa_context *rsa )
546{
547 mbedtls_mpi n;
548 psa_status_t status;
549 mbedtls_mpi_init( &n );
550 status = mbedtls_to_psa_error(
551 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
552 if( status == PSA_SUCCESS )
553 {
554 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
555 status = PSA_ERROR_NOT_SUPPORTED;
556 }
557 mbedtls_mpi_free( &n );
558 return( status );
559}
560
Steven Cooreman7f391872020-07-30 14:57:44 +0200561/** Load the contents of a key buffer into an internal RSA representation
Steven Cooremana01795d2020-07-24 22:48:15 +0200562 *
Steven Cooreman4fed4552020-08-03 14:46:03 +0200563 * \param[in] type The type of key contained in \p data.
564 * \param[in] data The buffer from which to load the representation.
565 * \param[in] data_length The size in bytes of \p data.
566 * \param[out] p_rsa Returns a pointer to an RSA context on success.
567 * The caller is responsible for freeing both the
568 * contents of the context and the context itself
569 * when done.
Steven Cooremana01795d2020-07-24 22:48:15 +0200570 */
Steven Cooreman4fed4552020-08-03 14:46:03 +0200571static psa_status_t psa_load_rsa_representation( psa_key_type_t type,
572 const uint8_t *data,
573 size_t data_length,
Steven Cooremana2371e52020-07-28 14:30:39 +0200574 mbedtls_rsa_context **p_rsa )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200575{
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000576 psa_status_t status;
Steven Cooremana01795d2020-07-24 22:48:15 +0200577 mbedtls_pk_context ctx;
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000578 size_t bits;
Steven Cooremana01795d2020-07-24 22:48:15 +0200579 mbedtls_pk_init( &ctx );
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000580
581 /* Parse the data. */
Steven Cooreman7f391872020-07-30 14:57:44 +0200582 if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000583 status = mbedtls_to_psa_error(
Steven Cooreman4fed4552020-08-03 14:46:03 +0200584 mbedtls_pk_parse_key( &ctx, data, data_length, NULL, 0 ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200585 else
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000586 status = mbedtls_to_psa_error(
Steven Cooreman4fed4552020-08-03 14:46:03 +0200587 mbedtls_pk_parse_public_key( &ctx, data, data_length ) );
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000588 if( status != PSA_SUCCESS )
589 goto exit;
590
591 /* We have something that the pkparse module recognizes. If it is a
592 * valid RSA key, store it. */
Steven Cooremana01795d2020-07-24 22:48:15 +0200593 if( mbedtls_pk_get_type( &ctx ) != MBEDTLS_PK_RSA )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200594 {
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000595 status = PSA_ERROR_INVALID_ARGUMENT;
596 goto exit;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200597 }
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000598
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000599 /* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
600 * supports non-byte-aligned key sizes, but not well. For example,
601 * mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
Steven Cooremana01795d2020-07-24 22:48:15 +0200602 bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( mbedtls_pk_rsa( ctx ) ) );
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000603 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
604 {
605 status = PSA_ERROR_NOT_SUPPORTED;
606 goto exit;
607 }
Steven Cooremana01795d2020-07-24 22:48:15 +0200608 status = psa_check_rsa_key_byte_aligned( mbedtls_pk_rsa( ctx ) );
Steven Cooremana01795d2020-07-24 22:48:15 +0200609 if( status != PSA_SUCCESS )
610 goto exit;
611
Steven Cooremana2371e52020-07-28 14:30:39 +0200612 /* Copy out the pointer to the RSA context, and reset the PK context
613 * such that pk_free doesn't free the RSA context we just grabbed. */
614 *p_rsa = mbedtls_pk_rsa( ctx );
615 ctx.pk_info = NULL;
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000616
617exit:
Steven Cooremana01795d2020-07-24 22:48:15 +0200618 mbedtls_pk_free( &ctx );
619 return( status );
Steven Cooremana01795d2020-07-24 22:48:15 +0200620}
621
John Durkop6ba40d12020-11-10 08:50:04 -0800622#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
623 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
624 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
625 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
626 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
627 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
628
629#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
630 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
631
Steven Cooremana01795d2020-07-24 22:48:15 +0200632/** Export an RSA key to export representation
633 *
634 * \param[in] type The type of key (public/private) to export
635 * \param[in] rsa The internal RSA representation from which to export
636 * \param[out] data The buffer to export to
637 * \param[in] data_size The length of the buffer to export to
638 * \param[out] data_length The amount of bytes written to \p data
639 */
640static psa_status_t psa_export_rsa_key( psa_key_type_t type,
641 mbedtls_rsa_context *rsa,
642 uint8_t *data,
643 size_t data_size,
644 size_t *data_length )
645{
646#if defined(MBEDTLS_PK_WRITE_C)
647 int ret;
648 mbedtls_pk_context pk;
649 uint8_t *pos = data + data_size;
650
651 mbedtls_pk_init( &pk );
652 pk.pk_info = &mbedtls_rsa_info;
653 pk.pk_ctx = rsa;
654
655 /* PSA Crypto API defines the format of an RSA key as a DER-encoded
Steven Cooreman75b74362020-07-28 14:30:13 +0200656 * representation of the non-encrypted PKCS#1 RSAPrivateKey for a
657 * private key and of the RFC3279 RSAPublicKey for a public key. */
Steven Cooremana01795d2020-07-24 22:48:15 +0200658 if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
659 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
660 else
661 ret = mbedtls_pk_write_pubkey( &pos, data, &pk );
662
663 if( ret < 0 )
Steven Cooreman4fed4552020-08-03 14:46:03 +0200664 {
665 /* Clean up in case pk_write failed halfway through. */
666 memset( data, 0, data_size );
Steven Cooreman29149862020-08-05 15:43:42 +0200667 return( mbedtls_to_psa_error( ret ) );
Steven Cooreman4fed4552020-08-03 14:46:03 +0200668 }
Steven Cooremana01795d2020-07-24 22:48:15 +0200669
670 /* The mbedtls_pk_xxx functions write to the end of the buffer.
671 * Move the data to the beginning and erase remaining data
672 * at the original location. */
673 if( 2 * (size_t) ret <= data_size )
674 {
675 memcpy( data, data + data_size - ret, ret );
676 memset( data + data_size - ret, 0, ret );
677 }
678 else if( (size_t) ret < data_size )
679 {
680 memmove( data, data + data_size - ret, ret );
681 memset( data + ret, 0, data_size - ret );
682 }
683
684 *data_length = ret;
685 return( PSA_SUCCESS );
686#else
687 (void) type;
688 (void) rsa;
689 (void) data;
690 (void) data_size;
691 (void) data_length;
692 return( PSA_ERROR_NOT_SUPPORTED );
693#endif /* MBEDTLS_PK_WRITE_C */
694}
695
696/** Import an RSA key from import representation to a slot
697 *
698 * \param[in,out] slot The slot where to store the export representation to
699 * \param[in] data The buffer containing the import representation
700 * \param[in] data_length The amount of bytes in \p data
701 */
702static psa_status_t psa_import_rsa_key( psa_key_slot_t *slot,
703 const uint8_t *data,
704 size_t data_length )
705{
706 psa_status_t status;
707 uint8_t* output = NULL;
Steven Cooremana2371e52020-07-28 14:30:39 +0200708 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +0200709
Steven Cooremana01795d2020-07-24 22:48:15 +0200710 /* Parse input */
Steven Cooreman4fed4552020-08-03 14:46:03 +0200711 status = psa_load_rsa_representation( slot->attr.type,
712 data,
Steven Cooreman7f391872020-07-30 14:57:44 +0200713 data_length,
Steven Cooreman7f391872020-07-30 14:57:44 +0200714 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +0200715 if( status != PSA_SUCCESS )
716 goto exit;
717
718 slot->attr.bits = (psa_key_bits_t) PSA_BYTES_TO_BITS(
Steven Cooremana2371e52020-07-28 14:30:39 +0200719 mbedtls_rsa_get_len( rsa ) );
Steven Cooremana01795d2020-07-24 22:48:15 +0200720
Steven Cooreman75b74362020-07-28 14:30:13 +0200721 /* Re-export the data to PSA export format, such that we can store export
722 * representation in the key slot. Export representation in case of RSA is
723 * the smallest representation that's allowed as input, so a straight-up
724 * allocation of the same size as the input buffer will be large enough. */
Steven Cooremana01795d2020-07-24 22:48:15 +0200725 output = mbedtls_calloc( 1, data_length );
Steven Cooremana01795d2020-07-24 22:48:15 +0200726 if( output == NULL )
727 {
728 status = PSA_ERROR_INSUFFICIENT_MEMORY;
729 goto exit;
730 }
731
Steven Cooremana01795d2020-07-24 22:48:15 +0200732 status = psa_export_rsa_key( slot->attr.type,
Steven Cooremana2371e52020-07-28 14:30:39 +0200733 rsa,
Steven Cooremana01795d2020-07-24 22:48:15 +0200734 output,
735 data_length,
736 &data_length);
Steven Cooremana01795d2020-07-24 22:48:15 +0200737exit:
738 /* Always free the RSA object */
Steven Cooremana2371e52020-07-28 14:30:39 +0200739 mbedtls_rsa_free( rsa );
Steven Cooreman6d839f02020-07-30 11:36:45 +0200740 mbedtls_free( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +0200741
742 /* Free the allocated buffer only on error. */
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000743 if( status != PSA_SUCCESS )
744 {
Steven Cooremana01795d2020-07-24 22:48:15 +0200745 mbedtls_free( output );
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000746 return( status );
747 }
748
Steven Cooremana01795d2020-07-24 22:48:15 +0200749 /* On success, store the allocated export-formatted key. */
750 slot->data.key.data = output;
751 slot->data.key.bytes = data_length;
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000752
753 return( PSA_SUCCESS );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200754}
John Durkop6ba40d12020-11-10 08:50:04 -0800755
756#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
John Durkop9814fa22020-11-04 12:28:15 -0800757 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200758
John Durkop9814fa22020-11-04 12:28:15 -0800759#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
John Durkop6ba40d12020-11-10 08:50:04 -0800760 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
761 defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
762 defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) || \
763 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Steven Cooreman7f391872020-07-30 14:57:44 +0200764/** Load the contents of a key buffer into an internal ECP representation
Steven Cooremana2371e52020-07-28 14:30:39 +0200765 *
Steven Cooreman4fed4552020-08-03 14:46:03 +0200766 * \param[in] type The type of key contained in \p data.
767 * \param[in] data The buffer from which to load the representation.
768 * \param[in] data_length The size in bytes of \p data.
769 * \param[out] p_ecp Returns a pointer to an ECP context on success.
770 * The caller is responsible for freeing both the
771 * contents of the context and the context itself
772 * when done.
Steven Cooremana2371e52020-07-28 14:30:39 +0200773 */
Steven Cooreman4fed4552020-08-03 14:46:03 +0200774static psa_status_t psa_load_ecp_representation( psa_key_type_t type,
775 const uint8_t *data,
776 size_t data_length,
Steven Cooremana2371e52020-07-28 14:30:39 +0200777 mbedtls_ecp_keypair **p_ecp )
Gilles Peskine4cd32772019-12-02 20:49:42 +0100778{
779 mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
Steven Cooremanacda8342020-07-24 23:09:52 +0200780 psa_status_t status;
Steven Cooreman6d839f02020-07-30 11:36:45 +0200781 mbedtls_ecp_keypair *ecp = NULL;
Steven Cooreman4fed4552020-08-03 14:46:03 +0200782 size_t curve_size = data_length;
Gilles Peskine4cd32772019-12-02 20:49:42 +0100783
Steven Cooreman4fed4552020-08-03 14:46:03 +0200784 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) &&
785 PSA_KEY_TYPE_ECC_GET_FAMILY( type ) != PSA_ECC_FAMILY_MONTGOMERY )
Gilles Peskine4295e8b2019-12-02 21:39:10 +0100786 {
Steven Cooreman4fed4552020-08-03 14:46:03 +0200787 /* A Weierstrass public key is represented as:
788 * - The byte 0x04;
789 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
790 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
Steven Cooreman3ea0ce42020-10-23 11:37:05 +0200791 * So its data length is 2m+1 where m is the curve size in bits.
Steven Cooreman4fed4552020-08-03 14:46:03 +0200792 */
793 if( ( data_length & 1 ) == 0 )
794 return( PSA_ERROR_INVALID_ARGUMENT );
795 curve_size = data_length / 2;
796
797 /* Montgomery public keys are represented in compressed format, meaning
798 * their curve_size is equal to the amount of input. */
799
800 /* Private keys are represented in uncompressed private random integer
801 * format, meaning their curve_size is equal to the amount of input. */
Gilles Peskine4295e8b2019-12-02 21:39:10 +0100802 }
803
Steven Cooreman6d839f02020-07-30 11:36:45 +0200804 /* Allocate and initialize a key representation. */
Steven Cooreman29149862020-08-05 15:43:42 +0200805 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
Steven Cooreman6d839f02020-07-30 11:36:45 +0200806 if( ecp == NULL )
Steven Cooreman29149862020-08-05 15:43:42 +0200807 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Steven Cooremana2371e52020-07-28 14:30:39 +0200808 mbedtls_ecp_keypair_init( ecp );
809
Gilles Peskine4cd32772019-12-02 20:49:42 +0100810 /* Load the group. */
Steven Cooreman7f391872020-07-30 14:57:44 +0200811 grp_id = mbedtls_ecc_group_of_psa( PSA_KEY_TYPE_ECC_GET_FAMILY( type ),
812 curve_size );
Gilles Peskine4295e8b2019-12-02 21:39:10 +0100813 if( grp_id == MBEDTLS_ECP_DP_NONE )
Steven Cooreman6d839f02020-07-30 11:36:45 +0200814 {
815 status = PSA_ERROR_INVALID_ARGUMENT;
816 goto exit;
817 }
818
Steven Cooremanacda8342020-07-24 23:09:52 +0200819 status = mbedtls_to_psa_error(
820 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
821 if( status != PSA_SUCCESS )
Steven Cooreman6d839f02020-07-30 11:36:45 +0200822 goto exit;
Steven Cooremanacda8342020-07-24 23:09:52 +0200823
Steven Cooreman6d839f02020-07-30 11:36:45 +0200824 /* Load the key material. */
Steven Cooreman7f391872020-07-30 14:57:44 +0200825 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
Steven Cooremanacda8342020-07-24 23:09:52 +0200826 {
827 /* Load the public value. */
828 status = mbedtls_to_psa_error(
829 mbedtls_ecp_point_read_binary( &ecp->grp, &ecp->Q,
Steven Cooreman4fed4552020-08-03 14:46:03 +0200830 data,
831 data_length ) );
Steven Cooremanacda8342020-07-24 23:09:52 +0200832 if( status != PSA_SUCCESS )
833 goto exit;
834
835 /* Check that the point is on the curve. */
836 status = mbedtls_to_psa_error(
837 mbedtls_ecp_check_pubkey( &ecp->grp, &ecp->Q ) );
838 if( status != PSA_SUCCESS )
839 goto exit;
840 }
841 else
842 {
Steven Cooreman6d839f02020-07-30 11:36:45 +0200843 /* Load and validate the secret value. */
Steven Cooremanacda8342020-07-24 23:09:52 +0200844 status = mbedtls_to_psa_error(
845 mbedtls_ecp_read_key( ecp->grp.id,
846 ecp,
Steven Cooreman4fed4552020-08-03 14:46:03 +0200847 data,
848 data_length ) );
Steven Cooremanacda8342020-07-24 23:09:52 +0200849 if( status != PSA_SUCCESS )
850 goto exit;
Steven Cooremanacda8342020-07-24 23:09:52 +0200851 }
Steven Cooremana2371e52020-07-28 14:30:39 +0200852
853 *p_ecp = ecp;
Steven Cooremanacda8342020-07-24 23:09:52 +0200854exit:
855 if( status != PSA_SUCCESS )
Steven Cooremana2371e52020-07-28 14:30:39 +0200856 {
Steven Cooremanacda8342020-07-24 23:09:52 +0200857 mbedtls_ecp_keypair_free( ecp );
Steven Cooremana2371e52020-07-28 14:30:39 +0200858 mbedtls_free( ecp );
859 }
860
Steven Cooreman29149862020-08-05 15:43:42 +0200861 return( status );
Gilles Peskine4cd32772019-12-02 20:49:42 +0100862}
John Durkop6ba40d12020-11-10 08:50:04 -0800863#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
864 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
865 * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
866 * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) ||
867 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Jaeden Ameroccdce902019-01-10 11:42:27 +0000868
John Durkop6ba40d12020-11-10 08:50:04 -0800869#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
870 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Steven Cooreman4fed4552020-08-03 14:46:03 +0200871/** Export an ECP key to export representation
872 *
873 * \param[in] type The type of key (public/private) to export
874 * \param[in] ecp The internal ECP representation from which to export
875 * \param[out] data The buffer to export to
876 * \param[in] data_size The length of the buffer to export to
877 * \param[out] data_length The amount of bytes written to \p data
878 */
Steven Cooremanacda8342020-07-24 23:09:52 +0200879static psa_status_t psa_export_ecp_key( psa_key_type_t type,
880 mbedtls_ecp_keypair *ecp,
881 uint8_t *data,
882 size_t data_size,
883 size_t *data_length )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200884{
Steven Cooremanacda8342020-07-24 23:09:52 +0200885 psa_status_t status;
Jaeden Ameroccdce902019-01-10 11:42:27 +0000886
Steven Cooremanacda8342020-07-24 23:09:52 +0200887 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200888 {
Steven Cooremanacda8342020-07-24 23:09:52 +0200889 /* Check whether the public part is loaded */
890 if( mbedtls_ecp_is_zero( &ecp->Q ) )
891 {
892 /* Calculate the public key */
893 status = mbedtls_to_psa_error(
894 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100895 mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
Steven Cooremanacda8342020-07-24 23:09:52 +0200896 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +0200897 return( status );
Steven Cooremanacda8342020-07-24 23:09:52 +0200898 }
899
Steven Cooreman4fed4552020-08-03 14:46:03 +0200900 status = mbedtls_to_psa_error(
Steven Cooremanacda8342020-07-24 23:09:52 +0200901 mbedtls_ecp_point_write_binary( &ecp->grp, &ecp->Q,
902 MBEDTLS_ECP_PF_UNCOMPRESSED,
903 data_length,
904 data,
Steven Cooreman4fed4552020-08-03 14:46:03 +0200905 data_size ) );
Steven Cooreman4fed4552020-08-03 14:46:03 +0200906 if( status != PSA_SUCCESS )
907 memset( data, 0, data_size );
908
Steven Cooreman29149862020-08-05 15:43:42 +0200909 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200910 }
Steven Cooremanacda8342020-07-24 23:09:52 +0200911 else
912 {
Steven Cooreman29149862020-08-05 15:43:42 +0200913 if( data_size < PSA_BITS_TO_BYTES( ecp->grp.nbits ) )
Steven Cooremanacda8342020-07-24 23:09:52 +0200914 return( PSA_ERROR_BUFFER_TOO_SMALL );
915
916 status = mbedtls_to_psa_error(
917 mbedtls_ecp_write_key( ecp,
918 data,
Steven Cooreman29149862020-08-05 15:43:42 +0200919 PSA_BITS_TO_BYTES( ecp->grp.nbits ) ) );
Steven Cooremanacda8342020-07-24 23:09:52 +0200920 if( status == PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +0200921 *data_length = PSA_BITS_TO_BYTES( ecp->grp.nbits );
Steven Cooremanb7f6dea2020-08-05 16:07:20 +0200922 else
923 memset( data, 0, data_size );
Steven Cooremanacda8342020-07-24 23:09:52 +0200924
925 return( status );
926 }
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200927}
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200928
Steven Cooreman4fed4552020-08-03 14:46:03 +0200929/** Import an ECP key from import representation to a slot
930 *
931 * \param[in,out] slot The slot where to store the export representation to
932 * \param[in] data The buffer containing the import representation
933 * \param[in] data_length The amount of bytes in \p data
934 */
Steven Cooremanacda8342020-07-24 23:09:52 +0200935static psa_status_t psa_import_ecp_key( psa_key_slot_t *slot,
936 const uint8_t *data,
937 size_t data_length )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100938{
Steven Cooremanacda8342020-07-24 23:09:52 +0200939 psa_status_t status;
940 uint8_t* output = NULL;
Steven Cooremana2371e52020-07-28 14:30:39 +0200941 mbedtls_ecp_keypair *ecp = NULL;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100942
Steven Cooremanacda8342020-07-24 23:09:52 +0200943 /* Parse input */
Steven Cooreman4fed4552020-08-03 14:46:03 +0200944 status = psa_load_ecp_representation( slot->attr.type,
945 data,
Steven Cooreman7f391872020-07-30 14:57:44 +0200946 data_length,
Steven Cooreman7f391872020-07-30 14:57:44 +0200947 &ecp );
Gilles Peskinef76aa772018-10-29 19:24:33 +0100948 if( status != PSA_SUCCESS )
949 goto exit;
Gilles Peskine4cd32772019-12-02 20:49:42 +0100950
Steven Cooremanacda8342020-07-24 23:09:52 +0200951 if( PSA_KEY_TYPE_ECC_GET_FAMILY( slot->attr.type ) == PSA_ECC_FAMILY_MONTGOMERY)
Steven Cooremana2371e52020-07-28 14:30:39 +0200952 slot->attr.bits = (psa_key_bits_t) ecp->grp.nbits + 1;
Steven Cooremanacda8342020-07-24 23:09:52 +0200953 else
Steven Cooremana2371e52020-07-28 14:30:39 +0200954 slot->attr.bits = (psa_key_bits_t) ecp->grp.nbits;
Steven Cooremane3fd3922020-06-11 16:50:36 +0200955
Steven Cooremanacda8342020-07-24 23:09:52 +0200956 /* Re-export the data to PSA export format. There is currently no support
957 * for other input formats then the export format, so this is a 1-1
958 * copy operation. */
959 output = mbedtls_calloc( 1, data_length );
Steven Cooremanacda8342020-07-24 23:09:52 +0200960 if( output == NULL )
961 {
962 status = PSA_ERROR_INSUFFICIENT_MEMORY;
963 goto exit;
964 }
965
966 status = psa_export_ecp_key( slot->attr.type,
Steven Cooremana2371e52020-07-28 14:30:39 +0200967 ecp,
Steven Cooremanacda8342020-07-24 23:09:52 +0200968 output,
969 data_length,
970 &data_length);
Gilles Peskinef76aa772018-10-29 19:24:33 +0100971exit:
Steven Cooremana2371e52020-07-28 14:30:39 +0200972 /* Always free the PK object (will also free contained ECP context) */
973 mbedtls_ecp_keypair_free( ecp );
Steven Cooreman6d839f02020-07-30 11:36:45 +0200974 mbedtls_free( ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +0200975
976 /* Free the allocated buffer only on error. */
977 if( status != PSA_SUCCESS )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100978 {
Steven Cooremanacda8342020-07-24 23:09:52 +0200979 mbedtls_free( output );
Steven Cooremanacda8342020-07-24 23:09:52 +0200980 return( status );
Gilles Peskinef76aa772018-10-29 19:24:33 +0100981 }
Steven Cooremanacda8342020-07-24 23:09:52 +0200982
983 /* On success, store the allocated export-formatted key. */
984 slot->data.key.data = output;
985 slot->data.key.bytes = data_length;
986
987 return( PSA_SUCCESS );
Gilles Peskinef76aa772018-10-29 19:24:33 +0100988}
John Durkop9814fa22020-11-04 12:28:15 -0800989#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
990 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
Gilles Peskinef76aa772018-10-29 19:24:33 +0100991
Gilles Peskineb46bef22019-07-30 21:32:04 +0200992/** Return the size of the key in the given slot, in bits.
993 *
994 * \param[in] slot A key slot.
995 *
996 * \return The key size in bits, read from the metadata in the slot.
997 */
998static inline size_t psa_get_key_slot_bits( const psa_key_slot_t *slot )
999{
1000 return( slot->attr.bits );
1001}
1002
Steven Cooreman75b74362020-07-28 14:30:13 +02001003/** Try to allocate a buffer to an empty key slot.
1004 *
1005 * \param[in,out] slot Key slot to attach buffer to.
1006 * \param[in] buffer_length Requested size of the buffer.
1007 *
1008 * \retval #PSA_SUCCESS
1009 * The buffer has been successfully allocated.
1010 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
1011 * Not enough memory was available for allocation.
1012 * \retval #PSA_ERROR_ALREADY_EXISTS
1013 * Trying to allocate a buffer to a non-empty key slot.
1014 */
1015static psa_status_t psa_allocate_buffer_to_slot( psa_key_slot_t *slot,
1016 size_t buffer_length )
1017{
1018 if( slot->data.key.data != NULL )
Steven Cooreman29149862020-08-05 15:43:42 +02001019 return( PSA_ERROR_ALREADY_EXISTS );
Steven Cooreman75b74362020-07-28 14:30:13 +02001020
1021 slot->data.key.data = mbedtls_calloc( 1, buffer_length );
1022 if( slot->data.key.data == NULL )
Steven Cooreman29149862020-08-05 15:43:42 +02001023 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Steven Cooreman75b74362020-07-28 14:30:13 +02001024
1025 slot->data.key.bytes = buffer_length;
Steven Cooreman29149862020-08-05 15:43:42 +02001026 return( PSA_SUCCESS );
Steven Cooreman75b74362020-07-28 14:30:13 +02001027}
1028
Steven Cooremanf7cebd42020-10-13 20:27:40 +02001029psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot,
1030 const uint8_t* data,
1031 size_t data_length )
1032{
1033 psa_status_t status = psa_allocate_buffer_to_slot( slot,
1034 data_length );
1035 if( status != PSA_SUCCESS )
1036 return( status );
1037
1038 memcpy( slot->data.key.data, data, data_length );
1039 return( PSA_SUCCESS );
1040}
1041
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001042/** Import key data into a slot.
1043 *
1044 * `slot->type` must have been set previously.
1045 * This function assumes that the slot does not contain any key material yet.
1046 * On failure, the slot content is unchanged.
1047 *
1048 * Persistent storage is not affected.
1049 *
1050 * \param[in,out] slot The key slot to import data into.
1051 * Its `type` field must have previously been set to
1052 * the desired key type.
1053 * It must not contain any key material yet.
1054 * \param[in] data Buffer containing the key material to parse and import.
1055 * \param data_length Size of \p data in bytes.
1056 *
1057 * \retval #PSA_SUCCESS
1058 * \retval #PSA_ERROR_INVALID_ARGUMENT
1059 * \retval #PSA_ERROR_NOT_SUPPORTED
1060 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
1061 */
1062static psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
1063 const uint8_t *data,
1064 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001065{
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001066 psa_status_t status = PSA_SUCCESS;
Steven Cooreman04524762020-10-13 17:43:44 +02001067 size_t bit_size;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001068
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001069 /* zero-length keys are never supported. */
1070 if( data_length == 0 )
1071 return( PSA_ERROR_NOT_SUPPORTED );
1072
Gilles Peskine8e338702019-07-30 20:06:31 +02001073 if( key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001074 {
Steven Cooreman04524762020-10-13 17:43:44 +02001075 bit_size = PSA_BYTES_TO_BITS( data_length );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001076
Steven Cooreman75b74362020-07-28 14:30:13 +02001077 /* Ensure that the bytes-to-bits conversion hasn't overflown. */
1078 if( data_length > SIZE_MAX / 8 )
1079 return( PSA_ERROR_NOT_SUPPORTED );
1080
Gilles Peskine1b9505c2019-08-07 10:59:45 +02001081 /* Enforce a size limit, and in particular ensure that the bit
1082 * size fits in its representation type. */
Gilles Peskinec744d992019-07-30 17:26:54 +02001083 if( bit_size > PSA_MAX_KEY_BITS )
1084 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001085
1086 status = validate_unstructured_key_bit_size( slot->attr.type, bit_size );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +02001087 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02001088 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001089
1090 /* Allocate memory for the key */
Steven Cooremanf7cebd42020-10-13 20:27:40 +02001091 status = psa_copy_key_material_into_slot( slot, data, data_length );
Steven Cooreman75b74362020-07-28 14:30:13 +02001092 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02001093 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001094
Steven Cooreman81be2fa2020-07-24 22:04:59 +02001095 /* Write the actual key size to the slot.
1096 * psa_start_key_creation() wrote the size declared by the
1097 * caller, which may be 0 (meaning unspecified) or wrong. */
1098 slot->attr.bits = (psa_key_bits_t) bit_size;
Steven Cooreman40120f62020-10-29 11:42:22 +01001099
1100 return( PSA_SUCCESS );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001101 }
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001102 else if( PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
Steven Cooreman19fd5742020-07-24 23:31:01 +02001103 {
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001104 /* Try validation through accelerators first. */
1105 bit_size = slot->attr.bits;
1106 psa_key_attributes_t attributes = {
1107 .core = slot->attr
1108 };
1109 status = psa_driver_wrapper_validate_key( &attributes,
1110 data,
1111 data_length,
1112 &bit_size );
1113 if( status == PSA_SUCCESS )
1114 {
1115 /* Key has been validated successfully by an accelerator.
1116 * Copy key material into slot. */
1117 status = psa_copy_key_material_into_slot( slot, data, data_length );
1118 if( status != PSA_SUCCESS )
1119 return( status );
1120
1121 slot->attr.bits = (psa_key_bits_t) bit_size;
1122 return( PSA_SUCCESS );
1123 }
1124 else if( status != PSA_ERROR_NOT_SUPPORTED )
1125 return( status );
1126
1127 /* Key format is not supported by any accelerator, try software fallback
1128 * if present. */
John Durkop9814fa22020-11-04 12:28:15 -08001129#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
1130 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001131 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
1132 {
Steven Cooreman40120f62020-10-29 11:42:22 +01001133 return( psa_import_ecp_key( slot, data, data_length ) );
1134 }
John Durkop9814fa22020-11-04 12:28:15 -08001135#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
1136 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
John Durkop0e005192020-10-31 22:06:54 -07001137#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1138 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Steven Cooreman40120f62020-10-29 11:42:22 +01001139 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001140 {
Steven Cooreman40120f62020-10-29 11:42:22 +01001141 return( psa_import_rsa_key( slot, data, data_length ) );
Steven Cooreman3ea0ce42020-10-23 11:37:05 +02001142 }
John Durkop9814fa22020-11-04 12:28:15 -08001143#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1144 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Steven Cooreman40120f62020-10-29 11:42:22 +01001145
1146 /* Fell through the fallback as well, so have nothing else to try. */
1147 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001148 }
1149 else
Gilles Peskinec66ea6a2018-02-03 22:43:28 +01001150 {
Steven Cooreman19fd5742020-07-24 23:31:01 +02001151 /* Unknown key type */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001152 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969ac722018-01-28 18:16:59 +01001153 }
Darryl Green06fd18d2018-07-16 11:21:11 +01001154}
1155
Gilles Peskinef603c712019-01-19 13:40:11 +01001156/** Calculate the intersection of two algorithm usage policies.
1157 *
1158 * Return 0 (which allows no operation) on incompatibility.
1159 */
1160static psa_algorithm_t psa_key_policy_algorithm_intersection(
1161 psa_algorithm_t alg1,
1162 psa_algorithm_t alg2 )
1163{
Gilles Peskine549ea862019-05-22 11:45:59 +02001164 /* Common case: both sides actually specify the same policy. */
Gilles Peskinef603c712019-01-19 13:40:11 +01001165 if( alg1 == alg2 )
1166 return( alg1 );
1167 /* If the policies are from the same hash-and-sign family, check
1168 * if one is a wildcard. If so the other has the specific algorithm. */
1169 if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) &&
1170 PSA_ALG_IS_HASH_AND_SIGN( alg2 ) &&
1171 ( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
1172 {
1173 if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
1174 return( alg2 );
1175 if( PSA_ALG_SIGN_GET_HASH( alg2 ) == PSA_ALG_ANY_HASH )
1176 return( alg1 );
1177 }
1178 /* If the policies are incompatible, allow nothing. */
1179 return( 0 );
1180}
1181
Gilles Peskined6f371b2019-05-10 19:33:38 +02001182static int psa_key_algorithm_permits( psa_algorithm_t policy_alg,
1183 psa_algorithm_t requested_alg )
1184{
Gilles Peskine549ea862019-05-22 11:45:59 +02001185 /* Common case: the policy only allows requested_alg. */
Gilles Peskined6f371b2019-05-10 19:33:38 +02001186 if( requested_alg == policy_alg )
1187 return( 1 );
1188 /* If policy_alg is a hash-and-sign with a wildcard for the hash,
Gilles Peskine549ea862019-05-22 11:45:59 +02001189 * and requested_alg is the same hash-and-sign family with any hash,
1190 * then requested_alg is compliant with policy_alg. */
Gilles Peskined6f371b2019-05-10 19:33:38 +02001191 if( PSA_ALG_IS_HASH_AND_SIGN( requested_alg ) &&
1192 PSA_ALG_SIGN_GET_HASH( policy_alg ) == PSA_ALG_ANY_HASH )
1193 {
1194 return( ( policy_alg & ~PSA_ALG_HASH_MASK ) ==
1195 ( requested_alg & ~PSA_ALG_HASH_MASK ) );
1196 }
Steven Cooremance48e852020-10-05 16:02:45 +02001197 /* If policy_alg is a generic key agreement operation, then using it for
Steven Cooremanfa5e6312020-10-15 17:07:12 +02001198 * a key derivation with that key agreement should also be allowed. This
1199 * behaviour is expected to be defined in a future specification version. */
Steven Cooremance48e852020-10-05 16:02:45 +02001200 if( PSA_ALG_IS_RAW_KEY_AGREEMENT( policy_alg ) &&
1201 PSA_ALG_IS_KEY_AGREEMENT( requested_alg ) )
1202 {
1203 return( PSA_ALG_KEY_AGREEMENT_GET_BASE( requested_alg ) ==
1204 policy_alg );
1205 }
Gilles Peskined6f371b2019-05-10 19:33:38 +02001206 /* If it isn't permitted, it's forbidden. */
1207 return( 0 );
1208}
1209
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001210/** Test whether a policy permits an algorithm.
1211 *
1212 * The caller must test usage flags separately.
1213 */
1214static int psa_key_policy_permits( const psa_key_policy_t *policy,
1215 psa_algorithm_t alg )
1216{
Gilles Peskined6f371b2019-05-10 19:33:38 +02001217 return( psa_key_algorithm_permits( policy->alg, alg ) ||
1218 psa_key_algorithm_permits( policy->alg2, alg ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001219}
1220
Gilles Peskinef603c712019-01-19 13:40:11 +01001221/** Restrict a key policy based on a constraint.
1222 *
1223 * \param[in,out] policy The policy to restrict.
1224 * \param[in] constraint The policy constraint to apply.
1225 *
1226 * \retval #PSA_SUCCESS
1227 * \c *policy contains the intersection of the original value of
1228 * \c *policy and \c *constraint.
1229 * \retval #PSA_ERROR_INVALID_ARGUMENT
1230 * \c *policy and \c *constraint are incompatible.
1231 * \c *policy is unchanged.
1232 */
1233static psa_status_t psa_restrict_key_policy(
1234 psa_key_policy_t *policy,
1235 const psa_key_policy_t *constraint )
1236{
1237 psa_algorithm_t intersection_alg =
1238 psa_key_policy_algorithm_intersection( policy->alg, constraint->alg );
Gilles Peskined6f371b2019-05-10 19:33:38 +02001239 psa_algorithm_t intersection_alg2 =
1240 psa_key_policy_algorithm_intersection( policy->alg2, constraint->alg2 );
Gilles Peskinef603c712019-01-19 13:40:11 +01001241 if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 )
1242 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined6f371b2019-05-10 19:33:38 +02001243 if( intersection_alg2 == 0 && policy->alg2 != 0 && constraint->alg2 != 0 )
1244 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinef603c712019-01-19 13:40:11 +01001245 policy->usage &= constraint->usage;
1246 policy->alg = intersection_alg;
Gilles Peskined6f371b2019-05-10 19:33:38 +02001247 policy->alg2 = intersection_alg2;
Gilles Peskinef603c712019-01-19 13:40:11 +01001248 return( PSA_SUCCESS );
1249}
1250
Ronald Cron5c522922020-11-14 16:35:34 +01001251/** Get the description of a key given its identifier and policy constraints
1252 * and lock it.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001253 *
Ronald Cron5c522922020-11-14 16:35:34 +01001254 * The key must have allow all the usage flags set in \p usage. If \p alg is
1255 * nonzero, the key must allow operations with this algorithm.
Ronald Cron7587ae42020-11-11 15:04:25 +01001256 *
Ronald Cron5c522922020-11-14 16:35:34 +01001257 * In case of a persistent key, the function loads the description of the key
1258 * into a key slot if not already done.
1259 *
1260 * On success, the returned key slot is locked. It is the responsibility of
1261 * the caller to unlock the key slot when it does not access it anymore.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001262 */
Ronald Cron5c522922020-11-14 16:35:34 +01001263static psa_status_t psa_get_and_lock_key_slot_with_policy(
1264 mbedtls_svc_key_id_t key,
1265 psa_key_slot_t **p_slot,
1266 psa_key_usage_t usage,
1267 psa_algorithm_t alg )
Darryl Green06fd18d2018-07-16 11:21:11 +01001268{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001269 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1270 psa_key_slot_t *slot;
Darryl Green06fd18d2018-07-16 11:21:11 +01001271
Ronald Cron5c522922020-11-14 16:35:34 +01001272 status = psa_get_and_lock_key_slot( key, p_slot );
Darryl Green06fd18d2018-07-16 11:21:11 +01001273 if( status != PSA_SUCCESS )
1274 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001275 slot = *p_slot;
Darryl Green06fd18d2018-07-16 11:21:11 +01001276
1277 /* Enforce that usage policy for the key slot contains all the flags
1278 * required by the usage parameter. There is one exception: public
1279 * keys can always be exported, so we treat public key objects as
1280 * if they had the export flag. */
Gilles Peskine8e338702019-07-30 20:06:31 +02001281 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
Darryl Green06fd18d2018-07-16 11:21:11 +01001282 usage &= ~PSA_KEY_USAGE_EXPORT;
Ronald Cronf95a2b12020-10-22 15:24:49 +02001283
1284 status = PSA_ERROR_NOT_PERMITTED;
Gilles Peskine8e338702019-07-30 20:06:31 +02001285 if( ( slot->attr.policy.usage & usage ) != usage )
Ronald Cronf95a2b12020-10-22 15:24:49 +02001286 goto error;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001287
1288 /* Enforce that the usage policy permits the requested algortihm. */
Gilles Peskine8e338702019-07-30 20:06:31 +02001289 if( alg != 0 && ! psa_key_policy_permits( &slot->attr.policy, alg ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02001290 goto error;
Darryl Green06fd18d2018-07-16 11:21:11 +01001291
Darryl Green06fd18d2018-07-16 11:21:11 +01001292 return( PSA_SUCCESS );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001293
1294error:
1295 *p_slot = NULL;
Ronald Cron5c522922020-11-14 16:35:34 +01001296 psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001297
1298 return( status );
Darryl Green06fd18d2018-07-16 11:21:11 +01001299}
Darryl Green940d72c2018-07-13 13:18:51 +01001300
Ronald Cron5c522922020-11-14 16:35:34 +01001301/** Get a key slot containing a transparent key and lock it.
Gilles Peskine28f8f302019-07-24 13:30:31 +02001302 *
1303 * A transparent key is a key for which the key material is directly
1304 * available, as opposed to a key in a secure element.
1305 *
Ronald Cron5c522922020-11-14 16:35:34 +01001306 * This is a temporary function to use instead of
1307 * psa_get_and_lock_key_slot_with_policy() until secure element support is
1308 * fully implemented.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001309 *
Ronald Cron5c522922020-11-14 16:35:34 +01001310 * On success, the returned key slot is locked. It is the responsibility of the
1311 * caller to unlock the key slot when it does not access it anymore.
Gilles Peskine28f8f302019-07-24 13:30:31 +02001312 */
1313#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Ronald Cron5c522922020-11-14 16:35:34 +01001314static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
1315 mbedtls_svc_key_id_t key,
1316 psa_key_slot_t **p_slot,
1317 psa_key_usage_t usage,
1318 psa_algorithm_t alg )
Gilles Peskine28f8f302019-07-24 13:30:31 +02001319{
Ronald Cron5c522922020-11-14 16:35:34 +01001320 psa_status_t status = psa_get_and_lock_key_slot_with_policy( key, p_slot,
1321 usage, alg );
Gilles Peskine28f8f302019-07-24 13:30:31 +02001322 if( status != PSA_SUCCESS )
1323 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001324
Gilles Peskineadad8132019-07-25 11:31:23 +02001325 if( psa_key_slot_is_external( *p_slot ) )
Gilles Peskine28f8f302019-07-24 13:30:31 +02001326 {
Ronald Cron5c522922020-11-14 16:35:34 +01001327 psa_unlock_key_slot( *p_slot );
Gilles Peskine28f8f302019-07-24 13:30:31 +02001328 *p_slot = NULL;
1329 return( PSA_ERROR_NOT_SUPPORTED );
1330 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02001331
Gilles Peskine28f8f302019-07-24 13:30:31 +02001332 return( PSA_SUCCESS );
1333}
1334#else /* MBEDTLS_PSA_CRYPTO_SE_C */
1335/* With no secure element support, all keys are transparent. */
Ronald Cron5c522922020-11-14 16:35:34 +01001336#define psa_get_and_lock_transparent_key_slot_with_policy( key, p_slot, usage, alg ) \
1337 psa_get_and_lock_key_slot_with_policy( key, p_slot, usage, alg )
Gilles Peskine28f8f302019-07-24 13:30:31 +02001338#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1339
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001340/** Wipe key data from a slot. Preserve metadata such as the policy. */
Gilles Peskine2f060a82018-12-04 17:12:32 +01001341static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
Darryl Green40225ba2018-11-15 14:48:15 +00001342{
Gilles Peskine73167e12019-07-12 23:44:37 +02001343#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Fredrik Strupe462aa572020-12-17 10:44:38 +01001344 if( psa_get_se_driver( slot->attr.lifetime, NULL, NULL ) &&
1345 psa_key_slot_is_external( slot ) )
Darryl Green40225ba2018-11-15 14:48:15 +00001346 {
1347 /* No key material to clean. */
1348 }
Gilles Peskine73167e12019-07-12 23:44:37 +02001349 else
1350#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Darryl Green40225ba2018-11-15 14:48:15 +00001351 {
Steven Cooremanfd4d69a2020-08-05 15:46:33 +02001352 /* Data pointer will always be either a valid pointer or NULL in an
1353 * initialized slot, so we can just free it. */
1354 if( slot->data.key.data != NULL )
1355 mbedtls_platform_zeroize( slot->data.key.data, slot->data.key.bytes);
Steven Cooremana01795d2020-07-24 22:48:15 +02001356 mbedtls_free( slot->data.key.data );
1357 slot->data.key.data = NULL;
1358 slot->data.key.bytes = 0;
Darryl Green40225ba2018-11-15 14:48:15 +00001359 }
Darryl Green40225ba2018-11-15 14:48:15 +00001360
1361 return( PSA_SUCCESS );
1362}
1363
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001364/** Completely wipe a slot in memory, including its policy.
1365 * Persistent storage is not affected. */
Gilles Peskine66fb1262018-12-10 16:29:04 +01001366psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot )
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001367{
1368 psa_status_t status = psa_remove_key_data_from_memory( slot );
Ronald Cronddd3d052020-10-30 14:07:07 +01001369
1370 /*
1371 * As the return error code may not be handled in case of multiple errors,
Ronald Cron5c522922020-11-14 16:35:34 +01001372 * do our best to report an unexpected lock counter: if available
Ronald Cronddd3d052020-10-30 14:07:07 +01001373 * call MBEDTLS_PARAM_FAILED that may terminate execution (if called as
1374 * part of the execution of a test suite this will stop the test suite
Ronald Cron4640c152020-11-13 10:11:01 +01001375 * execution).
Ronald Cronddd3d052020-10-30 14:07:07 +01001376 */
Ronald Cron5c522922020-11-14 16:35:34 +01001377 if( slot->lock_count != 1 )
Ronald Cronddd3d052020-10-30 14:07:07 +01001378 {
1379#ifdef MBEDTLS_CHECK_PARAMS
Ronald Cron5c522922020-11-14 16:35:34 +01001380 MBEDTLS_PARAM_FAILED( slot->lock_count == 1 );
Ronald Cronddd3d052020-10-30 14:07:07 +01001381#endif
Ronald Cronddd3d052020-10-30 14:07:07 +01001382 status = PSA_ERROR_CORRUPTION_DETECTED;
1383 }
1384
Gilles Peskine3f7cd622019-08-13 15:01:08 +02001385 /* Multipart operations may still be using the key. This is safe
1386 * because all multipart operation objects are independent from
1387 * the key slot: if they need to access the key after the setup
1388 * phase, they have a copy of the key. Note that this means that
1389 * key material can linger until all operations are completed. */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001390 /* At this point, key material and other type-specific content has
1391 * been wiped. Clear remaining metadata. We can call memset and not
1392 * zeroize because the metadata is not particularly sensitive. */
1393 memset( slot, 0, sizeof( *slot ) );
1394 return( status );
1395}
1396
Ronald Croncf56a0a2020-08-04 09:51:30 +02001397psa_status_t psa_destroy_key( mbedtls_svc_key_id_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001398{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001399 psa_key_slot_t *slot;
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001400 psa_status_t status; /* status of the last operation */
1401 psa_status_t overall_status = PSA_SUCCESS;
Gilles Peskine354f7672019-07-12 23:46:38 +02001402#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1403 psa_se_drv_table_entry_t *driver;
1404#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001405
Ronald Croncf56a0a2020-08-04 09:51:30 +02001406 if( mbedtls_svc_key_id_is_null( key ) )
Gilles Peskine1841cf42019-10-08 15:48:25 +02001407 return( PSA_SUCCESS );
1408
Ronald Cronf2911112020-10-29 17:51:10 +01001409 /*
Ronald Cron19daca92020-11-10 18:08:03 +01001410 * Get the description of the key in a key slot. In case of a persistent
Ronald Cronf2911112020-10-29 17:51:10 +01001411 * key, this will load the key description from persistent memory if not
1412 * done yet. We cannot avoid this loading as without it we don't know if
1413 * the key is operated by an SE or not and this information is needed by
1414 * the current implementation.
1415 */
Ronald Cron5c522922020-11-14 16:35:34 +01001416 status = psa_get_and_lock_key_slot( key, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001417 if( status != PSA_SUCCESS )
1418 return( status );
Gilles Peskine354f7672019-07-12 23:46:38 +02001419
Ronald Cronf2911112020-10-29 17:51:10 +01001420 /*
1421 * If the key slot containing the key description is under access by the
1422 * library (apart from the present access), the key cannot be destroyed
1423 * yet. For the time being, just return in error. Eventually (to be
1424 * implemented), the key should be destroyed when all accesses have
1425 * stopped.
1426 */
Ronald Cron5c522922020-11-14 16:35:34 +01001427 if( slot->lock_count > 1 )
Ronald Cronf2911112020-10-29 17:51:10 +01001428 {
Ronald Cron5c522922020-11-14 16:35:34 +01001429 psa_unlock_key_slot( slot );
Ronald Cronf2911112020-10-29 17:51:10 +01001430 return( PSA_ERROR_GENERIC_ERROR );
1431 }
1432
Gilles Peskine354f7672019-07-12 23:46:38 +02001433#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001434 driver = psa_get_se_driver_entry( slot->attr.lifetime );
Gilles Peskine354f7672019-07-12 23:46:38 +02001435 if( driver != NULL )
Gilles Peskinefc762652019-07-22 19:30:34 +02001436 {
Gilles Peskine60450a42019-07-25 11:32:45 +02001437 /* For a key in a secure element, we need to do three things:
1438 * remove the key file in internal storage, destroy the
1439 * key inside the secure element, and update the driver's
1440 * persistent data. Start a transaction that will encompass these
1441 * three actions. */
Gilles Peskinefc762652019-07-22 19:30:34 +02001442 psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_DESTROY_KEY );
Gilles Peskine8e338702019-07-30 20:06:31 +02001443 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
Gilles Peskinefc762652019-07-22 19:30:34 +02001444 psa_crypto_transaction.key.slot = slot->data.se.slot_number;
Gilles Peskine8e338702019-07-30 20:06:31 +02001445 psa_crypto_transaction.key.id = slot->attr.id;
Gilles Peskinefc762652019-07-22 19:30:34 +02001446 status = psa_crypto_save_transaction( );
1447 if( status != PSA_SUCCESS )
1448 {
Gilles Peskine66be51c2019-07-25 18:02:52 +02001449 (void) psa_crypto_stop_transaction( );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001450 /* We should still try to destroy the key in the secure
1451 * element and the key metadata in storage. This is especially
1452 * important if the error is that the storage is full.
1453 * But how to do it exactly without risking an inconsistent
1454 * state after a reset?
1455 * https://github.com/ARMmbed/mbed-crypto/issues/215
1456 */
1457 overall_status = status;
1458 goto exit;
Gilles Peskinefc762652019-07-22 19:30:34 +02001459 }
1460
Gilles Peskine354f7672019-07-12 23:46:38 +02001461 status = psa_destroy_se_key( driver, slot->data.se.slot_number );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001462 if( overall_status == PSA_SUCCESS )
1463 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001464 }
Gilles Peskine354f7672019-07-12 23:46:38 +02001465#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1466
Darryl Greend49a4992018-06-18 17:27:26 +01001467#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Ronald Crond98059d2020-10-23 18:00:55 +02001468 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
Darryl Greend49a4992018-06-18 17:27:26 +01001469 {
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001470 status = psa_destroy_persistent_key( slot->attr.id );
1471 if( overall_status == PSA_SUCCESS )
1472 overall_status = status;
1473
Gilles Peskine9ce31c42019-08-13 15:14:20 +02001474 /* TODO: other slots may have a copy of the same key. We should
1475 * invalidate them.
1476 * https://github.com/ARMmbed/mbed-crypto/issues/214
1477 */
Darryl Greend49a4992018-06-18 17:27:26 +01001478 }
1479#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskine354f7672019-07-12 23:46:38 +02001480
Gilles Peskinefc762652019-07-22 19:30:34 +02001481#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1482 if( driver != NULL )
1483 {
Gilles Peskine725f22a2019-07-25 11:31:48 +02001484 status = psa_save_se_persistent_data( driver );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001485 if( overall_status == PSA_SUCCESS )
1486 overall_status = status;
1487 status = psa_crypto_stop_transaction( );
1488 if( overall_status == PSA_SUCCESS )
1489 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001490 }
1491#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1492
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001493#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1494exit:
1495#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001496 status = psa_wipe_key_slot( slot );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001497 /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
1498 if( overall_status == PSA_SUCCESS )
1499 overall_status = status;
1500 return( overall_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001501}
1502
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001503void psa_reset_key_attributes( psa_key_attributes_t *attributes )
Gilles Peskineb870b182018-07-06 16:02:09 +02001504{
Gilles Peskineb699f072019-04-26 16:06:02 +02001505 mbedtls_free( attributes->domain_parameters );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001506 memset( attributes, 0, sizeof( *attributes ) );
Gilles Peskineb870b182018-07-06 16:02:09 +02001507}
1508
Gilles Peskineb699f072019-04-26 16:06:02 +02001509psa_status_t psa_set_key_domain_parameters( psa_key_attributes_t *attributes,
1510 psa_key_type_t type,
1511 const uint8_t *data,
1512 size_t data_length )
1513{
1514 uint8_t *copy = NULL;
1515
1516 if( data_length != 0 )
1517 {
1518 copy = mbedtls_calloc( 1, data_length );
1519 if( copy == NULL )
1520 return( PSA_ERROR_INSUFFICIENT_MEMORY );
1521 memcpy( copy, data, data_length );
1522 }
1523 /* After this point, this function is guaranteed to succeed, so it
1524 * can start modifying `*attributes`. */
1525
1526 if( attributes->domain_parameters != NULL )
1527 {
1528 mbedtls_free( attributes->domain_parameters );
1529 attributes->domain_parameters = NULL;
1530 attributes->domain_parameters_size = 0;
1531 }
1532
1533 attributes->domain_parameters = copy;
1534 attributes->domain_parameters_size = data_length;
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001535 attributes->core.type = type;
Gilles Peskineb699f072019-04-26 16:06:02 +02001536 return( PSA_SUCCESS );
1537}
1538
1539psa_status_t psa_get_key_domain_parameters(
1540 const psa_key_attributes_t *attributes,
1541 uint8_t *data, size_t data_size, size_t *data_length )
1542{
1543 if( attributes->domain_parameters_size > data_size )
1544 return( PSA_ERROR_BUFFER_TOO_SMALL );
1545 *data_length = attributes->domain_parameters_size;
1546 if( attributes->domain_parameters_size != 0 )
1547 memcpy( data, attributes->domain_parameters,
1548 attributes->domain_parameters_size );
1549 return( PSA_SUCCESS );
1550}
1551
John Durkop07cc04a2020-11-16 22:08:34 -08001552#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
John Durkop0e005192020-10-31 22:06:54 -07001553 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskineb699f072019-04-26 16:06:02 +02001554static psa_status_t psa_get_rsa_public_exponent(
1555 const mbedtls_rsa_context *rsa,
1556 psa_key_attributes_t *attributes )
1557{
1558 mbedtls_mpi mpi;
Janos Follath24eed8d2019-11-22 13:21:35 +00001559 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb699f072019-04-26 16:06:02 +02001560 uint8_t *buffer = NULL;
1561 size_t buflen;
1562 mbedtls_mpi_init( &mpi );
1563
1564 ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &mpi );
1565 if( ret != 0 )
1566 goto exit;
Gilles Peskine772c8b12019-04-26 17:37:21 +02001567 if( mbedtls_mpi_cmp_int( &mpi, 65537 ) == 0 )
1568 {
1569 /* It's the default value, which is reported as an empty string,
1570 * so there's nothing to do. */
1571 goto exit;
1572 }
Gilles Peskineb699f072019-04-26 16:06:02 +02001573
1574 buflen = mbedtls_mpi_size( &mpi );
1575 buffer = mbedtls_calloc( 1, buflen );
1576 if( buffer == NULL )
1577 {
1578 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
1579 goto exit;
1580 }
1581 ret = mbedtls_mpi_write_binary( &mpi, buffer, buflen );
1582 if( ret != 0 )
1583 goto exit;
1584 attributes->domain_parameters = buffer;
1585 attributes->domain_parameters_size = buflen;
1586
1587exit:
1588 mbedtls_mpi_free( &mpi );
1589 if( ret != 0 )
1590 mbedtls_free( buffer );
1591 return( mbedtls_to_psa_error( ret ) );
1592}
John Durkop07cc04a2020-11-16 22:08:34 -08001593#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
John Durkop9814fa22020-11-04 12:28:15 -08001594 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineb699f072019-04-26 16:06:02 +02001595
Gilles Peskinebfd322f2019-07-23 11:58:03 +02001596/** Retrieve all the publicly-accessible attributes of a key.
1597 */
Ronald Croncf56a0a2020-08-04 09:51:30 +02001598psa_status_t psa_get_key_attributes( mbedtls_svc_key_id_t key,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001599 psa_key_attributes_t *attributes )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001600{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001601 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001602 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001603 psa_key_slot_t *slot;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001604
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001605 psa_reset_key_attributes( attributes );
1606
Ronald Cron5c522922020-11-14 16:35:34 +01001607 status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001608 if( status != PSA_SUCCESS )
1609 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +02001610
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001611 attributes->core = slot->attr;
Gilles Peskinec8000c02019-08-02 20:15:51 +02001612 attributes->core.flags &= ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1613 MBEDTLS_PSA_KA_MASK_DUAL_USE );
1614
1615#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1616 if( psa_key_slot_is_external( slot ) )
1617 psa_set_key_slot_number( attributes, slot->data.se.slot_number );
1618#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineb699f072019-04-26 16:06:02 +02001619
Gilles Peskine8e338702019-07-30 20:06:31 +02001620 switch( slot->attr.type )
Gilles Peskineb699f072019-04-26 16:06:02 +02001621 {
John Durkop07cc04a2020-11-16 22:08:34 -08001622#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
John Durkop0e005192020-10-31 22:06:54 -07001623 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001624 case PSA_KEY_TYPE_RSA_KEY_PAIR:
Gilles Peskineb699f072019-04-26 16:06:02 +02001625 case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001626#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01001627 /* TODO: reporting the public exponent for opaque keys
Gilles Peskinec9d7f942019-08-13 16:17:16 +02001628 * is not yet implemented.
1629 * https://github.com/ARMmbed/mbed-crypto/issues/216
1630 */
Gilles Peskinec8000c02019-08-02 20:15:51 +02001631 if( psa_key_slot_is_external( slot ) )
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001632 break;
1633#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Steven Cooremana01795d2020-07-24 22:48:15 +02001634 {
Steven Cooremana2371e52020-07-28 14:30:39 +02001635 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02001636
Steven Cooreman4fed4552020-08-03 14:46:03 +02001637 status = psa_load_rsa_representation( slot->attr.type,
1638 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02001639 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02001640 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001641 if( status != PSA_SUCCESS )
1642 break;
1643
Steven Cooremana2371e52020-07-28 14:30:39 +02001644 status = psa_get_rsa_public_exponent( rsa,
Steven Cooremana01795d2020-07-24 22:48:15 +02001645 attributes );
Steven Cooremana2371e52020-07-28 14:30:39 +02001646 mbedtls_rsa_free( rsa );
1647 mbedtls_free( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001648 }
Gilles Peskineb699f072019-04-26 16:06:02 +02001649 break;
John Durkop07cc04a2020-11-16 22:08:34 -08001650#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
John Durkop9814fa22020-11-04 12:28:15 -08001651 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineb699f072019-04-26 16:06:02 +02001652 default:
1653 /* Nothing else to do. */
1654 break;
1655 }
1656
1657 if( status != PSA_SUCCESS )
1658 psa_reset_key_attributes( attributes );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001659
Ronald Cron5c522922020-11-14 16:35:34 +01001660 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001661
Ronald Cron5c522922020-11-14 16:35:34 +01001662 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001663}
1664
Gilles Peskinec8000c02019-08-02 20:15:51 +02001665#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1666psa_status_t psa_get_key_slot_number(
1667 const psa_key_attributes_t *attributes,
1668 psa_key_slot_number_t *slot_number )
1669{
1670 if( attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER )
1671 {
1672 *slot_number = attributes->slot_number;
1673 return( PSA_SUCCESS );
1674 }
1675 else
1676 return( PSA_ERROR_INVALID_ARGUMENT );
1677}
1678#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1679
Steven Cooremana01795d2020-07-24 22:48:15 +02001680static psa_status_t psa_internal_export_key_buffer( const psa_key_slot_t *slot,
1681 uint8_t *data,
1682 size_t data_size,
1683 size_t *data_length )
1684{
1685 if( slot->data.key.bytes > data_size )
1686 return( PSA_ERROR_BUFFER_TOO_SMALL );
1687 memcpy( data, slot->data.key.data, slot->data.key.bytes );
1688 memset( data + slot->data.key.bytes, 0,
1689 data_size - slot->data.key.bytes );
1690 *data_length = slot->data.key.bytes;
1691 return( PSA_SUCCESS );
1692}
1693
Gilles Peskinef603c712019-01-19 13:40:11 +01001694static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot,
1695 uint8_t *data,
1696 size_t data_size,
1697 size_t *data_length,
1698 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001699{
Gilles Peskine5d309672019-07-12 23:47:28 +02001700#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1701 const psa_drv_se_t *drv;
1702 psa_drv_se_context_t *drv_context;
1703#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1704
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001705 *data_length = 0;
1706
Gilles Peskine8e338702019-07-30 20:06:31 +02001707 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001708 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +03001709
Gilles Peskinef9168942019-09-12 19:20:29 +02001710 /* Reject a zero-length output buffer now, since this can never be a
1711 * valid key representation. This way we know that data must be a valid
1712 * pointer and we can do things like memset(data, ..., data_size). */
1713 if( data_size == 0 )
1714 return( PSA_ERROR_BUFFER_TOO_SMALL );
1715
Gilles Peskine5d309672019-07-12 23:47:28 +02001716#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001717 if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
Gilles Peskine5d309672019-07-12 23:47:28 +02001718 {
1719 psa_drv_se_export_key_t method;
1720 if( drv->key_management == NULL )
1721 return( PSA_ERROR_NOT_SUPPORTED );
1722 method = ( export_public_key ?
1723 drv->key_management->p_export_public :
1724 drv->key_management->p_export );
1725 if( method == NULL )
1726 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine2e0f3882019-07-25 11:34:33 +02001727 return( method( drv_context,
1728 slot->data.se.slot_number,
1729 data, data_size, data_length ) );
Gilles Peskine5d309672019-07-12 23:47:28 +02001730 }
1731#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1732
Gilles Peskine8e338702019-07-30 20:06:31 +02001733 if( key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001734 {
Steven Cooremanacda8342020-07-24 23:09:52 +02001735 return( psa_internal_export_key_buffer( slot, data, data_size, data_length ) );
Gilles Peskine188c71e2018-10-29 19:26:02 +01001736 }
Steven Cooreman560c28a2020-07-24 23:20:24 +02001737 else if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ||
1738 PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
Moran Peker17e36e12018-05-02 12:55:20 +03001739 {
Steven Cooreman560c28a2020-07-24 23:20:24 +02001740 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +01001741 {
Steven Cooreman560c28a2020-07-24 23:20:24 +02001742 /* Exporting public -> public */
1743 return( psa_internal_export_key_buffer( slot, data, data_size, data_length ) );
1744 }
1745 else if( !export_public_key )
1746 {
1747 /* Exporting private -> private */
1748 return( psa_internal_export_key_buffer( slot, data, data_size, data_length ) );
1749 }
Steven Cooremanb9b84422020-10-14 14:39:20 +02001750
Steven Cooreman560c28a2020-07-24 23:20:24 +02001751 /* Need to export the public part of a private key,
Steven Cooremanb9b84422020-10-14 14:39:20 +02001752 * so conversion is needed. Try the accelerators first. */
1753 psa_status_t status = psa_driver_wrapper_export_public_key( slot,
1754 data,
1755 data_size,
1756 data_length );
1757
1758 if( status != PSA_ERROR_NOT_SUPPORTED ||
1759 psa_key_lifetime_is_external( slot->attr.lifetime ) )
1760 return( status );
1761
Steven Cooreman560c28a2020-07-24 23:20:24 +02001762 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
1763 {
John Durkop0e005192020-10-31 22:06:54 -07001764#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1765 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Steven Cooremana2371e52020-07-28 14:30:39 +02001766 mbedtls_rsa_context *rsa = NULL;
Steven Cooremanb9b84422020-10-14 14:39:20 +02001767 status = psa_load_rsa_representation(
Steven Cooreman4fed4552020-08-03 14:46:03 +02001768 slot->attr.type,
Steven Cooreman7f391872020-07-30 14:57:44 +02001769 slot->data.key.data,
1770 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02001771 &rsa );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001772 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02001773 return( status );
Steven Cooremana01795d2020-07-24 22:48:15 +02001774
Steven Cooreman560c28a2020-07-24 23:20:24 +02001775 status = psa_export_rsa_key( PSA_KEY_TYPE_RSA_PUBLIC_KEY,
Steven Cooremana2371e52020-07-28 14:30:39 +02001776 rsa,
Steven Cooreman560c28a2020-07-24 23:20:24 +02001777 data,
1778 data_size,
1779 data_length );
Steven Cooremana01795d2020-07-24 22:48:15 +02001780
Steven Cooremana2371e52020-07-28 14:30:39 +02001781 mbedtls_rsa_free( rsa );
1782 mbedtls_free( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02001783
Steven Cooreman560c28a2020-07-24 23:20:24 +02001784 return( status );
Darryl Green9e2d7a02018-07-24 16:33:30 +01001785#else
Steven Cooreman560c28a2020-07-24 23:20:24 +02001786 /* We don't know how to convert a private RSA key to public. */
1787 return( PSA_ERROR_NOT_SUPPORTED );
John Durkop9814fa22020-11-04 12:28:15 -08001788#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
1789 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskine969ac722018-01-28 18:16:59 +01001790 }
1791 else
Moran Pekera998bc62018-04-16 18:16:20 +03001792 {
John Durkop6ba40d12020-11-10 08:50:04 -08001793#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
1794 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Steven Cooremana2371e52020-07-28 14:30:39 +02001795 mbedtls_ecp_keypair *ecp = NULL;
Steven Cooremanb9b84422020-10-14 14:39:20 +02001796 status = psa_load_ecp_representation(
Steven Cooreman4fed4552020-08-03 14:46:03 +02001797 slot->attr.type,
Steven Cooreman7f391872020-07-30 14:57:44 +02001798 slot->data.key.data,
1799 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02001800 &ecp );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001801 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02001802 return( status );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001803
1804 status = psa_export_ecp_key( PSA_KEY_TYPE_ECC_PUBLIC_KEY(
1805 PSA_KEY_TYPE_ECC_GET_FAMILY(
1806 slot->attr.type ) ),
Steven Cooremana2371e52020-07-28 14:30:39 +02001807 ecp,
Steven Cooreman560c28a2020-07-24 23:20:24 +02001808 data,
1809 data_size,
1810 data_length );
1811
Steven Cooremana2371e52020-07-28 14:30:39 +02001812 mbedtls_ecp_keypair_free( ecp );
1813 mbedtls_free( ecp );
Steven Cooreman560c28a2020-07-24 23:20:24 +02001814 return( status );
1815#else
1816 /* We don't know how to convert a private ECC key to public */
Moran Pekera998bc62018-04-16 18:16:20 +03001817 return( PSA_ERROR_NOT_SUPPORTED );
John Durkop9814fa22020-11-04 12:28:15 -08001818#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
1819 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
Moran Pekera998bc62018-04-16 18:16:20 +03001820 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001821 }
Steven Cooreman560c28a2020-07-24 23:20:24 +02001822 else
1823 {
1824 /* This shouldn't happen in the reference implementation, but
1825 it is valid for a special-purpose implementation to omit
1826 support for exporting certain key types. */
1827 return( PSA_ERROR_NOT_SUPPORTED );
1828 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001829}
1830
Ronald Croncf56a0a2020-08-04 09:51:30 +02001831psa_status_t psa_export_key( mbedtls_svc_key_id_t key,
Gilles Peskine2d277862018-06-18 15:41:12 +02001832 uint8_t *data,
1833 size_t data_size,
1834 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001835{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001836 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001837 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001838 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001839
1840 /* Set the key to empty now, so that even when there are errors, we always
1841 * set data_length to a value between 0 and data_size. On error, setting
1842 * the key to empty is a good choice because an empty key representation is
1843 * unlikely to be accepted anywhere. */
1844 *data_length = 0;
1845
1846 /* Export requires the EXPORT flag. There is an exception for public keys,
Ronald Cron5c522922020-11-14 16:35:34 +01001847 * which don't require any flag, but
1848 * psa_get_and_lock_key_slot_with_policy() takes care of this.
1849 */
1850 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
1851 PSA_KEY_USAGE_EXPORT, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001852 if( status != PSA_SUCCESS )
1853 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001854
1855 status = psa_internal_export_key( slot, data, data_size, data_length, 0 );
Ronald Cron5c522922020-11-14 16:35:34 +01001856 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001857
Ronald Cron5c522922020-11-14 16:35:34 +01001858 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001859}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001860
Ronald Croncf56a0a2020-08-04 09:51:30 +02001861psa_status_t psa_export_public_key( mbedtls_svc_key_id_t key,
Gilles Peskine2d277862018-06-18 15:41:12 +02001862 uint8_t *data,
1863 size_t data_size,
1864 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001865{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001866 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001867 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001868 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001869
1870 /* Set the key to empty now, so that even when there are errors, we always
1871 * set data_length to a value between 0 and data_size. On error, setting
1872 * the key to empty is a good choice because an empty key representation is
1873 * unlikely to be accepted anywhere. */
1874 *data_length = 0;
1875
1876 /* Exporting a public key doesn't require a usage flag. */
Ronald Cron5c522922020-11-14 16:35:34 +01001877 status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001878 if( status != PSA_SUCCESS )
1879 return( status );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001880
1881 status = psa_internal_export_key( slot, data, data_size, data_length, 1 );
Ronald Cron5c522922020-11-14 16:35:34 +01001882 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02001883
Ronald Cron5c522922020-11-14 16:35:34 +01001884 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001885}
1886
Gilles Peskine91e8c332019-08-02 19:19:39 +02001887#if defined(static_assert)
1888static_assert( ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
1889 "One or more key attribute flag is listed as both external-only and dual-use" );
Gilles Peskine5a680562019-08-05 17:32:13 +02001890static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
Gilles Peskine094dac12019-08-07 18:19:46 +02001891 "One or more key attribute flag is listed as both internal-only and dual-use" );
Gilles Peskine5a680562019-08-05 17:32:13 +02001892static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ) == 0,
Gilles Peskine91e8c332019-08-02 19:19:39 +02001893 "One or more key attribute flag is listed as both internal-only and external-only" );
1894#endif
1895
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001896/** Validate that a key policy is internally well-formed.
1897 *
1898 * This function only rejects invalid policies. It does not validate the
1899 * consistency of the policy with respect to other attributes of the key
1900 * such as the key type.
1901 */
1902static psa_status_t psa_validate_key_policy( const psa_key_policy_t *policy )
Gilles Peskine4747d192019-04-17 15:05:45 +02001903{
1904 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
Gilles Peskine8e0206a2019-05-14 14:24:28 +02001905 PSA_KEY_USAGE_COPY |
Gilles Peskine4747d192019-04-17 15:05:45 +02001906 PSA_KEY_USAGE_ENCRYPT |
1907 PSA_KEY_USAGE_DECRYPT |
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01001908 PSA_KEY_USAGE_SIGN_HASH |
1909 PSA_KEY_USAGE_VERIFY_HASH |
Gilles Peskine4747d192019-04-17 15:05:45 +02001910 PSA_KEY_USAGE_DERIVE ) ) != 0 )
1911 return( PSA_ERROR_INVALID_ARGUMENT );
1912
Gilles Peskine4747d192019-04-17 15:05:45 +02001913 return( PSA_SUCCESS );
1914}
1915
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001916/** Validate the internal consistency of key attributes.
1917 *
1918 * This function only rejects invalid attribute values. If does not
1919 * validate the consistency of the attributes with any key data that may
1920 * be involved in the creation of the key.
1921 *
1922 * Call this function early in the key creation process.
1923 *
1924 * \param[in] attributes Key attributes for the new key.
1925 * \param[out] p_drv On any return, the driver for the key, if any.
1926 * NULL for a transparent key.
1927 *
1928 */
1929static psa_status_t psa_validate_key_attributes(
1930 const psa_key_attributes_t *attributes,
1931 psa_se_drv_table_entry_t **p_drv )
Darryl Green0c6575a2018-11-07 16:05:30 +00001932{
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001933 psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
Ronald Crond2ed4812020-07-17 16:11:30 +02001934 psa_key_lifetime_t lifetime = psa_get_key_lifetime( attributes );
Ronald Cron65f38a32020-10-23 17:11:13 +02001935 mbedtls_svc_key_id_t key = psa_get_key_id( attributes );
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001936
Ronald Cron54b90082020-10-29 15:26:43 +01001937 status = psa_validate_key_location( lifetime, p_drv );
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001938 if( status != PSA_SUCCESS )
1939 return( status );
1940
Ronald Crond2ed4812020-07-17 16:11:30 +02001941 status = psa_validate_key_persistence( lifetime );
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001942 if( status != PSA_SUCCESS )
1943 return( status );
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001944
Ronald Cron65f38a32020-10-23 17:11:13 +02001945 if ( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) )
1946 {
1947 if( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key ) != 0 )
1948 return( PSA_ERROR_INVALID_ARGUMENT );
1949 }
1950 else
Ronald Crond2ed4812020-07-17 16:11:30 +02001951 {
Ronald Croncbd7bea2020-11-11 14:57:44 +01001952 status = psa_validate_key_id( psa_get_key_id( attributes ), 0 );
Ronald Crond2ed4812020-07-17 16:11:30 +02001953 if( status != PSA_SUCCESS )
1954 return( status );
1955 }
1956
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001957 status = psa_validate_key_policy( &attributes->core.policy );
Darryl Green0c6575a2018-11-07 16:05:30 +00001958 if( status != PSA_SUCCESS )
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001959 return( status );
1960
1961 /* Refuse to create overly large keys.
1962 * Note that this doesn't trigger on import if the attributes don't
1963 * explicitly specify a size (so psa_get_key_bits returns 0), so
1964 * psa_import_key() needs its own checks. */
1965 if( psa_get_key_bits( attributes ) > PSA_MAX_KEY_BITS )
1966 return( PSA_ERROR_NOT_SUPPORTED );
1967
Gilles Peskine91e8c332019-08-02 19:19:39 +02001968 /* Reject invalid flags. These should not be reachable through the API. */
1969 if( attributes->core.flags & ~ ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1970 MBEDTLS_PSA_KA_MASK_DUAL_USE ) )
1971 return( PSA_ERROR_INVALID_ARGUMENT );
1972
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001973 return( PSA_SUCCESS );
1974}
1975
Gilles Peskine4747d192019-04-17 15:05:45 +02001976/** Prepare a key slot to receive key material.
1977 *
1978 * This function allocates a key slot and sets its metadata.
1979 *
1980 * If this function fails, call psa_fail_key_creation().
1981 *
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001982 * This function is intended to be used as follows:
1983 * -# Call psa_start_key_creation() to allocate a key slot, prepare
Ronald Croncf56a0a2020-08-04 09:51:30 +02001984 * it with the specified attributes, and in case of a volatile key assign it
1985 * a volatile key identifier.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001986 * -# Populate the slot with the key material.
1987 * -# Call psa_finish_key_creation() to finalize the creation of the slot.
1988 * In case of failure at any step, stop the sequence and call
1989 * psa_fail_key_creation().
1990 *
Ronald Cron5c522922020-11-14 16:35:34 +01001991 * On success, the key slot is locked. It is the responsibility of the caller
1992 * to unlock the key slot when it does not access it anymore.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001993 *
Gilles Peskinedf179142019-07-15 22:02:14 +02001994 * \param method An identification of the calling function.
Gilles Peskine011e4282019-06-26 18:34:38 +02001995 * \param[in] attributes Key attributes for the new key.
Gilles Peskine011e4282019-06-26 18:34:38 +02001996 * \param[out] p_slot On success, a pointer to the prepared slot.
1997 * \param[out] p_drv On any return, the driver for the key, if any.
1998 * NULL for a transparent key.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001999 *
2000 * \retval #PSA_SUCCESS
2001 * The key slot is ready to receive key material.
2002 * \return If this function fails, the key slot is an invalid state.
2003 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02002004 */
2005static psa_status_t psa_start_key_creation(
Gilles Peskinedf179142019-07-15 22:02:14 +02002006 psa_key_creation_method_t method,
Gilles Peskine4747d192019-04-17 15:05:45 +02002007 const psa_key_attributes_t *attributes,
Gilles Peskine011e4282019-06-26 18:34:38 +02002008 psa_key_slot_t **p_slot,
Gilles Peskine8abe6a22019-07-12 23:40:35 +02002009 psa_se_drv_table_entry_t **p_drv )
Gilles Peskine4747d192019-04-17 15:05:45 +02002010{
2011 psa_status_t status;
Ronald Cron2a993152020-07-17 14:13:26 +02002012 psa_key_id_t volatile_key_id;
Gilles Peskine4747d192019-04-17 15:05:45 +02002013 psa_key_slot_t *slot;
2014
Gilles Peskinedf179142019-07-15 22:02:14 +02002015 (void) method;
Gilles Peskine011e4282019-06-26 18:34:38 +02002016 *p_drv = NULL;
2017
Gilles Peskine1b8594a2019-07-31 17:21:46 +02002018 status = psa_validate_key_attributes( attributes, p_drv );
2019 if( status != PSA_SUCCESS )
2020 return( status );
2021
Ronald Cronc4d1b512020-07-31 11:26:37 +02002022 status = psa_get_empty_key_slot( &volatile_key_id, p_slot );
Gilles Peskine4747d192019-04-17 15:05:45 +02002023 if( status != PSA_SUCCESS )
2024 return( status );
2025 slot = *p_slot;
2026
Gilles Peskine76aa09c2019-07-31 14:15:34 +02002027 /* We're storing the declared bit-size of the key. It's up to each
2028 * creation mechanism to verify that this information is correct.
2029 * It's automatically correct for mechanisms that use the bit-size as
Gilles Peskineb46bef22019-07-30 21:32:04 +02002030 * an input (generate, device) but not for those where the bit-size
Ronald Cronc4d1b512020-07-31 11:26:37 +02002031 * is optional (import, copy). In case of a volatile key, assign it the
2032 * volatile key identifier associated to the slot returned to contain its
2033 * definition. */
Gilles Peskine76aa09c2019-07-31 14:15:34 +02002034
2035 slot->attr = attributes->core;
Ronald Cronc4d1b512020-07-31 11:26:37 +02002036 if( PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
2037 {
2038#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
2039 slot->attr.id = volatile_key_id;
2040#else
2041 slot->attr.id.key_id = volatile_key_id;
2042#endif
2043 }
Gilles Peskinec744d992019-07-30 17:26:54 +02002044
Gilles Peskine91e8c332019-08-02 19:19:39 +02002045 /* Erase external-only flags from the internal copy. To access
Gilles Peskine013f5472019-08-07 15:42:14 +02002046 * external-only flags, query `attributes`. Thanks to the check
2047 * in psa_validate_key_attributes(), this leaves the dual-use
Gilles Peskineedbed562019-08-07 18:19:59 +02002048 * flags and any internal flag that psa_get_empty_key_slot()
Gilles Peskine013f5472019-08-07 15:42:14 +02002049 * may have set. */
2050 slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
Gilles Peskine91e8c332019-08-02 19:19:39 +02002051
Gilles Peskinecbaff462019-07-12 23:46:04 +02002052#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02002053 /* For a key in a secure element, we need to do three things
Steven Cooremanbbeaf182020-06-08 18:29:44 +02002054 * when creating or registering a persistent key:
Gilles Peskine60450a42019-07-25 11:32:45 +02002055 * create the key file in internal storage, create the
2056 * key inside the secure element, and update the driver's
Steven Cooremanbbeaf182020-06-08 18:29:44 +02002057 * persistent data. This is done by starting a transaction that will
2058 * encompass these three actions.
2059 * For registering a volatile key, we just need to find an appropriate
2060 * slot number inside the SE. Since the key is designated volatile, creating
2061 * a transaction is not required. */
Gilles Peskine60450a42019-07-25 11:32:45 +02002062 /* The first thing to do is to find a slot number for the new key.
2063 * We save the slot number in persistent storage as part of the
2064 * transaction data. It will be needed to recover if the power
2065 * fails during the key creation process, to clean up on the secure
2066 * element side after restarting. Obtaining a slot number from the
2067 * secure element driver updates its persistent state, but we do not yet
2068 * save the driver's persistent state, so that if the power fails,
Gilles Peskinefc762652019-07-22 19:30:34 +02002069 * we can roll back to a state where the key doesn't exist. */
Gilles Peskine3efcebb2019-10-01 14:18:35 +02002070 if( *p_drv != NULL )
Darryl Green0c6575a2018-11-07 16:05:30 +00002071 {
Gilles Peskinee88c2c12019-08-05 16:44:14 +02002072 status = psa_find_se_slot_for_key( attributes, method, *p_drv,
Gilles Peskinecbaff462019-07-12 23:46:04 +02002073 &slot->data.se.slot_number );
2074 if( status != PSA_SUCCESS )
2075 return( status );
Steven Cooremanbbeaf182020-06-08 18:29:44 +02002076
2077 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( attributes->core.lifetime ) )
Gilles Peskine66be51c2019-07-25 18:02:52 +02002078 {
Steven Cooremanbbeaf182020-06-08 18:29:44 +02002079 psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_CREATE_KEY );
2080 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
2081 psa_crypto_transaction.key.slot = slot->data.se.slot_number;
2082 psa_crypto_transaction.key.id = slot->attr.id;
2083 status = psa_crypto_save_transaction( );
2084 if( status != PSA_SUCCESS )
2085 {
2086 (void) psa_crypto_stop_transaction( );
2087 return( status );
2088 }
Gilles Peskine66be51c2019-07-25 18:02:52 +02002089 }
Darryl Green0c6575a2018-11-07 16:05:30 +00002090 }
Gilles Peskine3efcebb2019-10-01 14:18:35 +02002091
2092 if( *p_drv == NULL && method == PSA_KEY_CREATION_REGISTER )
2093 {
2094 /* Key registration only makes sense with a secure element. */
2095 return( PSA_ERROR_INVALID_ARGUMENT );
2096 }
Gilles Peskinecbaff462019-07-12 23:46:04 +02002097#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2098
Ronald Cronc4d1b512020-07-31 11:26:37 +02002099 return( PSA_SUCCESS );
Darryl Green0c6575a2018-11-07 16:05:30 +00002100}
Gilles Peskine4747d192019-04-17 15:05:45 +02002101
2102/** Finalize the creation of a key once its key material has been set.
2103 *
2104 * This entails writing the key to persistent storage.
2105 *
2106 * If this function fails, call psa_fail_key_creation().
Gilles Peskine9bc88c62019-04-28 11:37:03 +02002107 * See the documentation of psa_start_key_creation() for the intended use
2108 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02002109 *
Ronald Cron5c522922020-11-14 16:35:34 +01002110 * If the finalization succeeds, the function unlocks the key slot (it was
2111 * locked by psa_start_key_creation()) and the key slot cannot be accessed
2112 * anymore as part of the key creation process.
Ronald Cron50972942020-11-14 11:28:25 +01002113 *
Gilles Peskine011e4282019-06-26 18:34:38 +02002114 * \param[in,out] slot Pointer to the slot with key material.
2115 * \param[in] driver The secure element driver for the key,
2116 * or NULL for a transparent key.
Ronald Cron81709fc2020-11-14 12:10:32 +01002117 * \param[out] key On success, identifier of the key. Note that the
2118 * key identifier is also stored in the key slot.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02002119 *
2120 * \retval #PSA_SUCCESS
Ronald Croncf56a0a2020-08-04 09:51:30 +02002121 * The key was successfully created.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02002122 * \return If this function fails, the key slot is an invalid state.
2123 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02002124 */
Gilles Peskine011e4282019-06-26 18:34:38 +02002125static psa_status_t psa_finish_key_creation(
2126 psa_key_slot_t *slot,
Ronald Cron81709fc2020-11-14 12:10:32 +01002127 psa_se_drv_table_entry_t *driver,
2128 mbedtls_svc_key_id_t *key)
Gilles Peskine4747d192019-04-17 15:05:45 +02002129{
2130 psa_status_t status = PSA_SUCCESS;
Gilles Peskine30afafd2019-04-25 13:47:40 +02002131 (void) slot;
Gilles Peskine011e4282019-06-26 18:34:38 +02002132 (void) driver;
Gilles Peskine4747d192019-04-17 15:05:45 +02002133
2134#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Steven Cooremanc59de6a2020-06-08 18:28:25 +02002135 if( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
Gilles Peskine4747d192019-04-17 15:05:45 +02002136 {
Gilles Peskine1df83d42019-07-23 16:13:14 +02002137#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2138 if( driver != NULL )
2139 {
Gilles Peskineb46bef22019-07-30 21:32:04 +02002140 psa_se_key_data_storage_t data;
2141#if defined(static_assert)
2142 static_assert( sizeof( slot->data.se.slot_number ) ==
2143 sizeof( data.slot_number ),
2144 "Slot number size does not match psa_se_key_data_storage_t" );
Gilles Peskineb46bef22019-07-30 21:32:04 +02002145#endif
2146 memcpy( &data.slot_number, &slot->data.se.slot_number,
2147 sizeof( slot->data.se.slot_number ) );
Gilles Peskine76aa09c2019-07-31 14:15:34 +02002148 status = psa_save_persistent_key( &slot->attr,
Gilles Peskineb46bef22019-07-30 21:32:04 +02002149 (uint8_t*) &data,
2150 sizeof( data ) );
Gilles Peskine1df83d42019-07-23 16:13:14 +02002151 }
2152 else
2153#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2154 {
Steven Cooreman40120f62020-10-29 11:42:22 +01002155 /* Key material is saved in export representation in the slot, so
2156 * just pass the slot buffer for storage. */
2157 status = psa_save_persistent_key( &slot->attr,
2158 slot->data.key.data,
2159 slot->data.key.bytes );
Gilles Peskine1df83d42019-07-23 16:13:14 +02002160 }
Gilles Peskine4747d192019-04-17 15:05:45 +02002161 }
Darryl Green0c6575a2018-11-07 16:05:30 +00002162#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
2163
Gilles Peskinecbaff462019-07-12 23:46:04 +02002164#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02002165 /* Finish the transaction for a key creation. This does not
2166 * happen when registering an existing key. Detect this case
2167 * by checking whether a transaction is in progress (actual
Steven Cooremanbbeaf182020-06-08 18:29:44 +02002168 * creation of a persistent key in a secure element requires a transaction,
2169 * but registration or volatile key creation doesn't use one). */
Gilles Peskined7729582019-08-05 15:55:54 +02002170 if( driver != NULL &&
2171 psa_crypto_transaction.unknown.type == PSA_CRYPTO_TRANSACTION_CREATE_KEY )
Gilles Peskinecbaff462019-07-12 23:46:04 +02002172 {
2173 status = psa_save_se_persistent_data( driver );
2174 if( status != PSA_SUCCESS )
2175 {
Gilles Peskine8e338702019-07-30 20:06:31 +02002176 psa_destroy_persistent_key( slot->attr.id );
Gilles Peskinecbaff462019-07-12 23:46:04 +02002177 return( status );
2178 }
Gilles Peskinefc762652019-07-22 19:30:34 +02002179 status = psa_crypto_stop_transaction( );
Gilles Peskinecbaff462019-07-12 23:46:04 +02002180 }
2181#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2182
Ronald Cron50972942020-11-14 11:28:25 +01002183 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01002184 {
2185 *key = slot->attr.id;
Ronald Cron5c522922020-11-14 16:35:34 +01002186 status = psa_unlock_key_slot( slot );
Ronald Cron81709fc2020-11-14 12:10:32 +01002187 if( status != PSA_SUCCESS )
2188 *key = MBEDTLS_SVC_KEY_ID_INIT;
2189 }
Ronald Cron50972942020-11-14 11:28:25 +01002190
Gilles Peskine4747d192019-04-17 15:05:45 +02002191 return( status );
2192}
2193
2194/** Abort the creation of a key.
2195 *
2196 * You may call this function after calling psa_start_key_creation(),
2197 * or after psa_finish_key_creation() fails. In other circumstances, this
2198 * function may not clean up persistent storage.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02002199 * See the documentation of psa_start_key_creation() for the intended use
2200 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02002201 *
Gilles Peskine011e4282019-06-26 18:34:38 +02002202 * \param[in,out] slot Pointer to the slot with key material.
2203 * \param[in] driver The secure element driver for the key,
2204 * or NULL for a transparent key.
Gilles Peskine4747d192019-04-17 15:05:45 +02002205 */
Gilles Peskine011e4282019-06-26 18:34:38 +02002206static void psa_fail_key_creation( psa_key_slot_t *slot,
Gilles Peskine8abe6a22019-07-12 23:40:35 +02002207 psa_se_drv_table_entry_t *driver )
Gilles Peskine4747d192019-04-17 15:05:45 +02002208{
Gilles Peskine011e4282019-06-26 18:34:38 +02002209 (void) driver;
2210
Gilles Peskine4747d192019-04-17 15:05:45 +02002211 if( slot == NULL )
2212 return;
Gilles Peskine011e4282019-06-26 18:34:38 +02002213
2214#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01002215 /* TODO: If the key has already been created in the secure
Gilles Peskine011e4282019-06-26 18:34:38 +02002216 * element, and the failure happened later (when saving metadata
2217 * to internal storage), we need to destroy the key in the secure
Gilles Peskinec9d7f942019-08-13 16:17:16 +02002218 * element.
2219 * https://github.com/ARMmbed/mbed-crypto/issues/217
2220 */
Gilles Peskinefc762652019-07-22 19:30:34 +02002221
Gilles Peskined7729582019-08-05 15:55:54 +02002222 /* Abort the ongoing transaction if any (there may not be one if
2223 * the creation process failed before starting one, or if the
2224 * key creation is a registration of a key in a secure element).
2225 * Earlier functions must already have done what it takes to undo any
2226 * partial creation. All that's left is to update the transaction data
2227 * itself. */
Gilles Peskinefc762652019-07-22 19:30:34 +02002228 (void) psa_crypto_stop_transaction( );
Gilles Peskine011e4282019-06-26 18:34:38 +02002229#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2230
Gilles Peskine4747d192019-04-17 15:05:45 +02002231 psa_wipe_key_slot( slot );
2232}
2233
Gilles Peskine1b8594a2019-07-31 17:21:46 +02002234/** Validate optional attributes during key creation.
2235 *
2236 * Some key attributes are optional during key creation. If they are
2237 * specified in the attributes structure, check that they are consistent
2238 * with the data in the slot.
2239 *
2240 * This function should be called near the end of key creation, after
2241 * the slot in memory is fully populated but before saving persistent data.
2242 */
2243static psa_status_t psa_validate_optional_attributes(
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002244 const psa_key_slot_t *slot,
2245 const psa_key_attributes_t *attributes )
2246{
Gilles Peskine7e0cff92019-07-30 13:48:52 +02002247 if( attributes->core.type != 0 )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002248 {
Gilles Peskine8e338702019-07-30 20:06:31 +02002249 if( attributes->core.type != slot->attr.type )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002250 return( PSA_ERROR_INVALID_ARGUMENT );
2251 }
2252
2253 if( attributes->domain_parameters_size != 0 )
2254 {
John Durkop0e005192020-10-31 22:06:54 -07002255#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
2256 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskine8e338702019-07-30 20:06:31 +02002257 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002258 {
Steven Cooremana2371e52020-07-28 14:30:39 +02002259 mbedtls_rsa_context *rsa = NULL;
Steven Cooreman75b74362020-07-28 14:30:13 +02002260 mbedtls_mpi actual, required;
Steven Cooreman6d839f02020-07-30 11:36:45 +02002261 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooremana01795d2020-07-24 22:48:15 +02002262
Steven Cooreman7f391872020-07-30 14:57:44 +02002263 psa_status_t status = psa_load_rsa_representation(
Steven Cooreman4fed4552020-08-03 14:46:03 +02002264 slot->attr.type,
Steven Cooreman7f391872020-07-30 14:57:44 +02002265 slot->data.key.data,
2266 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02002267 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02002268 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02002269 return( status );
Steven Cooreman75b74362020-07-28 14:30:13 +02002270
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002271 mbedtls_mpi_init( &actual );
2272 mbedtls_mpi_init( &required );
Steven Cooremana2371e52020-07-28 14:30:39 +02002273 ret = mbedtls_rsa_export( rsa,
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002274 NULL, NULL, NULL, NULL, &actual );
Steven Cooremana2371e52020-07-28 14:30:39 +02002275 mbedtls_rsa_free( rsa );
2276 mbedtls_free( rsa );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002277 if( ret != 0 )
2278 goto rsa_exit;
2279 ret = mbedtls_mpi_read_binary( &required,
2280 attributes->domain_parameters,
2281 attributes->domain_parameters_size );
2282 if( ret != 0 )
2283 goto rsa_exit;
2284 if( mbedtls_mpi_cmp_mpi( &actual, &required ) != 0 )
2285 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2286 rsa_exit:
2287 mbedtls_mpi_free( &actual );
2288 mbedtls_mpi_free( &required );
2289 if( ret != 0)
2290 return( mbedtls_to_psa_error( ret ) );
2291 }
2292 else
John Durkop9814fa22020-11-04 12:28:15 -08002293#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
2294 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002295 {
2296 return( PSA_ERROR_INVALID_ARGUMENT );
2297 }
2298 }
2299
Gilles Peskine7e0cff92019-07-30 13:48:52 +02002300 if( attributes->core.bits != 0 )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002301 {
Gilles Peskineb46bef22019-07-30 21:32:04 +02002302 if( attributes->core.bits != slot->attr.bits )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002303 return( PSA_ERROR_INVALID_ARGUMENT );
2304 }
2305
2306 return( PSA_SUCCESS );
2307}
2308
Gilles Peskine4747d192019-04-17 15:05:45 +02002309psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
Gilles Peskine4747d192019-04-17 15:05:45 +02002310 const uint8_t *data,
Gilles Peskine73676cb2019-05-15 20:15:10 +02002311 size_t data_length,
Ronald Croncf56a0a2020-08-04 09:51:30 +02002312 mbedtls_svc_key_id_t *key )
Gilles Peskine4747d192019-04-17 15:05:45 +02002313{
2314 psa_status_t status;
2315 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02002316 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002317
Ronald Cron81709fc2020-11-14 12:10:32 +01002318 *key = MBEDTLS_SVC_KEY_ID_INIT;
2319
Gilles Peskine0f84d622019-09-12 19:03:13 +02002320 /* Reject zero-length symmetric keys (including raw data key objects).
2321 * This also rejects any key which might be encoded as an empty string,
2322 * which is never valid. */
2323 if( data_length == 0 )
2324 return( PSA_ERROR_INVALID_ARGUMENT );
2325
Gilles Peskinedf179142019-07-15 22:02:14 +02002326 status = psa_start_key_creation( PSA_KEY_CREATION_IMPORT, attributes,
Ronald Cron81709fc2020-11-14 12:10:32 +01002327 &slot, &driver );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002328 if( status != PSA_SUCCESS )
2329 goto exit;
2330
Gilles Peskine5d309672019-07-12 23:47:28 +02002331#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2332 if( driver != NULL )
2333 {
2334 const psa_drv_se_t *drv = psa_get_se_driver_methods( driver );
Darryl Green0892d0f2019-08-20 09:50:14 +01002335 /* The driver should set the number of key bits, however in
2336 * case it doesn't, we initialize bits to an invalid value. */
2337 size_t bits = PSA_MAX_KEY_BITS + 1;
Gilles Peskine5d309672019-07-12 23:47:28 +02002338 if( drv->key_management == NULL ||
2339 drv->key_management->p_import == NULL )
2340 {
2341 status = PSA_ERROR_NOT_SUPPORTED;
2342 goto exit;
2343 }
2344 status = drv->key_management->p_import(
2345 psa_get_se_driver_context( driver ),
Gilles Peskinef3801ff2019-08-06 17:32:04 +02002346 slot->data.se.slot_number, attributes, data, data_length,
Gilles Peskineb46bef22019-07-30 21:32:04 +02002347 &bits );
2348 if( status != PSA_SUCCESS )
2349 goto exit;
2350 if( bits > PSA_MAX_KEY_BITS )
2351 {
2352 status = PSA_ERROR_NOT_SUPPORTED;
2353 goto exit;
2354 }
2355 slot->attr.bits = (psa_key_bits_t) bits;
Gilles Peskine5d309672019-07-12 23:47:28 +02002356 }
2357 else
2358#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2359 {
2360 status = psa_import_key_into_slot( slot, data, data_length );
2361 if( status != PSA_SUCCESS )
2362 goto exit;
Gilles Peskine5d309672019-07-12 23:47:28 +02002363 }
Gilles Peskine1b8594a2019-07-31 17:21:46 +02002364 status = psa_validate_optional_attributes( slot, attributes );
Gilles Peskine18017402019-07-24 20:25:59 +02002365 if( status != PSA_SUCCESS )
2366 goto exit;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002367
Ronald Cron81709fc2020-11-14 12:10:32 +01002368 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002369exit:
Gilles Peskine4747d192019-04-17 15:05:45 +02002370 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02002371 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002372
Gilles Peskine4747d192019-04-17 15:05:45 +02002373 return( status );
2374}
2375
Gilles Peskined7729582019-08-05 15:55:54 +02002376#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2377psa_status_t mbedtls_psa_register_se_key(
2378 const psa_key_attributes_t *attributes )
2379{
2380 psa_status_t status;
2381 psa_key_slot_t *slot = NULL;
2382 psa_se_drv_table_entry_t *driver = NULL;
Ronald Croncf56a0a2020-08-04 09:51:30 +02002383 mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
Gilles Peskined7729582019-08-05 15:55:54 +02002384
2385 /* Leaving attributes unspecified is not currently supported.
2386 * It could make sense to query the key type and size from the
2387 * secure element, but not all secure elements support this
2388 * and the driver HAL doesn't currently support it. */
2389 if( psa_get_key_type( attributes ) == PSA_KEY_TYPE_NONE )
2390 return( PSA_ERROR_NOT_SUPPORTED );
2391 if( psa_get_key_bits( attributes ) == 0 )
2392 return( PSA_ERROR_NOT_SUPPORTED );
2393
2394 status = psa_start_key_creation( PSA_KEY_CREATION_REGISTER, attributes,
Ronald Cron81709fc2020-11-14 12:10:32 +01002395 &slot, &driver );
Gilles Peskined7729582019-08-05 15:55:54 +02002396 if( status != PSA_SUCCESS )
2397 goto exit;
2398
Ronald Cron81709fc2020-11-14 12:10:32 +01002399 status = psa_finish_key_creation( slot, driver, &key );
Gilles Peskined7729582019-08-05 15:55:54 +02002400
2401exit:
2402 if( status != PSA_SUCCESS )
Gilles Peskined7729582019-08-05 15:55:54 +02002403 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002404
Gilles Peskined7729582019-08-05 15:55:54 +02002405 /* Registration doesn't keep the key in RAM. */
Ronald Croncf56a0a2020-08-04 09:51:30 +02002406 psa_close_key( key );
Gilles Peskined7729582019-08-05 15:55:54 +02002407 return( status );
2408}
2409#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
2410
Gilles Peskinef603c712019-01-19 13:40:11 +01002411static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002412 psa_key_slot_t *target )
Gilles Peskinef603c712019-01-19 13:40:11 +01002413{
Steven Cooremanf7cebd42020-10-13 20:27:40 +02002414 psa_status_t status = psa_copy_key_material_into_slot( target,
2415 source->data.key.data,
2416 source->data.key.bytes );
Gilles Peskinef603c712019-01-19 13:40:11 +01002417 if( status != PSA_SUCCESS )
Steven Cooreman398aee52020-10-13 14:35:45 +02002418 return( status );
Gilles Peskinef603c712019-01-19 13:40:11 +01002419
Steven Cooreman398aee52020-10-13 14:35:45 +02002420 target->attr.type = source->attr.type;
2421 target->attr.bits = source->attr.bits;
2422
2423 return( PSA_SUCCESS );
Gilles Peskinef603c712019-01-19 13:40:11 +01002424}
2425
Ronald Croncf56a0a2020-08-04 09:51:30 +02002426psa_status_t psa_copy_key( mbedtls_svc_key_id_t source_key,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002427 const psa_key_attributes_t *specified_attributes,
Ronald Croncf56a0a2020-08-04 09:51:30 +02002428 mbedtls_svc_key_id_t *target_key )
Gilles Peskinef603c712019-01-19 13:40:11 +01002429{
Ronald Cronf95a2b12020-10-22 15:24:49 +02002430 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01002431 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskinef603c712019-01-19 13:40:11 +01002432 psa_key_slot_t *source_slot = NULL;
2433 psa_key_slot_t *target_slot = NULL;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002434 psa_key_attributes_t actual_attributes = *specified_attributes;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02002435 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskinef603c712019-01-19 13:40:11 +01002436
Ronald Cron81709fc2020-11-14 12:10:32 +01002437 *target_key = MBEDTLS_SVC_KEY_ID_INIT;
2438
Ronald Cron5c522922020-11-14 16:35:34 +01002439 status = psa_get_and_lock_transparent_key_slot_with_policy(
2440 source_key, &source_slot, PSA_KEY_USAGE_COPY, 0 );
Gilles Peskinef603c712019-01-19 13:40:11 +01002441 if( status != PSA_SUCCESS )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002442 goto exit;
2443
Gilles Peskine1b8594a2019-07-31 17:21:46 +02002444 status = psa_validate_optional_attributes( source_slot,
2445 specified_attributes );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002446 if( status != PSA_SUCCESS )
2447 goto exit;
2448
Gilles Peskine7e0cff92019-07-30 13:48:52 +02002449 status = psa_restrict_key_policy( &actual_attributes.core.policy,
Gilles Peskine8e338702019-07-30 20:06:31 +02002450 &source_slot->attr.policy );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002451 if( status != PSA_SUCCESS )
2452 goto exit;
2453
Ronald Cron81709fc2020-11-14 12:10:32 +01002454 status = psa_start_key_creation( PSA_KEY_CREATION_COPY, &actual_attributes,
2455 &target_slot, &driver );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002456 if( status != PSA_SUCCESS )
2457 goto exit;
2458
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002459#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2460 if( driver != NULL )
Gilles Peskinef603c712019-01-19 13:40:11 +01002461 {
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002462 /* Copying to a secure element is not implemented yet. */
2463 status = PSA_ERROR_NOT_SUPPORTED;
2464 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01002465 }
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002466#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinef603c712019-01-19 13:40:11 +01002467
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002468 status = psa_copy_key_material( source_slot, target_slot );
Gilles Peskinef603c712019-01-19 13:40:11 +01002469 if( status != PSA_SUCCESS )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002470 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01002471
Ronald Cron81709fc2020-11-14 12:10:32 +01002472 status = psa_finish_key_creation( target_slot, driver, target_key );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002473exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002474 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02002475 psa_fail_key_creation( target_slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002476
Ronald Cron5c522922020-11-14 16:35:34 +01002477 unlock_status = psa_unlock_key_slot( source_slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02002478
Ronald Cron5c522922020-11-14 16:35:34 +01002479 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskinef603c712019-01-19 13:40:11 +01002480}
2481
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002482
2483
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002484/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01002485/* Message digests */
2486/****************************************************************/
2487
John Durkop07cc04a2020-11-16 22:08:34 -08002488#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
John Durkop0e005192020-10-31 22:06:54 -07002489 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
2490 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
John Durkop9814fa22020-11-04 12:28:15 -08002491 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinedc2fc842018-03-07 16:42:59 +01002492static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01002493{
2494 switch( alg )
2495 {
John Durkopee4e6602020-11-27 08:48:46 -08002496#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine20035e32018-02-03 22:44:14 +01002497 case PSA_ALG_MD2:
2498 return( &mbedtls_md2_info );
2499#endif
John Durkopee4e6602020-11-27 08:48:46 -08002500#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine20035e32018-02-03 22:44:14 +01002501 case PSA_ALG_MD4:
2502 return( &mbedtls_md4_info );
2503#endif
John Durkopee4e6602020-11-27 08:48:46 -08002504#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine20035e32018-02-03 22:44:14 +01002505 case PSA_ALG_MD5:
2506 return( &mbedtls_md5_info );
2507#endif
John Durkopee4e6602020-11-27 08:48:46 -08002508#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine20035e32018-02-03 22:44:14 +01002509 case PSA_ALG_RIPEMD160:
2510 return( &mbedtls_ripemd160_info );
2511#endif
John Durkopee4e6602020-11-27 08:48:46 -08002512#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine20035e32018-02-03 22:44:14 +01002513 case PSA_ALG_SHA_1:
2514 return( &mbedtls_sha1_info );
2515#endif
John Durkopee4e6602020-11-27 08:48:46 -08002516#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine20035e32018-02-03 22:44:14 +01002517 case PSA_ALG_SHA_224:
2518 return( &mbedtls_sha224_info );
John Durkopee4e6602020-11-27 08:48:46 -08002519#endif
2520#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine20035e32018-02-03 22:44:14 +01002521 case PSA_ALG_SHA_256:
2522 return( &mbedtls_sha256_info );
2523#endif
John Durkopee4e6602020-11-27 08:48:46 -08002524#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine20035e32018-02-03 22:44:14 +01002525 case PSA_ALG_SHA_384:
2526 return( &mbedtls_sha384_info );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +02002527#endif
John Durkopee4e6602020-11-27 08:48:46 -08002528#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine20035e32018-02-03 22:44:14 +01002529 case PSA_ALG_SHA_512:
2530 return( &mbedtls_sha512_info );
2531#endif
2532 default:
2533 return( NULL );
2534 }
2535}
John Durkop07cc04a2020-11-16 22:08:34 -08002536#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
John Durkop9814fa22020-11-04 12:28:15 -08002537 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
2538 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
2539 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskine20035e32018-02-03 22:44:14 +01002540
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002541psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
2542{
2543 switch( operation->alg )
2544 {
Gilles Peskine81736312018-06-26 15:04:31 +02002545 case 0:
2546 /* The object has (apparently) been initialized but it is not
2547 * in use. It's ok to call abort on such an object, and there's
2548 * nothing to do. */
2549 break;
John Durkopee4e6602020-11-27 08:48:46 -08002550#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002551 case PSA_ALG_MD2:
2552 mbedtls_md2_free( &operation->ctx.md2 );
2553 break;
2554#endif
John Durkopee4e6602020-11-27 08:48:46 -08002555#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002556 case PSA_ALG_MD4:
2557 mbedtls_md4_free( &operation->ctx.md4 );
2558 break;
2559#endif
John Durkopee4e6602020-11-27 08:48:46 -08002560#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002561 case PSA_ALG_MD5:
2562 mbedtls_md5_free( &operation->ctx.md5 );
2563 break;
2564#endif
John Durkopee4e6602020-11-27 08:48:46 -08002565#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002566 case PSA_ALG_RIPEMD160:
2567 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
2568 break;
2569#endif
John Durkopee4e6602020-11-27 08:48:46 -08002570#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002571 case PSA_ALG_SHA_1:
2572 mbedtls_sha1_free( &operation->ctx.sha1 );
2573 break;
2574#endif
John Durkop6ca23272020-12-03 06:01:32 -08002575#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002576 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002577 mbedtls_sha256_free( &operation->ctx.sha256 );
2578 break;
2579#endif
2580#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002581 case PSA_ALG_SHA_256:
2582 mbedtls_sha256_free( &operation->ctx.sha256 );
2583 break;
2584#endif
John Durkop6ca23272020-12-03 06:01:32 -08002585#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002586 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002587 mbedtls_sha512_free( &operation->ctx.sha512 );
2588 break;
2589#endif
2590#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002591 case PSA_ALG_SHA_512:
2592 mbedtls_sha512_free( &operation->ctx.sha512 );
2593 break;
2594#endif
2595 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002596 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002597 }
2598 operation->alg = 0;
2599 return( PSA_SUCCESS );
2600}
2601
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002602psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002603 psa_algorithm_t alg )
2604{
Janos Follath24eed8d2019-11-22 13:21:35 +00002605 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002606
2607 /* A context must be freshly initialized before it can be set up. */
2608 if( operation->alg != 0 )
2609 {
2610 return( PSA_ERROR_BAD_STATE );
2611 }
2612
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002613 switch( alg )
2614 {
John Durkopee4e6602020-11-27 08:48:46 -08002615#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002616 case PSA_ALG_MD2:
2617 mbedtls_md2_init( &operation->ctx.md2 );
2618 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
2619 break;
2620#endif
John Durkopee4e6602020-11-27 08:48:46 -08002621#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002622 case PSA_ALG_MD4:
2623 mbedtls_md4_init( &operation->ctx.md4 );
2624 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
2625 break;
2626#endif
John Durkopee4e6602020-11-27 08:48:46 -08002627#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002628 case PSA_ALG_MD5:
2629 mbedtls_md5_init( &operation->ctx.md5 );
2630 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
2631 break;
2632#endif
John Durkopee4e6602020-11-27 08:48:46 -08002633#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002634 case PSA_ALG_RIPEMD160:
2635 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
2636 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
2637 break;
2638#endif
John Durkopee4e6602020-11-27 08:48:46 -08002639#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002640 case PSA_ALG_SHA_1:
2641 mbedtls_sha1_init( &operation->ctx.sha1 );
2642 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
2643 break;
2644#endif
John Durkopee4e6602020-11-27 08:48:46 -08002645#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002646 case PSA_ALG_SHA_224:
2647 mbedtls_sha256_init( &operation->ctx.sha256 );
2648 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
2649 break;
John Durkopee4e6602020-11-27 08:48:46 -08002650#endif
2651#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002652 case PSA_ALG_SHA_256:
2653 mbedtls_sha256_init( &operation->ctx.sha256 );
2654 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
2655 break;
2656#endif
John Durkopee4e6602020-11-27 08:48:46 -08002657#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002658 case PSA_ALG_SHA_384:
2659 mbedtls_sha512_init( &operation->ctx.sha512 );
2660 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
2661 break;
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002662#endif
John Durkopee4e6602020-11-27 08:48:46 -08002663#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002664 case PSA_ALG_SHA_512:
2665 mbedtls_sha512_init( &operation->ctx.sha512 );
2666 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
2667 break;
2668#endif
2669 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02002670 return( PSA_ALG_IS_HASH( alg ) ?
2671 PSA_ERROR_NOT_SUPPORTED :
2672 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002673 }
2674 if( ret == 0 )
2675 operation->alg = alg;
2676 else
2677 psa_hash_abort( operation );
2678 return( mbedtls_to_psa_error( ret ) );
2679}
2680
2681psa_status_t psa_hash_update( psa_hash_operation_t *operation,
2682 const uint8_t *input,
2683 size_t input_length )
2684{
Janos Follath24eed8d2019-11-22 13:21:35 +00002685 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine94e44542018-07-12 16:58:43 +02002686
2687 /* Don't require hash implementations to behave correctly on a
2688 * zero-length input, which may have an invalid pointer. */
2689 if( input_length == 0 )
2690 return( PSA_SUCCESS );
2691
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002692 switch( operation->alg )
2693 {
John Durkopee4e6602020-11-27 08:48:46 -08002694#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002695 case PSA_ALG_MD2:
2696 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
2697 input, input_length );
2698 break;
2699#endif
John Durkopee4e6602020-11-27 08:48:46 -08002700#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002701 case PSA_ALG_MD4:
2702 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
2703 input, input_length );
2704 break;
2705#endif
John Durkopee4e6602020-11-27 08:48:46 -08002706#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002707 case PSA_ALG_MD5:
2708 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
2709 input, input_length );
2710 break;
2711#endif
John Durkopee4e6602020-11-27 08:48:46 -08002712#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002713 case PSA_ALG_RIPEMD160:
2714 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
2715 input, input_length );
2716 break;
2717#endif
John Durkopee4e6602020-11-27 08:48:46 -08002718#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002719 case PSA_ALG_SHA_1:
2720 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
2721 input, input_length );
2722 break;
2723#endif
John Durkop6ca23272020-12-03 06:01:32 -08002724#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002725 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002726 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
2727 input, input_length );
2728 break;
2729#endif
2730#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002731 case PSA_ALG_SHA_256:
2732 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
2733 input, input_length );
2734 break;
2735#endif
John Durkop6ca23272020-12-03 06:01:32 -08002736#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002737 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002738 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
2739 input, input_length );
2740 break;
2741#endif
2742#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002743 case PSA_ALG_SHA_512:
2744 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
2745 input, input_length );
2746 break;
2747#endif
2748 default:
John Durkopee4e6602020-11-27 08:48:46 -08002749 (void)input;
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002750 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002751 }
Gilles Peskine94e44542018-07-12 16:58:43 +02002752
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002753 if( ret != 0 )
2754 psa_hash_abort( operation );
2755 return( mbedtls_to_psa_error( ret ) );
2756}
2757
2758psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
2759 uint8_t *hash,
2760 size_t hash_size,
2761 size_t *hash_length )
2762{
itayzafrir40835d42018-08-02 13:14:17 +03002763 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00002764 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02002765 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002766
2767 /* Fill the output buffer with something that isn't a valid hash
2768 * (barring an attack on the hash and deliberately-crafted input),
2769 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02002770 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002771 /* If hash_size is 0 then hash may be NULL and then the
2772 * call to memset would have undefined behavior. */
2773 if( hash_size != 0 )
2774 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002775
2776 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03002777 {
2778 status = PSA_ERROR_BUFFER_TOO_SMALL;
2779 goto exit;
2780 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002781
2782 switch( operation->alg )
2783 {
John Durkopee4e6602020-11-27 08:48:46 -08002784#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002785 case PSA_ALG_MD2:
2786 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
2787 break;
2788#endif
John Durkopee4e6602020-11-27 08:48:46 -08002789#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002790 case PSA_ALG_MD4:
2791 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
2792 break;
2793#endif
John Durkopee4e6602020-11-27 08:48:46 -08002794#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002795 case PSA_ALG_MD5:
2796 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
2797 break;
2798#endif
John Durkopee4e6602020-11-27 08:48:46 -08002799#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002800 case PSA_ALG_RIPEMD160:
2801 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
2802 break;
2803#endif
John Durkopee4e6602020-11-27 08:48:46 -08002804#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002805 case PSA_ALG_SHA_1:
2806 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
2807 break;
2808#endif
John Durkop6ca23272020-12-03 06:01:32 -08002809#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002810 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002811 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
2812 break;
2813#endif
2814#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002815 case PSA_ALG_SHA_256:
2816 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
2817 break;
2818#endif
John Durkop6ca23272020-12-03 06:01:32 -08002819#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002820 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002821 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
2822 break;
2823#endif
2824#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002825 case PSA_ALG_SHA_512:
2826 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
2827 break;
2828#endif
2829 default:
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002830 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002831 }
itayzafrir40835d42018-08-02 13:14:17 +03002832 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002833
itayzafrir40835d42018-08-02 13:14:17 +03002834exit:
2835 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002836 {
Gilles Peskineaee13332018-07-02 12:15:28 +02002837 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002838 return( psa_hash_abort( operation ) );
2839 }
2840 else
2841 {
2842 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03002843 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002844 }
2845}
2846
Gilles Peskine2d277862018-06-18 15:41:12 +02002847psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
2848 const uint8_t *hash,
2849 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002850{
2851 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
2852 size_t actual_hash_length;
2853 psa_status_t status = psa_hash_finish( operation,
2854 actual_hash, sizeof( actual_hash ),
2855 &actual_hash_length );
2856 if( status != PSA_SUCCESS )
2857 return( status );
2858 if( actual_hash_length != hash_length )
2859 return( PSA_ERROR_INVALID_SIGNATURE );
2860 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
2861 return( PSA_ERROR_INVALID_SIGNATURE );
2862 return( PSA_SUCCESS );
2863}
2864
Gilles Peskine0a749c82019-11-28 19:33:58 +01002865psa_status_t psa_hash_compute( psa_algorithm_t alg,
2866 const uint8_t *input, size_t input_length,
2867 uint8_t *hash, size_t hash_size,
2868 size_t *hash_length )
2869{
2870 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
2871 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2872
2873 *hash_length = hash_size;
2874 status = psa_hash_setup( &operation, alg );
2875 if( status != PSA_SUCCESS )
2876 goto exit;
2877 status = psa_hash_update( &operation, input, input_length );
2878 if( status != PSA_SUCCESS )
2879 goto exit;
2880 status = psa_hash_finish( &operation, hash, hash_size, hash_length );
2881 if( status != PSA_SUCCESS )
2882 goto exit;
2883
2884exit:
2885 if( status == PSA_SUCCESS )
2886 status = psa_hash_abort( &operation );
2887 else
2888 psa_hash_abort( &operation );
2889 return( status );
2890}
2891
2892psa_status_t psa_hash_compare( psa_algorithm_t alg,
2893 const uint8_t *input, size_t input_length,
2894 const uint8_t *hash, size_t hash_length )
2895{
2896 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
2897 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2898
2899 status = psa_hash_setup( &operation, alg );
2900 if( status != PSA_SUCCESS )
2901 goto exit;
2902 status = psa_hash_update( &operation, input, input_length );
2903 if( status != PSA_SUCCESS )
2904 goto exit;
2905 status = psa_hash_verify( &operation, hash, hash_length );
2906 if( status != PSA_SUCCESS )
2907 goto exit;
2908
2909exit:
2910 if( status == PSA_SUCCESS )
2911 status = psa_hash_abort( &operation );
2912 else
2913 psa_hash_abort( &operation );
2914 return( status );
2915}
2916
Gilles Peskineeb35d782019-01-22 17:56:16 +01002917psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation,
2918 psa_hash_operation_t *target_operation )
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002919{
2920 if( target_operation->alg != 0 )
2921 return( PSA_ERROR_BAD_STATE );
2922
2923 switch( source_operation->alg )
2924 {
2925 case 0:
2926 return( PSA_ERROR_BAD_STATE );
John Durkopee4e6602020-11-27 08:48:46 -08002927#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002928 case PSA_ALG_MD2:
2929 mbedtls_md2_clone( &target_operation->ctx.md2,
2930 &source_operation->ctx.md2 );
2931 break;
2932#endif
John Durkopee4e6602020-11-27 08:48:46 -08002933#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002934 case PSA_ALG_MD4:
2935 mbedtls_md4_clone( &target_operation->ctx.md4,
2936 &source_operation->ctx.md4 );
2937 break;
2938#endif
John Durkopee4e6602020-11-27 08:48:46 -08002939#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002940 case PSA_ALG_MD5:
2941 mbedtls_md5_clone( &target_operation->ctx.md5,
2942 &source_operation->ctx.md5 );
2943 break;
2944#endif
John Durkopee4e6602020-11-27 08:48:46 -08002945#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002946 case PSA_ALG_RIPEMD160:
2947 mbedtls_ripemd160_clone( &target_operation->ctx.ripemd160,
2948 &source_operation->ctx.ripemd160 );
2949 break;
2950#endif
John Durkopee4e6602020-11-27 08:48:46 -08002951#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002952 case PSA_ALG_SHA_1:
2953 mbedtls_sha1_clone( &target_operation->ctx.sha1,
2954 &source_operation->ctx.sha1 );
2955 break;
2956#endif
John Durkop6ca23272020-12-03 06:01:32 -08002957#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002958 case PSA_ALG_SHA_224:
John Durkop6ca23272020-12-03 06:01:32 -08002959 mbedtls_sha256_clone( &target_operation->ctx.sha256,
2960 &source_operation->ctx.sha256 );
2961 break;
2962#endif
2963#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002964 case PSA_ALG_SHA_256:
2965 mbedtls_sha256_clone( &target_operation->ctx.sha256,
2966 &source_operation->ctx.sha256 );
2967 break;
2968#endif
John Durkop6ca23272020-12-03 06:01:32 -08002969#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002970 case PSA_ALG_SHA_384:
John Durkop6ca23272020-12-03 06:01:32 -08002971 mbedtls_sha512_clone( &target_operation->ctx.sha512,
2972 &source_operation->ctx.sha512 );
2973 break;
2974#endif
2975#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002976 case PSA_ALG_SHA_512:
2977 mbedtls_sha512_clone( &target_operation->ctx.sha512,
2978 &source_operation->ctx.sha512 );
2979 break;
2980#endif
2981 default:
2982 return( PSA_ERROR_NOT_SUPPORTED );
2983 }
2984
2985 target_operation->alg = source_operation->alg;
2986 return( PSA_SUCCESS );
2987}
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002988
2989
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002990/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01002991/* MAC */
2992/****************************************************************/
2993
Gilles Peskinedc2fc842018-03-07 16:42:59 +01002994static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01002995 psa_algorithm_t alg,
2996 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02002997 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03002998 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002999{
Gilles Peskine8c9def32018-02-08 10:02:12 +01003000 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03003001 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003002
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003003 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02003004 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003005
Gilles Peskine8c9def32018-02-08 10:02:12 +01003006 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
3007 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03003008 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003009 {
Bence Szépkúti1de907d2020-12-07 18:20:28 +01003010 case PSA_ALG_STREAM_CIPHER:
Gilles Peskine8c9def32018-02-08 10:02:12 +01003011 mode = MBEDTLS_MODE_STREAM;
3012 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003013 case PSA_ALG_CTR:
3014 mode = MBEDTLS_MODE_CTR;
3015 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003016 case PSA_ALG_CFB:
3017 mode = MBEDTLS_MODE_CFB;
3018 break;
3019 case PSA_ALG_OFB:
3020 mode = MBEDTLS_MODE_OFB;
3021 break;
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003022 case PSA_ALG_ECB_NO_PADDING:
3023 mode = MBEDTLS_MODE_ECB;
3024 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003025 case PSA_ALG_CBC_NO_PADDING:
3026 mode = MBEDTLS_MODE_CBC;
3027 break;
3028 case PSA_ALG_CBC_PKCS7:
3029 mode = MBEDTLS_MODE_CBC;
3030 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02003031 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01003032 mode = MBEDTLS_MODE_CCM;
3033 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02003034 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01003035 mode = MBEDTLS_MODE_GCM;
3036 break;
Gilles Peskine26869f22019-05-06 15:25:00 +02003037 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CHACHA20_POLY1305, 0 ):
3038 mode = MBEDTLS_MODE_CHACHAPOLY;
3039 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003040 default:
3041 return( NULL );
3042 }
3043 }
3044 else if( alg == PSA_ALG_CMAC )
3045 mode = MBEDTLS_MODE_ECB;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003046 else
3047 return( NULL );
3048
3049 switch( key_type )
3050 {
3051 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03003052 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003053 break;
3054 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003055 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
3056 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01003057 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03003058 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003059 else
mohammad1603f4f0d612018-06-03 15:04:51 +03003060 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003061 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
3062 * but two-key Triple-DES is functionally three-key Triple-DES
3063 * with K1=K3, so that's how we present it to mbedtls. */
3064 if( key_bits == 128 )
3065 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003066 break;
3067 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03003068 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003069 break;
3070 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03003071 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003072 break;
Gilles Peskine26869f22019-05-06 15:25:00 +02003073 case PSA_KEY_TYPE_CHACHA20:
3074 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
3075 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003076 default:
3077 return( NULL );
3078 }
mohammad1603f4f0d612018-06-03 15:04:51 +03003079 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03003080 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003081
Jaeden Amero23bbb752018-06-26 14:16:54 +01003082 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
3083 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003084}
3085
John Durkop6ba40d12020-11-10 08:50:04 -08003086#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003087static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03003088{
Gilles Peskine2d277862018-06-18 15:41:12 +02003089 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03003090 {
3091 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003092 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003093 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003094 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003095 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003096 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003097 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003098 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003099 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003100 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003101 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003102 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003103 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003104 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003105 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03003106 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003107 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02003108 return( 128 );
3109 default:
3110 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03003111 }
3112}
John Durkop07cc04a2020-11-16 22:08:34 -08003113#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03003114
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003115/* Initialize the MAC operation structure. Once this function has been
3116 * called, psa_mac_abort can run and will do the right thing. */
3117static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
3118 psa_algorithm_t alg )
3119{
3120 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
3121
3122 operation->alg = alg;
3123 operation->key_set = 0;
3124 operation->iv_set = 0;
3125 operation->iv_required = 0;
3126 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02003127 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003128
3129#if defined(MBEDTLS_CMAC_C)
3130 if( alg == PSA_ALG_CMAC )
3131 {
3132 operation->iv_required = 0;
3133 mbedtls_cipher_init( &operation->ctx.cmac );
3134 status = PSA_SUCCESS;
3135 }
3136 else
3137#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003138#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003139 if( PSA_ALG_IS_HMAC( operation->alg ) )
3140 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02003141 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
3142 operation->ctx.hmac.hash_ctx.alg = 0;
3143 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003144 }
3145 else
John Durkopd0321952020-10-29 21:37:36 -07003146#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003147 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02003148 if( ! PSA_ALG_IS_MAC( alg ) )
3149 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003150 }
3151
3152 if( status != PSA_SUCCESS )
3153 memset( operation, 0, sizeof( *operation ) );
3154 return( status );
3155}
3156
John Durkop6ba40d12020-11-10 08:50:04 -08003157#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02003158static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
3159{
Gilles Peskine3f108122018-12-07 18:14:53 +01003160 mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003161 return( psa_hash_abort( &hmac->hash_ctx ) );
3162}
John Durkop6ba40d12020-11-10 08:50:04 -08003163#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine01126fa2018-07-12 17:04:55 +02003164
Gilles Peskine8c9def32018-02-08 10:02:12 +01003165psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
3166{
Gilles Peskinefbfac682018-07-08 20:51:54 +02003167 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003168 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02003169 /* The object has (apparently) been initialized but it is not
3170 * in use. It's ok to call abort on such an object, and there's
3171 * nothing to do. */
3172 return( PSA_SUCCESS );
3173 }
3174 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01003175#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003176 if( operation->alg == PSA_ALG_CMAC )
3177 {
3178 mbedtls_cipher_free( &operation->ctx.cmac );
3179 }
3180 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01003181#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003182#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003183 if( PSA_ALG_IS_HMAC( operation->alg ) )
3184 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02003185 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003186 }
3187 else
John Durkopd0321952020-10-29 21:37:36 -07003188#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003189 {
3190 /* Sanity check (shouldn't happen: operation->alg should
3191 * always have been initialized to a valid value). */
3192 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003193 }
Moran Peker41deec42018-04-04 15:43:05 +03003194
Gilles Peskine8c9def32018-02-08 10:02:12 +01003195 operation->alg = 0;
3196 operation->key_set = 0;
3197 operation->iv_set = 0;
3198 operation->iv_required = 0;
3199 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02003200 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03003201
Gilles Peskine8c9def32018-02-08 10:02:12 +01003202 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003203
3204bad_state:
3205 /* If abort is called on an uninitialized object, we can't trust
3206 * anything. Wipe the object in case it contains confidential data.
3207 * This may result in a memory leak if a pointer gets overwritten,
3208 * but it's too late to do anything about this. */
3209 memset( operation, 0, sizeof( *operation ) );
3210 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003211}
3212
Gilles Peskinee3b07d82018-06-19 11:57:35 +02003213#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02003214static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003215 size_t key_bits,
Gilles Peskine2f060a82018-12-04 17:12:32 +01003216 psa_key_slot_t *slot,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003217 const mbedtls_cipher_info_t *cipher_info )
3218{
Janos Follath24eed8d2019-11-22 13:21:35 +00003219 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003220
3221 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003222
3223 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
3224 if( ret != 0 )
3225 return( ret );
3226
3227 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02003228 slot->data.key.data,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003229 key_bits );
3230 return( ret );
3231}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02003232#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003233
John Durkop6ba40d12020-11-10 08:50:04 -08003234#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02003235static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
3236 const uint8_t *key,
3237 size_t key_length,
3238 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003239{
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02003240 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003241 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02003242 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003243 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003244 psa_status_t status;
3245
Gilles Peskine9aa369e2018-07-16 00:36:29 +02003246 /* Sanity checks on block_size, to guarantee that there won't be a buffer
3247 * overflow below. This should never trigger if the hash algorithm
3248 * is implemented correctly. */
3249 /* The size checks against the ipad and opad buffers cannot be written
3250 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
3251 * because that triggers -Wlogical-op on GCC 7.3. */
3252 if( block_size > sizeof( ipad ) )
3253 return( PSA_ERROR_NOT_SUPPORTED );
3254 if( block_size > sizeof( hmac->opad ) )
3255 return( PSA_ERROR_NOT_SUPPORTED );
3256 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003257 return( PSA_ERROR_NOT_SUPPORTED );
3258
Gilles Peskined223b522018-06-11 18:12:58 +02003259 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003260 {
Gilles Peskine84b8fc82019-11-28 20:07:20 +01003261 status = psa_hash_compute( hash_alg, key, key_length,
3262 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003263 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02003264 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003265 }
Gilles Peskine96889972018-07-12 17:07:03 +02003266 /* A 0-length key is not commonly used in HMAC when used as a MAC,
3267 * but it is permitted. It is common when HMAC is used in HKDF, for
3268 * example. Don't call `memcpy` in the 0-length because `key` could be
3269 * an invalid pointer which would make the behavior undefined. */
3270 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02003271 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003272
Gilles Peskined223b522018-06-11 18:12:58 +02003273 /* ipad contains the key followed by garbage. Xor and fill with 0x36
3274 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003275 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02003276 ipad[i] ^= 0x36;
3277 memset( ipad + key_length, 0x36, block_size - key_length );
3278
3279 /* Copy the key material from ipad to opad, flipping the requisite bits,
3280 * and filling the rest of opad with the requisite constant. */
3281 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02003282 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
3283 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003284
Gilles Peskine01126fa2018-07-12 17:04:55 +02003285 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003286 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02003287 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003288
Gilles Peskine01126fa2018-07-12 17:04:55 +02003289 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02003290
3291cleanup:
Steven Cooreman29149862020-08-05 15:43:42 +02003292 mbedtls_platform_zeroize( ipad, sizeof( ipad ) );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02003293
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003294 return( status );
3295}
John Durkop6ba40d12020-11-10 08:50:04 -08003296#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003297
Gilles Peskine89167cb2018-07-08 20:12:23 +02003298static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02003299 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02003300 psa_algorithm_t alg,
3301 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003302{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003303 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003304 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003305 psa_key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003306 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02003307 psa_key_usage_t usage =
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003308 is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH;
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02003309 uint8_t truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02003310 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003311
Jaeden Amero36ee5d02019-02-19 09:25:10 +00003312 /* A context must be freshly initialized before it can be set up. */
3313 if( operation->alg != 0 )
3314 {
3315 return( PSA_ERROR_BAD_STATE );
3316 }
3317
Gilles Peskined911eb72018-08-14 15:18:45 +02003318 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003319 if( status != PSA_SUCCESS )
3320 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003321 if( is_sign )
3322 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003323
Ronald Cron5c522922020-11-14 16:35:34 +01003324 status = psa_get_and_lock_transparent_key_slot_with_policy(
3325 key, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003326 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02003327 goto exit;
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02003328 key_bits = psa_get_key_slot_bits( slot );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02003329
Gilles Peskine8c9def32018-02-08 10:02:12 +01003330#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02003331 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02003332 {
3333 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02003334 mbedtls_cipher_info_from_psa( full_length_alg,
Gilles Peskine8e338702019-07-30 20:06:31 +02003335 slot->attr.type, key_bits, NULL );
Janos Follath24eed8d2019-11-22 13:21:35 +00003336 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinefbfac682018-07-08 20:51:54 +02003337 if( cipher_info == NULL )
3338 {
3339 status = PSA_ERROR_NOT_SUPPORTED;
3340 goto exit;
3341 }
3342 operation->mac_size = cipher_info->block_size;
3343 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
3344 status = mbedtls_to_psa_error( ret );
3345 }
3346 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01003347#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003348#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskined911eb72018-08-14 15:18:45 +02003349 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02003350 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02003351 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003352 if( hash_alg == 0 )
3353 {
3354 status = PSA_ERROR_NOT_SUPPORTED;
3355 goto exit;
3356 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02003357
3358 operation->mac_size = PSA_HASH_SIZE( hash_alg );
3359 /* Sanity check. This shouldn't fail on a valid configuration. */
3360 if( operation->mac_size == 0 ||
3361 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
3362 {
3363 status = PSA_ERROR_NOT_SUPPORTED;
3364 goto exit;
3365 }
3366
Gilles Peskine8e338702019-07-30 20:06:31 +02003367 if( slot->attr.type != PSA_KEY_TYPE_HMAC )
Gilles Peskine01126fa2018-07-12 17:04:55 +02003368 {
3369 status = PSA_ERROR_INVALID_ARGUMENT;
3370 goto exit;
3371 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02003372
Gilles Peskine01126fa2018-07-12 17:04:55 +02003373 status = psa_hmac_setup_internal( &operation->ctx.hmac,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02003374 slot->data.key.data,
3375 slot->data.key.bytes,
Gilles Peskine01126fa2018-07-12 17:04:55 +02003376 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003377 }
3378 else
John Durkopd0321952020-10-29 21:37:36 -07003379#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003380 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00003381 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02003382 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003383 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003384
Gilles Peskined911eb72018-08-14 15:18:45 +02003385 if( truncated == 0 )
3386 {
3387 /* The "normal" case: untruncated algorithm. Nothing to do. */
3388 }
3389 else if( truncated < 4 )
3390 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02003391 /* A very short MAC is too short for security since it can be
3392 * brute-forced. Ancient protocols with 32-bit MACs do exist,
3393 * so we make this our minimum, even though 32 bits is still
3394 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02003395 status = PSA_ERROR_NOT_SUPPORTED;
3396 }
3397 else if( truncated > operation->mac_size )
3398 {
3399 /* It's impossible to "truncate" to a larger length. */
3400 status = PSA_ERROR_INVALID_ARGUMENT;
3401 }
3402 else
3403 operation->mac_size = truncated;
3404
Gilles Peskinefbfac682018-07-08 20:51:54 +02003405exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003406 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003407 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02003408 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003409 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003410 else
3411 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02003412 operation->key_set = 1;
3413 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02003414
Ronald Cron5c522922020-11-14 16:35:34 +01003415 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02003416
Ronald Cron5c522922020-11-14 16:35:34 +01003417 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003418}
3419
Gilles Peskine89167cb2018-07-08 20:12:23 +02003420psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02003421 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02003422 psa_algorithm_t alg )
3423{
Ronald Croncf56a0a2020-08-04 09:51:30 +02003424 return( psa_mac_setup( operation, key, alg, 1 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003425}
3426
3427psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02003428 mbedtls_svc_key_id_t key,
Gilles Peskine89167cb2018-07-08 20:12:23 +02003429 psa_algorithm_t alg )
3430{
Ronald Croncf56a0a2020-08-04 09:51:30 +02003431 return( psa_mac_setup( operation, key, alg, 0 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003432}
3433
Gilles Peskine8c9def32018-02-08 10:02:12 +01003434psa_status_t psa_mac_update( psa_mac_operation_t *operation,
3435 const uint8_t *input,
3436 size_t input_length )
3437{
Gilles Peskinefbfac682018-07-08 20:51:54 +02003438 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003439 if( ! operation->key_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003440 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003441 if( operation->iv_required && ! operation->iv_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003442 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003443 operation->has_input = 1;
3444
Gilles Peskine8c9def32018-02-08 10:02:12 +01003445#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003446 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03003447 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02003448 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
3449 input, input_length );
3450 status = mbedtls_to_psa_error( ret );
3451 }
3452 else
3453#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003454#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003455 if( PSA_ALG_IS_HMAC( operation->alg ) )
3456 {
3457 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
3458 input_length );
3459 }
3460 else
John Durkopd0321952020-10-29 21:37:36 -07003461#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003462 {
3463 /* This shouldn't happen if `operation` was initialized by
3464 * a setup function. */
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003465 return( PSA_ERROR_BAD_STATE );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03003466 }
3467
Gilles Peskinefbfac682018-07-08 20:51:54 +02003468 if( status != PSA_SUCCESS )
3469 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003470 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003471}
3472
John Durkop6ba40d12020-11-10 08:50:04 -08003473#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine01126fa2018-07-12 17:04:55 +02003474static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
3475 uint8_t *mac,
3476 size_t mac_size )
3477{
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02003478 uint8_t tmp[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine01126fa2018-07-12 17:04:55 +02003479 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
3480 size_t hash_size = 0;
3481 size_t block_size = psa_get_hash_block_size( hash_alg );
3482 psa_status_t status;
3483
Gilles Peskine01126fa2018-07-12 17:04:55 +02003484 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
3485 if( status != PSA_SUCCESS )
3486 return( status );
3487 /* From here on, tmp needs to be wiped. */
3488
3489 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
3490 if( status != PSA_SUCCESS )
3491 goto exit;
3492
3493 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
3494 if( status != PSA_SUCCESS )
3495 goto exit;
3496
3497 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
3498 if( status != PSA_SUCCESS )
3499 goto exit;
3500
Gilles Peskined911eb72018-08-14 15:18:45 +02003501 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
3502 if( status != PSA_SUCCESS )
3503 goto exit;
3504
3505 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003506
3507exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01003508 mbedtls_platform_zeroize( tmp, hash_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003509 return( status );
3510}
John Durkop6ba40d12020-11-10 08:50:04 -08003511#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskine01126fa2018-07-12 17:04:55 +02003512
mohammad16036df908f2018-04-02 08:34:15 -07003513static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02003514 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003515 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003516{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02003517 if( ! operation->key_set )
3518 return( PSA_ERROR_BAD_STATE );
3519 if( operation->iv_required && ! operation->iv_set )
3520 return( PSA_ERROR_BAD_STATE );
3521
Gilles Peskine8c9def32018-02-08 10:02:12 +01003522 if( mac_size < operation->mac_size )
3523 return( PSA_ERROR_BUFFER_TOO_SMALL );
3524
Gilles Peskine8c9def32018-02-08 10:02:12 +01003525#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003526 if( operation->alg == PSA_ALG_CMAC )
3527 {
Gilles Peskined911eb72018-08-14 15:18:45 +02003528 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
3529 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
3530 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02003531 memcpy( mac, tmp, operation->mac_size );
Gilles Peskine3f108122018-12-07 18:14:53 +01003532 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003533 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003534 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02003535 else
3536#endif /* MBEDTLS_CMAC_C */
John Durkopd0321952020-10-29 21:37:36 -07003537#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003538 if( PSA_ALG_IS_HMAC( operation->alg ) )
3539 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02003540 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02003541 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003542 }
3543 else
John Durkopd0321952020-10-29 21:37:36 -07003544#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Gilles Peskinefbfac682018-07-08 20:51:54 +02003545 {
3546 /* This shouldn't happen if `operation` was initialized by
3547 * a setup function. */
3548 return( PSA_ERROR_BAD_STATE );
3549 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01003550}
3551
Gilles Peskineacd4be32018-07-08 19:56:25 +02003552psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
3553 uint8_t *mac,
3554 size_t mac_size,
3555 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07003556{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003557 psa_status_t status;
3558
Jaeden Amero252ef282019-02-15 14:05:35 +00003559 if( operation->alg == 0 )
3560 {
3561 return( PSA_ERROR_BAD_STATE );
3562 }
3563
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003564 /* Fill the output buffer with something that isn't a valid mac
3565 * (barring an attack on the mac and deliberately-crafted input),
3566 * in case the caller doesn't check the return status properly. */
3567 *mac_length = mac_size;
3568 /* If mac_size is 0 then mac may be NULL and then the
3569 * call to memset would have undefined behavior. */
3570 if( mac_size != 0 )
3571 memset( mac, '!', mac_size );
3572
Gilles Peskine89167cb2018-07-08 20:12:23 +02003573 if( ! operation->is_sign )
3574 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003575 return( PSA_ERROR_BAD_STATE );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003576 }
mohammad16036df908f2018-04-02 08:34:15 -07003577
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003578 status = psa_mac_finish_internal( operation, mac, mac_size );
3579
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003580 if( status == PSA_SUCCESS )
3581 {
3582 status = psa_mac_abort( operation );
3583 if( status == PSA_SUCCESS )
3584 *mac_length = operation->mac_size;
3585 else
3586 memset( mac, '!', mac_size );
3587 }
3588 else
3589 psa_mac_abort( operation );
3590 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07003591}
3592
Gilles Peskineacd4be32018-07-08 19:56:25 +02003593psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
3594 const uint8_t *mac,
3595 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003596{
Gilles Peskine828ed142018-06-18 23:25:51 +02003597 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07003598 psa_status_t status;
3599
Jaeden Amero252ef282019-02-15 14:05:35 +00003600 if( operation->alg == 0 )
3601 {
3602 return( PSA_ERROR_BAD_STATE );
3603 }
3604
Gilles Peskine89167cb2018-07-08 20:12:23 +02003605 if( operation->is_sign )
3606 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003607 return( PSA_ERROR_BAD_STATE );
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003608 }
3609 if( operation->mac_size != mac_length )
3610 {
3611 status = PSA_ERROR_INVALID_SIGNATURE;
3612 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02003613 }
mohammad16036df908f2018-04-02 08:34:15 -07003614
3615 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003616 actual_mac, sizeof( actual_mac ) );
Gilles Peskine28cd4162020-01-20 16:31:06 +01003617 if( status != PSA_SUCCESS )
3618 goto cleanup;
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003619
3620 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
3621 status = PSA_ERROR_INVALID_SIGNATURE;
3622
3623cleanup:
3624 if( status == PSA_SUCCESS )
3625 status = psa_mac_abort( operation );
3626 else
3627 psa_mac_abort( operation );
3628
Gilles Peskine3f108122018-12-07 18:14:53 +01003629 mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02003630
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003631 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003632}
3633
3634
Gilles Peskine20035e32018-02-03 22:44:14 +01003635
Gilles Peskine20035e32018-02-03 22:44:14 +01003636/****************************************************************/
3637/* Asymmetric cryptography */
3638/****************************************************************/
3639
John Durkop6ba40d12020-11-10 08:50:04 -08003640#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3641 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02003642/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003643 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02003644static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
3645 size_t hash_length,
3646 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003647{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02003648 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02003649 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003650 *md_alg = mbedtls_md_get_type( md_info );
3651
3652 /* The Mbed TLS RSA module uses an unsigned int for hash length
3653 * parameters. Validate that it fits so that we don't risk an
3654 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003655#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003656 if( hash_length > UINT_MAX )
3657 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003658#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003659
John Durkop0e005192020-10-31 22:06:54 -07003660#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003661 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
3662 * must be correct. */
3663 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
3664 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003665 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003666 if( md_info == NULL )
3667 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02003668 if( mbedtls_md_get_size( md_info ) != hash_length )
3669 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003670 }
John Durkop0e005192020-10-31 22:06:54 -07003671#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003672
John Durkop0e005192020-10-31 22:06:54 -07003673#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003674 /* PSS requires a hash internally. */
3675 if( PSA_ALG_IS_RSA_PSS( alg ) )
3676 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02003677 if( md_info == NULL )
3678 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003679 }
John Durkop0e005192020-10-31 22:06:54 -07003680#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003681
Gilles Peskine61b91d42018-06-08 16:09:36 +02003682 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003683}
3684
Gilles Peskine2b450e32018-06-27 15:42:46 +02003685static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
3686 psa_algorithm_t alg,
3687 const uint8_t *hash,
3688 size_t hash_length,
3689 uint8_t *signature,
3690 size_t signature_size,
3691 size_t *signature_length )
3692{
3693 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003694 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003695 mbedtls_md_type_t md_alg;
3696
3697 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
3698 if( status != PSA_SUCCESS )
3699 return( status );
3700
Gilles Peskine630a18a2018-06-29 17:49:35 +02003701 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02003702 return( PSA_ERROR_BUFFER_TOO_SMALL );
3703
John Durkop0e005192020-10-31 22:06:54 -07003704#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003705 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
3706 {
3707 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
3708 MBEDTLS_MD_NONE );
3709 ret = mbedtls_rsa_pkcs1_sign( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003710 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003711 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003712 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003713 md_alg,
3714 (unsigned int) hash_length,
3715 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003716 signature );
3717 }
3718 else
John Durkop0e005192020-10-31 22:06:54 -07003719#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
3720#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003721 if( PSA_ALG_IS_RSA_PSS( alg ) )
3722 {
3723 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3724 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003725 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003726 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003727 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003728 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003729 (unsigned int) hash_length,
3730 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003731 signature );
3732 }
3733 else
John Durkop0e005192020-10-31 22:06:54 -07003734#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003735 {
3736 return( PSA_ERROR_INVALID_ARGUMENT );
3737 }
3738
3739 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02003740 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003741 return( mbedtls_to_psa_error( ret ) );
3742}
3743
3744static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
3745 psa_algorithm_t alg,
3746 const uint8_t *hash,
3747 size_t hash_length,
3748 const uint8_t *signature,
3749 size_t signature_length )
3750{
3751 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003752 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003753 mbedtls_md_type_t md_alg;
3754
3755 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
3756 if( status != PSA_SUCCESS )
3757 return( status );
3758
Gilles Peskine89cc74f2019-09-12 22:08:23 +02003759 if( signature_length != mbedtls_rsa_get_len( rsa ) )
3760 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003761
John Durkop0e005192020-10-31 22:06:54 -07003762#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003763 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
3764 {
3765 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
3766 MBEDTLS_MD_NONE );
3767 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003768 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003769 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003770 MBEDTLS_RSA_PUBLIC,
3771 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003772 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003773 hash,
3774 signature );
3775 }
3776 else
John Durkop0e005192020-10-31 22:06:54 -07003777#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
3778#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine2b450e32018-06-27 15:42:46 +02003779 if( PSA_ALG_IS_RSA_PSS( alg ) )
3780 {
3781 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3782 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003783 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003784 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003785 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003786 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003787 (unsigned int) hash_length,
3788 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003789 signature );
3790 }
3791 else
John Durkop0e005192020-10-31 22:06:54 -07003792#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003793 {
3794 return( PSA_ERROR_INVALID_ARGUMENT );
3795 }
Gilles Peskineef12c632018-09-13 20:37:48 +02003796
3797 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
3798 * the rest of the signature is invalid". This has little use in
3799 * practice and PSA doesn't report this distinction. */
3800 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
3801 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003802 return( mbedtls_to_psa_error( ret ) );
3803}
John Durkop6ba40d12020-11-10 08:50:04 -08003804#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3805 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003806
John Durkop6ba40d12020-11-10 08:50:04 -08003807#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3808 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003809/* `ecp` cannot be const because `ecp->grp` needs to be non-const
3810 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
3811 * (even though these functions don't modify it). */
3812static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
3813 psa_algorithm_t alg,
3814 const uint8_t *hash,
3815 size_t hash_length,
3816 uint8_t *signature,
3817 size_t signature_size,
3818 size_t *signature_length )
3819{
Janos Follath24eed8d2019-11-22 13:21:35 +00003820 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003821 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003822 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003823 mbedtls_mpi_init( &r );
3824 mbedtls_mpi_init( &s );
3825
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003826 if( signature_size < 2 * curve_bytes )
3827 {
3828 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
3829 goto cleanup;
3830 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003831
John Durkop0ea39e02020-10-13 19:58:20 -07003832#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003833 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
3834 {
3835 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
3836 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
3837 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
Darryl Green5e843fa2019-09-05 14:06:34 +01003838 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det_ext( &ecp->grp, &r, &s,
3839 &ecp->d, hash,
3840 hash_length, md_alg,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003841 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003842 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003843 }
3844 else
John Durkop0ea39e02020-10-13 19:58:20 -07003845#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003846 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003847 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003848 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
3849 hash, hash_length,
Gilles Peskine30524eb2020-11-13 17:02:26 +01003850 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003851 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003852 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003853
3854 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
3855 signature,
3856 curve_bytes ) );
3857 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
3858 signature + curve_bytes,
3859 curve_bytes ) );
3860
3861cleanup:
3862 mbedtls_mpi_free( &r );
3863 mbedtls_mpi_free( &s );
3864 if( ret == 0 )
3865 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003866 return( mbedtls_to_psa_error( ret ) );
3867}
3868
3869static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
3870 const uint8_t *hash,
3871 size_t hash_length,
3872 const uint8_t *signature,
3873 size_t signature_length )
3874{
Janos Follath24eed8d2019-11-22 13:21:35 +00003875 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003876 mbedtls_mpi r, s;
3877 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
3878 mbedtls_mpi_init( &r );
3879 mbedtls_mpi_init( &s );
3880
3881 if( signature_length != 2 * curve_bytes )
3882 return( PSA_ERROR_INVALID_SIGNATURE );
3883
3884 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
3885 signature,
3886 curve_bytes ) );
3887 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
3888 signature + curve_bytes,
3889 curve_bytes ) );
3890
Steven Cooremanacda8342020-07-24 23:09:52 +02003891 /* Check whether the public part is loaded. If not, load it. */
3892 if( mbedtls_ecp_is_zero( &ecp->Q ) )
3893 {
3894 MBEDTLS_MPI_CHK(
3895 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01003896 mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
Steven Cooremanacda8342020-07-24 23:09:52 +02003897 }
3898
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003899 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
3900 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003901
3902cleanup:
3903 mbedtls_mpi_free( &r );
3904 mbedtls_mpi_free( &s );
3905 return( mbedtls_to_psa_error( ret ) );
3906}
John Durkop6ba40d12020-11-10 08:50:04 -08003907#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
3908 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003909
Ronald Croncf56a0a2020-08-04 09:51:30 +02003910psa_status_t psa_sign_hash( mbedtls_svc_key_id_t key,
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003911 psa_algorithm_t alg,
3912 const uint8_t *hash,
3913 size_t hash_length,
3914 uint8_t *signature,
3915 size_t signature_size,
3916 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01003917{
Ronald Cronf95a2b12020-10-22 15:24:49 +02003918 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01003919 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003920 psa_key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003921
3922 *signature_length = signature_size;
Gilles Peskine4019f0e2019-09-12 22:05:59 +02003923 /* Immediately reject a zero-length signature buffer. This guarantees
3924 * that signature must be a valid pointer. (On the other hand, the hash
3925 * buffer can in principle be empty since it doesn't actually have
3926 * to be a hash.) */
3927 if( signature_size == 0 )
3928 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003929
Ronald Cron5c522922020-11-14 16:35:34 +01003930 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
3931 PSA_KEY_USAGE_SIGN_HASH,
3932 alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003933 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003934 goto exit;
Gilles Peskine8e338702019-07-30 20:06:31 +02003935 if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003936 {
3937 status = PSA_ERROR_INVALID_ARGUMENT;
3938 goto exit;
3939 }
Gilles Peskine20035e32018-02-03 22:44:14 +01003940
Steven Cooremancd84cb42020-07-16 20:28:36 +02003941 /* Try any of the available accelerators first */
3942 status = psa_driver_wrapper_sign_hash( slot,
3943 alg,
3944 hash,
3945 hash_length,
3946 signature,
3947 signature_size,
3948 signature_length );
Steven Cooreman8d2bde72020-09-04 13:06:39 +02003949 if( status != PSA_ERROR_NOT_SUPPORTED ||
3950 psa_key_lifetime_is_external( slot->attr.lifetime ) )
Steven Cooremancd84cb42020-07-16 20:28:36 +02003951 goto exit;
3952
Steven Cooreman7a250572020-07-17 16:43:05 +02003953 /* If the operation was not supported by any accelerator, try fallback. */
John Durkop6ba40d12020-11-10 08:50:04 -08003954#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
3955 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8e338702019-07-30 20:06:31 +02003956 if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskine20035e32018-02-03 22:44:14 +01003957 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003958 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02003959
Steven Cooreman4fed4552020-08-03 14:46:03 +02003960 status = psa_load_rsa_representation( slot->attr.type,
3961 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02003962 slot->data.key.bytes,
Steven Cooremana01795d2020-07-24 22:48:15 +02003963 &rsa );
3964 if( status != PSA_SUCCESS )
3965 goto exit;
3966
Steven Cooremana2371e52020-07-28 14:30:39 +02003967 status = psa_rsa_sign( rsa,
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003968 alg,
3969 hash, hash_length,
3970 signature, signature_size,
3971 signature_length );
Steven Cooremana01795d2020-07-24 22:48:15 +02003972
Steven Cooremana2371e52020-07-28 14:30:39 +02003973 mbedtls_rsa_free( rsa );
3974 mbedtls_free( rsa );
Gilles Peskine20035e32018-02-03 22:44:14 +01003975 }
3976 else
John Durkop6ba40d12020-11-10 08:50:04 -08003977#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
3978 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine8e338702019-07-30 20:06:31 +02003979 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01003980 {
John Durkop9814fa22020-11-04 12:28:15 -08003981#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
3982 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea05219c2018-11-16 16:02:56 +01003983 if(
John Durkop0ea39e02020-10-13 19:58:20 -07003984#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea05219c2018-11-16 16:02:56 +01003985 PSA_ALG_IS_ECDSA( alg )
3986#else
3987 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
3988#endif
3989 )
Steven Cooremanacda8342020-07-24 23:09:52 +02003990 {
Steven Cooremana2371e52020-07-28 14:30:39 +02003991 mbedtls_ecp_keypair *ecp = NULL;
Steven Cooreman4fed4552020-08-03 14:46:03 +02003992 status = psa_load_ecp_representation( slot->attr.type,
3993 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02003994 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02003995 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02003996 if( status != PSA_SUCCESS )
3997 goto exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02003998 status = psa_ecdsa_sign( ecp,
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003999 alg,
4000 hash, hash_length,
4001 signature, signature_size,
4002 signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02004003 mbedtls_ecp_keypair_free( ecp );
4004 mbedtls_free( ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02004005 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004006 else
John Durkop9814fa22020-11-04 12:28:15 -08004007#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
4008 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004009 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02004010 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004011 }
itayzafrir5c753392018-05-08 11:18:38 +03004012 }
4013 else
itayzafrir5c753392018-05-08 11:18:38 +03004014 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02004015 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01004016 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02004017
4018exit:
4019 /* Fill the unused part of the output buffer (the whole buffer on error,
4020 * the trailing part on success) with something that isn't a valid mac
4021 * (barring an attack on the mac and deliberately-crafted input),
4022 * in case the caller doesn't check the return status properly. */
4023 if( status == PSA_SUCCESS )
4024 memset( signature + *signature_length, '!',
4025 signature_size - *signature_length );
Gilles Peskine4019f0e2019-09-12 22:05:59 +02004026 else
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02004027 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004028 /* If signature_size is 0 then we have nothing to do. We must not call
4029 * memset because signature may be NULL in this case. */
Ronald Cronf95a2b12020-10-22 15:24:49 +02004030
Ronald Cron5c522922020-11-14 16:35:34 +01004031 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004032
Ronald Cron5c522922020-11-14 16:35:34 +01004033 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
itayzafrir5c753392018-05-08 11:18:38 +03004034}
4035
Ronald Croncf56a0a2020-08-04 09:51:30 +02004036psa_status_t psa_verify_hash( mbedtls_svc_key_id_t key,
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004037 psa_algorithm_t alg,
4038 const uint8_t *hash,
4039 size_t hash_length,
4040 const uint8_t *signature,
4041 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03004042{
Ronald Cronf95a2b12020-10-22 15:24:49 +02004043 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01004044 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01004045 psa_key_slot_t *slot;
Gilles Peskine2b450e32018-06-27 15:42:46 +02004046
Ronald Cron5c522922020-11-14 16:35:34 +01004047 status = psa_get_and_lock_key_slot_with_policy( key, &slot,
4048 PSA_KEY_USAGE_VERIFY_HASH,
4049 alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004050 if( status != PSA_SUCCESS )
4051 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03004052
Steven Cooreman55ae2172020-07-17 19:46:15 +02004053 /* Try any of the available accelerators first */
4054 status = psa_driver_wrapper_verify_hash( slot,
4055 alg,
4056 hash,
4057 hash_length,
4058 signature,
4059 signature_length );
Steven Cooreman8d2bde72020-09-04 13:06:39 +02004060 if( status != PSA_ERROR_NOT_SUPPORTED ||
4061 psa_key_lifetime_is_external( slot->attr.lifetime ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004062 goto exit;
Steven Cooreman55ae2172020-07-17 19:46:15 +02004063
John Durkop6ba40d12020-11-10 08:50:04 -08004064#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
4065 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskine8e338702019-07-30 20:06:31 +02004066 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004067 {
Steven Cooremana2371e52020-07-28 14:30:39 +02004068 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02004069
Steven Cooreman4fed4552020-08-03 14:46:03 +02004070 status = psa_load_rsa_representation( slot->attr.type,
4071 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02004072 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02004073 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02004074 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004075 goto exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02004076
Steven Cooremana2371e52020-07-28 14:30:39 +02004077 status = psa_rsa_verify( rsa,
Steven Cooremana01795d2020-07-24 22:48:15 +02004078 alg,
4079 hash, hash_length,
4080 signature, signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02004081 mbedtls_rsa_free( rsa );
4082 mbedtls_free( rsa );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004083 goto exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004084 }
4085 else
John Durkop6ba40d12020-11-10 08:50:04 -08004086#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
4087 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
Gilles Peskine8e338702019-07-30 20:06:31 +02004088 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
itayzafrir5c753392018-05-08 11:18:38 +03004089 {
John Durkop9814fa22020-11-04 12:28:15 -08004090#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
4091 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004092 if( PSA_ALG_IS_ECDSA( alg ) )
Steven Cooremanacda8342020-07-24 23:09:52 +02004093 {
Steven Cooremana2371e52020-07-28 14:30:39 +02004094 mbedtls_ecp_keypair *ecp = NULL;
Steven Cooreman4fed4552020-08-03 14:46:03 +02004095 status = psa_load_ecp_representation( slot->attr.type,
4096 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02004097 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02004098 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02004099 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004100 goto exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02004101 status = psa_ecdsa_verify( ecp,
Steven Cooremanacda8342020-07-24 23:09:52 +02004102 hash, hash_length,
4103 signature, signature_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02004104 mbedtls_ecp_keypair_free( ecp );
4105 mbedtls_free( ecp );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004106 goto exit;
Steven Cooremanacda8342020-07-24 23:09:52 +02004107 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004108 else
John Durkop9814fa22020-11-04 12:28:15 -08004109#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
4110 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004111 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004112 status = PSA_ERROR_INVALID_ARGUMENT;
4113 goto exit;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02004114 }
itayzafrir5c753392018-05-08 11:18:38 +03004115 }
Gilles Peskine20035e32018-02-03 22:44:14 +01004116 else
Gilles Peskine20035e32018-02-03 22:44:14 +01004117 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004118 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01004119 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004120
4121exit:
Ronald Cron5c522922020-11-14 16:35:34 +01004122 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004123
Ronald Cron5c522922020-11-14 16:35:34 +01004124 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine20035e32018-02-03 22:44:14 +01004125}
4126
John Durkop0e005192020-10-31 22:06:54 -07004127#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine072ac562018-06-30 00:21:29 +02004128static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
4129 mbedtls_rsa_context *rsa )
4130{
4131 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
4132 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
4133 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
4134 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
4135}
John Durkop0e005192020-10-31 22:06:54 -07004136#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Gilles Peskine072ac562018-06-30 00:21:29 +02004137
Ronald Croncf56a0a2020-08-04 09:51:30 +02004138psa_status_t psa_asymmetric_encrypt( mbedtls_svc_key_id_t key,
Gilles Peskine61b91d42018-06-08 16:09:36 +02004139 psa_algorithm_t alg,
4140 const uint8_t *input,
4141 size_t input_length,
4142 const uint8_t *salt,
4143 size_t salt_length,
4144 uint8_t *output,
4145 size_t output_size,
4146 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004147{
Ronald Cronf95a2b12020-10-22 15:24:49 +02004148 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01004149 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01004150 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004151
Darryl Green5cc689a2018-07-24 15:34:10 +01004152 (void) input;
4153 (void) input_length;
4154 (void) salt;
4155 (void) output;
4156 (void) output_size;
4157
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03004158 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004159
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02004160 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
4161 return( PSA_ERROR_INVALID_ARGUMENT );
4162
Ronald Cron5c522922020-11-14 16:35:34 +01004163 status = psa_get_and_lock_transparent_key_slot_with_policy(
4164 key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004165 if( status != PSA_SUCCESS )
4166 return( status );
Gilles Peskine8e338702019-07-30 20:06:31 +02004167 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) ||
4168 PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004169 {
4170 status = PSA_ERROR_INVALID_ARGUMENT;
4171 goto exit;
4172 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004173
John Durkop6ba40d12020-11-10 08:50:04 -08004174#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
4175 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine8e338702019-07-30 20:06:31 +02004176 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004177 {
Steven Cooremana2371e52020-07-28 14:30:39 +02004178 mbedtls_rsa_context *rsa = NULL;
Steven Cooreman4fed4552020-08-03 14:46:03 +02004179 status = psa_load_rsa_representation( slot->attr.type,
4180 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02004181 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02004182 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02004183 if( status != PSA_SUCCESS )
Steven Cooreman4fed4552020-08-03 14:46:03 +02004184 goto rsa_exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02004185
4186 if( output_size < mbedtls_rsa_get_len( rsa ) )
Steven Cooremana01795d2020-07-24 22:48:15 +02004187 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004188 status = PSA_ERROR_BUFFER_TOO_SMALL;
4189 goto rsa_exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02004190 }
John Durkop0e005192020-10-31 22:06:54 -07004191#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
Gilles Peskine6afe7892018-05-31 13:16:08 +02004192 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004193 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004194 status = mbedtls_to_psa_error(
4195 mbedtls_rsa_pkcs1_encrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004196 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004197 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02004198 MBEDTLS_RSA_PUBLIC,
4199 input_length,
4200 input,
4201 output ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004202 }
4203 else
John Durkop0e005192020-10-31 22:06:54 -07004204#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
4205#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02004206 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004207 {
Steven Cooremana2371e52020-07-28 14:30:39 +02004208 psa_rsa_oaep_set_padding_mode( alg, rsa );
Steven Cooreman4fed4552020-08-03 14:46:03 +02004209 status = mbedtls_to_psa_error(
4210 mbedtls_rsa_rsaes_oaep_encrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004211 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004212 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02004213 MBEDTLS_RSA_PUBLIC,
4214 salt, salt_length,
4215 input_length,
4216 input,
4217 output ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004218 }
4219 else
John Durkop0e005192020-10-31 22:06:54 -07004220#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004221 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004222 status = PSA_ERROR_INVALID_ARGUMENT;
4223 goto rsa_exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004224 }
Steven Cooreman4fed4552020-08-03 14:46:03 +02004225rsa_exit:
4226 if( status == PSA_SUCCESS )
Steven Cooremana2371e52020-07-28 14:30:39 +02004227 *output_length = mbedtls_rsa_get_len( rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02004228
Steven Cooremana2371e52020-07-28 14:30:39 +02004229 mbedtls_rsa_free( rsa );
4230 mbedtls_free( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004231 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004232 else
John Durkop9814fa22020-11-04 12:28:15 -08004233#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
John Durkop6ba40d12020-11-10 08:50:04 -08004234 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004235 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004236 status = PSA_ERROR_NOT_SUPPORTED;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004237 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004238
4239exit:
Ronald Cron5c522922020-11-14 16:35:34 +01004240 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004241
Ronald Cron5c522922020-11-14 16:35:34 +01004242 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004243}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004244
Ronald Croncf56a0a2020-08-04 09:51:30 +02004245psa_status_t psa_asymmetric_decrypt( mbedtls_svc_key_id_t key,
Gilles Peskine61b91d42018-06-08 16:09:36 +02004246 psa_algorithm_t alg,
4247 const uint8_t *input,
4248 size_t input_length,
4249 const uint8_t *salt,
4250 size_t salt_length,
4251 uint8_t *output,
4252 size_t output_size,
4253 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004254{
Ronald Cronf95a2b12020-10-22 15:24:49 +02004255 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01004256 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01004257 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004258
Darryl Green5cc689a2018-07-24 15:34:10 +01004259 (void) input;
4260 (void) input_length;
4261 (void) salt;
4262 (void) output;
4263 (void) output_size;
4264
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03004265 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004266
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02004267 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
4268 return( PSA_ERROR_INVALID_ARGUMENT );
4269
Ronald Cron5c522922020-11-14 16:35:34 +01004270 status = psa_get_and_lock_transparent_key_slot_with_policy(
4271 key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004272 if( status != PSA_SUCCESS )
4273 return( status );
Gilles Peskine8e338702019-07-30 20:06:31 +02004274 if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004275 {
4276 status = PSA_ERROR_INVALID_ARGUMENT;
4277 goto exit;
4278 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004279
John Durkop6ba40d12020-11-10 08:50:04 -08004280#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
4281 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine8e338702019-07-30 20:06:31 +02004282 if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004283 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004284 mbedtls_rsa_context *rsa = NULL;
4285 status = psa_load_rsa_representation( slot->attr.type,
4286 slot->data.key.data,
Steven Cooreman7f391872020-07-30 14:57:44 +02004287 slot->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02004288 &rsa );
Steven Cooremana01795d2020-07-24 22:48:15 +02004289 if( status != PSA_SUCCESS )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004290 goto exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004291
Steven Cooremana2371e52020-07-28 14:30:39 +02004292 if( input_length != mbedtls_rsa_get_len( rsa ) )
Steven Cooremana01795d2020-07-24 22:48:15 +02004293 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004294 status = PSA_ERROR_INVALID_ARGUMENT;
4295 goto rsa_exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02004296 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004297
John Durkop0e005192020-10-31 22:06:54 -07004298#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
Gilles Peskine6afe7892018-05-31 13:16:08 +02004299 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004300 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004301 status = mbedtls_to_psa_error(
4302 mbedtls_rsa_pkcs1_decrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004303 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004304 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02004305 MBEDTLS_RSA_PRIVATE,
4306 output_length,
4307 input,
4308 output,
4309 output_size ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004310 }
4311 else
John Durkop0e005192020-10-31 22:06:54 -07004312#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
4313#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02004314 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004315 {
Steven Cooremana2371e52020-07-28 14:30:39 +02004316 psa_rsa_oaep_set_padding_mode( alg, rsa );
Steven Cooreman4fed4552020-08-03 14:46:03 +02004317 status = mbedtls_to_psa_error(
4318 mbedtls_rsa_rsaes_oaep_decrypt( rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004319 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004320 MBEDTLS_PSA_RANDOM_STATE,
Steven Cooreman4fed4552020-08-03 14:46:03 +02004321 MBEDTLS_RSA_PRIVATE,
4322 salt, salt_length,
4323 output_length,
4324 input,
4325 output,
4326 output_size ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004327 }
4328 else
John Durkop0e005192020-10-31 22:06:54 -07004329#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004330 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02004331 status = PSA_ERROR_INVALID_ARGUMENT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004332 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03004333
Steven Cooreman4fed4552020-08-03 14:46:03 +02004334rsa_exit:
Steven Cooremana2371e52020-07-28 14:30:39 +02004335 mbedtls_rsa_free( rsa );
4336 mbedtls_free( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004337 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004338 else
John Durkop6ba40d12020-11-10 08:50:04 -08004339#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
4340 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004341 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004342 status = PSA_ERROR_NOT_SUPPORTED;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004343 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004344
4345exit:
Ronald Cron5c522922020-11-14 16:35:34 +01004346 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004347
Ronald Cron5c522922020-11-14 16:35:34 +01004348 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004349}
Gilles Peskine20035e32018-02-03 22:44:14 +01004350
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004351
4352
mohammad1603503973b2018-03-12 15:59:30 +02004353/****************************************************************/
4354/* Symmetric cryptography */
4355/****************************************************************/
4356
Gilles Peskinee553c652018-06-04 16:22:46 +02004357static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004358 mbedtls_svc_key_id_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02004359 psa_algorithm_t alg,
4360 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02004361{
Ronald Cronf95a2b12020-10-22 15:24:49 +02004362 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01004363 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004364 int ret = 0;
Gilles Peskine2f060a82018-12-04 17:12:32 +01004365 psa_key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02004366 size_t key_bits;
4367 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004368 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
4369 PSA_KEY_USAGE_ENCRYPT :
4370 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02004371
Steven Cooremand3feccd2020-09-01 15:56:14 +02004372 /* A context must be freshly initialized before it can be set up. */
4373 if( operation->alg != 0 )
4374 return( PSA_ERROR_BAD_STATE );
4375
Steven Cooremana07b9972020-09-10 14:54:14 +02004376 /* The requested algorithm must be one that can be processed by cipher. */
4377 if( ! PSA_ALG_IS_CIPHER( alg ) )
Steven Cooremana07b9972020-09-10 14:54:14 +02004378 return( PSA_ERROR_INVALID_ARGUMENT );
Steven Cooremand3feccd2020-09-01 15:56:14 +02004379
Steven Cooremanef8575e2020-09-11 11:44:50 +02004380 /* Fetch key material from key storage. */
Ronald Cron5c522922020-11-14 16:35:34 +01004381 status = psa_get_and_lock_key_slot_with_policy( key, &slot, usage, alg );
Steven Cooremanef8575e2020-09-11 11:44:50 +02004382 if( status != PSA_SUCCESS )
4383 goto exit;
4384
4385 /* Initialize the operation struct members, except for alg. The alg member
4386 * is used to indicate to psa_cipher_abort that there are resources to free,
4387 * so we only set it after resources have been allocated/initialized. */
Steven Cooremana07b9972020-09-10 14:54:14 +02004388 operation->key_set = 0;
4389 operation->iv_set = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004390 operation->mbedtls_in_use = 0;
Steven Cooremana07b9972020-09-10 14:54:14 +02004391 operation->iv_size = 0;
4392 operation->block_size = 0;
4393 if( alg == PSA_ALG_ECB_NO_PADDING )
4394 operation->iv_required = 0;
4395 else
4396 operation->iv_required = 1;
4397
Steven Cooremana07b9972020-09-10 14:54:14 +02004398 /* Try doing the operation through a driver before using software fallback. */
Steven Cooreman37941cb2020-07-28 18:49:51 +02004399 if( cipher_operation == MBEDTLS_ENCRYPT )
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004400 status = psa_driver_wrapper_cipher_encrypt_setup( &operation->ctx.driver,
Steven Cooreman37941cb2020-07-28 18:49:51 +02004401 slot,
4402 alg );
4403 else
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004404 status = psa_driver_wrapper_cipher_decrypt_setup( &operation->ctx.driver,
Steven Cooreman37941cb2020-07-28 18:49:51 +02004405 slot,
4406 alg );
4407
Steven Cooremanef8575e2020-09-11 11:44:50 +02004408 if( status == PSA_SUCCESS )
Steven Cooreman6d81f7e2020-09-14 13:14:31 +02004409 {
Steven Cooremanef8575e2020-09-11 11:44:50 +02004410 /* Once the driver context is initialised, it needs to be freed using
4411 * psa_cipher_abort. Indicate this through setting alg. */
4412 operation->alg = alg;
Steven Cooreman6d81f7e2020-09-14 13:14:31 +02004413 }
Steven Cooremanef8575e2020-09-11 11:44:50 +02004414
Steven Cooremand3feccd2020-09-01 15:56:14 +02004415 if( status != PSA_ERROR_NOT_SUPPORTED ||
4416 psa_key_lifetime_is_external( slot->attr.lifetime ) )
4417 goto exit;
4418
Steven Cooremana07b9972020-09-10 14:54:14 +02004419 /* Proceed with initializing an mbed TLS cipher context if no driver is
Steven Cooremand3feccd2020-09-01 15:56:14 +02004420 * available for the given algorithm & key. */
4421 mbedtls_cipher_init( &operation->ctx.cipher );
mohammad1603503973b2018-03-12 15:59:30 +02004422
Steven Cooremana07b9972020-09-10 14:54:14 +02004423 /* Once the cipher context is initialised, it needs to be freed using
Steven Cooremanef8575e2020-09-11 11:44:50 +02004424 * psa_cipher_abort. Indicate there is something to be freed through setting
4425 * alg, and indicate the operation is being done using mbedtls crypto through
4426 * setting mbedtls_in_use. */
Steven Cooremana07b9972020-09-10 14:54:14 +02004427 operation->alg = alg;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004428 operation->mbedtls_in_use = 1;
Steven Cooremana07b9972020-09-10 14:54:14 +02004429
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02004430 key_bits = psa_get_key_slot_bits( slot );
Gilles Peskine8e338702019-07-30 20:06:31 +02004431 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->attr.type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02004432 if( cipher_info == NULL )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004433 {
4434 status = PSA_ERROR_NOT_SUPPORTED;
4435 goto exit;
4436 }
mohammad1603503973b2018-03-12 15:59:30 +02004437
mohammad1603503973b2018-03-12 15:59:30 +02004438 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03004439 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004440 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004441
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004442#if defined(MBEDTLS_DES_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02004443 if( slot->attr.type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004444 {
4445 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02004446 uint8_t keys[24];
Steven Cooreman71fd80d2020-07-07 21:12:27 +02004447 memcpy( keys, slot->data.key.data, 16 );
4448 memcpy( keys + 16, slot->data.key.data, 8 );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004449 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
4450 keys,
4451 192, cipher_operation );
4452 }
4453 else
4454#endif
4455 {
4456 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02004457 slot->data.key.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004458 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02004459 }
Moran Peker41deec42018-04-04 15:43:05 +03004460 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004461 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004462
mohammad16038481e742018-03-18 13:57:31 +02004463#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004464 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02004465 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004466 case PSA_ALG_CBC_NO_PADDING:
4467 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
4468 MBEDTLS_PADDING_NONE );
4469 break;
4470 case PSA_ALG_CBC_PKCS7:
4471 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
4472 MBEDTLS_PADDING_PKCS7 );
4473 break;
4474 default:
4475 /* The algorithm doesn't involve padding. */
4476 ret = 0;
4477 break;
4478 }
4479 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004480 goto exit;
mohammad16038481e742018-03-18 13:57:31 +02004481#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
4482
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004483 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
Gilles Peskine8e338702019-07-30 20:06:31 +02004484 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ) );
Steven Cooremana6033e92020-08-25 11:47:50 +02004485 if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 &&
4486 alg != PSA_ALG_ECB_NO_PADDING )
mohammad16038481e742018-03-18 13:57:31 +02004487 {
Gilles Peskine8e338702019-07-30 20:06:31 +02004488 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type );
mohammad16038481e742018-03-18 13:57:31 +02004489 }
Gilles Peskine26869f22019-05-06 15:25:00 +02004490#if defined(MBEDTLS_CHACHA20_C)
4491 else
Bence Szépkúticbe39532020-12-08 00:01:31 +01004492 if( alg == PSA_ALG_STREAM_CIPHER && slot->attr.type == PSA_KEY_TYPE_CHACHA20 )
Gilles Peskine26869f22019-05-06 15:25:00 +02004493 operation->iv_size = 12;
4494#endif
mohammad1603503973b2018-03-12 15:59:30 +02004495
Steven Cooreman7df02922020-09-09 15:28:49 +02004496 status = PSA_SUCCESS;
4497
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004498exit:
Steven Cooreman7df02922020-09-09 15:28:49 +02004499 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004500 status = mbedtls_to_psa_error( ret );
Steven Cooreman7df02922020-09-09 15:28:49 +02004501 if( status == PSA_SUCCESS )
4502 {
4503 /* Update operation flags for both driver and software implementations */
4504 operation->key_set = 1;
4505 }
4506 else
Gilles Peskine9ab61b62019-02-25 17:43:14 +01004507 psa_cipher_abort( operation );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004508
Ronald Cron5c522922020-11-14 16:35:34 +01004509 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02004510
Ronald Cron5c522922020-11-14 16:35:34 +01004511 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
mohammad1603503973b2018-03-12 15:59:30 +02004512}
4513
Gilles Peskinefe119512018-07-08 21:39:34 +02004514psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004515 mbedtls_svc_key_id_t key,
Gilles Peskinefe119512018-07-08 21:39:34 +02004516 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02004517{
Ronald Croncf56a0a2020-08-04 09:51:30 +02004518 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02004519}
4520
Gilles Peskinefe119512018-07-08 21:39:34 +02004521psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004522 mbedtls_svc_key_id_t key,
Gilles Peskinefe119512018-07-08 21:39:34 +02004523 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02004524{
Ronald Croncf56a0a2020-08-04 09:51:30 +02004525 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02004526}
4527
Gilles Peskinefe119512018-07-08 21:39:34 +02004528psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004529 uint8_t *iv,
Gilles Peskinefe119512018-07-08 21:39:34 +02004530 size_t iv_size,
4531 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02004532{
itayzafrir534bd7c2018-08-02 13:56:32 +03004533 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00004534 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooreman7df02922020-09-09 15:28:49 +02004535 if( operation->iv_set || ! operation->iv_required )
4536 {
4537 return( PSA_ERROR_BAD_STATE );
4538 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004539
Steven Cooremanef8575e2020-09-11 11:44:50 +02004540 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004541 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004542 status = psa_driver_wrapper_cipher_generate_iv( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004543 iv,
4544 iv_size,
4545 iv_length );
4546 goto exit;
4547 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004548
Moran Peker41deec42018-04-04 15:43:05 +03004549 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02004550 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004551 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03004552 goto exit;
4553 }
Gilles Peskine5894e8e2020-12-14 14:54:06 +01004554 ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine30524eb2020-11-13 17:02:26 +01004555 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03004556 if( ret != 0 )
4557 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004558 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02004559 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02004560 }
Gilles Peskinee553c652018-06-04 16:22:46 +02004561
mohammad16038481e742018-03-18 13:57:31 +02004562 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03004563 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03004564
Moran Peker395db872018-05-31 14:07:14 +03004565exit:
Steven Cooreman7df02922020-09-09 15:28:49 +02004566 if( status == PSA_SUCCESS )
4567 operation->iv_set = 1;
4568 else
Moran Peker395db872018-05-31 14:07:14 +03004569 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004570 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004571}
4572
Gilles Peskinefe119512018-07-08 21:39:34 +02004573psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004574 const uint8_t *iv,
Gilles Peskinefe119512018-07-08 21:39:34 +02004575 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02004576{
itayzafrir534bd7c2018-08-02 13:56:32 +03004577 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00004578 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooreman7df02922020-09-09 15:28:49 +02004579 if( operation->iv_set || ! operation->iv_required )
4580 {
4581 return( PSA_ERROR_BAD_STATE );
4582 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004583
Steven Cooremanef8575e2020-09-11 11:44:50 +02004584 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004585 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004586 status = psa_driver_wrapper_cipher_set_iv( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004587 iv,
4588 iv_length );
4589 goto exit;
4590 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004591
Moran Pekera28258c2018-05-29 16:25:04 +03004592 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03004593 {
itayzafrir534bd7c2018-08-02 13:56:32 +03004594 status = PSA_ERROR_INVALID_ARGUMENT;
4595 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03004596 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004597 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
4598 status = mbedtls_to_psa_error( ret );
4599exit:
4600 if( status == PSA_SUCCESS )
4601 operation->iv_set = 1;
4602 else
mohammad1603503973b2018-03-12 15:59:30 +02004603 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004604 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004605}
4606
Steven Cooreman177deba2020-09-07 17:14:14 +02004607/* Process input for which the algorithm is set to ECB mode. This requires
4608 * manual processing, since the PSA API is defined as being able to process
4609 * arbitrary-length calls to psa_cipher_update() with ECB mode, but the
4610 * underlying mbedtls_cipher_update only takes full blocks. */
4611static psa_status_t psa_cipher_update_ecb_internal(
4612 mbedtls_cipher_context_t *ctx,
4613 const uint8_t *input,
4614 size_t input_length,
4615 uint8_t *output,
4616 size_t output_size,
4617 size_t *output_length )
4618{
4619 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
4620 size_t block_size = ctx->cipher_info->block_size;
4621 size_t internal_output_length = 0;
4622 *output_length = 0;
4623
4624 if( input_length == 0 )
4625 {
4626 status = PSA_SUCCESS;
4627 goto exit;
4628 }
4629
4630 if( ctx->unprocessed_len > 0 )
4631 {
4632 /* Fill up to block size, and run the block if there's a full one. */
4633 size_t bytes_to_copy = block_size - ctx->unprocessed_len;
4634
4635 if( input_length < bytes_to_copy )
4636 bytes_to_copy = input_length;
4637
4638 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
4639 input, bytes_to_copy );
4640 input_length -= bytes_to_copy;
4641 input += bytes_to_copy;
4642 ctx->unprocessed_len += bytes_to_copy;
4643
4644 if( ctx->unprocessed_len == block_size )
4645 {
4646 status = mbedtls_to_psa_error(
4647 mbedtls_cipher_update( ctx,
4648 ctx->unprocessed_data,
4649 block_size,
4650 output, &internal_output_length ) );
4651
4652 if( status != PSA_SUCCESS )
4653 goto exit;
4654
4655 output += internal_output_length;
4656 output_size -= internal_output_length;
4657 *output_length += internal_output_length;
4658 ctx->unprocessed_len = 0;
4659 }
4660 }
4661
4662 while( input_length >= block_size )
4663 {
4664 /* Run all full blocks we have, one by one */
4665 status = mbedtls_to_psa_error(
4666 mbedtls_cipher_update( ctx, input,
4667 block_size,
4668 output, &internal_output_length ) );
4669
4670 if( status != PSA_SUCCESS )
4671 goto exit;
4672
4673 input_length -= block_size;
4674 input += block_size;
4675
4676 output += internal_output_length;
4677 output_size -= internal_output_length;
4678 *output_length += internal_output_length;
4679 }
4680
4681 if( input_length > 0 )
4682 {
4683 /* Save unprocessed bytes for later processing */
4684 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
4685 input, input_length );
4686 ctx->unprocessed_len += input_length;
4687 }
4688
4689 status = PSA_SUCCESS;
4690
4691exit:
4692 return( status );
4693}
4694
Gilles Peskinee553c652018-06-04 16:22:46 +02004695psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
4696 const uint8_t *input,
4697 size_t input_length,
Andrew Thoelke163639b2019-05-15 12:33:23 +01004698 uint8_t *output,
Gilles Peskinee553c652018-06-04 16:22:46 +02004699 size_t output_size,
4700 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02004701{
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004702 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine89d789c2018-06-04 17:17:16 +02004703 size_t expected_output_size;
Steven Cooreman7df02922020-09-09 15:28:49 +02004704 if( operation->alg == 0 )
4705 {
4706 return( PSA_ERROR_BAD_STATE );
4707 }
4708 if( operation->iv_required && ! operation->iv_set )
4709 {
4710 return( PSA_ERROR_BAD_STATE );
4711 }
Jaeden Ameroab439972019-02-15 14:12:05 +00004712
Steven Cooremanef8575e2020-09-11 11:44:50 +02004713 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004714 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004715 status = psa_driver_wrapper_cipher_update( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004716 input,
4717 input_length,
4718 output,
4719 output_size,
4720 output_length );
4721 goto exit;
4722 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004723
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004724 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02004725 {
4726 /* Take the unprocessed partial block left over from previous
4727 * update calls, if any, plus the input to this call. Remove
4728 * the last partial block, if any. You get the data that will be
4729 * output in this call. */
4730 expected_output_size =
4731 ( operation->ctx.cipher.unprocessed_len + input_length )
4732 / operation->block_size * operation->block_size;
4733 }
4734 else
4735 {
4736 expected_output_size = input_length;
4737 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004738
Gilles Peskine89d789c2018-06-04 17:17:16 +02004739 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03004740 {
4741 status = PSA_ERROR_BUFFER_TOO_SMALL;
4742 goto exit;
4743 }
mohammad160382759612018-03-12 18:16:40 +02004744
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004745 if( operation->alg == PSA_ALG_ECB_NO_PADDING )
4746 {
4747 /* mbedtls_cipher_update has an API inconsistency: it will only
4748 * process a single block at a time in ECB mode. Abstract away that
4749 * inconsistency here to match the PSA API behaviour. */
Steven Cooreman177deba2020-09-07 17:14:14 +02004750 status = psa_cipher_update_ecb_internal( &operation->ctx.cipher,
4751 input,
4752 input_length,
4753 output,
4754 output_size,
4755 output_length );
Steven Cooremanffecb7b2020-08-25 15:13:13 +02004756 }
4757 else
4758 {
4759 status = mbedtls_to_psa_error(
4760 mbedtls_cipher_update( &operation->ctx.cipher, input,
4761 input_length, output, output_length ) );
4762 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004763exit:
4764 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02004765 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004766 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004767}
4768
Gilles Peskinee553c652018-06-04 16:22:46 +02004769psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
4770 uint8_t *output,
4771 size_t output_size,
4772 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02004773{
David Saadab4ecc272019-02-14 13:48:10 +02004774 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskinee553c652018-06-04 16:22:46 +02004775 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Steven Cooreman7df02922020-09-09 15:28:49 +02004776 if( operation->alg == 0 )
4777 {
4778 return( PSA_ERROR_BAD_STATE );
4779 }
4780 if( operation->iv_required && ! operation->iv_set )
4781 {
4782 return( PSA_ERROR_BAD_STATE );
4783 }
Moran Pekerbed71a22018-04-22 20:19:20 +03004784
Steven Cooremanef8575e2020-09-11 11:44:50 +02004785 if( operation->mbedtls_in_use == 0 )
Steven Cooreman8b122252020-09-03 15:30:32 +02004786 {
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004787 status = psa_driver_wrapper_cipher_finish( &operation->ctx.driver,
Steven Cooreman8b122252020-09-03 15:30:32 +02004788 output,
4789 output_size,
4790 output_length );
Steven Cooremanef8575e2020-09-11 11:44:50 +02004791 goto exit;
Steven Cooreman8b122252020-09-03 15:30:32 +02004792 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02004793
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004794 if( operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03004795 {
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004796 if( operation->alg == PSA_ALG_ECB_NO_PADDING ||
Fredrik Strupef90e3012020-09-28 16:11:33 +02004797 operation->alg == PSA_ALG_CBC_NO_PADDING )
Steven Cooremana6033e92020-08-25 11:47:50 +02004798 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004799 status = PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004800 goto exit;
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02004801 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004802 }
4803
Steven Cooremanef8575e2020-09-11 11:44:50 +02004804 status = mbedtls_to_psa_error(
4805 mbedtls_cipher_finish( &operation->ctx.cipher,
4806 temp_output_buffer,
4807 output_length ) );
4808 if( status != PSA_SUCCESS )
4809 goto exit;
Janos Follath315b51c2018-07-09 16:04:51 +01004810
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004811 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01004812 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004813 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004814 memcpy( output, temp_output_buffer, *output_length );
4815 else
Janos Follath315b51c2018-07-09 16:04:51 +01004816 status = PSA_ERROR_BUFFER_TOO_SMALL;
mohammad1603503973b2018-03-12 15:59:30 +02004817
Steven Cooremanef8575e2020-09-11 11:44:50 +02004818exit:
4819 if( operation->mbedtls_in_use == 1 )
4820 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01004821
Steven Cooremanef8575e2020-09-11 11:44:50 +02004822 if( status == PSA_SUCCESS )
4823 return( psa_cipher_abort( operation ) );
4824 else
4825 {
4826 *output_length = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004827 (void) psa_cipher_abort( operation );
Janos Follath315b51c2018-07-09 16:04:51 +01004828
Steven Cooremanef8575e2020-09-11 11:44:50 +02004829 return( status );
4830 }
mohammad1603503973b2018-03-12 15:59:30 +02004831}
4832
Gilles Peskinee553c652018-06-04 16:22:46 +02004833psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
4834{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004835 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02004836 {
Steven Cooremana07b9972020-09-10 14:54:14 +02004837 /* The object has (apparently) been initialized but it is not (yet)
Gilles Peskine81736312018-06-26 15:04:31 +02004838 * in use. It's ok to call abort on such an object, and there's
4839 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004840 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02004841 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004842
Gilles Peskinef9c2c092018-06-21 16:57:07 +02004843 /* Sanity check (shouldn't happen: operation->alg should
4844 * always have been initialized to a valid value). */
4845 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
4846 return( PSA_ERROR_BAD_STATE );
4847
Steven Cooremanef8575e2020-09-11 11:44:50 +02004848 if( operation->mbedtls_in_use == 0 )
Steven Cooremanfb81aa52020-09-09 12:01:43 +02004849 psa_driver_wrapper_cipher_abort( &operation->ctx.driver );
Steven Cooremand3feccd2020-09-01 15:56:14 +02004850 else
4851 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02004852
Moran Peker41deec42018-04-04 15:43:05 +03004853 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004854 operation->key_set = 0;
4855 operation->iv_set = 0;
Steven Cooremanef8575e2020-09-11 11:44:50 +02004856 operation->mbedtls_in_use = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004857 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03004858 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004859 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03004860
Moran Peker395db872018-05-31 14:07:14 +03004861 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02004862}
4863
Gilles Peskinea0655c32018-04-30 17:06:50 +02004864
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004865
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004866
mohammad16035955c982018-04-26 00:53:03 +03004867/****************************************************************/
4868/* AEAD */
4869/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004870
Gilles Peskineedf9a652018-08-17 18:11:56 +02004871typedef struct
4872{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004873 psa_key_slot_t *slot;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004874 const mbedtls_cipher_info_t *cipher_info;
4875 union
4876 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02004877 unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
Gilles Peskineedf9a652018-08-17 18:11:56 +02004878#if defined(MBEDTLS_CCM_C)
4879 mbedtls_ccm_context ccm;
4880#endif /* MBEDTLS_CCM_C */
4881#if defined(MBEDTLS_GCM_C)
4882 mbedtls_gcm_context gcm;
4883#endif /* MBEDTLS_GCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02004884#if defined(MBEDTLS_CHACHAPOLY_C)
4885 mbedtls_chachapoly_context chachapoly;
4886#endif /* MBEDTLS_CHACHAPOLY_C */
Gilles Peskineedf9a652018-08-17 18:11:56 +02004887 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004888 psa_algorithm_t core_alg;
4889 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004890 uint8_t tag_length;
4891} aead_operation_t;
4892
Ronald Cronf95a2b12020-10-22 15:24:49 +02004893#define AEAD_OPERATION_INIT {0, 0, {0}, 0, 0, 0}
4894
Gilles Peskine30a9e412019-01-14 18:36:12 +01004895static void psa_aead_abort_internal( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004896{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02004897 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004898 {
4899#if defined(MBEDTLS_CCM_C)
4900 case PSA_ALG_CCM:
4901 mbedtls_ccm_free( &operation->ctx.ccm );
4902 break;
4903#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004904#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02004905 case PSA_ALG_GCM:
4906 mbedtls_gcm_free( &operation->ctx.gcm );
4907 break;
4908#endif /* MBEDTLS_GCM_C */
4909 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004910
Ronald Cron5c522922020-11-14 16:35:34 +01004911 psa_unlock_key_slot( operation->slot );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004912}
4913
4914static psa_status_t psa_aead_setup( aead_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02004915 mbedtls_svc_key_id_t key,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004916 psa_key_usage_t usage,
4917 psa_algorithm_t alg )
4918{
4919 psa_status_t status;
4920 size_t key_bits;
4921 mbedtls_cipher_id_t cipher_id;
4922
Ronald Cron5c522922020-11-14 16:35:34 +01004923 status = psa_get_and_lock_transparent_key_slot_with_policy(
4924 key, &operation->slot, usage, alg );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004925 if( status != PSA_SUCCESS )
4926 return( status );
4927
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02004928 key_bits = psa_get_key_slot_bits( operation->slot );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004929
4930 operation->cipher_info =
Gilles Peskine8e338702019-07-30 20:06:31 +02004931 mbedtls_cipher_info_from_psa( alg, operation->slot->attr.type, key_bits,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004932 &cipher_id );
4933 if( operation->cipher_info == NULL )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004934 {
4935 status = PSA_ERROR_NOT_SUPPORTED;
4936 goto cleanup;
4937 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004938
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004939 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004940 {
4941#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004942 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
4943 operation->core_alg = PSA_ALG_CCM;
4944 operation->full_tag_length = 16;
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004945 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
4946 * The call to mbedtls_ccm_encrypt_and_tag or
4947 * mbedtls_ccm_auth_decrypt will validate the tag length. */
Gilles Peskine8e338702019-07-30 20:06:31 +02004948 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004949 {
4950 status = PSA_ERROR_INVALID_ARGUMENT;
4951 goto cleanup;
4952 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004953 mbedtls_ccm_init( &operation->ctx.ccm );
4954 status = mbedtls_to_psa_error(
4955 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02004956 operation->slot->data.key.data,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004957 (unsigned int) key_bits ) );
4958 if( status != 0 )
4959 goto cleanup;
4960 break;
4961#endif /* MBEDTLS_CCM_C */
4962
4963#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004964 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
4965 operation->core_alg = PSA_ALG_GCM;
4966 operation->full_tag_length = 16;
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004967 /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
4968 * The call to mbedtls_gcm_crypt_and_tag or
4969 * mbedtls_gcm_auth_decrypt will validate the tag length. */
Gilles Peskine8e338702019-07-30 20:06:31 +02004970 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004971 {
4972 status = PSA_ERROR_INVALID_ARGUMENT;
4973 goto cleanup;
4974 }
Gilles Peskineedf9a652018-08-17 18:11:56 +02004975 mbedtls_gcm_init( &operation->ctx.gcm );
4976 status = mbedtls_to_psa_error(
4977 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02004978 operation->slot->data.key.data,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004979 (unsigned int) key_bits ) );
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004980 if( status != 0 )
4981 goto cleanup;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004982 break;
4983#endif /* MBEDTLS_GCM_C */
4984
Gilles Peskine26869f22019-05-06 15:25:00 +02004985#if defined(MBEDTLS_CHACHAPOLY_C)
4986 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CHACHA20_POLY1305, 0 ):
4987 operation->core_alg = PSA_ALG_CHACHA20_POLY1305;
4988 operation->full_tag_length = 16;
4989 /* We only support the default tag length. */
4990 if( alg != PSA_ALG_CHACHA20_POLY1305 )
Ronald Cronf95a2b12020-10-22 15:24:49 +02004991 {
4992 status = PSA_ERROR_NOT_SUPPORTED;
4993 goto cleanup;
4994 }
Gilles Peskine26869f22019-05-06 15:25:00 +02004995 mbedtls_chachapoly_init( &operation->ctx.chachapoly );
4996 status = mbedtls_to_psa_error(
4997 mbedtls_chachapoly_setkey( &operation->ctx.chachapoly,
Steven Cooreman71fd80d2020-07-07 21:12:27 +02004998 operation->slot->data.key.data ) );
Gilles Peskine26869f22019-05-06 15:25:00 +02004999 if( status != 0 )
5000 goto cleanup;
5001 break;
5002#endif /* MBEDTLS_CHACHAPOLY_C */
5003
Gilles Peskineedf9a652018-08-17 18:11:56 +02005004 default:
Ronald Cronf95a2b12020-10-22 15:24:49 +02005005 status = PSA_ERROR_NOT_SUPPORTED;
5006 goto cleanup;
Gilles Peskineedf9a652018-08-17 18:11:56 +02005007 }
5008
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02005009 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
5010 {
5011 status = PSA_ERROR_INVALID_ARGUMENT;
5012 goto cleanup;
5013 }
5014 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02005015
Gilles Peskineedf9a652018-08-17 18:11:56 +02005016 return( PSA_SUCCESS );
5017
5018cleanup:
Gilles Peskine30a9e412019-01-14 18:36:12 +01005019 psa_aead_abort_internal( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02005020 return( status );
5021}
5022
Ronald Croncf56a0a2020-08-04 09:51:30 +02005023psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key,
mohammad16035955c982018-04-26 00:53:03 +03005024 psa_algorithm_t alg,
5025 const uint8_t *nonce,
5026 size_t nonce_length,
5027 const uint8_t *additional_data,
5028 size_t additional_data_length,
5029 const uint8_t *plaintext,
5030 size_t plaintext_length,
5031 uint8_t *ciphertext,
5032 size_t ciphertext_size,
5033 size_t *ciphertext_length )
5034{
mohammad16035955c982018-04-26 00:53:03 +03005035 psa_status_t status;
Ronald Cronf95a2b12020-10-22 15:24:49 +02005036 aead_operation_t operation = AEAD_OPERATION_INIT;
mohammad160315223a82018-06-03 17:19:55 +03005037 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02005038
mohammad1603f08a5502018-06-03 15:05:47 +03005039 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07005040
Ronald Croncf56a0a2020-08-04 09:51:30 +02005041 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02005042 if( status != PSA_SUCCESS )
5043 return( status );
mohammad16035955c982018-04-26 00:53:03 +03005044
Gilles Peskineedf9a652018-08-17 18:11:56 +02005045 /* For all currently supported modes, the tag is at the end of the
5046 * ciphertext. */
5047 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
5048 {
5049 status = PSA_ERROR_BUFFER_TOO_SMALL;
5050 goto exit;
5051 }
5052 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03005053
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005054#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02005055 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03005056 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02005057 status = mbedtls_to_psa_error(
5058 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
5059 MBEDTLS_GCM_ENCRYPT,
5060 plaintext_length,
5061 nonce, nonce_length,
5062 additional_data, additional_data_length,
5063 plaintext, ciphertext,
5064 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03005065 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005066 else
5067#endif /* MBEDTLS_GCM_C */
5068#if defined(MBEDTLS_CCM_C)
5069 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03005070 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02005071 status = mbedtls_to_psa_error(
5072 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
5073 plaintext_length,
5074 nonce, nonce_length,
5075 additional_data,
5076 additional_data_length,
5077 plaintext, ciphertext,
5078 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03005079 }
mohammad16035c8845f2018-05-09 05:40:09 -07005080 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005081#endif /* MBEDTLS_CCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02005082#if defined(MBEDTLS_CHACHAPOLY_C)
5083 if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
5084 {
5085 if( nonce_length != 12 || operation.tag_length != 16 )
5086 {
5087 status = PSA_ERROR_NOT_SUPPORTED;
5088 goto exit;
5089 }
5090 status = mbedtls_to_psa_error(
5091 mbedtls_chachapoly_encrypt_and_tag( &operation.ctx.chachapoly,
5092 plaintext_length,
5093 nonce,
5094 additional_data,
5095 additional_data_length,
5096 plaintext,
5097 ciphertext,
5098 tag ) );
5099 }
5100 else
5101#endif /* MBEDTLS_CHACHAPOLY_C */
mohammad16035c8845f2018-05-09 05:40:09 -07005102 {
mohammad1603554faad2018-06-03 15:07:38 +03005103 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07005104 }
Gilles Peskine2d277862018-06-18 15:41:12 +02005105
Gilles Peskineedf9a652018-08-17 18:11:56 +02005106 if( status != PSA_SUCCESS && ciphertext_size != 0 )
5107 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02005108
Gilles Peskineedf9a652018-08-17 18:11:56 +02005109exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01005110 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02005111 if( status == PSA_SUCCESS )
5112 *ciphertext_length = plaintext_length + operation.tag_length;
5113 return( status );
mohammad16035955c982018-04-26 00:53:03 +03005114}
5115
Gilles Peskineee652a32018-06-01 19:23:52 +02005116/* Locate the tag in a ciphertext buffer containing the encrypted data
5117 * followed by the tag. Return the length of the part preceding the tag in
5118 * *plaintext_length. This is the size of the plaintext in modes where
5119 * the encrypted data has the same size as the plaintext, such as
5120 * CCM and GCM. */
5121static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
5122 const uint8_t *ciphertext,
5123 size_t ciphertext_length,
5124 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02005125 const uint8_t **p_tag )
5126{
5127 size_t payload_length;
5128 if( tag_length > ciphertext_length )
5129 return( PSA_ERROR_INVALID_ARGUMENT );
5130 payload_length = ciphertext_length - tag_length;
5131 if( payload_length > plaintext_size )
5132 return( PSA_ERROR_BUFFER_TOO_SMALL );
5133 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02005134 return( PSA_SUCCESS );
5135}
5136
Ronald Croncf56a0a2020-08-04 09:51:30 +02005137psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key,
mohammad16035955c982018-04-26 00:53:03 +03005138 psa_algorithm_t alg,
5139 const uint8_t *nonce,
5140 size_t nonce_length,
5141 const uint8_t *additional_data,
5142 size_t additional_data_length,
5143 const uint8_t *ciphertext,
5144 size_t ciphertext_length,
5145 uint8_t *plaintext,
5146 size_t plaintext_size,
5147 size_t *plaintext_length )
5148{
mohammad16035955c982018-04-26 00:53:03 +03005149 psa_status_t status;
Ronald Cronf95a2b12020-10-22 15:24:49 +02005150 aead_operation_t operation = AEAD_OPERATION_INIT;
Gilles Peskineedf9a652018-08-17 18:11:56 +02005151 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02005152
Gilles Peskineee652a32018-06-01 19:23:52 +02005153 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03005154
Ronald Croncf56a0a2020-08-04 09:51:30 +02005155 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02005156 if( status != PSA_SUCCESS )
5157 return( status );
mohammad16035955c982018-04-26 00:53:03 +03005158
Gilles Peskinef7e7b012019-05-06 15:27:16 +02005159 status = psa_aead_unpadded_locate_tag( operation.tag_length,
5160 ciphertext, ciphertext_length,
5161 plaintext_size, &tag );
5162 if( status != PSA_SUCCESS )
5163 goto exit;
5164
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005165#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02005166 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03005167 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02005168 status = mbedtls_to_psa_error(
5169 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
5170 ciphertext_length - operation.tag_length,
5171 nonce, nonce_length,
5172 additional_data,
5173 additional_data_length,
5174 tag, operation.tag_length,
5175 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03005176 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005177 else
5178#endif /* MBEDTLS_GCM_C */
5179#if defined(MBEDTLS_CCM_C)
5180 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03005181 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02005182 status = mbedtls_to_psa_error(
5183 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
5184 ciphertext_length - operation.tag_length,
5185 nonce, nonce_length,
5186 additional_data,
5187 additional_data_length,
5188 ciphertext, plaintext,
5189 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03005190 }
mohammad160339574652018-06-01 04:39:53 -07005191 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01005192#endif /* MBEDTLS_CCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02005193#if defined(MBEDTLS_CHACHAPOLY_C)
5194 if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
5195 {
5196 if( nonce_length != 12 || operation.tag_length != 16 )
5197 {
5198 status = PSA_ERROR_NOT_SUPPORTED;
5199 goto exit;
5200 }
5201 status = mbedtls_to_psa_error(
5202 mbedtls_chachapoly_auth_decrypt( &operation.ctx.chachapoly,
5203 ciphertext_length - operation.tag_length,
5204 nonce,
5205 additional_data,
5206 additional_data_length,
5207 tag,
5208 ciphertext,
5209 plaintext ) );
5210 }
5211 else
5212#endif /* MBEDTLS_CHACHAPOLY_C */
mohammad160339574652018-06-01 04:39:53 -07005213 {
mohammad1603554faad2018-06-03 15:07:38 +03005214 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07005215 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02005216
Gilles Peskineedf9a652018-08-17 18:11:56 +02005217 if( status != PSA_SUCCESS && plaintext_size != 0 )
5218 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03005219
Gilles Peskineedf9a652018-08-17 18:11:56 +02005220exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01005221 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02005222 if( status == PSA_SUCCESS )
5223 *plaintext_length = ciphertext_length - operation.tag_length;
5224 return( status );
mohammad16035955c982018-04-26 00:53:03 +03005225}
5226
Gilles Peskinea0655c32018-04-30 17:06:50 +02005227
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02005228
Gilles Peskine20035e32018-02-03 22:44:14 +01005229/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02005230/* Generators */
5231/****************************************************************/
5232
John Durkop07cc04a2020-11-16 22:08:34 -08005233#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
5234 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5235 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5236#define AT_LEAST_ONE_BUILTIN_KDF
5237#endif
5238
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005239#define HKDF_STATE_INIT 0 /* no input yet */
5240#define HKDF_STATE_STARTED 1 /* got salt */
5241#define HKDF_STATE_KEYED 2 /* got key */
5242#define HKDF_STATE_OUTPUT 3 /* output started */
5243
Gilles Peskinecbe66502019-05-16 16:59:18 +02005244static psa_algorithm_t psa_key_derivation_get_kdf_alg(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005245 const psa_key_derivation_operation_t *operation )
Gilles Peskine969c5d62019-01-16 15:53:06 +01005246{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005247 if ( PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
5248 return( PSA_ALG_KEY_AGREEMENT_GET_KDF( operation->alg ) );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005249 else
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005250 return( operation->alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005251}
5252
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005253psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005254{
5255 psa_status_t status = PSA_SUCCESS;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005256 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005257 if( kdf_alg == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005258 {
5259 /* The object has (apparently) been initialized but it is not
5260 * in use. It's ok to call abort on such an object, and there's
5261 * nothing to do. */
5262 }
5263 else
John Durkopd0321952020-10-29 21:37:36 -07005264#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005265 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02005266 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005267 mbedtls_free( operation->ctx.hkdf.info );
5268 status = psa_hmac_abort_internal( &operation->ctx.hkdf.hmac );
Gilles Peskinebef7f142018-07-12 17:22:21 +02005269 }
John Durkop07cc04a2020-11-16 22:08:34 -08005270 else
5271#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF */
5272#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5273 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5274 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005275 /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01005276 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005277 {
Janos Follath6a1d2622019-06-11 10:37:28 +01005278 if( operation->ctx.tls12_prf.seed != NULL )
5279 {
5280 mbedtls_platform_zeroize( operation->ctx.tls12_prf.seed,
5281 operation->ctx.tls12_prf.seed_length );
5282 mbedtls_free( operation->ctx.tls12_prf.seed );
5283 }
5284
5285 if( operation->ctx.tls12_prf.label != NULL )
5286 {
5287 mbedtls_platform_zeroize( operation->ctx.tls12_prf.label,
5288 operation->ctx.tls12_prf.label_length );
5289 mbedtls_free( operation->ctx.tls12_prf.label );
5290 }
5291
5292 status = psa_hmac_abort_internal( &operation->ctx.tls12_prf.hmac );
5293
5294 /* We leave the fields Ai and output_block to be erased safely by the
5295 * mbedtls_platform_zeroize() in the end of this function. */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005296 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02005297 else
John Durkop07cc04a2020-11-16 22:08:34 -08005298#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
5299 * defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) */
Gilles Peskineeab56e42018-07-12 17:12:33 +02005300 {
5301 status = PSA_ERROR_BAD_STATE;
5302 }
Janos Follath083036a2019-06-11 10:22:26 +01005303 mbedtls_platform_zeroize( operation, sizeof( *operation ) );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005304 return( status );
5305}
5306
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005307psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation,
Gilles Peskineeab56e42018-07-12 17:12:33 +02005308 size_t *capacity)
5309{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005310 if( operation->alg == 0 )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005311 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005312 /* This is a blank key derivation operation. */
Steven Cooreman29149862020-08-05 15:43:42 +02005313 return( PSA_ERROR_BAD_STATE );
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005314 }
5315
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005316 *capacity = operation->capacity;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005317 return( PSA_SUCCESS );
5318}
5319
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005320psa_status_t psa_key_derivation_set_capacity( psa_key_derivation_operation_t *operation,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005321 size_t capacity )
5322{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005323 if( operation->alg == 0 )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005324 return( PSA_ERROR_BAD_STATE );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005325 if( capacity > operation->capacity )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005326 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005327 operation->capacity = capacity;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005328 return( PSA_SUCCESS );
5329}
5330
John Durkopd0321952020-10-29 21:37:36 -07005331#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005332/* Read some bytes from an HKDF-based operation. This performs a chunk
Gilles Peskinebef7f142018-07-12 17:22:21 +02005333 * of the expand phase of the HKDF algorithm. */
Gilles Peskinecbe66502019-05-16 16:59:18 +02005334static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkdf,
Gilles Peskinebef7f142018-07-12 17:22:21 +02005335 psa_algorithm_t hash_alg,
5336 uint8_t *output,
5337 size_t output_length )
5338{
5339 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
5340 psa_status_t status;
5341
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005342 if( hkdf->state < HKDF_STATE_KEYED || ! hkdf->info_set )
5343 return( PSA_ERROR_BAD_STATE );
5344 hkdf->state = HKDF_STATE_OUTPUT;
5345
Gilles Peskinebef7f142018-07-12 17:22:21 +02005346 while( output_length != 0 )
5347 {
5348 /* Copy what remains of the current block */
5349 uint8_t n = hash_length - hkdf->offset_in_block;
5350 if( n > output_length )
5351 n = (uint8_t) output_length;
5352 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
5353 output += n;
5354 output_length -= n;
5355 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02005356 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02005357 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02005358 /* We can't be wanting more output after block 0xff, otherwise
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02005359 * the capacity check in psa_key_derivation_output_bytes() would have
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005360 * prevented this call. It could happen only if the operation
Gilles Peskined54931c2018-07-17 21:06:59 +02005361 * object was corrupted or if this function is called directly
5362 * inside the library. */
5363 if( hkdf->block_number == 0xff )
5364 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02005365
5366 /* We need a new block */
5367 ++hkdf->block_number;
5368 hkdf->offset_in_block = 0;
5369 status = psa_hmac_setup_internal( &hkdf->hmac,
5370 hkdf->prk, hash_length,
5371 hash_alg );
5372 if( status != PSA_SUCCESS )
5373 return( status );
5374 if( hkdf->block_number != 1 )
5375 {
5376 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5377 hkdf->output_block,
5378 hash_length );
5379 if( status != PSA_SUCCESS )
5380 return( status );
5381 }
5382 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5383 hkdf->info,
5384 hkdf->info_length );
5385 if( status != PSA_SUCCESS )
5386 return( status );
5387 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5388 &hkdf->block_number, 1 );
5389 if( status != PSA_SUCCESS )
5390 return( status );
5391 status = psa_hmac_finish_internal( &hkdf->hmac,
5392 hkdf->output_block,
5393 sizeof( hkdf->output_block ) );
5394 if( status != PSA_SUCCESS )
5395 return( status );
5396 }
5397
5398 return( PSA_SUCCESS );
5399}
John Durkop07cc04a2020-11-16 22:08:34 -08005400#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005401
John Durkop07cc04a2020-11-16 22:08:34 -08005402#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5403 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follath7742fee2019-06-17 12:58:10 +01005404static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
5405 psa_tls12_prf_key_derivation_t *tls12_prf,
5406 psa_algorithm_t alg )
5407{
5408 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
5409 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Janos Follathea29bfb2019-06-19 12:21:20 +01005410 psa_hash_operation_t backup = PSA_HASH_OPERATION_INIT;
5411 psa_status_t status, cleanup_status;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005412
Janos Follath7742fee2019-06-17 12:58:10 +01005413 /* We can't be wanting more output after block 0xff, otherwise
5414 * the capacity check in psa_key_derivation_output_bytes() would have
5415 * prevented this call. It could happen only if the operation
5416 * object was corrupted or if this function is called directly
5417 * inside the library. */
5418 if( tls12_prf->block_number == 0xff )
Janos Follath30090bc2019-06-25 10:15:04 +01005419 return( PSA_ERROR_CORRUPTION_DETECTED );
Janos Follath7742fee2019-06-17 12:58:10 +01005420
5421 /* We need a new block */
5422 ++tls12_prf->block_number;
Janos Follath844eb0e2019-06-19 12:10:49 +01005423 tls12_prf->left_in_block = hash_length;
Janos Follath7742fee2019-06-17 12:58:10 +01005424
5425 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
5426 *
5427 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
5428 *
5429 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
5430 * HMAC_hash(secret, A(2) + seed) +
5431 * HMAC_hash(secret, A(3) + seed) + ...
5432 *
5433 * A(0) = seed
Janos Follathea29bfb2019-06-19 12:21:20 +01005434 * A(i) = HMAC_hash(secret, A(i-1))
Janos Follath7742fee2019-06-17 12:58:10 +01005435 *
Janos Follathea29bfb2019-06-19 12:21:20 +01005436 * The `psa_tls12_prf_key_derivation` structure saves the block
Janos Follath7742fee2019-06-17 12:58:10 +01005437 * `HMAC_hash(secret, A(i) + seed)` from which the output
Janos Follath76c39842019-06-26 12:50:36 +01005438 * is currently extracted as `output_block` and where i is
5439 * `block_number`.
Janos Follath7742fee2019-06-17 12:58:10 +01005440 */
5441
Janos Follathea29bfb2019-06-19 12:21:20 +01005442 /* Save the hash context before using it, to preserve the hash state with
5443 * only the inner padding in it. We need this, because inner padding depends
5444 * on the key (secret in the RFC's terminology). */
5445 status = psa_hash_clone( &tls12_prf->hmac.hash_ctx, &backup );
5446 if( status != PSA_SUCCESS )
5447 goto cleanup;
5448
5449 /* Calculate A(i) where i = tls12_prf->block_number. */
5450 if( tls12_prf->block_number == 1 )
5451 {
5452 /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads
5453 * the variable seed and in this instance means it in the context of the
5454 * P_hash function, where seed = label + seed.) */
5455 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5456 tls12_prf->label, tls12_prf->label_length );
5457 if( status != PSA_SUCCESS )
5458 goto cleanup;
5459 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5460 tls12_prf->seed, tls12_prf->seed_length );
5461 if( status != PSA_SUCCESS )
5462 goto cleanup;
5463 }
5464 else
5465 {
5466 /* A(i) = HMAC_hash(secret, A(i-1)) */
5467 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5468 tls12_prf->Ai, hash_length );
5469 if( status != PSA_SUCCESS )
5470 goto cleanup;
5471 }
5472
5473 status = psa_hmac_finish_internal( &tls12_prf->hmac,
5474 tls12_prf->Ai, hash_length );
5475 if( status != PSA_SUCCESS )
5476 goto cleanup;
5477 status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
5478 if( status != PSA_SUCCESS )
5479 goto cleanup;
5480
5481 /* Calculate HMAC_hash(secret, A(i) + label + seed). */
5482 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5483 tls12_prf->Ai, hash_length );
5484 if( status != PSA_SUCCESS )
5485 goto cleanup;
5486 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5487 tls12_prf->label, tls12_prf->label_length );
5488 if( status != PSA_SUCCESS )
5489 goto cleanup;
5490 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
5491 tls12_prf->seed, tls12_prf->seed_length );
5492 if( status != PSA_SUCCESS )
5493 goto cleanup;
5494 status = psa_hmac_finish_internal( &tls12_prf->hmac,
5495 tls12_prf->output_block, hash_length );
5496 if( status != PSA_SUCCESS )
5497 goto cleanup;
5498 status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
5499 if( status != PSA_SUCCESS )
5500 goto cleanup;
5501
Janos Follath7742fee2019-06-17 12:58:10 +01005502
5503cleanup:
5504
Janos Follathea29bfb2019-06-19 12:21:20 +01005505 cleanup_status = psa_hash_abort( &backup );
5506 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
5507 status = cleanup_status;
5508
5509 return( status );
Janos Follath7742fee2019-06-17 12:58:10 +01005510}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005511
Janos Follath844eb0e2019-06-19 12:10:49 +01005512static psa_status_t psa_key_derivation_tls12_prf_read(
5513 psa_tls12_prf_key_derivation_t *tls12_prf,
5514 psa_algorithm_t alg,
5515 uint8_t *output,
5516 size_t output_length )
5517{
5518 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
5519 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
5520 psa_status_t status;
5521 uint8_t offset, length;
5522
5523 while( output_length != 0 )
5524 {
5525 /* Check if we have fully processed the current block. */
5526 if( tls12_prf->left_in_block == 0 )
5527 {
5528 status = psa_key_derivation_tls12_prf_generate_next_block( tls12_prf,
5529 alg );
5530 if( status != PSA_SUCCESS )
5531 return( status );
5532
5533 continue;
5534 }
5535
5536 if( tls12_prf->left_in_block > output_length )
5537 length = (uint8_t) output_length;
5538 else
5539 length = tls12_prf->left_in_block;
5540
5541 offset = hash_length - tls12_prf->left_in_block;
5542 memcpy( output, tls12_prf->output_block + offset, length );
5543 output += length;
5544 output_length -= length;
5545 tls12_prf->left_in_block -= length;
5546 }
5547
5548 return( PSA_SUCCESS );
5549}
John Durkop07cc04a2020-11-16 22:08:34 -08005550#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
5551 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskinebef7f142018-07-12 17:22:21 +02005552
Janos Follath6c6c8fc2019-06-17 12:38:20 +01005553psa_status_t psa_key_derivation_output_bytes(
5554 psa_key_derivation_operation_t *operation,
5555 uint8_t *output,
5556 size_t output_length )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005557{
5558 psa_status_t status;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005559 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005560
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005561 if( operation->alg == 0 )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005562 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005563 /* This is a blank operation. */
Steven Cooreman29149862020-08-05 15:43:42 +02005564 return( PSA_ERROR_BAD_STATE );
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005565 }
5566
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005567 if( output_length > operation->capacity )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005568 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005569 operation->capacity = 0;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005570 /* Go through the error path to wipe all confidential data now
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005571 * that the operation object is useless. */
David Saadab4ecc272019-02-14 13:48:10 +02005572 status = PSA_ERROR_INSUFFICIENT_DATA;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005573 goto exit;
5574 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005575 if( output_length == 0 && operation->capacity == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005576 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005577 /* Edge case: this is a finished operation, and 0 bytes
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005578 * were requested. The right error in this case could
Gilles Peskineeab56e42018-07-12 17:12:33 +02005579 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
5580 * INSUFFICIENT_CAPACITY, which is right for a finished
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005581 * operation, for consistency with the case when
Gilles Peskineeab56e42018-07-12 17:12:33 +02005582 * output_length > 0. */
David Saadab4ecc272019-02-14 13:48:10 +02005583 return( PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005584 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005585 operation->capacity -= output_length;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005586
John Durkopd0321952020-10-29 21:37:36 -07005587#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005588 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02005589 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01005590 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005591 status = psa_key_derivation_hkdf_read( &operation->ctx.hkdf, hash_alg,
Gilles Peskinebef7f142018-07-12 17:22:21 +02005592 output, output_length );
5593 }
Janos Follathadbec812019-06-14 11:05:39 +01005594 else
John Durkop07cc04a2020-11-16 22:08:34 -08005595#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
5596#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5597 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follathadbec812019-06-14 11:05:39 +01005598 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
John Durkop07cc04a2020-11-16 22:08:34 -08005599 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005600 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005601 status = psa_key_derivation_tls12_prf_read( &operation->ctx.tls12_prf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005602 kdf_alg, output,
Hanno Beckerc8a41d72018-10-09 17:33:01 +01005603 output_length );
5604 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02005605 else
John Durkop07cc04a2020-11-16 22:08:34 -08005606#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
5607 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineeab56e42018-07-12 17:12:33 +02005608 {
5609 return( PSA_ERROR_BAD_STATE );
5610 }
5611
5612exit:
5613 if( status != PSA_SUCCESS )
5614 {
Jaeden Amerocf2010c2019-02-15 13:05:49 +00005615 /* Preserve the algorithm upon errors, but clear all sensitive state.
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005616 * This allows us to differentiate between exhausted operations and
5617 * blank operations, so we can return PSA_ERROR_BAD_STATE on blank
5618 * operations. */
5619 psa_algorithm_t alg = operation->alg;
5620 psa_key_derivation_abort( operation );
5621 operation->alg = alg;
Gilles Peskineeab56e42018-07-12 17:12:33 +02005622 memset( output, '!', output_length );
5623 }
5624 return( status );
5625}
5626
Gilles Peskine08542d82018-07-19 17:05:42 +02005627#if defined(MBEDTLS_DES_C)
5628static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
5629{
5630 if( data_size >= 8 )
5631 mbedtls_des_key_set_parity( data );
5632 if( data_size >= 16 )
5633 mbedtls_des_key_set_parity( data + 8 );
5634 if( data_size >= 24 )
5635 mbedtls_des_key_set_parity( data + 16 );
5636}
5637#endif /* MBEDTLS_DES_C */
5638
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01005639static psa_status_t psa_generate_derived_key_internal(
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005640 psa_key_slot_t *slot,
5641 size_t bits,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005642 psa_key_derivation_operation_t *operation )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005643{
5644 uint8_t *data = NULL;
5645 size_t bytes = PSA_BITS_TO_BYTES( bits );
5646 psa_status_t status;
5647
Gilles Peskine8e338702019-07-30 20:06:31 +02005648 if( ! key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskineeab56e42018-07-12 17:12:33 +02005649 return( PSA_ERROR_INVALID_ARGUMENT );
5650 if( bits % 8 != 0 )
5651 return( PSA_ERROR_INVALID_ARGUMENT );
5652 data = mbedtls_calloc( 1, bytes );
5653 if( data == NULL )
5654 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5655
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005656 status = psa_key_derivation_output_bytes( operation, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005657 if( status != PSA_SUCCESS )
5658 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02005659#if defined(MBEDTLS_DES_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02005660 if( slot->attr.type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02005661 psa_des_set_key_parity( data, bytes );
5662#endif /* MBEDTLS_DES_C */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005663 status = psa_import_key_into_slot( slot, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02005664
5665exit:
5666 mbedtls_free( data );
5667 return( status );
5668}
5669
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02005670psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attributes,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005671 psa_key_derivation_operation_t *operation,
Ronald Croncf56a0a2020-08-04 09:51:30 +02005672 mbedtls_svc_key_id_t *key )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005673{
5674 psa_status_t status;
5675 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02005676 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine0f84d622019-09-12 19:03:13 +02005677
Ronald Cron81709fc2020-11-14 12:10:32 +01005678 *key = MBEDTLS_SVC_KEY_ID_INIT;
5679
Gilles Peskine0f84d622019-09-12 19:03:13 +02005680 /* Reject any attempt to create a zero-length key so that we don't
5681 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
5682 if( psa_get_key_bits( attributes ) == 0 )
5683 return( PSA_ERROR_INVALID_ARGUMENT );
5684
Gilles Peskine178c9aa2019-09-24 18:21:06 +02005685 if( ! operation->can_output_key )
5686 return( PSA_ERROR_NOT_PERMITTED );
5687
Ronald Cron81709fc2020-11-14 12:10:32 +01005688 status = psa_start_key_creation( PSA_KEY_CREATION_DERIVE, attributes,
5689 &slot, &driver );
Gilles Peskinef4ee6622019-07-24 13:44:30 +02005690#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
5691 if( driver != NULL )
5692 {
5693 /* Deriving a key in a secure element is not implemented yet. */
5694 status = PSA_ERROR_NOT_SUPPORTED;
5695 }
5696#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005697 if( status == PSA_SUCCESS )
5698 {
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01005699 status = psa_generate_derived_key_internal( slot,
Gilles Peskine7e0cff92019-07-30 13:48:52 +02005700 attributes->core.bits,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005701 operation );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005702 }
5703 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01005704 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005705 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02005706 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02005707
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005708 return( status );
5709}
5710
Gilles Peskineeab56e42018-07-12 17:12:33 +02005711
5712
5713/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02005714/* Key derivation */
5715/****************************************************************/
5716
John Durkop07cc04a2020-11-16 22:08:34 -08005717#ifdef AT_LEAST_ONE_BUILTIN_KDF
Gilles Peskine969c5d62019-01-16 15:53:06 +01005718static psa_status_t psa_key_derivation_setup_kdf(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005719 psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005720 psa_algorithm_t kdf_alg )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005721{
John Durkop07cc04a2020-11-16 22:08:34 -08005722 int is_kdf_alg_supported;
5723
Janos Follath5fe19732019-06-20 15:09:30 +01005724 /* Make sure that operation->ctx is properly zero-initialised. (Macro
5725 * initialisers for this union leave some bytes unspecified.) */
5726 memset( &operation->ctx, 0, sizeof( operation->ctx ) );
5727
Gilles Peskine969c5d62019-01-16 15:53:06 +01005728 /* Make sure that kdf_alg is a supported key derivation algorithm. */
John Durkopd0321952020-10-29 21:37:36 -07005729#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
John Durkop07cc04a2020-11-16 22:08:34 -08005730 if( PSA_ALG_IS_HKDF( kdf_alg ) )
5731 is_kdf_alg_supported = 1;
5732 else
5733#endif
5734#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
5735 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
5736 is_kdf_alg_supported = 1;
5737 else
5738#endif
5739#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5740 if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
5741 is_kdf_alg_supported = 1;
5742 else
5743#endif
5744 is_kdf_alg_supported = 0;
5745
5746 if( is_kdf_alg_supported )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005747 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01005748 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005749 size_t hash_size = PSA_HASH_SIZE( hash_alg );
5750 if( hash_size == 0 )
5751 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005752 if( ( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
5753 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) &&
Gilles Peskineab4b2012019-04-12 15:06:27 +02005754 ! ( hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384 ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005755 {
5756 return( PSA_ERROR_NOT_SUPPORTED );
5757 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005758 operation->capacity = 255 * hash_size;
Gilles Peskine969c5d62019-01-16 15:53:06 +01005759 return( PSA_SUCCESS );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005760 }
John Durkop07cc04a2020-11-16 22:08:34 -08005761
5762 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005763}
John Durkop07cc04a2020-11-16 22:08:34 -08005764#endif /* AT_LEAST_ONE_BUILTIN_KDF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01005765
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005766psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005767 psa_algorithm_t alg )
5768{
5769 psa_status_t status;
5770
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005771 if( operation->alg != 0 )
Gilles Peskine969c5d62019-01-16 15:53:06 +01005772 return( PSA_ERROR_BAD_STATE );
5773
Gilles Peskine6843c292019-01-18 16:44:49 +01005774 if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
5775 return( PSA_ERROR_INVALID_ARGUMENT );
John Durkop07cc04a2020-11-16 22:08:34 -08005776#ifdef AT_LEAST_ONE_BUILTIN_KDF
Gilles Peskine6843c292019-01-18 16:44:49 +01005777 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskine969c5d62019-01-16 15:53:06 +01005778 {
5779 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005780 status = psa_key_derivation_setup_kdf( operation, kdf_alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005781 }
5782 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
5783 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005784 status = psa_key_derivation_setup_kdf( operation, alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005785 }
John Durkop07cc04a2020-11-16 22:08:34 -08005786#endif
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005787 else
5788 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005789
5790 if( status == PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005791 operation->alg = alg;
Gilles Peskine969c5d62019-01-16 15:53:06 +01005792 return( status );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005793}
5794
John Durkopd0321952020-10-29 21:37:36 -07005795#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskinecbe66502019-05-16 16:59:18 +02005796static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005797 psa_algorithm_t hash_alg,
5798 psa_key_derivation_step_t step,
5799 const uint8_t *data,
5800 size_t data_length )
5801{
5802 psa_status_t status;
5803 switch( step )
5804 {
Gilles Peskine03410b52019-05-16 16:05:19 +02005805 case PSA_KEY_DERIVATION_INPUT_SALT:
Gilles Peskine2b522db2019-04-12 15:11:49 +02005806 if( hkdf->state != HKDF_STATE_INIT )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005807 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005808 status = psa_hmac_setup_internal( &hkdf->hmac,
5809 data, data_length,
5810 hash_alg );
5811 if( status != PSA_SUCCESS )
5812 return( status );
5813 hkdf->state = HKDF_STATE_STARTED;
5814 return( PSA_SUCCESS );
Gilles Peskine03410b52019-05-16 16:05:19 +02005815 case PSA_KEY_DERIVATION_INPUT_SECRET:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005816 /* If no salt was provided, use an empty salt. */
5817 if( hkdf->state == HKDF_STATE_INIT )
5818 {
5819 status = psa_hmac_setup_internal( &hkdf->hmac,
5820 NULL, 0,
Gilles Peskinef9ee6332019-04-11 21:22:52 +02005821 hash_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005822 if( status != PSA_SUCCESS )
5823 return( status );
5824 hkdf->state = HKDF_STATE_STARTED;
5825 }
Gilles Peskine2b522db2019-04-12 15:11:49 +02005826 if( hkdf->state != HKDF_STATE_STARTED )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005827 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005828 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5829 data, data_length );
5830 if( status != PSA_SUCCESS )
5831 return( status );
5832 status = psa_hmac_finish_internal( &hkdf->hmac,
5833 hkdf->prk,
5834 sizeof( hkdf->prk ) );
5835 if( status != PSA_SUCCESS )
5836 return( status );
5837 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
5838 hkdf->block_number = 0;
5839 hkdf->state = HKDF_STATE_KEYED;
5840 return( PSA_SUCCESS );
Gilles Peskine03410b52019-05-16 16:05:19 +02005841 case PSA_KEY_DERIVATION_INPUT_INFO:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005842 if( hkdf->state == HKDF_STATE_OUTPUT )
5843 return( PSA_ERROR_BAD_STATE );
5844 if( hkdf->info_set )
5845 return( PSA_ERROR_BAD_STATE );
5846 hkdf->info_length = data_length;
5847 if( data_length != 0 )
5848 {
5849 hkdf->info = mbedtls_calloc( 1, data_length );
5850 if( hkdf->info == NULL )
5851 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5852 memcpy( hkdf->info, data, data_length );
5853 }
5854 hkdf->info_set = 1;
5855 return( PSA_SUCCESS );
5856 default:
5857 return( PSA_ERROR_INVALID_ARGUMENT );
5858 }
5859}
John Durkop07cc04a2020-11-16 22:08:34 -08005860#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
Janos Follathb03233e2019-06-11 15:30:30 +01005861
John Durkop07cc04a2020-11-16 22:08:34 -08005862#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
5863 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follathf08e2652019-06-13 09:05:41 +01005864static psa_status_t psa_tls12_prf_set_seed( psa_tls12_prf_key_derivation_t *prf,
5865 const uint8_t *data,
5866 size_t data_length )
5867{
5868 if( prf->state != TLS12_PRF_STATE_INIT )
5869 return( PSA_ERROR_BAD_STATE );
5870
Janos Follathd6dce9f2019-07-04 09:11:38 +01005871 if( data_length != 0 )
5872 {
5873 prf->seed = mbedtls_calloc( 1, data_length );
5874 if( prf->seed == NULL )
5875 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Janos Follathf08e2652019-06-13 09:05:41 +01005876
Janos Follathd6dce9f2019-07-04 09:11:38 +01005877 memcpy( prf->seed, data, data_length );
5878 prf->seed_length = data_length;
5879 }
Janos Follathf08e2652019-06-13 09:05:41 +01005880
5881 prf->state = TLS12_PRF_STATE_SEED_SET;
5882
5883 return( PSA_SUCCESS );
5884}
5885
Janos Follath81550542019-06-13 14:26:34 +01005886static psa_status_t psa_tls12_prf_set_key( psa_tls12_prf_key_derivation_t *prf,
5887 psa_algorithm_t hash_alg,
5888 const uint8_t *data,
5889 size_t data_length )
5890{
5891 psa_status_t status;
5892 if( prf->state != TLS12_PRF_STATE_SEED_SET )
5893 return( PSA_ERROR_BAD_STATE );
5894
5895 status = psa_hmac_setup_internal( &prf->hmac, data, data_length, hash_alg );
5896 if( status != PSA_SUCCESS )
5897 return( status );
5898
5899 prf->state = TLS12_PRF_STATE_KEY_SET;
5900
5901 return( PSA_SUCCESS );
5902}
5903
Janos Follath63028dd2019-06-13 09:15:47 +01005904static psa_status_t psa_tls12_prf_set_label( psa_tls12_prf_key_derivation_t *prf,
5905 const uint8_t *data,
5906 size_t data_length )
5907{
5908 if( prf->state != TLS12_PRF_STATE_KEY_SET )
5909 return( PSA_ERROR_BAD_STATE );
5910
Janos Follathd6dce9f2019-07-04 09:11:38 +01005911 if( data_length != 0 )
5912 {
5913 prf->label = mbedtls_calloc( 1, data_length );
5914 if( prf->label == NULL )
5915 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Janos Follath63028dd2019-06-13 09:15:47 +01005916
Janos Follathd6dce9f2019-07-04 09:11:38 +01005917 memcpy( prf->label, data, data_length );
5918 prf->label_length = data_length;
5919 }
Janos Follath63028dd2019-06-13 09:15:47 +01005920
5921 prf->state = TLS12_PRF_STATE_LABEL_SET;
5922
5923 return( PSA_SUCCESS );
5924}
5925
Janos Follathb03233e2019-06-11 15:30:30 +01005926static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf,
5927 psa_algorithm_t hash_alg,
5928 psa_key_derivation_step_t step,
5929 const uint8_t *data,
5930 size_t data_length )
5931{
Janos Follathb03233e2019-06-11 15:30:30 +01005932 switch( step )
5933 {
Janos Follathf08e2652019-06-13 09:05:41 +01005934 case PSA_KEY_DERIVATION_INPUT_SEED:
5935 return( psa_tls12_prf_set_seed( prf, data, data_length ) );
Janos Follath81550542019-06-13 14:26:34 +01005936 case PSA_KEY_DERIVATION_INPUT_SECRET:
5937 return( psa_tls12_prf_set_key( prf, hash_alg, data, data_length ) );
Janos Follath63028dd2019-06-13 09:15:47 +01005938 case PSA_KEY_DERIVATION_INPUT_LABEL:
5939 return( psa_tls12_prf_set_label( prf, data, data_length ) );
Janos Follathb03233e2019-06-11 15:30:30 +01005940 default:
5941 return( PSA_ERROR_INVALID_ARGUMENT );
5942 }
5943}
John Durkop07cc04a2020-11-16 22:08:34 -08005944#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
5945 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
5946
5947#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
5948static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
5949 psa_tls12_prf_key_derivation_t *prf,
5950 psa_algorithm_t hash_alg,
5951 const uint8_t *data,
5952 size_t data_length )
5953{
5954 psa_status_t status;
5955 uint8_t pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
5956 uint8_t *cur = pms;
5957
5958 if( data_length > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
5959 return( PSA_ERROR_INVALID_ARGUMENT );
5960
5961 /* Quoting RFC 4279, Section 2:
5962 *
5963 * The premaster secret is formed as follows: if the PSK is N octets
5964 * long, concatenate a uint16 with the value N, N zero octets, a second
5965 * uint16 with the value N, and the PSK itself.
5966 */
5967
5968 *cur++ = ( data_length >> 8 ) & 0xff;
5969 *cur++ = ( data_length >> 0 ) & 0xff;
5970 memset( cur, 0, data_length );
5971 cur += data_length;
5972 *cur++ = pms[0];
5973 *cur++ = pms[1];
5974 memcpy( cur, data, data_length );
5975 cur += data_length;
5976
5977 status = psa_tls12_prf_set_key( prf, hash_alg, pms, cur - pms );
5978
5979 mbedtls_platform_zeroize( pms, sizeof( pms ) );
5980 return( status );
5981}
Janos Follath6660f0e2019-06-17 08:44:03 +01005982
5983static psa_status_t psa_tls12_prf_psk_to_ms_input(
5984 psa_tls12_prf_key_derivation_t *prf,
5985 psa_algorithm_t hash_alg,
5986 psa_key_derivation_step_t step,
5987 const uint8_t *data,
5988 size_t data_length )
5989{
5990 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
Janos Follath0c1ed842019-06-28 13:35:36 +01005991 {
Janos Follath6660f0e2019-06-17 08:44:03 +01005992 return( psa_tls12_prf_psk_to_ms_set_key( prf, hash_alg,
5993 data, data_length ) );
Janos Follath0c1ed842019-06-28 13:35:36 +01005994 }
Janos Follath6660f0e2019-06-17 08:44:03 +01005995
5996 return( psa_tls12_prf_input( prf, hash_alg, step, data, data_length ) );
5997}
John Durkop07cc04a2020-11-16 22:08:34 -08005998#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005999
Gilles Peskineb8965192019-09-24 16:21:10 +02006000/** Check whether the given key type is acceptable for the given
6001 * input step of a key derivation.
6002 *
6003 * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE.
6004 * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA.
6005 * Both secret and non-secret inputs can alternatively have the type
6006 * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning
6007 * that the input was passed as a buffer rather than via a key object.
6008 */
Gilles Peskine224b0d62019-09-23 18:13:17 +02006009static int psa_key_derivation_check_input_type(
6010 psa_key_derivation_step_t step,
6011 psa_key_type_t key_type )
6012{
6013 switch( step )
6014 {
6015 case PSA_KEY_DERIVATION_INPUT_SECRET:
Gilles Peskineb8965192019-09-24 16:21:10 +02006016 if( key_type == PSA_KEY_TYPE_DERIVE )
6017 return( PSA_SUCCESS );
6018 if( key_type == PSA_KEY_TYPE_NONE )
Gilles Peskine224b0d62019-09-23 18:13:17 +02006019 return( PSA_SUCCESS );
6020 break;
6021 case PSA_KEY_DERIVATION_INPUT_LABEL:
6022 case PSA_KEY_DERIVATION_INPUT_SALT:
6023 case PSA_KEY_DERIVATION_INPUT_INFO:
6024 case PSA_KEY_DERIVATION_INPUT_SEED:
Gilles Peskineb8965192019-09-24 16:21:10 +02006025 if( key_type == PSA_KEY_TYPE_RAW_DATA )
6026 return( PSA_SUCCESS );
6027 if( key_type == PSA_KEY_TYPE_NONE )
Gilles Peskine224b0d62019-09-23 18:13:17 +02006028 return( PSA_SUCCESS );
6029 break;
6030 }
6031 return( PSA_ERROR_INVALID_ARGUMENT );
6032}
6033
Janos Follathb80a94e2019-06-12 15:54:46 +01006034static psa_status_t psa_key_derivation_input_internal(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006035 psa_key_derivation_operation_t *operation,
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01006036 psa_key_derivation_step_t step,
Gilles Peskine224b0d62019-09-23 18:13:17 +02006037 psa_key_type_t key_type,
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01006038 const uint8_t *data,
6039 size_t data_length )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006040{
Gilles Peskine46d7faf2019-09-23 19:22:55 +02006041 psa_status_t status;
6042 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
6043
6044 status = psa_key_derivation_check_input_type( step, key_type );
Gilles Peskine224b0d62019-09-23 18:13:17 +02006045 if( status != PSA_SUCCESS )
6046 goto exit;
6047
John Durkopd0321952020-10-29 21:37:36 -07006048#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine969c5d62019-01-16 15:53:06 +01006049 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006050 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006051 status = psa_hkdf_input( &operation->ctx.hkdf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01006052 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006053 step, data, data_length );
6054 }
John Durkop07cc04a2020-11-16 22:08:34 -08006055 else
6056#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
6057#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
6058 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006059 {
Janos Follathb03233e2019-06-11 15:30:30 +01006060 status = psa_tls12_prf_input( &operation->ctx.tls12_prf,
6061 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
6062 step, data, data_length );
Janos Follath6660f0e2019-06-17 08:44:03 +01006063 }
John Durkop07cc04a2020-11-16 22:08:34 -08006064 else
6065#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF */
6066#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
6067 if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Janos Follath6660f0e2019-06-17 08:44:03 +01006068 {
6069 status = psa_tls12_prf_psk_to_ms_input( &operation->ctx.tls12_prf,
6070 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
6071 step, data, data_length );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006072 }
6073 else
John Durkop07cc04a2020-11-16 22:08:34 -08006074#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006075 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006076 /* This can't happen unless the operation object was not initialized */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006077 return( PSA_ERROR_BAD_STATE );
6078 }
6079
Gilles Peskine224b0d62019-09-23 18:13:17 +02006080exit:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006081 if( status != PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006082 psa_key_derivation_abort( operation );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006083 return( status );
6084}
6085
Janos Follath51f4a0f2019-06-14 11:35:55 +01006086psa_status_t psa_key_derivation_input_bytes(
6087 psa_key_derivation_operation_t *operation,
6088 psa_key_derivation_step_t step,
6089 const uint8_t *data,
6090 size_t data_length )
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01006091{
Gilles Peskineb8965192019-09-24 16:21:10 +02006092 return( psa_key_derivation_input_internal( operation, step,
6093 PSA_KEY_TYPE_NONE,
Janos Follathc5621512019-06-14 11:27:57 +01006094 data, data_length ) );
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01006095}
6096
Janos Follath51f4a0f2019-06-14 11:35:55 +01006097psa_status_t psa_key_derivation_input_key(
6098 psa_key_derivation_operation_t *operation,
6099 psa_key_derivation_step_t step,
Ronald Croncf56a0a2020-08-04 09:51:30 +02006100 mbedtls_svc_key_id_t key )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006101{
Ronald Cronf95a2b12020-10-22 15:24:49 +02006102 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01006103 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006104 psa_key_slot_t *slot;
Gilles Peskine178c9aa2019-09-24 18:21:06 +02006105
Ronald Cron5c522922020-11-14 16:35:34 +01006106 status = psa_get_and_lock_transparent_key_slot_with_policy(
6107 key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006108 if( status != PSA_SUCCESS )
Gilles Peskine593773d2019-09-23 18:17:40 +02006109 {
6110 psa_key_derivation_abort( operation );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006111 return( status );
Gilles Peskine593773d2019-09-23 18:17:40 +02006112 }
Gilles Peskine178c9aa2019-09-24 18:21:06 +02006113
6114 /* Passing a key object as a SECRET input unlocks the permission
6115 * to output to a key object. */
6116 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
6117 operation->can_output_key = 1;
6118
Ronald Cronf95a2b12020-10-22 15:24:49 +02006119 status = psa_key_derivation_input_internal( operation,
6120 step, slot->attr.type,
6121 slot->data.key.data,
6122 slot->data.key.bytes );
6123
Ronald Cron5c522922020-11-14 16:35:34 +01006124 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02006125
Ronald Cron5c522922020-11-14 16:35:34 +01006126 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01006127}
Gilles Peskineea0fb492018-07-12 17:17:20 +02006128
6129
6130
6131/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02006132/* Key agreement */
6133/****************************************************************/
6134
John Durkop6ba40d12020-11-10 08:50:04 -08006135#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006136static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
6137 size_t peer_key_length,
6138 const mbedtls_ecp_keypair *our_key,
6139 uint8_t *shared_secret,
6140 size_t shared_secret_size,
6141 size_t *shared_secret_length )
6142{
Steven Cooremand4867872020-08-05 16:31:39 +02006143 mbedtls_ecp_keypair *their_key = NULL;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006144 mbedtls_ecdh_context ecdh;
Jaeden Amero97271b32019-01-10 19:38:51 +00006145 psa_status_t status;
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01006146 size_t bits = 0;
Paul Elliott8ff510a2020-06-02 17:19:28 +01006147 psa_ecc_family_t curve = mbedtls_ecc_group_to_psa( our_key->grp.id, &bits );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006148 mbedtls_ecdh_init( &ecdh );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006149
Steven Cooreman4fed4552020-08-03 14:46:03 +02006150 status = psa_load_ecp_representation( PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
6151 peer_key,
Steven Cooreman7f391872020-07-30 14:57:44 +02006152 peer_key_length,
Steven Cooreman7f391872020-07-30 14:57:44 +02006153 &their_key );
Jaeden Amero97271b32019-01-10 19:38:51 +00006154 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006155 goto exit;
6156
Jaeden Amero97271b32019-01-10 19:38:51 +00006157 status = mbedtls_to_psa_error(
Steven Cooremana2371e52020-07-28 14:30:39 +02006158 mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS ) );
Jaeden Amero97271b32019-01-10 19:38:51 +00006159 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006160 goto exit;
Jaeden Amero97271b32019-01-10 19:38:51 +00006161 status = mbedtls_to_psa_error(
6162 mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS ) );
6163 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006164 goto exit;
6165
Jaeden Amero97271b32019-01-10 19:38:51 +00006166 status = mbedtls_to_psa_error(
6167 mbedtls_ecdh_calc_secret( &ecdh,
6168 shared_secret_length,
6169 shared_secret, shared_secret_size,
Gilles Peskine30524eb2020-11-13 17:02:26 +01006170 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006171 MBEDTLS_PSA_RANDOM_STATE ) );
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01006172 if( status != PSA_SUCCESS )
6173 goto exit;
6174 if( PSA_BITS_TO_BYTES( bits ) != *shared_secret_length )
6175 status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006176
6177exit:
Gilles Peskine3e819b72019-12-20 14:09:55 +01006178 if( status != PSA_SUCCESS )
6179 mbedtls_platform_zeroize( shared_secret, shared_secret_size );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006180 mbedtls_ecdh_free( &ecdh );
Steven Cooremana2371e52020-07-28 14:30:39 +02006181 mbedtls_ecp_keypair_free( their_key );
Steven Cooreman6d839f02020-07-30 11:36:45 +02006182 mbedtls_free( their_key );
Steven Cooremana2371e52020-07-28 14:30:39 +02006183
Jaeden Amero97271b32019-01-10 19:38:51 +00006184 return( status );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006185}
John Durkop6ba40d12020-11-10 08:50:04 -08006186#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006187
Gilles Peskine01d718c2018-09-18 12:01:02 +02006188#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
6189
Gilles Peskine0216fe12019-04-11 21:23:21 +02006190static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg,
6191 psa_key_slot_t *private_key,
6192 const uint8_t *peer_key,
6193 size_t peer_key_length,
6194 uint8_t *shared_secret,
6195 size_t shared_secret_size,
6196 size_t *shared_secret_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02006197{
Gilles Peskine0216fe12019-04-11 21:23:21 +02006198 switch( alg )
Gilles Peskine01d718c2018-09-18 12:01:02 +02006199 {
John Durkop6ba40d12020-11-10 08:50:04 -08006200#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
Gilles Peskine0216fe12019-04-11 21:23:21 +02006201 case PSA_ALG_ECDH:
Gilles Peskine8e338702019-07-30 20:06:31 +02006202 if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02006203 return( PSA_ERROR_INVALID_ARGUMENT );
Steven Cooremana2371e52020-07-28 14:30:39 +02006204 mbedtls_ecp_keypair *ecp = NULL;
Steven Cooreman7f391872020-07-30 14:57:44 +02006205 psa_status_t status = psa_load_ecp_representation(
Steven Cooreman4fed4552020-08-03 14:46:03 +02006206 private_key->attr.type,
Steven Cooreman7f391872020-07-30 14:57:44 +02006207 private_key->data.key.data,
6208 private_key->data.key.bytes,
Steven Cooreman7f391872020-07-30 14:57:44 +02006209 &ecp );
Steven Cooremanacda8342020-07-24 23:09:52 +02006210 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02006211 return( status );
Steven Cooremanacda8342020-07-24 23:09:52 +02006212 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
Steven Cooremana2371e52020-07-28 14:30:39 +02006213 ecp,
Steven Cooremanacda8342020-07-24 23:09:52 +02006214 shared_secret, shared_secret_size,
6215 shared_secret_length );
Steven Cooremana2371e52020-07-28 14:30:39 +02006216 mbedtls_ecp_keypair_free( ecp );
6217 mbedtls_free( ecp );
Steven Cooreman29149862020-08-05 15:43:42 +02006218 return( status );
John Durkop6ba40d12020-11-10 08:50:04 -08006219#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
Gilles Peskine01d718c2018-09-18 12:01:02 +02006220 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01006221 (void) private_key;
6222 (void) peer_key;
6223 (void) peer_key_length;
Gilles Peskine0216fe12019-04-11 21:23:21 +02006224 (void) shared_secret;
6225 (void) shared_secret_size;
6226 (void) shared_secret_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02006227 return( PSA_ERROR_NOT_SUPPORTED );
6228 }
Gilles Peskine0216fe12019-04-11 21:23:21 +02006229}
6230
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02006231/* Note that if this function fails, you must call psa_key_derivation_abort()
Gilles Peskine01d718c2018-09-18 12:01:02 +02006232 * to potentially free embedded data structures and wipe confidential data.
6233 */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006234static psa_status_t psa_key_agreement_internal( psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01006235 psa_key_derivation_step_t step,
Gilles Peskine01d718c2018-09-18 12:01:02 +02006236 psa_key_slot_t *private_key,
6237 const uint8_t *peer_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01006238 size_t peer_key_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02006239{
6240 psa_status_t status;
6241 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
6242 size_t shared_secret_length = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006243 psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE( operation->alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02006244
6245 /* Step 1: run the secret agreement algorithm to generate the shared
6246 * secret. */
Gilles Peskine0216fe12019-04-11 21:23:21 +02006247 status = psa_key_agreement_raw_internal( ka_alg,
6248 private_key,
6249 peer_key, peer_key_length,
itayzafrir0adf0fc2018-09-06 16:24:41 +03006250 shared_secret,
6251 sizeof( shared_secret ),
Gilles Peskine05d69892018-06-19 22:00:52 +02006252 &shared_secret_length );
Gilles Peskine53d991e2018-07-12 01:14:59 +02006253 if( status != PSA_SUCCESS )
Gilles Peskine12313cd2018-06-20 00:20:32 +02006254 goto exit;
6255
Gilles Peskineb0b255c2018-07-06 17:01:38 +02006256 /* Step 2: set up the key derivation to generate key material from
Gilles Peskine224b0d62019-09-23 18:13:17 +02006257 * the shared secret. A shared secret is permitted wherever a key
6258 * of type DERIVE is permitted. */
Janos Follathb80a94e2019-06-12 15:54:46 +01006259 status = psa_key_derivation_input_internal( operation, step,
Gilles Peskine224b0d62019-09-23 18:13:17 +02006260 PSA_KEY_TYPE_DERIVE,
Janos Follathb80a94e2019-06-12 15:54:46 +01006261 shared_secret,
6262 shared_secret_length );
Gilles Peskine12313cd2018-06-20 00:20:32 +02006263exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01006264 mbedtls_platform_zeroize( shared_secret, shared_secret_length );
Gilles Peskine12313cd2018-06-20 00:20:32 +02006265 return( status );
6266}
6267
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006268psa_status_t psa_key_derivation_key_agreement( psa_key_derivation_operation_t *operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02006269 psa_key_derivation_step_t step,
Ronald Croncf56a0a2020-08-04 09:51:30 +02006270 mbedtls_svc_key_id_t private_key,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02006271 const uint8_t *peer_key,
6272 size_t peer_key_length )
Gilles Peskine12313cd2018-06-20 00:20:32 +02006273{
Ronald Cronf95a2b12020-10-22 15:24:49 +02006274 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01006275 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01006276 psa_key_slot_t *slot;
Ronald Cronf95a2b12020-10-22 15:24:49 +02006277
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006278 if( ! PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02006279 return( PSA_ERROR_INVALID_ARGUMENT );
Ronald Cron5c522922020-11-14 16:35:34 +01006280 status = psa_get_and_lock_transparent_key_slot_with_policy(
6281 private_key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg );
Gilles Peskine12313cd2018-06-20 00:20:32 +02006282 if( status != PSA_SUCCESS )
6283 return( status );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006284 status = psa_key_agreement_internal( operation, step,
Gilles Peskine346797d2018-11-16 16:05:06 +01006285 slot,
Gilles Peskine969c5d62019-01-16 15:53:06 +01006286 peer_key, peer_key_length );
Gilles Peskine346797d2018-11-16 16:05:06 +01006287 if( status != PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02006288 psa_key_derivation_abort( operation );
Steven Cooremanfa5e6312020-10-15 17:07:12 +02006289 else
6290 {
6291 /* If a private key has been added as SECRET, we allow the derived
6292 * key material to be used as a key in PSA Crypto. */
6293 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
6294 operation->can_output_key = 1;
6295 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02006296
Ronald Cron5c522922020-11-14 16:35:34 +01006297 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02006298
Ronald Cron5c522922020-11-14 16:35:34 +01006299 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskineaf3baab2018-06-27 22:55:52 +02006300}
6301
Gilles Peskinebe697d82019-05-16 18:00:41 +02006302psa_status_t psa_raw_key_agreement( psa_algorithm_t alg,
Ronald Croncf56a0a2020-08-04 09:51:30 +02006303 mbedtls_svc_key_id_t private_key,
Gilles Peskinebe697d82019-05-16 18:00:41 +02006304 const uint8_t *peer_key,
6305 size_t peer_key_length,
6306 uint8_t *output,
6307 size_t output_size,
6308 size_t *output_length )
Gilles Peskine0216fe12019-04-11 21:23:21 +02006309{
Ronald Cronf95a2b12020-10-22 15:24:49 +02006310 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01006311 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cronf95a2b12020-10-22 15:24:49 +02006312 psa_key_slot_t *slot = NULL;
Gilles Peskine0216fe12019-04-11 21:23:21 +02006313
6314 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
6315 {
6316 status = PSA_ERROR_INVALID_ARGUMENT;
6317 goto exit;
6318 }
Ronald Cron5c522922020-11-14 16:35:34 +01006319 status = psa_get_and_lock_transparent_key_slot_with_policy(
6320 private_key, &slot, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine0216fe12019-04-11 21:23:21 +02006321 if( status != PSA_SUCCESS )
6322 goto exit;
6323
6324 status = psa_key_agreement_raw_internal( alg, slot,
6325 peer_key, peer_key_length,
6326 output, output_size,
6327 output_length );
6328
6329exit:
6330 if( status != PSA_SUCCESS )
6331 {
6332 /* If an error happens and is not handled properly, the output
6333 * may be used as a key to protect sensitive data. Arrange for such
6334 * a key to be random, which is likely to result in decryption or
6335 * verification errors. This is better than filling the buffer with
6336 * some constant data such as zeros, which would result in the data
6337 * being protected with a reproducible, easily knowable key.
6338 */
6339 psa_generate_random( output, output_size );
6340 *output_length = output_size;
6341 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02006342
Ronald Cron5c522922020-11-14 16:35:34 +01006343 unlock_status = psa_unlock_key_slot( slot );
Ronald Cronf95a2b12020-10-22 15:24:49 +02006344
Ronald Cron5c522922020-11-14 16:35:34 +01006345 return( ( status == PSA_SUCCESS ) ? unlock_status : status );
Gilles Peskine0216fe12019-04-11 21:23:21 +02006346}
Gilles Peskine86a440b2018-11-12 18:39:40 +01006347
6348
Gilles Peskine30524eb2020-11-13 17:02:26 +01006349
Gilles Peskine86a440b2018-11-12 18:39:40 +01006350/****************************************************************/
6351/* Random generation */
Gilles Peskine53d991e2018-07-12 01:14:59 +02006352/****************************************************************/
Gilles Peskine12313cd2018-06-20 00:20:32 +02006353
Gilles Peskine30524eb2020-11-13 17:02:26 +01006354/** Initialize the PSA random generator.
6355 */
6356static void mbedtls_psa_random_init( mbedtls_psa_random_context_t *rng )
6357{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006358#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6359 memset( rng, 0, sizeof( *rng ) );
6360#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
6361
Gilles Peskine30524eb2020-11-13 17:02:26 +01006362 /* Set default configuration if
6363 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
6364 if( rng->entropy_init == NULL )
6365 rng->entropy_init = mbedtls_entropy_init;
6366 if( rng->entropy_free == NULL )
6367 rng->entropy_free = mbedtls_entropy_free;
6368
6369 rng->entropy_init( &rng->entropy );
6370#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
6371 defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
6372 /* The PSA entropy injection feature depends on using NV seed as an entropy
6373 * source. Add NV seed as an entropy source for PSA entropy injection. */
6374 mbedtls_entropy_add_source( &rng->entropy,
6375 mbedtls_nv_seed_poll, NULL,
6376 MBEDTLS_ENTROPY_BLOCK_SIZE,
6377 MBEDTLS_ENTROPY_SOURCE_STRONG );
6378#endif
6379
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006380 mbedtls_psa_drbg_init( MBEDTLS_PSA_RANDOM_STATE );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006381#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006382}
6383
6384/** Deinitialize the PSA random generator.
6385 */
6386static void mbedtls_psa_random_free( mbedtls_psa_random_context_t *rng )
6387{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006388#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6389 memset( rng, 0, sizeof( *rng ) );
6390#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006391 mbedtls_psa_drbg_free( MBEDTLS_PSA_RANDOM_STATE );
Gilles Peskine30524eb2020-11-13 17:02:26 +01006392 rng->entropy_free( &rng->entropy );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006393#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006394}
6395
6396/** Seed the PSA random generator.
6397 */
6398static psa_status_t mbedtls_psa_random_seed( mbedtls_psa_random_context_t *rng )
6399{
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006400#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6401 /* Do nothing: the external RNG seeds itself. */
6402 (void) rng;
6403 return( PSA_SUCCESS );
6404#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006405 const unsigned char drbg_seed[] = "PSA";
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006406 int ret = mbedtls_psa_drbg_seed( &rng->entropy,
6407 drbg_seed, sizeof( drbg_seed ) - 1 );
Gilles Peskine30524eb2020-11-13 17:02:26 +01006408 return mbedtls_to_psa_error( ret );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006409#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01006410}
6411
Gilles Peskinee59236f2018-01-27 23:32:46 +01006412psa_status_t psa_generate_random( uint8_t *output,
6413 size_t output_size )
6414{
Gilles Peskinee59236f2018-01-27 23:32:46 +01006415 GUARD_MODULE_INITIALIZED;
6416
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006417#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6418
6419 size_t output_length = 0;
6420 psa_status_t status = mbedtls_psa_external_get_random( &global_data.rng,
6421 output, output_size,
6422 &output_length );
6423 if( status != PSA_SUCCESS )
6424 return( status );
6425 /* Breaking up a request into smaller chunks is currently not supported
6426 * for the extrernal RNG interface. */
6427 if( output_length != output_size )
6428 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
6429 return( PSA_SUCCESS );
6430
6431#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
6432
Gilles Peskine71ddab92021-01-04 21:01:07 +01006433 while( output_size > 0 )
Gilles Peskinef181eca2019-08-07 13:49:00 +02006434 {
Gilles Peskine71ddab92021-01-04 21:01:07 +01006435 size_t request_size =
6436 ( output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ?
6437 MBEDTLS_PSA_RANDOM_MAX_REQUEST :
6438 output_size );
Gilles Peskine0c59ba82021-01-05 14:10:59 +01006439 int ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
6440 output, request_size );
Gilles Peskinef181eca2019-08-07 13:49:00 +02006441 if( ret != 0 )
6442 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine71ddab92021-01-04 21:01:07 +01006443 output_size -= request_size;
6444 output += request_size;
Gilles Peskinef181eca2019-08-07 13:49:00 +02006445 }
Gilles Peskine0c59ba82021-01-05 14:10:59 +01006446 return( PSA_SUCCESS );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006447#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006448}
6449
Gilles Peskine8814fc42020-12-14 15:33:44 +01006450/* Wrapper function allowing the classic API to use the PSA RNG.
Gilles Peskine9c3e0602021-01-05 16:03:55 +01006451 *
6452 * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
6453 * `psa_generate_random(...)`. The state parameter is ignored since the
6454 * PSA API doesn't support passing an explicit state.
6455 *
6456 * In the non-external case, psa_generate_random() calls an
6457 * `mbedtls_xxx_drbg_random` function which has exactly the same signature
6458 * and semantics as mbedtls_psa_get_random(). As an optimization,
6459 * instead of doing this back-and-forth between the PSA API and the
6460 * classic API, psa_crypto_random_impl.h defines `mbedtls_psa_get_random`
6461 * as a constant function pointer to `mbedtls_xxx_drbg_random`.
Gilles Peskine8814fc42020-12-14 15:33:44 +01006462 */
6463#if defined (MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
6464int mbedtls_psa_get_random( void *p_rng,
6465 unsigned char *output,
6466 size_t output_size )
6467{
Gilles Peskine9c3e0602021-01-05 16:03:55 +01006468 /* This function takes a pointer to the RNG state because that's what
6469 * classic mbedtls functions using an RNG expect. The PSA RNG manages
6470 * its own state internally and doesn't let the caller access that state.
6471 * So we just ignore the state parameter, and in practice we'll pass
6472 * NULL. */
Gilles Peskine8814fc42020-12-14 15:33:44 +01006473 (void) p_rng;
6474 psa_status_t status = psa_generate_random( output, output_size );
6475 if( status == PSA_SUCCESS )
6476 return( 0 );
6477 else
6478 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
6479}
6480#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
6481
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006482#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
6483#include "mbedtls/entropy_poll.h"
6484
Gilles Peskine7228da22019-07-15 11:06:15 +02006485psa_status_t mbedtls_psa_inject_entropy( const uint8_t *seed,
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006486 size_t seed_size )
6487{
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006488 if( global_data.initialized )
6489 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02006490
6491 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
6492 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
6493 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
6494 return( PSA_ERROR_INVALID_ARGUMENT );
6495
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006496 return( mbedtls_psa_storage_inject_entropy( seed, seed_size ) );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006497}
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01006498#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02006499
John Durkop07cc04a2020-11-16 22:08:34 -08006500#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
Gilles Peskinee56e8782019-04-26 17:34:02 +02006501static psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters,
6502 size_t domain_parameters_size,
6503 int *exponent )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006504{
Gilles Peskinee56e8782019-04-26 17:34:02 +02006505 size_t i;
6506 uint32_t acc = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006507
Gilles Peskinee56e8782019-04-26 17:34:02 +02006508 if( domain_parameters_size == 0 )
6509 {
6510 *exponent = 65537;
6511 return( PSA_SUCCESS );
6512 }
6513
6514 /* Mbed TLS encodes the public exponent as an int. For simplicity, only
6515 * support values that fit in a 32-bit integer, which is larger than
6516 * int on just about every platform anyway. */
6517 if( domain_parameters_size > sizeof( acc ) )
6518 return( PSA_ERROR_NOT_SUPPORTED );
6519 for( i = 0; i < domain_parameters_size; i++ )
6520 acc = ( acc << 8 ) | domain_parameters[i];
6521 if( acc > INT_MAX )
6522 return( PSA_ERROR_NOT_SUPPORTED );
6523 *exponent = acc;
6524 return( PSA_SUCCESS );
6525}
John Durkop07cc04a2020-11-16 22:08:34 -08006526#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */
Gilles Peskinee56e8782019-04-26 17:34:02 +02006527
Gilles Peskine35ef36b2019-05-16 19:42:05 +02006528static psa_status_t psa_generate_key_internal(
Gilles Peskinee56e8782019-04-26 17:34:02 +02006529 psa_key_slot_t *slot, size_t bits,
6530 const uint8_t *domain_parameters, size_t domain_parameters_size )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006531{
Gilles Peskine8e338702019-07-30 20:06:31 +02006532 psa_key_type_t type = slot->attr.type;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006533
Gilles Peskinee56e8782019-04-26 17:34:02 +02006534 if( domain_parameters == NULL && domain_parameters_size != 0 )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006535 return( PSA_ERROR_INVALID_ARGUMENT );
6536
Gilles Peskinee59236f2018-01-27 23:32:46 +01006537 if( key_type_is_raw_bytes( type ) )
6538 {
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006539 psa_status_t status;
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006540
6541 status = validate_unstructured_key_bit_size( slot->attr.type, bits );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006542 if( status != PSA_SUCCESS )
6543 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006544
6545 /* Allocate memory for the key */
Steven Cooreman75b74362020-07-28 14:30:13 +02006546 status = psa_allocate_buffer_to_slot( slot, PSA_BITS_TO_BYTES( bits ) );
6547 if( status != PSA_SUCCESS )
Steven Cooreman29149862020-08-05 15:43:42 +02006548 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006549
Steven Cooreman71fd80d2020-07-07 21:12:27 +02006550 status = psa_generate_random( slot->data.key.data,
6551 slot->data.key.bytes );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006552 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006553 return( status );
Steven Cooreman81be2fa2020-07-24 22:04:59 +02006554
6555 slot->attr.bits = (psa_key_bits_t) bits;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006556#if defined(MBEDTLS_DES_C)
6557 if( type == PSA_KEY_TYPE_DES )
Steven Cooreman71fd80d2020-07-07 21:12:27 +02006558 psa_des_set_key_parity( slot->data.key.data,
6559 slot->data.key.bytes );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006560#endif /* MBEDTLS_DES_C */
6561 }
6562 else
6563
John Durkop07cc04a2020-11-16 22:08:34 -08006564#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02006565 if ( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006566 {
Steven Cooremana01795d2020-07-24 22:48:15 +02006567 mbedtls_rsa_context rsa;
Janos Follath24eed8d2019-11-22 13:21:35 +00006568 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinee56e8782019-04-26 17:34:02 +02006569 int exponent;
6570 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006571 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
6572 return( PSA_ERROR_NOT_SUPPORTED );
6573 /* Accept only byte-aligned keys, for the same reasons as
6574 * in psa_import_rsa_key(). */
6575 if( bits % 8 != 0 )
6576 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskinee56e8782019-04-26 17:34:02 +02006577 status = psa_read_rsa_exponent( domain_parameters,
6578 domain_parameters_size,
6579 &exponent );
6580 if( status != PSA_SUCCESS )
6581 return( status );
Steven Cooremana01795d2020-07-24 22:48:15 +02006582 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
6583 ret = mbedtls_rsa_gen_key( &rsa,
Gilles Peskine30524eb2020-11-13 17:02:26 +01006584 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006585 MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskinee59236f2018-01-27 23:32:46 +01006586 (unsigned int) bits,
6587 exponent );
6588 if( ret != 0 )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006589 return( mbedtls_to_psa_error( ret ) );
Steven Cooremana01795d2020-07-24 22:48:15 +02006590
6591 /* Make sure to always have an export representation available */
6592 size_t bytes = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE( bits );
6593
Steven Cooreman75b74362020-07-28 14:30:13 +02006594 status = psa_allocate_buffer_to_slot( slot, bytes );
6595 if( status != PSA_SUCCESS )
Steven Cooremana01795d2020-07-24 22:48:15 +02006596 {
6597 mbedtls_rsa_free( &rsa );
Steven Cooreman29149862020-08-05 15:43:42 +02006598 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006599 }
Steven Cooremana01795d2020-07-24 22:48:15 +02006600
6601 status = psa_export_rsa_key( type,
6602 &rsa,
6603 slot->data.key.data,
6604 bytes,
6605 &slot->data.key.bytes );
6606 mbedtls_rsa_free( &rsa );
6607 if( status != PSA_SUCCESS )
Steven Cooremana01795d2020-07-24 22:48:15 +02006608 psa_remove_key_data_from_memory( slot );
Steven Cooreman560c28a2020-07-24 23:20:24 +02006609 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006610 }
6611 else
John Durkop07cc04a2020-11-16 22:08:34 -08006612#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006613
John Durkop9814fa22020-11-04 12:28:15 -08006614#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02006615 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006616 {
Paul Elliott8ff510a2020-06-02 17:19:28 +01006617 psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( type );
Gilles Peskine4295e8b2019-12-02 21:39:10 +01006618 mbedtls_ecp_group_id grp_id =
6619 mbedtls_ecc_group_of_psa( curve, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006620 const mbedtls_ecp_curve_info *curve_info =
6621 mbedtls_ecp_curve_info_from_grp_id( grp_id );
Steven Cooremanacda8342020-07-24 23:09:52 +02006622 mbedtls_ecp_keypair ecp;
Janos Follath24eed8d2019-11-22 13:21:35 +00006623 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinee56e8782019-04-26 17:34:02 +02006624 if( domain_parameters_size != 0 )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006625 return( PSA_ERROR_NOT_SUPPORTED );
6626 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
6627 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooremanacda8342020-07-24 23:09:52 +02006628 mbedtls_ecp_keypair_init( &ecp );
6629 ret = mbedtls_ecp_gen_key( grp_id, &ecp,
Gilles Peskine30524eb2020-11-13 17:02:26 +01006630 mbedtls_psa_get_random,
Gilles Peskine5894e8e2020-12-14 14:54:06 +01006631 MBEDTLS_PSA_RANDOM_STATE );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006632 if( ret != 0 )
6633 {
Steven Cooremanacda8342020-07-24 23:09:52 +02006634 mbedtls_ecp_keypair_free( &ecp );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006635 return( mbedtls_to_psa_error( ret ) );
6636 }
Steven Cooremanacda8342020-07-24 23:09:52 +02006637
6638
6639 /* Make sure to always have an export representation available */
6640 size_t bytes = PSA_BITS_TO_BYTES( bits );
Steven Cooreman75b74362020-07-28 14:30:13 +02006641 psa_status_t status = psa_allocate_buffer_to_slot( slot, bytes );
6642 if( status != PSA_SUCCESS )
Steven Cooremanacda8342020-07-24 23:09:52 +02006643 {
6644 mbedtls_ecp_keypair_free( &ecp );
Steven Cooreman29149862020-08-05 15:43:42 +02006645 return( status );
Steven Cooremanacda8342020-07-24 23:09:52 +02006646 }
Steven Cooreman75b74362020-07-28 14:30:13 +02006647
6648 status = mbedtls_to_psa_error(
Steven Cooremanacda8342020-07-24 23:09:52 +02006649 mbedtls_ecp_write_key( &ecp, slot->data.key.data, bytes ) );
6650
6651 mbedtls_ecp_keypair_free( &ecp );
Steven Cooremanb7f6dea2020-08-05 16:07:20 +02006652 if( status != PSA_SUCCESS ) {
6653 memset( slot->data.key.data, 0, bytes );
Steven Cooremanacda8342020-07-24 23:09:52 +02006654 psa_remove_key_data_from_memory( slot );
Steven Cooremanb7f6dea2020-08-05 16:07:20 +02006655 }
Steven Cooreman560c28a2020-07-24 23:20:24 +02006656 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006657 }
6658 else
John Durkop9814fa22020-11-04 12:28:15 -08006659#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
Steven Cooreman29149862020-08-05 15:43:42 +02006660 {
Gilles Peskinee59236f2018-01-27 23:32:46 +01006661 return( PSA_ERROR_NOT_SUPPORTED );
Steven Cooreman29149862020-08-05 15:43:42 +02006662 }
Gilles Peskinee59236f2018-01-27 23:32:46 +01006663
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006664 return( PSA_SUCCESS );
6665}
Darryl Green0c6575a2018-11-07 16:05:30 +00006666
Gilles Peskine35ef36b2019-05-16 19:42:05 +02006667psa_status_t psa_generate_key( const psa_key_attributes_t *attributes,
Ronald Croncf56a0a2020-08-04 09:51:30 +02006668 mbedtls_svc_key_id_t *key )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006669{
6670 psa_status_t status;
6671 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02006672 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine11792082019-08-06 18:36:36 +02006673
Ronald Cron81709fc2020-11-14 12:10:32 +01006674 *key = MBEDTLS_SVC_KEY_ID_INIT;
6675
Gilles Peskine0f84d622019-09-12 19:03:13 +02006676 /* Reject any attempt to create a zero-length key so that we don't
6677 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
6678 if( psa_get_key_bits( attributes ) == 0 )
6679 return( PSA_ERROR_INVALID_ARGUMENT );
6680
Ronald Cron81709fc2020-11-14 12:10:32 +01006681 status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE, attributes,
6682 &slot, &driver );
Gilles Peskine11792082019-08-06 18:36:36 +02006683 if( status != PSA_SUCCESS )
6684 goto exit;
6685
Steven Cooreman2a1664c2020-07-20 15:33:08 +02006686 status = psa_driver_wrapper_generate_key( attributes,
6687 slot );
6688 if( status != PSA_ERROR_NOT_SUPPORTED ||
6689 psa_key_lifetime_is_external( attributes->core.lifetime ) )
6690 goto exit;
6691
6692 status = psa_generate_key_internal(
6693 slot, attributes->core.bits,
6694 attributes->domain_parameters, attributes->domain_parameters_size );
Gilles Peskine11792082019-08-06 18:36:36 +02006695
6696exit:
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006697 if( status == PSA_SUCCESS )
Ronald Cron81709fc2020-11-14 12:10:32 +01006698 status = psa_finish_key_creation( slot, driver, key );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02006699 if( status != PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02006700 psa_fail_key_creation( slot, driver );
Ronald Cronf95a2b12020-10-22 15:24:49 +02006701
Darryl Green0c6575a2018-11-07 16:05:30 +00006702 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006703}
6704
6705
Gilles Peskinee59236f2018-01-27 23:32:46 +01006706
6707/****************************************************************/
6708/* Module setup */
6709/****************************************************************/
6710
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006711#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
Gilles Peskine5e769522018-11-20 21:59:56 +01006712psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
6713 void (* entropy_init )( mbedtls_entropy_context *ctx ),
6714 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
6715{
6716 if( global_data.rng_state != RNG_NOT_INITIALIZED )
6717 return( PSA_ERROR_BAD_STATE );
Gilles Peskine30524eb2020-11-13 17:02:26 +01006718 global_data.rng.entropy_init = entropy_init;
6719 global_data.rng.entropy_free = entropy_free;
Gilles Peskine5e769522018-11-20 21:59:56 +01006720 return( PSA_SUCCESS );
6721}
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01006722#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
Gilles Peskine5e769522018-11-20 21:59:56 +01006723
Gilles Peskinee59236f2018-01-27 23:32:46 +01006724void mbedtls_psa_crypto_free( void )
6725{
Gilles Peskine66fb1262018-12-10 16:29:04 +01006726 psa_wipe_all_key_slots( );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006727 if( global_data.rng_state != RNG_NOT_INITIALIZED )
6728 {
Gilles Peskine30524eb2020-11-13 17:02:26 +01006729 mbedtls_psa_random_free( &global_data.rng );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006730 }
6731 /* Wipe all remaining data, including configuration.
6732 * In particular, this sets all state indicator to the value
6733 * indicating "uninitialized". */
Gilles Peskine3f108122018-12-07 18:14:53 +01006734 mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
Gilles Peskinea8ade162019-06-26 11:24:49 +02006735#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined0890212019-06-24 14:34:43 +02006736 /* Unregister all secure element drivers, so that we restart from
6737 * a pristine state. */
6738 psa_unregister_all_se_drivers( );
Gilles Peskinea8ade162019-06-26 11:24:49 +02006739#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006740}
6741
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006742#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
6743/** Recover a transaction that was interrupted by a power failure.
6744 *
6745 * This function is called during initialization, before psa_crypto_init()
6746 * returns. If this function returns a failure status, the initialization
6747 * fails.
6748 */
6749static psa_status_t psa_crypto_recover_transaction(
6750 const psa_crypto_transaction_t *transaction )
6751{
6752 switch( transaction->unknown.type )
6753 {
6754 case PSA_CRYPTO_TRANSACTION_CREATE_KEY:
6755 case PSA_CRYPTO_TRANSACTION_DESTROY_KEY:
Janos Follath1d57a202019-08-13 12:15:34 +01006756 /* TODO - fall through to the failure case until this
Gilles Peskinec9d7f942019-08-13 16:17:16 +02006757 * is implemented.
6758 * https://github.com/ARMmbed/mbed-crypto/issues/218
6759 */
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006760 default:
6761 /* We found an unsupported transaction in the storage.
6762 * We don't know what state the storage is in. Give up. */
6763 return( PSA_ERROR_STORAGE_FAILURE );
6764 }
6765}
6766#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
6767
Gilles Peskinee59236f2018-01-27 23:32:46 +01006768psa_status_t psa_crypto_init( void )
6769{
Gilles Peskine66fb1262018-12-10 16:29:04 +01006770 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006771
Gilles Peskinec6b69072018-11-20 21:42:52 +01006772 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006773 if( global_data.initialized != 0 )
6774 return( PSA_SUCCESS );
6775
Gilles Peskine30524eb2020-11-13 17:02:26 +01006776 /* Initialize and seed the random generator. */
6777 mbedtls_psa_random_init( &global_data.rng );
Gilles Peskinec6b69072018-11-20 21:42:52 +01006778 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskine30524eb2020-11-13 17:02:26 +01006779 status = mbedtls_psa_random_seed( &global_data.rng );
Gilles Peskine66fb1262018-12-10 16:29:04 +01006780 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006781 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01006782 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01006783
Gilles Peskine66fb1262018-12-10 16:29:04 +01006784 status = psa_initialize_key_slots( );
6785 if( status != PSA_SUCCESS )
6786 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01006787
Gilles Peskined9348f22019-10-01 15:22:29 +02006788#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
6789 status = psa_init_all_se_drivers( );
6790 if( status != PSA_SUCCESS )
6791 goto exit;
6792#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
6793
Gilles Peskine4b734222019-07-24 15:56:31 +02006794#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
Gilles Peskinefc762652019-07-22 19:30:34 +02006795 status = psa_crypto_load_transaction( );
6796 if( status == PSA_SUCCESS )
6797 {
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02006798 status = psa_crypto_recover_transaction( &psa_crypto_transaction );
6799 if( status != PSA_SUCCESS )
6800 goto exit;
6801 status = psa_crypto_stop_transaction( );
Gilles Peskinefc762652019-07-22 19:30:34 +02006802 }
6803 else if( status == PSA_ERROR_DOES_NOT_EXIST )
6804 {
6805 /* There's no transaction to complete. It's all good. */
6806 status = PSA_SUCCESS;
6807 }
Gilles Peskine4b734222019-07-24 15:56:31 +02006808#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
Gilles Peskinefc762652019-07-22 19:30:34 +02006809
Gilles Peskinec6b69072018-11-20 21:42:52 +01006810 /* All done. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01006811 global_data.initialized = 1;
6812
6813exit:
Gilles Peskine66fb1262018-12-10 16:29:04 +01006814 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01006815 mbedtls_psa_crypto_free( );
Gilles Peskine66fb1262018-12-10 16:29:04 +01006816 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01006817}
6818
6819#endif /* MBEDTLS_PSA_CRYPTO_C */