diff options
Diffstat (limited to 'src/pk_pad')
-rw-r--r-- | src/pk_pad/eme1/eme1.cpp | 95 | ||||
-rw-r--r-- | src/pk_pad/eme1/eme1.h | 35 | ||||
-rw-r--r-- | src/pk_pad/eme1/modinfo.txt | 10 | ||||
-rw-r--r-- | src/pk_pad/eme_pkcs/eme_pkcs.cpp | 68 | ||||
-rw-r--r-- | src/pk_pad/eme_pkcs/eme_pkcs.h | 28 | ||||
-rw-r--r-- | src/pk_pad/eme_pkcs/modinfo.txt | 10 | ||||
-rw-r--r-- | src/pk_pad/emsa1/emsa1.cpp | 112 | ||||
-rw-r--r-- | src/pk_pad/emsa1/emsa1.h | 36 | ||||
-rw-r--r-- | src/pk_pad/emsa1/modinfo.txt | 10 | ||||
-rw-r--r-- | src/pk_pad/emsa2/emsa2.cpp | 106 | ||||
-rw-r--r-- | src/pk_pad/emsa2/emsa2.h | 38 | ||||
-rw-r--r-- | src/pk_pad/emsa2/modinfo.txt | 10 | ||||
-rw-r--r-- | src/pk_pad/emsa3/emsa3.cpp | 97 | ||||
-rw-r--r-- | src/pk_pad/emsa3/emsa3.h | 38 | ||||
-rw-r--r-- | src/pk_pad/emsa3/modinfo.txt | 10 | ||||
-rw-r--r-- | src/pk_pad/emsa4/emsa4.cpp | 144 | ||||
-rw-r--r-- | src/pk_pad/emsa4/emsa4.h | 38 | ||||
-rw-r--r-- | src/pk_pad/emsa4/modinfo.txt | 10 | ||||
-rw-r--r-- | src/pk_pad/emsa_raw/emsa_raw.cpp | 48 | ||||
-rw-r--r-- | src/pk_pad/emsa_raw/emsa_raw.h | 32 | ||||
-rw-r--r-- | src/pk_pad/emsa_raw/modinfo.txt | 10 |
21 files changed, 985 insertions, 0 deletions
diff --git a/src/pk_pad/eme1/eme1.cpp b/src/pk_pad/eme1/eme1.cpp new file mode 100644 index 000000000..2ca10c166 --- /dev/null +++ b/src/pk_pad/eme1/eme1.cpp @@ -0,0 +1,95 @@ +/************************************************* +* EME1 Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/eme1.h> +#include <botan/lookup.h> +#include <memory> + +namespace Botan { + +/************************************************* +* EME1 Pad Operation * +*************************************************/ +SecureVector<byte> EME1::pad(const byte in[], u32bit in_length, + u32bit key_length, + RandomNumberGenerator& rng) const + { + key_length /= 8; + + if(in_length > key_length - 2*HASH_LENGTH - 1) + throw Exception("EME1: Input is too large"); + + SecureVector<byte> out(key_length); + + out.clear(); + + rng.randomize(out, HASH_LENGTH); + + out.copy(HASH_LENGTH, Phash, Phash.size()); + out[out.size() - in_length - 1] = 0x01; + out.copy(out.size() - in_length, in, in_length); + mgf->mask(out, HASH_LENGTH, out + HASH_LENGTH, out.size() - HASH_LENGTH); + mgf->mask(out + HASH_LENGTH, out.size() - HASH_LENGTH, out, HASH_LENGTH); + + return out; + } + +/************************************************* +* EME1 Unpad Operation * +*************************************************/ +SecureVector<byte> EME1::unpad(const byte in[], u32bit in_length, + u32bit key_length) const + { + key_length /= 8; + if(in_length > key_length) + throw Decoding_Error("Invalid EME1 encoding"); + + SecureVector<byte> tmp(key_length); + tmp.copy(key_length - in_length, in, in_length); + + mgf->mask(tmp + HASH_LENGTH, tmp.size() - HASH_LENGTH, tmp, HASH_LENGTH); + mgf->mask(tmp, HASH_LENGTH, tmp + HASH_LENGTH, tmp.size() - HASH_LENGTH); + + for(u32bit j = 0; j != Phash.size(); ++j) + if(tmp[j+HASH_LENGTH] != Phash[j]) + throw Decoding_Error("Invalid EME1 encoding"); + + for(u32bit j = HASH_LENGTH + Phash.size(); j != tmp.size(); ++j) + { + if(tmp[j] && tmp[j] != 0x01) + throw Decoding_Error("Invalid EME1 encoding"); + if(tmp[j] && tmp[j] == 0x01) + { + SecureVector<byte> retval(tmp + j + 1, tmp.size() - j - 1); + return retval; + } + } + throw Decoding_Error("Invalid EME1 encoding"); + } + +/************************************************* +* Return the max input size for a given key size * +*************************************************/ +u32bit EME1::maximum_input_size(u32bit keybits) const + { + if(keybits / 8 > 2*HASH_LENGTH + 1) + return ((keybits / 8) - 2*HASH_LENGTH - 1); + else + return 0; + } + +/************************************************* +* EME1 Constructor * +*************************************************/ +EME1::EME1(const std::string& hash_name, const std::string& mgf_name, + const std::string& P) : + HASH_LENGTH(output_length_of(hash_name)) + { + mgf = get_mgf(mgf_name + "(" + hash_name + ")"); + std::auto_ptr<HashFunction> hash(get_hash(hash_name)); + Phash = hash->process(P); + } + +} diff --git a/src/pk_pad/eme1/eme1.h b/src/pk_pad/eme1/eme1.h new file mode 100644 index 000000000..2a0ac92c4 --- /dev/null +++ b/src/pk_pad/eme1/eme1.h @@ -0,0 +1,35 @@ +/************************************************* +* EME1 Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_EME1_H__ +#define BOTAN_EME1_H__ + +#include <botan/pk_util.h> + +namespace Botan { + +/************************************************* +* EME1 * +*************************************************/ +class BOTAN_DLL EME1 : public EME + { + public: + u32bit maximum_input_size(u32bit) const; + + EME1(const std::string&, const std::string&, const std::string& = ""); + ~EME1() { delete mgf; } + private: + SecureVector<byte> pad(const byte[], u32bit, u32bit, + RandomNumberGenerator&) const; + SecureVector<byte> unpad(const byte[], u32bit, u32bit) const; + + const u32bit HASH_LENGTH; + SecureVector<byte> Phash; + MGF* mgf; + }; + +} + +#endif diff --git a/src/pk_pad/eme1/modinfo.txt b/src/pk_pad/eme1/modinfo.txt new file mode 100644 index 000000000..5383d59b6 --- /dev/null +++ b/src/pk_pad/eme1/modinfo.txt @@ -0,0 +1,10 @@ +realname "EME1" + +define EME1 + +load_on auto + +<add> +eme1.h +eme1.cpp +</add> diff --git a/src/pk_pad/eme_pkcs/eme_pkcs.cpp b/src/pk_pad/eme_pkcs/eme_pkcs.cpp new file mode 100644 index 000000000..494f238b4 --- /dev/null +++ b/src/pk_pad/eme_pkcs/eme_pkcs.cpp @@ -0,0 +1,68 @@ +/************************************************* +* PKCS1 EME Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/eme_pkcs.h> + +namespace Botan { + +/************************************************* +* PKCS1 Pad Operation * +*************************************************/ +SecureVector<byte> EME_PKCS1v15::pad(const byte in[], u32bit inlen, + u32bit olen, + RandomNumberGenerator& rng) const + { + olen /= 8; + + if(olen < 10) + throw Encoding_Error("PKCS1: Output space too small"); + if(inlen > olen - 10) + throw Encoding_Error("PKCS1: Input is too large"); + + SecureVector<byte> out(olen); + + out[0] = 0x02; + for(u32bit j = 1; j != olen - inlen - 1; ++j) + while(out[j] == 0) + out[j] = rng.next_byte(); + out.copy(olen - inlen, in, inlen); + + return out; + } + +/************************************************* +* PKCS1 Unpad Operation * +*************************************************/ +SecureVector<byte> EME_PKCS1v15::unpad(const byte in[], u32bit inlen, + u32bit key_len) const + { + if(inlen != key_len / 8 || inlen < 10 || in[0] != 0x02) + throw Decoding_Error("PKCS1::unpad"); + + u32bit seperator = 0; + for(u32bit j = 0; j != inlen; ++j) + if(in[j] == 0) + { + seperator = j; + break; + } + if(seperator < 9) + throw Decoding_Error("PKCS1::unpad"); + + return SecureVector<byte>(in + seperator + 1, inlen - seperator - 1); + } + +/************************************************* +* Return the max input size for a given key size * +*************************************************/ +u32bit EME_PKCS1v15::maximum_input_size(u32bit keybits) const + { + if(keybits / 8 > 10) + return ((keybits / 8) - 10); + else + return 0; + } + +} diff --git a/src/pk_pad/eme_pkcs/eme_pkcs.h b/src/pk_pad/eme_pkcs/eme_pkcs.h new file mode 100644 index 000000000..9ec500c54 --- /dev/null +++ b/src/pk_pad/eme_pkcs/eme_pkcs.h @@ -0,0 +1,28 @@ +/************************************************* +* EME PKCS#1 v1.5 Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_EME_PKCS1_H__ +#define BOTAN_EME_PKCS1_H__ + +#include <botan/pk_util.h> + +namespace Botan { + +/************************************************* +* EME_PKCS1v15 * +*************************************************/ +class BOTAN_DLL EME_PKCS1v15 : public EME + { + public: + u32bit maximum_input_size(u32bit) const; + private: + SecureVector<byte> pad(const byte[], u32bit, u32bit, + RandomNumberGenerator&) const; + SecureVector<byte> unpad(const byte[], u32bit, u32bit) const; + }; + +} + +#endif diff --git a/src/pk_pad/eme_pkcs/modinfo.txt b/src/pk_pad/eme_pkcs/modinfo.txt new file mode 100644 index 000000000..88d9caf17 --- /dev/null +++ b/src/pk_pad/eme_pkcs/modinfo.txt @@ -0,0 +1,10 @@ +realname "PKCSv1 v1.5 EME" + +define EME_PKCS1v15 + +load_on auto + +<add> +eme_pkcs.h +eme_pkcs.cpp +</add> diff --git a/src/pk_pad/emsa1/emsa1.cpp b/src/pk_pad/emsa1/emsa1.cpp new file mode 100644 index 000000000..15d53f6e5 --- /dev/null +++ b/src/pk_pad/emsa1/emsa1.cpp @@ -0,0 +1,112 @@ +/************************************************* +* EMSA1 Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/emsa1.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)) + { + } + +} diff --git a/src/pk_pad/emsa1/emsa1.h b/src/pk_pad/emsa1/emsa1.h new file mode 100644 index 000000000..f8d7ac043 --- /dev/null +++ b/src/pk_pad/emsa1/emsa1.h @@ -0,0 +1,36 @@ +/************************************************* +* EMSA1 Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_EMSA1_H__ +#define BOTAN_EMSA1_H__ + +#include <botan/pk_util.h> + +namespace Botan { + +/************************************************* +* EMSA1 * +*************************************************/ +class BOTAN_DLL EMSA1 : public EMSA + { + public: + EMSA1(const std::string&); + ~EMSA1() { delete hash; } + private: + void update(const byte[], u32bit); + SecureVector<byte> raw_data(); + + SecureVector<byte> encoding_of(const MemoryRegion<byte>&, u32bit, + RandomNumberGenerator& rng); + + bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, + u32bit) throw(); + + HashFunction* hash; + }; + +} + +#endif diff --git a/src/pk_pad/emsa1/modinfo.txt b/src/pk_pad/emsa1/modinfo.txt new file mode 100644 index 000000000..4040dd580 --- /dev/null +++ b/src/pk_pad/emsa1/modinfo.txt @@ -0,0 +1,10 @@ +realname "EMSA1" + +define EMSA1 + +load_on auto + +<add> +emsa1.h +emsa1.cpp +</add> diff --git a/src/pk_pad/emsa2/emsa2.cpp b/src/pk_pad/emsa2/emsa2.cpp new file mode 100644 index 000000000..24292d390 --- /dev/null +++ b/src/pk_pad/emsa2/emsa2.cpp @@ -0,0 +1,106 @@ +/************************************************* +* EMSA2 Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/emsa2.h> +#include <botan/hash_id.h> +#include <botan/lookup.h> + +namespace Botan { + +namespace { + +/************************************************* +* EMSA2 Encode Operation * +*************************************************/ +SecureVector<byte> emsa2_encoding(const MemoryRegion<byte>& msg, + u32bit output_bits, + const MemoryRegion<byte>& empty_hash, + byte hash_id) + { + const u32bit HASH_SIZE = empty_hash.size(); + + u32bit output_length = (output_bits + 1) / 8; + + if(msg.size() != HASH_SIZE) + throw Encoding_Error("EMSA2::encoding_of: Bad input length"); + if(output_length < HASH_SIZE + 4) + throw Encoding_Error("EMSA2::encoding_of: Output length is too small"); + + bool empty = true; + for(u32bit j = 0; j != HASH_SIZE; ++j) + if(empty_hash[j] != msg[j]) + empty = false; + + SecureVector<byte> output(output_length); + + output[0] = (empty ? 0x4B : 0x6B); + output[output_length - 3 - HASH_SIZE] = 0xBA; + set_mem(output + 1, output_length - 4 - HASH_SIZE, 0xBB); + output.copy(output_length - (HASH_SIZE + 2), msg, msg.size()); + output[output_length-2] = hash_id; + output[output_length-1] = 0xCC; + + return output; + } + +} + +/************************************************* +* EMSA2 Update Operation * +*************************************************/ +void EMSA2::update(const byte input[], u32bit length) + { + hash->update(input, length); + } + +/************************************************* +* Return the raw (unencoded) data * +*************************************************/ +SecureVector<byte> EMSA2::raw_data() + { + return hash->final(); + } + +/************************************************* +* EMSA2 Encode Operation * +*************************************************/ +SecureVector<byte> EMSA2::encoding_of(const MemoryRegion<byte>& msg, + u32bit output_bits, + RandomNumberGenerator&) + { + return emsa2_encoding(msg, output_bits, empty_hash, hash_id); + } + +/************************************************* +* EMSA2 Verify Operation * +*************************************************/ +bool EMSA2::verify(const MemoryRegion<byte>& coded, + const MemoryRegion<byte>& raw, + u32bit key_bits) throw() + { + try + { + return (coded == emsa2_encoding(raw, key_bits, + empty_hash, hash_id)); + } + catch(...) + { + return false; + } + } + +/************************************************* +* EMSA2 Constructor * +*************************************************/ +EMSA2::EMSA2(const std::string& hash_name) + { + hash_id = ieee1363_hash_id(hash_name); + if(hash_id == 0) + throw Encoding_Error("EMSA2 cannot be used with " + hash->name()); + hash = get_hash(hash_name); + empty_hash = hash->final(); + } + +} diff --git a/src/pk_pad/emsa2/emsa2.h b/src/pk_pad/emsa2/emsa2.h new file mode 100644 index 000000000..5db9593f8 --- /dev/null +++ b/src/pk_pad/emsa2/emsa2.h @@ -0,0 +1,38 @@ +/************************************************* +* EMSA2 Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_EMSA2_H__ +#define BOTAN_EMSA2_H__ + +#include <botan/pk_util.h> + +namespace Botan { + +/************************************************* +* EMSA2 * +*************************************************/ +class BOTAN_DLL EMSA2 : public EMSA + { + public: + EMSA2(const std::string&); + ~EMSA2() { delete hash; } + private: + void update(const byte[], u32bit); + SecureVector<byte> raw_data(); + + SecureVector<byte> encoding_of(const MemoryRegion<byte>&, u32bit, + RandomNumberGenerator& rng); + + bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, + u32bit) throw(); + + SecureVector<byte> empty_hash; + HashFunction* hash; + byte hash_id; + }; + +} + +#endif diff --git a/src/pk_pad/emsa2/modinfo.txt b/src/pk_pad/emsa2/modinfo.txt new file mode 100644 index 000000000..8d14da548 --- /dev/null +++ b/src/pk_pad/emsa2/modinfo.txt @@ -0,0 +1,10 @@ +realname "EMSA2" + +define EMSA2 + +load_on auto + +<add> +emsa2.h +emsa2.cpp +</add> diff --git a/src/pk_pad/emsa3/emsa3.cpp b/src/pk_pad/emsa3/emsa3.cpp new file mode 100644 index 000000000..60880d1aa --- /dev/null +++ b/src/pk_pad/emsa3/emsa3.cpp @@ -0,0 +1,97 @@ +/************************************************* +* EMSA3 Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/emsa3.h> +#include <botan/hash_id.h> +#include <botan/lookup.h> + +namespace Botan { + +namespace { + +/************************************************* +* EMSA3 Encode Operation * +*************************************************/ +SecureVector<byte> emsa3_encoding(const MemoryRegion<byte>& msg, + u32bit output_bits, + const MemoryRegion<byte>& hash_id, + u32bit hash_size) + { + if(msg.size() != hash_size) + throw Encoding_Error("EMSA3::encoding_of: Bad input length"); + + u32bit output_length = output_bits / 8; + if(output_length < hash_id.size() + hash_size + 10) + throw Encoding_Error("EMSA3::pad: Output length is too small"); + + SecureVector<byte> T(output_length); + const u32bit P_LENGTH = output_length - hash_size - hash_id.size() - 2; + + T[0] = 0x01; + set_mem(T+1, P_LENGTH, 0xFF); + T[P_LENGTH+1] = 0x00; + T.copy(P_LENGTH+2, hash_id, hash_id.size()); + T.copy(output_length-hash_size, msg, msg.size()); + return T; + } + +} + +/************************************************* +* EMSA3 Update Operation * +*************************************************/ +void EMSA3::update(const byte input[], u32bit length) + { + hash->update(input, length); + } + +/************************************************* +* Return the raw (unencoded) data * +*************************************************/ +SecureVector<byte> EMSA3::raw_data() + { + return hash->final(); + } + +/************************************************* +* EMSA3 Encode Operation * +*************************************************/ +SecureVector<byte> EMSA3::encoding_of(const MemoryRegion<byte>& msg, + u32bit output_bits, + RandomNumberGenerator&) + { + return emsa3_encoding(msg, output_bits, hash_id, + hash->OUTPUT_LENGTH); + } + +/************************************************* +* Default signature decoding * +*************************************************/ +bool EMSA3::verify(const MemoryRegion<byte>& coded, + const MemoryRegion<byte>& raw, + u32bit key_bits) throw() + { + try + { + return (coded == emsa3_encoding(raw, key_bits, + hash_id, + hash->OUTPUT_LENGTH)); + } + catch(...) + { + return false; + } + } + +/************************************************* +* EMSA3 Constructor * +*************************************************/ +EMSA3::EMSA3(const std::string& hash_name) + { + hash_id = pkcs_hash_id(hash_name); + hash = get_hash(hash_name); + } + +} diff --git a/src/pk_pad/emsa3/emsa3.h b/src/pk_pad/emsa3/emsa3.h new file mode 100644 index 000000000..fa8521216 --- /dev/null +++ b/src/pk_pad/emsa3/emsa3.h @@ -0,0 +1,38 @@ +/************************************************* +* EMSA3 Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_EMSA3_H__ +#define BOTAN_EMSA3_H__ + +#include <botan/pk_util.h> + +namespace Botan { + +/************************************************* +* EMSA3 * +*************************************************/ +class BOTAN_DLL EMSA3 : public EMSA + { + public: + EMSA3(const std::string&); + ~EMSA3() { delete hash; } + private: + void update(const byte[], u32bit); + + SecureVector<byte> raw_data(); + + SecureVector<byte> encoding_of(const MemoryRegion<byte>&, u32bit, + RandomNumberGenerator& rng); + + bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, + u32bit) throw(); + + HashFunction* hash; + SecureVector<byte> hash_id; + }; + +} + +#endif diff --git a/src/pk_pad/emsa3/modinfo.txt b/src/pk_pad/emsa3/modinfo.txt new file mode 100644 index 000000000..926f9a4e8 --- /dev/null +++ b/src/pk_pad/emsa3/modinfo.txt @@ -0,0 +1,10 @@ +realname "EMSA3" + +define EMSA3 + +load_on auto + +<add> +emsa3.h +emsa3.cpp +</add> diff --git a/src/pk_pad/emsa4/emsa4.cpp b/src/pk_pad/emsa4/emsa4.cpp new file mode 100644 index 000000000..9821c1f13 --- /dev/null +++ b/src/pk_pad/emsa4/emsa4.cpp @@ -0,0 +1,144 @@ +/************************************************* +* EMSA4 Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/emsa4.h> +#include <botan/lookup.h> +#include <botan/look_pk.h> +#include <botan/bit_ops.h> + +namespace Botan { + +/************************************************* +* EMSA4 Update Operation * +*************************************************/ +void EMSA4::update(const byte input[], u32bit length) + { + hash->update(input, length); + } + +/************************************************* +* Return the raw (unencoded) data * +*************************************************/ +SecureVector<byte> EMSA4::raw_data() + { + return hash->final(); + } + +/************************************************* +* EMSA4 Encode Operation * +*************************************************/ +SecureVector<byte> EMSA4::encoding_of(const MemoryRegion<byte>& msg, + u32bit output_bits, + RandomNumberGenerator& rng) + { + const u32bit HASH_SIZE = hash->OUTPUT_LENGTH; + + if(msg.size() != HASH_SIZE) + throw Encoding_Error("EMSA4::encoding_of: Bad input length"); + if(output_bits < 8*HASH_SIZE + 8*SALT_SIZE + 9) + throw Encoding_Error("EMSA4::encoding_of: Output length is too small"); + + const u32bit output_length = (output_bits + 7) / 8; + + SecureVector<byte> salt(SALT_SIZE); + rng.randomize(salt, SALT_SIZE); + + for(u32bit j = 0; j != 8; ++j) + hash->update(0); + hash->update(msg); + hash->update(salt, SALT_SIZE); + SecureVector<byte> H = hash->final(); + + SecureVector<byte> EM(output_length); + + EM[output_length - HASH_SIZE - SALT_SIZE - 2] = 0x01; + EM.copy(output_length - 1 - HASH_SIZE - SALT_SIZE, salt, SALT_SIZE); + mgf->mask(H, HASH_SIZE, EM, output_length - HASH_SIZE - 1); + EM[0] &= 0xFF >> (8 * ((output_bits + 7) / 8) - output_bits); + EM.copy(output_length - 1 - HASH_SIZE, H, HASH_SIZE); + EM[output_length-1] = 0xBC; + + return EM; + } + +/************************************************* +* EMSA4 Decode/Verify Operation * +*************************************************/ +bool EMSA4::verify(const MemoryRegion<byte>& const_coded, + const MemoryRegion<byte>& raw, u32bit key_bits) throw() + { + const u32bit HASH_SIZE = hash->OUTPUT_LENGTH; + const u32bit KEY_BYTES = (key_bits + 7) / 8; + + if(key_bits < 8*HASH_SIZE + 9) + return false; + if(raw.size() != HASH_SIZE) + return false; + if(const_coded.size() > KEY_BYTES) + return false; + if(const_coded[const_coded.size()-1] != 0xBC) + return false; + + SecureVector<byte> coded = const_coded; + if(coded.size() < KEY_BYTES) + { + SecureVector<byte> temp(KEY_BYTES); + temp.copy(KEY_BYTES - coded.size(), coded, coded.size()); + coded = temp; + } + + const u32bit TOP_BITS = 8 * ((key_bits + 7) / 8) - key_bits; + if(TOP_BITS > 8 - high_bit(coded[0])) + return false; + + SecureVector<byte> DB(coded.begin(), coded.size() - HASH_SIZE - 1); + SecureVector<byte> H(coded + coded.size() - HASH_SIZE - 1, HASH_SIZE); + + mgf->mask(H, H.size(), DB, coded.size() - H.size() - 1); + DB[0] &= 0xFF >> TOP_BITS; + + u32bit salt_offset = 0; + for(u32bit j = 0; j != DB.size(); ++j) + { + if(DB[j] == 0x01) + { salt_offset = j + 1; break; } + if(DB[j]) + return false; + } + if(salt_offset == 0) + return false; + + SecureVector<byte> salt(DB + salt_offset, DB.size() - salt_offset); + + for(u32bit j = 0; j != 8; ++j) + hash->update(0); + hash->update(raw); + hash->update(salt); + SecureVector<byte> H2 = hash->final(); + + return (H == H2); + } + +/************************************************* +* EMSA4 Constructor * +*************************************************/ +EMSA4::EMSA4(const std::string& hash_name, const std::string& mgf_name) : + SALT_SIZE(output_length_of(hash_name)) + { + hash = get_hash(hash_name); + mgf = get_mgf(mgf_name + "(" + hash_name + ")"); + } + +/************************************************* +* EMSA4 Constructor * +*************************************************/ +EMSA4::EMSA4(const std::string& hash_name, const std::string& mgf_name, + u32bit salt_size) : SALT_SIZE(salt_size) + { + hash = get_hash(hash_name); + mgf = get_mgf(mgf_name + "(" + hash_name + ")"); + } + +} diff --git a/src/pk_pad/emsa4/emsa4.h b/src/pk_pad/emsa4/emsa4.h new file mode 100644 index 000000000..f4d4a4b6d --- /dev/null +++ b/src/pk_pad/emsa4/emsa4.h @@ -0,0 +1,38 @@ +/************************************************* +* EMSA4 Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_EMSA4_H__ +#define BOTAN_EMSA4_H__ + +#include <botan/pk_util.h> + +namespace Botan { + +/************************************************* +* EMSA4 * +*************************************************/ +class BOTAN_DLL EMSA4 : public EMSA + { + public: + EMSA4(const std::string&, const std::string&); + EMSA4(const std::string&, const std::string&, u32bit); + ~EMSA4() { delete hash; delete mgf; } + private: + void update(const byte[], u32bit); + SecureVector<byte> raw_data(); + + SecureVector<byte> encoding_of(const MemoryRegion<byte>&, u32bit, + RandomNumberGenerator& rng); + bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, + u32bit) throw(); + + const u32bit SALT_SIZE; + HashFunction* hash; + const MGF* mgf; + }; + +} + +#endif diff --git a/src/pk_pad/emsa4/modinfo.txt b/src/pk_pad/emsa4/modinfo.txt new file mode 100644 index 000000000..39a34c619 --- /dev/null +++ b/src/pk_pad/emsa4/modinfo.txt @@ -0,0 +1,10 @@ +realname "EMSA4" + +define EMSA4 + +load_on auto + +<add> +emsa4.h +emsa4.cpp +</add> diff --git a/src/pk_pad/emsa_raw/emsa_raw.cpp b/src/pk_pad/emsa_raw/emsa_raw.cpp new file mode 100644 index 000000000..c10bb4890 --- /dev/null +++ b/src/pk_pad/emsa_raw/emsa_raw.cpp @@ -0,0 +1,48 @@ +/************************************************* +* EMSA-Raw Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/emsa_raw.h> + +namespace Botan { + +/************************************************* +* EMSA-Raw Encode Operation * +*************************************************/ +void EMSA_Raw::update(const byte input[], u32bit length) + { + message.append(input, length); + } + +/************************************************* +* Return the raw (unencoded) data * +*************************************************/ +SecureVector<byte> EMSA_Raw::raw_data() + { + SecureVector<byte> buf = message; + message.destroy(); + return buf; + } + +/************************************************* +* EMSA-Raw Encode Operation * +*************************************************/ +SecureVector<byte> EMSA_Raw::encoding_of(const MemoryRegion<byte>& msg, + u32bit, + RandomNumberGenerator&) + { + return msg; + } + +/************************************************* +* EMSA-Raw Verify Operation * +*************************************************/ +bool EMSA_Raw::verify(const MemoryRegion<byte>& coded, + const MemoryRegion<byte>& raw, + u32bit) throw() + { + return (coded == raw); + } + +} diff --git a/src/pk_pad/emsa_raw/emsa_raw.h b/src/pk_pad/emsa_raw/emsa_raw.h new file mode 100644 index 000000000..a9e21d0e0 --- /dev/null +++ b/src/pk_pad/emsa_raw/emsa_raw.h @@ -0,0 +1,32 @@ +/************************************************* +* EMSA-Raw Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_EMSA_RAW_H__ +#define BOTAN_EMSA_RAW_H__ + +#include <botan/pk_util.h> + +namespace Botan { + +/************************************************* +* EMSA-Raw * +*************************************************/ +class BOTAN_DLL EMSA_Raw : public EMSA + { + private: + void update(const byte[], u32bit); + SecureVector<byte> raw_data(); + + SecureVector<byte> encoding_of(const MemoryRegion<byte>&, u32bit, + RandomNumberGenerator&); + bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, + u32bit) throw(); + + SecureVector<byte> message; + }; + +} + +#endif diff --git a/src/pk_pad/emsa_raw/modinfo.txt b/src/pk_pad/emsa_raw/modinfo.txt new file mode 100644 index 000000000..2a88d10fa --- /dev/null +++ b/src/pk_pad/emsa_raw/modinfo.txt @@ -0,0 +1,10 @@ +realname "EMSA-Raw" + +define EMSA_RAW + +load_on auto + +<add> +emsa_raw.h +emsa_raw.cpp +</add> |