archive_cryptor.c revision 302001
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_cryptor_private.h"
33
34/*
35 * On systems that do not support any recognized crypto libraries,
36 * this file will normally 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 */
43int __libarchive_cryptor_build_hack(void) {
44	return 0;
45}
46
47#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
48
49static int
50pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
51    size_t salt_len, unsigned rounds, uint8_t *derived_key,
52    size_t derived_key_len)
53{
54	CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pw,
55	    pw_len, salt, salt_len, kCCPRFHmacAlgSHA1, rounds,
56	    derived_key, derived_key_len);
57	return 0;
58}
59
60#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
61#ifdef _MSC_VER
62#pragma comment(lib, "Bcrypt.lib")
63#endif
64
65static int
66pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
67	size_t salt_len, unsigned rounds, uint8_t *derived_key,
68	size_t derived_key_len)
69{
70	NTSTATUS status;
71	BCRYPT_ALG_HANDLE hAlg;
72
73	status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM,
74		MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
75	if (!BCRYPT_SUCCESS(status))
76		return -1;
77
78	status = BCryptDeriveKeyPBKDF2(hAlg,
79		(PUCHAR)(uintptr_t)pw, (ULONG)pw_len,
80		(PUCHAR)(uintptr_t)salt, (ULONG)salt_len, rounds,
81		(PUCHAR)derived_key, (ULONG)derived_key_len, 0);
82
83	BCryptCloseAlgorithmProvider(hAlg, 0);
84
85	return (BCRYPT_SUCCESS(status)) ? 0: -1;
86}
87
88#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_PBKDF2_H)
89
90static int
91pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
92    size_t salt_len, unsigned rounds, uint8_t *derived_key,
93    size_t derived_key_len) {
94	pbkdf2_hmac_sha1((unsigned)pw_len, (const uint8_t *)pw, rounds,
95	    salt_len, salt, derived_key_len, derived_key);
96	return 0;
97}
98
99#elif defined(HAVE_LIBCRYPTO) && defined(HAVE_PKCS5_PBKDF2_HMAC_SHA1)
100
101static int
102pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
103    size_t salt_len, unsigned rounds, uint8_t *derived_key,
104    size_t derived_key_len) {
105
106	PKCS5_PBKDF2_HMAC_SHA1(pw, pw_len, salt, salt_len, rounds,
107	    derived_key_len, derived_key);
108	return 0;
109}
110
111#else
112
113/* Stub */
114static int
115pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
116    size_t salt_len, unsigned rounds, uint8_t *derived_key,
117    size_t derived_key_len) {
118	(void)pw; /* UNUSED */
119	(void)pw_len; /* UNUSED */
120	(void)salt; /* UNUSED */
121	(void)salt_len; /* UNUSED */
122	(void)rounds; /* UNUSED */
123	(void)derived_key; /* UNUSED */
124	(void)derived_key_len; /* UNUSED */
125	return -1; /* UNSUPPORTED */
126}
127
128#endif
129
130#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
131# if MAC_OS_X_VERSION_MAX_ALLOWED < 1090
132#  define kCCAlgorithmAES kCCAlgorithmAES128
133# endif
134
135static int
136aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
137{
138	CCCryptorStatus r;
139
140	ctx->key_len = key_len;
141	memcpy(ctx->key, key, key_len);
142	memset(ctx->nonce, 0, sizeof(ctx->nonce));
143	ctx->encr_pos = AES_BLOCK_SIZE;
144	r = CCCryptorCreateWithMode(kCCEncrypt, kCCModeECB, kCCAlgorithmAES,
145	    ccNoPadding, NULL, key, key_len, NULL, 0, 0, 0, &ctx->ctx);
146	return (r == kCCSuccess)? 0: -1;
147}
148
149static int
150aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
151{
152	CCCryptorRef ref = ctx->ctx;
153	CCCryptorStatus r;
154
155	r = CCCryptorReset(ref, NULL);
156	if (r != kCCSuccess)
157		return -1;
158	r = CCCryptorUpdate(ref, ctx->nonce, AES_BLOCK_SIZE, ctx->encr_buf,
159	    AES_BLOCK_SIZE, NULL);
160	return (r == kCCSuccess)? 0: -1;
161}
162
163static int
164aes_ctr_release(archive_crypto_ctx *ctx)
165{
166	memset(ctx->key, 0, ctx->key_len);
167	memset(ctx->nonce, 0, sizeof(ctx->nonce));
168	return 0;
169}
170
171#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
172
173static int
174aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
175{
176	BCRYPT_ALG_HANDLE hAlg;
177	BCRYPT_KEY_HANDLE hKey;
178	DWORD keyObj_len, aes_key_len;
179	PBYTE keyObj;
180	ULONG result;
181	NTSTATUS status;
182	BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
183
184	ctx->hAlg = NULL;
185	ctx->hKey = NULL;
186	ctx->keyObj = NULL;
187	switch (key_len) {
188	case 16: aes_key_len = 128; break;
189	case 24: aes_key_len = 192; break;
190	case 32: aes_key_len = 256; break;
191	default: return -1;
192	}
193	status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM,
194		MS_PRIMITIVE_PROVIDER, 0);
195	if (!BCRYPT_SUCCESS(status))
196		return -1;
197	status = BCryptGetProperty(hAlg, BCRYPT_KEY_LENGTHS, (PUCHAR)&key_lengths,
198		sizeof(key_lengths), &result, 0);
199	if (!BCRYPT_SUCCESS(status)) {
200		BCryptCloseAlgorithmProvider(hAlg, 0);
201		return -1;
202	}
203	if (key_lengths.dwMinLength > aes_key_len
204		|| key_lengths.dwMaxLength < aes_key_len) {
205		BCryptCloseAlgorithmProvider(hAlg, 0);
206		return -1;
207	}
208	status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObj_len,
209		sizeof(keyObj_len), &result, 0);
210	if (!BCRYPT_SUCCESS(status)) {
211		BCryptCloseAlgorithmProvider(hAlg, 0);
212		return -1;
213	}
214	keyObj = (PBYTE)HeapAlloc(GetProcessHeap(), 0, keyObj_len);
215	if (keyObj == NULL) {
216		BCryptCloseAlgorithmProvider(hAlg, 0);
217		return -1;
218	}
219	status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE,
220		(PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0);
221	if (!BCRYPT_SUCCESS(status)) {
222		BCryptCloseAlgorithmProvider(hAlg, 0);
223		HeapFree(GetProcessHeap(), 0, keyObj);
224		return -1;
225	}
226	status = BCryptGenerateSymmetricKey(hAlg, &hKey,
227		keyObj, keyObj_len,
228		(PUCHAR)(uintptr_t)key, (ULONG)key_len, 0);
229	if (!BCRYPT_SUCCESS(status)) {
230		BCryptCloseAlgorithmProvider(hAlg, 0);
231		HeapFree(GetProcessHeap(), 0, keyObj);
232		return -1;
233	}
234
235	ctx->hAlg = hAlg;
236	ctx->hKey = hKey;
237	ctx->keyObj = keyObj;
238	ctx->keyObj_len = keyObj_len;
239	ctx->encr_pos = AES_BLOCK_SIZE;
240
241	return 0;
242}
243
244static int
245aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
246{
247	NTSTATUS status;
248	ULONG result;
249
250	status = BCryptEncrypt(ctx->hKey, (PUCHAR)ctx->nonce, AES_BLOCK_SIZE,
251		NULL, NULL, 0, (PUCHAR)ctx->encr_buf, AES_BLOCK_SIZE,
252		&result, 0);
253	return BCRYPT_SUCCESS(status) ? 0 : -1;
254}
255
256static int
257aes_ctr_release(archive_crypto_ctx *ctx)
258{
259
260	if (ctx->hAlg != NULL) {
261		BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
262		ctx->hAlg = NULL;
263		BCryptDestroyKey(ctx->hKey);
264		ctx->hKey = NULL;
265		HeapFree(GetProcessHeap(), 0, ctx->keyObj);
266		ctx->keyObj = NULL;
267	}
268	memset(ctx, 0, sizeof(*ctx));
269	return 0;
270}
271
272#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
273
274static int
275aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
276{
277	ctx->key_len = key_len;
278	memcpy(ctx->key, key, key_len);
279	memset(ctx->nonce, 0, sizeof(ctx->nonce));
280	ctx->encr_pos = AES_BLOCK_SIZE;
281	memset(&ctx->ctx, 0, sizeof(ctx->ctx));
282	return 0;
283}
284
285static int
286aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
287{
288	aes_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key);
289	aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce);
290	return 0;
291}
292
293static int
294aes_ctr_release(archive_crypto_ctx *ctx)
295{
296	memset(ctx, 0, sizeof(*ctx));
297	return 0;
298}
299
300#elif defined(HAVE_LIBCRYPTO)
301
302static int
303aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
304{
305
306	switch (key_len) {
307	case 16: ctx->type = EVP_aes_128_ecb(); break;
308	case 24: ctx->type = EVP_aes_192_ecb(); break;
309	case 32: ctx->type = EVP_aes_256_ecb(); break;
310	default: ctx->type = NULL; return -1;
311	}
312
313	ctx->key_len = key_len;
314	memcpy(ctx->key, key, key_len);
315	memset(ctx->nonce, 0, sizeof(ctx->nonce));
316	ctx->encr_pos = AES_BLOCK_SIZE;
317	EVP_CIPHER_CTX_init(&ctx->ctx);
318	return 0;
319}
320
321static int
322aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
323{
324	int outl = 0;
325	int r;
326
327	r = EVP_EncryptInit_ex(&ctx->ctx, ctx->type, NULL, ctx->key, NULL);
328	if (r == 0)
329		return -1;
330	r = EVP_EncryptUpdate(&ctx->ctx, ctx->encr_buf, &outl, ctx->nonce,
331	    AES_BLOCK_SIZE);
332	if (r == 0 || outl != AES_BLOCK_SIZE)
333		return -1;
334	return 0;
335}
336
337static int
338aes_ctr_release(archive_crypto_ctx *ctx)
339{
340	EVP_CIPHER_CTX_cleanup(&ctx->ctx);
341	memset(ctx->key, 0, ctx->key_len);
342	memset(ctx->nonce, 0, sizeof(ctx->nonce));
343	return 0;
344}
345
346#else
347
348#define ARCHIVE_CRYPTOR_STUB
349/* Stub */
350static int
351aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
352{
353	(void)ctx; /* UNUSED */
354	(void)key; /* UNUSED */
355	(void)key_len; /* UNUSED */
356	return -1;
357}
358
359static int
360aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
361{
362	(void)ctx; /* UNUSED */
363	return -1;
364}
365
366static int
367aes_ctr_release(archive_crypto_ctx *ctx)
368{
369	(void)ctx; /* UNUSED */
370	return 0;
371}
372
373#endif
374
375#ifdef ARCHIVE_CRYPTOR_STUB
376static int
377aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
378    size_t in_len, uint8_t * const out, size_t *out_len)
379{
380	(void)ctx; /* UNUSED */
381	(void)in; /* UNUSED */
382	(void)in_len; /* UNUSED */
383	(void)out; /* UNUSED */
384	(void)out_len; /* UNUSED */
385	aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */
386	return -1;
387}
388
389#else
390static void
391aes_ctr_increase_counter(archive_crypto_ctx *ctx)
392{
393	uint8_t *const nonce = ctx->nonce;
394	int j;
395
396	for (j = 0; j < 8; j++) {
397		if (++nonce[j])
398			break;
399	}
400}
401
402static int
403aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
404    size_t in_len, uint8_t * const out, size_t *out_len)
405{
406	uint8_t *const ebuf = ctx->encr_buf;
407	unsigned pos = ctx->encr_pos;
408	unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len);
409	unsigned i;
410
411	for (i = 0; i < max; ) {
412		if (pos == AES_BLOCK_SIZE) {
413			aes_ctr_increase_counter(ctx);
414			if (aes_ctr_encrypt_counter(ctx) != 0)
415				return -1;
416			while (max -i >= AES_BLOCK_SIZE) {
417				for (pos = 0; pos < AES_BLOCK_SIZE; pos++)
418					out[i+pos] = in[i+pos] ^ ebuf[pos];
419				i += AES_BLOCK_SIZE;
420				aes_ctr_increase_counter(ctx);
421				if (aes_ctr_encrypt_counter(ctx) != 0)
422					return -1;
423			}
424			pos = 0;
425			if (i >= max)
426				break;
427		}
428		out[i] = in[i] ^ ebuf[pos++];
429		i++;
430	}
431	ctx->encr_pos = pos;
432	*out_len = i;
433
434	return 0;
435}
436#endif /* ARCHIVE_CRYPTOR_STUB */
437
438
439const struct archive_cryptor __archive_cryptor =
440{
441  &pbkdf2_sha1,
442  &aes_ctr_init,
443  &aes_ctr_update,
444  &aes_ctr_release,
445  &aes_ctr_init,
446  &aes_ctr_update,
447  &aes_ctr_release,
448};
449