/*
 *
 *    Copyright (c) 2020-2023 Project CHIP Authors
 *
 *    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.
 */

/**
 *    @file
 *      Header that exposes the platform agnostic CHIP crypto primitives
 */

#pragma once

#if CHIP_HAVE_CONFIG_H
#include <crypto/CryptoBuildConfig.h>
#endif // CHIP_HAVE_CONFIG_H

#include <system/SystemConfig.h>

#include <lib/core/CHIPError.h>
#include <lib/core/CHIPVendorIdentifiers.hpp>
#include <lib/core/DataModelTypes.h>
#include <lib/core/Optional.h>
#include <lib/support/Base64.h>
#include <lib/support/BufferReader.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/SafePointerCast.h>
#include <lib/support/Span.h>
#include <lib/support/StringBuilder.h>

#include <stddef.h>
#include <string.h>

namespace chip {
namespace Crypto {

inline constexpr size_t kMax_x509_Certificate_Length = 600;

inline constexpr size_t kP256_FE_Length                        = 32;
inline constexpr size_t kP256_ECDSA_Signature_Length_Raw       = (2 * kP256_FE_Length);
inline constexpr size_t kP256_Point_Length                     = (2 * kP256_FE_Length + 1);
inline constexpr size_t kSHA256_Hash_Length                    = 32;
inline constexpr size_t kSHA1_Hash_Length                      = 20;
inline constexpr size_t kSubjectKeyIdentifierLength            = kSHA1_Hash_Length;
inline constexpr size_t kAuthorityKeyIdentifierLength          = kSHA1_Hash_Length;
inline constexpr size_t kMaxCertificateSerialNumberLength      = 20;
inline constexpr size_t kMaxCertificateDistinguishedNameLength = 200;
inline constexpr size_t kMaxCRLDistributionPointURLLength      = 100;

inline constexpr char kValidCDPURIHttpPrefix[]  = "http://";
inline constexpr char kValidCDPURIHttpsPrefix[] = "https://";

inline constexpr size_t CHIP_CRYPTO_GROUP_SIZE_BYTES      = kP256_FE_Length;
inline constexpr size_t CHIP_CRYPTO_PUBLIC_KEY_SIZE_BYTES = kP256_Point_Length;

inline constexpr size_t CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES      = 16;
inline constexpr size_t CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES = 16;

inline constexpr size_t kMax_ECDH_Secret_Length     = kP256_FE_Length;
inline constexpr size_t kMax_ECDSA_Signature_Length = kP256_ECDSA_Signature_Length_Raw;
inline constexpr size_t kMAX_FE_Length              = kP256_FE_Length;
inline constexpr size_t kMAX_Point_Length           = kP256_Point_Length;
inline constexpr size_t kMAX_Hash_Length            = kSHA256_Hash_Length;

// Minimum required CSR length buffer length is relatively small since it's a single
// P256 key and no metadata/extensions are expected to be honored by the CA.
inline constexpr size_t kMIN_CSR_Buffer_Size = 255;

[[deprecated("This constant is no longer used by common code and should be replaced by kMIN_CSR_Buffer_Size. Checks that a CSR is "
             "<= kMAX_CSR_Buffer_size must be updated. This remains to keep valid buffers working from previous public API "
             "usage.")]] constexpr size_t kMAX_CSR_Buffer_Size = 255;

inline constexpr size_t CHIP_CRYPTO_HASH_LEN_BYTES = kSHA256_Hash_Length;

inline constexpr size_t kSpake2p_Min_PBKDF_Salt_Length  = 16;
inline constexpr size_t kSpake2p_Max_PBKDF_Salt_Length  = 32;
inline constexpr uint32_t kSpake2p_Min_PBKDF_Iterations = 1000;
inline constexpr uint32_t kSpake2p_Max_PBKDF_Iterations = 100000;

inline constexpr size_t kP256_PrivateKey_Length = CHIP_CRYPTO_GROUP_SIZE_BYTES;
inline constexpr size_t kP256_PublicKey_Length  = CHIP_CRYPTO_PUBLIC_KEY_SIZE_BYTES;

inline constexpr size_t kAES_CCM128_Key_Length   = 128u / 8u;
inline constexpr size_t kAES_CCM128_Block_Length = kAES_CCM128_Key_Length;
inline constexpr size_t kAES_CCM128_Nonce_Length = 13;
inline constexpr size_t kAES_CCM128_Tag_Length   = 16;
inline constexpr size_t kHMAC_CCM128_Key_Length  = 128u / 8u;

inline constexpr size_t CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES = kAES_CCM128_Nonce_Length;

/* These sizes are hardcoded here to remove header dependency on underlying crypto library
 * in a public interface file. The validity of these sizes is verified by static_assert in
 * the implementation files.
 */
inline constexpr size_t kMAX_Spake2p_Context_Size     = 1024;
inline constexpr size_t kMAX_P256Keypair_Context_Size = 512;

inline constexpr size_t kEmitDerIntegerWithoutTagOverhead = 1; // 1 sign stuffer
inline constexpr size_t kEmitDerIntegerOverhead           = 3; // Tag + Length byte + 1 sign stuffer

inline constexpr size_t kMAX_Hash_SHA256_Context_Size = CHIP_CONFIG_SHA256_CONTEXT_SIZE;

inline constexpr size_t kSpake2p_WS_Length                 = kP256_FE_Length + 8;
inline constexpr size_t kSpake2p_VerifierSerialized_Length = kP256_FE_Length + kP256_Point_Length;

inline constexpr char kVIDPrefixForCNEncoding[]    = "Mvid:";
inline constexpr char kPIDPrefixForCNEncoding[]    = "Mpid:";
inline constexpr size_t kVIDandPIDHexLength        = sizeof(uint16_t) * 2;
inline constexpr size_t kMax_CommonNameAttr_Length = 64;

enum class FabricBindingVersion : uint8_t
{
    kVersion1 = 0x01 // Initial version using version 1.0 of the Matter Cryptographic Primitives.
};

// VidVerificationStatementVersion is on purpose different and non-overlapping with FabricBindingVersion.
enum class VidVerificationStatementVersion : uint8_t
{
    kVersion1 = 0x21 // Initial version using version 1.0 of the Matter Cryptographic Primitives.
};

inline constexpr uint8_t kFabricBindingVersionV1 = 1u;

inline constexpr size_t kVendorIdVerificationClientChallengeSize = 32u;

// VIDVerificationStatement := statement_version || vid_verification_signer_skid || vid_verification_statement_signature
inline constexpr size_t kVendorIdVerificationStatementV1Size =
    sizeof(uint8_t) + kSubjectKeyIdentifierLength + kP256_ECDSA_Signature_Length_Raw;
static_assert(
    kVendorIdVerificationStatementV1Size == 85,
    "Expected size of VendorIdVerificationStatement version 1 was computed incorrectly due to changes of fundamental constants");

// vendor_fabric_binding_message := fabric_binding_version (1 byte) || root_public_key || fabric_id || vendor_id
inline constexpr size_t kVendorFabricBindingMessageV1Size =
    sizeof(uint8_t) + CHIP_CRYPTO_PUBLIC_KEY_SIZE_BYTES + sizeof(uint64_t) + sizeof(uint16_t);
static_assert(
    kVendorFabricBindingMessageV1Size == 76,
    "Expected size of VendorFabricBindingMessage version 1 was computed incorrectly due to changes of fundamental constants");

// vendor_id_verification_tbs := fabric_binding_version || client_challenge || attestation_challenge || fabric_index ||
// vendor_fabric_binding_message || <vid_verification_statement>
inline constexpr size_t kVendorIdVerificationTbsV1MaxSize = sizeof(uint8_t) + kVendorIdVerificationClientChallengeSize +
    CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES + sizeof(uint8_t) + kVendorFabricBindingMessageV1Size +
    kVendorIdVerificationStatementV1Size;

/*
 * Overhead to encode a raw ECDSA signature in X9.62 format in ASN.1 DER
 *
 * Ecdsa-Sig-Value ::= SEQUENCE {
 *     r       INTEGER,
 *     s       INTEGER
 * }
 *
 * --> SEQUENCE, universal constructed tag (0x30), length over 2 bytes, up to 255 (to support future larger sizes up to 512 bits)
 *   -> SEQ_OVERHEAD = 3 bytes
 * --> INTEGER, universal primitive tag (0x02), length over 1 byte, one extra byte worst case
 *     over max for 0x00 when MSB is set.
 *       -> INT_OVERHEAD = 3 bytes
 *
 * There is 1 sequence of 2 integers. Overhead is SEQ_OVERHEAD + (2 * INT_OVERHEAD) = 3 + (2 * 3) = 9.
 */
inline constexpr size_t kMax_ECDSA_X9Dot62_Asn1_Overhead = 9;
inline constexpr size_t kMax_ECDSA_Signature_Length_Der  = kMax_ECDSA_Signature_Length + kMax_ECDSA_X9Dot62_Asn1_Overhead;

static_assert(kMax_ECDH_Secret_Length >= kP256_FE_Length, "ECDH shared secret is too short for crypto suite");
static_assert(kMax_ECDSA_Signature_Length >= kP256_ECDSA_Signature_Length_Raw,
              "ECDSA signature buffer length is too short for crypto suite");

inline constexpr size_t kCompressedFabricIdentifierSize = 8;

/**
 * Spake2+ parameters for P256
 * Defined in https://www.ietf.org/id/draft-bar-cfrg-spake2plus-01.html#name-ciphersuites
 */
const uint8_t spake2p_M_p256[] = {
    0x04, 0x88, 0x6e, 0x2f, 0x97, 0xac, 0xe4, 0x6e, 0x55, 0xba, 0x9d, 0xd7, 0x24, 0x25, 0x79, 0xf2, 0x99,
    0x3b, 0x64, 0xe1, 0x6e, 0xf3, 0xdc, 0xab, 0x95, 0xaf, 0xd4, 0x97, 0x33, 0x3d, 0x8f, 0xa1, 0x2f, 0x5f,
    0xf3, 0x55, 0x16, 0x3e, 0x43, 0xce, 0x22, 0x4e, 0x0b, 0x0e, 0x65, 0xff, 0x02, 0xac, 0x8e, 0x5c, 0x7b,
    0xe0, 0x94, 0x19, 0xc7, 0x85, 0xe0, 0xca, 0x54, 0x7d, 0x55, 0xa1, 0x2e, 0x2d, 0x20,
};
const uint8_t spake2p_N_p256[] = {
    0x04, 0xd8, 0xbb, 0xd6, 0xc6, 0x39, 0xc6, 0x29, 0x37, 0xb0, 0x4d, 0x99, 0x7f, 0x38, 0xc3, 0x77, 0x07,
    0x19, 0xc6, 0x29, 0xd7, 0x01, 0x4d, 0x49, 0xa2, 0x4b, 0x4f, 0x98, 0xba, 0xa1, 0x29, 0x2b, 0x49, 0x07,
    0xd6, 0x0a, 0xa6, 0xbf, 0xad, 0xe4, 0x50, 0x08, 0xa6, 0x36, 0x33, 0x7f, 0x51, 0x68, 0xc6, 0x4d, 0x9b,
    0xd3, 0x60, 0x34, 0x80, 0x8c, 0xd5, 0x64, 0x49, 0x0b, 0x1e, 0x65, 0x6e, 0xdb, 0xe7,
};

/**
 * Spake2+ state machine to ensure proper execution of the protocol.
 */
enum class CHIP_SPAKE2P_STATE : uint8_t
{
    PREINIT = 0, // Before any initialization
    INIT,        // First initialization
    STARTED,     // Prover & Verifier starts
    R1,          // Round one complete
    R2,          // Round two complete
    KC,          // Key confirmation complete
};

/**
 * Spake2+ role.
 */
enum class CHIP_SPAKE2P_ROLE : uint8_t
{
    VERIFIER = 0, // Accessory
    PROVER   = 1, // Commissioner
};

enum class SupportedECPKeyTypes : uint8_t
{
    ECP256R1 = 0,
};

enum class ECPKeyTarget : uint8_t
{
    ECDH  = 0,
    ECDSA = 1,
};

/** @brief Safely clears the first `len` bytes of memory area `buf`.
 * @param buf Pointer to a memory buffer holding secret data that must be cleared.
 * @param len Specifies secret data size in bytes.
 **/
void ClearSecretData(uint8_t * buf, size_t len);

/**
 * Helper for clearing a C array which auto-deduces the size.
 */
template <size_t N>
void ClearSecretData(uint8_t (&buf)[N])
{
    ClearSecretData(buf, N);
}

/**
 * @brief Constant-time buffer comparison
 *
 * This function implements constant time memcmp. It's good practice
 * to use constant time functions for cryptographic functions.
 *
 * @param a Pointer to first buffer
 * @param b Pointer to Second buffer
 * @param n Number of bytes to compare
 * @return true if `n` first bytes of both buffers are equal, false otherwise
 */
bool IsBufferContentEqualConstantTime(const void * a, const void * b, size_t n);

template <typename Sig>
class ECPKey
{
protected:
    // This base type can't be copied / assigned directly.
    // Sub-types should be either uncopyable or final.
    ECPKey()                           = default;
    ECPKey(const ECPKey &)             = default;
    ECPKey & operator=(const ECPKey &) = default;

public:
    virtual ~ECPKey() = default;

    virtual SupportedECPKeyTypes Type() const  = 0;
    virtual size_t Length() const              = 0;
    virtual bool IsUncompressed() const        = 0;
    virtual operator const uint8_t *() const   = 0;
    virtual operator uint8_t *()               = 0;
    virtual const uint8_t * ConstBytes() const = 0;
    virtual uint8_t * Bytes()                  = 0;

    virtual bool Matches(const ECPKey<Sig> & other) const
    {
        return (this->Length() == other.Length()) &&
            IsBufferContentEqualConstantTime(this->ConstBytes(), other.ConstBytes(), this->Length());
    }

    virtual CHIP_ERROR ECDSA_validate_msg_signature(const uint8_t * msg, const size_t msg_length, const Sig & signature) const = 0;
    virtual CHIP_ERROR ECDSA_validate_hash_signature(const uint8_t * hash, const size_t hash_length,
                                                     const Sig & signature) const                                              = 0;
};

/**
 * @brief Helper class for holding sensitive data that should be erased from memory after use.
 *
 * The sensitive data buffer is a variable-length, fixed-capacity buffer class that securely erases
 * the contents of a buffer when the buffer is destroyed.
 */
template <size_t kCapacity>
class SensitiveDataBuffer
{
public:
    ~SensitiveDataBuffer()
    {
        // Sanitize after use
        ClearSecretData(mBytes);
    }
    SensitiveDataBuffer() {}
    SensitiveDataBuffer(const SensitiveDataBuffer & other) { *this = other; }
    SensitiveDataBuffer & operator=(const SensitiveDataBuffer & other)
    {
        // Guard self assignment
        if (this == &other)
            return *this;

        ClearSecretData(mBytes);
        SuccessOrDie(SetLength(other.Length()));
        ::memcpy(Bytes(), other.ConstBytes(), other.Length());
        return *this;
    }

    /**
     * @brief Set current length of the buffer
     * @return Error if new length is exceeds capacity of the buffer
     */
    CHIP_ERROR SetLength(size_t length)
    {
        VerifyOrReturnError(length <= kCapacity, CHIP_ERROR_INVALID_ARGUMENT);
        mLength = length;
        return CHIP_NO_ERROR;
    }

    /**
     * @brief Returns current length of the buffer
     */
    size_t Length() const { return mLength; }

    /**
     * @brief Returns non-const pointer to start of the underlying buffer
     */
    uint8_t * Bytes() { return &mBytes[0]; }

    /**
     * @brief Returns const pointer to start of the underlying buffer
     */
    const uint8_t * ConstBytes() const { return &mBytes[0]; }

    /**
     * @brief Constructs span from the underlying buffer
     */
    ByteSpan Span() const { return ByteSpan(ConstBytes(), Length()); }

    /**
     * @brief Returns capacity of the buffer
     */
    static constexpr size_t Capacity() { return kCapacity; }

    void Clear()
    {
        mLength = 0;
        ClearSecretData(mBytes);
    }

private:
    uint8_t mBytes[kCapacity];
    size_t mLength = 0;
};

/**
 * @brief Helper class for holding fixed-sized sensitive data that should be erased from memory after use.
 *
 * The sensitive data buffer is a fixed-length, fixed-capacity buffer class that securely erases
 * the contents of a buffer when the buffer is destroyed.
 */
template <size_t kCapacity>
class SensitiveDataFixedBuffer
{
public:
    SensitiveDataFixedBuffer() = default;

    constexpr explicit SensitiveDataFixedBuffer(const uint8_t (&rawValue)[kCapacity])
    {
        memcpy(&mBytes[0], &rawValue[0], kCapacity);
    }

    constexpr explicit SensitiveDataFixedBuffer(const FixedByteSpan<kCapacity> & value)
    {
        memcpy(&mBytes[0], value.data(), kCapacity);
    }

    ~SensitiveDataFixedBuffer()
    {
        // Sanitize after use
        ClearSecretData(mBytes);
    }

    /**
     * @brief Returns fixed length of the buffer
     */
    static constexpr size_t Length() { return kCapacity; }

    /**
     * @brief Returns non-const pointer to start of the underlying buffer
     */
    uint8_t * Bytes() { return &mBytes[0]; }

    /**
     * @brief Returns const pointer to start of the underlying buffer
     */
    const uint8_t * ConstBytes() const { return &mBytes[0]; }

    /**
     * @brief Constructs fixed span from the underlying buffer
     */
    FixedByteSpan<kCapacity> Span() const { return FixedByteSpan<kCapacity>(mBytes); }

    /**
     * @brief Returns capacity of the buffer
     */
    static constexpr size_t Capacity() { return kCapacity; }

    void Clear() { ClearSecretData(mBytes); }

private:
    uint8_t mBytes[kCapacity];
};

using P256ECDSASignature    = SensitiveDataBuffer<kMax_ECDSA_Signature_Length>;
using P256ECDHDerivedSecret = SensitiveDataBuffer<kMax_ECDH_Secret_Length>;

using IdentityProtectionKey     = SensitiveDataFixedBuffer<CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES>;
using IdentityProtectionKeySpan = FixedByteSpan<Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES>;

using AttestationChallenge = SensitiveDataFixedBuffer<CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES>;

class P256PublicKey final // final due to being copyable
    : public ECPKey<P256ECDSASignature>
{
public:
    P256PublicKey() = default;

    template <size_t N>
    constexpr P256PublicKey(const uint8_t (&raw_value)[N])
    {
        static_assert(N == kP256_PublicKey_Length, "Can only array-initialize from proper bounds");
        memcpy(&bytes[0], &raw_value[0], N);
    }

    template <size_t N>
    constexpr P256PublicKey(const FixedByteSpan<N> & value)
    {
        static_assert(N == kP256_PublicKey_Length, "Can only initialize from proper sized byte span");
        memcpy(&bytes[0], value.data(), N);
    }

    template <size_t N>
    P256PublicKey & operator=(const FixedByteSpan<N> & value)
    {
        static_assert(N == kP256_PublicKey_Length, "Can only initialize from proper sized byte span");
        memcpy(&bytes[0], value.data(), N);
        return *this;
    }

    SupportedECPKeyTypes Type() const override { return SupportedECPKeyTypes::ECP256R1; }
    size_t Length() const override { return kP256_PublicKey_Length; }
    operator uint8_t *() override { return bytes; }
    operator const uint8_t *() const override { return bytes; }
    const uint8_t * ConstBytes() const override { return &bytes[0]; }
    uint8_t * Bytes() override { return &bytes[0]; }
    bool IsUncompressed() const override
    {
        constexpr uint8_t kUncompressedPointMarker = 0x04;
        // SEC1 definition of an uncompressed point is (0x04 || X || Y) where X and Y are
        // raw zero-padded big-endian large integers of the group size.
        return (Length() == ((kP256_FE_Length * 2) + 1)) && (ConstBytes()[0] == kUncompressedPointMarker);
    }

    CHIP_ERROR ECDSA_validate_msg_signature(const uint8_t * msg, size_t msg_length,
                                            const P256ECDSASignature & signature) const override;
    CHIP_ERROR ECDSA_validate_hash_signature(const uint8_t * hash, size_t hash_length,
                                             const P256ECDSASignature & signature) const override;

private:
    uint8_t bytes[kP256_PublicKey_Length];
};

template <typename PK, typename Secret, typename Sig>
class ECPKeypair
{
protected:
    // This base type can't be copied / assigned directly.
    // Sub-types should be either uncopyable or final.
    ECPKeypair()                               = default;
    ECPKeypair(const ECPKeypair &)             = default;
    ECPKeypair & operator=(const ECPKeypair &) = default;

public:
    virtual ~ECPKeypair() = default;

    /** @brief Generate a new Certificate Signing Request (CSR).
     * @param csr Newly generated CSR in DER format
     * @param csr_length The caller provides the length of input buffer (csr). The function returns the actual length of generated
     *CSR.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR NewCertificateSigningRequest(uint8_t * csr, size_t & csr_length) const = 0;

    /**
     * @brief A function to sign a msg using ECDSA
     * @param msg Message that needs to be signed
     * @param msg_length Length of message
     * @param out_signature Buffer that will hold the output signature. The signature consists of: 2 EC elements (r and s),
     * in raw <r,s> point form (see SEC1).
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, Sig & out_signature) const = 0;

    /**
     * @brief A variant of ECDSA_sign_msg() that uses Deterministic ECDSA (RFC 6979).
     */
    virtual CHIP_ERROR ECDSA_sign_msg_det(const uint8_t * msg, size_t msg_length, Sig & out_signature) const = 0;

    /** @brief A function to derive a shared secret using ECDH
     * @param remote_public_key Public key of remote peer with which we are trying to establish secure channel. remote_public_key is
     * ASN.1 DER encoded as padded big-endian field elements as described in SEC 1: Elliptic Curve Cryptography
     * [https://www.secg.org/sec1-v2.pdf]
     * @param out_secret Buffer to write out secret into. This is a byte array representing the x coordinate of the shared secret.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR ECDH_derive_secret(const PK & remote_public_key, Secret & out_secret) const = 0;

    virtual const PK & Pubkey() const = 0;
};

struct alignas(size_t) P256KeypairContext
{
    uint8_t mBytes[kMAX_P256Keypair_Context_Size];
};

/**
 * A serialized P256 key pair is the concatenation of the public and private keys, in that order.
 */
using P256SerializedKeypair = SensitiveDataBuffer<kP256_PublicKey_Length + kP256_PrivateKey_Length>;

/**
 * A platform-specific P256 keypair handle that is suitable for persistence.
 * On platforms that don't use PSA (or a similar API) this is simply a P256SerializedKeypair.
 *
 * Note that there are no general APIs in the CHIP Crypto PAL that operate on
 * P256KeypairHandles; such APIs are the domain of the relevant key store interfaces.
 */
#if CHIP_CONFIG_P256_KEYPAIR_HANDLE_SIZE > 0
using P256KeypairHandle = SensitiveDataBuffer<CHIP_CONFIG_P256_KEYPAIR_HANDLE_SIZE>;
#else
using P256KeypairHandle = P256SerializedKeypair;
#endif

// Base class of P256Keypair. Do not use directly.
class P256KeypairBase : public ECPKeypair<P256PublicKey, P256ECDHDerivedSecret, P256ECDSASignature>
{
protected:
    // This base type can't be copied / assigned directly.
    // Sub-types should be either uncopyable or final.
    P256KeypairBase()                                    = default;
    P256KeypairBase(const P256KeypairBase &)             = default;
    P256KeypairBase & operator=(const P256KeypairBase &) = default;

public:
    virtual CHIP_ERROR Initialize(ECPKeyTarget key_target)             = 0;
    virtual CHIP_ERROR Serialize(P256SerializedKeypair & output) const = 0;
    virtual CHIP_ERROR Deserialize(P256SerializedKeypair & input)      = 0;
};

/**
 * A platform-specific P256 keypair implementation.
 *
 * WARNING: This class does not currently define the behavior of certain sequences of operations;
 * depending on the platform and/or crypto backend, these sequences may work, return errors, or
 * have undefined behavior. Such sequences include:
 * - Calling any method that uses the keypair before calling a method that initializes it.
 * - Calling any method that uses the keypair after calling Clear()
 * - Calling any method that initializes, deserializes, or loads the key pair on a
 *   keypair that has already been initialized, without an intervening call to Clear().
 */
class P256Keypair : public P256KeypairBase
{
public:
    P256Keypair() = default;
    ~P256Keypair() override;

    // P256Keypair can't be copied / assigned.
    P256Keypair(const P256Keypair &)             = delete;
    P256Keypair & operator=(const P256Keypair &) = delete;

    /**
     * @brief Initializes this object by generating a new keypair.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    CHIP_ERROR Initialize(ECPKeyTarget key_target) override;

    /**
     * @brief Exports the keypair as a P256SerializedKeypair containing raw public and private key bytes.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    CHIP_ERROR Serialize(P256SerializedKeypair & output) const override;

    /**
     * @brief Initializes this object by importing from a P256SerializedKeypair containing raw public and private key bytes.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    CHIP_ERROR Deserialize(/* const */ P256SerializedKeypair & input) override;

    /**
     * @brief Initializes this object from raw private key material in accordance with FIPS 186-5 appendix A.4.2.
     * To be valid, the provided key material, when interpreted as a big endian integer x, must be in the range
     * [0, N-2], where N is the order of the P-256 curve, and the resulting private key is d = x + 1.
     *
     * @return CHIP_NO_ERROR on success,
     *         CHIP_ERROR_INVALID_ARGUMENT if the provided value is out of range,
     *         CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE if the platform does not support this operation,
     *         or another CHIP_ERROR otherwise.
     */
    virtual CHIP_ERROR InitializeFromBitsOrReject(FixedByteSpan<kP256_PrivateKey_Length> privateKeyBits);

    /**
     * @brief Generates a new Certificate Signing Request (CSR).
     * @param csr Newly generated CSR in DER format
     * @param csr_length The caller provides the length of input buffer (csr). The function returns the actual length of generated
     *CSR.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    CHIP_ERROR NewCertificateSigningRequest(uint8_t * csr, size_t & csr_length) const override;

    /**
     * @brief Signs a message using ECDSA
     * @param msg Message that needs to be signed
     * @param msg_length Length of message
     * @param out_signature Buffer that will hold the output signature. The signature consists of: 2 EC elements (r and s),
     * in raw <r,s> point form (see SEC1).
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, P256ECDSASignature & out_signature) const override;

    /**
     * @brief A variant of ECDSA_sign_msg() that uses Deterministic ECDSA (RFC 6979).
     */
    CHIP_ERROR ECDSA_sign_msg_det(const uint8_t * msg, size_t msg_length, P256ECDSASignature & out_signature) const override;

    /**
     * @brief Derives a shared secret using ECDH
     *
     * This implements the CHIP_Crypto_ECDH(PrivateKey myPrivateKey, PublicKey theirPublicKey) cryptographic primitive
     * from the specification, using this class's private key from `mKeypair` as `myPrivateKey` and the remote
     * public key from `remote_public_key` as `theirPublicKey`.
     *
     * @param remote_public_key Public key of remote peer with which we are trying to establish secure channel. remote_public_key is
     * ASN.1 DER encoded as padded big-endian field elements as described in SEC 1: Elliptic Curve Cryptography
     * [https://www.secg.org/sec1-v2.pdf]
     * @param out_secret Buffer to write out secret into. This is a byte array representing the x coordinate of the shared secret.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    CHIP_ERROR ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const override;

    /**
     * @brief Loads a P256 keypair from raw private and public key byte spans.
     *
     * !!!!!! IMPORTANT !!!!!!!
     * Raw private keys SHOULD NOT be loaded directly without extreme care about ensuring they do not get retained in
     * memory (e.g. stack or heap) and have the shortest possible lifecycle. Please consider replacing basic example
     * usage of private key loading with delegation of signing to another part of the system that preferably has key
     * material isolation or protection.
     *
     * Combines the public and private key data into a serialized keypair format,
     * then deserializes it into this keypair object.
     *
     * @param private_key ByteSpan containing the raw private key bytes.
     * @param public_key ByteSpan containing the raw public key bytes.
     * @return CHIP_ERROR indicating success or failure of the operation.
     */
    CHIP_ERROR HazardousOperationLoadKeypairFromRaw(ByteSpan private_key, ByteSpan public_key);

    /** @brief Returns the public key for the keypair.
     **/
    const P256PublicKey & Pubkey() const override { return mPublicKey; }

#if CHIP_WITH_NLFAULTINJECTION
    P256PublicKey & TestOnlyMutablePubkey() { return mPublicKey; }
#endif

    /** Release resources associated with this key pair */
    void Clear();

protected:
#if CHIP_WITH_NLFAULTINJECTION
    mutable P256PublicKey mPublicKey;
#else
    P256PublicKey mPublicKey;
#endif
    // P256PublicKey mPublicKey;
    mutable P256KeypairContext mKeypair;
    bool mInitialized = false;
};

/**
 * @brief Platform-specific symmetric key handle
 *
 * The class represents a key used by the Matter stack either in the form of raw key material or key
 * reference, depending on the platform. To achieve that, it contains an opaque context that can be
 * cast to a concrete representation used by the given platform.
 *
 * @note SymmetricKeyHandle is an abstract class to force child classes for each key handle type.
 *       SymmetricKeyHandle class implements all the necessary components for handles.
 */
template <size_t ContextSize>
class SymmetricKeyHandle
{
public:
    SymmetricKeyHandle(const SymmetricKeyHandle &) = delete;
    SymmetricKeyHandle(SymmetricKeyHandle &&)      = delete;
    void operator=(const SymmetricKeyHandle &)     = delete;
    void operator=(SymmetricKeyHandle &&)          = delete;

    /**
     * @brief Get internal context cast to the desired key representation
     */
    template <class T>
    const T & As() const
    {
        return *SafePointerCast<const T *>(&mContext);
    }

    /**
     * @brief Get internal context cast to the desired, mutable key representation
     */
    template <class T>
    T & AsMutable()
    {
        return *SafePointerCast<T *>(&mContext);
    }

    static constexpr size_t Size() { return ContextSize; }

    /**
     * @brief Access the raw opaque context bytes for persistence.
     *
     * The bytes may be either raw key material or a platform-specific key reference,
     * depending on the crypto backend, and must be treated as opaque.
     *
     * @note Do NOT use this to pass key material to crypto primitives.
     *       Backend-specific code should use As() / AsMutable() to access
     *       the backend-specific concrete representation instead.
     */
    FixedByteSpan<ContextSize> OpaqueBytes() const { return FixedSpan(mContext.mOpaque); }
    MutableFixedByteSpan<ContextSize> OpaqueBytes() { return FixedSpan(mContext.mOpaque); }

protected:
    SymmetricKeyHandle() = default;
    ~SymmetricKeyHandle() { ClearSecretData(mContext.mOpaque); }

private:
    struct alignas(uintptr_t) OpaqueContext
    {
        uint8_t mOpaque[ContextSize] = {};
    } mContext;
};

/**
 * @brief Platform-specific 128-bit symmetric key handle
 */
class Symmetric128BitsKeyHandle : public SymmetricKeyHandle<CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES>
{
};

using Symmetric128BitsKeyByteArray = uint8_t[Symmetric128BitsKeyHandle::Size()];

/**
 * @brief Platform-specific 128-bit AES key handle
 */
class Aes128KeyHandle final : public Symmetric128BitsKeyHandle
{
};

/**
 * @brief Platform-specific 128-bit HMAC key handle
 */
class Hmac128KeyHandle final : public Symmetric128BitsKeyHandle
{
};

/**
 * @brief Platform-specific HKDF key handle
 */
class HkdfKeyHandle final : public SymmetricKeyHandle<CHIP_CONFIG_HKDF_KEY_HANDLE_CONTEXT_SIZE>
{
};

/**
 * @brief Convert a raw ECDSA signature to ASN.1 signature (per X9.62) as used by TLS libraries.
 *
 * Errors are:
 *   - CHIP_ERROR_INVALID_ARGUMENT on any argument being invalid (e.g. nullptr), wrong sizes,
 *     wrong or unsupported format,
 *   - CHIP_ERROR_BUFFER_TOO_SMALL on running out of space at runtime.
 *   - CHIP_ERROR_INTERNAL on any unexpected processing error.
 *
 * @param[in] fe_length_bytes Field Element length in bytes (e.g. 32 for P256 curve)
 * @param[in] raw_sig Raw signature of <r,s> concatenated
 * @param[out] out_asn1_sig ASN.1 DER signature format output buffer. Size must have space for at least
 * kMax_ECDSA_X9Dot62_Asn1_Overhead. On CHIP_NO_ERROR, the out_asn1_sig buffer will be re-assigned
 * to have the correct size based on variable-length output.
 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
 */
CHIP_ERROR EcdsaRawSignatureToAsn1(size_t fe_length_bytes, const ByteSpan & raw_sig, MutableByteSpan & out_asn1_sig);

/**
 * @brief Convert an ASN.1 DER signature (per X9.62) as used by TLS libraries to SEC1 raw format
 *
 * Errors are:
 *   - CHIP_ERROR_INVALID_ARGUMENT on any argument being invalid (e.g. nullptr), wrong sizes,
 *     wrong or unsupported format,
 *   - CHIP_ERROR_BUFFER_TOO_SMALL on running out of space at runtime.
 *   - CHIP_ERROR_INTERNAL on any unexpected processing error.
 *
 * @param[in] fe_length_bytes Field Element length in bytes (e.g. 32 for P256 curve)
 * @param[in] asn1_sig ASN.1 DER signature input
 * @param[out] out_raw_sig Raw signature of <r,s> concatenated format output buffer. Size must be at
 * least >= `2 * fe_length_bytes`. On CHIP_NO_ERROR, the out_raw_sig buffer will be re-assigned
 * to have the correct size (2 * fe_length_bytes).
 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
 */
CHIP_ERROR EcdsaAsn1SignatureToRaw(size_t fe_length_bytes, const ByteSpan & asn1_sig, MutableByteSpan & out_raw_sig);

/**
 * @brief Utility to read a length field after a tag in a DER-encoded stream.
 * @param[in] reader Reader instance from which the input will be read
 * @param[out] length Length of the following element read from the stream
 * @return CHIP_ERROR_INVALID_ARGUMENT or CHIP_ERROR_BUFFER_TOO_SMALL on error, CHIP_NO_ERROR otherwise
 */
CHIP_ERROR ReadDerLength(chip::Encoding::LittleEndian::Reader & reader, size_t & length);

/**
 * @brief Utility to emit a DER-encoded INTEGER given a raw unsigned large integer
 *        in big-endian order. The `out_der_integer` span is updated to reflect the final
 *        variable length, including tag and length, and must have at least `kEmitDerIntegerOverhead`
 *        extra space in addition to the `raw_integer.size()`.
 * @param[in] raw_integer Bytes of a large unsigned integer in big-endian, possibly including leading zeroes
 * @param[out] out_der_integer Buffer to receive the DER-encoded integer
 * @return Returns CHIP_ERROR_INVALID_ARGUMENT or CHIP_ERROR_BUFFER_TOO_SMALL on error, CHIP_NO_ERROR otherwise.
 */
CHIP_ERROR ConvertIntegerRawToDer(const ByteSpan & raw_integer, MutableByteSpan & out_der_integer);

/**
 * @brief Utility to emit a DER-encoded INTEGER given a raw unsigned large integer
 *        in big-endian order. The `out_der_integer` span is updated to reflect the final
 *        variable length, excluding tag and length, and must have at least `kEmitDerIntegerWithoutTagOverhead`
 *        extra space in addition to the `raw_integer.size()`.
 * @param[in] raw_integer Bytes of a large unsigned integer in big-endian, possibly including leading zeroes
 * @param[out] out_der_integer Buffer to receive the DER-encoded integer
 * @return Returns CHIP_ERROR_INVALID_ARGUMENT or CHIP_ERROR_BUFFER_TOO_SMALL on error, CHIP_NO_ERROR otherwise.
 */
CHIP_ERROR ConvertIntegerRawToDerWithoutTag(const ByteSpan & raw_integer, MutableByteSpan & out_der_integer);

/**
 * @brief A function that implements AES-CCM encryption
 *
 * This implements the CHIP_Crypto_AEAD_GenerateEncrypt() cryptographic primitive
 * from the specification. For an empty plaintext, the user of the API can provide
 * an empty string, or a nullptr, and provide plaintext_length as 0. The output buffer,
 * ciphertext can also be an empty string, or a nullptr for this case.
 *
 * @param plaintext Plaintext to encrypt
 * @param plaintext_length Length of plain_text
 * @param aad Additional authentication data
 * @param aad_length Length of additional authentication data
 * @param key Encryption key
 * @param nonce Encryption nonce
 * @param nonce_length Length of encryption nonce
 * @param ciphertext Buffer to write ciphertext into. Caller must ensure this is large enough to hold the ciphertext
 * @param tag Buffer to write tag into. Caller must ensure this is large enough to hold the tag
 * @param tag_length Expected length of tag
 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
 * */
CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, const uint8_t * aad, size_t aad_length,
                           const Aes128KeyHandle & key, const uint8_t * nonce, size_t nonce_length, uint8_t * ciphertext,
                           uint8_t * tag, size_t tag_length);

/**
 * @brief A function that implements AES-CCM decryption
 *
 * This implements the CHIP_Crypto_AEAD_DecryptVerify() cryptographic primitive
 * from the specification. For an empty ciphertext, the user of the API can provide
 * an empty string, or a nullptr, and provide ciphertext_length as 0. The output buffer,
 * plaintext can also be an empty string, or a nullptr for this case.
 *
 * @param ciphertext Ciphertext to decrypt
 * @param ciphertext_length Length of ciphertext
 * @param aad Additional authentical data.
 * @param aad_length Length of additional authentication data
 * @param tag Tag to use to decrypt
 * @param tag_length Length of tag
 * @param key Decryption key
 * @param nonce Encryption nonce
 * @param nonce_length Length of encryption nonce
 * @param plaintext Buffer to write plaintext into
 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
 **/
CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_length, const uint8_t * aad, size_t aad_length,
                           const uint8_t * tag, size_t tag_length, const Aes128KeyHandle & key, const uint8_t * nonce,
                           size_t nonce_length, uint8_t * plaintext);

/**
 * @brief A function that implements AES-CTR encryption/decryption
 *
 * This implements the AES-CTR-Encrypt/Decrypt() cryptographic primitives per sections
 * 3.7.1 and 3.7.2 of the specification. For an empty input, the user of the API
 * can provide an empty string, or a nullptr, and provide input as 0.
 * The output buffer can also be an empty string, or a nullptr for this case.
 *
 * @param input Input text to encrypt/decrypt
 * @param input_length Length of ciphertext
 * @param key Decryption key
 * @param nonce Encryption nonce
 * @param nonce_length Length of encryption nonce
 * @param output Buffer to write output into
 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
 **/
CHIP_ERROR AES_CTR_crypt(const uint8_t * input, size_t input_length, const Aes128KeyHandle & key, const uint8_t * nonce,
                         size_t nonce_length, uint8_t * output);

/**
 * @brief Generate a PKCS#10 CSR, usable for Matter, from a P256Keypair.
 *
 * This uses first principles ASN.1 encoding to avoid relying on the CHIPCryptoPAL backend
 * itself, other than to provide an implementation of a P256Keypair * that supports
 * at least `::Pubkey()` and `::ECDSA_sign_msg`. This allows using it with
 * OS/Platform-bridged private key handling, without requiring a specific
 * implementation of other bits like ASN.1.
 *
 * The CSR will have subject OU set to `CSA`. This is needed since omiting
 * subject altogether often trips CSR parsing code. The profile at the CA can
 * be configured to ignore CSR requested subject.
 *
 * @param keypair The key pair for which a CSR should be generated. Must not be null.
 * @param csr_span Span to hold the resulting CSR. Must have size at least kMIN_CSR_Buffer_Size.
 *                 Otherwise returns CHIP_ERROR_BUFFER_TOO_SMALL. It will get resized to
 *                 actual size needed on success.

 * @return Returns a CHIP_ERROR from P256Keypair or ASN.1 backend on error, CHIP_NO_ERROR otherwise
 **/
CHIP_ERROR GenerateCertificateSigningRequest(const P256Keypair * keypair, MutableByteSpan & csr_span);

/**
 * @brief Common code to validate ASN.1 format/size of a CSR, used by VerifyCertificateSigningRequest.
 *
 * Ensures it's not obviously malformed and doesn't have trailing garbage.
 *
 * @param csr CSR in DER format
 * @param csr_length The length of the CSR buffer
 * @return CHIP_ERROR_UNSUPPORTED_CERT_FORMAT on invalid format, CHIP_NO_ERROR otherwise.
 */
CHIP_ERROR VerifyCertificateSigningRequestFormat(const uint8_t * csr, size_t csr_length);

/**
 * @brief Verify the Certificate Signing Request (CSR). If successfully verified, it outputs the public key from the CSR.
 *
 * The CSR is valid if the format is correct, the signature validates with the embedded public
 * key, and there is no trailing garbage data.
 *
 * @param csr CSR in DER format
 * @param csr_length The length of the CSR
 * @param pubkey The public key from the verified CSR
 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
 **/
CHIP_ERROR VerifyCertificateSigningRequest(const uint8_t * csr, size_t csr_length, P256PublicKey & pubkey);

/**
 * @brief A function that implements SHA-256 hash
 *
 * This implements the CHIP_Crypto_Hash() cryptographic primitive
 * in the the specification.
 *
 * @param data The data to hash
 * @param data_length Length of the data
 * @param out_buffer Pointer to buffer to write output into
 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
 **/

CHIP_ERROR Hash_SHA256(const uint8_t * data, size_t data_length, uint8_t * out_buffer);

/**
 * @brief A function that implements SHA-1 hash
 * @param data The data to hash
 * @param data_length Length of the data
 * @param out_buffer Pointer to buffer to write output into
 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
 **/

CHIP_ERROR Hash_SHA1(const uint8_t * data, size_t data_length, uint8_t * out_buffer);

/**
 * @brief A class that defines stream based implementation of SHA-256 hash
 *        It's expected that the object of this class can be safely copied.
 *        All implementations must check for std::is_trivially_copyable.
 **/

struct alignas(CHIP_CONFIG_SHA256_CONTEXT_ALIGN) HashSHA256OpaqueContext
{
    uint8_t mOpaque[kMAX_Hash_SHA256_Context_Size];
};

class Hash_SHA256_stream
{
public:
    Hash_SHA256_stream();
    ~Hash_SHA256_stream();

    /**
     * @brief Re-initialize digest computation to an empty context.
     *
     * @return CHIP_ERROR_INTERNAL on failure to initialize the context,
     *         CHIP_NO_ERROR otherwise.
     */
    CHIP_ERROR Begin();

    /**
     * @brief Add some data to the digest computation, updating internal state.
     *
     * @param[in] data The span of bytes to include in the digest update process.
     *
     * @return CHIP_ERROR_INTERNAL on failure to ingest the data, CHIP_NO_ERROR otherwise.
     */
    CHIP_ERROR AddData(const ByteSpan data);

    /**
     * @brief Get the intermediate padded digest for the current state of the stream.
     *
     * More data can be added before finish is called.
     *
     * @param[in,out] out_buffer Output buffer to receive the digest. `out_buffer` must
     * be at least `kSHA256_Hash_Length` bytes long. The `out_buffer` size
     * will be set to `kSHA256_Hash_Length` on success.
     *
     * @return CHIP_ERROR_INTERNAL on failure to compute the digest, CHIP_ERROR_BUFFER_TOO_SMALL
     *         if out_buffer is too small, CHIP_NO_ERROR otherwise.
     */
    CHIP_ERROR GetDigest(MutableByteSpan & out_buffer);

    /**
     * @brief Finalize the stream digest computation, getting the final digest.
     *
     * @param[in,out] out_buffer Output buffer to receive the digest. `out_buffer` must
     * be at least `kSHA256_Hash_Length` bytes long. The `out_buffer` size
     * will be set to `kSHA256_Hash_Length` on success.
     *
     * @return CHIP_ERROR_INTERNAL on failure to compute the digest, CHIP_ERROR_BUFFER_TOO_SMALL
     *         if out_buffer is too small, CHIP_NO_ERROR otherwise.
     */
    CHIP_ERROR Finish(MutableByteSpan & out_buffer);

    /**
     * @brief Clear-out internal digest data to avoid lingering the state.
     */
    void Clear();

private:
    // Check if the digest computation has been initialized; implement this if your backend needs it.
    bool IsInitialized();

    HashSHA256OpaqueContext mContext;
};

class HKDF_sha
{
public:
    HKDF_sha()          = default;
    virtual ~HKDF_sha() = default;

    /**
     * @brief A function that implements SHA-256 based HKDF
     *
     * This implements the CHIP_Crypto_KDF() cryptographic primitive
     * in the the specification.
     *
     *  Error values are:
     *   - CHIP_ERROR_INVALID_ARGUMENT: for any bad arguments or nullptr input on
     *     any pointer.
     *   - CHIP_ERROR_INTERNAL: for any unexpected error arising in the underlying
     *     cryptographic layers.
     *
     * @param secret The secret to use as the key to the HKDF
     * @param secret_length Length of the secret
     * @param salt Optional salt to use as input to the HKDF
     * @param salt_length Length of the salt
     * @param info Optional info to use as input to the HKDF
     * @param info_length Length of the info
     * @param out_buffer Pointer to buffer to write output into.
     * @param out_length Size of the underlying out_buffer. That length of output key material will be generated in out_buffer.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/

    virtual CHIP_ERROR HKDF_SHA256(const uint8_t * secret, size_t secret_length, const uint8_t * salt, size_t salt_length,
                                   const uint8_t * info, size_t info_length, uint8_t * out_buffer, size_t out_length);
};

class HMAC_sha
{
public:
    HMAC_sha()          = default;
    virtual ~HMAC_sha() = default;

    /**
     * @brief A function that implements SHA-256 based HMAC per FIPS1981.
     *
     * This implements the CHIP_Crypto_HMAC() cryptographic primitive
     * in the the specification.
     *
     * The `out_length` must be at least kSHA256_Hash_Length, and only
     * kSHA256_Hash_Length bytes are written to out_buffer.
     *
     * Error values are:
     *   - CHIP_ERROR_INVALID_ARGUMENT: for any bad arguments or nullptr input on
     *     any pointer.
     *   - CHIP_ERROR_INTERNAL: for any unexpected error arising in the underlying
     *     cryptographic layers.
     *
     * @param key The key to use for the HMAC operation
     * @param key_length Length of the key
     * @param message Message over which to compute the HMAC
     * @param message_length Length of the message over which to compute the HMAC
     * @param out_buffer Pointer to buffer into which to write the output.
     * @param out_length Underlying size of the `out_buffer`.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/

    virtual CHIP_ERROR HMAC_SHA256(const uint8_t * key, size_t key_length, const uint8_t * message, size_t message_length,
                                   uint8_t * out_buffer, size_t out_length);

    /**
     * @brief A function that implements SHA-256 based HMAC per FIPS1981.
     *
     * This implements the CHIP_Crypto_HMAC() cryptographic primitive
     * in the the specification.
     *
     * The `out_length` must be at least kSHA256_Hash_Length, and only
     * kSHA256_Hash_Length bytes are written to out_buffer.
     *
     * Error values are:
     *   - CHIP_ERROR_INVALID_ARGUMENT: for any bad arguments or nullptr input on
     *     any pointer.
     *   - CHIP_ERROR_INTERNAL: for any unexpected error arising in the underlying
     *     cryptographic layers.
     *
     * @param key The HMAC Key handle to use for the HMAC operation
     * @param message Message over which to compute the HMAC
     * @param message_length Length of the message over which to compute the HMAC
     * @param out_buffer Pointer to buffer into which to write the output.
     * @param out_length Underlying size of the `out_buffer`.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR HMAC_SHA256(const Hmac128KeyHandle & key, const uint8_t * message, size_t message_length,
                                   uint8_t * out_buffer, size_t out_length);
};

/**
 * @brief A cryptographically secure random number generator based on NIST SP800-90A
 * @param out_buffer Buffer into which to write random bytes
 * @param out_length Number of random bytes to generate
 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
 **/
CHIP_ERROR DRBG_get_bytes(uint8_t * out_buffer, size_t out_length);

/** @brief Entropy callback function
 * @param data Callback-specific data pointer
 * @param output Output data to fill
 * @param len Length of output buffer
 * @param olen The actual amount of data that was written to output buffer
 * @return 0 if success
 */
typedef int (*entropy_source)(void * data, uint8_t * output, size_t len, size_t * olen);

/** @brief A function to add entropy sources to crypto library
 *
 * This function can be called multiple times to add multiple entropy sources. However,
 * once the entropy source is added, it cannot be removed. Please make sure that the
 * entropy source is valid for the lifetime of the application. Also, make sure that the
 * same entropy source is not added multiple times, e.g.: by calling this function
 * in class constructor or initialization function.
 *
 * @param fn_source Function pointer to the entropy source
 * @param p_source  Data that should be provided when fn_source is called
 * @param threshold Minimum required from source before entropy is released
 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
 **/
CHIP_ERROR add_entropy_source(entropy_source fn_source, void * p_source, size_t threshold);

class PBKDF2_sha256
{
public:
    PBKDF2_sha256()          = default;
    virtual ~PBKDF2_sha256() = default;

    /** @brief Function to derive key using password. SHA256 hashing algorithm is used for calculating hmac.
     * @param password password used for key derivation
     * @param plen length of buffer containing password
     * @param salt salt to use as input to the KDF
     * @param slen length of salt
     * @param iteration_count number of iterations to run
     * @param key_length length of output key
     * @param output output buffer where the key will be written
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR pbkdf2_sha256(const uint8_t * password, size_t plen, const uint8_t * salt, size_t slen,
                                     unsigned int iteration_count, uint32_t key_length, uint8_t * output);
};

// TODO: Extract Spake2p to a separate header and replace the forward declaration with #include SessionKeystore.h
class SessionKeystore;

/**
 * The below class implements the draft 01 version of the Spake2+ protocol as
 * defined in https://www.ietf.org/id/draft-bar-cfrg-spake2plus-01.html.
 *
 * The following describes the protocol flows:
 *
 *     Commissioner                     Accessory
 *     ------------                     ---------
 *
 *     Init
 *     BeginProver
 *     ComputeRoundOne  ------------->
 *                                      Init
 *                                      BeginVerifier
 *                                  /-  ComputeRoundOne
 *                      <-------------  ComputeRoundTwo
 *     ComputeRoundTwo  ------------->
 *     KeyConfirm                       KeyConfirm
 *     GetKeys                          GetKeys
 *
 **/
class Spake2p
{
public:
    Spake2p(size_t fe_size, size_t point_size, size_t hash_size);
    virtual ~Spake2p() = default;

    /**
     * @brief Initialize Spake2+ with some context specific information.
     *
     * @param context     The context is arbitrary but should include information about the
     *                    protocol being run, contain the transcript for negotiation, include
     *                    the PKBDF parameters, etc.
     * @param context_len The length of the context.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR Init(const uint8_t * context, size_t context_len);

    /**
     * @brief Free Spake2+ underlying objects.
     **/
    virtual void Clear() = 0;

    /**
     * @brief Start the Spake2+ process as a verifier (i.e. an accessory being provisioned).
     *
     * @param my_identity       The verifier identity. May be NULL if identities are not established.
     * @param my_identity_len   The verifier identity length.
     * @param peer_identity     The peer identity. May be NULL if identities are not established.
     * @param peer_identity_len The peer identity length.
     * @param w0in              The input w0 (a parameter baked into the device or computed with ComputeW0).
     * @param w0in_len          The input w0 length.
     * @param Lin               The input L (a parameter baked into the device or computed with ComputeL).
     * @param Lin_len           The input L length.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR BeginVerifier(const uint8_t * my_identity, size_t my_identity_len, const uint8_t * peer_identity,
                                     size_t peer_identity_len, const uint8_t * w0in, size_t w0in_len, const uint8_t * Lin,
                                     size_t Lin_len);

    /**
     * @brief Start the Spake2+ process as a prover (i.e. a commissioner).
     *
     * @param my_identity       The prover identity. May be NULL if identities are not established.
     * @param my_identity_len   The prover identity length.
     * @param peer_identity     The peer identity. May be NULL if identities are not established.
     * @param peer_identity_len The peer identity length.
     * @param w0sin             The input w0s (an output from the PBKDF).
     * @param w0sin_len         The input w0s length.
     * @param w1sin             The input w1s (an output from the PBKDF).
     * @param w1sin_len         The input w1s length.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR BeginProver(const uint8_t * my_identity, size_t my_identity_len, const uint8_t * peer_identity,
                                   size_t peer_identity_len, const uint8_t * w0sin, size_t w0sin_len, const uint8_t * w1sin,
                                   size_t w1sin_len);

    /**
     * @brief Compute the first round of the protocol.
     *
     * @param pab      X value from commissioner.
     * @param pab_len  X length.
     * @param out     The output first round Spake2+ contribution.
     * @param out_len The output first round Spake2+ contribution length.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR ComputeRoundOne(const uint8_t * pab, size_t pab_len, uint8_t * out, size_t * out_len);

    /**
     * @brief Compute the second round of the protocol.
     *
     * @param in      The peer first round Spake2+ contribution.
     * @param in_len  The peer first round Spake2+ contribution length.
     * @param out     The output second round Spake2+ contribution.
     * @param out_len The output second round Spake2+ contribution length.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR ComputeRoundTwo(const uint8_t * in, size_t in_len, uint8_t * out, size_t * out_len);

    /**
     * @brief Confirm that each party computed the same keys.
     *
     * @param in     The peer second round Spake2+ contribution.
     * @param in_len The peer second round Spake2+ contribution length.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR KeyConfirm(const uint8_t * in, size_t in_len);

    /**
     * @brief Return the shared HKDF key.
     *
     * Returns the shared key established during the Spake2+ process, which can be used
     * to derive application-specific keys using HKDF.
     *
     * @param keystore The session keystore for managing the HKDF key lifetime.
     * @param key The output HKDF key.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    CHIP_ERROR GetKeys(SessionKeystore & keystore, HkdfKeyHandle & key);

    CHIP_ERROR InternalHash(const uint8_t * in, size_t in_len);
    CHIP_ERROR WriteMN();
    CHIP_ERROR GenerateKeys();

    /**
     * @brief Load a field element.
     *
     *  @param in     The input big endian field element.
     *  @param in_len The size of the input buffer in bytes.
     *  @param fe     A pointer to an initialized implementation dependent field element.
     *
     *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR FELoad(const uint8_t * in, size_t in_len, void * fe) = 0;

    /**
     * @brief Write a field element in big-endian format.
     *
     *  @param fe      The field element to write.
     *  @param out     The output buffer.
     *  @param out_len The length of the output buffer.
     *
     *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR FEWrite(const void * fe, uint8_t * out, size_t out_len) = 0;

    /**
     * @brief Generate a field element.
     *
     *  @param fe  A pointer to an initialized implementation dependent field element.
     *
     *  @note The implementation must generate a random element from [0, q) where q is the curve order.
     *
     *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR FEGenerate(void * fe) = 0;

    /**
     * @brief Multiply two field elements, fer = fe1 * fe2.
     *
     *  @param fer   A pointer to an initialized implementation dependent field element.
     *  @param fe1  A pointer to an initialized implementation dependent field element.
     *  @param fe2  A pointer to an initialized implementation dependent field element.
     *
     *  @note The result must be a field element (i.e. reduced by the curve order).
     *
     *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR FEMul(void * fer, const void * fe1, const void * fe2) = 0;

    /**
     * @brief Load a point from 0x04 || X || Y format
     *
     * @param in     Input buffer
     * @param in_len Input buffer length
     * @param R      A pointer to an initialized implementation dependent point.
     *
     *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR PointLoad(const uint8_t * in, size_t in_len, void * R) = 0;

    /**
     * @brief Write a point in 0x04 || X || Y format
     *
     * @param R       A pointer to an initialized implementation dependent point.
     * @param out     Output buffer
     * @param out_len Length of the output buffer
     *
     *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR PointWrite(const void * R, uint8_t * out, size_t out_len) = 0;

    /**
     * @brief Scalar multiplication, R = fe1 * P1.
     *
     * @param R   Resultant point
     * @param P1  Input point
     * @param fe1  Input field element.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR PointMul(void * R, const void * P1, const void * fe1) = 0;

    /**
     * @brief Scalar multiplication with addition, R = fe1 * P1 + fe2 * P2.
     *
     * @param R   Resultant point
     * @param P1  Input point
     * @param fe1  Input field element.
     * @param P2  Input point
     * @param fe2  Input field element.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR PointAddMul(void * R, const void * P1, const void * fe1, const void * P2, const void * fe2) = 0;

    /**
     * @brief Point inversion.
     *
     * @param R   Input/Output point to point_invert
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR PointInvert(void * R) = 0;

    /**
     * @brief Multiply a point by the curve cofactor.
     *
     * @param R   Input/Output point to point_invert
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR PointCofactorMul(void * R) = 0;

    /*
     *   @synopsis Check if a point is on the curve.
     *
     *   @param R   Input point to check.
     *
     *   @return CHIP_NO_ERROR if the point is valid, CHIP_ERROR otherwise.
     */
    virtual CHIP_ERROR PointIsValid(void * R) = 0;

    /*
     *   @synopsis Compute w0sin mod p
     *
     *   @param w0out       Output field element w0
     *   @param w0_len      Output field element length
     *   @param w0sin       Input field element
     *   @param w0sin_len   Input field element length
     *
     *   @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR ComputeW0(uint8_t * w0out, size_t * w0_len, const uint8_t * w0sin, size_t w0sin_len) = 0;

    /*
     *   @synopsis Compute w1in*G where w1in is w1sin mod p
     *
     *   @param Lout        Output point in 0x04 || X || Y format.
     *   @param L_len       Output point length
     *   @param w1sin       Input field element
     *   @param w1sin_len   Input field element size
     *
     *   @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR ComputeL(uint8_t * Lout, size_t * L_len, const uint8_t * w1sin, size_t w1sin_len) = 0;

    void * M;
    void * N;
    const void * G;
    void * X;
    void * Y;
    void * L;
    void * Z;
    void * V;
    void * w0;
    void * w1;
    void * xy;
    void * order;
    void * tempbn;

protected:
    /**
     * @brief Initialize underlying implementation curve, points, field elements, etc.
     *
     * @details The implementation needs to:
     *     1. Initialize each of the points below and set the relevant pointers on the class:
     *        a. M
     *        b. N
     *        c. G
     *        d. X
     *        e. Y
     *        f. L
     *        g. Z
     *        h. V
     *
     *        As an example:
     *           this.M = implementation_alloc_point();
     *     2. Initialize each of the field elements below and set the relevant pointers on the class:
     *        a. w0
     *        b. w1
     *        c. xy
     *        d. tempbn
     *     3. The hashing context should be initialized
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR InitImpl() = 0;

    /**
     * @brief Hash in_len bytes of in into the internal hash context.
     *
     * @param in     The input buffer.
     * @param in_len Size of the input buffer in bytes.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR Hash(const uint8_t * in, size_t in_len) = 0;

    /**
     * @brief Return the hash.
     *
     * @param out_span Output buffer. The size available must be >= the hash size. It gets resized
     *                 to hash size on success.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR HashFinalize(MutableByteSpan & out_span) = 0;

    /**
     * @brief Generate a message authentication code.
     *
     * @param key      The MAC key buffer.
     * @param key_len  The size of the MAC key in bytes.
     * @param in       The input buffer.
     * @param in_len   The size of the input data to MAC in bytes.
     * @param out_span The output MAC buffer span. Size must be >= the hash_size. Output size is updated to fit on success.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR Mac(const uint8_t * key, size_t key_len, const uint8_t * in, size_t in_len, MutableByteSpan & out_span) = 0;

    /**
     * @brief Verify a message authentication code.
     *
     *  @param key     The MAC key buffer.
     *  @param key_len The size of the MAC key in bytes.
     *  @param mac     The input MAC buffer.
     *  @param mac_len The size of the MAC in bytes.
     *  @param in      The input buffer to verify.
     *  @param in_len  The size of the input data to verify in bytes.
     *
     *  @return Returns a CHIP_ERROR when the MAC doesn't validate, CHIP_NO_ERROR otherwise.
     **/
    virtual CHIP_ERROR MacVerify(const uint8_t * key, size_t key_len, const uint8_t * mac, size_t mac_len, const uint8_t * in,
                                 size_t in_len) = 0;

    /**
     * @brief Derive an key of length out_len.
     *
     * @param ikm      The input key material buffer.
     * @param ikm_len  The input key material length.
     * @param salt     The optional salt. This may be NULL.
     * @param salt_len The size of the salt in bytes.
     * @param info     The info.
     * @param info_len The size of the info in bytes.
     * @param out      The output key
     * @param out_len  The output key length
     *
     * @return Returns a CHIP_ERROR when the MAC doesn't validate, CHIP_NO_ERROR otherwise.
     **/
    virtual CHIP_ERROR KDF(const uint8_t * ikm, size_t ikm_len, const uint8_t * salt, size_t salt_len, const uint8_t * info,
                           size_t info_len, uint8_t * out, size_t out_len) = 0;

    CHIP_SPAKE2P_ROLE role;
    CHIP_SPAKE2P_STATE state = CHIP_SPAKE2P_STATE::PREINIT;
    size_t fe_size;
    size_t hash_size;
    size_t point_size;
    uint8_t Kcab[kMAX_Hash_Length];
    uint8_t Kae[kMAX_Hash_Length];
    uint8_t * Kca;
    uint8_t * Kcb;
    uint8_t * Ka;
    uint8_t * Ke;
};

struct alignas(size_t) Spake2pOpaqueContext
{
    uint8_t mOpaque[kMAX_Spake2p_Context_Size];
};

class Spake2p_P256_SHA256_HKDF_HMAC : public Spake2p
{
public:
    Spake2p_P256_SHA256_HKDF_HMAC() : Spake2p(kP256_FE_Length, kP256_Point_Length, kSHA256_Hash_Length)
    {
        memset(&mSpake2pContext, 0, sizeof(mSpake2pContext));
    }

    ~Spake2p_P256_SHA256_HKDF_HMAC() override { Spake2p_P256_SHA256_HKDF_HMAC::Clear(); }

    void Clear() override;
    CHIP_ERROR Mac(const uint8_t * key, size_t key_len, const uint8_t * in, size_t in_len, MutableByteSpan & out_span) override;
    CHIP_ERROR MacVerify(const uint8_t * key, size_t key_len, const uint8_t * mac, size_t mac_len, const uint8_t * in,
                         size_t in_len) override;
    CHIP_ERROR FELoad(const uint8_t * in, size_t in_len, void * fe) override;
    CHIP_ERROR FEWrite(const void * fe, uint8_t * out, size_t out_len) override;
    CHIP_ERROR FEGenerate(void * fe) override;
    CHIP_ERROR FEMul(void * fer, const void * fe1, const void * fe2) override;

    CHIP_ERROR PointLoad(const uint8_t * in, size_t in_len, void * R) override;
    CHIP_ERROR PointWrite(const void * R, uint8_t * out, size_t out_len) override;
    CHIP_ERROR PointMul(void * R, const void * P1, const void * fe1) override;
    CHIP_ERROR PointAddMul(void * R, const void * P1, const void * fe1, const void * P2, const void * fe2) override;
    CHIP_ERROR PointInvert(void * R) override;
    CHIP_ERROR PointCofactorMul(void * R) override;
    CHIP_ERROR PointIsValid(void * R) override;

    CHIP_ERROR ComputeW0(uint8_t * w0out, size_t * w0_len, const uint8_t * w0sin, size_t w0sin_len) override;
    CHIP_ERROR ComputeL(uint8_t * Lout, size_t * L_len, const uint8_t * w1sin, size_t w1sin_len) override;

protected:
    CHIP_ERROR InitImpl() override;
    CHIP_ERROR Hash(const uint8_t * in, size_t in_len) override;
    CHIP_ERROR HashFinalize(MutableByteSpan & out_span) override;
    CHIP_ERROR KDF(const uint8_t * secret, size_t secret_length, const uint8_t * salt, size_t salt_length, const uint8_t * info,
                   size_t info_length, uint8_t * out, size_t out_length) override;

private:
    CHIP_ERROR InitInternal();
    Hash_SHA256_stream sha256_hash_ctx;

    Spake2pOpaqueContext mSpake2pContext;
};

/**
 * @brief Class used for verifying PASE secure sessions.
 **/
class Spake2pVerifier
{
public:
    uint8_t mW0[kP256_FE_Length];
    uint8_t mL[kP256_Point_Length];

    CHIP_ERROR Serialize(MutableByteSpan & outSerialized) const;
    CHIP_ERROR Deserialize(const ByteSpan & inSerialized);

    /**
     * @brief Generate the Spake2+ verifier.
     *
     * @param pbkdf2IterCount Iteration count for PBKDF2 function
     * @param salt            Salt to be used for Spake2+ operation
     * @param setupPin        Provided setup PIN (passcode)
     *
     * @return CHIP_ERROR     The result of Spake2+ verifier generation
     */
    CHIP_ERROR Generate(uint32_t pbkdf2IterCount, const ByteSpan & salt, uint32_t setupPin);

    /**
     * @brief Compute the initiator values (w0s, w1s) used for PAKE input.
     *
     * @param pbkdf2IterCount Iteration count for PBKDF2 function
     * @param salt            Salt to be used for Spake2+ operation
     * @param setupPin        Provided setup PIN (passcode)
     * @param ws              The output pair (w0s, w1s) stored sequentially
     * @param ws_len          The output length
     *
     * @return CHIP_ERROR     The result from running PBKDF2
     */
    static CHIP_ERROR ComputeWS(uint32_t pbkdf2IterCount, const ByteSpan & salt, uint32_t setupPin, uint8_t * ws, uint32_t ws_len);
};

/**
 * @brief Serialized format of the Spake2+ Verifier components.
 *
 *  This is used when the Verifier should be presented in a serialized form.
 *  For example, when it is generated using PBKDF function, when stored in the
 *  memory or when sent over the wire.
 *  The serialized format is concatentation of 'W0' and 'L' verifier components:
 *      { Spake2pVerifier.mW0[kP256_FE_Length], Spake2pVerifier.mL[kP256_Point_Length] }
 **/
typedef uint8_t Spake2pVerifierSerialized[kSpake2p_VerifierSerialized_Length];

/**
 * @brief Compute the compressed fabric identifier used for operational discovery service
 *        records from a Node's root public key and Fabric ID. On success, out_compressed_fabric_id
 *        will have a size of exactly kCompressedFabricIdentifierSize.
 *
 * Errors are:
 *   - CHIP_ERROR_INVALID_ARGUMENT if root_public_key is invalid
 *   - CHIP_ERROR_BUFFER_TOO_SMALL if out_compressed_fabric_id is too small for serialization
 *   - CHIP_ERROR_INTERNAL on any unexpected crypto or data conversion errors.
 *
 * @param[in] root_public_key The root public key associated with the node's fabric
 * @param[in] fabric_id The fabric ID associated with the node's fabric
 * @param[out] out_compressed_fabric_id Span where output will be written. Its size must be >= kCompressedFabricIdentifierSize.
 * @returns a CHIP_ERROR (see above) on failure or CHIP_NO_ERROR otherwise.
 */
CHIP_ERROR GenerateCompressedFabricId(const Crypto::P256PublicKey & root_public_key, uint64_t fabric_id,
                                      MutableByteSpan & out_compressed_fabric_id);

/**
 * @brief Compute the compressed fabric identifier used for operational discovery service
 *        records from a Node's root public key and Fabric ID.  This is a conveniance
 *        overload that writes to a uint64_t (CompressedFabricId) type.
 *
 * @param[in] rootPublicKey The root public key associated with the node's fabric
 * @param[in] fabricId The fabric ID associated with the node's fabric
 * @param[out] compressedFabricId output location for compressed fabric ID
 * @returns a CHIP_ERROR on failure or CHIP_NO_ERROR otherwise.
 */
CHIP_ERROR GenerateCompressedFabricId(const Crypto::P256PublicKey & rootPublicKey, uint64_t fabricId,
                                      uint64_t & compressedFabricId);

enum class CertificateChainValidationResult
{
    kSuccess = 0,

    kRootFormatInvalid   = 100,
    kRootArgumentInvalid = 101,

    kICAFormatInvalid   = 200,
    kICAArgumentInvalid = 201,

    kLeafFormatInvalid   = 300,
    kLeafArgumentInvalid = 301,

    kChainInvalid = 400,

    kNoMemory = 500,

    kInternalFrameworkError = 600,
};

CHIP_ERROR ValidateCertificateChain(const uint8_t * rootCertificate, size_t rootCertificateLen, const uint8_t * caCertificate,
                                    size_t caCertificateLen, const uint8_t * leafCertificate, size_t leafCertificateLen,
                                    CertificateChainValidationResult & result);

enum class AttestationCertType
{
    kPAA = 0,
    kPAI = 1,
    kDAC = 2,
};

CHIP_ERROR VerifyAttestationCertificateFormat(const ByteSpan & cert, AttestationCertType certType);

/**
 * @brief Generate a VendorFabricBindingMessage as used by the Fabric Table Vendor ID Verification Procedure.
 *
 * @param[in] fabricBindingVersion - Version of binding payload to generate. outputSpan size requirements are based on this.
 * @param[in] rootPublicKey - Root public key for the fabric in question
 * @param[in] fabricId - Fabric ID for the fabric in question
 * @param[in] vendorId - Vendor ID for the fabric in question
 * @param[inout] outputSpan - Span that will receive the binding message. Must be large enough for the
 *                            payload (otherwise CHIP_ERROR_BUFFER_TOO_SMALL) and will be resized to fit.
 * @return CHIP_NO_ERROR on success, otherwise another CHIP_ERROR value representative of the failure.
 */
CHIP_ERROR GenerateVendorFabricBindingMessage(FabricBindingVersion fabricBindingVersion, const P256PublicKey & rootPublicKey,
                                              FabricId fabricId, uint16_t vendorId, MutableByteSpan & outputSpan);

/**
 * @brief Generate the message to be signed for the Fabric Table Vendor ID Verification Procedure.
 *
 * The Fabric Binding Version value will be recovered from the vendorFabricBindingMessage.
 *
 * @param fabricIndex - Fabric Index for the fabric in question
 * @param clientChallenge - Client challenge to use
 * @param attestationChallenge - Attestation challenge to use
 * @param vendorFabricBindingMessage - The VendorFabricBindingMessage previously computed for the fabric
 * @param vidVerificationStatement - The VID Verification Statement to include in signature (may be empty)
 * @param outputSpan - Span that will receive the to-be-signed message. Must be large enough for the
 *                     payload (otherwise CHIP_ERROR_BUFFER_TOO_SMALL) and will be resized to fit.
 * @return CHIP_NO_ERROR on success, otherwise another CHIP_ERROR value representative of the failure.
 */
CHIP_ERROR GenerateVendorIdVerificationToBeSigned(FabricIndex fabricIndex, const ByteSpan & clientChallenge,
                                                  const ByteSpan & attestationChallenge,
                                                  const ByteSpan & vendorFabricBindingMessage,
                                                  const ByteSpan & vidVerificationStatement, MutableByteSpan & outputSpan);

/**
 * @brief Validate notBefore timestamp of a certificate (candidateCertificate) against validity period of the
 *        issuer certificate (issuerCertificate).
 *
 * Errors are:
 *   - CHIP_ERROR_CERT_EXPIRED if the candidateCertificate timestamp does not satisfy the issuerCertificate's timestamp.
 *   - CHIP_ERROR_INVALID_ARGUMENT when passing an invalid argument.
 *   - CHIP_ERROR_INTERNAL on any unexpected crypto or data conversion errors.
 *
 *  @param candidateCertificate     A DER Certificate ByteSpan those notBefore timestamp to be evaluated.
 *  @param issuerCertificate        A DER Certificate ByteSpan used to evaluate validity timestamp of the candidateCertificate.
 *
 *  @returns a CHIP_ERROR (see above) on failure or CHIP_NO_ERROR otherwise.
 **/
CHIP_ERROR IsCertificateValidAtIssuance(const ByteSpan & candidateCertificate, const ByteSpan & issuerCertificate);

/**
 * @brief Validate a certificate's validity date against current time.
 *
 * Errors are:
 *   - CHIP_ERROR_CERT_EXPIRED if the certificate has expired.
 *   - CHIP_ERROR_INVALID_ARGUMENT when passing an invalid argument.
 *   - CHIP_ERROR_INTERNAL on any unexpected crypto or data conversion errors.
 *
 *  @param certificate A DER Certificate ByteSpan used as the validity reference to be checked against current time.
 *
 *  @returns a CHIP_ERROR (see above) on failure or CHIP_NO_ERROR otherwise.
 **/
CHIP_ERROR IsCertificateValidAtCurrentTime(const ByteSpan & certificate);

CHIP_ERROR ExtractPubkeyFromX509Cert(const ByteSpan & certificate, Crypto::P256PublicKey & pubkey);

/**
 * @brief Extracts the Subject Key Identifier from an X509 Certificate.
 **/
CHIP_ERROR ExtractSKIDFromX509Cert(const ByteSpan & certificate, MutableByteSpan & skid);

/**
 * @brief Extracts the Authority Key Identifier from an X509 Certificate.
 **/
CHIP_ERROR ExtractAKIDFromX509Cert(const ByteSpan & certificate, MutableByteSpan & akid);

/**
 * @brief Extracts the CRL Distribution Point (CDP) extension from an X509 ASN.1 Encoded Certificate.
 *        The returned value only covers the URI of the CDP. Only a single URI distribution point
 *        GeneralName is supported, and only those that start with "http://" and "https://".
 *
 * @returns CHIP_ERROR_NOT_FOUND if not found or wrong format.
 *          CHIP_NO_ERROR otherwise.
 **/
CHIP_ERROR ExtractCRLDistributionPointURIFromX509Cert(const ByteSpan & certificate, MutableCharSpan & cdpurl);

/**
 * @brief Extracts the CRL Distribution Point (CDP) extension's cRLIssuer Name from an X509 ASN.1 Encoded Certificate.
 *        The value is copied into buffer in a raw ASN.1 X.509 format. This format should be directly comparable
 *        with the result of ExtractSubjectFromX509Cert().
 *
 * @returns CHIP_ERROR_NOT_FOUND if not found or wrong format.
 *          CHIP_NO_ERROR otherwise.
 **/
CHIP_ERROR ExtractCDPExtensionCRLIssuerFromX509Cert(const ByteSpan & certificate, MutableByteSpan & crlIssuer);

/**
 * @brief Extracts Serial Number from X509 Certificate.
 **/
CHIP_ERROR ExtractSerialNumberFromX509Cert(const ByteSpan & certificate, MutableByteSpan & serialNumber);

/**
 * @brief Extracts Subject Distinguished Name from X509 Certificate. The value is copied into buffer in a raw ASN.1 X.509 format.
 **/
CHIP_ERROR ExtractSubjectFromX509Cert(const ByteSpan & certificate, MutableByteSpan & subject);

/**
 * @brief Extracts Issuer Distinguished Name from X509 Certificate. The value is copied into buffer in a raw ASN.1 X.509 format.
 **/
CHIP_ERROR ExtractIssuerFromX509Cert(const ByteSpan & certificate, MutableByteSpan & issuer);

class PemEncoder
{
public:
    /**
     * @brief Construct a PEM encoder for element type `encodedElement` whose DER data is in `derBytes` span.
     *
     * LIFETIME: both encodedElement and derBytes lifetime must be >= PemEncoder lifetime.
     *           PemEncoder references these while processing `NextLine()` calls.
     *
     * @param encodedElement - Element type string to include in header/footer (e.g. "CERTIFICATE"). Caller must provide correct
     * uppercase.
     * @param derBytes - Byte span containing data to encode. May be empty.
     */
    explicit PemEncoder(const char * encodedElement, ByteSpan derBytes) : mEncodedElement(encodedElement), mDerBytes(derBytes) {}

    // No copies.
    PemEncoder(const PemEncoder &)             = delete;
    PemEncoder & operator=(const PemEncoder &) = delete;

    /**
     * @brief Returns the pointer to the next null-terminated line of the encoding, or nullptr if done.
     *
     * The returned pointer has the lifetime of this class and during that lifetime will always point
     * to valid memory.
     *
     * When header/footer are written, the heading type (`encodedElement` value) such as
     * `CERTIFICATE` is clamped so that the entire header line with `-----BEGIN ${encodedElement}-----`
     * and footer line with `-----END ${encodedElement}-----` are not wider than 64 bytes. This
     * will not happen in practice with the types of things this is meant to encode.
     *
     * Usage should be in a loop, for example:
     *
     *   std::vector<std::string> pemLines;
     *
     *   PemEncoder encoder("CERTIFICATE", TestCerts::sTestCert_PAA_FFF1_Cert);
     *
     *   const char* line = encoder.NextLine();
     *   while (line)
     *   {
     *       pemLines.push_back(std::string{ line });
     *       line = encoder.NextLine();
     *   }
     *
     * @return a pointer to the internal line buffer for next line or nullptr when done.
     */
    const char * NextLine();

private:
    static constexpr size_t kNumBytesPerLine = 48u;
    static constexpr size_t kLineBufferSize  = 64u + 1u; // PEM expects 64 characters wide and a null terminator at least.
    static_assert(kLineBufferSize == (BASE64_ENCODED_LEN(kNumBytesPerLine) + 1), "Internal incoherence of library configuration!");

    enum State : int
    {
        kPrintHeader = 0,
        kPrintBody   = 1,
        kPrintFooter = 2,
        kDone        = 3,
    };

    const char * mEncodedElement; // "CERTIFICATE", "EC PUBLIC KEY", etc. Must be capitalized by caller.
    ByteSpan mDerBytes;
    State mState           = State::kPrintHeader;
    size_t mProcessedBytes = 0;
    StringBuilder<kLineBufferSize> mStringBuilder{};
};

// Utility class to take subject Key IDs (AKID/SKID) and convert them to DCL format ("A5:FF:00.....:DE:AD").
class KeyIdStringifier
{
public:
    KeyIdStringifier() = default;

    /**
     * @brief Returns the null-terminated string buffer owned by the class containing converted KeyID.
     *
     * LIFETIME NOTE: The last returned value from KeyIdToHex is valid until the next call.
     *
     * This is optimized for standard 20-byte AKID/SKID but works for any length, truncating very long ones.
     *
     * @param keyIdBuffer - buffer of bytes of the key ID.
     * @return pointer to class-owned storage of a null-terminated string in DCL format.
     */
    const char * KeyIdToHex(ByteSpan keyIdBuffer)
    {
        mStringBuilder.Reset();
        if (keyIdBuffer.empty())
        {
            mStringBuilder.Add("<EMPTY KEY ID>");
            return mStringBuilder.c_str();
        }

        mStringBuilder.AddFormat("%02X", keyIdBuffer[0]);
        for (size_t i = 1; i < keyIdBuffer.size(); ++i)
        {
            mStringBuilder.Add(":");
            mStringBuilder.AddFormat("%02X", keyIdBuffer[i]);
        }

        return mStringBuilder.AddMarkerIfOverflow().c_str();
    }

private:
    StringBuilder<(Crypto::kAuthorityKeyIdentifierLength * 3) + 1> mStringBuilder;
};

/**
 * @brief Checks for resigned version of the certificate in the list and returns it.
 *
 * The following conditions SHOULD be satisfied for the certificate to qualify as
 * a resigned version of a reference certificate:
 *   - SKID of the candidate and the reference certificate should match.
 *   - SubjectDN of the candidate and the reference certificate should match.
 *
 * If no resigned version is found then reference certificate itself is returned.
 *
 *  @param referenceCertificate       A DER certificate.
 *  @param candidateCertificates      A pointer to the list of DER Certificates, which should be searched
 *                                    for the resigned version of `referenceCertificate`.
 *  @param candidateCertificatesCount Number of certificates in the `candidateCertificates` list.
 *  @param outCertificate             A reference to the certificate or it's resigned version if found.
 *                                    Note that it points to either `referenceCertificate` or one of
 *                                    `candidateCertificates`, but it doesn't copy data.
 *
 *  @returns error if there is certificate parsing/format issue or CHIP_NO_ERROR otherwise.
 **/
CHIP_ERROR ReplaceCertIfResignedCertFound(const ByteSpan & referenceCertificate, const ByteSpan * candidateCertificates,
                                          size_t candidateCertificatesCount, ByteSpan & outCertificate);

/**
 * Defines DN attribute types that can include endocing of VID/PID parameters.
 */
enum class DNAttrType
{
    kUnspecified = 0,
    kCommonName  = 1,
    kMatterVID   = 2,
    kMatterPID   = 3,
};

/**
 *  @struct AttestationCertVidPid
 *
 *  @brief
 *    A data structure representing Attestation Certificate VID and PID attributes.
 */
struct AttestationCertVidPid
{
    Optional<VendorId> mVendorId;
    Optional<uint16_t> mProductId;

    bool Initialized() const { return (mVendorId.HasValue() || mProductId.HasValue()); }
};

/**
 * @brief Extracts VID and PID attributes from the DN Attribute string.
 *        If attribute is not present the corresponding output value stays uninitialized.
 *
 * @return CHIP_ERROR_INVALID_ARGUMENT if wrong input is provided.
 *         CHIP_ERROR_WRONG_CERT_DN if encoding of kMatterVID and kMatterPID attributes is wrong.
 *         CHIP_NO_ERROR otherwise.
 **/
CHIP_ERROR ExtractVIDPIDFromAttributeString(DNAttrType attrType, const ByteSpan & attr,
                                            AttestationCertVidPid & vidpidFromMatterAttr, AttestationCertVidPid & vidpidFromCNAttr);

/**
 * @brief Extracts VID and PID attributes from the Subject DN of an X509 Certificate.
 *        If attribute is not present the corresponding output value stays uninitialized.
 **/
CHIP_ERROR ExtractVIDPIDFromX509Cert(const ByteSpan & x509Cert, AttestationCertVidPid & vidpid);

/**
 * @brief The set of credentials needed to operate group message security with symmetric keys.
 */
typedef struct GroupOperationalCredentials
{
    /// Validity start time in microseconds since 2000-01-01T00:00:00 UTC ("the Epoch")
    uint64_t start_time;
    /// Session Id
    uint16_t hash;
    /// Operational group key
    uint8_t encryption_key[Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES];
    /// Privacy key
    uint8_t privacy_key[Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES];
} GroupOperationalCredentials;

/**
 * @brief Opaque context used to protect a symmetric key. The key operations must
 *        be performed without exposing the protected key value.
 */
class SymmetricKeyContext
{
public:
    /**
     * @brief Returns the symmetric key hash
     *
     * TODO: Replace GetKeyHash() with DeriveGroupSessionId(SymmetricKeyContext &, uint16_t & session_id)
     *
     * @return Group Key Hash
     */
    virtual uint16_t GetKeyHash() = 0;

    virtual ~SymmetricKeyContext() = default;
    /**
     * @brief Perform the message encryption as described in 4.7.2. (Security Processing of Outgoing Messages)
     * @param[in] plaintext     Outgoing message payload.
     * @param[in] aad           Additional data (message header contents)
     * @param[in] nonce         Nonce (Security Flags | Message Counter | Source Node ID)
     * @param[out] mic          Outgoing Message Integrity Check
     * @param[out] ciphertext   Outgoing encrypted payload. Must be at least as big as plaintext. The same buffer may be used both
     * for ciphertext, and plaintext.
     * @return CHIP_ERROR
     */
    virtual CHIP_ERROR MessageEncrypt(const ByteSpan & plaintext, const ByteSpan & aad, const ByteSpan & nonce,
                                      MutableByteSpan & mic, MutableByteSpan & ciphertext) const = 0;
    /**
     * @brief Perform the message decryption as described in 4.7.3.(Security Processing of Incoming Messages)
     * @param[in] ciphertext    Incoming encrypted payload
     * @param[in] aad           Additional data (message header contents)
     * @param[in] nonce         Nonce (Security Flags | Message Counter | Source Node ID)
     * @param[in] mic           Incoming Message Integrity Check
     * @param[out] plaintext     Incoming message payload. Must be at least as big as ciphertext. The same buffer may be used both
     * for plaintext, and ciphertext.
     * @return CHIP_ERROR
     */
    virtual CHIP_ERROR MessageDecrypt(const ByteSpan & ciphertext, const ByteSpan & aad, const ByteSpan & nonce,
                                      const ByteSpan & mic, MutableByteSpan & plaintext) const = 0;

    /**
     * @brief Perform privacy encoding as described in 4.8.2. (Privacy Processing of Outgoing Messages)
     * @param[in] input         Message header to privacy encrypt
     * @param[in] nonce         Privacy Nonce = session_id | mic
     * @param[out] output       Message header obfuscated
     * @return CHIP_ERROR
     */
    virtual CHIP_ERROR PrivacyEncrypt(const ByteSpan & input, const ByteSpan & nonce, MutableByteSpan & output) const = 0;

    /**
     * @brief Perform privacy decoding as described in 4.8.3. (Privacy Processing of Incoming Messages)
     * @param[in] input         Message header to privacy decrypt
     * @param[in] nonce         Privacy Nonce = session_id | mic
     * @param[out] output       Message header deobfuscated
     * @return CHIP_ERROR
     */
    virtual CHIP_ERROR PrivacyDecrypt(const ByteSpan & input, const ByteSpan & nonce, MutableByteSpan & output) const = 0;

    /**
     * @brief Release resources such as dynamic memory used to allocate this instance of the SymmetricKeyContext
     */
    virtual void Release() = 0;
};

/**
 *  @brief Derives the Operational Group Key using the Key Derivation Function (KDF) from the given epoch key.
 * @param[in] epoch_key  The epoch key. Must be CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
 * @param[in] compressed_fabric_id The compressed fabric ID for the fabric (big endian byte string)
 * @param[out] out_key  Symmetric key used as the encryption key during message processing for group communication.
 The buffer size must be at least CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
 * @return Returns a CHIP_NO_ERROR on succcess, or CHIP_ERROR_INTERNAL if the provided key is invalid.
 **/
CHIP_ERROR DeriveGroupOperationalKey(const ByteSpan & epoch_key, const ByteSpan & compressed_fabric_id, MutableByteSpan & out_key);

/**
 *  @brief Derives the Group Session ID from a given operational group key using
 *         the Key Derivation Function (Group Key Hash)
 * @param[in] operational_key  The operational group key. Must be CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
 * @param[out] session_id  Output of the Group Key Hash
 * @return Returns a CHIP_NO_ERROR on succcess, or CHIP_ERROR_INVALID_ARGUMENT if the provided key is invalid.
 **/
CHIP_ERROR DeriveGroupSessionId(const ByteSpan & operational_key, uint16_t & session_id);

/**
 *  @brief Derives the Privacy Group Key using the Key Derivation Function (KDF) from the given epoch key.
 * @param[in] epoch_key  The epoch key. Must be CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
 * @param[out] out_key  Symmetric key used as the privacy key during message processing for group communication.
 *                      The buffer size must be at least CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
 * @return Returns a CHIP_NO_ERROR on succcess, or CHIP_ERROR_INTERNAL if the provided key is invalid.
 **/
CHIP_ERROR DeriveGroupPrivacyKey(const ByteSpan & epoch_key, MutableByteSpan & out_key);

/**
 *  @brief Derives the complete set of credentials needed for group security.
 *
 * This function will derive the Encryption Key, Group Key Hash (Session Id), and Privacy Key
 * for the given Epoch Key and Compressed Fabric Id.
 * @param[in] epoch_key  The epoch key. Must be CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
 * @param[in] compressed_fabric_id The compressed fabric ID for the fabric (big endian byte string)
 * @param[out] operational_credentials The set of Symmetric keys used during message processing for group communication.
 * @return Returns a CHIP_NO_ERROR on succcess, or CHIP_ERROR_INTERNAL if the provided key is invalid.
 **/
CHIP_ERROR DeriveGroupOperationalCredentials(const ByteSpan & epoch_key, const ByteSpan & compressed_fabric_id,
                                             GroupOperationalCredentials & operational_credentials);
} // namespace Crypto
} // namespace chip
