quickjs-tart

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

psa_exercise_key.c (56151B)


      1 /** Code to exercise a PSA key object, i.e. validate that it seems well-formed
      2  * and can do what it is supposed to do.
      3  */
      4 
      5 /*
      6  *  Copyright The Mbed TLS Contributors
      7  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
      8  */
      9 
     10 #include <test/helpers.h>
     11 #include <test/macros.h>
     12 #include <test/psa_exercise_key.h>
     13 
     14 #if (MBEDTLS_VERSION_MAJOR < 4 && defined(MBEDTLS_PSA_CRYPTO_C)) || \
     15     (MBEDTLS_VERSION_MAJOR >= 4 && defined(MBEDTLS_PSA_CRYPTO_CLIENT))
     16 
     17 #include <mbedtls/asn1.h>
     18 #include <psa/crypto.h>
     19 
     20 #include <test/asn1_helpers.h>
     21 #include <psa_crypto_slot_management.h>
     22 #include <test/psa_crypto_helpers.h>
     23 
     24 #if defined(MBEDTLS_PK_C)
     25 #include <pk_internal.h>
     26 #endif
     27 #if defined(MBEDTLS_ECP_C)
     28 #include <mbedtls/ecp.h>
     29 #endif
     30 #if defined(MBEDTLS_RSA_C)
     31 #include <rsa_internal.h>
     32 #endif
     33 
     34 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
     35 static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
     36 {
     37     return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
     38            PSA_KEY_LOCATION_LOCAL_STORAGE;
     39 }
     40 #endif
     41 
     42 static int check_key_attributes_sanity(mbedtls_svc_key_id_t key,
     43                                        int key_destroyable)
     44 {
     45     int ok = 0;
     46     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     47     psa_key_lifetime_t lifetime;
     48     mbedtls_svc_key_id_t id;
     49     psa_key_type_t type;
     50     size_t bits;
     51     psa_status_t status = psa_get_key_attributes(key, &attributes);
     52     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
     53         /* The key has been destroyed. */
     54         psa_reset_key_attributes(&attributes);
     55         return 1;
     56     }
     57     PSA_ASSERT(status);
     58     lifetime = psa_get_key_lifetime(&attributes);
     59     id = psa_get_key_id(&attributes);
     60     type = psa_get_key_type(&attributes);
     61     bits = psa_get_key_bits(&attributes);
     62 
     63     /* Persistence */
     64     if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
     65         TEST_ASSERT(
     66             (PSA_KEY_ID_VOLATILE_MIN <=
     67              MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
     68             (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
     69              PSA_KEY_ID_VOLATILE_MAX));
     70     } else {
     71         TEST_ASSERT(
     72             (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
     73             (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
     74     }
     75 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
     76     /* MBEDTLS_PSA_CRYPTO_SE_C does not support thread safety. */
     77     if (key_destroyable == 0) {
     78         /* randomly-generated 64-bit constant, should never appear in test data */
     79         psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
     80         status = psa_get_key_slot_number(&attributes, &slot_number);
     81         if (lifetime_is_dynamic_secure_element(lifetime)) {
     82             /* Mbed TLS currently always exposes the slot number to
     83              * applications. This is not mandated by the PSA specification
     84              * and may change in future versions. */
     85             TEST_EQUAL(status, 0);
     86             TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
     87         } else {
     88             TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
     89         }
     90     }
     91 #endif
     92 
     93     /* Type and size */
     94     TEST_ASSERT(type != 0);
     95     TEST_ASSERT(bits != 0);
     96     TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
     97     if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
     98         TEST_ASSERT(bits % 8 == 0);
     99     }
    100 
    101     /* MAX macros concerning specific key types */
    102     if (PSA_KEY_TYPE_IS_ECC(type)) {
    103         TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
    104     } else if (PSA_KEY_TYPE_IS_RSA(type)) {
    105         TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
    106     }
    107     TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
    108 
    109     ok = 1;
    110 
    111 exit:
    112     /*
    113      * Key attributes may have been returned by psa_get_key_attributes()
    114      * thus reset them as required.
    115      */
    116     psa_reset_key_attributes(&attributes);
    117 
    118     return ok;
    119 }
    120 
    121 static int exercise_mac_key(mbedtls_svc_key_id_t key,
    122                             psa_key_usage_t usage,
    123                             psa_algorithm_t alg,
    124                             int key_destroyable)
    125 {
    126     psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
    127     const unsigned char input[] = "foo";
    128     unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
    129     size_t mac_length = sizeof(mac);
    130     psa_status_t status = PSA_SUCCESS;
    131     /* Convert wildcard algorithm to exercisable algorithm */
    132     if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
    133         alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
    134     }
    135 
    136     if (usage & PSA_KEY_USAGE_SIGN_HASH) {
    137         status = psa_mac_sign_setup(&operation, key, alg);
    138         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    139             /* The key has been destroyed. */
    140             PSA_ASSERT(psa_mac_abort(&operation));
    141             return 1;
    142         }
    143         PSA_ASSERT(status);
    144         PSA_ASSERT(psa_mac_update(&operation,
    145                                   input, sizeof(input)));
    146         PSA_ASSERT(psa_mac_sign_finish(&operation,
    147                                        mac, sizeof(mac),
    148                                        &mac_length));
    149     }
    150 
    151     if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
    152         psa_status_t verify_status =
    153             (usage & PSA_KEY_USAGE_SIGN_HASH ?
    154              PSA_SUCCESS :
    155              PSA_ERROR_INVALID_SIGNATURE);
    156         status = psa_mac_verify_setup(&operation, key, alg);
    157         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    158             /* The key has been destroyed. */
    159             PSA_ASSERT(psa_mac_abort(&operation));
    160             return 1;
    161         }
    162         PSA_ASSERT(status);
    163         PSA_ASSERT(psa_mac_update(&operation,
    164                                   input, sizeof(input)));
    165         TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
    166                    verify_status);
    167     }
    168 
    169     return 1;
    170 
    171 exit:
    172     psa_mac_abort(&operation);
    173     return 0;
    174 }
    175 
    176 static int exercise_cipher_key(mbedtls_svc_key_id_t key,
    177                                psa_key_usage_t usage,
    178                                psa_algorithm_t alg,
    179                                int key_destroyable)
    180 {
    181     psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
    182     unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
    183     size_t iv_length;
    184     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    185     psa_key_type_t key_type;
    186     const unsigned char plaintext[16] = "Hello, world...";
    187     /* We need to tell the compiler that we meant to leave out the null character. */
    188     unsigned char ciphertext[32] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING =
    189         "(wabblewebblewibblewobblewubble)";
    190     size_t ciphertext_length = sizeof(ciphertext);
    191     unsigned char decrypted[sizeof(ciphertext)];
    192     size_t part_length;
    193     psa_status_t status = PSA_SUCCESS;
    194 
    195     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
    196     key_type = psa_get_key_type(&attributes);
    197     iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
    198 
    199     if (usage & PSA_KEY_USAGE_ENCRYPT) {
    200         status = psa_cipher_encrypt_setup(&operation, key, alg);
    201         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    202             /* The key has been destroyed. */
    203             PSA_ASSERT(psa_cipher_abort(&operation));
    204             return 1;
    205         }
    206         PSA_ASSERT(status);
    207         if (iv_length != 0) {
    208             PSA_ASSERT(psa_cipher_generate_iv(&operation,
    209                                               iv, sizeof(iv),
    210                                               &iv_length));
    211         }
    212         PSA_ASSERT(psa_cipher_update(&operation,
    213                                      plaintext, sizeof(plaintext),
    214                                      ciphertext, sizeof(ciphertext),
    215                                      &ciphertext_length));
    216         PSA_ASSERT(psa_cipher_finish(&operation,
    217                                      ciphertext + ciphertext_length,
    218                                      sizeof(ciphertext) - ciphertext_length,
    219                                      &part_length));
    220         ciphertext_length += part_length;
    221     }
    222 
    223     if (usage & PSA_KEY_USAGE_DECRYPT) {
    224         int maybe_invalid_padding = 0;
    225         if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
    226             maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
    227         }
    228         status = psa_cipher_decrypt_setup(&operation, key, alg);
    229         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    230             /* The key has been destroyed. */
    231             PSA_ASSERT(psa_cipher_abort(&operation));
    232             return 1;
    233         }
    234         PSA_ASSERT(status);
    235         if (iv_length != 0) {
    236             PSA_ASSERT(psa_cipher_set_iv(&operation,
    237                                          iv, iv_length));
    238         }
    239         PSA_ASSERT(psa_cipher_update(&operation,
    240                                      ciphertext, ciphertext_length,
    241                                      decrypted, sizeof(decrypted),
    242                                      &part_length));
    243         status = psa_cipher_finish(&operation,
    244                                    decrypted + part_length,
    245                                    sizeof(decrypted) - part_length,
    246                                    &part_length);
    247         /* For a stream cipher, all inputs are valid. For a block cipher,
    248          * if the input is some arbitrary data rather than an actual
    249            ciphertext, a padding error is likely.  */
    250         if (maybe_invalid_padding) {
    251             TEST_ASSERT(status == PSA_SUCCESS ||
    252                         status == PSA_ERROR_INVALID_PADDING);
    253         } else {
    254             PSA_ASSERT(status);
    255         }
    256     }
    257 
    258     return 1;
    259 
    260 exit:
    261     psa_cipher_abort(&operation);
    262     psa_reset_key_attributes(&attributes);
    263     return 0;
    264 }
    265 
    266 static int exercise_aead_key(mbedtls_svc_key_id_t key,
    267                              psa_key_usage_t usage,
    268                              psa_algorithm_t alg,
    269                              int key_destroyable)
    270 {
    271     unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
    272     size_t nonce_length;
    273     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    274     psa_key_type_t key_type;
    275     unsigned char plaintext[16] = "Hello, world...";
    276     unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
    277     size_t ciphertext_length = sizeof(ciphertext);
    278     size_t plaintext_length = sizeof(ciphertext);
    279     psa_status_t status = PSA_SUCCESS;
    280 
    281     /* Convert wildcard algorithm to exercisable algorithm */
    282     if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
    283         alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
    284     }
    285 
    286     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
    287     key_type = psa_get_key_type(&attributes);
    288     nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
    289 
    290     if (usage & PSA_KEY_USAGE_ENCRYPT) {
    291         status = psa_aead_encrypt(key, alg,
    292                                   nonce, nonce_length,
    293                                   NULL, 0,
    294                                   plaintext, sizeof(plaintext),
    295                                   ciphertext, sizeof(ciphertext),
    296                                   &ciphertext_length);
    297         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    298             /* The key has been destroyed. */
    299             return 1;
    300         }
    301         PSA_ASSERT(status);
    302     }
    303 
    304     if (usage & PSA_KEY_USAGE_DECRYPT) {
    305         psa_status_t verify_status =
    306             (usage & PSA_KEY_USAGE_ENCRYPT ?
    307              PSA_SUCCESS :
    308              PSA_ERROR_INVALID_SIGNATURE);
    309         status = psa_aead_decrypt(key, alg,
    310                                   nonce, nonce_length,
    311                                   NULL, 0,
    312                                   ciphertext, ciphertext_length,
    313                                   plaintext, sizeof(plaintext),
    314                                   &plaintext_length);
    315         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    316             /* The key has been destroyed. */
    317             return 1;
    318         }
    319         TEST_ASSERT(status == verify_status);
    320     }
    321 
    322     return 1;
    323 
    324 exit:
    325     psa_reset_key_attributes(&attributes);
    326     return 0;
    327 }
    328 
    329 static int can_sign_or_verify_message(psa_key_usage_t usage,
    330                                       psa_algorithm_t alg)
    331 {
    332     /* Sign-the-unspecified-hash algorithms can only be used with
    333      * {sign,verify}_hash, not with {sign,verify}_message. */
    334     if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
    335         return 0;
    336     }
    337     return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
    338                     PSA_KEY_USAGE_VERIFY_MESSAGE);
    339 }
    340 
    341 static int exercise_signature_key(mbedtls_svc_key_id_t key,
    342                                   psa_key_usage_t usage,
    343                                   psa_algorithm_t alg,
    344                                   int key_destroyable)
    345 {
    346     /* If the policy allows signing with any hash, just pick one. */
    347     psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
    348     if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
    349         usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
    350                  PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
    351 #if defined(KNOWN_SUPPORTED_HASH_ALG)
    352         hash_alg = KNOWN_SUPPORTED_HASH_ALG;
    353         alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
    354 #else
    355         TEST_FAIL("No hash algorithm for hash-and-sign testing");
    356 #endif
    357     }
    358     psa_status_t status = PSA_SUCCESS;
    359 
    360     if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
    361         PSA_ALG_IS_SIGN_HASH(alg)) {
    362         unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
    363         size_t payload_length = 16;
    364         unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
    365         size_t signature_length = sizeof(signature);
    366 
    367         /* Some algorithms require the payload to have the size of
    368          * the hash encoded in the algorithm. Use this input size
    369          * even for algorithms that allow other input sizes. */
    370         if (hash_alg != 0) {
    371             payload_length = PSA_HASH_LENGTH(hash_alg);
    372         }
    373 
    374         if (usage & PSA_KEY_USAGE_SIGN_HASH) {
    375             status = psa_sign_hash(key, alg,
    376                                    payload, payload_length,
    377                                    signature, sizeof(signature),
    378                                    &signature_length);
    379             if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    380                 /* The key has been destroyed. */
    381                 return 1;
    382             }
    383             PSA_ASSERT(status);
    384         }
    385 
    386         if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
    387             psa_status_t verify_status =
    388                 (usage & PSA_KEY_USAGE_SIGN_HASH ?
    389                  PSA_SUCCESS :
    390                  PSA_ERROR_INVALID_SIGNATURE);
    391             status = psa_verify_hash(key, alg,
    392                                      payload, payload_length,
    393                                      signature, signature_length);
    394             if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    395                 /* The key has been destroyed. */
    396                 return 1;
    397             }
    398             TEST_ASSERT(status == verify_status);
    399         }
    400     }
    401 
    402     if (can_sign_or_verify_message(usage, alg)) {
    403         unsigned char message[256] = "Hello, world...";
    404         unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
    405         size_t message_length = 16;
    406         size_t signature_length = sizeof(signature);
    407 
    408         if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
    409             status = psa_sign_message(key, alg,
    410                                       message, message_length,
    411                                       signature, sizeof(signature),
    412                                       &signature_length);
    413             if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    414                 /* The key has been destroyed. */
    415                 return 1;
    416             }
    417             PSA_ASSERT(status);
    418         }
    419 
    420         if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
    421             psa_status_t verify_status =
    422                 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
    423                  PSA_SUCCESS :
    424                  PSA_ERROR_INVALID_SIGNATURE);
    425             status = psa_verify_message(key, alg,
    426                                         message, message_length,
    427                                         signature, signature_length);
    428             if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    429                 /* The key has been destroyed. */
    430                 return 1;
    431             }
    432             TEST_ASSERT(status == verify_status);
    433         }
    434     }
    435 
    436     return 1;
    437 
    438 exit:
    439     return 0;
    440 }
    441 
    442 static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
    443                                               psa_key_usage_t usage,
    444                                               psa_algorithm_t alg,
    445                                               int key_destroyable)
    446 {
    447     unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
    448         "Hello, world...";
    449     unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
    450         "(wabblewebblewibblewobblewubble)";
    451     size_t ciphertext_length = sizeof(ciphertext);
    452     size_t plaintext_length = 16;
    453     psa_status_t status = PSA_SUCCESS;
    454     if (usage & PSA_KEY_USAGE_ENCRYPT) {
    455         status = psa_asymmetric_encrypt(key, alg,
    456                                         plaintext, plaintext_length,
    457                                         NULL, 0,
    458                                         ciphertext, sizeof(ciphertext),
    459                                         &ciphertext_length);
    460         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    461             /* The key has been destroyed. */
    462             return 1;
    463         }
    464         PSA_ASSERT(status);
    465     }
    466 
    467     if (usage & PSA_KEY_USAGE_DECRYPT) {
    468         status = psa_asymmetric_decrypt(key, alg,
    469                                         ciphertext, ciphertext_length,
    470                                         NULL, 0,
    471                                         plaintext, sizeof(plaintext),
    472                                         &plaintext_length);
    473         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    474             /* The key has been destroyed. */
    475             return 1;
    476         }
    477         TEST_ASSERT(status == PSA_SUCCESS ||
    478                     ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
    479                      (status == PSA_ERROR_INVALID_ARGUMENT ||
    480                       status == PSA_ERROR_INVALID_PADDING)));
    481     }
    482 
    483     return 1;
    484 
    485 exit:
    486     return 0;
    487 }
    488 
    489 int mbedtls_test_psa_setup_key_derivation_wrap(
    490     psa_key_derivation_operation_t *operation,
    491     mbedtls_svc_key_id_t key,
    492     psa_algorithm_t alg,
    493     const unsigned char *input1, size_t input1_length,
    494     const unsigned char *input2, size_t input2_length,
    495     size_t capacity, int key_destroyable)
    496 {
    497     PSA_ASSERT(psa_key_derivation_setup(operation, alg));
    498     psa_status_t status = PSA_SUCCESS;
    499     if (PSA_ALG_IS_HKDF(alg)) {
    500         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
    501                                                   PSA_KEY_DERIVATION_INPUT_SALT,
    502                                                   input1, input1_length));
    503         status = psa_key_derivation_input_key(operation,
    504                                               PSA_KEY_DERIVATION_INPUT_SECRET,
    505                                               key);
    506         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    507             /* The key has been destroyed. */
    508             return 1;
    509         }
    510         PSA_ASSERT(status);
    511         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
    512                                                   PSA_KEY_DERIVATION_INPUT_INFO,
    513                                                   input2,
    514                                                   input2_length));
    515     } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
    516         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
    517                                                   PSA_KEY_DERIVATION_INPUT_SALT,
    518                                                   input1, input1_length));
    519         status = psa_key_derivation_input_key(operation,
    520                                               PSA_KEY_DERIVATION_INPUT_SECRET,
    521                                               key);
    522         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    523             /* The key has been destroyed. */
    524             return 1;
    525         }
    526         PSA_ASSERT(status);
    527     } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
    528         status = psa_key_derivation_input_key(operation,
    529                                               PSA_KEY_DERIVATION_INPUT_SECRET,
    530                                               key);
    531         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    532             /* The key has been destroyed. */
    533             return 1;
    534         }
    535         PSA_ASSERT(status);
    536         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
    537                                                   PSA_KEY_DERIVATION_INPUT_INFO,
    538                                                   input2,
    539                                                   input2_length));
    540     } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
    541                PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
    542         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
    543                                                   PSA_KEY_DERIVATION_INPUT_SEED,
    544                                                   input1, input1_length));
    545         status = psa_key_derivation_input_key(operation,
    546                                               PSA_KEY_DERIVATION_INPUT_SECRET,
    547                                               key);
    548         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    549             /* The key has been destroyed. */
    550             return 1;
    551         }
    552         PSA_ASSERT(status);
    553         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
    554                                                   PSA_KEY_DERIVATION_INPUT_LABEL,
    555                                                   input2, input2_length));
    556     } else if (PSA_ALG_IS_PBKDF2(alg)) {
    557         PSA_ASSERT(psa_key_derivation_input_integer(operation,
    558                                                     PSA_KEY_DERIVATION_INPUT_COST,
    559                                                     1U));
    560         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
    561                                                   PSA_KEY_DERIVATION_INPUT_SALT,
    562                                                   input2,
    563                                                   input2_length));
    564         status = psa_key_derivation_input_key(operation,
    565                                               PSA_KEY_DERIVATION_INPUT_PASSWORD,
    566                                               key);
    567         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    568             /* The key has been destroyed. */
    569             return 1;
    570         }
    571         PSA_ASSERT(status);
    572     } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
    573         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
    574                                                   PSA_KEY_DERIVATION_INPUT_SECRET,
    575                                                   input1, input1_length));
    576     } else {
    577         TEST_FAIL("Key derivation algorithm not supported");
    578     }
    579 
    580     if (capacity != SIZE_MAX) {
    581         PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
    582     }
    583 
    584     return 1;
    585 
    586 exit:
    587     return 0;
    588 }
    589 
    590 
    591 static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
    592                                        psa_key_usage_t usage,
    593                                        psa_algorithm_t alg,
    594                                        int key_destroyable)
    595 {
    596     psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
    597     unsigned char input1[] = "Input 1";
    598     size_t input1_length = sizeof(input1);
    599     unsigned char input2[] = "Input 2";
    600     size_t input2_length = sizeof(input2);
    601     unsigned char output[1];
    602     size_t capacity = sizeof(output);
    603 
    604     if (usage & PSA_KEY_USAGE_DERIVE) {
    605         if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
    606                                                         input1, input1_length,
    607                                                         input2, input2_length,
    608                                                         capacity, key_destroyable)) {
    609             goto exit;
    610         }
    611 
    612         psa_status_t status = psa_key_derivation_output_bytes(&operation,
    613                                                               output,
    614                                                               capacity);
    615         if (key_destroyable && status == PSA_ERROR_BAD_STATE) {
    616             /* The key has been destroyed. */
    617             PSA_ASSERT(psa_key_derivation_abort(&operation));
    618         } else {
    619             PSA_ASSERT(status);
    620             PSA_ASSERT(psa_key_derivation_abort(&operation));
    621         }
    622     }
    623 
    624     return 1;
    625 
    626 exit:
    627     return 0;
    628 }
    629 
    630 /* We need two keys to exercise key agreement. Exercise the
    631  * private key against its own public key. */
    632 psa_status_t mbedtls_test_psa_key_agreement_with_self(
    633     psa_key_derivation_operation_t *operation,
    634     mbedtls_svc_key_id_t key, int key_destroyable)
    635 {
    636     psa_key_type_t private_key_type;
    637     psa_key_type_t public_key_type;
    638     size_t key_bits;
    639     uint8_t *public_key = NULL;
    640     size_t public_key_length;
    641     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    642 
    643     psa_status_t status = psa_get_key_attributes(key, &attributes);
    644     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    645         /* The key has been destroyed. */
    646         psa_reset_key_attributes(&attributes);
    647         return PSA_SUCCESS;
    648     }
    649     PSA_ASSERT(status);
    650 
    651     private_key_type = psa_get_key_type(&attributes);
    652     key_bits = psa_get_key_bits(&attributes);
    653     public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
    654     public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
    655     TEST_CALLOC(public_key, public_key_length);
    656     status = psa_export_public_key(key, public_key, public_key_length,
    657                                    &public_key_length);
    658     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    659         /* The key has been destroyed. */
    660         status = PSA_SUCCESS;
    661         goto exit;
    662     }
    663     PSA_ASSERT(status);
    664 
    665     status = psa_key_derivation_key_agreement(
    666         operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
    667         public_key, public_key_length);
    668     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    669         /* The key has been destroyed. */
    670         status = PSA_SUCCESS;
    671         goto exit;
    672     }
    673 exit:
    674     /*
    675      * Key attributes may have been returned by psa_get_key_attributes()
    676      * thus reset them as required.
    677      */
    678     psa_reset_key_attributes(&attributes);
    679 
    680     mbedtls_free(public_key);
    681     return status;
    682 }
    683 
    684 /* We need two keys to exercise key agreement. Exercise the
    685  * private key against its own public key. */
    686 psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
    687     psa_algorithm_t alg,
    688     mbedtls_svc_key_id_t key,
    689     int key_destroyable)
    690 {
    691     psa_key_type_t private_key_type;
    692     psa_key_type_t public_key_type;
    693     size_t key_bits;
    694     uint8_t *public_key = NULL;
    695     size_t public_key_length;
    696     uint8_t output[1024];
    697     size_t output_length;
    698 
    699 #if MBEDTLS_VERSION_MAJOR >= 4
    700     uint8_t *exported = NULL;
    701     size_t exported_size = 0;
    702     size_t exported_length = 0;
    703 
    704     psa_key_attributes_t export_attributes = PSA_KEY_ATTRIBUTES_INIT;
    705 
    706     mbedtls_svc_key_id_t shared_secret_id = MBEDTLS_SVC_KEY_ID_INIT;
    707     psa_key_attributes_t shared_secret_attributes = PSA_KEY_ATTRIBUTES_INIT;
    708 
    709     psa_key_agreement_iop_t iop_operation = psa_key_agreement_iop_init();
    710 #endif /* MBEDTLS_VERSION_MAJOR >= 4 */
    711 
    712     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    713 
    714     psa_status_t status = psa_get_key_attributes(key, &attributes);
    715     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    716         /* The key has been destroyed. */
    717         psa_reset_key_attributes(&attributes);
    718         return PSA_SUCCESS;
    719     }
    720     PSA_ASSERT(status);
    721 
    722     private_key_type = psa_get_key_type(&attributes);
    723     key_bits = psa_get_key_bits(&attributes);
    724     public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
    725     public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
    726     TEST_CALLOC(public_key, public_key_length);
    727     status = psa_export_public_key(key,
    728                                    public_key, public_key_length,
    729                                    &public_key_length);
    730     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    731         /* The key has been destroyed. */
    732         status = PSA_SUCCESS;
    733         goto exit;
    734     }
    735     PSA_ASSERT(status);
    736 
    737     status = psa_raw_key_agreement(
    738         alg, key, public_key, public_key_length,
    739         output, sizeof(output), &output_length);
    740     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    741         /* The key has been destroyed. */
    742         status = PSA_SUCCESS;
    743         goto exit;
    744     }
    745     if (status == PSA_SUCCESS) {
    746         TEST_ASSERT(output_length <=
    747                     PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
    748                                                       key_bits));
    749         TEST_ASSERT(output_length <=
    750                     PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
    751     }
    752 
    753 #if MBEDTLS_VERSION_MAJOR >= 4
    754     psa_status_t raw_status = status;
    755 
    756     psa_set_key_type(&shared_secret_attributes, PSA_KEY_TYPE_DERIVE);
    757     psa_set_key_usage_flags(&shared_secret_attributes,
    758                             PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT);
    759 
    760     status = psa_key_agreement(key, public_key, public_key_length, alg,
    761                                &shared_secret_attributes, &shared_secret_id);
    762 
    763     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    764         /* The key has been destroyed. */
    765         status = PSA_SUCCESS;
    766         goto exit;
    767     }
    768 
    769     /* In this function, we expect either success or a validation failure,
    770      * which should be identical for raw output and key output. So flag any
    771      * discrepancy between the two (in particular a key creation failure)
    772      * as a test failure. */
    773     TEST_EQUAL(raw_status, status);
    774 
    775     if (status == PSA_SUCCESS) {
    776         status = psa_get_key_attributes(shared_secret_id, &export_attributes);
    777         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    778             /* The key has been destroyed. */
    779             status = PSA_SUCCESS;
    780             goto exit;
    781         }
    782 
    783         exported_size =
    784             PSA_EXPORT_KEY_OUTPUT_SIZE(psa_get_key_type(&export_attributes),
    785                                        psa_get_key_bits(&export_attributes));
    786         TEST_CALLOC(exported, exported_size);
    787 
    788         status = psa_export_key(shared_secret_id,
    789                                 exported, exported_size, &exported_length);
    790         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    791             /* The key has been destroyed. */
    792             status = PSA_SUCCESS;
    793         } else {
    794             PSA_ASSERT(status);
    795             TEST_MEMORY_COMPARE(exported, exported_length,
    796                                 output, output_length);
    797         }
    798     }
    799 
    800  #if defined(MBEDTLS_ECP_RESTARTABLE) && defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
    801 
    802     psa_destroy_key(shared_secret_id);
    803 
    804     if (PSA_KEY_TYPE_IS_ECC(private_key_type)) {
    805 
    806         psa_interruptible_set_max_ops(1);
    807 
    808         status = psa_key_agreement_iop_setup(&iop_operation, key, public_key,
    809                                              public_key_length, alg,
    810                                              &shared_secret_attributes);
    811 
    812         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    813             /* The key has been destroyed. */
    814             status = PSA_SUCCESS;
    815             goto exit;
    816         }
    817 
    818         /* In this function, we expect either success or a validation failure,
    819          * which should be identical for one-shot and interruptible. For an
    820          * interruptible operation, we insist on detecting error conditions
    821          * early, in setup() rather than complete(). So flag any discrepancy
    822          * between one-shot and interruptible-setup as a test failure. */
    823         TEST_EQUAL(raw_status, status);
    824 
    825         if (status == PSA_SUCCESS) {
    826 
    827             do {
    828                 status = psa_key_agreement_iop_complete(&iop_operation,
    829                                                         &shared_secret_id);
    830             } while (status == PSA_OPERATION_INCOMPLETE);
    831 
    832             if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    833                 /* The key has been destroyed. */
    834                 status = PSA_SUCCESS;
    835             } else {
    836                 PSA_ASSERT(status);
    837                 status = psa_export_key(shared_secret_id,
    838                                         exported, exported_size,
    839                                         &exported_length);
    840                 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    841                     /* The key has been destroyed. */
    842                     status = PSA_SUCCESS;
    843                 } else {
    844                     PSA_ASSERT(status);
    845                     TEST_MEMORY_COMPARE(exported, exported_length,
    846                                         output, output_length);
    847                 }
    848             }
    849         }
    850     } else {
    851         TEST_EQUAL(psa_key_agreement_iop_setup(&iop_operation, key, public_key,
    852                                                public_key_length, alg,
    853                                                &shared_secret_attributes),
    854                    PSA_ERROR_INVALID_ARGUMENT);
    855     }
    856 
    857 #endif // defined(MBEDTLS_ECP_RESTARTABLE) && defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
    858 #endif /* MBEDTLS_VERSION_MAJOR >= 4 */
    859 
    860 exit:
    861     /*
    862      * Key attributes may have been returned by psa_get_key_attributes()
    863      * thus reset them as required.
    864      */
    865     psa_reset_key_attributes(&attributes);
    866 
    867 #if MBEDTLS_VERSION_MAJOR >= 4
    868     psa_reset_key_attributes(&export_attributes);
    869 
    870     /* Make sure to reset and free derived key attributes and slot. */
    871     psa_reset_key_attributes(&shared_secret_attributes);
    872     psa_destroy_key(shared_secret_id);
    873 
    874     mbedtls_free(exported);
    875     psa_key_agreement_iop_abort(&iop_operation);
    876 #endif /* MBEDTLS_VERSION_MAJOR >= 4 */
    877 
    878     mbedtls_free(public_key);
    879     return status;
    880 }
    881 
    882 static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
    883                                           psa_key_usage_t usage,
    884                                           psa_algorithm_t alg,
    885                                           int key_destroyable)
    886 {
    887     int ok = 0;
    888 
    889     if (usage & PSA_KEY_USAGE_DERIVE) {
    890         /* We need two keys to exercise key agreement. Exercise the
    891          * private key against its own public key. */
    892         PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key,
    893                                                                 key_destroyable));
    894     }
    895     ok = 1;
    896 
    897 exit:
    898     return ok;
    899 }
    900 
    901 static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
    902                                       psa_key_usage_t usage,
    903                                       psa_algorithm_t alg,
    904                                       int key_destroyable)
    905 {
    906     psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
    907     unsigned char input[1] = { 0 };
    908     unsigned char output[1];
    909     int ok = 0;
    910     psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
    911     psa_status_t expected_key_agreement_status = PSA_SUCCESS;
    912 
    913     if (usage & PSA_KEY_USAGE_DERIVE) {
    914         /* We need two keys to exercise key agreement. Exercise the
    915          * private key against its own public key. */
    916         PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
    917         if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
    918             PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
    919             PSA_ASSERT(psa_key_derivation_input_bytes(
    920                            &operation, PSA_KEY_DERIVATION_INPUT_SEED,
    921                            input, sizeof(input)));
    922         }
    923 
    924         if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
    925             PSA_ASSERT(psa_key_derivation_input_bytes(
    926                            &operation, PSA_KEY_DERIVATION_INPUT_SALT,
    927                            input, sizeof(input)));
    928         }
    929 
    930         /* For HKDF_EXPAND input secret may fail as secret size may not match
    931            to expected PRK size. In practice it means that key bits must match
    932            hash length. Otherwise test should fail with INVALID_ARGUMENT. */
    933         if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
    934             psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    935             psa_status_t status = psa_get_key_attributes(key, &attributes);
    936             if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
    937                 /* The key has been destroyed. */
    938                 ok = 1;
    939             }
    940             PSA_ASSERT(status);
    941             size_t key_bits = psa_get_key_bits(&attributes);
    942             psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
    943 
    944             if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
    945                 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
    946             }
    947         }
    948 
    949         TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key,
    950                                                             key_destroyable),
    951                    expected_key_agreement_status);
    952 
    953         if (expected_key_agreement_status != PSA_SUCCESS) {
    954             return 1;
    955         }
    956 
    957         if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
    958             PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
    959             PSA_ASSERT(psa_key_derivation_input_bytes(
    960                            &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
    961                            input, sizeof(input)));
    962         } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
    963             PSA_ASSERT(psa_key_derivation_input_bytes(
    964                            &operation, PSA_KEY_DERIVATION_INPUT_INFO,
    965                            input, sizeof(input)));
    966         }
    967         PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
    968                                                    output,
    969                                                    sizeof(output)));
    970         PSA_ASSERT(psa_key_derivation_abort(&operation));
    971     }
    972     ok = 1;
    973 
    974 exit:
    975     return ok;
    976 }
    977 
    978 int mbedtls_test_psa_exported_key_sanity_check(
    979     psa_key_type_t type, size_t bits,
    980     const uint8_t *exported, size_t exported_length)
    981 {
    982     TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
    983 
    984     if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
    985         TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
    986     } else
    987 
    988 #if defined(MBEDTLS_ASN1_PARSE_C)
    989     if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
    990         uint8_t *p = (uint8_t *) exported;
    991         const uint8_t *end = exported + exported_length;
    992         size_t len;
    993         /*   RSAPrivateKey ::= SEQUENCE {
    994          *       version             INTEGER,  -- must be 0
    995          *       modulus             INTEGER,  -- n
    996          *       publicExponent      INTEGER,  -- e
    997          *       privateExponent     INTEGER,  -- d
    998          *       prime1              INTEGER,  -- p
    999          *       prime2              INTEGER,  -- q
   1000          *       exponent1           INTEGER,  -- d mod (p-1)
   1001          *       exponent2           INTEGER,  -- d mod (q-1)
   1002          *       coefficient         INTEGER,  -- (inverse of q) mod p
   1003          *   }
   1004          */
   1005         TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
   1006                                         MBEDTLS_ASN1_SEQUENCE |
   1007                                         MBEDTLS_ASN1_CONSTRUCTED), 0);
   1008         TEST_EQUAL(len, end - p);
   1009         if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
   1010             goto exit;
   1011         }
   1012         if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
   1013             goto exit;
   1014         }
   1015         if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
   1016             goto exit;
   1017         }
   1018         /* Require d to be at least half the size of n. */
   1019         if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
   1020             goto exit;
   1021         }
   1022         /* Require p and q to be at most half the size of n, rounded up. */
   1023         if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
   1024             goto exit;
   1025         }
   1026         if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
   1027             goto exit;
   1028         }
   1029         if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
   1030             goto exit;
   1031         }
   1032         if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
   1033             goto exit;
   1034         }
   1035         if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
   1036             goto exit;
   1037         }
   1038         TEST_EQUAL(p - end, 0);
   1039 
   1040         TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
   1041     } else
   1042 #endif /* MBEDTLS_ASN1_PARSE_C */
   1043 
   1044     if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
   1045         /* Just the secret value */
   1046         TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
   1047 
   1048         TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
   1049     } else
   1050 
   1051 #if defined(MBEDTLS_ASN1_PARSE_C)
   1052     if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
   1053         uint8_t *p = (uint8_t *) exported;
   1054         const uint8_t *end = exported + exported_length;
   1055         size_t len;
   1056         /*   RSAPublicKey ::= SEQUENCE {
   1057          *      modulus            INTEGER,    -- n
   1058          *      publicExponent     INTEGER  }  -- e
   1059          */
   1060         TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
   1061                                         MBEDTLS_ASN1_SEQUENCE |
   1062                                         MBEDTLS_ASN1_CONSTRUCTED),
   1063                    0);
   1064         TEST_EQUAL(len, end - p);
   1065         if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
   1066             goto exit;
   1067         }
   1068         if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
   1069             goto exit;
   1070         }
   1071         TEST_EQUAL(p - end, 0);
   1072 
   1073 
   1074         TEST_ASSERT(exported_length <=
   1075                     PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
   1076         TEST_ASSERT(exported_length <=
   1077                     PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
   1078     } else
   1079 #endif /* MBEDTLS_ASN1_PARSE_C */
   1080 
   1081     if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
   1082 
   1083         TEST_ASSERT(exported_length <=
   1084                     PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
   1085         TEST_ASSERT(exported_length <=
   1086                     PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
   1087 
   1088         if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
   1089             /* The representation of an ECC Montgomery public key is
   1090              * the raw compressed point */
   1091             TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
   1092         } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
   1093             /* The representation of an ECC Edwards public key is
   1094              * the raw compressed point */
   1095             TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
   1096         } else {
   1097             /* The representation of an ECC Weierstrass public key is:
   1098              *      - The byte 0x04;
   1099              *      - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
   1100              *      - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
   1101              *      - where m is the bit size associated with the curve.
   1102              */
   1103             TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
   1104             TEST_EQUAL(exported[0], 4);
   1105         }
   1106     } else
   1107     if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
   1108         TEST_ASSERT(exported_length ==
   1109                     PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
   1110         TEST_ASSERT(exported_length <=
   1111                     PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
   1112     } else {
   1113         (void) exported;
   1114         TEST_FAIL("Sanity check not implemented for this key type");
   1115     }
   1116 
   1117 #if defined(MBEDTLS_DES_C)
   1118     if (type == PSA_KEY_TYPE_DES) {
   1119         /* Check the parity bits. */
   1120         unsigned i;
   1121         for (i = 0; i < bits / 8; i++) {
   1122             unsigned bit_count = 0;
   1123             unsigned m;
   1124             for (m = 1; m <= 0x100; m <<= 1) {
   1125                 if (exported[i] & m) {
   1126                     ++bit_count;
   1127                 }
   1128             }
   1129             TEST_ASSERT(bit_count % 2 != 0);
   1130         }
   1131     }
   1132 #endif
   1133 
   1134     return 1;
   1135 
   1136 exit:
   1137     return 0;
   1138 }
   1139 
   1140 static int exercise_export_key(mbedtls_svc_key_id_t key,
   1141                                psa_key_usage_t usage,
   1142                                int key_destroyable)
   1143 {
   1144     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
   1145     uint8_t *exported = NULL;
   1146     size_t exported_size = 0;
   1147     size_t exported_length = 0;
   1148     int ok = 0;
   1149 
   1150     psa_status_t status = psa_get_key_attributes(key, &attributes);
   1151     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
   1152         /* The key has been destroyed. */
   1153         psa_reset_key_attributes(&attributes);
   1154         return 1;
   1155     }
   1156     PSA_ASSERT(status);
   1157 
   1158     exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
   1159         psa_get_key_type(&attributes),
   1160         psa_get_key_bits(&attributes));
   1161     TEST_CALLOC(exported, exported_size);
   1162 
   1163     status = psa_export_key(key, exported, exported_size, &exported_length);
   1164     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
   1165         /* The key has been destroyed. */
   1166         ok = 1;
   1167         goto exit;
   1168     } else if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
   1169                !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
   1170         TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED);
   1171         ok = 1;
   1172         goto exit;
   1173     }
   1174     PSA_ASSERT(status);
   1175     ok = mbedtls_test_psa_exported_key_sanity_check(
   1176         psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
   1177         exported, exported_length);
   1178 
   1179 exit:
   1180     /*
   1181      * Key attributes may have been returned by psa_get_key_attributes()
   1182      * thus reset them as required.
   1183      */
   1184     psa_reset_key_attributes(&attributes);
   1185 
   1186     mbedtls_free(exported);
   1187     return ok;
   1188 }
   1189 
   1190 static int exercise_export_public_key(mbedtls_svc_key_id_t key,
   1191                                       int key_destroyable)
   1192 {
   1193     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
   1194     psa_key_type_t public_type;
   1195     uint8_t *exported = NULL;
   1196     size_t exported_size = 0;
   1197     size_t exported_length = 0;
   1198     int ok = 0;
   1199 
   1200     psa_status_t status = psa_get_key_attributes(key, &attributes);
   1201     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
   1202         /* The key has been destroyed. */
   1203         psa_reset_key_attributes(&attributes);
   1204         return 1;
   1205     }
   1206     PSA_ASSERT(status);
   1207     if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
   1208         exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
   1209             psa_get_key_type(&attributes),
   1210             psa_get_key_bits(&attributes));
   1211         TEST_CALLOC(exported, exported_size);
   1212 
   1213         status = psa_export_public_key(key, exported,
   1214                                        exported_size, &exported_length);
   1215         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
   1216             /* The key has been destroyed. */
   1217             ok = 1;
   1218             goto exit;
   1219         }
   1220         TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
   1221         ok = 1;
   1222         goto exit;
   1223     }
   1224 
   1225     public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
   1226         psa_get_key_type(&attributes));
   1227     exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
   1228                                                       psa_get_key_bits(&attributes));
   1229     TEST_CALLOC(exported, exported_size);
   1230 
   1231     status = psa_export_public_key(key, exported,
   1232                                    exported_size, &exported_length);
   1233     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
   1234         /* The key has been destroyed. */
   1235         ok = 1;
   1236         goto exit;
   1237     }
   1238     PSA_ASSERT(status);
   1239     ok = mbedtls_test_psa_exported_key_sanity_check(
   1240         public_type, psa_get_key_bits(&attributes),
   1241         exported, exported_length);
   1242 
   1243 exit:
   1244     /*
   1245      * Key attributes may have been returned by psa_get_key_attributes()
   1246      * thus reset them as required.
   1247      */
   1248     psa_reset_key_attributes(&attributes);
   1249 
   1250     mbedtls_free(exported);
   1251     return ok;
   1252 }
   1253 
   1254 int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
   1255                                   psa_key_usage_t usage,
   1256                                   psa_algorithm_t alg,
   1257                                   int key_destroyable)
   1258 {
   1259     int ok = 0;
   1260 
   1261     if (!check_key_attributes_sanity(key, key_destroyable)) {
   1262         return 0;
   1263     }
   1264 
   1265     if (alg == 0) {
   1266         ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
   1267     } else if (PSA_ALG_IS_MAC(alg)) {
   1268         ok = exercise_mac_key(key, usage, alg, key_destroyable);
   1269     } else if (PSA_ALG_IS_CIPHER(alg)) {
   1270         ok = exercise_cipher_key(key, usage, alg, key_destroyable);
   1271     } else if (PSA_ALG_IS_AEAD(alg)) {
   1272         ok = exercise_aead_key(key, usage, alg, key_destroyable);
   1273     } else if (PSA_ALG_IS_SIGN(alg)) {
   1274         ok = exercise_signature_key(key, usage, alg, key_destroyable);
   1275     } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
   1276         ok = exercise_asymmetric_encryption_key(key, usage, alg,
   1277                                                 key_destroyable);
   1278     } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
   1279         ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
   1280     } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
   1281         ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
   1282     } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
   1283         ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
   1284     } else {
   1285         TEST_FAIL("No code to exercise this category of algorithm");
   1286     }
   1287 
   1288     ok = ok && exercise_export_key(key,
   1289                                    usage,
   1290                                    key_destroyable);
   1291     ok = ok && exercise_export_public_key(key,
   1292                                           key_destroyable);
   1293 
   1294 exit:
   1295     return ok;
   1296 }
   1297 
   1298 psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
   1299                                                    psa_algorithm_t alg)
   1300 {
   1301     if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
   1302         if (PSA_ALG_IS_SIGN_HASH(alg)) {
   1303             if (PSA_ALG_SIGN_GET_HASH(alg)) {
   1304                 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
   1305                        PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
   1306                        PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
   1307                        PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
   1308             }
   1309         } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
   1310             return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
   1311                    PSA_KEY_USAGE_VERIFY_MESSAGE :
   1312                    PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
   1313         }
   1314 
   1315         return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
   1316                PSA_KEY_USAGE_VERIFY_HASH :
   1317                PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
   1318     } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
   1319                PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
   1320         return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
   1321                PSA_KEY_USAGE_ENCRYPT :
   1322                PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
   1323     } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
   1324                PSA_ALG_IS_KEY_AGREEMENT(alg)) {
   1325         return PSA_KEY_USAGE_DERIVE;
   1326     } else {
   1327         return 0;
   1328     }
   1329 
   1330 }
   1331 
   1332 int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
   1333 {
   1334     /* Reject algorithms that we know are not supported. Default to
   1335      * attempting exercise, so that if an algorithm is missing from this
   1336      * function, the result will be a test failure and not silently
   1337      * omitting exercise. */
   1338 #if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
   1339     if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
   1340         return 0;
   1341     }
   1342 #endif
   1343 #if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
   1344     if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
   1345         return 0;
   1346     }
   1347 #endif
   1348 #if !defined(PSA_WANT_ALG_RSA_PSS)
   1349     if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
   1350         return 0;
   1351     }
   1352 #endif
   1353 #if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
   1354     if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
   1355         return 0;
   1356     }
   1357 #endif
   1358 #if !defined(PSA_WANT_ALG_ECDSA)
   1359     if (PSA_ALG_IS_ECDSA(alg)) {
   1360         return 0;
   1361     }
   1362 #endif
   1363 #if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
   1364     if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
   1365         return 0;
   1366     }
   1367 #endif
   1368 #if !defined(PSA_WANT_ALG_ECDH)
   1369     if (PSA_ALG_IS_ECDH(alg)) {
   1370         return 0;
   1371     }
   1372 #endif
   1373     (void) alg;
   1374     return 1;
   1375 }
   1376 
   1377 #if defined(MBEDTLS_PK_C)
   1378 int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
   1379                                         const mbedtls_pk_context *pk)
   1380 {
   1381     psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
   1382     psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
   1383     int ok = 0;
   1384 
   1385     PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
   1386     psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
   1387     mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
   1388 
   1389     TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
   1390                 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
   1391     TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
   1392 
   1393     uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
   1394     const uint8_t *pk_public = NULL;
   1395     size_t pk_public_length = 0;
   1396 
   1397     switch (pk_type) {
   1398 #if defined(MBEDTLS_RSA_C)
   1399         case MBEDTLS_PK_RSA:
   1400             TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
   1401             const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
   1402             uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
   1403             uint8_t *cursor = end;
   1404             TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
   1405                                                   pk_public_buffer, &cursor));
   1406             pk_public = cursor;
   1407             pk_public_length = end - pk_public;
   1408             break;
   1409 #endif
   1410 
   1411 #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
   1412         case MBEDTLS_PK_ECKEY:
   1413         case MBEDTLS_PK_ECKEY_DH:
   1414         case MBEDTLS_PK_ECDSA:
   1415             TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
   1416             TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
   1417             pk_public = pk->pub_raw;
   1418             pk_public_length = pk->pub_raw_len;
   1419             break;
   1420 #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
   1421 
   1422 #if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
   1423         case MBEDTLS_PK_ECKEY:
   1424         case MBEDTLS_PK_ECKEY_DH:
   1425         case MBEDTLS_PK_ECDSA:
   1426             TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
   1427             const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
   1428             TEST_EQUAL(mbedtls_ecp_write_public_key(
   1429                            ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
   1430                            pk_public_buffer, sizeof(pk_public_buffer)), 0);
   1431             pk_public = pk_public_buffer;
   1432             break;
   1433 #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY && !MBEDTLS_PK_USE_PSA_EC_DATA */
   1434 
   1435 #if defined(MBEDTLS_USE_PSA_CRYPTO)
   1436         case MBEDTLS_PK_OPAQUE:
   1437             PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
   1438             psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
   1439             TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
   1440                        PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
   1441             PSA_ASSERT(psa_export_public_key(psa_key,
   1442                                              pk_public_buffer,
   1443                                              sizeof(pk_public_buffer),
   1444                                              &pk_public_length));
   1445             pk_public = pk_public_buffer;
   1446             break;
   1447 #endif /* MBEDTLS_USE_PSA_CRYPTO */
   1448 
   1449         default:
   1450             TEST_FAIL("pk type not supported");
   1451     }
   1452 
   1453     uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
   1454     size_t psa_public_length = 0;
   1455     PSA_ASSERT(psa_export_public_key(psa_key,
   1456                                      psa_public, sizeof(psa_public),
   1457                                      &psa_public_length));
   1458     TEST_MEMORY_COMPARE(pk_public, pk_public_length,
   1459                         psa_public, psa_public_length);
   1460 
   1461     ok = 1;
   1462 
   1463 exit:
   1464     psa_reset_key_attributes(&psa_attributes);
   1465     psa_reset_key_attributes(&pk_attributes);
   1466     return ok;
   1467 }
   1468 #endif /* MBEDTLS_PK_C */
   1469 
   1470 #endif /* MBEDTLS_PSA_CRYPTO_C || MBEDTLS_PSA_CRYPTO_CLIENT */