Crypto++

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0>
    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=IV_REQ)
    00121     CRYPTOPP_CONSTANT(IV_LENGTH=IV_L)
    00122
    00123     static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
    00124         {return T::StaticGetValidKeyLength(keylength);}
    00125 };
    00126
    00127 // ************** implementation helper for SimpleKeyed ***************
    00128
    00129 //! _
    00130 template <class BASE, class INFO = BASE>
    00131 class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE
    00132 {
    00133 public:
    00134     size_t MinKeyLength() const {return INFO::MIN_KEYLENGTH;}
    00135     size_t MaxKeyLength() const {return (size_t)INFO::MAX_KEYLENGTH;}
    00136     size_t DefaultKeyLength() const {return INFO::DEFAULT_KEYLENGTH;}
    00137     size_t GetValidKeyLength(size_t n) const {return INFO::StaticGetValidKeyLength(n);}
    00138     SimpleKeyingInterface::IV_Requirement IVRequirement() const {return (SimpleKeyingInterface::IV_Requirement)INFO::IV_REQUIREMENT;}
    00139     unsigned int IVSize() const {return INFO::IV_LENGTH;}
    00140 };
    00141
    00142 template <class INFO, class BASE = BlockCipher>
    00143 class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > >
    00144 {
    00145 public:
    00146     unsigned int BlockSize() const {return this->BLOCKSIZE;}
    00147 };
    00148
    00149 //! _
    00150 template <CipherDir DIR, class BASE>
    00151 class BlockCipherFinal : public ClonableImpl<BlockCipherFinal<DIR, BASE>, BASE>
    00152 {
    00153 public:
    00154     BlockCipherFinal() {}
    00155     BlockCipherFinal(const byte *key)
    00156         {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
    00157     BlockCipherFinal(const byte *key, size_t length)
    00158         {this->SetKey(key, length);}
    00159     BlockCipherFinal(const byte *key, size_t length, unsigned int rounds)
    00160         {this->SetKeyWithRounds(key, length, rounds);}
    00161
    00162     bool IsForwardTransformation() const {return DIR == ENCRYPTION;}
    00163 };
    00164
    00165 //! _
    00166 template <class BASE, class INFO = BASE>
    00167 class MessageAuthenticationCodeImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
    00168 {
    00169 };
    00170
    00171 //! _
    00172 template <class BASE>
    00173 class MessageAuthenticationCodeFinal : public ClonableImpl<MessageAuthenticationCodeFinal<BASE>, MessageAuthenticationCodeImpl<BASE> >
    00174 {
    00175 public:
    00176     MessageAuthenticationCodeFinal() {}
    00177     MessageAuthenticationCodeFinal(const byte *key)
    00178         {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
    00179     MessageAuthenticationCodeFinal(const byte *key, size_t length)
    00180         {this->SetKey(key, length);}
    00181 };
    00182
    00183 // ************** documentation ***************
    00184
    00185 //! These objects usually should not be used directly. See CipherModeDocumentation instead.
    00186 /*! Each class derived from this one defines two types, Encryption and Decryption,
    00187     both of which implement the BlockCipher interface. */
    00188 struct BlockCipherDocumentation
    00189 {
    00190     //! implements the BlockCipher interface
    00191     typedef BlockCipher Encryption;
    00192     //! implements the BlockCipher interface
    00193     typedef BlockCipher Decryption;
    00194 };
    00195
    00196 /*! \brief Each class derived from this one defines two types, Encryption and Decryption,
    00197     both of which implement the SymmetricCipher interface. Two types of classes derive
    00198     from this class: stream ciphers and block cipher modes. Stream ciphers can be used
    00199     alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation
    00200     for more for information about using cipher modes and block ciphers. */
    00201 struct SymmetricCipherDocumentation
    00202 {
    00203     //! implements the SymmetricCipher interface
    00204     typedef SymmetricCipher Encryption;
    00205     //! implements the SymmetricCipher interface
    00206     typedef SymmetricCipher Decryption;
    00207 };
    00208
    00209 /*! \brief Each class derived from this one defines two types, Encryption and Decryption,
    00210     both of which implement the AuthenticatedSymmetricCipher interface. */
    00211 struct AuthenticatedSymmetricCipherDocumentation
    00212 {
    00213     //! implements the AuthenticatedSymmetricCipher interface
    00214     typedef AuthenticatedSymmetricCipher Encryption;
    00215     //! implements the AuthenticatedSymmetricCipher interface
    00216     typedef AuthenticatedSymmetricCipher Decryption;
    00217 };
    00218
    00219 NAMESPACE_END
    00220
    00221 #endif