1109998Smarkm/*- 2109998Smarkm* Copyright (c) 2014 Michihiro NAKAJIMA 3160814Ssimon* All rights reserved. 4160814Ssimon* 5160814Ssimon* Redistribution and use in source and binary forms, with or without 6109998Smarkm* modification, are permitted provided that the following conditions 7160814Ssimon* are met: 8109998Smarkm* 1. Redistributions of source code must retain the above copyright 9109998Smarkm* notice, this list of conditions and the following disclaimer. 10109998Smarkm* 2. Redistributions in binary form must reproduce the above copyright 11109998Smarkm* notice, this list of conditions and the following disclaimer in the 12109998Smarkm* documentation and/or other materials provided with the distribution. 13109998Smarkm* 14109998Smarkm* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15109998Smarkm* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16109998Smarkm* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17109998Smarkm* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18109998Smarkm* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19109998Smarkm* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20109998Smarkm* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21109998Smarkm* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22109998Smarkm* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23109998Smarkm* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24109998Smarkm*/ 25109998Smarkm 26109998Smarkm#include "archive_platform.h" 27109998Smarkm 28109998Smarkm#ifdef HAVE_STRING_H 29109998Smarkm#include <string.h> 30109998Smarkm#endif 31109998Smarkm#include "archive.h" 32109998Smarkm#include "archive_cryptor_private.h" 33109998Smarkm 34109998Smarkm/* 35109998Smarkm * On systems that do not support any recognized crypto libraries, 36109998Smarkm * this file will normally define no usable symbols. 37109998Smarkm * 38109998Smarkm * But some compilers and linkers choke on empty object files, so 39109998Smarkm * define a public symbol that will always exist. This could 40109998Smarkm * be removed someday if this file gains another always-present 41109998Smarkm * symbol definition. 42109998Smarkm */ 43109998Smarkmint __libarchive_cryptor_build_hack(void) { 44109998Smarkm return 0; 45109998Smarkm} 46109998Smarkm 47109998Smarkm#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto 48109998Smarkm 49109998Smarkmstatic int 50109998Smarkmpbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, 51109998Smarkm size_t salt_len, unsigned rounds, uint8_t *derived_key, 52109998Smarkm size_t derived_key_len) 53109998Smarkm{ 54109998Smarkm CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pw, 55109998Smarkm pw_len, salt, salt_len, kCCPRFHmacAlgSHA1, rounds, 56109998Smarkm derived_key, derived_key_len); 57109998Smarkm return 0; 58109998Smarkm} 59160814Ssimon 60160814Ssimon#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) 61160814Ssimon#ifdef _MSC_VER 62160814Ssimon#pragma comment(lib, "Bcrypt.lib") 63160814Ssimon#endif 64109998Smarkm 65109998Smarkmstatic int 66160814Ssimonpbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, 67109998Smarkm size_t salt_len, unsigned rounds, uint8_t *derived_key, 68238405Sjkim size_t derived_key_len) 69238405Sjkim{ 70238405Sjkim NTSTATUS status; 71238405Sjkim BCRYPT_ALG_HANDLE hAlg; 72109998Smarkm 73109998Smarkm status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, 74109998Smarkm MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); 75109998Smarkm if (!BCRYPT_SUCCESS(status)) 76109998Smarkm return -1; 77238405Sjkim 78160814Ssimon status = BCryptDeriveKeyPBKDF2(hAlg, 79109998Smarkm (PUCHAR)(uintptr_t)pw, (ULONG)pw_len, 80109998Smarkm (PUCHAR)(uintptr_t)salt, (ULONG)salt_len, rounds, 81109998Smarkm (PUCHAR)derived_key, (ULONG)derived_key_len, 0); 82109998Smarkm 83160814Ssimon BCryptCloseAlgorithmProvider(hAlg, 0); 84160814Ssimon 85160814Ssimon return (BCRYPT_SUCCESS(status)) ? 0: -1; 86160814Ssimon} 87109998Smarkm 88109998Smarkm#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_PKCS5_H) 89109998Smarkm 90109998Smarkmstatic int 91109998Smarkmpbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, 92109998Smarkm size_t salt_len, unsigned rounds, uint8_t *derived_key, 93109998Smarkm size_t derived_key_len) 94160814Ssimon{ 95160814Ssimon mbedtls_md_context_t ctx; 96238405Sjkim const mbedtls_md_info_t *info; 97109998Smarkm int ret; 98109998Smarkm 99109998Smarkm mbedtls_md_init(&ctx); 100109998Smarkm info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); 101109998Smarkm if (info == NULL) { 102109998Smarkm mbedtls_md_free(&ctx); 103109998Smarkm return (-1); 104109998Smarkm } 105160814Ssimon ret = mbedtls_md_setup(&ctx, info, 1); 106160814Ssimon if (ret != 0) { 107160814Ssimon mbedtls_md_free(&ctx); 108109998Smarkm return (-1); 109109998Smarkm } 110160814Ssimon ret = mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char *)pw, 111109998Smarkm pw_len, salt, salt_len, rounds, derived_key_len, derived_key); 112109998Smarkm 113109998Smarkm mbedtls_md_free(&ctx); 114109998Smarkm return (ret); 115279264Sdelphij} 116279264Sdelphij 117279264Sdelphij#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_PBKDF2_H) 118279264Sdelphij 119279264Sdelphijstatic int 120109998Smarkmpbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, 121109998Smarkm size_t salt_len, unsigned rounds, uint8_t *derived_key, 122109998Smarkm size_t derived_key_len) { 123109998Smarkm pbkdf2_hmac_sha1((unsigned)pw_len, (const uint8_t *)pw, rounds, 124160814Ssimon salt_len, salt, derived_key_len, derived_key); 125160814Ssimon return 0; 126160814Ssimon} 127160814Ssimon 128160814Ssimon#elif defined(HAVE_LIBCRYPTO) && defined(HAVE_PKCS5_PBKDF2_HMAC_SHA1) 129160814Ssimon 130160814Ssimonstatic int 131160814Ssimonpbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, 132160814Ssimon size_t salt_len, unsigned rounds, uint8_t *derived_key, 133160814Ssimon size_t derived_key_len) { 134160814Ssimon 135160814Ssimon PKCS5_PBKDF2_HMAC_SHA1(pw, pw_len, salt, salt_len, rounds, 136160814Ssimon derived_key_len, derived_key); 137160814Ssimon return 0; 138109998Smarkm} 139109998Smarkm 140109998Smarkm#else 141109998Smarkm 142109998Smarkm/* Stub */ 143109998Smarkmstatic int 144109998Smarkmpbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, 145109998Smarkm size_t salt_len, unsigned rounds, uint8_t *derived_key, 146109998Smarkm size_t derived_key_len) { 147109998Smarkm (void)pw; /* UNUSED */ 148109998Smarkm (void)pw_len; /* UNUSED */ 149109998Smarkm (void)salt; /* UNUSED */ 150109998Smarkm (void)salt_len; /* UNUSED */ 151109998Smarkm (void)rounds; /* UNUSED */ 152109998Smarkm (void)derived_key; /* UNUSED */ 153109998Smarkm (void)derived_key_len; /* UNUSED */ 154109998Smarkm return -1; /* UNSUPPORTED */ 155109998Smarkm} 156109998Smarkm 157109998Smarkm#endif 158109998Smarkm 159109998Smarkm#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto 160109998Smarkm# if MAC_OS_X_VERSION_MAX_ALLOWED < 1090 161109998Smarkm# define kCCAlgorithmAES kCCAlgorithmAES128 162109998Smarkm# endif 163109998Smarkm 164109998Smarkmstatic int 165109998Smarkmaes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) 166109998Smarkm{ 167109998Smarkm CCCryptorStatus r; 168109998Smarkm 169109998Smarkm ctx->key_len = key_len; 170109998Smarkm memcpy(ctx->key, key, key_len); 171109998Smarkm memset(ctx->nonce, 0, sizeof(ctx->nonce)); 172109998Smarkm ctx->encr_pos = AES_BLOCK_SIZE; 173109998Smarkm r = CCCryptorCreateWithMode(kCCEncrypt, kCCModeECB, kCCAlgorithmAES, 174109998Smarkm ccNoPadding, NULL, key, key_len, NULL, 0, 0, 0, &ctx->ctx); 175109998Smarkm return (r == kCCSuccess)? 0: -1; 176160814Ssimon} 177109998Smarkm 178109998Smarkmstatic int 179109998Smarkmaes_ctr_encrypt_counter(archive_crypto_ctx *ctx) 180109998Smarkm{ 181109998Smarkm CCCryptorRef ref = ctx->ctx; 182109998Smarkm CCCryptorStatus r; 183109998Smarkm 184109998Smarkm r = CCCryptorReset(ref, NULL); 185109998Smarkm if (r != kCCSuccess && r != kCCUnimplemented) 186160814Ssimon return -1; 187109998Smarkm r = CCCryptorUpdate(ref, ctx->nonce, AES_BLOCK_SIZE, ctx->encr_buf, 188109998Smarkm AES_BLOCK_SIZE, NULL); 189109998Smarkm return (r == kCCSuccess)? 0: -1; 190109998Smarkm} 191109998Smarkm 192109998Smarkmstatic int 193109998Smarkmaes_ctr_release(archive_crypto_ctx *ctx) 194109998Smarkm{ 195109998Smarkm memset(ctx->key, 0, ctx->key_len); 196109998Smarkm memset(ctx->nonce, 0, sizeof(ctx->nonce)); 197109998Smarkm return 0; 198109998Smarkm} 199109998Smarkm 200109998Smarkm#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) 201109998Smarkm 202109998Smarkmstatic int 203160814Ssimonaes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) 204109998Smarkm{ 205109998Smarkm BCRYPT_ALG_HANDLE hAlg; 206109998Smarkm BCRYPT_KEY_HANDLE hKey; 207109998Smarkm DWORD keyObj_len, aes_key_len; 208109998Smarkm PBYTE keyObj; 209109998Smarkm ULONG result; 210109998Smarkm NTSTATUS status; 211109998Smarkm BCRYPT_KEY_LENGTHS_STRUCT key_lengths; 212109998Smarkm 213109998Smarkm ctx->hAlg = NULL; 214109998Smarkm ctx->hKey = NULL; 215109998Smarkm ctx->keyObj = NULL; 216109998Smarkm switch (key_len) { 217109998Smarkm case 16: aes_key_len = 128; break; 218109998Smarkm case 24: aes_key_len = 192; break; 219109998Smarkm case 32: aes_key_len = 256; break; 220109998Smarkm default: return -1; 221109998Smarkm } 222109998Smarkm status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, 223109998Smarkm MS_PRIMITIVE_PROVIDER, 0); 224109998Smarkm if (!BCRYPT_SUCCESS(status)) 225109998Smarkm return -1; 226109998Smarkm status = BCryptGetProperty(hAlg, BCRYPT_KEY_LENGTHS, (PUCHAR)&key_lengths, 227109998Smarkm sizeof(key_lengths), &result, 0); 228109998Smarkm if (!BCRYPT_SUCCESS(status)) { 229109998Smarkm BCryptCloseAlgorithmProvider(hAlg, 0); 230109998Smarkm return -1; 231160814Ssimon } 232109998Smarkm if (key_lengths.dwMinLength > aes_key_len 233109998Smarkm || key_lengths.dwMaxLength < aes_key_len) { 234109998Smarkm BCryptCloseAlgorithmProvider(hAlg, 0); 235109998Smarkm return -1; 236109998Smarkm } 237109998Smarkm status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObj_len, 238109998Smarkm sizeof(keyObj_len), &result, 0); 239109998Smarkm if (!BCRYPT_SUCCESS(status)) { 240109998Smarkm BCryptCloseAlgorithmProvider(hAlg, 0); 241109998Smarkm return -1; 242109998Smarkm } 243109998Smarkm keyObj = (PBYTE)HeapAlloc(GetProcessHeap(), 0, keyObj_len); 244109998Smarkm if (keyObj == NULL) { 245109998Smarkm BCryptCloseAlgorithmProvider(hAlg, 0); 246109998Smarkm return -1; 247109998Smarkm } 248109998Smarkm status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE, 249109998Smarkm (PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0); 250109998Smarkm if (!BCRYPT_SUCCESS(status)) { 251109998Smarkm BCryptCloseAlgorithmProvider(hAlg, 0); 252109998Smarkm HeapFree(GetProcessHeap(), 0, keyObj); 253109998Smarkm return -1; 254109998Smarkm } 255109998Smarkm status = BCryptGenerateSymmetricKey(hAlg, &hKey, 256109998Smarkm keyObj, keyObj_len, 257109998Smarkm (PUCHAR)(uintptr_t)key, (ULONG)key_len, 0); 258109998Smarkm if (!BCRYPT_SUCCESS(status)) { 259109998Smarkm BCryptCloseAlgorithmProvider(hAlg, 0); 260109998Smarkm HeapFree(GetProcessHeap(), 0, keyObj); 261109998Smarkm return -1; 262109998Smarkm } 263109998Smarkm 264109998Smarkm ctx->hAlg = hAlg; 265109998Smarkm ctx->hKey = hKey; 266109998Smarkm ctx->keyObj = keyObj; 267109998Smarkm ctx->keyObj_len = keyObj_len; 268109998Smarkm ctx->encr_pos = AES_BLOCK_SIZE; 269109998Smarkm 270109998Smarkm return 0; 271109998Smarkm} 272109998Smarkm 273109998Smarkmstatic int 274109998Smarkmaes_ctr_encrypt_counter(archive_crypto_ctx *ctx) 275109998Smarkm{ 276109998Smarkm NTSTATUS status; 277109998Smarkm ULONG result; 278109998Smarkm 279109998Smarkm status = BCryptEncrypt(ctx->hKey, (PUCHAR)ctx->nonce, AES_BLOCK_SIZE, 280109998Smarkm NULL, NULL, 0, (PUCHAR)ctx->encr_buf, AES_BLOCK_SIZE, 281109998Smarkm &result, 0); 282160814Ssimon return BCRYPT_SUCCESS(status) ? 0 : -1; 283160814Ssimon} 284160814Ssimon 285160814Ssimonstatic int 286109998Smarkmaes_ctr_release(archive_crypto_ctx *ctx) 287160814Ssimon{ 288160814Ssimon 289109998Smarkm if (ctx->hAlg != NULL) { 290160814Ssimon BCryptCloseAlgorithmProvider(ctx->hAlg, 0); 291160814Ssimon ctx->hAlg = NULL; 292160814Ssimon BCryptDestroyKey(ctx->hKey); 293160814Ssimon ctx->hKey = NULL; 294160814Ssimon HeapFree(GetProcessHeap(), 0, ctx->keyObj); 295160814Ssimon ctx->keyObj = NULL; 296109998Smarkm } 297160814Ssimon memset(ctx, 0, sizeof(*ctx)); 298160814Ssimon return 0; 299160814Ssimon} 300160814Ssimon 301160814Ssimon#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H) 302160814Ssimon 303109998Smarkmstatic int 304160814Ssimonaes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) 305160814Ssimon{ 306160814Ssimon mbedtls_aes_init(&ctx->ctx); 307160814Ssimon ctx->key_len = key_len; 308160814Ssimon memcpy(ctx->key, key, key_len); 309160814Ssimon memset(ctx->nonce, 0, sizeof(ctx->nonce)); 310160814Ssimon ctx->encr_pos = AES_BLOCK_SIZE; 311109998Smarkm return 0; 312160814Ssimon} 313109998Smarkm 314160814Ssimonstatic int 315160814Ssimonaes_ctr_encrypt_counter(archive_crypto_ctx *ctx) 316109998Smarkm{ 317109998Smarkm if (mbedtls_aes_setkey_enc(&ctx->ctx, ctx->key, 318160814Ssimon ctx->key_len * 8) != 0) 319160814Ssimon return (-1); 320160814Ssimon if (mbedtls_aes_crypt_ecb(&ctx->ctx, MBEDTLS_AES_ENCRYPT, ctx->nonce, 321160814Ssimon ctx->encr_buf) != 0) 322160814Ssimon return (-1); 323160814Ssimon return 0; 324160814Ssimon} 325160814Ssimon 326160814Ssimonstatic int 327160814Ssimonaes_ctr_release(archive_crypto_ctx *ctx) 328160814Ssimon{ 329160814Ssimon mbedtls_aes_free(&ctx->ctx); 330160814Ssimon memset(ctx, 0, sizeof(*ctx)); 331160814Ssimon return 0; 332160814Ssimon} 333160814Ssimon 334160814Ssimon#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H) 335160814Ssimon 336109998Smarkmstatic int 337160814Ssimonaes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) 338160814Ssimon{ 339160814Ssimon ctx->key_len = key_len; 340109998Smarkm memcpy(ctx->key, key, key_len); 341160814Ssimon memset(ctx->nonce, 0, sizeof(ctx->nonce)); 342160814Ssimon ctx->encr_pos = AES_BLOCK_SIZE; 343160814Ssimon memset(&ctx->ctx, 0, sizeof(ctx->ctx)); 344160814Ssimon return 0; 345109998Smarkm} 346160814Ssimon 347160814Ssimonstatic int 348160814Ssimonaes_ctr_encrypt_counter(archive_crypto_ctx *ctx) 349160814Ssimon{ 350160814Ssimon#if NETTLE_VERSION_MAJOR < 3 351160814Ssimon aes_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key); 352109998Smarkm aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce); 353109998Smarkm#else 354109998Smarkm switch(ctx->key_len) { 355109998Smarkm case AES128_KEY_SIZE: 356109998Smarkm aes128_set_encrypt_key(&ctx->ctx.c128, ctx->key); 357109998Smarkm aes128_encrypt(&ctx->ctx.c128, AES_BLOCK_SIZE, ctx->encr_buf, 358109998Smarkm ctx->nonce); 359109998Smarkm break; 360109998Smarkm case AES192_KEY_SIZE: 361109998Smarkm aes192_set_encrypt_key(&ctx->ctx.c192, ctx->key); 362109998Smarkm aes192_encrypt(&ctx->ctx.c192, AES_BLOCK_SIZE, ctx->encr_buf, 363109998Smarkm ctx->nonce); 364109998Smarkm break; 365109998Smarkm case AES256_KEY_SIZE: 366109998Smarkm aes256_set_encrypt_key(&ctx->ctx.c256, ctx->key); 367109998Smarkm aes256_encrypt(&ctx->ctx.c256, AES_BLOCK_SIZE, ctx->encr_buf, 368109998Smarkm ctx->nonce); 369109998Smarkm break; 370109998Smarkm default: 371109998Smarkm return -1; 372109998Smarkm break; 373109998Smarkm } 374109998Smarkm#endif 375109998Smarkm return 0; 376109998Smarkm} 377109998Smarkm 378109998Smarkmstatic int 379109998Smarkmaes_ctr_release(archive_crypto_ctx *ctx) 380109998Smarkm{ 381109998Smarkm memset(ctx, 0, sizeof(*ctx)); 382109998Smarkm return 0; 383109998Smarkm} 384109998Smarkm 385109998Smarkm#elif defined(HAVE_LIBCRYPTO) 386109998Smarkm 387109998Smarkmstatic int 388109998Smarkmaes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) 389109998Smarkm{ 390109998Smarkm if ((ctx->ctx = EVP_CIPHER_CTX_new()) == NULL) 391109998Smarkm return -1; 392109998Smarkm 393109998Smarkm switch (key_len) { 394109998Smarkm case 16: ctx->type = EVP_aes_128_ecb(); break; 395109998Smarkm case 24: ctx->type = EVP_aes_192_ecb(); break; 396109998Smarkm case 32: ctx->type = EVP_aes_256_ecb(); break; 397160814Ssimon default: ctx->type = NULL; return -1; 398160814Ssimon } 399109998Smarkm 400109998Smarkm ctx->key_len = key_len; 401109998Smarkm memcpy(ctx->key, key, key_len); 402109998Smarkm memset(ctx->nonce, 0, sizeof(ctx->nonce)); 403109998Smarkm ctx->encr_pos = AES_BLOCK_SIZE; 404109998Smarkm#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) 405109998Smarkm if (!EVP_CIPHER_CTX_reset(ctx->ctx)) { 406109998Smarkm EVP_CIPHER_CTX_free(ctx->ctx); 407109998Smarkm ctx->ctx = NULL; 408109998Smarkm } 409109998Smarkm#else 410109998Smarkm EVP_CIPHER_CTX_init(ctx->ctx); 411109998Smarkm#endif 412109998Smarkm return 0; 413109998Smarkm} 414109998Smarkm 415109998Smarkmstatic int 416109998Smarkmaes_ctr_encrypt_counter(archive_crypto_ctx *ctx) 417109998Smarkm{ 418109998Smarkm int outl = 0; 419109998Smarkm int r; 420109998Smarkm 421109998Smarkm r = EVP_EncryptInit_ex(ctx->ctx, ctx->type, NULL, ctx->key, NULL); 422109998Smarkm if (r == 0) 423109998Smarkm return -1; 424109998Smarkm r = EVP_EncryptUpdate(ctx->ctx, ctx->encr_buf, &outl, ctx->nonce, 425109998Smarkm AES_BLOCK_SIZE); 426109998Smarkm if (r == 0 || outl != AES_BLOCK_SIZE) 427109998Smarkm return -1; 428109998Smarkm return 0; 429109998Smarkm} 430109998Smarkm 431109998Smarkmstatic int 432109998Smarkmaes_ctr_release(archive_crypto_ctx *ctx) 433109998Smarkm{ 434109998Smarkm EVP_CIPHER_CTX_free(ctx->ctx); 435109998Smarkm memset(ctx->key, 0, ctx->key_len); 436109998Smarkm memset(ctx->nonce, 0, sizeof(ctx->nonce)); 437109998Smarkm return 0; 438109998Smarkm} 439109998Smarkm 440109998Smarkm#else 441109998Smarkm 442109998Smarkm#define ARCHIVE_CRYPTOR_STUB 443109998Smarkm/* Stub */ 444109998Smarkmstatic int 445109998Smarkmaes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) 446109998Smarkm{ 447109998Smarkm (void)ctx; /* UNUSED */ 448109998Smarkm (void)key; /* UNUSED */ 449109998Smarkm (void)key_len; /* UNUSED */ 450109998Smarkm return -1; 451109998Smarkm} 452109998Smarkm 453109998Smarkmstatic int 454109998Smarkmaes_ctr_encrypt_counter(archive_crypto_ctx *ctx) 455109998Smarkm{ 456109998Smarkm (void)ctx; /* UNUSED */ 457109998Smarkm return -1; 458109998Smarkm} 459109998Smarkm 460109998Smarkmstatic int 461109998Smarkmaes_ctr_release(archive_crypto_ctx *ctx) 462109998Smarkm{ 463109998Smarkm (void)ctx; /* UNUSED */ 464109998Smarkm return 0; 465109998Smarkm} 466109998Smarkm 467109998Smarkm#endif 468109998Smarkm 469109998Smarkm#ifdef ARCHIVE_CRYPTOR_STUB 470109998Smarkmstatic int 471109998Smarkmaes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in, 472109998Smarkm size_t in_len, uint8_t * const out, size_t *out_len) 473109998Smarkm{ 474109998Smarkm (void)ctx; /* UNUSED */ 475109998Smarkm (void)in; /* UNUSED */ 476109998Smarkm (void)in_len; /* UNUSED */ 477109998Smarkm (void)out; /* UNUSED */ 478109998Smarkm (void)out_len; /* UNUSED */ 479109998Smarkm aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */ 480109998Smarkm return -1; 481109998Smarkm} 482109998Smarkm 483109998Smarkm#else 484109998Smarkmstatic void 485109998Smarkmaes_ctr_increase_counter(archive_crypto_ctx *ctx) 486109998Smarkm{ 487109998Smarkm uint8_t *const nonce = ctx->nonce; 488109998Smarkm int j; 489109998Smarkm 490109998Smarkm for (j = 0; j < 8; j++) { 491109998Smarkm if (++nonce[j]) 492109998Smarkm break; 493109998Smarkm } 494109998Smarkm} 495109998Smarkm 496109998Smarkmstatic int 497109998Smarkmaes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in, 498109998Smarkm size_t in_len, uint8_t * const out, size_t *out_len) 499109998Smarkm{ 500109998Smarkm uint8_t *const ebuf = ctx->encr_buf; 501109998Smarkm unsigned pos = ctx->encr_pos; 502109998Smarkm unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len); 503109998Smarkm unsigned i; 504109998Smarkm 505109998Smarkm for (i = 0; i < max; ) { 506109998Smarkm if (pos == AES_BLOCK_SIZE) { 507109998Smarkm aes_ctr_increase_counter(ctx); 508109998Smarkm if (aes_ctr_encrypt_counter(ctx) != 0) 509109998Smarkm return -1; 510109998Smarkm while (max -i >= AES_BLOCK_SIZE) { 511109998Smarkm for (pos = 0; pos < AES_BLOCK_SIZE; pos++) 512109998Smarkm out[i+pos] = in[i+pos] ^ ebuf[pos]; 513109998Smarkm i += AES_BLOCK_SIZE; 514109998Smarkm aes_ctr_increase_counter(ctx); 515160814Ssimon if (aes_ctr_encrypt_counter(ctx) != 0) 516109998Smarkm return -1; 517109998Smarkm } 518109998Smarkm pos = 0; 519109998Smarkm if (i >= max) 520109998Smarkm break; 521160814Ssimon } 522109998Smarkm out[i] = in[i] ^ ebuf[pos++]; 523109998Smarkm i++; 524109998Smarkm } 525109998Smarkm ctx->encr_pos = pos; 526109998Smarkm *out_len = i; 527109998Smarkm 528109998Smarkm return 0; 529160814Ssimon} 530109998Smarkm#endif /* ARCHIVE_CRYPTOR_STUB */ 531109998Smarkm 532109998Smarkm 533160814Ssimonconst struct archive_cryptor __archive_cryptor = 534160814Ssimon{ 535109998Smarkm &pbkdf2_sha1, 536109998Smarkm &aes_ctr_init, 537109998Smarkm &aes_ctr_update, 538109998Smarkm &aes_ctr_release, 539160814Ssimon &aes_ctr_init, 540109998Smarkm &aes_ctr_update, 541109998Smarkm &aes_ctr_release, 542109998Smarkm}; 543109998Smarkm