/src/libtorrent/src/hasher.cpp
Line | Count | Source |
1 | | /* |
2 | | |
3 | | Copyright (c) 2013-2014, 2016-2021, Arvid Norberg |
4 | | Copyright (c) 2016, 2018, Alden Torres |
5 | | Copyright (c) 2017, 2019, Andrei Kurushin |
6 | | Copyright (c) 2017, Steven Siloti |
7 | | Copyright (c) 2020, Paul-Louis Ageneau |
8 | | All rights reserved. |
9 | | |
10 | | Redistribution and use in source and binary forms, with or without |
11 | | modification, are permitted provided that the following conditions |
12 | | are met: |
13 | | |
14 | | * Redistributions of source code must retain the above copyright |
15 | | notice, this list of conditions and the following disclaimer. |
16 | | * Redistributions in binary form must reproduce the above copyright |
17 | | notice, this list of conditions and the following disclaimer in |
18 | | the documentation and/or other materials provided with the distribution. |
19 | | * Neither the name of the author nor the names of its |
20 | | contributors may be used to endorse or promote products derived |
21 | | from this software without specific prior written permission. |
22 | | |
23 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
24 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
25 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
26 | | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
27 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
28 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
29 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
30 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
31 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
32 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
33 | | POSSIBILITY OF SUCH DAMAGE. |
34 | | |
35 | | */ |
36 | | |
37 | | #include "libtorrent/hasher.hpp" |
38 | | #include "libtorrent/error_code.hpp" |
39 | | #include "libtorrent/assert.hpp" |
40 | | |
41 | | #include "libtorrent/aux_/disable_deprecation_warnings_push.hpp" |
42 | | |
43 | | namespace libtorrent { |
44 | | |
45 | | TORRENT_CRYPTO_NAMESPACE |
46 | | |
47 | | hasher::hasher() |
48 | 0 | { |
49 | | #ifdef TORRENT_USE_LIBGCRYPT |
50 | | gcry_md_open(&m_context, GCRY_MD_SHA1, 0); |
51 | | #elif TORRENT_USE_COMMONCRYPTO |
52 | | CC_SHA1_Init(&m_context); |
53 | | #elif TORRENT_USE_CNG |
54 | | #elif TORRENT_USE_CRYPTOAPI |
55 | | #elif defined TORRENT_USE_LIBCRYPTO |
56 | | SHA1_Init(&m_context); |
57 | | #else |
58 | | SHA1_init(&m_context); |
59 | | #endif |
60 | 0 | } |
61 | | |
62 | | hasher::hasher(span<char const> data) |
63 | 0 | : hasher() |
64 | 0 | { |
65 | 0 | update(data); |
66 | 0 | } |
67 | | |
68 | | hasher::hasher(char const* data, int len) |
69 | 0 | : hasher() |
70 | 0 | { |
71 | 0 | TORRENT_ASSERT(len > 0); |
72 | 0 | update({data, len}); |
73 | 0 | } |
74 | | |
75 | | #ifdef TORRENT_USE_LIBGCRYPT |
76 | | hasher::hasher(hasher const& h) |
77 | | { |
78 | | gcry_md_copy(&m_context, h.m_context); |
79 | | } |
80 | | |
81 | | hasher& hasher::operator=(hasher const& h) & |
82 | | { |
83 | | if (this == &h) return *this; |
84 | | gcry_md_close(m_context); |
85 | | gcry_md_copy(&m_context, h.m_context); |
86 | | return *this; |
87 | | } |
88 | | #else |
89 | 0 | hasher::hasher(hasher const&) = default; |
90 | 0 | hasher& hasher::operator=(hasher const&) & = default; |
91 | | #endif |
92 | | |
93 | | hasher& hasher::update(char const* data, int len) |
94 | 0 | { |
95 | 0 | return update({data, len}); |
96 | 0 | } |
97 | | |
98 | | hasher& hasher::update(span<char const> data) |
99 | 0 | { |
100 | 0 | TORRENT_ASSERT(data.size() > 0); |
101 | | #ifdef TORRENT_USE_LIBGCRYPT |
102 | | gcry_md_write(m_context, data.data(), static_cast<std::size_t>(data.size())); |
103 | | #elif TORRENT_USE_COMMONCRYPTO |
104 | | CC_SHA1_Update(&m_context, reinterpret_cast<unsigned char const*>(data.data()), CC_LONG(data.size())); |
105 | | #elif TORRENT_USE_CNG |
106 | | m_context.update(data); |
107 | | #elif TORRENT_USE_CRYPTOAPI |
108 | | m_context.update(data); |
109 | | #elif defined TORRENT_USE_LIBCRYPTO |
110 | | SHA1_Update(&m_context, reinterpret_cast<unsigned char const*>(data.data()) |
111 | 0 | , static_cast<std::size_t>(data.size())); |
112 | | #else |
113 | | SHA1_update(&m_context, reinterpret_cast<unsigned char const*>(data.data()) |
114 | | , static_cast<std::size_t>(data.size())); |
115 | | #endif |
116 | 0 | return *this; |
117 | 0 | } |
118 | | |
119 | | sha1_hash hasher::final() |
120 | 0 | { |
121 | 0 | sha1_hash digest; |
122 | | #ifdef TORRENT_USE_LIBGCRYPT |
123 | | gcry_md_final(m_context); |
124 | | digest.assign(reinterpret_cast<char const*>(gcry_md_read(m_context, 0))); |
125 | | #elif TORRENT_USE_COMMONCRYPTO |
126 | | CC_SHA1_Final(reinterpret_cast<unsigned char*>(digest.data()), &m_context); |
127 | | #elif TORRENT_USE_CNG |
128 | | m_context.get_hash(digest.data(), digest.size()); |
129 | | #elif TORRENT_USE_CRYPTOAPI |
130 | | m_context.get_hash(digest.data(), digest.size()); |
131 | | #elif defined TORRENT_USE_LIBCRYPTO |
132 | | SHA1_Final(reinterpret_cast<unsigned char*>(digest.data()), &m_context); |
133 | | #else |
134 | | SHA1_final(reinterpret_cast<unsigned char*>(digest.data()), &m_context); |
135 | | #endif |
136 | 0 | return digest; |
137 | 0 | } |
138 | | |
139 | | void hasher::reset() |
140 | 0 | { |
141 | | #ifdef TORRENT_USE_LIBGCRYPT |
142 | | gcry_md_reset(m_context); |
143 | | #elif TORRENT_USE_COMMONCRYPTO |
144 | | CC_SHA1_Init(&m_context); |
145 | | #elif TORRENT_USE_CNG |
146 | | m_context.reset(); |
147 | | #elif TORRENT_USE_CRYPTOAPI |
148 | | m_context.reset(); |
149 | | #elif defined TORRENT_USE_LIBCRYPTO |
150 | | SHA1_Init(&m_context); |
151 | | #else |
152 | | SHA1_init(&m_context); |
153 | | #endif |
154 | 0 | } |
155 | | |
156 | | hasher::~hasher() |
157 | 0 | { |
158 | | #if defined TORRENT_USE_LIBGCRYPT |
159 | | gcry_md_close(m_context); |
160 | | #endif |
161 | 0 | } |
162 | | |
163 | | hasher256::hasher256() |
164 | 0 | { |
165 | | #ifdef TORRENT_USE_LIBGCRYPT |
166 | | gcry_md_open(&m_context, GCRY_MD_SHA256, 0); |
167 | | #elif TORRENT_USE_COMMONCRYPTO |
168 | | CC_SHA256_Init(&m_context); |
169 | | #elif TORRENT_USE_CNG |
170 | | #elif TORRENT_USE_CRYPTOAPI_SHA_512 |
171 | | #elif defined TORRENT_USE_LIBCRYPTO |
172 | | SHA256_Init(&m_context); |
173 | | #else |
174 | | SHA256_init(m_context); |
175 | | #endif |
176 | 0 | } |
177 | | |
178 | | hasher256::hasher256(span<char const> data) |
179 | 0 | : hasher256() |
180 | 0 | { |
181 | 0 | update(data); |
182 | 0 | } |
183 | | |
184 | | hasher256::hasher256(char const* data, int len) |
185 | 0 | : hasher256() |
186 | 0 | { |
187 | 0 | TORRENT_ASSERT(len > 0); |
188 | 0 | update({ data, len }); |
189 | 0 | } |
190 | | |
191 | | #ifdef TORRENT_USE_LIBGCRYPT |
192 | | hasher256::hasher256(hasher256 const& h) |
193 | | { |
194 | | gcry_md_copy(&m_context, h.m_context); |
195 | | } |
196 | | |
197 | | hasher256& hasher256::operator=(hasher256 const& h) & |
198 | | { |
199 | | if (this == &h) return *this; |
200 | | gcry_md_close(m_context); |
201 | | gcry_md_copy(&m_context, h.m_context); |
202 | | return *this; |
203 | | } |
204 | | #else |
205 | 0 | hasher256::hasher256(hasher256 const&) = default; |
206 | 0 | hasher256& hasher256::operator=(hasher256 const&) & = default; |
207 | | #endif |
208 | | |
209 | | hasher256& hasher256::update(char const* data, int len) |
210 | 0 | { |
211 | 0 | return update({ data, len }); |
212 | 0 | } |
213 | | |
214 | | hasher256& hasher256::update(span<char const> data) |
215 | 0 | { |
216 | 0 | TORRENT_ASSERT(!data.empty()); |
217 | | #ifdef TORRENT_USE_LIBGCRYPT |
218 | | gcry_md_write(m_context, data.data(), data.size()); |
219 | | #elif TORRENT_USE_COMMONCRYPTO |
220 | | CC_SHA256_Update(&m_context, reinterpret_cast<unsigned char const*>(data.data()), CC_LONG(data.size())); |
221 | | #elif TORRENT_USE_CNG |
222 | | m_context.update(data); |
223 | | #elif TORRENT_USE_CRYPTOAPI_SHA_512 |
224 | | m_context.update(data); |
225 | | #elif defined TORRENT_USE_LIBCRYPTO |
226 | | SHA256_Update(&m_context, reinterpret_cast<unsigned char const*>(data.data()) |
227 | 0 | , static_cast<std::size_t>(data.size())); |
228 | | #else |
229 | | SHA256_update(m_context, reinterpret_cast<unsigned char const*>(data.data()) |
230 | | , static_cast<std::size_t>(data.size())); |
231 | | #endif |
232 | 0 | return *this; |
233 | 0 | } |
234 | | |
235 | | sha256_hash hasher256::final() |
236 | 0 | { |
237 | 0 | sha256_hash digest; |
238 | | #ifdef TORRENT_USE_LIBGCRYPT |
239 | | gcry_md_final(m_context); |
240 | | digest.assign((char const*)gcry_md_read(m_context, 0)); |
241 | | #elif TORRENT_USE_COMMONCRYPTO |
242 | | CC_SHA256_Final(reinterpret_cast<unsigned char*>(digest.data()), &m_context); |
243 | | #elif TORRENT_USE_CNG |
244 | | m_context.get_hash(digest.data(), digest.size()); |
245 | | #elif TORRENT_USE_CRYPTOAPI_SHA_512 |
246 | | m_context.get_hash(digest.data(), digest.size()); |
247 | | #elif defined TORRENT_USE_LIBCRYPTO |
248 | | SHA256_Final(reinterpret_cast<unsigned char*>(digest.data()), &m_context); |
249 | | #else |
250 | | SHA256_final(reinterpret_cast<unsigned char*>(digest.data()), m_context); |
251 | | #endif |
252 | 0 | return digest; |
253 | 0 | } |
254 | | |
255 | | void hasher256::reset() |
256 | 0 | { |
257 | | #ifdef TORRENT_USE_LIBGCRYPT |
258 | | gcry_md_reset(m_context); |
259 | | #elif TORRENT_USE_COMMONCRYPTO |
260 | | CC_SHA256_Init(&m_context); |
261 | | #elif TORRENT_USE_CNG |
262 | | m_context.reset(); |
263 | | #elif TORRENT_USE_CRYPTOAPI_SHA_512 |
264 | | m_context.reset(); |
265 | | #elif defined TORRENT_USE_LIBCRYPTO |
266 | | SHA256_Init(&m_context); |
267 | | #else |
268 | | SHA256_init(m_context); |
269 | | #endif |
270 | 0 | } |
271 | | |
272 | | hasher256::~hasher256() |
273 | 0 | { |
274 | | #if defined TORRENT_USE_LIBGCRYPT |
275 | | gcry_md_close(m_context); |
276 | | #endif |
277 | 0 | } |
278 | | |
279 | | TORRENT_CRYPTO_NAMESPACE_END |
280 | | |
281 | | #include "libtorrent/aux_/disable_warnings_pop.hpp" |
282 | | |
283 | | } |