I'm trying to develop a class similar to the DefaultEncryptorWithMAC. Instead of deriving the DES-EDE2 key from a passphrase, it will be recovered from a secret share (so far so good).
I want to pipe the plaintext through a DES encryptor, and compute the
SHA-1 of the same plaintext. The SHA-1 value will be appended to the
plaintext, and encrypted with the same DES key. The DES IV will probably be prepended to the ciphertext, I just haven't decided yet.
A ChannelSwitch seems to be an appropriate means for encrypting and hashing "simultaneously", but I can't see how to attach it to the class inheriting from ProxyFilter.
I'm obviously close to the beginning of the learning curve...
Here's my class definition (with apologies for my clumsy hacks to DefaultEncryptor):
*****************************************************************
typedef DES_EDE3 MyBlockCipher; typedef SHA MyHashModule;
static const unsigned int DIGESTSIZE = MyHashModule::DIGESTSIZE; static const unsigned int BLOCKSIZE = \ MyBlockCipher::Encryption::BLOCKSIZE; static const unsigned int KEYLENGTH = \ MyBlockCipher::Encryption::DEFAULT_KEYLENGTH;
// Encryptor using DES-EDE3
class MyEncryptor : public ProxyFilter
{
public:
MyEncryptor(int threshold, char *const *shareFiles,
BufferedTransformation *attachment = NULL);protected:
void FirstPut(const byte *);
void LastPut(const byte *inString, unsigned int length);private:
MyHashModule m_hash;
CBC_Mode<MyBlockCipher>::Encryption m_cipher;
ChannelSwitch *m_input;
};
******************************************************************and here's my attempt at a constructor:
******************************************************************
MyEncryptor::MyEncryptor(int threshold, char *const *shareFiles,
BufferedTransformation *attachment)
: ProxyFilter(NULL, 0, 0, attachment)
{
// Recover the key from the shareFiles
SecByteBlock key(KEYLENGTH);
SecretRecover(key, KEYLENGTH, threshold, shareFiles); // Fill the IV with random data
SecByteBlock IV(BLOCKSIZE);
AutoSeededX917RNG<DES_EDE3> rng;
RandomNumberSource keyGen(rng, BLOCKSIZE, true, new
ArraySink(IV, BLOCKSIZE)); // Setup the encryption cipher
m_cipher.SetKeyWithIV(key, key.size(), IV); StreamTransformationFilter encryptor(m_cipher);
HashFilter h(m_hash);auto_ptr<ChannelSwitch> input_switch(new ChannelSwitch);
input_switch->AddRoute("Encrypt", encryptor, "TDES-CBC");
input_switch->AddRoute("MAC", h, "Sha1");m_input = input_switch.release();
SetFilter(m_input); } *******************************************************************
The strings in the AddRoute calls are meaningless values only inserted to satisfy the compiler (which couldn't seem to find the AddRoute(BufferedTransformation) version).
I have lots of questions. Here are just three of them...
1) The compiler objects to the SetFilter(m_input), although as far as I can seek, ChannelSwitch inherits from Sink, which inherits from BufferedTransformation. I guess I have to do some casting?
2) Should I create StreamTransformationFilter and HashFilter using "new"? So far I've failed with code like:
input_switch->AddRoute("Encrypt", new StreamTransformationFilter(m_cipher), "TDES-CBC");
but what happens to the StreamTransformationFilter and the HashFilter objects on completion of the code in the constructor? Do they get destroyed as they go out of scope?
3) Why is auto_ptr used in the DefaultEncryptor class when other smart pointers are available (e.g. member_ptr) in Crypto++?
Thanks in advance --
_____________________________________________ James Bishop Institute for the Protection and Security of the Citizen (IPSC) European Commission - Joint Research Centre I - 21020 Ispra, Italy Tel.: +39 0332 786225 Fax.: +39 0332 789757 e-mail: [EMAIL PROTECTED]
