18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Crypto wrapper for Microsoft CryptoAPI 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <windows.h> 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <wincrypt.h> 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef MS_ENH_RSA_AES_PROV 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MS_ENH_RSA_AES_PROV \ 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtL"Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MS_ENH_RSA_AES_PROV \ 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* MS_ENH_RSA_AES_PROV */ 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CALG_HMAC 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC) 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __MINGW32_VERSION 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MinGW does not yet include all the needed definitions for CryptoAPI, so 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * define here whatever extra is needed. 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic BOOL WINAPI 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt(*CryptImportPublicKeyInfo)(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType, 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PCERT_PUBLIC_KEY_INFO pInfo, HCRYPTKEY *phKey) 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt= NULL; /* to be loaded from crypt32.dll */ 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int mingw_load_crypto_func(void) 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HINSTANCE dll; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* MinGW does not yet have full CryptoAPI support, so load the needed 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * function here. */ 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CryptImportPublicKeyInfo) 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dll = LoadLibrary("crypt32"); 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dll == NULL) { 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: Could not load crypt32 " 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "library"); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptImportPublicKeyInfo = GetProcAddress( 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dll, "CryptImportPublicKeyInfo"); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CryptImportPublicKeyInfo == NULL) { 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: Could not get " 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CryptImportPublicKeyInfo() address from " 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "crypt32 library"); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* __MINGW32_VERSION */ 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int mingw_load_crypto_func(void) 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __MINGW32_VERSION */ 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void cryptoapi_report_error(const char *msg) 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *s, *pos; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD err = GetLastError(); 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FORMAT_MESSAGE_FROM_SYSTEM, 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, err, 0, (LPTSTR) &s, 0, NULL) == 0) { 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: %s: %d", msg, (int) err); 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = s; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos) { 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\n' || *pos == '\r') { 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: %s: %d: (%s)", msg, (int) err, s); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LocalFree(s); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint cryptoapi_hash_vector(ALG_ID alg, size_t hash_len, size_t num_elem, 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[], const size_t *len, u8 *mac) 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTPROV prov; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTHASH hash; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD hlen; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0)) { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptAcquireContext"); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptCreateHash(prov, alg, 0, 0, &hash)) { 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptCreateHash"); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(prov, 0); 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_elem; i++) { 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptHashData(hash, (BYTE *) addr[i], len[i], 0)) { 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptHashData"); 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyHash(hash); 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(prov, 0); 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = hash_len; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptGetHashParam(hash, HP_HASHVAL, mac, &hlen, 0)) { 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptGetHashParam"); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyHash(hash); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(prov, 0); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return cryptoapi_hash_vector(CALG_MD4, 16, num_elem, addr, len, mac); 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 next, tmp; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTPROV prov; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTKEY ckey; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dlen; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BLOBHEADER hdr; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD len; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BYTE key[8]; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } key_blob; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD mode = CRYPT_MODE_ECB; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.bType = PLAINTEXTKEYBLOB; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.bVersion = CUR_BLOB_VERSION; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.reserved = 0; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.aiKeyAlg = CALG_DES; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.len = 8; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Add parity bits to the key */ 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = 0; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 7; i++) { 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = key[i]; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.key[i] = (tmp >> i) | next | 1; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = tmp << (7 - i); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.key[i] = next | 1; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptAcquireContext(&prov, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_VERIFYCONTEXT)) { 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: CryptAcquireContext failed: " 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d", (int) GetLastError()); 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptImportKey(prov, (BYTE *) &key_blob, sizeof(key_blob), 0, 0, 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &ckey)) { 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: CryptImportKey failed: %d", 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(prov, 0); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSetKeyParam(ckey, KP_MODE, (BYTE *) &mode, 0)) { 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: CryptSetKeyParam(KP_MODE) " 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", (int) GetLastError()); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyKey(ckey); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(prov, 0); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(cypher, clear, 8); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = 8; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptEncrypt(ckey, 0, FALSE, 0, cypher, &dlen, 8)) { 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: CryptEncrypt failed: %d", 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(cypher, 0, 8); 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyKey(ckey); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(prov, 0); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return cryptoapi_hash_vector(CALG_MD5, 16, num_elem, addr, len, mac); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return cryptoapi_hash_vector(CALG_SHA, 20, num_elem, addr, len, mac); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct aes_context { 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTPROV prov; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTKEY ckey; 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * aes_encrypt_init(const u8 *key, size_t len) 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct aes_context *akey; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BLOBHEADER hdr; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD len; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BYTE key[16]; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } key_blob; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD mode = CRYPT_MODE_ECB; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len != 16) 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.bType = PLAINTEXTKEYBLOB; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.bVersion = CUR_BLOB_VERSION; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.reserved = 0; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.aiKeyAlg = CALG_AES_128; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.len = len; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key_blob.key, key, len); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt akey = os_zalloc(sizeof(*akey)); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (akey == NULL) 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptAcquireContext(&akey->prov, NULL, 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_VERIFYCONTEXT)) { 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: CryptAcquireContext failed: " 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d", (int) GetLastError()); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(akey); 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptImportKey(akey->prov, (BYTE *) &key_blob, sizeof(key_blob), 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, 0, &akey->ckey)) { 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: CryptImportKey failed: %d", 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(akey->prov, 0); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(akey); 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSetKeyParam(akey->ckey, KP_MODE, (BYTE *) &mode, 0)) { 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: CryptSetKeyParam(KP_MODE) " 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", (int) GetLastError()); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyKey(akey->ckey); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(akey->prov, 0); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(akey); 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return akey; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct aes_context *akey = ctx; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dlen; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(crypt, plain, 16); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = 16; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptEncrypt(akey->ckey, 0, FALSE, 0, crypt, &dlen, 16)) { 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: CryptEncrypt failed: %d", 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(crypt, 0, 16); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_encrypt_deinit(void *ctx) 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct aes_context *akey = ctx; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (akey) { 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyKey(akey->ckey); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(akey->prov, 0); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(akey); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * aes_decrypt_init(const u8 *key, size_t len) 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return aes_encrypt_init(key, len); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct aes_context *akey = ctx; 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dlen; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(plain, crypt, 16); 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = 16; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptDecrypt(akey->ckey, 0, FALSE, 0, plain, &dlen)) { 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: CryptDecrypt failed: %d", 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_decrypt_deinit(void *ctx) 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aes_encrypt_deinit(ctx); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_hash { 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum crypto_hash_alg alg; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int error; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTPROV prov; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTHASH hash; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTKEY key; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t key_len) 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct crypto_hash *ctx; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ALG_ID calg; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BLOBHEADER hdr; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD len; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BYTE key[32]; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } key_blob; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&key_blob, 0, sizeof(key_blob)); 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (alg) { 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_MD5: 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt calg = CALG_MD5; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_SHA1: 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt calg = CALG_SHA; 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_HMAC_MD5: 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_HMAC_SHA1: 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt calg = CALG_HMAC; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.bType = PLAINTEXTKEYBLOB; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.bVersion = CUR_BLOB_VERSION; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.reserved = 0; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: RC2 is not really used, but that can be used to 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * import HMAC keys of up to 16 byte long. 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * CRYPT_IPSEC_HMAC_KEY flag for CryptImportKey() is needed to 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * be able to import longer keys (HMAC-SHA1 uses 20-byte key). 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.aiKeyAlg = CALG_RC2; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.len = key_len; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_len > sizeof(key_blob.key)) 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key_blob.key, key, key_len); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx = os_zalloc(sizeof(*ctx)); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->alg = alg; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptAcquireContext(&ctx->prov, NULL, NULL, PROV_RSA_FULL, 0)) { 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptAcquireContext"); 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (calg == CALG_HMAC) { 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CRYPT_IPSEC_HMAC_KEY 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CRYPT_IPSEC_HMAC_KEY 0x00000100 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptImportKey(ctx->prov, (BYTE *) &key_blob, 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(key_blob), 0, CRYPT_IPSEC_HMAC_KEY, 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &ctx->key)) { 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptImportKey"); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(ctx->prov, 0); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptCreateHash(ctx->prov, calg, ctx->key, 0, &ctx->hash)) { 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptCreateHash"); 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(ctx->prov, 0); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (calg == CALG_HMAC) { 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HMAC_INFO info; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&info, 0, sizeof(info)); 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (alg) { 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_HMAC_MD5: 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt info.HashAlgid = CALG_MD5; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_HMAC_SHA1: 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt info.HashAlgid = CALG_SHA; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* unreachable */ 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSetHashParam(ctx->hash, HP_HMAC_INFO, (BYTE *) &info, 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0)) { 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptSetHashParam"); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyHash(ctx->hash); 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(ctx->prov, 0); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ctx; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL || ctx->error) 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptHashData(ctx->hash, (BYTE *) data, len, 0)) { 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptHashData"); 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->error = 1; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD hlen; 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mac == NULL || len == NULL) 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto done; 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx->error) { 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -2; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto done; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = *len; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptGetHashParam(ctx->hash, HP_HASHVAL, mac, &hlen, 0)) { 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptGetHashParam"); 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -2; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = hlen; 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdone: 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx->alg == CRYPTO_HASH_ALG_HMAC_SHA1 || 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->alg == CRYPTO_HASH_ALG_HMAC_MD5) 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyKey(ctx->key); 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_cipher { 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTPROV prov; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTKEY key; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *iv, const u8 *key, 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t key_len) 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct crypto_cipher *ctx; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BLOBHEADER hdr; 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD len; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BYTE key[32]; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } key_blob; 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD mode = CRYPT_MODE_CBC; 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.bType = PLAINTEXTKEYBLOB; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.bVersion = CUR_BLOB_VERSION; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.reserved = 0; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.len = key_len; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_len > sizeof(key_blob.key)) 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key_blob.key, key, key_len); 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (alg) { 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_AES: 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_len == 32) 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.aiKeyAlg = CALG_AES_256; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (key_len == 24) 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.aiKeyAlg = CALG_AES_192; 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.aiKeyAlg = CALG_AES_128; 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_3DES: 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.aiKeyAlg = CALG_3DES; 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_DES: 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.aiKeyAlg = CALG_DES; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_RC2: 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.aiKeyAlg = CALG_RC2; 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_RC4: 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_blob.hdr.aiKeyAlg = CALG_RC4; 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx = os_zalloc(sizeof(*ctx)); 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptAcquireContext(&ctx->prov, NULL, MS_ENH_RSA_AES_PROV, 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptAcquireContext"); 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail1; 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptImportKey(ctx->prov, (BYTE *) &key_blob, 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(key_blob), 0, 0, &ctx->key)) { 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptImportKey"); 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail2; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSetKeyParam(ctx->key, KP_MODE, (BYTE *) &mode, 0)) { 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptSetKeyParam(KP_MODE)"); 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail3; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iv && !CryptSetKeyParam(ctx->key, KP_IV, (BYTE *) iv, 0)) { 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptSetKeyParam(KP_IV)"); 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail3; 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ctx; 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail3: 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyKey(ctx->key); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail2: 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(ctx->prov, 0); 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail1: 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *crypt, size_t len) 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dlen; 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(crypt, plain, len); 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = len; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptEncrypt(ctx->key, 0, FALSE, 0, crypt, &dlen, len)) { 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptEncrypt"); 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(crypt, 0, len); 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *plain, size_t len) 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dlen; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(plain, crypt, len); 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = len; 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptDecrypt(ctx->key, 0, FALSE, 0, plain, &dlen)) { 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptDecrypt"); 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_cipher_deinit(struct crypto_cipher *ctx) 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyKey(ctx->key); 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(ctx->prov, 0); 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_public_key { 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTPROV prov; 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTKEY rsa; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_private_key { 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTPROV prov; 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTKEY rsa; 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len) 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Use crypto_public_key_from_cert() instead. */ 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_private_key * crypto_private_key_import(const u8 *key, 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *passwd) 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_public_key * crypto_public_key_from_cert(const u8 *buf, 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct crypto_public_key *pk; 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PCCERT_CONTEXT cc; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pk = os_zalloc(sizeof(*pk)); 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pk == NULL) 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cc = CertCreateCertificateContext(X509_ASN_ENCODING | 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS_7_ASN_ENCODING, buf, len); 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cc) { 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptCreateCertificateContext"); 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pk); 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptAcquireContext(&pk->prov, NULL, MS_DEF_PROV, PROV_RSA_FULL, 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0)) { 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptAcquireContext"); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pk); 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertFreeCertificateContext(cc); 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptImportPublicKeyInfo(pk->prov, X509_ASN_ENCODING | 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS_7_ASN_ENCODING, 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &cc->pCertInfo->SubjectPublicKeyInfo, 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &pk->rsa)) { 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_report_error("CryptImportPublicKeyInfo"); 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(pk->prov, 0); 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pk); 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertFreeCertificateContext(cc); 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertFreeCertificateContext(cc); 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pk; 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key, 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in, size_t inlen, 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out, size_t *outlen) 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD clen; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *tmp; 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*outlen < inlen) 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = malloc(*outlen); 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(tmp, in, inlen); 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clen = inlen; 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptEncrypt(key->rsa, 0, TRUE, 0, tmp, &clen, *outlen)) { 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CryptoAPI: Failed to encrypt using " 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "public key: %d", (int) GetLastError()); 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tmp); 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *outlen = clen; 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Reverse the output */ 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < *outlen; i++) 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out[i] = tmp[*outlen - 1 - i]; 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tmp); 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_private_key_sign_pkcs1(struct crypto_private_key *key, 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in, size_t inlen, 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out, size_t *outlen) 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_public_key_free(struct crypto_public_key *key) 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key) { 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyKey(key->rsa); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(key->prov, 0); 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(key); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_private_key_free(struct crypto_private_key *key) 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key) { 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyKey(key->rsa); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(key->prov, 0); 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(key); 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_global_init(void) 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return mingw_load_crypto_func(); 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_global_deinit(void) 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_mod_exp(const u8 *base, size_t base_len, 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *power, size_t power_len, 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *modulus, size_t modulus_len, 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *result, size_t *result_len) 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 784