diff options
Diffstat (limited to 'lib/pk_pad/emsa1')
-rw-r--r-- | lib/pk_pad/emsa1/emsa1.cpp | 105 | ||||
-rw-r--r-- | lib/pk_pad/emsa1/emsa1.h | 48 | ||||
-rw-r--r-- | lib/pk_pad/emsa1/info.txt | 5 |
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> |