/*
 *
 *    Copyright (c) 2020-2021 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 implements CHIP key types helper functions.
 *
 */
#include "CHIPKeyIds.h"

#include <lib/core/CHIPCore.h>
#include <lib/support/CodeUtils.h>

namespace chip {

/**
 *  Determine whether the specified key ID belongs to one of the application
 *  group key types (static or rotating).
 *
 *  @param[in]   keyId     CHIP key identifier.
 *  @return      true      if the keyId is of rotating or static key type.
 *
 */
bool ChipKeyId::IsAppGroupKey(uint32_t keyId)
{
    return IsAppStaticKey(keyId) || IsAppRotatingKey(keyId);
}

/**
 *  Determine whether the specified application group key ID uses "current" epoch key.
 *
 *  @param[in]   keyId     CHIP application group key identifier.
 *  @return      true      if the keyId indicates usage of the current epoch key.
 *
 */
bool ChipKeyId::UsesCurrentEpochKey(uint32_t keyId)
{
    return IncorporatesEpochKey(keyId) && ((keyId & kFlag_UseCurrentEpochKey) != 0);
}

/**
 *  Determine whether the specified application group key ID incorporates root key.
 *
 *  @param[in]   keyId     CHIP application group key identifier.
 *  @return      true      if the keyId incorporates root key.
 *
 */
bool ChipKeyId::IncorporatesRootKey(uint32_t keyId)
{
    uint32_t keyType = GetType(keyId);
    return keyType == kType_AppStaticKey || keyType == kType_AppRotatingKey || keyType == kType_AppRootKey ||
        keyType == kType_AppIntermediateKey;
}

/**
 *  Determine whether the specified application group key ID incorporates group master key.
 *
 *  @param[in]   keyId     CHIP application group key identifier.
 *  @return      true      if the keyId incorporates group master key.
 *
 */
bool ChipKeyId::IncorporatesAppGroupMasterKey(uint32_t keyId)
{
    uint32_t keyType = GetType(keyId);
    return keyType == kType_AppStaticKey || keyType == kType_AppRotatingKey || keyType == kType_AppGroupMasterKey;
}

/**
 *  Construct application group key ID given constituent key IDs and other information.
 *
 *  @param[in]   keyType               Derived application group key type.
 *  @param[in]   rootKeyId             Root key ID used to derive application group key.
 *  @param[in]   epochKeyId            Epoch key ID used to derive application group key.
 *  @param[in]   appGroupMasterKeyId   Application group master key ID used to derive
 *                                     application group key.
 *  @param[in]   useCurrentEpochKey    A boolean flag that indicates if key should be derived
 *                                     using "current" epoch key.
 *  @return      application group key ID.
 *
 */
uint32_t ChipKeyId::MakeAppKeyId(uint32_t keyType, uint32_t rootKeyId, uint32_t epochKeyId, uint32_t appGroupMasterKeyId,
                                 bool useCurrentEpochKey)
{
    return (keyType | (rootKeyId & kMask_RootKeyNumber) | (appGroupMasterKeyId & kMask_GroupLocalNumber) |
            (useCurrentEpochKey ? static_cast<uint32_t>(kFlag_UseCurrentEpochKey) : (epochKeyId & kMask_EpochKeyNumber)));
}

/**
 *  Construct application intermediate key ID given constituent key IDs.
 *
 *  @param[in]   rootKeyId             Root key ID used to derive application intermediate key.
 *  @param[in]   epochKeyId            Epoch key ID used to derive application intermediate key.
 *  @param[in]   useCurrentEpochKey    A boolean flag that indicates if key should be derived
 *                                     using "current" epoch key.
 *  @return      application intermediate key ID.
 *
 */
uint32_t ChipKeyId::MakeAppIntermediateKeyId(uint32_t rootKeyId, uint32_t epochKeyId, bool useCurrentEpochKey)
{
    return MakeAppKeyId(kType_AppIntermediateKey, rootKeyId, epochKeyId, kNone, useCurrentEpochKey);
}

/**
 *  Construct application rotating key ID given constituent key IDs and other information.
 *
 *  @param[in]   rootKeyId             Root key ID used to derive application rotating key.
 *  @param[in]   epochKeyId            Epoch key ID used to derive application rotating key.
 *  @param[in]   appGroupMasterKeyId   Application group master key ID used to derive
 *                                     application rotating key.
 *  @param[in]   useCurrentEpochKey    A boolean flag that indicates if key should be derived
 *                                     using "current" epoch key.
 *  @return      application rotating key ID.
 *
 */
uint32_t ChipKeyId::MakeAppRotatingKeyId(uint32_t rootKeyId, uint32_t epochKeyId, uint32_t appGroupMasterKeyId,
                                         bool useCurrentEpochKey)
{
    return MakeAppKeyId(kType_AppRotatingKey, rootKeyId, epochKeyId, appGroupMasterKeyId, useCurrentEpochKey);
}

/**
 *  Construct application static key ID given constituent key IDs.
 *
 *  @param[in]   rootKeyId             Root key ID used to derive application static key.
 *  @param[in]   appGroupMasterKeyId   Application group master key ID used to derive
 *                                     application static key.
 *  @return      application static key ID.
 *
 */
uint32_t ChipKeyId::MakeAppStaticKeyId(uint32_t rootKeyId, uint32_t appGroupMasterKeyId)
{
    return MakeAppKeyId(kType_AppStaticKey, rootKeyId, kNone, appGroupMasterKeyId, false);
}

/**
 *  Convert application key ID to application static key ID.
 *
 *  @param[in]   keyId                 Application key ID.
 *  @return      application static key ID.
 *
 */
uint32_t ChipKeyId::ConvertToStaticAppKeyId(uint32_t keyId)
{
    return MakeAppStaticKeyId(GetRootKeyId(keyId), GetAppGroupMasterKeyId(keyId));
}

/**
 *  Update application group key ID with new epoch key number.
 *
 *  @param[in]   keyId                 Application key ID.
 *  @param[in]   epochKeyId            Epoch key ID, which will be used in construction
 *                                     of the updated application key ID.
 *  @return      application key ID.
 *
 */
uint32_t ChipKeyId::UpdateEpochKeyId(uint32_t keyId, uint32_t epochKeyId)
{
    return (keyId & ~(kFlag_UseCurrentEpochKey | kMask_EpochKeyNumber)) | (epochKeyId & kMask_EpochKeyNumber);
}

/**
 *  Determine whether key identifier has valid (legal) value.
 *
 *  @param[in]   keyId                 CHIP key ID.
 *  @return      true                  if key ID value is valid.
 *
 */
bool ChipKeyId::IsValidKeyId(uint32_t keyId)
{
    unsigned int usedBits = kMask_KeyType;

    switch (GetType(keyId))
    {
    case kType_None:
        return false;
    case kType_General:
    case kType_Session:
        usedBits |= kMask_KeyNumber;
        break;
    case kType_AppStaticKey:
        usedBits |= kMask_RootKeyNumber | kMask_GroupLocalNumber;
        break;
    case kType_AppRotatingKey:
        usedBits |= kFlag_UseCurrentEpochKey | kMask_RootKeyNumber | kMask_GroupLocalNumber;
        if (!UsesCurrentEpochKey(keyId))
        {
            usedBits |= kMask_EpochKeyNumber;
        }
        break;
    case kType_AppRootKey:
        usedBits |= kMask_RootKeyNumber;
        break;
    case kType_AppIntermediateKey:
        usedBits |= kFlag_UseCurrentEpochKey | kMask_RootKeyNumber;
        if (!UsesCurrentEpochKey(keyId))
        {
            usedBits |= kMask_EpochKeyNumber;
        }
        break;
    case kType_AppEpochKey:
        usedBits |= kFlag_UseCurrentEpochKey;
        if (!UsesCurrentEpochKey(keyId))
        {
            usedBits |= kMask_EpochKeyNumber;
        }
        break;
    case kType_AppGroupMasterKey:
        usedBits |= kMask_GroupLocalNumber;
        break;
    default:
        return false;
    }

    if (IncorporatesRootKey(keyId))
    {
        uint32_t rootKeyId = GetRootKeyId(keyId);
        VerifyOrReturnError(rootKeyId == kFabricRootKey || rootKeyId == kClientRootKey || rootKeyId == kServiceRootKey, false);
    }

    return (keyId & ~usedBits) == 0;
}

/**
 *  Determine whether a given key ID identifies a key that is suitable for CHIP message encryption.
 *
 *  @param[in]   keyId                 CHIP key ID.
 *  @param[in]   allowLogicalKeys      Specifies whether logical keys IDs (such as the "current" rotating key)
 *                                     should be considered suitable for message encryption.
 *  @return      true                  If the identified key can be used to encrypt CHIP messages.
 *
 */
bool ChipKeyId::IsMessageSessionId(uint32_t keyId, bool allowLogicalKeys)
{
    switch (GetType(keyId))
    {
    case kType_Session:
    case kType_AppStaticKey:
        return true;
    case kType_AppRotatingKey:
        return allowLogicalKeys || !UsesCurrentEpochKey(keyId);
    default:
        return false;
    }
}

/**
 * Determines whether two key IDs identify the same key, or in the case of rotating keys, the same
 * group of keys independent of any particular epoch.
 *
 *  @param[in]   keyId1                The first key ID to test.
 *  @param[in]   keyId2                The second key ID to test.
 *
 *  @return                            True if the keys IDs represent the same key.
 */
bool ChipKeyId::IsSameKeyOrGroup(uint32_t keyId1, uint32_t keyId2)
{
    enum
    {
        kIgnoreEpochMask = ~(kMask_EpochKeyNumber | kFlag_UseCurrentEpochKey)
    };

    // If the key ids are identical then they represent the same key.
    if (keyId1 == keyId2)
        return true;

    // For rotating keys, treat the key ids as the same if they differ only in their choice of epoch
    // key number.
    if (IncorporatesEpochKey(keyId1) && !IsAppEpochKey(keyId1) && (keyId1 & kIgnoreEpochMask) == (keyId2 & kIgnoreEpochMask))
        return true;

    // Otherwise the key ids identify different keys.
    return false;
}

/**
 *  Decode a CHIP key identifier with a descriptive string.
 *
 *  @param[in]   keyId     CHIP key ID to decode and for which to return
 *                         a descriptive string.
 *
 *  @return  A pointer to a NULL-terminated string describing the specified key ID.
 *
 */
const char * ChipKeyId::DescribeKey(uint32_t keyId)
{
    const char * retval;

    switch (GetType(keyId))
    {
    case kType_None:
        retval = "No Key";
        break;
    case kType_General:
        if (keyId == kFabricSecret)
        {
            retval = "Fabric Secret";
        }
        else
        {
            retval = "Other General Key";
        }
        break;
    case kType_Session:
        retval = "Session Key";
        break;
    case kType_AppStaticKey:
        retval = "Application Static Key";
        break;
    case kType_AppRotatingKey:
        retval = "Application Rotating Key";
        break;
    case kType_AppRootKey:
        if (keyId == kFabricRootKey)
        {
            retval = "Fabric Root Key";
        }
        else if (keyId == kClientRootKey)
        {
            retval = "Client Root Key";
        }
        else if (keyId == kServiceRootKey)
        {
            retval = "Service Root Key";
        }
        else
        {
            retval = "Other Root Key";
        }
        break;
    case kType_AppIntermediateKey:
        retval = "Application Intermediate Key";
        break;
    case kType_AppEpochKey:
        retval = "Application Epoch Key";
        break;
    case kType_AppGroupMasterKey:
        retval = "Application Group Master Key";
        break;
    default:
        retval = "Unknown Key Type";
    }

    return retval;
}

} // namespace chip
