// seckey.h - written and placed in the public domain by Wei Dai // This file contains helper classes/functions for implementing secret key algorithms. #ifndef CRYPTOPP_SECKEY_H #define CRYPTOPP_SECKEY_H #include "cryptlib.h" #include "misc.h" #include "simple.h" NAMESPACE_BEGIN(CryptoPP) inline CipherDir ReverseCipherDir(CipherDir dir) { return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION; } //! to be inherited by block ciphers with fixed block size template class FixedBlockSize { public: CRYPTOPP_CONSTANT(BLOCKSIZE = N) }; // ************** rounds *************** //! to be inherited by ciphers with fixed number of rounds template class FixedRounds { public: CRYPTOPP_CONSTANT(ROUNDS = R) }; //! to be inherited by ciphers with variable number of rounds template // use INT_MAX here because enums are treated as signed ints class VariableRounds { public: CRYPTOPP_CONSTANT(DEFAULT_ROUNDS = D) CRYPTOPP_CONSTANT(MIN_ROUNDS = N) CRYPTOPP_CONSTANT(MAX_ROUNDS = M) static unsigned int StaticGetDefaultRounds(size_t keylength) {return DEFAULT_ROUNDS;} protected: inline void ThrowIfInvalidRounds(int rounds, const Algorithm *alg) { if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS) throw InvalidRounds(alg->AlgorithmName(), rounds); } inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs ¶m, const Algorithm *alg) { int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS); ThrowIfInvalidRounds(rounds, alg); return (unsigned int)rounds; } }; // ************** key length *************** //! to be inherited by keyed algorithms with fixed key length template class FixedKeyLength { public: CRYPTOPP_CONSTANT(KEYLENGTH=N) CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N) CRYPTOPP_CONSTANT(MAX_KEYLENGTH=N) CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=N) CRYPTOPP_CONSTANT(IV_REQUIREMENT = IV_REQ) CRYPTOPP_CONSTANT(IV_LENGTH = IV_L) static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t) {return KEYLENGTH;} }; /// support query of variable key length, template parameters are default, min, max, multiple (default multiple 1) template class VariableKeyLength { // make these private to avoid Doxygen documenting them in all derived classes CRYPTOPP_COMPILE_ASSERT(Q > 0); CRYPTOPP_COMPILE_ASSERT(N % Q == 0); CRYPTOPP_COMPILE_ASSERT(M % Q == 0); CRYPTOPP_COMPILE_ASSERT(N < M); CRYPTOPP_COMPILE_ASSERT(D >= N); CRYPTOPP_COMPILE_ASSERT(M >= D); public: CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N) CRYPTOPP_CONSTANT(MAX_KEYLENGTH=M) CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=D) CRYPTOPP_CONSTANT(KEYLENGTH_MULTIPLE=Q) CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ) CRYPTOPP_CONSTANT(IV_LENGTH=IV_L) static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t n) { if (n < (size_t)MIN_KEYLENGTH) return MIN_KEYLENGTH; else if (n > (size_t)MAX_KEYLENGTH) return (size_t)MAX_KEYLENGTH; else { n += KEYLENGTH_MULTIPLE-1; return n - n%KEYLENGTH_MULTIPLE; } } }; /// support query of key length that's the same as another class template class SameKeyLengthAs { public: CRYPTOPP_CONSTANT(MIN_KEYLENGTH=T::MIN_KEYLENGTH) CRYPTOPP_CONSTANT(MAX_KEYLENGTH=T::MAX_KEYLENGTH) CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH) CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ) CRYPTOPP_CONSTANT(IV_LENGTH=IV_L) static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) {return T::StaticGetValidKeyLength(keylength);} }; // ************** implementation helper for SimpleKeyed *************** //! _ template class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE { public: size_t MinKeyLength() const {return INFO::MIN_KEYLENGTH;} size_t MaxKeyLength() const {return (size_t)INFO::MAX_KEYLENGTH;} size_t DefaultKeyLength() const {return INFO::DEFAULT_KEYLENGTH;} size_t GetValidKeyLength(size_t n) const {return INFO::StaticGetValidKeyLength(n);} SimpleKeyingInterface::IV_Requirement IVRequirement() const {return (SimpleKeyingInterface::IV_Requirement)INFO::IV_REQUIREMENT;} unsigned int IVSize() const {return INFO::IV_LENGTH;} }; template class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl > > { public: unsigned int BlockSize() const {return this->BLOCKSIZE;} }; //! _ template class BlockCipherFinal : public ClonableImpl, BASE> { public: BlockCipherFinal() {} BlockCipherFinal(const byte *key) {this->SetKey(key, this->DEFAULT_KEYLENGTH);} BlockCipherFinal(const byte *key, size_t length) {this->SetKey(key, length);} BlockCipherFinal(const byte *key, size_t length, unsigned int rounds) {this->SetKeyWithRounds(key, length, rounds);} bool IsForwardTransformation() const {return DIR == ENCRYPTION;} }; //! _ template class MessageAuthenticationCodeImpl : public AlgorithmImpl, INFO> { }; //! _ template class MessageAuthenticationCodeFinal : public ClonableImpl, MessageAuthenticationCodeImpl > { public: MessageAuthenticationCodeFinal() {} MessageAuthenticationCodeFinal(const byte *key) {this->SetKey(key, this->DEFAULT_KEYLENGTH);} MessageAuthenticationCodeFinal(const byte *key, size_t length) {this->SetKey(key, length);} }; // ************** documentation *************** //! These objects usually should not be used directly. See CipherModeDocumentation instead. /*! Each class derived from this one defines two types, Encryption and Decryption, both of which implement the BlockCipher interface. */ struct BlockCipherDocumentation { //! implements the BlockCipher interface typedef BlockCipher Encryption; //! implements the BlockCipher interface typedef BlockCipher Decryption; }; /*! \brief Each class derived from this one defines two types, Encryption and Decryption, both of which implement the SymmetricCipher interface. Two types of classes derive from this class: stream ciphers and block cipher modes. Stream ciphers can be used alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation for more for information about using cipher modes and block ciphers. */ struct SymmetricCipherDocumentation { //! implements the SymmetricCipher interface typedef SymmetricCipher Encryption; //! implements the SymmetricCipher interface typedef SymmetricCipher Decryption; }; /*! \brief Each class derived from this one defines two types, Encryption and Decryption, both of which implement the AuthenticatedSymmetricCipher interface. */ struct AuthenticatedSymmetricCipherDocumentation { //! implements the AuthenticatedSymmetricCipher interface typedef AuthenticatedSymmetricCipher Encryption; //! implements the AuthenticatedSymmetricCipher interface typedef AuthenticatedSymmetricCipher Decryption; }; NAMESPACE_END #endif