/*
 *
 *    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 implements Weave key types helper functions.
 *
 */

#include <Weave/Core/WeaveCore.h>
#include "WeaveKeyIds.h"
#include <Weave/Support/CodeUtils.h>

namespace nl {
namespace Weave {

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

/**
 *  Determine whether the specified application group key ID uses "current" epoch key.
 *
 *  @param[in]   keyId     Weave application group key identifier.
 *  @return      true      if the keyId indicates usage of the current epoch key.
 *
 */
bool WeaveKeyId::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     Weave application group key identifier.
 *  @return      true      if the keyId incorporates root key.
 *
 */
bool WeaveKeyId::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     Weave application group key identifier.
 *  @return      true      if the keyId incorporates group master key.
 *
 */
bool WeaveKeyId::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 WeaveKeyId::MakeAppKeyId(uint32_t keyType, uint32_t rootKeyId, uint32_t epochKeyId,
                                  uint32_t appGroupMasterKeyId, bool useCurrentEpochKey)
{
    return (keyType |
            (rootKeyId & kMask_RootKeyNumber) |
            (appGroupMasterKeyId & kMask_GroupLocalNumber) |
            (useCurrentEpochKey ? 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 WeaveKeyId::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 WeaveKeyId::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 WeaveKeyId::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 WeaveKeyId::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 WeaveKeyId::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                 Weave key ID.
 *  @return      true                  if key ID value is valid.
 *
 */
bool WeaveKeyId::IsValidKeyId(uint32_t keyId)
{
    bool retval;
    int usedBits = kMask_KeyType;

    switch (GetType(keyId)) {
    case kType_None:
        ExitNow(retval = 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:
        ExitNow(retval = false);
    }

    if (IncorporatesRootKey(keyId))
    {
        int rootKeyId = GetRootKeyId(keyId);
        VerifyOrExit(rootKeyId == kFabricRootKey ||
                     rootKeyId == kClientRootKey ||
                     rootKeyId == kServiceRootKey, retval = false);
    }

    retval = (keyId & ~usedBits) == 0;

exit:
    return retval;
}

/**
 *  Determine whether a given key ID identifies a key that is suitable for Weave message encryption.
 *
 *  @param[in]   keyId                 Weave 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 Weave messages.
 *
 */
bool WeaveKeyId::IsMessageEncryptionKeyId(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 WeaveKeyId::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 Weave key identifier with a descriptive string.
 *
 *  @param[in]   keyId     Weave 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 *WeaveKeyId::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 Weave
} // namespace nl
