123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- // seckey.h - originally written and placed in the public domain by Wei Dai
- /// \file seckey.h
- /// \brief Classes and functions for implementing secret key algorithms.
- #ifndef CRYPTOPP_SECKEY_H
- #define CRYPTOPP_SECKEY_H
- #include "config.h"
- #include "cryptlib.h"
- #include "misc.h"
- #include "simple.h"
- #include "stdcpp.h"
- #if CRYPTOPP_MSC_VERSION
- # pragma warning(push)
- # pragma warning(disable: 4189 4296)
- #endif
- // Issue 340
- #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
- # pragma GCC diagnostic push
- # pragma GCC diagnostic ignored "-Wconversion"
- # pragma GCC diagnostic ignored "-Wsign-conversion"
- #endif
- NAMESPACE_BEGIN(CryptoPP)
- /// \brief Inverts the cipher's direction
- /// \param dir the cipher's direction
- /// \return DECRYPTION if \ref CipherDir "dir" is ENCRYPTION, DECRYPTION otherwise
- inline CipherDir ReverseCipherDir(CipherDir dir)
- {
- return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION;
- }
- /// \brief Inherited by algorithms with fixed block size
- /// \tparam N the blocksize of the algorithm
- template <unsigned int N>
- class FixedBlockSize
- {
- public:
- /// \brief The block size of the algorithm provided as a constant.
- CRYPTOPP_CONSTANT(BLOCKSIZE = N);
- };
- // ************** rounds ***************
- /// \brief Inherited by algorithms with fixed number of rounds
- /// \tparam R the number of rounds used by the algorithm
- template <unsigned int R>
- class FixedRounds
- {
- public:
- /// \brief The number of rounds for the algorithm provided as a constant.
- CRYPTOPP_CONSTANT(ROUNDS = R);
- };
- /// \brief Inherited by algorithms with variable number of rounds
- /// \tparam D Default number of rounds
- /// \tparam N Minimum number of rounds
- /// \tparam M Maximum number of rounds
- template <unsigned int D, unsigned int N=1, unsigned int M=INT_MAX> // use INT_MAX here because enums are treated as signed ints
- class VariableRounds
- {
- public:
- /// \brief The default number of rounds for the algorithm provided as a constant.
- CRYPTOPP_CONSTANT(DEFAULT_ROUNDS = D);
- /// \brief The minimum number of rounds for the algorithm provided as a constant.
- CRYPTOPP_CONSTANT(MIN_ROUNDS = N);
- /// \brief The maximum number of rounds for the algorithm provided as a constant.
- CRYPTOPP_CONSTANT(MAX_ROUNDS = M);
- /// \brief The default number of rounds for the algorithm based on key length
- /// provided by a static function.
- /// \param keylength the size of the key, in bytes
- /// \details keylength is unused in the default implementation.
- CRYPTOPP_STATIC_CONSTEXPR unsigned int StaticGetDefaultRounds(size_t keylength)
- {
- return CRYPTOPP_UNUSED(keylength), static_cast<unsigned int>(DEFAULT_ROUNDS);
- }
- protected:
- /// \brief Validates the number of rounds for an algorithm.
- /// \param rounds the candidate number of rounds
- /// \param alg an Algorithm object used if the number of rounds are invalid
- /// \throw InvalidRounds if the number of rounds are invalid
- /// \details ThrowIfInvalidRounds() validates the number of rounds and throws if invalid.
- inline void ThrowIfInvalidRounds(int rounds, const Algorithm *alg)
- {
- if (M == INT_MAX) // Coverity and result_independent_of_operands
- {
- if (rounds < MIN_ROUNDS)
- throw InvalidRounds(alg ? alg->AlgorithmName() : std::string("VariableRounds"), rounds);
- }
- else
- {
- if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS)
- throw InvalidRounds(alg ? alg->AlgorithmName() : std::string("VariableRounds"), rounds);
- }
- }
- /// \brief Validates the number of rounds for an algorithm
- /// \param param the candidate number of rounds
- /// \param alg an Algorithm object used if the number of rounds are invalid
- /// \return the number of rounds for the algorithm
- /// \throw InvalidRounds if the number of rounds are invalid
- /// \details GetRoundsAndThrowIfInvalid() validates the number of rounds and throws if invalid.
- inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs ¶m, const Algorithm *alg)
- {
- int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS);
- ThrowIfInvalidRounds(rounds, alg);
- return static_cast<unsigned int>(rounds);
- }
- };
- // ************** key length ***************
- /// \brief Inherited by keyed algorithms with fixed key length
- /// \tparam N Default key length, in bytes
- /// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements"
- /// \tparam IV_L default IV length, in bytes
- /// \sa SimpleKeyingInterface
- template <unsigned int N, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0>
- class FixedKeyLength
- {
- public:
- /// \brief The default key length used by the algorithm provided as a constant
- /// \details KEYLENGTH is provided in bytes, not bits
- CRYPTOPP_CONSTANT(KEYLENGTH=N);
- /// \brief The minimum key length used by the algorithm provided as a constant
- /// \details MIN_KEYLENGTH is provided in bytes, not bits
- CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N);
- /// \brief The maximum key length used by the algorithm provided as a constant
- /// \details MAX_KEYLENGTH is provided in bytes, not bits
- CRYPTOPP_CONSTANT(MAX_KEYLENGTH=N);
- /// \brief The default key length used by the algorithm provided as a constant
- /// \details DEFAULT_KEYLENGTH is provided in bytes, not bits
- CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=N);
- /// \brief The default IV requirements for the algorithm provided as a constant
- /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
- /// in cryptlib.h for allowed values.
- CRYPTOPP_CONSTANT(IV_REQUIREMENT = IV_REQ);
- /// \brief The default IV length used by the algorithm provided as a constant
- /// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0.
- CRYPTOPP_CONSTANT(IV_LENGTH = IV_L);
- /// \brief The default key length for the algorithm provided by a static function.
- /// \param keylength the size of the key, in bytes
- /// \details The default implementation returns KEYLENGTH. keylength is unused
- /// in the default implementation.
- CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
- {
- return CRYPTOPP_UNUSED(keylength), static_cast<size_t>(KEYLENGTH);
- }
- };
- /// \brief Inherited by keyed algorithms with variable key length
- /// \tparam D Default key length, in bytes
- /// \tparam N Minimum key length, in bytes
- /// \tparam M Maximum key length, in bytes
- /// \tparam Q Default key length multiple, in bytes. The default multiple is 1.
- /// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements"
- /// \tparam IV_L default IV length, in bytes. The default length is 0.
- /// \sa SimpleKeyingInterface
- 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>
- 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:
- /// \brief The minimum key length used by the algorithm provided as a constant
- /// \details MIN_KEYLENGTH is provided in bytes, not bits
- CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N);
- /// \brief The maximum key length used by the algorithm provided as a constant
- /// \details MAX_KEYLENGTH is provided in bytes, not bits
- CRYPTOPP_CONSTANT(MAX_KEYLENGTH=M);
- /// \brief The default key length used by the algorithm provided as a constant
- /// \details DEFAULT_KEYLENGTH is provided in bytes, not bits
- CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=D);
- /// \brief The key length multiple used by the algorithm provided as a constant
- /// \details MAX_KEYLENGTH is provided in bytes, not bits
- CRYPTOPP_CONSTANT(KEYLENGTH_MULTIPLE=Q);
- /// \brief The default IV requirements for the algorithm provided as a constant
- /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
- /// in cryptlib.h for allowed values.
- CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ);
- /// \brief The default initialization vector length for the algorithm provided as a constant
- /// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0.
- CRYPTOPP_CONSTANT(IV_LENGTH=IV_L);
- /// \brief Provides a valid key length for the algorithm provided by a static function.
- /// \param keylength the size of the key, in bytes
- /// \details If keylength is less than MIN_KEYLENGTH, then the function returns
- /// MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, then the function
- /// returns MAX_KEYLENGTH. If keylength is a multiple of KEYLENGTH_MULTIPLE,
- /// then keylength is returned. Otherwise, the function returns keylength rounded
- /// \a down to the next smaller multiple of KEYLENGTH_MULTIPLE.
- /// \details keylength is provided in bytes, not bits.
- CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
- {
- return (keylength <= N) ? N :
- (keylength >= M) ? M :
- (keylength+Q-1) - (keylength+Q-1)%Q;
- }
- };
- /// \brief Provides key lengths based on another class's key length
- /// \tparam T another FixedKeyLength or VariableKeyLength class
- /// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements"
- /// \tparam IV_L default IV length, in bytes
- /// \sa SimpleKeyingInterface
- template <class T, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0>
- class SameKeyLengthAs
- {
- public:
- /// \brief The minimum key length used by the algorithm provided as a constant
- /// \details MIN_KEYLENGTH is provided in bytes, not bits
- CRYPTOPP_CONSTANT(MIN_KEYLENGTH=T::MIN_KEYLENGTH);
- /// \brief The maximum key length used by the algorithm provided as a constant
- /// \details MIN_KEYLENGTH is provided in bytes, not bits
- CRYPTOPP_CONSTANT(MAX_KEYLENGTH=T::MAX_KEYLENGTH);
- /// \brief The default key length used by the algorithm provided as a constant
- /// \details MIN_KEYLENGTH is provided in bytes, not bits
- CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH);
- /// \brief The default IV requirements for the algorithm provided as a constant
- /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
- /// in cryptlib.h for allowed values.
- CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ);
- /// \brief The default initialization vector length for the algorithm provided as a constant
- /// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0.
- CRYPTOPP_CONSTANT(IV_LENGTH=IV_L);
- /// \brief Provides a valid key length for the algorithm provided by a static function.
- /// \param keylength the size of the key, in bytes
- /// \details If keylength is less than MIN_KEYLENGTH, then the function returns
- /// MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, then the function
- /// returns MAX_KEYLENGTH. If keylength is a multiple of KEYLENGTH_MULTIPLE,
- /// then keylength is returned. Otherwise, the function returns keylength rounded
- /// \a down to the next smaller multiple of KEYLENGTH_MULTIPLE.
- /// \details keylength is provided in bytes, not bits.
- CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
- {return T::StaticGetValidKeyLength(keylength);}
- };
- // ************** implementation helper for SimpleKeyingInterface ***************
- /// \brief Provides a base implementation of SimpleKeyingInterface
- /// \tparam BASE a SimpleKeyingInterface derived class
- /// \tparam INFO a SimpleKeyingInterface derived class
- /// \details SimpleKeyingInterfaceImpl() provides a default implementation for ciphers providing a keying interface.
- /// Functions are virtual and not eligible for C++11 <tt>constexpr</tt>-ness.
- /// \sa Algorithm(), SimpleKeyingInterface()
- template <class BASE, class INFO = BASE>
- class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE
- {
- public:
- /// \brief The minimum key length used by the algorithm
- /// \return minimum key length used by the algorithm, in bytes
- size_t MinKeyLength() const
- {return INFO::MIN_KEYLENGTH;}
- /// \brief The maximum key length used by the algorithm
- /// \return maximum key length used by the algorithm, in bytes
- size_t MaxKeyLength() const
- {return static_cast<size_t>(INFO::MAX_KEYLENGTH);}
- /// \brief The default key length used by the algorithm
- /// \return default key length used by the algorithm, in bytes
- size_t DefaultKeyLength() const
- {return INFO::DEFAULT_KEYLENGTH;}
- /// \brief Provides a valid key length for the algorithm
- /// \param keylength the size of the key, in bytes
- /// \return the valid key length, in bytes
- /// \details keylength is provided in bytes, not bits. If keylength is less than MIN_KEYLENGTH,
- /// then the function returns MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH,
- /// then the function returns MAX_KEYLENGTH. if If keylength is a multiple of KEYLENGTH_MULTIPLE,
- /// then keylength is returned. Otherwise, the function returns a \a lower multiple of
- /// KEYLENGTH_MULTIPLE.
- size_t GetValidKeyLength(size_t keylength) const {return INFO::StaticGetValidKeyLength(keylength);}
- /// \brief The default IV requirements for the algorithm
- /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
- /// in cryptlib.h for allowed values.
- SimpleKeyingInterface::IV_Requirement IVRequirement() const
- {return static_cast<SimpleKeyingInterface::IV_Requirement>(INFO::IV_REQUIREMENT);}
- /// \brief The initialization vector length for the algorithm
- /// \details IVSize is provided in bytes, not bits. The default implementation uses
- /// IV_LENGTH, which is 0.
- unsigned int IVSize() const
- {return INFO::IV_LENGTH;}
- };
- /// \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for block ciphers
- /// \tparam INFO a SimpleKeyingInterface derived class
- /// \tparam BASE a SimpleKeyingInterface derived class
- /// \details BlockCipherImpl() provides a default implementation for block ciphers using AlgorithmImpl()
- /// and SimpleKeyingInterfaceImpl(). Functions are virtual and not eligible for C++11 <tt>constexpr</tt>-ness.
- /// \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl()
- template <class INFO, class BASE = BlockCipher>
- class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > >
- {
- public:
- /// Provides the block size of the algorithm
- /// \return the block size of the algorithm, in bytes
- unsigned int BlockSize() const {return this->BLOCKSIZE;}
- };
- /// \brief Provides class member functions to key a block cipher
- /// \tparam DIR a CipherDir
- /// \tparam BASE a BlockCipherImpl derived class
- template <CipherDir DIR, class BASE>
- class BlockCipherFinal : public ClonableImpl<BlockCipherFinal<DIR, BASE>, BASE>
- {
- public:
- /// \brief Construct a default BlockCipherFinal
- /// \details The cipher is not keyed.
- BlockCipherFinal() {}
- /// \brief Construct a BlockCipherFinal
- /// \param key a byte array used to key the cipher
- /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
- /// SimpleKeyingInterface::SetKey.
- BlockCipherFinal(const byte *key)
- {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
- /// \brief Construct a BlockCipherFinal
- /// \param key a byte array used to key the cipher
- /// \param length the length of the byte array
- /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
- /// SimpleKeyingInterface::SetKey.
- BlockCipherFinal(const byte *key, size_t length)
- {this->SetKey(key, length);}
- /// \brief Construct a BlockCipherFinal
- /// \param key a byte array used to key the cipher
- /// \param length the length of the byte array
- /// \param rounds the number of rounds
- /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
- /// SimpleKeyingInterface::SetKeyWithRounds.
- BlockCipherFinal(const byte *key, size_t length, unsigned int rounds)
- {this->SetKeyWithRounds(key, length, rounds);}
- /// \brief Provides the direction of the cipher
- /// \return true if DIR is ENCRYPTION, false otherwise
- /// \sa GetCipherDirection(), IsPermutation()
- bool IsForwardTransformation() const {return DIR == ENCRYPTION;}
- };
- /// \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for message authentication codes
- /// \tparam INFO a SimpleKeyingInterface derived class
- /// \tparam BASE a SimpleKeyingInterface derived class
- /// \details MessageAuthenticationCodeImpl() provides a default implementation for message authentication codes
- /// using AlgorithmImpl() and SimpleKeyingInterfaceImpl(). Functions are virtual and not subject to C++11
- /// <tt>constexpr</tt>.
- /// \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl()
- template <class BASE, class INFO = BASE>
- class MessageAuthenticationCodeImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
- {
- };
- /// \brief Provides class member functions to key a message authentication code
- /// \tparam BASE a BlockCipherImpl derived class
- /// \details A default implementation for MessageAuthenticationCode
- template <class BASE>
- class MessageAuthenticationCodeFinal : public ClonableImpl<MessageAuthenticationCodeFinal<BASE>, MessageAuthenticationCodeImpl<BASE> >
- {
- public:
- /// \brief Construct a default MessageAuthenticationCodeFinal
- /// \details The message authentication code is not keyed.
- MessageAuthenticationCodeFinal() {}
- /// \brief Construct a BlockCipherFinal
- /// \param key a byte array used to key the algorithm
- /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
- /// SimpleKeyingInterface::SetKey.
- MessageAuthenticationCodeFinal(const byte *key)
- {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
- /// \brief Construct a BlockCipherFinal
- /// \param key a byte array used to key the algorithm
- /// \param length the length of the byte array
- /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
- /// SimpleKeyingInterface::SetKey.
- MessageAuthenticationCodeFinal(const byte *key, size_t length)
- {this->SetKey(key, length);}
- };
- // ************** documentation ***************
- /// \brief Provides Encryption and Decryption typedefs used by derived classes to
- /// implement a block cipher
- /// \details 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 Provides Encryption and Decryption typedefs used by derived classes to
- /// implement a symmetric cipher
- /// \details 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 Provides Encryption and Decryption typedefs used by derived classes to
- /// implement an authenticated encryption cipher
- /// \details 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
- #if CRYPTOPP_MSC_VERSION
- # pragma warning(pop)
- #endif
- // Issue 340
- #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
- # pragma GCC diagnostic pop
- #endif
- #endif
|