Path: blob/master/Utilities/cmlibarchive/libarchive/archive_hmac.c
3153 views
/*-1* Copyright (c) 2014 Michihiro NAKAJIMA2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR14* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES15* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.16* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,17* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT18* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,19* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY20* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT21* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF22* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.23*/2425#include "archive_platform.h"2627#ifdef HAVE_STRING_H28#include <string.h>29#endif30#include "archive.h"31#include "archive_hmac_private.h"3233/*34* On systems that do not support any recognized crypto libraries,35* the archive_hmac.c file is expected to define no usable symbols.36*37* But some compilers and linkers choke on empty object files, so38* define a public symbol that will always exist. This could39* be removed someday if this file gains another always-present40* symbol definition.41*/42int __libarchive_hmac_build_hack(void) {43return 0;44}454647#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto4849static int50__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)51{52CCHmacInit(ctx, kCCHmacAlgSHA1, key, key_len);53return 0;54}5556static void57__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,58size_t data_len)59{60CCHmacUpdate(ctx, data, data_len);61}6263static void64__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)65{66CCHmacFinal(ctx, out);67*out_len = 20;68}6970static void71__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)72{73memset(ctx, 0, sizeof(*ctx));74}7576#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA7778#ifndef BCRYPT_HASH_REUSABLE_FLAG79# define BCRYPT_HASH_REUSABLE_FLAG 0x0000002080#endif8182static int83__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)84{85#ifdef __GNUC__86#pragma GCC diagnostic ignored "-Wcast-qual"87#endif88BCRYPT_ALG_HANDLE hAlg;89BCRYPT_HASH_HANDLE hHash;90DWORD hash_len;91PBYTE hash;92ULONG result;93NTSTATUS status;9495ctx->hAlg = NULL;96status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM,97MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);98if (!BCRYPT_SUCCESS(status))99return -1;100status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PUCHAR)&hash_len,101sizeof(hash_len), &result, 0);102if (!BCRYPT_SUCCESS(status)) {103BCryptCloseAlgorithmProvider(hAlg, 0);104return -1;105}106hash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hash_len);107if (hash == NULL) {108BCryptCloseAlgorithmProvider(hAlg, 0);109return -1;110}111status = BCryptCreateHash(hAlg, &hHash, NULL, 0,112(PUCHAR)key, (ULONG)key_len, BCRYPT_HASH_REUSABLE_FLAG);113if (!BCRYPT_SUCCESS(status)) {114BCryptCloseAlgorithmProvider(hAlg, 0);115HeapFree(GetProcessHeap(), 0, hash);116return -1;117}118119ctx->hAlg = hAlg;120ctx->hHash = hHash;121ctx->hash_len = hash_len;122ctx->hash = hash;123124return 0;125}126127static void128__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,129size_t data_len)130{131BCryptHashData(ctx->hHash, (PUCHAR)(uintptr_t)data, (ULONG)data_len, 0);132}133134static void135__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)136{137BCryptFinishHash(ctx->hHash, ctx->hash, ctx->hash_len, 0);138if (ctx->hash_len == *out_len)139memcpy(out, ctx->hash, *out_len);140}141142static void143__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)144{145if (ctx->hAlg != NULL) {146BCryptCloseAlgorithmProvider(ctx->hAlg, 0);147HeapFree(GetProcessHeap(), 0, ctx->hash);148ctx->hAlg = NULL;149}150}151152#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H)153154static int155__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)156{157const mbedtls_md_info_t *info;158int ret;159160mbedtls_md_init(ctx);161info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);162if (info == NULL) {163mbedtls_md_free(ctx);164return (-1);165}166ret = mbedtls_md_setup(ctx, info, 1);167if (ret != 0) {168mbedtls_md_free(ctx);169return (-1);170}171ret = mbedtls_md_hmac_starts(ctx, key, key_len);172if (ret != 0) {173mbedtls_md_free(ctx);174return (-1);175}176return 0;177}178179static void180__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,181size_t data_len)182{183mbedtls_md_hmac_update(ctx, data, data_len);184}185186static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)187{188(void)out_len; /* UNUSED */189190mbedtls_md_hmac_finish(ctx, out);191}192193static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)194{195mbedtls_md_free(ctx);196memset(ctx, 0, sizeof(*ctx));197}198199#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)200201static int202__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)203{204hmac_sha1_set_key(ctx, key_len, key);205return 0;206}207208static void209__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,210size_t data_len)211{212hmac_sha1_update(ctx, data_len, data);213}214215static void216__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)217{218hmac_sha1_digest(ctx, (unsigned)*out_len, out);219}220221static void222__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)223{224memset(ctx, 0, sizeof(*ctx));225}226227#elif defined(HAVE_LIBCRYPTO)228229static int230__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)231{232#if OPENSSL_VERSION_NUMBER >= 0x30000000L233EVP_MAC *mac;234235char sha1[] = "SHA1";236OSSL_PARAM params[] = {237OSSL_PARAM_utf8_string("digest", sha1, sizeof(sha1) - 1),238OSSL_PARAM_END239};240241mac = EVP_MAC_fetch(NULL, "HMAC", NULL);242*ctx = EVP_MAC_CTX_new(mac);243EVP_MAC_free(mac);244if (*ctx == NULL)245return -1;246247EVP_MAC_init(*ctx, key, key_len, params);248#else249*ctx = HMAC_CTX_new();250if (*ctx == NULL)251return -1;252HMAC_Init_ex(*ctx, key, key_len, EVP_sha1(), NULL);253#endif254return 0;255}256257static void258__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,259size_t data_len)260{261#if OPENSSL_VERSION_NUMBER >= 0x30000000L262EVP_MAC_update(*ctx, data, data_len);263#else264HMAC_Update(*ctx, data, data_len);265#endif266}267268static void269__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)270{271#if OPENSSL_VERSION_NUMBER >= 0x30000000L272size_t len = *out_len;273#else274unsigned int len = (unsigned int)*out_len;275#endif276277#if OPENSSL_VERSION_NUMBER >= 0x30000000L278EVP_MAC_final(*ctx, out, &len, *out_len);279#else280HMAC_Final(*ctx, out, &len);281#endif282*out_len = len;283}284285static void286__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)287{288#if OPENSSL_VERSION_NUMBER >= 0x30000000L289EVP_MAC_CTX_free(*ctx);290#else291HMAC_CTX_free(*ctx);292#endif293*ctx = NULL;294}295296#else297298/* Stub */299static int300__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)301{302(void)ctx;/* UNUSED */303(void)key;/* UNUSED */304(void)key_len;/* UNUSED */305return -1;306}307308static void309__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,310size_t data_len)311{312(void)ctx;/* UNUSED */313(void)data;/* UNUSED */314(void)data_len;/* UNUSED */315}316317static void318__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)319{320(void)ctx;/* UNUSED */321(void)out;/* UNUSED */322(void)out_len;/* UNUSED */323}324325static void326__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)327{328(void)ctx;/* UNUSED */329}330331#endif332333const struct archive_hmac __archive_hmac = {334&__hmac_sha1_init,335&__hmac_sha1_update,336&__hmac_sha1_final,337&__hmac_sha1_cleanup,338};339340341