LCOV - code coverage report
Current view: top level - protocols/secure_channel - PASESession.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 7 7 100.0 %
Date: 2024-02-15 08:20:41 Functions: 5 5 100.0 %

          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             : #include <lib/support/Base64.h>
      31             : #include <messaging/ExchangeContext.h>
      32             : #include <messaging/ExchangeDelegate.h>
      33             : #include <messaging/ExchangeMessageDispatch.h>
      34             : #include <protocols/secure_channel/Constants.h>
      35             : #include <protocols/secure_channel/PairingSession.h>
      36             : #include <protocols/secure_channel/SessionEstablishmentExchangeDispatch.h>
      37             : #include <system/SystemPacketBuffer.h>
      38             : #include <transport/CryptoContext.h>
      39             : #include <transport/raw/MessageHeader.h>
      40             : #include <transport/raw/PeerAddress.h>
      41             : 
      42             : namespace chip {
      43             : 
      44             : extern const char kSpake2pI2RSessionInfo[];
      45             : extern const char kSpake2pR2ISessionInfo[];
      46             : 
      47             : inline constexpr uint16_t kPBKDFParamRandomNumberSize = 32;
      48             : 
      49             : using namespace Crypto;
      50             : 
      51             : struct PASESessionSerialized;
      52             : 
      53             : struct PASESessionSerializable
      54             : {
      55             :     uint16_t mKeLen;
      56             :     uint8_t mKe[kMAX_Hash_Length];
      57             :     uint8_t mPairingComplete;
      58             :     uint16_t mLocalSessionId;
      59             :     uint16_t mPeerSessionId;
      60             : };
      61             : 
      62             : class DLL_EXPORT PASESession : public Messaging::UnsolicitedMessageHandler,
      63             :                                public Messaging::ExchangeDelegate,
      64             :                                public PairingSession
      65             : {
      66             : public:
      67             :     ~PASESession() override;
      68             : 
      69           7 :     Transport::SecureSession::Type GetSecureSessionType() const override { return Transport::SecureSession::Type::kPASE; }
      70          40 :     ScopedNodeId GetPeer() const override
      71             :     {
      72          40 :         return ScopedNodeId(NodeIdFromPAKEKeyId(kDefaultCommissioningPasscodeId), kUndefinedFabricIndex);
      73             :     }
      74             : 
      75          10 :     ScopedNodeId GetLocalScopedNodeId() const override
      76             :     {
      77             :         // For PASE, source is always the undefined node ID
      78          10 :         return ScopedNodeId();
      79             :     }
      80             : 
      81          30 :     CATValues GetPeerCATs() const override { return CATValues(); };
      82             : 
      83             :     CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) override;
      84             : 
      85             :     /**
      86             :      * @brief
      87             :      *   Initialize using PASE verifier and wait for pairing requests.
      88             :      *
      89             :      * @param sessionManager      session manager from which to allocate a secure session object
      90             :      * @param verifier            PASE verifier to be used for SPAKE2P pairing
      91             :      * @param pbkdf2IterCount     Iteration count for PBKDF2 function
      92             :      * @param salt                Salt to be used for SPAKE2P operation
      93             :      * @param delegate            Callback object
      94             :      *
      95             :      * @return CHIP_ERROR     The result of initialization
      96             :      */
      97             :     CHIP_ERROR WaitForPairing(SessionManager & sessionManager, const Spake2pVerifier & verifier, uint32_t pbkdf2IterCount,
      98             :                               const ByteSpan & salt, Optional<ReliableMessageProtocolConfig> mrpLocalConfig,
      99             :                               SessionEstablishmentDelegate * delegate);
     100             : 
     101             :     /**
     102             :      * @brief
     103             :      *   Create a pairing request using peer's setup PIN code.
     104             :      *
     105             :      * @param sessionManager      session manager from which to allocate a secure session object
     106             :      * @param peerSetUpPINCode    Setup PIN code of the peer device
     107             :      * @param exchangeCtxt        The exchange context to send and receive messages with the peer
     108             :      *                            Note: It's expected that the caller of this API hands over the
     109             :      *                            ownership of the exchangeCtxt to PASESession object. PASESession
     110             :      *                            will close the exchange on (successful/failed) handshake completion.
     111             :      * @param delegate            Callback object
     112             :      *
     113             :      * @return CHIP_ERROR      The result of initialization
     114             :      */
     115             :     CHIP_ERROR Pair(SessionManager & sessionManager, uint32_t peerSetUpPINCode,
     116             :                     Optional<ReliableMessageProtocolConfig> mrpLocalConfig, Messaging::ExchangeContext * exchangeCtxt,
     117             :                     SessionEstablishmentDelegate * delegate);
     118             : 
     119             :     /**
     120             :      * @brief
     121             :      *   Generate a new PASE verifier.
     122             :      *
     123             :      * @param verifier        The generated PASE verifier
     124             :      * @param pbkdf2IterCount Iteration count for PBKDF2 function
     125             :      * @param salt            Salt to be used for SPAKE2P operation
     126             :      * @param useRandomPIN    Generate a random setup PIN, if true. Else, use the provided PIN
     127             :      * @param setupPIN        Provided setup PIN (if useRandomPIN is false), or the generated PIN
     128             :      *
     129             :      * @return CHIP_ERROR      The result of PASE verifier generation
     130             :      */
     131             :     static CHIP_ERROR GeneratePASEVerifier(Spake2pVerifier & verifier, uint32_t pbkdf2IterCount, const ByteSpan & salt,
     132             :                                            bool useRandomPIN, uint32_t & setupPIN);
     133             : 
     134             :     /**
     135             :      * @brief
     136             :      *   Derive a secure session from the paired session. The API will return error if called before pairing is established.
     137             :      *
     138             :      * @param session     Reference to the secure session that will be initialized once pairing is complete
     139             :      * @return CHIP_ERROR The result of session derivation
     140             :      */
     141             :     CHIP_ERROR DeriveSecureSession(CryptoContext & session) const override;
     142             : 
     143             :     // TODO: remove Clear, we should create a new instance instead reset the old instance.
     144             :     /** @brief This function zeroes out and resets the memory used by the object.
     145             :      **/
     146             :     void Clear();
     147             : 
     148             :     //// ExchangeDelegate Implementation ////
     149             :     /**
     150             :      * @brief
     151             :      *   This function is the called by exchange context or exchange manager when it receives
     152             :      *   a CHIP message corresponding to the context, or registered unsolicited message handler.
     153             :      *
     154             :      *   Note: If the function is called by unsolicited message handler, the ownership of the
     155             :      *         provide exchange context is handed over to PASE Session object. The PASE Session
     156             :      *         object ensures that the exchange will be closed on completion of the handshake.
     157             :      *
     158             :      *  @param[in]    ec            A pointer to the ExchangeContext object.
     159             :      *  @param[in]    payloadHeader A reference to the PayloadHeader object.
     160             :      *  @param[in]    payload       A handle to the PacketBuffer object holding the message payload.
     161             :      */
     162             :     CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader,
     163             :                                  System::PacketBufferHandle && payload) override;
     164             : 
     165             :     /**
     166             :      * @brief
     167             :      *   This function is the protocol callback to invoke when the timeout for the receipt
     168             :      *   of a response message has expired.
     169             :      *
     170             :      *  @param[in]    ec            A pointer to the ExchangeContext object.
     171             :      */
     172             :     void OnResponseTimeout(Messaging::ExchangeContext * ec) override;
     173             : 
     174          14 :     Messaging::ExchangeMessageDispatch & GetMessageDispatch() override { return SessionEstablishmentExchangeDispatch::Instance(); }
     175             : 
     176             :     //// SessionDelegate ////
     177             :     void OnSessionReleased() override;
     178             : 
     179             : private:
     180             :     enum Spake2pErrorType : uint8_t
     181             :     {
     182             :         kInvalidKeyConfirmation = 0x00,
     183             :         kUnexpected             = 0xff,
     184             :     };
     185             : 
     186             :     CHIP_ERROR Init(SessionManager & sessionManager, uint32_t setupCode, SessionEstablishmentDelegate * delegate);
     187             : 
     188             :     CHIP_ERROR ValidateReceivedMessage(Messaging::ExchangeContext * exchange, const PayloadHeader & payloadHeader,
     189             :                                        const System::PacketBufferHandle & msg);
     190             : 
     191             :     CHIP_ERROR SetupSpake2p();
     192             : 
     193             :     CHIP_ERROR SendPBKDFParamRequest();
     194             :     CHIP_ERROR HandlePBKDFParamRequest(System::PacketBufferHandle && msg);
     195             : 
     196             :     CHIP_ERROR SendPBKDFParamResponse(ByteSpan initiatorRandom, bool initiatorHasPBKDFParams);
     197             :     CHIP_ERROR HandlePBKDFParamResponse(System::PacketBufferHandle && msg);
     198             : 
     199             :     CHIP_ERROR SendMsg1();
     200             : 
     201             :     CHIP_ERROR HandleMsg1_and_SendMsg2(System::PacketBufferHandle && msg);
     202             :     CHIP_ERROR HandleMsg2_and_SendMsg3(System::PacketBufferHandle && msg);
     203             :     CHIP_ERROR HandleMsg3(System::PacketBufferHandle && msg);
     204             : 
     205             :     void OnSuccessStatusReport() override;
     206             :     CHIP_ERROR OnFailureStatusReport(Protocols::SecureChannel::GeneralStatusCode generalCode, uint16_t protocolCode) override;
     207             : 
     208             :     void Finish();
     209             : 
     210             :     // mNextExpectedMsg is set when we are expecting a message.
     211             :     Optional<Protocols::SecureChannel::MsgType> mNextExpectedMsg;
     212             : 
     213             :     Spake2p_P256_SHA256_HKDF_HMAC mSpake2p;
     214             : 
     215             :     Spake2pVerifier mPASEVerifier;
     216             : 
     217             :     uint32_t mSetupPINCode;
     218             : 
     219             :     bool mHavePBKDFParameters = false;
     220             : 
     221             :     uint8_t mPBKDFLocalRandomData[kPBKDFParamRandomNumberSize];
     222             : 
     223             :     Hash_SHA256_stream mCommissioningHash;
     224             :     uint32_t mIterationCount = 0;
     225             :     uint16_t mSaltLength     = 0;
     226             :     uint8_t * mSalt          = nullptr;
     227             : 
     228             :     struct Spake2pErrorMsg
     229             :     {
     230             :         Spake2pErrorType error;
     231             :     };
     232             : 
     233             : protected:
     234             :     uint8_t mKe[kMAX_Hash_Length];
     235             : 
     236             :     size_t mKeLen = sizeof(mKe);
     237             : 
     238             :     bool mPairingComplete = false;
     239             : };
     240             : 
     241             : // The following constants are node IDs that test devices and test controllers use.
     242             : inline constexpr chip::NodeId kTestControllerNodeId = 112233;
     243             : inline constexpr chip::NodeId kTestDeviceNodeId     = 12344321;
     244             : 
     245             : } // namespace chip

Generated by: LCOV version 1.14