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


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:33