/*
 *  PSA crypto layer on top of Mbed TLS crypto
 */
/*
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
 */

#include "common.h"

#if defined(MBEDTLS_PSA_CRYPTO_C)

#include "psa/crypto.h"

#include "psa_crypto_core.h"
#include "psa_crypto_driver_wrappers_no_static.h"
#include "psa_crypto_slot_management.h"
#include "psa_crypto_storage.h"
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
#include "psa_crypto_se.h"
#endif

#include <stdlib.h>
#include <string.h>
#include "mbedtls/platform.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif

typedef struct {
    psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT];
    uint8_t key_slots_initialized;
} psa_global_data_t;

static psa_global_data_t global_data;

int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok)
{
    psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key);

    if ((PSA_KEY_ID_USER_MIN <= key_id) &&
        (key_id <= PSA_KEY_ID_USER_MAX)) {
        return 1;
    }

    if (vendor_ok &&
        (PSA_KEY_ID_VENDOR_MIN <= key_id) &&
        (key_id <= PSA_KEY_ID_VENDOR_MAX)) {
        return 1;
    }

    return 0;
}

/** Get the description in memory of a key given its identifier and lock it.
 *
 * The descriptions of volatile keys and loaded persistent keys are
 * stored in key slots. This function returns a pointer to the key slot
 * containing the description of a key given its identifier.
 *
 * The function searches the key slots containing the description of the key
 * with \p key identifier. The function does only read accesses to the key
 * slots. The function does not load any persistent key thus does not access
 * any storage.
 *
 * For volatile key identifiers, only one key slot is queried as a volatile
 * key with identifier key_id can only be stored in slot of index
 * ( key_id - #PSA_KEY_ID_VOLATILE_MIN ).
 *
 * On success, the function locks the key slot. It is the responsibility of
 * the caller to unlock the key slot when it does not access it anymore.
 *
 * \param key           Key identifier to query.
 * \param[out] p_slot   On success, `*p_slot` contains a pointer to the
 *                      key slot containing the description of the key
 *                      identified by \p key.
 *
 * \retval #PSA_SUCCESS
 *         The pointer to the key slot containing the description of the key
 *         identified by \p key was returned.
 * \retval #PSA_ERROR_INVALID_HANDLE
 *         \p key is not a valid key identifier.
 * \retval #PSA_ERROR_DOES_NOT_EXIST
 *         There is no key with key identifier \p key in the key slots.
 */
static psa_status_t psa_get_and_lock_key_slot_in_memory(
    mbedtls_svc_key_id_t key, psa_key_slot_t **p_slot)
{
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key);
    size_t slot_idx;
    psa_key_slot_t *slot = NULL;

    if (psa_key_id_is_volatile(key_id)) {
        slot = &global_data.key_slots[key_id - PSA_KEY_ID_VOLATILE_MIN];

        /*
         * Check if both the PSA key identifier key_id and the owner
         * identifier of key match those of the key slot.
         *
         * Note that, if the key slot is not occupied, its PSA key identifier
         * is equal to zero. This is an invalid value for a PSA key identifier
         * and thus cannot be equal to the valid PSA key identifier key_id.
         */
        status = mbedtls_svc_key_id_equal(key, slot->attr.id) ?
                 PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
    } else {
        if (!psa_is_valid_key_id(key, 1)) {
            return PSA_ERROR_INVALID_HANDLE;
        }

        for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
            slot = &global_data.key_slots[slot_idx];
            /* Only consider slots which are in a full state. */
            if ((slot->state == PSA_SLOT_FULL) &&
                (mbedtls_svc_key_id_equal(key, slot->attr.id))) {
                break;
            }
        }
        status = (slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT) ?
                 PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
    }

    if (status == PSA_SUCCESS) {
        status = psa_register_read(slot);
        if (status == PSA_SUCCESS) {
            *p_slot = slot;
        }
    }

    return status;
}

psa_status_t psa_initialize_key_slots(void)
{
    /* Nothing to do: program startup and psa_wipe_all_key_slots() both
     * guarantee that the key slots are initialized to all-zero, which
     * means that all the key slots are in a valid, empty state. */
    global_data.key_slots_initialized = 1;
    return PSA_SUCCESS;
}

void psa_wipe_all_key_slots(void)
{
    size_t slot_idx;

    for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
        psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
        slot->registered_readers = 1;
        slot->state = PSA_SLOT_PENDING_DELETION;
        (void) psa_wipe_key_slot(slot);
    }
    global_data.key_slots_initialized = 0;
}

psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
                                       psa_key_slot_t **p_slot)
{
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    size_t slot_idx;
    psa_key_slot_t *selected_slot, *unused_persistent_key_slot;

    if (!global_data.key_slots_initialized) {
        status = PSA_ERROR_BAD_STATE;
        goto error;
    }

    selected_slot = unused_persistent_key_slot = NULL;
    for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
        psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
        if (slot->state == PSA_SLOT_EMPTY) {
            selected_slot = slot;
            break;
        }

        if ((unused_persistent_key_slot == NULL) &&
            (slot->state == PSA_SLOT_FULL) &&
            (!psa_key_slot_has_readers(slot)) &&
            (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime))) {
            unused_persistent_key_slot = slot;
        }
    }

    /*
     * If there is no unused key slot and there is at least one unlocked key
     * slot containing the description of a persistent key, recycle the first
     * such key slot we encountered. If we later need to operate on the
     * persistent key we are evicting now, we will reload its description from
     * storage.
     */
    if ((selected_slot == NULL) &&
        (unused_persistent_key_slot != NULL)) {
        selected_slot = unused_persistent_key_slot;
        psa_register_read(selected_slot);
        status = psa_wipe_key_slot(selected_slot);
        if (status != PSA_SUCCESS) {
            goto error;
        }
    }

    if (selected_slot != NULL) {
        status = psa_key_slot_state_transition(selected_slot, PSA_SLOT_EMPTY,
                                               PSA_SLOT_FILLING);
        if (status != PSA_SUCCESS) {
            goto error;
        }

        *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN +
                           ((psa_key_id_t) (selected_slot - global_data.key_slots));
        *p_slot = selected_slot;

        return PSA_SUCCESS;
    }
    status = PSA_ERROR_INSUFFICIENT_MEMORY;

error:
    *p_slot = NULL;
    *volatile_key_id = 0;

    return status;
}

#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
static psa_status_t psa_load_persistent_key_into_slot(psa_key_slot_t *slot)
{
    psa_status_t status = PSA_SUCCESS;
    uint8_t *key_data = NULL;
    size_t key_data_length = 0;

    status = psa_load_persistent_key(&slot->attr,
                                     &key_data, &key_data_length);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
    /* Special handling is required for loading keys associated with a
     * dynamically registered SE interface. */
    const psa_drv_se_t *drv;
    psa_drv_se_context_t *drv_context;
    if (psa_get_se_driver(slot->attr.lifetime, &drv, &drv_context)) {
        psa_se_key_data_storage_t *data;

        if (key_data_length != sizeof(*data)) {
            status = PSA_ERROR_DATA_INVALID;
            goto exit;
        }
        data = (psa_se_key_data_storage_t *) key_data;
        status = psa_copy_key_material_into_slot(
            slot, data->slot_number, sizeof(data->slot_number));

        if (status == PSA_SUCCESS) {
            status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
                                                   PSA_SLOT_FULL);
        }
        goto exit;
    }
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */

    status = psa_copy_key_material_into_slot(slot, key_data, key_data_length);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
                                           PSA_SLOT_FULL);

exit:
    psa_free_persistent_key_data(key_data, key_data_length);
    return status;
}
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */

#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)

static psa_status_t psa_load_builtin_key_into_slot(psa_key_slot_t *slot)
{
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_VOLATILE;
    psa_drv_slot_number_t slot_number = 0;
    size_t key_buffer_size = 0;
    size_t key_buffer_length = 0;

    if (!psa_key_id_is_builtin(
            MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id))) {
        return PSA_ERROR_DOES_NOT_EXIST;
    }

    /* Check the platform function to see whether this key actually exists */
    status = mbedtls_psa_platform_get_builtin_key(
        slot->attr.id, &lifetime, &slot_number);
    if (status != PSA_SUCCESS) {
        return status;
    }

    /* Set required key attributes to ensure get_builtin_key can retrieve the
     * full attributes. */
    psa_set_key_id(&attributes, slot->attr.id);
    psa_set_key_lifetime(&attributes, lifetime);

    /* Get the full key attributes from the driver in order to be able to
     * calculate the required buffer size. */
    status = psa_driver_wrapper_get_builtin_key(
        slot_number, &attributes,
        NULL, 0, NULL);
    if (status != PSA_ERROR_BUFFER_TOO_SMALL) {
        /* Builtin keys cannot be defined by the attributes alone */
        if (status == PSA_SUCCESS) {
            status = PSA_ERROR_CORRUPTION_DETECTED;
        }
        return status;
    }

    /* If the key should exist according to the platform, then ask the driver
     * what its expected size is. */
    status = psa_driver_wrapper_get_key_buffer_size(&attributes,
                                                    &key_buffer_size);
    if (status != PSA_SUCCESS) {
        return status;
    }

    /* Allocate a buffer of the required size and load the builtin key directly
     * into the (now properly sized) slot buffer. */
    status = psa_allocate_buffer_to_slot(slot, key_buffer_size);
    if (status != PSA_SUCCESS) {
        return status;
    }

    status = psa_driver_wrapper_get_builtin_key(
        slot_number, &attributes,
        slot->key.data, slot->key.bytes, &key_buffer_length);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    /* Copy actual key length and core attributes into the slot on success */
    slot->key.bytes = key_buffer_length;
    slot->attr = attributes.core;

    status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
                                           PSA_SLOT_FULL);
exit:
    if (status != PSA_SUCCESS) {
        psa_remove_key_data_from_memory(slot);
    }
    return status;
}
#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */

psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
                                       psa_key_slot_t **p_slot)
{
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

    *p_slot = NULL;
    if (!global_data.key_slots_initialized) {
        return PSA_ERROR_BAD_STATE;
    }

    /*
     * On success, the pointer to the slot is passed directly to the caller
     * thus no need to unlock the key slot here.
     */
    status = psa_get_and_lock_key_slot_in_memory(key, p_slot);
    if (status != PSA_ERROR_DOES_NOT_EXIST) {
        return status;
    }

    /* Loading keys from storage requires support for such a mechanism */
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || \
    defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
    psa_key_id_t volatile_key_id;

    status = psa_reserve_free_key_slot(&volatile_key_id, p_slot);
    if (status != PSA_SUCCESS) {
        return status;
    }

    (*p_slot)->attr.id = key;
    (*p_slot)->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT;

    status = PSA_ERROR_DOES_NOT_EXIST;
#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
    /* Load keys in the 'builtin' range through their own interface */
    status = psa_load_builtin_key_into_slot(*p_slot);
#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */

#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
    if (status == PSA_ERROR_DOES_NOT_EXIST) {
        status = psa_load_persistent_key_into_slot(*p_slot);
    }
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */

    if (status != PSA_SUCCESS) {
        psa_wipe_key_slot(*p_slot);

        if (status == PSA_ERROR_DOES_NOT_EXIST) {
            status = PSA_ERROR_INVALID_HANDLE;
        }
    } else {
        /* Add implicit usage flags. */
        psa_extend_key_usage_flags(&(*p_slot)->attr.policy.usage);

        psa_key_slot_state_transition((*p_slot), PSA_SLOT_FILLING,
                                      PSA_SLOT_FULL);
        status = psa_register_read(*p_slot);
    }

    return status;
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
    return PSA_ERROR_INVALID_HANDLE;
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
}

psa_status_t psa_unregister_read(psa_key_slot_t *slot)
{
    if (slot == NULL) {
        return PSA_SUCCESS;
    }
    if ((slot->state != PSA_SLOT_FULL) &&
        (slot->state != PSA_SLOT_PENDING_DELETION)) {
        return PSA_ERROR_CORRUPTION_DETECTED;
    }

    /* If we are the last reader and the slot is marked for deletion,
     * we must wipe the slot here. */
    if ((slot->state == PSA_SLOT_PENDING_DELETION) &&
        (slot->registered_readers == 1)) {
        return psa_wipe_key_slot(slot);
    }

    if (psa_key_slot_has_readers(slot)) {
        slot->registered_readers--;
        return PSA_SUCCESS;
    }

    /*
     * As the return error code may not be handled in case of multiple errors,
     * do our best to report if there are no registered readers. Assert with
     * MBEDTLS_TEST_HOOK_TEST_ASSERT that there are registered readers:
     * if the MBEDTLS_TEST_HOOKS configuration option is enabled and
     * the function is called as part of the execution of a test suite, the
     * execution of the test suite is stopped in error if the assertion fails.
     */
    MBEDTLS_TEST_HOOK_TEST_ASSERT(psa_key_slot_has_readers(slot));
    return PSA_ERROR_CORRUPTION_DETECTED;
}

psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime,
                                       psa_se_drv_table_entry_t **p_drv)
{
    if (psa_key_lifetime_is_external(lifetime)) {
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
        /* Check whether a driver is registered against this lifetime */
        psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry(lifetime);
        if (driver != NULL) {
            if (p_drv != NULL) {
                *p_drv = driver;
            }
            return PSA_SUCCESS;
        }
#else /* MBEDTLS_PSA_CRYPTO_SE_C */
        (void) p_drv;
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */

        /* Key location for external keys gets checked by the wrapper */
        return PSA_SUCCESS;
    } else {
        /* Local/internal keys are always valid */
        return PSA_SUCCESS;
    }
}

psa_status_t psa_validate_key_persistence(psa_key_lifetime_t lifetime)
{
    if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
        /* Volatile keys are always supported */
        return PSA_SUCCESS;
    } else {
        /* Persistent keys require storage support */
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
        if (PSA_KEY_LIFETIME_IS_READ_ONLY(lifetime)) {
            return PSA_ERROR_INVALID_ARGUMENT;
        } else {
            return PSA_SUCCESS;
        }
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
        return PSA_ERROR_NOT_SUPPORTED;
#endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
    }
}

psa_status_t psa_open_key(mbedtls_svc_key_id_t key, psa_key_handle_t *handle)
{
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || \
    defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
    psa_status_t status;
    psa_key_slot_t *slot;

    status = psa_get_and_lock_key_slot(key, &slot);
    if (status != PSA_SUCCESS) {
        *handle = PSA_KEY_HANDLE_INIT;
        if (status == PSA_ERROR_INVALID_HANDLE) {
            status = PSA_ERROR_DOES_NOT_EXIST;
        }

        return status;
    }

    *handle = key;

    return psa_unregister_read(slot);

#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
    (void) key;
    *handle = PSA_KEY_HANDLE_INIT;
    return PSA_ERROR_NOT_SUPPORTED;
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
}

psa_status_t psa_close_key(psa_key_handle_t handle)
{
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    psa_key_slot_t *slot;

    if (psa_key_handle_is_null(handle)) {
        return PSA_SUCCESS;
    }

#if defined(MBEDTLS_THREADING_C)
    /* We need to set status as success, otherwise CORRUPTION_DETECTED
     * would be returned if the lock fails. */
    status = PSA_SUCCESS;
    PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
                              &mbedtls_threading_key_slot_mutex));
#endif
    status = psa_get_and_lock_key_slot_in_memory(handle, &slot);
    if (status != PSA_SUCCESS) {
        if (status == PSA_ERROR_DOES_NOT_EXIST) {
            status = PSA_ERROR_INVALID_HANDLE;
        }
#if defined(MBEDTLS_THREADING_C)
        PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
                                  &mbedtls_threading_key_slot_mutex));
#endif
        return status;
    }

    if (slot->registered_readers == 1) {
        status = psa_wipe_key_slot(slot);
    } else {
        status = psa_unregister_read(slot);
    }
#if defined(MBEDTLS_THREADING_C)
    PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
                              &mbedtls_threading_key_slot_mutex));
#endif

    return status;
}

psa_status_t psa_purge_key(mbedtls_svc_key_id_t key)
{
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    psa_key_slot_t *slot;

#if defined(MBEDTLS_THREADING_C)
    /* We need to set status as success, otherwise CORRUPTION_DETECTED
     * would be returned if the lock fails. */
    status = PSA_SUCCESS;
    PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
                              &mbedtls_threading_key_slot_mutex));
#endif
    status = psa_get_and_lock_key_slot_in_memory(key, &slot);
    if (status != PSA_SUCCESS) {
#if defined(MBEDTLS_THREADING_C)
        PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
                                  &mbedtls_threading_key_slot_mutex));
#endif
        return status;
    }

    if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
        (slot->registered_readers == 1)) {
        status = psa_wipe_key_slot(slot);
    } else {
        status = psa_unregister_read(slot);
    }
#if defined(MBEDTLS_THREADING_C)
    PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
                              &mbedtls_threading_key_slot_mutex));
#endif

    return status;
}

void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats)
{
    size_t slot_idx;

    memset(stats, 0, sizeof(*stats));

    for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
        const psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
        if (psa_key_slot_has_readers(slot)) {
            ++stats->locked_slots;
        }
        if (slot->state == PSA_SLOT_EMPTY) {
            ++stats->empty_slots;
            continue;
        }
        if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
            ++stats->volatile_slots;
        } else {
            psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id);
            ++stats->persistent_slots;
            if (id > stats->max_open_internal_key_id) {
                stats->max_open_internal_key_id = id;
            }
        }
        if (PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime) !=
            PSA_KEY_LOCATION_LOCAL_STORAGE) {
            psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id);
            ++stats->external_slots;
            if (id > stats->max_open_external_key_id) {
                stats->max_open_external_key_id = id;
            }
        }
    }
}

#endif /* MBEDTLS_PSA_CRYPTO_C */
