xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/hcrypto/evp-w32.c (revision afab4e300d3a9fb07dd8c80daf53d0feb3345706)
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
wincng_check_availability(void)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
_hc_w32crypto_DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)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