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