00001
00016 #include "includes.h"
00017 #include <windows.h>
00018 #include <wincrypt.h>
00019
00020 #include "common.h"
00021 #include "crypto.h"
00022
00023 #ifndef MS_ENH_RSA_AES_PROV
00024 #ifdef UNICODE
00025 #define MS_ENH_RSA_AES_PROV \
00026 L"Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"
00027 #else
00028 #define MS_ENH_RSA_AES_PROV \
00029 "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"
00030 #endif
00031 #endif
00032
00033 #ifndef CALG_HMAC
00034 #define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC)
00035 #endif
00036
00037 #ifdef CONFIG_TLS_INTERNAL
00038 #ifdef __MINGW32_VERSION
00039
00040
00041
00042
00043
00044 static PCCERT_CONTEXT WINAPI
00045 (*CertCreateCertificateContext)(DWORD dwCertEncodingType,
00046 const BYTE *pbCertEncoded,
00047 DWORD cbCertEncoded)
00048 = NULL;
00049
00050 static BOOL WINAPI
00051 (*CryptImportPublicKeyInfo)(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType,
00052 PCERT_PUBLIC_KEY_INFO pInfo, HCRYPTKEY *phKey)
00053 = NULL;
00054
00055
00056 static int mingw_load_crypto_func(void)
00057 {
00058 HINSTANCE dll;
00059
00060
00061
00062
00063 if (CertCreateCertificateContext)
00064 return 0;
00065
00066 dll = LoadLibrary("crypt32");
00067 if (dll == NULL) {
00068 wpa_printf(MSG_DEBUG, "CryptoAPI: Could not load crypt32 "
00069 "library");
00070 return -1;
00071 }
00072
00073 CertCreateCertificateContext = (void *) GetProcAddress(
00074 dll, "CertCreateCertificateContext");
00075 if (CertCreateCertificateContext == NULL) {
00076 wpa_printf(MSG_DEBUG, "CryptoAPI: Could not get "
00077 "CertCreateCertificateContext() address from "
00078 "crypt32 library");
00079 return -1;
00080 }
00081
00082 CryptImportPublicKeyInfo = GetProcAddress(
00083 dll, "CryptImportPublicKeyInfo");
00084 if (CryptImportPublicKeyInfo == NULL) {
00085 wpa_printf(MSG_DEBUG, "CryptoAPI: Could not get "
00086 "CryptImportPublicKeyInfo() address from "
00087 "crypt32 library");
00088 return -1;
00089 }
00090
00091 return 0;
00092 }
00093
00094 #else
00095
00096 static int mingw_load_crypto_func(void)
00097 {
00098 return 0;
00099 }
00100
00101 #endif
00102 #endif
00103
00104
00105 static void cryptoapi_report_error(const char *msg)
00106 {
00107 char *s, *pos;
00108 DWORD err = GetLastError();
00109
00110 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
00111 FORMAT_MESSAGE_FROM_SYSTEM,
00112 NULL, err, 0, (LPTSTR) &s, 0, NULL) == 0) {
00113 wpa_printf(MSG_DEBUG, "CryptoAPI: %s: %d", msg, (int) err);
00114 }
00115
00116 pos = s;
00117 while (*pos) {
00118 if (*pos == '\n' || *pos == '\r') {
00119 *pos = '\0';
00120 break;
00121 }
00122 pos++;
00123 }
00124
00125 wpa_printf(MSG_DEBUG, "CryptoAPI: %s: %d: (%s)", msg, (int) err, s);
00126 LocalFree(s);
00127 }
00128
00129
00130 int cryptoapi_hash_vector(ALG_ID alg, size_t hash_len, size_t num_elem,
00131 const u8 *addr[], const size_t *len, u8 *mac)
00132 {
00133 HCRYPTPROV prov;
00134 HCRYPTHASH hash;
00135 size_t i;
00136 DWORD hlen;
00137 int ret = 0;
00138
00139 if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0)) {
00140 cryptoapi_report_error("CryptAcquireContext");
00141 return -1;
00142 }
00143
00144 if (!CryptCreateHash(prov, alg, 0, 0, &hash)) {
00145 cryptoapi_report_error("CryptCreateHash");
00146 CryptReleaseContext(prov, 0);
00147 return -1;
00148 }
00149
00150 for (i = 0; i < num_elem; i++) {
00151 if (!CryptHashData(hash, (BYTE *) addr[i], len[i], 0)) {
00152 cryptoapi_report_error("CryptHashData");
00153 CryptDestroyHash(hash);
00154 CryptReleaseContext(prov, 0);
00155 }
00156 }
00157
00158 hlen = hash_len;
00159 if (!CryptGetHashParam(hash, HP_HASHVAL, mac, &hlen, 0)) {
00160 cryptoapi_report_error("CryptGetHashParam");
00161 ret = -1;
00162 }
00163
00164 CryptDestroyHash(hash);
00165 CryptReleaseContext(prov, 0);
00166
00167 return ret;
00168 }
00169
00170
00171 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00172 {
00173 return cryptoapi_hash_vector(CALG_MD4, 16, num_elem, addr, len, mac);
00174 }
00175
00176
00177 void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
00178 {
00179 u8 next, tmp;
00180 int i;
00181 HCRYPTPROV prov;
00182 HCRYPTKEY ckey;
00183 DWORD dlen;
00184 struct {
00185 BLOBHEADER hdr;
00186 DWORD len;
00187 BYTE key[8];
00188 } key_blob;
00189 DWORD mode = CRYPT_MODE_ECB;
00190
00191 key_blob.hdr.bType = PLAINTEXTKEYBLOB;
00192 key_blob.hdr.bVersion = CUR_BLOB_VERSION;
00193 key_blob.hdr.reserved = 0;
00194 key_blob.hdr.aiKeyAlg = CALG_DES;
00195 key_blob.len = 8;
00196
00197
00198 next = 0;
00199 for (i = 0; i < 7; i++) {
00200 tmp = key[i];
00201 key_blob.key[i] = (tmp >> i) | next | 1;
00202 next = tmp << (7 - i);
00203 }
00204 key_blob.key[i] = next | 1;
00205
00206 if (!CryptAcquireContext(&prov, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,
00207 CRYPT_VERIFYCONTEXT)) {
00208 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptAcquireContext failed: "
00209 "%d", (int) GetLastError());
00210 return;
00211 }
00212
00213 if (!CryptImportKey(prov, (BYTE *) &key_blob, sizeof(key_blob), 0, 0,
00214 &ckey)) {
00215 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptImportKey failed: %d",
00216 (int) GetLastError());
00217 CryptReleaseContext(prov, 0);
00218 return;
00219 }
00220
00221 if (!CryptSetKeyParam(ckey, KP_MODE, (BYTE *) &mode, 0)) {
00222 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptSetKeyParam(KP_MODE) "
00223 "failed: %d", (int) GetLastError());
00224 CryptDestroyKey(ckey);
00225 CryptReleaseContext(prov, 0);
00226 return;
00227 }
00228
00229 os_memcpy(cypher, clear, 8);
00230 dlen = 8;
00231 if (!CryptEncrypt(ckey, 0, FALSE, 0, cypher, &dlen, 8)) {
00232 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptEncrypt failed: %d",
00233 (int) GetLastError());
00234 os_memset(cypher, 0, 8);
00235 }
00236
00237 CryptDestroyKey(ckey);
00238 CryptReleaseContext(prov, 0);
00239 }
00240
00241
00242 #ifdef EAP_TLS_FUNCS
00243 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00244 {
00245 return cryptoapi_hash_vector(CALG_MD5, 16, num_elem, addr, len, mac);
00246 }
00247
00248
00249 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00250 {
00251 return cryptoapi_hash_vector(CALG_SHA, 20, num_elem, addr, len, mac);
00252 }
00253
00254
00255 struct aes_context {
00256 HCRYPTPROV prov;
00257 HCRYPTKEY ckey;
00258 };
00259
00260
00261 void * aes_encrypt_init(const u8 *key, size_t len)
00262 {
00263 struct aes_context *akey;
00264 struct {
00265 BLOBHEADER hdr;
00266 DWORD len;
00267 BYTE key[16];
00268 } key_blob;
00269 DWORD mode = CRYPT_MODE_ECB;
00270
00271 if (len != 16)
00272 return NULL;
00273
00274 key_blob.hdr.bType = PLAINTEXTKEYBLOB;
00275 key_blob.hdr.bVersion = CUR_BLOB_VERSION;
00276 key_blob.hdr.reserved = 0;
00277 key_blob.hdr.aiKeyAlg = CALG_AES_128;
00278 key_blob.len = len;
00279 os_memcpy(key_blob.key, key, len);
00280
00281 akey = os_zalloc(sizeof(*akey));
00282 if (akey == NULL)
00283 return NULL;
00284
00285 if (!CryptAcquireContext(&akey->prov, NULL,
00286 MS_ENH_RSA_AES_PROV, PROV_RSA_AES,
00287 CRYPT_VERIFYCONTEXT)) {
00288 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptAcquireContext failed: "
00289 "%d", (int) GetLastError());
00290 os_free(akey);
00291 return NULL;
00292 }
00293
00294 if (!CryptImportKey(akey->prov, (BYTE *) &key_blob, sizeof(key_blob),
00295 0, 0, &akey->ckey)) {
00296 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptImportKey failed: %d",
00297 (int) GetLastError());
00298 CryptReleaseContext(akey->prov, 0);
00299 os_free(akey);
00300 return NULL;
00301 }
00302
00303 if (!CryptSetKeyParam(akey->ckey, KP_MODE, (BYTE *) &mode, 0)) {
00304 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptSetKeyParam(KP_MODE) "
00305 "failed: %d", (int) GetLastError());
00306 CryptDestroyKey(akey->ckey);
00307 CryptReleaseContext(akey->prov, 0);
00308 os_free(akey);
00309 return NULL;
00310 }
00311
00312 return akey;
00313 }
00314
00315
00316 void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
00317 {
00318 struct aes_context *akey = ctx;
00319 DWORD dlen;
00320
00321 os_memcpy(crypt, plain, 16);
00322 dlen = 16;
00323 if (!CryptEncrypt(akey->ckey, 0, FALSE, 0, crypt, &dlen, 16)) {
00324 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptEncrypt failed: %d",
00325 (int) GetLastError());
00326 os_memset(crypt, 0, 16);
00327 }
00328 }
00329
00330
00331 void aes_encrypt_deinit(void *ctx)
00332 {
00333 struct aes_context *akey = ctx;
00334 if (akey) {
00335 CryptDestroyKey(akey->ckey);
00336 CryptReleaseContext(akey->prov, 0);
00337 os_free(akey);
00338 }
00339 }
00340
00341
00342 void * aes_decrypt_init(const u8 *key, size_t len)
00343 {
00344 return aes_encrypt_init(key, len);
00345 }
00346
00347
00348 void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
00349 {
00350 struct aes_context *akey = ctx;
00351 DWORD dlen;
00352
00353 os_memcpy(plain, crypt, 16);
00354 dlen = 16;
00355
00356 if (!CryptDecrypt(akey->ckey, 0, FALSE, 0, plain, &dlen)) {
00357 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptDecrypt failed: %d",
00358 (int) GetLastError());
00359 }
00360 }
00361
00362
00363 void aes_decrypt_deinit(void *ctx)
00364 {
00365 aes_encrypt_deinit(ctx);
00366 }
00367
00368 #ifdef CONFIG_TLS_INTERNAL
00369
00370 struct crypto_hash {
00371 enum crypto_hash_alg alg;
00372 int error;
00373 HCRYPTPROV prov;
00374 HCRYPTHASH hash;
00375 HCRYPTKEY key;
00376 };
00377
00378 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
00379 size_t key_len)
00380 {
00381 struct crypto_hash *ctx;
00382 ALG_ID calg;
00383 struct {
00384 BLOBHEADER hdr;
00385 DWORD len;
00386 BYTE key[32];
00387 } key_blob;
00388
00389 os_memset(&key_blob, 0, sizeof(key_blob));
00390 switch (alg) {
00391 case CRYPTO_HASH_ALG_MD5:
00392 calg = CALG_MD5;
00393 break;
00394 case CRYPTO_HASH_ALG_SHA1:
00395 calg = CALG_SHA;
00396 break;
00397 case CRYPTO_HASH_ALG_HMAC_MD5:
00398 case CRYPTO_HASH_ALG_HMAC_SHA1:
00399 calg = CALG_HMAC;
00400 key_blob.hdr.bType = PLAINTEXTKEYBLOB;
00401 key_blob.hdr.bVersion = CUR_BLOB_VERSION;
00402 key_blob.hdr.reserved = 0;
00403
00404
00405
00406
00407
00408
00409 key_blob.hdr.aiKeyAlg = CALG_RC2;
00410 key_blob.len = key_len;
00411 if (key_len > sizeof(key_blob.key))
00412 return NULL;
00413 os_memcpy(key_blob.key, key, key_len);
00414 break;
00415 default:
00416 return NULL;
00417 }
00418
00419 ctx = os_zalloc(sizeof(*ctx));
00420 if (ctx == NULL)
00421 return NULL;
00422
00423 ctx->alg = alg;
00424
00425 if (!CryptAcquireContext(&ctx->prov, NULL, NULL, PROV_RSA_FULL, 0)) {
00426 cryptoapi_report_error("CryptAcquireContext");
00427 os_free(ctx);
00428 return NULL;
00429 }
00430
00431 if (calg == CALG_HMAC) {
00432 #ifndef CRYPT_IPSEC_HMAC_KEY
00433 #define CRYPT_IPSEC_HMAC_KEY 0x00000100
00434 #endif
00435 if (!CryptImportKey(ctx->prov, (BYTE *) &key_blob,
00436 sizeof(key_blob), 0, CRYPT_IPSEC_HMAC_KEY,
00437 &ctx->key)) {
00438 cryptoapi_report_error("CryptImportKey");
00439 CryptReleaseContext(ctx->prov, 0);
00440 os_free(ctx);
00441 return NULL;
00442 }
00443 }
00444
00445 if (!CryptCreateHash(ctx->prov, calg, ctx->key, 0, &ctx->hash)) {
00446 cryptoapi_report_error("CryptCreateHash");
00447 CryptReleaseContext(ctx->prov, 0);
00448 os_free(ctx);
00449 return NULL;
00450 }
00451
00452 if (calg == CALG_HMAC) {
00453 HMAC_INFO info;
00454 os_memset(&info, 0, sizeof(info));
00455 switch (alg) {
00456 case CRYPTO_HASH_ALG_HMAC_MD5:
00457 info.HashAlgid = CALG_MD5;
00458 break;
00459 case CRYPTO_HASH_ALG_HMAC_SHA1:
00460 info.HashAlgid = CALG_SHA;
00461 break;
00462 default:
00463
00464 break;
00465 }
00466
00467 if (!CryptSetHashParam(ctx->hash, HP_HMAC_INFO, (BYTE *) &info,
00468 0)) {
00469 cryptoapi_report_error("CryptSetHashParam");
00470 CryptDestroyHash(ctx->hash);
00471 CryptReleaseContext(ctx->prov, 0);
00472 os_free(ctx);
00473 return NULL;
00474 }
00475 }
00476
00477 return ctx;
00478 }
00479
00480
00481 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
00482 {
00483 if (ctx == NULL || ctx->error)
00484 return;
00485
00486 if (!CryptHashData(ctx->hash, (BYTE *) data, len, 0)) {
00487 cryptoapi_report_error("CryptHashData");
00488 ctx->error = 1;
00489 }
00490 }
00491
00492
00493 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
00494 {
00495 int ret = 0;
00496 DWORD hlen;
00497
00498 if (ctx == NULL)
00499 return -2;
00500
00501 if (mac == NULL || len == NULL)
00502 goto done;
00503
00504 if (ctx->error) {
00505 ret = -2;
00506 goto done;
00507 }
00508
00509 hlen = *len;
00510 if (!CryptGetHashParam(ctx->hash, HP_HASHVAL, mac, &hlen, 0)) {
00511 cryptoapi_report_error("CryptGetHashParam");
00512 ret = -2;
00513 }
00514 *len = hlen;
00515
00516 done:
00517 if (ctx->alg == CRYPTO_HASH_ALG_HMAC_SHA1 ||
00518 ctx->alg == CRYPTO_HASH_ALG_HMAC_MD5)
00519 CryptDestroyKey(ctx->key);
00520
00521 os_free(ctx);
00522
00523 return ret;
00524 }
00525
00526
00527 struct crypto_cipher {
00528 HCRYPTPROV prov;
00529 HCRYPTKEY key;
00530 };
00531
00532
00533 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
00534 const u8 *iv, const u8 *key,
00535 size_t key_len)
00536 {
00537 struct crypto_cipher *ctx;
00538 struct {
00539 BLOBHEADER hdr;
00540 DWORD len;
00541 BYTE key[32];
00542 } key_blob;
00543 DWORD mode = CRYPT_MODE_CBC;
00544
00545 key_blob.hdr.bType = PLAINTEXTKEYBLOB;
00546 key_blob.hdr.bVersion = CUR_BLOB_VERSION;
00547 key_blob.hdr.reserved = 0;
00548 key_blob.len = key_len;
00549 if (key_len > sizeof(key_blob.key))
00550 return NULL;
00551 os_memcpy(key_blob.key, key, key_len);
00552
00553 switch (alg) {
00554 case CRYPTO_CIPHER_ALG_AES:
00555 if (key_len == 32)
00556 key_blob.hdr.aiKeyAlg = CALG_AES_256;
00557 else if (key_len == 24)
00558 key_blob.hdr.aiKeyAlg = CALG_AES_192;
00559 else
00560 key_blob.hdr.aiKeyAlg = CALG_AES_128;
00561 break;
00562 case CRYPTO_CIPHER_ALG_3DES:
00563 key_blob.hdr.aiKeyAlg = CALG_3DES;
00564 break;
00565 case CRYPTO_CIPHER_ALG_DES:
00566 key_blob.hdr.aiKeyAlg = CALG_DES;
00567 break;
00568 case CRYPTO_CIPHER_ALG_RC2:
00569 key_blob.hdr.aiKeyAlg = CALG_RC2;
00570 break;
00571 case CRYPTO_CIPHER_ALG_RC4:
00572 key_blob.hdr.aiKeyAlg = CALG_RC4;
00573 break;
00574 default:
00575 return NULL;
00576 }
00577
00578 ctx = os_zalloc(sizeof(*ctx));
00579 if (ctx == NULL)
00580 return NULL;
00581
00582 if (!CryptAcquireContext(&ctx->prov, NULL, MS_ENH_RSA_AES_PROV,
00583 PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
00584 cryptoapi_report_error("CryptAcquireContext");
00585 goto fail1;
00586 }
00587
00588 if (!CryptImportKey(ctx->prov, (BYTE *) &key_blob,
00589 sizeof(key_blob), 0, 0, &ctx->key)) {
00590 cryptoapi_report_error("CryptImportKey");
00591 goto fail2;
00592 }
00593
00594 if (!CryptSetKeyParam(ctx->key, KP_MODE, (BYTE *) &mode, 0)) {
00595 cryptoapi_report_error("CryptSetKeyParam(KP_MODE)");
00596 goto fail3;
00597 }
00598
00599 if (iv && !CryptSetKeyParam(ctx->key, KP_IV, (BYTE *) iv, 0)) {
00600 cryptoapi_report_error("CryptSetKeyParam(KP_IV)");
00601 goto fail3;
00602 }
00603
00604 return ctx;
00605
00606 fail3:
00607 CryptDestroyKey(ctx->key);
00608 fail2:
00609 CryptReleaseContext(ctx->prov, 0);
00610 fail1:
00611 os_free(ctx);
00612 return NULL;
00613 }
00614
00615
00616 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
00617 u8 *crypt, size_t len)
00618 {
00619 DWORD dlen;
00620
00621 os_memcpy(crypt, plain, len);
00622 dlen = len;
00623 if (!CryptEncrypt(ctx->key, 0, FALSE, 0, crypt, &dlen, len)) {
00624 cryptoapi_report_error("CryptEncrypt");
00625 os_memset(crypt, 0, len);
00626 return -1;
00627 }
00628
00629 return 0;
00630 }
00631
00632
00633 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
00634 u8 *plain, size_t len)
00635 {
00636 DWORD dlen;
00637
00638 os_memcpy(plain, crypt, len);
00639 dlen = len;
00640 if (!CryptDecrypt(ctx->key, 0, FALSE, 0, plain, &dlen)) {
00641 cryptoapi_report_error("CryptDecrypt");
00642 return -1;
00643 }
00644
00645 return 0;
00646 }
00647
00648
00649 void crypto_cipher_deinit(struct crypto_cipher *ctx)
00650 {
00651 CryptDestroyKey(ctx->key);
00652 CryptReleaseContext(ctx->prov, 0);
00653 os_free(ctx);
00654 }
00655
00656
00657 struct crypto_public_key {
00658 HCRYPTPROV prov;
00659 HCRYPTKEY rsa;
00660 };
00661
00662 struct crypto_private_key {
00663 HCRYPTPROV prov;
00664 HCRYPTKEY rsa;
00665 };
00666
00667
00668 struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len)
00669 {
00670
00671 return NULL;
00672 }
00673
00674
00675 struct crypto_private_key * crypto_private_key_import(const u8 *key,
00676 size_t len,
00677 const char *passwd)
00678 {
00679
00680 return NULL;
00681 }
00682
00683
00684 struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
00685 size_t len)
00686 {
00687 struct crypto_public_key *pk;
00688 PCCERT_CONTEXT cc;
00689
00690 pk = os_zalloc(sizeof(*pk));
00691 if (pk == NULL)
00692 return NULL;
00693
00694 cc = CertCreateCertificateContext(X509_ASN_ENCODING |
00695 PKCS_7_ASN_ENCODING, buf, len);
00696 if (!cc) {
00697 cryptoapi_report_error("CryptCreateCertificateContext");
00698 os_free(pk);
00699 return NULL;
00700 }
00701
00702 if (!CryptAcquireContext(&pk->prov, NULL, MS_DEF_PROV, PROV_RSA_FULL,
00703 0)) {
00704 cryptoapi_report_error("CryptAcquireContext");
00705 os_free(pk);
00706 CertFreeCertificateContext(cc);
00707 return NULL;
00708 }
00709
00710 if (!CryptImportPublicKeyInfo(pk->prov, X509_ASN_ENCODING |
00711 PKCS_7_ASN_ENCODING,
00712 &cc->pCertInfo->SubjectPublicKeyInfo,
00713 &pk->rsa)) {
00714 cryptoapi_report_error("CryptImportPublicKeyInfo");
00715 CryptReleaseContext(pk->prov, 0);
00716 os_free(pk);
00717 CertFreeCertificateContext(cc);
00718 return NULL;
00719 }
00720
00721 CertFreeCertificateContext(cc);
00722
00723 return pk;
00724 }
00725
00726
00727 int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
00728 const u8 *in, size_t inlen,
00729 u8 *out, size_t *outlen)
00730 {
00731 DWORD clen;
00732 u8 *tmp;
00733 size_t i;
00734
00735 if (*outlen < inlen)
00736 return -1;
00737 tmp = malloc(*outlen);
00738 if (tmp == NULL)
00739 return -1;
00740
00741 os_memcpy(tmp, in, inlen);
00742 clen = inlen;
00743 if (!CryptEncrypt(key->rsa, 0, TRUE, 0, tmp, &clen, *outlen)) {
00744 wpa_printf(MSG_DEBUG, "CryptoAPI: Failed to encrypt using "
00745 "public key: %d", (int) GetLastError());
00746 os_free(tmp);
00747 return -1;
00748 }
00749
00750 *outlen = clen;
00751
00752
00753 for (i = 0; i < *outlen; i++)
00754 out[i] = tmp[*outlen - 1 - i];
00755
00756 os_free(tmp);
00757
00758 return 0;
00759 }
00760
00761
00762 int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
00763 const u8 *in, size_t inlen,
00764 u8 *out, size_t *outlen)
00765 {
00766
00767 return -1;
00768 }
00769
00770
00771 void crypto_public_key_free(struct crypto_public_key *key)
00772 {
00773 if (key) {
00774 CryptDestroyKey(key->rsa);
00775 CryptReleaseContext(key->prov, 0);
00776 os_free(key);
00777 }
00778 }
00779
00780
00781 void crypto_private_key_free(struct crypto_private_key *key)
00782 {
00783 if (key) {
00784 CryptDestroyKey(key->rsa);
00785 CryptReleaseContext(key->prov, 0);
00786 os_free(key);
00787 }
00788 }
00789
00790
00791 int crypto_global_init(void)
00792 {
00793 return mingw_load_crypto_func();
00794 }
00795
00796
00797 void crypto_global_deinit(void)
00798 {
00799 }
00800
00801 #endif
00802
00803 #endif
00804