Path: blob/master/Utilities/cmlibarchive/libarchive/archive_cryptor.c
3153 views
/*-1* Copyright (c) 2014 Michihiro NAKAJIMA2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR14* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES15* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.16* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,17* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT18* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,19* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY20* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT21* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF22* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.23*/2425#include "archive_platform.h"2627#ifdef HAVE_STRING_H28#include <string.h>29#endif30#include "archive.h"31#include "archive_cryptor_private.h"3233/*34* On systems that do not support any recognized crypto libraries,35* this file will normally define no usable symbols.36*37* But some compilers and linkers choke on empty object files, so38* define a public symbol that will always exist. This could39* be removed someday if this file gains another always-present40* symbol definition.41*/42int __libarchive_cryptor_build_hack(void) {43return 0;44}4546#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto4748static int49pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,50size_t salt_len, unsigned rounds, uint8_t *derived_key,51size_t derived_key_len)52{53CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pw,54pw_len, salt, salt_len, kCCPRFHmacAlgSHA1, rounds,55derived_key, derived_key_len);56return 0;57}5859#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA60#ifdef _MSC_VER61#pragma comment(lib, "Bcrypt.lib")62#endif6364static int65pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,66size_t salt_len, unsigned rounds, uint8_t *derived_key,67size_t derived_key_len)68{69NTSTATUS status;70BCRYPT_ALG_HANDLE hAlg;7172status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM,73MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);74if (!BCRYPT_SUCCESS(status))75return -1;7677status = BCryptDeriveKeyPBKDF2(hAlg,78(PUCHAR)(uintptr_t)pw, (ULONG)pw_len,79(PUCHAR)(uintptr_t)salt, (ULONG)salt_len, rounds,80(PUCHAR)derived_key, (ULONG)derived_key_len, 0);8182BCryptCloseAlgorithmProvider(hAlg, 0);8384return (BCRYPT_SUCCESS(status)) ? 0: -1;85}8687#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_PKCS5_H)8889static int90pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,91size_t salt_len, unsigned rounds, uint8_t *derived_key,92size_t derived_key_len)93{94mbedtls_md_context_t ctx;95const mbedtls_md_info_t *info;96int ret;9798mbedtls_md_init(&ctx);99info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);100if (info == NULL) {101mbedtls_md_free(&ctx);102return (-1);103}104ret = mbedtls_md_setup(&ctx, info, 1);105if (ret != 0) {106mbedtls_md_free(&ctx);107return (-1);108}109ret = mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char *)pw,110pw_len, salt, salt_len, rounds, derived_key_len, derived_key);111112mbedtls_md_free(&ctx);113return (ret);114}115116#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_PBKDF2_H)117118static int119pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,120size_t salt_len, unsigned rounds, uint8_t *derived_key,121size_t derived_key_len) {122pbkdf2_hmac_sha1((unsigned)pw_len, (const uint8_t *)pw, rounds,123salt_len, salt, derived_key_len, derived_key);124return 0;125}126127#elif defined(HAVE_LIBCRYPTO) && defined(HAVE_PKCS5_PBKDF2_HMAC_SHA1)128129static int130pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,131size_t salt_len, unsigned rounds, uint8_t *derived_key,132size_t derived_key_len) {133134PKCS5_PBKDF2_HMAC_SHA1(pw, pw_len, salt, salt_len, rounds,135derived_key_len, derived_key);136return 0;137}138139#else140141/* Stub */142static int143pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,144size_t salt_len, unsigned rounds, uint8_t *derived_key,145size_t derived_key_len) {146(void)pw; /* UNUSED */147(void)pw_len; /* UNUSED */148(void)salt; /* UNUSED */149(void)salt_len; /* UNUSED */150(void)rounds; /* UNUSED */151(void)derived_key; /* UNUSED */152(void)derived_key_len; /* UNUSED */153return -1; /* UNSUPPORTED */154}155156#endif157158#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto159# if MAC_OS_X_VERSION_MAX_ALLOWED < 1090160# define kCCAlgorithmAES kCCAlgorithmAES128161# endif162163static int164aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)165{166CCCryptorStatus r;167168ctx->key_len = key_len;169memcpy(ctx->key, key, key_len);170memset(ctx->nonce, 0, sizeof(ctx->nonce));171ctx->encr_pos = AES_BLOCK_SIZE;172r = CCCryptorCreateWithMode(kCCEncrypt, kCCModeECB, kCCAlgorithmAES,173ccNoPadding, NULL, key, key_len, NULL, 0, 0, 0, &ctx->ctx);174return (r == kCCSuccess)? 0: -1;175}176177static int178aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)179{180CCCryptorRef ref = ctx->ctx;181CCCryptorStatus r;182183r = CCCryptorReset(ref, NULL);184if (r != kCCSuccess && r != kCCUnimplemented)185return -1;186r = CCCryptorUpdate(ref, ctx->nonce, AES_BLOCK_SIZE, ctx->encr_buf,187AES_BLOCK_SIZE, NULL);188return (r == kCCSuccess)? 0: -1;189}190191static int192aes_ctr_release(archive_crypto_ctx *ctx)193{194memset(ctx->key, 0, ctx->key_len);195memset(ctx->nonce, 0, sizeof(ctx->nonce));196return 0;197}198199#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA200201static int202aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)203{204BCRYPT_ALG_HANDLE hAlg;205BCRYPT_KEY_HANDLE hKey;206DWORD keyObj_len, aes_key_len;207PBYTE keyObj;208ULONG result;209NTSTATUS status;210BCRYPT_KEY_LENGTHS_STRUCT key_lengths;211212ctx->hAlg = NULL;213ctx->hKey = NULL;214ctx->keyObj = NULL;215switch (key_len) {216case 16: aes_key_len = 128; break;217case 24: aes_key_len = 192; break;218case 32: aes_key_len = 256; break;219default: return -1;220}221status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM,222MS_PRIMITIVE_PROVIDER, 0);223if (!BCRYPT_SUCCESS(status))224return -1;225status = BCryptGetProperty(hAlg, BCRYPT_KEY_LENGTHS, (PUCHAR)&key_lengths,226sizeof(key_lengths), &result, 0);227if (!BCRYPT_SUCCESS(status)) {228BCryptCloseAlgorithmProvider(hAlg, 0);229return -1;230}231if (key_lengths.dwMinLength > aes_key_len232|| key_lengths.dwMaxLength < aes_key_len) {233BCryptCloseAlgorithmProvider(hAlg, 0);234return -1;235}236status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObj_len,237sizeof(keyObj_len), &result, 0);238if (!BCRYPT_SUCCESS(status)) {239BCryptCloseAlgorithmProvider(hAlg, 0);240return -1;241}242keyObj = (PBYTE)HeapAlloc(GetProcessHeap(), 0, keyObj_len);243if (keyObj == NULL) {244BCryptCloseAlgorithmProvider(hAlg, 0);245return -1;246}247status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE,248(PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0);249if (!BCRYPT_SUCCESS(status)) {250BCryptCloseAlgorithmProvider(hAlg, 0);251HeapFree(GetProcessHeap(), 0, keyObj);252return -1;253}254status = BCryptGenerateSymmetricKey(hAlg, &hKey,255keyObj, keyObj_len,256(PUCHAR)(uintptr_t)key, (ULONG)key_len, 0);257if (!BCRYPT_SUCCESS(status)) {258BCryptCloseAlgorithmProvider(hAlg, 0);259HeapFree(GetProcessHeap(), 0, keyObj);260return -1;261}262263ctx->hAlg = hAlg;264ctx->hKey = hKey;265ctx->keyObj = keyObj;266ctx->keyObj_len = keyObj_len;267ctx->encr_pos = AES_BLOCK_SIZE;268269return 0;270}271272static int273aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)274{275NTSTATUS status;276ULONG result;277278status = BCryptEncrypt(ctx->hKey, (PUCHAR)ctx->nonce, AES_BLOCK_SIZE,279NULL, NULL, 0, (PUCHAR)ctx->encr_buf, AES_BLOCK_SIZE,280&result, 0);281return BCRYPT_SUCCESS(status) ? 0 : -1;282}283284static int285aes_ctr_release(archive_crypto_ctx *ctx)286{287288if (ctx->hAlg != NULL) {289BCryptCloseAlgorithmProvider(ctx->hAlg, 0);290ctx->hAlg = NULL;291BCryptDestroyKey(ctx->hKey);292ctx->hKey = NULL;293HeapFree(GetProcessHeap(), 0, ctx->keyObj);294ctx->keyObj = NULL;295}296memset(ctx, 0, sizeof(*ctx));297return 0;298}299300#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H)301302static int303aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)304{305mbedtls_aes_init(&ctx->ctx);306ctx->key_len = key_len;307memcpy(ctx->key, key, key_len);308memset(ctx->nonce, 0, sizeof(ctx->nonce));309ctx->encr_pos = AES_BLOCK_SIZE;310return 0;311}312313static int314aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)315{316if (mbedtls_aes_setkey_enc(&ctx->ctx, ctx->key,317ctx->key_len * 8) != 0)318return (-1);319if (mbedtls_aes_crypt_ecb(&ctx->ctx, MBEDTLS_AES_ENCRYPT, ctx->nonce,320ctx->encr_buf) != 0)321return (-1);322return 0;323}324325static int326aes_ctr_release(archive_crypto_ctx *ctx)327{328mbedtls_aes_free(&ctx->ctx);329memset(ctx, 0, sizeof(*ctx));330return 0;331}332333#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)334335static int336aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)337{338ctx->key_len = key_len;339memcpy(ctx->key, key, key_len);340memset(ctx->nonce, 0, sizeof(ctx->nonce));341ctx->encr_pos = AES_BLOCK_SIZE;342memset(&ctx->ctx, 0, sizeof(ctx->ctx));343return 0;344}345346static int347aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)348{349#if NETTLE_VERSION_MAJOR < 3350aes_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key);351aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce);352#else353switch(ctx->key_len) {354case AES128_KEY_SIZE:355aes128_set_encrypt_key(&ctx->ctx.c128, ctx->key);356aes128_encrypt(&ctx->ctx.c128, AES_BLOCK_SIZE, ctx->encr_buf,357ctx->nonce);358break;359case AES192_KEY_SIZE:360aes192_set_encrypt_key(&ctx->ctx.c192, ctx->key);361aes192_encrypt(&ctx->ctx.c192, AES_BLOCK_SIZE, ctx->encr_buf,362ctx->nonce);363break;364case AES256_KEY_SIZE:365aes256_set_encrypt_key(&ctx->ctx.c256, ctx->key);366aes256_encrypt(&ctx->ctx.c256, AES_BLOCK_SIZE, ctx->encr_buf,367ctx->nonce);368break;369default:370return -1;371break;372}373#endif374return 0;375}376377static int378aes_ctr_release(archive_crypto_ctx *ctx)379{380memset(ctx, 0, sizeof(*ctx));381return 0;382}383384#elif defined(HAVE_LIBCRYPTO)385386static int387aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)388{389if ((ctx->ctx = EVP_CIPHER_CTX_new()) == NULL)390return -1;391392switch (key_len) {393case 16: ctx->type = EVP_aes_128_ecb(); break;394case 24: ctx->type = EVP_aes_192_ecb(); break;395case 32: ctx->type = EVP_aes_256_ecb(); break;396default: ctx->type = NULL; return -1;397}398399ctx->key_len = key_len;400memcpy(ctx->key, key, key_len);401memset(ctx->nonce, 0, sizeof(ctx->nonce));402ctx->encr_pos = AES_BLOCK_SIZE;403return 0;404}405406static int407aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)408{409int outl = 0;410int r;411412r = EVP_EncryptInit_ex(ctx->ctx, ctx->type, NULL, ctx->key, NULL);413if (r == 0)414return -1;415r = EVP_EncryptUpdate(ctx->ctx, ctx->encr_buf, &outl, ctx->nonce,416AES_BLOCK_SIZE);417if (r == 0 || outl != AES_BLOCK_SIZE)418return -1;419return 0;420}421422static int423aes_ctr_release(archive_crypto_ctx *ctx)424{425EVP_CIPHER_CTX_free(ctx->ctx);426OPENSSL_cleanse(ctx->key, ctx->key_len);427OPENSSL_cleanse(ctx->nonce, sizeof(ctx->nonce));428return 0;429}430431#else432433#define ARCHIVE_CRYPTOR_STUB434/* Stub */435static int436aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)437{438(void)ctx; /* UNUSED */439(void)key; /* UNUSED */440(void)key_len; /* UNUSED */441return -1;442}443444static int445aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)446{447(void)ctx; /* UNUSED */448return -1;449}450451static int452aes_ctr_release(archive_crypto_ctx *ctx)453{454(void)ctx; /* UNUSED */455return 0;456}457458#endif459460#ifdef ARCHIVE_CRYPTOR_STUB461static int462aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,463size_t in_len, uint8_t * const out, size_t *out_len)464{465(void)ctx; /* UNUSED */466(void)in; /* UNUSED */467(void)in_len; /* UNUSED */468(void)out; /* UNUSED */469(void)out_len; /* UNUSED */470aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */471return -1;472}473474#else475static void476aes_ctr_increase_counter(archive_crypto_ctx *ctx)477{478uint8_t *const nonce = ctx->nonce;479int j;480481for (j = 0; j < 8; j++) {482if (++nonce[j])483break;484}485}486487static int488aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,489size_t in_len, uint8_t * const out, size_t *out_len)490{491uint8_t *const ebuf = ctx->encr_buf;492unsigned pos = ctx->encr_pos;493unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len);494unsigned i;495496for (i = 0; i < max; ) {497if (pos == AES_BLOCK_SIZE) {498aes_ctr_increase_counter(ctx);499if (aes_ctr_encrypt_counter(ctx) != 0)500return -1;501while (max -i >= AES_BLOCK_SIZE) {502for (pos = 0; pos < AES_BLOCK_SIZE; pos++)503out[i+pos] = in[i+pos] ^ ebuf[pos];504i += AES_BLOCK_SIZE;505aes_ctr_increase_counter(ctx);506if (aes_ctr_encrypt_counter(ctx) != 0)507return -1;508}509pos = 0;510if (i >= max)511break;512}513out[i] = in[i] ^ ebuf[pos++];514i++;515}516ctx->encr_pos = pos;517*out_len = i;518519return 0;520}521#endif /* ARCHIVE_CRYPTOR_STUB */522523524const struct archive_cryptor __archive_cryptor =525{526&pbkdf2_sha1,527&aes_ctr_init,528&aes_ctr_update,529&aes_ctr_release,530&aes_ctr_init,531&aes_ctr_update,532&aes_ctr_release,533};534535536