/*
 *
 *    Copyright (c) 2020-2022 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/Optional.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/Span.h>

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

namespace chip {
namespace Crypto {

constexpr size_t kMax_x509_Certificate_Length = 600;

constexpr size_t kP256_FE_Length                  = 32;
constexpr size_t kP256_ECDSA_Signature_Length_Raw = (2 * kP256_FE_Length);
constexpr size_t kP256_Point_Length               = (2 * kP256_FE_Length + 1);
constexpr size_t kSHA256_Hash_Length              = 32;
constexpr size_t kSHA1_Hash_Length                = 20;
constexpr size_t kSubjectKeyIdentifierLength      = kSHA1_Hash_Length;
constexpr size_t kAuthorityKeyIdentifierLength    = kSHA1_Hash_Length;

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

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

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

// Max CSR length should be relatively small since it's a single P256 key and
// no metadata is expected to be honored by the CA.
constexpr size_t kMAX_CSR_Length = 255;

constexpr size_t CHIP_CRYPTO_HASH_LEN_BYTES = kSHA256_Hash_Length;

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

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

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

/* 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.
 */
constexpr size_t kMAX_Spake2p_Context_Size     = 1024;
constexpr size_t kMAX_P256Keypair_Context_Size = 512;

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

constexpr size_t kMAX_Hash_SHA256_Context_Size = CHIP_CONFIG_SHA256_CONTEXT_SIZE;

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

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

/*
 * 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.
 */
constexpr size_t kMax_ECDSA_X9Dot62_Asn1_Overhead = 9;
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");

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[65] = {
    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[65] = {
    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
{
public:
    virtual ~ECPKey() {}
    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;
};

template <size_t Cap>
class CapacityBoundBuffer
{
public:
    ~CapacityBoundBuffer()
    {
        // Sanitize after use
        ClearSecretData(&bytes[0], Cap);
    }

    CapacityBoundBuffer & operator=(const CapacityBoundBuffer & other)
    {
        // Guard self assignment
        if (this == &other)
            return *this;

        ClearSecretData(&bytes[0], Cap);
        SetLength(other.Length());
        ::memcpy(Bytes(), other.Bytes(), other.Length());
        return *this;
    }

    /** @brief Set current length of the buffer that's being used
     * @return Returns error if new length is > capacity
     **/
    CHIP_ERROR SetLength(size_t len)
    {
        VerifyOrReturnError(len <= sizeof(bytes), CHIP_ERROR_INVALID_ARGUMENT);
        length = len;
        return CHIP_NO_ERROR;
    }

    /** @brief Returns current length of the buffer that's being used
     * @return Returns 0 if SetLength() was never called
     **/
    size_t Length() const { return length; }

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

    /** @brief Returns pointer to start of underlying buffer
     **/
    uint8_t * Bytes() { return &bytes[0]; }

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

    /** @brief Returns buffer pointer
     **/
    operator uint8_t *() { return bytes; }
    operator const uint8_t *() const { return bytes; }

private:
    uint8_t bytes[Cap];
    size_t length = 0;
};

typedef CapacityBoundBuffer<kMax_ECDSA_Signature_Length> P256ECDSASignature;

typedef CapacityBoundBuffer<kMax_ECDH_Secret_Length> P256ECDHDerivedSecret;

class P256PublicKey : public ECPKey<P256ECDSASignature>
{
public:
    P256PublicKey() {}

    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
{
public:
    virtual ~ECPKeypair() {}

    /** @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 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];
};

typedef CapacityBoundBuffer<kP256_PublicKey_Length + kP256_PrivateKey_Length> P256SerializedKeypair;

class P256KeypairBase : public ECPKeypair<P256PublicKey, P256ECDHDerivedSecret, P256ECDSASignature>
{
public:
    /**
     * @brief Initialize the keypair.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR Initialize(ECPKeyTarget key_target) = 0;

    /**
     * @brief Serialize the keypair.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR Serialize(P256SerializedKeypair & output) const = 0;

    /**
     * @brief Deserialize the keypair.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    virtual CHIP_ERROR Deserialize(P256SerializedKeypair & input) = 0;
};

class P256Keypair : public P256KeypairBase
{
public:
    P256Keypair() {}
    ~P256Keypair() override;

    /**
     * @brief Initialize the keypair.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    CHIP_ERROR Initialize(ECPKeyTarget key_target) override;

    /**
     * @brief Serialize the keypair.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    CHIP_ERROR Serialize(P256SerializedKeypair & output) const override;

    /**
     * @brief Deserialize the keypair.
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    CHIP_ERROR Deserialize(P256SerializedKeypair & input) override;

    /**
     * @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
     **/
    CHIP_ERROR NewCertificateSigningRequest(uint8_t * csr, size_t & csr_length) const override;

    /**
     * @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
     **/
    CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, P256ECDSASignature & out_signature) const override;

    /**
     * @brief A function to derive 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 Return public key for the keypair.
     **/
    const P256PublicKey & Pubkey() const override { return mPublicKey; }

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

private:
    P256PublicKey mPublicKey;
    mutable P256KeypairContext mKeypair;
    bool mInitialized = false;
};

/**
 *  @brief  A data structure for holding an AES CCM128 symmetric key, without the ownership of it.
 */
using AesCcm128KeySpan = FixedByteSpan<Crypto::kAES_CCM128_Key_Length>;

class AesCcm128Key
{
public:
    AesCcm128Key() {}

    ~AesCcm128Key()
    {
        // Sanitize after use
        ClearSecretData(&bytes[0], Length());
    }

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

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

    size_t Length() const { return sizeof(bytes); }
    operator uint8_t *() { return bytes; }
    operator const uint8_t *() const { return bytes; }
    const uint8_t * ConstBytes() const { return &bytes[0]; }
    AesCcm128KeySpan Span() const { return AesCcm128KeySpan(bytes); }
    uint8_t * Bytes() { return &bytes[0]; }

private:
    uint8_t bytes[kAES_CCM128_Key_Length];
};

/**
 * @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 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 key_length Length of encryption key (in bytes)
 * @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 uint8_t * key, size_t key_length, 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 key_length Length of Decryption key (in bytes)
 * @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 uint8_t * key, size_t key_length, 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 key_length Length of Decryption key (in bytes)
 * @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 uint8_t * key, size_t key_length, 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 be at least kMAX_CSR_Length.  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(size_t) 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:
    HashSHA256OpaqueContext mContext;
};

class HKDF_sha
{
public:
    HKDF_sha() {}
    virtual ~HKDF_sha() {}

    /**
     * @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() {}
    virtual ~HMAC_sha() {}

    /**
     * @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 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
 * @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() {}
    virtual ~PBKDF2_sha256() {}

    /** @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);
};

/**
 * 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() {}

    /**
     * @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 w0in              The input w0 (an output from the PBKDF).
     * @param w0in_len          The input w0 length.
     * @param w1in              The input w1 (an output from the PBKDF).
     * @param w1in_len          The input w1 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 * w0in, size_t w0in_len, const uint8_t * w1in,
                                   size_t w1in_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 secret.
     *
     * @param out     The output secret.
     * @param out_len The output secret length.
     *
     * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     **/
    CHIP_ERROR GetKeys(uint8_t * out, size_t * out_len);

    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 dependant 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 dependant 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 dependant field element.
     *  @param fe1  A pointer to an initialized implementation dependant field element.
     *  @param fe2  A pointer to an initialized implementation dependant 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 dependant 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 dependant 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 (modulo p)
     *   @param w0_len      Output field element length
     *   @param w1sin       Input field element
     *   @param w1sin_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
     *
     *   @param Lout        Output point in 0x04 || X || Y format.
     *   @param L_len       Output point length
     *   @param w1in        Input field element
     *   @param w1in_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 * w1in, size_t w1in_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 * w1in, size_t w1in_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 (w0, w1) 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 (w0, w1) 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);

typedef CapacityBoundBuffer<kMax_x509_Certificate_Length> X509DerCertificate;

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 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);

/**
 * 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
