blob: 98ba675c5229032c869814eeaf3eed9716771f63 [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
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020050/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051 * Initialise a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020052 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053void mbedtls_pk_init( mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020054{
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020055
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +020056 ctx->pk_info = NULL;
57 ctx->pk_ctx = NULL;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020058}
59
60/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061 * Free (the components of) a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020062 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063void mbedtls_pk_free( mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020064{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050065 if( ctx == NULL )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020066 return;
67
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050068 if ( ctx->pk_info != NULL )
69 ctx->pk_info->ctx_free_func( ctx->pk_ctx );
Manuel Pégourié-Gonnard1f73a652013-07-09 10:26:41 +020070
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050071 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020072}
73
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +020074#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020075/*
76 * Initialize a restart context
77 */
78void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
79{
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020080 ctx->pk_info = NULL;
81 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020082}
83
84/*
85 * Free the components of a restart context
86 */
87void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
88{
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020089 if( ctx == NULL || ctx->pk_info == NULL ||
90 ctx->pk_info->rs_free_func == NULL )
91 {
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020092 return;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020093 }
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020094
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020095 ctx->pk_info->rs_free_func( ctx->rs_ctx );
96
97 ctx->pk_info = NULL;
98 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020099}
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200100#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200101
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200102/*
103 * Get pk_info structure from type
104 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200106{
107 switch( pk_type ) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108#if defined(MBEDTLS_RSA_C)
109 case MBEDTLS_PK_RSA:
110 return( &mbedtls_rsa_info );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200111#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112#if defined(MBEDTLS_ECP_C)
113 case MBEDTLS_PK_ECKEY:
114 return( &mbedtls_eckey_info );
115 case MBEDTLS_PK_ECKEY_DH:
116 return( &mbedtls_eckeydh_info );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200117#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118#if defined(MBEDTLS_ECDSA_C)
119 case MBEDTLS_PK_ECDSA:
120 return( &mbedtls_ecdsa_info );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200121#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122 /* MBEDTLS_PK_RSA_ALT omitted on purpose */
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200123 default:
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200124 return( NULL );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200125 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200126}
127
128/*
Manuel Pégourié-Gonnardab466942013-08-15 11:30:27 +0200129 * Initialise context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200130 */
Manuel Pégourié-Gonnardd9e6a3a2015-05-14 19:41:36 +0200131int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200132{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500133 if( info == NULL || ctx->pk_info != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200134 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200135
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200136 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200137 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200138
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200139 ctx->pk_info = info;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200140
141 return( 0 );
142}
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200143
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200144#if defined(MBEDTLS_USE_PSA_CRYPTO)
145/*
146 * Initialise a PSA-wrapping context
147 */
Ronald Croncf56a0a2020-08-04 09:51:30 +0200148int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx,
Andrzej Kurek03e01462022-01-03 12:53:24 +0100149 const mbedtls_svc_key_id_t key )
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200150{
Neil Armstrongeabbf9d2022-03-15 12:01:26 +0100151 const mbedtls_pk_info_t *info = NULL;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200152 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Andrzej Kurek03e01462022-01-03 12:53:24 +0100153 mbedtls_svc_key_id_t *pk_ctx;
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100154 psa_key_type_t type;
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200155
156 if( ctx == NULL || ctx->pk_info != NULL )
157 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
158
Gilles Peskined2d45c12019-05-27 14:53:13 +0200159 if( PSA_SUCCESS != psa_get_key_attributes( key, &attributes ) )
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100160 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Gilles Peskined2d45c12019-05-27 14:53:13 +0200161 type = psa_get_key_type( &attributes );
162 psa_reset_key_attributes( &attributes );
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100163
Neil Armstrongeabbf9d2022-03-15 12:01:26 +0100164 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
165 info = &mbedtls_pk_ecdsa_opaque_info;
Neil Armstrongeccf88f2022-04-08 15:11:50 +0200166 else if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Neil Armstrongeabbf9d2022-03-15 12:01:26 +0100167 info = &mbedtls_pk_rsa_opaque_info;
168 else
169 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100170
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200171 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
172 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
173
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200174 ctx->pk_info = info;
175
Andrzej Kurek03e01462022-01-03 12:53:24 +0100176 pk_ctx = (mbedtls_svc_key_id_t *) ctx->pk_ctx;
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100177 *pk_ctx = key;
178
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200179 return( 0 );
180}
181#endif /* MBEDTLS_USE_PSA_CRYPTO */
182
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200183#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnardb4fae572014-01-20 11:22:25 +0100184/*
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200185 * Initialize an RSA-alt context
186 */
Manuel Pégourié-Gonnardd9e6a3a2015-05-14 19:41:36 +0200187int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200188 mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
189 mbedtls_pk_rsa_alt_sign_func sign_func,
190 mbedtls_pk_rsa_alt_key_len_func key_len_func )
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200191{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192 mbedtls_rsa_alt_context *rsa_alt;
193 const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200194
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500195 if( ctx->pk_info != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200196 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200197
198 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200199 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200200
201 ctx->pk_info = info;
202
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203 rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200204
205 rsa_alt->key = key;
206 rsa_alt->decrypt_func = decrypt_func;
207 rsa_alt->sign_func = sign_func;
208 rsa_alt->key_len_func = key_len_func;
209
210 return( 0 );
211}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200213
214/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200215 * Tell if a PK can do the operations of the given type
216 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200217int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200218{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500219 /* A context with null pk_info is not set up yet and can't do anything.
220 * For backward compatibility, also accept NULL instead of a context
221 * pointer. */
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200222 if( ctx == NULL || ctx->pk_info == NULL )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200223 return( 0 );
224
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200225 return( ctx->pk_info->can_do( type ) );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200226}
227
Neil Armstronga88b1582022-05-11 14:11:25 +0200228#if defined(MBEDTLS_USE_PSA_CRYPTO)
229/*
230 * Tell if a PK can do the operations of the given PSA algorithm
231 */
Neil Armstrong408f6a62022-05-17 14:23:20 +0200232int mbedtls_pk_can_do_ext( const mbedtls_pk_context *ctx, psa_algorithm_t alg,
233 psa_key_usage_t usage )
Neil Armstronga88b1582022-05-11 14:11:25 +0200234{
Neil Armstrong408f6a62022-05-17 14:23:20 +0200235 psa_key_usage_t key_usage;
236
Neil Armstronga88b1582022-05-11 14:11:25 +0200237 /* A context with null pk_info is not set up yet and can't do anything.
238 * For backward compatibility, also accept NULL instead of a context
239 * pointer. */
240 if( ctx == NULL || ctx->pk_info == NULL )
241 return( 0 );
242
243 /* Filter out non allowed algorithms */
244 if( PSA_ALG_IS_ECDSA( alg ) == 0 &&
245 PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) == 0 &&
246 PSA_ALG_IS_RSA_PSS( alg ) == 0 &&
247 alg != PSA_ALG_RSA_PKCS1V15_CRYPT &&
248 PSA_ALG_IS_ECDH( alg ) == 0 )
249 return( 0 );
250
Neil Armstrong408f6a62022-05-17 14:23:20 +0200251 /* Filter out non allowed usage flags */
Neil Armstrong81d391f2022-05-20 09:26:16 +0200252 if( usage == 0 ||
253 ( usage & ~( PSA_KEY_USAGE_SIGN_HASH |
Neil Armstrong408f6a62022-05-17 14:23:20 +0200254 PSA_KEY_USAGE_DECRYPT |
255 PSA_KEY_USAGE_DERIVE ) ) != 0 )
256 return( 0 );
257
Neil Armstronga88b1582022-05-11 14:11:25 +0200258 /* Wildcard hash is not allowed */
259 if( PSA_ALG_IS_SIGN_HASH( alg ) &&
260 PSA_ALG_SIGN_GET_HASH( alg ) == PSA_ALG_ANY_HASH )
261 return( 0 );
262
263 if( mbedtls_pk_get_type( ctx ) != MBEDTLS_PK_OPAQUE )
264 {
265 mbedtls_pk_type_t type;
266
267 if( PSA_ALG_IS_ECDSA( alg ) || PSA_ALG_IS_ECDH( alg ) )
268 type = MBEDTLS_PK_ECKEY;
Neil Armstrong084338d2022-05-19 16:22:40 +0200269 else if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) ||
270 alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Neil Armstronga88b1582022-05-11 14:11:25 +0200271 type = MBEDTLS_PK_RSA;
272 else if( PSA_ALG_IS_RSA_PSS( alg ) )
273 type = MBEDTLS_PK_RSASSA_PSS;
274 else
275 return( 0 );
276
Neil Armstrong084338d2022-05-19 16:22:40 +0200277 if( ctx->pk_info->can_do( type ) == 0 )
Neil Armstrong408f6a62022-05-17 14:23:20 +0200278 return( 0 );
279
Neil Armstrong084338d2022-05-19 16:22:40 +0200280 switch( type )
281 {
282 case MBEDTLS_PK_ECKEY:
283 key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE;
284 break;
285 case MBEDTLS_PK_RSA:
286 case MBEDTLS_PK_RSASSA_PSS:
287 key_usage = PSA_KEY_USAGE_SIGN_HASH |
288 PSA_KEY_USAGE_SIGN_MESSAGE |
289 PSA_KEY_USAGE_DECRYPT;
290 break;
291 default:
Neil Armstrongb80785f2022-05-20 09:25:55 +0200292 /* Should never happen */
Neil Armstrong084338d2022-05-19 16:22:40 +0200293 return( 0 );
294 }
295
296 return( ( key_usage & usage ) == usage );
Neil Armstronga88b1582022-05-11 14:11:25 +0200297 }
298
299 const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx;
300 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
301 psa_algorithm_t key_alg, key_alg2;
302 psa_status_t status;
303
304 status = psa_get_key_attributes( *key, &attributes );
305 if( status != PSA_SUCCESS )
306 return( 0 );
307
308 key_alg = psa_get_key_algorithm( &attributes );
309 key_alg2 = psa_get_key_enrollment_algorithm( &attributes );
Neil Armstrong408f6a62022-05-17 14:23:20 +0200310 key_usage = psa_get_key_usage_flags( &attributes );
Neil Armstronga88b1582022-05-11 14:11:25 +0200311 psa_reset_key_attributes( &attributes );
312
Neil Armstrong408f6a62022-05-17 14:23:20 +0200313 if( ( key_usage & usage ) != usage )
314 return( 0 );
315
Neil Armstronga88b1582022-05-11 14:11:25 +0200316 /*
Neil Armstrongdab56ba2022-05-17 11:56:55 +0200317 * Common case: the key alg or alg2 only allows alg.
Neil Armstronga88b1582022-05-11 14:11:25 +0200318 * This will match PSA_ALG_RSA_PKCS1V15_CRYPT & PSA_ALG_IS_ECDH
319 * directly.
320 * This would also match ECDSA/RSA_PKCS1V15_SIGN/RSA_PSS with
321 * a fixed hash on key_alg/key_alg2.
322 */
323 if( alg == key_alg || alg == key_alg2 )
324 return( 1 );
325
326 /*
Neil Armstrongbbb8b752022-05-17 14:58:27 +0200327 * If key_alg or key_alg2 is a hash-and-sign with a wildcard for the hash,
328 * and alg is the same hash-and-sign family with any hash,
Neil Armstronga88b1582022-05-11 14:11:25 +0200329 * then alg is compliant with this key alg
330 */
331 if( PSA_ALG_IS_SIGN_HASH( alg ) )
332 {
333
334 if( PSA_ALG_IS_SIGN_HASH( key_alg ) &&
335 PSA_ALG_SIGN_GET_HASH( key_alg ) == PSA_ALG_ANY_HASH &&
336 ( alg & ~PSA_ALG_HASH_MASK ) == ( key_alg & ~PSA_ALG_HASH_MASK ) )
337 return( 1 );
338
339 if( PSA_ALG_IS_SIGN_HASH( key_alg2 ) &&
340 PSA_ALG_SIGN_GET_HASH( key_alg2 ) == PSA_ALG_ANY_HASH &&
341 ( alg & ~PSA_ALG_HASH_MASK ) == ( key_alg2 & ~PSA_ALG_HASH_MASK ) )
342 return( 1 );
343 }
344
345 return( 0 );
346}
347#endif /* MBEDTLS_USE_PSA_CRYPTO */
348
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200349/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 * Helper for mbedtls_pk_sign and mbedtls_pk_verify
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200351 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200353{
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200354 if( *hash_len != 0 )
355 return( 0 );
356
Manuel Pégourié-Gonnard47728842022-07-18 13:00:40 +0200357 *hash_len = mbedtls_hash_info_get_size( md_alg );
Manuel Pégourié-Gonnarda370e062022-07-05 11:55:20 +0200358
359 if( *hash_len == 0 )
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200360 return( -1 );
361
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200362 return( 0 );
363}
364
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200365#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200366/*
367 * Helper to set up a restart context if needed
368 */
369static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200370 const mbedtls_pk_info_t *info )
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200371{
Manuel Pégourié-Gonnardc8c12b62018-07-02 13:09:39 +0200372 /* Don't do anything if already set up or invalid */
373 if( ctx == NULL || ctx->pk_info != NULL )
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200374 return( 0 );
375
376 /* Should never happen when we're called */
377 if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
378 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
379
380 if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
381 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
382
383 ctx->pk_info = info;
384
385 return( 0 );
386}
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200387#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200388
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200389/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200390 * Verify a signature (restartable)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200391 */
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200392int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
393 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200394 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200395 const unsigned char *sig, size_t sig_len,
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200396 mbedtls_pk_restart_ctx *rs_ctx )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200397{
Tuvshinzaya Erdenekhuu78c1d8c2022-07-29 14:51:50 +0100398 if( ( md_alg != MBEDTLS_MD_NONE || hash_len != 0 ) &&
399 hash == NULL )
400 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500401
402 if( ctx->pk_info == NULL ||
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200403 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200405
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200406#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200407 /* optimization: use non-restartable version if restart disabled */
408 if( rs_ctx != NULL &&
Manuel Pégourié-Gonnardb843b152018-10-16 10:41:31 +0200409 mbedtls_ecp_restart_is_enabled() &&
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200410 ctx->pk_info->verify_rs_func != NULL )
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200411 {
Janos Follath24eed8d2019-11-22 13:21:35 +0000412 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200413
414 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
415 return( ret );
416
417 ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
418 md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
419
420 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
421 mbedtls_pk_restart_free( rs_ctx );
422
423 return( ret );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200424 }
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200425#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200426 (void) rs_ctx;
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200427#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200428
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200429 if( ctx->pk_info->verify_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200431
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200432 return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200433 sig, sig_len ) );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200434}
435
436/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200437 * Verify a signature
438 */
439int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
440 const unsigned char *hash, size_t hash_len,
441 const unsigned char *sig, size_t sig_len )
442{
443 return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
444 sig, sig_len, NULL ) );
445}
446
447/*
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200448 * Verify a signature with options
449 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
451 mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200452 const unsigned char *hash, size_t hash_len,
453 const unsigned char *sig, size_t sig_len )
454{
Tuvshinzaya Erdenekhuu78c1d8c2022-07-29 14:51:50 +0100455 if( ( md_alg != MBEDTLS_MD_NONE || hash_len != 0 ) &&
456 hash == NULL )
457 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500458
459 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200461
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462 if( ! mbedtls_pk_can_do( ctx, type ) )
463 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200464
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500465 if( type != MBEDTLS_PK_RSASSA_PSS )
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200466 {
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500467 /* General case: no options */
468 if( options != NULL )
469 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
470
471 return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
472 }
473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500475 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
476 const mbedtls_pk_rsassa_pss_options *pss_opts;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200477
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100478#if SIZE_MAX > UINT_MAX
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500479 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
480 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100481#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000482
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500483 if( options == NULL )
484 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200485
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500486 pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200487
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500488#if defined(MBEDTLS_USE_PSA_CRYPTO)
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500489 if( pss_opts->mgf1_hash_id == md_alg &&
490 ( (size_t) pss_opts->expected_salt_len == hash_len ||
491 pss_opts->expected_salt_len == MBEDTLS_RSA_SALT_LEN_ANY ) )
492 {
493 /* see RSA_PUB_DER_MAX_BYTES in pkwrite.c */
494 unsigned char buf[ 38 + 2 * MBEDTLS_MPI_MAX_SIZE ];
495 unsigned char *p;
Andrzej Kurek59550532022-02-16 07:46:42 -0500496 int key_len;
497 size_t signature_length;
Andrzej Kurekd70fa0e2022-02-17 10:51:15 -0500498 psa_status_t status = PSA_ERROR_DATA_CORRUPT;
499 psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT;
Andrzej Kurek59550532022-02-16 07:46:42 -0500500
Manuel Pégourié-Gonnardabac0372022-07-18 13:41:11 +0200501 psa_algorithm_t psa_md_alg = mbedtls_hash_info_psa_from_md( md_alg );
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500502 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
503 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Andrzej Kurek90ba2cb2022-02-15 08:18:44 -0500504 psa_algorithm_t psa_sig_alg =
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500505 ( pss_opts->expected_salt_len == MBEDTLS_RSA_SALT_LEN_ANY ?
506 PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg) :
507 PSA_ALG_RSA_PSS(psa_md_alg) );
508 p = buf + sizeof( buf );
509 key_len = mbedtls_pk_write_pubkey( &p, buf, ctx );
510
511 if( key_len < 0 )
512 return( key_len );
513
514 psa_set_key_type( &attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY );
515 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
Andrzej Kurek90ba2cb2022-02-15 08:18:44 -0500516 psa_set_key_algorithm( &attributes, psa_sig_alg );
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500517
518 status = psa_import_key( &attributes,
519 buf + sizeof( buf ) - key_len, key_len,
520 &key_id );
521 if( status != PSA_SUCCESS )
522 {
523 psa_destroy_key( key_id );
Neil Armstrong19915c22022-03-01 15:21:02 +0100524 return( mbedtls_pk_error_from_psa( status ) );
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500525 }
526
Andrzej Kurek4a953cd2022-02-16 06:13:35 -0500527 /* This function requires returning MBEDTLS_ERR_PK_SIG_LEN_MISMATCH
528 * on a valid signature with trailing data in a buffer, but
529 * mbedtls_psa_rsa_verify_hash requires the sig_len to be exact,
530 * so for this reason the passed sig_len is overwritten. Smaller
531 * signature lengths should not be accepted for verification. */
532 signature_length = sig_len > mbedtls_pk_get_len( ctx ) ?
533 mbedtls_pk_get_len( ctx ) : sig_len;
Andrzej Kurek90ba2cb2022-02-15 08:18:44 -0500534 status = psa_verify_hash( key_id, psa_sig_alg, hash,
Andrzej Kurek4a953cd2022-02-16 06:13:35 -0500535 hash_len, sig, signature_length );
Andrzej Kurekd70fa0e2022-02-17 10:51:15 -0500536 destruction_status = psa_destroy_key( key_id );
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500537
Andrzej Kurek8666df62022-02-15 08:23:02 -0500538 if( status == PSA_SUCCESS && sig_len > mbedtls_pk_get_len( ctx ) )
539 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
540
Andrzej Kurekd70fa0e2022-02-17 10:51:15 -0500541 if( status == PSA_SUCCESS )
542 status = destruction_status;
543
Neil Armstrong19915c22022-03-01 15:21:02 +0100544 return( mbedtls_pk_error_from_psa_rsa( status ) );
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500545 }
546 else
547#endif
548 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549 if( sig_len < mbedtls_pk_get_len( ctx ) )
550 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200551
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
Thomas Daubney782a7f52021-05-19 12:27:35 +0100553 md_alg, (unsigned int) hash_len, hash,
554 pss_opts->mgf1_hash_id,
555 pss_opts->expected_salt_len,
556 sig );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200557 if( ret != 0 )
558 return( ret );
559
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560 if( sig_len > mbedtls_pk_get_len( ctx ) )
561 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Andrzej Kurek90ba2cb2022-02-15 08:18:44 -0500562
563 return( 0 );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200564 }
Andrzej Kurek7db1b782022-02-09 14:13:44 -0500565#else
566 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
567#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200568}
569
570/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200571 * Make a signature (restartable)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200572 */
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200573int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
574 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200575 const unsigned char *hash, size_t hash_len,
Gilles Peskinef00f1522021-06-22 00:09:00 +0200576 unsigned char *sig, size_t sig_size, size_t *sig_len,
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200577 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200578 mbedtls_pk_restart_ctx *rs_ctx )
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200579{
Tuvshinzaya Erdenekhuu78c1d8c2022-07-29 14:51:50 +0100580 if( ( md_alg != MBEDTLS_MD_NONE || hash_len != 0 ) &&
581 hash == NULL )
582 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500583
584 if( ctx->pk_info == NULL ||
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200585 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200586 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200587
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200588#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200589 /* optimization: use non-restartable version if restart disabled */
590 if( rs_ctx != NULL &&
Manuel Pégourié-Gonnardb843b152018-10-16 10:41:31 +0200591 mbedtls_ecp_restart_is_enabled() &&
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200592 ctx->pk_info->sign_rs_func != NULL )
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200593 {
Janos Follath24eed8d2019-11-22 13:21:35 +0000594 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200595
596 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
597 return( ret );
598
599 ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
Gilles Peskinef00f1522021-06-22 00:09:00 +0200600 hash, hash_len,
601 sig, sig_size, sig_len,
602 f_rng, p_rng, rs_ctx->rs_ctx );
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200603
604 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
605 mbedtls_pk_restart_free( rs_ctx );
606
607 return( ret );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200608 }
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200609#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200610 (void) rs_ctx;
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200611#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200612
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200613 if( ctx->pk_info->sign_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200615
Gilles Peskinef00f1522021-06-22 00:09:00 +0200616 return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg,
617 hash, hash_len,
618 sig, sig_size, sig_len,
619 f_rng, p_rng ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200620}
621
622/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200623 * Make a signature
624 */
625int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
626 const unsigned char *hash, size_t hash_len,
Gilles Peskinef00f1522021-06-22 00:09:00 +0200627 unsigned char *sig, size_t sig_size, size_t *sig_len,
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200628 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
629{
630 return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
Gilles Peskinef00f1522021-06-22 00:09:00 +0200631 sig, sig_size, sig_len,
632 f_rng, p_rng, NULL ) );
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200633}
634
Jerry Yu1d172a32022-03-12 19:12:05 +0800635#if defined(MBEDTLS_PSA_CRYPTO_C)
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200636/*
Jerry Yufb0621d2022-03-23 11:42:06 +0800637 * Make a signature given a signature type.
Jerry Yud69439a2022-02-24 15:52:15 +0800638 */
Jerry Yu718a9b42022-03-12 22:43:01 +0800639int mbedtls_pk_sign_ext( mbedtls_pk_type_t pk_type,
Jerry Yu8beb9e12022-03-12 16:23:53 +0800640 mbedtls_pk_context *ctx,
641 mbedtls_md_type_t md_alg,
642 const unsigned char *hash, size_t hash_len,
643 unsigned char *sig, size_t sig_size, size_t *sig_len,
644 int (*f_rng)(void *, unsigned char *, size_t),
645 void *p_rng )
Jerry Yud69439a2022-02-24 15:52:15 +0800646{
Jerry Yufb0621d2022-03-23 11:42:06 +0800647#if defined(MBEDTLS_RSA_C)
648 psa_algorithm_t psa_md_alg;
649#endif /* MBEDTLS_RSA_C */
Jerry Yud69439a2022-02-24 15:52:15 +0800650 *sig_len = 0;
Jerry Yu1d172a32022-03-12 19:12:05 +0800651
Jerry Yud69439a2022-02-24 15:52:15 +0800652 if( ctx->pk_info == NULL )
653 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
654
Jerry Yu718a9b42022-03-12 22:43:01 +0800655 if( ! mbedtls_pk_can_do( ctx, pk_type ) )
Jerry Yud69439a2022-02-24 15:52:15 +0800656 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
657
Jerry Yu718a9b42022-03-12 22:43:01 +0800658 if( pk_type != MBEDTLS_PK_RSASSA_PSS )
Jerry Yud69439a2022-02-24 15:52:15 +0800659 {
Jerry Yu1d172a32022-03-12 19:12:05 +0800660 return( mbedtls_pk_sign( ctx, md_alg, hash, hash_len,
661 sig, sig_size, sig_len, f_rng, p_rng ) );
Jerry Yud69439a2022-02-24 15:52:15 +0800662 }
Neil Armstrong13e76be2022-04-21 12:08:52 +0200663
Jerry Yu89107d12022-03-22 14:20:15 +0800664#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnardabac0372022-07-18 13:41:11 +0200665 psa_md_alg = mbedtls_hash_info_psa_from_md( md_alg );
Jerry Yufb0621d2022-03-23 11:42:06 +0800666 if( psa_md_alg == 0 )
667 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Neil Armstrong13e76be2022-04-21 12:08:52 +0200668
669 if( mbedtls_pk_get_type( ctx ) == MBEDTLS_PK_OPAQUE )
670 {
671 const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx;
672 psa_status_t status;
673
674 status = psa_sign_hash( *key, PSA_ALG_RSA_PSS( psa_md_alg ),
675 hash, hash_len,
676 sig, sig_size, sig_len );
677 return( mbedtls_pk_error_from_psa_rsa( status ) );
678 }
679
Jerry Yufb0621d2022-03-23 11:42:06 +0800680 return( mbedtls_pk_psa_rsa_sign_ext( PSA_ALG_RSA_PSS( psa_md_alg ),
Jerry Yu89107d12022-03-22 14:20:15 +0800681 ctx->pk_ctx, hash, hash_len,
682 sig, sig_size, sig_len ) );
683#else /* MBEDTLS_RSA_C */
684 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
685#endif /* !MBEDTLS_RSA_C */
Jerry Yud69439a2022-02-24 15:52:15 +0800686
687}
Jerry Yu1d172a32022-03-12 19:12:05 +0800688#endif /* MBEDTLS_PSA_CRYPTO_C */
Jerry Yud69439a2022-02-24 15:52:15 +0800689
690/*
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200691 * Decrypt message
692 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200694 const unsigned char *input, size_t ilen,
695 unsigned char *output, size_t *olen, size_t osize,
696 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
697{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500698
699 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200700 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200701
702 if( ctx->pk_info->decrypt_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200703 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200704
705 return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
706 output, olen, osize, f_rng, p_rng ) );
707}
708
709/*
710 * Encrypt message
711 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200713 const unsigned char *input, size_t ilen,
714 unsigned char *output, size_t *olen, size_t osize,
715 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
716{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500717
718 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200720
721 if( ctx->pk_info->encrypt_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200722 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200723
724 return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
725 output, olen, osize, f_rng, p_rng ) );
726}
727
728/*
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100729 * Check public-private key pair
730 */
Manuel Pégourié-Gonnard39be1412021-06-15 11:29:26 +0200731int mbedtls_pk_check_pair( const mbedtls_pk_context *pub,
732 const mbedtls_pk_context *prv,
733 int (*f_rng)(void *, unsigned char *, size_t),
734 void *p_rng )
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100735{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500736
737 if( pub->pk_info == NULL ||
Andrzej Kurekefed3232019-02-05 05:09:05 -0500738 prv->pk_info == NULL )
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100739 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200740 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100741 }
742
Manuel Pégourié-Gonnard39be1412021-06-15 11:29:26 +0200743 if( f_rng == NULL )
744 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
745
Manuel Pégourié-Gonnardeaeb7b22018-10-24 12:37:44 +0200746 if( prv->pk_info->check_pair_func == NULL )
747 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
748
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100750 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200751 if( pub->pk_info->type != MBEDTLS_PK_RSA )
752 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100753 }
754 else
755 {
756 if( pub->pk_info != prv->pk_info )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200757 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100758 }
759
Manuel Pégourié-Gonnard39be1412021-06-15 11:29:26 +0200760 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 +0100761}
762
763/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200764 * Get key size in bits
765 */
Manuel Pégourié-Gonnard097c7bb2015-06-18 16:43:38 +0200766size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200767{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500768 /* For backward compatibility, accept NULL or a context that
769 * isn't set up yet, and return a fake value that should be safe. */
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200770 if( ctx == NULL || ctx->pk_info == NULL )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200771 return( 0 );
772
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200773 return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200774}
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200775
776/*
777 * Export debug information
778 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200779int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200780{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500781 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200782 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200783
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200784 if( ctx->pk_info->debug_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200786
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200787 ctx->pk_info->debug_func( ctx->pk_ctx, items );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200788 return( 0 );
789}
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200790
791/*
792 * Access the PK type name
793 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200795{
796 if( ctx == NULL || ctx->pk_info == NULL )
797 return( "invalid PK" );
798
799 return( ctx->pk_info->name );
800}
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200801
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200802/*
803 * Access the PK type
804 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200806{
807 if( ctx == NULL || ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808 return( MBEDTLS_PK_NONE );
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200809
810 return( ctx->pk_info->type );
811}
812
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100813#if defined(MBEDTLS_USE_PSA_CRYPTO)
814/*
815 * Load the key to a PSA key slot,
816 * then turn the PK context into a wrapper for that key slot.
817 *
Neil Armstrong56e71d42022-04-08 15:12:42 +0200818 * Currently only works for EC & RSA private keys.
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100819 */
820int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
Andrzej Kurek03e01462022-01-03 12:53:24 +0100821 mbedtls_svc_key_id_t *key,
Neil Armstronga1fc18f2022-04-22 13:57:14 +0200822 psa_algorithm_t alg,
823 psa_key_usage_t usage,
824 psa_algorithm_t alg2 )
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100825{
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100826#if !defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_RSA_C)
John Durkopf35069a2020-08-17 22:05:14 -0700827 ((void) pk);
Ronald Croncf56a0a2020-08-04 09:51:30 +0200828 ((void) key);
Neil Armstronga1fc18f2022-04-22 13:57:14 +0200829 ((void) alg);
830 ((void) usage);
831 ((void) alg2);
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100832#else
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100833#if defined(MBEDTLS_ECP_C)
834 if( mbedtls_pk_get_type( pk ) == MBEDTLS_PK_ECKEY )
835 {
836 const mbedtls_ecp_keypair *ec;
837 unsigned char d[MBEDTLS_ECP_MAX_BYTES];
838 size_t d_len;
839 psa_ecc_family_t curve_id;
840 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
841 psa_key_type_t key_type;
842 size_t bits;
843 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Neil Armstrongc1152e42022-03-22 10:29:06 +0100844 psa_status_t status;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100845
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100846 /* export the private key material in the format PSA wants */
847 ec = mbedtls_pk_ec( *pk );
Neil Armstrong7e1b4a42022-03-22 10:25:14 +0100848 d_len = PSA_BITS_TO_BYTES( ec->grp.nbits );
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100849 if( ( ret = mbedtls_mpi_write_binary( &ec->d, d, d_len ) ) != 0 )
850 return( ret );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100851
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100852 curve_id = mbedtls_ecc_group_to_psa( ec->grp.id, &bits );
853 key_type = PSA_KEY_TYPE_ECC_KEY_PAIR( curve_id );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100854
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100855 /* prepare the key attributes */
856 psa_set_key_type( &attributes, key_type );
857 psa_set_key_bits( &attributes, bits );
Neil Armstronga1fc18f2022-04-22 13:57:14 +0200858 psa_set_key_usage_flags( &attributes, usage );
859 psa_set_key_algorithm( &attributes, alg );
860 if( alg2 != PSA_ALG_NONE )
861 psa_set_key_enrollment_algorithm( &attributes, alg2 );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100862
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100863 /* import private key into PSA */
Neil Armstrongc1152e42022-03-22 10:29:06 +0100864 status = psa_import_key( &attributes, d, d_len, key );
865 if( status != PSA_SUCCESS )
866 return( mbedtls_pk_error_from_psa( status ) );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100867
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100868 /* make PK context wrap the key slot */
869 mbedtls_pk_free( pk );
870 mbedtls_pk_init( pk );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100871
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100872 return( mbedtls_pk_setup_opaque( pk, *key ) );
873 }
874 else
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100875#endif /* MBEDTLS_ECP_C */
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100876#if defined(MBEDTLS_RSA_C)
877 if( mbedtls_pk_get_type( pk ) == MBEDTLS_PK_RSA )
878 {
879 unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
880 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
881 int key_len;
882 psa_status_t status;
883
884 /* export the private key material in the format PSA wants */
885 key_len = mbedtls_pk_write_key_der( pk, buf, sizeof( buf ) );
886 if( key_len <= 0 )
887 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
888
889 /* prepare the key attributes */
890 psa_set_key_type( &attributes, PSA_KEY_TYPE_RSA_KEY_PAIR );
891 psa_set_key_bits( &attributes, mbedtls_pk_get_bitlen( pk ) );
Neil Armstronga1fc18f2022-04-22 13:57:14 +0200892 psa_set_key_usage_flags( &attributes, usage );
893 psa_set_key_algorithm( &attributes, alg );
894 if( alg2 != PSA_ALG_NONE )
895 psa_set_key_enrollment_algorithm( &attributes, alg2 );
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100896
897 /* import private key into PSA */
898 status = psa_import_key( &attributes,
899 buf + sizeof( buf ) - key_len,
900 key_len, key);
901
902 mbedtls_platform_zeroize( buf, sizeof( buf ) );
903
904 if( status != PSA_SUCCESS )
Neil Armstrongc1152e42022-03-22 10:29:06 +0100905 return( mbedtls_pk_error_from_psa( status ) );
Neil Armstrongca5b55f2022-03-15 15:00:55 +0100906
907 /* make PK context wrap the key slot */
908 mbedtls_pk_free( pk );
909 mbedtls_pk_init( pk );
910
911 return( mbedtls_pk_setup_opaque( pk, *key ) );
912 }
913 else
914#endif /* MBEDTLS_RSA_C */
915#endif /* !MBEDTLS_ECP_C && !MBEDTLS_RSA_C */
916 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100917}
918#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919#endif /* MBEDTLS_PK_C */