diff options
-rw-r--r-- | config.h | 6 | ||||
-rw-r--r-- | cryptlib.cpp | 16 | ||||
-rw-r--r-- | cryptlib.h | 104 | ||||
-rw-r--r-- | fipstest.cpp | 2 | ||||
-rw-r--r-- | pubkey.h | 151 | ||||
-rw-r--r-- | queue.cpp | 3 | ||||
-rw-r--r-- | smartptr.h | 8 | ||||
-rw-r--r-- | zinflate.cpp | 68 | ||||
-rw-r--r-- | zinflate.h | 10 |
9 files changed, 197 insertions, 171 deletions
@@ -178,6 +178,12 @@ NAMESPACE_END #endif #ifdef _MSC_VER +#define CRYPTOPP_NO_VTABLE __declspec(novtable) +#else +#define CRYPTOPP_NO_VTABLE +#endif + +#ifdef _MSC_VER // 4250: dominance // 4660: explicitly instantiating a class that's already implicitly instantiated // 4661: no suitable definition provided for explicit template instantiation request diff --git a/cryptlib.cpp b/cryptlib.cpp index 07dd87c..5254c85 100644 --- a/cryptlib.cpp +++ b/cryptlib.cpp @@ -612,22 +612,6 @@ BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenera return new DecryptionFilter(rng, *this, attachment); } -unsigned int PK_FixedLengthCryptoSystem::MaxPlaintextLength(unsigned int cipherTextLength) const -{ - if (cipherTextLength == FixedCiphertextLength()) - return FixedMaxPlaintextLength(); - else - return 0; -} - -unsigned int PK_FixedLengthCryptoSystem::CiphertextLength(unsigned int plainTextLength) const -{ - if (plainTextLength <= FixedMaxPlaintextLength()) - return FixedCiphertextLength(); - else - return 0; -} - DecodingResult PK_FixedLengthDecryptor::Decrypt(RandomNumberGenerator &rng, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const { if (cipherTextLength != FixedCiphertextLength()) @@ -198,7 +198,7 @@ struct DecodingResult alternatively, call GetIntValue() with the value name, and if the type is not int, a ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object. */ -class NameValuePairs +class CRYPTOPP_NO_VTABLE NameValuePairs { public: virtual ~NameValuePairs() {} @@ -306,7 +306,7 @@ extern const NullNameValuePairs g_nullNameValuePairs; // ******************************************************** //! interface for cloning objects, this is not implemented by most classes yet -class Clonable +class CRYPTOPP_NO_VTABLE Clonable { public: virtual ~Clonable() {} @@ -316,7 +316,7 @@ public: //! interface for all crypto algorithms -class Algorithm : public Clonable +class CRYPTOPP_NO_VTABLE Algorithm : public Clonable { public: /*! When FIPS 140-2 compliance is enabled and checkSelfTestStatus == true, @@ -328,7 +328,7 @@ public: //! keying interface for crypto algorithms that take byte strings as keys -class SimpleKeyingInterface +class CRYPTOPP_NO_VTABLE SimpleKeyingInterface { public: //! returns smallest valid key length in bytes */ @@ -399,7 +399,7 @@ protected: These classes should not be used directly, but only in combination with a mode class (see CipherModeDocumentation in modes.h). */ -class BlockTransformation : public Algorithm +class CRYPTOPP_NO_VTABLE BlockTransformation : public Algorithm { public: //! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock @@ -435,7 +435,7 @@ public: //! interface for the data processing part of stream ciphers -class StreamTransformation : public Algorithm +class CRYPTOPP_NO_VTABLE StreamTransformation : public Algorithm { public: //! return a reference to this object, @@ -498,7 +498,7 @@ public: be hashed in pieces by calling Update() on each piece followed by calling Final(). */ -class HashTransformation : public Algorithm +class CRYPTOPP_NO_VTABLE HashTransformation : public Algorithm { public: //! process more input @@ -559,7 +559,7 @@ protected: //! . template <class T> -class SimpleKeyedTransformation : public T, public SimpleKeyingInterface +class CRYPTOPP_NO_VTABLE SimpleKeyedTransformation : public T, public SimpleKeyingInterface { public: void ThrowIfInvalidKeyLength(unsigned int length) @@ -588,7 +588,7 @@ typedef SymmetricCipher StreamCipher; //! interface for random number generators /*! All return values are uniformly distributed over the range specified. */ -class RandomNumberGenerator : public Algorithm +class CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm { public: //! generate new random byte and return it @@ -632,7 +632,7 @@ class WaitObjectContainer; //! interface for objects that you can wait for -class Waitable +class CRYPTOPP_NO_VTABLE Waitable { public: //! maximum number of wait objects that this object can return @@ -670,7 +670,7 @@ public: \nosubgrouping */ -class BufferedTransformation : public Algorithm, public Waitable +class CRYPTOPP_NO_VTABLE BufferedTransformation : public Algorithm, public Waitable { public: // placed up here for CW8 @@ -929,7 +929,7 @@ BufferedTransformation & TheBitBucket(); //! interface for crypto material, such as public and private keys, and crypto parameters -class CryptoMaterial : public NameValuePairs +class CRYPTOPP_NO_VTABLE CryptoMaterial : public NameValuePairs { public: //! exception thrown when invalid crypto material is detected @@ -990,7 +990,7 @@ public: //! interface for generatable crypto material, such as private keys and crypto parameters -class GeneratableCryptoMaterial : virtual public CryptoMaterial +class CRYPTOPP_NO_VTABLE GeneratableCryptoMaterial : virtual public CryptoMaterial { public: //! generate a random key or crypto parameters @@ -1005,25 +1005,25 @@ public: //! interface for public keys -class PublicKey : virtual public CryptoMaterial +class CRYPTOPP_NO_VTABLE PublicKey : virtual public CryptoMaterial { }; //! interface for private keys -class PrivateKey : public GeneratableCryptoMaterial +class CRYPTOPP_NO_VTABLE PrivateKey : public GeneratableCryptoMaterial { }; //! interface for crypto prameters -class CryptoParameters : public GeneratableCryptoMaterial +class CRYPTOPP_NO_VTABLE CryptoParameters : public GeneratableCryptoMaterial { }; //! interface for asymmetric algorithms -class AsymmetricAlgorithm : public Algorithm +class CRYPTOPP_NO_VTABLE AsymmetricAlgorithm : public Algorithm { public: //! returns a reference to the crypto material used by this object @@ -1041,7 +1041,7 @@ public: //! interface for asymmetric algorithms using public keys -class PublicKeyAlgorithm : public AsymmetricAlgorithm +class CRYPTOPP_NO_VTABLE PublicKeyAlgorithm : public AsymmetricAlgorithm { public: // VC60 workaround: no co-variant return type @@ -1054,7 +1054,7 @@ public: //! interface for asymmetric algorithms using private keys -class PrivateKeyAlgorithm : public AsymmetricAlgorithm +class CRYPTOPP_NO_VTABLE PrivateKeyAlgorithm : public AsymmetricAlgorithm { public: CryptoMaterial & AccessMaterial() {return AccessPrivateKey();} @@ -1066,7 +1066,7 @@ public: //! interface for key agreement algorithms -class KeyAgreementAlgorithm : public AsymmetricAlgorithm +class CRYPTOPP_NO_VTABLE KeyAgreementAlgorithm : public AsymmetricAlgorithm { public: CryptoMaterial & AccessMaterial() {return AccessCryptoParameters();} @@ -1081,18 +1081,18 @@ public: /*! This class provides an interface common to encryptors and decryptors for querying their plaintext and ciphertext lengths. */ -class PK_CryptoSystem +class CRYPTOPP_NO_VTABLE PK_CryptoSystem { public: virtual ~PK_CryptoSystem() {} //! maximum length of plaintext for a given ciphertext length - /*! \note This function returns 0 if cipherTextLength is not valid (too long or too short). */ - virtual unsigned int MaxPlaintextLength(unsigned int cipherTextLength) const =0; + /*! \note This function returns 0 if ciphertextLength is not valid (too long or too short). */ + virtual unsigned int MaxPlaintextLength(unsigned int ciphertextLength) const =0; //! calculate length of ciphertext given length of plaintext - /*! \note This function returns 0 if plainTextLength is not valid (too long). */ - virtual unsigned int CiphertextLength(unsigned int plainTextLength) const =0; + /*! \note This function returns 0 if plaintextLength is not valid (too long). */ + virtual unsigned int CiphertextLength(unsigned int plaintextLength) const =0; #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);} @@ -1102,7 +1102,7 @@ public: //! interface for public-key encryptors -class PK_Encryptor : virtual public PK_CryptoSystem, public PublicKeyAlgorithm +class CRYPTOPP_NO_VTABLE PK_Encryptor : public PK_CryptoSystem, public PublicKeyAlgorithm { public: //! . @@ -1113,10 +1113,10 @@ public: }; //! encrypt a byte string - /*! \pre CipherTextLength(plainTextLength) != 0 (i.e., plainText isn't too long) - \pre size of cipherText == CipherTextLength(plainTextLength) + /*! \pre CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long) + \pre size of ciphertext == CiphertextLength(plaintextLength) */ - virtual void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const =0; + virtual void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, unsigned int plaintextLength, byte *ciphertext) const =0; //! create a new encryption filter /*! \note caller is responsible for deleting the returned pointer @@ -1126,14 +1126,14 @@ public: //! interface for public-key decryptors -class PK_Decryptor : virtual public PK_CryptoSystem, public PrivateKeyAlgorithm +class CRYPTOPP_NO_VTABLE PK_Decryptor : public PK_CryptoSystem, public PrivateKeyAlgorithm { public: //! decrypt a byte string, and return the length of plaintext - /*! \pre size of plainText == MaxPlainTextLength(cipherTextLength) bytes. + /*! \pre size of plaintext == MaxPlaintextLength(ciphertextLength) bytes. \return the actual length of the plaintext, or 0 if decryption fails. */ - virtual DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const =0; + virtual DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext) const =0; //! create a new decryption filter /*! \note caller is responsible for deleting the returned pointer @@ -1147,7 +1147,7 @@ public: as RSA) whose ciphertext length and maximum plaintext length depend only on the key. */ -class PK_FixedLengthCryptoSystem : virtual public PK_CryptoSystem +class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystem { public: //! @@ -1155,9 +1155,6 @@ public: //! virtual unsigned int FixedCiphertextLength() const =0; - unsigned int MaxPlaintextLength(unsigned int cipherTextLength) const; - unsigned int CiphertextLength(unsigned int plainTextLength) const; - #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);} unsigned int CipherTextLength(unsigned int plainTextLength) const {return CiphertextLength(plainTextLength);} @@ -1166,25 +1163,34 @@ public: #endif }; +template <class BASE> +class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE, public PK_FixedLengthCryptoSystem +{ + unsigned int MaxPlaintextLength(unsigned int ciphertextLength) const + {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;} + unsigned int CiphertextLength(unsigned int plaintextLength) const + {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;} +}; + //! interface for encryptors with fixed length ciphertext -class PK_FixedLengthEncryptor : public PK_Encryptor, virtual public PK_FixedLengthCryptoSystem +class CRYPTOPP_NO_VTABLE PK_FixedLengthEncryptor : public PK_FixedLengthCryptoSystemImpl<PK_Encryptor> { }; //! interface for decryptors with fixed length ciphertext -class PK_FixedLengthDecryptor : public PK_Decryptor, virtual public PK_FixedLengthCryptoSystem +class CRYPTOPP_NO_VTABLE PK_FixedLengthDecryptor : public PK_FixedLengthCryptoSystemImpl<PK_Decryptor> { public: //! decrypt a byte string, and return the length of plaintext - /*! \pre length of cipherText == CipherTextLength() - \pre size of plainText == MaxPlainTextLength() + /*! \pre length of ciphertext == FixedCiphertextLength() + \pre size of plaintext == FixedMaxPlaintextLength() \return the actual length of the plaintext, or 0 if decryption fails. */ - virtual DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const =0; + virtual DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *ciphertext, byte *plaintext) const =0; - DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const; + DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext) const; }; //! interface for public-key signers and verifiers @@ -1192,7 +1198,7 @@ public: /*! This class provides an interface common to signers and verifiers for querying scheme properties. */ -class PK_SignatureScheme +class CRYPTOPP_NO_VTABLE PK_SignatureScheme { public: //! invalid key exception, may be thrown by any function in this class if the private or public key has a length that can't be used @@ -1241,7 +1247,7 @@ public: /*! Only Update() should be called on this class. No other functions inherited from HashTransformation should be called. */ -class PK_MessageAccumulator : public HashTransformation +class CRYPTOPP_NO_VTABLE PK_MessageAccumulator : public HashTransformation { public: //! should not be called on PK_MessageAccumulator @@ -1254,7 +1260,7 @@ public: //! interface for public-key signers -class PK_Signer : virtual public PK_SignatureScheme, public PrivateKeyAlgorithm +class CRYPTOPP_NO_VTABLE PK_Signer : public PK_SignatureScheme, public PrivateKeyAlgorithm { public: //! create a new HashTransformation to accumulate the message to be signed @@ -1295,7 +1301,7 @@ public: recovery and the signature contains a non-empty recoverable message part. The Recovery* functions should be used in that case. */ -class PK_Verifier : virtual public PK_SignatureScheme, public PublicKeyAlgorithm +class CRYPTOPP_NO_VTABLE PK_Verifier : public PK_SignatureScheme, public PublicKeyAlgorithm { public: //! create a new HashTransformation to accumulate the message to be verified @@ -1338,7 +1344,7 @@ public: by two parties in a key agreement protocol, along with the algorithms for generating key pairs and deriving agreed values. */ -class SimpleKeyAgreementDomain : public KeyAgreementAlgorithm +class CRYPTOPP_NO_VTABLE SimpleKeyAgreementDomain : public KeyAgreementAlgorithm { public: //! return length of agreed value produced @@ -1376,7 +1382,7 @@ public: key pairs. The long-lived key pair is called the static key pair, and the short-lived key pair is called the ephemeral key pair. */ -class AuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm +class CRYPTOPP_NO_VTABLE AuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm { public: //! return length of agreed value produced @@ -1541,7 +1547,7 @@ public: }; //! interface for encoding and decoding ASN1 objects -class ASN1Object +class CRYPTOPP_NO_VTABLE ASN1Object { public: virtual ~ASN1Object() {} diff --git a/fipstest.cpp b/fipstest.cpp index 63727c2..5486e3b 100644 --- a/fipstest.cpp +++ b/fipstest.cpp @@ -277,7 +277,7 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleSha // hash from disk instead if (!verifier.GetLastResult()) { - OutputDebugString("In memory EDC test failed. This may be caused by debug breakpoints."); + OutputDebugString("In memory EDC test failed. This may be caused by debug breakpoints or DLL relocation.\n"); verifier.Put(expectedModuleSha1Digest, sha.DigestSize()); file.Initialize(MakeParameters(Name::InputFileName(), moduleFilename)); file.TransferAllTo(verifier); @@ -50,7 +50,7 @@ Integer DSA_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned // ******************************************************** //! . -class TrapdoorFunctionBounds +class CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds { public: virtual ~TrapdoorFunctionBounds() {} @@ -62,7 +62,7 @@ public: }; //! . -class RandomizedTrapdoorFunction : public TrapdoorFunctionBounds +class CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds { public: virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0; @@ -70,7 +70,7 @@ public: }; //! . -class TrapdoorFunction : public RandomizedTrapdoorFunction +class CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction { public: Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const @@ -81,7 +81,7 @@ public: }; //! . -class RandomizedTrapdoorFunctionInverse +class CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse { public: virtual ~RandomizedTrapdoorFunctionInverse() {} @@ -91,7 +91,7 @@ public: }; //! . -class TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse +class CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse { public: virtual ~TrapdoorFunctionInverse() {} @@ -106,7 +106,7 @@ public: // ******************************************************** //! . -class PK_EncryptionMessageEncodingMethod +class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod { public: virtual ~PK_EncryptionMessageEncodingMethod() {} @@ -123,7 +123,7 @@ public: //! . template <class TFI, class MEI> -class TF_Base +class CRYPTOPP_NO_VTABLE TF_Base { protected: virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0; @@ -139,7 +139,7 @@ protected: //! . template <class INTERFACE, class BASE> -class TF_CryptoSystemBase : public INTERFACE, protected BASE +class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public INTERFACE, protected BASE { public: unsigned int FixedMaxPlaintextLength() const {return GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());} @@ -151,14 +151,14 @@ protected: }; //! . -class TF_DecryptorBase : public TF_CryptoSystemBase<PK_FixedLengthDecryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> > +class CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_FixedLengthDecryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> > { public: DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const; }; //! . -class TF_EncryptorBase : public TF_CryptoSystemBase<PK_FixedLengthEncryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> > +class CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_FixedLengthEncryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> > { public: void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const; @@ -169,7 +169,7 @@ public: typedef std::pair<const byte *, unsigned int> HashIdentifier; //! . -class PK_SignatureMessageEncodingMethod +class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod { public: virtual ~PK_SignatureMessageEncodingMethod() {} @@ -232,7 +232,7 @@ public: }; }; -class PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod +class CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod { public: bool VerifyMessageRepresentative( @@ -240,7 +240,7 @@ public: byte *representative, unsigned int representativeBitLength) const; }; -class PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod +class CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod { public: bool VerifyMessageRepresentative( @@ -266,7 +266,7 @@ public: byte *representative, unsigned int representativeBitLength) const; }; -class PK_MessageAccumulatorBase : public PK_MessageAccumulator +class CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator { public: PK_MessageAccumulatorBase() : m_empty(true) {} @@ -293,7 +293,7 @@ public: //! . template <class INTERFACE, class BASE> -class TF_SignatureSchemeBase : public INTERFACE, protected BASE +class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTERFACE, protected BASE { public: unsigned int SignatureLength() const @@ -318,7 +318,7 @@ protected: }; //! . -class TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> > +class CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> > { public: void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, unsigned int recoverableMessageLength) const; @@ -326,7 +326,7 @@ public: }; //! . -class TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> > +class CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> > { public: void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const; @@ -356,24 +356,26 @@ struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions<T1, T2, T3> //! . template <class KEYS> -class PublicKeyCopier +class CRYPTOPP_NO_VTABLE PublicKeyCopier { public: + typedef KEYS::PublicKey KeyClass; virtual void CopyKeyInto(typename KEYS::PublicKey &key) const =0; }; //! . template <class KEYS> -class PrivateKeyCopier +class CRYPTOPP_NO_VTABLE PrivateKeyCopier { public: + typedef KEYS::PrivateKey KeyClass; virtual void CopyKeyInto(typename KEYS::PublicKey &key) const =0; virtual void CopyKeyInto(typename KEYS::PrivateKey &key) const =0; }; //! . template <class BASE, class SCHEME_OPTIONS, class KEY> -class TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo> +class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo> { public: typedef SCHEME_OPTIONS SchemeOptions; @@ -390,6 +392,15 @@ public: const KeyClass & GetTrapdoorFunction() const {return GetKey();} + PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const + { + return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>; + } + PK_MessageAccumulator * NewVerificationAccumulator() const + { + return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>; + } + protected: const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const {static typename SCHEME_OPTIONS::MessageEncodingMethod messageEncodingMethod; return messageEncodingMethod;} @@ -422,79 +433,54 @@ public: const KEY & GetKey() const {return *m_pKey;} KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");} - void CopyKeyInto(typename SCHEME_OPTIONS::PrivateKey &key) const {assert(false);} - void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {assert(false);} - private: const KEY * m_pKey; }; //! . -template <class BASE, class SCHEME_OPTIONS, class KEY> -class TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY> +template <class BASE, class SCHEME_OPTIONS, class KEY_COPIER> +class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<TwoBases<BASE, KEY_COPIER>, SCHEME_OPTIONS, typename KEY_COPIER::KeyClass> { public: - const KEY & GetKey() const {return m_trapdoorFunction;} - KEY & AccessKey() {return m_trapdoorFunction;} + typedef typename KEY_COPIER::KeyClass KeyClass; -private: - KEY m_trapdoorFunction; -}; - -//! . -template <class BASE, class SCHEME_OPTIONS> -class TF_PublicObjectImpl : public TF_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>, public PublicKeyCopier<SCHEME_OPTIONS> -{ -public: - void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {key = GetKey();} -}; + const KeyClass & GetKey() const {return m_trapdoorFunction;} + KeyClass & AccessKey() {return m_trapdoorFunction;} -//! . -template <class BASE, class SCHEME_OPTIONS> -class TF_PrivateObjectImpl : public TF_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>, public PrivateKeyCopier<SCHEME_OPTIONS> -{ -public: void CopyKeyInto(typename SCHEME_OPTIONS::PrivateKey &key) const {key = GetKey();} void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {key = GetKey();} + +private: + KeyClass m_trapdoorFunction; }; //! . template <class SCHEME_OPTIONS> -class TF_DecryptorImpl : public TF_PrivateObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS> +class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, PrivateKeyCopier<typename SCHEME_OPTIONS::Keys> > { }; //! . template <class SCHEME_OPTIONS> -class TF_EncryptorImpl : public TF_PublicObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS> +class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, PublicKeyCopier<typename SCHEME_OPTIONS::Keys> > { }; //! . template <class SCHEME_OPTIONS> -class TF_SignerImpl : public TF_PrivateObjectImpl<TF_SignerBase, SCHEME_OPTIONS> +class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, PrivateKeyCopier<typename SCHEME_OPTIONS::Keys> > { -public: - PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const - { - return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>; - } }; //! . template <class SCHEME_OPTIONS> -class TF_VerifierImpl : public TF_PublicObjectImpl<TF_VerifierBase, SCHEME_OPTIONS> +class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, PublicKeyCopier<typename SCHEME_OPTIONS::Keys> > { -public: - PK_MessageAccumulator * NewVerificationAccumulator() const - { - return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>; - } }; // ******************************************************** -class MaskGeneratingFunction +class CRYPTOPP_NO_VTABLE MaskGeneratingFunction { public: virtual ~MaskGeneratingFunction() {} @@ -548,7 +534,7 @@ public: //! . template <class T> -class DL_GroupParameters : public CryptoParameters +class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters { typedef DL_GroupParameters<T> ThisClass; @@ -658,7 +644,7 @@ protected: //! . template <class T> -class DL_Key +class CRYPTOPP_NO_VTABLE DL_Key { public: virtual const DL_GroupParameters<T> & GetAbstractGroupParameters() const =0; @@ -667,7 +653,7 @@ public: //! . template <class T> -class DL_PublicKey : public DL_Key<T> +class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key<T> { typedef DL_PublicKey<T> ThisClass; @@ -702,7 +688,7 @@ public: //! . template <class T> -class DL_PrivateKey : public DL_Key<T> +class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key<T> { typedef DL_PrivateKey<T> ThisClass; @@ -927,7 +913,7 @@ private: //! . template <class T> -class DL_ElgamalLikeSignatureAlgorithm +class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm { public: // virtual Integer EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLength) const =0; @@ -943,7 +929,7 @@ public: //! . template <class T> -class DL_KeyAgreementAlgorithm +class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm { public: typedef T Element; @@ -954,14 +940,14 @@ public: //! . template <class T> -class DL_KeyDerivationAlgorithm +class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm { public: virtual void Derive(const DL_GroupParameters<T> ¶ms, byte *derivedKey, unsigned int derivedLength, const T &agreedElement, const T &ephemeralPublicKey) const =0; }; //! . -class DL_SymmetricEncryptionAlgorithm +class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm { public: virtual unsigned int GetSymmetricKeyLength(unsigned int plainTextLength) const =0; @@ -973,7 +959,7 @@ public: //! . template <class KI> -class DL_Base +class CRYPTOPP_NO_VTABLE DL_Base { protected: typedef KI KeyInterface; @@ -988,7 +974,7 @@ protected: //! . template <class INTERFACE, class KEY_INTERFACE> -class DL_SignatureSchemeBase : public INTERFACE, public DL_Base<KEY_INTERFACE> +class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTERFACE, public DL_Base<KEY_INTERFACE> { public: unsigned int SignatureLength() const @@ -1020,7 +1006,7 @@ protected: //! . template <class T> -class DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> > +class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> > { public: // for validation testing @@ -1093,7 +1079,7 @@ protected: //! . template <class T> -class DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> > +class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> > { public: void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const @@ -1161,7 +1147,7 @@ public: //! . template <class PK, class KI> -class DL_CryptoSystemBase : public PK, public DL_Base<KI> +class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI> { public: typedef typename DL_Base<KI>::Element Element; @@ -1186,7 +1172,7 @@ protected: //! . template <class T, class PK = PK_Decryptor> -class DL_DecryptorBase : public DL_CryptoSystemBase<PK, DL_PrivateKey<T> > +class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK, DL_PrivateKey<T> > { public: typedef T Element; @@ -1222,7 +1208,7 @@ public: //! . template <class T, class PK = PK_Encryptor> -class DL_EncryptorBase : public DL_CryptoSystemBase<PK, DL_PublicKey<T> > +class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK, DL_PublicKey<T> > { public: typedef T Element; @@ -1288,19 +1274,18 @@ struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions<T1, T2> //! . template <class BASE, class SCHEME_OPTIONS, class KEY> -class DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo> +class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo> { public: typedef SCHEME_OPTIONS SchemeOptions; - typedef KEY KeyClass; - typedef typename KeyClass::Element Element; + typedef typename KEY::Element Element; PrivateKey & AccessPrivateKey() {return m_key;} PublicKey & AccessPublicKey() {return m_key;} // KeyAccessor - const KeyClass & GetKey() const {return m_key;} - KeyClass & AccessKey() {return m_key;} + const KEY & GetKey() const {return m_key;} + KEY & AccessKey() {return m_key;} protected: typename BASE::KeyInterface & AccessKeyInterface() {return m_key;} @@ -1319,12 +1304,12 @@ protected: } private: - KeyClass m_key; + KEY m_key; }; //! . template <class BASE, class SCHEME_OPTIONS, class KEY> -class DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY> +class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY> { public: typedef typename KEY::Element Element; @@ -1346,7 +1331,7 @@ protected: //! . template <class BASE, class SCHEME_OPTIONS> -class DL_PublicObjectImpl : public DL_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>, public PublicKeyCopier<SCHEME_OPTIONS> +class CRYPTOPP_NO_VTABLE DL_PublicObjectImpl : public DL_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>, public PublicKeyCopier<SCHEME_OPTIONS> { public: void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const @@ -1355,7 +1340,7 @@ public: //! . template <class BASE, class SCHEME_OPTIONS> -class DL_PrivateObjectImpl : public DL_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>, public PrivateKeyCopier<SCHEME_OPTIONS> +class CRYPTOPP_NO_VTABLE DL_PrivateObjectImpl : public DL_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>, public PrivateKeyCopier<SCHEME_OPTIONS> { public: void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const @@ -1404,7 +1389,7 @@ class DL_DecryptorImpl : public DL_PrivateObjectImpl<DL_DecryptorBase<typename S //! . template <class T> -class DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain +class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain { public: typedef T Element; @@ -344,8 +344,9 @@ void ByteQueue::Unget(byte inByte) void ByteQueue::Unget(const byte *inString, unsigned int length) { unsigned int len = STDMIN(length, m_head->m_head); - memcpy(m_head->buf + m_head->m_head - len, inString + length - len, len); length -= len; + m_head->m_head -= len; + memcpy(m_head->buf + m_head->m_head, inString + length, len); if (length > 0) { @@ -6,6 +6,14 @@ NAMESPACE_BEGIN(CryptoPP) +template<class T> class simple_ptr +{ +public: + simple_ptr() : m_p(NULL) {} + ~simple_ptr() {delete m_p;} + T *m_p; +}; + template<class T> class member_ptr { public: diff --git a/zinflate.cpp b/zinflate.cpp index fccbf83..2582cf1 100644 --- a/zinflate.cpp +++ b/zinflate.cpp @@ -210,8 +210,7 @@ bool HuffmanDecoder::Decode(LowFirstBitReader &reader, value_t &value) const Inflator::Inflator(BufferedTransformation *attachment, bool repeat, int propagation) : AutoSignaling<Filter>(attachment, propagation) - , m_state(PRE_STREAM), m_repeat(repeat) - , m_decodersInitializedWithFixedCodes(false), m_reader(m_inQueue) + , m_state(PRE_STREAM), m_repeat(repeat), m_reader(m_inQueue) { } @@ -366,23 +365,10 @@ void Inflator::DecodeHeader() break; } case 1: // fixed codes - if (!m_decodersInitializedWithFixedCodes) - { - unsigned int codeLengths[288]; - std::fill(codeLengths + 0, codeLengths + 144, 8); - std::fill(codeLengths + 144, codeLengths + 256, 9); - std::fill(codeLengths + 256, codeLengths + 280, 7); - std::fill(codeLengths + 280, codeLengths + 288, 8); - m_literalDecoder.Initialize(codeLengths, 288); - std::fill(codeLengths + 0, codeLengths + 32, 5); - m_distanceDecoder.Initialize(codeLengths, 32); - m_decodersInitializedWithFixedCodes = true; - } m_nextDecode = LITERAL; break; case 2: // dynamic codes { - m_decodersInitializedWithFixedCodes = false; if (!m_reader.FillBuffer(5+5+4)) throw UnexpectedEndErr(); unsigned int hlit = m_reader.GetBits(5); @@ -439,14 +425,14 @@ void Inflator::DecodeHeader() std::fill(codeLengths + i, codeLengths + i + count, repeater); i += count; } - m_literalDecoder.Initialize(codeLengths, hlit+257); + m_dynamicLiteralDecoder.Initialize(codeLengths, hlit+257); if (hdist == 0 && codeLengths[hlit+257] == 0) { if (hlit != 0) // a single zero distance code length means all literals throw BadBlockErr(); } else - m_distanceDecoder.Initialize(codeLengths+hlit+257, hdist+1); + m_dynamicDistanceDecoder.Initialize(codeLengths+hlit+257, hdist+1); m_nextDecode = LITERAL; } catch (HuffmanDecoder::Err &) @@ -497,12 +483,15 @@ bool Inflator::DecodeBody() 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + const HuffmanDecoder* pLiteralDecoder = GetLiteralDecoder(); + const HuffmanDecoder* pDistanceDecoder = GetDistanceDecoder(); + switch (m_nextDecode) { while (true) { case LITERAL: - if (!m_literalDecoder.Decode(m_reader, m_literal)) + if (!pLiteralDecoder->Decode(m_reader, m_literal)) { m_nextDecode = LITERAL; break; @@ -528,7 +517,7 @@ bool Inflator::DecodeBody() } m_literal = m_reader.GetBits(bits) + lengthStarts[m_literal-257]; case DISTANCE: - if (!m_distanceDecoder.Decode(m_reader, m_distance)) + if (!pDistanceDecoder->Decode(m_reader, m_distance)) { m_nextDecode = DISTANCE; break; @@ -578,4 +567,45 @@ void Inflator::FlushOutput() } } +const HuffmanDecoder *Inflator::FixedLiteralDecoder() +{ + static simple_ptr<HuffmanDecoder> s_pDecoder; + if (!s_pDecoder.m_p) + { + unsigned int codeLengths[288]; + std::fill(codeLengths + 0, codeLengths + 144, 8); + std::fill(codeLengths + 144, codeLengths + 256, 9); + std::fill(codeLengths + 256, codeLengths + 280, 7); + std::fill(codeLengths + 280, codeLengths + 288, 8); + HuffmanDecoder *pDecoder = new HuffmanDecoder; + pDecoder->Initialize(codeLengths, 288); + s_pDecoder.m_p = pDecoder; + } + return s_pDecoder.m_p; +} + +const HuffmanDecoder *Inflator::FixedDistanceDecoder() +{ + static simple_ptr<HuffmanDecoder> s_pDecoder; + if (!s_pDecoder.m_p) + { + unsigned int codeLengths[32]; + std::fill(codeLengths + 0, codeLengths + 32, 5); + HuffmanDecoder *pDecoder = new HuffmanDecoder; + pDecoder->Initialize(codeLengths, 32); + s_pDecoder.m_p = pDecoder; + } + return s_pDecoder.m_p; +} + +const HuffmanDecoder *Inflator::GetLiteralDecoder() const +{ + return m_blockType == 1 ? FixedLiteralDecoder() : &m_dynamicLiteralDecoder; +} + +const HuffmanDecoder *Inflator::GetDistanceDecoder() const +{ + return m_blockType == 1 ? FixedDistanceDecoder() : &m_dynamicDistanceDecoder; +} + NAMESPACE_END @@ -124,15 +124,21 @@ private: void OutputString(const byte *string, unsigned int length); void OutputPast(unsigned int length, unsigned int distance); + static const HuffmanDecoder *FixedLiteralDecoder(); + static const HuffmanDecoder *FixedDistanceDecoder(); + + const HuffmanDecoder *GetLiteralDecoder() const; + const HuffmanDecoder *GetDistanceDecoder() const; + enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END}; State m_state; - bool m_repeat, m_eof, m_decodersInitializedWithFixedCodes; + bool m_repeat, m_eof; byte m_blockType; word16 m_storedLen; enum NextDecode {LITERAL, LENGTH_BITS, DISTANCE, DISTANCE_BITS}; NextDecode m_nextDecode; unsigned int m_literal, m_distance; // for LENGTH_BITS or DISTANCE_BITS - HuffmanDecoder m_literalDecoder, m_distanceDecoder; + HuffmanDecoder m_dynamicLiteralDecoder, m_dynamicDistanceDecoder; LowFirstBitReader m_reader; SecByteBlock m_window; unsigned int m_maxDistance, m_current, m_lastFlush; |