/*
  zip_crypto_win.c -- Windows Crypto API wrapper.
  Copyright (C) 2018-2019 Dieter Baron and Thomas Klausner

  This file is part of libzip, a library to manipulate ZIP archives.
  The authors can be contacted at <libzip@nih.at>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in
  the documentation and/or other materials provided with the
  distribution.
  3. The names of the authors may not be used to endorse or promote
  products derived from this software without specific prior
  written permission.

  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>

#include "zipint.h"

#include "zip_crypto.h"

#define WIN32_LEAN_AND_MEAN
#define NOCRYPT

#include <windows.h>

#include <bcrypt.h>

#pragma comment(lib, "bcrypt.lib")

/*

This code is using the Cryptography API: Next Generation (CNG)
https://docs.microsoft.com/en-us/windows/desktop/seccng/cng-portal

This API is supported on
 - Windows Vista or later (client OS)
 - Windows Server 2008 (server OS)
 - Windows Embedded Compact 2013 (don't know about Windows Embedded Compact 7)

The code was developed for Windows Embedded Compact 2013 (WEC2013),
but should be working for all of the above mentioned OSes.

There are 2 restrictions for WEC2013, Windows Vista and Windows Server 2008:

1.) The function "BCryptDeriveKeyPBKDF2" is not available

I found some code which is implementing this function using the deprecated Crypto API here:
https://www.idrix.fr/Root/content/view/37/54/

I took this code and converted it to the newer CNG API. The original code was more
flexible, but this is not needed here so i refactored it a bit and just kept what is needed.

The define "HAS_BCRYPTDERIVEKEYPBKDF2" controls whether "BCryptDeriveKeyPBKDF2"
of the CNG API is used or not. This define must not be set if you are compiling for WEC2013 or Windows Vista.


2.) "BCryptCreateHash" can't manage the memory needed for the hash object internally

On Windows 7 or later it is possible to pass NULL for the hash object buffer.
This is not supported on WEC2013, so we have to handle the memory allocation/deallocation ourselves.
There is no #ifdef to control that, because this is working for all supported OSes.

*/

#if !defined(WINCE) && !defined(__MINGW32__)
#define HAS_BCRYPTDERIVEKEYPBKDF2
#endif

#ifdef HAS_BCRYPTDERIVEKEYPBKDF2

bool
_zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, zip_uint16_t iterations, zip_uint8_t *output, zip_uint16_t output_length) {
    BCRYPT_ALG_HANDLE hAlgorithm = NULL;

    if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG))) {
        return false;
    }

    bool result = BCRYPT_SUCCESS(BCryptDeriveKeyPBKDF2(hAlgorithm, (PUCHAR)key, (ULONG)key_length, (PUCHAR)salt, salt_length, iterations, output, output_length, 0));

    BCryptCloseAlgorithmProvider(hAlgorithm, 0);

    return result;
}

#else

#include <math.h>

#define DIGEST_SIZE 20
#define BLOCK_SIZE 64

typedef struct {
    BCRYPT_ALG_HANDLE hAlgorithm;
    BCRYPT_HASH_HANDLE hInnerHash;
    BCRYPT_HASH_HANDLE hOuterHash;
    ULONG cbHashObject;
    PUCHAR pbInnerHash;
    PUCHAR pbOuterHash;
} PRF_CTX;

static void
hmacFree(PRF_CTX *pContext) {
    if (pContext->hOuterHash)
        BCryptDestroyHash(pContext->hOuterHash);
    if (pContext->hInnerHash)
        BCryptDestroyHash(pContext->hInnerHash);
    free(pContext->pbOuterHash);
    free(pContext->pbInnerHash);
    if (pContext->hAlgorithm)
        BCryptCloseAlgorithmProvider(pContext->hAlgorithm, 0);
}

static BOOL
hmacPrecomputeDigest(BCRYPT_HASH_HANDLE hHash, PUCHAR pbPassword, DWORD cbPassword, BYTE mask) {
    BYTE buffer[BLOCK_SIZE];
    DWORD i;

    if (cbPassword > BLOCK_SIZE) {
        return FALSE;
    }

    memset(buffer, mask, sizeof(buffer));

    for (i = 0; i < cbPassword; ++i) {
        buffer[i] = (char)(pbPassword[i] ^ mask);
    }

    return BCRYPT_SUCCESS(BCryptHashData(hHash, buffer, sizeof(buffer), 0));
}

static BOOL
hmacInit(PRF_CTX *pContext, PUCHAR pbPassword, DWORD cbPassword) {
    BOOL bStatus = FALSE;
    ULONG cbResult;
    BYTE key[DIGEST_SIZE];

    if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&pContext->hAlgorithm, BCRYPT_SHA1_ALGORITHM, NULL, 0)) || !BCRYPT_SUCCESS(BCryptGetProperty(pContext->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&pContext->cbHashObject, sizeof(pContext->cbHashObject), &cbResult, 0)) || ((pContext->pbInnerHash = malloc(pContext->cbHashObject)) == NULL) || ((pContext->pbOuterHash = malloc(pContext->cbHashObject)) == NULL) || !BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &pContext->hInnerHash, pContext->pbInnerHash, pContext->cbHashObject, NULL, 0, 0)) || !BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &pContext->hOuterHash, pContext->pbOuterHash, pContext->cbHashObject, NULL, 0, 0))) {
        goto hmacInit_end;
    }

    if (cbPassword > BLOCK_SIZE) {
        BCRYPT_HASH_HANDLE hHash = NULL;
        PUCHAR pbHashObject = malloc(pContext->cbHashObject);
        if (pbHashObject == NULL) {
            goto hmacInit_end;
        }

        bStatus = BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &hHash, pbHashObject, pContext->cbHashObject, NULL, 0, 0)) && BCRYPT_SUCCESS(BCryptHashData(hHash, pbPassword, cbPassword, 0)) && BCRYPT_SUCCESS(BCryptGetProperty(hHash, BCRYPT_HASH_LENGTH, (PUCHAR)&cbPassword, sizeof(cbPassword), &cbResult, 0)) && BCRYPT_SUCCESS(BCryptFinishHash(hHash, key, cbPassword, 0));

        if (hHash)
            BCryptDestroyHash(hHash);
        free(pbHashObject);

        if (!bStatus) {
            goto hmacInit_end;
        }

        pbPassword = key;
    }

    bStatus = hmacPrecomputeDigest(pContext->hInnerHash, pbPassword, cbPassword, 0x36) && hmacPrecomputeDigest(pContext->hOuterHash, pbPassword, cbPassword, 0x5C);

hmacInit_end:

    if (bStatus == FALSE)
        hmacFree(pContext);

    return bStatus;
}

static BOOL
hmacCalculateInternal(BCRYPT_HASH_HANDLE hHashTemplate, PUCHAR pbData, DWORD cbData, PUCHAR pbOutput, DWORD cbOutput, DWORD cbHashObject) {
    BOOL success = FALSE;
    BCRYPT_HASH_HANDLE hHash = NULL;
    PUCHAR pbHashObject = malloc(cbHashObject);

    if (pbHashObject == NULL) {
        return FALSE;
    }

    if (BCRYPT_SUCCESS(BCryptDuplicateHash(hHashTemplate, &hHash, pbHashObject, cbHashObject, 0))) {
        success = BCRYPT_SUCCESS(BCryptHashData(hHash, pbData, cbData, 0)) && BCRYPT_SUCCESS(BCryptFinishHash(hHash, pbOutput, cbOutput, 0));

        BCryptDestroyHash(hHash);
    }

    free(pbHashObject);

    return success;
}

static BOOL
hmacCalculate(PRF_CTX *pContext, PUCHAR pbData, DWORD cbData, PUCHAR pbDigest) {
    DWORD cbResult;
    DWORD cbHashObject;

    return BCRYPT_SUCCESS(BCryptGetProperty(pContext->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&cbHashObject, sizeof(cbHashObject), &cbResult, 0)) && hmacCalculateInternal(pContext->hInnerHash, pbData, cbData, pbDigest, DIGEST_SIZE, cbHashObject) && hmacCalculateInternal(pContext->hOuterHash, pbDigest, DIGEST_SIZE, pbDigest, DIGEST_SIZE, cbHashObject);
}

static void
myxor(LPBYTE ptr1, LPBYTE ptr2, DWORD dwLen) {
    while (dwLen--)
        *ptr1++ ^= *ptr2++;
}

BOOL
pbkdf2(PUCHAR pbPassword, ULONG cbPassword, PUCHAR pbSalt, ULONG cbSalt, DWORD cIterations, PUCHAR pbDerivedKey, ULONG cbDerivedKey) {
    BOOL bStatus = FALSE;
    DWORD l, r, dwULen, i, j;
    BYTE Ti[DIGEST_SIZE];
    BYTE V[DIGEST_SIZE];
    LPBYTE U = malloc(max((cbSalt + 4), DIGEST_SIZE));
    PRF_CTX prfCtx = {0};

    if (U == NULL) {
        return FALSE;
    }

    if (pbPassword == NULL || cbPassword == 0 || pbSalt == NULL || cbSalt == 0 || cIterations == 0 || pbDerivedKey == NULL || cbDerivedKey == 0) {
        free(U);
        return FALSE;
    }

    if (!hmacInit(&prfCtx, pbPassword, cbPassword)) {
        goto PBKDF2_end;
    }

    l = (DWORD)ceil((double)cbDerivedKey / (double)DIGEST_SIZE);
    r = cbDerivedKey - (l - 1) * DIGEST_SIZE;

    for (i = 1; i <= l; i++) {
        ZeroMemory(Ti, DIGEST_SIZE);
        for (j = 0; j < cIterations; j++) {
            if (j == 0) {
                /* construct first input for PRF */
                memcpy(U, pbSalt, cbSalt);
                U[cbSalt] = (BYTE)((i & 0xFF000000) >> 24);
                U[cbSalt + 1] = (BYTE)((i & 0x00FF0000) >> 16);
                U[cbSalt + 2] = (BYTE)((i & 0x0000FF00) >> 8);
                U[cbSalt + 3] = (BYTE)((i & 0x000000FF));
                dwULen = cbSalt + 4;
            }
            else {
                memcpy(U, V, DIGEST_SIZE);
                dwULen = DIGEST_SIZE;
            }

            if (!hmacCalculate(&prfCtx, U, dwULen, V)) {
                goto PBKDF2_end;
            }

            myxor(Ti, V, DIGEST_SIZE);
        }

        if (i != l) {
            memcpy(&pbDerivedKey[(i - 1) * DIGEST_SIZE], Ti, DIGEST_SIZE);
        }
        else {
            /* Take only the first r bytes */
            memcpy(&pbDerivedKey[(i - 1) * DIGEST_SIZE], Ti, r);
        }
    }

    bStatus = TRUE;

PBKDF2_end:

    hmacFree(&prfCtx);
    free(U);
    return bStatus;
}

bool
_zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, zip_uint16_t iterations, zip_uint8_t *output, zip_uint16_t output_length) {
    return (key_length <= ZIP_UINT32_MAX) && pbkdf2((PUCHAR)key, (ULONG)key_length, (PUCHAR)salt, salt_length, iterations, output, output_length);
}

#endif


struct _zip_crypto_aes_s {
    BCRYPT_ALG_HANDLE hAlgorithm;
    BCRYPT_KEY_HANDLE hKey;
    ULONG cbKeyObject;
    PUCHAR pbKeyObject;
};

_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
    _zip_crypto_aes_t *aes = (_zip_crypto_aes_t *)calloc(1, sizeof(*aes));

    ULONG cbResult;
    ULONG key_length = key_size / 8;

    if (aes == NULL) {
        zip_error_set(error, ZIP_ER_MEMORY, 0);
        return NULL;
    }

    if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&aes->hAlgorithm, BCRYPT_AES_ALGORITHM, NULL, 0))) {
        _zip_crypto_aes_free(aes);
        return NULL;
    }

    if (!BCRYPT_SUCCESS(BCryptSetProperty(aes->hAlgorithm, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0))) {
        _zip_crypto_aes_free(aes);
        return NULL;
    }

    if (!BCRYPT_SUCCESS(BCryptGetProperty(aes->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&aes->cbKeyObject, sizeof(aes->cbKeyObject), &cbResult, 0))) {
        _zip_crypto_aes_free(aes);
        return NULL;
    }

    aes->pbKeyObject = malloc(aes->cbKeyObject);
    if (aes->pbKeyObject == NULL) {
        _zip_crypto_aes_free(aes);
        zip_error_set(error, ZIP_ER_MEMORY, 0);
        return NULL;
    }

    if (!BCRYPT_SUCCESS(BCryptGenerateSymmetricKey(aes->hAlgorithm, &aes->hKey, aes->pbKeyObject, aes->cbKeyObject, (PUCHAR)key, key_length, 0))) {
        _zip_crypto_aes_free(aes);
        return NULL;
    }

    return aes;
}

void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
    if (aes == NULL) {
        return;
    }

    if (aes->hKey != NULL) {
        BCryptDestroyKey(aes->hKey);
    }

    if (aes->pbKeyObject != NULL) {
        free(aes->pbKeyObject);
    }

    if (aes->hAlgorithm != NULL) {
        BCryptCloseAlgorithmProvider(aes->hAlgorithm, 0);
    }

    free(aes);
}

bool
_zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out) {
    ULONG cbResult;
    NTSTATUS status = BCryptEncrypt(aes->hKey, (PUCHAR)in, ZIP_CRYPTO_AES_BLOCK_LENGTH, NULL, NULL, 0, (PUCHAR)out, ZIP_CRYPTO_AES_BLOCK_LENGTH, &cbResult, 0);
    return BCRYPT_SUCCESS(status);
}

struct _zip_crypto_hmac_s {
    BCRYPT_ALG_HANDLE hAlgorithm;
    BCRYPT_HASH_HANDLE hHash;
    DWORD cbHashObject;
    PUCHAR pbHashObject;
    DWORD cbHash;
    PUCHAR pbHash;
};

/* https://code.msdn.microsoft.com/windowsdesktop/Hmac-Computation-Sample-11fe8ec1/sourcecode?fileId=42820&pathId=283874677 */

_zip_crypto_hmac_t *
_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error) {
    NTSTATUS status;
    ULONG cbResult;
    _zip_crypto_hmac_t *hmac;

    if (secret_length > INT_MAX) {
        zip_error_set(error, ZIP_ER_INVAL, 0);
        return NULL;
    }

    hmac = (_zip_crypto_hmac_t *)calloc(1, sizeof(*hmac));

    if (hmac == NULL) {
        zip_error_set(error, ZIP_ER_MEMORY, 0);
        return NULL;
    }

    status = BCryptOpenAlgorithmProvider(&hmac->hAlgorithm, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG);
    if (!BCRYPT_SUCCESS(status)) {
        _zip_crypto_hmac_free(hmac);
        return NULL;
    }

    status = BCryptGetProperty(hmac->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hmac->cbHashObject, sizeof(hmac->cbHashObject), &cbResult, 0);
    if (!BCRYPT_SUCCESS(status)) {
        _zip_crypto_hmac_free(hmac);
        return NULL;
    }

    hmac->pbHashObject = malloc(hmac->cbHashObject);
    if (hmac->pbHashObject == NULL) {
        _zip_crypto_hmac_free(hmac);
        zip_error_set(error, ZIP_ER_MEMORY, 0);
        return NULL;
    }

    status = BCryptGetProperty(hmac->hAlgorithm, BCRYPT_HASH_LENGTH, (PUCHAR)&hmac->cbHash, sizeof(hmac->cbHash), &cbResult, 0);
    if (!BCRYPT_SUCCESS(status)) {
        _zip_crypto_hmac_free(hmac);
        return NULL;
    }

    hmac->pbHash = malloc(hmac->cbHash);
    if (hmac->pbHash == NULL) {
        _zip_crypto_hmac_free(hmac);
        zip_error_set(error, ZIP_ER_MEMORY, 0);
        return NULL;
    }

    status = BCryptCreateHash(hmac->hAlgorithm, &hmac->hHash, hmac->pbHashObject, hmac->cbHashObject, (PUCHAR)secret, (ULONG)secret_length, 0);
    if (!BCRYPT_SUCCESS(status)) {
        _zip_crypto_hmac_free(hmac);
        return NULL;
    }

    return hmac;
}

void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
    if (hmac == NULL) {
        return;
    }

    if (hmac->hHash != NULL) {
        BCryptDestroyHash(hmac->hHash);
    }

    if (hmac->pbHash != NULL) {
        free(hmac->pbHash);
    }

    if (hmac->pbHashObject != NULL) {
        free(hmac->pbHashObject);
    }

    if (hmac->hAlgorithm) {
        BCryptCloseAlgorithmProvider(hmac->hAlgorithm, 0);
    }

    free(hmac);
}

bool
_zip_crypto_hmac(_zip_crypto_hmac_t *hmac, zip_uint8_t *data, zip_uint64_t length) {
    if (hmac == NULL || length > ULONG_MAX) {
        return false;
    }

    return BCRYPT_SUCCESS(BCryptHashData(hmac->hHash, data, (ULONG)length, 0));
}

bool
_zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data) {
    if (hmac == NULL) {
        return false;
    }

    return BCRYPT_SUCCESS(BCryptFinishHash(hmac->hHash, data, hmac->cbHash, 0));
}

ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
    return BCRYPT_SUCCESS(BCryptGenRandom(NULL, buffer, length, BCRYPT_USE_SYSTEM_PREFERRED_RNG));
}
