summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlibrhash upstream <kwrobot@kitware.com>2019-12-14 16:52:11 (GMT)
committerBrad King <brad.king@kitware.com>2020-03-02 21:31:07 (GMT)
commit641cc0030c45731298bcb3c237b122256d2855ae (patch)
tree886ff9d8a6783d693f61d0a5ad44a60d035cd6f3
parent7fcbd47e955d7e318f1f6dd96cc26d6737525c86 (diff)
downloadCMake-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--COPYING22
-rw-r--r--README61
-rw-r--r--librhash/algorithms.c144
-rw-r--r--librhash/algorithms.h49
-rw-r--r--librhash/byte_order.c53
-rw-r--r--librhash/byte_order.h156
-rw-r--r--librhash/hex.c170
-rw-r--r--librhash/hex.h13
-rw-r--r--librhash/md5.c30
-rw-r--r--librhash/md5.h6
-rw-r--r--librhash/rhash.c322
-rw-r--r--librhash/rhash.h401
-rw-r--r--librhash/sha1.c26
-rw-r--r--librhash/sha1.h6
-rw-r--r--librhash/sha256.c34
-rw-r--r--librhash/sha256.h8
-rw-r--r--librhash/sha3.c108
-rw-r--r--librhash/sha3.h14
-rw-r--r--librhash/sha512.c30
-rw-r--r--librhash/sha512.h8
-rw-r--r--librhash/ustd.h38
-rw-r--r--librhash/util.h2
22 files changed, 946 insertions, 755 deletions
diff --git a/COPYING b/COPYING
index bf65ee1..be7d4a9 100644
--- a/COPYING
+++ b/COPYING
@@ -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.
diff --git a/README b/README
deleted file mode 100644
index 1e51017..0000000
--- a/README
+++ /dev/null
@@ -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:&lt;magnet_name&gt;=&lt;hash_value&gt;.
- *
- * @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:&lt;magnet_name&gt;=&lt;hash_value&gt;.
+ *
+ * @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