Crypto++
|
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 ¶m, 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