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