LCOV - code coverage report
Current view: top level - externals/mbedtls/library - psa_crypto_ecp.c (source / functions) Coverage Total Hit
Test: lcov.info Lines: 66.7 % 219 146
Test Date: 2026-03-12 12:01:18 Functions: 80.0 % 10 8
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 42.3 % 111 47

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  *  PSA ECP layer on top of Mbed TLS crypto
       3                 :             :  */
       4                 :             : /*
       5                 :             :  *  Copyright The Mbed TLS Contributors
       6                 :             :  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       7                 :             :  */
       8                 :             : 
       9                 :             : #include "common.h"
      10                 :             : 
      11                 :             : #if defined(MBEDTLS_PSA_CRYPTO_C)
      12                 :             : 
      13                 :             : #include <psa/crypto.h>
      14                 :             : #include "psa_crypto_core.h"
      15                 :             : #include "psa_crypto_ecp.h"
      16                 :             : #include "psa_crypto_random_impl.h"
      17                 :             : #include "mbedtls/psa_util.h"
      18                 :             : 
      19                 :             : #include <stdlib.h>
      20                 :             : #include <string.h>
      21                 :             : #include "mbedtls/platform.h"
      22                 :             : 
      23                 :             : #include <mbedtls/ecdsa.h>
      24                 :             : #include <mbedtls/ecdh.h>
      25                 :             : #include <mbedtls/ecp.h>
      26                 :             : #include <mbedtls/error.h>
      27                 :             : 
      28                 :             : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
      29                 :             :     defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
      30                 :             :     defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
      31                 :             :     defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
      32                 :             :     defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
      33                 :             :     defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \
      34                 :             :     defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
      35                 :             : /* Helper function to verify if the provided EC's family and key bit size are valid.
      36                 :             :  *
      37                 :             :  * Note: "bits" parameter is used both as input and output and it might be updated
      38                 :             :  *       in case provided input value is not multiple of 8 ("sloppy" bits).
      39                 :             :  */
      40                 :          32 : static int check_ecc_parameters(psa_ecc_family_t family, size_t *bits)
      41                 :             : {
      42   [ +  -  -  -  :          32 :     switch (family) {
                      - ]
      43                 :          32 :         case PSA_ECC_FAMILY_SECP_R1:
      44      [ +  -  - ]:          32 :             switch (*bits) {
      45                 :             :                 case 192:
      46                 :             :                 case 224:
      47                 :             :                 case 256:
      48                 :             :                 case 384:
      49                 :             :                 case 521:
      50                 :             :                     return PSA_SUCCESS;
      51                 :           0 :                 case 528:
      52                 :           0 :                     *bits = 521;
      53                 :           0 :                     return PSA_SUCCESS;
      54                 :             :             }
      55                 :             :             break;
      56                 :             : 
      57                 :           0 :         case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
      58         [ #  # ]:           0 :             switch (*bits) {
      59                 :             :                 case 256:
      60                 :             :                 case 384:
      61                 :             :                 case 512:
      62                 :             :                     return PSA_SUCCESS;
      63                 :             :             }
      64                 :             :             break;
      65                 :             : 
      66                 :           0 :         case PSA_ECC_FAMILY_MONTGOMERY:
      67      [ #  #  # ]:           0 :             switch (*bits) {
      68                 :             :                 case 448:
      69                 :             :                 case 255:
      70                 :             :                     return PSA_SUCCESS;
      71                 :           0 :                 case 256:
      72                 :           0 :                     *bits = 255;
      73                 :           0 :                     return PSA_SUCCESS;
      74                 :             :             }
      75                 :             :             break;
      76                 :             : 
      77                 :           0 :         case PSA_ECC_FAMILY_SECP_K1:
      78         [ #  # ]:           0 :             switch (*bits) {
      79                 :             :                 case 192:
      80                 :             :                 /* secp224k1 is not and will not be supported in PSA (#3541). */
      81                 :             :                 case 256:
      82                 :             :                     return PSA_SUCCESS;
      83                 :             :             }
      84                 :             :             break;
      85                 :             :     }
      86                 :             : 
      87                 :             :     return PSA_ERROR_INVALID_ARGUMENT;
      88                 :             : }
      89                 :             : 
      90                 :          32 : psa_status_t mbedtls_psa_ecp_load_representation(
      91                 :             :     psa_key_type_t type, size_t curve_bits,
      92                 :             :     const uint8_t *data, size_t data_length,
      93                 :             :     mbedtls_ecp_keypair **p_ecp)
      94                 :             : {
      95                 :          32 :     mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
      96                 :          32 :     psa_status_t status;
      97                 :          32 :     mbedtls_ecp_keypair *ecp = NULL;
      98                 :          32 :     size_t curve_bytes = data_length;
      99                 :          32 :     int explicit_bits = (curve_bits != 0);
     100                 :             : 
     101         [ +  + ]:          32 :     if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) &&
     102   [ +  -  +  - ]:          16 :         PSA_KEY_TYPE_ECC_GET_FAMILY(type) != PSA_ECC_FAMILY_MONTGOMERY) {
     103                 :             :         /* A Weierstrass public key is represented as:
     104                 :             :          * - The byte 0x04;
     105                 :             :          * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
     106                 :             :          * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
     107                 :             :          * So its data length is 2m+1 where m is the curve size in bits.
     108                 :             :          */
     109         [ +  - ]:          16 :         if ((data_length & 1) == 0) {
     110                 :             :             return PSA_ERROR_INVALID_ARGUMENT;
     111                 :             :         }
     112                 :          16 :         curve_bytes = data_length / 2;
     113                 :             : 
     114                 :             :         /* Montgomery public keys are represented in compressed format, meaning
     115                 :             :          * their curve_bytes is equal to the amount of input. */
     116                 :             : 
     117                 :             :         /* Private keys are represented in uncompressed private random integer
     118                 :             :          * format, meaning their curve_bytes is equal to the amount of input. */
     119                 :             :     }
     120                 :             : 
     121         [ +  + ]:          32 :     if (explicit_bits) {
     122                 :             :         /* With an explicit bit-size, the data must have the matching length. */
     123         [ +  - ]:          28 :         if (curve_bytes != PSA_BITS_TO_BYTES(curve_bits)) {
     124                 :             :             return PSA_ERROR_INVALID_ARGUMENT;
     125                 :             :         }
     126                 :             :     } else {
     127                 :             :         /* We need to infer the bit-size from the data. Since the only
     128                 :             :          * information we have is the length in bytes, the value of curve_bits
     129                 :             :          * at this stage is rounded up to the nearest multiple of 8. */
     130                 :           4 :         curve_bits = PSA_BYTES_TO_BITS(curve_bytes);
     131                 :             :     }
     132                 :             : 
     133                 :             :     /* Allocate and initialize a key representation. */
     134                 :          32 :     ecp = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
     135         [ +  - ]:          32 :     if (ecp == NULL) {
     136                 :             :         return PSA_ERROR_INSUFFICIENT_MEMORY;
     137                 :             :     }
     138                 :          32 :     mbedtls_ecp_keypair_init(ecp);
     139                 :             : 
     140         [ +  - ]:          32 :     status = check_ecc_parameters(PSA_KEY_TYPE_ECC_GET_FAMILY(type), &curve_bits);
     141         [ -  + ]:          32 :     if (status != PSA_SUCCESS) {
     142                 :           0 :         goto exit;
     143                 :             :     }
     144                 :             : 
     145                 :             :     /* Load the group. */
     146                 :          32 :     grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type),
     147                 :             :                                         curve_bits);
     148         [ -  + ]:          32 :     if (grp_id == MBEDTLS_ECP_DP_NONE) {
     149                 :           0 :         status = PSA_ERROR_NOT_SUPPORTED;
     150                 :           0 :         goto exit;
     151                 :             :     }
     152                 :             : 
     153                 :          32 :     status = mbedtls_to_psa_error(
     154                 :             :         mbedtls_ecp_group_load(&ecp->grp, grp_id));
     155         [ -  + ]:          32 :     if (status != PSA_SUCCESS) {
     156                 :           0 :         goto exit;
     157                 :             :     }
     158                 :             : 
     159                 :             :     /* Load the key material. */
     160         [ +  + ]:          32 :     if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
     161                 :             :         /* Load the public value. */
     162                 :          16 :         status = mbedtls_to_psa_error(
     163                 :             :             mbedtls_ecp_point_read_binary(&ecp->grp, &ecp->Q,
     164                 :             :                                           data,
     165                 :             :                                           data_length));
     166         [ -  + ]:          16 :         if (status != PSA_SUCCESS) {
     167                 :           0 :             goto exit;
     168                 :             :         }
     169                 :             : 
     170                 :             :         /* Check that the point is on the curve. */
     171                 :          16 :         status = mbedtls_to_psa_error(
     172                 :             :             mbedtls_ecp_check_pubkey(&ecp->grp, &ecp->Q));
     173         [ -  + ]:          16 :         if (status != PSA_SUCCESS) {
     174                 :           0 :             goto exit;
     175                 :             :         }
     176                 :             :     } else {
     177                 :             :         /* Load and validate the secret value. */
     178                 :          16 :         status = mbedtls_to_psa_error(
     179                 :             :             mbedtls_ecp_read_key(ecp->grp.id,
     180                 :             :                                  ecp,
     181                 :             :                                  data,
     182                 :             :                                  data_length));
     183         [ -  + ]:          16 :         if (status != PSA_SUCCESS) {
     184                 :           0 :             goto exit;
     185                 :             :         }
     186                 :             :     }
     187                 :             : 
     188                 :          32 :     *p_ecp = ecp;
     189                 :             : exit:
     190                 :          32 :     if (status != PSA_SUCCESS) {
     191                 :           0 :         mbedtls_ecp_keypair_free(ecp);
     192                 :           0 :         mbedtls_free(ecp);
     193                 :             :     }
     194                 :             : 
     195                 :             :     return status;
     196                 :             : }
     197                 :             : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) ||
     198                 :             :         * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) ||
     199                 :             :         * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) ||
     200                 :             :         * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
     201                 :             :         * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
     202                 :             :         * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) ||
     203                 :             :         * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) */
     204                 :             : 
     205                 :             : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
     206                 :             :     defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
     207                 :             :     defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
     208                 :             : 
     209                 :          14 : psa_status_t mbedtls_psa_ecp_import_key(
     210                 :             :     const psa_key_attributes_t *attributes,
     211                 :             :     const uint8_t *data, size_t data_length,
     212                 :             :     uint8_t *key_buffer, size_t key_buffer_size,
     213                 :             :     size_t *key_buffer_length, size_t *bits)
     214                 :             : {
     215                 :          14 :     psa_status_t status;
     216                 :          14 :     mbedtls_ecp_keypair *ecp = NULL;
     217                 :             : 
     218                 :             :     /* Parse input */
     219                 :          28 :     status = mbedtls_psa_ecp_load_representation(attributes->type,
     220                 :          14 :                                                  attributes->bits,
     221                 :             :                                                  data,
     222                 :             :                                                  data_length,
     223                 :             :                                                  &ecp);
     224         [ -  + ]:          14 :     if (status != PSA_SUCCESS) {
     225                 :           0 :         goto exit;
     226                 :             :     }
     227                 :             : 
     228   [ +  -  -  + ]:          14 :     if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type) ==
     229                 :             :         PSA_ECC_FAMILY_MONTGOMERY) {
     230                 :           0 :         *bits = ecp->grp.nbits + 1;
     231                 :             :     } else {
     232                 :          14 :         *bits = ecp->grp.nbits;
     233                 :             :     }
     234                 :             : 
     235                 :             :     /* Re-export the data to PSA export format. There is currently no support
     236                 :             :      * for other input formats then the export format, so this is a 1-1
     237                 :             :      * copy operation. */
     238                 :          14 :     status = mbedtls_psa_ecp_export_key(attributes->type,
     239                 :             :                                         ecp,
     240                 :             :                                         key_buffer,
     241                 :             :                                         key_buffer_size,
     242                 :             :                                         key_buffer_length);
     243                 :          14 : exit:
     244                 :             :     /* Always free the PK object (will also free contained ECP context) */
     245                 :          14 :     mbedtls_ecp_keypair_free(ecp);
     246                 :          14 :     mbedtls_free(ecp);
     247                 :             : 
     248                 :          14 :     return status;
     249                 :             : }
     250                 :             : 
     251                 :          14 : psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type,
     252                 :             :                                         mbedtls_ecp_keypair *ecp,
     253                 :             :                                         uint8_t *data,
     254                 :             :                                         size_t data_size,
     255                 :             :                                         size_t *data_length)
     256                 :             : {
     257                 :          14 :     psa_status_t status;
     258                 :             : 
     259         [ +  + ]:          14 :     if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
     260                 :             :         /* Check whether the public part is loaded */
     261         [ -  + ]:           6 :         if (mbedtls_ecp_is_zero(&ecp->Q)) {
     262                 :             :             /* Calculate the public key */
     263                 :           0 :             status = mbedtls_to_psa_error(
     264                 :           0 :                 mbedtls_ecp_mul(&ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
     265                 :             :                                 mbedtls_psa_get_random,
     266                 :             :                                 MBEDTLS_PSA_RANDOM_STATE));
     267         [ #  # ]:           0 :             if (status != PSA_SUCCESS) {
     268                 :             :                 return status;
     269                 :             :             }
     270                 :             :         }
     271                 :             : 
     272                 :           6 :         status = mbedtls_to_psa_error(
     273                 :           6 :             mbedtls_ecp_point_write_binary(&ecp->grp, &ecp->Q,
     274                 :             :                                            MBEDTLS_ECP_PF_UNCOMPRESSED,
     275                 :             :                                            data_length,
     276                 :             :                                            data,
     277                 :             :                                            data_size));
     278         [ -  + ]:           6 :         if (status != PSA_SUCCESS) {
     279                 :           0 :             memset(data, 0, data_size);
     280                 :             :         }
     281                 :             : 
     282                 :           6 :         return status;
     283                 :             :     } else {
     284                 :           8 :         status = mbedtls_to_psa_error(
     285                 :             :             mbedtls_ecp_write_key_ext(ecp, data_length, data, data_size));
     286                 :           8 :         return status;
     287                 :             :     }
     288                 :             : }
     289                 :             : 
     290                 :           0 : psa_status_t mbedtls_psa_ecp_export_public_key(
     291                 :             :     const psa_key_attributes_t *attributes,
     292                 :             :     const uint8_t *key_buffer, size_t key_buffer_size,
     293                 :             :     uint8_t *data, size_t data_size, size_t *data_length)
     294                 :             : {
     295                 :           0 :     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     296                 :           0 :     mbedtls_ecp_keypair *ecp = NULL;
     297                 :             : 
     298                 :           0 :     status = mbedtls_psa_ecp_load_representation(
     299                 :           0 :         attributes->type, attributes->bits,
     300                 :             :         key_buffer, key_buffer_size, &ecp);
     301         [ #  # ]:           0 :     if (status != PSA_SUCCESS) {
     302                 :             :         return status;
     303                 :             :     }
     304                 :             : 
     305                 :           0 :     status = mbedtls_psa_ecp_export_key(
     306         [ #  # ]:           0 :         PSA_KEY_TYPE_ECC_PUBLIC_KEY(
     307                 :             :             PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)),
     308                 :             :         ecp, data, data_size, data_length);
     309                 :             : 
     310                 :           0 :     mbedtls_ecp_keypair_free(ecp);
     311                 :           0 :     mbedtls_free(ecp);
     312                 :             : 
     313                 :           0 :     return status;
     314                 :             : }
     315                 :             : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) ||
     316                 :             :         * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) ||
     317                 :             :         * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
     318                 :             : 
     319                 :             : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
     320                 :           0 : psa_status_t mbedtls_psa_ecp_generate_key(
     321                 :             :     const psa_key_attributes_t *attributes,
     322                 :             :     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
     323                 :             : {
     324         [ #  # ]:           0 :     psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
     325                 :             :         attributes->type);
     326                 :           0 :     mbedtls_ecp_group_id grp_id =
     327                 :           0 :         mbedtls_ecc_group_from_psa(curve, attributes->bits);
     328         [ #  # ]:           0 :     if (grp_id == MBEDTLS_ECP_DP_NONE) {
     329                 :             :         return PSA_ERROR_NOT_SUPPORTED;
     330                 :             :     }
     331                 :             : 
     332                 :           0 :     mbedtls_ecp_keypair ecp;
     333                 :           0 :     mbedtls_ecp_keypair_init(&ecp);
     334                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     335                 :             : 
     336                 :           0 :     ret = mbedtls_ecp_group_load(&ecp.grp, grp_id);
     337         [ #  # ]:           0 :     if (ret != 0) {
     338                 :           0 :         goto exit;
     339                 :             :     }
     340                 :             : 
     341                 :           0 :     ret = mbedtls_ecp_gen_privkey(&ecp.grp, &ecp.d,
     342                 :             :                                   mbedtls_psa_get_random,
     343                 :             :                                   MBEDTLS_PSA_RANDOM_STATE);
     344         [ #  # ]:           0 :     if (ret != 0) {
     345                 :           0 :         goto exit;
     346                 :             :     }
     347                 :             : 
     348                 :           0 :     ret = mbedtls_ecp_write_key_ext(&ecp, key_buffer_length,
     349                 :             :                                     key_buffer, key_buffer_size);
     350                 :             : 
     351                 :           0 : exit:
     352                 :           0 :     mbedtls_ecp_keypair_free(&ecp);
     353                 :           0 :     return mbedtls_to_psa_error(ret);
     354                 :             : }
     355                 :             : #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE */
     356                 :             : 
     357                 :             : /****************************************************************/
     358                 :             : /* ECDSA sign/verify */
     359                 :             : /****************************************************************/
     360                 :             : 
     361                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
     362                 :             :     defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
     363                 :           4 : psa_status_t mbedtls_psa_ecdsa_sign_hash(
     364                 :             :     const psa_key_attributes_t *attributes,
     365                 :             :     const uint8_t *key_buffer, size_t key_buffer_size,
     366                 :             :     psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
     367                 :             :     uint8_t *signature, size_t signature_size, size_t *signature_length)
     368                 :             : {
     369                 :           4 :     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     370                 :           4 :     mbedtls_ecp_keypair *ecp = NULL;
     371                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     372                 :           4 :     size_t curve_bytes;
     373                 :           4 :     mbedtls_mpi r, s;
     374                 :             : 
     375                 :           8 :     status = mbedtls_psa_ecp_load_representation(attributes->type,
     376                 :           4 :                                                  attributes->bits,
     377                 :             :                                                  key_buffer,
     378                 :             :                                                  key_buffer_size,
     379                 :             :                                                  &ecp);
     380         [ +  - ]:           4 :     if (status != PSA_SUCCESS) {
     381                 :             :         return status;
     382                 :             :     }
     383                 :             : 
     384                 :           4 :     curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits);
     385                 :           4 :     mbedtls_mpi_init(&r);
     386                 :           4 :     mbedtls_mpi_init(&s);
     387                 :             : 
     388         [ -  + ]:           4 :     if (signature_size < 2 * curve_bytes) {
     389                 :           0 :         ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
     390                 :           0 :         goto cleanup;
     391                 :             :     }
     392                 :             : 
     393         [ -  + ]:           4 :     if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) {
     394                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
     395                 :             :         psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
     396                 :             :         mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
     397                 :             :         MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_ext(
     398                 :             :                             &ecp->grp, &r, &s,
     399                 :             :                             &ecp->d, hash,
     400                 :             :                             hash_length, md_alg,
     401                 :             :                             mbedtls_psa_get_random,
     402                 :             :                             MBEDTLS_PSA_RANDOM_STATE));
     403                 :             : #else
     404                 :           0 :         ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
     405                 :           0 :         goto cleanup;
     406                 :             : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
     407                 :             :     } else {
     408                 :           4 :         (void) alg;
     409         [ -  + ]:           4 :         MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ecp->grp, &r, &s, &ecp->d,
     410                 :             :                                            hash, hash_length,
     411                 :             :                                            mbedtls_psa_get_random,
     412                 :             :                                            MBEDTLS_PSA_RANDOM_STATE));
     413                 :             :     }
     414                 :             : 
     415         [ -  + ]:           4 :     MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&r,
     416                 :             :                                              signature,
     417                 :             :                                              curve_bytes));
     418                 :           4 :     MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&s,
     419                 :             :                                              signature + curve_bytes,
     420                 :             :                                              curve_bytes));
     421                 :           4 : cleanup:
     422                 :           4 :     mbedtls_mpi_free(&r);
     423                 :           4 :     mbedtls_mpi_free(&s);
     424         [ +  - ]:           4 :     if (ret == 0) {
     425                 :           4 :         *signature_length = 2 * curve_bytes;
     426                 :             :     }
     427                 :             : 
     428                 :           4 :     mbedtls_ecp_keypair_free(ecp);
     429                 :           4 :     mbedtls_free(ecp);
     430                 :             : 
     431                 :           4 :     return mbedtls_to_psa_error(ret);
     432                 :             : }
     433                 :             : 
     434                 :           6 : psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp)
     435                 :             : {
     436                 :           6 :     int ret = 0;
     437                 :             : 
     438                 :             :     /* Check whether the public part is loaded. If not, load it. */
     439         [ -  + ]:           6 :     if (mbedtls_ecp_is_zero(&ecp->Q)) {
     440                 :           0 :         ret = mbedtls_ecp_mul(&ecp->grp, &ecp->Q,
     441                 :           0 :                               &ecp->d, &ecp->grp.G,
     442                 :             :                               mbedtls_psa_get_random,
     443                 :             :                               MBEDTLS_PSA_RANDOM_STATE);
     444                 :             :     }
     445                 :             : 
     446                 :           6 :     return mbedtls_to_psa_error(ret);
     447                 :             : }
     448                 :             : 
     449                 :           6 : psa_status_t mbedtls_psa_ecdsa_verify_hash(
     450                 :             :     const psa_key_attributes_t *attributes,
     451                 :             :     const uint8_t *key_buffer, size_t key_buffer_size,
     452                 :             :     psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
     453                 :             :     const uint8_t *signature, size_t signature_length)
     454                 :             : {
     455                 :           6 :     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     456                 :           6 :     mbedtls_ecp_keypair *ecp = NULL;
     457                 :           6 :     size_t curve_bytes;
     458                 :           6 :     mbedtls_mpi r, s;
     459                 :             : 
     460                 :           6 :     (void) alg;
     461                 :             : 
     462                 :          12 :     status = mbedtls_psa_ecp_load_representation(attributes->type,
     463                 :           6 :                                                  attributes->bits,
     464                 :             :                                                  key_buffer,
     465                 :             :                                                  key_buffer_size,
     466                 :             :                                                  &ecp);
     467         [ +  - ]:           6 :     if (status != PSA_SUCCESS) {
     468                 :             :         return status;
     469                 :             :     }
     470                 :             : 
     471                 :           6 :     curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits);
     472                 :           6 :     mbedtls_mpi_init(&r);
     473                 :           6 :     mbedtls_mpi_init(&s);
     474                 :             : 
     475         [ -  + ]:           6 :     if (signature_length != 2 * curve_bytes) {
     476                 :           0 :         status = PSA_ERROR_INVALID_SIGNATURE;
     477                 :           0 :         goto cleanup;
     478                 :             :     }
     479                 :             : 
     480                 :           6 :     status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&r,
     481                 :             :                                                           signature,
     482                 :             :                                                           curve_bytes));
     483         [ -  + ]:           6 :     if (status != PSA_SUCCESS) {
     484                 :           0 :         goto cleanup;
     485                 :             :     }
     486                 :             : 
     487                 :           6 :     status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&s,
     488                 :           6 :                                                           signature + curve_bytes,
     489                 :             :                                                           curve_bytes));
     490         [ -  + ]:           6 :     if (status != PSA_SUCCESS) {
     491                 :           0 :         goto cleanup;
     492                 :             :     }
     493                 :             : 
     494                 :           6 :     status = mbedtls_psa_ecp_load_public_part(ecp);
     495         [ -  + ]:           6 :     if (status != PSA_SUCCESS) {
     496                 :           0 :         goto cleanup;
     497                 :             :     }
     498                 :             : 
     499                 :           6 :     status = mbedtls_to_psa_error(mbedtls_ecdsa_verify(&ecp->grp, hash,
     500                 :           6 :                                                        hash_length, &ecp->Q,
     501                 :             :                                                        &r, &s));
     502                 :           6 : cleanup:
     503                 :           6 :     mbedtls_mpi_free(&r);
     504                 :           6 :     mbedtls_mpi_free(&s);
     505                 :           6 :     mbedtls_ecp_keypair_free(ecp);
     506                 :           6 :     mbedtls_free(ecp);
     507                 :             : 
     508                 :           6 :     return status;
     509                 :             : }
     510                 :             : 
     511                 :             : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
     512                 :             :         * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
     513                 :             : 
     514                 :             : /****************************************************************/
     515                 :             : /* ECDH Key Agreement */
     516                 :             : /****************************************************************/
     517                 :             : 
     518                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
     519                 :           4 : psa_status_t mbedtls_psa_key_agreement_ecdh(
     520                 :             :     const psa_key_attributes_t *attributes,
     521                 :             :     const uint8_t *key_buffer, size_t key_buffer_size,
     522                 :             :     psa_algorithm_t alg, const uint8_t *peer_key, size_t peer_key_length,
     523                 :             :     uint8_t *shared_secret, size_t shared_secret_size,
     524                 :             :     size_t *shared_secret_length)
     525                 :             : {
     526                 :           4 :     psa_status_t status;
     527         [ +  - ]:           4 :     if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type) ||
     528         [ +  - ]:           4 :         !PSA_ALG_IS_ECDH(alg)) {
     529                 :             :         return PSA_ERROR_INVALID_ARGUMENT;
     530                 :             :     }
     531                 :           4 :     mbedtls_ecp_keypair *ecp = NULL;
     532                 :           8 :     status = mbedtls_psa_ecp_load_representation(
     533                 :             :         attributes->type,
     534                 :           4 :         attributes->bits,
     535                 :             :         key_buffer,
     536                 :             :         key_buffer_size,
     537                 :             :         &ecp);
     538         [ +  - ]:           4 :     if (status != PSA_SUCCESS) {
     539                 :             :         return status;
     540                 :             :     }
     541                 :           4 :     mbedtls_ecp_keypair *their_key = NULL;
     542                 :           4 :     mbedtls_ecdh_context ecdh;
     543                 :           4 :     size_t bits = 0;
     544                 :           4 :     psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(ecp->grp.id, &bits);
     545                 :           4 :     mbedtls_ecdh_init(&ecdh);
     546                 :             : 
     547                 :           8 :     status = mbedtls_psa_ecp_load_representation(
     548                 :           4 :         PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
     549                 :             :         bits,
     550                 :             :         peer_key,
     551                 :             :         peer_key_length,
     552                 :             :         &their_key);
     553         [ -  + ]:           4 :     if (status != PSA_SUCCESS) {
     554                 :           0 :         goto exit;
     555                 :             :     }
     556                 :             : 
     557                 :           4 :     status = mbedtls_to_psa_error(
     558                 :             :         mbedtls_ecdh_get_params(&ecdh, their_key, MBEDTLS_ECDH_THEIRS));
     559         [ -  + ]:           4 :     if (status != PSA_SUCCESS) {
     560                 :           0 :         goto exit;
     561                 :             :     }
     562                 :           4 :     status = mbedtls_to_psa_error(
     563                 :             :         mbedtls_ecdh_get_params(&ecdh, ecp, MBEDTLS_ECDH_OURS));
     564         [ -  + ]:           4 :     if (status != PSA_SUCCESS) {
     565                 :           0 :         goto exit;
     566                 :             :     }
     567                 :             : 
     568                 :           4 :     status = mbedtls_to_psa_error(
     569                 :             :         mbedtls_ecdh_calc_secret(&ecdh,
     570                 :             :                                  shared_secret_length,
     571                 :             :                                  shared_secret, shared_secret_size,
     572                 :             :                                  mbedtls_psa_get_random,
     573                 :             :                                  MBEDTLS_PSA_RANDOM_STATE));
     574         [ -  + ]:           4 :     if (status != PSA_SUCCESS) {
     575                 :           0 :         goto exit;
     576                 :             :     }
     577         [ +  - ]:           4 :     if (PSA_BITS_TO_BYTES(bits) != *shared_secret_length) {
     578                 :             :         status = PSA_ERROR_CORRUPTION_DETECTED;
     579                 :             :     }
     580                 :           4 : exit:
     581                 :           0 :     if (status != PSA_SUCCESS) {
     582                 :           0 :         mbedtls_platform_zeroize(shared_secret, shared_secret_size);
     583                 :             :     }
     584                 :           4 :     mbedtls_ecdh_free(&ecdh);
     585                 :           4 :     mbedtls_ecp_keypair_free(their_key);
     586                 :           4 :     mbedtls_free(their_key);
     587                 :           4 :     mbedtls_ecp_keypair_free(ecp);
     588                 :           4 :     mbedtls_free(ecp);
     589                 :           4 :     return status;
     590                 :             : }
     591                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
     592                 :             : 
     593                 :             : 
     594                 :             : #endif /* MBEDTLS_PSA_CRYPTO_C */
        

Generated by: LCOV version 2.0-1