/*
 *
 *    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 a Wrapper for C++ implementation of pincode encryption/decryption functionality.
 *      for pin encryption.
 *
 */

#import "NLWeavePasscodeEncryptionSupport.h"
#include <Weave/Profiles/security/WeavePasscodes.h>

using namespace nl::Weave::Profiles::Security::Passcodes;

NSUInteger const NLWeavePasscode_Config1_TEST_ONLY = kPasscode_Config1_TEST_ONLY;
NSUInteger const NLWeavePasscode_Config2 = kPasscode_Config2;

UInt8 const NLWeavePasscodeEncKeyDiversifier[] = { 0x1A, 0x65, 0x5D, 0x96 };
UInt32 const NLWeavePasscodeEncKeyDiversifierSize = sizeof(NLWeavePasscodeEncKeyDiversifier);
UInt8 const NLWeavePasscodeFingerprintKeyDiversifier[] = { 0xD1, 0xA1, 0xD9, 0x6C };
UInt32 const NLWeavePasscodeFingerprintKeyDiversifierSize = sizeof(NLWeavePasscodeFingerprintKeyDiversifier);

UInt32 const NLWeavePasscodeEncryptionKeyLen = kPasscodeEncryptionKeyLen;
UInt32 const NLWeavePasscodeAuthenticationKeyLen = kPasscodeAuthenticationKeyLen;
UInt32 const NLWeavePasscodeFingerprintKeyLen = kPasscodeFingerprintKeyLen;

NSString * const NLPasscodeEncryptionSupportDomain = @"NLPasscodeEncryptionSupportDomain";

@implementation NLWeavePasscodeEncryptionSupport

#pragma mark Public Methods

+ (NSData *)encryptPasscode:(UInt8)config
                      keyId:(UInt32)keyId
                      nonce:(UInt32)nonce
                   passcode:(NSData *)passcode
                     encKey:(NSData *)encKey
                    authKey:(NSData *)authKey
             fingerprintKey:(NSData *)fingerprintKey
                      error:(NSError **)errOut
{

    if (config != NLWeavePasscode_Config1_TEST_ONLY) {
        if (![NLWeavePasscodeEncryptionSupport validateKeySize:encKey authKey:authKey fingerprintKey:fingerprintKey error:errOut]) {
            return nil;
        }
    }

    NSMutableData * encPasscodeBuff = [[NSMutableData alloc] initWithLength:kPasscodeMaxEncryptedLen];
    size_t encPasscodeLen = 0;

    WEAVE_ERROR err = EncryptPasscode(config, keyId, nonce, (unsigned char *) [passcode bytes], [passcode length],
        (unsigned char *) [encKey bytes], (unsigned char *) [authKey bytes], (unsigned char *) [fingerprintKey bytes],
        (unsigned char *) [encPasscodeBuff mutableBytes], [encPasscodeBuff length], encPasscodeLen);
    if (err != WEAVE_NO_ERROR) {
        if (errOut) {
            NSString * failureReason = [NSString stringWithFormat:NSLocalizedString(@"EncryptPasscode error: %d", @""), err];
            NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : failureReason };

            *errOut = [NSError errorWithDomain:NLPasscodeEncryptionSupportDomain
                                          code:NLPasscodeEncryptionSupportDomainEncryptionFailure
                                      userInfo:userInfo];
        }
        return nil;
    }

    [encPasscodeBuff setLength:encPasscodeLen];
    return encPasscodeBuff;
}

+ (nullable NSData *)decryptPasscode:(NSData *)encPasscode
                              config:(UInt8)config
                              encKey:(NSData *)encKey
                             authKey:(NSData *)authKey
                      fingerprintKey:(NSData *)fingerprintKey
                               error:(NSError **)errOut
{

    NSMutableData * passcodeBuff = [[NSMutableData alloc] initWithLength:kPasscodePaddedLen];
    size_t passcodeLen = 0;

    if (config != NLWeavePasscode_Config1_TEST_ONLY) {
        if (![NLWeavePasscodeEncryptionSupport validateKeySize:encKey authKey:authKey fingerprintKey:fingerprintKey error:errOut]) {
            return nil;
        }
    }

    WEAVE_ERROR err = DecryptPasscode((unsigned char *) [encPasscode bytes], [encPasscode length], (unsigned char *) [encKey bytes],
        (unsigned char *) [authKey bytes], (unsigned char *) [fingerprintKey bytes], (unsigned char *) [passcodeBuff mutableBytes],
        [passcodeBuff length], passcodeLen);
    if (err != WEAVE_NO_ERROR) {

        NSString * failureReason = [NSString stringWithFormat:NSLocalizedString(@"DecryptPasscode error: %d", @""), err];
        NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : failureReason };

        *errOut = [NSError errorWithDomain:NLPasscodeEncryptionSupportDomain
                                      code:NLPasscodeEncryptionSupportDomainDecryptionFailure
                                  userInfo:userInfo];
        return nil;
    }

    [passcodeBuff setLength:passcodeLen];
    return passcodeBuff;
}

+ (BOOL)isSupportedPasscodeEncryptionConfig:(UInt8)config
{
    return IsSupportedPasscodeEncryptionConfig(config);
}

+ (BOOL)getEncryptedPasscodeConfig:(NSData *)encPasscode config:(UInt8 *)configOut error:(NSError **)errOut
{
    UInt8 config = 0;
    WEAVE_ERROR err = GetEncryptedPasscodeConfig((unsigned char *) [encPasscode bytes], [encPasscode length], config);
    if (err != WEAVE_NO_ERROR) {
        NSString * failureReason =
            [NSString stringWithFormat:NSLocalizedString(@"retrieving encrypted config error: %d", @""), err];
        NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : failureReason };

        *errOut = [NSError errorWithDomain:NLPasscodeEncryptionSupportDomain
                                      code:NLPasscodeEncryptionSupportDomainInvalidData
                                  userInfo:userInfo];
        return FALSE;
    }
    *configOut = config;

    return TRUE;
}
+ (BOOL)getEncryptedPasscodeKeyId:(NSData *)encPasscode keyId:(UInt32 *)keyIdOut error:(NSError **)errOut
{
    UInt32 keyId = 0;
    WEAVE_ERROR err = GetEncryptedPasscodeKeyId((unsigned char *) [encPasscode bytes], [encPasscode length], (uint32_t &) keyId);
    if (err != WEAVE_NO_ERROR) {
        NSString * failureReason =
            [NSString stringWithFormat:NSLocalizedString(@"retrieving encrypted config error: %d", @""), err];
        NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : failureReason };

        *errOut = [NSError errorWithDomain:NLPasscodeEncryptionSupportDomain
                                      code:NLPasscodeEncryptionSupportDomainInvalidData
                                  userInfo:userInfo];
        return FALSE;
    }
    *keyIdOut = keyId;

    return TRUE;
}

+ (BOOL)getEncryptedPasscodeNonce:(NSData *)encPasscode nonce:(UInt32 *)nonceOut error:(NSError **)errOut
{
    UInt32 nonce = 0;
    WEAVE_ERROR err = GetEncryptedPasscodeNonce((unsigned char *) [encPasscode bytes], [encPasscode length], (uint32_t &) nonce);
    if (err != WEAVE_NO_ERROR) {
        NSString * failureReason =
            [NSString stringWithFormat:NSLocalizedString(@"retrieving encrypted passcode nonce: %d", @""), err];
        NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : failureReason };

        *errOut = [NSError errorWithDomain:NLPasscodeEncryptionSupportDomain
                                      code:NLPasscodeEncryptionSupportDomainInvalidData
                                  userInfo:userInfo];
        return FALSE;
    }
    *nonceOut = nonce;

    return TRUE;
}

+ (nullable NSData *)getEncryptedPasscodeFingerprint:(NSData *)encPasscode error:(NSError **)errOut
{

    NSMutableData * fingerprint = [[NSMutableData alloc] initWithLength:kPasscodeFingerprintLen];
    size_t fingerprintLen = 0;

    WEAVE_ERROR err = GetEncryptedPasscodeFingerprint((unsigned char *) [encPasscode bytes], [encPasscode length],
        (unsigned char *) [fingerprint mutableBytes], [fingerprint length], fingerprintLen);
    if (err != WEAVE_NO_ERROR) {

        NSString * failureReason = [NSString stringWithFormat:NSLocalizedString(@"get fingerprint error: %d", @""), err];
        NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : failureReason };

        *errOut = [NSError errorWithDomain:NLPasscodeEncryptionSupportDomain
                                      code:NLPasscodeEncryptionSupportDomainInvalidData
                                  userInfo:userInfo];
        return nil;
    }

    [fingerprint setLength:fingerprintLen];
    return fingerprint;
}

#pragma mark Private Methods

+ (BOOL)validateKeySize:(NSData *)encKey authKey:(NSData *)authKey fingerprintKey:(NSData *)fingerprintKey error:(NSError **)errOut
{

    if ([encKey length] != kPasscodeEncryptionKeyLen) {
        if (errOut) {
            *errOut = [NSError errorWithDomain:NLPasscodeEncryptionSupportDomain
                                          code:NLPasscodeEncryptionSupportDomainInvalidEncKeySize
                                      userInfo:nil];
        }
        return FALSE;
    }

    if ([authKey length] != kPasscodeAuthenticationKeyLen) {
        if (errOut) {
            *errOut = [NSError errorWithDomain:NLPasscodeEncryptionSupportDomain
                                          code:NLPasscodeEncryptionSupportDomainInvalidAuthKeySize
                                      userInfo:nil];
        }
        return FALSE;
    }

    if ([fingerprintKey length] != kPasscodeFingerprintKeyLen) {

        if (errOut) {
            *errOut = [NSError errorWithDomain:NLPasscodeEncryptionSupportDomain
                                          code:NLPasscodeEncryptionSupportDomainInvalidFingerprintKeySize
                                      userInfo:nil];
        }
        return FALSE;
    }

    return TRUE;
}

@end
