1 // SPDX-License-Identifier: Apache-2.0 2 /* 3 * Public Key abstraction layer 4 * 5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 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. 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 32 #include "mbedtls/platform_util.h" 33 #include "mbedtls/error.h" 34 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 45 #if defined(MBEDTLS_USE_PSA_CRYPTO) 46 #include "mbedtls/psa_util.h" 47 #endif 48 49 #include <limits.h> 50 #include <stdint.h> 51 52 /* 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 ) 57 58 /* 59 * Initialise a mbedtls_pk_context 60 */ 61 void mbedtls_pk_init( mbedtls_pk_context *ctx ) 62 { 63 PK_VALIDATE( ctx != NULL ); 64 65 ctx->pk_info = NULL; 66 ctx->pk_ctx = NULL; 67 } 68 69 /* 70 * Free (the components of) a mbedtls_pk_context 71 */ 72 void mbedtls_pk_free( mbedtls_pk_context *ctx ) 73 { 74 if( ctx == NULL ) 75 return; 76 77 if ( ctx->pk_info != NULL ) 78 ctx->pk_info->ctx_free_func( ctx->pk_ctx ); 79 80 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) ); 81 } 82 83 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 84 /* 85 * Initialize a restart context 86 */ 87 void 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 */ 97 void 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 112 /* 113 * Get pk_info structure from type 114 */ 115 const 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 */ 141 int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ) 142 { 143 PK_VALIDATE_RET( ctx != NULL ); 144 if( info == NULL || ctx->pk_info != NULL ) 145 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 155 #if defined(MBEDTLS_USE_PSA_CRYPTO) 156 /* 157 * Initialise a PSA-wrapping context 158 */ 159 int 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 190 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 191 /* 192 * Initialize an RSA-alt context 193 */ 194 int 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 202 PK_VALIDATE_RET( ctx != NULL ); 203 if( ctx->pk_info != NULL ) 204 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 */ 225 int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ) 226 { 227 /* 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. */ 230 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 */ 239 static 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 253 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 254 /* 255 * Helper to set up a restart context if needed 256 */ 257 static 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 */ 280 int 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 { 301 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 302 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 325 /* 326 * Verify a signature 327 */ 328 int 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 { 332 return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len, 333 sig, sig_len, NULL ) ); 334 } 335 336 /* 337 * Verify a signature with options 338 */ 339 int 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 { 344 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 ) 350 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) 358 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 359 const mbedtls_pk_rsassa_pss_options *pss_opts; 360 361 #if SIZE_MAX > UINT_MAX 362 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) 363 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 364 #endif /* SIZE_MAX > UINT_MAX */ 365 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 /* 400 * Make a signature (restartable) 401 */ 402 int 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 { 424 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 425 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 /* 449 * Make a signature 450 */ 451 int 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 { 456 return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len, 457 sig, sig_len, f_rng, p_rng, NULL ) ); 458 } 459 460 /* 461 * Decrypt message 462 */ 463 int 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 { 468 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 ) 474 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 */ 486 int 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 { 491 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 ) 497 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 */ 509 int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ) 510 { 511 PK_VALIDATE_RET( pub != NULL ); 512 PK_VALIDATE_RET( prv != NULL ); 513 514 if( pub->pk_info == NULL || 515 prv->pk_info == NULL ) 516 { 517 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 518 } 519 520 if( prv->pk_info->check_pair_func == NULL ) 521 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); 522 523 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 */ 540 size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ) 541 { 542 /* For backward compatibility, accept NULL or a context that 543 * isn't set up yet, and return a fake value that should be safe. */ 544 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 */ 553 int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items ) 554 { 555 PK_VALIDATE_RET( ctx != NULL ); 556 if( ctx->pk_info == NULL ) 557 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 */ 569 const 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 */ 580 mbedtls_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 588 #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 */ 595 int 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 */ 641 #endif /* MBEDTLS_PK_C */ 642