1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 
8 #ifndef INCLUDE_hash_sha1_win32_h__
9 #define INCLUDE_hash_sha1_win32_h__
10 
11 #include "hash/sha1.h"
12 
13 #include <wincrypt.h>
14 #include <strsafe.h>
15 
16 enum hash_win32_prov_type {
17 	INVALID = 0,
18 	CRYPTOAPI,
19 	CNG
20 };
21 
22 /*
23  * CryptoAPI is available for hashing on Windows XP and newer.
24  */
25 
26 struct hash_cryptoapi_prov {
27 	HCRYPTPROV handle;
28 };
29 
30 /*
31  * CNG (bcrypt.dll) is significantly more performant than CryptoAPI and is
32  * preferred, however it is only available on Windows 2008 and newer and
33  * must therefore be dynamically loaded, and we must inline constants that
34  * would not exist when building in pre-Windows 2008 environments.
35  */
36 
37 /* Function declarations for CNG */
38 typedef NTSTATUS (WINAPI *hash_win32_cng_open_algorithm_provider_fn)(
39 	HANDLE /* BCRYPT_ALG_HANDLE */ *phAlgorithm,
40 	LPCWSTR pszAlgId,
41 	LPCWSTR pszImplementation,
42 	DWORD dwFlags);
43 
44 typedef NTSTATUS (WINAPI *hash_win32_cng_get_property_fn)(
45 	HANDLE /* BCRYPT_HANDLE */ hObject,
46 	LPCWSTR pszProperty,
47 	PUCHAR pbOutput,
48 	ULONG cbOutput,
49 	ULONG *pcbResult,
50 	ULONG dwFlags);
51 
52 typedef NTSTATUS (WINAPI *hash_win32_cng_create_hash_fn)(
53 	HANDLE /* BCRYPT_ALG_HANDLE */ hAlgorithm,
54 	HANDLE /* BCRYPT_HASH_HANDLE */ *phHash,
55 	PUCHAR pbHashObject, ULONG cbHashObject,
56 	PUCHAR pbSecret,
57 	ULONG cbSecret,
58 	ULONG dwFlags);
59 
60 typedef NTSTATUS (WINAPI *hash_win32_cng_finish_hash_fn)(
61 	HANDLE /* BCRYPT_HASH_HANDLE */ hHash,
62 	PUCHAR pbOutput,
63 	ULONG cbOutput,
64 	ULONG dwFlags);
65 
66 typedef NTSTATUS (WINAPI *hash_win32_cng_hash_data_fn)(
67 	HANDLE /* BCRYPT_HASH_HANDLE */ hHash,
68 	PUCHAR pbInput,
69 	ULONG cbInput,
70 	ULONG dwFlags);
71 
72 typedef NTSTATUS (WINAPI *hash_win32_cng_destroy_hash_fn)(
73 	HANDLE /* BCRYPT_HASH_HANDLE */ hHash);
74 
75 typedef NTSTATUS (WINAPI *hash_win32_cng_close_algorithm_provider_fn)(
76 	HANDLE /* BCRYPT_ALG_HANDLE */ hAlgorithm,
77 	ULONG dwFlags);
78 
79 struct hash_cng_prov {
80 	/* DLL for CNG */
81 	HINSTANCE dll;
82 
83 	/* Function pointers for CNG */
84 	hash_win32_cng_open_algorithm_provider_fn open_algorithm_provider;
85 	hash_win32_cng_get_property_fn get_property;
86 	hash_win32_cng_create_hash_fn create_hash;
87 	hash_win32_cng_finish_hash_fn finish_hash;
88 	hash_win32_cng_hash_data_fn hash_data;
89 	hash_win32_cng_destroy_hash_fn destroy_hash;
90 	hash_win32_cng_close_algorithm_provider_fn close_algorithm_provider;
91 
92 	HANDLE /* BCRYPT_ALG_HANDLE */ handle;
93 	DWORD hash_object_size;
94 };
95 
96 typedef struct {
97 	enum hash_win32_prov_type type;
98 
99 	union {
100 		struct hash_cryptoapi_prov cryptoapi;
101 		struct hash_cng_prov cng;
102 	} prov;
103 } git_hash_prov;
104 
105 /* Hash contexts */
106 
107 struct hash_cryptoapi_ctx {
108 	bool valid;
109 	HCRYPTHASH hash_handle;
110 };
111 
112 struct hash_cng_ctx {
113 	bool updated;
114 	HANDLE /* BCRYPT_HASH_HANDLE */ hash_handle;
115 	PBYTE hash_object;
116 };
117 
118 struct git_hash_sha1_ctx {
119 	enum hash_win32_prov_type type;
120 	git_hash_prov *prov;
121 
122 	union {
123 		struct hash_cryptoapi_ctx cryptoapi;
124 		struct hash_cng_ctx cng;
125 	} ctx;
126 };
127 
128 #endif
129