فهرست منبع

Merge branch 'upstream-librhash' into update-librhash

* upstream-librhash:
  librhash 2019-12-14 (75716b45)
Brad King 6 سال پیش
والد
کامیت
471ebc590e

+ 11 - 11
Utilities/cmlibrhash/COPYING

@@ -1,15 +1,15 @@
 
-                                RHash License
+                           BSD Zero Clause License
 
-Copyright (c) 2005-2014 Aleksey Kravchenko <[email protected]>
+Copyright (c) 2005, Aleksey Kravchenko <[email protected]>
 
-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.

+ 0 - 7
Utilities/cmlibrhash/README

@@ -1,7 +0,0 @@
-                       === 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.

+ 104 - 42
Utilities/cmlibrhash/librhash/algorithms.c

@@ -1,17 +1,17 @@
 /* algorithms.c - the algorithms supported by the rhash library
  *
- * Copyright: 2011-2012 Aleksey Kravchenko <[email protected]>
+ * Copyright (c) 2011, Aleksey Kravchenko <[email protected]>
  *
- * 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>
@@ -27,7 +27,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"
 #endif
@@ -54,18 +55,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;
@@ -75,10 +71,14 @@ 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);
 #endif
 
 #if 0
-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" };
 #endif
 rhash_info info_md5 = { RHASH_MD5, F_LE32, 16, "MD5", "md5" };
@@ -91,8 +91,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" };
@@ -117,9 +119,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] =
 {
 #if 0
@@ -135,28 +138,35 @@ 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_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 */
 #endif
-	{ &info_sha224, sizeof(sha256_ctx), dgshft(sha256), ini(rhash_sha224), upd(rhash_sha256), fin(rhash_sha256), 0 }, /* 224 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 */
 #if 0
-	{ &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_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 */
+#endif
+	{ &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 */
+#if 0
+	{ &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 */
 #endif
-	{ &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 */
 };
 
 /**
  * Initialize requested algorithms.
+ *
+ * @param mask ids of hash sums to initialize
  */
 void rhash_init_algorithms(unsigned mask)
 {
@@ -165,15 +175,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;
+}
+
 #if 0
 /* CRC32 helper functions */
 
@@ -217,4 +238,45 @@ 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
+}
 #endif

+ 42 - 7
Utilities/cmlibrhash/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

+ 38 - 15
Utilities/cmlibrhash/librhash/byte_order.c

@@ -1,21 +1,21 @@
 /* byte_order.c - byte order related platform dependent routines,
  *
- * Copyright: 2008-2012 Aleksey Kravchenko <[email protected]>
+ * Copyright (c) 2008, Aleksey Kravchenko <[email protected]>
  *
- * 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

+ 106 - 39
Utilities/cmlibrhash/librhash/byte_order.h

@@ -4,6 +4,19 @@
 #include "ustd.h"
 #include <stdlib.h>
 
+#if 0
+#if defined(__GLIBC__)
+# include <endian.h>
+#endif
+#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" {
 #endif
@@ -26,8 +39,6 @@ extern "C" {
 # endif
 #endif
 
-
-/* detect CPU endianness */
 #include <cm_kwiml.h>
 #if KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_LITTLE
 # define CPU_LITTLE_ENDIAN
@@ -37,8 +48,53 @@ extern "C" {
 # define CPU_BIG_ENDIAN
 # define IS_BIG_ENDIAN 1
 # define IS_LITTLE_ENDIAN 0
+#endif
+
+#if 0
+#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
+
+/* 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)
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
 #endif
 
 #define IS_ALIGNED_32(p) (0 == (3 & ((const char*)(p) - (const char*)0)))
@@ -56,11 +112,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 */
@@ -69,42 +137,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);
 
-#ifndef __has_builtin
-# define __has_builtin(x) 0
-#endif
-
-/* 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 */
-# define bswap_32(x) __builtin_bswap32(x)
-#elif defined(__clang__) && __has_builtin(__builtin_bswap32)
+/* 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)
+# define bswap_64(x) _byteswap_uint64((__int64)x)
 #else
-/* general bswap_32 definition */
-static uint32_t bswap_32(uint32_t x) {
-	x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0x00FF00FF);
+/* 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
 }
-#endif /* bswap_32 */
-
-#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
-# define bswap_64(x) __builtin_bswap64(x)
-#elif defined(__clang__) && __has_builtin(__builtin_bswap64)
-# 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)
-#else
-static 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];
@@ -114,9 +171,9 @@ static uint64_t bswap_64(uint64_t x) {
 	r.l[1] = bswap_32(w.l[0]);
 	return r.ll;
 }
-#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)
@@ -129,7 +186,7 @@ static 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)
@@ -141,7 +198,7 @@ static 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))))
@@ -149,6 +206,16 @@ static 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 */

+ 96 - 74
Utilities/cmlibrhash/librhash/hex.c

@@ -1,71 +1,57 @@
 /* hex.c - conversion for hexadecimal and base32 strings.
  *
- * Copyright: 2008-2012 Aleksey Kravchenko <[email protected]>
+ * Copyright (c) 2008, Aleksey Kravchenko <[email protected]>
  *
- * 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) {

+ 7 - 6
Utilities/cmlibrhash/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)

+ 13 - 13
Utilities/cmlibrhash/librhash/md5.c

@@ -1,17 +1,17 @@
 /* md5.c - an implementation of the MD5 algorithm, based on RFC 1321.
  *
- * Copyright: 2007-2012 Aleksey Kravchenko <[email protected]>
+ * Copyright (c) 2007, Aleksey Kravchenko <[email protected]>
  *
- * 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;

+ 3 - 3
Utilities/cmlibrhash/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" */

+ 74 - 246
Utilities/cmlibrhash/librhash/rhash.c

@@ -1,42 +1,40 @@
 /* rhash.c - implementation of LibRHash library calls
  *
- * Copyright: 2008-2012 Aleksey Kravchenko <[email protected]>
+ * Copyright (c) 2008, Aleksey Kravchenko <[email protected]>
  *
- * 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.
  */
 
+/* modifier for Windows DLL */
+#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS)
+# define RHASH_API __declspec(dllexport)
+#endif
+
 /* macros for large file support, must be defined before any include file */
 #define _LARGEFILE64_SOURCE
 #define _FILE_OFFSET_BITS 64
 
 #include "ustd.h"   /* Need this first within CMake.  */
 
-#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)
-# define RHASH_API __declspec(dllexport)
-#endif
-
-#include "byte_order.h"
+#include "rhash.h"
 #include "algorithms.h"
-#include "util.h"
+#include "byte_order.h"
 #include "hex.h"
-#include "rhash.h" /* RHash library interface */
+#include "util.h"
+#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 */
@@ -170,11 +152,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;
@@ -195,12 +172,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;
@@ -223,15 +194,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;
@@ -251,13 +213,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;
@@ -295,7 +250,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;
 
@@ -332,34 +287,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;
@@ -372,22 +307,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 */
@@ -425,14 +350,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;
@@ -447,7 +364,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);
@@ -460,14 +380,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;
@@ -482,7 +394,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);
@@ -495,28 +410,7 @@ 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;
-}
-
 #if 0
-/**
- * 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 */
@@ -524,12 +418,6 @@ RHASH_API int rhash_is_base32(unsigned hash_id)
 }
 #endif
 
-/**
- * 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;
@@ -537,12 +425,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);
@@ -550,26 +432,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);
@@ -599,7 +467,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 */
@@ -610,34 +478,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) {
@@ -652,13 +506,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;
@@ -679,7 +533,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++) = '&';
 		}
 	}
@@ -688,62 +542,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;
@@ -764,15 +595,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;
 		}
 	}
 
@@ -781,7 +613,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;
@@ -793,7 +626,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)
@@ -814,17 +647,8 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
 }
 #endif
 
-#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 */
@@ -865,6 +689,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();
 
 	default:
 		return RHASH_ERROR; /* unknown message */

+ 312 - 81
Utilities/cmlibrhash/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
 
@@ -32,11 +34,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,
@@ -47,18 +49,28 @@ 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
 #else
 	RHASH_MD5        = 0x01,
 	RHASH_SHA1       = 0x02,
@@ -86,15 +98,17 @@ enum rhash_ids
 };
 
 /**
- * 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;
@@ -107,109 +121,285 @@ 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 */
 
 #if 0
 /**
- * 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
 };
 #endif
 
-/* 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) || \
@@ -219,14 +409,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);
 
@@ -239,22 +443,32 @@ 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
 
-/* helper macros */
+/* HELPER MACROS */
 
-/** Get a pointer to context of the specified hash function */
+/**
+ * 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)
 
@@ -267,19 +481,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" */

+ 13 - 13
Utilities/cmlibrhash/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 <[email protected]>
+ * Copyright (c) 2008, Aleksey Kravchenko <[email protected]>
  *
- * 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;

+ 3 - 3
Utilities/cmlibrhash/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" */

+ 15 - 15
Utilities/cmlibrhash/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 <[email protected]>
+ * Copyright (c) 2010, Aleksey Kravchenko <[email protected]>
  *
- * 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;

+ 4 - 4
Utilities/cmlibrhash/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" */

+ 57 - 51
Utilities/cmlibrhash/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 <[email protected]>
+ * Copyright (c) 2013, Aleksey Kravchenko <[email protected]>
  *
- * 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;

+ 7 - 7
Utilities/cmlibrhash/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

+ 15 - 15
Utilities/cmlibrhash/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 <[email protected]>
+ * Copyright (c) 2010, Aleksey Kravchenko <[email protected]>
  *
- * 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;

+ 4 - 4
Utilities/cmlibrhash/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" */

+ 32 - 0
Utilities/cmlibrhash/librhash/ustd.h

@@ -36,4 +36,36 @@
 # define uint8_t KWIML_INT_uint8_t
 #endif
 
+#include <stddef.h>
+
+#if 0
+#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)
+
+#else /* _MSC_VER > 1000 */
+
+# include <stdint.h>
+# include <unistd.h>
+
+#endif /* _MSC_VER > 1000 */
+#endif
+
 #endif /* LIBRHASH_USTD_H */

+ 1 - 1
Utilities/cmlibrhash/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