/*
 *  PSA crypto layer on top of Mbed TLS crypto
 */
/*
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H
#define PSA_CRYPTO_SLOT_MANAGEMENT_H

#include "psa/crypto.h"
#include "psa_crypto_core.h"
#include "psa_crypto_se.h"

/* Number of key slots (plus one because 0 is not used).
 * The value is a compile-time constant for now, for simplicity. */
#define PSA_KEY_SLOT_COUNT 32

/** Range of volatile key identifiers.
 *
 *  The last PSA_KEY_SLOT_COUNT identifiers of the implementation range
 *  of key identifiers are reserved for volatile key identifiers.
 *  A volatile key identifier is equal to PSA_KEY_ID_VOLATILE_MIN plus the
 *  index of the key slot containing the volatile key definition.
 */

/** The minimum value for a volatile key identifier.
 */
#define PSA_KEY_ID_VOLATILE_MIN  ( PSA_KEY_ID_VENDOR_MAX - \
                                   PSA_KEY_SLOT_COUNT + 1 )

/** The maximum value for a volatile key identifier.
 */
#define PSA_KEY_ID_VOLATILE_MAX  PSA_KEY_ID_VENDOR_MAX

/** Retrieve the description of a key given its identifier.
 *
 *  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.
 *
 *  In case of a persistent key, the function loads the description of the key
 *  into a key slot if not already done.
 *
 * \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_BAD_STATE
 *         The library has not been initialized.
 * \retval #PSA_ERROR_INVALID_HANDLE
 *         \p key is not a valid key identifier.
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
 *         \p key is a persistent key identifier. The implementation does not
 *         have sufficient resources to load the persistent key. This can be
 *         due to a lack of empty key slot, or available memory.
 * \retval #PSA_ERROR_DOES_NOT_EXIST
 *         There is no key with key identifier \p key.
 * \retval #PSA_ERROR_CORRUPTION_DETECTED
 * \retval #PSA_ERROR_STORAGE_FAILURE
 * \retval #PSA_ERROR_DATA_CORRUPT
 */
psa_status_t psa_get_key_slot( mbedtls_svc_key_id_t key,
                               psa_key_slot_t **p_slot );

/** Initialize the key slot structures.
 *
 * \retval PSA_SUCCESS
 *         Currently this function always succeeds.
 */
psa_status_t psa_initialize_key_slots( void );

/** Delete all data from key slots in memory.
 *
 * This does not affect persistent storage. */
void psa_wipe_all_key_slots( void );

/** Find a free key slot.
 *
 * This function returns a key slot that is available for use and is in its
 * ground state (all-bits-zero).
 *
 * \param[out] volatile_key_id   On success, volatile key identifier
 *                               associated to the returned slot.
 * \param[out] p_slot            On success, a pointer to the slot.
 *
 * \retval #PSA_SUCCESS
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
 * \retval #PSA_ERROR_BAD_STATE
 */
psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id,
                                     psa_key_slot_t **p_slot );

/** Test whether a lifetime designates a key in an external cryptoprocessor.
 *
 * \param lifetime      The lifetime to test.
 *
 * \retval 1
 *         The lifetime designates an external key. There should be a
 *         registered driver for this lifetime, otherwise the key cannot
 *         be created or manipulated.
 * \retval 0
 *         The lifetime designates a key that is volatile or in internal
 *         storage.
 */
static inline int psa_key_lifetime_is_external( psa_key_lifetime_t lifetime )
{
    return( PSA_KEY_LIFETIME_GET_LOCATION( lifetime )
                != PSA_KEY_LOCATION_LOCAL_STORAGE );
}

/** Validate a key's location.
 *
 * This function checks whether the key's attributes point to a location that
 * is known to the PSA Core, and returns the driver function table if the key
 * is to be found in an external location.
 *
 * \param[in] lifetime      The key lifetime attribute.
 * \param[out] p_drv        On success, when a key is located in external
 *                          storage, returns a pointer to the driver table
 *                          associated with the key's storage location.
 *
 * \retval #PSA_SUCCESS
 * \retval #PSA_ERROR_INVALID_ARGUMENT
 */
psa_status_t psa_validate_key_location( psa_key_lifetime_t lifetime,
                                        psa_se_drv_table_entry_t **p_drv );

/** Validate the persistence of a key.
 *
 * \param[in] lifetime  The key lifetime attribute.
 *
 * \retval #PSA_SUCCESS
 * \retval #PSA_ERROR_INVALID_ARGUMENT The key is persistent but persistent
 *         keys are not supported.
 */
psa_status_t psa_validate_key_persistence( psa_key_lifetime_t lifetime );

/** Validate a key identifier.
 *
 * \param[in] key        The key identifier.
 * \param[in] vendor_ok  Non-zero to indicate that key identifiers in the
 *                       vendor range are allowed, \c 0 otherwise.
 *
 * \retval #PSA_SUCCESS The identifier is valid.
 * \retval #PSA_ERROR_INVALID_ARGUMENT The key identifier is not valid.
 */
psa_status_t psa_validate_key_id( mbedtls_svc_key_id_t key, int vendor_ok );

#endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */
