blob: 5dd0fa832d6df99ffcf3d0d84f6375088a78d941 [file] [log] [blame]
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +02001/*
2 * Public Key abstraction layer
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020018 */
19
Gilles Peskinedb09ef62020-06-03 01:43:33 +020020#include "common.h"
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020021
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if defined(MBEDTLS_PK_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000023#include "mbedtls/pk.h"
Chris Jonesdaacb592021-03-09 17:03:29 +000024#include "pk_wrap.h"
Neil Armstrongca5b55f2022-03-15 15:00:55 +010025#include "pkwrite.h"
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020026
Manuel Pégourié-Gonnard47728842022-07-18 13:00:40 +020027#include "hash_info.h"
Manuel Pégourié-Gonnarda370e062022-07-05 11:55:20 +020028
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050029#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000030#include "mbedtls/error.h"
Andres AG72849872017-01-19 11:24:33 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000033#include "mbedtls/rsa.h"
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020034#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/ecp.h"
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020037#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000039#include "mbedtls/ecdsa.h"
Manuel Pégourié-Gonnard7c5819e2013-07-10 12:29:57 +020040#endif
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020041
Jerry Yub02ee182022-03-16 10:30:41 +080042#if defined(MBEDTLS_PSA_CRYPTO_C)
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +010043#include "mbedtls/psa_util.h"
44#endif
45
Andres AG72849872017-01-19 11:24:33 +000046#include <limits.h>
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010047#include <stdint.h>
Paul Bakker34617722014-06-13 17:20:13 +020048
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050049/* Parameter validation macros based on platform_util.h */
50#define PK_VALIDATE_RET( cond ) \
51 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
52#define PK_VALIDATE( cond ) \
53 MBEDTLS_INTERNAL_VALIDATE( cond )
54
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020055/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056 * Initialise a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020057 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058void mbedtls_pk_init( mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020059{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050060 PK_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020061
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +020062 ctx->pk_info = NULL;
63 ctx->pk_ctx = NULL;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020064}
65
66/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067 * Free (the components of) a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020068 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069void mbedtls_pk_free( mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020070{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050071 if( ctx == NULL )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020072 return;
73
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050074 if ( ctx->pk_info != NULL )
75 ctx->pk_info->ctx_free_func( ctx->pk_ctx );
Manuel Pégourié-Gonnard1f73a652013-07-09 10:26:41 +020076
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050077 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020078}
79
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +020080#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020081/*
82 * Initialize a restart context
83 */
84void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
85{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050086 PK_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020087 ctx->pk_info = NULL;
88 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020089}
90
91/*
92 * Free the components of a restart context
93 */
94void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
95{
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020096 if( ctx == NULL || ctx->pk_info == NULL ||
97 ctx->pk_info->rs_free_func == NULL )
98 {
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020099 return;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200100 }
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200101
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200102 ctx->pk_info->rs_free_func( ctx->rs_ctx );
103
104 ctx->pk_info = NULL;
105 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200106}
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200107#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200108
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200109/*
110 * Get pk_info structure from type
111 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200113{
114 switch( pk_type ) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115#if defined(MBEDTLS_RSA_C)
116 case MBEDTLS_PK_RSA:
117 return( &mbedtls_rsa_info );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200118#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200119#if defined(MBEDTLS_ECP_C)
120 case MBEDTLS_PK_ECKEY:
121 return( &mbedtls_eckey_info );
122 case MBEDTLS_PK_ECKEY_DH:
123 return( &mbedtls_eckeydh_info );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200124#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125#if defined(MBEDTLS_ECDSA_C)
126 case MBEDTLS_PK_ECDSA:
127 return( &mbedtls_ecdsa_info );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200128#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129 /* MBEDTLS_PK_RSA_ALT omitted on purpose */
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200130 default:
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200131 return( NULL );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200132 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200133}
134
135/*
Manuel Pégourié-Gonnardab466942013-08-15 11:30:27 +0200136 * Initialise context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200137 */
Manuel Pégourié-Gonnardd9e6a3a2015-05-14 19:41:36 +0200138int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200139{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500140 PK_VALIDATE_RET( ctx != NULL );
141 if( info == NULL || ctx->pk_info != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200143
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200144 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200145 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200146
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200147 ctx->pk_info = info;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200148
149 return( 0 );
150}
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200151
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200152#if defined(MBEDTLS_USE_PSA_CRYPTO)
153/*
154 * Initialise a PSA-wrapping context
155 */
Ronald Croncf56a0a2020-08-04 09:51:30 +0200156int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx,
Andrzej Kurek03e01462022-01-03 12:53:24 +0100157 const mbedtls_svc_key_id_t key )
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200158{
Neil Armstrongeabbf9d2022-03-15 12:01:26 +0100159 const mbedtls_pk_info_t *info = NULL;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200160 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Andrzej Kurek03e01462022-01-03 12:53:24 +0100161 mbedtls_svc_key_id_t *pk_ctx;
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100162 psa_key_type_t type;
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200163
164 if( ctx == NULL || ctx->pk_info != NULL )
165 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
166
Gilles Peskined2d45c12019-05-27 14:53:13 +0200167 if( PSA_SUCCESS != psa_get_key_attributes( key, &attributes ) )
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100168 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Gilles Peskined2d45c12019-05-27 14:53:13 +0200169 type = psa_get_key_type( &attributes );
170 psa_reset_key_attributes( &attributes );
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100171
Neil Armstrongeabbf9d2022-03-15 12:01:26 +0100172 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
173 info = &mbedtls_pk_ecdsa_opaque_info;
Neil Armstrongeccf88f2022-04-08 15:11:50 +0200174 else if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Neil Armstrongeabbf9d2022-03-15 12:01:26 +0100175 info = &mbedtls_pk_rsa_opaque_info;
176 else
177 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100178
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200179 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
180 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
181
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200182 ctx->pk_info = info;
183
Andrzej Kurek03e01462022-01-03 12:53:24 +0100184 pk_ctx = (mbedtls_svc_key_id_t *) ctx->pk_ctx;
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100185 *pk_ctx = key;
186
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200187 return( 0 );
188}
189#endif /* MBEDTLS_USE_PSA_CRYPTO */
190
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnardb4fae572014-01-20 11:22:25 +0100192/*
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200193 * Initialize an RSA-alt context
194 */
Manuel Pégourié-Gonnardd9e6a3a2015-05-14 19:41:36 +0200195int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200196 mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
197 mbedtls_pk_rsa_alt_sign_func sign_func,
198 mbedtls_pk_rsa_alt_key_len_func key_len_func )
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200199{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200 mbedtls_rsa_alt_context *rsa_alt;
201 const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200202
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500203 PK_VALIDATE_RET( ctx != NULL );
204 if( ctx->pk_info != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200205 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200206
207 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200208 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200209
210 ctx->pk_info = info;
211
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212 rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200213
214 rsa_alt->key = key;
215 rsa_alt->decrypt_func = decrypt_func;
216 rsa_alt->sign_func = sign_func;
217 rsa_alt->key_len_func = key_len_func;
218
219 return( 0 );
220}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200221#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200222
223/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200224 * Tell if a PK can do the operations of the given type
225 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200226int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200227{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500228 /* A context with null pk_info is not set up yet and can't do anything.
229 * For backward compatibility, also accept NULL instead of a context
230 * pointer. */
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200231 if( ctx == NULL || ctx->pk_info == NULL )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200232 return( 0 );
233
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200234 return( ctx->pk_info->can_do( type ) );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200235}
236
Neil Armstronga88b1582022-05-11 14:11:25 +0200237#if defined(MBEDTLS_USE_PSA_CRYPTO)
238/*
239 * Tell if a PK can do the operations of the given PSA algorithm
240 */
Neil Armstrong408f6a62022-05-17 14:23:20 +0200241int mbedtls_pk_can_do_ext( const mbedtls_pk_context *ctx, psa_algorithm_t alg,
242 psa_key_usage_t usage )
Neil Armstronga88b1582022-05-11 14:11:25 +0200243{
Neil Armstrong408f6a62022-05-17 14:23:20 +0200244 psa_key_usage_t key_usage;
245
Neil Armstronga88b1582022-05-11 14:11:25 +0200246 /* A context with null pk_info is not set up yet and can't do anything.
247 * For backward compatibility, also accept NULL instead of a context
248 * pointer. */
249 if( ctx == NULL || ctx->pk_info == NULL )
250 return( 0 );
251
252 /* Filter out non allowed algorithms */
253 if( PSA_ALG_IS_ECDSA( alg ) == 0 &&
254 PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) == 0 &&
255 PSA_ALG_IS_RSA_PSS( alg ) == 0 &&
256 alg != PSA_ALG_RSA_PKCS1V15_CRYPT &&
257 PSA_ALG_IS_ECDH( alg ) == 0 )
258 return( 0 );
259
Neil Armstrong408f6a62022-05-17 14:23:20 +0200260 /* Filter out non allowed usage flags */
Neil Armstrong81d391f2022-05-20 09:26:16 +0200261 if( usage == 0 ||
262 ( usage & ~( PSA_KEY_USAGE_SIGN_HASH |
Neil Armstrong408f6a62022-05-17 14:23:20 +0200263 PSA_KEY_USAGE_DECRYPT |
264 PSA_KEY_USAGE_DERIVE ) ) != 0 )
265 return( 0 );
266
Neil Armstronga88b1582022-05-11 14:11:25 +0200267 /* Wildcard hash is not allowed */
268 if( PSA_ALG_IS_SIGN_HASH( alg ) &&
269 PSA_ALG_SIGN_GET_HASH( alg ) == PSA_ALG_ANY_HASH )
270 return( 0 );
271
272 if( mbedtls_pk_get_type( ctx ) != MBEDTLS_PK_OPAQUE )
273 {
274 mbedtls_pk_type_t type;
275
276 if( PSA_ALG_IS_ECDSA( alg ) || PSA_ALG_IS_ECDH( alg ) )
277 type = MBEDTLS_PK_ECKEY;
Neil Armstrong084338d2022-05-19 16:22:40 +0200278 else if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) ||
279 alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Neil Armstronga88b1582022-05-11 14:11:25 +0200280 type = MBEDTLS_PK_RSA;
281 else if( PSA_ALG_IS_RSA_PSS( alg ) )
282 type = MBEDTLS_PK_RSASSA_PSS;
283 else
284 return( 0 );
285
Neil Armstrong084338d2022-05-19 16:22:40 +0200286 if( ctx->pk_info->can_do( type ) == 0 )
Neil Armstrong408f6a62022-05-17 14:23:20 +0200287 return( 0 );
288
Neil Armstrong084338d2022-05-19 16:22:40 +0200289 switch( type )
290 {
291 case MBEDTLS_PK_ECKEY:
292 key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE;
293 break;
294 case MBEDTLS_PK_RSA:
295 case MBEDTLS_PK_RSASSA_PSS:
296 key_usage = PSA_KEY_USAGE_SIGN_HASH |
297 PSA_KEY_USAGE_SIGN_MESSAGE |
298 PSA_KEY_USAGE_DECRYPT;
299 break;
300 default:
Neil Armstrongb80785f2022-05-20 09:25:55 +0200301 /* Should never happen */
Neil Armstrong084338d2022-05-19 16:22:40 +0200302 return( 0 );
303 }
304
305 return( ( key_usage & usage ) == usage );
Neil Armstronga88b1582022-05-11 14:11:25 +0200306 }
307
308 const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx;
309 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
310 psa_algorithm_t key_alg, key_alg2;
311 psa_status_t status;
312
313 status = psa_get_key_attributes( *key, &attributes );
314 if( status != PSA_SUCCESS )
315 return( 0 );
316
317 key_alg = psa_get_key_algorithm( &attributes );
318 key_alg2 = psa_get_key_enrollment_algorithm( &attributes );
Neil Armstrong408f6a62022-05-17 14:23:20 +0200319 key_usage = psa_get_key_usage_flags( &attributes );
Neil Armstronga88b1582022-05-11 14:11:25 +0200320 psa_reset_key_attributes( &attributes );
321
Neil Armstrong408f6a62022-05-17 14:23:20 +0200322 if( ( key_usage & usage ) != usage )
323 return( 0 );
324
Neil Armstronga88b1582022-05-11 14:11:25 +0200325 /*
Neil Armstrongdab56ba2022-05-17 11:56:55 +0200326 * Common case: the key alg or alg2 only allows alg.
Neil Armstronga88b1582022-05-11 14:11:25 +0200327 * This will match PSA_ALG_RSA_PKCS1V15_CRYPT & PSA_ALG_IS_ECDH
328 * directly.
329 * This would also match ECDSA/RSA_PKCS1V15_SIGN/RSA_PSS with
330 * a fixed hash on key_alg/key_alg2.
331 */
332 if( alg == key_alg || alg == key_alg2 )
333 return( 1 );
334
335 /*
Neil Armstrongbbb8b752022-05-17 14:58:27 +0200336 * If key_alg or key_alg2 is a hash-and-sign with a wildcard for the hash,
337 * and alg is the same hash-and-sign family with any hash,
Neil Armstronga88b1582022-05-11 14:11:25 +0200338 * then alg is compliant with this key alg
339 */
340 if( PSA_ALG_IS_SIGN_HASH( alg ) )
341 {
342
343 if( PSA_ALG_IS_SIGN_HASH( key_alg ) &&
344 PSA_ALG_SIGN_GET_HASH( key_alg ) == PSA_ALG_ANY_HASH &&
345 ( alg & ~PSA_ALG_HASH_MASK ) == ( key_alg & ~PSA_ALG_HASH_MASK ) )
346 return( 1 );
347
348 if( PSA_ALG_IS_SIGN_HASH( key_alg2 ) &&
349 PSA_ALG_SIGN_GET_HASH( key_alg2 ) == PSA_ALG_ANY_HASH &&
350 ( alg & ~PSA_ALG_HASH_MASK ) == ( key_alg2 & ~PSA_ALG_HASH_MASK ) )
351 return( 1 );
352 }
353
354 return( 0 );
355}
356#endif /* MBEDTLS_USE_PSA_CRYPTO */
357
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200358/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359 * Helper for mbedtls_pk_sign and mbedtls_pk_verify
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200360 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200362{
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200363 if( *hash_len != 0 )
364 return( 0 );
365
Manuel Pégourié-Gonnard47728842022-07-18 13:00:40 +0200366 *hash_len = mbedtls_hash_info_get_size( md_alg );
Manuel Pégourié-Gonnarda370e062022-07-05 11:55:20 +0200367
368 if( *hash_len == 0 )
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200369 return( -1 );
370
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200371 return( 0 );
372}
373
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200374#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200375/*
376 * Helper to set up a restart context if needed
377 */
378static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200379 const mbedtls_pk_info_t *info )
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200380{
Manuel Pégourié-Gonnardc8c12b62018-07-02 13:09:39 +0200381 /* Don't do anything if already set up or invalid */
382 if( ctx == NULL || ctx->pk_info != NULL )
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200383 return( 0 );
384
385 /* Should never happen when we're called */
386 if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
387 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
388
389 if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
390 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
391
392 ctx->pk_info = info;
393
394 return( 0 );
395}
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200396#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200397
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200398/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200399 * Verify a signature (restartable)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200400 */
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200401int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
402 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200403 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200404 const unsigned char *sig, size_t sig_len,
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200405 mbedtls_pk_restart_ctx *rs_ctx )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200406{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500407 PK_VALIDATE_RET( ctx != NULL );
408 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
409 hash != NULL );
410 PK_VALIDATE_RET( sig != NULL );
411
412 if( ctx->pk_info == NULL ||
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200413 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200415
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200416#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200417 /* optimization: use non-restartable version if restart disabled */
418 if( rs_ctx != NULL &&
Manuel Pégourié-Gonnardb843b152018-10-16 10:41:31 +0200419 mbedtls_ecp_restart_is_enabled() &&
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200420 ctx->pk_info->verify_rs_func != NULL )
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200421 {
Janos Follath24eed8d2019-11-22 13:21:35 +0000422 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200423
424 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
425 return( ret );
426
427 ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
428 md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
429
430 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
431 mbedtls_pk_restart_free( rs_ctx );
432
433 return( ret );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200434 }
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200435#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200436 (void) rs_ctx;
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200437#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200438
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200439 if( ctx->pk_info->verify_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200441
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200442 return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200443 sig, sig_len ) );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200444}
445
446/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200447 * Verify a signature
448 */
449int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
450 const unsigned char *hash, size_t hash_len,
451 const unsigned char *sig, size_t sig_len )
452{
453 return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
454 sig, sig_len, NULL ) );
455}
456
457/*
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200458 * Verify a signature with options
459 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
461 mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200462 const unsigned char *hash, size_t hash_len,
463 const unsigned char *sig, size_t sig_len )
464{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500465 PK_VALIDATE_RET( ctx != NULL );
466 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
467 hash != NULL );
468 PK_VALIDATE_RET( sig != NULL );
469
470 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 if( ! mbedtls_pk_can_do( ctx, type ) )
474 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200475
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500476 if( type != MBEDTLS_PK_RSASSA_PSS )
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200477 {
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500478 /* General case: no options */
479 if( options != NULL )
480 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
481
482 return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
483 }
484
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500486 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
487 const mbedtls_pk_rsassa_pss_options *pss_opts;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200488
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100489#if SIZE_MAX > UINT_MAX
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500490 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
491 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100492#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000493
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500494 if( options == NULL )
495 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200496
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500497 pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200498
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500499#if defined(MBEDTLS_USE_PSA_CRYPTO)
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500500 if( pss_opts->mgf1_hash_id == md_alg &&
501 ( (size_t) pss_opts->expected_salt_len == hash_len ||
502 pss_opts->expected_salt_len == MBEDTLS_RSA_SALT_LEN_ANY ) )
503 {
504 /* see RSA_PUB_DER_MAX_BYTES in pkwrite.c */
505 unsigned char buf[ 38 + 2 * MBEDTLS_MPI_MAX_SIZE ];
506 unsigned char *p;
Andrzej Kurek59550532022-02-16 07:46:42 -0500507 int key_len;
508 size_t signature_length;
Andrzej Kurekd70fa0e2022-02-17 10:51:15 -0500509 psa_status_t status = PSA_ERROR_DATA_CORRUPT;
510 psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT;
Andrzej Kurek59550532022-02-16 07:46:42 -0500511
Manuel Pégourié-Gonnardabac0372022-07-18 13:41:11 +0200512 psa_algorithm_t psa_md_alg = mbedtls_hash_info_psa_from_md( md_alg );
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500513 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
514 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Andrzej Kurek90ba2cb2022-02-15 08:18:44 -0500515 psa_algorithm_t psa_sig_alg =
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500516 ( pss_opts->expected_salt_len == MBEDTLS_RSA_SALT_LEN_ANY ?
517 PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg) :
518 PSA_ALG_RSA_PSS(psa_md_alg) );
519 p = buf + sizeof( buf );
520 key_len = mbedtls_pk_write_pubkey( &p, buf, ctx );
521
522 if( key_len < 0 )
523 return( key_len );
524
525 psa_set_key_type( &attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY );
526 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
Andrzej Kurek90ba2cb2022-02-15 08:18:44 -0500527 psa_set_key_algorithm( &attributes, psa_sig_alg );
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500528
529 status = psa_import_key( &attributes,
530 buf + sizeof( buf ) - key_len, key_len,
531 &key_id );
532 if( status != PSA_SUCCESS )
533 {
534 psa_destroy_key( key_id );
Neil Armstrong19915c22022-03-01 15:21:02 +0100535 return( mbedtls_pk_error_from_psa( status ) );
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500536 }
537
Andrzej Kurek4a953cd2022-02-16 06:13:35 -0500538 /* This function requires returning MBEDTLS_ERR_PK_SIG_LEN_MISMATCH
539 * on a valid signature with trailing data in a buffer, but
540 * mbedtls_psa_rsa_verify_hash requires the sig_len to be exact,
541 * so for this reason the passed sig_len is overwritten. Smaller
542 * signature lengths should not be accepted for verification. */
543 signature_length = sig_len > mbedtls_pk_get_len( ctx ) ?
544 mbedtls_pk_get_len( ctx ) : sig_len;
Andrzej Kurek90ba2cb2022-02-15 08:18:44 -0500545 status = psa_verify_hash( key_id, psa_sig_alg, hash,
Andrzej Kurek4a953cd2022-02-16 06:13:35 -0500546 hash_len, sig, signature_length );
Andrzej Kurekd70fa0e2022-02-17 10:51:15 -0500547 destruction_status = psa_destroy_key( key_id );
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500548
Andrzej Kurek8666df62022-02-15 08:23:02 -0500549 if( status == PSA_SUCCESS && sig_len > mbedtls_pk_get_len( ctx ) )
550 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
551
Andrzej Kurekd70fa0e2022-02-17 10:51:15 -0500552 if( status == PSA_SUCCESS )
553 status = destruction_status;
554
Neil Armstrong19915c22022-03-01 15:21:02 +0100555 return( mbedtls_pk_error_from_psa_rsa( status ) );
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500556 }
557 else
558#endif
559 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560 if( sig_len < mbedtls_pk_get_len( ctx ) )
561 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200562
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563 ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
Thomas Daubney782a7f52021-05-19 12:27:35 +0100564 md_alg, (unsigned int) hash_len, hash,
565 pss_opts->mgf1_hash_id,
566 pss_opts->expected_salt_len,
567 sig );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200568 if( ret != 0 )
569 return( ret );
570
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200571 if( sig_len > mbedtls_pk_get_len( ctx ) )
572 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Andrzej Kurek90ba2cb2022-02-15 08:18:44 -0500573
574 return( 0 );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200575 }
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500576#else
577 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
578#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200579}
580
581/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200582 * Make a signature (restartable)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200583 */
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200584int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
585 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200586 const unsigned char *hash, size_t hash_len,
Gilles Peskinef00f1522021-06-22 00:09:00 +0200587 unsigned char *sig, size_t sig_size, size_t *sig_len,
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200588 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200589 mbedtls_pk_restart_ctx *rs_ctx )
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200590{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500591 PK_VALIDATE_RET( ctx != NULL );
592 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
593 hash != NULL );
594 PK_VALIDATE_RET( sig != NULL );
595
596 if( ctx->pk_info == NULL ||
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200597 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200599
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200600#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200601 /* optimization: use non-restartable version if restart disabled */
602 if( rs_ctx != NULL &&
Manuel Pégourié-Gonnardb843b152018-10-16 10:41:31 +0200603 mbedtls_ecp_restart_is_enabled() &&
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200604 ctx->pk_info->sign_rs_func != NULL )
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200605 {
Janos Follath24eed8d2019-11-22 13:21:35 +0000606 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200607
608 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
609 return( ret );
610
611 ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
Gilles Peskinef00f1522021-06-22 00:09:00 +0200612 hash, hash_len,
613 sig, sig_size, sig_len,
614 f_rng, p_rng, rs_ctx->rs_ctx );
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200615
616 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
617 mbedtls_pk_restart_free( rs_ctx );
618
619 return( ret );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200620 }
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200621#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200622 (void) rs_ctx;
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200623#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200624
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200625 if( ctx->pk_info->sign_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200627
Gilles Peskinef00f1522021-06-22 00:09:00 +0200628 return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg,
629 hash, hash_len,
630 sig, sig_size, sig_len,
631 f_rng, p_rng ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200632}
633
634/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200635 * Make a signature
636 */
637int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
638 const unsigned char *hash, size_t hash_len,
Gilles Peskinef00f1522021-06-22 00:09:00 +0200639 unsigned char *sig, size_t sig_size, size_t *sig_len,
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200640 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
641{
642 return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
Gilles Peskinef00f1522021-06-22 00:09:00 +0200643 sig, sig_size, sig_len,
644 f_rng, p_rng, NULL ) );
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200645}
646
Jerry Yu1d172a32022-03-12 19:12:05 +0800647#if defined(MBEDTLS_PSA_CRYPTO_C)
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200648/*
Jerry Yufb0621d2022-03-23 11:42:06 +0800649 * Make a signature given a signature type.
Jerry Yud69439a2022-02-24 15:52:15 +0800650 */
Jerry Yu718a9b42022-03-12 22:43:01 +0800651int mbedtls_pk_sign_ext( mbedtls_pk_type_t pk_type,
Jerry Yu8beb9e12022-03-12 16:23:53 +0800652 mbedtls_pk_context *ctx,
653 mbedtls_md_type_t md_alg,
654 const unsigned char *hash, size_t hash_len,
655 unsigned char *sig, size_t sig_size, size_t *sig_len,
656 int (*f_rng)(void *, unsigned char *, size_t),
657 void *p_rng )
Jerry Yud69439a2022-02-24 15:52:15 +0800658{
Jerry Yufb0621d2022-03-23 11:42:06 +0800659#if defined(MBEDTLS_RSA_C)
660 psa_algorithm_t psa_md_alg;
661#endif /* MBEDTLS_RSA_C */
Jerry Yud69439a2022-02-24 15:52:15 +0800662 *sig_len = 0;
Jerry Yu1d172a32022-03-12 19:12:05 +0800663
Jerry Yud69439a2022-02-24 15:52:15 +0800664 if( ctx->pk_info == NULL )
665 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
666
Jerry Yu718a9b42022-03-12 22:43:01 +0800667 if( ! mbedtls_pk_can_do( ctx, pk_type ) )
Jerry Yud69439a2022-02-24 15:52:15 +0800668 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
669
Jerry Yu718a9b42022-03-12 22:43:01 +0800670 if( pk_type != MBEDTLS_PK_RSASSA_PSS )
Jerry Yud69439a2022-02-24 15:52:15 +0800671 {
Jerry Yu1d172a32022-03-12 19:12:05 +0800672 return( mbedtls_pk_sign( ctx, md_alg, hash, hash_len,
673 sig, sig_size, sig_len, f_rng, p_rng ) );
Jerry Yud69439a2022-02-24 15:52:15 +0800674 }
Neil Armstrong13e76be2022-04-21 12:08:52 +0200675
Jerry Yu89107d12022-03-22 14:20:15 +0800676#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnardabac0372022-07-18 13:41:11 +0200677 psa_md_alg = mbedtls_hash_info_psa_from_md( md_alg );
Jerry Yufb0621d2022-03-23 11:42:06 +0800678 if( psa_md_alg == 0 )
679 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Neil Armstrong13e76be2022-04-21 12:08:52 +0200680
681 if( mbedtls_pk_get_type( ctx ) == MBEDTLS_PK_OPAQUE )
682 {
683 const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx;
684 psa_status_t status;
685
686 status = psa_sign_hash( *key, PSA_ALG_RSA_PSS( psa_md_alg ),
687 hash, hash_len,
688 sig, sig_size, sig_len );
689 return( mbedtls_pk_error_from_psa_rsa( status ) );
690 }
691
Jerry Yufb0621d2022-03-23 11:42:06 +0800692 return( mbedtls_pk_psa_rsa_sign_ext( PSA_ALG_RSA_PSS( psa_md_alg ),
Jerry Yu89107d12022-03-22 14:20:15 +0800693 ctx->pk_ctx, hash, hash_len,
694 sig, sig_size, sig_len ) );
695#else /* MBEDTLS_RSA_C */
696 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
697#endif /* !MBEDTLS_RSA_C */
Jerry Yud69439a2022-02-24 15:52:15 +0800698
699}
Jerry Yu1d172a32022-03-12 19:12:05 +0800700#endif /* MBEDTLS_PSA_CRYPTO_C */
Jerry Yud69439a2022-02-24 15:52:15 +0800701
702/*
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200703 * Decrypt message
704 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200705int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200706 const unsigned char *input, size_t ilen,
707 unsigned char *output, size_t *olen, size_t osize,
708 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
709{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500710 PK_VALIDATE_RET( ctx != NULL );
711 PK_VALIDATE_RET( input != NULL || ilen == 0 );
712 PK_VALIDATE_RET( output != NULL || osize == 0 );
713 PK_VALIDATE_RET( olen != NULL );
714
715 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200717
718 if( ctx->pk_info->decrypt_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200720
721 return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
722 output, olen, osize, f_rng, p_rng ) );
723}
724
725/*
726 * Encrypt message
727 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200728int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200729 const unsigned char *input, size_t ilen,
730 unsigned char *output, size_t *olen, size_t osize,
731 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
732{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500733 PK_VALIDATE_RET( ctx != NULL );
734 PK_VALIDATE_RET( input != NULL || ilen == 0 );
735 PK_VALIDATE_RET( output != NULL || osize == 0 );
736 PK_VALIDATE_RET( olen != NULL );
737
738 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200740
741 if( ctx->pk_info->encrypt_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200742 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200743
744 return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
745 output, olen, osize, f_rng, p_rng ) );
746}
747
748/*
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100749 * Check public-private key pair
750 */
Manuel Pégourié-Gonnard39be1412021-06-15 11:29:26 +0200751int mbedtls_pk_check_pair( const mbedtls_pk_context *pub,
752 const mbedtls_pk_context *prv,
753 int (*f_rng)(void *, unsigned char *, size_t),
754 void *p_rng )
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100755{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500756 PK_VALIDATE_RET( pub != NULL );
757 PK_VALIDATE_RET( prv != NULL );
758
759 if( pub->pk_info == NULL ||
Andrzej Kurekefed3232019-02-05 05:09:05 -0500760 prv->pk_info == NULL )
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100761 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200762 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100763 }
764
Manuel Pégourié-Gonnard39be1412021-06-15 11:29:26 +0200765 if( f_rng == NULL )
766 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
767
Manuel Pégourié-Gonnardeaeb7b22018-10-24 12:37:44 +0200768 if( prv->pk_info->check_pair_func == NULL )
769 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
770
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200771 if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100772 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200773 if( pub->pk_info->type != MBEDTLS_PK_RSA )
774 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100775 }
776 else
777 {
778 if( pub->pk_info != prv->pk_info )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200779 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100780 }
781
Manuel Pégourié-Gonnard39be1412021-06-15 11:29:26 +0200782 return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx, f_rng, p_rng ) );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100783}
784
785/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200786 * Get key size in bits
787 */
Manuel Pégourié-Gonnard097c7bb2015-06-18 16:43:38 +0200788size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200789{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500790 /* For backward compatibility, accept NULL or a context that
791 * isn't set up yet, and return a fake value that should be safe. */
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200792 if( ctx == NULL || ctx->pk_info == NULL )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200793 return( 0 );
794
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200795 return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200796}
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200797
798/*
799 * Export debug information
800 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200801int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200802{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500803 PK_VALIDATE_RET( ctx != NULL );
804 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200806
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200807 if( ctx->pk_info->debug_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200809
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200810 ctx->pk_info->debug_func( ctx->pk_ctx, items );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200811 return( 0 );
812}
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200813
814/*
815 * Access the PK type name
816 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200817const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200818{
819 if( ctx == NULL || ctx->pk_info == NULL )
820 return( "invalid PK" );
821
822 return( ctx->pk_info->name );
823}
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200824
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200825/*
826 * Access the PK type
827 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200828mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200829{
830 if( ctx == NULL || ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200831 return( MBEDTLS_PK_NONE );
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200832
833 return( ctx->pk_info->type );
834}
835
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100836#if defined(MBEDTLS_USE_PSA_CRYPTO)
837/*
838 * Load the key to a PSA key slot,
839 * then turn the PK context into a wrapper for that key slot.
840 *
Neil Armstrong56e71d42022-04-08 15:12:42 +0200841 * Currently only works for EC & RSA private keys.
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100842 */
843int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
Andrzej Kurek03e01462022-01-03 12:53:24 +0100844 mbedtls_svc_key_id_t *key,
Neil Armstronga1fc18f2022-04-22 13:57:14 +0200845 psa_algorithm_t alg,
846 psa_key_usage_t usage,
847 psa_algorithm_t alg2 )
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100848{
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100849#if !defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_RSA_C)
John Durkopf35069a2020-08-17 22:05:14 -0700850 ((void) pk);
Ronald Croncf56a0a2020-08-04 09:51:30 +0200851 ((void) key);
Neil Armstronga1fc18f2022-04-22 13:57:14 +0200852 ((void) alg);
853 ((void) usage);
854 ((void) alg2);
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100855#else
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100856#if defined(MBEDTLS_ECP_C)
857 if( mbedtls_pk_get_type( pk ) == MBEDTLS_PK_ECKEY )
858 {
859 const mbedtls_ecp_keypair *ec;
860 unsigned char d[MBEDTLS_ECP_MAX_BYTES];
861 size_t d_len;
862 psa_ecc_family_t curve_id;
863 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
864 psa_key_type_t key_type;
865 size_t bits;
866 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Neil Armstrongc1152e42022-03-22 10:29:06 +0100867 psa_status_t status;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100868
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100869 /* export the private key material in the format PSA wants */
870 ec = mbedtls_pk_ec( *pk );
Neil Armstrong7e1b4a42022-03-22 10:25:14 +0100871 d_len = PSA_BITS_TO_BYTES( ec->grp.nbits );
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100872 if( ( ret = mbedtls_mpi_write_binary( &ec->d, d, d_len ) ) != 0 )
873 return( ret );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100874
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100875 curve_id = mbedtls_ecc_group_to_psa( ec->grp.id, &bits );
876 key_type = PSA_KEY_TYPE_ECC_KEY_PAIR( curve_id );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100877
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100878 /* prepare the key attributes */
879 psa_set_key_type( &attributes, key_type );
880 psa_set_key_bits( &attributes, bits );
Neil Armstronga1fc18f2022-04-22 13:57:14 +0200881 psa_set_key_usage_flags( &attributes, usage );
882 psa_set_key_algorithm( &attributes, alg );
883 if( alg2 != PSA_ALG_NONE )
884 psa_set_key_enrollment_algorithm( &attributes, alg2 );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100885
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100886 /* import private key into PSA */
Neil Armstrongc1152e42022-03-22 10:29:06 +0100887 status = psa_import_key( &attributes, d, d_len, key );
888 if( status != PSA_SUCCESS )
889 return( mbedtls_pk_error_from_psa( status ) );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100890
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100891 /* make PK context wrap the key slot */
892 mbedtls_pk_free( pk );
893 mbedtls_pk_init( pk );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100894
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100895 return( mbedtls_pk_setup_opaque( pk, *key ) );
896 }
897 else
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100898#endif /* MBEDTLS_ECP_C */
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100899#if defined(MBEDTLS_RSA_C)
900 if( mbedtls_pk_get_type( pk ) == MBEDTLS_PK_RSA )
901 {
902 unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
903 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
904 int key_len;
905 psa_status_t status;
906
907 /* export the private key material in the format PSA wants */
908 key_len = mbedtls_pk_write_key_der( pk, buf, sizeof( buf ) );
909 if( key_len <= 0 )
910 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
911
912 /* prepare the key attributes */
913 psa_set_key_type( &attributes, PSA_KEY_TYPE_RSA_KEY_PAIR );
914 psa_set_key_bits( &attributes, mbedtls_pk_get_bitlen( pk ) );
Neil Armstronga1fc18f2022-04-22 13:57:14 +0200915 psa_set_key_usage_flags( &attributes, usage );
916 psa_set_key_algorithm( &attributes, alg );
917 if( alg2 != PSA_ALG_NONE )
918 psa_set_key_enrollment_algorithm( &attributes, alg2 );
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100919
920 /* import private key into PSA */
921 status = psa_import_key( &attributes,
922 buf + sizeof( buf ) - key_len,
923 key_len, key);
924
925 mbedtls_platform_zeroize( buf, sizeof( buf ) );
926
927 if( status != PSA_SUCCESS )
Neil Armstrongc1152e42022-03-22 10:29:06 +0100928 return( mbedtls_pk_error_from_psa( status ) );
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100929
930 /* make PK context wrap the key slot */
931 mbedtls_pk_free( pk );
932 mbedtls_pk_init( pk );
933
934 return( mbedtls_pk_setup_opaque( pk, *key ) );
935 }
936 else
937#endif /* MBEDTLS_RSA_C */
938#endif /* !MBEDTLS_ECP_C && !MBEDTLS_RSA_C */
939 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100940}
941#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200942#endif /* MBEDTLS_PK_C */