LCOV - code coverage report
Current view: top level - crypto - CHIPCryptoPAL.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 64 68 94.1 %
Date: 2024-02-15 08:20:41 Functions: 69 80 86.2 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *    Copyright (c) 2020-2023 Project CHIP Authors
       4             :  *
       5             :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6             :  *    you may not use this file except in compliance with the License.
       7             :  *    You may obtain a copy of the License at
       8             :  *
       9             :  *        http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  *    Unless required by applicable law or agreed to in writing, software
      12             :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13             :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  *    See the License for the specific language governing permissions and
      15             :  *    limitations under the License.
      16             :  */
      17             : 
      18             : /**
      19             :  *    @file
      20             :  *      Header that exposes the platform agnostic CHIP crypto primitives
      21             :  */
      22             : 
      23             : #pragma once
      24             : 
      25             : #if CHIP_HAVE_CONFIG_H
      26             : #include <crypto/CryptoBuildConfig.h>
      27             : #endif // CHIP_HAVE_CONFIG_H
      28             : 
      29             : #include <system/SystemConfig.h>
      30             : 
      31             : #include <lib/core/CHIPError.h>
      32             : #include <lib/core/CHIPVendorIdentifiers.hpp>
      33             : #include <lib/core/Optional.h>
      34             : #include <lib/support/BufferReader.h>
      35             : #include <lib/support/CodeUtils.h>
      36             : #include <lib/support/SafePointerCast.h>
      37             : #include <lib/support/Span.h>
      38             : 
      39             : #include <stddef.h>
      40             : #include <string.h>
      41             : 
      42             : namespace chip {
      43             : namespace Crypto {
      44             : 
      45             : inline constexpr size_t kMax_x509_Certificate_Length = 600;
      46             : 
      47             : inline constexpr size_t kP256_FE_Length                        = 32;
      48             : inline constexpr size_t kP256_ECDSA_Signature_Length_Raw       = (2 * kP256_FE_Length);
      49             : inline constexpr size_t kP256_Point_Length                     = (2 * kP256_FE_Length + 1);
      50             : inline constexpr size_t kSHA256_Hash_Length                    = 32;
      51             : inline constexpr size_t kSHA1_Hash_Length                      = 20;
      52             : inline constexpr size_t kSubjectKeyIdentifierLength            = kSHA1_Hash_Length;
      53             : inline constexpr size_t kAuthorityKeyIdentifierLength          = kSHA1_Hash_Length;
      54             : inline constexpr size_t kMaxCertificateSerialNumberLength      = 20;
      55             : inline constexpr size_t kMaxCertificateDistinguishedNameLength = 200;
      56             : inline constexpr size_t kMaxCRLDistributionPointURLLength      = 100;
      57             : 
      58             : inline constexpr char kValidCDPURIHttpPrefix[]  = "http://";
      59             : inline constexpr char kValidCDPURIHttpsPrefix[] = "https://";
      60             : 
      61             : inline constexpr size_t CHIP_CRYPTO_GROUP_SIZE_BYTES      = kP256_FE_Length;
      62             : inline constexpr size_t CHIP_CRYPTO_PUBLIC_KEY_SIZE_BYTES = kP256_Point_Length;
      63             : 
      64             : inline constexpr size_t CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES      = 16;
      65             : inline constexpr size_t CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES = 16;
      66             : 
      67             : inline constexpr size_t kMax_ECDH_Secret_Length     = kP256_FE_Length;
      68             : inline constexpr size_t kMax_ECDSA_Signature_Length = kP256_ECDSA_Signature_Length_Raw;
      69             : inline constexpr size_t kMAX_FE_Length              = kP256_FE_Length;
      70             : inline constexpr size_t kMAX_Point_Length           = kP256_Point_Length;
      71             : inline constexpr size_t kMAX_Hash_Length            = kSHA256_Hash_Length;
      72             : 
      73             : // Minimum required CSR length buffer length is relatively small since it's a single
      74             : // P256 key and no metadata/extensions are expected to be honored by the CA.
      75             : inline constexpr size_t kMIN_CSR_Buffer_Size = 255;
      76             : 
      77             : [[deprecated("This constant is no longer used by common code and should be replaced by kMIN_CSR_Buffer_Size. Checks that a CSR is "
      78             :              "<= kMAX_CSR_Buffer_size must be updated. This remains to keep valid buffers working from previous public API "
      79             :              "usage.")]] constexpr size_t kMAX_CSR_Buffer_Size = 255;
      80             : 
      81             : inline constexpr size_t CHIP_CRYPTO_HASH_LEN_BYTES = kSHA256_Hash_Length;
      82             : 
      83             : inline constexpr size_t kSpake2p_Min_PBKDF_Salt_Length  = 16;
      84             : inline constexpr size_t kSpake2p_Max_PBKDF_Salt_Length  = 32;
      85             : inline constexpr uint32_t kSpake2p_Min_PBKDF_Iterations = 1000;
      86             : inline constexpr uint32_t kSpake2p_Max_PBKDF_Iterations = 100000;
      87             : 
      88             : inline constexpr size_t kP256_PrivateKey_Length = CHIP_CRYPTO_GROUP_SIZE_BYTES;
      89             : inline constexpr size_t kP256_PublicKey_Length  = CHIP_CRYPTO_PUBLIC_KEY_SIZE_BYTES;
      90             : 
      91             : inline constexpr size_t kAES_CCM128_Key_Length   = 128u / 8u;
      92             : inline constexpr size_t kAES_CCM128_Block_Length = kAES_CCM128_Key_Length;
      93             : inline constexpr size_t kAES_CCM128_Nonce_Length = 13;
      94             : inline constexpr size_t kAES_CCM128_Tag_Length   = 16;
      95             : inline constexpr size_t kHMAC_CCM128_Key_Length  = 128u / 8u;
      96             : 
      97             : inline constexpr size_t CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES = kAES_CCM128_Nonce_Length;
      98             : 
      99             : /* These sizes are hardcoded here to remove header dependency on underlying crypto library
     100             :  * in a public interface file. The validity of these sizes is verified by static_assert in
     101             :  * the implementation files.
     102             :  */
     103             : inline constexpr size_t kMAX_Spake2p_Context_Size     = 1024;
     104             : inline constexpr size_t kMAX_P256Keypair_Context_Size = 512;
     105             : 
     106             : inline constexpr size_t kEmitDerIntegerWithoutTagOverhead = 1; // 1 sign stuffer
     107             : inline constexpr size_t kEmitDerIntegerOverhead           = 3; // Tag + Length byte + 1 sign stuffer
     108             : 
     109             : inline constexpr size_t kMAX_Hash_SHA256_Context_Size = CHIP_CONFIG_SHA256_CONTEXT_SIZE;
     110             : 
     111             : inline constexpr size_t kSpake2p_WS_Length                 = kP256_FE_Length + 8;
     112             : inline constexpr size_t kSpake2p_VerifierSerialized_Length = kP256_FE_Length + kP256_Point_Length;
     113             : 
     114             : inline constexpr char kVIDPrefixForCNEncoding[]    = "Mvid:";
     115             : inline constexpr char kPIDPrefixForCNEncoding[]    = "Mpid:";
     116             : inline constexpr size_t kVIDandPIDHexLength        = sizeof(uint16_t) * 2;
     117             : inline constexpr size_t kMax_CommonNameAttr_Length = 64;
     118             : 
     119             : /*
     120             :  * Overhead to encode a raw ECDSA signature in X9.62 format in ASN.1 DER
     121             :  *
     122             :  * Ecdsa-Sig-Value ::= SEQUENCE {
     123             :  *     r       INTEGER,
     124             :  *     s       INTEGER
     125             :  * }
     126             :  *
     127             :  * --> SEQUENCE, universal constructed tag (0x30), length over 2 bytes, up to 255 (to support future larger sizes up to 512 bits)
     128             :  *   -> SEQ_OVERHEAD = 3 bytes
     129             :  * --> INTEGER, universal primitive tag (0x02), length over 1 byte, one extra byte worst case
     130             :  *     over max for 0x00 when MSB is set.
     131             :  *       -> INT_OVERHEAD = 3 bytes
     132             :  *
     133             :  * There is 1 sequence of 2 integers. Overhead is SEQ_OVERHEAD + (2 * INT_OVERHEAD) = 3 + (2 * 3) = 9.
     134             :  */
     135             : inline constexpr size_t kMax_ECDSA_X9Dot62_Asn1_Overhead = 9;
     136             : inline constexpr size_t kMax_ECDSA_Signature_Length_Der  = kMax_ECDSA_Signature_Length + kMax_ECDSA_X9Dot62_Asn1_Overhead;
     137             : 
     138             : static_assert(kMax_ECDH_Secret_Length >= kP256_FE_Length, "ECDH shared secret is too short for crypto suite");
     139             : static_assert(kMax_ECDSA_Signature_Length >= kP256_ECDSA_Signature_Length_Raw,
     140             :               "ECDSA signature buffer length is too short for crypto suite");
     141             : 
     142             : inline constexpr size_t kCompressedFabricIdentifierSize = 8;
     143             : 
     144             : /**
     145             :  * Spake2+ parameters for P256
     146             :  * Defined in https://www.ietf.org/id/draft-bar-cfrg-spake2plus-01.html#name-ciphersuites
     147             :  */
     148             : const uint8_t spake2p_M_p256[] = {
     149             :     0x04, 0x88, 0x6e, 0x2f, 0x97, 0xac, 0xe4, 0x6e, 0x55, 0xba, 0x9d, 0xd7, 0x24, 0x25, 0x79, 0xf2, 0x99,
     150             :     0x3b, 0x64, 0xe1, 0x6e, 0xf3, 0xdc, 0xab, 0x95, 0xaf, 0xd4, 0x97, 0x33, 0x3d, 0x8f, 0xa1, 0x2f, 0x5f,
     151             :     0xf3, 0x55, 0x16, 0x3e, 0x43, 0xce, 0x22, 0x4e, 0x0b, 0x0e, 0x65, 0xff, 0x02, 0xac, 0x8e, 0x5c, 0x7b,
     152             :     0xe0, 0x94, 0x19, 0xc7, 0x85, 0xe0, 0xca, 0x54, 0x7d, 0x55, 0xa1, 0x2e, 0x2d, 0x20,
     153             : };
     154             : const uint8_t spake2p_N_p256[] = {
     155             :     0x04, 0xd8, 0xbb, 0xd6, 0xc6, 0x39, 0xc6, 0x29, 0x37, 0xb0, 0x4d, 0x99, 0x7f, 0x38, 0xc3, 0x77, 0x07,
     156             :     0x19, 0xc6, 0x29, 0xd7, 0x01, 0x4d, 0x49, 0xa2, 0x4b, 0x4f, 0x98, 0xba, 0xa1, 0x29, 0x2b, 0x49, 0x07,
     157             :     0xd6, 0x0a, 0xa6, 0xbf, 0xad, 0xe4, 0x50, 0x08, 0xa6, 0x36, 0x33, 0x7f, 0x51, 0x68, 0xc6, 0x4d, 0x9b,
     158             :     0xd3, 0x60, 0x34, 0x80, 0x8c, 0xd5, 0x64, 0x49, 0x0b, 0x1e, 0x65, 0x6e, 0xdb, 0xe7,
     159             : };
     160             : 
     161             : /**
     162             :  * Spake2+ state machine to ensure proper execution of the protocol.
     163             :  */
     164             : enum class CHIP_SPAKE2P_STATE : uint8_t
     165             : {
     166             :     PREINIT = 0, // Before any initialization
     167             :     INIT,        // First initialization
     168             :     STARTED,     // Prover & Verifier starts
     169             :     R1,          // Round one complete
     170             :     R2,          // Round two complete
     171             :     KC,          // Key confirmation complete
     172             : };
     173             : 
     174             : /**
     175             :  * Spake2+ role.
     176             :  */
     177             : enum class CHIP_SPAKE2P_ROLE : uint8_t
     178             : {
     179             :     VERIFIER = 0, // Accessory
     180             :     PROVER   = 1, // Commissioner
     181             : };
     182             : 
     183             : enum class SupportedECPKeyTypes : uint8_t
     184             : {
     185             :     ECP256R1 = 0,
     186             : };
     187             : 
     188             : enum class ECPKeyTarget : uint8_t
     189             : {
     190             :     ECDH  = 0,
     191             :     ECDSA = 1,
     192             : };
     193             : 
     194             : /** @brief Safely clears the first `len` bytes of memory area `buf`.
     195             :  * @param buf Pointer to a memory buffer holding secret data that must be cleared.
     196             :  * @param len Specifies secret data size in bytes.
     197             :  **/
     198             : void ClearSecretData(uint8_t * buf, size_t len);
     199             : 
     200             : /**
     201             :  * Helper for clearing a C array which auto-deduces the size.
     202             :  */
     203             : template <size_t N>
     204      411446 : void ClearSecretData(uint8_t (&buf)[N])
     205             : {
     206      411446 :     ClearSecretData(buf, N);
     207      411446 : }
     208             : 
     209             : /**
     210             :  * @brief Constant-time buffer comparison
     211             :  *
     212             :  * This function implements constant time memcmp. It's good practice
     213             :  * to use constant time functions for cryptographic functions.
     214             :  *
     215             :  * @param a Pointer to first buffer
     216             :  * @param b Pointer to Second buffer
     217             :  * @param n Number of bytes to compare
     218             :  * @return true if `n` first bytes of both buffers are equal, false otherwise
     219             :  */
     220             : bool IsBufferContentEqualConstantTime(const void * a, const void * b, size_t n);
     221             : 
     222             : template <typename Sig>
     223             : class ECPKey
     224             : {
     225             : protected:
     226             :     // This base type can't be copied / assigned directly.
     227             :     // Sub-types should be either uncopyable or final.
     228        7896 :     ECPKey()                           = default;
     229             :     ECPKey(const ECPKey &)             = default;
     230        1348 :     ECPKey & operator=(const ECPKey &) = default;
     231             : 
     232             : public:
     233        7896 :     virtual ~ECPKey() = default;
     234             : 
     235             :     virtual SupportedECPKeyTypes Type() const  = 0;
     236             :     virtual size_t Length() const              = 0;
     237             :     virtual bool IsUncompressed() const        = 0;
     238             :     virtual operator const uint8_t *() const   = 0;
     239             :     virtual operator uint8_t *()               = 0;
     240             :     virtual const uint8_t * ConstBytes() const = 0;
     241             :     virtual uint8_t * Bytes()                  = 0;
     242             : 
     243         676 :     virtual bool Matches(const ECPKey<Sig> & other) const
     244             :     {
     245        1352 :         return (this->Length() == other.Length()) &&
     246        1352 :             IsBufferContentEqualConstantTime(this->ConstBytes(), other.ConstBytes(), this->Length());
     247             :     }
     248             : 
     249             :     virtual CHIP_ERROR ECDSA_validate_msg_signature(const uint8_t * msg, const size_t msg_length, const Sig & signature) const = 0;
     250             :     virtual CHIP_ERROR ECDSA_validate_hash_signature(const uint8_t * hash, const size_t hash_length,
     251             :                                                      const Sig & signature) const                                              = 0;
     252             : };
     253             : 
     254             : /**
     255             :  * @brief Helper class for holding sensitive data that should be erased from memory after use.
     256             :  *
     257             :  * The sensitive data buffer is a variable-length, fixed-capacity buffer class that securely erases
     258             :  * the contents of a buffer when the buffer is destroyed.
     259             :  */
     260             : template <size_t kCapacity>
     261             : class SensitiveDataBuffer
     262             : {
     263             : public:
     264        3123 :     ~SensitiveDataBuffer()
     265             :     {
     266             :         // Sanitize after use
     267        3123 :         ClearSecretData(mBytes);
     268        3123 :     }
     269             : 
     270             :     SensitiveDataBuffer & operator=(const SensitiveDataBuffer & other)
     271             :     {
     272             :         // Guard self assignment
     273             :         if (this == &other)
     274             :             return *this;
     275             : 
     276             :         ClearSecretData(mBytes);
     277             :         SetLength(other.Length());
     278             :         ::memcpy(Bytes(), other.ConstBytes(), other.Length());
     279             :         return *this;
     280             :     }
     281             : 
     282             :     /**
     283             :      * @brief Set current length of the buffer
     284             :      * @return Error if new length is exceeds capacity of the buffer
     285             :      */
     286        3876 :     CHIP_ERROR SetLength(size_t length)
     287             :     {
     288        3876 :         VerifyOrReturnError(length <= kCapacity, CHIP_ERROR_INVALID_ARGUMENT);
     289        3876 :         mLength = length;
     290        3876 :         return CHIP_NO_ERROR;
     291             :     }
     292             : 
     293             :     /**
     294             :      * @brief Returns current length of the buffer
     295             :      */
     296        4465 :     size_t Length() const { return mLength; }
     297             : 
     298             :     /**
     299             :      * @brief Returns non-const pointer to start of the underlying buffer
     300             :      */
     301        5310 :     uint8_t * Bytes() { return &mBytes[0]; }
     302             : 
     303             :     /**
     304             :      * @brief Returns const pointer to start of the underlying buffer
     305             :      */
     306        6348 :     const uint8_t * ConstBytes() const { return &mBytes[0]; }
     307             : 
     308             :     /**
     309             :      * @brief Constructs span from the underlying buffer
     310             :      */
     311          21 :     ByteSpan Span() const { return ByteSpan(ConstBytes(), Length()); }
     312             : 
     313             :     /**
     314             :      * @brief Returns capacity of the buffer
     315             :      */
     316        1710 :     static constexpr size_t Capacity() { return kCapacity; }
     317             : 
     318             : private:
     319             :     uint8_t mBytes[kCapacity];
     320             :     size_t mLength = 0;
     321             : };
     322             : 
     323             : /**
     324             :  * @brief Helper class for holding fixed-sized sensitive data that should be erased from memory after use.
     325             :  *
     326             :  * The sensitive data buffer is a fixed-length, fixed-capacity buffer class that securely erases
     327             :  * the contents of a buffer when the buffer is destroyed.
     328             :  */
     329             : template <size_t kCapacity>
     330             : class SensitiveDataFixedBuffer
     331             : {
     332             : public:
     333             :     SensitiveDataFixedBuffer() = default;
     334             : 
     335             :     constexpr explicit SensitiveDataFixedBuffer(const uint8_t (&rawValue)[kCapacity])
     336             :     {
     337             :         memcpy(&mBytes[0], &rawValue[0], kCapacity);
     338             :     }
     339             : 
     340           0 :     constexpr explicit SensitiveDataFixedBuffer(const FixedByteSpan<kCapacity> & value)
     341             :     {
     342           0 :         memcpy(&mBytes[0], value.data(), kCapacity);
     343           0 :     }
     344             : 
     345      135111 :     ~SensitiveDataFixedBuffer()
     346             :     {
     347             :         // Sanitize after use
     348      135111 :         ClearSecretData(mBytes);
     349      135111 :     }
     350             : 
     351             :     /**
     352             :      * @brief Returns fixed length of the buffer
     353             :      */
     354             :     constexpr size_t Length() const { return kCapacity; }
     355             : 
     356             :     /**
     357             :      * @brief Returns non-const pointer to start of the underlying buffer
     358             :      */
     359        1333 :     uint8_t * Bytes() { return &mBytes[0]; }
     360             : 
     361             :     /**
     362             :      * @brief Returns const pointer to start of the underlying buffer
     363             :      */
     364             :     const uint8_t * ConstBytes() const { return &mBytes[0]; }
     365             : 
     366             :     /**
     367             :      * @brief Constructs fixed span from the underlying buffer
     368             :      */
     369           0 :     FixedByteSpan<kCapacity> Span() const { return FixedByteSpan<kCapacity>(mBytes); }
     370             : 
     371             :     /**
     372             :      * @brief Returns capacity of the buffer
     373             :      */
     374        1318 :     static constexpr size_t Capacity() { return kCapacity; }
     375             : 
     376             : private:
     377             :     uint8_t mBytes[kCapacity];
     378             : };
     379             : 
     380             : using P256ECDSASignature    = SensitiveDataBuffer<kMax_ECDSA_Signature_Length>;
     381             : using P256ECDHDerivedSecret = SensitiveDataBuffer<kMax_ECDH_Secret_Length>;
     382             : 
     383             : using IdentityProtectionKey     = SensitiveDataFixedBuffer<CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES>;
     384             : using IdentityProtectionKeySpan = FixedByteSpan<Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES>;
     385             : 
     386             : using AttestationChallenge = SensitiveDataFixedBuffer<CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES>;
     387             : 
     388             : class P256PublicKey final // final due to being copyable
     389             :     : public ECPKey<P256ECDSASignature>
     390             : {
     391             : public:
     392        7202 :     P256PublicKey() = default;
     393             : 
     394             :     template <size_t N>
     395             :     constexpr P256PublicKey(const uint8_t (&raw_value)[N])
     396             :     {
     397             :         static_assert(N == kP256_PublicKey_Length, "Can only array-initialize from proper bounds");
     398             :         memcpy(&bytes[0], &raw_value[0], N);
     399             :     }
     400             : 
     401             :     template <size_t N>
     402         625 :     constexpr P256PublicKey(const FixedByteSpan<N> & value)
     403         625 :     {
     404             :         static_assert(N == kP256_PublicKey_Length, "Can only initialize from proper sized byte span");
     405         625 :         memcpy(&bytes[0], value.data(), N);
     406         625 :     }
     407             : 
     408             :     template <size_t N>
     409         799 :     P256PublicKey & operator=(const FixedByteSpan<N> & value)
     410             :     {
     411             :         static_assert(N == kP256_PublicKey_Length, "Can only initialize from proper sized byte span");
     412         799 :         memcpy(&bytes[0], value.data(), N);
     413         799 :         return *this;
     414             :     }
     415             : 
     416        3625 :     SupportedECPKeyTypes Type() const override { return SupportedECPKeyTypes::ECP256R1; }
     417       13903 :     size_t Length() const override { return kP256_PublicKey_Length; }
     418        4804 :     operator uint8_t *() override { return bytes; }
     419        2801 :     operator const uint8_t *() const override { return bytes; }
     420        2759 :     const uint8_t * ConstBytes() const override { return &bytes[0]; }
     421          17 :     uint8_t * Bytes() override { return &bytes[0]; }
     422         681 :     bool IsUncompressed() const override
     423             :     {
     424         681 :         constexpr uint8_t kUncompressedPointMarker = 0x04;
     425             :         // SEC1 definition of an uncompressed point is (0x04 || X || Y) where X and Y are
     426             :         // raw zero-padded big-endian large integers of the group size.
     427         681 :         return (Length() == ((kP256_FE_Length * 2) + 1)) && (ConstBytes()[0] == kUncompressedPointMarker);
     428             :     }
     429             : 
     430             :     CHIP_ERROR ECDSA_validate_msg_signature(const uint8_t * msg, size_t msg_length,
     431             :                                             const P256ECDSASignature & signature) const override;
     432             :     CHIP_ERROR ECDSA_validate_hash_signature(const uint8_t * hash, size_t hash_length,
     433             :                                              const P256ECDSASignature & signature) const override;
     434             : 
     435             : private:
     436             :     uint8_t bytes[kP256_PublicKey_Length];
     437             : };
     438             : 
     439             : template <typename PK, typename Secret, typename Sig>
     440             : class ECPKeypair
     441             : {
     442             : protected:
     443             :     // This base type can't be copied / assigned directly.
     444             :     // Sub-types should be either uncopyable or final.
     445        1197 :     ECPKeypair()                               = default;
     446             :     ECPKeypair(const ECPKeypair &)             = default;
     447             :     ECPKeypair & operator=(const ECPKeypair &) = default;
     448             : 
     449             : public:
     450        1489 :     virtual ~ECPKeypair() = default;
     451             : 
     452             :     /** @brief Generate a new Certificate Signing Request (CSR).
     453             :      * @param csr Newly generated CSR in DER format
     454             :      * @param csr_length The caller provides the length of input buffer (csr). The function returns the actual length of generated
     455             :      *CSR.
     456             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     457             :      **/
     458             :     virtual CHIP_ERROR NewCertificateSigningRequest(uint8_t * csr, size_t & csr_length) const = 0;
     459             : 
     460             :     /**
     461             :      * @brief A function to sign a msg using ECDSA
     462             :      * @param msg Message that needs to be signed
     463             :      * @param msg_length Length of message
     464             :      * @param out_signature Buffer that will hold the output signature. The signature consists of: 2 EC elements (r and s),
     465             :      * in raw <r,s> point form (see SEC1).
     466             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     467             :      **/
     468             :     virtual CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, Sig & out_signature) const = 0;
     469             : 
     470             :     /** @brief A function to derive a shared secret using ECDH
     471             :      * @param remote_public_key Public key of remote peer with which we are trying to establish secure channel. remote_public_key is
     472             :      * ASN.1 DER encoded as padded big-endian field elements as described in SEC 1: Elliptic Curve Cryptography
     473             :      * [https://www.secg.org/sec1-v2.pdf]
     474             :      * @param out_secret Buffer to write out secret into. This is a byte array representing the x coordinate of the shared secret.
     475             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     476             :      **/
     477             :     virtual CHIP_ERROR ECDH_derive_secret(const PK & remote_public_key, Secret & out_secret) const = 0;
     478             : 
     479             :     virtual const PK & Pubkey() const = 0;
     480             : };
     481             : 
     482             : struct alignas(size_t) P256KeypairContext
     483             : {
     484             :     uint8_t mBytes[kMAX_P256Keypair_Context_Size];
     485             : };
     486             : 
     487             : /**
     488             :  * A serialized P256 key pair is the concatenation of the public and private keys, in that order.
     489             :  */
     490             : using P256SerializedKeypair = SensitiveDataBuffer<kP256_PublicKey_Length + kP256_PrivateKey_Length>;
     491             : 
     492             : class P256KeypairBase : public ECPKeypair<P256PublicKey, P256ECDHDerivedSecret, P256ECDSASignature>
     493             : {
     494             : protected:
     495             :     // This base type can't be copied / assigned directly.
     496             :     // Sub-types should be either uncopyable or final.
     497        1197 :     P256KeypairBase()                                    = default;
     498             :     P256KeypairBase(const P256KeypairBase &)             = default;
     499             :     P256KeypairBase & operator=(const P256KeypairBase &) = default;
     500             : 
     501             : public:
     502             :     /**
     503             :      * @brief Initialize the keypair.
     504             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     505             :      **/
     506             :     virtual CHIP_ERROR Initialize(ECPKeyTarget key_target) = 0;
     507             : 
     508             :     /**
     509             :      * @brief Serialize the keypair.
     510             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     511             :      **/
     512             :     virtual CHIP_ERROR Serialize(P256SerializedKeypair & output) const = 0;
     513             : 
     514             :     /**
     515             :      * @brief Deserialize the keypair.
     516             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     517             :      **/
     518             :     virtual CHIP_ERROR Deserialize(P256SerializedKeypair & input) = 0;
     519             : };
     520             : 
     521             : class P256Keypair : public P256KeypairBase
     522             : {
     523             : public:
     524        1197 :     P256Keypair() = default;
     525             :     ~P256Keypair() override;
     526             : 
     527             :     // P256Keypair can't be copied / assigned.
     528             :     P256Keypair(const P256Keypair &)             = delete;
     529             :     P256Keypair & operator=(const P256Keypair &) = delete;
     530             : 
     531             :     /**
     532             :      * @brief Initialize the keypair.
     533             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     534             :      **/
     535             :     CHIP_ERROR Initialize(ECPKeyTarget key_target) override;
     536             : 
     537             :     /**
     538             :      * @brief Serialize the keypair.
     539             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     540             :      **/
     541             :     CHIP_ERROR Serialize(P256SerializedKeypair & output) const override;
     542             : 
     543             :     /**
     544             :      * @brief Deserialize the keypair.
     545             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     546             :      **/
     547             :     CHIP_ERROR Deserialize(P256SerializedKeypair & input) override;
     548             : 
     549             :     /**
     550             :      * @brief Generate a new Certificate Signing Request (CSR).
     551             :      * @param csr Newly generated CSR in DER format
     552             :      * @param csr_length The caller provides the length of input buffer (csr). The function returns the actual length of generated
     553             :      *CSR.
     554             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     555             :      **/
     556             :     CHIP_ERROR NewCertificateSigningRequest(uint8_t * csr, size_t & csr_length) const override;
     557             : 
     558             :     /**
     559             :      * @brief A function to sign a msg using ECDSA
     560             :      * @param msg Message that needs to be signed
     561             :      * @param msg_length Length of message
     562             :      * @param out_signature Buffer that will hold the output signature. The signature consists of: 2 EC elements (r and s),
     563             :      * in raw <r,s> point form (see SEC1).
     564             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     565             :      **/
     566             :     CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, P256ECDSASignature & out_signature) const override;
     567             : 
     568             :     /**
     569             :      * @brief A function to derive a shared secret using ECDH
     570             :      *
     571             :      * This implements the CHIP_Crypto_ECDH(PrivateKey myPrivateKey, PublicKey theirPublicKey) cryptographic primitive
     572             :      * from the specification, using this class's private key from `mKeypair` as `myPrivateKey` and the remote
     573             :      * public key from `remote_public_key` as `theirPublicKey`.
     574             :      *
     575             :      * @param remote_public_key Public key of remote peer with which we are trying to establish secure channel. remote_public_key is
     576             :      * ASN.1 DER encoded as padded big-endian field elements as described in SEC 1: Elliptic Curve Cryptography
     577             :      * [https://www.secg.org/sec1-v2.pdf]
     578             :      * @param out_secret Buffer to write out secret into. This is a byte array representing the x coordinate of the shared secret.
     579             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     580             :      **/
     581             :     CHIP_ERROR ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const override;
     582             : 
     583             :     /** @brief Return public key for the keypair.
     584             :      **/
     585         978 :     const P256PublicKey & Pubkey() const override { return mPublicKey; }
     586             : 
     587             :     /** Release resources associated with this key pair */
     588             :     void Clear();
     589             : 
     590             : protected:
     591             :     P256PublicKey mPublicKey;
     592             :     mutable P256KeypairContext mKeypair;
     593             :     bool mInitialized = false;
     594             : };
     595             : 
     596             : /**
     597             :  * @brief Platform-specific symmetric key handle
     598             :  *
     599             :  * The class represents a key used by the Matter stack either in the form of raw key material or key
     600             :  * reference, depending on the platform. To achieve that, it contains an opaque context that can be
     601             :  * cast to a concrete representation used by the given platform.
     602             :  *
     603             :  * @note SymmetricKeyHandle is an abstract class to force child classes for each key handle type.
     604             :  *       SymmetricKeyHandle class implements all the necessary components for handles.
     605             :  */
     606             : template <size_t ContextSize>
     607             : class SymmetricKeyHandle
     608             : {
     609             : public:
     610             :     SymmetricKeyHandle(const SymmetricKeyHandle &) = delete;
     611             :     SymmetricKeyHandle(SymmetricKeyHandle &&)      = delete;
     612             :     void operator=(const SymmetricKeyHandle &)     = delete;
     613             :     void operator=(SymmetricKeyHandle &&)          = delete;
     614             : 
     615             :     /**
     616             :      * @brief Get internal context cast to the desired key representation
     617             :      */
     618             :     template <class T>
     619       19247 :     const T & As() const
     620             :     {
     621       19247 :         return *SafePointerCast<const T *>(&mContext);
     622             :     }
     623             : 
     624             :     /**
     625             :      * @brief Get internal context cast to the desired, mutable key representation
     626             :      */
     627             :     template <class T>
     628        6046 :     T & AsMutable()
     629             :     {
     630        6046 :         return *SafePointerCast<T *>(&mContext);
     631             :     }
     632             : 
     633             : protected:
     634      270388 :     SymmetricKeyHandle() = default;
     635      270388 :     ~SymmetricKeyHandle() { ClearSecretData(mContext.mOpaque); }
     636             : 
     637             : private:
     638             :     struct alignas(uintptr_t) OpaqueContext
     639             :     {
     640             :         uint8_t mOpaque[ContextSize] = {};
     641             :     } mContext;
     642             : };
     643             : 
     644             : using Symmetric128BitsKeyByteArray = uint8_t[CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES];
     645             : 
     646             : /**
     647             :  * @brief Platform-specific 128-bit symmetric key handle
     648             :  */
     649             : class Symmetric128BitsKeyHandle : public SymmetricKeyHandle<CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES>
     650             : {
     651             : };
     652             : 
     653             : /**
     654             :  * @brief Platform-specific 128-bit AES key handle
     655             :  */
     656             : class Aes128KeyHandle final : public Symmetric128BitsKeyHandle
     657             : {
     658             : };
     659             : 
     660             : /**
     661             :  * @brief Platform-specific 128-bit HMAC key handle
     662             :  */
     663             : class Hmac128KeyHandle final : public Symmetric128BitsKeyHandle
     664             : {
     665             : };
     666             : 
     667             : /**
     668             :  * @brief Platform-specific HKDF key handle
     669             :  */
     670             : class HkdfKeyHandle final : public SymmetricKeyHandle<CHIP_CONFIG_HKDF_KEY_HANDLE_CONTEXT_SIZE>
     671             : {
     672             : };
     673             : 
     674             : /**
     675             :  * @brief Convert a raw ECDSA signature to ASN.1 signature (per X9.62) as used by TLS libraries.
     676             :  *
     677             :  * Errors are:
     678             :  *   - CHIP_ERROR_INVALID_ARGUMENT on any argument being invalid (e.g. nullptr), wrong sizes,
     679             :  *     wrong or unsupported format,
     680             :  *   - CHIP_ERROR_BUFFER_TOO_SMALL on running out of space at runtime.
     681             :  *   - CHIP_ERROR_INTERNAL on any unexpected processing error.
     682             :  *
     683             :  * @param[in] fe_length_bytes Field Element length in bytes (e.g. 32 for P256 curve)
     684             :  * @param[in] raw_sig Raw signature of <r,s> concatenated
     685             :  * @param[out] out_asn1_sig ASN.1 DER signature format output buffer. Size must have space for at least
     686             :  * kMax_ECDSA_X9Dot62_Asn1_Overhead. On CHIP_NO_ERROR, the out_asn1_sig buffer will be re-assigned
     687             :  * to have the correct size based on variable-length output.
     688             :  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     689             :  */
     690             : CHIP_ERROR EcdsaRawSignatureToAsn1(size_t fe_length_bytes, const ByteSpan & raw_sig, MutableByteSpan & out_asn1_sig);
     691             : 
     692             : /**
     693             :  * @brief Convert an ASN.1 DER signature (per X9.62) as used by TLS libraries to SEC1 raw format
     694             :  *
     695             :  * Errors are:
     696             :  *   - CHIP_ERROR_INVALID_ARGUMENT on any argument being invalid (e.g. nullptr), wrong sizes,
     697             :  *     wrong or unsupported format,
     698             :  *   - CHIP_ERROR_BUFFER_TOO_SMALL on running out of space at runtime.
     699             :  *   - CHIP_ERROR_INTERNAL on any unexpected processing error.
     700             :  *
     701             :  * @param[in] fe_length_bytes Field Element length in bytes (e.g. 32 for P256 curve)
     702             :  * @param[in] asn1_sig ASN.1 DER signature input
     703             :  * @param[out] out_raw_sig Raw signature of <r,s> concatenated format output buffer. Size must be at
     704             :  * least >= `2 * fe_length_bytes`. On CHIP_NO_ERROR, the out_raw_sig buffer will be re-assigned
     705             :  * to have the correct size (2 * fe_length_bytes).
     706             :  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     707             :  */
     708             : CHIP_ERROR EcdsaAsn1SignatureToRaw(size_t fe_length_bytes, const ByteSpan & asn1_sig, MutableByteSpan & out_raw_sig);
     709             : 
     710             : /**
     711             :  * @brief Utility to read a length field after a tag in a DER-encoded stream.
     712             :  * @param[in] reader Reader instance from which the input will be read
     713             :  * @param[out] length Length of the following element read from the stream
     714             :  * @return CHIP_ERROR_INVALID_ARGUMENT or CHIP_ERROR_BUFFER_TOO_SMALL on error, CHIP_NO_ERROR otherwise
     715             :  */
     716             : CHIP_ERROR ReadDerLength(chip::Encoding::LittleEndian::Reader & reader, size_t & length);
     717             : 
     718             : /**
     719             :  * @brief Utility to emit a DER-encoded INTEGER given a raw unsigned large integer
     720             :  *        in big-endian order. The `out_der_integer` span is updated to reflect the final
     721             :  *        variable length, including tag and length, and must have at least `kEmitDerIntegerOverhead`
     722             :  *        extra space in addition to the `raw_integer.size()`.
     723             :  * @param[in] raw_integer Bytes of a large unsigned integer in big-endian, possibly including leading zeroes
     724             :  * @param[out] out_der_integer Buffer to receive the DER-encoded integer
     725             :  * @return Returns CHIP_ERROR_INVALID_ARGUMENT or CHIP_ERROR_BUFFER_TOO_SMALL on error, CHIP_NO_ERROR otherwise.
     726             :  */
     727             : CHIP_ERROR ConvertIntegerRawToDer(const ByteSpan & raw_integer, MutableByteSpan & out_der_integer);
     728             : 
     729             : /**
     730             :  * @brief Utility to emit a DER-encoded INTEGER given a raw unsigned large integer
     731             :  *        in big-endian order. The `out_der_integer` span is updated to reflect the final
     732             :  *        variable length, excluding tag and length, and must have at least `kEmitDerIntegerWithoutTagOverhead`
     733             :  *        extra space in addition to the `raw_integer.size()`.
     734             :  * @param[in] raw_integer Bytes of a large unsigned integer in big-endian, possibly including leading zeroes
     735             :  * @param[out] out_der_integer Buffer to receive the DER-encoded integer
     736             :  * @return Returns CHIP_ERROR_INVALID_ARGUMENT or CHIP_ERROR_BUFFER_TOO_SMALL on error, CHIP_NO_ERROR otherwise.
     737             :  */
     738             : CHIP_ERROR ConvertIntegerRawToDerWithoutTag(const ByteSpan & raw_integer, MutableByteSpan & out_der_integer);
     739             : 
     740             : /**
     741             :  * @brief A function that implements AES-CCM encryption
     742             :  *
     743             :  * This implements the CHIP_Crypto_AEAD_GenerateEncrypt() cryptographic primitive
     744             :  * from the specification. For an empty plaintext, the user of the API can provide
     745             :  * an empty string, or a nullptr, and provide plaintext_length as 0. The output buffer,
     746             :  * ciphertext can also be an empty string, or a nullptr for this case.
     747             :  *
     748             :  * @param plaintext Plaintext to encrypt
     749             :  * @param plaintext_length Length of plain_text
     750             :  * @param aad Additional authentication data
     751             :  * @param aad_length Length of additional authentication data
     752             :  * @param key Encryption key
     753             :  * @param nonce Encryption nonce
     754             :  * @param nonce_length Length of encryption nonce
     755             :  * @param ciphertext Buffer to write ciphertext into. Caller must ensure this is large enough to hold the ciphertext
     756             :  * @param tag Buffer to write tag into. Caller must ensure this is large enough to hold the tag
     757             :  * @param tag_length Expected length of tag
     758             :  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     759             :  * */
     760             : CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, const uint8_t * aad, size_t aad_length,
     761             :                            const Aes128KeyHandle & key, const uint8_t * nonce, size_t nonce_length, uint8_t * ciphertext,
     762             :                            uint8_t * tag, size_t tag_length);
     763             : 
     764             : /**
     765             :  * @brief A function that implements AES-CCM decryption
     766             :  *
     767             :  * This implements the CHIP_Crypto_AEAD_DecryptVerify() cryptographic primitive
     768             :  * from the specification. For an empty ciphertext, the user of the API can provide
     769             :  * an empty string, or a nullptr, and provide ciphertext_length as 0. The output buffer,
     770             :  * plaintext can also be an empty string, or a nullptr for this case.
     771             :  *
     772             :  * @param ciphertext Ciphertext to decrypt
     773             :  * @param ciphertext_length Length of ciphertext
     774             :  * @param aad Additional authentical data.
     775             :  * @param aad_length Length of additional authentication data
     776             :  * @param tag Tag to use to decrypt
     777             :  * @param tag_length Length of tag
     778             :  * @param key Decryption key
     779             :  * @param nonce Encryption nonce
     780             :  * @param nonce_length Length of encryption nonce
     781             :  * @param plaintext Buffer to write plaintext into
     782             :  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     783             :  **/
     784             : CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_length, const uint8_t * aad, size_t aad_length,
     785             :                            const uint8_t * tag, size_t tag_length, const Aes128KeyHandle & key, const uint8_t * nonce,
     786             :                            size_t nonce_length, uint8_t * plaintext);
     787             : 
     788             : /**
     789             :  * @brief A function that implements AES-CTR encryption/decryption
     790             :  *
     791             :  * This implements the AES-CTR-Encrypt/Decrypt() cryptographic primitives per sections
     792             :  * 3.7.1 and 3.7.2 of the specification. For an empty input, the user of the API
     793             :  * can provide an empty string, or a nullptr, and provide input as 0.
     794             :  * The output buffer can also be an empty string, or a nullptr for this case.
     795             :  *
     796             :  * @param input Input text to encrypt/decrypt
     797             :  * @param input_length Length of ciphertext
     798             :  * @param key Decryption key
     799             :  * @param nonce Encryption nonce
     800             :  * @param nonce_length Length of encryption nonce
     801             :  * @param output Buffer to write output into
     802             :  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     803             :  **/
     804             : CHIP_ERROR AES_CTR_crypt(const uint8_t * input, size_t input_length, const Aes128KeyHandle & key, const uint8_t * nonce,
     805             :                          size_t nonce_length, uint8_t * output);
     806             : 
     807             : /**
     808             :  * @brief Generate a PKCS#10 CSR, usable for Matter, from a P256Keypair.
     809             :  *
     810             :  * This uses first principles ASN.1 encoding to avoid relying on the CHIPCryptoPAL backend
     811             :  * itself, other than to provide an implementation of a P256Keypair * that supports
     812             :  * at least `::Pubkey()` and `::ECDSA_sign_msg`. This allows using it with
     813             :  * OS/Platform-bridged private key handling, without requiring a specific
     814             :  * implementation of other bits like ASN.1.
     815             :  *
     816             :  * The CSR will have subject OU set to `CSA`. This is needed since omiting
     817             :  * subject altogether often trips CSR parsing code. The profile at the CA can
     818             :  * be configured to ignore CSR requested subject.
     819             :  *
     820             :  * @param keypair The key pair for which a CSR should be generated. Must not be null.
     821             :  * @param csr_span Span to hold the resulting CSR. Must have size at least kMIN_CSR_Buffer_Size.
     822             :  *                 Otherwise returns CHIP_ERROR_BUFFER_TOO_SMALL. It will get resized to
     823             :  *                 actual size needed on success.
     824             : 
     825             :  * @return Returns a CHIP_ERROR from P256Keypair or ASN.1 backend on error, CHIP_NO_ERROR otherwise
     826             :  **/
     827             : CHIP_ERROR GenerateCertificateSigningRequest(const P256Keypair * keypair, MutableByteSpan & csr_span);
     828             : 
     829             : /**
     830             :  * @brief Common code to validate ASN.1 format/size of a CSR, used by VerifyCertificateSigningRequest.
     831             :  *
     832             :  * Ensures it's not obviously malformed and doesn't have trailing garbage.
     833             :  *
     834             :  * @param csr CSR in DER format
     835             :  * @param csr_length The length of the CSR buffer
     836             :  * @return CHIP_ERROR_UNSUPPORTED_CERT_FORMAT on invalid format, CHIP_NO_ERROR otherwise.
     837             :  */
     838             : CHIP_ERROR VerifyCertificateSigningRequestFormat(const uint8_t * csr, size_t csr_length);
     839             : 
     840             : /**
     841             :  * @brief Verify the Certificate Signing Request (CSR). If successfully verified, it outputs the public key from the CSR.
     842             :  *
     843             :  * The CSR is valid if the format is correct, the signature validates with the embedded public
     844             :  * key, and there is no trailing garbage data.
     845             :  *
     846             :  * @param csr CSR in DER format
     847             :  * @param csr_length The length of the CSR
     848             :  * @param pubkey The public key from the verified CSR
     849             :  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     850             :  **/
     851             : CHIP_ERROR VerifyCertificateSigningRequest(const uint8_t * csr, size_t csr_length, P256PublicKey & pubkey);
     852             : 
     853             : /**
     854             :  * @brief A function that implements SHA-256 hash
     855             :  *
     856             :  * This implements the CHIP_Crypto_Hash() cryptographic primitive
     857             :  * in the the specification.
     858             :  *
     859             :  * @param data The data to hash
     860             :  * @param data_length Length of the data
     861             :  * @param out_buffer Pointer to buffer to write output into
     862             :  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     863             :  **/
     864             : 
     865             : CHIP_ERROR Hash_SHA256(const uint8_t * data, size_t data_length, uint8_t * out_buffer);
     866             : 
     867             : /**
     868             :  * @brief A function that implements SHA-1 hash
     869             :  * @param data The data to hash
     870             :  * @param data_length Length of the data
     871             :  * @param out_buffer Pointer to buffer to write output into
     872             :  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     873             :  **/
     874             : 
     875             : CHIP_ERROR Hash_SHA1(const uint8_t * data, size_t data_length, uint8_t * out_buffer);
     876             : 
     877             : /**
     878             :  * @brief A class that defines stream based implementation of SHA-256 hash
     879             :  *        It's expected that the object of this class can be safely copied.
     880             :  *        All implementations must check for std::is_trivially_copyable.
     881             :  **/
     882             : 
     883             : struct alignas(CHIP_CONFIG_SHA256_CONTEXT_ALIGN) HashSHA256OpaqueContext
     884             : {
     885             :     uint8_t mOpaque[kMAX_Hash_SHA256_Context_Size];
     886             : };
     887             : 
     888             : class Hash_SHA256_stream
     889             : {
     890             : public:
     891             :     Hash_SHA256_stream();
     892             :     ~Hash_SHA256_stream();
     893             : 
     894             :     /**
     895             :      * @brief Re-initialize digest computation to an empty context.
     896             :      *
     897             :      * @return CHIP_ERROR_INTERNAL on failure to initialize the context,
     898             :      *         CHIP_NO_ERROR otherwise.
     899             :      */
     900             :     CHIP_ERROR Begin();
     901             : 
     902             :     /**
     903             :      * @brief Add some data to the digest computation, updating internal state.
     904             :      *
     905             :      * @param[in] data The span of bytes to include in the digest update process.
     906             :      *
     907             :      * @return CHIP_ERROR_INTERNAL on failure to ingest the data, CHIP_NO_ERROR otherwise.
     908             :      */
     909             :     CHIP_ERROR AddData(const ByteSpan data);
     910             : 
     911             :     /**
     912             :      * @brief Get the intermediate padded digest for the current state of the stream.
     913             :      *
     914             :      * More data can be added before finish is called.
     915             :      *
     916             :      * @param[in,out] out_buffer Output buffer to receive the digest. `out_buffer` must
     917             :      * be at least `kSHA256_Hash_Length` bytes long. The `out_buffer` size
     918             :      * will be set to `kSHA256_Hash_Length` on success.
     919             :      *
     920             :      * @return CHIP_ERROR_INTERNAL on failure to compute the digest, CHIP_ERROR_BUFFER_TOO_SMALL
     921             :      *         if out_buffer is too small, CHIP_NO_ERROR otherwise.
     922             :      */
     923             :     CHIP_ERROR GetDigest(MutableByteSpan & out_buffer);
     924             : 
     925             :     /**
     926             :      * @brief Finalize the stream digest computation, getting the final digest.
     927             :      *
     928             :      * @param[in,out] out_buffer Output buffer to receive the digest. `out_buffer` must
     929             :      * be at least `kSHA256_Hash_Length` bytes long. The `out_buffer` size
     930             :      * will be set to `kSHA256_Hash_Length` on success.
     931             :      *
     932             :      * @return CHIP_ERROR_INTERNAL on failure to compute the digest, CHIP_ERROR_BUFFER_TOO_SMALL
     933             :      *         if out_buffer is too small, CHIP_NO_ERROR otherwise.
     934             :      */
     935             :     CHIP_ERROR Finish(MutableByteSpan & out_buffer);
     936             : 
     937             :     /**
     938             :      * @brief Clear-out internal digest data to avoid lingering the state.
     939             :      */
     940             :     void Clear();
     941             : 
     942             : private:
     943             :     HashSHA256OpaqueContext mContext;
     944             : };
     945             : 
     946             : class HKDF_sha
     947             : {
     948             : public:
     949             :     HKDF_sha()          = default;
     950        3477 :     virtual ~HKDF_sha() = default;
     951             : 
     952             :     /**
     953             :      * @brief A function that implements SHA-256 based HKDF
     954             :      *
     955             :      * This implements the CHIP_Crypto_KDF() cryptographic primitive
     956             :      * in the the specification.
     957             :      *
     958             :      *  Error values are:
     959             :      *   - CHIP_ERROR_INVALID_ARGUMENT: for any bad arguments or nullptr input on
     960             :      *     any pointer.
     961             :      *   - CHIP_ERROR_INTERNAL: for any unexpected error arising in the underlying
     962             :      *     cryptographic layers.
     963             :      *
     964             :      * @param secret The secret to use as the key to the HKDF
     965             :      * @param secret_length Length of the secret
     966             :      * @param salt Optional salt to use as input to the HKDF
     967             :      * @param salt_length Length of the salt
     968             :      * @param info Optional info to use as input to the HKDF
     969             :      * @param info_length Length of the info
     970             :      * @param out_buffer Pointer to buffer to write output into.
     971             :      * @param out_length Size of the underlying out_buffer. That length of output key material will be generated in out_buffer.
     972             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     973             :      **/
     974             : 
     975             :     virtual CHIP_ERROR HKDF_SHA256(const uint8_t * secret, size_t secret_length, const uint8_t * salt, size_t salt_length,
     976             :                                    const uint8_t * info, size_t info_length, uint8_t * out_buffer, size_t out_length);
     977             : };
     978             : 
     979             : class HMAC_sha
     980             : {
     981             : public:
     982             :     HMAC_sha()          = default;
     983          98 :     virtual ~HMAC_sha() = default;
     984             : 
     985             :     /**
     986             :      * @brief A function that implements SHA-256 based HMAC per FIPS1981.
     987             :      *
     988             :      * This implements the CHIP_Crypto_HMAC() cryptographic primitive
     989             :      * in the the specification.
     990             :      *
     991             :      * The `out_length` must be at least kSHA256_Hash_Length, and only
     992             :      * kSHA256_Hash_Length bytes are written to out_buffer.
     993             :      *
     994             :      * Error values are:
     995             :      *   - CHIP_ERROR_INVALID_ARGUMENT: for any bad arguments or nullptr input on
     996             :      *     any pointer.
     997             :      *   - CHIP_ERROR_INTERNAL: for any unexpected error arising in the underlying
     998             :      *     cryptographic layers.
     999             :      *
    1000             :      * @param key The key to use for the HMAC operation
    1001             :      * @param key_length Length of the key
    1002             :      * @param message Message over which to compute the HMAC
    1003             :      * @param message_length Length of the message over which to compute the HMAC
    1004             :      * @param out_buffer Pointer to buffer into which to write the output.
    1005             :      * @param out_length Underlying size of the `out_buffer`.
    1006             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1007             :      **/
    1008             : 
    1009             :     virtual CHIP_ERROR HMAC_SHA256(const uint8_t * key, size_t key_length, const uint8_t * message, size_t message_length,
    1010             :                                    uint8_t * out_buffer, size_t out_length);
    1011             : 
    1012             :     /**
    1013             :      * @brief A function that implements SHA-256 based HMAC per FIPS1981.
    1014             :      *
    1015             :      * This implements the CHIP_Crypto_HMAC() cryptographic primitive
    1016             :      * in the the specification.
    1017             :      *
    1018             :      * The `out_length` must be at least kSHA256_Hash_Length, and only
    1019             :      * kSHA256_Hash_Length bytes are written to out_buffer.
    1020             :      *
    1021             :      * Error values are:
    1022             :      *   - CHIP_ERROR_INVALID_ARGUMENT: for any bad arguments or nullptr input on
    1023             :      *     any pointer.
    1024             :      *   - CHIP_ERROR_INTERNAL: for any unexpected error arising in the underlying
    1025             :      *     cryptographic layers.
    1026             :      *
    1027             :      * @param key The HMAC Key handle to use for the HMAC operation
    1028             :      * @param message Message over which to compute the HMAC
    1029             :      * @param message_length Length of the message over which to compute the HMAC
    1030             :      * @param out_buffer Pointer to buffer into which to write the output.
    1031             :      * @param out_length Underlying size of the `out_buffer`.
    1032             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1033             :      **/
    1034             :     virtual CHIP_ERROR HMAC_SHA256(const Hmac128KeyHandle & key, const uint8_t * message, size_t message_length,
    1035             :                                    uint8_t * out_buffer, size_t out_length);
    1036             : };
    1037             : 
    1038             : /**
    1039             :  * @brief A cryptographically secure random number generator based on NIST SP800-90A
    1040             :  * @param out_buffer Buffer into which to write random bytes
    1041             :  * @param out_length Number of random bytes to generate
    1042             :  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1043             :  **/
    1044             : CHIP_ERROR DRBG_get_bytes(uint8_t * out_buffer, size_t out_length);
    1045             : 
    1046             : /** @brief Entropy callback function
    1047             :  * @param data Callback-specific data pointer
    1048             :  * @param output Output data to fill
    1049             :  * @param len Length of output buffer
    1050             :  * @param olen The actual amount of data that was written to output buffer
    1051             :  * @return 0 if success
    1052             :  */
    1053             : typedef int (*entropy_source)(void * data, uint8_t * output, size_t len, size_t * olen);
    1054             : 
    1055             : /** @brief A function to add entropy sources to crypto library
    1056             :  *
    1057             :  * This function can be called multiple times to add multiple entropy sources. However,
    1058             :  * once the entropy source is added, it cannot be removed. Please make sure that the
    1059             :  * entropy source is valid for the lifetime of the application. Also, make sure that the
    1060             :  * same entropy source is not added multiple times, e.g.: by calling this function
    1061             :  * in class constructor or initialization function.
    1062             :  *
    1063             :  * @param fn_source Function pointer to the entropy source
    1064             :  * @param p_source  Data that should be provided when fn_source is called
    1065             :  * @param threshold Minimum required from source before entropy is released
    1066             :  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1067             :  **/
    1068             : CHIP_ERROR add_entropy_source(entropy_source fn_source, void * p_source, size_t threshold);
    1069             : 
    1070             : class PBKDF2_sha256
    1071             : {
    1072             : public:
    1073             :     PBKDF2_sha256()          = default;
    1074           7 :     virtual ~PBKDF2_sha256() = default;
    1075             : 
    1076             :     /** @brief Function to derive key using password. SHA256 hashing algorithm is used for calculating hmac.
    1077             :      * @param password password used for key derivation
    1078             :      * @param plen length of buffer containing password
    1079             :      * @param salt salt to use as input to the KDF
    1080             :      * @param slen length of salt
    1081             :      * @param iteration_count number of iterations to run
    1082             :      * @param key_length length of output key
    1083             :      * @param output output buffer where the key will be written
    1084             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1085             :      **/
    1086             :     virtual CHIP_ERROR pbkdf2_sha256(const uint8_t * password, size_t plen, const uint8_t * salt, size_t slen,
    1087             :                                      unsigned int iteration_count, uint32_t key_length, uint8_t * output);
    1088             : };
    1089             : 
    1090             : // TODO: Extract Spake2p to a separate header and replace the forward declaration with #include SessionKeystore.h
    1091             : class SessionKeystore;
    1092             : 
    1093             : /**
    1094             :  * The below class implements the draft 01 version of the Spake2+ protocol as
    1095             :  * defined in https://www.ietf.org/id/draft-bar-cfrg-spake2plus-01.html.
    1096             :  *
    1097             :  * The following describes the protocol flows:
    1098             :  *
    1099             :  *     Commissioner                     Accessory
    1100             :  *     ------------                     ---------
    1101             :  *
    1102             :  *     Init
    1103             :  *     BeginProver
    1104             :  *     ComputeRoundOne  ------------->
    1105             :  *                                      Init
    1106             :  *                                      BeginVerifier
    1107             :  *                                  /-  ComputeRoundOne
    1108             :  *                      <-------------  ComputeRoundTwo
    1109             :  *     ComputeRoundTwo  ------------->
    1110             :  *     KeyConfirm                       KeyConfirm
    1111             :  *     GetKeys                          GetKeys
    1112             :  *
    1113             :  **/
    1114             : class Spake2p
    1115             : {
    1116             : public:
    1117             :     Spake2p(size_t fe_size, size_t point_size, size_t hash_size);
    1118         147 :     virtual ~Spake2p() = default;
    1119             : 
    1120             :     /**
    1121             :      * @brief Initialize Spake2+ with some context specific information.
    1122             :      *
    1123             :      * @param context     The context is arbitrary but should include information about the
    1124             :      *                    protocol being run, contain the transcript for negotiation, include
    1125             :      *                    the PKBDF parameters, etc.
    1126             :      * @param context_len The length of the context.
    1127             :      *
    1128             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1129             :      **/
    1130             :     virtual CHIP_ERROR Init(const uint8_t * context, size_t context_len);
    1131             : 
    1132             :     /**
    1133             :      * @brief Free Spake2+ underlying objects.
    1134             :      **/
    1135             :     virtual void Clear() = 0;
    1136             : 
    1137             :     /**
    1138             :      * @brief Start the Spake2+ process as a verifier (i.e. an accessory being provisioned).
    1139             :      *
    1140             :      * @param my_identity       The verifier identity. May be NULL if identities are not established.
    1141             :      * @param my_identity_len   The verifier identity length.
    1142             :      * @param peer_identity     The peer identity. May be NULL if identities are not established.
    1143             :      * @param peer_identity_len The peer identity length.
    1144             :      * @param w0in              The input w0 (a parameter baked into the device or computed with ComputeW0).
    1145             :      * @param w0in_len          The input w0 length.
    1146             :      * @param Lin               The input L (a parameter baked into the device or computed with ComputeL).
    1147             :      * @param Lin_len           The input L length.
    1148             :      *
    1149             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1150             :      **/
    1151             :     virtual CHIP_ERROR BeginVerifier(const uint8_t * my_identity, size_t my_identity_len, const uint8_t * peer_identity,
    1152             :                                      size_t peer_identity_len, const uint8_t * w0in, size_t w0in_len, const uint8_t * Lin,
    1153             :                                      size_t Lin_len);
    1154             : 
    1155             :     /**
    1156             :      * @brief Start the Spake2+ process as a prover (i.e. a commissioner).
    1157             :      *
    1158             :      * @param my_identity       The prover identity. May be NULL if identities are not established.
    1159             :      * @param my_identity_len   The prover identity length.
    1160             :      * @param peer_identity     The peer identity. May be NULL if identities are not established.
    1161             :      * @param peer_identity_len The peer identity length.
    1162             :      * @param w0in              The input w0 (an output from the PBKDF).
    1163             :      * @param w0in_len          The input w0 length.
    1164             :      * @param w1in              The input w1 (an output from the PBKDF).
    1165             :      * @param w1in_len          The input w1 length.
    1166             :      *
    1167             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1168             :      **/
    1169             :     virtual CHIP_ERROR BeginProver(const uint8_t * my_identity, size_t my_identity_len, const uint8_t * peer_identity,
    1170             :                                    size_t peer_identity_len, const uint8_t * w0in, size_t w0in_len, const uint8_t * w1in,
    1171             :                                    size_t w1in_len);
    1172             : 
    1173             :     /**
    1174             :      * @brief Compute the first round of the protocol.
    1175             :      *
    1176             :      * @param pab      X value from commissioner.
    1177             :      * @param pab_len  X length.
    1178             :      * @param out     The output first round Spake2+ contribution.
    1179             :      * @param out_len The output first round Spake2+ contribution length.
    1180             :      *
    1181             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1182             :      **/
    1183             :     virtual CHIP_ERROR ComputeRoundOne(const uint8_t * pab, size_t pab_len, uint8_t * out, size_t * out_len);
    1184             : 
    1185             :     /**
    1186             :      * @brief Compute the second round of the protocol.
    1187             :      *
    1188             :      * @param in      The peer first round Spake2+ contribution.
    1189             :      * @param in_len  The peer first round Spake2+ contribution length.
    1190             :      * @param out     The output second round Spake2+ contribution.
    1191             :      * @param out_len The output second round Spake2+ contribution length.
    1192             :      *
    1193             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1194             :      **/
    1195             :     virtual CHIP_ERROR ComputeRoundTwo(const uint8_t * in, size_t in_len, uint8_t * out, size_t * out_len);
    1196             : 
    1197             :     /**
    1198             :      * @brief Confirm that each party computed the same keys.
    1199             :      *
    1200             :      * @param in     The peer second round Spake2+ contribution.
    1201             :      * @param in_len The peer second round Spake2+ contribution length.
    1202             :      *
    1203             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1204             :      **/
    1205             :     virtual CHIP_ERROR KeyConfirm(const uint8_t * in, size_t in_len);
    1206             : 
    1207             :     /**
    1208             :      * @brief Return the shared HKDF key.
    1209             :      *
    1210             :      * Returns the shared key established during the Spake2+ process, which can be used
    1211             :      * to derive application-specific keys using HKDF.
    1212             :      *
    1213             :      * @param keystore The session keystore for managing the HKDF key lifetime.
    1214             :      * @param key The output HKDF key.
    1215             :      *
    1216             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1217             :      **/
    1218             :     CHIP_ERROR GetKeys(SessionKeystore & keystore, HkdfKeyHandle & key) const;
    1219             : 
    1220             :     CHIP_ERROR InternalHash(const uint8_t * in, size_t in_len);
    1221             :     CHIP_ERROR WriteMN();
    1222             :     CHIP_ERROR GenerateKeys();
    1223             : 
    1224             :     /**
    1225             :      * @brief Load a field element.
    1226             :      *
    1227             :      *  @param in     The input big endian field element.
    1228             :      *  @param in_len The size of the input buffer in bytes.
    1229             :      *  @param fe     A pointer to an initialized implementation dependant field element.
    1230             :      *
    1231             :      *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1232             :      **/
    1233             :     virtual CHIP_ERROR FELoad(const uint8_t * in, size_t in_len, void * fe) = 0;
    1234             : 
    1235             :     /**
    1236             :      * @brief Write a field element in big-endian format.
    1237             :      *
    1238             :      *  @param fe      The field element to write.
    1239             :      *  @param out     The output buffer.
    1240             :      *  @param out_len The length of the output buffer.
    1241             :      *
    1242             :      *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1243             :      **/
    1244             :     virtual CHIP_ERROR FEWrite(const void * fe, uint8_t * out, size_t out_len) = 0;
    1245             : 
    1246             :     /**
    1247             :      * @brief Generate a field element.
    1248             :      *
    1249             :      *  @param fe  A pointer to an initialized implementation dependant field element.
    1250             :      *
    1251             :      *  @note The implementation must generate a random element from [0, q) where q is the curve order.
    1252             :      *
    1253             :      *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1254             :      **/
    1255             :     virtual CHIP_ERROR FEGenerate(void * fe) = 0;
    1256             : 
    1257             :     /**
    1258             :      * @brief Multiply two field elements, fer = fe1 * fe2.
    1259             :      *
    1260             :      *  @param fer   A pointer to an initialized implementation dependant field element.
    1261             :      *  @param fe1  A pointer to an initialized implementation dependant field element.
    1262             :      *  @param fe2  A pointer to an initialized implementation dependant field element.
    1263             :      *
    1264             :      *  @note The result must be a field element (i.e. reduced by the curve order).
    1265             :      *
    1266             :      *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1267             :      **/
    1268             :     virtual CHIP_ERROR FEMul(void * fer, const void * fe1, const void * fe2) = 0;
    1269             : 
    1270             :     /**
    1271             :      * @brief Load a point from 0x04 || X || Y format
    1272             :      *
    1273             :      * @param in     Input buffer
    1274             :      * @param in_len Input buffer length
    1275             :      * @param R      A pointer to an initialized implementation dependant point.
    1276             :      *
    1277             :      *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1278             :      **/
    1279             :     virtual CHIP_ERROR PointLoad(const uint8_t * in, size_t in_len, void * R) = 0;
    1280             : 
    1281             :     /**
    1282             :      * @brief Write a point in 0x04 || X || Y format
    1283             :      *
    1284             :      * @param R       A pointer to an initialized implementation dependant point.
    1285             :      * @param out     Output buffer
    1286             :      * @param out_len Length of the output buffer
    1287             :      *
    1288             :      *  @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1289             :      **/
    1290             :     virtual CHIP_ERROR PointWrite(const void * R, uint8_t * out, size_t out_len) = 0;
    1291             : 
    1292             :     /**
    1293             :      * @brief Scalar multiplication, R = fe1 * P1.
    1294             :      *
    1295             :      * @param R   Resultant point
    1296             :      * @param P1  Input point
    1297             :      * @param fe1  Input field element.
    1298             :      *
    1299             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1300             :      **/
    1301             :     virtual CHIP_ERROR PointMul(void * R, const void * P1, const void * fe1) = 0;
    1302             : 
    1303             :     /**
    1304             :      * @brief Scalar multiplication with addition, R = fe1 * P1 + fe2 * P2.
    1305             :      *
    1306             :      * @param R   Resultant point
    1307             :      * @param P1  Input point
    1308             :      * @param fe1  Input field element.
    1309             :      * @param P2  Input point
    1310             :      * @param fe2  Input field element.
    1311             :      *
    1312             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1313             :      **/
    1314             :     virtual CHIP_ERROR PointAddMul(void * R, const void * P1, const void * fe1, const void * P2, const void * fe2) = 0;
    1315             : 
    1316             :     /**
    1317             :      * @brief Point inversion.
    1318             :      *
    1319             :      * @param R   Input/Output point to point_invert
    1320             :      *
    1321             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1322             :      **/
    1323             :     virtual CHIP_ERROR PointInvert(void * R) = 0;
    1324             : 
    1325             :     /**
    1326             :      * @brief Multiply a point by the curve cofactor.
    1327             :      *
    1328             :      * @param R   Input/Output point to point_invert
    1329             :      *
    1330             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1331             :      **/
    1332             :     virtual CHIP_ERROR PointCofactorMul(void * R) = 0;
    1333             : 
    1334             :     /*
    1335             :      *   @synopsis Check if a point is on the curve.
    1336             :      *
    1337             :      *   @param R   Input point to check.
    1338             :      *
    1339             :      *   @return CHIP_NO_ERROR if the point is valid, CHIP_ERROR otherwise.
    1340             :      */
    1341             :     virtual CHIP_ERROR PointIsValid(void * R) = 0;
    1342             : 
    1343             :     /*
    1344             :      *   @synopsis Compute w0sin mod p
    1345             :      *
    1346             :      *   @param w0out       Output field element (modulo p)
    1347             :      *   @param w0_len      Output field element length
    1348             :      *   @param w1sin       Input field element
    1349             :      *   @param w1sin_len   Input field element length
    1350             :      *
    1351             :      *   @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1352             :      **/
    1353             :     virtual CHIP_ERROR ComputeW0(uint8_t * w0out, size_t * w0_len, const uint8_t * w0sin, size_t w0sin_len) = 0;
    1354             : 
    1355             :     /*
    1356             :      *   @synopsis Compute w1in*G
    1357             :      *
    1358             :      *   @param Lout        Output point in 0x04 || X || Y format.
    1359             :      *   @param L_len       Output point length
    1360             :      *   @param w1in        Input field element
    1361             :      *   @param w1in_len    Input field element size
    1362             :      *
    1363             :      *   @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1364             :      **/
    1365             :     virtual CHIP_ERROR ComputeL(uint8_t * Lout, size_t * L_len, const uint8_t * w1in, size_t w1in_len) = 0;
    1366             : 
    1367             :     void * M;
    1368             :     void * N;
    1369             :     const void * G;
    1370             :     void * X;
    1371             :     void * Y;
    1372             :     void * L;
    1373             :     void * Z;
    1374             :     void * V;
    1375             :     void * w0;
    1376             :     void * w1;
    1377             :     void * xy;
    1378             :     void * order;
    1379             :     void * tempbn;
    1380             : 
    1381             : protected:
    1382             :     /**
    1383             :      * @brief Initialize underlying implementation curve, points, field elements, etc.
    1384             :      *
    1385             :      * @details The implementation needs to:
    1386             :      *     1. Initialize each of the points below and set the relevant pointers on the class:
    1387             :      *        a. M
    1388             :      *        b. N
    1389             :      *        c. G
    1390             :      *        d. X
    1391             :      *        e. Y
    1392             :      *        f. L
    1393             :      *        g. Z
    1394             :      *        h. V
    1395             :      *
    1396             :      *        As an example:
    1397             :      *           this.M = implementation_alloc_point();
    1398             :      *     2. Initialize each of the field elements below and set the relevant pointers on the class:
    1399             :      *        a. w0
    1400             :      *        b. w1
    1401             :      *        c. xy
    1402             :      *        d. tempbn
    1403             :      *     3. The hashing context should be initialized
    1404             :      *
    1405             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1406             :      **/
    1407             :     virtual CHIP_ERROR InitImpl() = 0;
    1408             : 
    1409             :     /**
    1410             :      * @brief Hash in_len bytes of in into the internal hash context.
    1411             :      *
    1412             :      * @param in     The input buffer.
    1413             :      * @param in_len Size of the input buffer in bytes.
    1414             :      *
    1415             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1416             :      **/
    1417             :     virtual CHIP_ERROR Hash(const uint8_t * in, size_t in_len) = 0;
    1418             : 
    1419             :     /**
    1420             :      * @brief Return the hash.
    1421             :      *
    1422             :      * @param out_span Output buffer. The size available must be >= the hash size. It gets resized
    1423             :      *                 to hash size on success.
    1424             :      *
    1425             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1426             :      **/
    1427             :     virtual CHIP_ERROR HashFinalize(MutableByteSpan & out_span) = 0;
    1428             : 
    1429             :     /**
    1430             :      * @brief Generate a message authentication code.
    1431             :      *
    1432             :      * @param key      The MAC key buffer.
    1433             :      * @param key_len  The size of the MAC key in bytes.
    1434             :      * @param in       The input buffer.
    1435             :      * @param in_len   The size of the input data to MAC in bytes.
    1436             :      * @param out_span The output MAC buffer span. Size must be >= the hash_size. Output size is updated to fit on success.
    1437             :      *
    1438             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
    1439             :      **/
    1440             :     virtual CHIP_ERROR Mac(const uint8_t * key, size_t key_len, const uint8_t * in, size_t in_len, MutableByteSpan & out_span) = 0;
    1441             : 
    1442             :     /**
    1443             :      * @brief Verify a message authentication code.
    1444             :      *
    1445             :      *  @param key     The MAC key buffer.
    1446             :      *  @param key_len The size of the MAC key in bytes.
    1447             :      *  @param mac     The input MAC buffer.
    1448             :      *  @param mac_len The size of the MAC in bytes.
    1449             :      *  @param in      The input buffer to verify.
    1450             :      *  @param in_len  The size of the input data to verify in bytes.
    1451             :      *
    1452             :      *  @return Returns a CHIP_ERROR when the MAC doesn't validate, CHIP_NO_ERROR otherwise.
    1453             :      **/
    1454             :     virtual CHIP_ERROR MacVerify(const uint8_t * key, size_t key_len, const uint8_t * mac, size_t mac_len, const uint8_t * in,
    1455             :                                  size_t in_len) = 0;
    1456             : 
    1457             :     /**
    1458             :      * @brief Derive an key of length out_len.
    1459             :      *
    1460             :      * @param ikm      The input key material buffer.
    1461             :      * @param ikm_len  The input key material length.
    1462             :      * @param salt     The optional salt. This may be NULL.
    1463             :      * @param salt_len The size of the salt in bytes.
    1464             :      * @param info     The info.
    1465             :      * @param info_len The size of the info in bytes.
    1466             :      * @param out      The output key
    1467             :      * @param out_len  The output key length
    1468             :      *
    1469             :      * @return Returns a CHIP_ERROR when the MAC doesn't validate, CHIP_NO_ERROR otherwise.
    1470             :      **/
    1471             :     virtual CHIP_ERROR KDF(const uint8_t * ikm, size_t ikm_len, const uint8_t * salt, size_t salt_len, const uint8_t * info,
    1472             :                            size_t info_len, uint8_t * out, size_t out_len) = 0;
    1473             : 
    1474             :     CHIP_SPAKE2P_ROLE role;
    1475             :     CHIP_SPAKE2P_STATE state = CHIP_SPAKE2P_STATE::PREINIT;
    1476             :     size_t fe_size;
    1477             :     size_t hash_size;
    1478             :     size_t point_size;
    1479             :     uint8_t Kcab[kMAX_Hash_Length];
    1480             :     uint8_t Kae[kMAX_Hash_Length];
    1481             :     uint8_t * Kca;
    1482             :     uint8_t * Kcb;
    1483             :     uint8_t * Ka;
    1484             :     uint8_t * Ke;
    1485             : };
    1486             : 
    1487             : struct alignas(size_t) Spake2pOpaqueContext
    1488             : {
    1489             :     uint8_t mOpaque[kMAX_Spake2p_Context_Size];
    1490             : };
    1491             : 
    1492             : class Spake2p_P256_SHA256_HKDF_HMAC : public Spake2p
    1493             : {
    1494             : public:
    1495           1 :     Spake2p_P256_SHA256_HKDF_HMAC() : Spake2p(kP256_FE_Length, kP256_Point_Length, kSHA256_Hash_Length)
    1496             :     {
    1497           1 :         memset(&mSpake2pContext, 0, sizeof(mSpake2pContext));
    1498           1 :     }
    1499             : 
    1500         147 :     ~Spake2p_P256_SHA256_HKDF_HMAC() override { Spake2p_P256_SHA256_HKDF_HMAC::Clear(); }
    1501             : 
    1502             :     void Clear() override;
    1503             :     CHIP_ERROR Mac(const uint8_t * key, size_t key_len, const uint8_t * in, size_t in_len, MutableByteSpan & out_span) override;
    1504             :     CHIP_ERROR MacVerify(const uint8_t * key, size_t key_len, const uint8_t * mac, size_t mac_len, const uint8_t * in,
    1505             :                          size_t in_len) override;
    1506             :     CHIP_ERROR FELoad(const uint8_t * in, size_t in_len, void * fe) override;
    1507             :     CHIP_ERROR FEWrite(const void * fe, uint8_t * out, size_t out_len) override;
    1508             :     CHIP_ERROR FEGenerate(void * fe) override;
    1509             :     CHIP_ERROR FEMul(void * fer, const void * fe1, const void * fe2) override;
    1510             : 
    1511             :     CHIP_ERROR PointLoad(const uint8_t * in, size_t in_len, void * R) override;
    1512             :     CHIP_ERROR PointWrite(const void * R, uint8_t * out, size_t out_len) override;
    1513             :     CHIP_ERROR PointMul(void * R, const void * P1, const void * fe1) override;
    1514             :     CHIP_ERROR PointAddMul(void * R, const void * P1, const void * fe1, const void * P2, const void * fe2) override;
    1515             :     CHIP_ERROR PointInvert(void * R) override;
    1516             :     CHIP_ERROR PointCofactorMul(void * R) override;
    1517             :     CHIP_ERROR PointIsValid(void * R) override;
    1518             : 
    1519             :     CHIP_ERROR ComputeW0(uint8_t * w0out, size_t * w0_len, const uint8_t * w0sin, size_t w0sin_len) override;
    1520             :     CHIP_ERROR ComputeL(uint8_t * Lout, size_t * L_len, const uint8_t * w1in, size_t w1in_len) override;
    1521             : 
    1522             : protected:
    1523             :     CHIP_ERROR InitImpl() override;
    1524             :     CHIP_ERROR Hash(const uint8_t * in, size_t in_len) override;
    1525             :     CHIP_ERROR HashFinalize(MutableByteSpan & out_span) override;
    1526             :     CHIP_ERROR KDF(const uint8_t * secret, size_t secret_length, const uint8_t * salt, size_t salt_length, const uint8_t * info,
    1527             :                    size_t info_length, uint8_t * out, size_t out_length) override;
    1528             : 
    1529             : private:
    1530             :     CHIP_ERROR InitInternal();
    1531             :     Hash_SHA256_stream sha256_hash_ctx;
    1532             : 
    1533             :     Spake2pOpaqueContext mSpake2pContext;
    1534             : };
    1535             : 
    1536             : /**
    1537             :  * @brief Class used for verifying PASE secure sessions.
    1538             :  **/
    1539             : class Spake2pVerifier
    1540             : {
    1541             : public:
    1542             :     uint8_t mW0[kP256_FE_Length];
    1543             :     uint8_t mL[kP256_Point_Length];
    1544             : 
    1545             :     CHIP_ERROR Serialize(MutableByteSpan & outSerialized) const;
    1546             :     CHIP_ERROR Deserialize(const ByteSpan & inSerialized);
    1547             : 
    1548             :     /**
    1549             :      * @brief Generate the Spake2+ verifier.
    1550             :      *
    1551             :      * @param pbkdf2IterCount Iteration count for PBKDF2 function
    1552             :      * @param salt            Salt to be used for Spake2+ operation
    1553             :      * @param setupPin        Provided setup PIN (passcode)
    1554             :      *
    1555             :      * @return CHIP_ERROR     The result of Spake2+ verifier generation
    1556             :      */
    1557             :     CHIP_ERROR Generate(uint32_t pbkdf2IterCount, const ByteSpan & salt, uint32_t setupPin);
    1558             : 
    1559             :     /**
    1560             :      * @brief Compute the initiator values (w0, w1) used for PAKE input.
    1561             :      *
    1562             :      * @param pbkdf2IterCount Iteration count for PBKDF2 function
    1563             :      * @param salt            Salt to be used for Spake2+ operation
    1564             :      * @param setupPin        Provided setup PIN (passcode)
    1565             :      * @param ws              The output pair (w0, w1) stored sequentially
    1566             :      * @param ws_len          The output length
    1567             :      *
    1568             :      * @return CHIP_ERROR     The result from running PBKDF2
    1569             :      */
    1570             :     static CHIP_ERROR ComputeWS(uint32_t pbkdf2IterCount, const ByteSpan & salt, uint32_t setupPin, uint8_t * ws, uint32_t ws_len);
    1571             : };
    1572             : 
    1573             : /**
    1574             :  * @brief Serialized format of the Spake2+ Verifier components.
    1575             :  *
    1576             :  *  This is used when the Verifier should be presented in a serialized form.
    1577             :  *  For example, when it is generated using PBKDF function, when stored in the
    1578             :  *  memory or when sent over the wire.
    1579             :  *  The serialized format is concatentation of 'W0' and 'L' verifier components:
    1580             :  *      { Spake2pVerifier.mW0[kP256_FE_Length], Spake2pVerifier.mL[kP256_Point_Length] }
    1581             :  **/
    1582             : typedef uint8_t Spake2pVerifierSerialized[kSpake2p_VerifierSerialized_Length];
    1583             : 
    1584             : /**
    1585             :  * @brief Compute the compressed fabric identifier used for operational discovery service
    1586             :  *        records from a Node's root public key and Fabric ID. On success, out_compressed_fabric_id
    1587             :  *        will have a size of exactly kCompressedFabricIdentifierSize.
    1588             :  *
    1589             :  * Errors are:
    1590             :  *   - CHIP_ERROR_INVALID_ARGUMENT if root_public_key is invalid
    1591             :  *   - CHIP_ERROR_BUFFER_TOO_SMALL if out_compressed_fabric_id is too small for serialization
    1592             :  *   - CHIP_ERROR_INTERNAL on any unexpected crypto or data conversion errors.
    1593             :  *
    1594             :  * @param[in] root_public_key The root public key associated with the node's fabric
    1595             :  * @param[in] fabric_id The fabric ID associated with the node's fabric
    1596             :  * @param[out] out_compressed_fabric_id Span where output will be written. Its size must be >= kCompressedFabricIdentifierSize.
    1597             :  * @returns a CHIP_ERROR (see above) on failure or CHIP_NO_ERROR otherwise.
    1598             :  */
    1599             : CHIP_ERROR GenerateCompressedFabricId(const Crypto::P256PublicKey & root_public_key, uint64_t fabric_id,
    1600             :                                       MutableByteSpan & out_compressed_fabric_id);
    1601             : 
    1602             : /**
    1603             :  * @brief Compute the compressed fabric identifier used for operational discovery service
    1604             :  *        records from a Node's root public key and Fabric ID.  This is a conveniance
    1605             :  *        overload that writes to a uint64_t (CompressedFabricId) type.
    1606             :  *
    1607             :  * @param[in] rootPublicKey The root public key associated with the node's fabric
    1608             :  * @param[in] fabricId The fabric ID associated with the node's fabric
    1609             :  * @param[out] compressedFabricId output location for compressed fabric ID
    1610             :  * @returns a CHIP_ERROR on failure or CHIP_NO_ERROR otherwise.
    1611             :  */
    1612             : CHIP_ERROR GenerateCompressedFabricId(const Crypto::P256PublicKey & rootPublicKey, uint64_t fabricId,
    1613             :                                       uint64_t & compressedFabricId);
    1614             : 
    1615             : enum class CertificateChainValidationResult
    1616             : {
    1617             :     kSuccess = 0,
    1618             : 
    1619             :     kRootFormatInvalid   = 100,
    1620             :     kRootArgumentInvalid = 101,
    1621             : 
    1622             :     kICAFormatInvalid   = 200,
    1623             :     kICAArgumentInvalid = 201,
    1624             : 
    1625             :     kLeafFormatInvalid   = 300,
    1626             :     kLeafArgumentInvalid = 301,
    1627             : 
    1628             :     kChainInvalid = 400,
    1629             : 
    1630             :     kNoMemory = 500,
    1631             : 
    1632             :     kInternalFrameworkError = 600,
    1633             : };
    1634             : 
    1635             : CHIP_ERROR ValidateCertificateChain(const uint8_t * rootCertificate, size_t rootCertificateLen, const uint8_t * caCertificate,
    1636             :                                     size_t caCertificateLen, const uint8_t * leafCertificate, size_t leafCertificateLen,
    1637             :                                     CertificateChainValidationResult & result);
    1638             : 
    1639             : enum class AttestationCertType
    1640             : {
    1641             :     kPAA = 0,
    1642             :     kPAI = 1,
    1643             :     kDAC = 2,
    1644             : };
    1645             : 
    1646             : CHIP_ERROR VerifyAttestationCertificateFormat(const ByteSpan & cert, AttestationCertType certType);
    1647             : 
    1648             : /**
    1649             :  * @brief Validate notBefore timestamp of a certificate (candidateCertificate) against validity period of the
    1650             :  *        issuer certificate (issuerCertificate).
    1651             :  *
    1652             :  * Errors are:
    1653             :  *   - CHIP_ERROR_CERT_EXPIRED if the candidateCertificate timestamp does not satisfy the issuerCertificate's timestamp.
    1654             :  *   - CHIP_ERROR_INVALID_ARGUMENT when passing an invalid argument.
    1655             :  *   - CHIP_ERROR_INTERNAL on any unexpected crypto or data conversion errors.
    1656             :  *
    1657             :  *  @param candidateCertificate     A DER Certificate ByteSpan those notBefore timestamp to be evaluated.
    1658             :  *  @param issuerCertificate        A DER Certificate ByteSpan used to evaluate validity timestamp of the candidateCertificate.
    1659             :  *
    1660             :  *  @returns a CHIP_ERROR (see above) on failure or CHIP_NO_ERROR otherwise.
    1661             :  **/
    1662             : CHIP_ERROR IsCertificateValidAtIssuance(const ByteSpan & candidateCertificate, const ByteSpan & issuerCertificate);
    1663             : 
    1664             : /**
    1665             :  * @brief Validate a certificate's validity date against current time.
    1666             :  *
    1667             :  * Errors are:
    1668             :  *   - CHIP_ERROR_CERT_EXPIRED if the certificate has expired.
    1669             :  *   - CHIP_ERROR_INVALID_ARGUMENT when passing an invalid argument.
    1670             :  *   - CHIP_ERROR_INTERNAL on any unexpected crypto or data conversion errors.
    1671             :  *
    1672             :  *  @param certificate A DER Certificate ByteSpan used as the validity reference to be checked against current time.
    1673             :  *
    1674             :  *  @returns a CHIP_ERROR (see above) on failure or CHIP_NO_ERROR otherwise.
    1675             :  **/
    1676             : CHIP_ERROR IsCertificateValidAtCurrentTime(const ByteSpan & certificate);
    1677             : 
    1678             : CHIP_ERROR ExtractPubkeyFromX509Cert(const ByteSpan & certificate, Crypto::P256PublicKey & pubkey);
    1679             : 
    1680             : /**
    1681             :  * @brief Extracts the Subject Key Identifier from an X509 Certificate.
    1682             :  **/
    1683             : CHIP_ERROR ExtractSKIDFromX509Cert(const ByteSpan & certificate, MutableByteSpan & skid);
    1684             : 
    1685             : /**
    1686             :  * @brief Extracts the Authority Key Identifier from an X509 Certificate.
    1687             :  **/
    1688             : CHIP_ERROR ExtractAKIDFromX509Cert(const ByteSpan & certificate, MutableByteSpan & akid);
    1689             : 
    1690             : /**
    1691             :  * @brief Extracts the CRL Distribution Point (CDP) extension from an X509 ASN.1 Encoded Certificate.
    1692             :  *        The returned value only covers the URI of the CDP. Only a single URI distribution point
    1693             :  *        GeneralName is supported, and only those that start with "http://" and "https://".
    1694             :  *
    1695             :  * @returns CHIP_ERROR_NOT_FOUND if not found or wrong format.
    1696             :  *          CHIP_NO_ERROR otherwise.
    1697             :  **/
    1698             : CHIP_ERROR ExtractCRLDistributionPointURIFromX509Cert(const ByteSpan & certificate, MutableCharSpan & cdpurl);
    1699             : 
    1700             : /**
    1701             :  * @brief Extracts the CRL Distribution Point (CDP) extension's cRLIssuer Name from an X509 ASN.1 Encoded Certificate.
    1702             :  *        The value is copied into buffer in a raw ASN.1 X.509 format. This format should be directly comparable
    1703             :  *        with the result of ExtractSubjectFromX509Cert().
    1704             :  *
    1705             :  * @returns CHIP_ERROR_NOT_FOUND if not found or wrong format.
    1706             :  *          CHIP_NO_ERROR otherwise.
    1707             :  **/
    1708             : CHIP_ERROR ExtractCDPExtensionCRLIssuerFromX509Cert(const ByteSpan & certificate, MutableByteSpan & crlIssuer);
    1709             : 
    1710             : /**
    1711             :  * @brief Extracts Serial Number from X509 Certificate.
    1712             :  **/
    1713             : CHIP_ERROR ExtractSerialNumberFromX509Cert(const ByteSpan & certificate, MutableByteSpan & serialNumber);
    1714             : 
    1715             : /**
    1716             :  * @brief Extracts Subject Distinguished Name from X509 Certificate. The value is copied into buffer in a raw ASN.1 X.509 format.
    1717             :  **/
    1718             : CHIP_ERROR ExtractSubjectFromX509Cert(const ByteSpan & certificate, MutableByteSpan & subject);
    1719             : 
    1720             : /**
    1721             :  * @brief Extracts Issuer Distinguished Name from X509 Certificate. The value is copied into buffer in a raw ASN.1 X.509 format.
    1722             :  **/
    1723             : CHIP_ERROR ExtractIssuerFromX509Cert(const ByteSpan & certificate, MutableByteSpan & issuer);
    1724             : 
    1725             : /**
    1726             :  * @brief Checks for resigned version of the certificate in the list and returns it.
    1727             :  *
    1728             :  * The following conditions SHOULD be satisfied for the certificate to qualify as
    1729             :  * a resigned version of a reference certificate:
    1730             :  *   - SKID of the candidate and the reference certificate should match.
    1731             :  *   - SubjectDN of the candidate and the reference certificate should match.
    1732             :  *
    1733             :  * If no resigned version is found then reference certificate itself is returned.
    1734             :  *
    1735             :  *  @param referenceCertificate       A DER certificate.
    1736             :  *  @param candidateCertificates      A pointer to the list of DER Certificates, which should be searched
    1737             :  *                                    for the resigned version of `referenceCertificate`.
    1738             :  *  @param candidateCertificatesCount Number of certificates in the `candidateCertificates` list.
    1739             :  *  @param outCertificate             A reference to the certificate or it's resigned version if found.
    1740             :  *                                    Note that it points to either `referenceCertificate` or one of
    1741             :  *                                    `candidateCertificates`, but it doesn't copy data.
    1742             :  *
    1743             :  *  @returns error if there is certificate parsing/format issue or CHIP_NO_ERROR otherwise.
    1744             :  **/
    1745             : CHIP_ERROR ReplaceCertIfResignedCertFound(const ByteSpan & referenceCertificate, const ByteSpan * candidateCertificates,
    1746             :                                           size_t candidateCertificatesCount, ByteSpan & outCertificate);
    1747             : 
    1748             : /**
    1749             :  * Defines DN attribute types that can include endocing of VID/PID parameters.
    1750             :  */
    1751             : enum class DNAttrType
    1752             : {
    1753             :     kUnspecified = 0,
    1754             :     kCommonName  = 1,
    1755             :     kMatterVID   = 2,
    1756             :     kMatterPID   = 3,
    1757             : };
    1758             : 
    1759             : /**
    1760             :  *  @struct AttestationCertVidPid
    1761             :  *
    1762             :  *  @brief
    1763             :  *    A data structure representing Attestation Certificate VID and PID attributes.
    1764             :  */
    1765             : struct AttestationCertVidPid
    1766             : {
    1767             :     Optional<VendorId> mVendorId;
    1768             :     Optional<uint16_t> mProductId;
    1769             : 
    1770         659 :     bool Initialized() const { return (mVendorId.HasValue() || mProductId.HasValue()); }
    1771             : };
    1772             : 
    1773             : /**
    1774             :  * @brief Extracts VID and PID attributes from the DN Attribute string.
    1775             :  *        If attribute is not present the corresponding output value stays uninitialized.
    1776             :  *
    1777             :  * @return CHIP_ERROR_INVALID_ARGUMENT if wrong input is provided.
    1778             :  *         CHIP_ERROR_WRONG_CERT_DN if encoding of kMatterVID and kMatterPID attributes is wrong.
    1779             :  *         CHIP_NO_ERROR otherwise.
    1780             :  **/
    1781             : CHIP_ERROR ExtractVIDPIDFromAttributeString(DNAttrType attrType, const ByteSpan & attr,
    1782             :                                             AttestationCertVidPid & vidpidFromMatterAttr, AttestationCertVidPid & vidpidFromCNAttr);
    1783             : 
    1784             : /**
    1785             :  * @brief Extracts VID and PID attributes from the Subject DN of an X509 Certificate.
    1786             :  *        If attribute is not present the corresponding output value stays uninitialized.
    1787             :  **/
    1788             : CHIP_ERROR ExtractVIDPIDFromX509Cert(const ByteSpan & x509Cert, AttestationCertVidPid & vidpid);
    1789             : 
    1790             : /**
    1791             :  * @brief The set of credentials needed to operate group message security with symmetric keys.
    1792             :  */
    1793             : typedef struct GroupOperationalCredentials
    1794             : {
    1795             :     /// Validity start time in microseconds since 2000-01-01T00:00:00 UTC ("the Epoch")
    1796             :     uint64_t start_time;
    1797             :     /// Session Id
    1798             :     uint16_t hash;
    1799             :     /// Operational group key
    1800             :     uint8_t encryption_key[Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES];
    1801             :     /// Privacy key
    1802             :     uint8_t privacy_key[Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES];
    1803             : } GroupOperationalCredentials;
    1804             : 
    1805             : /**
    1806             :  * @brief Opaque context used to protect a symmetric key. The key operations must
    1807             :  *        be performed without exposing the protected key value.
    1808             :  */
    1809             : class SymmetricKeyContext
    1810             : {
    1811             : public:
    1812             :     /**
    1813             :      * @brief Returns the symmetric key hash
    1814             :      *
    1815             :      * TODO: Replace GetKeyHash() with DeriveGroupSessionId(SymmetricKeyContext &, uint16_t & session_id)
    1816             :      *
    1817             :      * @return Group Key Hash
    1818             :      */
    1819             :     virtual uint16_t GetKeyHash() = 0;
    1820             : 
    1821           9 :     virtual ~SymmetricKeyContext() = default;
    1822             :     /**
    1823             :      * @brief Perform the message encryption as described in 4.7.2. (Security Processing of Outgoing Messages)
    1824             :      * @param[in] plaintext     Outgoing message payload.
    1825             :      * @param[in] aad           Additional data (message header contents)
    1826             :      * @param[in] nonce         Nonce (Security Flags | Message Counter | Source Node ID)
    1827             :      * @param[out] mic          Outgoing Message Integrity Check
    1828             :      * @param[out] ciphertext   Outgoing encrypted payload. Must be at least as big as plaintext. The same buffer may be used both
    1829             :      * for ciphertext, and plaintext.
    1830             :      * @return CHIP_ERROR
    1831             :      */
    1832             :     virtual CHIP_ERROR MessageEncrypt(const ByteSpan & plaintext, const ByteSpan & aad, const ByteSpan & nonce,
    1833             :                                       MutableByteSpan & mic, MutableByteSpan & ciphertext) const = 0;
    1834             :     /**
    1835             :      * @brief Perform the message decryption as described in 4.7.3.(Security Processing of Incoming Messages)
    1836             :      * @param[in] ciphertext    Incoming encrypted payload
    1837             :      * @param[in] aad           Additional data (message header contents)
    1838             :      * @param[in] nonce         Nonce (Security Flags | Message Counter | Source Node ID)
    1839             :      * @param[in] mic           Incoming Message Integrity Check
    1840             :      * @param[out] plaintext     Incoming message payload. Must be at least as big as ciphertext. The same buffer may be used both
    1841             :      * for plaintext, and ciphertext.
    1842             :      * @return CHIP_ERROR
    1843             :      */
    1844             :     virtual CHIP_ERROR MessageDecrypt(const ByteSpan & ciphertext, const ByteSpan & aad, const ByteSpan & nonce,
    1845             :                                       const ByteSpan & mic, MutableByteSpan & plaintext) const = 0;
    1846             : 
    1847             :     /**
    1848             :      * @brief Perform privacy encoding as described in 4.8.2. (Privacy Processing of Outgoing Messages)
    1849             :      * @param[in] input         Message header to privacy encrypt
    1850             :      * @param[in] nonce         Privacy Nonce = session_id | mic
    1851             :      * @param[out] output       Message header obfuscated
    1852             :      * @return CHIP_ERROR
    1853             :      */
    1854             :     virtual CHIP_ERROR PrivacyEncrypt(const ByteSpan & input, const ByteSpan & nonce, MutableByteSpan & output) const = 0;
    1855             : 
    1856             :     /**
    1857             :      * @brief Perform privacy decoding as described in 4.8.3. (Privacy Processing of Incoming Messages)
    1858             :      * @param[in] input         Message header to privacy decrypt
    1859             :      * @param[in] nonce         Privacy Nonce = session_id | mic
    1860             :      * @param[out] output       Message header deobfuscated
    1861             :      * @return CHIP_ERROR
    1862             :      */
    1863             :     virtual CHIP_ERROR PrivacyDecrypt(const ByteSpan & input, const ByteSpan & nonce, MutableByteSpan & output) const = 0;
    1864             : 
    1865             :     /**
    1866             :      * @brief Release resources such as dynamic memory used to allocate this instance of the SymmetricKeyContext
    1867             :      */
    1868             :     virtual void Release() = 0;
    1869             : };
    1870             : 
    1871             : /**
    1872             :  *  @brief Derives the Operational Group Key using the Key Derivation Function (KDF) from the given epoch key.
    1873             :  * @param[in] epoch_key  The epoch key. Must be CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
    1874             :  * @param[in] compressed_fabric_id The compressed fabric ID for the fabric (big endian byte string)
    1875             :  * @param[out] out_key  Symmetric key used as the encryption key during message processing for group communication.
    1876             :  The buffer size must be at least CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
    1877             :  * @return Returns a CHIP_NO_ERROR on succcess, or CHIP_ERROR_INTERNAL if the provided key is invalid.
    1878             :  **/
    1879             : CHIP_ERROR DeriveGroupOperationalKey(const ByteSpan & epoch_key, const ByteSpan & compressed_fabric_id, MutableByteSpan & out_key);
    1880             : 
    1881             : /**
    1882             :  *  @brief Derives the Group Session ID from a given operational group key using
    1883             :  *         the Key Derivation Function (Group Key Hash)
    1884             :  * @param[in] operational_key  The operational group key. Must be CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
    1885             :  * @param[out] session_id  Output of the Group Key Hash
    1886             :  * @return Returns a CHIP_NO_ERROR on succcess, or CHIP_ERROR_INVALID_ARGUMENT if the provided key is invalid.
    1887             :  **/
    1888             : CHIP_ERROR DeriveGroupSessionId(const ByteSpan & operational_key, uint16_t & session_id);
    1889             : 
    1890             : /**
    1891             :  *  @brief Derives the Privacy Group Key using the Key Derivation Function (KDF) from the given epoch key.
    1892             :  * @param[in] epoch_key  The epoch key. Must be CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
    1893             :  * @param[out] out_key  Symmetric key used as the privacy key during message processing for group communication.
    1894             :  *                      The buffer size must be at least CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
    1895             :  * @return Returns a CHIP_NO_ERROR on succcess, or CHIP_ERROR_INTERNAL if the provided key is invalid.
    1896             :  **/
    1897             : CHIP_ERROR DeriveGroupPrivacyKey(const ByteSpan & epoch_key, MutableByteSpan & out_key);
    1898             : 
    1899             : /**
    1900             :  *  @brief Derives the complete set of credentials needed for group security.
    1901             :  *
    1902             :  * This function will derive the Encryption Key, Group Key Hash (Session Id), and Privacy Key
    1903             :  * for the given Epoch Key and Compressed Fabric Id.
    1904             :  * @param[in] epoch_key  The epoch key. Must be CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES bytes length.
    1905             :  * @param[in] compressed_fabric_id The compressed fabric ID for the fabric (big endian byte string)
    1906             :  * @param[out] operational_credentials The set of Symmetric keys used during message processing for group communication.
    1907             :  * @return Returns a CHIP_NO_ERROR on succcess, or CHIP_ERROR_INTERNAL if the provided key is invalid.
    1908             :  **/
    1909             : CHIP_ERROR DeriveGroupOperationalCredentials(const ByteSpan & epoch_key, const ByteSpan & compressed_fabric_id,
    1910             :                                              GroupOperationalCredentials & operational_credentials);
    1911             : } // namespace Crypto
    1912             : } // namespace chip

Generated by: LCOV version 1.14