diff options
author | librhash upstream <kwrobot@kitware.com> | 2019-12-14 16:52:11 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-03-02 21:31:07 (GMT) |
commit | 641cc0030c45731298bcb3c237b122256d2855ae (patch) | |
tree | 886ff9d8a6783d693f61d0a5ad44a60d035cd6f3 | |
parent | 7fcbd47e955d7e318f1f6dd96cc26d6737525c86 (diff) | |
download | CMake-641cc0030c45731298bcb3c237b122256d2855ae.zip CMake-641cc0030c45731298bcb3c237b122256d2855ae.tar.gz CMake-641cc0030c45731298bcb3c237b122256d2855ae.tar.bz2 |
librhash 2019-12-14 (75716b45)
Code extracted from:
https://github.com/rhash/rhash.git
at commit 75716b45c21416c98c0ab2e3c2735b150e7afb03 (v1.3.9).
-rw-r--r-- | COPYING | 22 | ||||
-rw-r--r-- | README | 61 | ||||
-rw-r--r-- | librhash/algorithms.c | 144 | ||||
-rw-r--r-- | librhash/algorithms.h | 49 | ||||
-rw-r--r-- | librhash/byte_order.c | 53 | ||||
-rw-r--r-- | librhash/byte_order.h | 156 | ||||
-rw-r--r-- | librhash/hex.c | 170 | ||||
-rw-r--r-- | librhash/hex.h | 13 | ||||
-rw-r--r-- | librhash/md5.c | 30 | ||||
-rw-r--r-- | librhash/md5.h | 6 | ||||
-rw-r--r-- | librhash/rhash.c | 322 | ||||
-rw-r--r-- | librhash/rhash.h | 401 | ||||
-rw-r--r-- | librhash/sha1.c | 26 | ||||
-rw-r--r-- | librhash/sha1.h | 6 | ||||
-rw-r--r-- | librhash/sha256.c | 34 | ||||
-rw-r--r-- | librhash/sha256.h | 8 | ||||
-rw-r--r-- | librhash/sha3.c | 108 | ||||
-rw-r--r-- | librhash/sha3.h | 14 | ||||
-rw-r--r-- | librhash/sha512.c | 30 | ||||
-rw-r--r-- | librhash/sha512.h | 8 | ||||
-rw-r--r-- | librhash/ustd.h | 38 | ||||
-rw-r--r-- | librhash/util.h | 2 |
22 files changed, 946 insertions, 755 deletions
@@ -1,15 +1,15 @@ - RHash License + BSD Zero Clause License -Copyright (c) 2005-2014 Aleksey Kravchenko <rhash.admin@gmail.com> +Copyright (c) 2005, Aleksey Kravchenko <rhash.admin@gmail.com> -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so. +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. -The Software is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. Use this program at your own risk! +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. @@ -1,61 +0,0 @@ - === RHash program === - -RHash is a console utility for calculation and verification of magnet links -and a wide range of hash sums like CRC32, MD4, MD5, SHA1, SHA256, SHA512, -SHA3, AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, -RIPEMD-160, HAS-160, EDON-R, Whirlpool and Snefru. - -Hash sums are used to ensure and verify integrity of large volumes of data -for a long-term storing or transferring. - -Features: - * Output in a predefined (SFV, BSD-like) or a user-defined format. - * Can calculate Magnet links. - * Updating hash files (adding hash sums of files missing in the hash file). - * Calculates several hash sums in one pass - * Ability to process directories recursively. - * Portability: the program works the same on Linux, *BSD or Windows. - - - === The LibRHash library === - -LibRHash is a professional, portable, thread-safe C library for computing -a wide variety of hash sums, such as CRC32, MD4, MD5, SHA1, SHA256, SHA512, -SHA3, AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, -RIPEMD-160, HAS-160, EDON-R, Whirlpool and Snefru. -Hash sums are used to ensure and verify integrity of large volumes of data -for a long-term storing or transferring. - -Features: - * Small and easy to learn interface. - * Hi-level and Low-level API. - * Allows calculating of several hash functions simultaneously. - * Portability: the library works on Linux, *BSD and Windows. - - - === Links === - - * Project Home Page: http://rhash.sourceforge.net/ - * Official Releases: http://sf.net/projects/rhash/files/rhash/ - - * RHash hash functions descriptions http://rhash.anz.ru/hashes.php - * The table of the hash functions supported by RHash - http://sf.net/apps/mediawiki/rhash/index.php?title=Hash_sums - * ECRYPT: The Hash Function Zoo - http://ehash.iaik.tugraz.at/wiki/The_Hash_Function_Zoo - - - === Getting latest source code === - -The latest source code can be obtained from Git repository by command: - - git clone git://github.com/rhash/RHash.git - - - === Notes on RHash License === - -The RHash program and LibRHash library are distributed under RHash License, -see the COPYING file for details. In particular, the program, the library -and source code can be used free of charge under the MIT, BSD, GPL, -commercial or freeware license without additional restrictions. In the case -the OSI-approved license is required the MIT license should be used. diff --git a/librhash/algorithms.c b/librhash/algorithms.c index 1f343a1..f73a7c7 100644 --- a/librhash/algorithms.c +++ b/librhash/algorithms.c @@ -1,17 +1,17 @@ /* algorithms.c - the algorithms supported by the rhash library * - * Copyright: 2011-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2011, Aleksey Kravchenko <rhash.admin@gmail.com> * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <stdio.h> @@ -26,7 +26,8 @@ #include "crc32.h" #include "ed2k.h" #include "edonr.h" -#include "gost.h" +#include "gost12.h" +#include "gost94.h" #include "has160.h" #include "md4.h" #include "md5.h" @@ -49,18 +50,13 @@ #else # define NEED_OPENSSL_INIT 0 #endif /* USE_OPENSSL */ -#ifdef GENERATE_GOST_LOOKUP_TABLE -# define NEED_GOST_INIT (RHASH_GOST | RHASH_GOST_CRYPTOPRO) +#ifdef GENERATE_GOST94_LOOKUP_TABLE +# define NEED_GOST94_INIT (RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO) #else -# define NEED_GOST_INIT 0 -#endif /* GENERATE_GOST_LOOKUP_TABLE */ -#ifdef GENERATE_CRC32_TABLE -# define NEED_CRC32_INIT RHASH_CRC32 -#else -# define NEED_CRC32_INIT 0 -#endif /* GENERATE_CRC32_TABLE */ +# define NEED_GOST94_INIT 0 +#endif /* GENERATE_GOST94_LOOKUP_TABLE */ -#define RHASH_NEED_INIT_ALG (NEED_CRC32_INIT | NEED_GOST_INIT | NEED_OPENSSL_INIT) +#define RHASH_NEED_INIT_ALG (NEED_GOST94_INIT | NEED_OPENSSL_INIT) unsigned rhash_uninitialized_algorithms = RHASH_NEED_INIT_ALG; rhash_hash_info* rhash_info_table = rhash_hash_info_default; @@ -69,8 +65,12 @@ int rhash_info_size = RHASH_HASH_COUNT; static void rhash_crc32_init(uint32_t* crc32); static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size); static void rhash_crc32_final(uint32_t* crc32, unsigned char* result); +static void rhash_crc32c_init(uint32_t* crc32); +static void rhash_crc32c_update(uint32_t* crc32, const unsigned char* msg, size_t size); +static void rhash_crc32c_final(uint32_t* crc32, unsigned char* result); -rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" }; +rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" }; +rhash_info info_crc32c = { RHASH_CRC32C, F_BE32, 4, "CRC32C", "crc32c" }; rhash_info info_md4 = { RHASH_MD4, F_LE32, 16, "MD4", "md4" }; rhash_info info_md5 = { RHASH_MD5, F_LE32, 16, "MD5", "md5" }; rhash_info info_sha1 = { RHASH_SHA1, F_BE32, 20, "SHA1", "sha1" }; @@ -81,8 +81,10 @@ rhash_info info_ed2k = { RHASH_ED2K, F_LE32, 16, "ED2K", "ed2k" }; rhash_info info_aich = { RHASH_AICH, F_BS32, 20, "AICH", "aich" }; rhash_info info_whirlpool = { RHASH_WHIRLPOOL, F_BE64, 64, "WHIRLPOOL", "whirlpool" }; rhash_info info_rmd160 = { RHASH_RIPEMD160, F_LE32, 20, "RIPEMD-160", "ripemd160" }; -rhash_info info_gost = { RHASH_GOST, F_LE32, 32, "GOST", "gost" }; -rhash_info info_gostpro = { RHASH_GOST_CRYPTOPRO, F_LE32, 32, "GOST-CRYPTOPRO", "gost-cryptopro" }; +rhash_info info_gost12_256 = { RHASH_GOST12_256, F_LE64, 32, "GOST12-256", "gost12-256" }; +rhash_info info_gost12_512 = { RHASH_GOST12_512, F_LE64, 64, "GOST12-512", "gost12-512" }; +rhash_info info_gost94 = { RHASH_GOST94, F_LE32, 32, "GOST94", "gost94" }; +rhash_info info_gost94pro = { RHASH_GOST94_CRYPTOPRO, F_LE32, 32, "GOST94-CRYPTOPRO", "gost94-cryptopro" }; rhash_info info_has160 = { RHASH_HAS160, F_LE32, 20, "HAS-160", "has160" }; rhash_info info_snf128 = { RHASH_SNEFRU128, F_BE32, 16, "SNEFRU-128", "snefru128" }; rhash_info info_snf256 = { RHASH_SNEFRU256, F_BE32, 32, "SNEFRU-256", "snefru256" }; @@ -104,9 +106,10 @@ rhash_info info_sha3_512 = { RHASH_SHA3_512, F_LE64, 64, "SHA3-512", "sha3-512" #define upd(name) ((pupdate_t)(name##_update)) #define fin(name) ((pfinal_t)(name##_final)) #define iuf(name) ini(name), upd(name), fin(name) +#define iuf2(name1, name2) ini(name1), upd(name2), fin(name2) #define diuf(name) dgshft(name), ini(name), upd(name), fin(name) -/* information about all hashes */ +/* information about all supported hash functions */ rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] = { { &info_crc32, sizeof(uint32_t), 0, iuf(rhash_crc32), 0 }, /* 32 bit */ @@ -120,25 +123,30 @@ rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] = { &info_aich, sizeof(aich_ctx), dgshft2(aich, sha1_context.hash), iuf(rhash_aich), (pcleanup_t)rhash_aich_cleanup }, /* 160 bit */ { &info_whirlpool, sizeof(whirlpool_ctx), dgshft(whirlpool), iuf(rhash_whirlpool), 0 }, /* 512 bit */ { &info_rmd160, sizeof(ripemd160_ctx), dgshft(ripemd160), iuf(rhash_ripemd160), 0 }, /* 160 bit */ - { &info_gost, sizeof(gost_ctx), dgshft(gost), iuf(rhash_gost), 0 }, /* 256 bit */ - { &info_gostpro, sizeof(gost_ctx), dgshft(gost), ini(rhash_gost_cryptopro), upd(rhash_gost), fin(rhash_gost), 0 }, /* 256 bit */ + { &info_gost94, sizeof(gost94_ctx), dgshft(gost94), iuf(rhash_gost94), 0 }, /* 256 bit */ + { &info_gost94pro, sizeof(gost94_ctx), dgshft(gost94), iuf2(rhash_gost94_cryptopro, rhash_gost94), 0 }, /* 256 bit */ { &info_has160, sizeof(has160_ctx), dgshft(has160), iuf(rhash_has160), 0 }, /* 160 bit */ - { &info_snf128, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru128), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 128 bit */ - { &info_snf256, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru256), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 256 bit */ - { &info_sha224, sizeof(sha256_ctx), dgshft(sha256), ini(rhash_sha224), upd(rhash_sha256), fin(rhash_sha256), 0 }, /* 224 bit */ + { &info_gost12_256, sizeof(gost12_ctx), dgshft2(gost12, h) + 32, iuf2(rhash_gost12_256, rhash_gost12), 0 }, /* 256 bit */ + { &info_gost12_512, sizeof(gost12_ctx), dgshft2(gost12, h), iuf2(rhash_gost12_512, rhash_gost12), 0 }, /* 512 bit */ + { &info_sha224, sizeof(sha256_ctx), dgshft(sha256), iuf2(rhash_sha224, rhash_sha256), 0 }, /* 224 bit */ { &info_sha256, sizeof(sha256_ctx), dgshft(sha256), iuf(rhash_sha256), 0 }, /* 256 bit */ - { &info_sha384, sizeof(sha512_ctx), dgshft(sha512), ini(rhash_sha384), upd(rhash_sha512), fin(rhash_sha512), 0 }, /* 384 bit */ + { &info_sha384, sizeof(sha512_ctx), dgshft(sha512), iuf2(rhash_sha384, rhash_sha512), 0 }, /* 384 bit */ { &info_sha512, sizeof(sha512_ctx), dgshft(sha512), iuf(rhash_sha512), 0 }, /* 512 bit */ - { &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 }, /* 256 bit */ - { &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 }, /* 512 bit */ - { &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_224), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 224 bit */ - { &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_256), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 256 bit */ - { &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_384), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 384 bit */ - { &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_512), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 512 bit */ + { &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 }, /* 256 bit */ + { &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 }, /* 512 bit */ + { &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_224, rhash_sha3), 0 }, /* 224 bit */ + { &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_256, rhash_sha3), 0 }, /* 256 bit */ + { &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_384, rhash_sha3), 0 }, /* 384 bit */ + { &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_512, rhash_sha3), 0 }, /* 512 bit */ + { &info_crc32c, sizeof(uint32_t), 0, iuf(rhash_crc32c), 0 }, /* 32 bit */ + { &info_snf128, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru128, rhash_snefru), 0 }, /* 128 bit */ + { &info_snf256, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru256, rhash_snefru), 0 }, /* 256 bit */ }; /** * Initialize requested algorithms. + * + * @param mask ids of hash sums to initialize */ void rhash_init_algorithms(unsigned mask) { @@ -147,15 +155,26 @@ void rhash_init_algorithms(unsigned mask) /* verify that RHASH_HASH_COUNT is the index of the major bit of RHASH_ALL_HASHES */ assert(1 == (RHASH_ALL_HASHES >> (RHASH_HASH_COUNT - 1))); -#ifdef GENERATE_CRC32_TABLE - rhash_crc32_init_table(); -#endif -#ifdef GENERATE_GOST_LOOKUP_TABLE - rhash_gost_init_table(); +#ifdef GENERATE_GOST94_LOOKUP_TABLE + rhash_gost94_init_table(); #endif rhash_uninitialized_algorithms = 0; } +/** + * Returns information about a hash function by its hash_id. + * + * @param hash_id the id of hash algorithm + * @return pointer to the rhash_info structure containing the information + */ +const rhash_info* rhash_info_by_id(unsigned hash_id) +{ + hash_id &= RHASH_ALL_HASHES; + /* check that one and only one bit is set */ + if (!hash_id || (hash_id & (hash_id - 1)) != 0) return NULL; + return rhash_info_table[rhash_ctz(hash_id)].info; +} + /* CRC32 helper functions */ /** @@ -198,3 +217,44 @@ static void rhash_crc32_final(uint32_t* crc32, unsigned char* result) result[2] = (unsigned char)(*crc32 >> 8), result[3] = (unsigned char)(*crc32); #endif } + +/** + * Initialize crc32c hash. + * + * @param crc32c pointer to the hash to initialize + */ +static void rhash_crc32c_init(uint32_t* crc32c) +{ + *crc32c = 0; /* note: context size is sizeof(uint32_t) */ +} + +/** + * Calculate message CRC32C hash. + * Can be called repeatedly with chunks of the message to be hashed. + * + * @param crc32c pointer to the hash + * @param msg message chunk + * @param size length of the message chunk + */ +static void rhash_crc32c_update(uint32_t* crc32c, const unsigned char* msg, size_t size) +{ + *crc32c = rhash_get_crc32c(*crc32c, msg, size); +} + +/** + * Store calculated hash into the given array. + * + * @param crc32c pointer to the current hash value + * @param result calculated hash in binary form + */ +static void rhash_crc32c_final(uint32_t* crc32c, unsigned char* result) +{ +#if defined(CPU_IA32) || defined(CPU_X64) + /* intel CPUs support assigment with non 32-bit aligned pointers */ + *(unsigned*)result = be2me_32(*crc32c); +#else + /* correct saving BigEndian integer on all archs */ + result[0] = (unsigned char)(*crc32c >> 24), result[1] = (unsigned char)(*crc32c >> 16); + result[2] = (unsigned char)(*crc32c >> 8), result[3] = (unsigned char)(*crc32c); +#endif +} diff --git a/librhash/algorithms.h b/librhash/algorithms.h index 4db2517..01dda88 100644 --- a/librhash/algorithms.h +++ b/librhash/algorithms.h @@ -2,9 +2,9 @@ #ifndef RHASH_ALGORITHMS_H #define RHASH_ALGORITHMS_H -#include <stddef.h> /* for ptrdiff_t */ #include "rhash.h" #include "byte_order.h" +#include <stddef.h> #ifdef __cplusplus extern "C" { @@ -15,8 +15,40 @@ extern "C" { # define RHASH_API #endif +/** + * Bit flag: default hash output format is base32. + */ +#define RHASH_INFO_BASE32 1 + +/** + * Information about a hash function. + */ +typedef struct rhash_info +{ + /** + * Hash function indentifier. + */ + unsigned hash_id; + /** + * Flags bit-mask, including RHASH_INFO_BASE32 bit. + */ + unsigned flags; + /** + The size of of the raw message digest in bytes. + */ + size_t digest_size; + /** + * The hash function name. + */ + const char* name; + /** + * The corresponding paramenter name in a magnet link. + */ + const char* magnet_name; +} rhash_info; + typedef void (*pinit_t)(void*); -typedef void (*pupdate_t)(void *ctx, const void* msg, size_t size); +typedef void (*pupdate_t)(void* ctx, const void* msg, size_t size); typedef void (*pfinal_t)(void*, unsigned char*); typedef void (*pcleanup_t)(void*); @@ -25,7 +57,7 @@ typedef void (*pcleanup_t)(void*); */ typedef struct rhash_hash_info { - rhash_info *info; + rhash_info* info; size_t context_size; ptrdiff_t digest_diff; pinit_t init; @@ -40,7 +72,7 @@ typedef struct rhash_hash_info typedef struct rhash_vector_item { struct rhash_hash_info* hash_info; - void *context; + void* context; } rhash_vector_item; /** @@ -52,8 +84,9 @@ typedef struct rhash_context_ext unsigned hash_vector_size; /* number of contained hash sums */ unsigned flags; unsigned state; - void *callback, *callback_data; - void *bt_ctx; + void* callback; + void* callback_data; + void* bt_ctx; rhash_vector_item vector[1]; /* contexts of contained hash sums */ } rhash_context_ext; @@ -63,6 +96,7 @@ extern int rhash_info_size; extern unsigned rhash_uninitialized_algorithms; extern rhash_info info_crc32; +extern rhash_info info_crc32c; extern rhash_info info_md4; extern rhash_info info_md5; extern rhash_info info_sha1; @@ -95,7 +129,7 @@ extern rhash_info info_edr512; #define F_SWAP64 4 /* define endianness flags */ -#ifndef CPU_BIG_ENDIAN +#if IS_LITTLE_ENDIAN #define F_LE32 0 #define F_LE64 0 #define F_BE32 F_SWAP32 @@ -108,6 +142,7 @@ extern rhash_info info_edr512; #endif void rhash_init_algorithms(unsigned mask); +const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */ #if defined(OPENSSL_RUNTIME) && !defined(USE_OPENSSL) # define USE_OPENSSL diff --git a/librhash/byte_order.c b/librhash/byte_order.c index 8ce6fc8..de2c583 100644 --- a/librhash/byte_order.c +++ b/librhash/byte_order.c @@ -1,21 +1,21 @@ /* byte_order.c - byte order related platform dependent routines, * - * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com> * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include "byte_order.h" -#if !(__GNUC__ >= 4 || (__GNUC__ ==3 && __GNUC_MINOR__ >= 4)) /* if !GCC or GCC < 4.3 */ +#ifndef rhash_ctz # if _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) /* if MSVC++ >= 2002 on x86/x64 */ # include <intrin.h> @@ -59,7 +59,7 @@ unsigned rhash_ctz(unsigned x) return (unsigned)bit_pos[((uint32_t)((x & -x) * 0x077CB531U)) >> 27]; } # endif /* _MSC_VER >= 1300... */ -#endif /* !(GCC >= 4.3) */ +#endif /* rhash_ctz */ /** * Copy a memory block with simultaneous exchanging byte order. @@ -79,10 +79,12 @@ void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t le const uint32_t* src = (const uint32_t*)from; const uint32_t* end = (const uint32_t*)((const char*)src + length); uint32_t* dst = (uint32_t*)((char*)to + index); - while (src < end) *(dst++) = bswap_32( *(src++) ); + for (; src < end; dst++, src++) + *dst = bswap_32(*src); } else { const char* src = (const char*)from; - for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 3] = *(src++); + for (length += index; (size_t)index < length; index++) + ((char*)to)[index ^ 3] = *(src++); } } @@ -141,10 +143,31 @@ void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length) * @param arr the array to process * @param length array length */ -void rhash_u32_mem_swap(unsigned *arr, int length) +void rhash_u32_mem_swap(unsigned* arr, int length) { unsigned* end = arr + length; for (; arr < end; arr++) { *arr = bswap_32(*arr); } } + +#ifdef HAS_INTEL_CPUID +#include <cpuid.h> + +static uint64_t get_cpuid_features(void) +{ + uint32_t tmp, edx, ecx; + if (__get_cpuid(1, &tmp, &tmp, &ecx, &edx)) + return ((((uint64_t)ecx) << 32) ^ edx); + return 0; +} + +int has_cpu_feature(unsigned feature_bit) +{ + static uint64_t features; + const uint64_t feature = ((uint64_t)1) << feature_bit; + if (!features) + features = (get_cpuid_features() | 1); + return !!(features & feature); +} +#endif diff --git a/librhash/byte_order.h b/librhash/byte_order.h index 77b8bb9..bbd285a 100644 --- a/librhash/byte_order.h +++ b/librhash/byte_order.h @@ -4,13 +4,15 @@ #include "ustd.h" #include <stdlib.h> -#ifdef IN_RHASH -#include "config.h" -#endif - -#ifdef __GLIBC__ +#if defined(__GLIBC__) # include <endian.h> #endif +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) +# include <sys/types.h> +#elif defined (__NetBSD__) || defined(__OpenBSD__) +# include <sys/param.h> +#endif + #ifdef __cplusplus extern "C" { @@ -34,29 +36,49 @@ extern "C" { # endif #endif +#define RHASH_BYTE_ORDER_LE 1234 +#define RHASH_BYTE_ORDER_BE 4321 + +#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE +#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE +#elif defined(_BYTE_ORDER) +# if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE +# elif defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE +# endif +#elif defined(__sun) && defined(_LITTLE_ENDIAN) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE +#elif defined(__sun) && defined(_BIG_ENDIAN) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE +#endif -/* detect CPU endianness */ -#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ - __BYTE_ORDER == __LITTLE_ENDIAN) || \ - defined(CPU_IA32) || defined(CPU_X64) || \ - defined(__ia64) || defined(__ia64__) || defined(__alpha__) || defined(_M_ALPHA) || \ - defined(vax) || defined(MIPSEL) || defined(_ARM_) || defined(__arm__) -# define CPU_LITTLE_ENDIAN -# define IS_BIG_ENDIAN 0 -# define IS_LITTLE_ENDIAN 1 -#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ - __BYTE_ORDER == __BIG_ENDIAN) || \ - defined(__sparc) || defined(__sparc__) || defined(sparc) || \ - defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_POWER) || \ - defined(__POWERPC__) || defined(POWERPC) || defined(__powerpc) || \ - defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || \ - defined(__hpux) || defined(_MIPSEB) || defined(mc68000) || \ - defined(__s390__) || defined(__s390x__) || defined(sel) -# define CPU_BIG_ENDIAN -# define IS_BIG_ENDIAN 1 -# define IS_LITTLE_ENDIAN 0 +/* try detecting endianness by CPU */ +#ifdef RHASH_BYTE_ORDER +#elif defined(CPU_IA32) || defined(CPU_X64) || defined(__ia64) || defined(__ia64__) || \ + defined(__alpha__) || defined(_M_ALPHA) || defined(vax) || defined(MIPSEL) || \ + defined(_ARM_) || defined(__arm__) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE +#elif defined(__sparc) || defined(__sparc__) || defined(sparc) || \ + defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_POWER) || \ + defined(__POWERPC__) || defined(POWERPC) || defined(__powerpc) || \ + defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || \ + defined(__hpux) || defined(_MIPSEB) || defined(mc68000) || \ + defined(__s390__) || defined(__s390x__) || defined(sel) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE #else -# error "Can't detect CPU architechture" +# error "Can't detect CPU architechture" +#endif + +#define IS_BIG_ENDIAN (RHASH_BYTE_ORDER == RHASH_BYTE_ORDER_BE) +#define IS_LITTLE_ENDIAN (RHASH_BYTE_ORDER == RHASH_BYTE_ORDER_LE) + +#ifndef __has_builtin +# define __has_builtin(x) 0 #endif #define IS_ALIGNED_32(p) (0 == (3 & ((const char*)(p) - (const char*)0))) @@ -74,11 +96,23 @@ extern "C" { #if defined(_MSC_VER) || defined(__BORLANDC__) #define I64(x) x##ui64 #else -#define I64(x) x##LL +#define I64(x) x##ULL #endif -/* convert a hash flag to index */ -#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) /* GCC < 3.4 */ +#if defined(_MSC_VER) +#define RHASH_INLINE __inline +#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define RHASH_INLINE inline +#elif defined(__GNUC__) +#define RHASH_INLINE __inline__ +#else +#define RHASH_INLINE +#endif + +/* define rhash_ctz - count traling zero bits */ +#if (defined(__GNUC__) && __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) || \ + (defined(__clang__) && __has_builtin(__builtin_ctz)) +/* GCC >= 3.4 or clang */ # define rhash_ctz(x) __builtin_ctz(x) #else unsigned rhash_ctz(unsigned); /* define as function */ @@ -87,37 +121,31 @@ unsigned rhash_ctz(unsigned); /* define as function */ void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length); void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length); void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length); -void rhash_u32_mem_swap(unsigned *p, int length_in_u32); +void rhash_u32_mem_swap(unsigned* p, int length_in_u32); -/* define bswap_32 */ -#if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__) -/* for intel x86 CPU */ -static inline uint32_t bswap_32(uint32_t x) { - __asm("bswap\t%0" : "=r" (x) : "0" (x)); - return x; -} -#elif defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3) -/* for GCC >= 4.3 */ +/* bswap definitions */ +#if (defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)) || \ + (defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)) +/* GCC >= 4.3 or clang */ # define bswap_32(x) __builtin_bswap32(x) +# define bswap_64(x) __builtin_bswap64(x) #elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */ # define bswap_32(x) _byteswap_ulong((unsigned long)x) -#elif !defined(__STRICT_ANSI__) -/* general bswap_32 definition */ -static inline uint32_t bswap_32(uint32_t x) { - x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0x00FF00FF); +# define bswap_64(x) _byteswap_uint64((__int64)x) +#else +/* fallback to generic bswap definition */ +static RHASH_INLINE uint32_t bswap_32(uint32_t x) +{ +# if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__) && !defined(RHASH_NO_ASM) + __asm("bswap\t%0" : "=r" (x) : "0" (x)); /* gcc x86 version */ + return x; +# else + x = ((x << 8) & 0xFF00FF00u) | ((x >> 8) & 0x00FF00FFu); return (x >> 16) | (x << 16); +# endif } -#else -#define bswap_32(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ - (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) -#endif /* bswap_32 */ - -#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3) -# define bswap_64(x) __builtin_bswap64(x) -#elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */ -# define bswap_64(x) _byteswap_uint64((__int64)x) -#elif !defined(__STRICT_ANSI__) -static inline uint64_t bswap_64(uint64_t x) { +static RHASH_INLINE uint64_t bswap_64(uint64_t x) +{ union { uint64_t ll; uint32_t l[2]; @@ -127,11 +155,9 @@ static inline uint64_t bswap_64(uint64_t x) { r.l[1] = bswap_32(w.l[0]); return r.ll; } -#else -#error "bswap_64 unsupported" -#endif +#endif /* bswap definitions */ -#ifdef CPU_BIG_ENDIAN +#if IS_BIG_ENDIAN # define be2me_32(x) (x) # define be2me_64(x) (x) # define le2me_32(x) bswap_32(x) @@ -144,7 +170,7 @@ static inline uint64_t bswap_64(uint64_t x) { # define me64_to_be_str(to, from, length) memcpy((to), (from), (length)) # define me64_to_le_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length)) -#else /* CPU_BIG_ENDIAN */ +#else /* IS_BIG_ENDIAN */ # define be2me_32(x) bswap_32(x) # define be2me_64(x) bswap_64(x) # define le2me_32(x) (x) @@ -156,7 +182,7 @@ static inline uint64_t bswap_64(uint64_t x) { # define le64_copy(to, index, from, length) memcpy((to) + (index), (from), (length)) # define me64_to_be_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length)) # define me64_to_le_str(to, from, length) memcpy((to), (from), (length)) -#endif /* CPU_BIG_ENDIAN */ +#endif /* IS_BIG_ENDIAN */ /* ROTL/ROTR macros rotate a 32/64-bit word left/right by n bits */ #define ROTL32(dword, n) ((dword) << (n) ^ ((dword) >> (32 - (n)))) @@ -164,6 +190,16 @@ static inline uint64_t bswap_64(uint64_t x) { #define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n)))) #define ROTR64(qword, n) ((qword) >> (n) ^ ((qword) << (64 - (n)))) +#define CPU_FEATURE_SSE4_2 (52) + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) \ + && (defined(CPU_X64) || defined(CPU_IA32)) +# define HAS_INTEL_CPUID +int has_cpu_feature(unsigned feature_bit); +#else +# define has_cpu_feature(x) (0) +#endif + #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ diff --git a/librhash/hex.c b/librhash/hex.c index c941149..f0bbf04 100644 --- a/librhash/hex.c +++ b/librhash/hex.c @@ -1,71 +1,57 @@ /* hex.c - conversion for hexadecimal and base32 strings. * - * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com> * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ -#include <string.h> -#include <ctype.h> #include "hex.h" - -/** -* Convert a byte to a hexadecimal number. The result, consisting of two -* hexadecimal digits is stored into a buffer. - * - * @param dest the buffer to receive two symbols of hex representation - * @param byte the byte to decode - * @param upper_case flag to print string in uppercase - * @return pointer to the chararcter just after the written number (dest + 2) - */ -char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case) -{ - const char add = (upper_case ? 'A' - 10 : 'a' - 10); - unsigned char c = (byte >> 4) & 15; - *dest++ = (c > 9 ? c + add : c + '0'); - c = byte & 15; - *dest++ = (c > 9 ? c + add : c + '0'); - return dest; -} +#include <assert.h> +#include <ctype.h> +#include <string.h> /** * Store hexadecimal representation of a binary string to given buffer. * - * @param dest the buffer to receive hexadecimal representation + * @param dst the buffer to receive hexadecimal representation * @param src binary string - * @param len string length + * @param length string length * @param upper_case flag to print string in uppercase */ -void rhash_byte_to_hex(char *dest, const unsigned char *src, unsigned len, int upper_case) +void rhash_byte_to_hex(char* dst, const unsigned char* src, size_t length, int upper_case) { - while (len-- > 0) { - dest = rhash_print_hex_byte(dest, *src++, upper_case); + const char hex_add = (upper_case ? 'A' - 10 : 'a' - 10); + for (; length > 0; src++, length--) { + const unsigned char hi = (*src >> 4) & 15; + const unsigned char lo = *src & 15; + *dst++ = (hi > 9 ? hi + hex_add : hi + '0'); + *dst++ = (lo > 9 ? lo + hex_add : lo + '0'); } - *dest = '\0'; + *dst = '\0'; } /** * Encode a binary string to base32. * - * @param dest the buffer to store result + * @param dst the buffer to store result * @param src binary string - * @param len string length + * @param length string length * @param upper_case flag to print string in uppercase */ -void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case) +void rhash_byte_to_base32(char* dst, const unsigned char* src, size_t length, int upper_case) { const char a = (upper_case ? 'A' : 'a'); unsigned shift = 0; unsigned char word; - const unsigned char* e = src + len; + const unsigned char* e = src + length; while (src < e) { if (shift > 3) { word = (*src & (0xFF >> shift)); @@ -79,25 +65,25 @@ void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, in word = ( *src >> ( (8 - shift) & 7 ) ) & 0x1F; if (shift == 0) src++; } - *dest++ = ( word < 26 ? word + a : word + '2' - 26 ); + *dst++ = ( word < 26 ? word + a : word + '2' - 26 ); } - *dest = '\0'; + *dst = '\0'; } /** * Encode a binary string to base64. * Encoded output length is always a multiple of 4 bytes. * - * @param dest the buffer to store result + * @param dst the buffer to store result * @param src binary string - * @param len string length + * @param length string length */ -void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len) +void rhash_byte_to_base64(char* dst, const unsigned char* src, size_t length) { static const char* tail = "0123456789+/"; unsigned shift = 0; unsigned char word; - const unsigned char* e = src + len; + const unsigned char* e = src + length; while (src < e) { if (shift > 2) { word = (*src & (0xFF >> shift)); @@ -111,45 +97,80 @@ void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len) word = ( *src >> ( (8 - shift) & 7 ) ) & 0x3F; if (shift == 0) src++; } - *dest++ = ( word < 52 ? (word < 26 ? word + 'A' : word - 26 + 'a') : tail[word - 52]); + *dst++ = ( word < 52 ? (word < 26 ? word + 'A' : word - 26 + 'a') : tail[word - 52]); } if (shift > 0) { - *dest++ = '='; - if (shift == 4) *dest++ = '='; + *dst++ = '='; + if (shift == 4) *dst++ = '='; } - *dest = '\0'; + *dst = '\0'; } -/* unsafe characters are "<>{}[]%#/|\^~`@:;?=&+ */ -#define IS_GOOD_URL_CHAR(c) (isalnum((unsigned char)c) || strchr("$-_.!'(),", c)) +size_t rhash_base64_url_encoded_helper(char* dst, const unsigned char* src, size_t length, int url_encode, int upper_case) +{ +#define B64_CHUNK_SIZE 120 + char buffer[164]; + assert((BASE64_LENGTH(B64_CHUNK_SIZE) + 4) <= sizeof(buffer)); + assert((B64_CHUNK_SIZE % 6) == 0); + if (url_encode) { + size_t result_length = 0; + for (; length > 0; src += B64_CHUNK_SIZE) { + size_t chunk_size = (length < B64_CHUNK_SIZE ? length : B64_CHUNK_SIZE); + size_t encoded_length; + rhash_byte_to_base64(buffer, src, chunk_size); + encoded_length = rhash_urlencode(dst, buffer, BASE64_LENGTH(chunk_size), upper_case); + result_length += encoded_length; + dst += encoded_length; + length -= chunk_size; + } + return result_length; + } + rhash_byte_to_base64(dst, src, length); + return BASE64_LENGTH(length); +} + +/* RFC 3986: safe url characters are ascii alpha-numeric and "-._~", other characters should be percent-encoded */ +static unsigned url_safe_char_mask[4] = { 0, 0x03ff6000, 0x87fffffe, 0x47fffffe }; +#define IS_URL_GOOD_CHAR(c) ((unsigned)(c) < 128 && (url_safe_char_mask[c >> 5] & (1 << (c & 31)))) /** - * URL-encode a string. + * URL-encode specified binary string. * - * @param dst buffer to receive result or NULL to calculate - * the lengths of encoded string - * @param filename the file name + * @param dst (nullable) buffer to output encoded string to, + * NULL to just calculate the lengths of encoded string + * @param src binary string to encode + * @param size size of the binary string + * @param upper_case flag to output hex-codes in uppercase * @return the length of the result string */ -int rhash_urlencode(char *dst, const char *name) +size_t rhash_urlencode(char* dst, const char* src, size_t size, int upper_case) { - const char *start; + const char* start; + size_t i; if (!dst) { - int len; - for (len = 0; *name; name++) len += (IS_GOOD_URL_CHAR(*name) ? 1 : 3); - return len; - } - /* encode URL as specified by RFC 1738 */ - for (start = dst; *name; name++) { - if ( IS_GOOD_URL_CHAR(*name) ) { - *dst++ = *name; - } else { - *dst++ = '%'; - dst = rhash_print_hex_byte(dst, *name, 'A'); + size_t length = size; + for (i = 0; i < size; i++) + if (!IS_URL_GOOD_CHAR(src[i])) + length += 2; + return length; + } else { + const char hex_add = (upper_case ? 'A' - 10 : 'a' - 10); + start = dst; + /* percent-encode all but unreserved URL characters */ + for (i = 0; i < size; i++) { + if (IS_URL_GOOD_CHAR(src[i])) { + *dst++ = src[i]; + } else { + unsigned char hi = ((unsigned char)(src[i]) >> 4) & 0x0f; + unsigned char lo = (unsigned char)(src[i]) & 0x0f; + *dst++ = '%'; + *dst++ = (hi > 9 ? hi + hex_add : hi + '0'); + *dst++ = (lo > 9 ? lo + hex_add : lo + '0'); + } } + *dst = 0; } - *dst = 0; - return (int)(dst - start); + return dst - start; } /** @@ -160,10 +181,11 @@ int rhash_urlencode(char *dst, const char *name) * @param number the number to print * @return length of the printed number (without trailing '\0') */ -int rhash_sprintI64(char *dst, uint64_t number) +int rhash_sprintI64(char* dst, uint64_t number) { /* The biggest number has 20 digits: 2^64 = 18 446 744 073 709 551 616 */ - char buf[24], *p; + char buf[24]; + char* p; size_t length; if (dst == NULL) { diff --git a/librhash/hex.h b/librhash/hex.h index 2b365e2..6bea036 100644 --- a/librhash/hex.h +++ b/librhash/hex.h @@ -8,12 +8,13 @@ extern "C" { #endif -void rhash_byte_to_hex(char *dest, const unsigned char *src, unsigned len, int upper_case); -void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case); -void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len); -char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case); -int rhash_urlencode(char *dst, const char *name); -int rhash_sprintI64(char *dst, uint64_t number); +void rhash_byte_to_hex(char* dest, const unsigned char* src, size_t length, int upper_case); +void rhash_byte_to_base32(char* dest, const unsigned char* src, size_t length, int upper_case); +void rhash_byte_to_base64(char* dest, const unsigned char* src, size_t length); +char* rhash_print_hex_byte(char* dest, const unsigned char byte, int upper_case); +size_t rhash_urlencode(char* dst, const char* str, size_t size, int upper_case); +size_t rhash_base64_url_encoded_helper(char* dst, const unsigned char* src, size_t length, int url_encode, int upper_case); +int rhash_sprintI64(char* dst, uint64_t number); #define BASE32_LENGTH(bytes) (((bytes) * 8 + 4) / 5) #define BASE64_LENGTH(bytes) ((((bytes) + 2) / 3) * 4) diff --git a/librhash/md5.c b/librhash/md5.c index 0feb090..9b76822 100644 --- a/librhash/md5.c +++ b/librhash/md5.c @@ -1,17 +1,17 @@ /* md5.c - an implementation of the MD5 algorithm, based on RFC 1321. * - * Copyright: 2007-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2007, Aleksey Kravchenko <rhash.admin@gmail.com> * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <string.h> @@ -23,7 +23,7 @@ * * @param ctx context to initialize */ -void rhash_md5_init(md5_ctx *ctx) +void rhash_md5_init(md5_ctx* ctx) { ctx->length = 0; @@ -162,7 +162,7 @@ static void rhash_md5_process_block(unsigned state[4], const unsigned* x) * @param msg message chunk * @param size length of the message chunk */ -void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size) +void rhash_md5_update(md5_ctx* ctx, const unsigned char* msg, size_t size) { unsigned index = (unsigned)ctx->length & 63; ctx->length += size; @@ -205,7 +205,7 @@ void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_md5_final(md5_ctx *ctx, unsigned char* result) +void rhash_md5_final(md5_ctx* ctx, unsigned char* result) { unsigned index = ((unsigned)ctx->length & 63) >> 2; unsigned shift = ((unsigned)ctx->length & 3) * 8; @@ -213,8 +213,8 @@ void rhash_md5_final(md5_ctx *ctx, unsigned char* result) /* pad message and run for last block */ /* append the byte 0x80 to the message */ - ctx->message[index] &= ~(0xFFFFFFFF << shift); - ctx->message[index++] ^= 0x80 << shift; + ctx->message[index] &= ~(0xFFFFFFFFu << shift); + ctx->message[index++] ^= 0x80u << shift; /* if no room left in the message to store 64-bit message length */ if (index > 14) { diff --git a/librhash/md5.h b/librhash/md5.h index 1af6f13..12a6b52 100644 --- a/librhash/md5.h +++ b/librhash/md5.h @@ -20,9 +20,9 @@ typedef struct md5_ctx /* hash functions */ -void rhash_md5_init(md5_ctx *ctx); -void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size); -void rhash_md5_final(md5_ctx *ctx, unsigned char result[16]); +void rhash_md5_init(md5_ctx* ctx); +void rhash_md5_update(md5_ctx* ctx, const unsigned char* msg, size_t size); +void rhash_md5_final(md5_ctx* ctx, unsigned char result[16]); #ifdef __cplusplus } /* extern "C" */ diff --git a/librhash/rhash.c b/librhash/rhash.c index 98cf97e..1cb89d1 100644 --- a/librhash/rhash.c +++ b/librhash/rhash.c @@ -1,42 +1,40 @@ /* rhash.c - implementation of LibRHash library calls * - * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com> * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ -/* macros for large file support, must be defined before any include file */ -#define _LARGEFILE64_SOURCE -#define _FILE_OFFSET_BITS 64 - -#include <string.h> /* memset() */ -#include <stdlib.h> /* free() */ -#include <stddef.h> /* ptrdiff_t */ -#include <stdio.h> -#include <assert.h> -#include <errno.h> - /* modifier for Windows DLL */ -#if defined(_WIN32) && defined(RHASH_EXPORTS) +#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS) # define RHASH_API __declspec(dllexport) #endif -#include "byte_order.h" +/* macros for large file support, must be defined before any include file */ +#define _LARGEFILE64_SOURCE +#define _FILE_OFFSET_BITS 64 + +#include "rhash.h" #include "algorithms.h" -#include "torrent.h" +#include "byte_order.h" +#include "hex.h" #include "plug_openssl.h" +#include "torrent.h" #include "util.h" -#include "hex.h" -#include "rhash.h" /* RHash library interface */ +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> #define STATE_ACTIVE 0xb01dbabe #define STATE_STOPED 0xdeadbeef @@ -45,11 +43,8 @@ #define RCTX_FINALIZED 0x2 #define RCTX_FINALIZED_MASK (RCTX_AUTO_FINAL | RCTX_FINALIZED) #define RHPR_FORMAT (RHPR_RAW | RHPR_HEX | RHPR_BASE32 | RHPR_BASE64) -#define RHPR_MODIFIER (RHPR_UPPERCASE | RHPR_REVERSE) +#define RHPR_MODIFIER (RHPR_UPPERCASE | RHPR_URLENCODE | RHPR_REVERSE) -/** - * Initialize static data of rhash algorithms - */ void rhash_library_init(void) { rhash_init_algorithms(RHASH_ALL_HASHES); @@ -58,31 +53,18 @@ void rhash_library_init(void) #endif } -/** - * Returns the number of supported hash algorithms. - * - * @return the number of supported hash functions - */ int RHASH_API rhash_count(void) { return rhash_info_size; } -/* Lo-level rhash library functions */ +/* LOW-LEVEL LIBRHASH INTERFACE */ -/** - * Allocate and initialize RHash context for calculating hash(es). - * After initializing rhash_update()/rhash_final() functions should be used. - * Then the context must be freed by calling rhash_free(). - * - * @param hash_id union of bit flags, containing ids of hashes to calculate. - * @return initialized rhash context, NULL on error and errno is set - */ RHASH_API rhash rhash_init(unsigned hash_id) { unsigned tail_bit_index; /* index of hash_id trailing bit */ unsigned num = 0; /* number of hashes to compute */ - rhash_context_ext *rctx = NULL; /* allocated rhash context */ + rhash_context_ext* rctx = NULL; /* allocated rhash context */ size_t hash_size_sum = 0; /* size of hash contexts to store in rctx */ unsigned i, bit_index, id; @@ -123,7 +105,7 @@ RHASH_API rhash rhash_init(unsigned hash_id) } /* align the size of the rhash context common part */ - aligned_size = (offsetof(rhash_context_ext, vector[num]) + 7) & ~7; + aligned_size = ((offsetof(rhash_context_ext, vector) + sizeof(rhash_vector_item) * num) + 7) & ~7; assert(aligned_size >= sizeof(rhash_context_ext)); /* allocate rhash context with enough memory to store contexts of all used hashes */ @@ -168,11 +150,6 @@ RHASH_API rhash rhash_init(unsigned hash_id) return &rctx->rc; /* return allocated and initialized rhash context */ } -/** - * Free RHash context memory. - * - * @param ctx the context to free. - */ void rhash_free(rhash ctx) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; @@ -193,12 +170,6 @@ void rhash_free(rhash ctx) free(ectx); } -/** - * Re-initialize RHash context to reuse it. - * Useful to speed up processing of many small messages. - * - * @param ctx context to reinitialize - */ RHASH_API void rhash_reset(rhash ctx) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; @@ -221,15 +192,6 @@ RHASH_API void rhash_reset(rhash ctx) ectx->flags &= ~RCTX_FINALIZED; /* clear finalized state */ } -/** - * Calculate hashes of message. - * Can be called repeatedly with chunks of the message to be hashed. - * - * @param ctx the rhash context - * @param message message chunk - * @param length length of the message chunk - * @return 0 on success; On fail return -1 and set errno - */ RHASH_API int rhash_update(rhash ctx, const void* message, size_t length) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; @@ -249,13 +211,6 @@ RHASH_API int rhash_update(rhash ctx, const void* message, size_t length) return 0; /* no error processing at the moment */ } -/** - * Finalize hash calculation and optionally store the first hash. - * - * @param ctx the rhash context - * @param first_result optional buffer to store a calculated hash with the lowest available id - * @return 0 on success; On fail return -1 and set errno - */ RHASH_API int rhash_final(rhash ctx, unsigned char* first_result) { unsigned i = 0; @@ -293,7 +248,7 @@ static void rhash_put_digest(rhash ctx, unsigned hash_id, unsigned char* result) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; unsigned i; - rhash_vector_item *item; + rhash_vector_item* item; struct rhash_hash_info* info; unsigned char* digest; @@ -330,34 +285,14 @@ static void rhash_put_digest(rhash ctx, unsigned hash_id, unsigned char* result) } } -/** - * Set the callback function to be called from the - * rhash_file() and rhash_file_update() functions - * on processing every file block. The file block - * size is set internally by rhash and now is 8 KiB. - * - * @param ctx rhash context - * @param callback pointer to the callback function - * @param callback_data pointer to data passed to the callback - */ RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data) { - ((rhash_context_ext*)ctx)->callback = callback; + ((rhash_context_ext*)ctx)->callback = (void*)callback; ((rhash_context_ext*)ctx)->callback_data = callback_data; } +/* HIGH-LEVEL LIBRHASH INTERFACE */ -/* hi-level message hashing interface */ - -/** - * Compute a hash of the given message. - * - * @param hash_id id of hash sum to compute - * @param message the message to process - * @param length message length - * @param result buffer to receive binary hash string - * @return 0 on success, -1 on error - */ RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result) { rhash ctx; @@ -370,22 +305,12 @@ RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, un return 0; } -/** - * Hash a file or stream. Multiple hashes can be computed. - * First, inintialize ctx parameter with rhash_init() before calling - * rhash_file_update(). Then use rhash_final() and rhash_print() - * to retrive hash values. Finaly call rhash_free() on ctx - * to free allocated memory or call rhash_reset() to reuse ctx. - * - * @param ctx rhash context - * @param fd descriptor of the file to hash - * @return 0 on success, -1 on error and errno is set - */ RHASH_API int rhash_file_update(rhash ctx, FILE* fd) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; const size_t block_size = 8192; - unsigned char *buffer, *pmem; + unsigned char* buffer; + unsigned char* pmem; size_t length = 0, align8; int res = 0; if (ectx->state != STATE_ACTIVE) return 0; /* do nothing if canceled */ @@ -423,14 +348,6 @@ RHASH_API int rhash_file_update(rhash ctx, FILE* fd) return res; } -/** - * Compute a single hash for given file. - * - * @param hash_id id of hash sum to compute - * @param filepath path to the file to hash - * @param result buffer to receive hash value with the lowest requested id - * @return 0 on success, -1 on error and errno is set - */ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result) { FILE* fd; @@ -445,7 +362,10 @@ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* if ((fd = fopen(filepath, "rb")) == NULL) return -1; - if ((ctx = rhash_init(hash_id)) == NULL) return -1; + if ((ctx = rhash_init(hash_id)) == NULL) { + fclose(fd); + return -1; + } res = rhash_file_update(ctx, fd); /* hash the file */ fclose(fd); @@ -458,14 +378,6 @@ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* #ifdef _WIN32 /* windows only function */ #include <share.h> -/** - * Compute a single hash for given file. - * - * @param hash_id id of hash sum to compute - * @param filepath path to the file to hash - * @param result buffer to receive hash value with the lowest requested id - * @return 0 on success, -1 on error, -1 on error and errno is set - */ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result) { FILE* fd; @@ -480,7 +392,10 @@ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned ch if ((fd = _wfsopen(filepath, L"rb", _SH_DENYWR)) == NULL) return -1; - if ((ctx = rhash_init(hash_id)) == NULL) return -1; + if ((ctx = rhash_init(hash_id)) == NULL) { + fclose(fd); + return -1; + } res = rhash_file_update(ctx, fd); /* hash the file */ fclose(fd); @@ -493,39 +408,12 @@ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned ch /* RHash information functions */ -/** - * Returns information about a hash function by its hash_id. - * - * @param hash_id the id of hash algorithm - * @return pointer to the rhash_info structure containing the information - */ -const rhash_info* rhash_info_by_id(unsigned hash_id) -{ - hash_id &= RHASH_ALL_HASHES; - /* check that only one bit is set */ - if (hash_id != (hash_id & -(int)hash_id)) return NULL; - /* note: alternative condition is (hash_id == 0 || (hash_id & (hash_id - 1)) != 0) */ - return rhash_info_table[rhash_ctz(hash_id)].info; -} - -/** - * Detect default digest output format for given hash algorithm. - * - * @param hash_id the id of hash algorithm - * @return 1 for base32 format, 0 for hexadecimal - */ RHASH_API int rhash_is_base32(unsigned hash_id) { /* fast method is just to test a bit-mask */ return ((hash_id & (RHASH_TTH | RHASH_AICH)) != 0); } -/** - * Returns size of binary digest for given hash algorithm. - * - * @param hash_id the id of hash algorithm - * @return digest size in bytes - */ RHASH_API int rhash_get_digest_size(unsigned hash_id) { hash_id &= RHASH_ALL_HASHES; @@ -533,12 +421,6 @@ RHASH_API int rhash_get_digest_size(unsigned hash_id) return (int)rhash_info_table[rhash_ctz(hash_id)].info->digest_size; } -/** - * Returns length of digest hash string in default output format. - * - * @param hash_id the id of hash algorithm - * @return the length of hash string - */ RHASH_API int rhash_get_hash_length(unsigned hash_id) { const rhash_info* info = rhash_info_by_id(hash_id); @@ -546,26 +428,12 @@ RHASH_API int rhash_get_hash_length(unsigned hash_id) BASE32_LENGTH(info->digest_size) : info->digest_size * 2) : 0); } -/** - * Returns a name of given hash algorithm. - * - * @param hash_id the id of hash algorithm - * @return algorithm name - */ RHASH_API const char* rhash_get_name(unsigned hash_id) { const rhash_info* info = rhash_info_by_id(hash_id); return (info ? info->name : 0); } -/** - * Returns a name part of magnet urn of the given hash algorithm. - * Such magnet_name is used to generate a magnet link of the form - * urn:<magnet_name>=<hash_value>. - * - * @param hash_id the id of hash algorithm - * @return name - */ RHASH_API const char* rhash_get_magnet_name(unsigned hash_id) { const rhash_info* info = rhash_info_by_id(hash_id); @@ -594,7 +462,7 @@ static size_t rhash_get_magnet_url_size(const char* filepath, } if (filepath) { - size += 4 + rhash_urlencode(NULL, filepath); + size += 4 + rhash_urlencode(NULL, filepath, strlen(filepath), 0); } /* loop through hash values */ @@ -605,34 +473,20 @@ static size_t rhash_get_magnet_url_size(const char* filepath, size += (7 + 2) + strlen(name); size += rhash_print(NULL, context, bit, - (bit & (RHASH_SHA1 | RHASH_BTIH) ? RHPR_BASE32 : 0)); + (bit & RHASH_SHA1 ? RHPR_BASE32 : 0)); } return size; } -/** - * Print magnet link with given filepath and calculated hash sums into the - * output buffer. The hash_mask can limit which hash values will be printed. - * The function returns the size of the required buffer. - * If output is NULL the . - * - * @param output a string buffer to receive the magnet link or NULL - * @param filepath the file path to be printed or NULL - * @param context algorithms state - * @param hash_mask bit mask of the hash sums to add to the link - * @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET, - * RHPR_FILESIZE - * @return number of written characters, including terminating '\0' on success, 0 on fail - */ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, rhash context, unsigned hash_mask, int flags) { int i; const char* begin = output; - if (output == NULL) return rhash_get_magnet_url_size( - filepath, context, hash_mask, flags); + if (output == NULL) + return rhash_get_magnet_url_size(filepath, context, hash_mask, flags); /* RHPR_NO_MAGNET, RHPR_FILESIZE */ if ((flags & RHPR_NO_MAGNET) == 0) { @@ -647,13 +501,13 @@ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, *(output++) = '&'; } + flags &= RHPR_UPPERCASE; if (filepath) { strcpy(output, "dn="); output += 3; - output += rhash_urlencode(output, filepath); + output += rhash_urlencode(output, filepath, strlen(filepath), flags); *(output++) = '&'; } - flags &= RHPR_UPPERCASE; for (i = 0; i < 2; i++) { unsigned bit; @@ -674,7 +528,7 @@ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, output += strlen(name); *(output++) = ':'; output += rhash_print(output, context, bit, - (bit & (RHASH_SHA1 | RHASH_BTIH) ? flags | RHPR_BASE32 : flags)); + (bit & RHASH_SHA1 ? flags | RHPR_BASE32 : flags)); *(output++) = '&'; } } @@ -683,62 +537,39 @@ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, return (output - begin); } -/* hash sum output */ -/** - * Print a text presentation of a given hash sum to the specified buffer, - * - * @param output a buffer to print the hash to - * @param bytes a hash sum to print - * @param size a size of hash sum in bytes - * @param flags a bit-mask controlling how to format the hash sum, - * can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32, - * RHPR_BASE64, RHPR_UPPERCASE, RHPR_REVERSE - * @return the number of written characters - */ -size_t rhash_print_bytes(char* output, const unsigned char* bytes, - size_t size, int flags) +/* HASH SUM OUTPUT INTERFACE */ + +size_t rhash_print_bytes(char* output, const unsigned char* bytes, size_t size, int flags) { - size_t str_len; + size_t result_length; int upper_case = (flags & RHPR_UPPERCASE); int format = (flags & ~RHPR_MODIFIER); switch (format) { case RHPR_HEX: - str_len = size * 2; - rhash_byte_to_hex(output, bytes, (unsigned)size, upper_case); + result_length = size * 2; + rhash_byte_to_hex(output, bytes, size, upper_case); break; case RHPR_BASE32: - str_len = BASE32_LENGTH(size); - rhash_byte_to_base32(output, bytes, (unsigned)size, upper_case); + result_length = BASE32_LENGTH(size); + rhash_byte_to_base32(output, bytes, size, upper_case); break; case RHPR_BASE64: - str_len = BASE64_LENGTH(size); - rhash_byte_to_base64(output, bytes, (unsigned)size); + result_length = rhash_base64_url_encoded_helper(output, bytes, size, (flags & RHPR_URLENCODE), upper_case); break; default: - str_len = size; - memcpy(output, bytes, size); + if (flags & RHPR_URLENCODE) { + result_length = rhash_urlencode(output, (char*)bytes, size, upper_case); + } else { + memcpy(output, bytes, size); + result_length = size; + } break; } - return str_len; + return result_length; } -/** - * Print text presentation of a hash sum with given hash_id to the specified - * output buffer. If the hash_id is zero, then print the hash sum with - * the lowest id stored in the hash context. - * The function call fails if the context doesn't include a hash with the - * given hash_id. - * - * @param output a buffer to print the hash to - * @param context algorithms state - * @param hash_id id of the hash sum to print or 0 to print the first hash - * saved in the context. - * @param flags a bitmask controlling how to print the hash. Can contain flags - * RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc. - * @return the number of written characters on success or 0 on fail - */ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int flags) { const rhash_info* info; @@ -759,15 +590,16 @@ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int } if (output == NULL) { + size_t multiplier = (flags & RHPR_URLENCODE ? 3 : 1); switch (flags & RHPR_FORMAT) { case RHPR_HEX: return (digest_size * 2); case RHPR_BASE32: return BASE32_LENGTH(digest_size); case RHPR_BASE64: - return BASE64_LENGTH(digest_size); + return BASE64_LENGTH(digest_size) * multiplier; default: - return digest_size; + return digest_size * multiplier; } } @@ -776,7 +608,8 @@ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int if ((flags & ~RHPR_UPPERCASE) == (RHPR_REVERSE | RHPR_HEX)) { /* reverse the digest */ - unsigned char *p = digest, *r = digest + digest_size - 1; + unsigned char* p = digest; + unsigned char* r = digest + digest_size - 1; char tmp; for (; p < r; p++, r--) { tmp = *p; @@ -788,7 +621,7 @@ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int return rhash_print_bytes(output, digest, digest_size, flags); } -#if defined(_WIN32) && defined(RHASH_EXPORTS) +#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS) #include <windows.h> BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved); BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved) @@ -850,17 +683,8 @@ static rhash_uptr_t process_bt_msg(unsigned msg_id, torrent_ctx* bt, rhash_uptr_ return 0; } -#define PVOID2UPTR(p) ((rhash_uptr_t)((char*)p - 0)) +#define PVOID2UPTR(p) ((rhash_uptr_t)(((char*)(p)) + 0)) -/** - * Process a rhash message. - * - * @param msg_id message identifier - * @param dst message destination (can be NULL for generic messages) - * @param ldata data depending on message - * @param rdata data depending on message - * @return message-specific data - */ RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata) { /* for messages working with rhash context */ @@ -901,6 +725,10 @@ RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t l case RMSG_GET_OPENSSL_MASK: return rhash_openssl_hash_mask; #endif + case RMSG_GET_OPENSSL_SUPPORTED_MASK: + return rhash_get_openssl_supported_hash_mask(); + case RMSG_GET_OPENSSL_AVAILABLE_MASK: + return rhash_get_openssl_available_hash_mask(); /* BitTorrent related messages */ case RMSG_BT_ADD_FILE: diff --git a/librhash/rhash.h b/librhash/rhash.h index 4276938..d0cb2f2 100644 --- a/librhash/rhash.h +++ b/librhash/rhash.h @@ -9,7 +9,9 @@ extern "C" { #endif #ifndef RHASH_API -/* modifier for LibRHash functions */ +/** + * Modifier for LibRHash functions + */ # define RHASH_API #endif @@ -31,11 +33,11 @@ enum rhash_ids RHASH_AICH = 0x100, RHASH_WHIRLPOOL = 0x200, RHASH_RIPEMD160 = 0x400, - RHASH_GOST = 0x800, - RHASH_GOST_CRYPTOPRO = 0x1000, - RHASH_HAS160 = 0x2000, - RHASH_SNEFRU128 = 0x4000, - RHASH_SNEFRU256 = 0x8000, + RHASH_GOST94 = 0x800, + RHASH_GOST94_CRYPTOPRO = 0x1000, + RHASH_HAS160 = 0x2000, + RHASH_GOST12_256 = 0x4000, + RHASH_GOST12_512 = 0x8000, RHASH_SHA224 = 0x10000, RHASH_SHA256 = 0x20000, RHASH_SHA384 = 0x40000, @@ -46,30 +48,42 @@ enum rhash_ids RHASH_SHA3_256 = 0x0800000, RHASH_SHA3_384 = 0x1000000, RHASH_SHA3_512 = 0x2000000, + RHASH_CRC32C = 0x4000000, + RHASH_SNEFRU128 = 0x8000000, + RHASH_SNEFRU256 = 0x10000000, - /** The bit-mask containing all supported hashe functions */ - RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_MD4 | RHASH_MD5 | RHASH_ED2K | RHASH_SHA1 | - RHASH_TIGER | RHASH_TTH | RHASH_GOST | RHASH_GOST_CRYPTOPRO | + /** + * The bit-mask containing all supported hashe functions. + */ + RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_CRC32C | RHASH_MD4 | RHASH_MD5 | + RHASH_ED2K | RHASH_SHA1 |RHASH_TIGER | RHASH_TTH | + RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO | RHASH_GOST12_256 | RHASH_GOST12_512 | RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 | RHASH_HAS160 | RHASH_SNEFRU128 | RHASH_SNEFRU256 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 | RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512 | RHASH_EDONR256 | RHASH_EDONR512, - /** The number of supported hash functions */ - RHASH_HASH_COUNT = 26 + RHASH_GOST = RHASH_GOST94, /* deprecated constant name */ + RHASH_GOST_CRYPTOPRO = RHASH_GOST94_CRYPTOPRO, /* deprecated constant name */ + /** + * The number of supported hash functions. + */ + RHASH_HASH_COUNT = 29 }; /** - * The rhash context structure contains contexts for several hash functions + * The rhash context structure contains contexts for several hash functions. */ typedef struct rhash_context { - /** The size of the hashed message */ + /** + * The size of the hashed message. + */ unsigned long long msg_size; /** - * The bit-mask containing identifiers of the hashes being calculated + * The bit-mask containing identifiers of the hashes being calculated. */ unsigned hash_id; } rhash_context; @@ -82,107 +96,283 @@ typedef struct rhash_context typedef struct rhash_context* rhash; #endif /* LIBRHASH_RHASH_CTX_DEFINED */ -/** type of a callback to be called periodically while hashing a file */ +/** + * Type of a callback to be called periodically while hashing a file. + */ typedef void (*rhash_callback_t)(void* data, unsigned long long offset); -RHASH_API void rhash_library_init(void); /* initialize static data */ +/** + * Initialize static data of rhash algorithms + */ +RHASH_API void rhash_library_init(void); -/* hi-level hashing functions */ + +/* HIGH-LEVEL LIBRHASH INTERFACE */ + +/** + * Compute a hash of the given message. + * + * @param hash_id id of hash sum to compute + * @param message the message to process + * @param length message length + * @param result buffer to receive binary hash string + * @return 0 on success, -1 on error + */ RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result); + +/** + * Compute a single hash for given file. + * + * @param hash_id id of hash sum to compute + * @param filepath path to the file to hash + * @param result buffer to receive hash value with the lowest requested id + * @return 0 on success, -1 on error and errno is set + */ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result); -RHASH_API int rhash_file_update(rhash ctx, FILE* fd); -#ifdef _WIN32 /* windows only function */ +#ifdef _WIN32 +/** + * Compute a single hash for given file (Windows-specific function). + * + * @param hash_id id of hash sum to compute + * @param filepath path to the file to hash + * @param result buffer to receive hash value with the lowest requested id + * @return 0 on success, -1 on error, -1 on error and errno is set + */ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result); #endif -/* lo-level interface */ + +/* LOW-LEVEL LIBRHASH INTERFACE */ + +/** + * Allocate and initialize RHash context for calculating hash(es). + * After initializing rhash_update()/rhash_final() functions should be used. + * Then the context must be freed by calling rhash_free(). + * + * @param hash_id union of bit flags, containing ids of hashes to calculate. + * @return initialized rhash context, NULL on error and errno is set + */ RHASH_API rhash rhash_init(unsigned hash_id); -/*RHASH_API rhash rhash_init_by_ids(unsigned hash_ids[], unsigned count);*/ -RHASH_API int rhash_update(rhash ctx, const void* message, size_t length); -RHASH_API int rhash_final(rhash ctx, unsigned char* first_result); -RHASH_API void rhash_reset(rhash ctx); /* reinitialize the context */ + +/** + * Calculate hashes of message. + * Can be called repeatedly with chunks of the message to be hashed. + * + * @param ctx the rhash context + * @param message message chunk + * @param length length of the message chunk + * @return 0 on success; On fail return -1 and set errno + */ +RHASH_API int rhash_update(rhash ctx, const void* message, size_t length); + +/** + * Hash a file or stream. Multiple hashes can be computed. + * First, inintialize ctx parameter with rhash_init() before calling + * rhash_file_update(). Then use rhash_final() and rhash_print() + * to retrive hash values. Finaly call rhash_free() on ctx + * to free allocated memory or call rhash_reset() to reuse ctx. + * + * @param ctx rhash context + * @param fd descriptor of the file to hash + * @return 0 on success, -1 on error and errno is set + */ +RHASH_API int rhash_file_update(rhash ctx, FILE* fd); + +/** + * Finalize hash calculation and optionally store the first hash. + * + * @param ctx the rhash context + * @param first_result optional buffer to store a calculated hash with the lowest available id + * @return 0 on success; On fail return -1 and set errno + */ +RHASH_API int rhash_final(rhash ctx, unsigned char* first_result); + +/** + * Re-initialize RHash context to reuse it. + * Useful to speed up processing of many small messages. + * + * @param ctx context to reinitialize + */ +RHASH_API void rhash_reset(rhash ctx); + +/** + * Free RHash context memory. + * + * @param ctx the context to free. + */ RHASH_API void rhash_free(rhash ctx); -/* additional lo-level functions */ +/** + * Set the callback function to be called from the + * rhash_file() and rhash_file_update() functions + * on processing every file block. The file block + * size is set internally by rhash and now is 8 KiB. + * + * @param ctx rhash context + * @param callback pointer to the callback function + * @param callback_data pointer to data passed to the callback + */ RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data); -/** bit-flag: default hash output format is base32 */ -#define RHASH_INFO_BASE32 1 + +/* INFORMATION FUNCTIONS */ /** - * Information about a hash function. + * Returns the number of supported hash algorithms. + * + * @return the number of supported hash functions */ -typedef struct rhash_info -{ - /** hash function indentifier */ - unsigned hash_id; - /** flags bit-mask, including RHASH_INFO_BASE32 bit */ - unsigned flags; - /** size of binary message digest in bytes */ - size_t digest_size; - const char* name; - const char* magnet_name; -} rhash_info; - -/* information functions */ RHASH_API int rhash_count(void); /* number of supported hashes */ + +/** + * Returns size of binary digest for given hash algorithm. + * + * @param hash_id the id of hash algorithm + * @return digest size in bytes + */ RHASH_API int rhash_get_digest_size(unsigned hash_id); /* size of binary message digest */ + +/** + * Returns length of digest hash string in default output format. + * + * @param hash_id the id of hash algorithm + * @return the length of hash string + */ RHASH_API int rhash_get_hash_length(unsigned hash_id); /* length of formatted hash string */ + +/** + * Detect default digest output format for given hash algorithm. + * + * @param hash_id the id of hash algorithm + * @return 1 for base32 format, 0 for hexadecimal + */ RHASH_API int rhash_is_base32(unsigned hash_id); /* default digest output format */ + +/** + * Returns a name of given hash algorithm. + * + * @param hash_id the id of hash algorithm + * @return algorithm name + */ RHASH_API const char* rhash_get_name(unsigned hash_id); /* get hash function name */ + +/** + * Returns a name part of magnet urn of the given hash algorithm. + * Such magnet_name is used to generate a magnet link of the form + * urn:<magnet_name>=<hash_value>. + * + * @param hash_id the id of hash algorithm + * @return name + */ RHASH_API const char* rhash_get_magnet_name(unsigned hash_id); /* get name part of magnet urn */ -/* note, that rhash_info_by_id() is not exported to a shared library or DLL */ -const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */ +/* HASH SUM OUTPUT INTERFACE */ /** - * Flags for printing a hash sum + * Flags for printing a hash sum. */ enum rhash_print_sum_flags { - /** print in a default format */ + /* + * Print in a default format + */ RHPR_DEFAULT = 0x0, - /** output as binary message digest */ + /* + * Output as binary message digest + */ RHPR_RAW = 0x1, - /** print as a hexadecimal string */ + /* + * Print as a hexadecimal string + */ RHPR_HEX = 0x2, - /** print as a base32-encoded string */ + /* + * Print as a base32-encoded string + */ RHPR_BASE32 = 0x3, - /** print as a base64-encoded string */ + /* + * Print as a base64-encoded string + */ RHPR_BASE64 = 0x4, - - /** + /* * Print as an uppercase string. Can be used * for base32 or hexadecimal format only. */ RHPR_UPPERCASE = 0x8, - - /** + /* * Reverse hash bytes. Can be used for GOST hash. */ RHPR_REVERSE = 0x10, - - /** don't print 'magnet:?' prefix in rhash_print_magnet */ + /* + * Don't print 'magnet:?' prefix in rhash_print_magnet + */ RHPR_NO_MAGNET = 0x20, - /** print file size in rhash_print_magnet */ + /* + * Print file size in rhash_print_magnet + */ RHPR_FILESIZE = 0x40, + /* + * Print as URL-encoded string + */ + RHPR_URLENCODE = 0x80 }; -/* output hash into the given buffer */ + +/** + * Print a text presentation of a given hash sum to the specified buffer. + * + * @param output a buffer to print the hash to + * @param bytes a hash sum to print + * @param size a size of hash sum in bytes + * @param flags a bit-mask controlling how to format the hash sum, + * can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32, + * RHPR_BASE64, RHPR_URLENCODE, RHPR_UPPERCASE, RHPR_REVERSE + * @return the number of written characters + */ RHASH_API size_t rhash_print_bytes(char* output, const unsigned char* bytes, size_t size, int flags); +/** + * Print text presentation of a hash sum with given hash_id to the specified + * output buffer. If the hash_id is zero, then print the hash sum with + * the lowest id stored in the hash context. + * The function call fails if the context doesn't include a hash with the + * given hash_id. + * + * @param output a buffer to print the hash to + * @param context algorithms state + * @param hash_id id of the hash sum to print or 0 to print the first hash + * saved in the context. + * @param flags a bitmask controlling how to print the hash. Can contain flags + * RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc. + * @return the number of written characters on success or 0 on fail + */ RHASH_API size_t rhash_print(char* output, rhash ctx, unsigned hash_id, int flags); -/* output magnet URL into the given buffer */ +/** + * Print magnet link with given filepath and calculated hash sums into the + * output buffer. The hash_mask can limit which hash values will be printed. + * The function returns the size of the required buffer. + * If output is NULL the . + * + * @param output a string buffer to receive the magnet link or NULL + * @param filepath the file path to be printed or NULL + * @param context algorithms state + * @param hash_mask bit mask of the hash sums to add to the link + * @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET, + * RHPR_FILESIZE + * @return number of written characters, including terminating '\0' on success, 0 on fail + */ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, rhash context, unsigned hash_mask, int flags); -/* macros for message API */ -/** The type of an unsigned integer large enough to hold a pointer */ +/* MESSAGE API */ + +/** + * The type of an unsigned integer large enough to hold a pointer. + */ #if defined(UINTPTR_MAX) typedef uintptr_t rhash_uptr_t; #elif defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \ @@ -192,14 +382,28 @@ typedef unsigned long long rhash_uptr_t; typedef unsigned long rhash_uptr_t; #endif -/** The value returned by rhash_transmit on error */ +/** + * The value returned by rhash_transmit on error. + */ #define RHASH_ERROR ((rhash_uptr_t)-1) -/** Convert a pointer to rhash_uptr_t */ +/** + * Convert a pointer to rhash_uptr_t. + */ #define RHASH_STR2UPTR(str) ((rhash_uptr_t)(char*)(str)) -/** Convert a rhash_uptr_t to a void* pointer */ -#define RHASH_UPTR2PVOID(u) ((void*)((char*)0 + (u))) +/** + * Convert a rhash_uptr_t to a void* pointer. + */ +#define RHASH_UPTR2PVOID(u) ((void*)((u) + 0)) -/* rhash API to set/get data via messages */ +/** + * Process a rhash message. + * + * @param msg_id message identifier + * @param dst message destination (can be NULL for generic messages) + * @param ldata data depending on message + * @param rdata data depending on message + * @return message-specific data + */ RHASH_API rhash_uptr_t rhash_transmit( unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata); @@ -212,6 +416,8 @@ RHASH_API rhash_uptr_t rhash_transmit( #define RMSG_SET_AUTOFINAL 5 #define RMSG_SET_OPENSSL_MASK 10 #define RMSG_GET_OPENSSL_MASK 11 +#define RMSG_GET_OPENSSL_SUPPORTED_MASK 12 +#define RMSG_GET_OPENSSL_AVAILABLE_MASK 13 #define RMSG_BT_ADD_FILE 32 #define RMSG_BT_SET_OPTIONS 33 @@ -221,25 +427,39 @@ RHASH_API rhash_uptr_t rhash_transmit( #define RMSG_BT_GET_TEXT 37 #define RMSG_BT_SET_BATCH_SIZE 38 -/* possible BitTorrent options for the RMSG_BT_SET_OPTIONS message */ +/** + * RMSG_BT_SET_OPTIONS message option: generate private BitTorrent. + */ #define RHASH_BT_OPT_PRIVATE 1 +/** + * RMSG_BT_SET_OPTIONS message option: calculate infohash without torrent file body. + */ #define RHASH_BT_OPT_INFOHASH_ONLY 2 -/* helper macros */ -/** Get a pointer to context of the specified hash function */ +/* HELPER MACROS */ + +/** + * Get a pointer to context of the specified hash function. + */ #define rhash_get_context_ptr(ctx, hash_id) RHASH_UPTR2PVOID(rhash_transmit(RMSG_GET_CONTEXT, ctx, hash_id, 0)) -/** Cancel hash calculation of a file */ +/** + * Cancel hash calculation of a file. + */ #define rhash_cancel(ctx) rhash_transmit(RMSG_CANCEL, ctx, 0, 0) -/** Return non-zero if hash calculation was canceled, zero otherwise */ +/** + * Return non-zero if hash calculation was canceled, zero otherwise. + */ #define rhash_is_canceled(ctx) rhash_transmit(RMSG_IS_CANCELED, ctx, 0, 0) -/** Return non-zero if rhash_final was called for rhash_context */ +/** + * Return non-zero if rhash_final was called for rhash_context. + */ #define rhash_get_finalized(ctx) rhash_transmit(RMSG_GET_FINALIZED, ctx, 0, 0) /** * Turn on/off the auto-final flag for the given rhash_context. By default * auto-final is on, which means rhash_final is called automatically, if - * needed when a hash value is retrived by rhash_print call. + * needed when a hash value is retrieved by rhash_print call. */ #define rhash_set_autofinal(ctx, on) rhash_transmit(RMSG_SET_AUTOFINAL, ctx, on, 0) @@ -252,19 +472,36 @@ RHASH_API rhash_uptr_t rhash_transmit( #define rhash_set_openssl_mask(mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, NULL, mask, 0) /** - * Return current bit-mask of hash algorithms selected to be calculated - * by OpenSSL library. + * Return current bit-mask of hash algorithms selected to be calculated by OpenSSL + * library. Return RHASH_ERROR if LibRHash is compiled without OpenSSL support. */ #define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0) -/** The bit mask of hash algorithms implemented by OpenSSL */ -#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) -# define RHASH_OPENSSL_SUPPORTED_HASHES (RHASH_MD4 | RHASH_MD5 | \ - RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | \ - RHASH_SHA512 | RHASH_RIPEMD160 | RHASH_WHIRLPOOL) -#else -# define RHASH_OPENSSL_SUPPORTED_HASHES 0 -#endif +/** + * Return the bit-mask of algorithms that can be provided by the OpenSSL plugin, + * if the library is compiled with OpenSSL support, 0 otherwise. This bit-mask is + * a constant value computed at compile-time. + */ +#define rhash_get_openssl_supported_mask() rhash_transmit(RMSG_GET_OPENSSL_SUPPORTED_MASK, NULL, 0, 0) + +/** + * Return the bit-mask of algorithms that are successfully loaded from + * OpenSSL library. If the library is not loaded or not supported by LibRHash, + * then return 0. + */ +#define rhash_get_openssl_available_mask() rhash_transmit(RMSG_GET_OPENSSL_AVAILABLE_MASK, NULL, 0, 0) + + +/** + * Return non-zero if LibRHash hash been compiled with OpenSSL support, + * and zero otherwise. + */ +#define rhash_is_openssl_supported() (rhash_get_openssl_mask() != RHASH_ERROR) + +/** + * Legacy macro. The bit mask of hash algorithms implemented by OpenSSL. + */ +# define RHASH_OPENSSL_SUPPORTED_HASHES (rhash_get_openssl_supported_mask()) #ifdef __cplusplus } /* extern "C" */ diff --git a/librhash/sha1.c b/librhash/sha1.c index f5a053b..b226925 100644 --- a/librhash/sha1.c +++ b/librhash/sha1.c @@ -1,18 +1,18 @@ /* sha1.c - an implementation of Secure Hash Algorithm 1 (SHA1) * based on RFC 3174. * - * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com> * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <string.h> @@ -24,7 +24,7 @@ * * @param ctx context to initialize */ -void rhash_sha1_init(sha1_ctx *ctx) +void rhash_sha1_init(sha1_ctx* ctx) { ctx->length = 0; @@ -121,7 +121,7 @@ static void rhash_sha1_process_block(unsigned* hash, const unsigned* block) * @param msg message chunk * @param size length of the message chunk */ -void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size) +void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size) { unsigned index = (unsigned)ctx->length & 63; ctx->length += size; @@ -164,7 +164,7 @@ void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result) +void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result) { unsigned index = (unsigned)ctx->length & 63; unsigned* msg32 = (unsigned*)ctx->message; diff --git a/librhash/sha1.h b/librhash/sha1.h index 74b2f94..7e99542 100644 --- a/librhash/sha1.h +++ b/librhash/sha1.h @@ -20,9 +20,9 @@ typedef struct sha1_ctx /* hash functions */ -void rhash_sha1_init(sha1_ctx *ctx); -void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size); -void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result); +void rhash_sha1_init(sha1_ctx* ctx); +void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size); +void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result); #ifdef __cplusplus } /* extern "C" */ diff --git a/librhash/sha256.c b/librhash/sha256.c index 064dfe2..21a69aa 100644 --- a/librhash/sha256.c +++ b/librhash/sha256.c @@ -1,18 +1,18 @@ /* sha256.c - an implementation of SHA-256/224 hash functions * based on FIPS 180-3 (Federal Information Processing Standart). * - * Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2010, Aleksey Kravchenko <rhash.admin@gmail.com> * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <string.h> @@ -65,7 +65,7 @@ static const unsigned rhash_k256[64] = { * * @param ctx context to initialize */ -void rhash_sha256_init(sha256_ctx *ctx) +void rhash_sha256_init(sha256_ctx* ctx) { /* Initial values. These words were obtained by taking the first 32 * bits of the fractional parts of the square roots of the first @@ -87,7 +87,7 @@ void rhash_sha256_init(sha256_ctx *ctx) * * @param ctx context to initialize */ -void rhash_sha224_init(struct sha256_ctx *ctx) +void rhash_sha224_init(struct sha256_ctx* ctx) { /* Initial values from FIPS 180-3. These words were obtained by taking * bits from 33th to 64th of the fractional parts of the square @@ -113,7 +113,7 @@ static void rhash_sha256_process_block(unsigned hash[8], unsigned block[16]) { unsigned A, B, C, D, E, F, G, H; unsigned W[16]; - const unsigned *k; + const unsigned* k; int i; A = hash[0], B = hash[1], C = hash[2], D = hash[3]; @@ -168,7 +168,7 @@ static void rhash_sha256_process_block(unsigned hash[8], unsigned block[16]) * @param msg message chunk * @param size length of the message chunk */ -void rhash_sha256_update(sha256_ctx *ctx, const unsigned char *msg, size_t size) +void rhash_sha256_update(sha256_ctx* ctx, const unsigned char* msg, size_t size) { size_t index = (size_t)ctx->length & 63; ctx->length += size; @@ -210,7 +210,7 @@ void rhash_sha256_update(sha256_ctx *ctx, const unsigned char *msg, size_t size) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_sha256_final(sha256_ctx *ctx, unsigned char* result) +void rhash_sha256_final(sha256_ctx* ctx, unsigned char* result) { size_t index = ((unsigned)ctx->length & 63) >> 2; unsigned shift = ((unsigned)ctx->length & 3) * 8; @@ -218,8 +218,8 @@ void rhash_sha256_final(sha256_ctx *ctx, unsigned char* result) /* pad message and run for last block */ /* append the byte 0x80 to the message */ - ctx->message[index] &= le2me_32(~(0xFFFFFFFF << shift)); - ctx->message[index++] ^= le2me_32(0x80 << shift); + ctx->message[index] &= le2me_32(~(0xFFFFFFFFu << shift)); + ctx->message[index++] ^= le2me_32(0x80u << shift); /* if no room left in the message to store 64-bit message length */ if (index > 14) { diff --git a/librhash/sha256.h b/librhash/sha256.h index f87ebaa..3625cfe 100644 --- a/librhash/sha256.h +++ b/librhash/sha256.h @@ -20,10 +20,10 @@ typedef struct sha256_ctx unsigned digest_length; /* length of the algorithm digest in bytes */ } sha256_ctx; -void rhash_sha224_init(sha256_ctx *ctx); -void rhash_sha256_init(sha256_ctx *ctx); -void rhash_sha256_update(sha256_ctx *ctx, const unsigned char* data, size_t length); -void rhash_sha256_final(sha256_ctx *ctx, unsigned char result[32]); +void rhash_sha224_init(sha256_ctx* ctx); +void rhash_sha256_init(sha256_ctx* ctx); +void rhash_sha256_update(sha256_ctx* ctx, const unsigned char* data, size_t length); +void rhash_sha256_final(sha256_ctx* ctx, unsigned char result[32]); #ifdef __cplusplus } /* extern "C" */ diff --git a/librhash/sha3.c b/librhash/sha3.c index e4a845f..bd2854f 100644 --- a/librhash/sha3.c +++ b/librhash/sha3.c @@ -3,18 +3,18 @@ * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011 * by Guido Bertoni, Joan Daemen, Michaƫl Peeters and Gilles Van Assche * - * Copyright: 2013 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2013, Aleksey Kravchenko <rhash.admin@gmail.com> * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <assert.h> @@ -36,7 +36,7 @@ static uint64_t keccak_round_constants[NumberOfRounds] = { }; /* Initializing a sha3 context for given number of output bits */ -static void rhash_keccak_init(sha3_ctx *ctx, unsigned bits) +static void rhash_keccak_init(sha3_ctx* ctx, unsigned bits) { /* NB: The Keccak capacity parameter = bits * 2 */ unsigned rate = 1600 - bits * 2; @@ -51,7 +51,7 @@ static void rhash_keccak_init(sha3_ctx *ctx, unsigned bits) * * @param ctx context to initialize */ -void rhash_sha3_224_init(sha3_ctx *ctx) +void rhash_sha3_224_init(sha3_ctx* ctx) { rhash_keccak_init(ctx, 224); } @@ -61,7 +61,7 @@ void rhash_sha3_224_init(sha3_ctx *ctx) * * @param ctx context to initialize */ -void rhash_sha3_256_init(sha3_ctx *ctx) +void rhash_sha3_256_init(sha3_ctx* ctx) { rhash_keccak_init(ctx, 256); } @@ -71,7 +71,7 @@ void rhash_sha3_256_init(sha3_ctx *ctx) * * @param ctx context to initialize */ -void rhash_sha3_384_init(sha3_ctx *ctx) +void rhash_sha3_384_init(sha3_ctx* ctx) { rhash_keccak_init(ctx, 384); } @@ -81,37 +81,37 @@ void rhash_sha3_384_init(sha3_ctx *ctx) * * @param ctx context to initialize */ -void rhash_sha3_512_init(sha3_ctx *ctx) +void rhash_sha3_512_init(sha3_ctx* ctx) { rhash_keccak_init(ctx, 512); } +#define XORED_A(i) A[(i)] ^ A[(i) + 5] ^ A[(i) + 10] ^ A[(i) + 15] ^ A[(i) + 20] +#define THETA_STEP(i) \ + A[(i)] ^= D[(i)]; \ + A[(i) + 5] ^= D[(i)]; \ + A[(i) + 10] ^= D[(i)]; \ + A[(i) + 15] ^= D[(i)]; \ + A[(i) + 20] ^= D[(i)] \ + /* Keccak theta() transformation */ -static void keccak_theta(uint64_t *A) +static void keccak_theta(uint64_t* A) { - unsigned int x; - uint64_t C[5], D[5]; - - for (x = 0; x < 5; x++) { - C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20]; - } - D[0] = ROTL64(C[1], 1) ^ C[4]; - D[1] = ROTL64(C[2], 1) ^ C[0]; - D[2] = ROTL64(C[3], 1) ^ C[1]; - D[3] = ROTL64(C[4], 1) ^ C[2]; - D[4] = ROTL64(C[0], 1) ^ C[3]; - - for (x = 0; x < 5; x++) { - A[x] ^= D[x]; - A[x + 5] ^= D[x]; - A[x + 10] ^= D[x]; - A[x + 15] ^= D[x]; - A[x + 20] ^= D[x]; - } + uint64_t D[5]; + D[0] = ROTL64(XORED_A(1), 1) ^ XORED_A(4); + D[1] = ROTL64(XORED_A(2), 1) ^ XORED_A(0); + D[2] = ROTL64(XORED_A(3), 1) ^ XORED_A(1); + D[3] = ROTL64(XORED_A(4), 1) ^ XORED_A(2); + D[4] = ROTL64(XORED_A(0), 1) ^ XORED_A(3); + THETA_STEP(0); + THETA_STEP(1); + THETA_STEP(2); + THETA_STEP(3); + THETA_STEP(4); } /* Keccak pi() transformation */ -static void keccak_pi(uint64_t *A) +static void keccak_pi(uint64_t* A) { uint64_t A1; A1 = A[1]; @@ -142,21 +142,27 @@ static void keccak_pi(uint64_t *A) /* note: A[ 0] is left as is */ } +#define CHI_STEP(i) \ + A0 = A[0 + (i)]; \ + A1 = A[1 + (i)]; \ + A[0 + (i)] ^= ~A1 & A[2 + (i)]; \ + A[1 + (i)] ^= ~A[2 + (i)] & A[3 + (i)]; \ + A[2 + (i)] ^= ~A[3 + (i)] & A[4 + (i)]; \ + A[3 + (i)] ^= ~A[4 + (i)] & A0; \ + A[4 + (i)] ^= ~A0 & A1 \ + /* Keccak chi() transformation */ -static void keccak_chi(uint64_t *A) +static void keccak_chi(uint64_t* A) { - int i; - for (i = 0; i < 25; i += 5) { - uint64_t A0 = A[0 + i], A1 = A[1 + i]; - A[0 + i] ^= ~A1 & A[2 + i]; - A[1 + i] ^= ~A[2 + i] & A[3 + i]; - A[2 + i] ^= ~A[3 + i] & A[4 + i]; - A[3 + i] ^= ~A[4 + i] & A0; - A[4 + i] ^= ~A0 & A1; - } + uint64_t A0, A1; + CHI_STEP(0); + CHI_STEP(5); + CHI_STEP(10); + CHI_STEP(15); + CHI_STEP(20); } -static void rhash_sha3_permutation(uint64_t *state) +static void rhash_sha3_permutation(uint64_t* state) { int round; for (round = 0; round < NumberOfRounds; round++) @@ -204,7 +210,7 @@ static void rhash_sha3_permutation(uint64_t *state) * @param block the message block to process * @param block_size the size of the processed block in bytes */ -static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size) +static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t* block, size_t block_size) { /* expanded loop */ hash[ 0] ^= le2me_64(block[ 0]); @@ -260,7 +266,7 @@ static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t *block, s * @param msg message chunk * @param size length of the message chunk */ -void rhash_sha3_update(sha3_ctx *ctx, const unsigned char *msg, size_t size) +void rhash_sha3_update(sha3_ctx* ctx, const unsigned char* msg, size_t size) { size_t index = (size_t)ctx->rest; size_t block_size = (size_t)ctx->block_size; @@ -305,7 +311,7 @@ void rhash_sha3_update(sha3_ctx *ctx, const unsigned char *msg, size_t size) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result) +void rhash_sha3_final(sha3_ctx* ctx, unsigned char* result) { size_t digest_length = 100 - ctx->block_size / 2; const size_t block_size = ctx->block_size; @@ -333,7 +339,7 @@ void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result) +void rhash_keccak_final(sha3_ctx* ctx, unsigned char* result) { size_t digest_length = 100 - ctx->block_size / 2; const size_t block_size = ctx->block_size; diff --git a/librhash/sha3.h b/librhash/sha3.h index 2831997..e00041d 100644 --- a/librhash/sha3.h +++ b/librhash/sha3.h @@ -31,12 +31,12 @@ typedef struct sha3_ctx /* methods for calculating the hash function */ -void rhash_sha3_224_init(sha3_ctx *ctx); -void rhash_sha3_256_init(sha3_ctx *ctx); -void rhash_sha3_384_init(sha3_ctx *ctx); -void rhash_sha3_512_init(sha3_ctx *ctx); -void rhash_sha3_update(sha3_ctx *ctx, const unsigned char* msg, size_t size); -void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result); +void rhash_sha3_224_init(sha3_ctx* ctx); +void rhash_sha3_256_init(sha3_ctx* ctx); +void rhash_sha3_384_init(sha3_ctx* ctx); +void rhash_sha3_512_init(sha3_ctx* ctx); +void rhash_sha3_update(sha3_ctx* ctx, const unsigned char* msg, size_t size); +void rhash_sha3_final(sha3_ctx* ctx, unsigned char* result); #ifdef USE_KECCAK #define rhash_keccak_224_init rhash_sha3_224_init @@ -44,7 +44,7 @@ void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result); #define rhash_keccak_384_init rhash_sha3_384_init #define rhash_keccak_512_init rhash_sha3_512_init #define rhash_keccak_update rhash_sha3_update -void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result); +void rhash_keccak_final(sha3_ctx* ctx, unsigned char* result); #endif #ifdef __cplusplus diff --git a/librhash/sha512.c b/librhash/sha512.c index a3e681d..555e6ef 100644 --- a/librhash/sha512.c +++ b/librhash/sha512.c @@ -1,18 +1,18 @@ /* sha512.c - an implementation of SHA-384/512 hash functions * based on FIPS 180-3 (Federal Information Processing Standart). * - * Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2010, Aleksey Kravchenko <rhash.admin@gmail.com> * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <string.h> @@ -81,7 +81,7 @@ static const uint64_t rhash_k512[80] = { * * @param ctx context to initialize */ -void rhash_sha512_init(sha512_ctx *ctx) +void rhash_sha512_init(sha512_ctx* ctx) { /* Initial values. These words were obtained by taking the first 32 * bits of the fractional parts of the square roots of the first @@ -104,7 +104,7 @@ void rhash_sha512_init(sha512_ctx *ctx) * * @param ctx context to initialize */ -void rhash_sha384_init(struct sha512_ctx *ctx) +void rhash_sha384_init(struct sha512_ctx* ctx) { /* Initial values from FIPS 180-3. These words were obtained by taking * the first sixty-four bits of the fractional parts of the square @@ -131,7 +131,7 @@ static void rhash_sha512_process_block(uint64_t hash[8], uint64_t block[16]) { uint64_t A, B, C, D, E, F, G, H; uint64_t W[16]; - const uint64_t *k; + const uint64_t* k; int i; A = hash[0], B = hash[1], C = hash[2], D = hash[3]; @@ -186,7 +186,7 @@ static void rhash_sha512_process_block(uint64_t hash[8], uint64_t block[16]) * @param msg message chunk * @param size length of the message chunk */ -void rhash_sha512_update(sha512_ctx *ctx, const unsigned char *msg, size_t size) +void rhash_sha512_update(sha512_ctx* ctx, const unsigned char* msg, size_t size) { size_t index = (size_t)ctx->length & 127; ctx->length += size; @@ -228,7 +228,7 @@ void rhash_sha512_update(sha512_ctx *ctx, const unsigned char *msg, size_t size) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_sha512_final(sha512_ctx *ctx, unsigned char* result) +void rhash_sha512_final(sha512_ctx* ctx, unsigned char* result) { size_t index = ((unsigned)ctx->length & 127) >> 3; unsigned shift = ((unsigned)ctx->length & 7) * 8; diff --git a/librhash/sha512.h b/librhash/sha512.h index 7c689be..f80ae0d 100644 --- a/librhash/sha512.h +++ b/librhash/sha512.h @@ -20,10 +20,10 @@ typedef struct sha512_ctx unsigned digest_length; /* length of the algorithm digest in bytes */ } sha512_ctx; -void rhash_sha384_init(sha512_ctx *ctx); -void rhash_sha512_init(sha512_ctx *ctx); -void rhash_sha512_update(sha512_ctx *ctx, const unsigned char* data, size_t length); -void rhash_sha512_final(sha512_ctx *ctx, unsigned char* result); +void rhash_sha384_init(sha512_ctx* ctx); +void rhash_sha512_init(sha512_ctx* ctx); +void rhash_sha512_update(sha512_ctx* ctx, const unsigned char* data, size_t length); +void rhash_sha512_final(sha512_ctx* ctx, unsigned char* result); #ifdef __cplusplus } /* extern "C" */ diff --git a/librhash/ustd.h b/librhash/ustd.h index 94f1ae2..fd09b9c 100644 --- a/librhash/ustd.h +++ b/librhash/ustd.h @@ -2,29 +2,33 @@ #ifndef LIBRHASH_USTD_H #define LIBRHASH_USTD_H -#if _MSC_VER >= 1300 - -# define int64_t __int64 -# define int32_t __int32 -# define int16_t __int16 -# define int8_t __int8 -# define uint64_t unsigned __int64 -# define uint32_t unsigned __int32 -# define uint16_t unsigned __int16 -# define uint8_t unsigned __int8 +#if _MSC_VER > 1000 +# include <stddef.h> /* size_t for vc6.0 */ + +# if _MSC_VER >= 1600 +/* Visual Studio >= 2010 has stdint.h */ +# include <stdint.h> +# else + /* vc6.0 has bug with __int8, so using char instead */ + typedef signed char int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef signed __int64 int64_t; + typedef unsigned char uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; +# endif /* _MSC_VER >= 1600 */ /* disable warnings: The POSIX name for this item is deprecated. Use the ISO C++ conformant name. */ -#pragma warning(disable : 4996) +# pragma warning(disable : 4996) -#else /* _MSC_VER >= 1300 */ +#else /* _MSC_VER > 1000 */ # include <stdint.h> # include <unistd.h> -#endif /* _MSC_VER >= 1300 */ - -#if _MSC_VER <= 1300 -# include <stdlib.h> /* size_t for vc6.0 */ -#endif /* _MSC_VER <= 1300 */ +#endif /* _MSC_VER > 1000 */ #endif /* LIBRHASH_USTD_H */ + diff --git a/librhash/util.h b/librhash/util.h index 9f37157..57cae9b 100644 --- a/librhash/util.h +++ b/librhash/util.h @@ -20,7 +20,7 @@ extern "C" { # define atomic_compare_and_swap(ptr, oldval, newval) atomic_cas_32(ptr, oldval, newval) #else /* pray that it will work */ -# define atomic_compare_and_swap(ptr, oldval, newval) { if(*(ptr) == (oldval)) *(ptr) = (newval); } +# define atomic_compare_and_swap(ptr, oldval, newval) { if (*(ptr) == (oldval)) *(ptr) = (newval); } # define NO_ATOMIC_BUILTINS #endif |