Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmlibarchive/libarchive/archive_hmac.c
3153 views
1
/*-
2
* Copyright (c) 2014 Michihiro NAKAJIMA
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
*/
25
26
#include "archive_platform.h"
27
28
#ifdef HAVE_STRING_H
29
#include <string.h>
30
#endif
31
#include "archive.h"
32
#include "archive_hmac_private.h"
33
34
/*
35
* On systems that do not support any recognized crypto libraries,
36
* the archive_hmac.c file is expected to define no usable symbols.
37
*
38
* But some compilers and linkers choke on empty object files, so
39
* define a public symbol that will always exist. This could
40
* be removed someday if this file gains another always-present
41
* symbol definition.
42
*/
43
int __libarchive_hmac_build_hack(void) {
44
return 0;
45
}
46
47
48
#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto
49
50
static int
51
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
52
{
53
CCHmacInit(ctx, kCCHmacAlgSHA1, key, key_len);
54
return 0;
55
}
56
57
static void
58
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
59
size_t data_len)
60
{
61
CCHmacUpdate(ctx, data, data_len);
62
}
63
64
static void
65
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
66
{
67
CCHmacFinal(ctx, out);
68
*out_len = 20;
69
}
70
71
static void
72
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
73
{
74
memset(ctx, 0, sizeof(*ctx));
75
}
76
77
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
78
79
#ifndef BCRYPT_HASH_REUSABLE_FLAG
80
# define BCRYPT_HASH_REUSABLE_FLAG 0x00000020
81
#endif
82
83
static int
84
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
85
{
86
#ifdef __GNUC__
87
#pragma GCC diagnostic ignored "-Wcast-qual"
88
#endif
89
BCRYPT_ALG_HANDLE hAlg;
90
BCRYPT_HASH_HANDLE hHash;
91
DWORD hash_len;
92
PBYTE hash;
93
ULONG result;
94
NTSTATUS status;
95
96
ctx->hAlg = NULL;
97
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM,
98
MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
99
if (!BCRYPT_SUCCESS(status))
100
return -1;
101
status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PUCHAR)&hash_len,
102
sizeof(hash_len), &result, 0);
103
if (!BCRYPT_SUCCESS(status)) {
104
BCryptCloseAlgorithmProvider(hAlg, 0);
105
return -1;
106
}
107
hash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hash_len);
108
if (hash == NULL) {
109
BCryptCloseAlgorithmProvider(hAlg, 0);
110
return -1;
111
}
112
status = BCryptCreateHash(hAlg, &hHash, NULL, 0,
113
(PUCHAR)key, (ULONG)key_len, BCRYPT_HASH_REUSABLE_FLAG);
114
if (!BCRYPT_SUCCESS(status)) {
115
BCryptCloseAlgorithmProvider(hAlg, 0);
116
HeapFree(GetProcessHeap(), 0, hash);
117
return -1;
118
}
119
120
ctx->hAlg = hAlg;
121
ctx->hHash = hHash;
122
ctx->hash_len = hash_len;
123
ctx->hash = hash;
124
125
return 0;
126
}
127
128
static void
129
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
130
size_t data_len)
131
{
132
BCryptHashData(ctx->hHash, (PUCHAR)(uintptr_t)data, (ULONG)data_len, 0);
133
}
134
135
static void
136
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
137
{
138
BCryptFinishHash(ctx->hHash, ctx->hash, ctx->hash_len, 0);
139
if (ctx->hash_len == *out_len)
140
memcpy(out, ctx->hash, *out_len);
141
}
142
143
static void
144
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
145
{
146
if (ctx->hAlg != NULL) {
147
BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
148
HeapFree(GetProcessHeap(), 0, ctx->hash);
149
ctx->hAlg = NULL;
150
}
151
}
152
153
#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H)
154
155
static int
156
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
157
{
158
const mbedtls_md_info_t *info;
159
int ret;
160
161
mbedtls_md_init(ctx);
162
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
163
if (info == NULL) {
164
mbedtls_md_free(ctx);
165
return (-1);
166
}
167
ret = mbedtls_md_setup(ctx, info, 1);
168
if (ret != 0) {
169
mbedtls_md_free(ctx);
170
return (-1);
171
}
172
ret = mbedtls_md_hmac_starts(ctx, key, key_len);
173
if (ret != 0) {
174
mbedtls_md_free(ctx);
175
return (-1);
176
}
177
return 0;
178
}
179
180
static void
181
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
182
size_t data_len)
183
{
184
mbedtls_md_hmac_update(ctx, data, data_len);
185
}
186
187
static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
188
{
189
(void)out_len; /* UNUSED */
190
191
mbedtls_md_hmac_finish(ctx, out);
192
}
193
194
static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
195
{
196
mbedtls_md_free(ctx);
197
memset(ctx, 0, sizeof(*ctx));
198
}
199
200
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
201
202
static int
203
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
204
{
205
hmac_sha1_set_key(ctx, key_len, key);
206
return 0;
207
}
208
209
static void
210
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
211
size_t data_len)
212
{
213
hmac_sha1_update(ctx, data_len, data);
214
}
215
216
static void
217
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
218
{
219
hmac_sha1_digest(ctx, (unsigned)*out_len, out);
220
}
221
222
static void
223
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
224
{
225
memset(ctx, 0, sizeof(*ctx));
226
}
227
228
#elif defined(HAVE_LIBCRYPTO)
229
230
static int
231
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
232
{
233
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
234
EVP_MAC *mac;
235
236
char sha1[] = "SHA1";
237
OSSL_PARAM params[] = {
238
OSSL_PARAM_utf8_string("digest", sha1, sizeof(sha1) - 1),
239
OSSL_PARAM_END
240
};
241
242
mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
243
*ctx = EVP_MAC_CTX_new(mac);
244
EVP_MAC_free(mac);
245
if (*ctx == NULL)
246
return -1;
247
248
EVP_MAC_init(*ctx, key, key_len, params);
249
#else
250
*ctx = HMAC_CTX_new();
251
if (*ctx == NULL)
252
return -1;
253
HMAC_Init_ex(*ctx, key, key_len, EVP_sha1(), NULL);
254
#endif
255
return 0;
256
}
257
258
static void
259
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
260
size_t data_len)
261
{
262
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
263
EVP_MAC_update(*ctx, data, data_len);
264
#else
265
HMAC_Update(*ctx, data, data_len);
266
#endif
267
}
268
269
static void
270
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
271
{
272
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
273
size_t len = *out_len;
274
#else
275
unsigned int len = (unsigned int)*out_len;
276
#endif
277
278
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
279
EVP_MAC_final(*ctx, out, &len, *out_len);
280
#else
281
HMAC_Final(*ctx, out, &len);
282
#endif
283
*out_len = len;
284
}
285
286
static void
287
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
288
{
289
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
290
EVP_MAC_CTX_free(*ctx);
291
#else
292
HMAC_CTX_free(*ctx);
293
#endif
294
*ctx = NULL;
295
}
296
297
#else
298
299
/* Stub */
300
static int
301
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
302
{
303
(void)ctx;/* UNUSED */
304
(void)key;/* UNUSED */
305
(void)key_len;/* UNUSED */
306
return -1;
307
}
308
309
static void
310
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
311
size_t data_len)
312
{
313
(void)ctx;/* UNUSED */
314
(void)data;/* UNUSED */
315
(void)data_len;/* UNUSED */
316
}
317
318
static void
319
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
320
{
321
(void)ctx;/* UNUSED */
322
(void)out;/* UNUSED */
323
(void)out_len;/* UNUSED */
324
}
325
326
static void
327
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
328
{
329
(void)ctx;/* UNUSED */
330
}
331
332
#endif
333
334
const struct archive_hmac __archive_hmac = {
335
&__hmac_sha1_init,
336
&__hmac_sha1_update,
337
&__hmac_sha1_final,
338
&__hmac_sha1_cleanup,
339
};
340
341