aboutsummaryrefslogtreecommitdiffstats
path: root/modules/pk_pad/emsa1/emsa1.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/pk_pad/emsa1/emsa1.cpp')
-rw-r--r--modules/pk_pad/emsa1/emsa1.cpp112
1 files changed, 112 insertions, 0 deletions
diff --git a/modules/pk_pad/emsa1/emsa1.cpp b/modules/pk_pad/emsa1/emsa1.cpp
new file mode 100644
index 000000000..8977356e8
--- /dev/null
+++ b/modules/pk_pad/emsa1/emsa1.cpp
@@ -0,0 +1,112 @@
+/*************************************************
+* EMSA1 Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/emsa.h>
+#include <botan/lookup.h>
+
+namespace Botan {
+
+namespace {
+
+SecureVector<byte> emsa1_encoding(const MemoryRegion<byte>& msg,
+ u32bit output_bits)
+ {
+ if(8*msg.size() <= output_bits)
+ return msg;
+
+ u32bit shift = 8*msg.size() - output_bits;
+
+ u32bit byte_shift = shift / 8, bit_shift = shift % 8;
+ SecureVector<byte> digest(msg.size() - byte_shift);
+
+ for(u32bit j = 0; j != msg.size() - byte_shift; ++j)
+ digest[j] = msg[j];
+
+ if(bit_shift)
+ {
+ byte carry = 0;
+ for(u32bit j = 0; j != digest.size(); ++j)
+ {
+ byte temp = digest[j];
+ digest[j] = (temp >> bit_shift) | carry;
+ carry = (temp << (8 - bit_shift));
+ }
+ }
+ return digest;
+ }
+
+}
+
+/*************************************************
+* EMSA1 Update Operation *
+*************************************************/
+void EMSA1::update(const byte input[], u32bit length)
+ {
+ hash->update(input, length);
+ }
+
+/*************************************************
+* Return the raw (unencoded) data *
+*************************************************/
+SecureVector<byte> EMSA1::raw_data()
+ {
+ return hash->final();
+ }
+
+/*************************************************
+* EMSA1 Encode Operation *
+*************************************************/
+SecureVector<byte> EMSA1::encoding_of(const MemoryRegion<byte>& msg,
+ u32bit output_bits,
+ RandomNumberGenerator&)
+ {
+ if(msg.size() != hash->OUTPUT_LENGTH)
+ throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
+ return emsa1_encoding(msg, output_bits);
+ }
+
+/*************************************************
+* EMSA1 Decode/Verify Operation *
+*************************************************/
+bool EMSA1::verify(const MemoryRegion<byte>& coded,
+ const MemoryRegion<byte>& raw, u32bit key_bits) throw()
+ {
+ try {
+ if(raw.size() != hash->OUTPUT_LENGTH)
+ throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
+
+ SecureVector<byte> our_coding = emsa1_encoding(raw, key_bits);
+
+ if(our_coding == coded) return true;
+ if(our_coding[0] != 0) return false;
+ if(our_coding.size() <= coded.size()) return false;
+
+ u32bit offset = 0;
+ while(our_coding[offset] == 0 && offset < our_coding.size())
+ ++offset;
+ if(our_coding.size() - offset != coded.size())
+ return false;
+
+ for(u32bit j = 0; j != coded.size(); ++j)
+ if(coded[j] != our_coding[j+offset])
+ return false;
+
+ return true;
+ }
+ catch(Invalid_Argument)
+ {
+ return false;
+ }
+ }
+
+/*************************************************
+* EMSA1 Constructor *
+*************************************************/
+EMSA1::EMSA1(const std::string& hash_name) :
+ hash(get_hash(hash_name))
+ {
+ }
+
+}