/*
* Crypto wrapper for Microsoft CryptoAPI
*
* 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 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 (CryptImportPublicKeyInfo)
return 0;
dll = LoadLibrary("crypt32");
if (dll == NULL) {
wpa_printf(MSG_DEBUG, "CryptoAPI: Could not load 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,
crypto_cryptoapi.rar_CRYPTO_Crypto++_cryptoAPI
版权申诉
107 浏览量
2022-09-14
20:54:58
上传
评论
收藏 4KB RAR 举报
局外狗
- 粉丝: 64
- 资源: 1万+
最新资源
- 基于matlab实现对表面肌电信号进行归一化处理,并对归一化后的图形显示 .rar
- 基于matlab实现单级倒立摆的 T-S 模型 包括 LMI 程序源码
- 图书管理系统(struts+hibernate+spring+ext).rar
- 基于matlab实现此压缩包包含语音信号处理中的语音变声代码加音频.rar
- STM32使用PWM驱动舵机并通过OLED显示
- 基于matlab实现车辆路径规划;遗传算法;matlab代码.rar
- 图书管理系统(struts+hibernate+spring)130225.rar
- 基于matlab实现采用标量衍射理论,实现菲涅尔衍射和夫琅禾费衍射,对光波的波前传播和数字全息的应用有帮助.rar
- JavaScript版去除链表重复元素
- 微信小程序项目-功德木鱼(带设置面板-自定义文字、可选字体颜色、可选木鱼样式)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈