Index: head/contrib/libarchive/libarchive/archive_cryptor.c =================================================================== --- head/contrib/libarchive/libarchive/archive_cryptor.c (revision 356365) +++ head/contrib/libarchive/libarchive/archive_cryptor.c (revision 356366) @@ -1,457 +1,518 @@ /*- * Copyright (c) 2014 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "archive_platform.h" #ifdef HAVE_STRING_H #include #endif #include "archive.h" #include "archive_cryptor_private.h" /* * On systems that do not support any recognized crypto libraries, * this file will normally define no usable symbols. * * But some compilers and linkers choke on empty object files, so * define a public symbol that will always exist. This could * be removed someday if this file gains another always-present * symbol definition. */ int __libarchive_cryptor_build_hack(void) { return 0; } #ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto static int pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, size_t salt_len, unsigned rounds, uint8_t *derived_key, size_t derived_key_len) { CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pw, pw_len, salt, salt_len, kCCPRFHmacAlgSHA1, rounds, derived_key, derived_key_len); return 0; } #elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) #ifdef _MSC_VER #pragma comment(lib, "Bcrypt.lib") #endif static int pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, size_t salt_len, unsigned rounds, uint8_t *derived_key, size_t derived_key_len) { NTSTATUS status; BCRYPT_ALG_HANDLE hAlg; status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); if (!BCRYPT_SUCCESS(status)) return -1; status = BCryptDeriveKeyPBKDF2(hAlg, (PUCHAR)(uintptr_t)pw, (ULONG)pw_len, (PUCHAR)(uintptr_t)salt, (ULONG)salt_len, rounds, (PUCHAR)derived_key, (ULONG)derived_key_len, 0); BCryptCloseAlgorithmProvider(hAlg, 0); return (BCRYPT_SUCCESS(status)) ? 0: -1; } +#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_PKCS5_H) + +static int +pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, + size_t salt_len, unsigned rounds, uint8_t *derived_key, + size_t derived_key_len) +{ + mbedtls_md_context_t ctx; + const mbedtls_md_info_t *info; + int ret; + + mbedtls_md_init(&ctx); + info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); + if (info == NULL) { + mbedtls_md_free(&ctx); + return (-1); + } + ret = mbedtls_md_setup(&ctx, info, 1); + if (ret != 0) { + mbedtls_md_free(&ctx); + return (-1); + } + ret = mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char *)pw, + pw_len, salt, salt_len, rounds, derived_key_len, derived_key); + + mbedtls_md_free(&ctx); + return (ret); +} + #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_PBKDF2_H) static int pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, size_t salt_len, unsigned rounds, uint8_t *derived_key, size_t derived_key_len) { pbkdf2_hmac_sha1((unsigned)pw_len, (const uint8_t *)pw, rounds, salt_len, salt, derived_key_len, derived_key); return 0; } #elif defined(HAVE_LIBCRYPTO) && defined(HAVE_PKCS5_PBKDF2_HMAC_SHA1) static int pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, size_t salt_len, unsigned rounds, uint8_t *derived_key, size_t derived_key_len) { PKCS5_PBKDF2_HMAC_SHA1(pw, pw_len, salt, salt_len, rounds, derived_key_len, derived_key); return 0; } #else /* Stub */ static int pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, size_t salt_len, unsigned rounds, uint8_t *derived_key, size_t derived_key_len) { (void)pw; /* UNUSED */ (void)pw_len; /* UNUSED */ (void)salt; /* UNUSED */ (void)salt_len; /* UNUSED */ (void)rounds; /* UNUSED */ (void)derived_key; /* UNUSED */ (void)derived_key_len; /* UNUSED */ return -1; /* UNSUPPORTED */ } #endif #ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto # if MAC_OS_X_VERSION_MAX_ALLOWED < 1090 # define kCCAlgorithmAES kCCAlgorithmAES128 # endif static int aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) { CCCryptorStatus r; ctx->key_len = key_len; memcpy(ctx->key, key, key_len); memset(ctx->nonce, 0, sizeof(ctx->nonce)); ctx->encr_pos = AES_BLOCK_SIZE; r = CCCryptorCreateWithMode(kCCEncrypt, kCCModeECB, kCCAlgorithmAES, ccNoPadding, NULL, key, key_len, NULL, 0, 0, 0, &ctx->ctx); return (r == kCCSuccess)? 0: -1; } static int aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) { CCCryptorRef ref = ctx->ctx; CCCryptorStatus r; r = CCCryptorReset(ref, NULL); if (r != kCCSuccess && r != kCCUnimplemented) return -1; r = CCCryptorUpdate(ref, ctx->nonce, AES_BLOCK_SIZE, ctx->encr_buf, AES_BLOCK_SIZE, NULL); return (r == kCCSuccess)? 0: -1; } static int aes_ctr_release(archive_crypto_ctx *ctx) { memset(ctx->key, 0, ctx->key_len); memset(ctx->nonce, 0, sizeof(ctx->nonce)); return 0; } #elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) static int aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) { BCRYPT_ALG_HANDLE hAlg; BCRYPT_KEY_HANDLE hKey; DWORD keyObj_len, aes_key_len; PBYTE keyObj; ULONG result; NTSTATUS status; BCRYPT_KEY_LENGTHS_STRUCT key_lengths; ctx->hAlg = NULL; ctx->hKey = NULL; ctx->keyObj = NULL; switch (key_len) { case 16: aes_key_len = 128; break; case 24: aes_key_len = 192; break; case 32: aes_key_len = 256; break; default: return -1; } status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); if (!BCRYPT_SUCCESS(status)) return -1; status = BCryptGetProperty(hAlg, BCRYPT_KEY_LENGTHS, (PUCHAR)&key_lengths, sizeof(key_lengths), &result, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } if (key_lengths.dwMinLength > aes_key_len || key_lengths.dwMaxLength < aes_key_len) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObj_len, sizeof(keyObj_len), &result, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } keyObj = (PBYTE)HeapAlloc(GetProcessHeap(), 0, keyObj_len); if (keyObj == NULL) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); HeapFree(GetProcessHeap(), 0, keyObj); return -1; } status = BCryptGenerateSymmetricKey(hAlg, &hKey, keyObj, keyObj_len, (PUCHAR)(uintptr_t)key, (ULONG)key_len, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); HeapFree(GetProcessHeap(), 0, keyObj); return -1; } ctx->hAlg = hAlg; ctx->hKey = hKey; ctx->keyObj = keyObj; ctx->keyObj_len = keyObj_len; ctx->encr_pos = AES_BLOCK_SIZE; return 0; } static int aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) { NTSTATUS status; ULONG result; status = BCryptEncrypt(ctx->hKey, (PUCHAR)ctx->nonce, AES_BLOCK_SIZE, NULL, NULL, 0, (PUCHAR)ctx->encr_buf, AES_BLOCK_SIZE, &result, 0); return BCRYPT_SUCCESS(status) ? 0 : -1; } static int aes_ctr_release(archive_crypto_ctx *ctx) { if (ctx->hAlg != NULL) { BCryptCloseAlgorithmProvider(ctx->hAlg, 0); ctx->hAlg = NULL; BCryptDestroyKey(ctx->hKey); ctx->hKey = NULL; HeapFree(GetProcessHeap(), 0, ctx->keyObj); ctx->keyObj = NULL; } + memset(ctx, 0, sizeof(*ctx)); + return 0; +} + +#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H) +static int +aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) +{ + mbedtls_aes_init(&ctx->ctx); + ctx->key_len = key_len; + memcpy(ctx->key, key, key_len); + memset(ctx->nonce, 0, sizeof(ctx->nonce)); + ctx->encr_pos = AES_BLOCK_SIZE; + return 0; +} + +static int +aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) +{ + if (mbedtls_aes_setkey_enc(&ctx->ctx, ctx->key, + ctx->key_len * 8) != 0) + return (-1); + if (mbedtls_aes_crypt_ecb(&ctx->ctx, MBEDTLS_AES_ENCRYPT, ctx->nonce, + ctx->encr_buf) != 0) + return (-1); + return 0; +} + +static int +aes_ctr_release(archive_crypto_ctx *ctx) +{ + mbedtls_aes_free(&ctx->ctx); memset(ctx, 0, sizeof(*ctx)); return 0; } #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H) static int aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) { ctx->key_len = key_len; memcpy(ctx->key, key, key_len); memset(ctx->nonce, 0, sizeof(ctx->nonce)); ctx->encr_pos = AES_BLOCK_SIZE; memset(&ctx->ctx, 0, sizeof(ctx->ctx)); return 0; } static int aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) { aes_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key); aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce); return 0; } static int aes_ctr_release(archive_crypto_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); return 0; } #elif defined(HAVE_LIBCRYPTO) static int aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) { if ((ctx->ctx = EVP_CIPHER_CTX_new()) == NULL) return -1; switch (key_len) { case 16: ctx->type = EVP_aes_128_ecb(); break; case 24: ctx->type = EVP_aes_192_ecb(); break; case 32: ctx->type = EVP_aes_256_ecb(); break; default: ctx->type = NULL; return -1; } ctx->key_len = key_len; memcpy(ctx->key, key, key_len); memset(ctx->nonce, 0, sizeof(ctx->nonce)); ctx->encr_pos = AES_BLOCK_SIZE; #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) if (!EVP_CIPHER_CTX_reset(ctx->ctx)) { EVP_CIPHER_CTX_free(ctx->ctx); ctx->ctx = NULL; } #else EVP_CIPHER_CTX_init(ctx->ctx); #endif return 0; } static int aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) { int outl = 0; int r; r = EVP_EncryptInit_ex(ctx->ctx, ctx->type, NULL, ctx->key, NULL); if (r == 0) return -1; r = EVP_EncryptUpdate(ctx->ctx, ctx->encr_buf, &outl, ctx->nonce, AES_BLOCK_SIZE); if (r == 0 || outl != AES_BLOCK_SIZE) return -1; return 0; } static int aes_ctr_release(archive_crypto_ctx *ctx) { EVP_CIPHER_CTX_free(ctx->ctx); memset(ctx->key, 0, ctx->key_len); memset(ctx->nonce, 0, sizeof(ctx->nonce)); return 0; } #else #define ARCHIVE_CRYPTOR_STUB /* Stub */ static int aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) { (void)ctx; /* UNUSED */ (void)key; /* UNUSED */ (void)key_len; /* UNUSED */ return -1; } static int aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) { (void)ctx; /* UNUSED */ return -1; } static int aes_ctr_release(archive_crypto_ctx *ctx) { (void)ctx; /* UNUSED */ return 0; } #endif #ifdef ARCHIVE_CRYPTOR_STUB static int aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in, size_t in_len, uint8_t * const out, size_t *out_len) { (void)ctx; /* UNUSED */ (void)in; /* UNUSED */ (void)in_len; /* UNUSED */ (void)out; /* UNUSED */ (void)out_len; /* UNUSED */ aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */ return -1; } #else static void aes_ctr_increase_counter(archive_crypto_ctx *ctx) { uint8_t *const nonce = ctx->nonce; int j; for (j = 0; j < 8; j++) { if (++nonce[j]) break; } } static int aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in, size_t in_len, uint8_t * const out, size_t *out_len) { uint8_t *const ebuf = ctx->encr_buf; unsigned pos = ctx->encr_pos; unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len); unsigned i; for (i = 0; i < max; ) { if (pos == AES_BLOCK_SIZE) { aes_ctr_increase_counter(ctx); if (aes_ctr_encrypt_counter(ctx) != 0) return -1; while (max -i >= AES_BLOCK_SIZE) { for (pos = 0; pos < AES_BLOCK_SIZE; pos++) out[i+pos] = in[i+pos] ^ ebuf[pos]; i += AES_BLOCK_SIZE; aes_ctr_increase_counter(ctx); if (aes_ctr_encrypt_counter(ctx) != 0) return -1; } pos = 0; if (i >= max) break; } out[i] = in[i] ^ ebuf[pos++]; i++; } ctx->encr_pos = pos; *out_len = i; return 0; } #endif /* ARCHIVE_CRYPTOR_STUB */ const struct archive_cryptor __archive_cryptor = { &pbkdf2_sha1, &aes_ctr_init, &aes_ctr_update, &aes_ctr_release, &aes_ctr_init, &aes_ctr_update, &aes_ctr_release, }; Index: head/contrib/libarchive/libarchive/archive_cryptor_private.h =================================================================== --- head/contrib/libarchive/libarchive/archive_cryptor_private.h (revision 356365) +++ head/contrib/libarchive/libarchive/archive_cryptor_private.h (revision 356366) @@ -1,163 +1,180 @@ /*- * Copyright (c) 2014 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif #ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED #define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED /* * On systems that do not support any recognized crypto libraries, * the archive_cryptor.c file will normally define no usable symbols. * * But some compilers and linkers choke on empty object files, so * define a public symbol that will always exist. This could * be removed someday if this file gains another always-present * symbol definition. */ int __libarchive_cryptor_build_hack(void); #ifdef __APPLE__ # include # if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 # define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto # endif #endif #ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto #include #include #define AES_BLOCK_SIZE 16 #define AES_MAX_KEY_SIZE kCCKeySizeAES256 typedef struct { CCCryptorRef ctx; uint8_t key[AES_MAX_KEY_SIZE]; unsigned key_len; uint8_t nonce[AES_BLOCK_SIZE]; uint8_t encr_buf[AES_BLOCK_SIZE]; unsigned encr_pos; } archive_crypto_ctx; #elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) #include /* Common in other bcrypt implementations, but missing from VS2008. */ #ifndef BCRYPT_SUCCESS #define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS) #endif #define AES_MAX_KEY_SIZE 32 #define AES_BLOCK_SIZE 16 typedef struct { BCRYPT_ALG_HANDLE hAlg; BCRYPT_KEY_HANDLE hKey; PBYTE keyObj; DWORD keyObj_len; uint8_t nonce[AES_BLOCK_SIZE]; uint8_t encr_buf[AES_BLOCK_SIZE]; unsigned encr_pos; } archive_crypto_ctx; +#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H) +#include +#include +#include + +#define AES_MAX_KEY_SIZE 32 +#define AES_BLOCK_SIZE 16 + +typedef struct { + mbedtls_aes_context ctx; + uint8_t key[AES_MAX_KEY_SIZE]; + unsigned key_len; + uint8_t nonce[AES_BLOCK_SIZE]; + uint8_t encr_buf[AES_BLOCK_SIZE]; + unsigned encr_pos; +} archive_crypto_ctx; + #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H) #if defined(HAVE_NETTLE_PBKDF2_H) #include #endif #include typedef struct { struct aes_ctx ctx; uint8_t key[AES_MAX_KEY_SIZE]; unsigned key_len; uint8_t nonce[AES_BLOCK_SIZE]; uint8_t encr_buf[AES_BLOCK_SIZE]; unsigned encr_pos; } archive_crypto_ctx; #elif defined(HAVE_LIBCRYPTO) #include "archive_openssl_evp_private.h" #define AES_BLOCK_SIZE 16 #define AES_MAX_KEY_SIZE 32 typedef struct { EVP_CIPHER_CTX *ctx; const EVP_CIPHER *type; uint8_t key[AES_MAX_KEY_SIZE]; unsigned key_len; uint8_t nonce[AES_BLOCK_SIZE]; uint8_t encr_buf[AES_BLOCK_SIZE]; unsigned encr_pos; } archive_crypto_ctx; #else #define AES_BLOCK_SIZE 16 #define AES_MAX_KEY_SIZE 32 typedef int archive_crypto_ctx; #endif /* defines */ #define archive_pbkdf2_sha1(pw, pw_len, salt, salt_len, rounds, dk, dk_len)\ __archive_cryptor.pbkdf2sha1(pw, pw_len, salt, salt_len, rounds, dk, dk_len) #define archive_decrypto_aes_ctr_init(ctx, key, key_len) \ __archive_cryptor.decrypto_aes_ctr_init(ctx, key, key_len) #define archive_decrypto_aes_ctr_update(ctx, in, in_len, out, out_len) \ __archive_cryptor.decrypto_aes_ctr_update(ctx, in, in_len, out, out_len) #define archive_decrypto_aes_ctr_release(ctx) \ __archive_cryptor.decrypto_aes_ctr_release(ctx) #define archive_encrypto_aes_ctr_init(ctx, key, key_len) \ __archive_cryptor.encrypto_aes_ctr_init(ctx, key, key_len) #define archive_encrypto_aes_ctr_update(ctx, in, in_len, out, out_len) \ __archive_cryptor.encrypto_aes_ctr_update(ctx, in, in_len, out, out_len) #define archive_encrypto_aes_ctr_release(ctx) \ __archive_cryptor.encrypto_aes_ctr_release(ctx) /* Minimal interface to cryptographic functionality for internal use in * libarchive */ struct archive_cryptor { /* PKCS5 PBKDF2 HMAC-SHA1 */ int (*pbkdf2sha1)(const char *pw, size_t pw_len, const uint8_t *salt, size_t salt_len, unsigned rounds, uint8_t *derived_key, size_t derived_key_len); /* AES CTR mode(little endian version) */ int (*decrypto_aes_ctr_init)(archive_crypto_ctx *, const uint8_t *, size_t); int (*decrypto_aes_ctr_update)(archive_crypto_ctx *, const uint8_t *, size_t, uint8_t *, size_t *); int (*decrypto_aes_ctr_release)(archive_crypto_ctx *); int (*encrypto_aes_ctr_init)(archive_crypto_ctx *, const uint8_t *, size_t); int (*encrypto_aes_ctr_update)(archive_crypto_ctx *, const uint8_t *, size_t, uint8_t *, size_t *); int (*encrypto_aes_ctr_release)(archive_crypto_ctx *); }; extern const struct archive_cryptor __archive_cryptor; #endif Index: head/contrib/libarchive/libarchive/archive_digest.c =================================================================== --- head/contrib/libarchive/libarchive/archive_digest.c (revision 356365) +++ head/contrib/libarchive/libarchive/archive_digest.c (revision 356366) @@ -1,1463 +1,1691 @@ /*- * Copyright (c) 2003-2007 Tim Kientzle * Copyright (c) 2011 Andres Mejia * Copyright (c) 2011 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "archive_platform.h" #include "archive.h" #include "archive_digest_private.h" /* In particular, force the configure probe to break if it tries * to test a combination of OpenSSL and libmd. */ #if defined(ARCHIVE_CRYPTO_OPENSSL) && defined(ARCHIVE_CRYPTO_LIBMD) #error Cannot use both OpenSSL and libmd. #endif /* * Message digest functions for Windows platform. */ #if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\ defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\ defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\ defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\ defined(ARCHIVE_CRYPTO_SHA512_WIN) /* * Initialize a Message digest. */ static int win_crypto_init(Digest_CTX *ctx, ALG_ID algId) { ctx->valid = 0; if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { if (GetLastError() != (DWORD)NTE_BAD_KEYSET) return (ARCHIVE_FAILED); if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) return (ARCHIVE_FAILED); } if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) { CryptReleaseContext(ctx->cryptProv, 0); return (ARCHIVE_FAILED); } ctx->valid = 1; return (ARCHIVE_OK); } /* * Update a Message digest. */ static int win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len) { if (!ctx->valid) return (ARCHIVE_FAILED); CryptHashData(ctx->hash, (unsigned char *)(uintptr_t)buf, (DWORD)len, 0); return (ARCHIVE_OK); } static int win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx) { DWORD siglen = (DWORD)bufsize; if (!ctx->valid) return (ARCHIVE_FAILED); CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0); CryptDestroyHash(ctx->hash); CryptReleaseContext(ctx->cryptProv, 0); ctx->valid = 0; return (ARCHIVE_OK); } #endif /* defined(ARCHIVE_CRYPTO_*_WIN) */ /* MD5 implementations */ #if defined(ARCHIVE_CRYPTO_MD5_LIBC) static int __archive_libc_md5init(archive_md5_ctx *ctx) { MD5Init(ctx); return (ARCHIVE_OK); } static int __archive_libc_md5update(archive_md5_ctx *ctx, const void *indata, size_t insize) { MD5Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc_md5final(archive_md5_ctx *ctx, void *md) { MD5Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_MD5_LIBMD) static int __archive_libmd_md5init(archive_md5_ctx *ctx) { MD5Init(ctx); return (ARCHIVE_OK); } static int __archive_libmd_md5update(archive_md5_ctx *ctx, const void *indata, size_t insize) { MD5Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libmd_md5final(archive_md5_ctx *ctx, void *md) { MD5Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) static int __archive_libsystem_md5init(archive_md5_ctx *ctx) { CC_MD5_Init(ctx); return (ARCHIVE_OK); } static int __archive_libsystem_md5update(archive_md5_ctx *ctx, const void *indata, size_t insize) { CC_MD5_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libsystem_md5final(archive_md5_ctx *ctx, void *md) { CC_MD5_Final(md, ctx); return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) + +static int +__archive_mbedtls_md5init(archive_md5_ctx *ctx) +{ + mbedtls_md5_init(ctx); + if (mbedtls_md5_starts_ret(ctx) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_md5update(archive_md5_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_md5_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_md5final(archive_md5_ctx *ctx, void *md) +{ + if (mbedtls_md5_finish_ret(ctx, md) == 0) { + mbedtls_md5_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_md5_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_MD5_NETTLE) static int __archive_nettle_md5init(archive_md5_ctx *ctx) { md5_init(ctx); return (ARCHIVE_OK); } static int __archive_nettle_md5update(archive_md5_ctx *ctx, const void *indata, size_t insize) { md5_update(ctx, insize, indata); return (ARCHIVE_OK); } static int __archive_nettle_md5final(archive_md5_ctx *ctx, void *md) { md5_digest(ctx, MD5_DIGEST_SIZE, md); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL) static int __archive_openssl_md5init(archive_md5_ctx *ctx) { if ((*ctx = EVP_MD_CTX_new()) == NULL) return (ARCHIVE_FAILED); EVP_DigestInit(*ctx, EVP_md5()); return (ARCHIVE_OK); } static int __archive_openssl_md5update(archive_md5_ctx *ctx, const void *indata, size_t insize) { EVP_DigestUpdate(*ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_openssl_md5final(archive_md5_ctx *ctx, void *md) { /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so * this is meant to cope with that. Real fix is probably to fix * archive_write_set_format_xar.c */ if (*ctx) { EVP_DigestFinal(*ctx, md, NULL); EVP_MD_CTX_free(*ctx); *ctx = NULL; } return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_MD5_WIN) static int __archive_windowsapi_md5init(archive_md5_ctx *ctx) { return (win_crypto_init(ctx, CALG_MD5)); } static int __archive_windowsapi_md5update(archive_md5_ctx *ctx, const void *indata, size_t insize) { return (win_crypto_Update(ctx, indata, insize)); } static int __archive_windowsapi_md5final(archive_md5_ctx *ctx, void *md) { return (win_crypto_Final(md, 16, ctx)); } #else static int __archive_stub_md5init(archive_md5_ctx *ctx) { (void)ctx; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_md5update(archive_md5_ctx *ctx, const void *indata, size_t insize) { (void)ctx; /* UNUSED */ (void)indata; /* UNUSED */ (void)insize; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_md5final(archive_md5_ctx *ctx, void *md) { (void)ctx; /* UNUSED */ (void)md; /* UNUSED */ return (ARCHIVE_FAILED); } #endif /* RIPEMD160 implementations */ #if defined(ARCHIVE_CRYPTO_RMD160_LIBC) static int __archive_libc_ripemd160init(archive_rmd160_ctx *ctx) { RMD160Init(ctx); return (ARCHIVE_OK); } static int __archive_libc_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, size_t insize) { RMD160Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc_ripemd160final(archive_rmd160_ctx *ctx, void *md) { RMD160Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD) static int __archive_libmd_ripemd160init(archive_rmd160_ctx *ctx) { RIPEMD160_Init(ctx); return (ARCHIVE_OK); } static int __archive_libmd_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, size_t insize) { RIPEMD160_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libmd_ripemd160final(archive_rmd160_ctx *ctx, void *md) { RIPEMD160_Final(md, ctx); return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) + +static int +__archive_mbedtls_ripemd160init(archive_rmd160_ctx *ctx) +{ + mbedtls_ripemd160_init(ctx); + if (mbedtls_ripemd160_starts_ret(ctx) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_ripemd160_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_ripemd160final(archive_rmd160_ctx *ctx, void *md) +{ + if (mbedtls_ripemd160_finish_ret(ctx, md) == 0) { + mbedtls_ripemd160_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_ripemd160_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE) static int __archive_nettle_ripemd160init(archive_rmd160_ctx *ctx) { ripemd160_init(ctx); return (ARCHIVE_OK); } static int __archive_nettle_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, size_t insize) { ripemd160_update(ctx, insize, indata); return (ARCHIVE_OK); } static int __archive_nettle_ripemd160final(archive_rmd160_ctx *ctx, void *md) { ripemd160_digest(ctx, RIPEMD160_DIGEST_SIZE, md); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) static int __archive_openssl_ripemd160init(archive_rmd160_ctx *ctx) { if ((*ctx = EVP_MD_CTX_new()) == NULL) return (ARCHIVE_FAILED); EVP_DigestInit(*ctx, EVP_ripemd160()); return (ARCHIVE_OK); } static int __archive_openssl_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, size_t insize) { EVP_DigestUpdate(*ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_openssl_ripemd160final(archive_rmd160_ctx *ctx, void *md) { if (*ctx) { EVP_DigestFinal(*ctx, md, NULL); EVP_MD_CTX_free(*ctx); *ctx = NULL; } return (ARCHIVE_OK); } #else static int __archive_stub_ripemd160init(archive_rmd160_ctx *ctx) { (void)ctx; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, size_t insize) { (void)ctx; /* UNUSED */ (void)indata; /* UNUSED */ (void)insize; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_ripemd160final(archive_rmd160_ctx *ctx, void *md) { (void)ctx; /* UNUSED */ (void)md; /* UNUSED */ return (ARCHIVE_FAILED); } #endif /* SHA1 implementations */ #if defined(ARCHIVE_CRYPTO_SHA1_LIBC) static int __archive_libc_sha1init(archive_sha1_ctx *ctx) { SHA1Init(ctx); return (ARCHIVE_OK); } static int __archive_libc_sha1update(archive_sha1_ctx *ctx, const void *indata, size_t insize) { SHA1Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc_sha1final(archive_sha1_ctx *ctx, void *md) { SHA1Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD) static int __archive_libmd_sha1init(archive_sha1_ctx *ctx) { SHA1_Init(ctx); return (ARCHIVE_OK); } static int __archive_libmd_sha1update(archive_sha1_ctx *ctx, const void *indata, size_t insize) { SHA1_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libmd_sha1final(archive_sha1_ctx *ctx, void *md) { SHA1_Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) static int __archive_libsystem_sha1init(archive_sha1_ctx *ctx) { CC_SHA1_Init(ctx); return (ARCHIVE_OK); } static int __archive_libsystem_sha1update(archive_sha1_ctx *ctx, const void *indata, size_t insize) { CC_SHA1_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libsystem_sha1final(archive_sha1_ctx *ctx, void *md) { CC_SHA1_Final(md, ctx); return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) + +static int +__archive_mbedtls_sha1init(archive_sha1_ctx *ctx) +{ + mbedtls_sha1_init(ctx); + if (mbedtls_sha1_starts_ret(ctx) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha1update(archive_sha1_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_sha1_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha1final(archive_sha1_ctx *ctx, void *md) +{ + if (mbedtls_sha1_finish_ret(ctx, md) == 0) { + mbedtls_sha1_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_sha1_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE) static int __archive_nettle_sha1init(archive_sha1_ctx *ctx) { sha1_init(ctx); return (ARCHIVE_OK); } static int __archive_nettle_sha1update(archive_sha1_ctx *ctx, const void *indata, size_t insize) { sha1_update(ctx, insize, indata); return (ARCHIVE_OK); } static int __archive_nettle_sha1final(archive_sha1_ctx *ctx, void *md) { sha1_digest(ctx, SHA1_DIGEST_SIZE, md); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) static int __archive_openssl_sha1init(archive_sha1_ctx *ctx) { if ((*ctx = EVP_MD_CTX_new()) == NULL) return (ARCHIVE_FAILED); EVP_DigestInit(*ctx, EVP_sha1()); return (ARCHIVE_OK); } static int __archive_openssl_sha1update(archive_sha1_ctx *ctx, const void *indata, size_t insize) { EVP_DigestUpdate(*ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_openssl_sha1final(archive_sha1_ctx *ctx, void *md) { /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so * this is meant to cope with that. Real fix is probably to fix * archive_write_set_format_xar.c */ if (*ctx) { EVP_DigestFinal(*ctx, md, NULL); EVP_MD_CTX_free(*ctx); *ctx = NULL; } return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA1_WIN) static int __archive_windowsapi_sha1init(archive_sha1_ctx *ctx) { return (win_crypto_init(ctx, CALG_SHA1)); } static int __archive_windowsapi_sha1update(archive_sha1_ctx *ctx, const void *indata, size_t insize) { return (win_crypto_Update(ctx, indata, insize)); } static int __archive_windowsapi_sha1final(archive_sha1_ctx *ctx, void *md) { return (win_crypto_Final(md, 20, ctx)); } #else static int __archive_stub_sha1init(archive_sha1_ctx *ctx) { (void)ctx; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_sha1update(archive_sha1_ctx *ctx, const void *indata, size_t insize) { (void)ctx; /* UNUSED */ (void)indata; /* UNUSED */ (void)insize; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_sha1final(archive_sha1_ctx *ctx, void *md) { (void)ctx; /* UNUSED */ (void)md; /* UNUSED */ return (ARCHIVE_FAILED); } #endif /* SHA256 implementations */ #if defined(ARCHIVE_CRYPTO_SHA256_LIBC) static int __archive_libc_sha256init(archive_sha256_ctx *ctx) { SHA256_Init(ctx); return (ARCHIVE_OK); } static int __archive_libc_sha256update(archive_sha256_ctx *ctx, const void *indata, size_t insize) { SHA256_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc_sha256final(archive_sha256_ctx *ctx, void *md) { SHA256_Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2) static int __archive_libc2_sha256init(archive_sha256_ctx *ctx) { SHA256Init(ctx); return (ARCHIVE_OK); } static int __archive_libc2_sha256update(archive_sha256_ctx *ctx, const void *indata, size_t insize) { SHA256Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc2_sha256final(archive_sha256_ctx *ctx, void *md) { SHA256Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3) static int __archive_libc3_sha256init(archive_sha256_ctx *ctx) { SHA256Init(ctx); return (ARCHIVE_OK); } static int __archive_libc3_sha256update(archive_sha256_ctx *ctx, const void *indata, size_t insize) { SHA256Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc3_sha256final(archive_sha256_ctx *ctx, void *md) { SHA256Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD) static int __archive_libmd_sha256init(archive_sha256_ctx *ctx) { SHA256_Init(ctx); return (ARCHIVE_OK); } static int __archive_libmd_sha256update(archive_sha256_ctx *ctx, const void *indata, size_t insize) { SHA256_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libmd_sha256final(archive_sha256_ctx *ctx, void *md) { SHA256_Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) static int __archive_libsystem_sha256init(archive_sha256_ctx *ctx) { CC_SHA256_Init(ctx); return (ARCHIVE_OK); } static int __archive_libsystem_sha256update(archive_sha256_ctx *ctx, const void *indata, size_t insize) { CC_SHA256_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libsystem_sha256final(archive_sha256_ctx *ctx, void *md) { CC_SHA256_Final(md, ctx); return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) + +static int +__archive_mbedtls_sha256init(archive_sha256_ctx *ctx) +{ + mbedtls_sha256_init(ctx); + if (mbedtls_sha256_starts_ret(ctx, 0) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha256update(archive_sha256_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_sha256_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha256final(archive_sha256_ctx *ctx, void *md) +{ + if (mbedtls_sha256_finish_ret(ctx, md) == 0) { + mbedtls_sha256_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_sha256_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE) static int __archive_nettle_sha256init(archive_sha256_ctx *ctx) { sha256_init(ctx); return (ARCHIVE_OK); } static int __archive_nettle_sha256update(archive_sha256_ctx *ctx, const void *indata, size_t insize) { sha256_update(ctx, insize, indata); return (ARCHIVE_OK); } static int __archive_nettle_sha256final(archive_sha256_ctx *ctx, void *md) { sha256_digest(ctx, SHA256_DIGEST_SIZE, md); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) static int __archive_openssl_sha256init(archive_sha256_ctx *ctx) { if ((*ctx = EVP_MD_CTX_new()) == NULL) return (ARCHIVE_FAILED); EVP_DigestInit(*ctx, EVP_sha256()); return (ARCHIVE_OK); } static int __archive_openssl_sha256update(archive_sha256_ctx *ctx, const void *indata, size_t insize) { EVP_DigestUpdate(*ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_openssl_sha256final(archive_sha256_ctx *ctx, void *md) { if (*ctx) { EVP_DigestFinal(*ctx, md, NULL); EVP_MD_CTX_free(*ctx); *ctx = NULL; } return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA256_WIN) static int __archive_windowsapi_sha256init(archive_sha256_ctx *ctx) { return (win_crypto_init(ctx, CALG_SHA_256)); } static int __archive_windowsapi_sha256update(archive_sha256_ctx *ctx, const void *indata, size_t insize) { return (win_crypto_Update(ctx, indata, insize)); } static int __archive_windowsapi_sha256final(archive_sha256_ctx *ctx, void *md) { return (win_crypto_Final(md, 32, ctx)); } #else static int __archive_stub_sha256init(archive_sha256_ctx *ctx) { (void)ctx; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_sha256update(archive_sha256_ctx *ctx, const void *indata, size_t insize) { (void)ctx; /* UNUSED */ (void)indata; /* UNUSED */ (void)insize; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_sha256final(archive_sha256_ctx *ctx, void *md) { (void)ctx; /* UNUSED */ (void)md; /* UNUSED */ return (ARCHIVE_FAILED); } #endif /* SHA384 implementations */ #if defined(ARCHIVE_CRYPTO_SHA384_LIBC) static int __archive_libc_sha384init(archive_sha384_ctx *ctx) { SHA384_Init(ctx); return (ARCHIVE_OK); } static int __archive_libc_sha384update(archive_sha384_ctx *ctx, const void *indata, size_t insize) { SHA384_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc_sha384final(archive_sha384_ctx *ctx, void *md) { SHA384_Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2) static int __archive_libc2_sha384init(archive_sha384_ctx *ctx) { SHA384Init(ctx); return (ARCHIVE_OK); } static int __archive_libc2_sha384update(archive_sha384_ctx *ctx, const void *indata, size_t insize) { SHA384Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc2_sha384final(archive_sha384_ctx *ctx, void *md) { SHA384Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3) static int __archive_libc3_sha384init(archive_sha384_ctx *ctx) { SHA384Init(ctx); return (ARCHIVE_OK); } static int __archive_libc3_sha384update(archive_sha384_ctx *ctx, const void *indata, size_t insize) { SHA384Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc3_sha384final(archive_sha384_ctx *ctx, void *md) { SHA384Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) static int __archive_libsystem_sha384init(archive_sha384_ctx *ctx) { CC_SHA384_Init(ctx); return (ARCHIVE_OK); } static int __archive_libsystem_sha384update(archive_sha384_ctx *ctx, const void *indata, size_t insize) { CC_SHA384_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libsystem_sha384final(archive_sha384_ctx *ctx, void *md) { CC_SHA384_Final(md, ctx); return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) + +static int +__archive_mbedtls_sha384init(archive_sha384_ctx *ctx) +{ + mbedtls_sha512_init(ctx); + if (mbedtls_sha512_starts_ret(ctx, 1) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha384update(archive_sha384_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha384final(archive_sha384_ctx *ctx, void *md) +{ + if (mbedtls_sha512_finish_ret(ctx, md) == 0) { + mbedtls_sha512_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_sha512_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE) static int __archive_nettle_sha384init(archive_sha384_ctx *ctx) { sha384_init(ctx); return (ARCHIVE_OK); } static int __archive_nettle_sha384update(archive_sha384_ctx *ctx, const void *indata, size_t insize) { sha384_update(ctx, insize, indata); return (ARCHIVE_OK); } static int __archive_nettle_sha384final(archive_sha384_ctx *ctx, void *md) { sha384_digest(ctx, SHA384_DIGEST_SIZE, md); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) static int __archive_openssl_sha384init(archive_sha384_ctx *ctx) { if ((*ctx = EVP_MD_CTX_new()) == NULL) return (ARCHIVE_FAILED); EVP_DigestInit(*ctx, EVP_sha384()); return (ARCHIVE_OK); } static int __archive_openssl_sha384update(archive_sha384_ctx *ctx, const void *indata, size_t insize) { EVP_DigestUpdate(*ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_openssl_sha384final(archive_sha384_ctx *ctx, void *md) { if (*ctx) { EVP_DigestFinal(*ctx, md, NULL); EVP_MD_CTX_free(*ctx); *ctx = NULL; } return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA384_WIN) static int __archive_windowsapi_sha384init(archive_sha384_ctx *ctx) { return (win_crypto_init(ctx, CALG_SHA_384)); } static int __archive_windowsapi_sha384update(archive_sha384_ctx *ctx, const void *indata, size_t insize) { return (win_crypto_Update(ctx, indata, insize)); } static int __archive_windowsapi_sha384final(archive_sha384_ctx *ctx, void *md) { return (win_crypto_Final(md, 48, ctx)); } #else static int __archive_stub_sha384init(archive_sha384_ctx *ctx) { (void)ctx; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_sha384update(archive_sha384_ctx *ctx, const void *indata, size_t insize) { (void)ctx; /* UNUSED */ (void)indata; /* UNUSED */ (void)insize; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_sha384final(archive_sha384_ctx *ctx, void *md) { (void)ctx; /* UNUSED */ (void)md; /* UNUSED */ return (ARCHIVE_FAILED); } #endif /* SHA512 implementations */ #if defined(ARCHIVE_CRYPTO_SHA512_LIBC) static int __archive_libc_sha512init(archive_sha512_ctx *ctx) { SHA512_Init(ctx); return (ARCHIVE_OK); } static int __archive_libc_sha512update(archive_sha512_ctx *ctx, const void *indata, size_t insize) { SHA512_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc_sha512final(archive_sha512_ctx *ctx, void *md) { SHA512_Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2) static int __archive_libc2_sha512init(archive_sha512_ctx *ctx) { SHA512Init(ctx); return (ARCHIVE_OK); } static int __archive_libc2_sha512update(archive_sha512_ctx *ctx, const void *indata, size_t insize) { SHA512Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc2_sha512final(archive_sha512_ctx *ctx, void *md) { SHA512Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3) static int __archive_libc3_sha512init(archive_sha512_ctx *ctx) { SHA512Init(ctx); return (ARCHIVE_OK); } static int __archive_libc3_sha512update(archive_sha512_ctx *ctx, const void *indata, size_t insize) { SHA512Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libc3_sha512final(archive_sha512_ctx *ctx, void *md) { SHA512Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD) static int __archive_libmd_sha512init(archive_sha512_ctx *ctx) { SHA512_Init(ctx); return (ARCHIVE_OK); } static int __archive_libmd_sha512update(archive_sha512_ctx *ctx, const void *indata, size_t insize) { SHA512_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libmd_sha512final(archive_sha512_ctx *ctx, void *md) { SHA512_Final(md, ctx); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) static int __archive_libsystem_sha512init(archive_sha512_ctx *ctx) { CC_SHA512_Init(ctx); return (ARCHIVE_OK); } static int __archive_libsystem_sha512update(archive_sha512_ctx *ctx, const void *indata, size_t insize) { CC_SHA512_Update(ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_libsystem_sha512final(archive_sha512_ctx *ctx, void *md) { CC_SHA512_Final(md, ctx); return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) + +static int +__archive_mbedtls_sha512init(archive_sha512_ctx *ctx) +{ + mbedtls_sha512_init(ctx); + if (mbedtls_sha512_starts_ret(ctx, 0) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha512update(archive_sha512_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha512final(archive_sha512_ctx *ctx, void *md) +{ + if (mbedtls_sha512_finish_ret(ctx, md) == 0) { + mbedtls_sha512_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_sha512_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE) static int __archive_nettle_sha512init(archive_sha512_ctx *ctx) { sha512_init(ctx); return (ARCHIVE_OK); } static int __archive_nettle_sha512update(archive_sha512_ctx *ctx, const void *indata, size_t insize) { sha512_update(ctx, insize, indata); return (ARCHIVE_OK); } static int __archive_nettle_sha512final(archive_sha512_ctx *ctx, void *md) { sha512_digest(ctx, SHA512_DIGEST_SIZE, md); return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) static int __archive_openssl_sha512init(archive_sha512_ctx *ctx) { if ((*ctx = EVP_MD_CTX_new()) == NULL) return (ARCHIVE_FAILED); EVP_DigestInit(*ctx, EVP_sha512()); return (ARCHIVE_OK); } static int __archive_openssl_sha512update(archive_sha512_ctx *ctx, const void *indata, size_t insize) { EVP_DigestUpdate(*ctx, indata, insize); return (ARCHIVE_OK); } static int __archive_openssl_sha512final(archive_sha512_ctx *ctx, void *md) { if (*ctx) { EVP_DigestFinal(*ctx, md, NULL); EVP_MD_CTX_free(*ctx); *ctx = NULL; } return (ARCHIVE_OK); } #elif defined(ARCHIVE_CRYPTO_SHA512_WIN) static int __archive_windowsapi_sha512init(archive_sha512_ctx *ctx) { return (win_crypto_init(ctx, CALG_SHA_512)); } static int __archive_windowsapi_sha512update(archive_sha512_ctx *ctx, const void *indata, size_t insize) { return (win_crypto_Update(ctx, indata, insize)); } static int __archive_windowsapi_sha512final(archive_sha512_ctx *ctx, void *md) { return (win_crypto_Final(md, 64, ctx)); } #else static int __archive_stub_sha512init(archive_sha512_ctx *ctx) { (void)ctx; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_sha512update(archive_sha512_ctx *ctx, const void *indata, size_t insize) { (void)ctx; /* UNUSED */ (void)indata; /* UNUSED */ (void)insize; /* UNUSED */ return (ARCHIVE_FAILED); } static int __archive_stub_sha512final(archive_sha512_ctx *ctx, void *md) { (void)ctx; /* UNUSED */ (void)md; /* UNUSED */ return (ARCHIVE_FAILED); } #endif /* NOTE: Message Digest functions are set based on availability and by the * following order of preference. * 1. libc * 2. libc2 * 3. libc3 * 4. libSystem * 5. Nettle * 6. OpenSSL * 7. libmd * 8. Windows API */ const struct archive_digest __archive_digest = { /* MD5 */ #if defined(ARCHIVE_CRYPTO_MD5_LIBC) &__archive_libc_md5init, &__archive_libc_md5update, &__archive_libc_md5final, #elif defined(ARCHIVE_CRYPTO_MD5_LIBMD) &__archive_libmd_md5init, &__archive_libmd_md5update, &__archive_libmd_md5final, #elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) &__archive_libsystem_md5init, &__archive_libsystem_md5update, &__archive_libsystem_md5final, +#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) + &__archive_mbedtls_md5init, + &__archive_mbedtls_md5update, + &__archive_mbedtls_md5final, #elif defined(ARCHIVE_CRYPTO_MD5_NETTLE) &__archive_nettle_md5init, &__archive_nettle_md5update, &__archive_nettle_md5final, #elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL) &__archive_openssl_md5init, &__archive_openssl_md5update, &__archive_openssl_md5final, #elif defined(ARCHIVE_CRYPTO_MD5_WIN) &__archive_windowsapi_md5init, &__archive_windowsapi_md5update, &__archive_windowsapi_md5final, #elif !defined(ARCHIVE_MD5_COMPILE_TEST) &__archive_stub_md5init, &__archive_stub_md5update, &__archive_stub_md5final, #endif /* RIPEMD160 */ #if defined(ARCHIVE_CRYPTO_RMD160_LIBC) &__archive_libc_ripemd160init, &__archive_libc_ripemd160update, &__archive_libc_ripemd160final, #elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD) &__archive_libmd_ripemd160init, &__archive_libmd_ripemd160update, &__archive_libmd_ripemd160final, +#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) + &__archive_mbedtls_ripemd160init, + &__archive_mbedtls_ripemd160update, + &__archive_mbedtls_ripemd160final, #elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE) &__archive_nettle_ripemd160init, &__archive_nettle_ripemd160update, &__archive_nettle_ripemd160final, #elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) &__archive_openssl_ripemd160init, &__archive_openssl_ripemd160update, &__archive_openssl_ripemd160final, #elif !defined(ARCHIVE_RMD160_COMPILE_TEST) &__archive_stub_ripemd160init, &__archive_stub_ripemd160update, &__archive_stub_ripemd160final, #endif /* SHA1 */ #if defined(ARCHIVE_CRYPTO_SHA1_LIBC) &__archive_libc_sha1init, &__archive_libc_sha1update, &__archive_libc_sha1final, #elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD) &__archive_libmd_sha1init, &__archive_libmd_sha1update, &__archive_libmd_sha1final, #elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) &__archive_libsystem_sha1init, &__archive_libsystem_sha1update, &__archive_libsystem_sha1final, +#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) + &__archive_mbedtls_sha1init, + &__archive_mbedtls_sha1update, + &__archive_mbedtls_sha1final, #elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE) &__archive_nettle_sha1init, &__archive_nettle_sha1update, &__archive_nettle_sha1final, #elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) &__archive_openssl_sha1init, &__archive_openssl_sha1update, &__archive_openssl_sha1final, #elif defined(ARCHIVE_CRYPTO_SHA1_WIN) &__archive_windowsapi_sha1init, &__archive_windowsapi_sha1update, &__archive_windowsapi_sha1final, #elif !defined(ARCHIVE_SHA1_COMPILE_TEST) &__archive_stub_sha1init, &__archive_stub_sha1update, &__archive_stub_sha1final, #endif /* SHA256 */ #if defined(ARCHIVE_CRYPTO_SHA256_LIBC) &__archive_libc_sha256init, &__archive_libc_sha256update, &__archive_libc_sha256final, #elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2) &__archive_libc2_sha256init, &__archive_libc2_sha256update, &__archive_libc2_sha256final, #elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3) &__archive_libc3_sha256init, &__archive_libc3_sha256update, &__archive_libc3_sha256final, #elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD) &__archive_libmd_sha256init, &__archive_libmd_sha256update, &__archive_libmd_sha256final, #elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) &__archive_libsystem_sha256init, &__archive_libsystem_sha256update, &__archive_libsystem_sha256final, +#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) + &__archive_mbedtls_sha256init, + &__archive_mbedtls_sha256update, + &__archive_mbedtls_sha256final, #elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE) &__archive_nettle_sha256init, &__archive_nettle_sha256update, &__archive_nettle_sha256final, #elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) &__archive_openssl_sha256init, &__archive_openssl_sha256update, &__archive_openssl_sha256final, #elif defined(ARCHIVE_CRYPTO_SHA256_WIN) &__archive_windowsapi_sha256init, &__archive_windowsapi_sha256update, &__archive_windowsapi_sha256final, #elif !defined(ARCHIVE_SHA256_COMPILE_TEST) &__archive_stub_sha256init, &__archive_stub_sha256update, &__archive_stub_sha256final, #endif /* SHA384 */ #if defined(ARCHIVE_CRYPTO_SHA384_LIBC) &__archive_libc_sha384init, &__archive_libc_sha384update, &__archive_libc_sha384final, #elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2) &__archive_libc2_sha384init, &__archive_libc2_sha384update, &__archive_libc2_sha384final, #elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3) &__archive_libc3_sha384init, &__archive_libc3_sha384update, &__archive_libc3_sha384final, #elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) &__archive_libsystem_sha384init, &__archive_libsystem_sha384update, &__archive_libsystem_sha384final, +#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) + &__archive_mbedtls_sha384init, + &__archive_mbedtls_sha384update, + &__archive_mbedtls_sha384final, #elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE) &__archive_nettle_sha384init, &__archive_nettle_sha384update, &__archive_nettle_sha384final, #elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) &__archive_openssl_sha384init, &__archive_openssl_sha384update, &__archive_openssl_sha384final, #elif defined(ARCHIVE_CRYPTO_SHA384_WIN) &__archive_windowsapi_sha384init, &__archive_windowsapi_sha384update, &__archive_windowsapi_sha384final, #elif !defined(ARCHIVE_SHA384_COMPILE_TEST) &__archive_stub_sha384init, &__archive_stub_sha384update, &__archive_stub_sha384final, #endif /* SHA512 */ #if defined(ARCHIVE_CRYPTO_SHA512_LIBC) &__archive_libc_sha512init, &__archive_libc_sha512update, &__archive_libc_sha512final #elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2) &__archive_libc2_sha512init, &__archive_libc2_sha512update, &__archive_libc2_sha512final #elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3) &__archive_libc3_sha512init, &__archive_libc3_sha512update, &__archive_libc3_sha512final #elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD) &__archive_libmd_sha512init, &__archive_libmd_sha512update, &__archive_libmd_sha512final #elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) &__archive_libsystem_sha512init, &__archive_libsystem_sha512update, &__archive_libsystem_sha512final +#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) + &__archive_mbedtls_sha512init, + &__archive_mbedtls_sha512update, + &__archive_mbedtls_sha512final #elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE) &__archive_nettle_sha512init, &__archive_nettle_sha512update, &__archive_nettle_sha512final #elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) &__archive_openssl_sha512init, &__archive_openssl_sha512update, &__archive_openssl_sha512final #elif defined(ARCHIVE_CRYPTO_SHA512_WIN) &__archive_windowsapi_sha512init, &__archive_windowsapi_sha512update, &__archive_windowsapi_sha512final #elif !defined(ARCHIVE_SHA512_COMPILE_TEST) &__archive_stub_sha512init, &__archive_stub_sha512update, &__archive_stub_sha512final #endif }; Index: head/contrib/libarchive/libarchive/archive_digest_private.h =================================================================== --- head/contrib/libarchive/libarchive/archive_digest_private.h (revision 356365) +++ head/contrib/libarchive/libarchive/archive_digest_private.h (revision 356366) @@ -1,377 +1,413 @@ /*- * Copyright (c) 2003-2007 Tim Kientzle * Copyright (c) 2011 Andres Mejia * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif #ifndef ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED #define ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED /* * Crypto support in various Operating Systems: * * NetBSD: * - MD5 and SHA1 in libc: without _ after algorithm name * - SHA2 in libc: with _ after algorithm name * * OpenBSD: * - MD5, SHA1 and SHA2 in libc: without _ after algorithm name * - OpenBSD 4.4 and earlier have SHA2 in libc with _ after algorithm name * * DragonFly and FreeBSD: * - MD5 libmd: without _ after algorithm name * - SHA1, SHA256 and SHA512 in libmd: with _ after algorithm name * * Mac OS X (10.4 and later): * - MD5, SHA1 and SHA2 in libSystem: with CC_ prefix and _ after algorithm name * * OpenSSL: * - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name * * Windows: * - MD5, SHA1 and SHA2 in archive_crypto.c using Windows crypto API */ /* libc crypto headers */ #if defined(ARCHIVE_CRYPTO_MD5_LIBC) #include #endif #if defined(ARCHIVE_CRYPTO_RMD160_LIBC) #include #endif #if defined(ARCHIVE_CRYPTO_SHA1_LIBC) #include #endif #if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\ defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\ defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\ defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\ defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\ defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\ defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\ defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\ defined(ARCHIVE_CRYPTO_SHA512_LIBC3) #include #endif /* libmd crypto headers */ #if defined(ARCHIVE_CRYPTO_MD5_LIBMD) ||\ defined(ARCHIVE_CRYPTO_RMD160_LIBMD) ||\ defined(ARCHIVE_CRYPTO_SHA1_LIBMD) ||\ defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\ defined(ARCHIVE_CRYPTO_SHA512_LIBMD) #define ARCHIVE_CRYPTO_LIBMD 1 #endif #if defined(ARCHIVE_CRYPTO_MD5_LIBMD) #include #endif #if defined(ARCHIVE_CRYPTO_RMD160_LIBMD) #include #endif #if defined(ARCHIVE_CRYPTO_SHA1_LIBMD) #include #endif #if defined(ARCHIVE_CRYPTO_SHA256_LIBMD) #include #endif #if defined(ARCHIVE_CRYPTO_SHA512_LIBMD) #include #endif /* libSystem crypto headers */ #if defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\ defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\ defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\ defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\ defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) #include #endif +/* mbed TLS crypto headers */ +#if defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) +#include +#endif +#if defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) +#include +#endif +#if defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) +#include +#endif +#if defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) +#include +#endif +#if defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\ + defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) +#include +#endif + /* Nettle crypto headers */ #if defined(ARCHIVE_CRYPTO_MD5_NETTLE) #include #endif #if defined(ARCHIVE_CRYPTO_RMD160_NETTLE) #include #endif #if defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\ defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\ defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\ defined(ARCHIVE_CRYPTO_SHA512_NETTLE) #include #endif /* OpenSSL crypto headers */ #if defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) #define ARCHIVE_CRYPTO_OPENSSL 1 #include "archive_openssl_evp_private.h" #endif /* Windows crypto headers */ #if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\ defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\ defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\ defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\ defined(ARCHIVE_CRYPTO_SHA512_WIN) #include #include typedef struct { int valid; HCRYPTPROV cryptProv; HCRYPTHASH hash; } Digest_CTX; #endif /* typedefs */ #if defined(ARCHIVE_CRYPTO_MD5_LIBC) typedef MD5_CTX archive_md5_ctx; #elif defined(ARCHIVE_CRYPTO_MD5_LIBMD) typedef MD5_CTX archive_md5_ctx; #elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) typedef CC_MD5_CTX archive_md5_ctx; +#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) +typedef mbedtls_md5_context archive_md5_ctx; #elif defined(ARCHIVE_CRYPTO_MD5_NETTLE) typedef struct md5_ctx archive_md5_ctx; #elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL) typedef EVP_MD_CTX *archive_md5_ctx; #elif defined(ARCHIVE_CRYPTO_MD5_WIN) typedef Digest_CTX archive_md5_ctx; #else typedef unsigned char archive_md5_ctx; #endif #if defined(ARCHIVE_CRYPTO_RMD160_LIBC) typedef RMD160_CTX archive_rmd160_ctx; #elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD) typedef RIPEMD160_CTX archive_rmd160_ctx; +#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) +typedef mbedtls_ripemd160_context archive_rmd160_ctx; #elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE) typedef struct ripemd160_ctx archive_rmd160_ctx; #elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) typedef EVP_MD_CTX *archive_rmd160_ctx; #else typedef unsigned char archive_rmd160_ctx; #endif #if defined(ARCHIVE_CRYPTO_SHA1_LIBC) typedef SHA1_CTX archive_sha1_ctx; #elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD) typedef SHA1_CTX archive_sha1_ctx; #elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) typedef CC_SHA1_CTX archive_sha1_ctx; +#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) +typedef mbedtls_sha1_context archive_sha1_ctx; #elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE) typedef struct sha1_ctx archive_sha1_ctx; #elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) typedef EVP_MD_CTX *archive_sha1_ctx; #elif defined(ARCHIVE_CRYPTO_SHA1_WIN) typedef Digest_CTX archive_sha1_ctx; #else typedef unsigned char archive_sha1_ctx; #endif #if defined(ARCHIVE_CRYPTO_SHA256_LIBC) typedef SHA256_CTX archive_sha256_ctx; #elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2) typedef SHA256_CTX archive_sha256_ctx; #elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3) typedef SHA2_CTX archive_sha256_ctx; #elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD) typedef SHA256_CTX archive_sha256_ctx; #elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) typedef CC_SHA256_CTX archive_sha256_ctx; +#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) +typedef mbedtls_sha256_context archive_sha256_ctx; #elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE) typedef struct sha256_ctx archive_sha256_ctx; #elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) typedef EVP_MD_CTX *archive_sha256_ctx; #elif defined(ARCHIVE_CRYPTO_SHA256_WIN) typedef Digest_CTX archive_sha256_ctx; #else typedef unsigned char archive_sha256_ctx; #endif #if defined(ARCHIVE_CRYPTO_SHA384_LIBC) typedef SHA384_CTX archive_sha384_ctx; #elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2) typedef SHA384_CTX archive_sha384_ctx; #elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3) typedef SHA2_CTX archive_sha384_ctx; #elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) typedef CC_SHA512_CTX archive_sha384_ctx; +#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) +typedef mbedtls_sha512_context archive_sha384_ctx; #elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE) typedef struct sha384_ctx archive_sha384_ctx; #elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) typedef EVP_MD_CTX *archive_sha384_ctx; #elif defined(ARCHIVE_CRYPTO_SHA384_WIN) typedef Digest_CTX archive_sha384_ctx; #else typedef unsigned char archive_sha384_ctx; #endif #if defined(ARCHIVE_CRYPTO_SHA512_LIBC) typedef SHA512_CTX archive_sha512_ctx; #elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2) typedef SHA512_CTX archive_sha512_ctx; #elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3) typedef SHA2_CTX archive_sha512_ctx; #elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD) typedef SHA512_CTX archive_sha512_ctx; #elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) typedef CC_SHA512_CTX archive_sha512_ctx; +#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) +typedef mbedtls_sha512_context archive_sha512_ctx; #elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE) typedef struct sha512_ctx archive_sha512_ctx; #elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) typedef EVP_MD_CTX *archive_sha512_ctx; #elif defined(ARCHIVE_CRYPTO_SHA512_WIN) typedef Digest_CTX archive_sha512_ctx; #else typedef unsigned char archive_sha512_ctx; #endif /* defines */ #if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\ defined(ARCHIVE_CRYPTO_MD5_LIBMD) || \ defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\ + defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\ defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_MD5_WIN) #define ARCHIVE_HAS_MD5 #endif #define archive_md5_init(ctx)\ __archive_digest.md5init(ctx) #define archive_md5_final(ctx, md)\ __archive_digest.md5final(ctx, md) #define archive_md5_update(ctx, buf, n)\ __archive_digest.md5update(ctx, buf, n) #if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\ + defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\ defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) #define ARCHIVE_HAS_RMD160 #endif #define archive_rmd160_init(ctx)\ __archive_digest.rmd160init(ctx) #define archive_rmd160_final(ctx, md)\ __archive_digest.rmd160final(ctx, md) #define archive_rmd160_update(ctx, buf, n)\ __archive_digest.rmd160update(ctx, buf, n) #if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\ defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \ defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\ + defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\ defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA1_WIN) #define ARCHIVE_HAS_SHA1 #endif #define archive_sha1_init(ctx)\ __archive_digest.sha1init(ctx) #define archive_sha1_final(ctx, md)\ __archive_digest.sha1final(ctx, md) #define archive_sha1_update(ctx, buf, n)\ __archive_digest.sha1update(ctx, buf, n) #if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\ defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\ defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\ defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\ defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\ + defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\ defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA256_WIN) #define ARCHIVE_HAS_SHA256 #endif #define archive_sha256_init(ctx)\ __archive_digest.sha256init(ctx) #define archive_sha256_final(ctx, md)\ __archive_digest.sha256final(ctx, md) #define archive_sha256_update(ctx, buf, n)\ __archive_digest.sha256update(ctx, buf, n) #if defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\ defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\ defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\ defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\ + defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\ defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA384_WIN) #define ARCHIVE_HAS_SHA384 #endif #define archive_sha384_init(ctx)\ __archive_digest.sha384init(ctx) #define archive_sha384_final(ctx, md)\ __archive_digest.sha384final(ctx, md) #define archive_sha384_update(ctx, buf, n)\ __archive_digest.sha384update(ctx, buf, n) #if defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\ defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\ defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\ defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\ defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\ + defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\ defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA512_WIN) #define ARCHIVE_HAS_SHA512 #endif #define archive_sha512_init(ctx)\ __archive_digest.sha512init(ctx) #define archive_sha512_final(ctx, md)\ __archive_digest.sha512final(ctx, md) #define archive_sha512_update(ctx, buf, n)\ __archive_digest.sha512update(ctx, buf, n) /* Minimal interface to digest functionality for internal use in libarchive */ struct archive_digest { /* Message Digest */ int (*md5init)(archive_md5_ctx *ctx); int (*md5update)(archive_md5_ctx *, const void *, size_t); int (*md5final)(archive_md5_ctx *, void *); int (*rmd160init)(archive_rmd160_ctx *); int (*rmd160update)(archive_rmd160_ctx *, const void *, size_t); int (*rmd160final)(archive_rmd160_ctx *, void *); int (*sha1init)(archive_sha1_ctx *); int (*sha1update)(archive_sha1_ctx *, const void *, size_t); int (*sha1final)(archive_sha1_ctx *, void *); int (*sha256init)(archive_sha256_ctx *); int (*sha256update)(archive_sha256_ctx *, const void *, size_t); int (*sha256final)(archive_sha256_ctx *, void *); int (*sha384init)(archive_sha384_ctx *); int (*sha384update)(archive_sha384_ctx *, const void *, size_t); int (*sha384final)(archive_sha384_ctx *, void *); int (*sha512init)(archive_sha512_ctx *); int (*sha512update)(archive_sha512_ctx *, const void *, size_t); int (*sha512final)(archive_sha512_ctx *, void *); }; extern const struct archive_digest __archive_digest; #endif Index: head/contrib/libarchive/libarchive/archive_hmac.c =================================================================== --- head/contrib/libarchive/libarchive/archive_hmac.c (revision 356365) +++ head/contrib/libarchive/libarchive/archive_hmac.c (revision 356366) @@ -1,257 +1,304 @@ /*- * Copyright (c) 2014 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "archive_platform.h" #ifdef HAVE_STRING_H #include #endif #include "archive.h" #include "archive_hmac_private.h" /* * On systems that do not support any recognized crypto libraries, * the archive_hmac.c file is expected to define no usable symbols. * * But some compilers and linkers choke on empty object files, so * define a public symbol that will always exist. This could * be removed someday if this file gains another always-present * symbol definition. */ int __libarchive_hmac_build_hack(void) { return 0; } #ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto static int __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) { CCHmacInit(ctx, kCCHmacAlgSHA1, key, key_len); return 0; } static void __hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, size_t data_len) { CCHmacUpdate(ctx, data, data_len); } static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) { CCHmacFinal(ctx, out); *out_len = 20; } static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); } #elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) #ifndef BCRYPT_HASH_REUSABLE_FLAG # define BCRYPT_HASH_REUSABLE_FLAG 0x00000020 #endif static int __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) { #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wcast-qual" #endif BCRYPT_ALG_HANDLE hAlg; BCRYPT_HASH_HANDLE hHash; DWORD hash_len; PBYTE hash; ULONG result; NTSTATUS status; ctx->hAlg = NULL; status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); if (!BCRYPT_SUCCESS(status)) return -1; status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PUCHAR)&hash_len, sizeof(hash_len), &result, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } hash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hash_len); if (hash == NULL) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } status = BCryptCreateHash(hAlg, &hHash, NULL, 0, (PUCHAR)key, (ULONG)key_len, BCRYPT_HASH_REUSABLE_FLAG); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); HeapFree(GetProcessHeap(), 0, hash); return -1; } ctx->hAlg = hAlg; ctx->hHash = hHash; ctx->hash_len = hash_len; ctx->hash = hash; return 0; } static void __hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, size_t data_len) { BCryptHashData(ctx->hHash, (PUCHAR)(uintptr_t)data, (ULONG)data_len, 0); } static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) { BCryptFinishHash(ctx->hHash, ctx->hash, ctx->hash_len, 0); if (ctx->hash_len == *out_len) memcpy(out, ctx->hash, *out_len); } static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) { if (ctx->hAlg != NULL) { BCryptCloseAlgorithmProvider(ctx->hAlg, 0); HeapFree(GetProcessHeap(), 0, ctx->hash); ctx->hAlg = NULL; } } +#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H) +static int +__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) +{ + const mbedtls_md_info_t *info; + int ret; + + mbedtls_md_init(ctx); + info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); + if (info == NULL) { + mbedtls_md_free(ctx); + return (-1); + } + ret = mbedtls_md_setup(ctx, info, 1); + if (ret != 0) { + mbedtls_md_free(ctx); + return (-1); + } + ret = mbedtls_md_hmac_starts(ctx, key, key_len); + if (ret != 0) { + mbedtls_md_free(ctx); + return (-1); + } + return 0; +} + +static void +__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, + size_t data_len) +{ + mbedtls_md_hmac_update(ctx, data, data_len); +} + +static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) +{ + (void)out_len; /* UNUSED */ + + mbedtls_md_hmac_finish(ctx, out); +} + +static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) +{ + mbedtls_md_free(ctx); + memset(ctx, 0, sizeof(*ctx)); +} + #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H) static int __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) { hmac_sha1_set_key(ctx, key_len, key); return 0; } static void __hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, size_t data_len) { hmac_sha1_update(ctx, data_len, data); } static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) { hmac_sha1_digest(ctx, (unsigned)*out_len, out); } static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); } #elif defined(HAVE_LIBCRYPTO) static int __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) { *ctx = HMAC_CTX_new(); if (*ctx == NULL) return -1; HMAC_Init_ex(*ctx, key, key_len, EVP_sha1(), NULL); return 0; } static void __hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, size_t data_len) { HMAC_Update(*ctx, data, data_len); } static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) { unsigned int len = (unsigned int)*out_len; + HMAC_Final(*ctx, out, &len); *out_len = len; } static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) { HMAC_CTX_free(*ctx); *ctx = NULL; } #else /* Stub */ static int __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) { (void)ctx;/* UNUSED */ (void)key;/* UNUSED */ (void)key_len;/* UNUSED */ return -1; } static void __hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, size_t data_len) { (void)ctx;/* UNUSED */ (void)data;/* UNUSED */ (void)data_len;/* UNUSED */ } static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) { (void)ctx;/* UNUSED */ (void)out;/* UNUSED */ (void)out_len;/* UNUSED */ } static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) { (void)ctx;/* UNUSED */ } #endif const struct archive_hmac __archive_hmac = { &__hmac_sha1_init, &__hmac_sha1_update, &__hmac_sha1_final, &__hmac_sha1_cleanup, }; Index: head/contrib/libarchive/libarchive/archive_hmac_private.h =================================================================== --- head/contrib/libarchive/libarchive/archive_hmac_private.h (revision 356365) +++ head/contrib/libarchive/libarchive/archive_hmac_private.h (revision 356366) @@ -1,106 +1,111 @@ /*- * Copyright (c) 2014 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif #ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED #define ARCHIVE_HMAC_PRIVATE_H_INCLUDED /* * On systems that do not support any recognized crypto libraries, * the archive_hmac.c file is expected to define no usable symbols. * * But some compilers and linkers choke on empty object files, so * define a public symbol that will always exist. This could * be removed someday if this file gains another always-present * symbol definition. */ int __libarchive_hmac_build_hack(void); #ifdef __APPLE__ # include # if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 # define ARCHIVE_HMAC_USE_Apple_CommonCrypto # endif #endif #ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto #include typedef CCHmacContext archive_hmac_sha1_ctx; #elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) #include typedef struct { BCRYPT_ALG_HANDLE hAlg; BCRYPT_HASH_HANDLE hHash; DWORD hash_len; PBYTE hash; } archive_hmac_sha1_ctx; +#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H) +#include + +typedef mbedtls_md_context_t archive_hmac_sha1_ctx; + #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H) #include typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx; #elif defined(HAVE_LIBCRYPTO) #include "archive_openssl_hmac_private.h" typedef HMAC_CTX* archive_hmac_sha1_ctx; #else typedef int archive_hmac_sha1_ctx; #endif /* HMAC */ #define archive_hmac_sha1_init(ctx, key, key_len)\ __archive_hmac.__hmac_sha1_init(ctx, key, key_len) #define archive_hmac_sha1_update(ctx, data, data_len)\ __archive_hmac.__hmac_sha1_update(ctx, data, data_len) #define archive_hmac_sha1_final(ctx, out, out_len)\ __archive_hmac.__hmac_sha1_final(ctx, out, out_len) #define archive_hmac_sha1_cleanup(ctx)\ __archive_hmac.__hmac_sha1_cleanup(ctx) struct archive_hmac { /* HMAC */ int (*__hmac_sha1_init)(archive_hmac_sha1_ctx *, const uint8_t *, size_t); void (*__hmac_sha1_update)(archive_hmac_sha1_ctx *, const uint8_t *, size_t); void (*__hmac_sha1_final)(archive_hmac_sha1_ctx *, uint8_t *, size_t *); void (*__hmac_sha1_cleanup)(archive_hmac_sha1_ctx *); }; extern const struct archive_hmac __archive_hmac; #endif /* ARCHIVE_HMAC_PRIVATE_H_INCLUDED */ Index: head/contrib/libarchive/libarchive/archive_write.c =================================================================== --- head/contrib/libarchive/libarchive/archive_write.c (revision 356365) +++ head/contrib/libarchive/libarchive/archive_write.c (revision 356366) @@ -1,782 +1,799 @@ /*- * Copyright (c) 2003-2010 Tim Kientzle * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "archive_platform.h" __FBSDID("$FreeBSD$"); /* * This file contains the "essential" portions of the write API, that * is, stuff that will essentially always be used by any client that * actually needs to write an archive. Optional pieces have been, as * far as possible, separated out into separate files to reduce * needlessly bloating statically-linked clients. */ #ifdef HAVE_SYS_WAIT_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_LIMITS_H #include #endif #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #include "archive.h" #include "archive_entry.h" #include "archive_private.h" #include "archive_write_private.h" static struct archive_vtable *archive_write_vtable(void); static int _archive_filter_code(struct archive *, int); static const char *_archive_filter_name(struct archive *, int); static int64_t _archive_filter_bytes(struct archive *, int); static int _archive_write_filter_count(struct archive *); static int _archive_write_close(struct archive *); static int _archive_write_free(struct archive *); static int _archive_write_header(struct archive *, struct archive_entry *); static int _archive_write_finish_entry(struct archive *); static ssize_t _archive_write_data(struct archive *, const void *, size_t); struct archive_none { size_t buffer_size; size_t avail; char *buffer; char *next; }; static struct archive_vtable * archive_write_vtable(void) { static struct archive_vtable av; static int inited = 0; if (!inited) { av.archive_close = _archive_write_close; av.archive_filter_bytes = _archive_filter_bytes; av.archive_filter_code = _archive_filter_code; av.archive_filter_name = _archive_filter_name; av.archive_filter_count = _archive_write_filter_count; av.archive_free = _archive_write_free; av.archive_write_header = _archive_write_header; av.archive_write_finish_entry = _archive_write_finish_entry; av.archive_write_data = _archive_write_data; inited = 1; } return (&av); } /* * Allocate, initialize and return an archive object. */ struct archive * archive_write_new(void) { struct archive_write *a; unsigned char *nulls; a = (struct archive_write *)calloc(1, sizeof(*a)); if (a == NULL) return (NULL); a->archive.magic = ARCHIVE_WRITE_MAGIC; a->archive.state = ARCHIVE_STATE_NEW; a->archive.vtable = archive_write_vtable(); /* * The value 10240 here matches the traditional tar default, * but is otherwise arbitrary. * TODO: Set the default block size from the format selected. */ a->bytes_per_block = 10240; a->bytes_in_last_block = -1; /* Default */ /* Initialize a block of nulls for padding purposes. */ a->null_length = 1024; nulls = (unsigned char *)calloc(1, a->null_length); if (nulls == NULL) { free(a); return (NULL); } a->nulls = nulls; return (&a->archive); } /* * Set the block size. Returns 0 if successful. */ int archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block) { struct archive_write *a = (struct archive_write *)_a; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block"); a->bytes_per_block = bytes_per_block; return (ARCHIVE_OK); } /* * Get the current block size. -1 if it has never been set. */ int archive_write_get_bytes_per_block(struct archive *_a) { struct archive_write *a = (struct archive_write *)_a; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block"); return (a->bytes_per_block); } /* * Set the size for the last block. * Returns 0 if successful. */ int archive_write_set_bytes_in_last_block(struct archive *_a, int bytes) { struct archive_write *a = (struct archive_write *)_a; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block"); a->bytes_in_last_block = bytes; return (ARCHIVE_OK); } /* * Return the value set above. -1 indicates it has not been set. */ int archive_write_get_bytes_in_last_block(struct archive *_a) { struct archive_write *a = (struct archive_write *)_a; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block"); return (a->bytes_in_last_block); } /* * dev/ino of a file to be rejected. Used to prevent adding * an archive to itself recursively. */ int archive_write_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i) { struct archive_write *a = (struct archive_write *)_a; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_ANY, "archive_write_set_skip_file"); a->skip_file_set = 1; a->skip_file_dev = d; a->skip_file_ino = i; return (ARCHIVE_OK); } /* * Allocate and return the next filter structure. */ struct archive_write_filter * __archive_write_allocate_filter(struct archive *_a) { struct archive_write *a = (struct archive_write *)_a; struct archive_write_filter *f; f = calloc(1, sizeof(*f)); f->archive = _a; f->state = ARCHIVE_WRITE_FILTER_STATE_NEW; if (a->filter_first == NULL) a->filter_first = f; else a->filter_last->next_filter = f; a->filter_last = f; return f; } /* * Write data to a particular filter. */ int __archive_write_filter(struct archive_write_filter *f, const void *buff, size_t length) { int r; /* Never write to non-open filters */ if (f->state != ARCHIVE_WRITE_FILTER_STATE_OPEN) return(ARCHIVE_FATAL); if (length == 0) return(ARCHIVE_OK); if (f->write == NULL) /* If unset, a fatal error has already occurred, so this filter * didn't open. We cannot write anything. */ return(ARCHIVE_FATAL); r = (f->write)(f, buff, length); f->bytes_written += length; return (r); } /* * Recursive function for opening the filter chain * Last filter is opened first */ static int __archive_write_open_filter(struct archive_write_filter *f) { int ret; ret = ARCHIVE_OK; if (f->next_filter != NULL) ret = __archive_write_open_filter(f->next_filter); if (ret != ARCHIVE_OK) return (ret); if (f->state != ARCHIVE_WRITE_FILTER_STATE_NEW) return (ARCHIVE_FATAL); if (f->open == NULL) { f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; return (ARCHIVE_OK); } ret = (f->open)(f); if (ret == ARCHIVE_OK) f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; else f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; return (ret); } /* * Open all filters */ static int __archive_write_filters_open(struct archive_write *a) { return (__archive_write_open_filter(a->filter_first)); } /* * Close all filtes */ static int __archive_write_filters_close(struct archive_write *a) { struct archive_write_filter *f; int ret, ret1; ret = ARCHIVE_OK; for (f = a->filter_first; f != NULL; f = f->next_filter) { /* Do not close filters that are not open */ if (f->state == ARCHIVE_WRITE_FILTER_STATE_OPEN) { if (f->close != NULL) { ret1 = (f->close)(f); if (ret1 < ret) ret = ret1; if (ret1 == ARCHIVE_OK) { f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; } else { f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; } } else f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; } } return (ret); } int __archive_write_output(struct archive_write *a, const void *buff, size_t length) { return (__archive_write_filter(a->filter_first, buff, length)); } int __archive_write_nulls(struct archive_write *a, size_t length) { if (length == 0) return (ARCHIVE_OK); while (length > 0) { size_t to_write = length < a->null_length ? length : a->null_length; int r = __archive_write_output(a, a->nulls, to_write); if (r < ARCHIVE_OK) return (r); length -= to_write; } return (ARCHIVE_OK); } static int archive_write_client_open(struct archive_write_filter *f) { struct archive_write *a = (struct archive_write *)f->archive; struct archive_none *state; void *buffer; size_t buffer_size; f->bytes_per_block = archive_write_get_bytes_per_block(f->archive); f->bytes_in_last_block = archive_write_get_bytes_in_last_block(f->archive); buffer_size = f->bytes_per_block; state = (struct archive_none *)calloc(1, sizeof(*state)); buffer = (char *)malloc(buffer_size); if (state == NULL || buffer == NULL) { free(state); free(buffer); archive_set_error(f->archive, ENOMEM, "Can't allocate data for output buffering"); return (ARCHIVE_FATAL); } state->buffer_size = buffer_size; state->buffer = buffer; state->next = state->buffer; state->avail = state->buffer_size; f->data = state; if (a->client_opener == NULL) return (ARCHIVE_OK); return (a->client_opener(f->archive, a->client_data)); } static int archive_write_client_write(struct archive_write_filter *f, const void *_buff, size_t length) { struct archive_write *a = (struct archive_write *)f->archive; struct archive_none *state = (struct archive_none *)f->data; const char *buff = (const char *)_buff; ssize_t remaining, to_copy; ssize_t bytes_written; remaining = length; /* * If there is no buffer for blocking, just pass the data * straight through to the client write callback. In * particular, this supports "no write delay" operation for * special applications. Just set the block size to zero. */ if (state->buffer_size == 0) { while (remaining > 0) { bytes_written = (a->client_writer)(&a->archive, a->client_data, buff, remaining); if (bytes_written <= 0) return (ARCHIVE_FATAL); remaining -= bytes_written; buff += bytes_written; } return (ARCHIVE_OK); } /* If the copy buffer isn't empty, try to fill it. */ if (state->avail < state->buffer_size) { /* If buffer is not empty... */ /* ... copy data into buffer ... */ to_copy = ((size_t)remaining > state->avail) ? state->avail : (size_t)remaining; memcpy(state->next, buff, to_copy); state->next += to_copy; state->avail -= to_copy; buff += to_copy; remaining -= to_copy; /* ... if it's full, write it out. */ if (state->avail == 0) { char *p = state->buffer; size_t to_write = state->buffer_size; while (to_write > 0) { bytes_written = (a->client_writer)(&a->archive, a->client_data, p, to_write); if (bytes_written <= 0) return (ARCHIVE_FATAL); if ((size_t)bytes_written > to_write) { archive_set_error(&(a->archive), -1, "write overrun"); return (ARCHIVE_FATAL); } p += bytes_written; to_write -= bytes_written; } state->next = state->buffer; state->avail = state->buffer_size; } } while ((size_t)remaining >= state->buffer_size) { /* Write out full blocks directly to client. */ bytes_written = (a->client_writer)(&a->archive, a->client_data, buff, state->buffer_size); if (bytes_written <= 0) return (ARCHIVE_FATAL); buff += bytes_written; remaining -= bytes_written; } if (remaining > 0) { /* Copy last bit into copy buffer. */ memcpy(state->next, buff, remaining); state->next += remaining; state->avail -= remaining; } return (ARCHIVE_OK); } static int +archive_write_client_free(struct archive_write_filter *f) +{ + struct archive_write *a = (struct archive_write *)f->archive; + struct archive_none *state = (struct archive_none *)f->data; + + if (state != NULL) { + free(state->buffer); + free(state); + state = NULL; + } + + a->client_data = NULL; + /* Clear passphrase. */ + if (a->passphrase != NULL) { + memset(a->passphrase, 0, strlen(a->passphrase)); + free(a->passphrase); + a->passphrase = NULL; + } + + return (ARCHIVE_OK); +} + + +static int archive_write_client_close(struct archive_write_filter *f) { struct archive_write *a = (struct archive_write *)f->archive; struct archive_none *state = (struct archive_none *)f->data; ssize_t block_length; ssize_t target_block_length; ssize_t bytes_written; int ret = ARCHIVE_OK; /* If there's pending data, pad and write the last block */ if (state->next != state->buffer) { block_length = state->buffer_size - state->avail; /* Tricky calculation to determine size of last block */ if (a->bytes_in_last_block <= 0) /* Default or Zero: pad to full block */ target_block_length = a->bytes_per_block; else /* Round to next multiple of bytes_in_last_block. */ target_block_length = a->bytes_in_last_block * ( (block_length + a->bytes_in_last_block - 1) / a->bytes_in_last_block); if (target_block_length > a->bytes_per_block) target_block_length = a->bytes_per_block; if (block_length < target_block_length) { memset(state->next, 0, target_block_length - block_length); block_length = target_block_length; } bytes_written = (a->client_writer)(&a->archive, a->client_data, state->buffer, block_length); ret = bytes_written <= 0 ? ARCHIVE_FATAL : ARCHIVE_OK; } if (a->client_closer) (*a->client_closer)(&a->archive, a->client_data); - free(state->buffer); - free(state); + /* Clear the close handler myself not to be called again. */ f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; - a->client_data = NULL; - /* Clear passphrase. */ - if (a->passphrase != NULL) { - memset(a->passphrase, 0, strlen(a->passphrase)); - free(a->passphrase); - a->passphrase = NULL; - } return (ret); } /* * Open the archive using the current settings. */ int archive_write_open(struct archive *_a, void *client_data, archive_open_callback *opener, archive_write_callback *writer, archive_close_callback *closer) { struct archive_write *a = (struct archive_write *)_a; struct archive_write_filter *client_filter; int ret, r1; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW, "archive_write_open"); archive_clear_error(&a->archive); a->client_writer = writer; a->client_opener = opener; a->client_closer = closer; a->client_data = client_data; client_filter = __archive_write_allocate_filter(_a); client_filter->open = archive_write_client_open; client_filter->write = archive_write_client_write; client_filter->close = archive_write_client_close; + client_filter->free = archive_write_client_free; ret = __archive_write_filters_open(a); if (ret < ARCHIVE_WARN) { r1 = __archive_write_filters_close(a); __archive_write_filters_free(_a); return (r1 < ret ? r1 : ret); } a->archive.state = ARCHIVE_STATE_HEADER; if (a->format_init) ret = (a->format_init)(a); return (ret); } /* * Close out the archive. */ static int _archive_write_close(struct archive *_a) { struct archive_write *a = (struct archive_write *)_a; int r = ARCHIVE_OK, r1 = ARCHIVE_OK; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_close"); if (a->archive.state == ARCHIVE_STATE_NEW || a->archive.state == ARCHIVE_STATE_CLOSED) return (ARCHIVE_OK); /* Okay to close() when not open. */ archive_clear_error(&a->archive); /* Finish the last entry if a finish callback is specified */ if (a->archive.state == ARCHIVE_STATE_DATA && a->format_finish_entry != NULL) r = ((a->format_finish_entry)(a)); /* Finish off the archive. */ /* TODO: have format closers invoke compression close. */ if (a->format_close != NULL) { r1 = (a->format_close)(a); if (r1 < r) r = r1; } /* Finish the compression and close the stream. */ r1 = __archive_write_filters_close(a); if (r1 < r) r = r1; if (a->archive.state != ARCHIVE_STATE_FATAL) a->archive.state = ARCHIVE_STATE_CLOSED; return (r); } static int _archive_write_filter_count(struct archive *_a) { struct archive_write *a = (struct archive_write *)_a; struct archive_write_filter *p = a->filter_first; int count = 0; while(p) { count++; p = p->next_filter; } return count; } void __archive_write_filters_free(struct archive *_a) { struct archive_write *a = (struct archive_write *)_a; int r = ARCHIVE_OK, r1; while (a->filter_first != NULL) { struct archive_write_filter *next = a->filter_first->next_filter; if (a->filter_first->free != NULL) { r1 = (*a->filter_first->free)(a->filter_first); if (r > r1) r = r1; } free(a->filter_first); a->filter_first = next; } a->filter_last = NULL; } /* * Destroy the archive structure. * * Be careful: user might just call write_new and then write_free. * Don't assume we actually wrote anything or performed any non-trivial * initialization. */ static int _archive_write_free(struct archive *_a) { struct archive_write *a = (struct archive_write *)_a; int r = ARCHIVE_OK, r1; if (_a == NULL) return (ARCHIVE_OK); /* It is okay to call free() in state FATAL. */ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free"); if (a->archive.state != ARCHIVE_STATE_FATAL) r = archive_write_close(&a->archive); /* Release format resources. */ if (a->format_free != NULL) { r1 = (a->format_free)(a); if (r1 < r) r = r1; } __archive_write_filters_free(_a); /* Release various dynamic buffers. */ free((void *)(uintptr_t)(const void *)a->nulls); archive_string_free(&a->archive.error_string); if (a->passphrase != NULL) { /* A passphrase should be cleaned. */ memset(a->passphrase, 0, strlen(a->passphrase)); free(a->passphrase); } a->archive.magic = 0; __archive_clean(&a->archive); free(a); return (r); } /* * Write the appropriate header. */ static int _archive_write_header(struct archive *_a, struct archive_entry *entry) { struct archive_write *a = (struct archive_write *)_a; int ret, r2; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header"); archive_clear_error(&a->archive); if (a->format_write_header == NULL) { archive_set_error(&(a->archive), -1, "Format must be set before you can write to an archive."); a->archive.state = ARCHIVE_STATE_FATAL; return (ARCHIVE_FATAL); } /* In particular, "retry" and "fatal" get returned immediately. */ ret = archive_write_finish_entry(&a->archive); if (ret == ARCHIVE_FATAL) { a->archive.state = ARCHIVE_STATE_FATAL; return (ARCHIVE_FATAL); } if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN) return (ret); if (a->skip_file_set && archive_entry_dev_is_set(entry) && archive_entry_ino_is_set(entry) && archive_entry_dev(entry) == (dev_t)a->skip_file_dev && archive_entry_ino64(entry) == a->skip_file_ino) { archive_set_error(&a->archive, 0, "Can't add archive to itself"); return (ARCHIVE_FAILED); } /* Format and write header. */ r2 = ((a->format_write_header)(a, entry)); if (r2 == ARCHIVE_FAILED) { return (ARCHIVE_FAILED); } if (r2 == ARCHIVE_FATAL) { a->archive.state = ARCHIVE_STATE_FATAL; return (ARCHIVE_FATAL); } if (r2 < ret) ret = r2; a->archive.state = ARCHIVE_STATE_DATA; return (ret); } static int _archive_write_finish_entry(struct archive *_a) { struct archive_write *a = (struct archive_write *)_a; int ret = ARCHIVE_OK; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, "archive_write_finish_entry"); if (a->archive.state & ARCHIVE_STATE_DATA && a->format_finish_entry != NULL) ret = (a->format_finish_entry)(a); a->archive.state = ARCHIVE_STATE_HEADER; return (ret); } /* * Note that the compressor is responsible for blocking. */ static ssize_t _archive_write_data(struct archive *_a, const void *buff, size_t s) { struct archive_write *a = (struct archive_write *)_a; const size_t max_write = INT_MAX; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_DATA, "archive_write_data"); /* In particular, this catches attempts to pass negative values. */ if (s > max_write) s = max_write; archive_clear_error(&a->archive); return ((a->format_write_data)(a, buff, s)); } static struct archive_write_filter * filter_lookup(struct archive *_a, int n) { struct archive_write *a = (struct archive_write *)_a; struct archive_write_filter *f = a->filter_first; if (n == -1) return a->filter_last; if (n < 0) return NULL; while (n > 0 && f != NULL) { f = f->next_filter; --n; } return f; } static int _archive_filter_code(struct archive *_a, int n) { struct archive_write_filter *f = filter_lookup(_a, n); return f == NULL ? -1 : f->code; } static const char * _archive_filter_name(struct archive *_a, int n) { struct archive_write_filter *f = filter_lookup(_a, n); return f != NULL ? f->name : NULL; } static int64_t _archive_filter_bytes(struct archive *_a, int n) { struct archive_write_filter *f = filter_lookup(_a, n); return f == NULL ? -1 : f->bytes_written; } Index: head/contrib/libarchive =================================================================== --- head/contrib/libarchive (revision 356365) +++ head/contrib/libarchive (revision 356366) Property changes on: head/contrib/libarchive ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /vendor/libarchive/dist:r356365