quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

psa_util.c (20831B)


      1 /*
      2  *  PSA hashing layer on top of Mbed TLS software 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 /* This is needed for MBEDTLS_ERR_XXX macros */
     12 #include <mbedtls/error.h>
     13 
     14 #if defined(MBEDTLS_ASN1_WRITE_C)
     15 #include <mbedtls/asn1write.h>
     16 #include <psa/crypto_sizes.h>
     17 #endif
     18 
     19 #include "psa_util_internal.h"
     20 
     21 #if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
     22 
     23 #include <psa/crypto.h>
     24 
     25 #if defined(MBEDTLS_MD_LIGHT)
     26 #include <mbedtls/md.h>
     27 #endif
     28 #if defined(MBEDTLS_LMS_C)
     29 #include <mbedtls/lms.h>
     30 #endif
     31 #if defined(MBEDTLS_SSL_TLS_C) && \
     32     (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
     33 #include <mbedtls/ssl.h>
     34 #endif
     35 #if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) ||    \
     36     defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
     37 #include <mbedtls/rsa.h>
     38 #endif
     39 #if defined(MBEDTLS_USE_PSA_CRYPTO) && \
     40     defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
     41 #include <mbedtls/ecp.h>
     42 #endif
     43 #if defined(MBEDTLS_PK_C)
     44 #include <mbedtls/pk.h>
     45 #endif
     46 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
     47 #include <mbedtls/cipher.h>
     48 #endif
     49 #include <mbedtls/entropy.h>
     50 
     51 /* PSA_SUCCESS is kept at the top of each error table since
     52  * it's the most common status when everything functions properly. */
     53 #if defined(MBEDTLS_MD_LIGHT)
     54 const mbedtls_error_pair_t psa_to_md_errors[] =
     55 {
     56     { PSA_SUCCESS,                     0 },
     57     { PSA_ERROR_NOT_SUPPORTED,         MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE },
     58     { PSA_ERROR_INVALID_ARGUMENT,      MBEDTLS_ERR_MD_BAD_INPUT_DATA },
     59     { PSA_ERROR_INSUFFICIENT_MEMORY,   MBEDTLS_ERR_MD_ALLOC_FAILED }
     60 };
     61 #endif
     62 
     63 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
     64 const mbedtls_error_pair_t psa_to_cipher_errors[] =
     65 {
     66     { PSA_SUCCESS,                     0 },
     67     { PSA_ERROR_NOT_SUPPORTED,         MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE },
     68     { PSA_ERROR_INVALID_ARGUMENT,      MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA },
     69     { PSA_ERROR_INSUFFICIENT_MEMORY,   MBEDTLS_ERR_CIPHER_ALLOC_FAILED }
     70 };
     71 #endif
     72 
     73 #if defined(MBEDTLS_LMS_C)
     74 const mbedtls_error_pair_t psa_to_lms_errors[] =
     75 {
     76     { PSA_SUCCESS,                     0 },
     77     { PSA_ERROR_BUFFER_TOO_SMALL,      MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL },
     78     { PSA_ERROR_INVALID_ARGUMENT,      MBEDTLS_ERR_LMS_BAD_INPUT_DATA }
     79 };
     80 #endif
     81 
     82 #if defined(MBEDTLS_SSL_TLS_C) && \
     83     (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
     84 const mbedtls_error_pair_t psa_to_ssl_errors[] =
     85 {
     86     { PSA_SUCCESS,                     0 },
     87     { PSA_ERROR_INSUFFICIENT_MEMORY,   MBEDTLS_ERR_SSL_ALLOC_FAILED },
     88     { PSA_ERROR_NOT_SUPPORTED,         MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE },
     89     { PSA_ERROR_INVALID_SIGNATURE,     MBEDTLS_ERR_SSL_INVALID_MAC },
     90     { PSA_ERROR_INVALID_ARGUMENT,      MBEDTLS_ERR_SSL_BAD_INPUT_DATA },
     91     { PSA_ERROR_BAD_STATE,             MBEDTLS_ERR_SSL_INTERNAL_ERROR },
     92     { PSA_ERROR_BUFFER_TOO_SMALL,      MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL }
     93 };
     94 #endif
     95 
     96 #if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) ||    \
     97     defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
     98 const mbedtls_error_pair_t psa_to_pk_rsa_errors[] =
     99 {
    100     { PSA_SUCCESS,                     0 },
    101     { PSA_ERROR_NOT_PERMITTED,         MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
    102     { PSA_ERROR_INVALID_ARGUMENT,      MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
    103     { PSA_ERROR_INVALID_HANDLE,        MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
    104     { PSA_ERROR_BUFFER_TOO_SMALL,      MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE },
    105     { PSA_ERROR_INSUFFICIENT_ENTROPY,  MBEDTLS_ERR_RSA_RNG_FAILED },
    106     { PSA_ERROR_INVALID_SIGNATURE,     MBEDTLS_ERR_RSA_VERIFY_FAILED },
    107     { PSA_ERROR_INVALID_PADDING,       MBEDTLS_ERR_RSA_INVALID_PADDING }
    108 };
    109 #endif
    110 
    111 #if defined(MBEDTLS_USE_PSA_CRYPTO) && \
    112     defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
    113 const mbedtls_error_pair_t psa_to_pk_ecdsa_errors[] =
    114 {
    115     { PSA_SUCCESS,                     0 },
    116     { PSA_ERROR_NOT_PERMITTED,         MBEDTLS_ERR_ECP_BAD_INPUT_DATA },
    117     { PSA_ERROR_INVALID_ARGUMENT,      MBEDTLS_ERR_ECP_BAD_INPUT_DATA },
    118     { PSA_ERROR_INVALID_HANDLE,        MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE },
    119     { PSA_ERROR_BUFFER_TOO_SMALL,      MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL },
    120     { PSA_ERROR_INSUFFICIENT_ENTROPY,  MBEDTLS_ERR_ECP_RANDOM_FAILED },
    121     { PSA_ERROR_INVALID_SIGNATURE,     MBEDTLS_ERR_ECP_VERIFY_FAILED }
    122 };
    123 #endif
    124 
    125 int psa_generic_status_to_mbedtls(psa_status_t status)
    126 {
    127     switch (status) {
    128         case PSA_SUCCESS:
    129             return 0;
    130         case PSA_ERROR_NOT_SUPPORTED:
    131             return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
    132         case PSA_ERROR_CORRUPTION_DETECTED:
    133             return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    134         case PSA_ERROR_COMMUNICATION_FAILURE:
    135         case PSA_ERROR_HARDWARE_FAILURE:
    136             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    137         case PSA_ERROR_NOT_PERMITTED:
    138         default:
    139             return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
    140     }
    141 }
    142 
    143 int psa_status_to_mbedtls(psa_status_t status,
    144                           const mbedtls_error_pair_t *local_translations,
    145                           size_t local_errors_num,
    146                           int (*fallback_f)(psa_status_t))
    147 {
    148     for (size_t i = 0; i < local_errors_num; i++) {
    149         if (status == local_translations[i].psa_status) {
    150             return local_translations[i].mbedtls_error;
    151         }
    152     }
    153     return fallback_f(status);
    154 }
    155 
    156 #if defined(MBEDTLS_PK_C)
    157 int psa_pk_status_to_mbedtls(psa_status_t status)
    158 {
    159     switch (status) {
    160         case PSA_ERROR_INVALID_HANDLE:
    161             return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
    162         case PSA_ERROR_BUFFER_TOO_SMALL:
    163             return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
    164         case PSA_ERROR_NOT_SUPPORTED:
    165             return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
    166         case PSA_ERROR_INVALID_ARGUMENT:
    167             return MBEDTLS_ERR_PK_INVALID_ALG;
    168         case PSA_ERROR_NOT_PERMITTED:
    169             return MBEDTLS_ERR_PK_TYPE_MISMATCH;
    170         case PSA_ERROR_INSUFFICIENT_MEMORY:
    171             return MBEDTLS_ERR_PK_ALLOC_FAILED;
    172         case PSA_ERROR_BAD_STATE:
    173             return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
    174         case PSA_ERROR_DATA_CORRUPT:
    175         case PSA_ERROR_DATA_INVALID:
    176         case PSA_ERROR_STORAGE_FAILURE:
    177             return MBEDTLS_ERR_PK_FILE_IO_ERROR;
    178         default:
    179             return psa_generic_status_to_mbedtls(status);
    180     }
    181 }
    182 #endif /* MBEDTLS_PK_C */
    183 
    184 /****************************************************************/
    185 /* Key management */
    186 /****************************************************************/
    187 
    188 #if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
    189 psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
    190                                           size_t *bits)
    191 {
    192     switch (grpid) {
    193 #if defined(MBEDTLS_ECP_HAVE_SECP192R1)
    194         case MBEDTLS_ECP_DP_SECP192R1:
    195             *bits = 192;
    196             return PSA_ECC_FAMILY_SECP_R1;
    197 #endif
    198 #if defined(MBEDTLS_ECP_HAVE_SECP224R1)
    199         case MBEDTLS_ECP_DP_SECP224R1:
    200             *bits = 224;
    201             return PSA_ECC_FAMILY_SECP_R1;
    202 #endif
    203 #if defined(MBEDTLS_ECP_HAVE_SECP256R1)
    204         case MBEDTLS_ECP_DP_SECP256R1:
    205             *bits = 256;
    206             return PSA_ECC_FAMILY_SECP_R1;
    207 #endif
    208 #if defined(MBEDTLS_ECP_HAVE_SECP384R1)
    209         case MBEDTLS_ECP_DP_SECP384R1:
    210             *bits = 384;
    211             return PSA_ECC_FAMILY_SECP_R1;
    212 #endif
    213 #if defined(MBEDTLS_ECP_HAVE_SECP521R1)
    214         case MBEDTLS_ECP_DP_SECP521R1:
    215             *bits = 521;
    216             return PSA_ECC_FAMILY_SECP_R1;
    217 #endif
    218 #if defined(MBEDTLS_ECP_HAVE_BP256R1)
    219         case MBEDTLS_ECP_DP_BP256R1:
    220             *bits = 256;
    221             return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
    222 #endif
    223 #if defined(MBEDTLS_ECP_HAVE_BP384R1)
    224         case MBEDTLS_ECP_DP_BP384R1:
    225             *bits = 384;
    226             return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
    227 #endif
    228 #if defined(MBEDTLS_ECP_HAVE_BP512R1)
    229         case MBEDTLS_ECP_DP_BP512R1:
    230             *bits = 512;
    231             return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
    232 #endif
    233 #if defined(MBEDTLS_ECP_HAVE_CURVE25519)
    234         case MBEDTLS_ECP_DP_CURVE25519:
    235             *bits = 255;
    236             return PSA_ECC_FAMILY_MONTGOMERY;
    237 #endif
    238 #if defined(MBEDTLS_ECP_HAVE_SECP192K1)
    239         case MBEDTLS_ECP_DP_SECP192K1:
    240             *bits = 192;
    241             return PSA_ECC_FAMILY_SECP_K1;
    242 #endif
    243 #if defined(MBEDTLS_ECP_HAVE_SECP224K1)
    244     /* secp224k1 is not and will not be supported in PSA (#3541). */
    245 #endif
    246 #if defined(MBEDTLS_ECP_HAVE_SECP256K1)
    247         case MBEDTLS_ECP_DP_SECP256K1:
    248             *bits = 256;
    249             return PSA_ECC_FAMILY_SECP_K1;
    250 #endif
    251 #if defined(MBEDTLS_ECP_HAVE_CURVE448)
    252         case MBEDTLS_ECP_DP_CURVE448:
    253             *bits = 448;
    254             return PSA_ECC_FAMILY_MONTGOMERY;
    255 #endif
    256         default:
    257             *bits = 0;
    258             return 0;
    259     }
    260 }
    261 
    262 mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
    263                                                 size_t bits)
    264 {
    265     switch (family) {
    266         case PSA_ECC_FAMILY_SECP_R1:
    267             switch (bits) {
    268 #if defined(PSA_WANT_ECC_SECP_R1_192)
    269                 case 192:
    270                     return MBEDTLS_ECP_DP_SECP192R1;
    271 #endif
    272 #if defined(PSA_WANT_ECC_SECP_R1_224)
    273                 case 224:
    274                     return MBEDTLS_ECP_DP_SECP224R1;
    275 #endif
    276 #if defined(PSA_WANT_ECC_SECP_R1_256)
    277                 case 256:
    278                     return MBEDTLS_ECP_DP_SECP256R1;
    279 #endif
    280 #if defined(PSA_WANT_ECC_SECP_R1_384)
    281                 case 384:
    282                     return MBEDTLS_ECP_DP_SECP384R1;
    283 #endif
    284 #if defined(PSA_WANT_ECC_SECP_R1_521)
    285                 case 521:
    286                     return MBEDTLS_ECP_DP_SECP521R1;
    287 #endif
    288             }
    289             break;
    290 
    291         case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
    292             switch (bits) {
    293 #if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
    294                 case 256:
    295                     return MBEDTLS_ECP_DP_BP256R1;
    296 #endif
    297 #if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
    298                 case 384:
    299                     return MBEDTLS_ECP_DP_BP384R1;
    300 #endif
    301 #if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
    302                 case 512:
    303                     return MBEDTLS_ECP_DP_BP512R1;
    304 #endif
    305             }
    306             break;
    307 
    308         case PSA_ECC_FAMILY_MONTGOMERY:
    309             switch (bits) {
    310 #if defined(PSA_WANT_ECC_MONTGOMERY_255)
    311                 case 255:
    312                     return MBEDTLS_ECP_DP_CURVE25519;
    313 #endif
    314 #if defined(PSA_WANT_ECC_MONTGOMERY_448)
    315                 case 448:
    316                     return MBEDTLS_ECP_DP_CURVE448;
    317 #endif
    318             }
    319             break;
    320 
    321         case PSA_ECC_FAMILY_SECP_K1:
    322             switch (bits) {
    323 #if defined(PSA_WANT_ECC_SECP_K1_192)
    324                 case 192:
    325                     return MBEDTLS_ECP_DP_SECP192K1;
    326 #endif
    327 #if defined(PSA_WANT_ECC_SECP_K1_224)
    328             /* secp224k1 is not and will not be supported in PSA (#3541). */
    329 #endif
    330 #if defined(PSA_WANT_ECC_SECP_K1_256)
    331                 case 256:
    332                     return MBEDTLS_ECP_DP_SECP256K1;
    333 #endif
    334             }
    335             break;
    336     }
    337 
    338     return MBEDTLS_ECP_DP_NONE;
    339 }
    340 #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
    341 
    342 /* Wrapper function allowing the classic API to use the PSA RNG.
    343  *
    344  * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
    345  * `psa_generate_random(...)`. The state parameter is ignored since the
    346  * PSA API doesn't support passing an explicit state.
    347  */
    348 int mbedtls_psa_get_random(void *p_rng,
    349                            unsigned char *output,
    350                            size_t output_size)
    351 {
    352     /* This function takes a pointer to the RNG state because that's what
    353      * classic mbedtls functions using an RNG expect. The PSA RNG manages
    354      * its own state internally and doesn't let the caller access that state.
    355      * So we just ignore the state parameter, and in practice we'll pass
    356      * NULL. */
    357     (void) p_rng;
    358     psa_status_t status = psa_generate_random(output, output_size);
    359     if (status == PSA_SUCCESS) {
    360         return 0;
    361     } else {
    362         return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
    363     }
    364 }
    365 
    366 #endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
    367 
    368 #if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
    369 
    370 /**
    371  * \brief  Convert a single raw coordinate to DER ASN.1 format. The output der
    372  *         buffer is filled backward (i.e. starting from its end).
    373  *
    374  * \param raw_buf           Buffer containing the raw coordinate to be
    375  *                          converted.
    376  * \param raw_len           Length of raw_buf in bytes. This must be > 0.
    377  * \param der_buf_start     Pointer to the beginning of the buffer which
    378  *                          will be filled with the DER converted data.
    379  * \param der_buf_end       End of the buffer used to store the DER output.
    380  *
    381  * \return                  On success, the amount of data (in bytes) written to
    382  *                          the DER buffer.
    383  * \return                  MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if the provided der
    384  *                          buffer is too small to contain all the converted data.
    385  * \return                  MBEDTLS_ERR_ASN1_INVALID_DATA if the input raw
    386  *                          coordinate is null (i.e. all zeros).
    387  *
    388  * \warning                 Raw and der buffer must not be overlapping.
    389  */
    390 static int convert_raw_to_der_single_int(const unsigned char *raw_buf, size_t raw_len,
    391                                          unsigned char *der_buf_start,
    392                                          unsigned char *der_buf_end)
    393 {
    394     unsigned char *p = der_buf_end;
    395     int len;
    396     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    397 
    398     /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
    399      * Provided input MPIs should not be 0, but as a failsafe measure, still
    400      * detect that and return error in case. */
    401     while (*raw_buf == 0x00) {
    402         ++raw_buf;
    403         --raw_len;
    404         if (raw_len == 0) {
    405             return MBEDTLS_ERR_ASN1_INVALID_DATA;
    406         }
    407     }
    408     len = (int) raw_len;
    409 
    410     /* Copy the raw coordinate to the end of der_buf. */
    411     if ((p - der_buf_start) < len) {
    412         return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
    413     }
    414     p -= len;
    415     memcpy(p, raw_buf, len);
    416 
    417     /* If MSb is 1, ASN.1 requires that we prepend a 0. */
    418     if (*p & 0x80) {
    419         if ((p - der_buf_start) < 1) {
    420             return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
    421         }
    422         --p;
    423         *p = 0x00;
    424         ++len;
    425     }
    426 
    427     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der_buf_start, len));
    428     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der_buf_start, MBEDTLS_ASN1_INTEGER));
    429 
    430     return len;
    431 }
    432 
    433 int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
    434                              unsigned char *der, size_t der_size, size_t *der_len)
    435 {
    436     unsigned char r[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
    437     unsigned char s[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
    438     const size_t coordinate_len = PSA_BITS_TO_BYTES(bits);
    439     size_t len = 0;
    440     unsigned char *p = der + der_size;
    441     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    442 
    443     if (bits == 0) {
    444         return MBEDTLS_ERR_ASN1_INVALID_DATA;
    445     }
    446     if (raw_len != (2 * coordinate_len)) {
    447         return MBEDTLS_ERR_ASN1_INVALID_DATA;
    448     }
    449     if (coordinate_len > sizeof(r)) {
    450         return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
    451     }
    452 
    453     /* Since raw and der buffers might overlap, dump r and s before starting
    454      * the conversion. */
    455     memcpy(r, raw, coordinate_len);
    456     memcpy(s, raw + coordinate_len, coordinate_len);
    457 
    458     /* der buffer will initially be written starting from its end so we pick s
    459      * first and then r. */
    460     ret = convert_raw_to_der_single_int(s, coordinate_len, der, p);
    461     if (ret < 0) {
    462         return ret;
    463     }
    464     p -= ret;
    465     len += ret;
    466 
    467     ret = convert_raw_to_der_single_int(r, coordinate_len, der, p);
    468     if (ret < 0) {
    469         return ret;
    470     }
    471     p -= ret;
    472     len += ret;
    473 
    474     /* Add ASN.1 header (len + tag). */
    475     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der, len));
    476     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der,
    477                                                      MBEDTLS_ASN1_CONSTRUCTED |
    478                                                      MBEDTLS_ASN1_SEQUENCE));
    479 
    480     /* memmove the content of der buffer to its beginnig. */
    481     memmove(der, p, len);
    482     *der_len = len;
    483 
    484     return 0;
    485 }
    486 
    487 /**
    488  * \brief Convert a single integer from ASN.1 DER format to raw.
    489  *
    490  * \param der               Buffer containing the DER integer value to be
    491  *                          converted.
    492  * \param der_len           Length of the der buffer in bytes.
    493  * \param raw               Output buffer that will be filled with the
    494  *                          converted data. This should be at least
    495  *                          coordinate_size bytes and it must be zeroed before
    496  *                          calling this function.
    497  * \param coordinate_size   Size (in bytes) of a single coordinate in raw
    498  *                          format.
    499  *
    500  * \return                  On success, the amount of DER data parsed from the
    501  *                          provided der buffer.
    502  * \return                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the integer tag
    503  *                          is missing in the der buffer.
    504  * \return                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the integer
    505  *                          is null (i.e. all zeros) or if the output raw buffer
    506  *                          is too small to contain the converted raw value.
    507  *
    508  * \warning                 Der and raw buffers must not be overlapping.
    509  */
    510 static int convert_der_to_raw_single_int(unsigned char *der, size_t der_len,
    511                                          unsigned char *raw, size_t coordinate_size)
    512 {
    513     unsigned char *p = der;
    514     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    515     size_t unpadded_len, padding_len = 0;
    516 
    517     /* Get the length of ASN.1 element (i.e. the integer we need to parse). */
    518     ret = mbedtls_asn1_get_tag(&p, p + der_len, &unpadded_len,
    519                                MBEDTLS_ASN1_INTEGER);
    520     if (ret != 0) {
    521         return ret;
    522     }
    523 
    524     /* It's invalid to have:
    525      * - unpadded_len == 0.
    526      * - MSb set without a leading 0x00 (leading 0x00 is checked below). */
    527     if (((unpadded_len == 0) || (*p & 0x80) != 0)) {
    528         return MBEDTLS_ERR_ASN1_INVALID_DATA;
    529     }
    530 
    531     /* Skip possible leading zero */
    532     if (*p == 0x00) {
    533         p++;
    534         unpadded_len--;
    535         /* It is not allowed to have more than 1 leading zero.
    536          * Ignore the case in which unpadded_len = 0 because that's a 0 encoded
    537          * in ASN.1 format (i.e. 020100). */
    538         if ((unpadded_len > 0) && (*p == 0x00)) {
    539             return MBEDTLS_ERR_ASN1_INVALID_DATA;
    540         }
    541     }
    542 
    543     if (unpadded_len > coordinate_size) {
    544         /* Parsed number is longer than the maximum expected value. */
    545         return MBEDTLS_ERR_ASN1_INVALID_DATA;
    546     }
    547     padding_len = coordinate_size - unpadded_len;
    548     /* raw buffer was already zeroed by the calling function so zero-padding
    549      * operation is skipped here. */
    550     memcpy(raw + padding_len, p, unpadded_len);
    551     p += unpadded_len;
    552 
    553     return (int) (p - der);
    554 }
    555 
    556 int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
    557                              unsigned char *raw, size_t raw_size, size_t *raw_len)
    558 {
    559     unsigned char raw_tmp[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
    560     unsigned char *p = (unsigned char *) der;
    561     size_t data_len;
    562     size_t coordinate_size = PSA_BITS_TO_BYTES(bits);
    563     int ret;
    564 
    565     if (bits == 0) {
    566         return MBEDTLS_ERR_ASN1_INVALID_DATA;
    567     }
    568     /* The output raw buffer should be at least twice the size of a raw
    569      * coordinate in order to store r and s. */
    570     if (raw_size < coordinate_size * 2) {
    571         return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
    572     }
    573     if (2 * coordinate_size > sizeof(raw_tmp)) {
    574         return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
    575     }
    576 
    577     /* Check that the provided input DER buffer has the right header. */
    578     ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len,
    579                                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
    580     if (ret != 0) {
    581         return ret;
    582     }
    583 
    584     memset(raw_tmp, 0, 2 * coordinate_size);
    585 
    586     /* Extract r */
    587     ret = convert_der_to_raw_single_int(p, data_len, raw_tmp, coordinate_size);
    588     if (ret < 0) {
    589         return ret;
    590     }
    591     p += ret;
    592     data_len -= ret;
    593 
    594     /* Extract s */
    595     ret = convert_der_to_raw_single_int(p, data_len, raw_tmp + coordinate_size,
    596                                         coordinate_size);
    597     if (ret < 0) {
    598         return ret;
    599     }
    600     p += ret;
    601     data_len -= ret;
    602 
    603     /* Check that we consumed all the input der data. */
    604     if ((size_t) (p - der) != der_len) {
    605         return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
    606     }
    607 
    608     memcpy(raw, raw_tmp, 2 * coordinate_size);
    609     *raw_len = 2 * coordinate_size;
    610 
    611     return 0;
    612 }
    613 
    614 #endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */