1// seckey.h - written and placed in the public domain by Wei Dai 2 3// This file contains helper classes/functions for implementing secret key algorithms. 4 5#ifndef CRYPTOPP_SECKEY_H 6#define CRYPTOPP_SECKEY_H 7 8#include "cryptlib.h" 9#include "misc.h" 10#include "simple.h" 11 12NAMESPACE_BEGIN(CryptoPP) 13 14inline CipherDir ReverseCipherDir(CipherDir dir) 15{ 16 return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION; 17} 18 19//! to be inherited by block ciphers with fixed block size 20template <unsigned int N> 21class FixedBlockSize 22{ 23public: 24 CRYPTOPP_CONSTANT(BLOCKSIZE = N) 25}; 26 27// ************** rounds *************** 28 29//! to be inherited by ciphers with fixed number of rounds 30template <unsigned int R> 31class FixedRounds 32{ 33public: 34 CRYPTOPP_CONSTANT(ROUNDS = R) 35}; 36 37//! to be inherited by ciphers with variable number of rounds 38template <unsigned int D, unsigned int N=1, unsigned int M=INT_MAX> // use INT_MAX here because enums are treated as signed ints 39class VariableRounds 40{ 41public: 42 CRYPTOPP_CONSTANT(DEFAULT_ROUNDS = D) 43 CRYPTOPP_CONSTANT(MIN_ROUNDS = N) 44 CRYPTOPP_CONSTANT(MAX_ROUNDS = M) 45 static unsigned int StaticGetDefaultRounds(size_t keylength) {return DEFAULT_ROUNDS;} 46 47protected: 48 inline void ThrowIfInvalidRounds(int rounds, const Algorithm *alg) 49 { 50 if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS) 51 throw InvalidRounds(alg->AlgorithmName(), rounds); 52 } 53 54 inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs ¶m, const Algorithm *alg) 55 { 56 int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS); 57 ThrowIfInvalidRounds(rounds, alg); 58 return (unsigned int)rounds; 59 } 60}; 61 62// ************** key length *************** 63 64//! to be inherited by keyed algorithms with fixed key length 65template <unsigned int N, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0> 66class FixedKeyLength 67{ 68public: 69 CRYPTOPP_CONSTANT(KEYLENGTH=N) 70 CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N) 71 CRYPTOPP_CONSTANT(MAX_KEYLENGTH=N) 72 CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=N) 73 CRYPTOPP_CONSTANT(IV_REQUIREMENT = IV_REQ) 74 CRYPTOPP_CONSTANT(IV_LENGTH = IV_L) 75 static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t) {return KEYLENGTH;} 76}; 77 78/// support query of variable key length, template parameters are default, min, max, multiple (default multiple 1) 79template <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> 80class VariableKeyLength 81{ 82 // make these private to avoid Doxygen documenting them in all derived classes 83 CRYPTOPP_COMPILE_ASSERT(Q > 0); 84 CRYPTOPP_COMPILE_ASSERT(N % Q == 0); 85 CRYPTOPP_COMPILE_ASSERT(M % Q == 0); 86 CRYPTOPP_COMPILE_ASSERT(N < M); 87 CRYPTOPP_COMPILE_ASSERT(D >= N); 88 CRYPTOPP_COMPILE_ASSERT(M >= D); 89 90public: 91 CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N) 92 CRYPTOPP_CONSTANT(MAX_KEYLENGTH=M) 93 CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=D) 94 CRYPTOPP_CONSTANT(KEYLENGTH_MULTIPLE=Q) 95 CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ) 96 CRYPTOPP_CONSTANT(IV_LENGTH=IV_L) 97 98 static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t n) 99 { 100 if (n < (size_t)MIN_KEYLENGTH) 101 return MIN_KEYLENGTH; 102 else if (n > (size_t)MAX_KEYLENGTH) 103 return (size_t)MAX_KEYLENGTH; 104 else 105 { 106 n += KEYLENGTH_MULTIPLE-1; 107 return n - n%KEYLENGTH_MULTIPLE; 108 } 109 } 110}; 111 112/// support query of key length that's the same as another class 113template <class T, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0> 114class SameKeyLengthAs 115{ 116public: 117 CRYPTOPP_CONSTANT(MIN_KEYLENGTH=T::MIN_KEYLENGTH) 118 CRYPTOPP_CONSTANT(MAX_KEYLENGTH=T::MAX_KEYLENGTH) 119 CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH) 120 CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ) 121 CRYPTOPP_CONSTANT(IV_LENGTH=IV_L) 122 123 static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) 124 {return T::StaticGetValidKeyLength(keylength);} 125}; 126 127// ************** implementation helper for SimpleKeyed *************** 128 129//! _ 130template <class BASE, class INFO = BASE> 131class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE 132{ 133public: 134 size_t MinKeyLength() const {return INFO::MIN_KEYLENGTH;} 135 size_t MaxKeyLength() const {return (size_t)INFO::MAX_KEYLENGTH;} 136 size_t DefaultKeyLength() const {return INFO::DEFAULT_KEYLENGTH;} 137 size_t GetValidKeyLength(size_t n) const {return INFO::StaticGetValidKeyLength(n);} 138 SimpleKeyingInterface::IV_Requirement IVRequirement() const {return (SimpleKeyingInterface::IV_Requirement)INFO::IV_REQUIREMENT;} 139 unsigned int IVSize() const {return INFO::IV_LENGTH;} 140}; 141 142template <class INFO, class BASE = BlockCipher> 143class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > > 144{ 145public: 146 unsigned int BlockSize() const {return this->BLOCKSIZE;} 147}; 148 149//! _ 150template <CipherDir DIR, class BASE> 151class BlockCipherFinal : public ClonableImpl<BlockCipherFinal<DIR, BASE>, BASE> 152{ 153public: 154 BlockCipherFinal() {} 155 BlockCipherFinal(const byte *key) 156 {this->SetKey(key, this->DEFAULT_KEYLENGTH);} 157 BlockCipherFinal(const byte *key, size_t length) 158 {this->SetKey(key, length);} 159 BlockCipherFinal(const byte *key, size_t length, unsigned int rounds) 160 {this->SetKeyWithRounds(key, length, rounds);} 161 162 bool IsForwardTransformation() const {return DIR == ENCRYPTION;} 163}; 164 165//! _ 166template <class BASE, class INFO = BASE> 167class MessageAuthenticationCodeImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO> 168{ 169}; 170 171//! _ 172template <class BASE> 173class MessageAuthenticationCodeFinal : public ClonableImpl<MessageAuthenticationCodeFinal<BASE>, MessageAuthenticationCodeImpl<BASE> > 174{ 175public: 176 MessageAuthenticationCodeFinal() {} 177 MessageAuthenticationCodeFinal(const byte *key) 178 {this->SetKey(key, this->DEFAULT_KEYLENGTH);} 179 MessageAuthenticationCodeFinal(const byte *key, size_t length) 180 {this->SetKey(key, length);} 181}; 182 183// ************** documentation *************** 184 185//! These objects usually should not be used directly. See CipherModeDocumentation instead. 186/*! Each class derived from this one defines two types, Encryption and Decryption, 187 both of which implement the BlockCipher interface. */ 188struct BlockCipherDocumentation 189{ 190 //! implements the BlockCipher interface 191 typedef BlockCipher Encryption; 192 //! implements the BlockCipher interface 193 typedef BlockCipher Decryption; 194}; 195 196/*! \brief Each class derived from this one defines two types, Encryption and Decryption, 197 both of which implement the SymmetricCipher interface. Two types of classes derive 198 from this class: stream ciphers and block cipher modes. Stream ciphers can be used 199 alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation 200 for more for information about using cipher modes and block ciphers. */ 201struct SymmetricCipherDocumentation 202{ 203 //! implements the SymmetricCipher interface 204 typedef SymmetricCipher Encryption; 205 //! implements the SymmetricCipher interface 206 typedef SymmetricCipher Decryption; 207}; 208 209/*! \brief Each class derived from this one defines two types, Encryption and Decryption, 210 both of which implement the AuthenticatedSymmetricCipher interface. */ 211struct AuthenticatedSymmetricCipherDocumentation 212{ 213 //! implements the AuthenticatedSymmetricCipher interface 214 typedef AuthenticatedSymmetricCipher Encryption; 215 //! implements the AuthenticatedSymmetricCipher interface 216 typedef AuthenticatedSymmetricCipher Decryption; 217}; 218 219NAMESPACE_END 220 221#endif 222