archive_hmac.c revision 358090
1168404Spjd/*- 2168404Spjd* Copyright (c) 2014 Michihiro NAKAJIMA 3168404Spjd* All rights reserved. 4168404Spjd* 5168404Spjd* Redistribution and use in source and binary forms, with or without 6168404Spjd* modification, are permitted provided that the following conditions 7168404Spjd* are met: 8168404Spjd* 1. Redistributions of source code must retain the above copyright 9168404Spjd* notice, this list of conditions and the following disclaimer. 10168404Spjd* 2. Redistributions in binary form must reproduce the above copyright 11168404Spjd* notice, this list of conditions and the following disclaimer in the 12168404Spjd* documentation and/or other materials provided with the distribution. 13168404Spjd* 14168404Spjd* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15168404Spjd* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16168404Spjd* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17168404Spjd* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18168404Spjd* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19168404Spjd* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20168404Spjd* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21168404Spjd* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22219089Spjd* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23277826Sdelphij* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24286766Smav*/ 25260835Sdelphij 26286764Smav#include "archive_platform.h" 27168404Spjd 28168404Spjd#ifdef HAVE_STRING_H 29168404Spjd#include <string.h> 30168404Spjd#endif 31168404Spjd#include "archive.h" 32168404Spjd#include "archive_hmac_private.h" 33168404Spjd 34168404Spjd/* 35168404Spjd * On systems that do not support any recognized crypto libraries, 36168404Spjd * the archive_hmac.c file is expected to define no usable symbols. 37168404Spjd * 38168404Spjd * But some compilers and linkers choke on empty object files, so 39168404Spjd * define a public symbol that will always exist. This could 40168404Spjd * be removed someday if this file gains another always-present 41168404Spjd * symbol definition. 42168404Spjd */ 43168404Spjdint __libarchive_hmac_build_hack(void) { 44168404Spjd return 0; 45168404Spjd} 46168404Spjd 47168404Spjd 48168404Spjd#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto 49168404Spjd 50168404Spjdstatic int 51185029Spjd__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 52185029Spjd{ 53168404Spjd CCHmacInit(ctx, kCCHmacAlgSHA1, key, key_len); 54168404Spjd return 0; 55168404Spjd} 56168404Spjd 57185029Spjdstatic void 58168404Spjd__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 59168404Spjd size_t data_len) 60168404Spjd{ 61168404Spjd CCHmacUpdate(ctx, data, data_len); 62251631Sdelphij} 63168404Spjd 64168404Spjdstatic void 65168404Spjd__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 66251631Sdelphij{ 67168404Spjd CCHmacFinal(ctx, out); 68168404Spjd *out_len = 20; 69168404Spjd} 70168404Spjd 71168404Spjdstatic void 72168404Spjd__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 73168404Spjd{ 74168404Spjd memset(ctx, 0, sizeof(*ctx)); 75168404Spjd} 76168404Spjd 77168404Spjd#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) 78168404Spjd 79185029Spjd#ifndef BCRYPT_HASH_REUSABLE_FLAG 80168404Spjd# define BCRYPT_HASH_REUSABLE_FLAG 0x00000020 81251631Sdelphij#endif 82168404Spjd 83168404Spjdstatic int 84168404Spjd__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 85286774Smav{ 86286774Smav#ifdef __GNUC__ 87286774Smav#pragma GCC diagnostic ignored "-Wcast-qual" 88168404Spjd#endif 89168404Spjd BCRYPT_ALG_HANDLE hAlg; 90168404Spjd BCRYPT_HASH_HANDLE hHash; 91168404Spjd DWORD hash_len; 92168404Spjd PBYTE hash; 93168404Spjd ULONG result; 94168404Spjd NTSTATUS status; 95168404Spjd 96168404Spjd ctx->hAlg = NULL; 97168404Spjd status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, 98168404Spjd MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); 99168404Spjd if (!BCRYPT_SUCCESS(status)) 100168404Spjd return -1; 101168404Spjd status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PUCHAR)&hash_len, 102168404Spjd sizeof(hash_len), &result, 0); 103168404Spjd if (!BCRYPT_SUCCESS(status)) { 104168404Spjd BCryptCloseAlgorithmProvider(hAlg, 0); 105168404Spjd return -1; 106168404Spjd } 107168404Spjd hash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hash_len); 108268858Sdelphij if (hash == NULL) { 109168404Spjd BCryptCloseAlgorithmProvider(hAlg, 0); 110168404Spjd return -1; 111168404Spjd } 112168404Spjd status = BCryptCreateHash(hAlg, &hHash, NULL, 0, 113185029Spjd (PUCHAR)key, (ULONG)key_len, BCRYPT_HASH_REUSABLE_FLAG); 114286570Smav if (!BCRYPT_SUCCESS(status)) { 115185029Spjd BCryptCloseAlgorithmProvider(hAlg, 0); 116185029Spjd HeapFree(GetProcessHeap(), 0, hash); 117185029Spjd return -1; 118185029Spjd } 119185029Spjd 120185029Spjd ctx->hAlg = hAlg; 121168404Spjd ctx->hHash = hHash; 122168404Spjd ctx->hash_len = hash_len; 123168404Spjd ctx->hash = hash; 124168404Spjd 125251478Sdelphij return 0; 126168404Spjd} 127168404Spjd 128168404Spjdstatic void 129185029Spjd__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 130219089Spjd size_t data_len) 131258632Savg{ 132286763Smav BCryptHashData(ctx->hHash, (PUCHAR)(uintptr_t)data, (ULONG)data_len, 0); 133168404Spjd} 134168404Spjd 135297633Straszstatic void 136168404Spjd__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 137168404Spjd{ 138168404Spjd BCryptFinishHash(ctx->hHash, ctx->hash, ctx->hash_len, 0); 139248572Ssmh if (ctx->hash_len == *out_len) 140219089Spjd memcpy(out, ctx->hash, *out_len); 141168404Spjd} 142168404Spjd 143272483Ssmhstatic void 144191902Skmacy__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 145240133Smm{ 146240133Smm if (ctx->hAlg != NULL) { 147240133Smm BCryptCloseAlgorithmProvider(ctx->hAlg, 0); 148240133Smm HeapFree(GetProcessHeap(), 0, ctx->hash); 149240133Smm ctx->hAlg = NULL; 150240133Smm } 151240133Smm} 152240133Smm 153286763Smav#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H) 154286763Smav 155286763Smavstatic int 156286763Smav__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 157168404Spjd{ 158286763Smav const mbedtls_md_info_t *info; 159286763Smav int ret; 160286763Smav 161286763Smav mbedtls_md_init(ctx); 162286625Smav info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); 163168404Spjd if (info == NULL) { 164258632Savg mbedtls_md_free(ctx); 165286763Smav return (-1); 166286763Smav } 167286763Smav ret = mbedtls_md_setup(ctx, info, 1); 168286763Smav if (ret != 0) { 169286763Smav mbedtls_md_free(ctx); 170258632Savg return (-1); 171286763Smav } 172258632Savg ret = mbedtls_md_hmac_starts(ctx, key, key_len); 173286763Smav if (ret != 0) { 174286763Smav mbedtls_md_free(ctx); 175286763Smav return (-1); 176286763Smav } 177286763Smav return 0; 178286763Smav} 179286763Smav 180168404Spjdstatic void 181168404Spjd__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 182168404Spjd size_t data_len) 183286763Smav{ 184286763Smav mbedtls_md_hmac_update(ctx, data, data_len); 185286763Smav} 186208373Smm 187208373Smmstatic void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 188208373Smm{ 189208373Smm (void)out_len; /* UNUSED */ 190286625Smav 191208373Smm mbedtls_md_hmac_finish(ctx, out); 192168404Spjd} 193286625Smav 194286625Smavstatic void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 195286625Smav{ 196286625Smav mbedtls_md_free(ctx); 197286625Smav memset(ctx, 0, sizeof(*ctx)); 198286625Smav} 199286625Smav 200286625Smav#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H) 201286625Smav 202286625Smavstatic int 203286625Smav__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 204286625Smav{ 205168404Spjd hmac_sha1_set_key(ctx, key_len, key); 206168404Spjd return 0; 207168404Spjd} 208168404Spjd 209168404Spjdstatic void 210258632Savg__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 211258632Savg size_t data_len) 212258632Savg{ 213258632Savg hmac_sha1_update(ctx, data_len, data); 214258632Savg} 215208373Smm 216287702Sdelphijstatic void 217168404Spjd__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 218168404Spjd{ 219185029Spjd hmac_sha1_digest(ctx, (unsigned)*out_len, out); 220185029Spjd} 221185029Spjd 222185029Spjdstatic void 223286762Smav__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 224286762Smav{ 225286762Smav memset(ctx, 0, sizeof(*ctx)); 226185029Spjd} 227185029Spjd 228185029Spjd#elif defined(HAVE_LIBCRYPTO) 229275780Sdelphij 230208373Smmstatic int 231208373Smm__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 232208373Smm{ 233242845Sdelphij *ctx = HMAC_CTX_new(); 234269230Sdelphij if (*ctx == NULL) 235272483Ssmh return -1; 236185029Spjd HMAC_Init_ex(*ctx, key, key_len, EVP_sha1(), NULL); 237270759Ssmh return 0; 238275748Sdelphij} 239270759Ssmh 240270759Ssmhstatic void 241270759Ssmh__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 242270759Ssmh size_t data_len) 243270759Ssmh{ 244270759Ssmh HMAC_Update(*ctx, data, data_len); 245272483Ssmh} 246270759Ssmh 247270759Ssmhstatic void 248270759Ssmh__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 249270759Ssmh{ 250185029Spjd unsigned int len = (unsigned int)*out_len; 251275780Sdelphij 252273026Sdelphij HMAC_Final(*ctx, out, &len); 253168473Spjd *out_len = len; 254217367Smdf} 255168473Spjd 256217367Smdfstatic void 257168473Spjd__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 258269230Sdelphij{ 259269230Sdelphij HMAC_CTX_free(*ctx); 260269230Sdelphij *ctx = NULL; 261273026Sdelphij} 262273026Sdelphij 263273026Sdelphij#else 264273026Sdelphij 265270759Ssmh/* Stub */ 266270759Ssmhstatic int 267270759Ssmh__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 268270759Ssmh{ 269270759Ssmh (void)ctx;/* UNUSED */ 270270759Ssmh (void)key;/* UNUSED */ 271270759Ssmh (void)key_len;/* UNUSED */ 272270759Ssmh return -1; 273168404Spjd} 274270759Ssmh 275270759Ssmhstatic void 276270759Ssmh__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 277270759Ssmh size_t data_len) 278270759Ssmh{ 279270759Ssmh (void)ctx;/* UNUSED */ 280270759Ssmh (void)data;/* UNUSED */ 281270759Ssmh (void)data_len;/* UNUSED */ 282270759Ssmh} 283270759Ssmh 284270759Ssmhstatic void 285272483Ssmh__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 286270759Ssmh{ 287272483Ssmh (void)ctx;/* UNUSED */ 288270759Ssmh (void)out;/* UNUSED */ 289270759Ssmh (void)out_len;/* UNUSED */ 290270759Ssmh} 291270759Ssmh 292270759Ssmhstatic void 293270759Ssmh__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 294275748Sdelphij{ 295275748Sdelphij (void)ctx;/* UNUSED */ 296275748Sdelphij} 297275748Sdelphij 298275748Sdelphij#endif 299275748Sdelphij 300275748Sdelphijconst struct archive_hmac __archive_hmac = { 301275748Sdelphij &__hmac_sha1_init, 302275748Sdelphij &__hmac_sha1_update, 303272483Ssmh &__hmac_sha1_final, 304270759Ssmh &__hmac_sha1_cleanup, 305168404Spjd}; 306185029Spjd