Home | History | Annotate | Line # | Download | only in hcrypto
      1 /*	$NetBSD: evp-w32.c,v 1.3 2023/06/19 21:41:43 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, md4)
    115 EVP_W32CRYPTO_PROVIDER(EVP_MD, md5)
    116 EVP_W32CRYPTO_PROVIDER(EVP_MD, sha1)
    117 EVP_W32CRYPTO_PROVIDER(EVP_MD, sha256)
    118 EVP_W32CRYPTO_PROVIDER(EVP_MD, sha384)
    119 EVP_W32CRYPTO_PROVIDER(EVP_MD, sha512)
    120 
    121 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc2_cbc)
    122 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc2_40_cbc)
    123 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc2_64_cbc)
    124 
    125 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc4)
    126 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc4_40)
    127 
    128 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, des_cbc)
    129 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, des_ede3_cbc)
    130 
    131 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_128_cbc)
    132 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_192_cbc)
    133 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_256_cbc)
    134 
    135 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_128_cfb8)
    136 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_192_cfb8)
    137 EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_256_cfb8)
    138 
    139 EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(EVP_CIPHER, camellia_128_cbc)
    140 EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(EVP_CIPHER, camellia_192_cbc)
    141 EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(EVP_CIPHER, camellia_256_cbc)
    142