Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | 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 enum {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 enum {ROUNDS = R}; 00035 00036 protected: 00037 template <class T> 00038 static inline void CheckedSetKey(T *obj, CipherDir dir, const byte *key, unsigned int length, const NameValuePairs &param) 00039 { 00040 obj->ThrowIfInvalidKeyLength(length); 00041 int rounds = param.GetIntValueWithDefault("Rounds", ROUNDS); 00042 if (rounds != ROUNDS) 00043 throw InvalidRounds(obj->StaticAlgorithmName(), rounds); 00044 obj->UncheckedSetKey(dir, key, length); 00045 } 00046 }; 00047 00048 //! to be inherited by ciphers with variable number of rounds 00049 template <unsigned int D, unsigned int N=1, unsigned int M=INT_MAX> // use INT_MAX here because enums are treated as signed ints 00050 class VariableRounds 00051 { 00052 public: 00053 enum {DEFAULT_ROUNDS = D, MIN_ROUNDS = N, MAX_ROUNDS = M}; 00054 static unsigned int StaticGetDefaultRounds(unsigned int keylength) {return DEFAULT_ROUNDS;} 00055 00056 protected: 00057 static inline void AssertValidRounds(unsigned int rounds) 00058 { 00059 assert(rounds >= (unsigned int)MIN_ROUNDS && rounds <= (unsigned int)MAX_ROUNDS); 00060 } 00061 00062 template <class T> 00063 static inline void CheckedSetKey(T *obj, CipherDir dir, const byte *key, unsigned int length, const NameValuePairs &param) 00064 { 00065 obj->ThrowIfInvalidKeyLength(length); 00066 int rounds = param.GetIntValueWithDefault("Rounds", obj->StaticGetDefaultRounds(length)); 00067 if (rounds < (int)MIN_ROUNDS || rounds > (int)MAX_ROUNDS) 00068 throw InvalidRounds(obj->AlgorithmName(), rounds); 00069 obj->UncheckedSetKey(dir, key, length, rounds); 00070 } 00071 }; 00072 00073 // ************** key length *************** 00074 00075 //! to be inherited by keyed algorithms with fixed key length 00076 template <unsigned int N, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> 00077 class FixedKeyLength 00078 { 00079 public: 00080 enum {KEYLENGTH=N, MIN_KEYLENGTH=N, MAX_KEYLENGTH=N, DEFAULT_KEYLENGTH=N}; 00081 enum {IV_REQUIREMENT = IV_REQ}; 00082 static unsigned int StaticGetValidKeyLength(unsigned int) {return KEYLENGTH;} 00083 }; 00084 00085 /// support query of variable key length, template parameters are default, min, max, multiple (default multiple 1) 00086 template <unsigned int D, unsigned int N, unsigned int M, unsigned int Q = 1, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> 00087 class VariableKeyLength 00088 { 00089 // make these private to avoid Doxygen documenting them in all derived classes 00090 CRYPTOPP_COMPILE_ASSERT(Q > 0); 00091 CRYPTOPP_COMPILE_ASSERT(N % Q == 0); 00092 CRYPTOPP_COMPILE_ASSERT(M % Q == 0); 00093 CRYPTOPP_COMPILE_ASSERT(N < M); 00094 CRYPTOPP_COMPILE_ASSERT(D >= N && M >= D); 00095 00096 public: 00097 enum {MIN_KEYLENGTH=N, MAX_KEYLENGTH=M, DEFAULT_KEYLENGTH=D, KEYLENGTH_MULTIPLE=Q}; 00098 enum {IV_REQUIREMENT = IV_REQ}; 00099 static unsigned int StaticGetValidKeyLength(unsigned int n) 00100 { 00101 if (n < (unsigned int)MIN_KEYLENGTH) 00102 return MIN_KEYLENGTH; 00103 else if (n > (unsigned int)MAX_KEYLENGTH) 00104 return (unsigned int)MAX_KEYLENGTH; 00105 else 00106 { 00107 n += KEYLENGTH_MULTIPLE-1; 00108 return n - n%KEYLENGTH_MULTIPLE; 00109 } 00110 } 00111 }; 00112 00113 /// support query of key length that's the same as another class 00114 template <class T> 00115 class SameKeyLengthAs 00116 { 00117 public: 00118 enum {MIN_KEYLENGTH=T::MIN_KEYLENGTH, MAX_KEYLENGTH=T::MAX_KEYLENGTH, DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH}; 00119 enum {IV_REQUIREMENT = T::IV_REQUIREMENT}; 00120 static unsigned int StaticGetValidKeyLength(unsigned int keylength) 00121 {return T::StaticGetValidKeyLength(keylength);} 00122 }; 00123 00124 // ************** implementation helper for SimpledKeyed *************** 00125 00126 template <class T> 00127 static inline void CheckedSetKey(T *obj, Empty empty, const byte *key, unsigned int length, const NameValuePairs &param) 00128 { 00129 obj->ThrowIfInvalidKeyLength(length); 00130 obj->UncheckedSetKey(key, length); 00131 } 00132 00133 template <class T> 00134 static inline void CheckedSetKey(T *obj, CipherDir dir, const byte *key, unsigned int length, const NameValuePairs &param) 00135 { 00136 obj->ThrowIfInvalidKeyLength(length); 00137 obj->UncheckedSetKey(dir, key, length); 00138 } 00139 00140 //! _ 00141 template <class BASE, class INFO = BASE> 00142 class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE 00143 { 00144 public: 00145 unsigned int MinKeyLength() const {return INFO::MIN_KEYLENGTH;} 00146 unsigned int MaxKeyLength() const {return (unsigned int)INFO::MAX_KEYLENGTH;} 00147 unsigned int DefaultKeyLength() const {return INFO::DEFAULT_KEYLENGTH;} 00148 unsigned int GetValidKeyLength(unsigned int n) const {return INFO::StaticGetValidKeyLength(n);} 00149 typename BASE::IV_Requirement IVRequirement() const {return (typename BASE::IV_Requirement)INFO::IV_REQUIREMENT;} 00150 00151 protected: 00152 void AssertValidKeyLength(unsigned int length) {assert(GetValidKeyLength(length) == length);} 00153 }; 00154 00155 template <class INFO, class BASE = BlockCipher> 00156 class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > > 00157 { 00158 public: 00159 unsigned int BlockSize() const {return this->BLOCKSIZE;} 00160 }; 00161 00162 //! _ 00163 template <CipherDir DIR, class BASE> 00164 class BlockCipherFinal : public ClonableImpl<BlockCipherFinal<DIR, BASE>, BASE> 00165 { 00166 public: 00167 BlockCipherFinal() {} 00168 BlockCipherFinal(const byte *key) 00169 {SetKey(key, this->DEFAULT_KEYLENGTH);} 00170 BlockCipherFinal(const byte *key, unsigned int length) 00171 {SetKey(key, length);} 00172 BlockCipherFinal(const byte *key, unsigned int length, unsigned int rounds) 00173 {this->SetKeyWithRounds(key, length, rounds);} 00174 00175 bool IsForwardTransformation() const {return DIR == ENCRYPTION;} 00176 00177 void SetKey(const byte *key, unsigned int length, const NameValuePairs &param = g_nullNameValuePairs) 00178 { 00179 CheckedSetKey(this, DIR, key, length, param); 00180 } 00181 }; 00182 00183 //! _ 00184 template <class BASE, class INFO = BASE> 00185 class MessageAuthenticationCodeImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO> 00186 { 00187 public: 00188 void SetKey(const byte *key, unsigned int length, const NameValuePairs &params = g_nullNameValuePairs) 00189 { 00190 CheckedSetKey(this, Empty(), key, length, params); 00191 } 00192 }; 00193 00194 //! _ 00195 template <class BASE> 00196 class MessageAuthenticationCodeFinal : public ClonableImpl<MessageAuthenticationCodeFinal<BASE>, MessageAuthenticationCodeImpl<BASE> > 00197 { 00198 public: 00199 MessageAuthenticationCodeFinal() {} 00200 MessageAuthenticationCodeFinal(const byte *key) 00201 {SetKey(key, this->DEFAULT_KEYLENGTH);} 00202 MessageAuthenticationCodeFinal(const byte *key, unsigned int length) 00203 {this->SetKey(key, length);} 00204 }; 00205 00206 // ************** documentation *************** 00207 00208 //! These objects usually should not be used directly. See CipherModeDocumentation instead. 00209 /*! Each class derived from this one defines two types, Encryption and Decryption, 00210 both of which implement the BlockCipher interface. */ 00211 struct BlockCipherDocumentation 00212 { 00213 //! implements the BlockCipher interface 00214 typedef BlockCipher Encryption; 00215 //! implements the BlockCipher interface 00216 typedef BlockCipher Decryption; 00217 }; 00218 00219 /*! \brief Each class derived from this one defines two types, Encryption and Decryption, 00220 both of which implement the SymmetricCipher interface. Two types of classes derive 00221 from this class: stream ciphers and block cipher modes. Stream ciphers can be used 00222 alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation 00223 for more for information about using cipher modes and block ciphers. */ 00224 struct SymmetricCipherDocumentation 00225 { 00226 //! implements the SymmetricCipher interface 00227 typedef SymmetricCipher Encryption; 00228 //! implements the SymmetricCipher interface 00229 typedef SymmetricCipher Decryption; 00230 }; 00231 00232 NAMESPACE_END 00233 00234 #endif

Generated on Wed Jul 21 19:15:33 2004 for Crypto++ by doxygen 1.3.7-20040704