| /* |
| * |
| * Copyright (c) 2020 Project CHIP Authors |
| * Copyright (c) 2016-2017 Nest Labs, Inc. |
| * |
| * 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 constant enumerations for all CHIP key types, |
| * key flags, key ID fields, and helper API functions. |
| * |
| */ |
| |
| #pragma once |
| |
| #include <limits.h> |
| #include <stdint.h> |
| |
| namespace chip { |
| |
| /** |
| * @class ChipKeyId |
| * |
| * @brief |
| * The definition of the CHIP Key identifier. This class contains |
| * key types, key flags, key ID fields definition, and API functions. |
| * |
| */ |
| class ChipKeyId |
| { |
| private: |
| /** |
| * @brief |
| * Private CHIP key ID fields, flags, and types. |
| */ |
| enum |
| { |
| kMask_KeyFlags = 0xF0000000, /**< CHIP key flag field mask. */ |
| kMask_KeyType = 0x0FFFF000, /**< CHIP key type field mask. */ |
| kMask_KeyNumber = 0x00000FFF, /**< CHIP key number field mask. */ |
| kMask_RootKeyNumber = 0x00000C00, /**< Application group root key number field mask. */ |
| kMask_EpochKeyNumber = 0x00000380, /**< Application group epoch key number field mask. */ |
| kMask_GroupLocalNumber = 0x0000007F, /**< Application group local number field mask. */ |
| |
| kShift_RootKeyNumber = 10, /**< Application group root key number field shift. */ |
| kShift_EpochKeyNumber = 7, /**< Application group epoch key number field shift. */ |
| kShift_GroupLocalNumber = 0, /**< Application group local number field shift. */ |
| |
| kFlag_UseCurrentEpochKey = 0x80000000, /**< Used to indicate that the key is of logical current type. */ |
| |
| kTypeModifier_IncorporatesEpochKey = 0x00001000, /**< Used to indicate that the key incorporates group epoch key. */ |
| }; |
| |
| public: |
| /** |
| * @brief |
| * Public CHIP key ID fields, flags, and types. |
| */ |
| enum |
| { |
| /** |
| * @brief CHIP key types used for CHIP message encryption. |
| * |
| * @note 16 (out of 32) most significant bits of the message encryption key |
| * type should be zero because only 16 least significant bits of the ID |
| * are encoded in the CHIP message. |
| * @{ |
| */ |
| kType_None = 0x00000000, /**< CHIP message is unencrypted. */ |
| kType_General = 0x00001000, /**< General key type. */ |
| kType_Session = 0x00002000, /**< Session key type. */ |
| kType_AppStaticKey = 0x00004000, /**< Application static key type. */ |
| /** Application rotating key type. */ |
| kType_AppRotatingKey = kType_AppStaticKey | kTypeModifier_IncorporatesEpochKey, |
| /** @} */ |
| |
| /** |
| * @brief CHIP key types (other than CHIP message encryption types). |
| * |
| * @note 16 (out of 32) most significant bits of these types cannot be all zeros, |
| * because these values are reserved for the CHIP message encryption keys only. |
| * @{ |
| */ |
| |
| /** |
| * @brief Constituent group key types. |
| * @{ |
| */ |
| /** Application group root key type. */ |
| kType_AppRootKey = 0x00010000, |
| /** Application group epoch key type. */ |
| kType_AppEpochKey = 0x00020000 | kTypeModifier_IncorporatesEpochKey, |
| /** Application group master key type. */ |
| kType_AppGroupMasterKey = 0x00030000, |
| /** Application group intermediate key type. */ |
| kType_AppIntermediateKey = kType_AppRootKey | kTypeModifier_IncorporatesEpochKey, |
| /** @} */ |
| |
| /** |
| * @brief CHIP global key IDs. |
| * @{ |
| */ |
| /** Unspecified CHIP key ID. */ |
| kNone = kType_None | 0x0000, |
| /** CHIP fabric secret ID. */ |
| kFabricSecret = kType_General | 0x0001, |
| /** Fabric root key ID. */ |
| kFabricRootKey = kType_AppRootKey | (0 << kShift_RootKeyNumber), |
| /** Client root key ID. */ |
| kClientRootKey = kType_AppRootKey | (1 << kShift_RootKeyNumber), |
| /** Service root key ID. */ |
| kServiceRootKey = kType_AppRootKey | (2 << kShift_RootKeyNumber), |
| /** @} */ |
| |
| /** |
| * @brief Maximum values for key ID subfields. |
| * @{ |
| */ |
| kKeyNumber_Max = kMask_KeyNumber, |
| kRootKeyNumber_Max = (kMask_RootKeyNumber >> kShift_RootKeyNumber), |
| kEpochKeyNumber_Max = (kMask_EpochKeyNumber >> kShift_EpochKeyNumber), |
| kGroupLocalNumber_Max = (kMask_GroupLocalNumber >> kShift_GroupLocalNumber), |
| /** @} */ |
| }; |
| |
| /** |
| * Get CHIP key type of the specified key ID. |
| * |
| * @param[in] keyId CHIP key identifier. |
| * @return type of the key ID. |
| * |
| */ |
| static uint32_t GetType(uint32_t keyId) { return keyId & kMask_KeyType; } |
| |
| /** |
| * Determine whether the specified key ID is of a general type. |
| * |
| * @param[in] keyId CHIP key identifier. |
| * @return true if the keyId has General type. |
| * |
| */ |
| static bool IsGeneralKey(uint32_t keyId) { return GetType(keyId) == kType_General; } |
| |
| /** |
| * Determine whether the specified key ID is of a session type. |
| * |
| * @param[in] keyId CHIP key identifier. |
| * @return true if the keyId of a session type. |
| * |
| */ |
| static bool IsSessionKey(uint32_t keyId) { return GetType(keyId) == kType_Session; } |
| |
| /** |
| * Determine whether the specified key ID is of an application static type. |
| * |
| * @param[in] keyId CHIP key identifier. |
| * @return true if the keyId of an application static type. |
| * |
| */ |
| static bool IsAppStaticKey(uint32_t keyId) { return GetType(keyId) == kType_AppStaticKey; } |
| |
| /** |
| * Determine whether the specified key ID is of an application rotating type. |
| * |
| * @param[in] keyId CHIP key identifier. |
| * @return true if the keyId of an application rotating type. |
| * |
| */ |
| static bool IsAppRotatingKey(uint32_t keyId) { return GetType(keyId) == kType_AppRotatingKey; } |
| |
| static bool IsAppGroupKey(uint32_t keyId); |
| |
| /** |
| * Determine whether the specified key ID is of an application root key type. |
| * |
| * @param[in] keyId CHIP key identifier. |
| * @return true if the keyId of an application root key type. |
| * |
| */ |
| static bool IsAppRootKey(uint32_t keyId) { return GetType(keyId) == kType_AppRootKey; } |
| |
| /** |
| * Determine whether the specified key ID is of an application epoch key type. |
| * |
| * @param[in] keyId CHIP key identifier. |
| * @return true if the keyId of an application epoch key type. |
| * |
| */ |
| static bool IsAppEpochKey(uint32_t keyId) { return GetType(keyId) == kType_AppEpochKey; } |
| |
| /** |
| * Determine whether the specified key ID is of an application group master key type. |
| * |
| * @param[in] keyId CHIP key identifier. |
| * @return true if the keyId of an application group master key type. |
| * |
| */ |
| static bool IsAppGroupMasterKey(uint32_t keyId) { return GetType(keyId) == kType_AppGroupMasterKey; } |
| |
| /** |
| * Construct session key ID given session key number. |
| * |
| * @param[in] sessionKeyNumber Session key number. |
| * @return session key ID. |
| * |
| */ |
| static uint16_t MakeSessionKeyId(uint16_t sessionKeyNumber) |
| { |
| static_assert(kType_Session <= UINT16_MAX, "We'll overflow"); |
| return static_cast<uint16_t>(kType_Session | (sessionKeyNumber & kMask_KeyNumber)); |
| } |
| |
| /** |
| * Construct general key ID given general key number. |
| * |
| * @param[in] generalKeyNumber General key number. |
| * @return general key ID. |
| * |
| */ |
| static uint16_t MakeGeneralKeyId(uint16_t generalKeyNumber) |
| { |
| static_assert(kType_General <= UINT16_MAX, "We'll overflow"); |
| return static_cast<uint16_t>(kType_General | (generalKeyNumber & kMask_KeyNumber)); |
| } |
| |
| /** |
| * Get application group root key ID that was used to derive specified application key. |
| * |
| * @param[in] keyId CHIP application group key identifier. |
| * @return root key ID. |
| * |
| */ |
| static uint32_t GetRootKeyId(uint32_t keyId) { return kType_AppRootKey | (keyId & kMask_RootKeyNumber); } |
| |
| /** |
| * Get application group epoch key ID that was used to derive specified application key. |
| * |
| * @param[in] keyId CHIP application group key identifier. |
| * @return epoch key ID. |
| * |
| */ |
| static uint32_t GetEpochKeyId(uint32_t keyId) { return kType_AppEpochKey | (keyId & kMask_EpochKeyNumber); } |
| |
| /** |
| * Get application group master key ID that was used to derive specified application key. |
| * |
| * @param[in] keyId CHIP application group key identifier. |
| * @return application group master key ID. |
| * |
| */ |
| static uint32_t GetAppGroupMasterKeyId(uint32_t keyId) { return kType_AppGroupMasterKey | (keyId & kMask_GroupLocalNumber); } |
| |
| /** |
| * Get application group root key number that was used to derive specified application key. |
| * |
| * @param[in] keyId CHIP application group key identifier. |
| * @return root key number. |
| * |
| */ |
| static uint8_t GetRootKeyNumber(uint32_t keyId) { return (keyId & kMask_RootKeyNumber) >> kShift_RootKeyNumber; } |
| |
| /** |
| * Get application group epoch key number that was used to derive specified application key. |
| * |
| * @param[in] keyId CHIP application group key identifier. |
| * @return epoch key number. |
| * |
| */ |
| static uint8_t GetEpochKeyNumber(uint32_t keyId) { return (keyId & kMask_EpochKeyNumber) >> kShift_EpochKeyNumber; } |
| |
| /** |
| * Get application group local number that was used to derive specified application key. |
| * |
| * @param[in] keyId CHIP application group key identifier. |
| * @return application group local number. |
| * |
| */ |
| static uint8_t GetAppGroupLocalNumber(uint32_t keyId) { return (keyId & kMask_GroupLocalNumber) >> kShift_GroupLocalNumber; } |
| |
| /** |
| * Construct application group root key ID given root key number. |
| * |
| * @param[in] rootKeyNumber Root key number. |
| * @return root key ID. |
| * |
| */ |
| static uint32_t MakeRootKeyId(uint8_t rootKeyNumber) |
| { |
| return static_cast<uint32_t>(kType_AppRootKey | (rootKeyNumber << kShift_RootKeyNumber)); |
| } |
| |
| /** |
| * Construct application group root key ID given epoch key number. |
| * |
| * @param[in] epochKeyNumber Epoch key number. |
| * @return epoch key ID. |
| * |
| */ |
| static uint32_t MakeEpochKeyId(uint8_t epochKeyNumber) |
| { |
| return static_cast<uint32_t>(kType_AppEpochKey | (epochKeyNumber << kShift_EpochKeyNumber)); |
| } |
| |
| /** |
| * Construct application group master key ID given application group local number. |
| * |
| * @param[in] appGroupLocalNumber Application group local number. |
| * @return application group master key ID. |
| * |
| */ |
| static uint32_t MakeAppGroupMasterKeyId(uint8_t appGroupLocalNumber) |
| { |
| return static_cast<uint32_t>(kType_AppGroupMasterKey | (appGroupLocalNumber << kShift_GroupLocalNumber)); |
| } |
| |
| /** |
| * Convert application group key ID to application current key ID. |
| * |
| * @param[in] keyId Application key ID. |
| * @return application current key ID. |
| * |
| */ |
| static uint32_t ConvertToCurrentAppKeyId(uint32_t keyId) { return (keyId & ~kMask_EpochKeyNumber) | kFlag_UseCurrentEpochKey; } |
| |
| /** |
| * Determine whether the specified application group key ID incorporates epoch key. |
| * |
| * @param[in] keyId CHIP application group key identifier. |
| * @return true if the keyId incorporates epoch key. |
| * |
| */ |
| static bool IncorporatesEpochKey(uint32_t keyId) { return (keyId & kTypeModifier_IncorporatesEpochKey) != 0; } |
| |
| static bool UsesCurrentEpochKey(uint32_t keyId); |
| static bool IncorporatesRootKey(uint32_t keyId); |
| static bool IncorporatesAppGroupMasterKey(uint32_t keyId); |
| |
| static uint32_t MakeAppKeyId(uint32_t keyType, uint32_t rootKeyId, uint32_t epochKeyId, uint32_t appGroupMasterKeyId, |
| bool useCurrentEpochKey); |
| static uint32_t MakeAppIntermediateKeyId(uint32_t rootKeyId, uint32_t epochKeyId, bool useCurrentEpochKey); |
| static uint32_t MakeAppRotatingKeyId(uint32_t rootKeyId, uint32_t epochKeyId, uint32_t appGroupMasterKeyId, |
| bool useCurrentEpochKey); |
| static uint32_t MakeAppStaticKeyId(uint32_t rootKeyId, uint32_t appGroupMasterKeyId); |
| static uint32_t ConvertToStaticAppKeyId(uint32_t keyId); |
| static uint32_t UpdateEpochKeyId(uint32_t keyId, uint32_t epochKeyId); |
| |
| static bool IsValidKeyId(uint32_t keyId); |
| static bool IsMessageSessionId(uint32_t keyId, bool allowLogicalKeys = true); |
| static bool IsSameKeyOrGroup(uint32_t keyId1, uint32_t keyId2); |
| static const char * DescribeKey(uint32_t keyId); |
| }; |
| |
| } // namespace chip |