blob: ecc4a1d6931996e908c10bbabf01c7a59307f907 [file] [log] [blame]
/*
*
* Copyright (c) 2013-2017 Nest Labs, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* This file defines data types and objects for managing the
* active node state necessary to participate in a Weave fabric.
*
*/
#ifndef WEAVE_FABRIC_STATE_H
#define WEAVE_FABRIC_STATE_H
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <inttypes.h>
#include <Weave/Support/NLDLLUtil.h>
#include <Weave/Support/WeaveCounter.h>
#include <Weave/Support/PersistedCounter.h>
#include <Weave/Support/FlagUtils.hpp>
#include <Weave/Core/WeaveCore.h>
#include <Weave/Core/WeaveKeyIds.h>
#include <Weave/Profiles/security/WeaveSecurity.h>
#include <Weave/Profiles/security/WeaveApplicationKeys.h>
namespace nl {
namespace Weave {
class NL_DLL_EXPORT WeaveConnection;
class NL_DLL_EXPORT WeaveMessageLayer;
class NL_DLL_EXPORT WeaveExchangeManager;
struct WeaveMessageInfo;
// Special node id values.
enum
{
kNodeIdNotSpecified = 0ULL,
kAnyNodeId = 0xFFFFFFFFFFFFFFFFULL
};
// Special fabric id values.
enum
{
kFabricIdNotSpecified = 0ULL,
/** Default fabric ID, which should only be used for testing purposes. */
kFabricIdDefaultForTest = 1ULL,
// Ids >= kReservedFabricIdStart and <= kMaxFabricId are reserved for special uses. The
// meanings of values in this range are context-specific; e.g. in the IdentifyRequest
// message, these value are used to match devices that are/are not members of a fabric.
kReservedFabricIdStart = 0xFFFFFFFFFFFFFF00ULL,
kMaxFabricId = 0xFFFFFFFFFFFFFFFFULL
};
/** Identifies the purpose or application of certificate
*
* A certificate type is a label that describes a certificate's purpose or application.
* Certificate types are not carried as attributes of the corresponding certificates, but
* rather are derived from the certificate's structure and/or the context in which it is used.
* The certificate type enumeration includes a set of pre-defined values describing commonly
* used certificate applications. Developers can also extend the certificate type value
* range with application-specific types that described custom certificates or certificates
* with unique security properties.
*
* Certificate types are primarily used in the implementation of access control policies,
* where access to application features is influenced by the type of certificate presented
* by a requester.
*
* @note Cert type is an API data type only; it should never be sent over-the-wire.
*/
enum
{
// NOTE: When adding additional types, please update the PrintCertType() function.
kCertType_NotSpecified = 0x00, /**< The certificate's type has not been specified. */
kCertType_General = 0x01, /**< The certificate is of a general or non-specific type. */
kCertType_Device = 0x02, /**< A Weave device certificate. */
kCertType_ServiceEndpoint = 0x03, /**< A Weave service endpoint certificate. */
kCertType_FirmwareSigning = 0x04, /**< A Weave firmware signing certificate. */
kCertType_AccessToken = 0x05, /**< A Weave access token certificate. */
kCertType_CA = 0x06, /**< A CA certificate. */
kCertType_AppDefinedBase = 0x7F, /**< Application-specific certificate types should have values >= this value. */
kCertType_Max = 0xFF, /**< Certificate types should not be greater than this value. */
};
/** Identifies the source for the password used in a password-based authentication protocol (e.g. Weave PASE)
*
* @note Password Source is protocol data type; do not renumber.
*/
enum
{
kPasswordSource_NotSpecified = 0x0,
kPasswordSource_PairingCode = 0x1,
kPasswordSource_Max = 0xF,
};
/** Identifies how a peer node is authenticated.
*
* WeaveAuthMode describes the means by which a peer node has been, or should be,
* authenticated during a Weave message exchange. In an initiating context,
* applications use WeaveAuthMode to express a desired peer authentication mode
* for an exchange, thereby instructing the Weave security and messaging layers
* to achieve the desired mode or fail the communication. In a responding context,
* WeaveAuthMode identifies how the requesting node (the peer) was authenticated,
* allowing the responding application to enforce access controls based on this
* information.
*
* The WeaveAuthMode assigned to an incoming Weave message is related to the nature
* of the key that was used to encrypt that message. The WeaveAuthMode derives from
* the mechanism by which the key was established and the criteria used to verify the
* identities of the communicating parties at the time of key establishment.
*
* WeaveAuthMode includes a set of pre-defined values describing common
* authentication modes. These are broken down by the key agreement mechanism
* (CASE, PASE, GroupKey, etc.). Developers can extend WeaveAuthMode by defining
* application-specific mode, which they can attach to specific encryption keys.
*
* @note WeaveAuthMode is an API data type only; it should never be sent over-the-wire.
*/
typedef uint16_t WeaveAuthMode;
enum
{
kWeaveAuthMode_NotSpecified = 0x0000, /**< Authentication mode not specified. */
// ===== Major authentication categories =====
kWeaveAuthModeCategory_General = 0x0000, /**< Peer authenticated using one of a set of general mechanisms */
kWeaveAuthModeCategory_PASE = 0x1000, /**< Peer authenticated using Weave PASE protocol */
kWeaveAuthModeCategory_CASE = 0x2000, /**< Peer authenticated using Weave CASE protocol */
kWeaveAuthModeCategory_TAKE = 0x3000, /**< Peer authenticated using Weave TAKE protocol */
kWeaveAuthModeCategory_GroupKey = 0x4000, /**< Peer authenticated using a shared group key */
kWeaveAuthModeCategory_AppDefinedBase = 0xC000, /**< Base value for application-defined authentication categories */
// ===== General authentication modes =====
kWeaveAuthMode_Unauthenticated = kWeaveAuthModeCategory_General | 0x001,
/**< Peer not authenticated. */
// ===== PASE authentication modes =====
kWeaveAuthMode_PASE_PairingCode = kWeaveAuthModeCategory_PASE | kPasswordSource_PairingCode,
/**< Peer authenticated using PASE with device pairing code. */
// ===== CASE authentication modes =====
kWeaveAuthMode_CASE_AnyCert = kWeaveAuthModeCategory_CASE | kCertType_NotSpecified,
/**< Peer authenticated using CASE with arbitrary certificate, or certificate of unknown type. */
kWeaveAuthMode_CASE_GeneralCert = kWeaveAuthModeCategory_CASE | kCertType_General,
/**< Peer authenticated using CASE with a general, or non-specific certificate type. */
kWeaveAuthMode_CASE_Device = kWeaveAuthModeCategory_CASE | kCertType_Device,
/**< Peer authenticated using CASE with Weave device certificate. */
kWeaveAuthMode_CASE_ServiceEndPoint = kWeaveAuthModeCategory_CASE | kCertType_ServiceEndpoint,
/**< Peer authenticated using CASE with Weave service endpoint certificate. */
kWeaveAuthMode_CASE_AccessToken = kWeaveAuthModeCategory_CASE | kCertType_AccessToken,
/**< Peer authenticated using CASE with Weave access token certificate. */
// ===== TAKE authentication modes =====
kWeaveAuthMode_TAKE_IdentificationKey = kWeaveAuthModeCategory_TAKE | 0x001,
/**< Peer authenticated using TAKE with a token identification key. */
// ===== Subfield Masks =====
kWeaveAuthModeCategory_Mask = 0xF000,
kWeaveAuthMode_PASE_PasswordSourceMask = kPasswordSource_Max,
kWeaveAuthMode_CASE_CertTypeMask = kCertType_Max,
kWeaveAuthMode_GroupKey_AppGroupLocalNumber = WeaveKeyId::kGroupLocalNumber_Max,
// ===== DEPRECATED ALIASES =====
kWeaveAuthMode_None = kWeaveAuthMode_Unauthenticated,
kWeaveAuthMode_Password_PairingCode = kWeaveAuthMode_PASE_PairingCode,
kWeaveAuthMode_Cert_Device = kWeaveAuthMode_CASE_Device,
kWeaveAuthMode_Cert_ServiceEndPoint = kWeaveAuthMode_CASE_ServiceEndPoint,
};
/** True if the authentication mode is based on the Weave PASE protocol. */
inline bool IsPASEAuthMode(WeaveAuthMode authMode) { return (authMode & kWeaveAuthModeCategory_Mask) == kWeaveAuthModeCategory_PASE; }
/** True if the authentication mode is based on the Weave CASE protocol. */
inline bool IsCASEAuthMode(WeaveAuthMode authMode) { return (authMode & kWeaveAuthModeCategory_Mask) == kWeaveAuthModeCategory_CASE; }
/** True if the authentication mode is based on the Weave TAKE protocol. */
inline bool IsTAKEAuthMode(WeaveAuthMode authMode) { return (authMode & kWeaveAuthModeCategory_Mask) == kWeaveAuthModeCategory_TAKE; }
/** True if the authentication mode is based possession of a shared password. */
inline bool IsPasswordAuthMode(WeaveAuthMode authMode) { return IsPASEAuthMode(authMode); }
/** True if the authentication mode is based on possession of a private key associated with a certificate. */
inline bool IsCertAuthMode(WeaveAuthMode authMode) { return IsCASEAuthMode(authMode); }
/** True if the authentication mode is based on possession of a shared group key. */
inline bool IsGroupKeyAuthMode(WeaveAuthMode authMode) { return (authMode & kWeaveAuthModeCategory_Mask) == kWeaveAuthModeCategory_GroupKey; }
/** Returns the password source for the given authentication mode.
*
* @note The result is only valid when the supplied mode is one of the password authentication modes.
*/
inline uint8_t PasswordSourceFromAuthMode(WeaveAuthMode authMode) { return (uint8_t)(authMode & kWeaveAuthMode_PASE_PasswordSourceMask); }
/** Returns the password source for the given authentication mode.
*
* @note The result is only valid when the supplied mode is one of the certificate authentication modes.
*/
inline uint8_t CertTypeFromAuthMode(WeaveAuthMode authMode) { return (uint8_t)(authMode & kWeaveAuthMode_CASE_CertTypeMask); }
/** Returns the application group master key ID associated with the authentication mode.
*
* @note The result is only valid when the supplied mode is one of the group key modes.
*/
inline uint8_t AppGroupMasterKeyIdFromAuthMode(WeaveAuthMode authMode) { return WeaveKeyId::MakeAppGroupMasterKeyId(authMode & kWeaveAuthMode_GroupKey_AppGroupLocalNumber); }
/** Returns a corresponding PASE authentication mode for a given password source. */
inline WeaveAuthMode PASEAuthMode(uint8_t pwSource) { return kWeaveAuthModeCategory_PASE | pwSource; }
/** Returns a corresponding CASE authentication mode for a given certificate type. */
inline WeaveAuthMode CASEAuthMode(uint8_t certType) { return kWeaveAuthModeCategory_CASE | certType; }
/** Returns a corresponding group key authentication mode for a given key ID.
*
* @note The result is only valid when the supplied key ID is an application group key.
*/
inline WeaveAuthMode GroupKeyAuthMode(uint32_t keyId) { return kWeaveAuthModeCategory_GroupKey | WeaveKeyId::GetAppGroupLocalNumber(keyId); }
/**
* @typedef FabricSecretScope
*
* @brief
* Identifies the category of devices that can possess and use fabric secret.
*
* @note FabricSecretScope is protocol data type; do not renumber.
*/
typedef uint8_t FabricSecretScope;
enum
{
kFabricSecretScope_All = 0x00 /**< All devices can possess corresponding fabric secret. */
};
// Encryption key for the AES-128-CTR-SHA-1 message encryption type
class WeaveEncryptionKey_AES128CTRSHA1
{
public:
enum
{
DataKeySize = 16,
DataKeySizeInWords = DataKeySize/sizeof(uint32_t),
IntegrityKeySize = 20,
KeySize = DataKeySize + IntegrityKeySize
};
union {
uint8_t DataKey[DataKeySize];
uint32_t DataKeyWords[DataKeySizeInWords];
};
uint8_t IntegrityKey[IntegrityKeySize];
};
// Represents a key or key set used to encrypt Weave messages.
typedef union WeaveEncryptionKey
{
WeaveEncryptionKey_AES128CTRSHA1 AES128CTRSHA1;
} WeaveEncryptionKey;
// AES128CTRSHA1 encryption and integrity test keys, which should only be used for testing purposes.
enum
{
kTestKey_AES128CTRSHA1_DataKeyByte = 0xAB, /**< Byte value that constructs encryption key, which is used only for testing. */
kTestKey_AES128CTRSHA1_IntegrityKeyByte = 0xBA /**< Byte value that constructs integrity key, which is used only for testing. */
};
/**
* @class WeaveMsgEncryptionKey
*
* @brief
* Contains information about Weave message encryption key.
*
*/
class WeaveMsgEncryptionKey
{
public:
uint16_t KeyId; /**< The key ID. */
uint8_t EncType; /**< The encryption type supported by the key. */
WeaveEncryptionKey EncKey; /**< The secret key material. */
};
// WeaveSessionState -- Conveys the communication state needed to send/receive messages with another node.
class WeaveSessionState
{
public:
typedef uint16_t ReceiveFlagsType;
enum
{
kReceiveFlags_NumMessageIdFlags = (sizeof(ReceiveFlagsType) * 8) - 1,
kReceiveFlags_MessageIdSynchronized = (1 << kReceiveFlags_NumMessageIdFlags),
kReceiveFlags_MessageIdFlagsMask = ~kReceiveFlags_MessageIdSynchronized
};
WeaveSessionState(void);
WeaveSessionState(WeaveMsgEncryptionKey *msgEncKey, WeaveAuthMode authMode,
MonotonicallyIncreasingCounter *nextMsgId, uint32_t *maxRcvdMsgId, ReceiveFlagsType *rcvFlags);
WeaveMsgEncryptionKey *MsgEncKey;
WeaveAuthMode AuthMode;
uint32_t NewMessageId(void);
bool MessageIdNotSynchronized(void);
bool IsDuplicateMessage(uint32_t msgId);
private:
MonotonicallyIncreasingCounter *NextMsgId;
uint32_t *MaxMsgIdRcvd;
ReceiveFlagsType *RcvFlags;
};
// WeaveSessionKey -- Contains information about a Weave session key.
class WeaveSessionKey
{
public:
enum FlagsEnum
{
kFlag_IsLocallyInitiated = 0x01, // The session was initiated by the local node.
kFlag_IsSharedSession = 0x02, // The session is a shared session.
kFlag_IsRemoveOnIdle = 0x04, // The session should be removed when idle (only applies to sessions
// that are not bound to a connection).
kFlag_RecentlyActive = 0x08, // The session was recently active.
};
uint64_t NodeId; // The id of the node with which the session key is shared.
MonotonicallyIncreasingCounter NextMsgId; // The next message id to be used under the session key.
uint32_t MaxRcvdMsgId; // The maximum message id received under the session key.
WeaveConnection *BoundCon; // The connection to which the key is bound.
WeaveSessionState::ReceiveFlagsType RcvFlags; // Flags tracking messages received under the key.
WeaveAuthMode AuthMode; // The means by which the peer node was authenticated during session establishment.
WeaveMsgEncryptionKey MsgEncKey; // The Weave message encryption key.
uint8_t ReserveCount; // Number of times the session key has been reserved.
uint8_t Flags; // Various flags associated with the session.
void Init(void);
void Clear(void);
bool IsAllocated() const { return MsgEncKey.KeyId != WeaveKeyId::kNone; }
bool IsKeySet() const { return MsgEncKey.EncType != 0; }
bool IsLocallyInitiated() const { return GetFlag(Flags, kFlag_IsLocallyInitiated); }
void SetLocallyInitiated(bool val) { SetFlag(Flags, kFlag_IsLocallyInitiated, val); }
bool IsSharedSession() const { return GetFlag(Flags, kFlag_IsSharedSession); }
void SetSharedSession(bool val) { SetFlag(Flags, kFlag_IsSharedSession, val); }
bool IsRemoveOnIdle() const { return GetFlag(Flags, kFlag_IsRemoveOnIdle); }
void SetRemoveOnIdle(bool val) { SetFlag(Flags, kFlag_IsRemoveOnIdle, val); }
bool IsRecentlyActive() const { return GetFlag(Flags, kFlag_RecentlyActive); }
void MarkRecentlyActive() { SetFlag(Flags, kFlag_RecentlyActive); }
void ClearRecentlyActive() { ClearFlag(Flags, kFlag_RecentlyActive); }
};
// Key cache for Weave message encryption keys.
class WeaveMsgEncryptionKeyCache
{
public:
void Init(void);
void Reset(void);
void Shutdown(void);
WeaveMsgEncryptionKey *FindOrAllocateKeyEntry(uint16_t keyId, uint8_t encType);
private:
// Array of Weave message encryption keys.
WeaveMsgEncryptionKey mKeyCache[WEAVE_CONFIG_MAX_CACHED_MSG_ENC_APP_KEYS];
// Array of key entry indexes in sorted order from most- to least- recently used.
uint8_t mMostRecentlyUsedKeyEntries[WEAVE_CONFIG_MAX_CACHED_MSG_ENC_APP_KEYS];
void Clear(uint8_t keyEntryIndex);
};
/**
* @brief
* Key diversifier used for Weave message encryption key derivation. This value
* represents first 4 bytes of the SHA-1 HASH of "Nest Weave Message EK and AK" phrase.
*/
extern const uint8_t kWeaveMsgEncAppKeyDiversifier[4];
/**
* Weave message encryption application key diversifier size.
*/
enum
{
kWeaveMsgEncAppKeyDiversifierSize = sizeof(kWeaveMsgEncAppKeyDiversifier) + sizeof(uint8_t)
};
// Forward declaration of WeaveFabricState
class WeaveFabricState;
/**
* This abstract delegate class communicates fabric state changes.
*/
class FabricStateDelegate
{
public:
/**
* This method is called when WeaveFabricState joins or creates a new fabric.
*
* @param[in] fabricState: A pointer to WeaveFabricState that was changed.
* @param[in] newFabricId: The new fabric ID of the WeaveFabricState.
*
* @retval None.
*/
virtual void DidJoinFabric(WeaveFabricState *fabricState, uint64_t newFabricId) = 0;
/**
* This method is called when WeaveFabricState leaves a fabric (i.e., fabric state
* is cleared).
*
* @param[in] fabricState: A pointer to the WeaveFabricState that was changed.
* @param[in] oldFabricId: The old fabric ID that was cleared.
*
* @retval None.
*/
virtual void DidLeaveFabric(WeaveFabricState *fabricState, uint64_t oldFabricId) = 0;
};
class NL_DLL_EXPORT WeaveFabricState
{
public:
#if WEAVE_CONFIG_MAX_PEER_NODES <= UINT8_MAX
typedef uint8_t PeerIndexType;
#else
typedef uint16_t PeerIndexType;
#endif
enum State
{
kState_NotInitialized = 0, kState_Initialized = 1
};
WeaveFabricState(void);
WeaveMessageLayer *MessageLayer; // [READ ONLY] The associated WeaveMessageLayer object.
uint64_t FabricId; // [READ ONLY] Node's Fabric Id (0 means node is not a member of a fabric).
uint64_t LocalNodeId;
const char *PairingCode;
uint16_t DefaultSubnet;
uint8_t State; // [READ ONLY] State of the Weave Fabric State object
nl::Weave::Profiles::Security::AppKeys::GroupKeyStoreBase *GroupKeyStore;
#if WEAVE_CONFIG_SECURITY_TEST_MODE
uint64_t DebugFabricId;
bool LogKeys;
bool UseTestKey; // DEPRECATED -- Temporarily retained for API compaibility
bool AutoCreateKeys; // DEPRECATED -- Temporarily retained for API compaibility
#endif
#if WEAVE_CONFIG_ENABLE_TARGETED_LISTEN
IPAddress ListenIPv4Addr;
IPAddress ListenIPv6Addr;
#endif
WEAVE_ERROR Init(void);
WEAVE_ERROR Init(nl::Weave::Profiles::Security::AppKeys::GroupKeyStoreBase *groupKeyStore);
WEAVE_ERROR Shutdown(void);
WEAVE_ERROR AllocSessionKey(uint64_t peerNodeId, uint16_t keyId, WeaveConnection *boundCon, WeaveSessionKey *& sessionKey);
WEAVE_ERROR SetSessionKey(uint16_t keyId, uint64_t peerNodeId, uint8_t encType, WeaveAuthMode authMode, const WeaveEncryptionKey *encKey);
void SetSessionKey(WeaveSessionKey *sessionKey, uint8_t encType, WeaveAuthMode authMode, const WeaveEncryptionKey *encKey);
WEAVE_ERROR GetSessionKey(uint16_t keyId, uint64_t peerNodeId, WeaveSessionKey *& outSessionKey);
WEAVE_ERROR FindSessionKey(uint16_t keyId, uint64_t peerNodeId, bool create, WeaveSessionKey *& retRec);
WEAVE_ERROR RemoveSessionKey(uint16_t keyId, uint64_t peerNodeId);
void RemoveSessionKey(WeaveSessionKey *sessionKey, bool wasIdle = false);
bool RemoveIdleSessionKeys();
WeaveSessionKey *FindSharedSession(uint64_t terminatingNodeId, WeaveAuthMode authMode, uint8_t encType);
bool IsSharedSession(uint16_t keyId, uint64_t peerNodeId);
WEAVE_ERROR AddSharedSessionEndNode(uint64_t endNodeId, uint64_t terminatingNodeId, uint16_t keyId);
WEAVE_ERROR AddSharedSessionEndNode(WeaveSessionKey *sessionKey, uint64_t endNodeId);
WEAVE_ERROR GetSharedSessionEndNodeIds(const WeaveSessionKey *sessionKey, uint64_t *endNodeIds,
uint8_t endNodeIdsBufSize, uint8_t& endNodeIdsCount);
WEAVE_ERROR GetSessionState(uint64_t remoteNodeId, uint16_t keyId, uint8_t encType, WeaveConnection *con, WeaveSessionState& outSessionState);
/**
* This method returns an IPAddress representing the ULA of a Thread Node.
* This variant allows for a subnet to be specified.
*
* @param[in] nodeId The Node ID number of the node in question.
*
* @param[in] subnet The desired subnet of the ULA.
*
* @retval IPAddress An IPAddress object.
*/
IPAddress SelectNodeAddress(uint64_t nodeId, uint16_t subnet) const;
/**
* This method returns an IPAddress representing the ULA of a Thread Node.
* This variant uses the fabric state's default subnet.
*
* @param[in] nodeId The Node ID number of the node in question.
*
* @retval IPAddress An IPAddress object.
*/
IPAddress SelectNodeAddress(uint64_t nodeId) const;
/**
* This method returns true if the given IP Address represents a node
* within the local fabric.
*
* @param[in] addr The IP Address being checked.
*
* @retval bool Whether or not the IP represents a
* node in the local fabric.
*/
bool IsFabricAddress(const IPAddress &addr) const;
WEAVE_ERROR GetPassword(uint8_t pwSrc, const char *& ps, uint16_t& pwLen);
WEAVE_ERROR CreateFabric(void);
void ClearFabricState(void);
WEAVE_ERROR GetFabricState(uint8_t *buf, uint32_t bufSize, uint32_t &fabricStateLen);
WEAVE_ERROR JoinExistingFabric(const uint8_t *fabricState, uint32_t fabricStateLen);
void HandleConnectionClosed(WeaveConnection *con);
/**
* This method sets the delegate object.
* The callback methods of delegate are invoked whenever the FabricId is changed,
* i.e., when we join/create a fabric, or when we leave a fabric (clear fabric state)
*
* If the delegate is previously set, then a second call to this method will overwrite
* the previous delegate.
*
* @param[in] aDelegate The delegate object. It can be NULL if no
* delegate is required.
* @retval None.
*/
void SetDelegate(FabricStateDelegate *aDelegate);
#if WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC
void OnMsgCounterSyncRespRcvd(uint64_t peerNodeId, uint32_t peerMsgId, uint32_t requestorMsgCounter);
void OnMsgCounterSyncReqSent(uint32_t messageId);
/**
* This method returns true if at least one peer's message counter
* synchronization request is in progress.
*
* @retval bool Whether or not peer's message counter synchronization
* is in progress.
*/
bool IsMsgCounterSyncReqInProgress(void)
{
return (MsgCounterSyncStatus & kFlag_ReqInProgress) != 0;
}
WEAVE_ERROR GetMsgEncKeyIdForAppGroup(uint32_t appGroupGlobalId, uint32_t rootKeyId, bool useRotatingKey, uint32_t& keyId);
WEAVE_ERROR CheckMsgEncForAppGroup(const WeaveMessageInfo *msgInfo, uint32_t appGroupGlobalId, uint32_t rootKeyId, bool requireRotatingKey);
#endif // WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC
private:
PeerIndexType PeerCount;
MonotonicallyIncreasingCounter NextUnencUDPMsgId;
MonotonicallyIncreasingCounter NextUnencTCPMsgId;
WeaveSessionKey SessionKeys[WEAVE_CONFIG_MAX_SESSION_KEYS];
#if WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC
PersistedCounter NextGroupKeyMsgId;
// The earliest message id that will be considered "fresh" in a message counter synchronization
// response, but only if kReqInProgressFlag is true when the response is received.
uint32_t GroupKeyMsgIdFreshWindowStart;
// Status flags to control message counter synchronization protocol flow and the fresh window width.
uint16_t MsgCounterSyncStatus;
enum
{
// Flag indicates if there may be outstanding request for which we may receive a response.
kFlag_ReqInProgress = 0x8000,
// Flag indicates if request has been sent in the current timeout period.
kFlag_ReqSentThisPeriod = 0x4000,
// Mask for fresh group message counter window width.
kMask_GroupKeyMsgIdFreshWindowWidth = 0x3FFF,
};
WeaveMsgEncryptionKeyCache AppKeyCache;
#endif // WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC
struct
{
uint64_t NodeId[WEAVE_CONFIG_MAX_PEER_NODES];
uint32_t MaxUnencUDPMsgIdRcvd[WEAVE_CONFIG_MAX_PEER_NODES];
#if WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC
uint32_t MaxGroupKeyMsgIdRcvd[WEAVE_CONFIG_MAX_PEER_NODES];
WeaveSessionState::ReceiveFlagsType GroupKeyRcvFlags[WEAVE_CONFIG_MAX_PEER_NODES];
#endif
WeaveSessionState::ReceiveFlagsType UnencRcvFlags[WEAVE_CONFIG_MAX_PEER_NODES];
// Array of peer indexes in sorted order from most- to least- recently used.
PeerIndexType MostRecentlyUsedIndexes[WEAVE_CONFIG_MAX_PEER_NODES];
} PeerStates;
FabricStateDelegate *Delegate;
// This structure contains information about shared session end node.
struct SharedSessionEndNode
{
uint64_t EndNodeId;
WeaveSessionKey *SessionKey;
};
// Record of all active shared session end nodes.
SharedSessionEndNode SharedSessionsNodes[WEAVE_CONFIG_MAX_SHARED_SESSIONS_END_NODES];
bool FindSharedSessionEndNode(uint64_t endNodeId, const WeaveSessionKey *sessionKey);
#if WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC
void StartMsgCounterSyncTimer(void);
static void OnMsgCounterSyncRespTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError);
#endif
bool FindOrAllocPeerEntry(uint64_t peerNodeId, bool allocEntry, PeerIndexType& retPeerIndex);
WEAVE_ERROR FindMsgEncAppKey(uint16_t keyId, uint8_t encType, WeaveMsgEncryptionKey *& retRec);
WEAVE_ERROR DeriveMsgEncAppKey(uint32_t keyId, uint8_t encType, WeaveMsgEncryptionKey & appKey, uint32_t& appGroupGlobalId);
};
#if WEAVE_CONFIG_SECURITY_TEST_MODE
enum
{
kMaxEncKeyStringSize = WeaveEncryptionKey_AES128CTRSHA1::DataKeySize * 2 // Hex digits for data key
+ 1 // Field separator (,)
+ WeaveEncryptionKey_AES128CTRSHA1::IntegrityKeySize * 2 // Hex digits for integrity key
+ 1, // Null terminator
};
extern void WeaveEncryptionKeyToString(uint8_t encType, const WeaveEncryptionKey& key, char *buf, size_t bufSize);
#endif // WEAVE_CONFIG_SECURITY_TEST_MODE
} // namespace nl
} // namespace Weave
#endif // WEAVE_FABRIC_STATE_H