aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-01-30 12:16:50 -0500
committerJack Lloyd <[email protected]>2018-01-30 12:41:35 -0500
commitc3a2c598f7f9ac714681e7f7c7568dd022451382 (patch)
treef2d7bc6939cbdc81653115eb64bde1f6634df93f
parentd8e6c5bd2912e19654ad46389fb27dcb00610b66 (diff)
Avoid allocating zero bytes for SHA-3 padding
Inspired by #1433
-rw-r--r--src/lib/hash/keccak/keccak.cpp7
-rw-r--r--src/lib/hash/sha3/sha3.cpp17
-rw-r--r--src/lib/hash/sha3/sha3.h14
-rw-r--r--src/lib/hash/shake/shake.cpp17
4 files changed, 28 insertions, 27 deletions
diff --git a/src/lib/hash/keccak/keccak.cpp b/src/lib/hash/keccak/keccak.cpp
index 94e3f70ba..a4d4cef7d 100644
--- a/src/lib/hash/keccak/keccak.cpp
+++ b/src/lib/hash/keccak/keccak.cpp
@@ -53,12 +53,7 @@ void Keccak_1600::add_data(const uint8_t input[], size_t length)
void Keccak_1600::final_result(uint8_t output[])
{
- std::vector<uint8_t> padding(m_bitrate / 8 - m_S_pos);
-
- padding[0] = 0x01;
- padding[padding.size()-1] |= 0x80;
-
- add_data(padding.data(), padding.size());
+ SHA_3::finish(m_bitrate, m_S, m_S_pos, 0x01, 0x80);
/*
* We never have to run the permutation again because we only support
diff --git a/src/lib/hash/sha3/sha3.cpp b/src/lib/hash/sha3/sha3.cpp
index 1556e5498..df6fa64e5 100644
--- a/src/lib/hash/sha3/sha3.cpp
+++ b/src/lib/hash/sha3/sha3.cpp
@@ -177,6 +177,16 @@ size_t SHA_3::absorb(size_t bitrate,
}
//static
+void SHA_3::finish(size_t bitrate,
+ secure_vector<uint64_t>& S, size_t S_pos,
+ uint8_t init_pad, uint8_t fini_pad)
+ {
+ S[S_pos / 8] ^= static_cast<uint64_t>(init_pad) << (8 * (S_pos % 8));
+ S[(bitrate / 64) - 1] ^= static_cast<uint64_t>(fini_pad) << 56;
+ SHA_3::permute(S.data());
+ }
+
+//static
void SHA_3::expand(size_t bitrate,
secure_vector<uint64_t>& S,
uint8_t output[], size_t output_length)
@@ -211,12 +221,7 @@ void SHA_3::add_data(const uint8_t input[], size_t length)
void SHA_3::final_result(uint8_t output[])
{
- std::vector<uint8_t> padding(m_bitrate / 8 - m_S_pos);
-
- padding[0] = 0x06;
- padding[padding.size()-1] |= 0x80;
-
- add_data(padding.data(), padding.size());
+ SHA_3::finish(m_bitrate, m_S, m_S_pos, 0x06, 0x80);
/*
* We never have to run the permutation again because we only support
diff --git a/src/lib/hash/sha3/sha3.h b/src/lib/hash/sha3/sha3.h
index ac01ca6dc..a3a666971 100644
--- a/src/lib/hash/sha3/sha3.h
+++ b/src/lib/hash/sha3/sha3.h
@@ -50,6 +50,20 @@ class BOTAN_PUBLIC_API(2,0) SHA_3 : public HashFunction
const uint8_t input[], size_t length);
/**
+ * Add final padding and permute. The padding is assumed to be
+ * init_pad || 00... || fini_pad
+ *
+ * @param bitrate the bitrate to absorb into the sponge
+ * @param S the sponge state
+ * @param S_pos where to begin absorbing into S
+ * @param init_pad the leading pad bits
+ * @param fini_pad the final pad bits
+ */
+ static void finish(size_t bitrate,
+ secure_vector<uint64_t>& S, size_t S_pos,
+ uint8_t init_pad, uint8_t fini_pad);
+
+ /**
* Expand from provided state
* @param bitrate sponge parameter
* @param S the state
diff --git a/src/lib/hash/shake/shake.cpp b/src/lib/hash/shake/shake.cpp
index ab7c9debe..76ed79a27 100644
--- a/src/lib/hash/shake/shake.cpp
+++ b/src/lib/hash/shake/shake.cpp
@@ -47,15 +47,8 @@ void SHAKE_128::add_data(const uint8_t input[], size_t length)
void SHAKE_128::final_result(uint8_t output[])
{
- std::vector<uint8_t> padding(SHAKE_128_BITRATE / 8 - m_S_pos);
-
- padding[0] = 0x1F;
- padding[padding.size()-1] |= 0x80;
-
- add_data(padding.data(), padding.size());
-
+ SHA_3::finish(SHAKE_128_BITRATE, m_S, m_S_pos, 0x1F, 0x80);
SHA_3::expand(SHAKE_128_BITRATE, m_S, output, output_length());
-
clear();
}
@@ -95,13 +88,7 @@ void SHAKE_256::add_data(const uint8_t input[], size_t length)
void SHAKE_256::final_result(uint8_t output[])
{
- std::vector<uint8_t> padding(SHAKE_256_BITRATE / 8 - m_S_pos);
-
- padding[0] = 0x1F;
- padding[padding.size()-1] |= 0x80;
-
- add_data(padding.data(), padding.size());
-
+ SHA_3::finish(SHAKE_256_BITRATE, m_S, m_S_pos, 0x1F, 0x80);
SHA_3::expand(SHAKE_256_BITRATE, m_S, output, output_length());
clear();