Matter SDK Coverage Report
Current view: top level - protocols/secure_channel - PASESession.h (source / functions) Coverage Total Hit
Test: SHA:f84fe08d06f240e801b5d923f8a938a9938ca110 Lines: 100.0 % 7 7
Test Date: 2025-02-22 08:08:07 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020-2022 Project CHIP Authors
       4              :  *    All rights reserved.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : 
      19              : /**
      20              :  *    @file
      21              :  *      This file defines the CHIP SPAKE2P Session object that provides
      22              :  *      APIs for constructing spake2p messages and establishing encryption
      23              :  *      keys.
      24              :  *
      25              :  */
      26              : 
      27              : #pragma once
      28              : 
      29              : #include <crypto/CHIPCryptoPAL.h>
      30              : #if CHIP_CRYPTO_PSA_SPAKE2P
      31              : #include <crypto/PSASpake2p.h>
      32              : #endif
      33              : #include <lib/support/Base64.h>
      34              : #include <messaging/ExchangeContext.h>
      35              : #include <messaging/ExchangeDelegate.h>
      36              : #include <messaging/ExchangeMessageDispatch.h>
      37              : #include <protocols/secure_channel/Constants.h>
      38              : #include <protocols/secure_channel/PairingSession.h>
      39              : #include <protocols/secure_channel/SessionEstablishmentExchangeDispatch.h>
      40              : #include <system/SystemPacketBuffer.h>
      41              : #include <system/TLVPacketBufferBackingStore.h>
      42              : #include <transport/CryptoContext.h>
      43              : #include <transport/raw/MessageHeader.h>
      44              : #include <transport/raw/PeerAddress.h>
      45              : 
      46              : namespace chip {
      47              : namespace Testing {
      48              : class TestPASESession;
      49              : }
      50              : extern const char kSpake2pI2RSessionInfo[];
      51              : extern const char kSpake2pR2ISessionInfo[];
      52              : 
      53              : inline constexpr uint16_t kPBKDFParamRandomNumberSize = 32;
      54              : 
      55              : class DLL_EXPORT PASESession : public Messaging::UnsolicitedMessageHandler,
      56              :                                public Messaging::ExchangeDelegate,
      57              :                                public PairingSession
      58              : {
      59              : public:
      60              :     ~PASESession() override;
      61              : 
      62            6 :     Transport::SecureSession::Type GetSecureSessionType() const override { return Transport::SecureSession::Type::kPASE; }
      63           40 :     ScopedNodeId GetPeer() const override
      64              :     {
      65           40 :         return ScopedNodeId(NodeIdFromPAKEKeyId(kDefaultCommissioningPasscodeId), kUndefinedFabricIndex);
      66              :     }
      67              : 
      68           10 :     ScopedNodeId GetLocalScopedNodeId() const override
      69              :     {
      70              :         // For PASE, source is always the undefined node ID
      71           10 :         return ScopedNodeId();
      72              :     }
      73              : 
      74           30 :     CATValues GetPeerCATs() const override { return CATValues(); };
      75              : 
      76              :     CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) override;
      77              : 
      78              :     /**
      79              :      * @brief
      80              :      *   Initialize using PASE verifier and wait for pairing requests.
      81              :      *
      82              :      * @param sessionManager      session manager from which to allocate a secure session object
      83              :      * @param verifier            PASE verifier to be used for SPAKE2P pairing
      84              :      * @param pbkdf2IterCount     Iteration count for PBKDF2 function
      85              :      * @param salt                Salt to be used for SPAKE2P operation
      86              :      * @param delegate            Callback object
      87              :      *
      88              :      * @return CHIP_ERROR     The result of initialization
      89              :      */
      90              :     CHIP_ERROR WaitForPairing(SessionManager & sessionManager, const Crypto::Spake2pVerifier & verifier, uint32_t pbkdf2IterCount,
      91              :                               const ByteSpan & salt, Optional<ReliableMessageProtocolConfig> mrpLocalConfig,
      92              :                               SessionEstablishmentDelegate * delegate);
      93              : 
      94              :     /**
      95              :      * @brief
      96              :      *   Create a pairing request using peer's setup PIN code.
      97              :      *
      98              :      * @param sessionManager      session manager from which to allocate a secure session object
      99              :      * @param peerSetUpPINCode    Setup PIN code of the peer device
     100              :      * @param exchangeCtxt        The exchange context to send and receive messages with the peer
     101              :      *                            Note: It's expected that the caller of this API hands over the
     102              :      *                            ownership of the exchangeCtxt to PASESession object. PASESession
     103              :      *                            will close the exchange on (successful/failed) handshake completion.
     104              :      * @param delegate            Callback object
     105              :      *                            The delegate will be notified if and only if Pair() returns success. Errors occurring after Pair()
     106              :      *                            returns success will be reported via the delegate.
     107              :      *
     108              :      * @return CHIP_ERROR      The result of initialization
     109              :      */
     110              :     CHIP_ERROR Pair(SessionManager & sessionManager, uint32_t peerSetUpPINCode,
     111              :                     Optional<ReliableMessageProtocolConfig> mrpLocalConfig, Messaging::ExchangeContext * exchangeCtxt,
     112              :                     SessionEstablishmentDelegate * delegate);
     113              : 
     114              :     /**
     115              :      * @brief
     116              :      *   Generate a new PASE verifier.
     117              :      *
     118              :      * @param verifier        The generated PASE verifier
     119              :      * @param pbkdf2IterCount Iteration count for PBKDF2 function
     120              :      * @param salt            Salt to be used for SPAKE2P operation
     121              :      * @param useRandomPIN    Generate a random setup PIN, if true. Else, use the provided PIN
     122              :      * @param setupPIN        Provided setup PIN (if useRandomPIN is false), or the generated PIN
     123              :      *
     124              :      * @return CHIP_ERROR      The result of PASE verifier generation
     125              :      */
     126              :     static CHIP_ERROR GeneratePASEVerifier(Crypto::Spake2pVerifier & verifier, uint32_t pbkdf2IterCount, const ByteSpan & salt,
     127              :                                            bool useRandomPIN, uint32_t & setupPIN);
     128              : 
     129              :     /**
     130              :      * @brief
     131              :      *   Derive a secure session from the paired session. The API will return error if called before pairing is established.
     132              :      *
     133              :      * @param session     Reference to the secure session that will be initialized once pairing is complete
     134              :      * @return CHIP_ERROR The result of session derivation
     135              :      */
     136              :     CHIP_ERROR DeriveSecureSession(CryptoContext & session) override;
     137              : 
     138              :     // TODO: remove Clear, we should create a new instance instead reset the old instance.
     139              :     /** @brief This function zeroes out and resets the memory used by the object.
     140              :      **/
     141              :     void Clear();
     142              : 
     143              :     //// ExchangeDelegate Implementation ////
     144              :     /**
     145              :      * @brief
     146              :      *   This function is the called by exchange context or exchange manager when it receives
     147              :      *   a CHIP message corresponding to the context, or registered unsolicited message handler.
     148              :      *
     149              :      *   Note: If the function is called by unsolicited message handler, the ownership of the
     150              :      *         provide exchange context is handed over to PASE Session object. The PASE Session
     151              :      *         object ensures that the exchange will be closed on completion of the handshake.
     152              :      *
     153              :      *  @param[in]    ec            A pointer to the ExchangeContext object.
     154              :      *  @param[in]    payloadHeader A reference to the PayloadHeader object.
     155              :      *  @param[in]    payload       A handle to the PacketBuffer object holding the message payload.
     156              :      */
     157              :     CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader,
     158              :                                  System::PacketBufferHandle && payload) override;
     159              : 
     160              :     /**
     161              :      * @brief
     162              :      *   This function is the protocol callback to invoke when the timeout for the receipt
     163              :      *   of a response message has expired.
     164              :      *
     165              :      *  @param[in]    ec            A pointer to the ExchangeContext object.
     166              :      */
     167              :     void OnResponseTimeout(Messaging::ExchangeContext * ec) override;
     168              : 
     169           14 :     Messaging::ExchangeMessageDispatch & GetMessageDispatch() override { return SessionEstablishmentExchangeDispatch::Instance(); }
     170              : 
     171              :     //// SessionDelegate ////
     172              :     void OnSessionReleased() override;
     173              : 
     174              : private:
     175              :     enum Spake2pErrorType : uint8_t
     176              :     {
     177              :         kInvalidKeyConfirmation = 0x00,
     178              :         kUnexpected             = 0xff,
     179              :     };
     180              :     friend class Testing::TestPASESession;
     181              : 
     182              :     CHIP_ERROR Init(SessionManager & sessionManager, uint32_t setupCode, SessionEstablishmentDelegate * delegate);
     183              : 
     184              :     CHIP_ERROR ValidateReceivedMessage(Messaging::ExchangeContext * exchange, const PayloadHeader & payloadHeader,
     185              :                                        const System::PacketBufferHandle & msg);
     186              : 
     187              :     CHIP_ERROR SetupSpake2p();
     188              : 
     189              :     CHIP_ERROR SendPBKDFParamRequest();
     190              :     CHIP_ERROR HandlePBKDFParamRequest(System::PacketBufferHandle && msg);
     191              : 
     192              :     CHIP_ERROR SendPBKDFParamResponse(ByteSpan initiatorRandom, bool initiatorHasPBKDFParams);
     193              :     CHIP_ERROR HandlePBKDFParamResponse(System::PacketBufferHandle && msg);
     194              : 
     195              :     CHIP_ERROR SendMsg1();
     196              : 
     197              :     CHIP_ERROR HandleMsg1_and_SendMsg2(System::PacketBufferHandle && msg);
     198              :     CHIP_ERROR HandleMsg2_and_SendMsg3(System::PacketBufferHandle && msg);
     199              :     CHIP_ERROR HandleMsg3(System::PacketBufferHandle && msg);
     200              : 
     201              :     void OnSuccessStatusReport() override;
     202              :     CHIP_ERROR OnFailureStatusReport(Protocols::SecureChannel::GeneralStatusCode generalCode, uint16_t protocolCode,
     203              :                                      Optional<uintptr_t> protocolData) override;
     204              : 
     205              :     /** This function returns the CHIP_ERROR from a call to TLVReader::Next() method.
     206              :      *
     207              :      * @retval #CHIP_END_OF_TLV            If the end of the TLV encoding is reached.
     208              :      * @retval #CHIP_NO_ERROR              If there are additional non-parsed TLV Elements.
     209              :      * @retval other                       See return values of TLVReader::Next()
     210              :      **/
     211              :     CHIP_ERROR ReadSessionParamsIfPresent(const TLV::Tag & SessionParamsTag, System::PacketBufferTLVReader & tlvReader);
     212              : 
     213              :     void Finish();
     214              : 
     215              :     // mNextExpectedMsg is set when we are expecting a message.
     216              :     Optional<Protocols::SecureChannel::MsgType> mNextExpectedMsg;
     217              : 
     218              : #if CHIP_CRYPTO_PSA_SPAKE2P
     219              :     Crypto::PSASpake2p_P256_SHA256_HKDF_HMAC mSpake2p;
     220              : #else
     221              :     Crypto::Spake2p_P256_SHA256_HKDF_HMAC mSpake2p;
     222              : #endif
     223              : 
     224              :     Crypto::Spake2pVerifier mPASEVerifier;
     225              : 
     226              :     uint32_t mSetupPINCode;
     227              : 
     228              :     bool mHavePBKDFParameters = false;
     229              : 
     230              :     uint8_t mPBKDFLocalRandomData[kPBKDFParamRandomNumberSize];
     231              : 
     232              :     Crypto::Hash_SHA256_stream mCommissioningHash;
     233              :     uint32_t mIterationCount = 0;
     234              :     uint16_t mSaltLength     = 0;
     235              :     uint8_t * mSalt          = nullptr;
     236              : 
     237              :     struct Spake2pErrorMsg
     238              :     {
     239              :         Spake2pErrorType error;
     240              :     };
     241              : 
     242              : protected:
     243              :     uint8_t mKe[Crypto::kMAX_Hash_Length];
     244              : 
     245              :     size_t mKeLen = sizeof(mKe);
     246              : 
     247              :     bool mPairingComplete = false;
     248              : };
     249              : 
     250              : // The following constants are node IDs that test devices and test controllers use.
     251              : inline constexpr chip::NodeId kTestControllerNodeId = 112233;
     252              : inline constexpr chip::NodeId kTestDeviceNodeId     = 12344321;
     253              : 
     254              : } // namespace chip
        

Generated by: LCOV version 2.0-1