aboutsummaryrefslogtreecommitdiffstats
path: root/lib/pk_pad/emsa1
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pk_pad/emsa1')
-rw-r--r--lib/pk_pad/emsa1/emsa1.cpp105
-rw-r--r--lib/pk_pad/emsa1/emsa1.h48
-rw-r--r--lib/pk_pad/emsa1/info.txt5
3 files changed, 158 insertions, 0 deletions
diff --git a/lib/pk_pad/emsa1/emsa1.cpp b/lib/pk_pad/emsa1/emsa1.cpp
new file mode 100644
index 000000000..2358023f8
--- /dev/null
+++ b/lib/pk_pad/emsa1/emsa1.cpp
@@ -0,0 +1,105 @@
+/*
+* EMSA1
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/emsa1.h>
+
+namespace Botan {
+
+namespace {
+
+secure_vector<byte> emsa1_encoding(const secure_vector<byte>& msg,
+ size_t output_bits)
+ {
+ if(8*msg.size() <= output_bits)
+ return msg;
+
+ size_t shift = 8*msg.size() - output_bits;
+
+ size_t byte_shift = shift / 8, bit_shift = shift % 8;
+ secure_vector<byte> digest(msg.size() - byte_shift);
+
+ for(size_t j = 0; j != msg.size() - byte_shift; ++j)
+ digest[j] = msg[j];
+
+ if(bit_shift)
+ {
+ byte carry = 0;
+ for(size_t 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[], size_t length)
+ {
+ hash->update(input, length);
+ }
+
+/*
+* Return the raw (unencoded) data
+*/
+secure_vector<byte> EMSA1::raw_data()
+ {
+ return hash->final();
+ }
+
+/*
+* EMSA1 Encode Operation
+*/
+secure_vector<byte> EMSA1::encoding_of(const secure_vector<byte>& msg,
+ size_t 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 secure_vector<byte>& coded,
+ const secure_vector<byte>& raw, size_t key_bits)
+ {
+ try {
+ if(raw.size() != hash->output_length())
+ throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
+
+ secure_vector<byte> our_coding = emsa1_encoding(raw, key_bits);
+
+ if(our_coding == coded) return true;
+ if(our_coding.empty() || our_coding[0] != 0) return false;
+ if(our_coding.size() <= coded.size()) return false;
+
+ size_t offset = 0;
+ while(offset < our_coding.size() && our_coding[offset] == 0)
+ ++offset;
+ if(our_coding.size() - offset != coded.size())
+ return false;
+
+ for(size_t j = 0; j != coded.size(); ++j)
+ if(coded[j] != our_coding[j+offset])
+ return false;
+
+ return true;
+ }
+ catch(Invalid_Argument)
+ {
+ return false;
+ }
+ }
+
+}
diff --git a/lib/pk_pad/emsa1/emsa1.h b/lib/pk_pad/emsa1/emsa1.h
new file mode 100644
index 000000000..f84ca5ae7
--- /dev/null
+++ b/lib/pk_pad/emsa1/emsa1.h
@@ -0,0 +1,48 @@
+/*
+* EMSA1
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_EMSA1_H__
+#define BOTAN_EMSA1_H__
+
+#include <botan/emsa.h>
+#include <botan/hash.h>
+
+namespace Botan {
+
+/**
+* EMSA1 from IEEE 1363
+* Essentially, sign the hash directly
+*/
+class BOTAN_DLL EMSA1 : public EMSA
+ {
+ public:
+ /**
+ * @param h the hash object to use
+ */
+ EMSA1(HashFunction* h) : hash(h) {}
+ ~EMSA1() { delete hash; }
+ protected:
+ /**
+ * @return const pointer to the underlying hash
+ */
+ const HashFunction* hash_ptr() const { return hash; }
+ private:
+ void update(const byte[], size_t);
+ secure_vector<byte> raw_data();
+
+ secure_vector<byte> encoding_of(const secure_vector<byte>&, size_t,
+ RandomNumberGenerator& rng);
+
+ bool verify(const secure_vector<byte>&, const secure_vector<byte>&,
+ size_t);
+
+ HashFunction* hash;
+ };
+
+}
+
+#endif
diff --git a/lib/pk_pad/emsa1/info.txt b/lib/pk_pad/emsa1/info.txt
new file mode 100644
index 000000000..83d9744e6
--- /dev/null
+++ b/lib/pk_pad/emsa1/info.txt
@@ -0,0 +1,5 @@
+define EMSA1 20131128
+
+<requires>
+hash
+</requires>