/** Code to exercise a PSA key object, i.e. validate that it seems well-formed
 * and can do what it is supposed to do.
 */

/*
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
 */

#include <test/helpers.h>
#include <test/macros.h>
#include <test/psa_exercise_key.h>

#if defined(MBEDTLS_PSA_CRYPTO_C)

#include <mbedtls/asn1.h>
#include <psa/crypto.h>

#include <test/asn1_helpers.h>
#include <psa_crypto_slot_management.h>
#include <test/psa_crypto_helpers.h>

#if defined(MBEDTLS_PK_C)
#include <pk_internal.h>
#endif
#if defined(MBEDTLS_ECP_C)
#include <mbedtls/ecp.h>
#endif
#if defined(MBEDTLS_RSA_C)
#include <rsa_internal.h>
#endif

#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
{
    return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
           PSA_KEY_LOCATION_LOCAL_STORAGE;
}
#endif

static int check_key_attributes_sanity(mbedtls_svc_key_id_t key)
{
    int ok = 0;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_lifetime_t lifetime;
    mbedtls_svc_key_id_t id;
    psa_key_type_t type;
    size_t bits;

    PSA_ASSERT(psa_get_key_attributes(key, &attributes));
    lifetime = psa_get_key_lifetime(&attributes);
    id = psa_get_key_id(&attributes);
    type = psa_get_key_type(&attributes);
    bits = psa_get_key_bits(&attributes);

    /* Persistence */
    if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
        TEST_ASSERT(
            (PSA_KEY_ID_VOLATILE_MIN <=
             MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
            (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
             PSA_KEY_ID_VOLATILE_MAX));
    } else {
        TEST_ASSERT(
            (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
            (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
    }
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
    /* randomly-generated 64-bit constant, should never appear in test data */
    psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
    psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number);
    if (lifetime_is_dynamic_secure_element(lifetime)) {
        /* Mbed TLS currently always exposes the slot number to
         * applications. This is not mandated by the PSA specification
         * and may change in future versions. */
        TEST_EQUAL(status, 0);
        TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
    } else {
        TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
    }
#endif

    /* Type and size */
    TEST_ASSERT(type != 0);
    TEST_ASSERT(bits != 0);
    TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
    if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
        TEST_ASSERT(bits % 8 == 0);
    }

    /* MAX macros concerning specific key types */
    if (PSA_KEY_TYPE_IS_ECC(type)) {
        TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
    } else if (PSA_KEY_TYPE_IS_RSA(type)) {
        TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
    }
    TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);

    ok = 1;

exit:
    /*
     * Key attributes may have been returned by psa_get_key_attributes()
     * thus reset them as required.
     */
    psa_reset_key_attributes(&attributes);

    return ok;
}

static int exercise_mac_key(mbedtls_svc_key_id_t key,
                            psa_key_usage_t usage,
                            psa_algorithm_t alg)
{
    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
    const unsigned char input[] = "foo";
    unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
    size_t mac_length = sizeof(mac);

    /* Convert wildcard algorithm to exercisable algorithm */
    if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
        alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
    }

    if (usage & PSA_KEY_USAGE_SIGN_HASH) {
        PSA_ASSERT(psa_mac_sign_setup(&operation, key, alg));
        PSA_ASSERT(psa_mac_update(&operation,
                                  input, sizeof(input)));
        PSA_ASSERT(psa_mac_sign_finish(&operation,
                                       mac, sizeof(mac),
                                       &mac_length));
    }

    if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
        psa_status_t verify_status =
            (usage & PSA_KEY_USAGE_SIGN_HASH ?
             PSA_SUCCESS :
             PSA_ERROR_INVALID_SIGNATURE);
        PSA_ASSERT(psa_mac_verify_setup(&operation, key, alg));
        PSA_ASSERT(psa_mac_update(&operation,
                                  input, sizeof(input)));
        TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
                   verify_status);
    }

    return 1;

exit:
    psa_mac_abort(&operation);
    return 0;
}

static int exercise_cipher_key(mbedtls_svc_key_id_t key,
                               psa_key_usage_t usage,
                               psa_algorithm_t alg)
{
    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
    unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
    size_t iv_length;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_type_t key_type;
    const unsigned char plaintext[16] = "Hello, world...";
    unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
    size_t ciphertext_length = sizeof(ciphertext);
    unsigned char decrypted[sizeof(ciphertext)];
    size_t part_length;

    PSA_ASSERT(psa_get_key_attributes(key, &attributes));
    key_type = psa_get_key_type(&attributes);
    iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);

    if (usage & PSA_KEY_USAGE_ENCRYPT) {
        PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
        if (iv_length != 0) {
            PSA_ASSERT(psa_cipher_generate_iv(&operation,
                                              iv, sizeof(iv),
                                              &iv_length));
        }
        PSA_ASSERT(psa_cipher_update(&operation,
                                     plaintext, sizeof(plaintext),
                                     ciphertext, sizeof(ciphertext),
                                     &ciphertext_length));
        PSA_ASSERT(psa_cipher_finish(&operation,
                                     ciphertext + ciphertext_length,
                                     sizeof(ciphertext) - ciphertext_length,
                                     &part_length));
        ciphertext_length += part_length;
    }

    if (usage & PSA_KEY_USAGE_DECRYPT) {
        psa_status_t status;
        int maybe_invalid_padding = 0;
        if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
            maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
        }
        PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
        if (iv_length != 0) {
            PSA_ASSERT(psa_cipher_set_iv(&operation,
                                         iv, iv_length));
        }
        PSA_ASSERT(psa_cipher_update(&operation,
                                     ciphertext, ciphertext_length,
                                     decrypted, sizeof(decrypted),
                                     &part_length));
        status = psa_cipher_finish(&operation,
                                   decrypted + part_length,
                                   sizeof(decrypted) - part_length,
                                   &part_length);
        /* For a stream cipher, all inputs are valid. For a block cipher,
         * if the input is some arbitrary data rather than an actual
           ciphertext, a padding error is likely.  */
        if (maybe_invalid_padding) {
            TEST_ASSERT(status == PSA_SUCCESS ||
                        status == PSA_ERROR_INVALID_PADDING);
        } else {
            PSA_ASSERT(status);
        }
    }

    return 1;

exit:
    psa_cipher_abort(&operation);
    psa_reset_key_attributes(&attributes);
    return 0;
}

static int exercise_aead_key(mbedtls_svc_key_id_t key,
                             psa_key_usage_t usage,
                             psa_algorithm_t alg)
{
    unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
    size_t nonce_length;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_type_t key_type;
    unsigned char plaintext[16] = "Hello, world...";
    unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
    size_t ciphertext_length = sizeof(ciphertext);
    size_t plaintext_length = sizeof(ciphertext);

    /* Convert wildcard algorithm to exercisable algorithm */
    if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
        alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
    }

    PSA_ASSERT(psa_get_key_attributes(key, &attributes));
    key_type = psa_get_key_type(&attributes);
    nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);

    if (usage & PSA_KEY_USAGE_ENCRYPT) {
        PSA_ASSERT(psa_aead_encrypt(key, alg,
                                    nonce, nonce_length,
                                    NULL, 0,
                                    plaintext, sizeof(plaintext),
                                    ciphertext, sizeof(ciphertext),
                                    &ciphertext_length));
    }

    if (usage & PSA_KEY_USAGE_DECRYPT) {
        psa_status_t verify_status =
            (usage & PSA_KEY_USAGE_ENCRYPT ?
             PSA_SUCCESS :
             PSA_ERROR_INVALID_SIGNATURE);
        TEST_EQUAL(psa_aead_decrypt(key, alg,
                                    nonce, nonce_length,
                                    NULL, 0,
                                    ciphertext, ciphertext_length,
                                    plaintext, sizeof(plaintext),
                                    &plaintext_length),
                   verify_status);
    }

    return 1;

exit:
    psa_reset_key_attributes(&attributes);
    return 0;
}

static int can_sign_or_verify_message(psa_key_usage_t usage,
                                      psa_algorithm_t alg)
{
    /* Sign-the-unspecified-hash algorithms can only be used with
     * {sign,verify}_hash, not with {sign,verify}_message. */
    if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
        return 0;
    }
    return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
                    PSA_KEY_USAGE_VERIFY_MESSAGE);
}

static int exercise_signature_key(mbedtls_svc_key_id_t key,
                                  psa_key_usage_t usage,
                                  psa_algorithm_t alg)
{
    /* If the policy allows signing with any hash, just pick one. */
    psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
    if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
        usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
                 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
#if defined(KNOWN_SUPPORTED_HASH_ALG)
        hash_alg = KNOWN_SUPPORTED_HASH_ALG;
        alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
#else
        TEST_FAIL("No hash algorithm for hash-and-sign testing");
#endif
    }

    if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
        PSA_ALG_IS_SIGN_HASH(alg)) {
        unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
        size_t payload_length = 16;
        unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
        size_t signature_length = sizeof(signature);

        /* Some algorithms require the payload to have the size of
         * the hash encoded in the algorithm. Use this input size
         * even for algorithms that allow other input sizes. */
        if (hash_alg != 0) {
            payload_length = PSA_HASH_LENGTH(hash_alg);
        }

        if (usage & PSA_KEY_USAGE_SIGN_HASH) {
            PSA_ASSERT(psa_sign_hash(key, alg,
                                     payload, payload_length,
                                     signature, sizeof(signature),
                                     &signature_length));
        }

        if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
            psa_status_t verify_status =
                (usage & PSA_KEY_USAGE_SIGN_HASH ?
                 PSA_SUCCESS :
                 PSA_ERROR_INVALID_SIGNATURE);
            TEST_EQUAL(psa_verify_hash(key, alg,
                                       payload, payload_length,
                                       signature, signature_length),
                       verify_status);
        }
    }

    if (can_sign_or_verify_message(usage, alg)) {
        unsigned char message[256] = "Hello, world...";
        unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
        size_t message_length = 16;
        size_t signature_length = sizeof(signature);

        if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
            PSA_ASSERT(psa_sign_message(key, alg,
                                        message, message_length,
                                        signature, sizeof(signature),
                                        &signature_length));
        }

        if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
            psa_status_t verify_status =
                (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
                 PSA_SUCCESS :
                 PSA_ERROR_INVALID_SIGNATURE);
            TEST_EQUAL(psa_verify_message(key, alg,
                                          message, message_length,
                                          signature, signature_length),
                       verify_status);
        }
    }

    return 1;

exit:
    return 0;
}

static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
                                              psa_key_usage_t usage,
                                              psa_algorithm_t alg)
{
    unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
        "Hello, world...";
    unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
        "(wabblewebblewibblewobblewubble)";
    size_t ciphertext_length = sizeof(ciphertext);
    size_t plaintext_length = 16;

    if (usage & PSA_KEY_USAGE_ENCRYPT) {
        PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
                                          plaintext, plaintext_length,
                                          NULL, 0,
                                          ciphertext, sizeof(ciphertext),
                                          &ciphertext_length));
    }

    if (usage & PSA_KEY_USAGE_DECRYPT) {
        psa_status_t status =
            psa_asymmetric_decrypt(key, alg,
                                   ciphertext, ciphertext_length,
                                   NULL, 0,
                                   plaintext, sizeof(plaintext),
                                   &plaintext_length);
        TEST_ASSERT(status == PSA_SUCCESS ||
                    ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
                     (status == PSA_ERROR_INVALID_ARGUMENT ||
                      status == PSA_ERROR_INVALID_PADDING)));
    }

    return 1;

exit:
    return 0;
}

int mbedtls_test_psa_setup_key_derivation_wrap(
    psa_key_derivation_operation_t *operation,
    mbedtls_svc_key_id_t key,
    psa_algorithm_t alg,
    const unsigned char *input1, size_t input1_length,
    const unsigned char *input2, size_t input2_length,
    size_t capacity)
{
    PSA_ASSERT(psa_key_derivation_setup(operation, alg));
    if (PSA_ALG_IS_HKDF(alg)) {
        PSA_ASSERT(psa_key_derivation_input_bytes(operation,
                                                  PSA_KEY_DERIVATION_INPUT_SALT,
                                                  input1, input1_length));
        PSA_ASSERT(psa_key_derivation_input_key(operation,
                                                PSA_KEY_DERIVATION_INPUT_SECRET,
                                                key));
        PSA_ASSERT(psa_key_derivation_input_bytes(operation,
                                                  PSA_KEY_DERIVATION_INPUT_INFO,
                                                  input2,
                                                  input2_length));
    } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
        PSA_ASSERT(psa_key_derivation_input_bytes(operation,
                                                  PSA_KEY_DERIVATION_INPUT_SALT,
                                                  input1, input1_length));
        PSA_ASSERT(psa_key_derivation_input_key(operation,
                                                PSA_KEY_DERIVATION_INPUT_SECRET,
                                                key));
    } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
        PSA_ASSERT(psa_key_derivation_input_key(operation,
                                                PSA_KEY_DERIVATION_INPUT_SECRET,
                                                key));
        PSA_ASSERT(psa_key_derivation_input_bytes(operation,
                                                  PSA_KEY_DERIVATION_INPUT_INFO,
                                                  input2,
                                                  input2_length));
    } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
               PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
        PSA_ASSERT(psa_key_derivation_input_bytes(operation,
                                                  PSA_KEY_DERIVATION_INPUT_SEED,
                                                  input1, input1_length));
        PSA_ASSERT(psa_key_derivation_input_key(operation,
                                                PSA_KEY_DERIVATION_INPUT_SECRET,
                                                key));
        PSA_ASSERT(psa_key_derivation_input_bytes(operation,
                                                  PSA_KEY_DERIVATION_INPUT_LABEL,
                                                  input2, input2_length));
    } else if (PSA_ALG_IS_PBKDF2(alg)) {
        PSA_ASSERT(psa_key_derivation_input_integer(operation,
                                                    PSA_KEY_DERIVATION_INPUT_COST,
                                                    1U));
        PSA_ASSERT(psa_key_derivation_input_bytes(operation,
                                                  PSA_KEY_DERIVATION_INPUT_SALT,
                                                  input2,
                                                  input2_length));
        PSA_ASSERT(psa_key_derivation_input_key(operation,
                                                PSA_KEY_DERIVATION_INPUT_PASSWORD,
                                                key));
    } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
        PSA_ASSERT(psa_key_derivation_input_bytes(operation,
                                                  PSA_KEY_DERIVATION_INPUT_SECRET,
                                                  input1, input1_length));
    } else {
        TEST_FAIL("Key derivation algorithm not supported");
    }

    if (capacity != SIZE_MAX) {
        PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
    }

    return 1;

exit:
    return 0;
}


static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
                                       psa_key_usage_t usage,
                                       psa_algorithm_t alg)
{
    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
    unsigned char input1[] = "Input 1";
    size_t input1_length = sizeof(input1);
    unsigned char input2[] = "Input 2";
    size_t input2_length = sizeof(input2);
    unsigned char output[1];
    size_t capacity = sizeof(output);

    if (usage & PSA_KEY_USAGE_DERIVE) {
        if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
                                                        input1, input1_length,
                                                        input2, input2_length,
                                                        capacity)) {
            goto exit;
        }

        PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
                                                   output,
                                                   capacity));
        PSA_ASSERT(psa_key_derivation_abort(&operation));
    }

    return 1;

exit:
    return 0;
}

/* We need two keys to exercise key agreement. Exercise the
 * private key against its own public key. */
psa_status_t mbedtls_test_psa_key_agreement_with_self(
    psa_key_derivation_operation_t *operation,
    mbedtls_svc_key_id_t key)
{
    psa_key_type_t private_key_type;
    psa_key_type_t public_key_type;
    size_t key_bits;
    uint8_t *public_key = NULL;
    size_t public_key_length;
    /* Return GENERIC_ERROR if something other than the final call to
     * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
     * but it's good enough: callers will report it as a failed test anyway. */
    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

    PSA_ASSERT(psa_get_key_attributes(key, &attributes));
    private_key_type = psa_get_key_type(&attributes);
    key_bits = psa_get_key_bits(&attributes);
    public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
    public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
    TEST_CALLOC(public_key, public_key_length);
    PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
                                     &public_key_length));

    status = psa_key_derivation_key_agreement(
        operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
        public_key, public_key_length);
exit:
    /*
     * Key attributes may have been returned by psa_get_key_attributes()
     * thus reset them as required.
     */
    psa_reset_key_attributes(&attributes);

    mbedtls_free(public_key);
    return status;
}

/* We need two keys to exercise key agreement. Exercise the
 * private key against its own public key. */
psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
    psa_algorithm_t alg,
    mbedtls_svc_key_id_t key)
{
    psa_key_type_t private_key_type;
    psa_key_type_t public_key_type;
    size_t key_bits;
    uint8_t *public_key = NULL;
    size_t public_key_length;
    uint8_t output[1024];
    size_t output_length;
    /* Return GENERIC_ERROR if something other than the final call to
     * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
     * but it's good enough: callers will report it as a failed test anyway. */
    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

    PSA_ASSERT(psa_get_key_attributes(key, &attributes));
    private_key_type = psa_get_key_type(&attributes);
    key_bits = psa_get_key_bits(&attributes);
    public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
    public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
    TEST_CALLOC(public_key, public_key_length);
    PSA_ASSERT(psa_export_public_key(key,
                                     public_key, public_key_length,
                                     &public_key_length));

    status = psa_raw_key_agreement(alg, key,
                                   public_key, public_key_length,
                                   output, sizeof(output), &output_length);
    if (status == PSA_SUCCESS) {
        TEST_ASSERT(output_length <=
                    PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
                                                      key_bits));
        TEST_ASSERT(output_length <=
                    PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
    }

exit:
    /*
     * Key attributes may have been returned by psa_get_key_attributes()
     * thus reset them as required.
     */
    psa_reset_key_attributes(&attributes);

    mbedtls_free(public_key);
    return status;
}

static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
                                          psa_key_usage_t usage,
                                          psa_algorithm_t alg)
{
    int ok = 0;

    if (usage & PSA_KEY_USAGE_DERIVE) {
        /* We need two keys to exercise key agreement. Exercise the
         * private key against its own public key. */
        PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
    }
    ok = 1;

exit:
    return ok;
}

static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
                                      psa_key_usage_t usage,
                                      psa_algorithm_t alg)
{
    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
    unsigned char input[1] = { 0 };
    unsigned char output[1];
    int ok = 0;
    psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
    psa_status_t expected_key_agreement_status = PSA_SUCCESS;

    if (usage & PSA_KEY_USAGE_DERIVE) {
        /* We need two keys to exercise key agreement. Exercise the
         * private key against its own public key. */
        PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
        if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
            PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
            PSA_ASSERT(psa_key_derivation_input_bytes(
                           &operation, PSA_KEY_DERIVATION_INPUT_SEED,
                           input, sizeof(input)));
        }

        if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
            PSA_ASSERT(psa_key_derivation_input_bytes(
                           &operation, PSA_KEY_DERIVATION_INPUT_SALT,
                           input, sizeof(input)));
        }

        /* For HKDF_EXPAND input secret may fail as secret size may not match
           to expected PRK size. In practice it means that key bits must match
           hash length. Otherwise test should fail with INVALID_ARGUMENT. */
        if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
            psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
            PSA_ASSERT(psa_get_key_attributes(key, &attributes));
            size_t key_bits = psa_get_key_bits(&attributes);
            psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);

            if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
                expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
            }
        }

        TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
                   expected_key_agreement_status);

        if (expected_key_agreement_status != PSA_SUCCESS) {
            return 1;
        }

        if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
            PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
            PSA_ASSERT(psa_key_derivation_input_bytes(
                           &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
                           input, sizeof(input)));
        } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
            PSA_ASSERT(psa_key_derivation_input_bytes(
                           &operation, PSA_KEY_DERIVATION_INPUT_INFO,
                           input, sizeof(input)));
        }
        PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
                                                   output,
                                                   sizeof(output)));
        PSA_ASSERT(psa_key_derivation_abort(&operation));
    }
    ok = 1;

exit:
    return ok;
}

int mbedtls_test_psa_exported_key_sanity_check(
    psa_key_type_t type, size_t bits,
    const uint8_t *exported, size_t exported_length)
{
    TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));

    if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
        TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
    } else

#if defined(MBEDTLS_ASN1_PARSE_C)
    if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
        uint8_t *p = (uint8_t *) exported;
        const uint8_t *end = exported + exported_length;
        size_t len;
        /*   RSAPrivateKey ::= SEQUENCE {
         *       version             INTEGER,  -- must be 0
         *       modulus             INTEGER,  -- n
         *       publicExponent      INTEGER,  -- e
         *       privateExponent     INTEGER,  -- d
         *       prime1              INTEGER,  -- p
         *       prime2              INTEGER,  -- q
         *       exponent1           INTEGER,  -- d mod (p-1)
         *       exponent2           INTEGER,  -- d mod (q-1)
         *       coefficient         INTEGER,  -- (inverse of q) mod p
         *   }
         */
        TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
                                        MBEDTLS_ASN1_SEQUENCE |
                                        MBEDTLS_ASN1_CONSTRUCTED), 0);
        TEST_EQUAL(len, end - p);
        if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
            goto exit;
        }
        if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
            goto exit;
        }
        if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
            goto exit;
        }
        /* Require d to be at least half the size of n. */
        if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
            goto exit;
        }
        /* Require p and q to be at most half the size of n, rounded up. */
        if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
            goto exit;
        }
        if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
            goto exit;
        }
        if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
            goto exit;
        }
        if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
            goto exit;
        }
        if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
            goto exit;
        }
        TEST_EQUAL(p - end, 0);

        TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
    } else
#endif /* MBEDTLS_ASN1_PARSE_C */

    if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
        /* Just the secret value */
        TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));

        TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
    } else

#if defined(MBEDTLS_ASN1_PARSE_C)
    if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
        uint8_t *p = (uint8_t *) exported;
        const uint8_t *end = exported + exported_length;
        size_t len;
        /*   RSAPublicKey ::= SEQUENCE {
         *      modulus            INTEGER,    -- n
         *      publicExponent     INTEGER  }  -- e
         */
        TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
                                        MBEDTLS_ASN1_SEQUENCE |
                                        MBEDTLS_ASN1_CONSTRUCTED),
                   0);
        TEST_EQUAL(len, end - p);
        if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
            goto exit;
        }
        if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
            goto exit;
        }
        TEST_EQUAL(p - end, 0);


        TEST_ASSERT(exported_length <=
                    PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
        TEST_ASSERT(exported_length <=
                    PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
    } else
#endif /* MBEDTLS_ASN1_PARSE_C */

    if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {

        TEST_ASSERT(exported_length <=
                    PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
        TEST_ASSERT(exported_length <=
                    PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);

        if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
            /* The representation of an ECC Montgomery public key is
             * the raw compressed point */
            TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
        } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
            /* The representation of an ECC Edwards public key is
             * the raw compressed point */
            TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
        } else {
            /* The representation of an ECC Weierstrass public key is:
             *      - The byte 0x04;
             *      - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
             *      - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
             *      - where m is the bit size associated with the curve.
             */
            TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
            TEST_EQUAL(exported[0], 4);
        }
    } else
    if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
        TEST_ASSERT(exported_length ==
                    PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
        TEST_ASSERT(exported_length <=
                    PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
    } else {
        (void) exported;
        TEST_FAIL("Sanity check not implemented for this key type");
    }

#if defined(MBEDTLS_DES_C)
    if (type == PSA_KEY_TYPE_DES) {
        /* Check the parity bits. */
        unsigned i;
        for (i = 0; i < bits / 8; i++) {
            unsigned bit_count = 0;
            unsigned m;
            for (m = 1; m <= 0x100; m <<= 1) {
                if (exported[i] & m) {
                    ++bit_count;
                }
            }
            TEST_ASSERT(bit_count % 2 != 0);
        }
    }
#endif

    return 1;

exit:
    return 0;
}

static int exercise_export_key(mbedtls_svc_key_id_t key,
                               psa_key_usage_t usage)
{
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    uint8_t *exported = NULL;
    size_t exported_size = 0;
    size_t exported_length = 0;
    int ok = 0;

    PSA_ASSERT(psa_get_key_attributes(key, &attributes));

    exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
        psa_get_key_type(&attributes),
        psa_get_key_bits(&attributes));
    TEST_CALLOC(exported, exported_size);

    if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
        !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
        TEST_EQUAL(psa_export_key(key, exported,
                                  exported_size, &exported_length),
                   PSA_ERROR_NOT_PERMITTED);
        ok = 1;
        goto exit;
    }

    PSA_ASSERT(psa_export_key(key,
                              exported, exported_size,
                              &exported_length));
    ok = mbedtls_test_psa_exported_key_sanity_check(
        psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
        exported, exported_length);

exit:
    /*
     * Key attributes may have been returned by psa_get_key_attributes()
     * thus reset them as required.
     */
    psa_reset_key_attributes(&attributes);

    mbedtls_free(exported);
    return ok;
}

static int exercise_export_public_key(mbedtls_svc_key_id_t key)
{
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_type_t public_type;
    uint8_t *exported = NULL;
    size_t exported_size = 0;
    size_t exported_length = 0;
    int ok = 0;

    PSA_ASSERT(psa_get_key_attributes(key, &attributes));
    if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
        exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
            psa_get_key_type(&attributes),
            psa_get_key_bits(&attributes));
        TEST_CALLOC(exported, exported_size);

        TEST_EQUAL(psa_export_public_key(key, exported,
                                         exported_size, &exported_length),
                   PSA_ERROR_INVALID_ARGUMENT);
        ok = 1;
        goto exit;
    }

    public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
        psa_get_key_type(&attributes));
    exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
                                                      psa_get_key_bits(&attributes));
    TEST_CALLOC(exported, exported_size);

    PSA_ASSERT(psa_export_public_key(key,
                                     exported, exported_size,
                                     &exported_length));
    ok = mbedtls_test_psa_exported_key_sanity_check(
        public_type, psa_get_key_bits(&attributes),
        exported, exported_length);

exit:
    /*
     * Key attributes may have been returned by psa_get_key_attributes()
     * thus reset them as required.
     */
    psa_reset_key_attributes(&attributes);

    mbedtls_free(exported);
    return ok;
}

int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
                                  psa_key_usage_t usage,
                                  psa_algorithm_t alg)
{
    int ok = 0;

    if (!check_key_attributes_sanity(key)) {
        return 0;
    }

    if (alg == 0) {
        ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
    } else if (PSA_ALG_IS_MAC(alg)) {
        ok = exercise_mac_key(key, usage, alg);
    } else if (PSA_ALG_IS_CIPHER(alg)) {
        ok = exercise_cipher_key(key, usage, alg);
    } else if (PSA_ALG_IS_AEAD(alg)) {
        ok = exercise_aead_key(key, usage, alg);
    } else if (PSA_ALG_IS_SIGN(alg)) {
        ok = exercise_signature_key(key, usage, alg);
    } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
        ok = exercise_asymmetric_encryption_key(key, usage, alg);
    } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
        ok = exercise_key_derivation_key(key, usage, alg);
    } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
        ok = exercise_raw_key_agreement_key(key, usage, alg);
    } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
        ok = exercise_key_agreement_key(key, usage, alg);
    } else {
        TEST_FAIL("No code to exercise this category of algorithm");
    }

    ok = ok && exercise_export_key(key, usage);
    ok = ok && exercise_export_public_key(key);

exit:
    return ok;
}

psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
                                                   psa_algorithm_t alg)
{
    if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
        if (PSA_ALG_IS_SIGN_HASH(alg)) {
            if (PSA_ALG_SIGN_GET_HASH(alg)) {
                return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
                       PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
                       PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
                       PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
            }
        } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
            return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
                   PSA_KEY_USAGE_VERIFY_MESSAGE :
                   PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
        }

        return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
               PSA_KEY_USAGE_VERIFY_HASH :
               PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
    } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
               PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
        return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
               PSA_KEY_USAGE_ENCRYPT :
               PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
    } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
               PSA_ALG_IS_KEY_AGREEMENT(alg)) {
        return PSA_KEY_USAGE_DERIVE;
    } else {
        return 0;
    }

}

int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
{
    /* Reject algorithms that we know are not supported. Default to
     * attempting exercise, so that if an algorithm is missing from this
     * function, the result will be a test failure and not silently
     * omitting exercise. */
#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
    if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
        return 0;
    }
#endif
#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
    if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
        return 0;
    }
#endif
#if !defined(PSA_WANT_ALG_RSA_PSS)
    if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
        return 0;
    }
#endif
#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
    if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
        return 0;
    }
#endif
#if !defined(PSA_WANT_ALG_ECDSA)
    if (PSA_ALG_IS_ECDSA(alg)) {
        return 0;
    }
#endif
#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
    if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
        return 0;
    }
#endif
#if !defined(PSA_WANT_ALG_ECDH)
    if (PSA_ALG_IS_ECDH(alg)) {
        return 0;
    }
#endif
    (void) alg;
    return 1;
}

#if defined(MBEDTLS_PK_C)
int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
                                        const mbedtls_pk_context *pk)
{
    psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
    int ok = 0;

    PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
    psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
    mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);

    TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
                PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
    TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));

    uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
    const uint8_t *pk_public = NULL;
    size_t pk_public_length = 0;

    switch (pk_type) {
#if defined(MBEDTLS_RSA_C)
        case MBEDTLS_PK_RSA:
            TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
            const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
            uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
            uint8_t *cursor = end;
            TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
                                                  pk_public_buffer, &cursor));
            pk_public = cursor;
            pk_public_length = end - pk_public;
            break;
#endif

#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
        case MBEDTLS_PK_ECKEY:
        case MBEDTLS_PK_ECKEY_DH:
        case MBEDTLS_PK_ECDSA:
            TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
            TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
            pk_public = pk->pub_raw;
            pk_public_length = pk->pub_raw_len;
            break;
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */

#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
        case MBEDTLS_PK_ECKEY:
        case MBEDTLS_PK_ECKEY_DH:
        case MBEDTLS_PK_ECDSA:
            TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
            const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
            TEST_EQUAL(mbedtls_ecp_write_public_key(
                           ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
                           pk_public_buffer, sizeof(pk_public_buffer)), 0);
            pk_public = pk_public_buffer;
            break;
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */

#if defined(MBEDTLS_USE_PSA_CRYPTO)
        case MBEDTLS_PK_OPAQUE:
            PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
            psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
            TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
                       PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
            PSA_ASSERT(psa_export_public_key(psa_key,
                                             pk_public_buffer,
                                             sizeof(pk_public_buffer),
                                             &pk_public_length));
            pk_public = pk_public_buffer;
            break;
#endif /* MBEDTLS_USE_PSA_CRYPTO */

        default:
            TEST_FAIL("pk type not supported");
    }

    uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
    size_t psa_public_length = 0;
    PSA_ASSERT(psa_export_public_key(psa_key,
                                     psa_public, sizeof(psa_public),
                                     &psa_public_length));
    TEST_MEMORY_COMPARE(pk_public, pk_public_length,
                        psa_public, psa_public_length);

    ok = 1;

exit:
    psa_reset_key_attributes(&psa_attributes);
    psa_reset_key_attributes(&pk_attributes);
    return ok;
}
#endif /* MBEDTLS_PK_C */

#endif /* MBEDTLS_PSA_CRYPTO_C */
