seckey.h

00001 // seckey.h - written and placed in the public domain by Wei Dai
00002 
00003 // This file contains helper classes/functions for implementing secret key algorithms.
00004 
00005 #ifndef CRYPTOPP_SECKEY_H
00006 #define CRYPTOPP_SECKEY_H
00007 
00008 #include "cryptlib.h"
00009 #include "misc.h"
00010 #include "simple.h"
00011 
00012 NAMESPACE_BEGIN(CryptoPP)
00013 
00014 inline CipherDir ReverseCipherDir(CipherDir dir)
00015 {
00016         return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION;
00017 }
00018 
00019 //! to be inherited by block ciphers with fixed block size
00020 template <unsigned int N>
00021 class FixedBlockSize
00022 {
00023 public:
00024         CRYPTOPP_CONSTANT(BLOCKSIZE = N)
00025 };
00026 
00027 // ************** rounds ***************
00028 
00029 //! to be inherited by ciphers with fixed number of rounds
00030 template <unsigned int R>
00031 class FixedRounds
00032 {
00033 public:
00034         CRYPTOPP_CONSTANT(ROUNDS = R)
00035 };
00036 
00037 //! to be inherited by ciphers with variable number of rounds
00038 template <unsigned int D, unsigned int N=1, unsigned int M=INT_MAX>             // use INT_MAX here because enums are treated as signed ints
00039 class VariableRounds
00040 {
00041 public:
00042         CRYPTOPP_CONSTANT(DEFAULT_ROUNDS = D)
00043         CRYPTOPP_CONSTANT(MIN_ROUNDS = N)
00044         CRYPTOPP_CONSTANT(MAX_ROUNDS = M)
00045         static unsigned int StaticGetDefaultRounds(size_t keylength) {return DEFAULT_ROUNDS;}
00046 
00047 protected:
00048         inline void ThrowIfInvalidRounds(int rounds, const Algorithm *alg)
00049         {
00050                 if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS)
00051                         throw InvalidRounds(alg->AlgorithmName(), rounds);
00052         }
00053 
00054         inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs &param, const Algorithm *alg)
00055         {
00056                 int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS);
00057                 ThrowIfInvalidRounds(rounds, alg);
00058                 return (unsigned int)rounds;
00059         }
00060 };
00061 
00062 // ************** key length ***************
00063 
00064 //! to be inherited by keyed algorithms with fixed key length
00065 template <unsigned int N, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0>
00066 class FixedKeyLength
00067 {
00068 public:
00069         CRYPTOPP_CONSTANT(KEYLENGTH=N)
00070         CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N)
00071         CRYPTOPP_CONSTANT(MAX_KEYLENGTH=N)
00072         CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=N)
00073         CRYPTOPP_CONSTANT(IV_REQUIREMENT = IV_REQ)
00074         CRYPTOPP_CONSTANT(IV_LENGTH = IV_L)
00075         static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t) {return KEYLENGTH;}
00076 };
00077 
00078 /// support query of variable key length, template parameters are default, min, max, multiple (default multiple 1)
00079 template <unsigned int D, unsigned int N, unsigned int M, unsigned int Q = 1, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0>
00080 class VariableKeyLength
00081 {
00082         // make these private to avoid Doxygen documenting them in all derived classes
00083         CRYPTOPP_COMPILE_ASSERT(Q > 0);
00084         CRYPTOPP_COMPILE_ASSERT(N % Q == 0);
00085         CRYPTOPP_COMPILE_ASSERT(M % Q == 0);
00086         CRYPTOPP_COMPILE_ASSERT(N < M);
00087         CRYPTOPP_COMPILE_ASSERT(D >= N);
00088         CRYPTOPP_COMPILE_ASSERT(M >= D);
00089 
00090 public:
00091         CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N)
00092         CRYPTOPP_CONSTANT(MAX_KEYLENGTH=M)
00093         CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=D)
00094         CRYPTOPP_CONSTANT(KEYLENGTH_MULTIPLE=Q)
00095         CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ)
00096         CRYPTOPP_CONSTANT(IV_LENGTH=IV_L)
00097 
00098         static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t n)
00099         {
00100                 if (n < (size_t)MIN_KEYLENGTH)
00101                         return MIN_KEYLENGTH;
00102                 else if (n > (size_t)MAX_KEYLENGTH)
00103                         return (size_t)MAX_KEYLENGTH;
00104                 else
00105                 {
00106                         n += KEYLENGTH_MULTIPLE-1;
00107                         return n - n%KEYLENGTH_MULTIPLE;
00108                 }
00109         }
00110 };
00111 
00112 /// support query of key length that's the same as another class
00113 template <class T>
00114 class SameKeyLengthAs
00115 {
00116 public:
00117         CRYPTOPP_CONSTANT(MIN_KEYLENGTH=T::MIN_KEYLENGTH)
00118         CRYPTOPP_CONSTANT(MAX_KEYLENGTH=T::MAX_KEYLENGTH)
00119         CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH)
00120         CRYPTOPP_CONSTANT(IV_REQUIREMENT = T::IV_REQUIREMENT)
00121         CRYPTOPP_CONSTANT(IV_LENGTH = T::IV_LENGTH)
00122         static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
00123                 {return T::StaticGetValidKeyLength(keylength);}
00124 };
00125 
00126 // ************** implementation helper for SimpleKeyed ***************
00127 
00128 //! _
00129 template <class BASE, class INFO = BASE>
00130 class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE
00131 {
00132 public:
00133         size_t MinKeyLength() const {return INFO::MIN_KEYLENGTH;}
00134         size_t MaxKeyLength() const {return (size_t)INFO::MAX_KEYLENGTH;}
00135         size_t DefaultKeyLength() const {return INFO::DEFAULT_KEYLENGTH;}
00136         size_t GetValidKeyLength(size_t n) const {return INFO::StaticGetValidKeyLength(n);}
00137         typename BASE::IV_Requirement IVRequirement() const {return (typename BASE::IV_Requirement)INFO::IV_REQUIREMENT;}
00138         unsigned int IVSize() const {return INFO::IV_LENGTH;}
00139 };
00140 
00141 template <class INFO, class BASE = BlockCipher>
00142 class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > >
00143 {
00144 public:
00145         unsigned int BlockSize() const {return this->BLOCKSIZE;}
00146 };
00147 
00148 //! _
00149 template <CipherDir DIR, class BASE>
00150 class BlockCipherFinal : public ClonableImpl<BlockCipherFinal<DIR, BASE>, BASE>
00151 {
00152 public:
00153         BlockCipherFinal() {}
00154         BlockCipherFinal(const byte *key)
00155                 {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
00156         BlockCipherFinal(const byte *key, size_t length)
00157                 {this->SetKey(key, length);}
00158         BlockCipherFinal(const byte *key, size_t length, unsigned int rounds)
00159                 {this->SetKeyWithRounds(key, length, rounds);}
00160 
00161         bool IsForwardTransformation() const {return DIR == ENCRYPTION;}
00162 };
00163 
00164 //! _
00165 template <class BASE, class INFO = BASE>
00166 class MessageAuthenticationCodeImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
00167 {
00168 };
00169 
00170 //! _
00171 template <class BASE>
00172 class MessageAuthenticationCodeFinal : public ClonableImpl<MessageAuthenticationCodeFinal<BASE>, MessageAuthenticationCodeImpl<BASE> >
00173 {
00174 public:
00175         MessageAuthenticationCodeFinal() {}
00176         MessageAuthenticationCodeFinal(const byte *key)
00177                 {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
00178         MessageAuthenticationCodeFinal(const byte *key, size_t length)
00179                 {this->SetKey(key, length);}
00180 };
00181 
00182 // ************** documentation ***************
00183 
00184 //! These objects usually should not be used directly. See CipherModeDocumentation instead.
00185 /*! Each class derived from this one defines two types, Encryption and Decryption, 
00186         both of which implement the BlockCipher interface. */
00187 struct BlockCipherDocumentation
00188 {
00189         //! implements the BlockCipher interface
00190         typedef BlockCipher Encryption;
00191         //! implements the BlockCipher interface
00192         typedef BlockCipher Decryption;
00193 };
00194 
00195 /*! \brief Each class derived from this one defines two types, Encryption and Decryption, 
00196         both of which implement the SymmetricCipher interface. Two types of classes derive
00197         from this class: stream ciphers and block cipher modes. Stream ciphers can be used
00198         alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation
00199         for more for information about using cipher modes and block ciphers. */
00200 struct SymmetricCipherDocumentation
00201 {
00202         //! implements the SymmetricCipher interface
00203         typedef SymmetricCipher Encryption;
00204         //! implements the SymmetricCipher interface
00205         typedef SymmetricCipher Decryption;
00206 };
00207 
00208 NAMESPACE_END
00209 
00210 #endif

Generated on Sat Dec 23 02:07:10 2006 for Crypto++ by  doxygen 1.5.1-p1