|
|
// 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 <unsigned int N> class FixedBlockSize { public: CRYPTOPP_CONSTANT(BLOCKSIZE = N) };
// ************** rounds ***************
//! to be inherited by ciphers with fixed number of rounds
template <unsigned int R> class FixedRounds { public: CRYPTOPP_CONSTANT(ROUNDS = R) };
//! to be inherited by ciphers with variable 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: 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 <unsigned int N, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0> 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 <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: 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 T, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0> 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 BASE, class INFO = BASE> 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 INFO, class BASE = BlockCipher> class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > > { public: unsigned int BlockSize() const {return this->BLOCKSIZE;} };
//! _
template <CipherDir DIR, class BASE> class BlockCipherFinal : public ClonableImpl<BlockCipherFinal<DIR, BASE>, 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 BASE, class INFO = BASE> class MessageAuthenticationCodeImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO> { };
//! _
template <class BASE> class MessageAuthenticationCodeFinal : public ClonableImpl<MessageAuthenticationCodeFinal<BASE>, MessageAuthenticationCodeImpl<BASE> > { 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
|