archive_cryptor.c revision 338796
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