1 /* $NetBSD: evp-w32.c,v 1.2 2017/01/28 21:31:47 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2015, Secure Endpoints Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * - Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 30 * OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Windows fallback provider: decides whether to use hcrypto or 35 * wincng depending on whether bcrypt.dll is available (i.e. it 36 * is runtime compatible back to XP, but will use the native 37 * crypto APIs from Vista onwards). 38 */ 39 40 #include <config.h> 41 #include <krb5/roken.h> 42 43 #include <assert.h> 44 45 #include <evp.h> 46 #include <evp-w32.h> 47 #include <evp-hcrypto.h> 48 49 #include <evp-wincng.h> 50 51 static LONG wincng_available = -1; 52 53 static __inline int 54 wincng_check_availability(void) 55 { 56 if (wincng_available == -1) { 57 char szBCryptDllPath[MAX_PATH]; 58 UINT cbBCryptDllPath; 59 60 cbBCryptDllPath = GetSystemDirectory(szBCryptDllPath, 61 sizeof(szBCryptDllPath)); 62 if (cbBCryptDllPath > 0 && 63 cbBCryptDllPath < sizeof(szBCryptDllPath) && 64 strncat_s(szBCryptDllPath, 65 sizeof(szBCryptDllPath), "\\bcrypt.dll", 11) == 0) { 66 HANDLE hBCryptDll = LoadLibrary(szBCryptDllPath); 67 68 InterlockedCompareExchangeRelease(&wincng_available, 69 !!hBCryptDll, -1); 70 if (hBCryptDll) 71 FreeLibrary(hBCryptDll); 72 } 73 } 74 75 return wincng_available == 1; 76 } 77 78 BOOL WINAPI 79 _hc_w32crypto_DllMain(HINSTANCE hinstDLL, 80 DWORD fdwReason, 81 LPVOID lpvReserved) 82 { 83 if (fdwReason == DLL_PROCESS_DETACH) { 84 /* 85 * Don't bother cleaning up on process exit, only on 86 * FreeLibrary() (in which case lpvReserved will be NULL). 87 */ 88 if (lpvReserved == NULL) 89 _hc_wincng_cleanup(); 90 } 91 92 return TRUE; 93 } 94 95 #define EVP_W32CRYPTO_PROVIDER(type, name) \ 96 \ 97 const type *hc_EVP_w32crypto_ ##name (void) \ 98 { \ 99 if (wincng_check_availability()) \ 100 return hc_EVP_wincng_ ##name (); \ 101 else if (HCRYPTO_FALLBACK) \ 102 return hc_EVP_hcrypto_ ##name (); \ 103 else \ 104 return NULL; \ 105 } 106 107 #define EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(type, name) \ 108 \ 109 const type *hc_EVP_w32crypto_ ##name (void) \ 110 { \ 111 return hc_EVP_hcrypto_ ##name (); \ 112 } 113 114 EVP_W32CRYPTO_PROVIDER(EVP_MD, md2) 115 EVP_W32CRYPTO_PROVIDER(EVP_MD, md4) 116 EVP_W32CRYPTO_PROVIDER(EVP_MD, md5) 117 EVP_W32CRYPTO_PROVIDER(EVP_MD, sha1) 118 EVP_W32CRYPTO_PROVIDER(EVP_MD, sha256) 119 EVP_W32CRYPTO_PROVIDER(EVP_MD, sha384) 120 EVP_W32CRYPTO_PROVIDER(EVP_MD, sha512) 121 122 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc2_cbc) 123 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc2_40_cbc) 124 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc2_64_cbc) 125 126 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc4) 127 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc4_40) 128 129 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, des_cbc) 130 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, des_ede3_cbc) 131 132 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_128_cbc) 133 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_192_cbc) 134 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_256_cbc) 135 136 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_128_cfb8) 137 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_192_cfb8) 138 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_256_cfb8) 139 140 EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(EVP_CIPHER, camellia_128_cbc) 141 EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(EVP_CIPHER, camellia_192_cbc) 142 EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(EVP_CIPHER, camellia_256_cbc) 143