archive_cryptor.c revision 338795
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 && r != kCCUnimplemented)
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	if ((ctx->ctx = EVP_CIPHER_CTX_new()) == NULL)
306		return -1;
307
308	switch (key_len) {
309	case 16: ctx->type = EVP_aes_128_ecb(); break;
310	case 24: ctx->type = EVP_aes_192_ecb(); break;
311	case 32: ctx->type = EVP_aes_256_ecb(); break;
312	default: ctx->type = NULL; return -1;
313	}
314
315	ctx->key_len = key_len;
316	memcpy(ctx->key, key, key_len);
317	memset(ctx->nonce, 0, sizeof(ctx->nonce));
318	ctx->encr_pos = AES_BLOCK_SIZE;
319	EVP_CIPHER_CTX_init(ctx->ctx);
320	return 0;
321}
322
323static int
324aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
325{
326	int outl = 0;
327	int r;
328
329	r = EVP_EncryptInit_ex(ctx->ctx, ctx->type, NULL, ctx->key, NULL);
330	if (r == 0)
331		return -1;
332	r = EVP_EncryptUpdate(ctx->ctx, ctx->encr_buf, &outl, ctx->nonce,
333	    AES_BLOCK_SIZE);
334	if (r == 0 || outl != AES_BLOCK_SIZE)
335		return -1;
336	return 0;
337}
338
339static int
340aes_ctr_release(archive_crypto_ctx *ctx)
341{
342	EVP_CIPHER_CTX_free(ctx->ctx);
343	memset(ctx->key, 0, ctx->key_len);
344	memset(ctx->nonce, 0, sizeof(ctx->nonce));
345	return 0;
346}
347
348#else
349
350#define ARCHIVE_CRYPTOR_STUB
351/* Stub */
352static int
353aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
354{
355	(void)ctx; /* UNUSED */
356	(void)key; /* UNUSED */
357	(void)key_len; /* UNUSED */
358	return -1;
359}
360
361static int
362aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
363{
364	(void)ctx; /* UNUSED */
365	return -1;
366}
367
368static int
369aes_ctr_release(archive_crypto_ctx *ctx)
370{
371	(void)ctx; /* UNUSED */
372	return 0;
373}
374
375#endif
376
377#ifdef ARCHIVE_CRYPTOR_STUB
378static int
379aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
380    size_t in_len, uint8_t * const out, size_t *out_len)
381{
382	(void)ctx; /* UNUSED */
383	(void)in; /* UNUSED */
384	(void)in_len; /* UNUSED */
385	(void)out; /* UNUSED */
386	(void)out_len; /* UNUSED */
387	aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */
388	return -1;
389}
390
391#else
392static void
393aes_ctr_increase_counter(archive_crypto_ctx *ctx)
394{
395	uint8_t *const nonce = ctx->nonce;
396	int j;
397
398	for (j = 0; j < 8; j++) {
399		if (++nonce[j])
400			break;
401	}
402}
403
404static int
405aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
406    size_t in_len, uint8_t * const out, size_t *out_len)
407{
408	uint8_t *const ebuf = ctx->encr_buf;
409	unsigned pos = ctx->encr_pos;
410	unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len);
411	unsigned i;
412
413	for (i = 0; i < max; ) {
414		if (pos == AES_BLOCK_SIZE) {
415			aes_ctr_increase_counter(ctx);
416			if (aes_ctr_encrypt_counter(ctx) != 0)
417				return -1;
418			while (max -i >= AES_BLOCK_SIZE) {
419				for (pos = 0; pos < AES_BLOCK_SIZE; pos++)
420					out[i+pos] = in[i+pos] ^ ebuf[pos];
421				i += AES_BLOCK_SIZE;
422				aes_ctr_increase_counter(ctx);
423				if (aes_ctr_encrypt_counter(ctx) != 0)
424					return -1;
425			}
426			pos = 0;
427			if (i >= max)
428				break;
429		}
430		out[i] = in[i] ^ ebuf[pos++];
431		i++;
432	}
433	ctx->encr_pos = pos;
434	*out_len = i;
435
436	return 0;
437}
438#endif /* ARCHIVE_CRYPTOR_STUB */
439
440
441const struct archive_cryptor __archive_cryptor =
442{
443  &pbkdf2_sha1,
444  &aes_ctr_init,
445  &aes_ctr_update,
446  &aes_ctr_release,
447  &aes_ctr_init,
448  &aes_ctr_update,
449  &aes_ctr_release,
450};
451