1299425Smm/*- 2299425Smm* Copyright (c) 2014 Michihiro NAKAJIMA 3299425Smm* All rights reserved. 4299425Smm* 5299425Smm* Redistribution and use in source and binary forms, with or without 6299425Smm* modification, are permitted provided that the following conditions 7299425Smm* are met: 8299425Smm* 1. Redistributions of source code must retain the above copyright 9299425Smm* notice, this list of conditions and the following disclaimer. 10299425Smm* 2. Redistributions in binary form must reproduce the above copyright 11299425Smm* notice, this list of conditions and the following disclaimer in the 12299425Smm* documentation and/or other materials provided with the distribution. 13299425Smm* 14299425Smm* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15299425Smm* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16299425Smm* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17299425Smm* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18299425Smm* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19299425Smm* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20299425Smm* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21299425Smm* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22299425Smm* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23299425Smm* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24299425Smm*/ 25299425Smm 26299425Smm#include "archive_platform.h" 27299425Smm 28299425Smm#ifdef HAVE_STRING_H 29299425Smm#include <string.h> 30299425Smm#endif 31299425Smm#include "archive.h" 32299425Smm#include "archive_hmac_private.h" 33299425Smm 34299425Smm/* 35299425Smm * On systems that do not support any recognized crypto libraries, 36299425Smm * the archive_hmac.c file is expected to define no usable symbols. 37299425Smm * 38299425Smm * But some compilers and linkers choke on empty object files, so 39299425Smm * define a public symbol that will always exist. This could 40299425Smm * be removed someday if this file gains another always-present 41299425Smm * symbol definition. 42299425Smm */ 43299425Smmint __libarchive_hmac_build_hack(void) { 44299425Smm return 0; 45299425Smm} 46299425Smm 47299425Smm 48299425Smm#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto 49299425Smm 50299425Smmstatic int 51299425Smm__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 52299425Smm{ 53299425Smm CCHmacInit(ctx, kCCHmacAlgSHA1, key, key_len); 54299425Smm return 0; 55299425Smm} 56299425Smm 57299425Smmstatic void 58299425Smm__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 59299425Smm size_t data_len) 60299425Smm{ 61299425Smm CCHmacUpdate(ctx, data, data_len); 62299425Smm} 63299425Smm 64299425Smmstatic void 65299425Smm__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 66299425Smm{ 67299425Smm CCHmacFinal(ctx, out); 68299425Smm *out_len = 20; 69299425Smm} 70299425Smm 71299425Smmstatic void 72299425Smm__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 73299425Smm{ 74299425Smm memset(ctx, 0, sizeof(*ctx)); 75299425Smm} 76299425Smm 77299425Smm#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) 78299425Smm 79315433Smm#ifndef BCRYPT_HASH_REUSABLE_FLAG 80315433Smm# define BCRYPT_HASH_REUSABLE_FLAG 0x00000020 81315433Smm#endif 82315433Smm 83299425Smmstatic int 84299425Smm__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 85299425Smm{ 86358090Smm#ifdef __GNUC__ 87348608Smm#pragma GCC diagnostic ignored "-Wcast-qual" 88358090Smm#endif 89299425Smm BCRYPT_ALG_HANDLE hAlg; 90299425Smm BCRYPT_HASH_HANDLE hHash; 91299425Smm DWORD hash_len; 92299425Smm PBYTE hash; 93299425Smm ULONG result; 94299425Smm NTSTATUS status; 95299425Smm 96299425Smm ctx->hAlg = NULL; 97299425Smm status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, 98299425Smm MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); 99299425Smm if (!BCRYPT_SUCCESS(status)) 100299425Smm return -1; 101299425Smm status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PUCHAR)&hash_len, 102299425Smm sizeof(hash_len), &result, 0); 103299425Smm if (!BCRYPT_SUCCESS(status)) { 104299425Smm BCryptCloseAlgorithmProvider(hAlg, 0); 105299425Smm return -1; 106299425Smm } 107299425Smm hash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hash_len); 108299425Smm if (hash == NULL) { 109299425Smm BCryptCloseAlgorithmProvider(hAlg, 0); 110299425Smm return -1; 111299425Smm } 112299425Smm status = BCryptCreateHash(hAlg, &hHash, NULL, 0, 113299425Smm (PUCHAR)key, (ULONG)key_len, BCRYPT_HASH_REUSABLE_FLAG); 114299425Smm if (!BCRYPT_SUCCESS(status)) { 115299425Smm BCryptCloseAlgorithmProvider(hAlg, 0); 116299425Smm HeapFree(GetProcessHeap(), 0, hash); 117299425Smm return -1; 118299425Smm } 119299425Smm 120299425Smm ctx->hAlg = hAlg; 121299425Smm ctx->hHash = hHash; 122299425Smm ctx->hash_len = hash_len; 123299425Smm ctx->hash = hash; 124299425Smm 125299425Smm return 0; 126299425Smm} 127299425Smm 128299425Smmstatic void 129299425Smm__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 130299425Smm size_t data_len) 131299425Smm{ 132299425Smm BCryptHashData(ctx->hHash, (PUCHAR)(uintptr_t)data, (ULONG)data_len, 0); 133299425Smm} 134299425Smm 135299425Smmstatic void 136299425Smm__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 137299425Smm{ 138299425Smm BCryptFinishHash(ctx->hHash, ctx->hash, ctx->hash_len, 0); 139299425Smm if (ctx->hash_len == *out_len) 140299425Smm memcpy(out, ctx->hash, *out_len); 141299425Smm} 142299425Smm 143299425Smmstatic void 144299425Smm__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 145299425Smm{ 146299425Smm if (ctx->hAlg != NULL) { 147299425Smm BCryptCloseAlgorithmProvider(ctx->hAlg, 0); 148299425Smm HeapFree(GetProcessHeap(), 0, ctx->hash); 149299425Smm ctx->hAlg = NULL; 150299425Smm } 151299425Smm} 152299425Smm 153358090Smm#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H) 154358090Smm 155358090Smmstatic int 156358090Smm__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 157358090Smm{ 158358090Smm const mbedtls_md_info_t *info; 159358090Smm int ret; 160358090Smm 161358090Smm mbedtls_md_init(ctx); 162358090Smm info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); 163358090Smm if (info == NULL) { 164358090Smm mbedtls_md_free(ctx); 165358090Smm return (-1); 166358090Smm } 167358090Smm ret = mbedtls_md_setup(ctx, info, 1); 168358090Smm if (ret != 0) { 169358090Smm mbedtls_md_free(ctx); 170358090Smm return (-1); 171358090Smm } 172358090Smm ret = mbedtls_md_hmac_starts(ctx, key, key_len); 173358090Smm if (ret != 0) { 174358090Smm mbedtls_md_free(ctx); 175358090Smm return (-1); 176358090Smm } 177358090Smm return 0; 178358090Smm} 179358090Smm 180358090Smmstatic void 181358090Smm__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 182358090Smm size_t data_len) 183358090Smm{ 184358090Smm mbedtls_md_hmac_update(ctx, data, data_len); 185358090Smm} 186358090Smm 187358090Smmstatic void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 188358090Smm{ 189358090Smm (void)out_len; /* UNUSED */ 190358090Smm 191358090Smm mbedtls_md_hmac_finish(ctx, out); 192358090Smm} 193358090Smm 194358090Smmstatic void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 195358090Smm{ 196358090Smm mbedtls_md_free(ctx); 197358090Smm memset(ctx, 0, sizeof(*ctx)); 198358090Smm} 199358090Smm 200299425Smm#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H) 201299425Smm 202299425Smmstatic int 203299425Smm__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 204299425Smm{ 205299425Smm hmac_sha1_set_key(ctx, key_len, key); 206299425Smm return 0; 207299425Smm} 208299425Smm 209299425Smmstatic void 210299425Smm__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 211299425Smm size_t data_len) 212299425Smm{ 213299425Smm hmac_sha1_update(ctx, data_len, data); 214299425Smm} 215299425Smm 216299425Smmstatic void 217299425Smm__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 218299425Smm{ 219299425Smm hmac_sha1_digest(ctx, (unsigned)*out_len, out); 220299425Smm} 221299425Smm 222299425Smmstatic void 223299425Smm__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 224299425Smm{ 225299425Smm memset(ctx, 0, sizeof(*ctx)); 226299425Smm} 227299425Smm 228299425Smm#elif defined(HAVE_LIBCRYPTO) 229299425Smm 230299425Smmstatic int 231299425Smm__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 232299425Smm{ 233311042Smm *ctx = HMAC_CTX_new(); 234311042Smm if (*ctx == NULL) 235311042Smm return -1; 236311042Smm HMAC_Init_ex(*ctx, key, key_len, EVP_sha1(), NULL); 237299425Smm return 0; 238299425Smm} 239299425Smm 240299425Smmstatic void 241299425Smm__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 242299425Smm size_t data_len) 243299425Smm{ 244311042Smm HMAC_Update(*ctx, data, data_len); 245299425Smm} 246299425Smm 247299425Smmstatic void 248299425Smm__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 249299425Smm{ 250299425Smm unsigned int len = (unsigned int)*out_len; 251358090Smm 252311042Smm HMAC_Final(*ctx, out, &len); 253299425Smm *out_len = len; 254299425Smm} 255299425Smm 256299425Smmstatic void 257299425Smm__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 258299425Smm{ 259311042Smm HMAC_CTX_free(*ctx); 260311042Smm *ctx = NULL; 261299425Smm} 262299425Smm 263299425Smm#else 264299425Smm 265299425Smm/* Stub */ 266299425Smmstatic int 267299425Smm__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) 268299425Smm{ 269299425Smm (void)ctx;/* UNUSED */ 270299425Smm (void)key;/* UNUSED */ 271299425Smm (void)key_len;/* UNUSED */ 272299425Smm return -1; 273299425Smm} 274299425Smm 275299425Smmstatic void 276299425Smm__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, 277299425Smm size_t data_len) 278299425Smm{ 279299425Smm (void)ctx;/* UNUSED */ 280299425Smm (void)data;/* UNUSED */ 281299425Smm (void)data_len;/* UNUSED */ 282299425Smm} 283299425Smm 284299425Smmstatic void 285299425Smm__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) 286299425Smm{ 287299425Smm (void)ctx;/* UNUSED */ 288299425Smm (void)out;/* UNUSED */ 289299425Smm (void)out_len;/* UNUSED */ 290299425Smm} 291299425Smm 292299425Smmstatic void 293299425Smm__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) 294299425Smm{ 295299425Smm (void)ctx;/* UNUSED */ 296299425Smm} 297299425Smm 298299425Smm#endif 299299425Smm 300299425Smmconst struct archive_hmac __archive_hmac = { 301299425Smm &__hmac_sha1_init, 302299425Smm &__hmac_sha1_update, 303299425Smm &__hmac_sha1_final, 304299425Smm &__hmac_sha1_cleanup, 305299425Smm}; 306