blob: 98ad7b8212acf17fdee3071bb68b257bf5904e75 [file] [log] [blame]
Edison Aic6672fd2018-02-28 15:01:47 +08001// SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02002/*
3 * Public Key abstraction layer
4 *
5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PK_C)
29#include "mbedtls/pk.h"
30#include "mbedtls/pk_internal.h"
31
Jens Wiklander3d3b0592019-03-20 15:30:29 +010032#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020033#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020034
35#if defined(MBEDTLS_RSA_C)
36#include "mbedtls/rsa.h"
37#endif
38#if defined(MBEDTLS_ECP_C)
39#include "mbedtls/ecp.h"
40#endif
41#if defined(MBEDTLS_ECDSA_C)
42#include "mbedtls/ecdsa.h"
43#endif
44
Jerome Forissier11fa71b2020-04-20 17:17:56 +020045#if defined(MBEDTLS_USE_PSA_CRYPTO)
46#include "mbedtls/psa_util.h"
47#endif
48
Jens Wiklander817466c2018-05-22 13:49:31 +020049#include <limits.h>
Jens Wiklander3d3b0592019-03-20 15:30:29 +010050#include <stdint.h>
Jens Wiklander817466c2018-05-22 13:49:31 +020051
Jens Wiklander3d3b0592019-03-20 15:30:29 +010052/* Parameter validation macros based on platform_util.h */
53#define PK_VALIDATE_RET( cond ) \
54 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
55#define PK_VALIDATE( cond ) \
56 MBEDTLS_INTERNAL_VALIDATE( cond )
Jens Wiklander817466c2018-05-22 13:49:31 +020057
58/*
59 * Initialise a mbedtls_pk_context
60 */
61void mbedtls_pk_init( mbedtls_pk_context *ctx )
62{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010063 PK_VALIDATE( ctx != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +020064
65 ctx->pk_info = NULL;
66 ctx->pk_ctx = NULL;
67}
68
69/*
70 * Free (the components of) a mbedtls_pk_context
71 */
72void mbedtls_pk_free( mbedtls_pk_context *ctx )
73{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010074 if( ctx == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +020075 return;
76
Jens Wiklander3d3b0592019-03-20 15:30:29 +010077 if ( ctx->pk_info != NULL )
78 ctx->pk_info->ctx_free_func( ctx->pk_ctx );
Jens Wiklander817466c2018-05-22 13:49:31 +020079
Jens Wiklander3d3b0592019-03-20 15:30:29 +010080 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
Jens Wiklander817466c2018-05-22 13:49:31 +020081}
82
Jens Wiklander3d3b0592019-03-20 15:30:29 +010083#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
84/*
85 * Initialize a restart context
86 */
87void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
88{
89 PK_VALIDATE( ctx != NULL );
90 ctx->pk_info = NULL;
91 ctx->rs_ctx = NULL;
92}
93
94/*
95 * Free the components of a restart context
96 */
97void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
98{
99 if( ctx == NULL || ctx->pk_info == NULL ||
100 ctx->pk_info->rs_free_func == NULL )
101 {
102 return;
103 }
104
105 ctx->pk_info->rs_free_func( ctx->rs_ctx );
106
107 ctx->pk_info = NULL;
108 ctx->rs_ctx = NULL;
109}
110#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
111
Jens Wiklander817466c2018-05-22 13:49:31 +0200112/*
113 * Get pk_info structure from type
114 */
115const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
116{
117 switch( pk_type ) {
118#if defined(MBEDTLS_RSA_C)
119 case MBEDTLS_PK_RSA:
120 return( &mbedtls_rsa_info );
121#endif
122#if defined(MBEDTLS_ECP_C)
123 case MBEDTLS_PK_ECKEY:
124 return( &mbedtls_eckey_info );
125 case MBEDTLS_PK_ECKEY_DH:
126 return( &mbedtls_eckeydh_info );
127#endif
128#if defined(MBEDTLS_ECDSA_C)
129 case MBEDTLS_PK_ECDSA:
130 return( &mbedtls_ecdsa_info );
131#endif
132 /* MBEDTLS_PK_RSA_ALT omitted on purpose */
133 default:
134 return( NULL );
135 }
136}
137
138/*
139 * Initialise context
140 */
141int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
142{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100143 PK_VALIDATE_RET( ctx != NULL );
144 if( info == NULL || ctx->pk_info != NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200145 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
146
147 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
148 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
149
150 ctx->pk_info = info;
151
152 return( 0 );
153}
154
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200155#if defined(MBEDTLS_USE_PSA_CRYPTO)
156/*
157 * Initialise a PSA-wrapping context
158 */
159int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx, const psa_key_handle_t key )
160{
161 const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info;
162 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
163 psa_key_handle_t *pk_ctx;
164 psa_key_type_t type;
165
166 if( ctx == NULL || ctx->pk_info != NULL )
167 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
168
169 if( PSA_SUCCESS != psa_get_key_attributes( key, &attributes ) )
170 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
171 type = psa_get_key_type( &attributes );
172 psa_reset_key_attributes( &attributes );
173
174 /* Current implementation of can_do() relies on this. */
175 if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
176 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ;
177
178 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
179 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
180
181 ctx->pk_info = info;
182
183 pk_ctx = (psa_key_handle_t *) ctx->pk_ctx;
184 *pk_ctx = key;
185
186 return( 0 );
187}
188#endif /* MBEDTLS_USE_PSA_CRYPTO */
189
Jens Wiklander817466c2018-05-22 13:49:31 +0200190#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
191/*
192 * Initialize an RSA-alt context
193 */
194int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
195 mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
196 mbedtls_pk_rsa_alt_sign_func sign_func,
197 mbedtls_pk_rsa_alt_key_len_func key_len_func )
198{
199 mbedtls_rsa_alt_context *rsa_alt;
200 const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
201
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100202 PK_VALIDATE_RET( ctx != NULL );
203 if( ctx->pk_info != NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200204 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
205
206 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
207 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
208
209 ctx->pk_info = info;
210
211 rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
212
213 rsa_alt->key = key;
214 rsa_alt->decrypt_func = decrypt_func;
215 rsa_alt->sign_func = sign_func;
216 rsa_alt->key_len_func = key_len_func;
217
218 return( 0 );
219}
220#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
221
222/*
223 * Tell if a PK can do the operations of the given type
224 */
225int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
226{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100227 /* A context with null pk_info is not set up yet and can't do anything.
228 * For backward compatibility, also accept NULL instead of a context
229 * pointer. */
Jens Wiklander817466c2018-05-22 13:49:31 +0200230 if( ctx == NULL || ctx->pk_info == NULL )
231 return( 0 );
232
233 return( ctx->pk_info->can_do( type ) );
234}
235
236/*
237 * Helper for mbedtls_pk_sign and mbedtls_pk_verify
238 */
239static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
240{
241 const mbedtls_md_info_t *md_info;
242
243 if( *hash_len != 0 )
244 return( 0 );
245
246 if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
247 return( -1 );
248
249 *hash_len = mbedtls_md_get_size( md_info );
250 return( 0 );
251}
252
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100253#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
254/*
255 * Helper to set up a restart context if needed
256 */
257static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
258 const mbedtls_pk_info_t *info )
259{
260 /* Don't do anything if already set up or invalid */
261 if( ctx == NULL || ctx->pk_info != NULL )
262 return( 0 );
263
264 /* Should never happen when we're called */
265 if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
266 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
267
268 if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
269 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
270
271 ctx->pk_info = info;
272
273 return( 0 );
274}
275#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
276
277/*
278 * Verify a signature (restartable)
279 */
280int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
281 mbedtls_md_type_t md_alg,
282 const unsigned char *hash, size_t hash_len,
283 const unsigned char *sig, size_t sig_len,
284 mbedtls_pk_restart_ctx *rs_ctx )
285{
286 PK_VALIDATE_RET( ctx != NULL );
287 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
288 hash != NULL );
289 PK_VALIDATE_RET( sig != NULL );
290
291 if( ctx->pk_info == NULL ||
292 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
293 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
294
295#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
296 /* optimization: use non-restartable version if restart disabled */
297 if( rs_ctx != NULL &&
298 mbedtls_ecp_restart_is_enabled() &&
299 ctx->pk_info->verify_rs_func != NULL )
300 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200301 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100302
303 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
304 return( ret );
305
306 ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
307 md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
308
309 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
310 mbedtls_pk_restart_free( rs_ctx );
311
312 return( ret );
313 }
314#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
315 (void) rs_ctx;
316#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
317
318 if( ctx->pk_info->verify_func == NULL )
319 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
320
321 return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
322 sig, sig_len ) );
323}
324
Jens Wiklander817466c2018-05-22 13:49:31 +0200325/*
326 * Verify a signature
327 */
328int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
329 const unsigned char *hash, size_t hash_len,
330 const unsigned char *sig, size_t sig_len )
331{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100332 return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
333 sig, sig_len, NULL ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200334}
335
336/*
337 * Verify a signature with options
338 */
339int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
340 mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
341 const unsigned char *hash, size_t hash_len,
342 const unsigned char *sig, size_t sig_len )
343{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100344 PK_VALIDATE_RET( ctx != NULL );
345 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
346 hash != NULL );
347 PK_VALIDATE_RET( sig != NULL );
348
349 if( ctx->pk_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200350 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
351
352 if( ! mbedtls_pk_can_do( ctx, type ) )
353 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
354
355 if( type == MBEDTLS_PK_RSASSA_PSS )
356 {
357#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200358 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200359 const mbedtls_pk_rsassa_pss_options *pss_opts;
360
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100361#if SIZE_MAX > UINT_MAX
Jens Wiklander817466c2018-05-22 13:49:31 +0200362 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
363 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100364#endif /* SIZE_MAX > UINT_MAX */
Jens Wiklander817466c2018-05-22 13:49:31 +0200365
366 if( options == NULL )
367 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
368
369 pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
370
371 if( sig_len < mbedtls_pk_get_len( ctx ) )
372 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
373
374 ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
375 NULL, NULL, MBEDTLS_RSA_PUBLIC,
376 md_alg, (unsigned int) hash_len, hash,
377 pss_opts->mgf1_hash_id,
378 pss_opts->expected_salt_len,
379 sig );
380 if( ret != 0 )
381 return( ret );
382
383 if( sig_len > mbedtls_pk_get_len( ctx ) )
384 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
385
386 return( 0 );
387#else
388 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
389#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
390 }
391
392 /* General case: no options */
393 if( options != NULL )
394 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
395
396 return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
397}
398
399/*
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100400 * Make a signature (restartable)
401 */
402int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
403 mbedtls_md_type_t md_alg,
404 const unsigned char *hash, size_t hash_len,
405 unsigned char *sig, size_t *sig_len,
406 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
407 mbedtls_pk_restart_ctx *rs_ctx )
408{
409 PK_VALIDATE_RET( ctx != NULL );
410 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
411 hash != NULL );
412 PK_VALIDATE_RET( sig != NULL );
413
414 if( ctx->pk_info == NULL ||
415 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
416 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
417
418#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
419 /* optimization: use non-restartable version if restart disabled */
420 if( rs_ctx != NULL &&
421 mbedtls_ecp_restart_is_enabled() &&
422 ctx->pk_info->sign_rs_func != NULL )
423 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200424 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100425
426 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
427 return( ret );
428
429 ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
430 hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx );
431
432 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
433 mbedtls_pk_restart_free( rs_ctx );
434
435 return( ret );
436 }
437#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
438 (void) rs_ctx;
439#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
440
441 if( ctx->pk_info->sign_func == NULL )
442 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
443
444 return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
445 sig, sig_len, f_rng, p_rng ) );
446}
447
448/*
Jens Wiklander817466c2018-05-22 13:49:31 +0200449 * Make a signature
450 */
451int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
452 const unsigned char *hash, size_t hash_len,
453 unsigned char *sig, size_t *sig_len,
454 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
455{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100456 return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
457 sig, sig_len, f_rng, p_rng, NULL ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200458}
459
460/*
461 * Decrypt message
462 */
463int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
464 const unsigned char *input, size_t ilen,
465 unsigned char *output, size_t *olen, size_t osize,
466 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
467{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100468 PK_VALIDATE_RET( ctx != NULL );
469 PK_VALIDATE_RET( input != NULL || ilen == 0 );
470 PK_VALIDATE_RET( output != NULL || osize == 0 );
471 PK_VALIDATE_RET( olen != NULL );
472
473 if( ctx->pk_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200474 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
475
476 if( ctx->pk_info->decrypt_func == NULL )
477 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
478
479 return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
480 output, olen, osize, f_rng, p_rng ) );
481}
482
483/*
484 * Encrypt message
485 */
486int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
487 const unsigned char *input, size_t ilen,
488 unsigned char *output, size_t *olen, size_t osize,
489 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
490{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100491 PK_VALIDATE_RET( ctx != NULL );
492 PK_VALIDATE_RET( input != NULL || ilen == 0 );
493 PK_VALIDATE_RET( output != NULL || osize == 0 );
494 PK_VALIDATE_RET( olen != NULL );
495
496 if( ctx->pk_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200497 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
498
499 if( ctx->pk_info->encrypt_func == NULL )
500 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
501
502 return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
503 output, olen, osize, f_rng, p_rng ) );
504}
505
506/*
507 * Check public-private key pair
508 */
509int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
510{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100511 PK_VALIDATE_RET( pub != NULL );
512 PK_VALIDATE_RET( prv != NULL );
513
514 if( pub->pk_info == NULL ||
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200515 prv->pk_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200516 {
517 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
518 }
519
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200520 if( prv->pk_info->check_pair_func == NULL )
521 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
522
Jens Wiklander817466c2018-05-22 13:49:31 +0200523 if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
524 {
525 if( pub->pk_info->type != MBEDTLS_PK_RSA )
526 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
527 }
528 else
529 {
530 if( pub->pk_info != prv->pk_info )
531 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
532 }
533
534 return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
535}
536
537/*
538 * Get key size in bits
539 */
540size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
541{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100542 /* For backward compatibility, accept NULL or a context that
543 * isn't set up yet, and return a fake value that should be safe. */
Jens Wiklander817466c2018-05-22 13:49:31 +0200544 if( ctx == NULL || ctx->pk_info == NULL )
545 return( 0 );
546
547 return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
548}
549
550/*
551 * Export debug information
552 */
553int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
554{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100555 PK_VALIDATE_RET( ctx != NULL );
556 if( ctx->pk_info == NULL )
Jens Wiklander817466c2018-05-22 13:49:31 +0200557 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
558
559 if( ctx->pk_info->debug_func == NULL )
560 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
561
562 ctx->pk_info->debug_func( ctx->pk_ctx, items );
563 return( 0 );
564}
565
566/*
567 * Access the PK type name
568 */
569const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
570{
571 if( ctx == NULL || ctx->pk_info == NULL )
572 return( "invalid PK" );
573
574 return( ctx->pk_info->name );
575}
576
577/*
578 * Access the PK type
579 */
580mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
581{
582 if( ctx == NULL || ctx->pk_info == NULL )
583 return( MBEDTLS_PK_NONE );
584
585 return( ctx->pk_info->type );
586}
587
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200588#if defined(MBEDTLS_USE_PSA_CRYPTO)
589/*
590 * Load the key to a PSA key slot,
591 * then turn the PK context into a wrapper for that key slot.
592 *
593 * Currently only works for EC private keys.
594 */
595int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
596 psa_key_handle_t *handle,
597 psa_algorithm_t hash_alg )
598{
599#if !defined(MBEDTLS_ECP_C)
600 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
601#else
602 const mbedtls_ecp_keypair *ec;
603 unsigned char d[MBEDTLS_ECP_MAX_BYTES];
604 size_t d_len;
605 psa_ecc_curve_t curve_id;
606 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
607 psa_key_type_t key_type;
608 size_t bits;
609 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
610
611 /* export the private key material in the format PSA wants */
612 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
613 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
614
615 ec = mbedtls_pk_ec( *pk );
616 d_len = ( ec->grp.nbits + 7 ) / 8;
617 if( ( ret = mbedtls_mpi_write_binary( &ec->d, d, d_len ) ) != 0 )
618 return( ret );
619
620 curve_id = mbedtls_ecc_group_to_psa( ec->grp.id, &bits );
621 key_type = PSA_KEY_TYPE_ECC_KEY_PAIR( curve_id );
622
623 /* prepare the key attributes */
624 psa_set_key_type( &attributes, key_type );
625 psa_set_key_bits( &attributes, bits );
626 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
627 psa_set_key_algorithm( &attributes, PSA_ALG_ECDSA(hash_alg) );
628
629 /* import private key into PSA */
630 if( PSA_SUCCESS != psa_import_key( &attributes, d, d_len, handle ) )
631 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
632
633 /* make PK context wrap the key slot */
634 mbedtls_pk_free( pk );
635 mbedtls_pk_init( pk );
636
637 return( mbedtls_pk_setup_opaque( pk, *handle ) );
638#endif /* MBEDTLS_ECP_C */
639}
640#endif /* MBEDTLS_USE_PSA_CRYPTO */
Jens Wiklander817466c2018-05-22 13:49:31 +0200641#endif /* MBEDTLS_PK_C */