/*
 *  Copyright (c) 2021, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file includes definitions for Crypto Internal Trusted Storage (ITS) APIs.
 */

#ifndef STORAGE_HPP_
#define STORAGE_HPP_

#include "openthread-core-config.h"

#include <openthread/platform/crypto.h>

#include "common/as_core_type.hpp"
#include "common/clearable.hpp"
#include "common/code_utils.hpp"
#include "common/error.hpp"
#include "common/non_copyable.hpp"

namespace ot {
namespace Crypto {

#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE

namespace Storage {

/**
 * This enumeration defines the key types.
 *
 */
enum KeyType : uint8_t
{
    kKeyTypeRaw  = OT_CRYPTO_KEY_TYPE_RAW,  ///< Key Type: Raw Data.
    kKeyTypeAes  = OT_CRYPTO_KEY_TYPE_AES,  ///< Key Type: AES.
    kKeyTypeHmac = OT_CRYPTO_KEY_TYPE_HMAC, ///< Key Type: HMAC.
};

/**
 * This enumeration defines the key algorithms.
 *
 */
enum KeyAlgorithm : uint8_t
{
    kKeyAlgorithmVendor     = OT_CRYPTO_KEY_ALG_VENDOR,       ///< Key Algorithm: Vendor Defined.
    kKeyAlgorithmAesEcb     = OT_CRYPTO_KEY_ALG_AES_ECB,      ///< Key Algorithm: AES ECB.
    kKeyAlgorithmHmacSha256 = OT_CRYPTO_KEY_ALG_HMAC_SHA_256, ///< Key Algorithm: HMAC SHA-256.
};

constexpr uint8_t kUsageNone     = OT_CRYPTO_KEY_USAGE_NONE;      ///< Key Usage: Key Usage is empty.
constexpr uint8_t kUsageExport   = OT_CRYPTO_KEY_USAGE_EXPORT;    ///< Key Usage: Key can be exported.
constexpr uint8_t kUsageEncrypt  = OT_CRYPTO_KEY_USAGE_ENCRYPT;   ///< Key Usage: Encrypt (vendor defined).
constexpr uint8_t kUsageDecrypt  = OT_CRYPTO_KEY_USAGE_DECRYPT;   ///< Key Usage: AES ECB.
constexpr uint8_t kUsageSignHash = OT_CRYPTO_KEY_USAGE_SIGN_HASH; ///< Key Usage: HMAC SHA-256.

/**
 * This enumeration defines the key storage types.
 *
 */
enum StorageType : uint8_t
{
    kTypeVolatile   = OT_CRYPTO_KEY_STORAGE_VOLATILE,   ///< Key is volatile.
    kTypePersistent = OT_CRYPTO_KEY_STORAGE_PERSISTENT, ///< Key is persistent.
};

/**
 * This datatype represents the key reference.
 *
 */
typedef otCryptoKeyRef KeyRef;

constexpr KeyRef kInvalidKeyRef               = 0x80000000; ///< Invalid `KeyRef` value (PSA_KEY_ID_VENDOR_MAX + 1).
constexpr KeyRef kNetworkKeyRef               = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 1;
constexpr KeyRef kPskcRef                     = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 2;
constexpr KeyRef kActiveDatasetNetworkKeyRef  = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 3;
constexpr KeyRef kActiveDatasetPskcRef        = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 4;
constexpr KeyRef kPendingDatasetNetworkKeyRef = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 5;
constexpr KeyRef kPendingDatasetPskcRef       = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 6;

/**
 * Determine if a given `KeyRef` is valid or not.
 *
 * @param[in] aKeyRef   The `KeyRef` to check.
 *
 * @retval TRUE   If @p aKeyRef is valid.
 * @retval FALSE  If @p aKeyRef is not valid.
 *
 */
inline bool IsKeyRefValid(KeyRef aKeyRef)
{
    return (aKeyRef < kInvalidKeyRef);
}

/**
 * Import a key into PSA ITS.
 *
 * @param[in,out] aKeyRef          Reference to the key ref to be used for crypto operations.
 * @param[in]     aKeyType         Key Type encoding for the key.
 * @param[in]     aKeyAlgorithm    Key algorithm encoding for the key.
 * @param[in]     aKeyUsage        Key Usage encoding for the key.
 * @param[in]     aStorageType     Key storage type.
 * @param[in]     aKey             Actual key to be imported.
 * @param[in]     aKeyLen          Length of the key to be imported.
 *
 * @retval kErrorNone          Successfully imported the key.
 * @retval kErrorFailed        Failed to import the key.
 * @retval kErrorInvalidArgs   @p aKey was set to `nullptr`.
 *
 */
inline Error ImportKey(KeyRef &       aKeyRef,
                       KeyType        aKeyType,
                       KeyAlgorithm   aKeyAlgorithm,
                       int            aKeyUsage,
                       StorageType    aStorageType,
                       const uint8_t *aKey,
                       size_t         aKeyLen)
{
    return otPlatCryptoImportKey(&aKeyRef, static_cast<otCryptoKeyType>(aKeyType),
                                 static_cast<otCryptoKeyAlgorithm>(aKeyAlgorithm), aKeyUsage,
                                 static_cast<otCryptoKeyStorage>(aStorageType), aKey, aKeyLen);
}

/**
 * Export a key stored in PSA ITS.
 *
 * @param[in]   aKeyRef        The key ref to be used for crypto operations.
 * @param[out]  aBuffer        Pointer to the buffer where key needs to be exported.
 * @param[in]   aBufferLen     Length of the buffer passed to store the exported key.
 * @param[out]  aKeyLen        Reference to variable to return the length of the exported key.
 *
 * @retval kErrorNone          Successfully exported  @p aKeyRef.
 * @retval kErrorFailed        Failed to export @p aKeyRef.
 * @retval kErrorInvalidArgs   @p aBuffer was `nullptr`.
 *
 */
inline Error ExportKey(KeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen, size_t &aKeyLen)
{
    return otPlatCryptoExportKey(aKeyRef, aBuffer, aBufferLen, &aKeyLen);
}

/**
 * Destroy a key stored in PSA ITS.
 *
 * @param[in]   aKeyRef   The key ref to be removed.
 *
 */
inline void DestroyKey(KeyRef aKeyRef)
{
    if (IsKeyRefValid(aKeyRef))
    {
        IgnoreError(otPlatCryptoDestroyKey(aKeyRef));
    }
}

/**
 * Check if the keyRef passed has an associated key in PSA ITS.
 *
 * @param[in]  aKeyRef          The Key Ref for to check.
 *
 * @retval true                 Key Ref passed has a key associated in PSA.
 * @retval false                Key Ref passed is invalid and has no key associated in PSA.
 *
 */
inline bool HasKey(KeyRef aKeyRef)
{
    return otPlatCryptoHasKey(aKeyRef);
}

} // namespace Storage

#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE

/**
 * This class represents a crypto key.
 *
 * The `Key` can represent a literal key (i.e., a pointer to a byte array containing the key along with a key length)
 * or a `KeyRef` (if `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled).
 *
 */
class Key : public otCryptoKey, public Clearable<Key>
{
public:
    /**
     * This method sets the `Key` as a literal key from a given byte array and length.
     *
     * @param[in] aKeyBytes   A pointer to buffer containing the key.
     * @param[in] aKeyLength  The key length (number of bytes in @p akeyBytes).
     *
     */
    void Set(const uint8_t *aKeyBytes, uint16_t aKeyLength)
    {
        mKey       = aKeyBytes;
        mKeyLength = aKeyLength;
    }

    /**
     * This method gets the pointer to the bye array containing the key.
     *
     * If `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled and `IsKeyRef()` returns `true`, then this
     * method returns `nullptr`.
     *
     * @returns The pointer to the byte array containing the key, or `nullptr` if the `Key` represents a `KeyRef`
     *
     */
    const uint8_t *GetBytes(void) const { return mKey; }

    /**
     * This method gets the key length (number of bytes).
     *
     * If `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled and `IsKeyRef()` returns `true`, then this
     * method returns zero.
     *
     * @returns The key length (number of bytes in the byte array from `GetBytes()`), or zero if `Key` represents a
     *          `keyRef`.
     *
     */
    uint16_t GetLength(void) const { return mKeyLength; }

#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
    /**
     * This method indicates whether or not the key is represented as a `KeyRef`.
     *
     * @retval TRUE  The `Key` represents a `KeyRef`
     * @retval FALSE The `Key` represents a literal key.
     *
     */
    bool IsKeyRef(void) const { return (mKey == nullptr); }

    /**
     * This method gets the `KeyRef`.
     *
     * This method MUST be used when `IsKeyRef()` returns `true`, otherwise its behavior is undefined.
     *
     * @returns The `KeyRef` associated with `Key`.
     *
     */
    Storage::KeyRef GetKeyRef(void) const { return mKeyRef; }

    /**
     * This method sets the `Key` as a `KeyRef`.
     *
     * @param[in] aKeyRef   The `KeyRef` to set from.
     *
     */
    void SetAsKeyRef(Storage::KeyRef aKeyRef)
    {
        mKey       = nullptr;
        mKeyLength = 0;
        mKeyRef    = aKeyRef;
    }

    /**
     * This method extracts and return the literal key when the key is represented as a `KeyRef`
     *
     * This method MUST be used when `IsKeyRef()` returns `true`.
     *
     * @param[out]     aKeyBuffer  Pointer to a byte array buffer to place the extracted key.
     * @param[in,out]  aKeyLength  On input, the size of @p aKeyBuffer.
     *                             On exit, returns the key length (number of bytes written in @p aKeyBuffer).
     *
     * @retval kErrorNone    Successfully extracted the key, @p aKeyBuffer and @p aKeyLength are updated.
     * @retval kErrorNoBufs  Key does not fit in @p aKeyBuffer (extracted key length is larger than @p aKeyLength).
     *
     */
    Error ExtractKey(uint8_t *aKeyBuffer, uint16_t &aKeyLength) const;
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
};

/**
 * This class represents a literal key derived from a `Key`.
 *
 */
class LiteralKey : public Clearable<LiteralKey>, private NonCopyable
{
public:
    static constexpr uint16_t kMaxSize = 32; ///< Maximum size of the key.

    /**
     * This constructor initializes the `LiteralKey` from a given `Key`.
     *
     * If the @p aKey is itself represents a literal key the same key buffer pointers are used. If the @p aKey is
     * a `KeyRef` then the literal key is extracted. In this case, the extracted key MUST be smaller than `kMaxSize`.
     *
     * @param[in] aKey   The key to convert from.
     *
     */
    explicit LiteralKey(const Key &aKey);

    /*
     * This method gets the pointer to the byte array containing the literal key.
     *
     * @returns The pointer to the byte array containing the literal key.
     *
     */
    const uint8_t *GetBytes(void) const { return mKey; }

    /**
     * This method gets the key length.
     *
     * @returns The key length (number of bytes in the byte array from `GetBytes()`).
     *
     */
    uint16_t GetLength(void) const { return mLength; }

private:
    const uint8_t *mKey;
    uint16_t       mLength;
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
    uint8_t mBuffer[kMaxSize];
#endif
};

} // namespace Crypto

DefineCoreType(otCryptoKey, Crypto::Key);

} // namespace ot

#endif // STORAGE_HPP_
