From: LoRd_MuldeR Date: Sun, 1 Feb 2015 20:03:28 +0000 (+0100) Subject: Added the BLAKE2 hash algorithm. X-Git-Tag: v1.02~12 X-Git-Url: http://git.osdn.net/view?p=mutilities%2FMUtilities.git;a=commitdiff_plain;h=02be92208f62616a7a20e0670a4a1ecad2a84d7e Added the BLAKE2 hash algorithm. --- diff --git a/MUtilities_VS2013.vcxproj b/MUtilities_VS2013.vcxproj index 89f6468..02f7fe4 100644 --- a/MUtilities_VS2013.vcxproj +++ b/MUtilities_VS2013.vcxproj @@ -18,6 +18,7 @@ + @@ -25,9 +26,10 @@ + - + @@ -43,9 +45,10 @@ + - + @@ -53,6 +56,7 @@ + diff --git a/MUtilities_VS2013.vcxproj.filters b/MUtilities_VS2013.vcxproj.filters index c7a6ad8..91b0a68 100644 --- a/MUtilities_VS2013.vcxproj.filters +++ b/MUtilities_VS2013.vcxproj.filters @@ -39,9 +39,6 @@ Source Files - - Source Files - Source Files @@ -90,6 +87,15 @@ Source Files\Generated + + Source Files + + + Source Files + + + Source Files\3rd Party + @@ -107,9 +113,6 @@ Public Headers - - Public Headers - Header Files @@ -155,6 +158,15 @@ Public Headers + + Public Headers + + + Public Headers + + + Header Files\3rd Party + diff --git a/include/MUtils/Hash_Blake2.h b/include/MUtils/Hash_Blake2.h new file mode 100644 index 0000000..dd9bbd2 --- /dev/null +++ b/include/MUtils/Hash_Blake2.h @@ -0,0 +1,67 @@ +/////////////////////////////////////////////////////////////////////////////// +// Simple x264 Launcher +// Copyright (C) 2004-2015 LoRd_MuldeR +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// 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. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// http://www.gnu.org/licenses/gpl-2.0.txt +/////////////////////////////////////////////////////////////////////////////// + +/* + BLAKE2 reference source code package - reference C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ + +#pragma once + +//MUtils +#include + +//Qt +#include +#include + +namespace MUtils +{ + namespace Hash + { + class MUTILS_API Blake2_Context; + + class MUTILS_API Blake2 + { + public: + Blake2(const char* key = NULL); + ~Blake2(void); + + void update(const QByteArray &data); + void update(QFile &file); + QByteArray finalize(const bool bAsHex = true); + + private: + QByteArray m_hash; + Blake2_Context *const m_context; + bool m_finalized; + }; + + } +} diff --git a/include/MUtils/KeccakHash.h b/include/MUtils/Hash_Keccak.h similarity index 66% rename from include/MUtils/KeccakHash.h rename to include/MUtils/Hash_Keccak.h index 6301695..533c3cb 100644 --- a/include/MUtils/KeccakHash.h +++ b/include/MUtils/Hash_Keccak.h @@ -56,61 +56,64 @@ namespace MUtils { - namespace Internal + namespace Hash { - // Section from KeccakSponge.h - // needed here, since hashState needs to be explicitly 32-byte aligned and therefore can't be - // transformed into a class (in order to forward declarate) like in the other hash wrappers. - namespace KeccakImpl + namespace Internal { - #define KeccakPermutationSize 1600 - #define KeccakPermutationSizeInBytes (KeccakPermutationSize/8) - #define KeccakMaximumRate 1536 - #define KeccakMaximumRateInBytes (KeccakMaximumRate/8) + // Section from KeccakSponge.h + // needed here, since hashState needs to be explicitly 32-byte aligned and therefore can't be + // transformed into a class (in order to forward declarate) like in the other hash wrappers. + namespace KeccakImpl + { + #define KeccakPermutationSize 1600 + #define KeccakPermutationSizeInBytes (KeccakPermutationSize/8) + #define KeccakMaximumRate 1536 + #define KeccakMaximumRateInBytes (KeccakMaximumRate/8) - #if defined(__GNUC__) - #define ALIGN __attribute__ ((aligned(32))) - #elif defined(_MSC_VER) - #define ALIGN __declspec(align(32)) - #else - #define ALIGN - #endif + #if defined(__GNUC__) + #define ALIGN __attribute__ ((aligned(32))) + #elif defined(_MSC_VER) + #define ALIGN __declspec(align(32)) + #else + #define ALIGN + #endif - ALIGN typedef struct spongeStateStruct - { - ALIGN unsigned char state[KeccakPermutationSizeInBytes]; - ALIGN unsigned char dataQueue[KeccakMaximumRateInBytes]; - unsigned int rate; - unsigned int capacity; - unsigned int bitsInQueue; - unsigned int fixedOutputLength; - int squeezing; - unsigned int bitsAvailableForSqueezing; + ALIGN typedef struct spongeStateStruct + { + ALIGN unsigned char state[KeccakPermutationSizeInBytes]; + ALIGN unsigned char dataQueue[KeccakMaximumRateInBytes]; + unsigned int rate; + unsigned int capacity; + unsigned int bitsInQueue; + unsigned int fixedOutputLength; + int squeezing; + unsigned int bitsAvailableForSqueezing; + } + spongeState; + typedef spongeState hashState; } - spongeState; - typedef spongeState hashState; + // End Section from KeccakSponge.h } - // End Section from KeccakSponge.h - } - class MUTILS_API KeccakHash - { - public: - enum HashBits {hb224, hb256, hb384, hb512}; + class MUTILS_API Keccak + { + public: + enum HashBits {hb224, hb256, hb384, hb512}; - KeccakHash(); - ~KeccakHash(); + Keccak(); + ~Keccak(); - static bool selfTest(void); + static bool selfTest(void); - bool init(HashBits hashBits=hb256); - bool addData(const QByteArray &data); - bool addData(const char *data, int size); - const QByteArray &finalize(); + bool init(HashBits hashBits=hb256); + bool addData(const QByteArray &data); + bool addData(const char *data, int size); + const QByteArray &finalize(); - protected: - bool m_initialized; - Internal::KeccakImpl::hashState *m_state; - QByteArray m_hashResult; - }; + protected: + bool m_initialized; + Internal::KeccakImpl::hashState *m_state; + QByteArray m_hashResult; + }; + } }; diff --git a/src/3rd_party/blake2/COPYING.txt b/src/3rd_party/blake2/COPYING.txt new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/src/3rd_party/blake2/COPYING.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/src/3rd_party/blake2/README.txt b/src/3rd_party/blake2/README.txt new file mode 100644 index 0000000..a977aa8 --- /dev/null +++ b/src/3rd_party/blake2/README.txt @@ -0,0 +1,19 @@ + +this is the reference source code package of BLAKE2, which includes + +ref/ +C implementations of blake2b, blake2bp, blake2s, blake2sp, aimed at +portability and simplicity + +sse/ +C implementations of blake2b, blake2bp, blake2s, blake2sp, optimized +for speed on CPUs supporting SSE2, SSSE3, SSE4.1, AVX, or XOP + +csharp/ +C# implementation of blake2b + +b2sum/ +command line tool to hash files, based on the sse/ implementations + +bench/ +benchmark tool to measure cycles-per-byte speeds and produce graphs diff --git a/src/3rd_party/blake2/include/blake2.h b/src/3rd_party/blake2/include/blake2.h new file mode 100644 index 0000000..2c4acd8 --- /dev/null +++ b/src/3rd_party/blake2/include/blake2.h @@ -0,0 +1,93 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ +#pragma once +#ifndef __BLAKE2_H__ +#define __BLAKE2_H__ + +#include +#include + +#if defined(_MSC_VER) +#define ALIGN(x) __declspec(align(x)) +#ifndef __cplusplus +#define inline __inline +#endif +#else +#define ALIGN(x) __attribute__((aligned(x))) +#endif + +namespace MUtils +{ + namespace Hash + { + namespace Internal + { + namespace Blake2Impl + { + enum blake2b_constant + { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 + }; + + #pragma pack(push, 1) + typedef struct __blake2b_param + { + uint8_t digest_length; // 1 + uint8_t key_length; // 2 + uint8_t fanout; // 3 + uint8_t depth; // 4 + uint32_t leaf_length; // 8 + uint64_t node_offset; // 16 + uint8_t node_depth; // 17 + uint8_t inner_length; // 18 + uint8_t reserved[14]; // 32 + uint8_t salt[BLAKE2B_SALTBYTES]; // 48 + uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64 + } blake2b_param; + + ALIGN( 64 ) typedef struct __blake2b_state + { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[2 * BLAKE2B_BLOCKBYTES]; + size_t buflen; + uint8_t last_node; + } blake2b_state; + #pragma pack(pop) + + // Streaming API + int blake2b_init( blake2b_state *S, const uint8_t outlen ); + int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); + int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); + int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ); + int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ); + + // Simple API + int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); + + static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) + { + return blake2b( out, in, key, outlen, inlen, keylen ); + } + } + } + } +} + +#endif + diff --git a/src/3rd_party/blake2/src/blake2.cpp b/src/3rd_party/blake2/src/blake2.cpp new file mode 100644 index 0000000..99b6519 --- /dev/null +++ b/src/3rd_party/blake2/src/blake2.cpp @@ -0,0 +1,514 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ + +#include +#include +#include + +#include "../include/blake2.h" + +/*------------------------------------*/ +/* blake2-impl.h */ +/*------------------------------------*/ + +static inline uint32_t load32( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + return *( uint32_t * )( src ); +#else + const uint8_t *p = ( uint8_t * )src; + uint32_t w = *p++; + w |= ( uint32_t )( *p++ ) << 8; + w |= ( uint32_t )( *p++ ) << 16; + w |= ( uint32_t )( *p++ ) << 24; + return w; +#endif +} + +static inline uint64_t load64( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + return *( uint64_t * )( src ); +#else + const uint8_t *p = ( uint8_t * )src; + uint64_t w = *p++; + w |= ( uint64_t )( *p++ ) << 8; + w |= ( uint64_t )( *p++ ) << 16; + w |= ( uint64_t )( *p++ ) << 24; + w |= ( uint64_t )( *p++ ) << 32; + w |= ( uint64_t )( *p++ ) << 40; + w |= ( uint64_t )( *p++ ) << 48; + w |= ( uint64_t )( *p++ ) << 56; + return w; +#endif +} + +static inline void store32( void *dst, uint32_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + *( uint32_t * )( dst ) = w; +#else + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +#endif +} + +static inline void store64( void *dst, uint64_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + *( uint64_t * )( dst ) = w; +#else + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +#endif +} + +static inline uint64_t load48( const void *src ) +{ + const uint8_t *p = ( const uint8_t * )src; + uint64_t w = *p++; + w |= ( uint64_t )( *p++ ) << 8; + w |= ( uint64_t )( *p++ ) << 16; + w |= ( uint64_t )( *p++ ) << 24; + w |= ( uint64_t )( *p++ ) << 32; + w |= ( uint64_t )( *p++ ) << 40; + return w; +} + +static inline void store48( void *dst, uint64_t w ) +{ + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +} + +static inline uint32_t rotl32( const uint32_t w, const unsigned c ) +{ + return ( w << c ) | ( w >> ( 32 - c ) ); +} + +static inline uint64_t rotl64( const uint64_t w, const unsigned c ) +{ + return ( w << c ) | ( w >> ( 64 - c ) ); +} + +static inline uint32_t rotr32( const uint32_t w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 32 - c ) ); +} + +static inline uint64_t rotr64( const uint64_t w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 64 - c ) ); +} + +/* prevents compiler optimizing out memset() */ +static inline void secure_zero_memory( void *v, size_t n ) +{ + volatile uint8_t *p = ( volatile uint8_t * )v; + + while( n-- ) *p++ = 0; +} + +/*------------------------------------*/ +/* blake2b-ref.c */ +/*------------------------------------*/ + +static const uint64_t blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +static const uint8_t blake2b_sigma[12][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + + +static inline int blake2b_set_lastnode( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S ) +{ + S->f[1] = ~0ULL; + return 0; +} + +static inline int blake2b_clear_lastnode( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S ) +{ + S->f[1] = 0ULL; + return 0; +} + +/* Some helper functions, not necessarily useful */ +static inline int blake2b_set_lastblock( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S ) +{ + if( S->last_node ) blake2b_set_lastnode( S ); + + S->f[0] = ~0ULL; + return 0; +} + +static inline int blake2b_clear_lastblock( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S ) +{ + if( S->last_node ) blake2b_clear_lastnode( S ); + + S->f[0] = 0ULL; + return 0; +} + +static inline int blake2b_increment_counter( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S, const uint64_t inc ) +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); + return 0; +} + + + +// Parameter-related functions +static inline int blake2b_param_set_digest_length( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t digest_length ) +{ + P->digest_length = digest_length; + return 0; +} + +static inline int blake2b_param_set_fanout( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t fanout ) +{ + P->fanout = fanout; + return 0; +} + +static inline int blake2b_param_set_max_depth( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t depth ) +{ + P->depth = depth; + return 0; +} + +static inline int blake2b_param_set_leaf_length( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint32_t leaf_length ) +{ + store32( &P->leaf_length, leaf_length ); + return 0; +} + +static inline int blake2b_param_set_node_offset( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint64_t node_offset ) +{ + store64( &P->node_offset, node_offset ); + return 0; +} + +static inline int blake2b_param_set_node_depth( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t node_depth ) +{ + P->node_depth = node_depth; + return 0; +} + +static inline int blake2b_param_set_inner_length( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t inner_length ) +{ + P->inner_length = inner_length; + return 0; +} + +static inline int blake2b_param_set_salt( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t salt[MUtils::Hash::Internal::Blake2Impl::BLAKE2B_SALTBYTES] ) +{ + memcpy( P->salt, salt, MUtils::Hash::Internal::Blake2Impl::BLAKE2B_SALTBYTES ); + return 0; +} + +static inline int blake2b_param_set_personal( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t personal[MUtils::Hash::Internal::Blake2Impl::BLAKE2B_PERSONALBYTES] ) +{ + memcpy( P->personal, personal, MUtils::Hash::Internal::Blake2Impl::BLAKE2B_PERSONALBYTES ); + return 0; +} + +static inline int blake2b_init0( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S ) +{ + int i; + + memset( S, 0, sizeof( MUtils::Hash::Internal::Blake2Impl::blake2b_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; + + return 0; +} + +/* init xors IV with input parameter block */ +int MUtils::Hash::Internal::Blake2Impl::blake2b_init_param( blake2b_state *S, const blake2b_param *P ) +{ + uint8_t *p; + size_t i; + + blake2b_init0( S ); + p = ( uint8_t * )( P ); + + /* IV XOR ParamBlock */ + for( i = 0; i < 8; ++i ) + S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); + + return 0; +} + +int MUtils::Hash::Internal::Blake2Impl::blake2b_init( blake2b_state *S, const uint8_t outlen ) +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + P->digest_length = outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store64( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + return blake2b_init_param( S, P ); +} + +int MUtils::Hash::Internal::Blake2Impl::blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; + + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store64( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + if( blake2b_init_param( S, P ) < 0 ) return -1; + + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + +static int blake2b_compress( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S, const uint8_t block[MUtils::Hash::Internal::Blake2Impl::BLAKE2B_BLOCKBYTES] ) +{ + uint64_t m[16]; + uint64_t v[16]; + int i; + + for( i = 0; i < 16; ++i ) + m[i] = load64( block + i * sizeof( m[i] ) ); + + for( i = 0; i < 8; ++i ) + v[i] = S->h[i]; + + v[ 8] = blake2b_IV[0]; + v[ 9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = S->t[0] ^ blake2b_IV[4]; + v[13] = S->t[1] ^ blake2b_IV[5]; + v[14] = S->f[0] ^ blake2b_IV[6]; + v[15] = S->f[1] ^ blake2b_IV[7]; +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2*i+0]]; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2*i+1]]; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while(0) +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + ROUND( 10 ); + ROUND( 11 ); + + for( i = 0; i < 8; ++i ) + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + +#undef G +#undef ROUND + return 0; +} + +/* inlen now in bytes */ +int MUtils::Hash::Internal::Blake2Impl::blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ) +{ + while( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = 2 * BLAKE2B_BLOCKBYTES - left; + + if( inlen > fill ) + { + memcpy( S->buf + left, in, fill ); // Fill buffer + S->buflen += fill; + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + blake2b_compress( S, S->buf ); // Compress + memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left + S->buflen -= BLAKE2B_BLOCKBYTES; + in += fill; + inlen -= fill; + } + else // inlen <= fill + { + memcpy( S->buf + left, in, (size_t) inlen ); + S->buflen = (size_t)(S->buflen + inlen); // Be lazy, do not compress + in += inlen; + inlen -= inlen; + } + } + + return 0; +} + +/* Is this correct? */ +int MUtils::Hash::Internal::Blake2Impl::blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ) +{ + int i; + + uint8_t buffer[BLAKE2B_OUTBYTES]; + + if( S->buflen > BLAKE2B_BLOCKBYTES ) + { + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + blake2b_compress( S, S->buf ); + S->buflen -= BLAKE2B_BLOCKBYTES; + memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen ); + } + + blake2b_increment_counter( S, S->buflen ); + blake2b_set_lastblock( S ); + memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ + blake2b_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, outlen ); + return 0; +} + +/* inlen, at least, should be uint64_t. Others can be size_t. */ +int MUtils::Hash::Internal::Blake2Impl::blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) +{ + blake2b_state S[1]; + + /* Verify parameters */ + if ( NULL == in ) return -1; + + if ( NULL == out ) return -1; + + if( NULL == key ) keylen = 0; + + if( keylen > 0 ) + { + if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2b_init( S, outlen ) < 0 ) return -1; + } + + blake2b_update( S, ( uint8_t * )in, inlen ); + blake2b_final( S, out, outlen ); + return 0; +} + +#if defined(BLAKE2B_SELFTEST) +#include +#include "blake2-kat.h" +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2B_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + + for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2B_OUTBYTES]; + blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ); + + if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} +#endif diff --git a/src/3rd_party/keccak/include/keccak_impl.h b/src/3rd_party/keccak/include/keccak_impl.h index 84bd6bc..74649e9 100644 --- a/src/3rd_party/keccak/include/keccak_impl.h +++ b/src/3rd_party/keccak/include/keccak_impl.h @@ -19,6 +19,7 @@ ***************************************************************************/ namespace MUtils { +namespace Hash { namespace Internal { namespace KeccakImpl { @@ -1999,5 +2000,6 @@ HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, } // end of namespace KeccakImpl } // end of namespace Internal +} // end of namespace Hash } // end of namespace MUtils diff --git a/src/Hash_Blake2.cpp b/src/Hash_Blake2.cpp new file mode 100644 index 0000000..816421f --- /dev/null +++ b/src/Hash_Blake2.cpp @@ -0,0 +1,143 @@ +/////////////////////////////////////////////////////////////////////////////// +// Simple x264 Launcher +// Copyright (C) 2004-2015 LoRd_MuldeR +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// 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. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// http://www.gnu.org/licenses/gpl-2.0.txt +/////////////////////////////////////////////////////////////////////////////// + +/* + BLAKE2 reference source code package - reference C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ + +//MUtils +#include +#include + +//Internal +#include "3rd_party/blake2/include/blake2.h" + +#include +#include +#include + +static const size_t HASH_SIZE = 64; + +class MUtils::Hash::Blake2_Context +{ + friend Blake2; + + Blake2_Context(void) + { + if(!(state = (MUtils::Hash::Internal::Blake2Impl::blake2b_state*) _aligned_malloc(sizeof(MUtils::Hash::Internal::Blake2Impl::blake2b_state), 64))) + { + MUTILS_THROW("Aligend malloc has failed!"); + } + memset(state, 0, sizeof(MUtils::Hash::Internal::Blake2Impl::blake2b_state)); + } + + ~Blake2_Context(void) + { + memset(state, 0, sizeof(MUtils::Hash::Internal::Blake2Impl::blake2b_state)); + _aligned_free(state); + } + +private: + MUtils::Hash::Internal::Blake2Impl::blake2b_state *state; +}; + +MUtils::Hash::Blake2::Blake2(const char* key) +: + m_hash(HASH_SIZE, '\0'), + m_context(new Blake2_Context()), + m_finalized(false) +{ + if(key && key[0]) + { + blake2b_init_key(m_context->state, HASH_SIZE, key, strlen(key)); + } + else + { + blake2b_init(m_context->state, HASH_SIZE); + } +} + +MUtils::Hash::Blake2::~Blake2(void) +{ + delete m_context; +} + +void MUtils::Hash::Blake2::update(const QByteArray &data) +{ + if(m_finalized) + { + MUTILS_THROW("BLAKE2 was already finalized!"); + } + + if(data.size() > 0) + { + if(blake2b_update(m_context->state, (const uint8_t*) data.constData(), data.size()) != 0) + { + MUTILS_THROW("BLAKE2 internal error!"); + } + } +} + +void MUtils::Hash::Blake2::update(QFile &file) +{ + bool okay = false; + + for(;;) + { + QByteArray data = file.read(16384); + if(data.size() > 0) + { + okay = true; + update(data); + continue; + } + break; + } + + if(!okay) + { + qWarning("[QBlake2Checksum] Could not ready any data from file!"); + } +} + +QByteArray MUtils::Hash::Blake2::finalize(const bool bAsHex) +{ + if(!m_finalized) + { + if(blake2b_final(m_context->state, (uint8_t*) m_hash.data(), m_hash.size()) != 0) + { + MUTILS_THROW("BLAKE2 internal error!"); + } + + m_finalized = true; + } + + return bAsHex ? m_hash.toHex() : m_hash; +} diff --git a/src/KeccakHash.cpp b/src/Hash_Keccak.cpp similarity index 81% rename from src/KeccakHash.cpp rename to src/Hash_Keccak.cpp index 6962a49..4a55a3a 100644 --- a/src/KeccakHash.cpp +++ b/src/Hash_Keccak.cpp @@ -44,24 +44,24 @@ ** Date: 12.01.12 ** ****************************************************************************/ -#include +#include #include #include "3rd_party/keccak/include/keccak_impl.h" -MUtils::KeccakHash::KeccakHash() +MUtils::Hash::Keccak::Keccak() { m_initialized = false; - m_state = (MUtils::Internal::KeccakImpl::hashState*) _aligned_malloc(sizeof(MUtils::Internal::KeccakImpl::hashState), 32); + m_state = (MUtils::Hash::Internal::KeccakImpl::hashState*) _aligned_malloc(sizeof(MUtils::Hash::Internal::KeccakImpl::hashState), 32); if(!m_state) { throw "[MUtils::KeccakHash] Error: _aligned_malloc() has failed, probably out of heap space!"; } - memset(m_state, 0, sizeof(MUtils::Internal::KeccakImpl::hashState)); + memset(m_state, 0, sizeof(MUtils::Hash::Internal::KeccakImpl::hashState)); m_hashResult.clear(); } -MUtils::KeccakHash::~KeccakHash() +MUtils::Hash::Keccak::~Keccak() { m_hashResult.clear(); @@ -72,7 +72,7 @@ MUtils::KeccakHash::~KeccakHash() } } -bool MUtils::KeccakHash::init(HashBits hashBits) +bool MUtils::Hash::Keccak::init(HashBits hashBits) { if(m_initialized) { @@ -81,7 +81,7 @@ bool MUtils::KeccakHash::init(HashBits hashBits) } m_hashResult.clear(); - memset(m_state, 0, sizeof(MUtils::Internal::KeccakImpl::hashState)); + memset(m_state, 0, sizeof(MUtils::Hash::Internal::KeccakImpl::hashState)); int hashBitLength = 0; switch (hashBits) @@ -93,7 +93,7 @@ bool MUtils::KeccakHash::init(HashBits hashBits) default: throw "Invalid hash length!!"; } - if(MUtils::Internal::KeccakImpl::Init(m_state, hashBitLength) != MUtils::Internal::KeccakImpl::SUCCESS) + if(MUtils::Hash::Internal::KeccakImpl::Init(m_state, hashBitLength) != MUtils::Hash::Internal::KeccakImpl::SUCCESS) { qWarning("KeccakImpl::Init() has failed unexpectedly!"); return false; @@ -105,12 +105,12 @@ bool MUtils::KeccakHash::init(HashBits hashBits) return true; } -bool MUtils::KeccakHash::addData(const QByteArray &data) +bool MUtils::Hash::Keccak::addData(const QByteArray &data) { return addData(data.constData(), data.size()); } -bool MUtils::KeccakHash::addData(const char *data, int size) +bool MUtils::Hash::Keccak::addData(const char *data, int size) { if(!m_initialized) { @@ -118,7 +118,7 @@ bool MUtils::KeccakHash::addData(const char *data, int size) return false; } - if(MUtils::Internal::KeccakImpl::Update(m_state, (MUtils::Internal::KeccakImpl::BitSequence*)data, size*8) != MUtils::Internal::KeccakImpl::SUCCESS) + if(MUtils::Hash::Internal::KeccakImpl::Update(m_state, (MUtils::Hash::Internal::KeccakImpl::BitSequence*)data, size*8) != MUtils::Hash::Internal::KeccakImpl::SUCCESS) { qWarning("KeccakImpl::Update() has failed unexpectedly!"); m_hashResult.clear(); @@ -129,7 +129,7 @@ bool MUtils::KeccakHash::addData(const char *data, int size) return true; } -const QByteArray &MUtils::KeccakHash::finalize() +const QByteArray &MUtils::Hash::Keccak::finalize() { if(!m_initialized) { @@ -138,7 +138,7 @@ const QByteArray &MUtils::KeccakHash::finalize() return m_hashResult; } - if(MUtils::Internal::KeccakImpl::Final(m_state, (MUtils::Internal::KeccakImpl::BitSequence*)m_hashResult.data()) != MUtils::Internal::KeccakImpl::SUCCESS) + if(MUtils::Hash::Internal::KeccakImpl::Final(m_state, (MUtils::Hash::Internal::KeccakImpl::BitSequence*)m_hashResult.data()) != MUtils::Hash::Internal::KeccakImpl::SUCCESS) { qWarning("KeccakImpl::Final() has failed unexpectedly!"); m_hashResult.clear(); @@ -148,13 +148,13 @@ const QByteArray &MUtils::KeccakHash::finalize() return m_hashResult; } -bool MUtils::KeccakHash::selfTest(void) +bool MUtils::Hash::Keccak::selfTest(void) { - MUtils::KeccakHash hash; + MUtils::Hash::Keccak hash; const QByteArray input("The quick brown fox jumps over the lazy dog"); bool passed[4] = {false, false, false, false}; - if(hash.init(MUtils::KeccakHash::hb224)) + if(hash.init(MUtils::Hash::Keccak::hb224)) { if(hash.addData(input)) { @@ -167,7 +167,7 @@ bool MUtils::KeccakHash::selfTest(void) } } - if(hash.init(MUtils::KeccakHash::hb256)) + if(hash.init(MUtils::Hash::Keccak::hb256)) { if(hash.addData(input)) { @@ -180,7 +180,7 @@ bool MUtils::KeccakHash::selfTest(void) } } - if(hash.init(MUtils::KeccakHash::hb384)) + if(hash.init(MUtils::Hash::Keccak::hb384)) { if(hash.addData(input)) { @@ -193,7 +193,7 @@ bool MUtils::KeccakHash::selfTest(void) } } - if(hash.init(MUtils::KeccakHash::hb512)) + if(hash.init(MUtils::Hash::Keccak::hb512)) { if(hash.addData(input)) { diff --git a/src/UpdateChecker.cpp b/src/UpdateChecker.cpp index 5e1e0b8..2834652 100644 --- a/src/UpdateChecker.cpp +++ b/src/UpdateChecker.cpp @@ -588,6 +588,7 @@ bool UpdateChecker::checkSignature(const QString &file, const QString &signature qWarning("CheckSignature: File and signature should be in same folder!"); return false; } + if(QFileInfo(file).absolutePath().compare(QFileInfo(m_binaryKeys).absolutePath(), Qt::CaseInsensitive) != 0) { qWarning("CheckSignature: File and keyring should be in same folder!");