aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2015-01-08 01:11:17 +0000
committerlloyd <[email protected]>2015-01-08 01:11:17 +0000
commit718d577455c2e431e32064950f2612e1381c275a (patch)
treef7fbbad052a82c9f17309f64f3de7e2cec5ad603
parent624787ec08f215a7b0be51ceeeb211a717bf7f50 (diff)
Add SHA-512/256
Define some new functions for copying out arrays of words and use them across hashes.
-rw-r--r--doc/relnotes/1_11_13.rst2
-rw-r--r--src/lib/engine/core_engine/lookup_hash.cpp2
-rw-r--r--src/lib/hash/has160/has160.cpp3
-rw-r--r--src/lib/hash/md4/md4.cpp3
-rw-r--r--src/lib/hash/md5/md5.cpp3
-rw-r--r--src/lib/hash/rmd128/rmd128.cpp3
-rw-r--r--src/lib/hash/rmd160/rmd160.cpp3
-rw-r--r--src/lib/hash/sha1/sha160.cpp3
-rw-r--r--src/lib/hash/sha2_32/sha2_32.cpp6
-rw-r--r--src/lib/hash/sha2_64/sha2_64.cpp93
-rw-r--r--src/lib/hash/sha2_64/sha2_64.h30
-rw-r--r--src/lib/hash/skein/skein_512.cpp5
-rw-r--r--src/lib/hash/tiger/tiger.cpp3
-rw-r--r--src/lib/hash/whirlpool/whirlpool.cpp3
-rw-r--r--src/lib/utils/loadstor.h42
-rw-r--r--src/tests/data/hash/sha2_64.vec4
-rw-r--r--src/tests/test_hash.cpp3
17 files changed, 136 insertions, 75 deletions
diff --git a/doc/relnotes/1_11_13.rst b/doc/relnotes/1_11_13.rst
index 3be7bff70..f72c0f56b 100644
--- a/doc/relnotes/1_11_13.rst
+++ b/doc/relnotes/1_11_13.rst
@@ -5,6 +5,8 @@ Version 1.11.13, Not Yet Released
now uses "TLS SESSION" instead of "SSL SESSION" as the header,
and the version number of the binary format has also changed.
+* Add SHA-512/256
+
* Add DTLS-SRTP negotiation defined in RFC 5764
* The Python install script added in version 1.11.10 failed to place
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<u64bit>& 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<u64bit> digest;
+ secure_vector<u64bit> 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<u64bit> digest;
+ secure_vector<u64bit> 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<u64bit> 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<typename T>
+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<typename T, typename Alloc>
+void copy_out_vec_be(byte out[], size_t out_bytes, const std::vector<T, Alloc>& in)
+ {
+ copy_out_be(out, out_bytes, &in[0]);
+ }
+
+template<typename T>
+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<typename T, typename Alloc>
+void copy_out_vec_le(byte out[], size_t out_bytes, const std::vector<T, Alloc>& 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;
}
}