From 718d577455c2e431e32064950f2612e1381c275a Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 8 Jan 2015 01:11:17 +0000 Subject: Add SHA-512/256 Define some new functions for copying out arrays of words and use them across hashes. --- src/lib/engine/core_engine/lookup_hash.cpp | 2 + src/lib/hash/has160/has160.cpp | 3 +- src/lib/hash/md4/md4.cpp | 3 +- src/lib/hash/md5/md5.cpp | 3 +- src/lib/hash/rmd128/rmd128.cpp | 3 +- src/lib/hash/rmd160/rmd160.cpp | 3 +- src/lib/hash/sha1/sha160.cpp | 3 +- src/lib/hash/sha2_32/sha2_32.cpp | 6 +- src/lib/hash/sha2_64/sha2_64.cpp | 93 +++++++++++++++--------------- src/lib/hash/sha2_64/sha2_64.h | 30 ++++++++-- src/lib/hash/skein/skein_512.cpp | 5 +- src/lib/hash/tiger/tiger.cpp | 3 +- src/lib/hash/whirlpool/whirlpool.cpp | 3 +- src/lib/utils/loadstor.h | 42 ++++++++++++++ src/tests/data/hash/sha2_64.vec | 4 ++ src/tests/test_hash.cpp | 3 +- 16 files changed, 134 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/lib/engine/core_engine/lookup_hash.cpp b/src/lib/engine/core_engine/lookup_hash.cpp index 5665b3040..b5a071c4e 100644 --- a/src/lib/engine/core_engine/lookup_hash.cpp +++ b/src/lib/engine/core_engine/lookup_hash.cpp @@ -165,6 +165,8 @@ HashFunction* Core_Engine::find_hash(const SCAN_Name& request, return new SHA_384; if(request.algo_name() == "SHA-512") return new SHA_512; + if(request.algo_name() == "SHA-512-256") + return new SHA_512_256; #endif #if defined(BOTAN_HAS_TIGER) diff --git a/src/lib/hash/has160/has160.cpp b/src/lib/hash/has160/has160.cpp index 6890ccb85..fa14b5dca 100644 --- a/src/lib/hash/has160/has160.cpp +++ b/src/lib/hash/has160/has160.cpp @@ -144,8 +144,7 @@ void HAS_160::compress_n(const byte input[], size_t blocks) */ void HAS_160::copy_out(byte output[]) { - for(size_t i = 0; i != output_length(); i += 4) - store_le(digest[i/4], output + i); + copy_out_vec_le(output, output_length(), digest); } /* diff --git a/src/lib/hash/md4/md4.cpp b/src/lib/hash/md4/md4.cpp index 9b9ebab36..4018758aa 100644 --- a/src/lib/hash/md4/md4.cpp +++ b/src/lib/hash/md4/md4.cpp @@ -94,8 +94,7 @@ void MD4::compress_n(const byte input[], size_t blocks) */ void MD4::copy_out(byte output[]) { - for(size_t i = 0; i != output_length(); i += 4) - store_le(digest[i/4], output + i); + copy_out_vec_le(output, output_length(), digest); } /* diff --git a/src/lib/hash/md5/md5.cpp b/src/lib/hash/md5/md5.cpp index 948f4e73b..a68bb725d 100644 --- a/src/lib/hash/md5/md5.cpp +++ b/src/lib/hash/md5/md5.cpp @@ -116,8 +116,7 @@ void MD5::compress_n(const byte input[], size_t blocks) */ void MD5::copy_out(byte output[]) { - for(size_t i = 0; i != output_length(); i += 4) - store_le(digest[i/4], output + i); + copy_out_vec_le(output, output_length(), digest); } /* diff --git a/src/lib/hash/rmd128/rmd128.cpp b/src/lib/hash/rmd128/rmd128.cpp index cab4adf8b..1a55b467d 100644 --- a/src/lib/hash/rmd128/rmd128.cpp +++ b/src/lib/hash/rmd128/rmd128.cpp @@ -156,8 +156,7 @@ void RIPEMD_128::compress_n(const byte input[], size_t blocks) */ void RIPEMD_128::copy_out(byte output[]) { - for(size_t i = 0; i != output_length(); i += 4) - store_le(digest[i/4], output + i); + copy_out_vec_le(output, output_length(), digest); } /* diff --git a/src/lib/hash/rmd160/rmd160.cpp b/src/lib/hash/rmd160/rmd160.cpp index ff1c1c4ec..29e2b4daa 100644 --- a/src/lib/hash/rmd160/rmd160.cpp +++ b/src/lib/hash/rmd160/rmd160.cpp @@ -189,8 +189,7 @@ void RIPEMD_160::compress_n(const byte input[], size_t blocks) */ void RIPEMD_160::copy_out(byte output[]) { - for(size_t i = 0; i != output_length(); i += 4) - store_le(digest[i/4], output + i); + copy_out_vec_le(output, output_length(), digest); } /* diff --git a/src/lib/hash/sha1/sha160.cpp b/src/lib/hash/sha1/sha160.cpp index f5daaadb2..42dc8a206 100644 --- a/src/lib/hash/sha1/sha160.cpp +++ b/src/lib/hash/sha1/sha160.cpp @@ -140,8 +140,7 @@ void SHA_160::compress_n(const byte input[], size_t blocks) */ void SHA_160::copy_out(byte output[]) { - for(size_t i = 0; i != output_length(); i += 4) - store_be(digest[i/4], output + i); + copy_out_vec_be(output, output_length(), digest); } /* diff --git a/src/lib/hash/sha2_32/sha2_32.cpp b/src/lib/hash/sha2_32/sha2_32.cpp index cffc8bd2a..8e649771f 100644 --- a/src/lib/hash/sha2_32/sha2_32.cpp +++ b/src/lib/hash/sha2_32/sha2_32.cpp @@ -171,8 +171,7 @@ void SHA_224::compress_n(const byte input[], size_t blocks) */ void SHA_224::copy_out(byte output[]) { - for(size_t i = 0; i != output_length(); i += 4) - store_be(digest[i/4], output + i); + copy_out_vec_be(output, output_length(), digest); } /* @@ -204,8 +203,7 @@ void SHA_256::compress_n(const byte input[], size_t blocks) */ void SHA_256::copy_out(byte output[]) { - for(size_t i = 0; i != output_length(); i += 4) - store_be(digest[i/4], output + i); + copy_out_vec_be(output, output_length(), digest); } /* diff --git a/src/lib/hash/sha2_64/sha2_64.cpp b/src/lib/hash/sha2_64/sha2_64.cpp index 8dcb4684e..7d32c8ef1 100644 --- a/src/lib/hash/sha2_64/sha2_64.cpp +++ b/src/lib/hash/sha2_64/sha2_64.cpp @@ -1,6 +1,6 @@ /* * SHA-{384,512} -* (C) 1999-2011 Jack Lloyd +* (C) 1999-2011,2015 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -173,70 +173,73 @@ void compress(secure_vector& digest, } -/* -* SHA-384 compression function -*/ +void SHA_512_256::compress_n(const byte input[], size_t blocks) + { + SHA2_64::compress(m_digest, input, blocks); + } + void SHA_384::compress_n(const byte input[], size_t blocks) { - SHA2_64::compress(digest, input, blocks); + SHA2_64::compress(m_digest, input, blocks); } -/* -* Copy out the digest -*/ -void SHA_384::copy_out(byte output[]) +void SHA_512::compress_n(const byte input[], size_t blocks) { - for(size_t i = 0; i != output_length(); i += 8) - store_be(digest[i/8], output + i); + SHA2_64::compress(m_digest, input, blocks); } -/* -* Clear memory of sensitive data -*/ -void SHA_384::clear() +void SHA_512_256::copy_out(byte output[]) { - MDx_HashFunction::clear(); - digest[0] = 0xCBBB9D5DC1059ED8; - digest[1] = 0x629A292A367CD507; - digest[2] = 0x9159015A3070DD17; - digest[3] = 0x152FECD8F70E5939; - digest[4] = 0x67332667FFC00B31; - digest[5] = 0x8EB44A8768581511; - digest[6] = 0xDB0C2E0D64F98FA7; - digest[7] = 0x47B5481DBEFA4FA4; + copy_out_vec_be(output, output_length(), m_digest); } -/* -* SHA-512 compression function -*/ -void SHA_512::compress_n(const byte input[], size_t blocks) +void SHA_384::copy_out(byte output[]) { - SHA2_64::compress(digest, input, blocks); + copy_out_vec_be(output, output_length(), m_digest); } -/* -* Copy out the digest -*/ void SHA_512::copy_out(byte output[]) { - for(size_t i = 0; i != output_length(); i += 8) - store_be(digest[i/8], output + i); + copy_out_vec_be(output, output_length(), m_digest); + } + +void SHA_512_256::clear() + { + MDx_HashFunction::clear(); + m_digest[0] = 0x22312194FC2BF72C; + m_digest[1] = 0x9F555FA3C84C64C2; + m_digest[2] = 0x2393B86B6F53B151; + m_digest[3] = 0x963877195940EABD; + m_digest[4] = 0x96283EE2A88EFFE3; + m_digest[5] = 0xBE5E1E2553863992; + m_digest[6] = 0x2B0199FC2C85B8AA; + m_digest[7] = 0x0EB72DDC81C52CA2; + } + +void SHA_384::clear() + { + MDx_HashFunction::clear(); + m_digest[0] = 0xCBBB9D5DC1059ED8; + m_digest[1] = 0x629A292A367CD507; + m_digest[2] = 0x9159015A3070DD17; + m_digest[3] = 0x152FECD8F70E5939; + m_digest[4] = 0x67332667FFC00B31; + m_digest[5] = 0x8EB44A8768581511; + m_digest[6] = 0xDB0C2E0D64F98FA7; + m_digest[7] = 0x47B5481DBEFA4FA4; } -/* -* Clear memory of sensitive data -*/ void SHA_512::clear() { MDx_HashFunction::clear(); - digest[0] = 0x6A09E667F3BCC908; - digest[1] = 0xBB67AE8584CAA73B; - digest[2] = 0x3C6EF372FE94F82B; - digest[3] = 0xA54FF53A5F1D36F1; - digest[4] = 0x510E527FADE682D1; - digest[5] = 0x9B05688C2B3E6C1F; - digest[6] = 0x1F83D9ABFB41BD6B; - digest[7] = 0x5BE0CD19137E2179; + m_digest[0] = 0x6A09E667F3BCC908; + m_digest[1] = 0xBB67AE8584CAA73B; + m_digest[2] = 0x3C6EF372FE94F82B; + m_digest[3] = 0xA54FF53A5F1D36F1; + m_digest[4] = 0x510E527FADE682D1; + m_digest[5] = 0x9B05688C2B3E6C1F; + m_digest[6] = 0x1F83D9ABFB41BD6B; + m_digest[7] = 0x5BE0CD19137E2179; } } diff --git a/src/lib/hash/sha2_64/sha2_64.h b/src/lib/hash/sha2_64/sha2_64.h index 58b154170..33bcb1100 100644 --- a/src/lib/hash/sha2_64/sha2_64.h +++ b/src/lib/hash/sha2_64/sha2_64.h @@ -1,6 +1,6 @@ /* * SHA-{384,512} -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2010,2015 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -24,13 +24,13 @@ class BOTAN_DLL SHA_384 : public MDx_HashFunction void clear(); - SHA_384() : MDx_HashFunction(128, true, true, 16), digest(8) + SHA_384() : MDx_HashFunction(128, true, true, 16), m_digest(8) { clear(); } private: void compress_n(const byte[], size_t blocks); void copy_out(byte[]); - secure_vector digest; + secure_vector m_digest; }; /** @@ -45,13 +45,33 @@ class BOTAN_DLL SHA_512 : public MDx_HashFunction void clear(); - SHA_512() : MDx_HashFunction(128, true, true, 16), digest(8) + SHA_512() : MDx_HashFunction(128, true, true, 16), m_digest(8) { clear(); } private: void compress_n(const byte[], size_t blocks); void copy_out(byte[]); - secure_vector digest; + secure_vector m_digest; + }; + +/** +* SHA-512/256 +*/ +class BOTAN_DLL SHA_512_256 : public MDx_HashFunction + { + public: + std::string name() const { return "SHA-512/256"; } + size_t output_length() const { return 32; } + HashFunction* clone() const { return new SHA_512_256; } + + void clear(); + + SHA_512_256() : MDx_HashFunction(128, true, true, 16), m_digest(8) { clear(); } + private: + void compress_n(const byte[], size_t blocks); + void copy_out(byte[]); + + secure_vector m_digest; }; } diff --git a/src/lib/hash/skein/skein_512.cpp b/src/lib/hash/skein/skein_512.cpp index 38eb3c89f..aac481648 100644 --- a/src/lib/hash/skein/skein_512.cpp +++ b/src/lib/hash/skein/skein_512.cpp @@ -158,10 +158,7 @@ void Skein_512::final_result(byte out[]) reset_tweak(SKEIN_OUTPUT, true); ubi_512(counter, sizeof(counter)); - const size_t out_bytes = output_bits / 8; - - for(size_t i = 0; i != out_bytes; ++i) - out[i] = get_byte(7-i%8, m_threefish->m_K[i/8]); + copy_out_vec_le(out, output_bits / 8, m_threefish->m_K); buf_pos = 0; initial_block(); diff --git a/src/lib/hash/tiger/tiger.cpp b/src/lib/hash/tiger/tiger.cpp index 57250d6f5..b6d796f29 100644 --- a/src/lib/hash/tiger/tiger.cpp +++ b/src/lib/hash/tiger/tiger.cpp @@ -75,8 +75,7 @@ void Tiger::compress_n(const byte input[], size_t blocks) */ void Tiger::copy_out(byte output[]) { - for(size_t i = 0; i != output_length(); ++i) - output[i] = get_byte(7 - (i % 8), digest[i/8]); + copy_out_vec_le(output, output_length(), digest); } /* diff --git a/src/lib/hash/whirlpool/whirlpool.cpp b/src/lib/hash/whirlpool/whirlpool.cpp index 5356252b2..736de0e1d 100644 --- a/src/lib/hash/whirlpool/whirlpool.cpp +++ b/src/lib/hash/whirlpool/whirlpool.cpp @@ -129,8 +129,7 @@ void Whirlpool::compress_n(const byte in[], size_t blocks) */ void Whirlpool::copy_out(byte output[]) { - for(size_t i = 0; i != output_length(); i += 8) - store_be(digest[i/8], output + i); + copy_out_vec_be(output, output_length(), digest); } /* diff --git a/src/lib/utils/loadstor.h b/src/lib/utils/loadstor.h index 29e00592a..1dbced60e 100644 --- a/src/lib/utils/loadstor.h +++ b/src/lib/utils/loadstor.h @@ -622,6 +622,48 @@ inline void store_be(byte out[], T x0, T x1, T x2, T x3, store_be(x7, out + (7 * sizeof(T))); } +template +void copy_out_be(byte out[], size_t out_bytes, const T in[]) + { + while(out_bytes >= sizeof(T)) + { + store_be(in[0], out); + out += sizeof(T); + out_bytes -= sizeof(T); + in += 1; + } + + for(size_t i = 0; i != out_bytes; ++i) + out[i] = get_byte(i%8, in[0]); + } + +template +void copy_out_vec_be(byte out[], size_t out_bytes, const std::vector& in) + { + copy_out_be(out, out_bytes, &in[0]); + } + +template +void copy_out_le(byte out[], size_t out_bytes, const T in[]) + { + while(out_bytes >= sizeof(T)) + { + store_le(in[0], out); + out += sizeof(T); + out_bytes -= sizeof(T); + in += 1; + } + + for(size_t i = 0; i != out_bytes; ++i) + out[i] = get_byte(sizeof(T) - 1 - (i % 8), in[0]); + } + +template +void copy_out_vec_le(byte out[], size_t out_bytes, const std::vector& in) + { + copy_out_le(out, out_bytes, &in[0]); + } + } #endif diff --git a/src/tests/data/hash/sha2_64.vec b/src/tests/data/hash/sha2_64.vec index 189e55ef5..e8d44e990 100644 --- a/src/tests/data/hash/sha2_64.vec +++ b/src/tests/data/hash/sha2_64.vec @@ -42,3 +42,7 @@ Out = 8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA17299AEADB6889018501D289E49 In = 3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930 Out = 72EC1EF1124A45B047E8B7C75A932195135BB61DE24EC0D1914042246E0AEC3A2354E093D76F3048B456764346900CB130D2A4FD5DD16ABB5E30BCB850DEE843 +[SHA-512-256] + +In = +Out = C672B8D1EF56ED28AB87C3622C5114069BDD3AD7B8F9737498D0C01ECEF0967A diff --git a/src/tests/test_hash.cpp b/src/tests/test_hash.cpp index 6077bf906..ec14d6dd4 100644 --- a/src/tests/test_hash.cpp +++ b/src/tests/test_hash.cpp @@ -58,7 +58,8 @@ size_t hash_test(const std::string& algo, if(h != hex_decode_locked(out_hex)) { - std::cout << algo << " " << provider << " got " << hex_encode(h) << " != " << out_hex << "\n"; + std::cout << algo << " " << provider << " got " << hex_encode(h) << " != " << out_hex + << " (with discarded input)\n"; ++fails; } } -- cgit v1.2.3