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