📄 crypto_cryptoapi.c
字号:
/* * 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_FUNCSvoid 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_INTERNALstruct 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -