/*
 *
 *    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
 *      Platform agnostic implementation of CHIP crypto algorithms
 */

#include "CHIPCryptoPAL.h"
#include <lib/asn1/ASN1.h>
#include <lib/asn1/ASN1Macros.h>
#include <lib/core/CHIPEncoding.h>
#include <lib/support/BufferReader.h>
#include <lib/support/BufferWriter.h>
#include <lib/support/BytesToHex.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/Span.h>
#include <string.h>

using chip::ByteSpan;
using chip::MutableByteSpan;
using chip::Encoding::BufferWriter;
using chip::Encoding::LittleEndian::Reader;

using namespace chip::ASN1;

namespace {

constexpr uint8_t kIntegerTag         = 0x02u;
constexpr uint8_t kSeqTag             = 0x30u;
constexpr size_t kMinSequenceOverhead = 1 /* tag */ + 1 /* length */ + 1 /* actual data or second length byte*/;

/**
 * @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(Reader & reader, uint8_t & length)
{
    length = 0;

    uint8_t cur_byte = 0;
    ReturnErrorOnFailure(reader.Read8(&cur_byte).StatusCode());

    if ((cur_byte & (1u << 7)) == 0)
    {
        // 7 bit length, the rest of the byte is the length.
        length = cur_byte & 0x7Fu;
        return CHIP_NO_ERROR;
    }

    // Did not early return: > 7 bit length, the number of bytes of the length is provided next.
    uint8_t length_bytes = cur_byte & 0x7Fu;

    if ((length_bytes > 1) || !reader.HasAtLeast(length_bytes))
    {
        // We only support lengths of 0..255 over 2 bytes
        return CHIP_ERROR_INVALID_ARGUMENT;
    }

    // Next byte has length 0..255.
    return reader.Read8(&length).StatusCode();
}

/**
 * @brief Utility to convert DER-encoded INTEGER into a raw integer buffer in big-endian order
 *        with leading zeroes if the output buffer is larger than needed.
 * @param[in] reader Reader instance from which the input will be read
 * @param[out] raw_integer_out Buffer to receive the DER-encoded integer
 * @return CHIP_ERROR_INVALID_ARGUMENT or CHIP_ERROR_BUFFER_TOO_SMALL on error, CHIP_NO_ERROR otherwise
 */
CHIP_ERROR ReadDerUnsignedIntegerIntoRaw(Reader & reader, MutableByteSpan raw_integer_out)
{
    uint8_t cur_byte = 0;

    ReturnErrorOnFailure(reader.Read8(&cur_byte).StatusCode());

    // We expect first tag to be INTEGER
    VerifyOrReturnError(cur_byte == kIntegerTag, CHIP_ERROR_INVALID_ARGUMENT);

    // Read the length
    uint8_t integer_len = 0;
    ReturnErrorOnFailure(ReadDerLength(reader, integer_len));

    // Clear the destination buffer, so we can blit the unsigned value into place
    memset(raw_integer_out.data(), 0, raw_integer_out.size());

    // Check for pseudo-zero to mark unsigned value
    // This means we have too large an integer (should be at most 1 byte too large), it's invalid
    ReturnErrorCodeIf(integer_len > (raw_integer_out.size() + 1), CHIP_ERROR_INVALID_ARGUMENT);

    if (integer_len == (raw_integer_out.size() + 1u))
    {
        // Means we had a 0x00 byte stuffed due to MSB being high in original integer
        ReturnErrorOnFailure(reader.Read8(&cur_byte).StatusCode());

        // The extra byte must be a leading zero
        VerifyOrReturnError(cur_byte == 0, CHIP_ERROR_INVALID_ARGUMENT);
        --integer_len;
    }

    // We now have the rest of the tag that is a "minimal length" unsigned integer.
    // Blit it at the correct offset, since the order we use is MSB first for
    // both ASN.1 and EC curve raw points.
    size_t offset = raw_integer_out.size() - integer_len;
    return reader.ReadBytes(raw_integer_out.data() + offset, integer_len).StatusCode();
}

CHIP_ERROR ConvertIntegerRawToDerInternal(const ByteSpan & raw_integer, MutableByteSpan & out_der_integer,
                                          bool include_tag_and_length)
{
    if (!IsSpanUsable(raw_integer) || !IsSpanUsable(out_der_integer))
    {
        return CHIP_ERROR_INVALID_ARGUMENT;
    }

    Reader reader(raw_integer);
    BufferWriter writer(out_der_integer);

    bool needs_leading_zero_byte = false;

    uint8_t cur_byte = 0;
    while ((reader.Remaining() > 0) && (reader.Read8(&cur_byte).StatusCode() == CHIP_NO_ERROR) && (cur_byte == 0))
    {
        // Omit all leading zeros
    }

    if ((cur_byte & 0x80u) != 0)
    {
        // If overall MSB (from leftmost byte) is set, we will need to push out a zero to avoid it being
        // considered a negative number.
        needs_leading_zero_byte = true;
    }

    // The + 1 is to account for the last consumed byte of the loop to skip leading zeros
    size_t length = reader.Remaining() + 1 + (needs_leading_zero_byte ? 1 : 0);

    if (length > 127)
    {
        // We do not support length over more than 1 bytes.
        return CHIP_ERROR_INVALID_ARGUMENT;
    }

    if (include_tag_and_length)
    {
        // Put INTEGER tag
        writer.Put(kIntegerTag);

        // Put length over 1 byte (i.e. MSB clear)
        writer.Put(static_cast<uint8_t>(length));
    }

    // If leading zero or no more bytes remaining, must ensure we start with at least a zero byte
    if (needs_leading_zero_byte)
    {
        writer.Put(static_cast<uint8_t>(0u));
    }

    // Put first consumed byte from last read iteration of leading zero suppression
    writer.Put(cur_byte);

    // Fill the rest from the input in order
    while (reader.Read8(&cur_byte).StatusCode() == CHIP_NO_ERROR)
    {
        // Emit all other bytes as-is
        writer.Put(cur_byte);
    }

    size_t actually_written = 0;
    if (!writer.Fit(actually_written))
    {
        return CHIP_ERROR_BUFFER_TOO_SMALL;
    }

    out_der_integer = out_der_integer.SubSpan(0, actually_written);

    return CHIP_NO_ERROR;
}

} // namespace

namespace chip {
namespace Crypto {

using HKDF_sha_crypto = HKDF_sha;

CHIP_ERROR Spake2p::InternalHash(const uint8_t * in, size_t in_len)
{
    const uint64_t u64_len = in_len;

    uint8_t lb[8];
    lb[0] = static_cast<uint8_t>((u64_len >> 0) & 0xff);
    lb[1] = static_cast<uint8_t>((u64_len >> 8) & 0xff);
    lb[2] = static_cast<uint8_t>((u64_len >> 16) & 0xff);
    lb[3] = static_cast<uint8_t>((u64_len >> 24) & 0xff);
    lb[4] = static_cast<uint8_t>((u64_len >> 32) & 0xff);
    lb[5] = static_cast<uint8_t>((u64_len >> 40) & 0xff);
    lb[6] = static_cast<uint8_t>((u64_len >> 48) & 0xff);
    lb[7] = static_cast<uint8_t>((u64_len >> 56) & 0xff);

    ReturnErrorOnFailure(Hash(lb, sizeof(lb)));
    if (in != nullptr)
    {
        ReturnErrorOnFailure(Hash(in, in_len));
    }

    return CHIP_NO_ERROR;
}

Spake2p::Spake2p(size_t _fe_size, size_t _point_size, size_t _hash_size)
{
    fe_size    = _fe_size;
    point_size = _point_size;
    hash_size  = _hash_size;

    Kca = &Kcab[0];
    Kcb = &Kcab[hash_size / 2];
    Ka  = &Kae[0];
    Ke  = &Kae[hash_size / 2];

    M  = nullptr;
    N  = nullptr;
    G  = nullptr;
    X  = nullptr;
    Y  = nullptr;
    L  = nullptr;
    Z  = nullptr;
    V  = nullptr;
    w0 = nullptr;
    w1 = nullptr;
    xy = nullptr;

    order  = nullptr;
    tempbn = nullptr;
}

CHIP_ERROR Spake2p::Init(const uint8_t * context, size_t context_len)
{
    if (state != CHIP_SPAKE2P_STATE::PREINIT)
    {
        Clear();
    }

    ReturnErrorOnFailure(InitImpl());
    ReturnErrorOnFailure(PointLoad(spake2p_M_p256, sizeof(spake2p_M_p256), M));
    ReturnErrorOnFailure(PointLoad(spake2p_N_p256, sizeof(spake2p_N_p256), N));
    ReturnErrorOnFailure(InternalHash(context, context_len));

    state = CHIP_SPAKE2P_STATE::INIT;
    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2p::WriteMN()
{
    ReturnErrorOnFailure(InternalHash(spake2p_M_p256, sizeof(spake2p_M_p256)));
    ReturnErrorOnFailure(InternalHash(spake2p_N_p256, sizeof(spake2p_N_p256)));

    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2p::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)
{
    VerifyOrReturnError(state == CHIP_SPAKE2P_STATE::INIT, CHIP_ERROR_INTERNAL);

    ReturnErrorOnFailure(InternalHash(peer_identity, peer_identity_len));
    ReturnErrorOnFailure(InternalHash(my_identity, my_identity_len));
    ReturnErrorOnFailure(WriteMN());
    ReturnErrorOnFailure(FELoad(w0in, w0in_len, w0));
    ReturnErrorOnFailure(PointLoad(Lin, Lin_len, L));

    state = CHIP_SPAKE2P_STATE::STARTED;
    role  = CHIP_SPAKE2P_ROLE::VERIFIER;
    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2p::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)
{
    VerifyOrReturnError(state == CHIP_SPAKE2P_STATE::INIT, CHIP_ERROR_INTERNAL);

    ReturnErrorOnFailure(InternalHash(my_identity, my_identity_len));
    ReturnErrorOnFailure(InternalHash(peer_identity, peer_identity_len));
    ReturnErrorOnFailure(WriteMN());
    ReturnErrorOnFailure(FELoad(w0in, w0in_len, w0));
    ReturnErrorOnFailure(FELoad(w1in, w1in_len, w1));

    state = CHIP_SPAKE2P_STATE::STARTED;
    role  = CHIP_SPAKE2P_ROLE::PROVER;
    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2p::ComputeRoundOne(const uint8_t * pab, size_t pab_len, uint8_t * out, size_t * out_len)
{
    CHIP_ERROR error = CHIP_ERROR_INTERNAL;
    void * MN        = nullptr; // Choose M if a prover, N if a verifier
    void * XY        = nullptr; // Choose X if a prover, Y if a verifier

    VerifyOrExit(state == CHIP_SPAKE2P_STATE::STARTED, error = CHIP_ERROR_INTERNAL);
    VerifyOrExit(*out_len >= point_size, error = CHIP_ERROR_INTERNAL);

    ReturnErrorOnFailure(FEGenerate(xy));

    if (role == CHIP_SPAKE2P_ROLE::PROVER)
    {
        MN = M;
        XY = X;
    }
    else if (role == CHIP_SPAKE2P_ROLE::VERIFIER)
    {
        MN = N;
        XY = Y;
    }
    VerifyOrExit(MN != nullptr, error = CHIP_ERROR_INTERNAL);
    VerifyOrExit(XY != nullptr, error = CHIP_ERROR_INTERNAL);

    SuccessOrExit(error = PointAddMul(XY, G, xy, MN, w0));
    SuccessOrExit(error = PointWrite(XY, out, *out_len));

    state = CHIP_SPAKE2P_STATE::R1;
    error = CHIP_NO_ERROR;
exit:
    *out_len = point_size;
    return error;
}

CHIP_ERROR Spake2p::ComputeRoundTwo(const uint8_t * in, size_t in_len, uint8_t * out, size_t * out_len)
{
    CHIP_ERROR error = CHIP_ERROR_INTERNAL;
    MutableByteSpan out_span{ out, *out_len };
    uint8_t point_buffer[kMAX_Point_Length];
    void * MN        = nullptr; // Choose N if a prover, M if a verifier
    void * XY        = nullptr; // Choose Y if a prover, X if a verifier
    uint8_t * Kcaorb = nullptr; // Choose Kca if a prover, Kcb if a verifier

    VerifyOrExit(*out_len >= hash_size, error = CHIP_ERROR_INTERNAL);
    VerifyOrExit(state == CHIP_SPAKE2P_STATE::R1, error = CHIP_ERROR_INTERNAL);
    VerifyOrExit(in_len == point_size, error = CHIP_ERROR_INTERNAL);

    if (role == CHIP_SPAKE2P_ROLE::PROVER)
    {
        SuccessOrExit(error = PointWrite(X, point_buffer, point_size));
        SuccessOrExit(error = InternalHash(point_buffer, point_size));
        SuccessOrExit(error = InternalHash(in, in_len));

        MN     = N;
        XY     = Y;
        Kcaorb = Kca;
    }
    else if (role == CHIP_SPAKE2P_ROLE::VERIFIER)
    {
        SuccessOrExit(error = InternalHash(in, in_len));
        SuccessOrExit(error = PointWrite(Y, point_buffer, point_size));
        SuccessOrExit(error = InternalHash(point_buffer, point_size));

        MN     = M;
        XY     = X;
        Kcaorb = Kcb;
    }
    VerifyOrExit(MN != nullptr, error = CHIP_ERROR_INTERNAL);
    VerifyOrExit(XY != nullptr, error = CHIP_ERROR_INTERNAL);

    SuccessOrExit(error = PointLoad(in, in_len, XY));
    SuccessOrExit(error = PointIsValid(XY));
    SuccessOrExit(error = FEMul(tempbn, xy, w0));
    SuccessOrExit(error = PointInvert(MN));
    SuccessOrExit(error = PointAddMul(Z, XY, xy, MN, tempbn));
    SuccessOrExit(error = PointCofactorMul(Z));

    if (role == CHIP_SPAKE2P_ROLE::PROVER)
    {
        SuccessOrExit(error = FEMul(tempbn, w1, w0));
        SuccessOrExit(error = PointAddMul(V, XY, w1, MN, tempbn));
    }
    else if (role == CHIP_SPAKE2P_ROLE::VERIFIER)
    {
        SuccessOrExit(error = PointMul(V, L, xy));
    }

    SuccessOrExit(error = PointCofactorMul(V));
    SuccessOrExit(error = PointWrite(Z, point_buffer, point_size));
    SuccessOrExit(error = InternalHash(point_buffer, point_size));

    SuccessOrExit(error = PointWrite(V, point_buffer, point_size));
    SuccessOrExit(error = InternalHash(point_buffer, point_size));

    SuccessOrExit(error = FEWrite(w0, point_buffer, fe_size));
    SuccessOrExit(error = InternalHash(point_buffer, fe_size));

    SuccessOrExit(error = GenerateKeys());

    SuccessOrExit(error = Mac(Kcaorb, hash_size / 2, in, in_len, out_span));
    VerifyOrExit(out_span.size() == hash_size, error = CHIP_ERROR_INTERNAL);

    state = CHIP_SPAKE2P_STATE::R2;
    error = CHIP_NO_ERROR;
exit:
    *out_len = hash_size;
    return error;
}

CHIP_ERROR Spake2p::GenerateKeys()
{
    static const uint8_t info_keyconfirm[16] = { 'C', 'o', 'n', 'f', 'i', 'r', 'm', 'a', 't', 'i', 'o', 'n', 'K', 'e', 'y', 's' };

    MutableByteSpan Kae_span{ &Kae[0], sizeof(Kae) };

    ReturnErrorOnFailure(HashFinalize(Kae_span));
    ReturnErrorOnFailure(KDF(Ka, hash_size / 2, nullptr, 0, info_keyconfirm, sizeof(info_keyconfirm), Kcab, hash_size));

    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2p::KeyConfirm(const uint8_t * in, size_t in_len)
{
    uint8_t point_buffer[kP256_Point_Length];
    void * XY        = nullptr; // Choose X if a prover, Y if a verifier
    uint8_t * Kcaorb = nullptr; // Choose Kcb if a prover, Kca if a verifier

    VerifyOrReturnError(state == CHIP_SPAKE2P_STATE::R2, CHIP_ERROR_INTERNAL);

    if (role == CHIP_SPAKE2P_ROLE::PROVER)
    {
        XY     = X;
        Kcaorb = Kcb;
    }
    else if (role == CHIP_SPAKE2P_ROLE::VERIFIER)
    {
        XY     = Y;
        Kcaorb = Kca;
    }
    VerifyOrReturnError(XY != nullptr, CHIP_ERROR_INTERNAL);
    VerifyOrReturnError(Kcaorb != nullptr, CHIP_ERROR_INTERNAL);

    ReturnErrorOnFailure(PointWrite(XY, point_buffer, point_size));

    CHIP_ERROR err = MacVerify(Kcaorb, hash_size / 2, in, in_len, point_buffer, point_size);
    if (err == CHIP_ERROR_INTERNAL)
    {
        ChipLogError(SecureChannel, "Failed to verify peer's MAC. This can happen when setup code is incorrect.");
    }
    ReturnErrorOnFailure(err);

    state = CHIP_SPAKE2P_STATE::KC;
    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2p::GetKeys(uint8_t * out, size_t * out_len)
{
    CHIP_ERROR error = CHIP_ERROR_INTERNAL;

    VerifyOrExit(state == CHIP_SPAKE2P_STATE::KC, error = CHIP_ERROR_INTERNAL);
    VerifyOrExit(*out_len >= hash_size / 2, error = CHIP_ERROR_INVALID_ARGUMENT);

    memcpy(out, Ke, hash_size / 2);
    error = CHIP_NO_ERROR;
exit:
    *out_len = hash_size / 2;
    return error;
}

CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::InitImpl()
{
    ReturnErrorOnFailure(sha256_hash_ctx.Begin());
    ReturnErrorOnFailure(InitInternal());
    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::Hash(const uint8_t * in, size_t in_len)
{
    ReturnErrorOnFailure(sha256_hash_ctx.AddData(ByteSpan{ in, in_len }));
    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::HashFinalize(MutableByteSpan & out_span)
{
    ReturnErrorOnFailure(sha256_hash_ctx.Finish(out_span));
    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::KDF(const uint8_t * ikm, const size_t ikm_len, const uint8_t * salt,
                                              const size_t salt_len, const uint8_t * info, const size_t info_len, uint8_t * out,
                                              size_t out_len)
{
    HKDF_sha_crypto mHKDF;

    ReturnErrorOnFailure(mHKDF.HKDF_SHA256(ikm, ikm_len, salt, salt_len, info, info_len, out, out_len));

    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::ComputeW0(uint8_t * w0out, size_t * w0_len, const uint8_t * w0sin, size_t w0sin_len)
{
    ReturnErrorOnFailure(FELoad(w0sin, w0sin_len, w0));
    ReturnErrorOnFailure(FEWrite(w0, w0out, *w0_len));

    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2pVerifier::Serialize(MutableByteSpan & outSerialized) const
{
    VerifyOrReturnError(outSerialized.size() >= kSpake2p_VerifierSerialized_Length, CHIP_ERROR_INVALID_ARGUMENT);

    memcpy(&outSerialized.data()[0], mW0, sizeof(mW0));
    memcpy(&outSerialized.data()[sizeof(mW0)], mL, sizeof(mL));

    outSerialized.reduce_size(kSpake2p_VerifierSerialized_Length);

    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2pVerifier::Deserialize(const ByteSpan & inSerialized)
{
    VerifyOrReturnError(inSerialized.size() >= kSpake2p_VerifierSerialized_Length, CHIP_ERROR_INVALID_ARGUMENT);

    memcpy(mW0, &inSerialized.data()[0], sizeof(mW0));
    memcpy(mL, &inSerialized.data()[sizeof(mW0)], sizeof(mL));

    return CHIP_NO_ERROR;
}

CHIP_ERROR Spake2pVerifier::Generate(uint32_t pbkdf2IterCount, const ByteSpan & salt, uint32_t setupPin)
{
    uint8_t serializedWS[kSpake2p_WS_Length * 2] = { 0 };
    ReturnErrorOnFailure(ComputeWS(pbkdf2IterCount, salt, setupPin, serializedWS, sizeof(serializedWS)));

    CHIP_ERROR err = CHIP_NO_ERROR;
    size_t len;

    // Create local Spake2+ object for w0 and L computations.
    Spake2p_P256_SHA256_HKDF_HMAC spake2p;
    uint8_t context[kSHA256_Hash_Length] = { 0 };
    SuccessOrExit(err = spake2p.Init(context, sizeof(context)));

    // Compute w0
    len = sizeof(mW0);
    SuccessOrExit(err = spake2p.ComputeW0(mW0, &len, &serializedWS[0], kSpake2p_WS_Length));
    VerifyOrExit(len == sizeof(mW0), err = CHIP_ERROR_INTERNAL);

    // Compute L
    len = sizeof(mL);
    SuccessOrExit(err = spake2p.ComputeL(mL, &len, &serializedWS[kSpake2p_WS_Length], kSpake2p_WS_Length));
    VerifyOrExit(len == sizeof(mL), err = CHIP_ERROR_INTERNAL);

exit:
    spake2p.Clear();
    return err;
}

CHIP_ERROR Spake2pVerifier::ComputeWS(uint32_t pbkdf2IterCount, const ByteSpan & salt, uint32_t setupPin, uint8_t * ws,
                                      uint32_t ws_len)
{
    PBKDF2_sha256 pbkdf2;
    uint8_t littleEndianSetupPINCode[sizeof(uint32_t)];
    Encoding::LittleEndian::Put32(littleEndianSetupPINCode, setupPin);

    ReturnErrorCodeIf(salt.size() < kSpake2p_Min_PBKDF_Salt_Length || salt.size() > kSpake2p_Max_PBKDF_Salt_Length,
                      CHIP_ERROR_INVALID_ARGUMENT);
    ReturnErrorCodeIf(pbkdf2IterCount < kSpake2p_Min_PBKDF_Iterations || pbkdf2IterCount > kSpake2p_Max_PBKDF_Iterations,
                      CHIP_ERROR_INVALID_ARGUMENT);

    return pbkdf2.pbkdf2_sha256(littleEndianSetupPINCode, sizeof(littleEndianSetupPINCode), salt.data(), salt.size(),
                                pbkdf2IterCount, ws_len, ws);
}

CHIP_ERROR ConvertIntegerRawToDerWithoutTag(const ByteSpan & raw_integer, MutableByteSpan & out_der_integer)
{
    return ConvertIntegerRawToDerInternal(raw_integer, out_der_integer, /* include_tag_and_length = */ false);
}

CHIP_ERROR ConvertIntegerRawToDer(const ByteSpan & raw_integer, MutableByteSpan & out_der_integer)
{
    return ConvertIntegerRawToDerInternal(raw_integer, out_der_integer, /* include_tag_and_length = */ true);
}

CHIP_ERROR EcdsaRawSignatureToAsn1(size_t fe_length_bytes, const ByteSpan & raw_sig, MutableByteSpan & out_asn1_sig)
{
    VerifyOrReturnError(fe_length_bytes > 0, CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(raw_sig.size() == (2u * fe_length_bytes), CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(out_asn1_sig.size() >= (raw_sig.size() + kMax_ECDSA_X9Dot62_Asn1_Overhead), CHIP_ERROR_BUFFER_TOO_SMALL);

    // Write both R an S integers past the overhead, we will shift them back later if we only needed 2 size bytes.
    uint8_t * cursor = out_asn1_sig.data() + kMinSequenceOverhead;
    size_t remaining = out_asn1_sig.size() - kMinSequenceOverhead;

    size_t integers_length = 0;

    // Write R (first `fe_length_bytes` block of raw signature)
    {
        MutableByteSpan out_der_integer(cursor, remaining);
        ReturnErrorOnFailure(ConvertIntegerRawToDer(raw_sig.SubSpan(0, fe_length_bytes), out_der_integer));
        VerifyOrReturnError(out_der_integer.size() <= remaining, CHIP_ERROR_INTERNAL);

        integers_length += out_der_integer.size();
        remaining -= out_der_integer.size();
        cursor += out_der_integer.size();
    }

    // Write S (second `fe_length_bytes` block of raw signature)
    {
        MutableByteSpan out_der_integer(cursor, remaining);
        ReturnErrorOnFailure(ConvertIntegerRawToDer(raw_sig.SubSpan(fe_length_bytes, fe_length_bytes), out_der_integer));
        VerifyOrReturnError(out_der_integer.size() <= remaining, CHIP_ERROR_INTERNAL);
        integers_length += out_der_integer.size();
    }

    // We only support outputs that would use 1 or 2 bytes of DER length after the SEQUENCE tag
    VerifyOrReturnError(integers_length <= UINT8_MAX, CHIP_ERROR_INVALID_ARGUMENT);

    // We now know the length of both variable sized integers in the sequence, so we
    // can write the tag and length.
    BufferWriter writer(out_asn1_sig);

    // Put SEQUENCE tag
    writer.Put(kSeqTag);

    // Put the length over 1 or two bytes depending on case
    constexpr uint8_t kExtendedLengthMarker = 0x80u;
    if (integers_length > 127u)
    {
        writer.Put(static_cast<uint8_t>(kExtendedLengthMarker | 1)); // Length is extended length, over 1 subsequent byte
        writer.Put(static_cast<uint8_t>(integers_length));
    }
    else
    {
        // Length is directly in the first byte with MSB clear if <= 127.
        writer.Put(static_cast<uint8_t>(integers_length));
    }

    // Put the contents of the integers previously serialized in the buffer.
    // The writer.Put is memmove-safe, so the shifting will happen from the read
    // of the same buffer where the write is taking place.
    writer.Put(out_asn1_sig.data() + kMinSequenceOverhead, integers_length);

    size_t actually_written = 0;
    VerifyOrReturnError(writer.Fit(actually_written), CHIP_ERROR_BUFFER_TOO_SMALL);

    out_asn1_sig = out_asn1_sig.SubSpan(0, actually_written);
    return CHIP_NO_ERROR;
}

CHIP_ERROR EcdsaAsn1SignatureToRaw(size_t fe_length_bytes, const ByteSpan & asn1_sig, MutableByteSpan & out_raw_sig)
{
    VerifyOrReturnError(fe_length_bytes > 0, CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(asn1_sig.size() > kMinSequenceOverhead, CHIP_ERROR_BUFFER_TOO_SMALL);

    // Output raw signature is <r,s> both of which are of fe_length_bytes (see SEC1).
    VerifyOrReturnError(out_raw_sig.size() >= (2u * fe_length_bytes), CHIP_ERROR_BUFFER_TOO_SMALL);

    Reader reader(asn1_sig);

    // Make sure we have a starting Sequence
    uint8_t tag = 0;
    ReturnErrorOnFailure(reader.Read8(&tag).StatusCode());
    VerifyOrReturnError(tag == kSeqTag, CHIP_ERROR_INVALID_ARGUMENT);

    // Read length of sequence
    uint8_t tag_len = 0;
    ReturnErrorOnFailure(ReadDerLength(reader, tag_len));

    // Length of sequence must match what is left of signature
    VerifyOrReturnError(tag_len == reader.Remaining(), CHIP_ERROR_INVALID_ARGUMENT);

    // Can now clear raw signature integers r,s one by one
    uint8_t * raw_cursor = out_raw_sig.data();

    // Read R
    ReturnErrorOnFailure(ReadDerUnsignedIntegerIntoRaw(reader, MutableByteSpan{ raw_cursor, fe_length_bytes }));

    raw_cursor += fe_length_bytes;

    // Read S
    ReturnErrorOnFailure(ReadDerUnsignedIntegerIntoRaw(reader, MutableByteSpan{ raw_cursor, fe_length_bytes }));

    out_raw_sig = out_raw_sig.SubSpan(0, (2u * fe_length_bytes));

    return CHIP_NO_ERROR;
}

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)
{
    // Discard tag portion of CCM to apply only CTR mode encryption/decryption.
    constexpr size_t kTagLen = Crypto::kAES_CCM128_Tag_Length;
    uint8_t tag[kTagLen];

    return AES_CCM_encrypt(input, input_length, nullptr, 0, key, nonce, nonce_length, output, tag, kTagLen);
}

CHIP_ERROR GenerateCompressedFabricId(const Crypto::P256PublicKey & root_public_key, uint64_t fabric_id,
                                      MutableByteSpan & out_compressed_fabric_id)
{
    VerifyOrReturnError(root_public_key.IsUncompressed(), CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(out_compressed_fabric_id.size() >= kCompressedFabricIdentifierSize, CHIP_ERROR_BUFFER_TOO_SMALL);

    // Ensure proper endianness for Fabric ID (i.e. big-endian as it appears in certificates)
    uint8_t fabric_id_as_big_endian_salt[kCompressedFabricIdentifierSize];
    chip::Encoding::BigEndian::Put64(&fabric_id_as_big_endian_salt[0], fabric_id);

    // Compute Compressed fabric reference per spec pseudocode
    //   CompressedFabricIdentifier =
    //     CHIP_Crypto_KDF(
    //       inputKey := TargetOperationalRootPublicKey,
    //       salt:= TargetOperationalFabricID,
    //       info := CompressedFabricInfo,
    //       len := 64)
    //
    // NOTE: len=64 bits is implied by output buffer size when calling HKDF_sha::HKDF_SHA256.

    constexpr uint8_t kCompressedFabricInfo[16] = /* "CompressedFabric" */
        { 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x46, 0x61, 0x62, 0x72, 0x69, 0x63 };
    HKDF_sha hkdf;

    // Must drop uncompressed point form format specifier (first byte), per spec method
    ByteSpan input_key_span(root_public_key.ConstBytes() + 1, root_public_key.Length() - 1);

    CHIP_ERROR status = hkdf.HKDF_SHA256(
        input_key_span.data(), input_key_span.size(), &fabric_id_as_big_endian_salt[0], sizeof(fabric_id_as_big_endian_salt),
        &kCompressedFabricInfo[0], sizeof(kCompressedFabricInfo), out_compressed_fabric_id.data(), kCompressedFabricIdentifierSize);

    // Resize output to final bounds on success
    if (status == CHIP_NO_ERROR)
    {
        out_compressed_fabric_id = out_compressed_fabric_id.SubSpan(0, kCompressedFabricIdentifierSize);
    }

    return status;
}

CHIP_ERROR GenerateCompressedFabricId(const Crypto::P256PublicKey & rootPublicKey, uint64_t fabricId, uint64_t & compressedFabricId)
{
    uint8_t allocated[sizeof(fabricId)];
    MutableByteSpan span(allocated);
    ReturnErrorOnFailure(GenerateCompressedFabricId(rootPublicKey, fabricId, span));
    // Decode compressed fabric ID accounting for endianness, as GenerateCompressedFabricId()
    // returns a binary buffer and is agnostic of usage of the output as an integer type.
    compressedFabricId = Encoding::BigEndian::Get64(allocated);
    return CHIP_NO_ERROR;
}

/* Operational Group Key Group, Security Info: "GroupKey v1.0" */
static const uint8_t kGroupSecurityInfo[] = { 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x20, 0x76, 0x31, 0x2e, 0x30 };

/* Group Key Derivation Function, Info: "GroupKeyHash" ” */
static const uint8_t kGroupKeyHashInfo[]  = { 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x48, 0x61, 0x73, 0x68 };
static const uint8_t kGroupKeyHashSalt[0] = {};

/*
    OperationalGroupKey =
        Crypto_KDF
        (
            InputKey = Epoch Key,
            Salt = CompressedFabricIdentifier,
            Info = "GroupKey v1.0",
            Length = CRYPTO_SYMMETRIC_KEY_LENGTH_BITS
        )
*/
CHIP_ERROR DeriveGroupOperationalKey(const ByteSpan & epoch_key, const ByteSpan & compressed_fabric_id, MutableByteSpan & out_key)
{
    VerifyOrReturnError(Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES == epoch_key.size(), CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES <= out_key.size(), CHIP_ERROR_INVALID_ARGUMENT);

    Crypto::HKDF_sha crypto;
    return crypto.HKDF_SHA256(epoch_key.data(), epoch_key.size(), compressed_fabric_id.data(), compressed_fabric_id.size(),
                              kGroupSecurityInfo, sizeof(kGroupSecurityInfo), out_key.data(),
                              Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES);
}

/*
    GKH = Crypto_KDF (
        InputKey = OperationalGroupKey,
        Salt = [],
        Info = "GroupKeyHash",
        Length = 16)
*/
CHIP_ERROR DeriveGroupSessionId(const ByteSpan & operational_key, uint16_t & session_id)
{
    VerifyOrReturnError(Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES == operational_key.size(), CHIP_ERROR_INVALID_ARGUMENT);
    Crypto::HKDF_sha crypto;
    uint8_t out_key[sizeof(uint16_t)];

    ReturnErrorOnFailure(crypto.HKDF_SHA256(operational_key.data(), operational_key.size(), kGroupKeyHashSalt,
                                            sizeof(kGroupKeyHashSalt), kGroupKeyHashInfo, sizeof(kGroupKeyHashInfo), out_key,
                                            sizeof(out_key)));
    session_id = Encoding::BigEndian::Get16(out_key);
    return CHIP_NO_ERROR;
}

/* Operational Group Key Group, PrivacyKey Info: "PrivacyKey" */
static const uint8_t kGroupPrivacyInfo[] = { 'P', 'r', 'i', 'v', 'a', 'c', 'y', 'K', 'e', 'y' };

/*
    PrivacyKey =
         Crypto_KDF
         (
            InputKey = EncryptionKey,
            Salt = [],
            Info = "PrivacyKey",
            Length = CRYPTO_SYMMETRIC_KEY_LENGTH_BITS
         )
*/
CHIP_ERROR DeriveGroupPrivacyKey(const ByteSpan & encryption_key, MutableByteSpan & out_key)
{
    VerifyOrReturnError(Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES == encryption_key.size(), CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES <= out_key.size(), CHIP_ERROR_INVALID_ARGUMENT);

    const ByteSpan null_span = ByteSpan(nullptr, 0);

    Crypto::HKDF_sha crypto;
    return crypto.HKDF_SHA256(encryption_key.data(), encryption_key.size(), null_span.data(), null_span.size(), kGroupPrivacyInfo,
                              sizeof(kGroupPrivacyInfo), out_key.data(), Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES);
}

CHIP_ERROR DeriveGroupOperationalCredentials(const ByteSpan & epoch_key, const ByteSpan & compressed_fabric_id,
                                             GroupOperationalCredentials & operational_credentials)
{
    MutableByteSpan encryption_key(operational_credentials.encryption_key);
    MutableByteSpan privacy_key(operational_credentials.privacy_key);

    ReturnErrorOnFailure(Crypto::DeriveGroupOperationalKey(epoch_key, compressed_fabric_id, encryption_key));
    ReturnErrorOnFailure(Crypto::DeriveGroupSessionId(encryption_key, operational_credentials.hash));
    ReturnErrorOnFailure(Crypto::DeriveGroupPrivacyKey(encryption_key, privacy_key));

    return CHIP_NO_ERROR;
}

CHIP_ERROR ExtractVIDPIDFromAttributeString(DNAttrType attrType, const ByteSpan & attr,
                                            AttestationCertVidPid & vidpidFromMatterAttr, AttestationCertVidPid & vidpidFromCNAttr)
{
    ReturnErrorCodeIf(attrType == DNAttrType::kUnspecified, CHIP_NO_ERROR);
    ReturnErrorCodeIf(attr.empty(), CHIP_ERROR_INVALID_ARGUMENT);

    if (attrType == DNAttrType::kMatterVID || attrType == DNAttrType::kMatterPID)
    {
        uint16_t matterAttr;
        VerifyOrReturnError(attr.size() == kVIDandPIDHexLength, CHIP_ERROR_WRONG_CERT_DN);
        VerifyOrReturnError(Encoding::UppercaseHexToUint16(reinterpret_cast<const char *>(attr.data()), attr.size(), matterAttr) ==
                                sizeof(matterAttr),
                            CHIP_ERROR_WRONG_CERT_DN);

        if (attrType == DNAttrType::kMatterVID)
        {
            // Not more than one VID attribute can be present.
            ReturnErrorCodeIf(vidpidFromMatterAttr.mVendorId.HasValue(), CHIP_ERROR_WRONG_CERT_DN);
            vidpidFromMatterAttr.mVendorId.SetValue(static_cast<VendorId>(matterAttr));
        }
        else
        {
            // Not more than one PID attribute can be present.
            ReturnErrorCodeIf(vidpidFromMatterAttr.mProductId.HasValue(), CHIP_ERROR_WRONG_CERT_DN);
            vidpidFromMatterAttr.mProductId.SetValue(matterAttr);
        }
    }
    // Otherwise, it is a CommonName attribute.
    else if (!vidpidFromCNAttr.Initialized())
    {
        char cnAttr[kMax_CommonNameAttr_Length + 1];
        if (attr.size() <= chip::Crypto::kMax_CommonNameAttr_Length)
        {
            memcpy(cnAttr, attr.data(), attr.size());
            cnAttr[attr.size()] = 0;

            char * vid = strstr(cnAttr, kVIDPrefixForCNEncoding);
            if (vid != nullptr)
            {
                vid += strlen(kVIDPrefixForCNEncoding);
                if (cnAttr + attr.size() >= vid + kVIDandPIDHexLength)
                {
                    uint16_t matterAttr;
                    if (Encoding::UppercaseHexToUint16(vid, kVIDandPIDHexLength, matterAttr) == sizeof(matterAttr))
                    {
                        vidpidFromCNAttr.mVendorId.SetValue(static_cast<VendorId>(matterAttr));
                    }
                }
            }

            char * pid = strstr(cnAttr, kPIDPrefixForCNEncoding);
            if (pid != nullptr)
            {
                pid += strlen(kPIDPrefixForCNEncoding);
                if (cnAttr + attr.size() >= pid + kVIDandPIDHexLength)
                {
                    uint16_t matterAttr;
                    if (Encoding::UppercaseHexToUint16(pid, kVIDandPIDHexLength, matterAttr) == sizeof(matterAttr))
                    {
                        vidpidFromCNAttr.mProductId.SetValue(matterAttr);
                    }
                }
            }
        }
    }
    return CHIP_NO_ERROR;
}

// Generates the to-be-signed portion of a PKCS#10 CSR (`CertificationRequestInformation`)
// that contains the
static CHIP_ERROR GenerateCertificationRequestInformation(ASN1Writer & writer, const Crypto::P256PublicKey & pubkey)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    /**
     *
     *  CertificationRequestInfo ::=
     *     SEQUENCE {
     *        version       INTEGER { v1(0) } (v1,...),
     *        subject       Name,
     *        subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
     *        attributes    [0] Attributes{{ CRIAttributes }}
     * }
     */
    ASN1_START_SEQUENCE
    {
        ASN1_ENCODE_INTEGER(0); // version INTEGER { v1(0) }

        // subject Name
        ASN1_START_SEQUENCE
        {
            ASN1_START_SET
            {
                ASN1_START_SEQUENCE
                {
                    // Any subject, placeholder is good, since this
                    // is going to usually be ignored
                    ASN1_ENCODE_OBJECT_ID(kOID_AttributeType_OrganizationalUnitName);
                    ASN1_ENCODE_STRING(kASN1UniversalTag_UTF8String, "CSA", static_cast<uint16_t>(strlen("CSA")));
                }
                ASN1_END_SEQUENCE;
            }
            ASN1_END_SET;
        }
        ASN1_END_SEQUENCE;

        // subjectPKInfo
        ASN1_START_SEQUENCE
        {
            ASN1_START_SEQUENCE
            {
                ASN1_ENCODE_OBJECT_ID(kOID_PubKeyAlgo_ECPublicKey);
                ASN1_ENCODE_OBJECT_ID(kOID_EllipticCurve_prime256v1);
            }
            ASN1_END_SEQUENCE;
            ReturnErrorOnFailure(writer.PutBitString(0, pubkey, static_cast<uint8_t>(pubkey.Length())));
        }
        ASN1_END_SEQUENCE;

        // attributes [0]
        ASN1_START_CONSTRUCTED(kASN1TagClass_ContextSpecific, 0)
        {
            // Using a plain empty attributes request
            ASN1_START_SEQUENCE
            {
                ASN1_ENCODE_OBJECT_ID(kOID_Extension_CSRRequest);
                ASN1_START_SET
                {
                    ASN1_START_SEQUENCE {}
                    ASN1_END_SEQUENCE;
                }
                ASN1_END_SET;
            }
            ASN1_END_SEQUENCE;
        }
        ASN1_END_CONSTRUCTED;
    }
    ASN1_END_SEQUENCE;
exit:
    return err;
}

CHIP_ERROR GenerateCertificateSigningRequest(const P256Keypair * keypair, MutableByteSpan & csr_span)
{
    VerifyOrReturnError(keypair != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(csr_span.size() >= kMAX_CSR_Length, CHIP_ERROR_BUFFER_TOO_SMALL);

    // First pass: Generate the CertificatioRequestInformation inner
    // encoding one time, to sign it, before re-generating it within the
    // full ASN1 writer later, since it's easier than trying to
    // figure-out the span we need to sign of the overall object.
    P256ECDSASignature signature;

    {
        // The first pass will just generate a signature, so we can use the
        // output buffer as scratch to avoid needing more stack space. There
        // are no secrets here and the contents is not reused since all we
        // need is the signature which is already separately stored.
        ASN1Writer toBeSignedWriter;
        toBeSignedWriter.Init(csr_span);
        CHIP_ERROR err = GenerateCertificationRequestInformation(toBeSignedWriter, keypair->Pubkey());
        ReturnErrorOnFailure(err);

        size_t encodedLen = (uint16_t) toBeSignedWriter.GetLengthWritten();
        // This should not/will not happen
        if (encodedLen > csr_span.size())
        {
            return CHIP_ERROR_INTERNAL;
        }

        err = keypair->ECDSA_sign_msg(csr_span.data(), encodedLen, signature);
        ReturnErrorOnFailure(err);
    }

    // Second pass: Generate the entire CSR body, restarting a new write
    // of the CertificationRequestInformation (cheap) and adding the
    // signature.
    //
    // See RFC2986 for ASN.1 module, repeated here in snippets
    CHIP_ERROR err = CHIP_NO_ERROR;

    ASN1Writer writer;
    writer.Init(csr_span);

    ASN1_START_SEQUENCE
    {

        /*  CertificationRequestInfo ::=
         *     SEQUENCE {
         *        version       INTEGER { v1(0) } (v1,...),
         *        subject       Name,
         *        subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
         *        attributes    [0] Attributes{{ CRIAttributes }}
         *     }
         */
        GenerateCertificationRequestInformation(writer, keypair->Pubkey());

        // algorithm  AlgorithmIdentifier
        ASN1_START_SEQUENCE
        {
            // See RFC5480 sec 2.1
            ASN1_ENCODE_OBJECT_ID(kOID_SigAlgo_ECDSAWithSHA256);
        }
        ASN1_END_SEQUENCE;

        // signature  BIT STRING --> ECDSA-with-SHA256 signature with P256 key with R,S integers format
        // (see RFC3279 sec 2.2.3 ECDSA Signature Algorithm)
        ASN1_START_BIT_STRING_ENCAPSULATED
        {
            // Convert raw signature to embedded signature
            FixedByteSpan<Crypto::kP256_ECDSA_Signature_Length_Raw> rawSig(signature.Bytes());

            uint8_t derInt[kP256_FE_Length + kEmitDerIntegerWithoutTagOverhead];

            // Ecdsa-Sig-Value ::= SEQUENCE
            ASN1_START_SEQUENCE
            {
                using P256IntegerSpan = FixedByteSpan<Crypto::kP256_FE_Length>;
                // r INTEGER
                {
                    MutableByteSpan derIntSpan(derInt, sizeof(derInt));
                    ReturnErrorOnFailure(ConvertIntegerRawToDerWithoutTag(P256IntegerSpan(rawSig.data()), derIntSpan));
                    ReturnErrorOnFailure(writer.PutValue(kASN1TagClass_Universal, kASN1UniversalTag_Integer, false,
                                                         derIntSpan.data(), static_cast<uint16_t>(derIntSpan.size())));
                }

                // s INTEGER
                {
                    MutableByteSpan derIntSpan(derInt, sizeof(derInt));
                    ReturnErrorOnFailure(
                        ConvertIntegerRawToDerWithoutTag(P256IntegerSpan(rawSig.data() + kP256_FE_Length), derIntSpan));
                    ReturnErrorOnFailure(writer.PutValue(kASN1TagClass_Universal, kASN1UniversalTag_Integer, false,
                                                         derIntSpan.data(), static_cast<uint16_t>(derIntSpan.size())));
                }
            }
            ASN1_END_SEQUENCE;
        }
        ASN1_END_ENCAPSULATED;
    }
    ASN1_END_SEQUENCE;

exit:
    // Update size of output buffer on success
    if (err == CHIP_NO_ERROR)
    {
        csr_span.reduce_size(writer.GetLengthWritten());
    }
    return err;
}

CHIP_ERROR VerifyCertificateSigningRequestFormat(const uint8_t * csr, size_t csr_length)
{
    // Ensure we have enough size to validate header
    VerifyOrReturnError((csr_length >= 16) && (csr_length <= kMAX_CSR_Length), CHIP_ERROR_UNSUPPORTED_CERT_FORMAT);

    Reader reader(csr, csr_length);

    // Ensure we have an outermost SEQUENCE
    uint8_t seq_header = 0;
    ReturnErrorOnFailure(reader.Read8(&seq_header).StatusCode());
    VerifyOrReturnError(seq_header == kSeqTag, CHIP_ERROR_UNSUPPORTED_CERT_FORMAT);

    uint8_t seq_length = 0;
    VerifyOrReturnError(ReadDerLength(reader, seq_length) == CHIP_NO_ERROR, CHIP_ERROR_UNSUPPORTED_CERT_FORMAT);

    // Ensure that outer length matches sequence length + tag overhead, otherwise
    // we have trailing garbage
    size_t header_overhead = (seq_length <= 127) ? 2 : 3;
    VerifyOrReturnError(csr_length == (seq_length + header_overhead), CHIP_ERROR_UNSUPPORTED_CERT_FORMAT);

    return CHIP_NO_ERROR;
}

} // namespace Crypto
} // namespace chip
