/*
  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
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));
}
