blob: 62e13c5f687c897aa38165f24a1e97d1ebfb1cf8 [file] [log] [blame]
/*
*
* Copyright (c) 2016-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 constant enumerations for all Weave key types,
* key flags, key ID fields, and helper API functions.
*
*/
#ifndef WEAVEKEYS_H_
#define WEAVEKEYS_H_
namespace nl {
namespace Weave {
/**
* @class WeaveKeyId
*
* @brief
* The definition of the Weave Key identifier. This class contains
* key types, key flags, key ID fields definition, and API functions.
*
*/
class WeaveKeyId
{
private:
/**
* @brief
* Private Weave key ID fields, flags, and types.
*/
enum
{
kMask_KeyFlags = 0xF0000000, /**< Weave key flag field mask. */
kMask_KeyType = 0x0FFFF000, /**< Weave key type field mask. */
kMask_KeyNumber = 0x00000FFF, /**< Weave 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 Weave key ID fields, flags, and types.
*/
enum
{
/**
* @brief Weave key types used for Weave 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 Weave message.
* @{
*/
kType_None = 0x00000000, /**< Weave 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 Weave key types (other than Weave 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 Weave 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 Weave global key IDs.
* @{
*/
/** Unspecified Weave key ID. */
kNone = kType_None | 0x0000,
/** Weave 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 Weave key type of the specified key ID.
*
* @param[in] keyId Weave 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 Weave 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 Weave 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 Weave 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 Weave 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 Weave 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 Weave 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 Weave 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)
{
return kType_Session | (sessionKeyNumber & kMask_KeyNumber);
}
/**
* Construct fabric key ID given fabric key number.
*
* @param[in] fabricKeyNumber Fabric key number.
* @return fabric key ID.
*
*/
static uint16_t MakeGeneralKeyId(uint16_t generalKeyNumber)
{
return kType_General | (generalKeyNumber & kMask_KeyNumber);
}
/**
* Get application group root key ID that was used to derive specified application key.
*
* @param[in] keyId Weave 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 Weave 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 Weave 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 Weave 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 Weave 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 Weave 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 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 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 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 Weave 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 IsMessageEncryptionKeyId(uint32_t keyId, bool allowLogicalKeys = true);
static bool IsSameKeyOrGroup(uint32_t keyId1, uint32_t keyId2);
static const char *DescribeKey(uint32_t keyId);
};
} // namespace Weave
} // namespace nl
#endif /* WEAVEKEYS_H_ */