/*
  zip_crypto_win.c -- Windows Crypto API wrapper.
  Copyright (C) 2018 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
xor(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;
	    }

	    xor(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));
}
