LCOV - code coverage report
Current view: top level - src/common - crypto_wrapper.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 186 239 77.8 %
Date: 2024-09-16 20:15:30 Functions: 9 10 90.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 73 206 35.4 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :    Copyright (c) 2021 Fraunhofer AISEC. See the COPYRIGHT
       3                 :            :    file at the top-level directory of this distribution.
       4                 :            : 
       5                 :            :    Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
       6                 :            :    http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
       7                 :            :    <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
       8                 :            :    option. This file may not be copied, modified, or distributed
       9                 :            :    except according to those terms.
      10                 :            : */
      11                 :            : #include <string.h>
      12                 :            : 
      13                 :            : #include "edhoc.h"
      14                 :            : 
      15                 :            : #include "common/crypto_wrapper.h"
      16                 :            : #include "common/byte_array.h"
      17                 :            : #include "common/oscore_edhoc_error.h"
      18                 :            : #include "common/print_util.h"
      19                 :            : #include "common/memcpy_s.h"
      20                 :            : 
      21                 :            : #include "edhoc/suites.h"
      22                 :            : #include "edhoc/buffer_sizes.h"
      23                 :            : 
      24                 :            : #ifdef EDHOC_MOCK_CRYPTO_WRAPPER
      25                 :            : struct edhoc_mock_cb edhoc_crypto_mock_cb;
      26                 :            : #endif // EDHOC_MOCK_CRYPTO_WRAPPER
      27                 :            : 
      28                 :            : #ifdef MBEDTLS
      29                 :            : /*
      30                 :            : IMPORTANT!!!!
      31                 :            : make sure MBEDTLS_PSA_CRYPTO_CONFIG is defined in include/mbedtls/mbedtls_config.h
      32                 :            : 
      33                 :            : 
      34                 :            : modify setting in include/psa/crypto_config.h 
      35                 :            : */
      36                 :            : #define MBEDTLS_ALLOW_PRIVATE_ACCESS
      37                 :            : 
      38                 :            : #include <psa/crypto.h>
      39                 :            : 
      40                 :            : #include "mbedtls/ecp.h"
      41                 :            : #include "mbedtls/platform.h"
      42                 :            : #include "mbedtls/entropy.h"
      43                 :            : #include "mbedtls/ctr_drbg.h"
      44                 :            : #include "mbedtls/ecdsa.h"
      45                 :            : #include "mbedtls/error.h"
      46                 :            : #include "mbedtls/rsa.h"
      47                 :            : #include "mbedtls/x509.h"
      48                 :            : 
      49                 :            : #endif
      50                 :            : 
      51                 :            : #ifdef COMPACT25519
      52                 :            : #include <c25519.h>
      53                 :            : #include <edsign.h>
      54                 :            : #include <compact_x25519.h>
      55                 :            : #endif
      56                 :            : 
      57                 :            : #ifdef TINYCRYPT
      58                 :            : #include <tinycrypt/aes.h>
      59                 :            : #include <tinycrypt/ccm_mode.h>
      60                 :            : #include <tinycrypt/constants.h>
      61                 :            : #include <tinycrypt/hmac.h>
      62                 :            : #include <tinycrypt/ecc_dsa.h>
      63                 :            : #include <tinycrypt/ecc_dh.h>
      64                 :            : #endif
      65                 :            : 
      66                 :            : #ifdef MBEDTLS
      67                 :            : #define TRY_EXPECT_PSA(x, expected_result, key_id, err_code)                   \
      68                 :            :         do {                                                                   \
      69                 :            :                 int retval = (int)(x);                                         \
      70                 :            :                 if ((expected_result) != retval) {                             \
      71                 :            :                         if (PSA_KEY_HANDLE_INIT != (key_id)) {                 \
      72                 :            :                                 psa_destroy_key(key_id);                       \
      73                 :            :                         }                                                      \
      74                 :            :                         handle_external_runtime_error(retval, __FILE__,        \
      75                 :            :                                                       __LINE__);               \
      76                 :            :                         return err_code;                                       \
      77                 :            :                 }                                                              \
      78                 :            :         } while (0)
      79                 :            : 
      80                 :            : /**
      81                 :            :  * @brief Decompresses an elliptic curve point. 
      82                 :            :  * 
      83                 :            :  * 
      84                 :            :  * @param grp elliptic curve group point
      85                 :            :  * @param input the compressed key
      86                 :            :  * @param ilen the lenhgt if the compressed key
      87                 :            :  * @param output the uncopressed key
      88                 :            :  * @param olen the lenhgt of the output
      89                 :            :  * @param osize the actual available size of the out buffer
      90                 :            :  * @return 0 on success
      91                 :            :  */
      92                 :          4 : static inline int mbedtls_ecp_decompress(const mbedtls_ecp_group *grp,
      93                 :            :                                          const unsigned char *input,
      94                 :            :                                          size_t ilen, unsigned char *output,
      95                 :            :                                          size_t *olen, size_t osize)
      96                 :            : {
      97                 :            :         int ret;
      98                 :            :         size_t plen;
      99                 :            :         mbedtls_mpi r;
     100                 :            :         mbedtls_mpi x;
     101                 :            :         mbedtls_mpi n;
     102                 :            : 
     103                 :          4 :         plen = mbedtls_mpi_size(&grp->P);
     104                 :            : 
     105                 :          4 :         *olen = 2 * plen + 1;
     106                 :            : 
     107         [ -  + ]:          4 :         if (osize < *olen)
     108                 :          0 :                 return (MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
     109                 :            : 
     110                 :            :         // output will consist of 0x04|X|Y
     111                 :          4 :         memcpy(output + 1, input, ilen);
     112                 :          4 :         output[0] = 0x04;
     113                 :            : 
     114                 :          4 :         mbedtls_mpi_init(&r);
     115                 :          4 :         mbedtls_mpi_init(&x);
     116                 :          4 :         mbedtls_mpi_init(&n);
     117                 :            : 
     118                 :            :         // x <= input
     119         [ -  + ]:          4 :         MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&x, input, plen));
     120                 :            : 
     121                 :            :         // r = x^2
     122         [ -  + ]:          4 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&r, &x, &x));
     123                 :            : 
     124                 :            :         // r = x^2 + a
     125         [ +  - ]:          4 :         if (grp->A.p == NULL) {
     126                 :            :                 // Special case where a is -3
     127         [ -  + ]:          4 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&r, &r, 3));
     128                 :            :         } else {
     129         [ #  # ]:          0 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&r, &r, &grp->A));
     130                 :            :         }
     131                 :            : 
     132                 :            :         // r = x^3 + ax
     133         [ -  + ]:          4 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&r, &r, &x));
     134                 :            : 
     135                 :            :         // r = x^3 + ax + b
     136         [ -  + ]:          4 :         MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&r, &r, &grp->B));
     137                 :            : 
     138                 :            :         // Calculate square root of r over finite field P:
     139                 :            :         //   r = sqrt(x^3 + ax + b) = (x^3 + ax + b) ^ ((P + 1) / 4) (mod P)
     140                 :            : 
     141                 :            :         // n = P + 1
     142         [ -  + ]:          4 :         MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&n, &grp->P, 1));
     143                 :            : 
     144                 :            :         // n = (P + 1) / 4
     145         [ -  + ]:          4 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&n, 2));
     146                 :            : 
     147                 :            :         // r ^ ((P + 1) / 4) (mod p)
     148         [ -  + ]:          4 :         MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&r, &r, &n, &grp->P, NULL));
     149                 :            : 
     150                 :            :         // Select solution that has the correct "sign" (equals odd/even solution in finite group)
     151         [ +  - ]:          4 :         if ((input[0] == 0x03) != mbedtls_mpi_get_bit(&r, 0)) {
     152                 :            :                 // r = p - r
     153         [ -  + ]:          4 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&r, &grp->P, &r));
     154                 :            :         }
     155                 :            : 
     156                 :            :         // y => output
     157                 :          4 :         ret = mbedtls_mpi_write_binary(&r, output + 1 + plen, plen);
     158                 :            : 
     159                 :          4 : cleanup:
     160                 :          4 :         mbedtls_mpi_free(&r);
     161                 :          4 :         mbedtls_mpi_free(&x);
     162                 :          4 :         mbedtls_mpi_free(&n);
     163                 :            : 
     164                 :          4 :         return (ret);
     165                 :            : }
     166                 :            : 
     167                 :            : #endif
     168                 :            : 
     169                 :            : #ifdef TINYCRYPT
     170                 :            : /* Declaration of function from TinyCrypt ecc.c */
     171                 :            : uECC_word_t cond_set(uECC_word_t p_true, uECC_word_t p_false,
     172                 :            :                      unsigned int cond);
     173                 :            : 
     174                 :            : /* From uECC project embedded in TinyCrypt - ecc.c
     175                 :            :    BSD-2-Clause license */
     176                 :            : static uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *left,
     177                 :            :                                 const uECC_word_t *right, wordcount_t num_words)
     178                 :            : {
     179                 :            :         uECC_word_t carry = 0U;
     180                 :            :         wordcount_t i;
     181                 :            :         for (i = 0; i < num_words; ++i) {
     182                 :            :                 uECC_word_t sum = left[i] + right[i] + carry;
     183                 :            :                 uECC_word_t val = (sum < left[i]);
     184                 :            :                 carry = cond_set(val, carry, (sum != left[i]));
     185                 :            :                 result[i] = sum;
     186                 :            :         }
     187                 :            :         return carry;
     188                 :            : }
     189                 :            : 
     190                 :            : /* From uECC project; curve-specific.inc */
     191                 :            : /* Calculates EC square root of bignum (Very Large Integer) based on curve */
     192                 :            : static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve)
     193                 :            : {
     194                 :            :         bitcount_t i;
     195                 :            :         uECC_word_t p1[NUM_ECC_WORDS] = { 1 };
     196                 :            :         uECC_word_t l_result[NUM_ECC_WORDS] = { 1 };
     197                 :            :         wordcount_t num_words = curve->num_words;
     198                 :            : 
     199                 :            :         /* When curve->p == 3 (mod 4), we can compute
     200                 :            :        sqrt(a) = a^((curve->p + 1) / 4) (mod curve->p). */
     201                 :            :         uECC_vli_add(p1, curve->p, p1, num_words); /* p1 = curve_p + 1 */
     202                 :            :         for (i = uECC_vli_numBits(p1, num_words) - 1; i > 1; --i) {
     203                 :            :                 uECC_vli_modMult_fast(l_result, l_result, l_result, curve);
     204                 :            :                 if (uECC_vli_testBit(p1, i)) {
     205                 :            :                         uECC_vli_modMult_fast(l_result, l_result, a, curve);
     206                 :            :                 }
     207                 :            :         }
     208                 :            :         uECC_vli_set(a, l_result, num_words);
     209                 :            : }
     210                 :            : 
     211                 :            : /**
     212                 :            :  * @brief Decompresses an elliptic curve point. 
     213                 :            :  * 
     214                 :            :  * 
     215                 :            :  * @param compressed the compressed key
     216                 :            :  * @param public_key the uncopressed key
     217                 :            :  * @param curve elliptic curve group point
     218                 :            :  */
     219                 :            : /* From uECC project 
     220                 :            :    BSD-2-Clause license */
     221                 :            : static inline void uECC_decompress(const uint8_t *compressed,
     222                 :            :                                    uint8_t *public_key, uECC_Curve curve)
     223                 :            : {
     224                 :            :         uECC_word_t point[NUM_ECC_WORDS * 2];
     225                 :            : 
     226                 :            :         uECC_word_t *y = point + curve->num_words;
     227                 :            : 
     228                 :            :         uECC_vli_bytesToNative(point, compressed, curve->num_bytes);
     229                 :            : 
     230                 :            :         curve->x_side(y, point, curve);
     231                 :            :         mod_sqrt_default(y, curve);
     232                 :            : 
     233                 :            :         if ((y[0] & 0x01) != (compressed[0] == 0x03)) {
     234                 :            :                 uECC_vli_sub(y, curve->p, y, curve->num_words);
     235                 :            :         }
     236                 :            : 
     237                 :            :         uECC_vli_nativeToBytes(public_key, curve->num_bytes, point);
     238                 :            :         uECC_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes,
     239                 :            :                                y);
     240                 :            : }
     241                 :            : #endif
     242                 :            : 
     243                 :            : #ifdef EDHOC_MOCK_CRYPTO_WRAPPER
     244                 :            : static bool
     245                 :            : aead_mock_args_match_predefined(struct edhoc_mock_aead_in_out *predefined,
     246                 :            :                                 const uint8_t *key, const uint16_t key_len,
     247                 :            :                                 uint8_t *nonce, const uint16_t nonce_len,
     248                 :            :                                 const uint8_t *aad, const uint16_t aad_len,
     249                 :            :                                 uint8_t *tag, const uint16_t tag_len)
     250                 :            : {
     251                 :            :         return array_equals(&predefined->key,
     252                 :            :                             &(struct byte_array){ .ptr = (void *)key,
     253                 :            :                                                   .len = key_len }) &&
     254                 :            :                array_equals(&predefined->nonce,
     255                 :            :                             &(struct byte_array){ .ptr = nonce,
     256                 :            :                                                   .len = nonce_len }) &&
     257                 :            :                array_equals(&predefined->aad,
     258                 :            :                             &(struct byte_array){ .ptr = (void *)aad,
     259                 :            :                                                   .len = aad_len }) &&
     260                 :            :                array_equals(&predefined->tag,
     261                 :            :                             &(struct byte_array){ .ptr = tag, .len = tag_len });
     262                 :            : }
     263                 :            : #endif // EDHOC_MOCK_CRYPTO_WRAPPER
     264                 :            : 
     265                 :         34 : enum err WEAK aead(enum aes_operation op, const struct byte_array *in,
     266                 :            :                    const struct byte_array *key, struct byte_array *nonce,
     267                 :            :                    const struct byte_array *aad, struct byte_array *out,
     268                 :            :                    struct byte_array *tag)
     269                 :            : {
     270                 :            : #ifdef EDHOC_MOCK_CRYPTO_WRAPPER
     271                 :            :         for (uint32_t i = 0; i < edhoc_crypto_mock_cb.aead_in_out_count; i++) {
     272                 :            :                 struct edhoc_mock_aead_in_out *predefined_in_out =
     273                 :            :                         edhoc_crypto_mock_cb.aead_in_out + i;
     274                 :            :                 if (aead_mock_args_match_predefined(
     275                 :            :                             predefined_in_out, key->ptr, key->len, nonce->ptr,
     276                 :            :                             nonce->len, aad->ptr, aad->len, tag->ptr,
     277                 :            :                             tag->len)) {
     278                 :            :                         memcpy(out->ptr, predefined_in_out->out.ptr,
     279                 :            :                                predefined_in_out->out.len);
     280                 :            :                         return ok;
     281                 :            :                 }
     282                 :            :         }
     283                 :            :         // if no mocked data has been found - continue with normal aead
     284                 :            : #endif
     285                 :            : 
     286                 :            : #if defined(TINYCRYPT)
     287                 :            :         struct tc_ccm_mode_struct c;
     288                 :            :         struct tc_aes_key_sched_struct sched;
     289                 :            :         TRY_EXPECT(tc_aes128_set_encrypt_key(&sched, key->ptr), 1);
     290                 :            :         TRY_EXPECT(tc_ccm_config(&c, &sched, nonce->ptr, nonce->len, tag->len),
     291                 :            :                    1);
     292                 :            : 
     293                 :            :         if (op == DECRYPT) {
     294                 :            :                 TRY_EXPECT(tc_ccm_decryption_verification(out->ptr, out->len,
     295                 :            :                                                           aad->ptr, aad->len,
     296                 :            :                                                           in->ptr, in->len, &c),
     297                 :            :                            1);
     298                 :            : 
     299                 :            :         } else {
     300                 :            :                 TRY_EXPECT(tc_ccm_generation_encryption(
     301                 :            :                                    out->ptr, (out->len + tag->len), aad->ptr,
     302                 :            :                                    aad->len, in->ptr, in->len, &c),
     303                 :            :                            1);
     304                 :            :                 memcpy(tag->ptr, out->ptr + out->len, tag->len);
     305                 :            :         }
     306                 :            : #elif defined(MBEDTLS)
     307                 :         34 :         psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
     308                 :            : 
     309   [ -  +  -  - ]:         34 :         TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id,
     310                 :            :                        unexpected_result_from_ext_lib);
     311                 :            : 
     312                 :         34 :         psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(
     313                 :            :                 PSA_ALG_CCM, (uint32_t)tag->len);
     314                 :            : 
     315                 :         34 :         psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
     316                 :         34 :         psa_set_key_usage_flags(&attr,
     317                 :            :                                 PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_ENCRYPT);
     318                 :         34 :         psa_set_key_algorithm(&attr, alg);
     319                 :         34 :         psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
     320                 :         34 :         psa_set_key_bits(&attr, ((size_t)key->len << 3));
     321                 :         34 :         psa_set_key_lifetime(&attr, PSA_KEY_LIFETIME_VOLATILE);
     322   [ -  +  -  - ]:         34 :         TRY_EXPECT_PSA(psa_import_key(&attr, key->ptr, key->len, &key_id),
     323                 :            :                        PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
     324                 :            : 
     325         [ +  + ]:         34 :         if (op == DECRYPT) {
     326                 :         16 :                 size_t out_len_re = 0;
     327   [ -  +  -  - ]:         16 :                 TRY_EXPECT_PSA(
     328                 :            :                         psa_aead_decrypt(key_id, alg, nonce->ptr, nonce->len,
     329                 :            :                                          aad->ptr, aad->len, in->ptr, in->len,
     330                 :            :                                          out->ptr, out->len, &out_len_re),
     331                 :            :                         PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
     332                 :            :         } else {
     333                 :            :                 size_t out_len_re;
     334   [ -  +  -  - ]:         18 :                 TRY_EXPECT_PSA(
     335                 :            :                         psa_aead_encrypt(key_id, alg, nonce->ptr, nonce->len,
     336                 :            :                                          aad->ptr, aad->len, in->ptr, in->len,
     337                 :            :                                          out->ptr, (size_t)(in->len + tag->len),
     338                 :            :                                          &out_len_re),
     339                 :            :                         PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
     340                 :         18 :                 memcpy(tag->ptr, out->ptr + out_len_re - tag->len, tag->len);
     341                 :            :         }
     342         [ -  + ]:         34 :         TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
     343                 :            : 
     344                 :            : #endif
     345                 :         34 :         return ok;
     346                 :            : }
     347                 :            : 
     348                 :            : #ifdef EDHOC_MOCK_CRYPTO_WRAPPER
     349                 :            : static bool
     350                 :            : sign_mock_args_match_predefined(struct edhoc_mock_sign_in_out *predefined,
     351                 :            :                                 const uint8_t *sk, const size_t sk_len,
     352                 :            :                                 const uint8_t *pk, const size_t pk_len,
     353                 :            :                                 const uint8_t *msg, const size_t msg_len)
     354                 :            : {
     355                 :            :         return array_equals(&predefined->sk,
     356                 :            :                             &(struct byte_array){ .len = sk_len,
     357                 :            :                                                   .ptr = (void *)sk }) &&
     358                 :            :                array_equals(&predefined->pk,
     359                 :            :                             &(struct byte_array){ .len = pk_len,
     360                 :            :                                                   .ptr = (void *)pk }) &&
     361                 :            :                array_equals(&predefined->msg,
     362                 :            :                             &(struct byte_array){ .len = msg_len,
     363                 :            :                                                   .ptr = (void *)msg });
     364                 :            : }
     365                 :            : #endif // EDHOC_MOCK_CRYPTO_WRAPPER
     366                 :            : 
     367                 :          6 : enum err WEAK sign(enum sign_alg alg, const struct byte_array *sk,
     368                 :            :                    const struct byte_array *pk, const struct byte_array *msg,
     369                 :            :                    uint8_t *out)
     370                 :            : {
     371                 :            : #ifdef EDHOC_MOCK_CRYPTO_WRAPPER
     372                 :            :         for (uint32_t i = 0; i < edhoc_crypto_mock_cb.sign_in_out_count; i++) {
     373                 :            :                 struct edhoc_mock_sign_in_out *predefined_in_out =
     374                 :            :                         edhoc_crypto_mock_cb.sign_in_out + i;
     375                 :            :                 if (sign_mock_args_match_predefined(predefined_in_out, sk->ptr,
     376                 :            :                                                     sk->len, pk->ptr, PK_SIZE,
     377                 :            :                                                     msg->ptr, msg->len)) {
     378                 :            :                         memcpy(out, predefined_in_out->out.ptr,
     379                 :            :                                predefined_in_out->out.len);
     380                 :            :                         return ok;
     381                 :            :                 }
     382                 :            :         }
     383                 :            : #endif // EDHOC_MOCK_CRYPTO_WRAPPER
     384                 :            : 
     385         [ +  + ]:          6 :         if (alg == EdDSA) {
     386                 :            : #if defined(COMPACT25519)
     387                 :          2 :                 edsign_sign(out, pk->ptr, sk->ptr, msg->ptr, msg->len);
     388                 :          2 :                 return ok;
     389                 :            : #endif
     390         [ +  - ]:          4 :         } else if (alg == ES256) {
     391                 :            : #if defined(TINYCRYPT)
     392                 :            : 
     393                 :            :                 uECC_Curve p256 = uECC_secp256r1();
     394                 :            :                 struct tc_sha256_state_struct ctx_sha256;
     395                 :            :                 uint8_t hash[NUM_ECC_BYTES];
     396                 :            : 
     397                 :            :                 TRY_EXPECT(tc_sha256_init(&ctx_sha256), 1);
     398                 :            :                 TRY_EXPECT(tc_sha256_update(&ctx_sha256, msg->ptr, msg->len),
     399                 :            :                            1);
     400                 :            :                 TRY_EXPECT(tc_sha256_final(hash, &ctx_sha256), 1);
     401                 :            : 
     402                 :            :                 TRY_EXPECT(uECC_sign(sk->ptr, hash, NUM_ECC_BYTES, out, p256),
     403                 :            :                            TC_CRYPTO_SUCCESS);
     404                 :            : 
     405                 :            :                 return ok;
     406                 :            : 
     407                 :            : #elif defined(MBEDTLS)
     408                 :            :                 psa_algorithm_t psa_alg;
     409                 :            :                 size_t bits;
     410                 :          4 :                 psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
     411                 :            : 
     412                 :          4 :                 psa_alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
     413                 :          4 :                 bits = PSA_BYTES_TO_BITS((size_t)sk->len);
     414                 :            : 
     415   [ -  +  -  - ]:          4 :                 TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id,
     416                 :            :                                unexpected_result_from_ext_lib);
     417                 :            : 
     418                 :          4 :                 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     419                 :          4 :                 psa_set_key_usage_flags(&attributes,
     420                 :            :                                         PSA_KEY_USAGE_VERIFY_MESSAGE |
     421                 :            :                                                 PSA_KEY_USAGE_VERIFY_HASH |
     422                 :            :                                                 PSA_KEY_USAGE_SIGN_MESSAGE |
     423                 :            :                                                 PSA_KEY_USAGE_SIGN_HASH);
     424                 :          4 :                 psa_set_key_algorithm(&attributes, psa_alg);
     425                 :          4 :                 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(
     426                 :            :                                                       PSA_ECC_FAMILY_SECP_R1));
     427                 :          4 :                 psa_set_key_bits(&attributes, bits);
     428                 :          4 :                 psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
     429                 :            : 
     430   [ -  +  -  - ]:          4 :                 TRY_EXPECT_PSA(
     431                 :            :                         psa_import_key(&attributes, sk->ptr, sk->len, &key_id),
     432                 :            :                         PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
     433                 :            : 
     434                 :            :                 size_t signature_length;
     435   [ -  +  -  - ]:          4 :                 TRY_EXPECT_PSA(psa_sign_message(key_id, psa_alg, msg->ptr,
     436                 :            :                                                 msg->len, out, SIGNATURE_SIZE,
     437                 :            :                                                 &signature_length),
     438                 :            :                                PSA_SUCCESS, key_id,
     439                 :            :                                unexpected_result_from_ext_lib);
     440                 :            : 
     441   [ -  +  -  - ]:          4 :                 TRY_EXPECT_PSA(signature_length, SIGNATURE_SIZE, key_id,
     442                 :            :                                sign_failed);
     443         [ -  + ]:          4 :                 TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
     444                 :          4 :                 return ok;
     445                 :            : #endif
     446                 :            :         }
     447                 :          0 :         return unsupported_ecdh_curve;
     448                 :            : }
     449                 :            : 
     450                 :          8 : enum err WEAK verify(enum sign_alg alg, const struct byte_array *pk,
     451                 :            :                      struct const_byte_array *msg, struct const_byte_array *sgn,
     452                 :            :                      bool *result)
     453                 :            : {
     454         [ +  + ]:          8 :         if (alg == EdDSA) {
     455                 :            : #ifdef COMPACT25519
     456                 :          2 :                 int verified =
     457                 :          2 :                         edsign_verify(sgn->ptr, pk->ptr, msg->ptr, msg->len);
     458         [ +  - ]:          2 :                 if (verified) {
     459                 :          2 :                         *result = true;
     460                 :            :                 } else {
     461                 :          0 :                         *result = false;
     462                 :            :                 }
     463                 :          2 :                 return ok;
     464                 :            : #endif
     465                 :            :         }
     466         [ +  - ]:          6 :         if (alg == ES256) {
     467                 :            : #if defined(MBEDTLS)
     468                 :            :                 psa_status_t status;
     469                 :            :                 psa_algorithm_t psa_alg;
     470                 :            :                 size_t bits;
     471                 :          6 :                 psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
     472                 :            : 
     473                 :          6 :                 psa_alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
     474                 :          6 :                 bits = PSA_BYTES_TO_BITS(P_256_PRIV_KEY_SIZE);
     475                 :            : 
     476   [ -  +  -  - ]:          6 :                 TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id,
     477                 :            :                                unexpected_result_from_ext_lib);
     478                 :            : 
     479                 :          6 :                 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     480                 :            : 
     481                 :          6 :                 psa_set_key_usage_flags(&attributes,
     482                 :            :                                         PSA_KEY_USAGE_VERIFY_MESSAGE |
     483                 :            :                                                 PSA_KEY_USAGE_VERIFY_HASH);
     484                 :          6 :                 psa_set_key_algorithm(&attributes, psa_alg);
     485                 :          6 :                 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(
     486                 :            :                                                       PSA_ECC_FAMILY_SECP_R1));
     487                 :          6 :                 psa_set_key_bits(&attributes, bits);
     488   [ -  +  -  - ]:          6 :                 TRY_EXPECT_PSA(
     489                 :            :                         psa_import_key(&attributes, pk->ptr, pk->len, &key_id),
     490                 :            :                         PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
     491                 :            : 
     492                 :          6 :                 status = psa_verify_message(key_id, psa_alg, msg->ptr, msg->len,
     493                 :            :                                             sgn->ptr, sgn->len);
     494         [ +  - ]:          6 :                 if (PSA_SUCCESS == status) {
     495                 :          6 :                         *result = true;
     496                 :            :                 } else {
     497                 :          0 :                         *result = false;
     498                 :            :                 }
     499         [ -  + ]:          6 :                 TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
     500                 :          6 :                 return ok;
     501                 :            : #elif defined(TINYCRYPT)
     502                 :            :                 uECC_Curve p256 = uECC_secp256r1();
     503                 :            :                 struct tc_sha256_state_struct ctx_sha256;
     504                 :            :                 uint8_t hash[NUM_ECC_BYTES];
     505                 :            :                 TRY_EXPECT(tc_sha256_init(&ctx_sha256), 1);
     506                 :            :                 TRY_EXPECT(tc_sha256_update(&ctx_sha256, msg->ptr, msg->len),
     507                 :            :                            1);
     508                 :            :                 TRY_EXPECT(tc_sha256_final(hash, &ctx_sha256), 1);
     509                 :            :                 uint8_t *pk_ptr = pk->ptr;
     510                 :            :                 if ((P_256_PUB_KEY_UNCOMPRESSED_SIZE == pk->len) &&
     511                 :            :                     (0x04 == *pk->ptr)) {
     512                 :            :                         pk_ptr++;
     513                 :            :                 }
     514                 :            :                 TRY_EXPECT(uECC_verify(pk_ptr, hash, NUM_ECC_BYTES, sgn->ptr,
     515                 :            :                                        p256),
     516                 :            :                            1);
     517                 :            :                 *result = true;
     518                 :            :                 return ok;
     519                 :            : #endif
     520                 :            :         }
     521                 :          0 :         return crypto_operation_not_implemented;
     522                 :            : }
     523                 :            : 
     524                 :         39 : enum err WEAK hkdf_extract(enum hash_alg alg, const struct byte_array *salt,
     525                 :            :                            struct byte_array *ikm, uint8_t *out)
     526                 :            : {
     527                 :            :         /*"Note that [RFC5869] specifies that if the salt is not provided, 
     528                 :            :         it is set to a string of zeros.  For implementation purposes, 
     529                 :            :         not providing the salt is the same as setting the salt to the empty byte 
     530                 :            :         string. OSCORE sets the salt default value to empty byte string, which 
     531                 :            :         is converted to a string of zeroes (see Section 2.2 of [RFC5869])".*/
     532                 :            : 
     533                 :            :         /*all currently prosed suites use hmac-sha256*/
     534         [ -  + ]:         39 :         if (alg != SHA_256) {
     535                 :          0 :                 return crypto_operation_not_implemented;
     536                 :            :         }
     537                 :            : #ifdef TINYCRYPT
     538                 :            :         struct tc_hmac_state_struct h;
     539                 :            :         memset(&h, 0x00, sizeof(h));
     540                 :            :         if (salt->ptr == NULL || salt->len == 0) {
     541                 :            :                 uint8_t zero_salt[32] = { 0 };
     542                 :            :                 TRY_EXPECT(tc_hmac_set_key(&h, zero_salt, 32), 1);
     543                 :            :         } else {
     544                 :            :                 TRY_EXPECT(tc_hmac_set_key(&h, salt->ptr, salt->len), 1);
     545                 :            :         }
     546                 :            :         TRY_EXPECT(tc_hmac_init(&h), 1);
     547                 :            :         TRY_EXPECT(tc_hmac_update(&h, ikm->ptr, ikm->len), 1);
     548                 :            :         TRY_EXPECT(tc_hmac_final(out, TC_SHA256_DIGEST_SIZE, &h), 1);
     549                 :            : #endif
     550                 :            : #ifdef MBEDTLS
     551                 :         39 :         psa_algorithm_t psa_alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
     552                 :         39 :         psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
     553                 :         39 :         psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
     554                 :            : 
     555   [ -  +  -  - ]:         39 :         TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id,
     556                 :            :                        unexpected_result_from_ext_lib);
     557                 :            : 
     558                 :         39 :         psa_set_key_lifetime(&attr, PSA_KEY_LIFETIME_VOLATILE);
     559                 :         39 :         psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_HASH);
     560                 :         39 :         psa_set_key_algorithm(&attr, psa_alg);
     561                 :         39 :         psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
     562                 :            : 
     563   [ +  +  +  - ]:         39 :         if (salt->ptr && salt->len) {
     564   [ -  +  -  - ]:         33 :                 TRY_EXPECT_PSA(
     565                 :            :                         psa_import_key(&attr, salt->ptr, salt->len, &key_id),
     566                 :            :                         PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
     567                 :            :         } else {
     568                 :          6 :                 uint8_t zero_salt[32] = { 0 };
     569                 :            : 
     570   [ -  +  -  - ]:          6 :                 TRY_EXPECT_PSA(psa_import_key(&attr, zero_salt, 32, &key_id),
     571                 :            :                                PSA_SUCCESS, key_id,
     572                 :            :                                unexpected_result_from_ext_lib);
     573                 :            :         }
     574                 :            :         size_t out_len;
     575   [ -  +  -  - ]:         39 :         TRY_EXPECT_PSA(psa_mac_compute(key_id, psa_alg, ikm->ptr, ikm->len, out,
     576                 :            :                                        32, &out_len),
     577                 :            :                        PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
     578                 :            : 
     579         [ -  + ]:         39 :         TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
     580                 :            : #endif
     581                 :         39 :         return ok;
     582                 :            : }
     583                 :            : 
     584                 :         85 : enum err WEAK hkdf_expand(enum hash_alg alg, const struct byte_array *prk,
     585                 :            :                           const struct byte_array *info, struct byte_array *out)
     586                 :            : {
     587         [ -  + ]:         85 :         if (alg != SHA_256) {
     588                 :          0 :                 return crypto_operation_not_implemented;
     589                 :            :         }
     590                 :            :         /* "N = ceil(L/HashLen)" */
     591                 :         85 :         uint32_t iterations = (out->len + 31) / 32;
     592                 :            :         /* "L length of output keying material in octets (<= 255*HashLen)"*/
     593         [ -  + ]:         85 :         if (iterations > 255) {
     594                 :          0 :                 return hkdf_failed;
     595                 :            :         }
     596                 :            : 
     597                 :            : #ifdef TINYCRYPT
     598                 :            :         uint8_t t[32] = { 0 };
     599                 :            :         struct tc_hmac_state_struct h;
     600                 :            :         for (uint8_t i = 1; i <= iterations; i++) {
     601                 :            :                 memset(&h, 0x00, sizeof(h));
     602                 :            :                 TRY_EXPECT(tc_hmac_set_key(&h, prk->ptr, prk->len), 1);
     603                 :            :                 tc_hmac_init(&h);
     604                 :            :                 if (i > 1) {
     605                 :            :                         TRY_EXPECT(tc_hmac_update(&h, t, 32), 1);
     606                 :            :                 }
     607                 :            :                 TRY_EXPECT(tc_hmac_update(&h, info->ptr, info->len), 1);
     608                 :            :                 TRY_EXPECT(tc_hmac_update(&h, &i, 1), 1);
     609                 :            :                 TRY_EXPECT(tc_hmac_final(t, TC_SHA256_DIGEST_SIZE, &h), 1);
     610                 :            :                 if (out->len < i * 32) {
     611                 :            :                         memcpy(&out->ptr[(i - 1) * 32], t, out->len % 32);
     612                 :            :                 } else {
     613                 :            :                         memcpy(&out->ptr[(i - 1) * 32], t, 32);
     614                 :            :                 }
     615                 :            :         }
     616                 :            : #endif
     617                 :            : #ifdef MBEDTLS
     618                 :            :         psa_status_t status;
     619                 :         85 :         psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
     620                 :         85 :         psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
     621                 :         85 :         PRINTF("key_id: %d\n", key_id);
     622                 :            : 
     623   [ -  +  -  - ]:         85 :         TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id,
     624                 :            :                        unexpected_result_from_ext_lib);
     625                 :         85 :         psa_set_key_lifetime(&attr, PSA_KEY_LIFETIME_VOLATILE);
     626                 :         85 :         psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_HASH);
     627                 :         85 :         psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));
     628                 :         85 :         psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
     629                 :            : 
     630                 :         85 :         PRINT_ARRAY("PRK:", prk->ptr, prk->len);
     631   [ -  +  -  - ]:         85 :         TRY_EXPECT_PSA(psa_import_key(&attr, prk->ptr, prk->len, &key_id),
     632                 :            :                        PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
     633                 :            : 
     634                 :         85 :         size_t combo_len = (32 + (size_t)info->len + 1);
     635                 :            : 
     636   [ -  +  -  - ]:         85 :         TRY_EXPECT_PSA(check_buffer_size(INFO_MAX_SIZE + 32 + 1,
     637                 :            :                                          (uint32_t)combo_len),
     638                 :            :                        ok, key_id, unexpected_result_from_ext_lib);
     639                 :            : 
     640                 :            :         uint8_t combo[INFO_MAX_SIZE + 32 + 1];
     641                 :            :         uint8_t tmp_out[32];
     642                 :         85 :         memset(tmp_out, 0, 32);
     643                 :         85 :         memcpy(combo + 32, info->ptr, info->len);
     644                 :         85 :         size_t offset = 32;
     645         [ +  + ]:        200 :         for (uint32_t i = 1; i <= iterations; i++) {
     646                 :        115 :                 memcpy(combo, tmp_out, 32);
     647                 :        115 :                 combo[combo_len - 1] = (uint8_t)i;
     648                 :            :                 size_t tmp_out_len;
     649                 :        115 :                 status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
     650                 :            :                                          combo + offset, combo_len - offset,
     651                 :            :                                          tmp_out, 32, &tmp_out_len);
     652   [ -  +  -  - ]:        115 :                 TRY_EXPECT_PSA(status, PSA_SUCCESS, key_id,
     653                 :            :                                unexpected_result_from_ext_lib);
     654                 :        115 :                 offset = 0;
     655                 :        115 :                 uint8_t *dest = out->ptr + ((i - 1) << 5);
     656         [ +  + ]:        115 :                 if (out->len < (uint32_t)(i << 5)) {
     657                 :         61 :                         memcpy(dest, tmp_out, out->len & 31);
     658                 :            :                 } else {
     659                 :         54 :                         memcpy(dest, tmp_out, 32);
     660                 :            :                 }
     661                 :            :         }
     662         [ -  + ]:         85 :         TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
     663                 :            : #endif
     664                 :         85 :         return ok;
     665                 :            : }
     666                 :            : 
     667                 :         33 : enum err WEAK hkdf_sha_256(struct byte_array *master_secret,
     668                 :            :                            struct byte_array *master_salt,
     669                 :            :                            struct byte_array *info, struct byte_array *out)
     670                 :            : {
     671         [ -  + ]:         33 :         BYTE_ARRAY_NEW(prk, HASH_SIZE, HASH_SIZE);
     672         [ -  + ]:         33 :         TRY(hkdf_extract(SHA_256, master_salt, master_secret, prk.ptr));
     673         [ -  + ]:         33 :         TRY(hkdf_expand(SHA_256, &prk, info, out));
     674                 :         33 :         return ok;
     675                 :            : }
     676                 :            : 
     677                 :          6 : enum err WEAK shared_secret_derive(enum ecdh_alg alg,
     678                 :            :                                    const struct byte_array *sk,
     679                 :            :                                    const struct byte_array *pk,
     680                 :            :                                    uint8_t *shared_secret)
     681                 :            : {
     682         [ +  + ]:          6 :         if (alg == X25519) {
     683                 :            : #ifdef COMPACT25519
     684                 :            :                 uint8_t e[F25519_SIZE];
     685                 :          2 :                 f25519_copy(e, sk->ptr);
     686                 :          2 :                 c25519_prepare(e);
     687                 :          2 :                 c25519_smult(shared_secret, pk->ptr, e);
     688                 :          2 :                 return ok;
     689                 :            : #endif
     690                 :            :         }
     691         [ +  - ]:          4 :         if (alg == P256) {
     692                 :            : #if defined(TINYCRYPT)
     693                 :            :                 uECC_Curve p256 = uECC_secp256r1();
     694                 :            :                 uint8_t pk_decompressed[P_256_PUB_KEY_UNCOMPRESSED_SIZE];
     695                 :            : 
     696                 :            :                 uECC_decompress(pk->ptr, pk_decompressed, p256);
     697                 :            : 
     698                 :            :                 PRINT_ARRAY("pk_decompressed", pk_decompressed,
     699                 :            :                             2 * P_256_PUB_KEY_X_CORD_SIZE);
     700                 :            : 
     701                 :            :                 TRY_EXPECT(uECC_shared_secret(pk_decompressed, sk->ptr,
     702                 :            :                                               shared_secret, p256),
     703                 :            :                            1);
     704                 :            : 
     705                 :            :                 return ok;
     706                 :            : #elif defined(MBEDTLS) /* TINYCRYPT / MBEDTLS */
     707                 :          4 :                 psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
     708                 :            :                 psa_algorithm_t psa_alg;
     709                 :            :                 size_t bits;
     710                 :          4 :                 psa_status_t result = ok;
     711                 :            : 
     712                 :          4 :                 psa_alg = PSA_ALG_ECDH;
     713                 :          4 :                 bits = PSA_BYTES_TO_BITS(sk->len);
     714                 :            : 
     715   [ -  +  -  - ]:          4 :                 TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id,
     716                 :            :                                unexpected_result_from_ext_lib);
     717                 :            : 
     718                 :          4 :                 psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
     719                 :          4 :                 psa_set_key_lifetime(&attr, PSA_KEY_LIFETIME_VOLATILE);
     720                 :          4 :                 psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_DERIVE);
     721                 :          4 :                 psa_set_key_algorithm(&attr, psa_alg);
     722                 :          4 :                 psa_set_key_type(&attr, PSA_KEY_TYPE_ECC_KEY_PAIR(
     723                 :            :                                                 PSA_ECC_FAMILY_SECP_R1));
     724                 :            : 
     725   [ -  +  -  - ]:          4 :                 TRY_EXPECT_PSA(psa_import_key(&attr, sk->ptr, (size_t)sk->len,
     726                 :            :                                               &key_id),
     727                 :            :                                PSA_SUCCESS, key_id,
     728                 :            :                                unexpected_result_from_ext_lib);
     729                 :          4 :                 psa_key_type_t type = psa_get_key_type(&attr);
     730                 :          4 :                 size_t shared_size =
     731         [ +  - ]:          4 :                         PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(type, bits);
     732                 :            : 
     733                 :          4 :                 size_t shared_secret_len = 0;
     734                 :            : 
     735                 :            :                 size_t pk_decompressed_len;
     736                 :            :                 uint8_t pk_decompressed[P_256_PUB_KEY_UNCOMPRESSED_SIZE];
     737                 :            : 
     738                 :          4 :                 mbedtls_pk_context ctx_verify = { 0 };
     739                 :          4 :                 mbedtls_pk_init(&ctx_verify);
     740         [ -  + ]:          4 :                 if (PSA_SUCCESS !=
     741                 :          4 :                     mbedtls_pk_setup(&ctx_verify, mbedtls_pk_info_from_type(
     742                 :            :                                                           MBEDTLS_PK_ECKEY))) {
     743                 :          0 :                         result = unexpected_result_from_ext_lib;
     744                 :          0 :                         goto cleanup;
     745                 :            :                 }
     746         [ -  + ]:          4 :                 if (PSA_SUCCESS !=
     747                 :          4 :                     mbedtls_ecp_group_load(&mbedtls_pk_ec(ctx_verify)->grp,
     748                 :            :                                            MBEDTLS_ECP_DP_SECP256R1)) {
     749                 :          0 :                         result = unexpected_result_from_ext_lib;
     750                 :          0 :                         goto cleanup;
     751                 :            :                 }
     752         [ -  + ]:          4 :                 if (PSA_SUCCESS !=
     753                 :          4 :                     mbedtls_ecp_decompress(&mbedtls_pk_ec(ctx_verify)->grp,
     754                 :          4 :                                            pk->ptr, pk->len, pk_decompressed,
     755                 :            :                                            &pk_decompressed_len,
     756                 :            :                                            sizeof(pk_decompressed))) {
     757                 :          0 :                         result = unexpected_result_from_ext_lib;
     758                 :          0 :                         goto cleanup;
     759                 :            :                 }
     760                 :            : 
     761                 :          4 :                 PRINT_ARRAY("pk_decompressed", pk_decompressed,
     762                 :            :                             (uint32_t)pk_decompressed_len);
     763                 :            : 
     764         [ +  - ]:          4 :                 if (PSA_SUCCESS !=
     765                 :          4 :                     psa_raw_key_agreement(PSA_ALG_ECDH, key_id, pk_decompressed,
     766                 :            :                                           pk_decompressed_len, shared_secret,
     767                 :            :                                           shared_size, &shared_secret_len)) {
     768                 :          0 :                         result = unexpected_result_from_ext_lib;
     769                 :          0 :                         goto cleanup;
     770                 :            :                 }
     771                 :          4 :         cleanup:
     772         [ +  - ]:          4 :                 if (PSA_KEY_HANDLE_INIT != key_id) {
     773         [ -  + ]:          4 :                         TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
     774                 :            :                 }
     775                 :          4 :                 mbedtls_pk_free(&ctx_verify);
     776                 :          4 :                 return result;
     777                 :            : #endif
     778                 :            :         }
     779                 :          0 :         return crypto_operation_not_implemented;
     780                 :            : }
     781                 :            : 
     782                 :          0 : enum err WEAK ephemeral_dh_key_gen(enum ecdh_alg alg, uint32_t seed,
     783                 :            :                                    struct byte_array *sk, struct byte_array *pk)
     784                 :            : {
     785         [ #  # ]:          0 :         if (alg == X25519) {
     786                 :            : #ifdef COMPACT25519
     787                 :            :                 uint8_t extended_seed[32];
     788                 :            : #if defined(TINYCRYPT)
     789                 :            :                 struct tc_sha256_state_struct s;
     790                 :            :                 TRY_EXPECT(tc_sha256_init(&s), 1);
     791                 :            :                 TRY_EXPECT(tc_sha256_update(&s, (uint8_t *)&seed, sizeof(seed)),
     792                 :            :                            1);
     793                 :            :                 TRY_EXPECT(tc_sha256_final(extended_seed, &s),
     794                 :            :                            TC_CRYPTO_SUCCESS);
     795                 :            : #elif defined(MBEDTLS) /* TINYCRYPT / MBEDTLS */
     796                 :            :                 size_t length;
     797         [ #  # ]:          0 :                 TRY_EXPECT(psa_hash_compute(PSA_ALG_SHA_256, (uint8_t *)&seed,
     798                 :            :                                             sizeof(seed), sk->ptr, HASH_SIZE,
     799                 :            :                                             &length),
     800                 :            :                            0);
     801         [ #  # ]:          0 :                 if (length != 32) {
     802                 :          0 :                         return sha_failed;
     803                 :            :                 }
     804                 :            : #endif
     805                 :          0 :                 compact_x25519_keygen(sk->ptr, pk->ptr, extended_seed);
     806                 :          0 :                 pk->len = X25519_KEY_SIZE;
     807                 :          0 :                 sk->len = X25519_KEY_SIZE;
     808                 :            : #endif
     809         [ #  # ]:          0 :         } else if (alg == P256) {
     810                 :            : #if defined(TINYCRYPT)
     811                 :            :                 if (P_256_PUB_KEY_X_CORD_SIZE > pk->len) {
     812                 :            :                         return buffer_to_small;
     813                 :            :                 }
     814                 :            :                 uECC_Curve p256 = uECC_secp256r1();
     815                 :            :                 uint8_t pk_decompressed[P_256_PUB_KEY_UNCOMPRESSED_SIZE];
     816                 :            :                 TRY_EXPECT(uECC_make_key(pk_decompressed, sk->ptr, p256),
     817                 :            :                            TC_CRYPTO_SUCCESS);
     818                 :            :                 TRY(_memcpy_s(pk->ptr, P_256_PUB_KEY_X_CORD_SIZE,
     819                 :            :                               pk_decompressed, P_256_PUB_KEY_X_CORD_SIZE));
     820                 :            :                 pk->len = P_256_PUB_KEY_X_CORD_SIZE;
     821                 :            :                 return ok;
     822                 :            : #elif defined(MBEDTLS) /* TINYCRYPT / MBEDTLS */
     823                 :          0 :                 psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
     824                 :          0 :                 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     825                 :          0 :                 psa_algorithm_t psa_alg = PSA_ALG_ECDH;
     826                 :          0 :                 uint8_t priv_key_size = P_256_PRIV_KEY_SIZE;
     827                 :          0 :                 size_t bits = PSA_BYTES_TO_BITS((size_t)priv_key_size);
     828                 :          0 :                 size_t pub_key_uncompressed_size =
     829                 :            :                         P_256_PUB_KEY_UNCOMPRESSED_SIZE;
     830                 :            :                 uint8_t pub_key_uncompressed[P_256_PUB_KEY_UNCOMPRESSED_SIZE];
     831                 :            : 
     832         [ #  # ]:          0 :                 if (P_256_PUB_KEY_X_CORD_SIZE > pk->len) {
     833                 :          0 :                         return buffer_to_small;
     834                 :            :                 }
     835   [ #  #  #  # ]:          0 :                 TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id,
     836                 :            :                                unexpected_result_from_ext_lib);
     837                 :            : 
     838                 :          0 :                 psa_set_key_usage_flags(&attributes,
     839                 :            :                                         PSA_KEY_USAGE_EXPORT |
     840                 :            :                                                 PSA_KEY_USAGE_DERIVE |
     841                 :            :                                                 PSA_KEY_USAGE_SIGN_MESSAGE |
     842                 :            :                                                 PSA_KEY_USAGE_SIGN_HASH);
     843                 :          0 :                 psa_set_key_algorithm(&attributes, psa_alg);
     844                 :          0 :                 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(
     845                 :            :                                                       PSA_ECC_FAMILY_SECP_R1));
     846                 :          0 :                 psa_set_key_bits(&attributes, bits);
     847                 :            : 
     848   [ #  #  #  # ]:          0 :                 TRY_EXPECT_PSA(psa_generate_key(&attributes, &key_id),
     849                 :            :                                PSA_SUCCESS, key_id,
     850                 :            :                                unexpected_result_from_ext_lib);
     851                 :            : 
     852                 :          0 :                 size_t key_len = 0;
     853                 :          0 :                 size_t public_key_len = 0;
     854                 :            : 
     855   [ #  #  #  # ]:          0 :                 TRY_EXPECT_PSA(psa_export_key(key_id, sk->ptr, priv_key_size,
     856                 :            :                                               &key_len),
     857                 :            :                                PSA_SUCCESS, key_id,
     858                 :            :                                unexpected_result_from_ext_lib);
     859   [ #  #  #  # ]:          0 :                 TRY_EXPECT_PSA(
     860                 :            :                         psa_export_public_key(key_id, pub_key_uncompressed,
     861                 :            :                                               pub_key_uncompressed_size,
     862                 :            :                                               &public_key_len),
     863                 :            :                         PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
     864   [ #  #  #  # ]:          0 :                 TRY_EXPECT_PSA(public_key_len, P_256_PUB_KEY_UNCOMPRESSED_SIZE,
     865                 :            :                                key_id, unexpected_result_from_ext_lib);
     866                 :            :                 /* Prepare output format - only x parameter */
     867                 :          0 :                 memcpy(pk->ptr, (pub_key_uncompressed + 1),
     868                 :            :                        P_256_PUB_KEY_X_CORD_SIZE);
     869         [ #  # ]:          0 :                 TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
     870                 :          0 :                 pk->len = P_256_PUB_KEY_X_CORD_SIZE;
     871                 :            : #endif
     872                 :            :         } else {
     873                 :          0 :                 return unsupported_ecdh_curve;
     874                 :            :         }
     875                 :          0 :         return ok;
     876                 :            : }
     877                 :            : 
     878                 :         24 : enum err WEAK hash(enum hash_alg alg, const struct byte_array *in,
     879                 :            :                    struct byte_array *out)
     880                 :            : {
     881         [ +  - ]:         24 :         if (alg == SHA_256) {
     882                 :            : #ifdef TINYCRYPT
     883                 :            :                 struct tc_sha256_state_struct s;
     884                 :            :                 TRY_EXPECT(tc_sha256_init(&s), 1);
     885                 :            :                 TRY_EXPECT(tc_sha256_update(&s, in->ptr, in->len), 1);
     886                 :            :                 TRY_EXPECT(tc_sha256_final(out->ptr, &s), 1);
     887                 :            :                 out->len = HASH_SIZE;
     888                 :            :                 return ok;
     889                 :            : #endif
     890                 :            : #ifdef MBEDTLS
     891                 :            :                 size_t length;
     892         [ -  + ]:         24 :                 TRY_EXPECT(psa_hash_compute(PSA_ALG_SHA_256, in->ptr, in->len,
     893                 :            :                                             out->ptr, HASH_SIZE, &length),
     894                 :            :                            PSA_SUCCESS);
     895         [ -  + ]:         24 :                 if (length != HASH_SIZE) {
     896                 :          0 :                         return sha_failed;
     897                 :            :                 }
     898                 :         24 :                 out->len = HASH_SIZE;
     899                 :         24 :                 PRINT_ARRAY("hash", out->ptr, out->len);
     900                 :         24 :                 return ok;
     901                 :            : #endif
     902                 :            :         }
     903                 :            : 
     904                 :          0 :         return crypto_operation_not_implemented;
     905                 :            : }

Generated by: LCOV version 1.14