diff options
Diffstat (limited to 'Utilities/cmlibrhash/librhash/algorithms.c')
-rw-r--r-- | Utilities/cmlibrhash/librhash/algorithms.c | 146 |
1 files changed, 104 insertions, 42 deletions
diff --git a/Utilities/cmlibrhash/librhash/algorithms.c b/Utilities/cmlibrhash/librhash/algorithms.c index fc0169058a..cdd4053334 100644 --- a/Utilities/cmlibrhash/librhash/algorithms.c +++ b/Utilities/cmlibrhash/librhash/algorithms.c @@ -1,17 +1,17 @@ /* algorithms.c - the algorithms supported by the rhash library * - * Copyright: 2011-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2011, Aleksey Kravchenko <rhash.admin@gmail.com> * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <stdio.h> @@ -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 |