/*
 * WPA Supplicant / Crypto wrapper for Microsoft CryptoAPI
 * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Alternatively, this software may be distributed under the terms of BSD
 * license.
 *
 * See README and COPYING for more details.
 */

#include "includes.h"
#include <windows.h>
#include <wincrypt.h>

#include "common.h"
#include "crypto.h"

#ifndef MS_ENH_RSA_AES_PROV
#ifdef UNICODE
#define MS_ENH_RSA_AES_PROV \
L"Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"
#else
#define MS_ENH_RSA_AES_PROV \
"Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"
#endif
#endif /* MS_ENH_RSA_AES_PROV */

#ifndef CALG_HMAC
#define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC)
#endif

#ifdef CONFIG_TLS_INTERNAL
#ifdef __MINGW32_VERSION
/*
 * MinGW does not yet include all the needed definitions for CryptoAPI, so
 * define here whatever extra is needed.
 */

static PCCERT_CONTEXT WINAPI
(*CertCreateCertificateContext)(DWORD dwCertEncodingType,
				const BYTE *pbCertEncoded,
				DWORD cbCertEncoded)
= NULL; /* to be loaded from crypt32.dll */

static BOOL WINAPI
(*CryptImportPublicKeyInfo)(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType,
			    PCERT_PUBLIC_KEY_INFO pInfo, HCRYPTKEY *phKey)
= NULL; /* to be loaded from crypt32.dll */


static int mingw_load_crypto_func(void)
{
	HINSTANCE dll;

	/* MinGW does not yet have full CryptoAPI support, so load the needed
	 * function here. */

	if (CertCreateCertificateContext)
		return 0;

	dll = LoadLibrary("crypt32");
	if (dll == NULL) {
		wpa_printf(MSG_DEBUG, "CryptoAPI: Could not load crypt32 "
			   "library");
		return -1;
	}

	CertCreateCertificateContext = (void *) GetProcAddress(
		dll, "CertCreateCertificateContext");
	if (CertCreateCertificateContext == NULL) {
		wpa_printf(MSG_DEBUG, "CryptoAPI: Could not get "
			   "CertCreateCertificateContext() address from "
			   "crypt32 library");
		return -1;
	}

	CryptImportPublicKeyInfo = GetProcAddress(
		dll, "CryptImportPublicKeyInfo");
	if (CryptImportPublicKeyInfo == NULL) {
		wpa_printf(MSG_DEBUG, "CryptoAPI: Could not get "
			   "CryptImportPublicKeyInfo() address from "
			   "crypt32 library");
		return -1;
	}

	return 0;
}

#else /* __MINGW32_VERSION */

static int mingw_load_crypto_func(void)
{
	return 0;
}

#endif /* __MINGW32_VERSION */
#endif /* CONFIG_TLS_INTERNAL */


static void cryptoapi_report_error(const char *msg)
{
	char *s, *pos;
	DWORD err = GetLastError();

	if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
			  FORMAT_MESSAGE_FROM_SYSTEM,
			  NULL, err, 0, (LPTSTR) &s, 0, NULL) == 0) {
 		wpa_printf(MSG_DEBUG, "CryptoAPI: %s: %d", msg, (int) err);
	}

	pos = s;
	while (*pos) {
		if (*pos == '\n' || *pos == '\r') {
			*pos = '\0';
			break;
		}
		pos++;
	}

	wpa_printf(MSG_DEBUG, "CryptoAPI: %s: %d: (%s)", msg, (int) err, s);
	LocalFree(s);
}


int cryptoapi_hash_vector(ALG_ID alg, size_t hash_len, size_t num_elem,
			  const u8 *addr[], const size_t *len, u8 *mac)
{
	HCRYPTPROV prov;
	HCRYPTHASH hash;
	size_t i;
	DWORD hlen;
	int ret = 0;

	if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0)) {
		cryptoapi_report_error("CryptAcquireContext");
		return -1;
	}

	if (!CryptCreateHash(prov, alg, 0, 0, &hash)) {
		cryptoapi_report_error("CryptCreateHash");
		CryptReleaseContext(prov, 0);
		return -1;
	}

	for (i = 0; i < num_elem; i++) {
		if (!CryptHashData(hash, (BYTE *) addr[i], len[i], 0)) {
			cryptoapi_report_error("CryptHashData");
			CryptDestroyHash(hash);
			CryptReleaseContext(prov, 0);
		}
	}

	hlen = hash_len;
	if (!CryptGetHashParam(hash, HP_HASHVAL, mac, &hlen, 0)) {
		cryptoapi_report_error("CryptGetHashParam");
		ret = -1;
	}

	CryptDestroyHash(hash);
	CryptReleaseContext(prov, 0);

	return ret;
}


void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
{
	cryptoapi_hash_vector(CALG_MD4, 16, num_elem, addr, len, mac);
}


void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
{
	u8 next, tmp;
	int i;
	HCRYPTPROV prov;
	HCRYPTKEY ckey;
	DWORD dlen;
	struct {
		BLOBHEADER hdr;
		DWORD len;
		BYTE key[8];
	} key_blob;
	DWORD mode = CRYPT_MODE_ECB;

	key_blob.hdr.bType = PLAINTEXTKEYBLOB;
	key_blob.hdr.bVersion = CUR_BLOB_VERSION;
	key_blob.hdr.reserved = 0;
	key_blob.hdr.aiKeyAlg = CALG_DES;
	key_blob.len = 8;

	/* Add parity bits to the key */
	next = 0;
	for (i = 0; i < 7; i++) {
		tmp = key[i];
		key_blob.key[i] = (tmp >> i) | next | 1;
		next = tmp << (7 - i);
	}
	key_blob.key[i] = next | 1;

	if (!CryptAcquireContext(&prov, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,
				 CRYPT_VERIFYCONTEXT)) {
 		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptAcquireContext failed: "
			   "%d", (int) GetLastError());
		return;
	}

	if (!CryptImportKey(prov, (BYTE *) &key_blob, sizeof(key_blob), 0, 0,
			    &ckey)) {
 		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptImportKey failed: %d",
			   (int) GetLastError());
		CryptReleaseContext(prov, 0);
		return;
	}

	if (!CryptSetKeyParam(ckey, KP_MODE, (BYTE *) &mode, 0)) {
 		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptSetKeyParam(KP_MODE) "
			   "failed: %d", (int) GetLastError());
		CryptDestroyKey(ckey);
		CryptReleaseContext(prov, 0);
		return;
	}

	os_memcpy(cypher, clear, 8);
	dlen = 8;
	if (!CryptEncrypt(ckey, 0, FALSE, 0, cypher, &dlen, 8)) {
		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptEncrypt failed: %d",
			   (int) GetLastError());
		os_memset(cypher, 0, 8);
	}

	CryptDestroyKey(ckey);
	CryptReleaseContext(prov, 0);
}


#ifdef EAP_TLS_FUNCS
void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
{
	cryptoapi_hash_vector(CALG_MD5, 16, num_elem, addr, len, mac);
}


void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
{
	cryptoapi_hash_vector(CALG_SHA, 20, num_elem, addr, len, mac);
}


struct aes_context {
	HCRYPTPROV prov;
	HCRYPTKEY ckey;
};


void * aes_encrypt_init(const u8 *key, size_t len)
{
	struct aes_context *akey;
	struct {
		BLOBHEADER hdr;
		DWORD len;
		BYTE key[16];
	} key_blob;
	DWORD mode = CRYPT_MODE_ECB;

	if (len != 16)
		return NULL;

	key_blob.hdr.bType = PLAINTEXTKEYBLOB;
	key_blob.hdr.bVersion = CUR_BLOB_VERSION;
	key_blob.hdr.reserved = 0;
	key_blob.hdr.aiKeyAlg = CALG_AES_128;
	key_blob.len = len;
	os_memcpy(key_blob.key, key, len);

	akey = os_zalloc(sizeof(*akey));
	if (akey == NULL)
		return NULL;

	if (!CryptAcquireContext(&akey->prov, NULL,
				 MS_ENH_RSA_AES_PROV, PROV_RSA_AES,
				 CRYPT_VERIFYCONTEXT)) {
 		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptAcquireContext failed: "
			   "%d", (int) GetLastError());
		os_free(akey);
		return NULL;
	}

	if (!CryptImportKey(akey->prov, (BYTE *) &key_blob, sizeof(key_blob),
			    0, 0, &akey->ckey)) {
 		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptImportKey failed: %d",
			   (int) GetLastError());
		CryptReleaseContext(akey->prov, 0);
		os_free(akey);
		return NULL;
	}

	if (!CryptSetKeyParam(akey->ckey, KP_MODE, (BYTE *) &mode, 0)) {
 		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptSetKeyParam(KP_MODE) "
			   "failed: %d", (int) GetLastError());
		CryptDestroyKey(akey->ckey);
		CryptReleaseContext(akey->prov, 0);
		os_free(akey);
		return NULL;
	}

	return akey;
}


void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
{
	struct aes_context *akey = ctx;
	DWORD dlen;

	os_memcpy(crypt, plain, 16);
	dlen = 16;
	if (!CryptEncrypt(akey->ckey, 0, FALSE, 0, crypt, &dlen, 16)) {
		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptEncrypt failed: %d",
			   (int) GetLastError());
		os_memset(crypt, 0, 16);
	}
}


void aes_encrypt_deinit(void *ctx)
{
	struct aes_context *akey = ctx;
	if (akey) {
		CryptDestroyKey(akey->ckey);
		CryptReleaseContext(akey->prov, 0);
		os_free(akey);
	}
}


void * aes_decrypt_init(const u8 *key, size_t len)
{
	return aes_encrypt_init(key, len);
}


void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
{
	struct aes_context *akey = ctx;
	DWORD dlen;

	os_memcpy(plain, crypt, 16);
	dlen = 16;

	if (!CryptDecrypt(akey->ckey, 0, FALSE, 0, plain, &dlen)) {
		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptDecrypt failed: %d",
			   (int) GetLastError());
	}
}


void aes_decrypt_deinit(void *ctx)
{
	aes_encrypt_deinit(ctx);
}

#ifdef CONFIG_TLS_INTERNAL

struct crypto_hash {
	enum crypto_hash_alg alg;
	int error;
	HCRYPTPROV prov;
	HCRYPTHASH hash;
	HCRYPTKEY key;
};

struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
				      size_t key_len)
{
	struct crypto_hash *ctx;
	ALG_ID calg;
	struct {
		BLOBHEADER hdr;
		DWORD len;
		BYTE key[32];
	} key_blob;

	os_memset(&key_blob, 0, sizeof(key_blob));
	switch (alg) {
	case CRYPTO_HASH_ALG_MD5:
		calg = CALG_MD5;
		break;
	case CRYPTO_HASH_ALG_SHA1:
		calg = CALG_SHA;
		break;
	case CRYPTO_HASH_ALG_HMAC_MD5:
	case CRYPTO_HASH_ALG_HMAC_SHA1:
		calg = CALG_HMAC;
		key_blob.hdr.bType = PLAINTEXTKEYBLOB;
		key_blob.hdr.bVersion = CUR_BLOB_VERSION;
		key_blob.hdr.reserved = 0;
		/*
		 * Note: RC2 is not really used, but that can be used to
		 * import HMAC keys of up to 16 byte long.
		 * CRYPT_IPSEC_HMAC_KEY flag for CryptImportKey() is needed to
		 * be able to import longer keys (HMAC-SHA1 uses 20-byte key).
		 */
		key_blob.hdr.aiKeyAlg = CALG_RC2;
		key_blob.len = key_len;
		if (key_len > sizeof(key_blob.key))
			return NULL;
		os_memcpy(key_blob.key, key, key_len);
		break;
	default:
		return NULL;
	}

	ctx = os_zalloc(sizeof(*ctx));
	if (ctx == NULL)
		return NULL;

	ctx->alg = alg;

	if (!CryptAcquireContext(&ctx->prov, NULL, NULL, PROV_RSA_FULL, 0)) {
		cryptoapi_report_error("CryptAcquireContext");
		os_free(ctx);
		return NULL;
	}

	if (calg == CALG_HMAC) {
#ifndef CRYPT_IPSEC_HMAC_KEY
#define CRYPT_IPSEC_HMAC_KEY 0x00000100
#endif
		if (!CryptImportKey(ctx->prov, (BYTE *) &key_blob,
				    sizeof(key_blob), 0, CRYPT_IPSEC_HMAC_KEY,
				    &ctx->key)) {
			cryptoapi_report_error("CryptImportKey");
			CryptReleaseContext(ctx->prov, 0);
			os_free(ctx);
			return NULL;
		}
	}

	if (!CryptCreateHash(ctx->prov, calg, ctx->key, 0, &ctx->hash)) {
		cryptoapi_report_error("CryptCreateHash");
		CryptReleaseContext(ctx->prov, 0);
		os_free(ctx);
		return NULL;
	}

	if (calg == CALG_HMAC) {
		HMAC_INFO info;
		os_memset(&info, 0, sizeof(info));
		switch (alg) {
		case CRYPTO_HASH_ALG_HMAC_MD5:
			info.HashAlgid = CALG_MD5;
			break;
		case CRYPTO_HASH_ALG_HMAC_SHA1:
			info.HashAlgid = CALG_SHA;
			break;
		default:
			/* unreachable */
			break;
		}

		if (!CryptSetHashParam(ctx->hash, HP_HMAC_INFO, (BYTE *) &info,
				       0)) {
			cryptoapi_report_error("CryptSetHashParam");
			CryptDestroyHash(ctx->hash);
			CryptReleaseContext(ctx->prov, 0);
			os_free(ctx);
			return NULL;
		}
	}

	return ctx;
}


void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
{
	if (ctx == NULL || ctx->error)
		return;

	if (!CryptHashData(ctx->hash, (BYTE *) data, len, 0)) {
		cryptoapi_report_error("CryptHashData");
		ctx->error = 1;
	}
}


int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
{
	int ret = 0;
	DWORD hlen;

	if (ctx == NULL)
		return -2;

	if (mac == NULL || len == NULL)
		goto done;

	if (ctx->error) {
		ret = -2;
		goto done;
	}

	hlen = *len;
	if (!CryptGetHashParam(ctx->hash, HP_HASHVAL, mac, &hlen, 0)) {
		cryptoapi_report_error("CryptGetHashParam");
		ret = -2;
	}
	*len = hlen;

done:
	if (ctx->alg == CRYPTO_HASH_ALG_HMAC_SHA1 ||
	    ctx->alg == CRYPTO_HASH_ALG_HMAC_MD5)
		CryptDestroyKey(ctx->key);

	os_free(ctx);

	return ret;
}


struct crypto_cipher {
	HCRYPTPROV prov;
	HCRYPTKEY key;
};


struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
					  const u8 *iv, const u8 *key,
					  size_t key_len)
{	
	struct crypto_cipher *ctx;
	struct {
		BLOBHEADER hdr;
		DWORD len;
		BYTE key[32];
	} key_blob;
	DWORD mode = CRYPT_MODE_CBC;

	key_blob.hdr.bType = PLAINTEXTKEYBLOB;
	key_blob.hdr.bVersion = CUR_BLOB_VERSION;
	key_blob.hdr.reserved = 0;
	key_blob.len = key_len;
	if (key_len > sizeof(key_blob.key))
		return NULL;
	os_memcpy(key_blob.key, key, key_len);

	switch (alg) {
	case CRYPTO_CIPHER_ALG_AES:
		if (key_len == 32)
			key_blob.hdr.aiKeyAlg = CALG_AES_256;
		else if (key_len == 24)
			key_blob.hdr.aiKeyAlg = CALG_AES_192;
		else
			key_blob.hdr.aiKeyAlg = CALG_AES_128;
		break;
	case CRYPTO_CIPHER_ALG_3DES:
		key_blob.hdr.aiKeyAlg = CALG_3DES;
		break;
	case CRYPTO_CIPHER_ALG_DES:
		key_blob.hdr.aiKeyAlg = CALG_DES;
		break;
	case CRYPTO_CIPHER_ALG_RC2:
		key_blob.hdr.aiKeyAlg = CALG_RC2;
		break;
	case CRYPTO_CIPHER_ALG_RC4:
		key_blob.hdr.aiKeyAlg = CALG_RC4;
		break;
	default:
		return NULL;
	}

	ctx = os_zalloc(sizeof(*ctx));
	if (ctx == NULL)
		return NULL;

	if (!CryptAcquireContext(&ctx->prov, NULL, MS_ENH_RSA_AES_PROV,
				 PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
		cryptoapi_report_error("CryptAcquireContext");
		goto fail1;
	}

	if (!CryptImportKey(ctx->prov, (BYTE *) &key_blob,
			    sizeof(key_blob), 0, 0, &ctx->key)) {
 		cryptoapi_report_error("CryptImportKey");
		goto fail2;
	}

	if (!CryptSetKeyParam(ctx->key, KP_MODE, (BYTE *) &mode, 0)) {
 		cryptoapi_report_error("CryptSetKeyParam(KP_MODE)");
		goto fail3;
	}

	if (iv && !CryptSetKeyParam(ctx->key, KP_IV, (BYTE *) iv, 0)) {
 		cryptoapi_report_error("CryptSetKeyParam(KP_IV)");
		goto fail3;
	}

	return ctx;

fail3:
	CryptDestroyKey(ctx->key);
fail2:
	CryptReleaseContext(ctx->prov, 0);
fail1:
	os_free(ctx);
	return NULL;
}


int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
			  u8 *crypt, size_t len)
{
	DWORD dlen;

	os_memcpy(crypt, plain, len);
	dlen = len;
	if (!CryptEncrypt(ctx->key, 0, FALSE, 0, crypt, &dlen, len)) {
 		cryptoapi_report_error("CryptEncrypt");
		os_memset(crypt, 0, len);
		return -1;
	}

	return 0;
}


int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
			  u8 *plain, size_t len)
{
	DWORD dlen;

	os_memcpy(plain, crypt, len);
	dlen = len;
	if (!CryptDecrypt(ctx->key, 0, FALSE, 0, plain, &dlen)) {
 		cryptoapi_report_error("CryptDecrypt");
		return -1;
	}

	return 0;
}


void crypto_cipher_deinit(struct crypto_cipher *ctx)
{
	CryptDestroyKey(ctx->key);
	CryptReleaseContext(ctx->prov, 0);
	os_free(ctx);
}


struct crypto_public_key {
	HCRYPTPROV prov;
	HCRYPTKEY rsa;
};

struct crypto_private_key {
	HCRYPTPROV prov;
	HCRYPTKEY rsa;
};


struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len)
{
	/* Use crypto_public_key_from_cert() instead. */
	return NULL;
}


struct crypto_private_key * crypto_private_key_import(const u8 *key,
						      size_t len)
{
	/* TODO */
	return NULL;
}


struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
						       size_t len)
{
	struct crypto_public_key *pk;
	PCCERT_CONTEXT cc;

	pk = os_zalloc(sizeof(*pk));
	if (pk == NULL)
		return NULL;

	cc = CertCreateCertificateContext(X509_ASN_ENCODING |
					  PKCS_7_ASN_ENCODING, buf, len);
	if (!cc) {
 		cryptoapi_report_error("CryptCreateCertificateContext");
		os_free(pk);
		return NULL;
	}

	if (!CryptAcquireContext(&pk->prov, NULL, MS_DEF_PROV, PROV_RSA_FULL,
				 0)) {
 		cryptoapi_report_error("CryptAcquireContext");
		os_free(pk);
		CertFreeCertificateContext(cc);
		return NULL;
	}

	if (!CryptImportPublicKeyInfo(pk->prov, X509_ASN_ENCODING |
				      PKCS_7_ASN_ENCODING,
				      &cc->pCertInfo->SubjectPublicKeyInfo,
				      &pk->rsa)) {
 		cryptoapi_report_error("CryptImportPublicKeyInfo");
		CryptReleaseContext(pk->prov, 0);
		os_free(pk);
		CertFreeCertificateContext(cc);
		return NULL;
	}

	CertFreeCertificateContext(cc);

	return pk;
}


int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
					const u8 *in, size_t inlen,
					u8 *out, size_t *outlen)
{
	DWORD clen;
	u8 *tmp;
	size_t i;

	if (*outlen < inlen)
		return -1;
	tmp = malloc(*outlen);
	if (tmp == NULL)
		return -1;

	os_memcpy(tmp, in, inlen);
	clen = inlen;
	if (!CryptEncrypt(key->rsa, 0, TRUE, 0, tmp, &clen, *outlen)) {
		wpa_printf(MSG_DEBUG, "CryptoAPI: Failed to encrypt using "
			   "public key: %d", (int) GetLastError());
		os_free(tmp);
		return -1;
	}

	*outlen = clen;

	/* Reverse the output */
	for (i = 0; i < *outlen; i++)
		out[i] = tmp[*outlen - 1 - i];

	os_free(tmp);

	return 0;
}


int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
				  const u8 *in, size_t inlen,
				  u8 *out, size_t *outlen)
{
	/* TODO */
	return -1;
}


void crypto_public_key_free(struct crypto_public_key *key)
{
	if (key) {
		CryptDestroyKey(key->rsa);
		CryptReleaseContext(key->prov, 0);
		os_free(key);
	}
}


void crypto_private_key_free(struct crypto_private_key *key)
{
	if (key) {
		CryptDestroyKey(key->rsa);
		CryptReleaseContext(key->prov, 0);
		os_free(key);
	}
}


int crypto_global_init(void)
{
	return mingw_load_crypto_func();
}


void crypto_global_deinit(void)
{
}

#endif /* CONFIG_TLS_INTERNAL */

#endif /* EAP_TLS_FUNCS */
