aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pk_pad/emsa_pssr
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-09-16 14:00:17 -0400
committerJack Lloyd <[email protected]>2017-09-16 14:04:47 -0400
commit6123db0a94f38f218bfdf61409b52ca23c28545b (patch)
treed7d62a1b429f7d783bdef8969853e279754c52a0 /src/lib/pk_pad/emsa_pssr
parente3f2528713840b128ab7645ef826f331ad7cbb29 (diff)
Support PSSR_Raw
Allows PSS-signing a raw hash while also still specifying the salt length. GH #1211
Diffstat (limited to 'src/lib/pk_pad/emsa_pssr')
-rw-r--r--src/lib/pk_pad/emsa_pssr/pssr.cpp161
-rw-r--r--src/lib/pk_pad/emsa_pssr/pssr.h38
2 files changed, 152 insertions, 47 deletions
diff --git a/src/lib/pk_pad/emsa_pssr/pssr.cpp b/src/lib/pk_pad/emsa_pssr/pssr.cpp
index 5f76b5a6f..e78a696f6 100644
--- a/src/lib/pk_pad/emsa_pssr/pssr.cpp
+++ b/src/lib/pk_pad/emsa_pssr/pssr.cpp
@@ -1,6 +1,6 @@
/*
* PSSR
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2007,2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -11,65 +11,49 @@
namespace Botan {
-/*
-* PSSR Update Operation
-*/
-void PSSR::update(const uint8_t input[], size_t length)
- {
- m_hash->update(input, length);
- }
-
-/*
-* Return the raw (unencoded) data
-*/
-secure_vector<uint8_t> PSSR::raw_data()
- {
- return m_hash->final();
- }
+namespace {
/*
* PSSR Encode Operation
*/
-secure_vector<uint8_t> PSSR::encoding_of(const secure_vector<uint8_t>& msg,
- size_t output_bits,
- RandomNumberGenerator& rng)
+secure_vector<uint8_t> pss_encode(HashFunction& hash,
+ const secure_vector<uint8_t>& msg,
+ const secure_vector<uint8_t>& salt,
+ size_t output_bits)
{
- const size_t HASH_SIZE = m_hash->output_length();
+ const size_t HASH_SIZE = hash.output_length();
+ const size_t SALT_SIZE = salt.size();
if(msg.size() != HASH_SIZE)
- throw Encoding_Error("PSSR::encoding_of: Bad input length");
- if(output_bits < 8*HASH_SIZE + 8*m_SALT_SIZE + 9)
- throw Encoding_Error("PSSR::encoding_of: Output length is too small");
+ throw Encoding_Error("Cannot encode PSS string, input length invalid for hash");
+ if(output_bits < 8*HASH_SIZE + 8*SALT_SIZE + 9)
+ throw Encoding_Error("Cannot encode PSS string, output length too small");
const size_t output_length = (output_bits + 7) / 8;
- secure_vector<uint8_t> salt = rng.random_vec(m_SALT_SIZE);
-
- for(size_t j = 0; j != 8; ++j)
- m_hash->update(0);
- m_hash->update(msg);
- m_hash->update(salt);
- secure_vector<uint8_t> H = m_hash->final();
+ for(size_t i = 0; i != 8; ++i)
+ hash.update(0);
+ hash.update(msg);
+ hash.update(salt);
+ secure_vector<uint8_t> H = hash.final();
secure_vector<uint8_t> EM(output_length);
- EM[output_length - HASH_SIZE - m_SALT_SIZE - 2] = 0x01;
- buffer_insert(EM, output_length - 1 - HASH_SIZE - m_SALT_SIZE, salt);
- mgf1_mask(*m_hash, H.data(), HASH_SIZE, EM.data(), output_length - HASH_SIZE - 1);
+ EM[output_length - HASH_SIZE - SALT_SIZE - 2] = 0x01;
+ buffer_insert(EM, output_length - 1 - HASH_SIZE - SALT_SIZE, salt);
+ mgf1_mask(hash, H.data(), HASH_SIZE, EM.data(), output_length - HASH_SIZE - 1);
EM[0] &= 0xFF >> (8 * ((output_bits + 7) / 8) - output_bits);
buffer_insert(EM, output_length - 1 - HASH_SIZE, H);
EM[output_length-1] = 0xBC;
-
return EM;
}
-/*
-* PSSR Decode/Verify Operation
-*/
-bool PSSR::verify(const secure_vector<uint8_t>& const_coded,
- const secure_vector<uint8_t>& raw, size_t key_bits)
+bool pss_verify(HashFunction& hash,
+ const secure_vector<uint8_t>& const_coded,
+ const secure_vector<uint8_t>& raw,
+ size_t key_bits)
{
- const size_t HASH_SIZE = m_hash->output_length();
+ const size_t HASH_SIZE = hash.output_length();
const size_t KEY_BYTES = (key_bits + 7) / 8;
if(key_bits < 8*HASH_SIZE + 9)
@@ -102,7 +86,7 @@ bool PSSR::verify(const secure_vector<uint8_t>& const_coded,
const uint8_t* H = &coded[DB_size];
const size_t H_size = HASH_SIZE;
- mgf1_mask(*m_hash, H, H_size, DB, DB_size);
+ mgf1_mask(hash, H, H_size, DB, DB_size);
DB[0] &= 0xFF >> TOP_BITS;
size_t salt_offset = 0;
@@ -116,23 +100,106 @@ bool PSSR::verify(const secure_vector<uint8_t>& const_coded,
if(salt_offset == 0)
return false;
+ const size_t salt_size = DB_size - salt_offset;
+
for(size_t j = 0; j != 8; ++j)
- m_hash->update(0);
- m_hash->update(raw);
- m_hash->update(&DB[salt_offset], DB_size - salt_offset);
- secure_vector<uint8_t> H2 = m_hash->final();
+ hash.update(0);
+ hash.update(raw);
+ hash.update(&DB[salt_offset], salt_size);
+
+ secure_vector<uint8_t> H2 = hash.final();
return same_mem(H, H2.data(), HASH_SIZE);
}
+}
+
PSSR::PSSR(HashFunction* h) :
- m_SALT_SIZE(h->output_length()), m_hash(h)
+ m_hash(h), m_SALT_SIZE(m_hash->output_length())
{
}
PSSR::PSSR(HashFunction* h, size_t salt_size) :
- m_SALT_SIZE(salt_size), m_hash(h)
+ m_hash(h), m_SALT_SIZE(salt_size)
+ {
+ }
+
+/*
+* PSSR Update Operation
+*/
+void PSSR::update(const uint8_t input[], size_t length)
+ {
+ m_hash->update(input, length);
+ }
+
+/*
+* Return the raw (unencoded) data
+*/
+secure_vector<uint8_t> PSSR::raw_data()
+ {
+ return m_hash->final();
+ }
+
+secure_vector<uint8_t> PSSR::encoding_of(const secure_vector<uint8_t>& msg,
+ size_t output_bits,
+ RandomNumberGenerator& rng)
+ {
+ secure_vector<uint8_t> salt = rng.random_vec(m_SALT_SIZE);
+ return pss_encode(*m_hash, msg, salt, output_bits);
+ }
+
+/*
+* PSSR Decode/Verify Operation
+*/
+bool PSSR::verify(const secure_vector<uint8_t>& coded,
+ const secure_vector<uint8_t>& raw,
+ size_t key_bits)
+ {
+ return pss_verify(*m_hash, coded, raw, key_bits);
+ }
+
+PSSR_Raw::PSSR_Raw(HashFunction* h) :
+ m_hash(h), m_SALT_SIZE(m_hash->output_length())
+ {
+ }
+
+PSSR_Raw::PSSR_Raw(HashFunction* h, size_t salt_size) :
+ m_hash(h), m_SALT_SIZE(salt_size)
+ {
+ }
+
+/*
+* PSSR_Raw Update Operation
+*/
+void PSSR_Raw::update(const uint8_t input[], size_t length)
+ {
+ m_msg.insert(m_msg.end(), input, input + length);
+ }
+
+/*
+* Return the raw (unencoded) data
+*/
+secure_vector<uint8_t> PSSR_Raw::raw_data()
+ {
+ return m_msg;
+ }
+
+secure_vector<uint8_t> PSSR_Raw::encoding_of(const secure_vector<uint8_t>& msg,
+ size_t output_bits,
+ RandomNumberGenerator& rng)
+ {
+ secure_vector<uint8_t> salt = rng.random_vec(m_SALT_SIZE);
+ return pss_encode(*m_hash, msg, salt, output_bits);
+ }
+
+/*
+* PSSR_Raw Decode/Verify Operation
+*/
+bool PSSR_Raw::verify(const secure_vector<uint8_t>& coded,
+ const secure_vector<uint8_t>& raw,
+ size_t key_bits)
{
+ return pss_verify(*m_hash, coded, raw, key_bits);
}
}
diff --git a/src/lib/pk_pad/emsa_pssr/pssr.h b/src/lib/pk_pad/emsa_pssr/pssr.h
index 0ed47c466..5bf36c198 100644
--- a/src/lib/pk_pad/emsa_pssr/pssr.h
+++ b/src/lib/pk_pad/emsa_pssr/pssr.h
@@ -45,8 +45,46 @@ class BOTAN_DLL PSSR final : public EMSA
const secure_vector<uint8_t>& raw,
size_t key_bits) override;
+ std::unique_ptr<HashFunction> m_hash;
size_t m_SALT_SIZE;
+ };
+
+/**
+* PSSR_Raw
+* This accepts a pre-hashed buffer
+*/
+class BOTAN_DLL PSSR_Raw final : public EMSA
+ {
+ public:
+
+ /**
+ * @param hash the hash function to use
+ */
+ explicit PSSR_Raw(HashFunction* hash);
+
+ /**
+ * @param hash the hash function to use
+ * @param salt_size the size of the salt to use in bytes
+ */
+ PSSR_Raw(HashFunction* hash, size_t salt_size);
+
+ EMSA* clone() override { return new PSSR_Raw(m_hash->clone(), m_SALT_SIZE); }
+ private:
+ void update(const uint8_t input[], size_t length) override;
+
+ secure_vector<uint8_t> raw_data() override;
+
+ secure_vector<uint8_t> encoding_of(const secure_vector<uint8_t>& msg,
+ size_t output_bits,
+ RandomNumberGenerator& rng) override;
+
+ bool verify(const secure_vector<uint8_t>& coded,
+ const secure_vector<uint8_t>& raw,
+ size_t key_bits) override;
+
std::unique_ptr<HashFunction> m_hash;
+ size_t m_SALT_SIZE;
+ secure_vector<uint8_t> m_msg;
};
}