LCOV - code coverage report
Current view: top level - externals/mbedtls/library - pk.c (source / functions) Coverage Total Hit
Test: lcov.info Lines: 7.7 % 207 16
Test Date: 2026-03-12 12:01:18 Functions: 15.4 % 26 4
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 6.2 % 161 10

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  *  Public Key abstraction layer
       3                 :             :  *
       4                 :             :  *  Copyright The Mbed TLS Contributors
       5                 :             :  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       6                 :             :  */
       7                 :             : 
       8                 :             : #include "common.h"
       9                 :             : 
      10                 :             : #if defined(MBEDTLS_PK_C)
      11                 :             : #include "mbedtls/pk.h"
      12                 :             : #include "pk_wrap.h"
      13                 :             : #include "pkwrite.h"
      14                 :             : #include "pk_internal.h"
      15                 :             : 
      16                 :             : #include "mbedtls/platform_util.h"
      17                 :             : #include "mbedtls/error.h"
      18                 :             : 
      19                 :             : #if defined(MBEDTLS_RSA_C)
      20                 :             : #include "mbedtls/rsa.h"
      21                 :             : #include "rsa_internal.h"
      22                 :             : #endif
      23                 :             : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
      24                 :             : #include "mbedtls/ecp.h"
      25                 :             : #endif
      26                 :             : #if defined(MBEDTLS_ECDSA_C)
      27                 :             : #include "mbedtls/ecdsa.h"
      28                 :             : #endif
      29                 :             : 
      30                 :             : #if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
      31                 :             : #include "psa_util_internal.h"
      32                 :             : #include "mbedtls/psa_util.h"
      33                 :             : #endif
      34                 :             : 
      35                 :             : #include <limits.h>
      36                 :             : #include <stdint.h>
      37                 :             : 
      38                 :             : /*
      39                 :             :  * Initialise a mbedtls_pk_context
      40                 :             :  */
      41                 :           0 : void mbedtls_pk_init(mbedtls_pk_context *ctx)
      42                 :             : {
      43                 :           0 :     ctx->pk_info = NULL;
      44                 :           0 :     ctx->pk_ctx = NULL;
      45                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO)
      46                 :             :     ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT;
      47                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
      48                 :             : #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
      49                 :             :     memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw));
      50                 :             :     ctx->pub_raw_len = 0;
      51                 :             :     ctx->ec_family = 0;
      52                 :             :     ctx->ec_bits = 0;
      53                 :             : #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
      54                 :           0 : }
      55                 :             : 
      56                 :             : /*
      57                 :             :  * Free (the components of) a mbedtls_pk_context
      58                 :             :  */
      59                 :           4 : void mbedtls_pk_free(mbedtls_pk_context *ctx)
      60                 :             : {
      61         [ +  - ]:           4 :     if (ctx == NULL) {
      62                 :             :         return;
      63                 :             :     }
      64                 :             : 
      65   [ +  -  +  - ]:           4 :     if ((ctx->pk_info != NULL) && (ctx->pk_info->ctx_free_func != NULL)) {
      66                 :           4 :         ctx->pk_info->ctx_free_func(ctx->pk_ctx);
      67                 :             :     }
      68                 :             : 
      69                 :             : #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
      70                 :             :     /* The ownership of the priv_id key for opaque keys is external of the PK
      71                 :             :      * module. It's the user responsibility to clear it after use. */
      72                 :             :     if ((ctx->pk_info != NULL) && (ctx->pk_info->type != MBEDTLS_PK_OPAQUE)) {
      73                 :             :         psa_destroy_key(ctx->priv_id);
      74                 :             :     }
      75                 :             : #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
      76                 :             : 
      77                 :           4 :     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context));
      78                 :             : }
      79                 :             : 
      80                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
      81                 :             : /*
      82                 :             :  * Initialize a restart context
      83                 :             :  */
      84                 :             : void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx)
      85                 :             : {
      86                 :             :     ctx->pk_info = NULL;
      87                 :             :     ctx->rs_ctx = NULL;
      88                 :             : }
      89                 :             : 
      90                 :             : /*
      91                 :             :  * Free the components of a restart context
      92                 :             :  */
      93                 :             : void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx)
      94                 :             : {
      95                 :             :     if (ctx == NULL || ctx->pk_info == NULL ||
      96                 :             :         ctx->pk_info->rs_free_func == NULL) {
      97                 :             :         return;
      98                 :             :     }
      99                 :             : 
     100                 :             :     ctx->pk_info->rs_free_func(ctx->rs_ctx);
     101                 :             : 
     102                 :             :     ctx->pk_info = NULL;
     103                 :             :     ctx->rs_ctx = NULL;
     104                 :             : }
     105                 :             : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
     106                 :             : 
     107                 :             : /*
     108                 :             :  * Get pk_info structure from type
     109                 :             :  */
     110                 :           4 : const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type)
     111                 :             : {
     112         [ -  + ]:           4 :     switch (pk_type) {
     113                 :             : #if defined(MBEDTLS_RSA_C)
     114                 :             :         case MBEDTLS_PK_RSA:
     115                 :             :             return &mbedtls_rsa_info;
     116                 :             : #endif /* MBEDTLS_RSA_C */
     117                 :             : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     118                 :             :         case MBEDTLS_PK_ECKEY:
     119                 :             :             return &mbedtls_eckey_info;
     120                 :             :         case MBEDTLS_PK_ECKEY_DH:
     121                 :             :             return &mbedtls_eckeydh_info;
     122                 :             : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     123                 :             : #if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
     124                 :             :         case MBEDTLS_PK_ECDSA:
     125                 :             :             return &mbedtls_ecdsa_info;
     126                 :             : #endif /* MBEDTLS_PK_CAN_ECDSA_SOME */
     127                 :             :         /* MBEDTLS_PK_RSA_ALT omitted on purpose */
     128                 :             :         default:
     129                 :             :             return NULL;
     130                 :             :     }
     131                 :             : }
     132                 :             : 
     133                 :             : /*
     134                 :             :  * Initialise context
     135                 :             :  */
     136                 :           4 : int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info)
     137                 :             : {
     138   [ +  -  +  - ]:           4 :     if (info == NULL || ctx->pk_info != NULL) {
     139                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     140                 :             :     }
     141                 :             : 
     142         [ +  - ]:           4 :     if ((info->ctx_alloc_func != NULL) &&
     143         [ +  - ]:           4 :         ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)) {
     144                 :             :         return MBEDTLS_ERR_PK_ALLOC_FAILED;
     145                 :             :     }
     146                 :             : 
     147                 :           4 :     ctx->pk_info = info;
     148                 :             : 
     149                 :           4 :     return 0;
     150                 :             : }
     151                 :             : 
     152                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO)
     153                 :             : /*
     154                 :             :  * Initialise a PSA-wrapping context
     155                 :             :  */
     156                 :             : int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
     157                 :             :                             const mbedtls_svc_key_id_t key)
     158                 :             : {
     159                 :             :     const mbedtls_pk_info_t *info = NULL;
     160                 :             :     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     161                 :             :     psa_key_type_t type;
     162                 :             : 
     163                 :             :     if (ctx == NULL || ctx->pk_info != NULL) {
     164                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     165                 :             :     }
     166                 :             : 
     167                 :             :     if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes)) {
     168                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     169                 :             :     }
     170                 :             :     type = psa_get_key_type(&attributes);
     171                 :             :     psa_reset_key_attributes(&attributes);
     172                 :             : 
     173                 :             : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     174                 :             :     if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
     175                 :             :         info = &mbedtls_ecdsa_opaque_info;
     176                 :             :     } else
     177                 :             : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     178                 :             :     if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
     179                 :             :         info = &mbedtls_rsa_opaque_info;
     180                 :             :     } else {
     181                 :             :         return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
     182                 :             :     }
     183                 :             : 
     184                 :             :     ctx->pk_info = info;
     185                 :             :     ctx->priv_id = key;
     186                 :             : 
     187                 :             :     return 0;
     188                 :             : }
     189                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
     190                 :             : 
     191                 :             : #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
     192                 :             : /*
     193                 :             :  * Initialize an RSA-alt context
     194                 :             :  */
     195                 :             : int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key,
     196                 :             :                              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)
     199                 :             : {
     200                 :             :     mbedtls_rsa_alt_context *rsa_alt;
     201                 :             :     const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
     202                 :             : 
     203                 :             :     if (ctx->pk_info != NULL) {
     204                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     205                 :             :     }
     206                 :             : 
     207                 :             :     if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
     208                 :             :         return MBEDTLS_ERR_PK_ALLOC_FAILED;
     209                 :             :     }
     210                 :             : 
     211                 :             :     ctx->pk_info = info;
     212                 :             : 
     213                 :             :     rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
     214                 :             : 
     215                 :             :     rsa_alt->key = key;
     216                 :             :     rsa_alt->decrypt_func = decrypt_func;
     217                 :             :     rsa_alt->sign_func = sign_func;
     218                 :             :     rsa_alt->key_len_func = key_len_func;
     219                 :             : 
     220                 :             :     return 0;
     221                 :             : }
     222                 :             : #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
     223                 :             : 
     224                 :             : /*
     225                 :             :  * Tell if a PK can do the operations of the given type
     226                 :             :  */
     227                 :           0 : int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type)
     228                 :             : {
     229                 :             :     /* A context with null pk_info is not set up yet and can't do anything.
     230                 :             :      * For backward compatibility, also accept NULL instead of a context
     231                 :             :      * pointer. */
     232   [ #  #  #  # ]:           0 :     if (ctx == NULL || ctx->pk_info == NULL) {
     233                 :             :         return 0;
     234                 :             :     }
     235                 :             : 
     236                 :           0 :     return ctx->pk_info->can_do(type);
     237                 :             : }
     238                 :             : 
     239                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO)
     240                 :             : /*
     241                 :             :  * Tell if a PK can do the operations of the given PSA algorithm
     242                 :             :  */
     243                 :             : int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
     244                 :             :                           psa_key_usage_t usage)
     245                 :             : {
     246                 :             :     psa_key_usage_t key_usage;
     247                 :             : 
     248                 :             :     /* A context with null pk_info is not set up yet and can't do anything.
     249                 :             :      * For backward compatibility, also accept NULL instead of a context
     250                 :             :      * pointer. */
     251                 :             :     if (ctx == NULL || ctx->pk_info == NULL) {
     252                 :             :         return 0;
     253                 :             :     }
     254                 :             : 
     255                 :             :     /* Filter out non allowed algorithms */
     256                 :             :     if (PSA_ALG_IS_ECDSA(alg) == 0 &&
     257                 :             :         PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) == 0 &&
     258                 :             :         PSA_ALG_IS_RSA_PSS(alg) == 0 &&
     259                 :             :         alg != PSA_ALG_RSA_PKCS1V15_CRYPT &&
     260                 :             :         PSA_ALG_IS_ECDH(alg) == 0) {
     261                 :             :         return 0;
     262                 :             :     }
     263                 :             : 
     264                 :             :     /* Filter out non allowed usage flags */
     265                 :             :     if (usage == 0 ||
     266                 :             :         (usage & ~(PSA_KEY_USAGE_SIGN_HASH |
     267                 :             :                    PSA_KEY_USAGE_DECRYPT |
     268                 :             :                    PSA_KEY_USAGE_DERIVE)) != 0) {
     269                 :             :         return 0;
     270                 :             :     }
     271                 :             : 
     272                 :             :     /* Wildcard hash is not allowed */
     273                 :             :     if (PSA_ALG_IS_SIGN_HASH(alg) &&
     274                 :             :         PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH) {
     275                 :             :         return 0;
     276                 :             :     }
     277                 :             : 
     278                 :             :     if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_OPAQUE) {
     279                 :             :         mbedtls_pk_type_t type;
     280                 :             : 
     281                 :             :         if (PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_ECDH(alg)) {
     282                 :             :             type = MBEDTLS_PK_ECKEY;
     283                 :             :         } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
     284                 :             :                    alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
     285                 :             :             type = MBEDTLS_PK_RSA;
     286                 :             :         } else if (PSA_ALG_IS_RSA_PSS(alg)) {
     287                 :             :             type = MBEDTLS_PK_RSASSA_PSS;
     288                 :             :         } else {
     289                 :             :             return 0;
     290                 :             :         }
     291                 :             : 
     292                 :             :         if (ctx->pk_info->can_do(type) == 0) {
     293                 :             :             return 0;
     294                 :             :         }
     295                 :             : 
     296                 :             :         switch (type) {
     297                 :             :             case MBEDTLS_PK_ECKEY:
     298                 :             :                 key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE;
     299                 :             :                 break;
     300                 :             :             case MBEDTLS_PK_RSA:
     301                 :             :             case MBEDTLS_PK_RSASSA_PSS:
     302                 :             :                 key_usage = PSA_KEY_USAGE_SIGN_HASH |
     303                 :             :                             PSA_KEY_USAGE_SIGN_MESSAGE |
     304                 :             :                             PSA_KEY_USAGE_DECRYPT;
     305                 :             :                 break;
     306                 :             :             default:
     307                 :             :                 /* Should never happen */
     308                 :             :                 return 0;
     309                 :             :         }
     310                 :             : 
     311                 :             :         return (key_usage & usage) == usage;
     312                 :             :     }
     313                 :             : 
     314                 :             :     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     315                 :             :     psa_status_t status;
     316                 :             : 
     317                 :             :     status = psa_get_key_attributes(ctx->priv_id, &attributes);
     318                 :             :     if (status != PSA_SUCCESS) {
     319                 :             :         return 0;
     320                 :             :     }
     321                 :             : 
     322                 :             :     psa_algorithm_t key_alg = psa_get_key_algorithm(&attributes);
     323                 :             :     /* Key's enrollment is available only when an Mbed TLS implementation of PSA
     324                 :             :      * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined.
     325                 :             :      * Even though we don't officially support using other implementations of PSA
     326                 :             :      * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations
     327                 :             :      * separated. */
     328                 :             : #if defined(MBEDTLS_PSA_CRYPTO_C)
     329                 :             :     psa_algorithm_t key_alg2 = psa_get_key_enrollment_algorithm(&attributes);
     330                 :             : #endif /* MBEDTLS_PSA_CRYPTO_C */
     331                 :             :     key_usage = psa_get_key_usage_flags(&attributes);
     332                 :             :     psa_reset_key_attributes(&attributes);
     333                 :             : 
     334                 :             :     if ((key_usage & usage) != usage) {
     335                 :             :         return 0;
     336                 :             :     }
     337                 :             : 
     338                 :             :     /*
     339                 :             :      * Common case: the key alg [or alg2] only allows alg.
     340                 :             :      * This will match PSA_ALG_RSA_PKCS1V15_CRYPT & PSA_ALG_IS_ECDH
     341                 :             :      * directly.
     342                 :             :      * This would also match ECDSA/RSA_PKCS1V15_SIGN/RSA_PSS with
     343                 :             :      * a fixed hash on key_alg [or key_alg2].
     344                 :             :      */
     345                 :             :     if (alg == key_alg) {
     346                 :             :         return 1;
     347                 :             :     }
     348                 :             : #if defined(MBEDTLS_PSA_CRYPTO_C)
     349                 :             :     if (alg == key_alg2) {
     350                 :             :         return 1;
     351                 :             :     }
     352                 :             : #endif /* MBEDTLS_PSA_CRYPTO_C */
     353                 :             : 
     354                 :             :     /*
     355                 :             :      * If key_alg [or key_alg2] is a hash-and-sign with a wildcard for the hash,
     356                 :             :      * and alg is the same hash-and-sign family with any hash,
     357                 :             :      * then alg is compliant with this key alg
     358                 :             :      */
     359                 :             :     if (PSA_ALG_IS_SIGN_HASH(alg)) {
     360                 :             :         if (PSA_ALG_IS_SIGN_HASH(key_alg) &&
     361                 :             :             PSA_ALG_SIGN_GET_HASH(key_alg) == PSA_ALG_ANY_HASH &&
     362                 :             :             (alg & ~PSA_ALG_HASH_MASK) == (key_alg & ~PSA_ALG_HASH_MASK)) {
     363                 :             :             return 1;
     364                 :             :         }
     365                 :             : #if defined(MBEDTLS_PSA_CRYPTO_C)
     366                 :             :         if (PSA_ALG_IS_SIGN_HASH(key_alg2) &&
     367                 :             :             PSA_ALG_SIGN_GET_HASH(key_alg2) == PSA_ALG_ANY_HASH &&
     368                 :             :             (alg & ~PSA_ALG_HASH_MASK) == (key_alg2 & ~PSA_ALG_HASH_MASK)) {
     369                 :             :             return 1;
     370                 :             :         }
     371                 :             : #endif /* MBEDTLS_PSA_CRYPTO_C */
     372                 :             :     }
     373                 :             : 
     374                 :             :     return 0;
     375                 :             : }
     376                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
     377                 :             : 
     378                 :             : #if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
     379                 :             : #if defined(MBEDTLS_RSA_C)
     380                 :             : static psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa,
     381                 :             :                                              int want_crypt)
     382                 :             : {
     383                 :             :     if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
     384                 :             :         if (want_crypt) {
     385                 :             :             mbedtls_md_type_t md_type = (mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa);
     386                 :             :             return PSA_ALG_RSA_OAEP(mbedtls_md_psa_alg_from_type(md_type));
     387                 :             :         } else {
     388                 :             :             return PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH);
     389                 :             :         }
     390                 :             :     } else {
     391                 :             :         if (want_crypt) {
     392                 :             :             return PSA_ALG_RSA_PKCS1V15_CRYPT;
     393                 :             :         } else {
     394                 :             :             return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH);
     395                 :             :         }
     396                 :             :     }
     397                 :             : }
     398                 :             : #endif /* MBEDTLS_RSA_C */
     399                 :             : 
     400                 :           0 : int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
     401                 :             :                                   psa_key_usage_t usage,
     402                 :             :                                   psa_key_attributes_t *attributes)
     403                 :             : {
     404                 :           0 :     mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
     405                 :             : 
     406                 :           0 :     psa_key_usage_t more_usage = usage;
     407         [ #  # ]:           0 :     if (usage == PSA_KEY_USAGE_SIGN_MESSAGE) {
     408                 :             :         more_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
     409         [ #  # ]:           0 :     } else if (usage == PSA_KEY_USAGE_SIGN_HASH) {
     410                 :             :         more_usage |= PSA_KEY_USAGE_VERIFY_HASH;
     411         [ #  # ]:           0 :     } else if (usage == PSA_KEY_USAGE_DECRYPT) {
     412                 :           0 :         more_usage |= PSA_KEY_USAGE_ENCRYPT;
     413                 :             :     }
     414                 :           0 :     more_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY;
     415                 :             : 
     416         [ #  # ]:           0 :     int want_private = !(usage == PSA_KEY_USAGE_VERIFY_MESSAGE ||
     417         [ #  # ]:           0 :                          usage == PSA_KEY_USAGE_VERIFY_HASH ||
     418                 :             :                          usage == PSA_KEY_USAGE_ENCRYPT);
     419                 :             : 
     420         [ #  # ]:           0 :     switch (pk_type) {
     421                 :             : #if defined(MBEDTLS_RSA_C)
     422                 :             :         case MBEDTLS_PK_RSA:
     423                 :             :         {
     424                 :             :             int want_crypt = 0; /* 0: sign/verify; 1: encrypt/decrypt */
     425                 :             :             switch (usage) {
     426                 :             :                 case PSA_KEY_USAGE_SIGN_MESSAGE:
     427                 :             :                 case PSA_KEY_USAGE_SIGN_HASH:
     428                 :             :                 case PSA_KEY_USAGE_VERIFY_MESSAGE:
     429                 :             :                 case PSA_KEY_USAGE_VERIFY_HASH:
     430                 :             :                     /* Nothing to do. */
     431                 :             :                     break;
     432                 :             :                 case PSA_KEY_USAGE_DECRYPT:
     433                 :             :                 case PSA_KEY_USAGE_ENCRYPT:
     434                 :             :                     want_crypt = 1;
     435                 :             :                     break;
     436                 :             :                 default:
     437                 :             :                     return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     438                 :             :             }
     439                 :             :             /* Detect the presence of a private key in a way that works both
     440                 :             :              * in CRT and non-CRT configurations. */
     441                 :             :             mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
     442                 :             :             int has_private = (mbedtls_rsa_check_privkey(rsa) == 0);
     443                 :             :             if (want_private && !has_private) {
     444                 :             :                 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     445                 :             :             }
     446                 :             :             psa_set_key_type(attributes, (want_private ?
     447                 :             :                                           PSA_KEY_TYPE_RSA_KEY_PAIR :
     448                 :             :                                           PSA_KEY_TYPE_RSA_PUBLIC_KEY));
     449                 :             :             psa_set_key_bits(attributes, mbedtls_pk_get_bitlen(pk));
     450                 :             :             psa_set_key_algorithm(attributes,
     451                 :             :                                   psa_algorithm_for_rsa(rsa, want_crypt));
     452                 :             :             break;
     453                 :             :         }
     454                 :             : #endif /* MBEDTLS_RSA_C */
     455                 :             : 
     456                 :             : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     457                 :           0 :         case MBEDTLS_PK_ECKEY:
     458                 :             :         case MBEDTLS_PK_ECKEY_DH:
     459                 :             :         case MBEDTLS_PK_ECDSA:
     460                 :             :         {
     461                 :           0 :             int sign_ok = (pk_type != MBEDTLS_PK_ECKEY_DH);
     462                 :           0 :             int derive_ok = (pk_type != MBEDTLS_PK_ECDSA);
     463                 :             : #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
     464                 :             :             psa_ecc_family_t family = pk->ec_family;
     465                 :             :             size_t bits = pk->ec_bits;
     466                 :             :             int has_private = 0;
     467                 :             :             if (pk->priv_id != MBEDTLS_SVC_KEY_ID_INIT) {
     468                 :             :                 has_private = 1;
     469                 :             :             }
     470                 :             : #else
     471                 :           0 :             const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
     472                 :           0 :             int has_private = (ec->d.n != 0);
     473                 :           0 :             size_t bits = 0;
     474                 :           0 :             psa_ecc_family_t family =
     475                 :           0 :                 mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
     476                 :             : #endif
     477                 :           0 :             psa_algorithm_t alg = 0;
     478      [ #  #  # ]:           0 :             switch (usage) {
     479                 :           0 :                 case PSA_KEY_USAGE_SIGN_MESSAGE:
     480                 :             :                 case PSA_KEY_USAGE_SIGN_HASH:
     481                 :             :                 case PSA_KEY_USAGE_VERIFY_MESSAGE:
     482                 :             :                 case PSA_KEY_USAGE_VERIFY_HASH:
     483         [ #  # ]:           0 :                     if (!sign_ok) {
     484                 :           0 :                         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     485                 :             :                     }
     486                 :             : #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
     487                 :             :                     alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH);
     488                 :             : #else
     489                 :             :                     alg = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH);
     490                 :             : #endif
     491                 :             :                     break;
     492                 :           0 :                 case PSA_KEY_USAGE_DERIVE:
     493                 :           0 :                     alg = PSA_ALG_ECDH;
     494         [ #  # ]:           0 :                     if (!derive_ok) {
     495                 :             :                         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     496                 :             :                     }
     497                 :             :                     break;
     498                 :             :                 default:
     499                 :             :                     return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     500                 :             :             }
     501         [ #  # ]:           0 :             if (want_private && !has_private) {
     502                 :             :                 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     503                 :             :             }
     504         [ #  # ]:           0 :             psa_set_key_type(attributes, (want_private ?
     505                 :           0 :                                           PSA_KEY_TYPE_ECC_KEY_PAIR(family) :
     506                 :           0 :                                           PSA_KEY_TYPE_ECC_PUBLIC_KEY(family)));
     507                 :           0 :             psa_set_key_bits(attributes, bits);
     508                 :           0 :             psa_set_key_algorithm(attributes, alg);
     509                 :           0 :             break;
     510                 :             :         }
     511                 :             : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     512                 :             : 
     513                 :             : #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
     514                 :             :         case MBEDTLS_PK_RSA_ALT:
     515                 :             :             return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
     516                 :             : #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
     517                 :             : 
     518                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO)
     519                 :             :         case MBEDTLS_PK_OPAQUE:
     520                 :             :         {
     521                 :             :             psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
     522                 :             :             psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     523                 :             :             status = psa_get_key_attributes(pk->priv_id, &old_attributes);
     524                 :             :             if (status != PSA_SUCCESS) {
     525                 :             :                 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     526                 :             :             }
     527                 :             :             psa_key_type_t old_type = psa_get_key_type(&old_attributes);
     528                 :             :             switch (usage) {
     529                 :             :                 case PSA_KEY_USAGE_SIGN_MESSAGE:
     530                 :             :                 case PSA_KEY_USAGE_SIGN_HASH:
     531                 :             :                 case PSA_KEY_USAGE_VERIFY_MESSAGE:
     532                 :             :                 case PSA_KEY_USAGE_VERIFY_HASH:
     533                 :             :                     if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type) ||
     534                 :             :                           old_type == PSA_KEY_TYPE_RSA_KEY_PAIR)) {
     535                 :             :                         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     536                 :             :                     }
     537                 :             :                     break;
     538                 :             :                 case PSA_KEY_USAGE_DECRYPT:
     539                 :             :                 case PSA_KEY_USAGE_ENCRYPT:
     540                 :             :                     if (old_type != PSA_KEY_TYPE_RSA_KEY_PAIR) {
     541                 :             :                         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     542                 :             :                     }
     543                 :             :                     break;
     544                 :             :                 case PSA_KEY_USAGE_DERIVE:
     545                 :             :                     if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type))) {
     546                 :             :                         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     547                 :             :                     }
     548                 :             :                     break;
     549                 :             :                 default:
     550                 :             :                     return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     551                 :             :             }
     552                 :             :             psa_key_type_t new_type = old_type;
     553                 :             :             /* Opaque keys are always key pairs, so we don't need a check
     554                 :             :              * on the input if the required usage is private. We just need
     555                 :             :              * to adjust the type correctly if the required usage is public. */
     556                 :             :             if (!want_private) {
     557                 :             :                 new_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(new_type);
     558                 :             :             }
     559                 :             :             more_usage = psa_get_key_usage_flags(&old_attributes);
     560                 :             :             if ((usage & more_usage) == 0) {
     561                 :             :                 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     562                 :             :             }
     563                 :             :             psa_set_key_type(attributes, new_type);
     564                 :             :             psa_set_key_bits(attributes, psa_get_key_bits(&old_attributes));
     565                 :             :             psa_set_key_algorithm(attributes, psa_get_key_algorithm(&old_attributes));
     566                 :             :             break;
     567                 :             :         }
     568                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
     569                 :             : 
     570                 :             :         default:
     571                 :             :             return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     572                 :             :     }
     573                 :             : 
     574                 :           0 :     psa_set_key_usage_flags(attributes, more_usage);
     575                 :             :     /* Key's enrollment is available only when an Mbed TLS implementation of PSA
     576                 :             :      * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined.
     577                 :             :      * Even though we don't officially support using other implementations of PSA
     578                 :             :      * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations
     579                 :             :      * separated. */
     580                 :             : #if defined(MBEDTLS_PSA_CRYPTO_C)
     581                 :           0 :     psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE);
     582                 :             : #endif
     583                 :             : 
     584                 :           0 :     return 0;
     585                 :             : }
     586                 :             : 
     587                 :             : #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_USE_PSA_CRYPTO)
     588                 :             : static psa_status_t export_import_into_psa(mbedtls_svc_key_id_t old_key_id,
     589                 :             :                                            const psa_key_attributes_t *attributes,
     590                 :             :                                            mbedtls_svc_key_id_t *new_key_id)
     591                 :             : {
     592                 :             :     unsigned char key_buffer[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
     593                 :             :     size_t key_length = 0;
     594                 :             :     psa_status_t status = psa_export_key(old_key_id,
     595                 :             :                                          key_buffer, sizeof(key_buffer),
     596                 :             :                                          &key_length);
     597                 :             :     if (status != PSA_SUCCESS) {
     598                 :             :         return status;
     599                 :             :     }
     600                 :             :     status = psa_import_key(attributes, key_buffer, key_length, new_key_id);
     601                 :             :     mbedtls_platform_zeroize(key_buffer, key_length);
     602                 :             :     return status;
     603                 :             : }
     604                 :             : 
     605                 :             : static int copy_into_psa(mbedtls_svc_key_id_t old_key_id,
     606                 :             :                          const psa_key_attributes_t *attributes,
     607                 :             :                          mbedtls_svc_key_id_t *new_key_id)
     608                 :             : {
     609                 :             :     /* Normally, we prefer copying: it's more efficient and works even
     610                 :             :      * for non-exportable keys. */
     611                 :             :     psa_status_t status = psa_copy_key(old_key_id, attributes, new_key_id);
     612                 :             :     if (status == PSA_ERROR_NOT_PERMITTED /*missing COPY usage*/ ||
     613                 :             :         status == PSA_ERROR_INVALID_ARGUMENT /*incompatible policy*/) {
     614                 :             :         /* There are edge cases where copying won't work, but export+import
     615                 :             :          * might:
     616                 :             :          * - If the old key does not allow PSA_KEY_USAGE_COPY.
     617                 :             :          * - If the old key's usage does not allow what attributes wants.
     618                 :             :          *   Because the key was intended for use in the pk module, and may
     619                 :             :          *   have had a policy chosen solely for what pk needs rather than
     620                 :             :          *   based on a detailed understanding of PSA policies, we are a bit
     621                 :             :          *   more liberal than psa_copy_key() here.
     622                 :             :          */
     623                 :             :         /* Here we need to check that the types match, otherwise we risk
     624                 :             :          * importing nonsensical data. */
     625                 :             :         psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
     626                 :             :         status = psa_get_key_attributes(old_key_id, &old_attributes);
     627                 :             :         if (status != PSA_SUCCESS) {
     628                 :             :             return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     629                 :             :         }
     630                 :             :         psa_key_type_t old_type = psa_get_key_type(&old_attributes);
     631                 :             :         psa_reset_key_attributes(&old_attributes);
     632                 :             :         if (old_type != psa_get_key_type(attributes)) {
     633                 :             :             return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     634                 :             :         }
     635                 :             :         status = export_import_into_psa(old_key_id, attributes, new_key_id);
     636                 :             :     }
     637                 :             :     return PSA_PK_TO_MBEDTLS_ERR(status);
     638                 :             : }
     639                 :             : #endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_USE_PSA_CRYPTO */
     640                 :             : 
     641                 :           0 : static int import_pair_into_psa(const mbedtls_pk_context *pk,
     642                 :             :                                 const psa_key_attributes_t *attributes,
     643                 :             :                                 mbedtls_svc_key_id_t *key_id)
     644                 :             : {
     645         [ #  # ]:           0 :     switch (mbedtls_pk_get_type(pk)) {
     646                 :             : #if defined(MBEDTLS_RSA_C)
     647                 :             :         case MBEDTLS_PK_RSA:
     648                 :             :         {
     649                 :             :             if (psa_get_key_type(attributes) != PSA_KEY_TYPE_RSA_KEY_PAIR) {
     650                 :             :                 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     651                 :             :             }
     652                 :             :             unsigned char key_buffer[
     653                 :             :                 PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)];
     654                 :             :             unsigned char *const key_end = key_buffer + sizeof(key_buffer);
     655                 :             :             unsigned char *key_data = key_end;
     656                 :             :             int ret = mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk),
     657                 :             :                                             key_buffer, &key_data);
     658                 :             :             if (ret < 0) {
     659                 :             :                 return ret;
     660                 :             :             }
     661                 :             :             size_t key_length = key_end - key_data;
     662                 :             :             ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
     663                 :             :                                                        key_data, key_length,
     664                 :             :                                                        key_id));
     665                 :             :             mbedtls_platform_zeroize(key_data, key_length);
     666                 :             :             return ret;
     667                 :             :         }
     668                 :             : #endif /* MBEDTLS_RSA_C */
     669                 :             : 
     670                 :             : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     671                 :           0 :         case MBEDTLS_PK_ECKEY:
     672                 :             :         case MBEDTLS_PK_ECKEY_DH:
     673                 :             :         case MBEDTLS_PK_ECDSA:
     674                 :             :         {
     675                 :             :             /* We need to check the curve family, otherwise the import could
     676                 :             :              * succeed with nonsensical data.
     677                 :             :              * We don't check the bit-size: it's optional in attributes,
     678                 :             :              * and if it's specified, psa_import_key() will know from the key
     679                 :             :              * data length and will check that the bit-size matches. */
     680                 :           0 :             psa_key_type_t to_type = psa_get_key_type(attributes);
     681                 :             : #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
     682                 :             :             psa_ecc_family_t from_family = pk->ec_family;
     683                 :             : #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
     684                 :           0 :             const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
     685                 :           0 :             size_t from_bits = 0;
     686                 :           0 :             psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id,
     687                 :             :                                                                     &from_bits);
     688                 :             : #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
     689         [ #  # ]:           0 :             if (to_type != PSA_KEY_TYPE_ECC_KEY_PAIR(from_family)) {
     690                 :             :                 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     691                 :             :             }
     692                 :             : 
     693                 :             : #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
     694                 :             :             if (mbedtls_svc_key_id_is_null(pk->priv_id)) {
     695                 :             :                 /* We have a public key and want a key pair. */
     696                 :             :                 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     697                 :             :             }
     698                 :             :             return copy_into_psa(pk->priv_id, attributes, key_id);
     699                 :             : #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
     700         [ #  # ]:           0 :             if (ec->d.n == 0) {
     701                 :             :                 /* Private key not set. Assume the input is a public key only.
     702                 :             :                  * (The other possibility is that it's an incomplete object
     703                 :             :                  * where the group is set but neither the public key nor
     704                 :             :                  * the private key. This is not possible through ecp.h
     705                 :             :                  * functions, so we don't bother reporting a more suitable
     706                 :             :                  * error in that case.) */
     707                 :             :                 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     708                 :             :             }
     709                 :           0 :             unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
     710                 :           0 :             size_t key_length = 0;
     711                 :           0 :             int ret = mbedtls_ecp_write_key_ext(ec, &key_length,
     712                 :             :                                                 key_buffer, sizeof(key_buffer));
     713         [ #  # ]:           0 :             if (ret < 0) {
     714                 :             :                 return ret;
     715                 :             :             }
     716                 :           0 :             ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
     717                 :             :                                                        key_buffer, key_length,
     718                 :             :                                                        key_id));
     719                 :           0 :             mbedtls_platform_zeroize(key_buffer, key_length);
     720                 :           0 :             return ret;
     721                 :             : #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
     722                 :             :         }
     723                 :             : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     724                 :             : 
     725                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO)
     726                 :             :         case MBEDTLS_PK_OPAQUE:
     727                 :             :             return copy_into_psa(pk->priv_id, attributes, key_id);
     728                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
     729                 :             : 
     730                 :             :         default:
     731                 :             :             return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     732                 :             :     }
     733                 :             : }
     734                 :             : 
     735                 :           0 : static int import_public_into_psa(const mbedtls_pk_context *pk,
     736                 :             :                                   const psa_key_attributes_t *attributes,
     737                 :             :                                   mbedtls_svc_key_id_t *key_id)
     738                 :             : {
     739                 :           0 :     psa_key_type_t psa_type = psa_get_key_type(attributes);
     740                 :             : 
     741                 :             : #if defined(MBEDTLS_RSA_C) ||                                           \
     742                 :             :     (defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)) || \
     743                 :             :     defined(MBEDTLS_USE_PSA_CRYPTO)
     744                 :           0 :     unsigned char key_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
     745                 :             : #endif
     746                 :           0 :     unsigned char *key_data = NULL;
     747                 :           0 :     size_t key_length = 0;
     748                 :             : 
     749         [ #  # ]:           0 :     switch (mbedtls_pk_get_type(pk)) {
     750                 :             : #if defined(MBEDTLS_RSA_C)
     751                 :             :         case MBEDTLS_PK_RSA:
     752                 :             :         {
     753                 :             :             if (psa_type != PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
     754                 :             :                 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     755                 :             :             }
     756                 :             :             unsigned char *const key_end = key_buffer + sizeof(key_buffer);
     757                 :             :             key_data = key_end;
     758                 :             :             int ret = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*pk),
     759                 :             :                                                key_buffer, &key_data);
     760                 :             :             if (ret < 0) {
     761                 :             :                 return ret;
     762                 :             :             }
     763                 :             :             key_length = (size_t) ret;
     764                 :             :             break;
     765                 :             :         }
     766                 :             : #endif /*MBEDTLS_RSA_C */
     767                 :             : 
     768                 :             : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     769                 :           0 :         case MBEDTLS_PK_ECKEY:
     770                 :             :         case MBEDTLS_PK_ECKEY_DH:
     771                 :             :         case MBEDTLS_PK_ECDSA:
     772                 :             :         {
     773                 :             :             /* We need to check the curve family, otherwise the import could
     774                 :             :              * succeed with nonsensical data.
     775                 :             :              * We don't check the bit-size: it's optional in attributes,
     776                 :             :              * and if it's specified, psa_import_key() will know from the key
     777                 :             :              * data length and will check that the bit-size matches. */
     778                 :             : #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
     779                 :             :             if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)) {
     780                 :             :                 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     781                 :             :             }
     782                 :             :             key_data = (unsigned char *) pk->pub_raw;
     783                 :             :             key_length = pk->pub_raw_len;
     784                 :             : #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
     785                 :           0 :             const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
     786                 :           0 :             size_t from_bits = 0;
     787                 :           0 :             psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id,
     788                 :             :                                                                     &from_bits);
     789         [ #  # ]:           0 :             if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(from_family)) {
     790                 :           0 :                 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     791                 :             :             }
     792                 :           0 :             int ret = mbedtls_ecp_write_public_key(
     793                 :             :                 ec, MBEDTLS_ECP_PF_UNCOMPRESSED,
     794                 :             :                 &key_length, key_buffer, sizeof(key_buffer));
     795         [ #  # ]:           0 :             if (ret < 0) {
     796                 :             :                 return ret;
     797                 :             :             }
     798                 :           0 :             key_data = key_buffer;
     799                 :             : #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
     800                 :           0 :             break;
     801                 :             :         }
     802                 :             : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     803                 :             : 
     804                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO)
     805                 :             :         case MBEDTLS_PK_OPAQUE:
     806                 :             :         {
     807                 :             :             psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
     808                 :             :             psa_status_t status =
     809                 :             :                 psa_get_key_attributes(pk->priv_id, &old_attributes);
     810                 :             :             if (status != PSA_SUCCESS) {
     811                 :             :                 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     812                 :             :             }
     813                 :             :             psa_key_type_t old_type = psa_get_key_type(&old_attributes);
     814                 :             :             psa_reset_key_attributes(&old_attributes);
     815                 :             :             if (psa_type != PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(old_type)) {
     816                 :             :                 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
     817                 :             :             }
     818                 :             :             status = psa_export_public_key(pk->priv_id,
     819                 :             :                                            key_buffer, sizeof(key_buffer),
     820                 :             :                                            &key_length);
     821                 :             :             if (status != PSA_SUCCESS) {
     822                 :             :                 return PSA_PK_TO_MBEDTLS_ERR(status);
     823                 :             :             }
     824                 :             :             key_data = key_buffer;
     825                 :             :             break;
     826                 :             :         }
     827                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
     828                 :             : 
     829                 :             :         default:
     830                 :             :             return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     831                 :             :     }
     832                 :             : 
     833                 :           0 :     return PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
     834                 :             :                                                 key_data, key_length,
     835                 :             :                                                 key_id));
     836                 :             : }
     837                 :             : 
     838                 :           0 : int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk,
     839                 :             :                                const psa_key_attributes_t *attributes,
     840                 :             :                                mbedtls_svc_key_id_t *key_id)
     841                 :             : {
     842                 :             :     /* Set the output immediately so that it won't contain garbage even
     843                 :             :      * if we error out before calling psa_import_key(). */
     844                 :           0 :     *key_id = MBEDTLS_SVC_KEY_ID_INIT;
     845                 :             : 
     846                 :             : #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
     847                 :             :     if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA_ALT) {
     848                 :             :         return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
     849                 :             :     }
     850                 :             : #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
     851                 :             : 
     852                 :           0 :     int want_public = PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(attributes));
     853         [ #  # ]:           0 :     if (want_public) {
     854                 :           0 :         return import_public_into_psa(pk, attributes, key_id);
     855                 :             :     } else {
     856                 :           0 :         return import_pair_into_psa(pk, attributes, key_id);
     857                 :             :     }
     858                 :             : }
     859                 :             : 
     860                 :           0 : static int copy_from_psa(mbedtls_svc_key_id_t key_id,
     861                 :             :                          mbedtls_pk_context *pk,
     862                 :             :                          int public_only)
     863                 :             : {
     864                 :           0 :     psa_status_t status;
     865                 :           0 :     psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
     866                 :           0 :     psa_key_type_t key_type;
     867                 :           0 :     size_t key_bits;
     868                 :             :     /* Use a buffer size large enough to contain either a key pair or public key. */
     869                 :           0 :     unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE];
     870                 :           0 :     size_t exp_key_len;
     871                 :           0 :     int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     872                 :             : 
     873         [ #  # ]:           0 :     if (pk == NULL) {
     874                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     875                 :             :     }
     876                 :             : 
     877                 :           0 :     status = psa_get_key_attributes(key_id, &key_attr);
     878         [ #  # ]:           0 :     if (status != PSA_SUCCESS) {
     879                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     880                 :             :     }
     881                 :             : 
     882         [ #  # ]:           0 :     if (public_only) {
     883                 :           0 :         status = psa_export_public_key(key_id, exp_key, sizeof(exp_key), &exp_key_len);
     884                 :             :     } else {
     885                 :           0 :         status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len);
     886                 :             :     }
     887         [ #  # ]:           0 :     if (status != PSA_SUCCESS) {
     888                 :           0 :         ret = PSA_PK_TO_MBEDTLS_ERR(status);
     889                 :           0 :         goto exit;
     890                 :             :     }
     891                 :             : 
     892                 :           0 :     key_type = psa_get_key_type(&key_attr);
     893         [ #  # ]:           0 :     if (public_only) {
     894                 :           0 :         key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
     895                 :             :     }
     896                 :           0 :     key_bits = psa_get_key_bits(&key_attr);
     897                 :             : 
     898                 :             : #if defined(MBEDTLS_RSA_C)
     899                 :             :     if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) ||
     900                 :             :         (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) {
     901                 :             : 
     902                 :             :         ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
     903                 :             :         if (ret != 0) {
     904                 :             :             goto exit;
     905                 :             :         }
     906                 :             : 
     907                 :             :         if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
     908                 :             :             ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len);
     909                 :             :         } else {
     910                 :             :             ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len);
     911                 :             :         }
     912                 :             :         if (ret != 0) {
     913                 :             :             goto exit;
     914                 :             :         }
     915                 :             : 
     916                 :             :         psa_algorithm_t alg_type = psa_get_key_algorithm(&key_attr);
     917                 :             :         mbedtls_md_type_t md_type = MBEDTLS_MD_NONE;
     918                 :             :         if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) {
     919                 :             :             md_type = mbedtls_md_type_from_psa_alg(alg_type);
     920                 :             :         }
     921                 :             : 
     922                 :             :         if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) {
     923                 :             :             ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type);
     924                 :             :         } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) ||
     925                 :             :                    alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) {
     926                 :             :             ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type);
     927                 :             :         }
     928                 :             :         if (ret != 0) {
     929                 :             :             goto exit;
     930                 :             :         }
     931                 :             :     } else
     932                 :             : #endif /* MBEDTLS_RSA_C */
     933                 :             : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     934         [ #  # ]:           0 :     if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ||
     935                 :             :         PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) {
     936                 :           0 :         mbedtls_ecp_group_id grp_id;
     937                 :             : 
     938                 :           0 :         ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY));
     939         [ #  # ]:           0 :         if (ret != 0) {
     940                 :           0 :             goto exit;
     941                 :             :         }
     942                 :             : 
     943                 :           0 :         grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits);
     944                 :           0 :         ret = mbedtls_pk_ecc_set_group(pk, grp_id);
     945         [ #  # ]:           0 :         if (ret != 0) {
     946                 :           0 :             goto exit;
     947                 :             :         }
     948                 :             : 
     949         [ #  # ]:           0 :         if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) {
     950                 :           0 :             ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len);
     951         [ #  # ]:           0 :             if (ret != 0) {
     952                 :           0 :                 goto exit;
     953                 :             :             }
     954                 :           0 :             ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len,
     955                 :             :                                                      mbedtls_psa_get_random,
     956                 :             :                                                      MBEDTLS_PSA_RANDOM_STATE);
     957                 :             :         } else {
     958                 :           0 :             ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len);
     959                 :             :         }
     960                 :           0 :         if (ret != 0) {
     961                 :             :             goto exit;
     962                 :             :         }
     963                 :             :     } else
     964                 :             : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     965                 :             :     {
     966                 :             :         (void) key_bits;
     967                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     968                 :             :     }
     969                 :             : 
     970                 :           0 : exit:
     971                 :           0 :     psa_reset_key_attributes(&key_attr);
     972                 :           0 :     mbedtls_platform_zeroize(exp_key, sizeof(exp_key));
     973                 :             : 
     974                 :           0 :     return ret;
     975                 :             : }
     976                 :             : 
     977                 :           0 : int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id,
     978                 :             :                              mbedtls_pk_context *pk)
     979                 :             : {
     980                 :           0 :     return copy_from_psa(key_id, pk, 0);
     981                 :             : }
     982                 :             : 
     983                 :           0 : int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id,
     984                 :             :                                     mbedtls_pk_context *pk)
     985                 :             : {
     986                 :           0 :     return copy_from_psa(key_id, pk, 1);
     987                 :             : }
     988                 :             : #endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
     989                 :             : 
     990                 :             : /*
     991                 :             :  * Helper for mbedtls_pk_sign and mbedtls_pk_verify
     992                 :             :  */
     993                 :           0 : static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len)
     994                 :             : {
     995         [ #  # ]:           0 :     if (*hash_len != 0) {
     996                 :             :         return 0;
     997                 :             :     }
     998                 :             : 
     999                 :           0 :     *hash_len = mbedtls_md_get_size_from_type(md_alg);
    1000                 :             : 
    1001         [ #  # ]:           0 :     if (*hash_len == 0) {
    1002                 :             :         return -1;
    1003                 :             :     }
    1004                 :             : 
    1005                 :             :     return 0;
    1006                 :             : }
    1007                 :             : 
    1008                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    1009                 :             : /*
    1010                 :             :  * Helper to set up a restart context if needed
    1011                 :             :  */
    1012                 :             : static int pk_restart_setup(mbedtls_pk_restart_ctx *ctx,
    1013                 :             :                             const mbedtls_pk_info_t *info)
    1014                 :             : {
    1015                 :             :     /* Don't do anything if already set up or invalid */
    1016                 :             :     if (ctx == NULL || ctx->pk_info != NULL) {
    1017                 :             :         return 0;
    1018                 :             :     }
    1019                 :             : 
    1020                 :             :     /* Should never happen when we're called */
    1021                 :             :     if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) {
    1022                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1023                 :             :     }
    1024                 :             : 
    1025                 :             :     if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) {
    1026                 :             :         return MBEDTLS_ERR_PK_ALLOC_FAILED;
    1027                 :             :     }
    1028                 :             : 
    1029                 :             :     ctx->pk_info = info;
    1030                 :             : 
    1031                 :             :     return 0;
    1032                 :             : }
    1033                 :             : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
    1034                 :             : 
    1035                 :             : /*
    1036                 :             :  * Verify a signature (restartable)
    1037                 :             :  */
    1038                 :           0 : int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx,
    1039                 :             :                                   mbedtls_md_type_t md_alg,
    1040                 :             :                                   const unsigned char *hash, size_t hash_len,
    1041                 :             :                                   const unsigned char *sig, size_t sig_len,
    1042                 :             :                                   mbedtls_pk_restart_ctx *rs_ctx)
    1043                 :             : {
    1044   [ #  #  #  # ]:           0 :     if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) {
    1045                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1046                 :             :     }
    1047                 :             : 
    1048   [ #  #  #  # ]:           0 :     if (ctx->pk_info == NULL ||
    1049                 :           0 :         pk_hashlen_helper(md_alg, &hash_len) != 0) {
    1050                 :           0 :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1051                 :             :     }
    1052                 :             : 
    1053                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    1054                 :             :     /* optimization: use non-restartable version if restart disabled */
    1055                 :             :     if (rs_ctx != NULL &&
    1056                 :             :         mbedtls_ecp_restart_is_enabled() &&
    1057                 :             :         ctx->pk_info->verify_rs_func != NULL) {
    1058                 :             :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1059                 :             : 
    1060                 :             :         if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
    1061                 :             :             return ret;
    1062                 :             :         }
    1063                 :             : 
    1064                 :             :         ret = ctx->pk_info->verify_rs_func(ctx,
    1065                 :             :                                            md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx);
    1066                 :             : 
    1067                 :             :         if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
    1068                 :             :             mbedtls_pk_restart_free(rs_ctx);
    1069                 :             :         }
    1070                 :             : 
    1071                 :             :         return ret;
    1072                 :             :     }
    1073                 :             : #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
    1074                 :           0 :     (void) rs_ctx;
    1075                 :             : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
    1076                 :             : 
    1077         [ #  # ]:           0 :     if (ctx->pk_info->verify_func == NULL) {
    1078                 :             :         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
    1079                 :             :     }
    1080                 :             : 
    1081                 :           0 :     return ctx->pk_info->verify_func(ctx, md_alg, hash, hash_len,
    1082                 :             :                                      sig, sig_len);
    1083                 :             : }
    1084                 :             : 
    1085                 :             : /*
    1086                 :             :  * Verify a signature
    1087                 :             :  */
    1088                 :           0 : int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
    1089                 :             :                       const unsigned char *hash, size_t hash_len,
    1090                 :             :                       const unsigned char *sig, size_t sig_len)
    1091                 :             : {
    1092                 :           0 :     return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len,
    1093                 :             :                                          sig, sig_len, NULL);
    1094                 :             : }
    1095                 :             : 
    1096                 :             : /*
    1097                 :             :  * Verify a signature with options
    1098                 :             :  */
    1099                 :           0 : int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
    1100                 :             :                           mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
    1101                 :             :                           const unsigned char *hash, size_t hash_len,
    1102                 :             :                           const unsigned char *sig, size_t sig_len)
    1103                 :             : {
    1104   [ #  #  #  # ]:           0 :     if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) {
    1105                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1106                 :             :     }
    1107                 :             : 
    1108         [ #  # ]:           0 :     if (ctx->pk_info == NULL) {
    1109                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1110                 :             :     }
    1111                 :             : 
    1112         [ #  # ]:           0 :     if (!mbedtls_pk_can_do(ctx, type)) {
    1113                 :             :         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
    1114                 :             :     }
    1115                 :             : 
    1116         [ #  # ]:           0 :     if (type != MBEDTLS_PK_RSASSA_PSS) {
    1117                 :             :         /* General case: no options */
    1118         [ #  # ]:           0 :         if (options != NULL) {
    1119                 :             :             return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1120                 :             :         }
    1121                 :             : 
    1122                 :           0 :         return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len);
    1123                 :             :     }
    1124                 :             : 
    1125                 :             :     /* Ensure the PK context is of the right type otherwise mbedtls_pk_rsa()
    1126                 :             :      * below would return a NULL pointer. */
    1127                 :             :     if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_RSA) {
    1128                 :             :         return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
    1129                 :             :     }
    1130                 :             : 
    1131                 :             : #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
    1132                 :             :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1133                 :             :     const mbedtls_pk_rsassa_pss_options *pss_opts;
    1134                 :             : 
    1135                 :             : #if SIZE_MAX > UINT_MAX
    1136                 :             :     if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
    1137                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1138                 :             :     }
    1139                 :             : #endif
    1140                 :             : 
    1141                 :             :     if (options == NULL) {
    1142                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1143                 :             :     }
    1144                 :             : 
    1145                 :             :     pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
    1146                 :             : 
    1147                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO)
    1148                 :             :     if (pss_opts->mgf1_hash_id == md_alg) {
    1149                 :             :         unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
    1150                 :             :         unsigned char *p;
    1151                 :             :         int key_len;
    1152                 :             :         size_t signature_length;
    1153                 :             :         psa_status_t status = PSA_ERROR_DATA_CORRUPT;
    1154                 :             :         psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT;
    1155                 :             : 
    1156                 :             :         psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
    1157                 :             :         mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
    1158                 :             :         psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    1159                 :             :         psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg);
    1160                 :             :         p = buf + sizeof(buf);
    1161                 :             :         key_len = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*ctx), buf, &p);
    1162                 :             : 
    1163                 :             :         if (key_len < 0) {
    1164                 :             :             return key_len;
    1165                 :             :         }
    1166                 :             : 
    1167                 :             :         psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
    1168                 :             :         psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
    1169                 :             :         psa_set_key_algorithm(&attributes, psa_sig_alg);
    1170                 :             : 
    1171                 :             :         status = psa_import_key(&attributes,
    1172                 :             :                                 buf + sizeof(buf) - key_len, key_len,
    1173                 :             :                                 &key_id);
    1174                 :             :         if (status != PSA_SUCCESS) {
    1175                 :             :             psa_destroy_key(key_id);
    1176                 :             :             return PSA_PK_TO_MBEDTLS_ERR(status);
    1177                 :             :         }
    1178                 :             : 
    1179                 :             :         /* This function requires returning MBEDTLS_ERR_PK_SIG_LEN_MISMATCH
    1180                 :             :          * on a valid signature with trailing data in a buffer, but
    1181                 :             :          * mbedtls_psa_rsa_verify_hash requires the sig_len to be exact,
    1182                 :             :          * so for this reason the passed sig_len is overwritten. Smaller
    1183                 :             :          * signature lengths should not be accepted for verification. */
    1184                 :             :         signature_length = sig_len > mbedtls_pk_get_len(ctx) ?
    1185                 :             :                            mbedtls_pk_get_len(ctx) : sig_len;
    1186                 :             :         status = psa_verify_hash(key_id, psa_sig_alg, hash,
    1187                 :             :                                  hash_len, sig, signature_length);
    1188                 :             :         destruction_status = psa_destroy_key(key_id);
    1189                 :             : 
    1190                 :             :         if (status == PSA_SUCCESS && sig_len > mbedtls_pk_get_len(ctx)) {
    1191                 :             :             return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
    1192                 :             :         }
    1193                 :             : 
    1194                 :             :         if (status == PSA_SUCCESS) {
    1195                 :             :             status = destruction_status;
    1196                 :             :         }
    1197                 :             : 
    1198                 :             :         return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
    1199                 :             :     } else
    1200                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
    1201                 :             :     {
    1202                 :             :         if (sig_len < mbedtls_pk_get_len(ctx)) {
    1203                 :             :             return MBEDTLS_ERR_RSA_VERIFY_FAILED;
    1204                 :             :         }
    1205                 :             : 
    1206                 :             :         ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx),
    1207                 :             :                                                 md_alg, (unsigned int) hash_len, hash,
    1208                 :             :                                                 pss_opts->mgf1_hash_id,
    1209                 :             :                                                 pss_opts->expected_salt_len,
    1210                 :             :                                                 sig);
    1211                 :             :         if (ret != 0) {
    1212                 :             :             return ret;
    1213                 :             :         }
    1214                 :             : 
    1215                 :             :         if (sig_len > mbedtls_pk_get_len(ctx)) {
    1216                 :             :             return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
    1217                 :             :         }
    1218                 :             : 
    1219                 :             :         return 0;
    1220                 :             :     }
    1221                 :             : #else
    1222                 :             :     return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
    1223                 :             : #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
    1224                 :             : }
    1225                 :             : 
    1226                 :             : /*
    1227                 :             :  * Make a signature (restartable)
    1228                 :             :  */
    1229                 :           0 : int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
    1230                 :             :                                 mbedtls_md_type_t md_alg,
    1231                 :             :                                 const unsigned char *hash, size_t hash_len,
    1232                 :             :                                 unsigned char *sig, size_t sig_size, size_t *sig_len,
    1233                 :             :                                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
    1234                 :             :                                 mbedtls_pk_restart_ctx *rs_ctx)
    1235                 :             : {
    1236   [ #  #  #  # ]:           0 :     if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) {
    1237                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1238                 :             :     }
    1239                 :             : 
    1240   [ #  #  #  # ]:           0 :     if (ctx->pk_info == NULL || pk_hashlen_helper(md_alg, &hash_len) != 0) {
    1241                 :           0 :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1242                 :             :     }
    1243                 :             : 
    1244                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    1245                 :             :     /* optimization: use non-restartable version if restart disabled */
    1246                 :             :     if (rs_ctx != NULL &&
    1247                 :             :         mbedtls_ecp_restart_is_enabled() &&
    1248                 :             :         ctx->pk_info->sign_rs_func != NULL) {
    1249                 :             :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1250                 :             : 
    1251                 :             :         if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
    1252                 :             :             return ret;
    1253                 :             :         }
    1254                 :             : 
    1255                 :             :         ret = ctx->pk_info->sign_rs_func(ctx, md_alg,
    1256                 :             :                                          hash, hash_len,
    1257                 :             :                                          sig, sig_size, sig_len,
    1258                 :             :                                          f_rng, p_rng, rs_ctx->rs_ctx);
    1259                 :             : 
    1260                 :             :         if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
    1261                 :             :             mbedtls_pk_restart_free(rs_ctx);
    1262                 :             :         }
    1263                 :             : 
    1264                 :             :         return ret;
    1265                 :             :     }
    1266                 :             : #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
    1267                 :           0 :     (void) rs_ctx;
    1268                 :             : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
    1269                 :             : 
    1270         [ #  # ]:           0 :     if (ctx->pk_info->sign_func == NULL) {
    1271                 :             :         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
    1272                 :             :     }
    1273                 :             : 
    1274                 :           0 :     return ctx->pk_info->sign_func(ctx, md_alg,
    1275                 :             :                                    hash, hash_len,
    1276                 :             :                                    sig, sig_size, sig_len,
    1277                 :             :                                    f_rng, p_rng);
    1278                 :             : }
    1279                 :             : 
    1280                 :             : /*
    1281                 :             :  * Make a signature
    1282                 :             :  */
    1283                 :           0 : int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
    1284                 :             :                     const unsigned char *hash, size_t hash_len,
    1285                 :             :                     unsigned char *sig, size_t sig_size, size_t *sig_len,
    1286                 :             :                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
    1287                 :             : {
    1288                 :           0 :     return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len,
    1289                 :             :                                        sig, sig_size, sig_len,
    1290                 :             :                                        f_rng, p_rng, NULL);
    1291                 :             : }
    1292                 :             : 
    1293                 :             : /*
    1294                 :             :  * Make a signature given a signature type.
    1295                 :             :  */
    1296                 :           0 : int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
    1297                 :             :                         mbedtls_pk_context *ctx,
    1298                 :             :                         mbedtls_md_type_t md_alg,
    1299                 :             :                         const unsigned char *hash, size_t hash_len,
    1300                 :             :                         unsigned char *sig, size_t sig_size, size_t *sig_len,
    1301                 :             :                         int (*f_rng)(void *, unsigned char *, size_t),
    1302                 :             :                         void *p_rng)
    1303                 :             : {
    1304         [ #  # ]:           0 :     if (ctx->pk_info == NULL) {
    1305                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1306                 :             :     }
    1307                 :             : 
    1308         [ #  # ]:           0 :     if (!mbedtls_pk_can_do(ctx, pk_type)) {
    1309                 :             :         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
    1310                 :             :     }
    1311                 :             : 
    1312         [ #  # ]:           0 :     if (pk_type != MBEDTLS_PK_RSASSA_PSS) {
    1313                 :           0 :         return mbedtls_pk_sign(ctx, md_alg, hash, hash_len,
    1314                 :             :                                sig, sig_size, sig_len, f_rng, p_rng);
    1315                 :             :     }
    1316                 :             : 
    1317                 :             : #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
    1318                 :             : 
    1319                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO)
    1320                 :             :     const psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
    1321                 :             :     if (psa_md_alg == 0) {
    1322                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1323                 :             :     }
    1324                 :             : 
    1325                 :             :     if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
    1326                 :             :         psa_status_t status;
    1327                 :             : 
    1328                 :             :         /* PSA_ALG_RSA_PSS() behaves the same as PSA_ALG_RSA_PSS_ANY_SALT() when
    1329                 :             :          * performing a signature, but they are encoded differently. Instead of
    1330                 :             :          * extracting the proper one from the wrapped key policy, just try both. */
    1331                 :             :         status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg),
    1332                 :             :                                hash, hash_len,
    1333                 :             :                                sig, sig_size, sig_len);
    1334                 :             :         if (status == PSA_ERROR_NOT_PERMITTED) {
    1335                 :             :             status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg),
    1336                 :             :                                    hash, hash_len,
    1337                 :             :                                    sig, sig_size, sig_len);
    1338                 :             :         }
    1339                 :             :         return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
    1340                 :             :     }
    1341                 :             : 
    1342                 :             :     return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PSS(psa_md_alg),
    1343                 :             :                                        ctx->pk_ctx, hash, hash_len,
    1344                 :             :                                        sig, sig_size, sig_len);
    1345                 :             : #else /* MBEDTLS_USE_PSA_CRYPTO */
    1346                 :             : 
    1347                 :             :     if (sig_size < mbedtls_pk_get_len(ctx)) {
    1348                 :             :         return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
    1349                 :             :     }
    1350                 :             : 
    1351                 :             :     if (pk_hashlen_helper(md_alg, &hash_len) != 0) {
    1352                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1353                 :             :     }
    1354                 :             : 
    1355                 :             :     mbedtls_rsa_context *const rsa_ctx = mbedtls_pk_rsa(*ctx);
    1356                 :             : 
    1357                 :             :     const int ret = mbedtls_rsa_rsassa_pss_sign_no_mode_check(rsa_ctx, f_rng, p_rng, md_alg,
    1358                 :             :                                                               (unsigned int) hash_len, hash, sig);
    1359                 :             :     if (ret == 0) {
    1360                 :             :         *sig_len = rsa_ctx->len;
    1361                 :             :     }
    1362                 :             :     return ret;
    1363                 :             : 
    1364                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
    1365                 :             : 
    1366                 :             : #else
    1367                 :             :     return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
    1368                 :             : #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
    1369                 :             : }
    1370                 :             : 
    1371                 :             : /*
    1372                 :             :  * Decrypt message
    1373                 :             :  */
    1374                 :           0 : int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
    1375                 :             :                        const unsigned char *input, size_t ilen,
    1376                 :             :                        unsigned char *output, size_t *olen, size_t osize,
    1377                 :             :                        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
    1378                 :             : {
    1379         [ #  # ]:           0 :     if (ctx->pk_info == NULL) {
    1380                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1381                 :             :     }
    1382                 :             : 
    1383         [ #  # ]:           0 :     if (ctx->pk_info->decrypt_func == NULL) {
    1384                 :             :         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
    1385                 :             :     }
    1386                 :             : 
    1387                 :           0 :     return ctx->pk_info->decrypt_func(ctx, input, ilen,
    1388                 :             :                                       output, olen, osize, f_rng, p_rng);
    1389                 :             : }
    1390                 :             : 
    1391                 :             : /*
    1392                 :             :  * Encrypt message
    1393                 :             :  */
    1394                 :           0 : int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
    1395                 :             :                        const unsigned char *input, size_t ilen,
    1396                 :             :                        unsigned char *output, size_t *olen, size_t osize,
    1397                 :             :                        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
    1398                 :             : {
    1399         [ #  # ]:           0 :     if (ctx->pk_info == NULL) {
    1400                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1401                 :             :     }
    1402                 :             : 
    1403         [ #  # ]:           0 :     if (ctx->pk_info->encrypt_func == NULL) {
    1404                 :             :         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
    1405                 :             :     }
    1406                 :             : 
    1407                 :           0 :     return ctx->pk_info->encrypt_func(ctx, input, ilen,
    1408                 :             :                                       output, olen, osize, f_rng, p_rng);
    1409                 :             : }
    1410                 :             : 
    1411                 :             : /*
    1412                 :             :  * Check public-private key pair
    1413                 :             :  */
    1414                 :           0 : int mbedtls_pk_check_pair(const mbedtls_pk_context *pub,
    1415                 :             :                           const mbedtls_pk_context *prv,
    1416                 :             :                           int (*f_rng)(void *, unsigned char *, size_t),
    1417                 :             :                           void *p_rng)
    1418                 :             : {
    1419         [ #  # ]:           0 :     if (pub->pk_info == NULL ||
    1420         [ #  # ]:           0 :         prv->pk_info == NULL) {
    1421                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1422                 :             :     }
    1423                 :             : 
    1424         [ #  # ]:           0 :     if (f_rng == NULL) {
    1425                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1426                 :             :     }
    1427                 :             : 
    1428         [ #  # ]:           0 :     if (prv->pk_info->check_pair_func == NULL) {
    1429                 :             :         return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
    1430                 :             :     }
    1431                 :             : 
    1432         [ #  # ]:           0 :     if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) {
    1433         [ #  # ]:           0 :         if (pub->pk_info->type != MBEDTLS_PK_RSA) {
    1434                 :             :             return MBEDTLS_ERR_PK_TYPE_MISMATCH;
    1435                 :             :         }
    1436                 :             :     } else {
    1437   [ #  #  #  # ]:           0 :         if ((prv->pk_info->type != MBEDTLS_PK_OPAQUE) &&
    1438                 :             :             (pub->pk_info != prv->pk_info)) {
    1439                 :             :             return MBEDTLS_ERR_PK_TYPE_MISMATCH;
    1440                 :             :         }
    1441                 :             :     }
    1442                 :             : 
    1443                 :           0 :     return prv->pk_info->check_pair_func((mbedtls_pk_context *) pub,
    1444                 :             :                                          (mbedtls_pk_context *) prv,
    1445                 :             :                                          f_rng, p_rng);
    1446                 :             : }
    1447                 :             : 
    1448                 :             : /*
    1449                 :             :  * Get key size in bits
    1450                 :             :  */
    1451                 :           0 : size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx)
    1452                 :             : {
    1453                 :             :     /* For backward compatibility, accept NULL or a context that
    1454                 :             :      * isn't set up yet, and return a fake value that should be safe. */
    1455   [ #  #  #  # ]:           0 :     if (ctx == NULL || ctx->pk_info == NULL) {
    1456                 :             :         return 0;
    1457                 :             :     }
    1458                 :             : 
    1459                 :           0 :     return ctx->pk_info->get_bitlen((mbedtls_pk_context *) ctx);
    1460                 :             : }
    1461                 :             : 
    1462                 :             : /*
    1463                 :             :  * Export debug information
    1464                 :             :  */
    1465                 :           0 : int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items)
    1466                 :             : {
    1467         [ #  # ]:           0 :     if (ctx->pk_info == NULL) {
    1468                 :             :         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    1469                 :             :     }
    1470                 :             : 
    1471         [ #  # ]:           0 :     if (ctx->pk_info->debug_func == NULL) {
    1472                 :             :         return MBEDTLS_ERR_PK_TYPE_MISMATCH;
    1473                 :             :     }
    1474                 :             : 
    1475                 :           0 :     ctx->pk_info->debug_func((mbedtls_pk_context *) ctx, items);
    1476                 :           0 :     return 0;
    1477                 :             : }
    1478                 :             : 
    1479                 :             : /*
    1480                 :             :  * Access the PK type name
    1481                 :             :  */
    1482                 :           0 : const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx)
    1483                 :             : {
    1484   [ #  #  #  # ]:           0 :     if (ctx == NULL || ctx->pk_info == NULL) {
    1485                 :             :         return "invalid PK";
    1486                 :             :     }
    1487                 :             : 
    1488                 :           0 :     return ctx->pk_info->name;
    1489                 :             : }
    1490                 :             : 
    1491                 :             : /*
    1492                 :             :  * Access the PK type
    1493                 :             :  */
    1494                 :           8 : mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx)
    1495                 :             : {
    1496   [ +  -  +  - ]:           8 :     if (ctx == NULL || ctx->pk_info == NULL) {
    1497                 :             :         return MBEDTLS_PK_NONE;
    1498                 :             :     }
    1499                 :             : 
    1500                 :           8 :     return ctx->pk_info->type;
    1501                 :             : }
    1502                 :             : 
    1503                 :             : #endif /* MBEDTLS_PK_C */
        

Generated by: LCOV version 2.0-1