summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--3way.cpp2
-rw-r--r--3way.h2
-rw-r--r--adler32.cpp7
-rw-r--r--adler32.h3
-rw-r--r--algebra.cpp3
-rw-r--r--algebra.h5
-rw-r--r--algparam.h55
-rw-r--r--arc4.cpp2
-rw-r--r--arc4.h12
-rw-r--r--argnames.h10
-rw-r--r--asn.h5
-rw-r--r--authenc.h4
-rw-r--r--base32.h2
-rw-r--r--base64.h2
-rw-r--r--basecode.h17
-rw-r--r--bench.cpp74
-rw-r--r--bench.h2
-rw-r--r--bench2.cpp22
-rw-r--r--blowfish.h2
-rw-r--r--blumshub.cpp6
-rw-r--r--blumshub.h19
-rw-r--r--camellia.h6
-rw-r--r--cast.h6
-rw-r--r--cbcmac.h8
-rw-r--r--ccm.h8
-rw-r--r--channels.h26
-rw-r--r--cmac.cpp14
-rw-r--r--cmac.h8
-rw-r--r--config.h111
-rw-r--r--cpu.cpp60
-rw-r--r--cpu.h61
-rw-r--r--crc.h6
-rw-r--r--cryptlib.cpp48
-rw-r--r--cryptlib.h1109
-rw-r--r--datatest.cpp12
-rw-r--r--default.h6
-rw-r--r--des.h9
-rw-r--r--dh.cpp2
-rw-r--r--dh.h9
-rw-r--r--dh2.cpp2
-rw-r--r--dh2.h9
-rw-r--r--dll.h6
-rw-r--r--dmac.h8
-rw-r--r--dsa.h9
-rw-r--r--eax.h27
-rw-r--r--ec2n.h7
-rw-r--r--eccrypto.cpp2
-rw-r--r--eccrypto.h2
-rw-r--r--ecp.cpp1
-rw-r--r--ecp.h6
-rw-r--r--elgamal.cpp2
-rw-r--r--esign.cpp2
-rw-r--r--esign.h3
-rw-r--r--files.cpp2
-rw-r--r--files.h8
-rw-r--r--filters.cpp23
-rw-r--r--filters.h180
-rw-r--r--gcm.cpp41
-rw-r--r--gcm.h29
-rw-r--r--gf2n.cpp28
-rw-r--r--gf2n.h2
-rw-r--r--gfpcrypt.cpp5
-rw-r--r--gfpcrypt.h8
-rw-r--r--gzip.cpp2
-rw-r--r--gzip.h4
-rw-r--r--hrtimer.h4
-rw-r--r--ida.h9
-rw-r--r--integer.cpp184
-rw-r--r--integer.h368
-rw-r--r--iterhash.cpp2
-rw-r--r--luc.cpp2
-rw-r--r--md5.cpp2
-rw-r--r--misc.cpp27
-rw-r--r--misc.h535
-rw-r--r--modarith.h33
-rw-r--r--modes.cpp12
-rw-r--r--modes.h70
-rw-r--r--mqv.cpp2
-rw-r--r--mqv.h1
-rw-r--r--oids.h6
-rw-r--r--panama.cpp4
-rw-r--r--pch.h17
-rw-r--r--pkcspad.h5
-rw-r--r--polynomi.h7
-rw-r--r--pssr.cpp7
-rw-r--r--pssr.h6
-rw-r--r--pubkey.h157
-rw-r--r--queue.cpp2
-rw-r--r--queue.h9
-rw-r--r--rabin.h9
-rw-r--r--rc2.h30
-rw-r--r--rijndael.cpp4
-rw-r--r--rijndael.h9
-rw-r--r--rng.h18
-rw-r--r--rsa.cpp6
-rw-r--r--rsa.h12
-rw-r--r--rw.cpp3
-rw-r--r--rw.h10
-rw-r--r--salsa.cpp19
-rw-r--r--salsa.h29
-rw-r--r--seal.cpp2
-rw-r--r--seal.h6
-rw-r--r--secblock.h226
-rw-r--r--seckey.h149
-rw-r--r--seed.h9
-rw-r--r--sha.cpp8
-rw-r--r--sha.h21
-rw-r--r--sha3.cpp10
-rw-r--r--sha3.h4
-rw-r--r--shark.h9
-rw-r--r--simple.h113
-rw-r--r--skipjack.h8
-rw-r--r--smartptr.h48
-rw-r--r--sosemanuk.cpp14
-rw-r--r--sosemanuk.h6
-rw-r--r--square.h8
-rw-r--r--stdcpp.h26
-rw-r--r--test.cpp121
-rw-r--r--tiger.cpp4
-rw-r--r--trdlocal.cpp12
-rw-r--r--ttmac.cpp4
-rw-r--r--validat1.cpp102
-rw-r--r--validat2.cpp128
-rw-r--r--validat3.cpp16
-rw-r--r--validate.h17
-rw-r--r--vmac.cpp4
-rw-r--r--vmac.h16
-rw-r--r--wait.cpp2
-rw-r--r--wake.cpp2
-rw-r--r--whrlpool.cpp20
-rw-r--r--xtr.cpp1
-rw-r--r--xtrcrypt.cpp6
-rw-r--r--zdeflate.cpp39
-rw-r--r--zinflate.cpp23
-rw-r--r--zinflate.h18
-rw-r--r--zlib.cpp2
136 files changed, 3461 insertions, 1546 deletions
diff --git a/3way.cpp b/3way.cpp
index 30cd14a3..ad57edf5 100644
--- a/3way.cpp
+++ b/3way.cpp
@@ -7,11 +7,13 @@
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void ThreeWay_TestInstantiations()
{
ThreeWay::Encryption x1;
ThreeWay::Decryption x2;
}
+#endif
static const word32 START_E = 0x0b0b; // round constant of first encryption round
static const word32 START_D = 0xb1b1; // round constant of first decryption round
diff --git a/3way.h b/3way.h
index ca6c0d15..8c85aa2e 100644
--- a/3way.h
+++ b/3way.h
@@ -2,7 +2,7 @@
//! \file
//! \headerfile 3way.h
-//! \brief Class files for the 3way cipher
+//! \brief Class file for the 3way cipher
#ifndef CRYPTOPP_THREEWAY_H
#define CRYPTOPP_THREEWAY_H
diff --git a/adler32.cpp b/adler32.cpp
index 22702027..54cf892b 100644
--- a/adler32.cpp
+++ b/adler32.cpp
@@ -61,14 +61,19 @@ void Adler32::TruncatedFinal(byte *hash, size_t size)
{
default:
hash[3] = byte(m_s1);
+ // fall through
case 3:
hash[2] = byte(m_s1 >> 8);
+ // fall through
case 2:
hash[1] = byte(m_s2);
+ // fall through
case 1:
hash[0] = byte(m_s2 >> 8);
+ // fall through
case 0:
- ;
+ ;;
+ // fall through
}
Reset();
diff --git a/adler32.h b/adler32.h
index a6da34a4..e8caa897 100644
--- a/adler32.h
+++ b/adler32.h
@@ -1,7 +1,8 @@
// adler32.h - written and placed in the public domain by Wei Dai
//! \file
-//! \brief Class files for ADLER-32 checksum calculations
+//! \headerfile adler32.h
+//! \brief Class file for ADLER-32 checksum calculations
#ifndef CRYPTOPP_ADLER32_H
#define CRYPTOPP_ADLER32_H
diff --git a/algebra.cpp b/algebra.cpp
index 686002d4..5a106c4a 100644
--- a/algebra.cpp
+++ b/algebra.cpp
@@ -206,7 +206,8 @@ template <class Element, class Iterator> Element GeneralCascadeMultiplication(co
struct WindowSlider
{
WindowSlider(const Integer &expIn, bool fastNegate, unsigned int windowSizeIn=0)
- : exp(expIn), windowModulus(Integer::One()), windowSize(windowSizeIn), windowBegin(0), fastNegate(fastNegate), negateNext(false), firstTime(true), finished(false)
+ : exp(expIn), windowModulus(Integer::One()), windowSize(windowSizeIn), windowBegin(0), expWindow(0)
+ , fastNegate(fastNegate), negateNext(false), firstTime(true), finished(false)
{
if (windowSize == 0)
{
diff --git a/algebra.h b/algebra.h
index c14ed545..647a4d61 100644
--- a/algebra.h
+++ b/algebra.h
@@ -1,14 +1,15 @@
// algebra.h - written and placed in the public domain by Wei Dai
//! \file
-//! \brief Classes and functions for performing mathematics over different fields
+//! \headerfile algebra.h
+//! \brief Classes for performing mathematics over different fields
#ifndef CRYPTOPP_ALGEBRA_H
#define CRYPTOPP_ALGEBRA_H
#include "config.h"
-#include "integer.h"
#include "misc.h"
+#include "integer.h"
NAMESPACE_BEGIN(CryptoPP)
diff --git a/algparam.h b/algparam.h
index 987652d1..af198183 100644
--- a/algparam.h
+++ b/algparam.h
@@ -1,7 +1,8 @@
// algparam.h - written and placed in the public domain by Wei Dai
//! \file
-//! \brief Classes and functions for working with NameValuePairs
+//! \headerfile algparam.h
+//! \brief Classes for working with NameValuePairs
#ifndef CRYPTOPP_ALGPARAM_H
@@ -30,21 +31,26 @@ class ConstByteArrayParameter
{
public:
ConstByteArrayParameter(const char *data = NULL, bool deepCopy = false)
+ : m_deepCopy(false), m_data(NULL), m_size(0)
{
Assign((const byte *)data, data ? strlen(data) : 0, deepCopy);
}
ConstByteArrayParameter(const byte *data, size_t size, bool deepCopy = false)
+ : m_deepCopy(false), m_data(NULL), m_size(0)
{
Assign(data, size, deepCopy);
}
template <class T> ConstByteArrayParameter(const T &string, bool deepCopy = false)
+ : m_deepCopy(false), m_data(NULL), m_size(0)
{
- CRYPTOPP_COMPILE_ASSERT(sizeof(CPP_TYPENAME T::value_type) == 1);
+ CRYPTOPP_COMPILE_ASSERT(sizeof(CPP_TYPENAME T::value_type) == 1);
Assign((const byte *)string.data(), string.size(), deepCopy);
}
void Assign(const byte *data, size_t size, bool deepCopy)
{
+ // This fires, which means: no data with a size, or data with no size.
+ // assert((data && size) || !(data || size));
if (deepCopy)
m_block.Assign(data, size);
else
@@ -400,6 +406,19 @@ CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<bool>;
CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<int>;
CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<ConstByteArrayParameter>;
+//! \class AlgorithmParameters
+//! \brief An object that implements NameValuePairs
+//! \tparam T the class or type
+//! \param name the name of the object or value to retrieve
+//! \param value reference to a variable that receives the value
+//! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed
+//! \note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(),
+//! such as MSVC 7.0 and earlier.
+//! \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by
+//! repeatedly using operator() on the object returned by MakeParameters, for example:
+//! <pre>
+//! AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3);
+//! </pre>
class CRYPTOPP_DLL AlgorithmParameters : public NameValuePairs
{
public:
@@ -418,6 +437,10 @@ public:
AlgorithmParameters & operator=(const AlgorithmParameters &x);
+ //! \tparam T the class or type
+ //! \param name the name of the object or value to retrieve
+ //! \param value reference to a variable that receives the value
+ //! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed
template <class T>
AlgorithmParameters & operator()(const char *name, const T &value, bool throwIfNotUsed)
{
@@ -428,6 +451,10 @@ public:
return *this;
}
+ //! \brief Appends a NameValuePair to a collection of NameValuePairs
+ //! \tparam T the class or type
+ //! \param name the name of the object or value to retrieve
+ //! \param value reference to a variable that receives the value
template <class T>
AlgorithmParameters & operator()(const char *name, const T &value)
{
@@ -441,23 +468,23 @@ protected:
bool m_defaultThrowIfNotUsed;
};
-//! Create an object that implements NameValuePairs for passing parameters
-/*! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed
- \note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(),
- such as MSVC 7.0 and earlier.
- \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by
- repeatedly using operator() on the object returned by MakeParameters, for example:
- AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3);
-*/
+//! \brief Create an object that implements NameValuePairs
+//! \tparam T the class or type
+//! \param name the name of the object or value to retrieve
+//! \param value reference to a variable that receives the value
+//! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed
+//! \note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(),
+//! such as MSVC 7.0 and earlier.
+//! \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by
+//! repeatedly using \p operator() on the object returned by \p MakeParameters, for example:
+//! <pre>
+//! AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3);
+//! </pre>
#ifdef __BORLANDC__
typedef AlgorithmParameters MakeParameters;
#else
template <class T>
-#if __APPLE__
-AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed = false)
-#else
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed = true)
-#endif
{
return AlgorithmParameters()(name, value, throwIfNotUsed);
}
diff --git a/arc4.cpp b/arc4.cpp
index f9b918c4..f2faec96 100644
--- a/arc4.cpp
+++ b/arc4.cpp
@@ -13,10 +13,12 @@
NAMESPACE_BEGIN(CryptoPP)
namespace Weak1 {
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void ARC4_TestInstantiations()
{
ARC4 x;
}
+#endif
ARC4_Base::~ARC4_Base()
{
diff --git a/arc4.h b/arc4.h
index 24e99118..d02bd9ba 100644
--- a/arc4.h
+++ b/arc4.h
@@ -1,7 +1,8 @@
// arc4.h - written and placed in the public domain by Wei Dai
//! \file
-//! \brief Implementation of ARC4
+//! \headerfile arc4.h
+//! \brief Classes for ARC4 cipher
#ifndef CRYPTOPP_ARC4_H
#define CRYPTOPP_ARC4_H
@@ -16,7 +17,8 @@ NAMESPACE_BEGIN(CryptoPP)
namespace Weak1 {
//! \class ARC4_Base
-//! \brief Allegedly RC4
+//! \brief Class specific methods used to operate the cipher.
+//! \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions
class CRYPTOPP_NO_VTABLE ARC4_Base : public VariableKeyLength<16, 1, 256>, public RandomNumberGenerator, public SymmetricCipher, public SymmetricCipherDocumentation
{
public:
@@ -47,7 +49,10 @@ protected:
//! <a href="http://www.weidai.com/scan-mirror/cs.html#RC4">Alleged RC4</a>
DOCUMENTED_TYPEDEF(SymmetricCipherFinal<ARC4_Base>, ARC4)
-//! _
+//! \class MARC4_Base
+//! \brief Class specific methods used to operate the cipher.
+//! \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions
+//! \details MARC4 discards the first 256 bytes of keystream, which may be weaker than the rest
class CRYPTOPP_NO_VTABLE MARC4_Base : public ARC4_Base
{
public:
@@ -60,7 +65,6 @@ protected:
unsigned int GetDefaultDiscardBytes() const {return 256;}
};
-//! Modified ARC4: it discards the first 256 bytes of keystream which may be weaker than the rest
DOCUMENTED_TYPEDEF(SymmetricCipherFinal<MARC4_Base>, MARC4)
}
diff --git a/argnames.h b/argnames.h
index 83a47b6f..8f24e577 100644
--- a/argnames.h
+++ b/argnames.h
@@ -1,7 +1,7 @@
// argnames.h - written and placed in the public domain by Wei Dai
-//! \file
-//! \brief Standard names for retrieving values when working with \p NameValuePairs
+//! \file argnames.h
+//! \brief Standard names for retrieving values by name when working with \p NameValuePairs
#ifndef CRYPTOPP_ARGNAMES_H
#define CRYPTOPP_ARGNAMES_H
@@ -78,9 +78,9 @@ CRYPTOPP_DEFINE_NAME_STRING(MaxLineLength) //< int
CRYPTOPP_DEFINE_NAME_STRING(DigestSize) //!< int, in bytes
CRYPTOPP_DEFINE_NAME_STRING(L1KeyLength) //!< int, in bytes
CRYPTOPP_DEFINE_NAME_STRING(TableSize) //!< int, in bytes
-CRYPTOPP_DEFINE_NAME_STRING(DerivedKey) //< ByteArrayParameter, key derivation, derived key
-CRYPTOPP_DEFINE_NAME_STRING(DerivedLength) //< int, key derivation, derived key length in bytes
-
+CRYPTOPP_DEFINE_NAME_STRING(Blinding) //!< bool
+CRYPTOPP_DEFINE_NAME_STRING(DerivedKey) //!< ByteArrayParameter, key derivation, derived key
+CRYPTOPP_DEFINE_NAME_STRING(DerivedLength) //!< int, key derivation, derived key length in bytes
DOCUMENTED_NAMESPACE_END
NAMESPACE_END
diff --git a/asn.h b/asn.h
index 89448b19..ba4a3191 100644
--- a/asn.h
+++ b/asn.h
@@ -1,6 +1,7 @@
// asn.h - written and placed in the public domain by Wei Dai
//! \file
+//! \headerfile asn.h
//! \brief Classes and functions for working with ANS.1 objects
#ifndef CRYPTOPP_ASN_H
@@ -348,7 +349,9 @@ void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
BERDecodeError();
size_t bc;
- BERLengthDecode(in, bc);
+ bool definite = BERLengthDecode(in, bc);
+ if (!definite)
+ BERDecodeError();
SecByteBlock buf(bc);
diff --git a/authenc.h b/authenc.h
index 36d5e6c3..a41dcd21 100644
--- a/authenc.h
+++ b/authenc.h
@@ -1,6 +1,7 @@
// authenc.h - written and placed in the public domain by Wei Dai
//! \file
+//! \headerfile authenc.h
//! \brief Base classes for working with authenticated encryption modes of encryption
#ifndef CRYPTOPP_AUTHENC_H
@@ -16,7 +17,8 @@ NAMESPACE_BEGIN(CryptoPP)
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipherBase : public AuthenticatedSymmetricCipher
{
public:
- AuthenticatedSymmetricCipherBase() : m_state(State_Start) {}
+ AuthenticatedSymmetricCipherBase() : m_state(State_Start), m_bufferedDataLength(0),
+ m_totalHeaderLength(0), m_totalMessageLength(0), m_totalFooterLength(0) {}
bool IsRandomAccess() const {return false;}
bool IsSelfInverting() const {return true;}
diff --git a/base32.h b/base32.h
index ab5ab575..6bc48c8a 100644
--- a/base32.h
+++ b/base32.h
@@ -1,7 +1,7 @@
// base32.h - written and placed in the public domain by Wei Dai
//! \file
-//! \brief Class files for the Base32 encoder and decoder
+//! \brief Classes for Base32 encoder and decoder
#ifndef CRYPTOPP_BASE32_H
#define CRYPTOPP_BASE32_H
diff --git a/base64.h b/base64.h
index 5b3f02db..24b184b0 100644
--- a/base64.h
+++ b/base64.h
@@ -1,7 +1,7 @@
// .h - written and placed in the public domain by Wei Dai
//! \file
-//! \brief Class files for the Base64Encoder, Base64Decoder, Base64URLEncoder and Base64URLDecoder
+//! \brief Classes for the Base64Encoder, Base64Decoder, Base64URLEncoder and Base64URLDecoder
#ifndef CRYPTOPP_BASE64_H
#define CRYPTOPP_BASE64_H
diff --git a/basecode.h b/basecode.h
index ca2323d1..bce550f4 100644
--- a/basecode.h
+++ b/basecode.h
@@ -1,7 +1,7 @@
// basecode.h - written and placed in the public domain by Wei Dai
//! \file
-//! \brief Base class files for working with encoders and decoders.
+//! \brief Base classes for working with encoders and decoders.
#ifndef CRYPTOPP_BASECODE_H
#define CRYPTOPP_BASECODE_H
@@ -19,9 +19,13 @@ class CRYPTOPP_DLL BaseN_Encoder : public Unflushable<Filter>
{
public:
BaseN_Encoder(BufferedTransformation *attachment=NULL)
- {Detach(attachment);}
+ : m_alphabet(NULL), m_padding(0), m_bitsPerChar(0)
+ , m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
+ {Detach(attachment);}
BaseN_Encoder(const byte *alphabet, int log2base, BufferedTransformation *attachment=NULL, int padding=-1)
+ : m_alphabet(NULL), m_padding(0), m_bitsPerChar(0)
+ , m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
{
Detach(attachment);
IsolatedInitialize(MakeParameters(Name::EncodingLookupArray(), alphabet)
@@ -46,9 +50,13 @@ class CRYPTOPP_DLL BaseN_Decoder : public Unflushable<Filter>
{
public:
BaseN_Decoder(BufferedTransformation *attachment=NULL)
- {Detach(attachment);}
+ : m_lookup(0), m_padding(0), m_bitsPerChar(0)
+ , m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
+ {Detach(attachment);}
BaseN_Decoder(const int *lookup, int log2base, BufferedTransformation *attachment=NULL)
+ : m_lookup(0), m_padding(0), m_bitsPerChar(0)
+ , m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
{
Detach(attachment);
IsolatedInitialize(MakeParameters(Name::DecodingLookupArray(), lookup)(Name::Log2Base(), log2base));
@@ -71,9 +79,10 @@ class CRYPTOPP_DLL Grouper : public Bufferless<Filter>
{
public:
Grouper(BufferedTransformation *attachment=NULL)
- {Detach(attachment);}
+ : m_groupSize(0), m_counter(0) {Detach(attachment);}
Grouper(int groupSize, const std::string &separator, const std::string &terminator, BufferedTransformation *attachment=NULL)
+ : m_groupSize(0), m_counter(0)
{
Detach(attachment);
IsolatedInitialize(MakeParameters(Name::GroupSize(), groupSize)
diff --git a/bench.cpp b/bench.cpp
index bf50b612..da9ca00d 100644
--- a/bench.cpp
+++ b/bench.cpp
@@ -17,6 +17,7 @@
#include <time.h>
#include <math.h>
#include <iostream>
+#include <sstream>
#include <iomanip>
// These are noisy enoguh due to test.cpp. Turn them off here.
@@ -35,46 +36,72 @@ const double CLOCK_TICKS_PER_SECOND = (double)CLK_TCK;
const double CLOCK_TICKS_PER_SECOND = 1000000.0;
#endif
-double logtotal = 0, g_allocatedTime, g_hertz;
+double logtotal = 0.0, g_allocatedTime = 0, g_hertz = 0;
unsigned int logcount = 0;
-static const byte defaultKey[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
+static const byte defaultKey[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
void OutputResultBytes(const char *name, double length, double timeTaken)
{
+ // Coverity finding (http://stackoverflow.com/a/30968371 does not squash the finding)
+ std::ostringstream out;
+ out.copyfmt(cout);
+
+ // Coverity finding
+ if (length < 0.0000000001f) length = 0.000001f;
+ if (timeTaken < 0.0000000001f) timeTaken = 0.000001f;
+
double mbs = length / timeTaken / (1024*1024);
- cout << "\n<TR><TH>" << name;
-// cout << "<TD>" << setprecision(3) << length / (1024*1024);
- cout << setiosflags(ios::fixed);
-// cout << "<TD>" << setprecision(3) << timeTaken;
- cout << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << mbs;
+ out << "\n<TR><TH>" << name;
+// out << "<TD>" << setprecision(3) << length / (1024*1024);
+ out << setiosflags(ios::fixed);
+// out << "<TD>" << setprecision(3) << timeTaken;
+ out << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << mbs;
if (g_hertz)
- cout << "<TD>" << setprecision(1) << setiosflags(ios::fixed) << timeTaken * g_hertz / length;
- cout << resetiosflags(ios::fixed);
+ out << "<TD>" << setprecision(1) << setiosflags(ios::fixed) << timeTaken * g_hertz / length;
logtotal += log(mbs);
logcount++;
+
+ cout << out.str();
}
void OutputResultKeying(double iterations, double timeTaken)
{
- cout << "<TD>" << setprecision(3) << setiosflags(ios::fixed) << (1000*1000*timeTaken/iterations);
+ // Coverity finding (http://stackoverflow.com/a/30968371 does not squash the finding)
+ std::ostringstream out;
+ out.copyfmt(cout);
+
+ // Coverity finding
+ if (iterations < 0.0000000001f) iterations = 0.000001f;
+ if (timeTaken < 0.0000000001f) timeTaken = 0.000001f;
+
+ out << "<TD>" << setprecision(3) << setiosflags(ios::fixed) << (1000*1000*timeTaken/iterations);
if (g_hertz)
- cout << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations;
+ out << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations;
+
+ cout << out.str();
}
void OutputResultOperations(const char *name, const char *operation, bool pc, unsigned long iterations, double timeTaken)
{
- cout << "\n<TR><TH>" << name << " " << operation << (pc ? " with precomputation" : "");
-// cout << "<TD>" << iterations;
-// cout << setiosflags(ios::fixed);
-// cout << "<TD>" << setprecision(3) << timeTaken;
- cout << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << (1000*timeTaken/iterations);
+ // Coverity finding (http://stackoverflow.com/a/30968371 does not squash the finding)
+ std::ostringstream out;
+ out.copyfmt(cout);
+
+ // Coverity finding
+ if (!iterations) iterations++;
+ if (timeTaken < 0.0000000001f) timeTaken = 0.000001f;
+
+ out << "\n<TR><TH>" << name << " " << operation << (pc ? " with precomputation" : "");
+ out << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << (1000*timeTaken/iterations);
if (g_hertz)
- cout << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations / 1000000;
- cout << resetiosflags(ios::fixed);
+ out << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations / 1000000;
logtotal += log(iterations/timeTaken);
logcount++;
+
+ cout << out.str();
}
/*
@@ -196,14 +223,16 @@ void BenchMarkByName2(const char *factoryName, size_t keyLength = 0, const char
CRYPTOPP_UNUSED(x), CRYPTOPP_UNUSED(y), CRYPTOPP_UNUSED(params);
std::string name(factoryName ? factoryName : "");
+ member_ptr<T_FactoryOutput> obj(ObjectFactoryRegistry<T_FactoryOutput>::Registry().CreateObject(name.c_str()));
+
+ if (!keyLength)
+ keyLength = obj->DefaultKeyLength();
+
if (displayName)
name = displayName;
else if (keyLength)
name += " (" + IntToString(keyLength * 8) + "-bit key)";
- member_ptr<T_FactoryOutput> obj(ObjectFactoryRegistry<T_FactoryOutput>::Registry().CreateObject(factoryName));
- if (!keyLength)
- keyLength = obj->DefaultKeyLength();
obj->SetKey(defaultKey, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), ConstByteArrayParameter(defaultKey, obj->IVSize()), false)));
BenchMark(name.c_str(), *static_cast<T_Interface *>(obj.get()), g_allocatedTime);
BenchMarkKeying(*obj, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), ConstByteArrayParameter(defaultKey, obj->IVSize()), false)));
@@ -347,8 +376,7 @@ void BenchmarkAll(double t, double hertz)
cout << "</TABLE>" << endl;
BenchmarkAll2(t, hertz);
-
- cout << "Throughput Geometric Average: " << setiosflags(ios::fixed) << exp(logtotal/logcount) << endl;
+ cout << "Throughput Geometric Average: " << setiosflags(ios::fixed) << exp(logtotal/(logcount ? logcount : 1)) << endl;
// Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55
#if defined(CRYPTOPP_MSC_VERSION)
diff --git a/bench.h b/bench.h
index c5da2cf6..bf966ffc 100644
--- a/bench.h
+++ b/bench.h
@@ -1,3 +1,5 @@
+// bench.h - written and placed in the public domain by Wei Dai
+
#ifndef CRYPTOPP_BENCH_H
#define CRYPTOPP_BENCH_H
diff --git a/bench2.cpp b/bench2.cpp
index afe4b77b..308136ca 100644
--- a/bench2.cpp
+++ b/bench2.cpp
@@ -48,7 +48,7 @@ void BenchMarkEncryption(const char *name, PK_Encryptor &key, double timeTotal,
SecByteBlock plaintext(len), ciphertext(key.CiphertextLength(len));
GlobalRNG().GenerateBlock(plaintext, len);
- clock_t start = clock();
+ const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
@@ -71,7 +71,7 @@ void BenchMarkDecryption(const char *name, PK_Decryptor &priv, PK_Encryptor &pub
GlobalRNG().GenerateBlock(plaintext, len);
pub.Encrypt(GlobalRNG(), plaintext, len, ciphertext);
- clock_t start = clock();
+ const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
@@ -86,7 +86,7 @@ void BenchMarkSigning(const char *name, PK_Signer &key, double timeTotal, bool p
AlignedSecByteBlock message(len), signature(key.SignatureLength());
GlobalRNG().GenerateBlock(message, len);
- clock_t start = clock();
+ const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
@@ -108,11 +108,15 @@ void BenchMarkVerification(const char *name, const PK_Signer &priv, PK_Verifier
GlobalRNG().GenerateBlock(message, len);
priv.SignMessage(GlobalRNG(), message, len, signature);
- clock_t start = clock();
+ const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
- pub.VerifyMessage(message, len, signature, signature.size());
+ {
+ // The return value is ignored because we are interested in throughput
+ bool unused = pub.VerifyMessage(message, len, signature, signature.size());
+ CRYPTOPP_UNUSED(unused);
+ }
OutputResultOperations(name, "Verification", pc, i, timeTaken);
@@ -127,7 +131,7 @@ void BenchMarkKeyGen(const char *name, SimpleKeyAgreementDomain &d, double timeT
{
SecByteBlock priv(d.PrivateKeyLength()), pub(d.PublicKeyLength());
- clock_t start = clock();
+ const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
@@ -146,7 +150,7 @@ void BenchMarkKeyGen(const char *name, AuthenticatedKeyAgreementDomain &d, doubl
{
SecByteBlock priv(d.EphemeralPrivateKeyLength()), pub(d.EphemeralPublicKeyLength());
- clock_t start = clock();
+ const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
@@ -169,7 +173,7 @@ void BenchMarkAgreement(const char *name, SimpleKeyAgreementDomain &d, double ti
d.GenerateKeyPair(GlobalRNG(), priv2, pub2);
SecByteBlock val(d.AgreedValueLength());
- clock_t start = clock();
+ const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2)
@@ -193,7 +197,7 @@ void BenchMarkAgreement(const char *name, AuthenticatedKeyAgreementDomain &d, do
d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2);
SecByteBlock val(d.AgreedValueLength());
- clock_t start = clock();
+ const clock_t start = clock();
unsigned int i;
double timeTaken;
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2)
diff --git a/blowfish.h b/blowfish.h
index d440977e..ee8445cc 100644
--- a/blowfish.h
+++ b/blowfish.h
@@ -1,7 +1,7 @@
// blowfish.h - written and placed in the public domain by Wei Dai
//! \file
-//! \brief Class files for the Blowfish algorithm
+//! \brief Classes for the Blowfish algorithm
#ifndef CRYPTOPP_BLOWFISH_H
#define CRYPTOPP_BLOWFISH_H
diff --git a/blumshub.cpp b/blumshub.cpp
index d180c203..3e7345cd 100644
--- a/blumshub.cpp
+++ b/blumshub.cpp
@@ -8,10 +8,10 @@ NAMESPACE_BEGIN(CryptoPP)
PublicBlumBlumShub::PublicBlumBlumShub(const Integer &n, const Integer &seed)
: modn(n),
- maxBits(BitPrecision(n.BitCount())-1)
+ current(modn.Square(modn.Square(seed))),
+ maxBits(BitPrecision(n.BitCount())-1),
+ bitsLeft(maxBits)
{
- current = modn.Square(modn.Square(seed));
- bitsLeft = maxBits;
}
unsigned int PublicBlumBlumShub::GenerateBit()
diff --git a/blumshub.h b/blumshub.h
index cd194965..3ceef899 100644
--- a/blumshub.h
+++ b/blumshub.h
@@ -1,3 +1,9 @@
+// blumshub.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile blumshub.h
+//! \brief Classes for Blum Blum Shub generator
+
#ifndef CRYPTOPP_BLUMSHUB_H
#define CRYPTOPP_BLUMSHUB_H
@@ -21,14 +27,15 @@ public:
bool IsSelfInverting() const {return true;}
bool IsForwardTransformation() const {return true;}
+
+#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
+ virtual ~PublicBlumBlumShub() {}
+#endif
protected:
ModularArithmetic modn;
- word maxBits, bitsLeft;
Integer current;
-
- friend class BlumGoldwasserPublicKey;
- friend class BlumGoldwasserPrivateKey;
+ word maxBits, bitsLeft;
};
//! BlumBlumShub with factorization of the modulus
@@ -42,6 +49,10 @@ public:
bool IsRandomAccess() const {return true;}
void Seek(lword index);
+#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
+ virtual ~BlumBlumShub() {}
+#endif
+
protected:
const Integer p, q;
const Integer x0;
diff --git a/camellia.h b/camellia.h
index d0893e23..79d9b819 100644
--- a/camellia.h
+++ b/camellia.h
@@ -1,3 +1,9 @@
+// camellia.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile camellia.h
+//! \brief Classes for Cameliia cipher
+
#ifndef CRYPTOPP_CAMELLIA_H
#define CRYPTOPP_CAMELLIA_H
diff --git a/cast.h b/cast.h
index f527be8a..2db1e652 100644
--- a/cast.h
+++ b/cast.h
@@ -1,3 +1,9 @@
+// cast.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile cast.h
+//! \brief Classes for CAST cipher
+
#ifndef CRYPTOPP_CAST_H
#define CRYPTOPP_CAST_H
diff --git a/cbcmac.h b/cbcmac.h
index 2fc13e54..d4745b6b 100644
--- a/cbcmac.h
+++ b/cbcmac.h
@@ -1,3 +1,9 @@
+// cbcmac.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile cbcmac.h
+//! \brief Classes for CBC MAC
+
#ifndef CRYPTOPP_CBCMAC_H
#define CRYPTOPP_CBCMAC_H
@@ -10,7 +16,7 @@ NAMESPACE_BEGIN(CryptoPP)
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_MAC_Base : public MessageAuthenticationCode
{
public:
- CBC_MAC_Base() {}
+ CBC_MAC_Base() : m_counter(0) {}
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
void Update(const byte *input, size_t length);
diff --git a/ccm.h b/ccm.h
index 6f6e4e41..65d5287f 100644
--- a/ccm.h
+++ b/ccm.h
@@ -1,3 +1,9 @@
+// ccm.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile ccm.h
+//! \brief CCM block cipher mode of operation
+
#ifndef CRYPTOPP_CCM_H
#define CRYPTOPP_CCM_H
@@ -10,7 +16,7 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CCM_Base : public AuthenticatedSymmetricCi
{
public:
CCM_Base()
- : m_digestSize(0), m_L(0) {}
+ : m_digestSize(0), m_L(0), m_messageLength(0), m_aadLength(0) {}
// AuthenticatedSymmetricCipher
std::string AlgorithmName() const
diff --git a/channels.h b/channels.h
index 3a9bf81e..1a140775 100644
--- a/channels.h
+++ b/channels.h
@@ -1,11 +1,16 @@
+// channels.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile channels.h
+//! \brief Classes for multiple named channels
+
#ifndef CRYPTOPP_CHANNELS_H
#define CRYPTOPP_CHANNELS_H
#include "cryptlib.h"
#include "simple.h"
#include "smartptr.h"
-#include <map>
-#include <list>
+#include "stdcpp.h"
NAMESPACE_BEGIN(CryptoPP)
@@ -64,18 +69,23 @@ class ChannelSwitch;
class ChannelRouteIterator : public ChannelSwitchTypedefs
{
public:
- ChannelSwitch& m_cs;
- std::string m_channel;
- bool m_useDefault;
- MapIterator m_itMapCurrent, m_itMapEnd;
- ListIterator m_itListCurrent, m_itListEnd;
+ ChannelRouteIterator(ChannelSwitch &cs) : m_cs(cs), m_useDefault(false) {}
- ChannelRouteIterator(ChannelSwitch &cs) : m_cs(cs) {}
void Reset(const std::string &channel);
bool End() const;
void Next();
BufferedTransformation & Destination();
const std::string & Channel();
+
+ ChannelSwitch& m_cs;
+ std::string m_channel;
+ bool m_useDefault;
+ MapIterator m_itMapCurrent, m_itMapEnd;
+ ListIterator m_itListCurrent, m_itListEnd;
+
+protected:
+ // Hide this to see if we break something...
+ ChannelRouteIterator();
};
//! Route input to different and/or multiple channels based on channel ID
diff --git a/cmac.cpp b/cmac.cpp
index e8fa6fea..150abd47 100644
--- a/cmac.cpp
+++ b/cmac.cpp
@@ -57,6 +57,7 @@ void CMAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const Name
void CMAC_Base::Update(const byte *input, size_t length)
{
+ assert((input && length) || !(input || length));
if (!length)
return;
@@ -65,11 +66,14 @@ void CMAC_Base::Update(const byte *input, size_t length)
if (m_counter > 0)
{
- unsigned int len = UnsignedMin(blockSize - m_counter, length);
- xorbuf(m_reg+m_counter, input, len);
- length -= len;
- input += len;
- m_counter += len;
+ const unsigned int len = UnsignedMin(blockSize - m_counter, length);
+ if (len)
+ {
+ xorbuf(m_reg+m_counter, input, len);
+ length -= len;
+ input += len;
+ m_counter += len;
+ }
if (m_counter == blockSize && length > 0)
{
diff --git a/cmac.h b/cmac.h
index ab3ecf8c..dfbdbffe 100644
--- a/cmac.h
+++ b/cmac.h
@@ -1,3 +1,9 @@
+// cmac.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile cmac.h
+//! \brief Classes for CMAC message authentication code
+
#ifndef CRYPTOPP_CMAC_H
#define CRYPTOPP_CMAC_H
@@ -10,7 +16,7 @@ NAMESPACE_BEGIN(CryptoPP)
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CMAC_Base : public MessageAuthenticationCode
{
public:
- CMAC_Base() {}
+ CMAC_Base() : m_counter(0) {}
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
void Update(const byte *input, size_t length);
diff --git a/config.h b/config.h
index 9728ee22..77c969cd 100644
--- a/config.h
+++ b/config.h
@@ -1,3 +1,9 @@
+// config.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile config.h
+//! \brief Library configuration file
+
#ifndef CRYPTOPP_CONFIG_H
#define CRYPTOPP_CONFIG_H
@@ -54,8 +60,16 @@
# endif
#endif
+// Define this if you want or need the library's memcpy_s and memmove_s.
+// See http://github.com/weidai11/cryptopp/issues/28.
+// #if !defined(CRYPTOPP_WANT_SECURE_LIB)
+// # define CRYPTOPP_WANT_SECURE_LIB
+// #endif
+
// File system code to write to GZIP archive.
-#define GZIP_OS_CODE 0
+#if !defined(GZIP_OS_CODE)
+# define GZIP_OS_CODE 0
+#endif
// Try this if your CPU has 256K internal cache or a slow multiply instruction
// and you want a (possibly) faster IDEA implementation using log tables
@@ -90,7 +104,7 @@
#if defined(CRYPTOPP_INIT_PRIORITY) && (CRYPTOPP_INIT_PRIORITY > 0)
# define CRYPTOPP_USER_PRIORITY (CRYPTOPP_INIT_PRIORITY + 101)
#else
-# define CRYPTOPP_USER_PRIORITY 500
+# define CRYPTOPP_USER_PRIORITY 250
#endif
// ***************** Important Settings Again ********************
@@ -113,8 +127,8 @@
//! \details Nearly all classes are located in the CryptoPP namespace. Within
//! the namespace, there are two additional namespaces.
//! <ul>
-//! <li>Name - the namespace for names used with \p NameValuePairs and documented in argnames.h
-//! <li>Weak - the namespace for weak and wounded algorithms, like ARC4, MD5 and Pananma
+//! <li>Name - namespace for names used with \p NameValuePairs and documented in argnames.h
+//! <li>Weak - namespace for weak and wounded algorithms, like ARC4, MD5 and Pananma
//! </ul>
namespace CryptoPP { }
// Bring in the symbols fund in the weak namespace; and fold Weak1 into Weak
@@ -126,12 +140,15 @@ namespace CryptoPP { }
# define NAMESPACE_END
// Get Doxygen to generate better documentation for these typedefs
# define DOCUMENTED_TYPEDEF(x, y) class y : public x {};
+// Make "protected" "private" so the functions and members are not documented
+# define protected private
#else
# define NAMESPACE_BEGIN(x) namespace x {
# define NAMESPACE_END }
# define DOCUMENTED_TYPEDEF(x, y) typedef x y;
#endif
#define ANONYMOUS_NAMESPACE_BEGIN namespace {
+#define ANONYMOUS_NAMESPACE_END }
#define USING_NAMESPACE(x) using namespace x;
#define DOCUMENTED_NAMESPACE_BEGIN(x) namespace x {
#define DOCUMENTED_NAMESPACE_END }
@@ -175,32 +192,31 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff);
#define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
-#ifdef __clang__
+// Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7
+#if defined(__clang__ ) && !defined(__apple_build_version__)
#define CRYPTOPP_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
+#elif defined(__clang__ ) && defined(__apple_build_version__)
+ #define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#endif
#ifdef _MSC_VER
#define CRYPTOPP_MSC_VERSION (_MSC_VER)
#endif
-// Need GCC 4.6/Clang 1.7 or above due to "GCC diagnostic {push|pop}"
-#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 10700)
+// Need GCC 4.6/Clang 1.7/Apple Clang 2.0 or above due to "GCC diagnostic {push|pop}"
+#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000)
#define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1
#endif
-// Detect availabliltiy of int128_t and uint128_t in preprocessor, http://gcc.gnu.org/ml/gcc-help/2015-08/msg00185.html.
-// Both GCC and Clang respond to it.
-#if ((defined(__GNUC__) || defined(__clang__) || defined(_INTEL_COMPILER)) && (__SIZEOF_INT128__ >= 16))
- #define CRYPTOPP_NATIVE_DWORD_AVAILABLE
- #define CRYPTOPP_WORD128_AVAILABLE
- typedef word32 hword;
- typedef word64 word;
- typedef __uint128_t dword;
- typedef __uint128_t word128;
+// Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232
+// TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes.
+#if (defined(CRYPTOPP_CLANG_VERSION) && CRYPTOPP_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000)
+ #define CRYPTOPP_DISABLE_INTEL_ASM 1
+#endif
// define hword, word, and dword. these are used for multiprecision integer arithmetic
// Intel compiler won't have _umul128 until version 10.0. See http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30231625.aspx
-#elif (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && defined(__x86_64__)) || (defined(__SUNPRO_CC) && defined(__x86_64__))
+#if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER < 1000) && defined(__x86_64__)) || (defined(__SUNPRO_CC) && defined(__x86_64__))
typedef word32 hword;
typedef word64 word;
#else
@@ -214,12 +230,26 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff);
typedef word64 word;
typedef __uint128_t dword;
typedef __uint128_t word128;
+ #elif defined(__GNUC__) && (__SIZEOF_INT128__ >= 16)
+ // Detect availabliltiy of int128_t and uint128_t in preprocessor, http://gcc.gnu.org/ml/gcc-help/2015-08/msg00185.html.
+ #define CRYPTOPP_WORD128_AVAILABLE
+ typedef word32 hword;
+ typedef word64 word;
+ typedef __uint128_t dword;
+ typedef __uint128_t word128;
#else
// if we're here, it means we're on a 64-bit CPU but we don't have a way to obtain 128-bit multiplication results
typedef word16 hword;
typedef word32 word;
typedef word64 dword;
#endif
+ #elif defined(__GNUC__) && (__SIZEOF_INT128__ >= 16)
+ // Detect availabliltiy of int128_t and uint128_t in preprocessor, http://gcc.gnu.org/ml/gcc-help/2015-08/msg00185.html.
+ #define CRYPTOPP_WORD128_AVAILABLE
+ typedef word32 hword;
+ typedef word64 word;
+ typedef __uint128_t dword;
+ typedef __uint128_t word128;
#else
// being here means the native register size is probably 32 bits or less
#define CRYPTOPP_BOOL_SLOW_WORD64 1
@@ -233,7 +263,7 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff);
#endif
// Produce a compiler error. It can be commented out, but you may not get the benefit of the fastest integers.
-#if (__SIZEOF_INT128__ >= 16) && !defined(CRYPTOPP_WORD128_AVAILABLE)
+#if (__SIZEOF_INT128__ >= 16) && !defined(CRYPTOPP_WORD128_AVAILABLE) && !defined(__aarch64__)
# error "An int128_t and uint128_t are available, but CRYPTOPP_WORD128_AVAILABLE is not defined"
#endif
@@ -351,6 +381,11 @@ NAMESPACE_END
#define CRYPTOPP_DISABLE_ASM
#define CRYPTOPP_DISABLE_SSE2
#endif
+
+// Apple's Clang prior to 5.0 cannot handle SSE2 (and Apple does not use LLVM Clang numbering...)
+#if defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION < 50000)
+# define CRYPTOPP_DISABLE_ASM
+#endif
#if !defined(CRYPTOPP_DISABLE_ASM) && ((defined(_MSC_VER) && defined(_M_IX86)) || (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))))
// C++Builder 2010 does not allow "call label" where label is defined within inline assembly
@@ -380,7 +415,7 @@ NAMESPACE_END
#define CRYPTOPP_X64_ASM_AVAILABLE
#endif
-#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || defined(__SSE2__) || defined(__AES__))
+#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || defined(__SSE2__))
#define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 1
#else
#define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 0
@@ -401,6 +436,8 @@ NAMESPACE_END
// how to allocate 16-byte aligned memory (for SSE2)
#if defined(CRYPTOPP_MSVC6PP_OR_LATER)
#define CRYPTOPP_MM_MALLOC_AVAILABLE
+#elif defined(__APPLE__)
+ #define CRYPTOPP_APPLE_MALLOC_AVAILABLE
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#define CRYPTOPP_MALLOC_ALIGNMENT_IS_16
#elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__)
@@ -408,6 +445,9 @@ NAMESPACE_END
#else
#define CRYPTOPP_NO_ALIGNED_ALLOC
#endif
+
+// Apple always provides 16-byte aligned, and tells us to use calloc
+// http://developer.apple.com/library/mac/documentation/Performance/Conceptual/ManagingMemory/Articles/MemoryAlloc.html
// how to disable inlining
#if defined(_MSC_VER) && _MSC_VER >= 1300
@@ -462,13 +502,6 @@ NAMESPACE_END
#endif
#endif
-// For use in template parameters; also see CRYPTOPP_BOOL_ALIGN16 for MMX and above.
-#if defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS)
- #define CRYPTOPP_BOOL_ALIGN 0
-#else
- #define CRYPTOPP_BOOL_ALIGN 1
-#endif
-
// ***************** determine availability of OS features ********************
#ifndef NO_OS_DEPENDENCE
@@ -547,7 +580,7 @@ NAMESPACE_END
#define CRYPTOPP_API __cdecl
-#else // CRYPTOPP_WIN32_AVAILABLE
+#else // not CRYPTOPP_WIN32_AVAILABLE
#define CRYPTOPP_DLL
#define CRYPTOPP_API
@@ -583,12 +616,14 @@ NAMESPACE_END
#endif
// ************** Unused variable ***************
-// Portable way to suppress warning
+
+// Portable way to suppress warnings.
+// Moved from misc.h due to circular depenedencies.
#define CRYPTOPP_UNUSED(x) ((void)x)
// ***************** C++11 related ********************
-// Visual Studio and C++11 language features began at Visual Studio 2010, http://msdn.microsoft.com/en-us/library/hh567368%28v=vs.110%29.aspx.
+// Visual Studio began at VS2010, http://msdn.microsoft.com/en-us/library/hh567368%28v=vs.110%29.aspx.
// Intel and C++11 language features, http://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler
// GCC and C++11 language features, http://gcc.gnu.org/projects/cxx0x.html
// Clang and C++11 language features, http://clang.llvm.org/cxx_status.html
@@ -601,8 +636,8 @@ NAMESPACE_END
// way. However, modern standard libraries have <forward_list>, so we test for it instead.
// Thanks to Jonathan Wakely for devising the clever test for modern/ancient versions.
// TODO: test under Xcode 3, where g++ is really g++.
-#if defined(__clang__)
-# if !(__has_include(<forward_list>))
+#if defined(__APPLE__) && defined(__clang__)
+# if !(defined(__has_include) && __has_include(<forward_list>))
# undef CRYPTOPP_CXX11
# endif
#endif
@@ -610,18 +645,22 @@ NAMESPACE_END
// C++11 or C++14 is available
#if defined(CRYPTOPP_CXX11)
-// alignof/alignas: MS at VS2013 (18.00); GCC at 4.8; Clang at 3.3; and Intel 15.0.
-#if (CRYPTOPP_MSC_VERSION >= 1800)
+// alignof/alignas: MS at VS2013 (19.00); GCC at 4.8; Clang at 3.3; and Intel 15.0.
+#if (CRYPTOPP_MSC_VERSION >= 1900)
+# define CRYPTOPP_CXX11_ALIGNAS 1
# define CRYPTOPP_CXX11_ALIGNOF 1
#elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
+# define CRYPTOPP_CXX11_ALIGNAS 1
# define CRYPTOPP_CXX11_ALIGNOF 1
#elif defined(__clang__)
# if __has_feature(cxx_alignof)
-# define CRYPTOPP_CXX11_ALIGNOF 1
+# define CRYPTOPP_CXX11_ALIGNAS 1
+# define CRYPTOPP_CXX11_ALIGNOF 1
# endif
#elif (CRYPTOPP_GCC_VERSION >= 40800)
+# define CRYPTOPP_CXX11_ALIGNAS 1
# define CRYPTOPP_CXX11_ALIGNOF 1
-#endif
+#endif // alignof/alignas
// noexcept: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; and Intel 14.0.
#if (CRYPTOPP_MSC_VERSION >= 1900)
@@ -647,7 +686,7 @@ NAMESPACE_END
# endif
#elif (CRYPTOPP_GCC_VERSION >= 40300)
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
-#endif // noexcept compilers
+#endif // variadic templates
// TODO: Emplacement, R-values and Move semantics
// Needed because we are catching warnings with GCC and MSC
diff --git a/cpu.cpp b/cpu.cpp
index 924df6f9..2b041321 100644
--- a/cpu.cpp
+++ b/cpu.cpp
@@ -83,11 +83,15 @@ bool CpuId(word32 input, word32 output[4])
return true;
#else
+ // longjmp and clobber warnings. Volatile is required.
+ // http://github.com/weidai11/cryptopp/issues/24
+ // http://stackoverflow.com/q/7721854
+ volatile bool result = true;
+
SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
if (oldHandler == SIG_ERR)
- return false;
+ result = false;
- bool result = true;
if (setjmp(s_jmpNoCPUID))
result = false;
else
@@ -134,13 +138,17 @@ static bool TrySSE2()
}
return true;
#else
+ // longjmp and clobber warnings. Volatile is required.
+ // http://github.com/weidai11/cryptopp/issues/24
+ // http://stackoverflow.com/q/7721854
+ volatile bool result = true;
+
SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
if (oldHandler == SIG_ERR)
return false;
- bool result = true;
if (setjmp(s_jmpNoSSE2))
- result = false;
+ result = true;
else
{
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
@@ -156,20 +164,30 @@ static bool TrySSE2()
#endif
}
-#if 0
-static bool g_x86DetectionDone = false;
-static bool g_hasMMX = false, g_hasISSE = false, g_hasSSE2 = false, g_hasSSSE3 = false, g_hasAESNI = false, g_hasCLMUL = false, g_isP4 = false;
-static word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
-#else
bool g_x86DetectionDone = false;
-bool g_hasMMX = false, g_hasISSE = false, g_hasSSE2 = false, g_hasSSSE3 = false, g_hasAESNI = false, g_hasCLMUL = false, g_isP4 = false;
+bool g_hasMMX = false, g_hasISSE = false, g_hasSSE2 = false, g_hasSSSE3 = false, g_hasAESNI = false, g_hasCLMUL = false, g_isP4 = false, g_hasRDRAND = false, g_hasRDSEED = false;
word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
-#endif
// MacPorts/GCC does not provide constructor(priority). Apple/GCC and Fink/GCC do provide it.
-#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 1000)) && !(MACPORTS_GCC_COMPILER > 0))
+#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0))
#define HAVE_GCC_CONSTRUCTOR0 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && !(MACPORTS_GCC_COMPILER > 0))
+static inline bool IsIntel(const word32 output[4])
+{
+ // This is the "GenuineIntel" string
+ return (output[1] /*EBX*/ == 0x756e6547) &&
+ (output[2] /*ECX*/ == 0x6c65746e) &&
+ (output[3] /*EDX*/ == 0x49656e69);
+}
+
+static inline bool IsAMD(const word32 output[4])
+{
+ // This is the "AuthenticAMD" string
+ return (output[1] /*EBX*/ == 0x68747541) &&
+ (output[2] /*ECX*/ == 0x69746E65) &&
+ (output[3] /*EDX*/ == 0x444D4163);
+}
+
#if HAVE_GCC_CONSTRUCTOR1
void __attribute__ ((constructor (CRYPTOPP_INIT_PRIORITY + 50))) DetectX86Features()
#elif HAVE_GCC_CONSTRUCTOR0
@@ -204,22 +222,32 @@ void DetectX86Features()
}
}
- std::swap(cpuid[2], cpuid[3]);
- if (memcmp(cpuid+1, "GenuineIntel", 12) == 0)
+ static const unsigned int RDRAND_FLAG = (1 << 30);
+ static const unsigned int RDSEED_FLAG = (1 << 18);
+ if (IsIntel(cpuid))
{
g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf;
g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1);
+ g_hasRDRAND = !!(cpuid1[2] /*ECX*/ & RDRAND_FLAG);
+
+ if (cpuid[0] /*EAX*/ >= 7)
+ {
+ word32 cpuid3[4];
+ if (CpuId(7, cpuid3))
+ g_hasRDSEED = !!(cpuid3[1] /*EBX*/ & RDSEED_FLAG);
+ }
}
- else if (memcmp(cpuid+1, "AuthenticAMD", 12) == 0)
+ else if (IsAMD(cpuid))
{
CpuId(0x80000005, cpuid);
g_cacheLineSize = GETBYTE(cpuid[2], 0);
+ g_hasRDRAND = !!(cpuid[2] /*ECX*/ & RDRAND_FLAG);
}
if (!g_cacheLineSize)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
- g_x86DetectionDone = true;
+ *((volatile bool*)&g_x86DetectionDone) = true;
}
#endif
diff --git a/cpu.h b/cpu.h
index 2871ae93..c0b0122e 100644
--- a/cpu.h
+++ b/cpu.h
@@ -1,3 +1,9 @@
+// cpu.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile cpu.h
+//! \brief Classes, functions, intrinsics and features for X86, X32 nd X64 assembly
+
#ifndef CRYPTOPP_CPU_H
#define CRYPTOPP_CPU_H
@@ -20,16 +26,19 @@
#if !defined(__GNUC__) || defined(__SSSE3__) || defined(__INTEL_COMPILER)
#include <tmmintrin.h>
#else
+NAMESPACE_BEGIN(CryptoPP)
__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_shuffle_epi8 (__m128i a, __m128i b)
{
asm ("pshufb %1, %0" : "+x"(a) : "xm"(b));
return a;
}
-#endif
+NAMESPACE_END
+#endif // tmmintrin.h
#if !defined(__GNUC__) || defined(__SSE4_1__) || defined(__INTEL_COMPILER)
#include <smmintrin.h>
#else
+NAMESPACE_BEGIN(CryptoPP)
__inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_extract_epi32 (__m128i a, const int i)
{
@@ -43,10 +52,12 @@ _mm_insert_epi32 (__m128i a, int b, const int i)
asm ("pinsrd %2, %1, %0" : "+x"(a) : "rm"(b), "i"(i));
return a;
}
-#endif
+NAMESPACE_END
+#endif // smmintrin.h
#if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER)
#include <wmmintrin.h>
#else
+NAMESPACE_BEGIN(CryptoPP)
__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_clmulepi64_si128 (__m128i a, __m128i b, const int i)
{
@@ -91,8 +102,9 @@ _mm_aesdeclast_si128 (__m128i a, __m128i b)
asm ("aesdeclast %1, %0" : "+x"(a) : "xm"(b));
return a;
}
-#endif
-#endif
+NAMESPACE_END
+#endif // wmmintrin.h
+#endif // CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
NAMESPACE_BEGIN(CryptoPP)
@@ -109,6 +121,8 @@ extern CRYPTOPP_DLL bool g_hasSSSE3;
extern CRYPTOPP_DLL bool g_hasAESNI;
extern CRYPTOPP_DLL bool g_hasCLMUL;
extern CRYPTOPP_DLL bool g_isP4;
+extern CRYPTOPP_DLL bool g_hasRDRAND;
+extern CRYPTOPP_DLL bool g_hasRDSEED;
extern CRYPTOPP_DLL word32 g_cacheLineSize;
CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features();
@@ -175,6 +189,20 @@ inline bool IsP4()
return g_isP4;
}
+inline bool HasRDRAND()
+{
+ if (!g_x86DetectionDone)
+ DetectX86Features();
+ return g_hasRDRAND;
+}
+
+inline bool HasRDSEED()
+{
+ if (!g_x86DetectionDone)
+ DetectX86Features();
+ return g_hasRDSEED;
+}
+
inline int GetCacheLineSize()
{
if (!g_x86DetectionDone)
@@ -215,12 +243,27 @@ inline int GetCacheLineSize()
#define AS_HEX(y) 0x##y
#else
#define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
+
+#if defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)
+ #define NEW_LINE "\n"
+ #define INTEL_PREFIX ".intel_syntax;"
+ #define INTEL_NOPREFIX ".intel_syntax;"
+ #define ATT_PREFIX ".att_syntax;"
+ #define ATT_NOPREFIX ".att_syntax;"
+#else
+ #define NEW_LINE
+ #define INTEL_PREFIX ".intel_syntax prefix;"
+ #define INTEL_NOPREFIX ".intel_syntax noprefix;"
+ #define ATT_PREFIX ".att_syntax prefix;"
+ #define ATT_NOPREFIX ".att_syntax noprefix;"
+#endif
+
// define these in two steps to allow arguments to be expanded
- #define GNU_AS1(x) #x ";"
- #define GNU_AS2(x, y) #x ", " #y ";"
- #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";"
- #define GNU_ASL(x) "\n" #x ":"
- #define GNU_ASJ(x, y, z) #x " " #y #z ";"
+ #define GNU_AS1(x) #x ";" NEW_LINE
+ #define GNU_AS2(x, y) #x ", " #y ";" NEW_LINE
+ #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";" NEW_LINE
+ #define GNU_ASL(x) "\n" #x ":" NEW_LINE
+ #define GNU_ASJ(x, y, z) #x " " #y #z ";" NEW_LINE
#define AS1(x) GNU_AS1(x)
#define AS2(x, y) GNU_AS2(x, y)
#define AS3(x, y, z) GNU_AS3(x, y, z)
diff --git a/crc.h b/crc.h
index a9a657d0..d31555dd 100644
--- a/crc.h
+++ b/crc.h
@@ -1,3 +1,9 @@
+// crc.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile crc.h
+//! \brief Classes for CRC-32 checksum algorithm
+
#ifndef CRYPTOPP_CRC32_H
#define CRYPTOPP_CRC32_H
diff --git a/cryptlib.cpp b/cryptlib.cpp
index 4b950257..4fa36538 100644
--- a/cryptlib.cpp
+++ b/cryptlib.cpp
@@ -180,6 +180,10 @@ void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *IV)
size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const
{
+ assert(inBlocks);
+ assert(outBlocks);
+ assert(length);
+
size_t blockSize = BlockSize();
size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize;
size_t xorIncrement = xorBlocks ? blockSize : 0;
@@ -200,11 +204,20 @@ size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const by
{
if (flags & BT_XorInput)
{
+ // Coverity finding. However, xorBlocks is never NULL if BT_XorInput.
+ assert(xorBlocks);
+#if defined(__COVERITY__)
+ if (xorBlocks)
+#endif
xorbuf(outBlocks, xorBlocks, inBlocks, blockSize);
ProcessBlock(outBlocks);
}
else
+ {
+ // xorBlocks can be NULL. See, for example, ECB_OneWay::ProcessData.
ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks);
+ }
+
if (flags & BT_InBlockIsCounter)
const_cast<byte *>(inBlocks)[blockSize-1]++;
inBlocks += inIncrement;
@@ -344,16 +357,49 @@ void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransform
}
}
-//! see NullRNG()
+//! \class ClassNullRNG
+//! \brief Random Number Generator that does not produce random numbers
+//! \details ClassNullRNG can be used for functions that require a RandomNumberGenerator
+//! but don't actually use it. The class throws NotImplemented when a generation function is called.
+//! \sa NullRNG()
class ClassNullRNG : public RandomNumberGenerator
{
public:
+ //! \brief The name of the generator
+ //! \returns the string \a NullRNGs
std::string AlgorithmName() const {return "NullRNG";}
+
+#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
+ //! \brief An implementation that throws NotImplemented
+ byte GenerateByte () {}
+ //! \brief An implementation that throws NotImplemented
+ unsigned int GenerateBit () {}
+ //! \brief An implementation that throws NotImplemented
+ word32 GenerateWord32 (word32 min, word32 max) {}
+#endif
+
+ //! \brief An implementation that throws NotImplemented
void GenerateBlock(byte *output, size_t size)
{
CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size);
throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");
}
+
+#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
+ //! \brief An implementation that throws NotImplemented
+ void GenerateIntoBufferedTransformation (BufferedTransformation &target, const std::string &channel, lword length) {}
+ //! \brief An implementation that throws NotImplemented
+ void IncorporateEntropy (const byte *input, size_t length) {}
+ //! \brief An implementation that returns \p false
+ bool CanIncorporateEntropy () const {}
+ //! \brief An implementation that does nothing
+ void DiscardBytes (size_t n) {}
+ //! \brief An implementation that does nothing
+ void Shuffle (IT begin, IT end) {}
+
+private:
+ Clonable* Clone () const { return NULL; }
+#endif
};
RandomNumberGenerator & NullRNG()
diff --git a/cryptlib.h b/cryptlib.h
index cfac5684..f858af67 100644
--- a/cryptlib.h
+++ b/cryptlib.h
@@ -1,7 +1,7 @@
// cryptlib.h - written and placed in the public domain by Wei Dai
-//! \file
-//! Abstract base classes that provide a uniform interface to this library.
+//! \file cryptlib.h
+//! \brief Abstract base classes that provide a uniform interface to this library.
/*! \mainpage Crypto++ Library 5.6.3 API Reference
<dl>
@@ -12,13 +12,13 @@
<dt>Symmetric Ciphers<dd>
SymmetricCipherDocumentation
<dt>Hash Functions<dd>
- SHA1, SHA224, SHA256, SHA384, SHA512, Tiger, Whirlpool, RIPEMD160, RIPEMD320, RIPEMD128, RIPEMD256, Weak1::MD2, Weak1::MD4, Weak1::MD5
+ SHA1, SHA224, SHA256, SHA384, SHA512, Tiger, Whirlpool, RIPEMD160, RIPEMD320, RIPEMD128, RIPEMD256, Weak::MD2, Weak::MD4, Weak::MD5
<dt>Non-Cryptographic Checksums<dd>
CRC32, Adler32
<dt>Message Authentication Codes<dd>
VMAC, HMAC, CBC_MAC, CMAC, DMAC, TTMAC, GCM (GMAC)
<dt>Random Number Generators<dd>
- NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG, DefaultAutoSeededRNG
+ NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG
<dt>Key Derivation<dd>
HKDF
<dt>Password-based Cryptography<dd>
@@ -111,9 +111,9 @@ struct EnumToType
//! \brief Provides the byte ordering
enum ByteOrder {LITTLE_ENDIAN_ORDER = 0, BIG_ENDIAN_ORDER = 1};
-//! \typedef Provides a constant for \p LittleEndian
+//! \typedef Provides a constant for LittleEndian
typedef EnumToType<ByteOrder, LITTLE_ENDIAN_ORDER> LittleEndian;
-//! \typedef Provides a constant for \p BigEndian
+//! \typedef Provides a constant for BigEndian
typedef EnumToType<ByteOrder, BIG_ENDIAN_ORDER> BigEndian;
//! \class Exception
@@ -127,7 +127,7 @@ public:
NOT_IMPLEMENTED,
//! \brief An invalid argument was detected
INVALID_ARGUMENT,
- //! \brief \p BufferedTransformation received a Flush(true) signal but can't flush buffers
+ //! \brief BufferedTransformation received a Flush(true) signal but can't flush buffers
CANNOT_FLUSH,
//! \brief Data integerity check, such as CRC or MAC, failed
DATA_INTEGRITY_CHECK_FAILED,
@@ -139,15 +139,15 @@ public:
OTHER_ERROR
};
- //! \brief Construct a new \p Exception
+ //! \brief Construct a new Exception
explicit Exception(ErrorType errorType, const std::string &s) : m_errorType(errorType), m_what(s) {}
virtual ~Exception() throw() {}
//! \brief Retrieves a C-string describing the exception
const char *what() const throw() {return (m_what.c_str());}
- //! \brief Retrieves a \p string describing the exception
+ //! \brief Retrieves a string describing the exception
const std::string &GetWhat() const {return m_what;}
- //! \brief Sets the error \p string for the exception
+ //! \brief Sets the error string for the exception
void SetWhat(const std::string &s) {m_what = s;}
//! \brief Retrieves the error type for the exception
ErrorType GetErrorType() const {return m_errorType;}
@@ -216,12 +216,22 @@ protected:
//! \brief Returns a decoding results
struct CRYPTOPP_DLL DecodingResult
{
- //! \brief Constructs a \p DecodingResult
+ //! \brief Constructs a DecodingResult
+ //! \details isValidCoding is initialized to false and messageLength is initialized to 0.
explicit DecodingResult() : isValidCoding(false), messageLength(0) {}
- //! \brief Constructs a \p DecodingResult
+ //! \brief Constructs a DecodingResult
+ //! \param len the message length
+ //! \details isValidCoding is initialized to true.
explicit DecodingResult(size_t len) : isValidCoding(true), messageLength(len) {}
+ //! \brief Compare two DecodingResult
+ //! \param rhs the other DecodingResult
+ //! \returns true if both isValidCoding and messageLength are equal, false otherwise
bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;}
+ //! \brief Compare two DecodingResult
+ //! \param rhs the other DecodingResult
+ //! \returns true if both isValidCoding and messageLength are \a not equal, false otherwise
+ //! \details Returns <tt>!operator==(rhs)</tt>.
bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);}
bool isValidCoding;
@@ -239,10 +249,10 @@ struct CRYPTOPP_DLL DecodingResult
//! \details To obtain an object that implements NameValuePairs for the purpose of parameter
//! passing, use the MakeParameters() function.
//! \details To get a value from NameValuePairs, you need to know the name and the type of the value.
-//! Call \p GetValueNames on a NameValuePairs object to obtain a list of value names that it supports.
+//! Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports.
//! then look at the Name namespace documentation to see what the type of each value is, or
//! alternatively, call GetIntValue() with the value name, and if the type is not int, a
-//! \p ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object.
+//! ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object.
class CRYPTOPP_NO_VTABLE NameValuePairs
{
public:
@@ -293,11 +303,13 @@ public:
return GetValue((std::string("ThisPointer:")+typeid(T).name()).c_str(), ptr);
}
- //! \brief Get a named value, returns true if the name exists
+ //! \brief Get a named value
//! \tparam T class or type
//! \param name the name of the object or value to retrieve
//! \param value reference to a variable that receives the value
- //! \returns \p true if the value was retrieved, \p false otherwise
+ //! \returns true if the value was retrieved, false otherwise
+ //! \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
+ //! GetRequiredParameter() and GetRequiredIntParameter()
template <class T>
bool GetValue(const char *name, T &value) const
{
@@ -309,10 +321,15 @@ public:
//! \param name the name of the object or value to retrieve
//! \param defaultValue the default value of the class or type if it does not exist
//! \returns the object or value
+ //! \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
+ //! GetRequiredParameter() and GetRequiredIntParameter()
template <class T>
T GetValueWithDefault(const char *name, T defaultValue) const
{
- GetValue(name, defaultValue);
+ T value;
+ bool result = GetValue(name, value);
+ // No assert... this recovers from failure
+ if (result) {return value;}
return defaultValue;
}
@@ -325,15 +342,20 @@ public:
//! \brief Get a named value with type int
//! \param name the name of the value to retrieve
//! \param value the value retrieved upon success
- //! \details Used to ensure we don't accidentally try to get an unsigned int
- //! or some other type when we mean int (which is the most common case)
+ //! \returns true if an int value was retrieved, false otherwise
+ //! \details GetIntValue() is used to ensure we don't accidentally try to get an
+ //! unsigned int or some other type when we mean int (which is the most common case)
+ //! \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
+ //! GetRequiredParameter() and GetRequiredIntParameter()
CRYPTOPP_DLL bool GetIntValue(const char *name, int &value) const
{return GetValue(name, value);}
//! \brief Get a named value with type int, with default
//! \param name the name of the value to retrieve
//! \param defaultValue the default value if the name does not exist
- //! \returns the value retrieved or the default value
+ //! \returns the value retrieved on success or the default value
+ //! \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
+ //! GetRequiredParameter() and GetRequiredIntParameter()
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
{return GetValueWithDefault(name, defaultValue);}
@@ -342,8 +364,10 @@ public:
//! \param stored the type that was stored for the name
//! \param retrieving the type that is being retrieved for the name
//! \throws ValueTypeMismatch
- //! \details \p ThrowIfTypeMismatch() effectively performs a type safety check.
- //! \p stored and \p retrieving are C++ mangled names for the type.
+ //! \details ThrowIfTypeMismatch() effectively performs a type safety check.
+ //! stored and retrieving are C++ mangled names for the type.
+ //! \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
+ //! GetRequiredParameter() and GetRequiredIntParameter()
CRYPTOPP_DLL static void CRYPTOPP_API ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving)
{if (stored != retrieving) throw ValueTypeMismatch(name, stored, retrieving);}
@@ -353,8 +377,10 @@ public:
//! \param name the name of the value
//! \param value reference to a variable to receive the value
//! \throws InvalidArgument
- //! \details \p GetRequiredParameter() throws \p InvalidArgument if the \p name
- //! is not present or not of the expected type \p T.
+ //! \details GetRequiredParameter() throws InvalidArgument if the name
+ //! is not present or not of the expected type T.
+ //! \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
+ //! GetRequiredParameter() and GetRequiredIntParameter()
template <class T>
void GetRequiredParameter(const char *className, const char *name, T &value) const
{
@@ -367,32 +393,49 @@ public:
//! \param name the name of the value
//! \param value reference to a variable to receive the value
//! \throws InvalidArgument
- //! \details \p GetRequiredParameter() throws \p InvalidArgument if the \p name
- //! is not present or not of the expected type \p T.
+ //! \details GetRequiredParameter() throws InvalidArgument if the name
+ //! is not present or not of the expected type T.
+ //! \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
+ //! GetRequiredParameter() and GetRequiredIntParameter()
CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const
{
if (!GetIntValue(name, value))
throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'");
}
-
- //! to be implemented by derived classes, users should use one of the above functions instead
+
+ //! \brief Get a named value
+ //! \param name the name of the object or value to retrieve
+ //! \param valueType reference to a variable that receives the value
+ //! \param pValue void pointer to a variable that receives the value
+ //! \returns true if the value was retrieved, false otherwise
+ //! \details GetVoidValue() retrives the value of name if it exists.
+ //! \note GetVoidValue() is an internal function and should be implemented
+ //! by derived classes. Users should use one of the other functions instead.
+ //! \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
+ //! GetRequiredParameter() and GetRequiredIntParameter()
CRYPTOPP_DLL virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const =0;
};
-
-//! \brief Namespace containing value name definitions
-/*! \details value names, types and semantics:
- ThisObject:ClassName (ClassName, copy of this object or a subobject)
- ThisPointer:ClassName (const ClassName *, pointer to this object or a subobject)
-*/
+#if CRYPTOPP_DOXYGEN_PROCESSING
+
+//! \brief Namespace containing value name definitions.
+//! \details Name is part of the CryptoPP namespace.
+//! \details The semantics of value names, types are:
+//! <pre>
+//! ThisObject:ClassName (ClassName, copy of this object or a subobject)
+//! ThisPointer:ClassName (const ClassName *, pointer to this object or a subobject)
+//! </pre>
DOCUMENTED_NAMESPACE_BEGIN(Name)
// more names defined in argnames.h
DOCUMENTED_NAMESPACE_END
-//! \brief Namespace containing weak and wounded algorithms
+//! \brief Namespace containing weak and wounded algorithms.
+//! \details Weak is part of the CryptoPP namespace. Schemes and algorithms are moved into Weak
+//! when their security level is reduced to an unacceptable value by contemporary standards.
DOCUMENTED_NAMESPACE_BEGIN(Weak)
// weak and wounded algorithms
DOCUMENTED_NAMESPACE_END
+#endif
//! \brief An empty set of name-value pairs
extern CRYPTOPP_DLL const NameValuePairs &g_nullNameValuePairs;
@@ -402,15 +445,17 @@ extern CRYPTOPP_DLL const NameValuePairs &g_nullNameValuePairs;
//! \class Clonable
//! \brief Interface for cloning objects
//! \note this is \a not implemented by most classes
+//! \sa ClonableImpl, NotCopyable
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Clonable
{
public:
virtual ~Clonable() {}
- //! \brief Copies \p this object
+ //! \brief Copies this object
//! \returns a copy of this object
//! \throws NotImplemented
//! \note this is \a not implemented by most classes
+ //! \sa NotCopyable
virtual Clonable* Clone() const {throw NotImplemented("Clone() is not implemented yet.");} // TODO: make this =0
};
@@ -426,15 +471,15 @@ public:
//! this constructor throws SelfTestFailure if the self test hasn't been run or fails.
//! \details FIPS 140-2 compliance is disabled by default. It is only used by certain
//! versions of the library when the library is built as a DLL on Windows. Also see
- //! \p CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 in \headerfile config.h.
+ //! CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 in config.h.
Algorithm(bool checkSelfTestStatus = true);
//! \brief Provides the name of this algorithm
//! \returns the standard algorithm name
//! \details The standard algorithm name can be a name like \a AES or \a AES/GCM. Some algorithms
//! do not have standard names yet. For example, there is no standard algorithm name for
- //! Shoup's \p ECIES.
- //! \note \p AlgorithmName is not universally implemented yet
+ //! Shoup's ECIES.
+ //! \note AlgorithmName is not universally implemented yet
virtual std::string AlgorithmName() const {return "unknown";}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
@@ -460,8 +505,8 @@ public:
//! \returns the smallest valid key length in bytes that is greater than or equal to <tt>min(n, GetMaxKeyLength())</tt>
virtual size_t GetValidKeyLength(size_t n) const =0;
- //! \brief Returns whether \p keylength is a valid key length
- //! \details Internally the function calls \p GetValidKeyLength()
+ //! \brief Returns whether keylength is a valid key length
+ //! \details Internally the function calls GetValidKeyLength()
virtual bool IsValidKeyLength(size_t keylength) const
{return keylength == GetValidKeyLength(keylength);}
@@ -477,8 +522,8 @@ public:
//! \param length the size of the key, in bytes
//! \param rounds the number of rounds to apply the transformation function,
//! if applicable
- //! \details \p SetKeyWithRounds calls \p SetKey with an \p NameValuePairs
- //! object that just specifies \p rounds. \p rounds is an integer parameter,
+ //! \details SetKeyWithRounds calls SetKey with an NameValuePairs
+ //! object that just specifies rounds. rounds is an integer parameter,
//! and <tt>-1</tt> means use the default number of rounds.
void SetKeyWithRounds(const byte *key, size_t length, int rounds);
@@ -487,17 +532,17 @@ public:
//! \param length the size of the key, in bytes
//! \param iv the intiialization vector to use when keying the object
//! \param ivLength the size of the iv, in bytes
- //! \details \p SetKeyWithIV calls \p SetKey with an \p NameValuePairs object
- //! that just specifies \p iv. \p iv is a \p byte array with size \p ivLength.
+ //! \details SetKeyWithIV calls SetKey with an NameValuePairs object
+ //! that just specifies iv. iv is a byte buffer with size ivLength.
void SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength);
//! \brief Sets or reset the key of this object
//! \param key the key to use when keying the object
//! \param length the size of the key, in bytes
//! \param iv the intiialization vector to use when keying the object
- //! \details \p SetKeyWithIV calls \p SetKey with an \p NameValuePairs object
- //! that just specifies \p iv. \p iv is a \p byte array, and it must have
- //! a size \p IVSize.
+ //! \details SetKeyWithIV calls SetKey with an NameValuePairs object
+ //! that just specifies iv. iv is a byte buffer, and it must have
+ //! a size IVSize.
void SetKeyWithIV(const byte *key, size_t length, const byte *iv)
{SetKeyWithIV(key, length, iv, IVSize());}
@@ -529,7 +574,7 @@ public:
bool CanUseStructuredIVs() const {return IVRequirement() <= UNIQUE_IV;}
//! \brief Returns length of the IV accepted by this object
- //! \details The default implementation throws \p NotImplemented
+ //! \details The default implementation throws NotImplemented
virtual unsigned int IVSize() const
{throw NotImplemented(GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");}
//! returns default length of IVs accepted by this object
@@ -545,25 +590,25 @@ public:
}
//! \brief Gets a secure IV for the next message
- //! \param rng a \p RandomNumberGenerator to produce keying material
+ //! \param rng a RandomNumberGenerator to produce keying material
//! \param iv a block of bytes to receive the IV
//! \details This method should be called after you finish encrypting one message and are ready
- //! to start the next one. After calling it, you must call \p SetKey() or \p Resynchronize()
+ //! to start the next one. After calling it, you must call SetKey() or Resynchronize()
//! before using this object again.
- //! \details \p key must be at least \p IVSize() in length.
+ //! \details key must be at least IVSize() in length.
//! \note This method is not implemented on decryption objects.
virtual void GetNextIV(RandomNumberGenerator &rng, byte *iv);
protected:
- //! \brief Returns the base class \p Algorithm
- //! \returns the base class \p Algorithm
+ //! \brief Returns the base class Algorithm
+ //! \returns the base class Algorithm
virtual const Algorithm & GetAlgorithm() const =0;
//! \brief Sets the key for this object without performing parameter validation
- //! \param key a byte array used to key the cipher
- //! \param length the length of the byte array
- //! \param params additional parameters passed as \p NameValuePairs
- //! \details \p key must be at least \p DEFAULT_KEYLENGTH in length.
+ //! \param key a byte buffer used to key the cipher
+ //! \param length the length of the byte buffer
+ //! \param params additional parameters passed as NameValuePairs
+ //! \details key must be at least DEFAULT_KEYLENGTH in length.
virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params) =0;
//! \brief Validates the key length
@@ -573,30 +618,30 @@ protected:
//! \brief Validates the object
//! \throws InvalidArgument if the IV is present
- //! \details Internally, the default implementation calls \p IsResynchronizable() and throws
- //! \p InvalidArgument if the function returns \p true.
+ //! \details Internally, the default implementation calls IsResynchronizable() and throws
+ //! InvalidArgument if the function returns true.
//! \note called when no IV is passed
void ThrowIfResynchronizable();
//! \brief Validates the IV
- //! \param iv the IV with a length of \p IVSize, in bytes
+ //! \param iv the IV with a length of IVSize, in bytes
//! \throws InvalidArgument on failure
- //! \details Internally, the default implementation checks the \p iv. If \p iv is not \p NULL,
- //! then the function succeeds. If \p iv is \p NULL, then \p IVRequirement is checked against
- //! \p UNPREDICTABLE_RANDOM_IV. If \p IVRequirement is \p UNPREDICTABLE_RANDOM_IV, then
+ //! \details Internally, the default implementation checks the iv. If iv is not NULL,
+ //! then the function succeeds. If iv is NULL, then IVRequirement is checked against
+ //! UNPREDICTABLE_RANDOM_IV. If IVRequirement is UNPREDICTABLE_RANDOM_IV, then
//! then the function succeeds. Otherwise, an exception is thrown.
void ThrowIfInvalidIV(const byte *iv);
//! \brief Validates the IV length
//! \param length the size of the IV, in bytes
- //! \throws InvalidArgument if the number of \p rounds are invalid
+ //! \throws InvalidArgument if the number of rounds are invalid
size_t ThrowIfInvalidIVLength(int length);
//! \brief retrieves and validates the IV
- //! \param params \p NameValuePairs with the IV supplied as a \p ConstByteArrayParameter
+ //! \param params NameValuePairs with the IV supplied as a ConstByteArrayParameter
//! \param size the length of the IV, in bytes
- //! \returns a pointer to the first byte of the \p IV
- //! \throws InvalidArgument if the number of \p rounds are invalid
+ //! \returns a pointer to the first byte of the IV
+ //! \throws InvalidArgument if the number of rounds are invalid
const byte * GetIVAndThrowIfInvalid(const NameValuePairs &params, size_t &size);
//! \brief Validates the key length
@@ -606,48 +651,89 @@ protected:
};
//! \brief Interface for the data processing part of block ciphers
-
-/*! Classes derived from BlockTransformation are block ciphers
- in ECB mode (for example the DES::Encryption class), which are stateless.
- These classes should not be used directly, but only in combination with
- a mode class (see CipherModeDocumentation in modes.h).
-*/
+//! \details Classes derived from BlockTransformation are block ciphers
+//! in ECB mode (for example the DES::Encryption class), which are stateless.
+//! These classes should not be used directly, but only in combination with
+//! a mode class (see CipherModeDocumentation in modes.h).
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockTransformation : public Algorithm
{
public:
- //! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock
+ //! \brief Encrypt or decrypt a block
+ //! \param inBlock the input message before processing
+ //! \param outBlock the output message after processing
+ //! \param xorBlock an optional XOR mask
+ //! \details ProcessAndXorBlock encrypts or decrypts inBlock, xor with xorBlock, and write to outBlock.
+ //! \details The size of the block is determined by the block cipher and its documentation. Use
+ //! BLOCKSIZE at compile time, or BlockSize() at runtime.
+ //! \note The message can be transformed in-place, or the buffers must \a not overlap
+ //! \sa FixedBlockSize, BlockCipherFinal from seckey.h and BlockSize()
virtual void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const =0;
- //! encrypt or decrypt one block
- /*! \pre size of inBlock and outBlock == BlockSize() */
+ //! \brief Encrypt or decrypt a block
+ //! \param inBlock the input message before processing
+ //! \param outBlock the output message after processing
+ //! \details ProcessBlock encrypts or decrypts inBlock and write to outBlock.
+ //! \details The size of the block is determined by the block cipher and its documentation.
+ //! Use BLOCKSIZE at compile time, or BlockSize() at runtime.
+ //! \sa FixedBlockSize, BlockCipherFinal from seckey.h and BlockSize()
+ //! \note The message can be transformed in-place, or the buffers must \a not overlap
void ProcessBlock(const byte *inBlock, byte *outBlock) const
{ProcessAndXorBlock(inBlock, NULL, outBlock);}
- //! encrypt or decrypt one block in place
+ //! \brief Encrypt or decrypt a block in place
+ //! \param inoutBlock the input message before processing
+ //! \details ProcessBlock encrypts or decrypts inoutBlock in-place.
+ //! \details The size of the block is determined by the block cipher and its documentation.
+ //! Use BLOCKSIZE at compile time, or BlockSize() at runtime.
+ //! \sa FixedBlockSize, BlockCipherFinal from seckey.h and BlockSize()
void ProcessBlock(byte *inoutBlock) const
{ProcessAndXorBlock(inoutBlock, NULL, inoutBlock);}
- //! block size of the cipher in bytes
+ //! Provides the block size of the cipher
+ //! \returns the block size of the cipher, in bytes
virtual unsigned int BlockSize() const =0;
- //! returns how inputs and outputs should be aligned for optimal performance
+ //! \brief Provides input and output data alignment for optimal performance.
+ //! \returns the input data alignment that provides optimal performance
virtual unsigned int OptimalDataAlignment() const;
//! returns true if this is a permutation (i.e. there is an inverse transformation)
virtual bool IsPermutation() const {return true;}
- //! returns true if this is an encryption object
+ //! \brief Determines if the cipher is being operated in its forward direction
+ //! \returns true if DIR is ENCRYPTION, false otherwise
+ //! \sa IsForwardTransformation(), IsPermutation(), GetCipherDirection()
virtual bool IsForwardTransformation() const =0;
- //! return number of blocks that can be processed in parallel, for bit-slicing implementations
+ //! \brief Determines the number of blocks that can be processed in parallel
+ //! \return the number of blocks that can be processed in parallel, for bit-slicing implementations
+ //! \details Bit-slicing is often used to improve throughput and minimize timing attacks.
virtual unsigned int OptimalNumberOfParallelBlocks() const {return 1;}
- enum {BT_InBlockIsCounter=1, BT_DontIncrementInOutPointers=2, BT_XorInput=4, BT_ReverseDirection=8, BT_AllowParallel=16} FlagsForAdvancedProcessBlocks;
-
- //! encrypt and xor blocks according to flags (see FlagsForAdvancedProcessBlocks)
- /*! /note If BT_InBlockIsCounter is set, then the last byte of inBlocks may be modified. */
+ //! \brief Bit flags that control AdvancedProcessBlocks() behavior
+ enum FlagsForAdvancedProcessBlocks {
+ //! \brief inBlock is a counter
+ BT_InBlockIsCounter=1,
+ //! \brief should not modify block pointers
+ BT_DontIncrementInOutPointers=2,
+ //! \brief
+ BT_XorInput=4,
+ //! \brief perform the transformation in reverse
+ BT_ReverseDirection=8,
+ //! \brief
+ BT_AllowParallel=16};
+
+ //! \brief Encrypt and xor multiple blocks using additional flags
+ //! \param inBlocks the input message before processing
+ //! \param xorBlocks an optional XOR mask
+ //! \param outBlocks the output message after processing
+ //! \param length the size of the blocks, in bytes
+ //! \param flags additional flags to control processing
+ //! \details Encrypt and xor multiple blocks according to FlagsForAdvancedProcessBlocks flags.
+ //! \note If BT_InBlockIsCounter is set, then the last byte of inBlocks may be modified.
virtual size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
+ //! \sa IsForwardTransformation(), IsPermutation(), GetCipherDirection()
inline CipherDir GetCipherDirection() const {return IsForwardTransformation() ? ENCRYPTION : DECRYPTION;}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
@@ -655,59 +741,100 @@ public:
#endif
};
+//! \class StreamTransformation
//! \brief Interface for the data processing portion of stream ciphers
+//! \sa StreamTransformationFilter()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE StreamTransformation : public Algorithm
{
public:
- //! \brief Return a reference to this object
+ //! \brief Provides a reference to this object
+ //! \returns A reference to this object
//! \details Useful for passing a temporary object to a function that takes a non-const reference
StreamTransformation& Ref() {return *this;}
- //! \brief returns block size, if input must be processed in blocks, otherwise 1
+ //! \brief Provides the mandatory block size of the cipher
+ //! \returns The block size of the cipher if input must be processed in blocks, 1 otherwise
virtual unsigned int MandatoryBlockSize() const {return 1;}
- //! \brief returns the input block size that is most efficient for this cipher
- /*! \note optimal input length is n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n > 0 */
+ //! \brief Provides the input block size most efficient for this cipher.
+ //! \returns The input block size that is most efficient for the cipher
+ //! \details The base class implemnetation returns MandatoryBlockSize().
+ //! \note Optimal input length is
+ //! <tt>n * OptimalBlockSize() - GetOptimalBlockSizeUsed()</tt> for any <tt>n \> 0</tt>.
virtual unsigned int OptimalBlockSize() const {return MandatoryBlockSize();}
- //! \brief returns how much of the current block is used up
+
+ //! \brief Provides the number of bytes used in the current block when processing at optimal block size.
+ //! \returns the number of bytes used in the current block when processing at the optimal block size
virtual unsigned int GetOptimalBlockSizeUsed() const {return 0;}
-
- //! \brief returns how input should be aligned for optimal performance
+
+ //! \brief Provides input and output data alignment for optimal performance.
+ //! \returns the input data alignment that provides optimal performance
virtual unsigned int OptimalDataAlignment() const;
- //! \brief encrypt or decrypt an array of bytes of specified length
- //! \note either inString == outString, or they don't overlap
+ //! \brief Encrypt or decrypt an array of bytes
+ //! \param outString the output byte buffer
+ //! \param inString the input byte buffer
+ //! \param length the size of the input and output byte buffers, in bytes
+ //! \details Either <tt>inString == outString</tt>, or they must not overlap.
virtual void ProcessData(byte *outString, const byte *inString, size_t length) =0;
- //! \brief Encrypt or decrypt the last block of data for ciphers where the last block of data is special
- //! For now the only use of this function is for CBC-CTS mode.
+ //! \brief Encrypt or decrypt the last block of data
+ //! \param outString the output byte buffer
+ //! \param inString the input byte buffer
+ //! \param length the size of the input and output byte buffers, in bytes
+ //! ProcessLastBlock is used when the last block of data is special.
+ //! Currently the only use of this function is CBC-CTS mode.
virtual void ProcessLastBlock(byte *outString, const byte *inString, size_t length);
+
//! returns the minimum size of the last block, 0 indicating the last block is not special
virtual unsigned int MinLastBlockSize() const {return 0;}
- //! same as ProcessData(inoutString, inoutString, length)
+ //! \brief Encrypt or decrypt a string of bytes
+ //! \param inoutString the string to process
+ //! \param length the size of the inoutString, in bytes
+ //! \details Internally, the base class implementation calls ProcessData().
inline void ProcessString(byte *inoutString, size_t length)
{ProcessData(inoutString, inoutString, length);}
- //! same as ProcessData(outString, inString, length)
+
+ //! \brief Encrypt or decrypt a string of bytes
+ //! \param outString the output string to process
+ //! \param inString the input string to process
+ //! \param length the size of the input and output strings, in bytes
+ //! \details Internally, the base class implementation calls ProcessData().
inline void ProcessString(byte *outString, const byte *inString, size_t length)
{ProcessData(outString, inString, length);}
- //! implemented as {ProcessData(&input, &input, 1); return input;}
+
+ //! \brief Encrypt or decrypt a byte
+ //! \param input the input byte to process
+ //! \details Internally, the base class implementation calls ProcessData() with a size of 1.
inline byte ProcessByte(byte input)
{ProcessData(&input, &input, 1); return input;}
- //! returns whether this cipher supports random access
+ //! \brief Determines whether the cipher supports random access
+ //! \returns true if the cipher supports random access, false otherwise
virtual bool IsRandomAccess() const =0;
- //! for random access ciphers, seek to an absolute position
- virtual void Seek(lword n)
+
+ //! \brief Seek to an absolute position
+ //! \param pos position to seek
+ //! \throws NotImplemented
+ //! \details The base class implementation throws NotImplemented. The function
+ //! asserts IsRandomAccess() in debug builds.
+ virtual void Seek(lword pos)
{
- CRYPTOPP_UNUSED(n);
+ CRYPTOPP_UNUSED(pos);
assert(!IsRandomAccess());
throw NotImplemented("StreamTransformation: this object doesn't support random access");
}
- //! returns whether this transformation is self-inverting (e.g. xor with a keystream)
+ //! \brief Determines whether the cipher is self-inverting
+ //! \returns true if the cipher is self-inverting, false otherwise
+ //! \details IsSelfInverting determines whether this transformation is
+ //! self-inverting (e.g. xor with a keystream).
virtual bool IsSelfInverting() const =0;
- //! returns whether this is an encryption object
+
+ //! \brief Determines if the cipher is being operated in its forward direction
+ //! \returns true if DIR is ENCRYPTION, false otherwise
+ //! \sa IsForwardTransformation(), IsPermutation(), GetCipherDirection()
virtual bool IsForwardTransformation() const =0;
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
@@ -715,76 +842,153 @@ public:
#endif
};
+//! \class HashTransformation
//! \brief Interface for hash functions and data processing part of MACs
-/*! HashTransformation objects are stateful. They are created in an initial state,
- change state as Update() is called, and return to the initial
- state when Final() is called. This interface allows a large message to
- be hashed in pieces by calling Update() on each piece followed by
- calling Final().
-*/
+//! \details HashTransformation objects are stateful. They are created in an initial state,
+//! change state as Update() is called, and return to the initial
+//! state when Final() is called. This interface allows a large message to
+//! be hashed in pieces by calling Update() on each piece followed by
+//! calling Final().
+//! \sa HashFilter(), HashVerificationFilter()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HashTransformation : public Algorithm
{
public:
- //! \brief Return a reference to this object
+ //! \brief Provides a reference to this object
+ //! \returns A reference to this object
//! \details Useful for passing a temporary object to a function that takes a non-const reference
HashTransformation& Ref() {return *this;}
- //! process more input
+ //! \brief Updates a hash with additional input
+ //! \param input the additional input as a buffer
+ //! \param length the size of the buffer, in bytes
virtual void Update(const byte *input, size_t length) =0;
- //! request space to write input into
+ //! \brief Request space which can be written into by the caller
+ //! \param size the requested size of the buffer
+ //! \details The purpose of this method is to help avoid extra memory allocations.
+ //! \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made,
+ //! size is the requested size of the buffer. When the call returns, size is the size of
+ //! the array returned to the caller.
+ //! \details The base class implementation sets size to 0 and returns NULL.
+ //! \note Some objects, like ArraySink, cannot create a space because its fixed. In the case of
virtual byte * CreateUpdateSpace(size_t &size) {size=0; return NULL;}
- //! compute hash for current message, then restart for a new message
- /*! \pre size of digest == DigestSize(). */
+ //! \brief Computes the hash of the current message
+ //! \param digest a pointer to the buffer to receive the hash
+ //! \details digest must be equal to (or greater than) DigestSize(). Final() restarts the
+ //! hash for a new message.
virtual void Final(byte *digest)
{TruncatedFinal(digest, DigestSize());}
- //! discard the current state, and restart with a new message
+ //! \brief Restart the hash
+ //! \details Discards the current state, and restart for a new message
virtual void Restart()
{TruncatedFinal(NULL, 0);}
- //! size of the hash/digest/MAC returned by Final()
+ //! Provides the digest size of the hash
+ //! \returns the digest size of the hash.
+ //! \details Calls to Final() require a buffer that is equal to (or greater than) DigestSize().
virtual unsigned int DigestSize() const =0;
- //! same as DigestSize()
+ //! Provides the tag size of the hash
+ //! \returns the tag size of the hash.
+ //! \details Same as DigestSize().
unsigned int TagSize() const {return DigestSize();}
-
-
- //! block size of underlying compression function, or 0 if not block based
+
+ //! \brief Provides the block size of the compression function
+ //! \returns the block size of the compression function, in bytes
+ //! \details BlockSize() will return 0 if the hash is not block based. For example,
+ //! SHA3 is a recursive hash (not an iterative hash), and it does not have a block size.
virtual unsigned int BlockSize() const {return 0;}
- //! input to Update() should have length a multiple of this for optimal speed
+ //! \brief Provides the input block size most efficient for this hash.
+ //! \returns The input block size that is most efficient for the cipher
+ //! \details The base class implemnetation returns MandatoryBlockSize().
+ //! \note Optimal input length is
+ //! <tt>n * OptimalBlockSize() - GetOptimalBlockSizeUsed()</tt> for any <tt>n \> 0</tt>.
virtual unsigned int OptimalBlockSize() const {return 1;}
- //! returns how input should be aligned for optimal performance
+ //! \brief Provides input and output data alignment for optimal performance
+ //! \returns the input data alignment that provides optimal performance
virtual unsigned int OptimalDataAlignment() const;
-
- //! use this if your input is in one piece and you don't want to call Update() and Final() separately
+
+ //! \brief Updates the hash with additional input and computes the hash of the current message
+ //! \param digest a pointer to the buffer to receive the hash
+ //! \param input the additional input as a buffer
+ //! \param length the size of the buffer, in bytes
+ //! \details Use this if your input is in one piece and you don't want to call Update()
+ //! and Final() separately
+ //! \details CalculateDigest() restarts the hash for the next nmessage.
virtual void CalculateDigest(byte *digest, const byte *input, size_t length)
{Update(input, length); Final(digest);}
-
- //! verify that digest is a valid digest for the current message, then reinitialize the object
- /*! Default implementation is to call Final() and do a bitwise comparison
- between its output and digest. */
+
+ //! \brief Verifies the hash of the current message
+ //! \param digest a pointer to the buffer of an \a existing hash
+ //! \returns \p true if the existing hash matches the computed hash, \p false otherwise
+ //! \throws ThrowIfInvalidTruncatedSize() if the existing hash's size exceeds DigestSize()
+ //! \details Calls to Verify() require a buffer that is equal to (or greater than) DigestSize().
+ //! \details Verify() performs a bitwise compare on the buffers using VerifyBufsEqual(), which is
+ //! a constant time comparison function. digestLength cannot exceed DigestSize().
+ //! \details Verify() restarts the hash for the next nmessage.
virtual bool Verify(const byte *digest)
{return TruncatedVerify(digest, DigestSize());}
- //! use this if your input is in one piece and you don't want to call Update() and Verify() separately
+ //! \brief Updates the hash with additional input and verifies the hash of the current message
+ //! \param digest a pointer to the buffer of an \a existing hash
+ //! \param input the additional input as a buffer
+ //! \param length the size of the buffer, in bytes
+ //! \returns \p true if the existing hash matches the computed hash, \p false otherwise
+ //! \throws ThrowIfInvalidTruncatedSize() if the existing hash's size exceeds DigestSize()
+ //! \details Use this if your input is in one piece and you don't want to call Update()
+ //! and Verify() separately
+ //! \details VerifyDigest() performs a bitwise compare on the buffers using VerifyBufsEqual(),
+ //! which is a constant time comparison function. digestLength cannot exceed DigestSize().
+ //! \details VerifyDigest() restarts the hash for the next nmessage.
virtual bool VerifyDigest(const byte *digest, const byte *input, size_t length)
{Update(input, length); return Verify(digest);}
- //! truncated version of Final()
+ //! \brief Computes the hash of the current message
+ //! \param digest a pointer to the buffer to receive the hash
+ //! \param digestSize the size of the truncated digest, in bytes
+ //! \details TruncatedFinal() call Final() and then copies digestSize bytes to digest
+ //! \details TruncatedFinal() restarts the hash for the next nmessage.
virtual void TruncatedFinal(byte *digest, size_t digestSize) =0;
- //! truncated version of CalculateDigest()
+ //! \brief Updates the hash with additional input and computes the hash of the current message
+ //! \param digest a pointer to the buffer to receive the hash
+ //! \param digestSize the length of the truncated hash, in bytes
+ //! \param input the additional input as a buffer
+ //! \param length the size of the buffer, in bytes
+ //! \details Use this if your input is in one piece and you don't want to call Update()
+ //! and CalculateDigest() separately.
+ //! \details CalculateTruncatedDigest() restarts the hash for the next nmessage.
virtual void CalculateTruncatedDigest(byte *digest, size_t digestSize, const byte *input, size_t length)
{Update(input, length); TruncatedFinal(digest, digestSize);}
- //! truncated version of Verify()
+ //! \brief Verifies the hash of the current message
+ //! \param digest a pointer to the buffer of an \a existing hash
+ //! \param digestLength the size of the truncated hash, in bytes
+ //! \returns \p true if the existing hash matches the computed hash, \p false otherwise
+ //! \throws ThrowIfInvalidTruncatedSize() if digestLength exceeds DigestSize()
+ //! \details TruncatedVerify() is a truncated version of Verify(). It can operate on a
+ //! buffer smaller than DigestSize(). However, digestLength cannot exceed DigestSize().
+ //! \details Verify() performs a bitwise compare on the buffers using VerifyBufsEqual(), which is
+ //! a constant time comparison function. digestLength cannot exceed DigestSize().
+ //! \details TruncatedVerify() restarts the hash for the next nmessage.
virtual bool TruncatedVerify(const byte *digest, size_t digestLength);
- //! truncated version of VerifyDigest()
+ //! \brief Updates the hash with additional input and verifies the hash of the current message
+ //! \param digest a pointer to the buffer of an \a existing hash
+ //! \param digestLength the size of the truncated hash, in bytes
+ //! \param input the additional input as a buffer
+ //! \param length the size of the buffer, in bytes
+ //! \returns \p true if the existing hash matches the computed hash, \p false otherwise
+ //! \throws ThrowIfInvalidTruncatedSize() if digestLength exceeds DigestSize()
+ //! \details Use this if your input is in one piece and you don't want to call Update()
+ //! and TruncatedVerify() separately.
+ //! \details VerifyTruncatedDigest() is a truncated version of VerifyDigest(). It can operate
+ //! on a buffer smaller than DigestSize(). However, digestLength cannot exceed DigestSize().
+ //! \details VerifyTruncatedDigest() restarts the hash for the next nmessage.
virtual bool VerifyTruncatedDigest(const byte *digest, size_t digestLength, const byte *input, size_t length)
{Update(input, length); return TruncatedVerify(digest, digestLength);}
@@ -793,6 +997,7 @@ public:
#endif
protected:
+ //! \brief Exception thrown when the truncated digest size is greater than DigestSize()
void ThrowIfInvalidTruncatedSize(size_t size) const;
};
@@ -820,7 +1025,7 @@ protected:
const Algorithm & GetAlgorithm() const {return *this;}
};
-//! \brief Interface for for one direction (encryption or decryption) of a stream cipher or block cipher mode with authentication
+//! \brief Interface for one direction (encryption or decryption) of a stream cipher or block cipher mode with authentication
/*! The StreamTransformation part of this interface is used to encrypt/decrypt the data, and the MessageAuthenticationCode part of this
interface is used to input additional authenticated data (AAD, which is MAC'ed but not encrypted), and to generate/verify the MAC. */
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipher : public MessageAuthenticationCode, public StreamTransformation
@@ -879,10 +1084,10 @@ public:
//! \param input the entropy to add to the generator
//! \param length the size of the input buffer
//! \throws NotImplemented
- //! \details A generator may or may not accept additional entropy. Call \p CanIncorporateEntropy to test for the
+ //! \details A generator may or may not accept additional entropy. Call CanIncorporateEntropy to test for the
//! ability to use additional entropy.
- //! \details If a derived class does not override \p IncorporateEntropy, then the base class throws
- //! \p NotImplemented.
+ //! \details If a derived class does not override IncorporateEntropy, then the base class throws
+ //! NotImplemented.
virtual void IncorporateEntropy(const byte *input, size_t length)
{
CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length);
@@ -906,28 +1111,28 @@ public:
//! \param min the lower bound of the range
//! \param max the upper bound of the range
//! \returns a random 32-bit word
- //! \details The default implementation calls \p Crop on the difference between \p max and
- //! \p min, and then returns the result added to \p min.
- virtual word32 GenerateWord32(word32 min=0, word32 max=0xffffffffL);
+ //! \details The default implementation calls Crop on the difference between max and
+ //! min, and then returns the result added to min.
+ virtual word32 GenerateWord32(word32 min=0, word32 max=0xffffffffUL);
//! \brief Generate random array of bytes
//! \param output the byte buffer
//! \param size the length of the buffer, in bytes
- //! \note A derived generator \a must override either \p GenerateBlock or
- //! \p GenerateIntoBufferedTransformation. They can override both, or have one call the other.
+ //! \note A derived generator \a must override either GenerateBlock or
+ //! GenerateIntoBufferedTransformation. They can override both, or have one call the other.
virtual void GenerateBlock(byte *output, size_t size);
//! \brief Generate random bytes into a BufferedTransformation
//! \param target the BufferedTransformation object which receives the bytes
//! \param channel the channel on which the bytes should be pumped
//! \param length the number of bytes to generate
- //! \details The default implementation calls \p GenerateBlock() and pumps the result into
- //! the \p DEFAULT_CHANNEL of the target.
- //! \note A derived generator \a must override either \p GenerateBlock or
- //! \p GenerateIntoBufferedTransformation. They can override both, or have one call the other.
+ //! \details The default implementation calls GenerateBlock() and pumps the result into
+ //! the DEFAULT_CHANNEL of the target.
+ //! \note A derived generator \a must override either GenerateBlock or
+ //! GenerateIntoBufferedTransformation. They can override both, or have one call the other.
virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length);
- //! \brief Generate and discard \p n bytes
+ //! \brief Generate and discard n bytes
//! \param n the number of bytes to generate and discard
virtual void DiscardBytes(size_t n);
@@ -955,98 +1160,14 @@ public:
#endif
};
-//! returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it
+//! \brief Random Number Generator that does not produce random numbers
+//! \returns reference that can be passed to functions that require a RandomNumberGenerator
+//! \details NullRNG() returns a reference that can be passed to functions that require a
+//! RandomNumberGenerator but don't actually use it. The NullRNG() throws NotImplemented
+//! when a generation function is called.
+//! \sa ClassNullRNG
CRYPTOPP_DLL RandomNumberGenerator & CRYPTOPP_API NullRNG();
-//! \brief Interface for checking device state
-//! \details Generally speaking, this class attempts to provide four states: (1) not available/not present,
-//! (2) available/present, (3) offline/not ready, and (4) online/ready.
-//! If a device is Available, then it generally means its present at the time of the call. For example,
-//! a 2012 Ivy Bridge processor will return \a Available for RDRAND, and a Broadwell processor will return
-//! \a Available for and RDSEED.
-//! \details If a device is Not Available, then it could be missing. For example, RDRAND and RDSEED are not
-//! present on a 2000 era X86 CPU, so it should never be Available. Or a Smartcard or YubiKey may not be
-//! plugged into a computer.
-//! \details If a device is Ready, then it can service requests at the time of the call. For example, a
-//! 2012 Ivy Bridge processor will return \a Ready for RDRAND, and a Broadwell processor will return
-//! \a Ready for and RDSEED.
-//! \details If a device is Not Ready, then it could uninitialized or locked. For example, a Smartcard or YubiKey
-//! may be present but unitiialized or locked. The device may be waiting on a driver to be installed,
-//! may be waiting to be intialized, or may be waiting for a PIN or Passcode to unlock it, etc.
-//! \details Ready should always follow Available; however, the converse is not true. That is, a device that
-//! is Not Ready does not mean that its Not Available. Not Ready only indicates the device is offline
-//! at the time of the call.
-//! \details A not-so-apparent use case is a software implementation. For example, you can have a Crypto++
-//! wrapper around Microsoft's CryptoNG or Apple's CommonCrypto for FIPS 140-2 validated cryptography.
-//! The \p DeviceState could provide the standard interface to query the relevant Crypto++ implementation
-//! for the feature.
-class CRYPTOPP_NO_VTABLE DeviceState
-{
-public:
- //! \enum State
- //! \brief Enumeration of potential device states.
- //! \details The library reserves the lower 8 bits. Derived classes are free to use the 24 unallocated bits.
- enum State {
- //! \brief the device is available or present
- AVAILABLE = 1,
- //! \brief the device is available or present
- PRESENT = 1,
- //! \brief the device is ready or online
- READY = 2,
- //! \brief the device is ready or online
- ONLINE = 2,
- //! \brief mask for Available and Ready bits
- AR_MASK = 0x3,
- //! \brief mask for bits reserved by the library
- LIB_MASK= 0xff,
- //! \brief mask for bits available for derived classes
- USER_MASK = 0xffffff00
- };
-
- //! \var NO_EXTENDED_INFO
- //! \brief Distinguished value to indicate \p extendedInfo is not available
- //! \details The value is \a not -1 to avoid conflicts with user values.
- static const word64 NO_EXTENDED_INFO;
-
- //! \fn virtual bool Available(word64& extendedInfo) const
- //! \brief Determines the availability of a device.
- //! \param extendedInfo extended information for Availability status, if available.
- //! \returns true if the device is present at the time of the call, false otherwise.
- //! \details Derived classes can set \p extendedInfo to a meaningful code. There's no
- //! guarantee a derived class will set it for either success and failure. Derived
- //! classes should set \p extendedInfo to \p NO_EXTENDED_INFO if its not available.
- //! \details Must be implemented by derived classes. See the class documentation for
- //! \p DeviceState for semantics.
- virtual bool Available(word64& extendedInfo) const = 0;
-
- //! \fn virtual bool Available() const
- //! \brief Determines the availability of a device.
- //! \returns true if the device is present at the time of the call, false otherwise.
- //! \details Must be implemented by derived classes. See the class documentation for
- //! \p DeviceState for semantics.
- virtual bool Available() const = 0;
-
- //! \fn virtual bool Ready(word64& extendedInfo) const
- //! \brief Determines the readiness of a device.
- //! \param extendedInfo extended information for Ready status, if available.
- //! \returns true if the device can service a request at the time of the call, false otherwise.
- //! \details Derived classes can set \p extendedInfo to a meaningful code. There's no guarantee
- //! a derived class will set it for either success and failure. Derived classes should set
- //! \p extendedInfo to \p NO_EXTENDED_INFO if its not available.
- //! \details Must be implemented by derived classes. See the class documentation for
- //! \p DeviceState for semantics.
- virtual bool Ready(word64& extendedInfo) const = 0;
-
- //! \fn virtual bool Ready() const
- //! \brief Determines the readiness of a device.
- //! \returns true if the device can service a request at the time of the call, false otherwise.
- //! \details Must be implemented by derived classes. See the class documentation for
- //! \p DeviceState for semantics.
- virtual bool Ready() const = 0;
-
- virtual ~DeviceState() {}
-};
-
//! \class WaitObjectContainer
class WaitObjectContainer;
//! \class CallStack
@@ -1063,10 +1184,10 @@ public:
//! \brief Retrieves waitable objects
//! \param container the wait container to receive the references to the objects.
- //! \param callStack \p CallStack object used to select waitable objects
- //! \details \p GetWaitObjects is usually called in one of two ways. First, it can
+ //! \param callStack CallStack object used to select waitable objects
+ //! \details GetWaitObjects is usually called in one of two ways. First, it can
//! be called like <tt>something.GetWaitObjects(c, CallStack("my func after X", 0));</tt>.
- //! Second, if in an outer \p GetWaitObjects() method that itself takes a callStack
+ //! Second, if in an outer GetWaitObjects() method that itself takes a callStack
//! parameter, it can be called like
//! <tt>innerThing.GetWaitObjects(c, CallStack("MyClass::GetWaitObjects at X", &callStack));</tt>.
virtual void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) =0;
@@ -1076,22 +1197,22 @@ public:
bool Wait(unsigned long milliseconds, CallStack const& callStack);
};
-//! \brief Default channel for \p BufferedTransformation
-//! \details \p DEFAULT_CHANNEL is equal to an empty \p string
+//! \brief Default channel for BufferedTransformation
+//! \details DEFAULT_CHANNEL is equal to an empty string
extern CRYPTOPP_DLL const std::string DEFAULT_CHANNEL;
//! \brief Channel for additional authenticated data
-//! \details \p AAD_CHANNEL is equal to "AAD"
+//! \details AAD_CHANNEL is equal to "AAD"
extern CRYPTOPP_DLL const std::string AAD_CHANNEL;
//! \brief Interface for buffered transformations
-//! \details \p BufferedTransformation is a generalization of \p BlockTransformation,
-//! \p StreamTransformation and \p HashTransformation.
+//! \details BufferedTransformation is a generalization of BlockTransformation,
+//! StreamTransformation and HashTransformation.
//! \details A buffered transformation is an object that takes a stream of bytes as input (this may
//! be done in stages), does some computation on them, and then places the result into an internal
//! buffer for later retrieval. Any partial result already in the output buffer is not modified
//! by further input.
-//! \details If a method takes a "blocking" parameter, and you pass \p false for it, then the method
+//! \details If a method takes a "blocking" parameter, and you pass false for it, then the method
//! will return before all input has been processed if the input cannot be processed without waiting
//! (for network buffers to become available, for example). In this case the method will return true
//! or a non-zero integer value. When this happens you must continue to call the method with the same
@@ -1099,11 +1220,11 @@ extern CRYPTOPP_DLL const std::string AAD_CHANNEL;
//! /p BufferedTransformation. The integer return value in this case is approximately
//! the number of bytes left to be processed, and can be used to implement a progress bar.
//! \details For functions that take a "propagation" parameter, <tt>propagation != 0</tt> means pass on
-//! the signal to attached \p BufferedTransformation objects, with propagation decremented at each
+//! the signal to attached BufferedTransformation objects, with propagation decremented at each
//! step until it reaches <tt>0</tt>. <tt>-1</tt> means unlimited propagation.
-//! \details \a All of the retrieval functions, like \p Get and \p GetWord32, return the actual
-//! number of bytes retrieved, which is the lesser of the request number and \p MaxRetrievable().
-//! \details \a Most of the input functions, like \p Put and \p PutWord32, return the number of
+//! \details \a All of the retrieval functions, like Get() and GetWord32(), return the actual
+//! number of bytes retrieved, which is the lesser of the request number and MaxRetrievable().
+//! \details \a Most of the input functions, like Put() and PutWord32(), return the number of
//! bytes remaining to be processed. A 0 value means all bytes were processed, and a non-0 value
//! means bytes remain to be processed.
//! \nosubgrouping
@@ -1116,7 +1237,7 @@ public:
BufferedTransformation() : Algorithm(false) {}
//! \brief Provides a reference to this object
- //! \returns a reference to this object
+ //! \returns A reference to this object
//! \details Useful for passing a temporary object to a function that takes a non-const reference
BufferedTransformation& Ref() {return *this;}
@@ -1131,49 +1252,49 @@ public:
size_t Put(byte inByte, bool blocking=true)
{return Put(&inByte, 1, blocking);}
- //! \brief Input a byte array for processing
- //! \param inString the byte array to process
+ //! \brief Input a byte buffer for processing
+ //! \param inString the byte buffer to process
//! \param length the size of the string, in bytes
//! \param blocking specifies whether the object should block when processing input
//! \returns the number of bytes that remain in the block (i.e., bytes not processed)
- //! \details Internally, \p Put() calls \p Put2().
+ //! \details Internally, Put() calls Put2().
size_t Put(const byte *inString, size_t length, bool blocking=true)
{return Put2(inString, length, 0, blocking);}
//! Input a 16-bit word for processing.
//! \param value the 16-bit value to be processed
- //! \param order the \p ByteOrder in which the word should be processed
+ //! \param order the ByteOrder in which the word should be processed
//! \param blocking specifies whether the object should block when processing input
//! \returns the number of bytes that remain in the block (i.e., bytes not processed)
size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
//! Input a 32-bit word for processing.
//! \param value the 32-bit value to be processed.
- //! \param order the \p ByteOrder in which the word should be processed.
+ //! \param order the ByteOrder in which the word should be processed.
//! \param blocking specifies whether the object should block when processing input.
//! \returns the number of bytes that remain in the block (i.e., bytes not processed)
size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
- //! \brief Request space which can be written into by the caller, and then used as input to \p Put
+ //! \brief Request space which can be written into by the caller
//! \param size the requested size of the buffer
//! \details The purpose of this method is to help avoid extra memory allocations.
- //! \details \p size is an \a IN and \a OUT parameter and used as a hint. When the call is made,
- //! \p size is the requested size of the buffer. When the call returns, \p size is the size of
+ //! \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made,
+ //! size is the requested size of the buffer. When the call returns, size is the size of
//! the array returned to the caller.
- //! \details The base class implementation sets \p size to 0 and returns \p NULL.
- //! \note Some objects, like \p ArraySink, cannot create a space because its fixed. In the case of
- //! an \p ArraySink, the pointer to the array is returned and the \p size is remaining size.
+ //! \details The base class implementation sets size to 0 and returns NULL.
+ //! \note Some objects, like ArraySink, cannot create a space because its fixed. In the case of
+ //! an ArraySink, the pointer to the array is returned and the size is remaining size.
virtual byte * CreatePutSpace(size_t &size)
{size=0; return NULL;}
//! \brief Determines whether input can be modifed by the callee
//! \returns true if input can be modified, false otherwise
- //! \details The base class implementation returns \p false.
+ //! \details The base class implementation returns false.
virtual bool CanModifyInput() const
{return false;}
//! \brief Input multiple bytes that may be modified by callee.
- //! \param inString the byte array to process
+ //! \param inString the byte buffer to process
//! \param length the size of the string, in bytes
//! \param blocking specifies whether the object should block when processing input
//! \returns 0 indicates all bytes were processed during the call. Non-0 indicates the
@@ -1182,39 +1303,39 @@ public:
{return PutModifiable2(inString, length, 0, blocking);}
//! \brief Signals the end of messages to the object
- //! \param propagation the number of attached transformations the \p MessageEnd() signal should be passed
+ //! \param propagation the number of attached transformations the MessageEnd() signal should be passed
//! \param blocking specifies whether the object should block when processing input
- //! \details \p propagation count includes this object. Setting \p propagation to <tt>1</tt> means this
- //! object only. Setting \p propagation to <tt>-1</tt> means unlimited propagation.
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
bool MessageEnd(int propagation=-1, bool blocking=true)
{return !!Put2(NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);}
//! \brief Input multiple bytes for processing and signal the end of a message
- //! \param inString the byte array to process
+ //! \param inString the byte buffer to process
//! \param length the size of the string, in bytes
- //! \param propagation the number of attached transformations the \p MessageEnd() signal should be passed
+ //! \param propagation the number of attached transformations the MessageEnd() signal should be passed
//! \param blocking specifies whether the object should block when processing input
- //! \details Internally, \p PutMessageEnd() calls \p Put2() with a modified \p propagation to
+ //! \details Internally, PutMessageEnd() calls Put2() with a modified propagation to
//! ensure all attached transformations finish processing the message.
- //! \details \p propagation count includes this object. Setting \p propagation to <tt>1</tt> means this
- //! object only. Setting \p propagation to <tt>-1</tt> means unlimited propagation.
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
size_t PutMessageEnd(const byte *inString, size_t length, int propagation=-1, bool blocking=true)
{return Put2(inString, length, propagation < 0 ? -1 : propagation+1, blocking);}
- //! \brief Input multiple bytes for processing.
- //! \param inString the byte array to process.
- //! \param length the size of the string, in bytes.
- //! \param messageEnd means how many filters to signal \p MessageEnd to, including this one.
- //! \param blocking specifies whether the object should block when processing input.
- //! \details Derived classes must implement \p Put2.
+ //! \brief Input multiple bytes for processing
+ //! \param inString the byte buffer to process
+ //! \param length the size of the string, in bytes
+ //! \param messageEnd means how many filters to signal MessageEnd() to, including this one
+ //! \param blocking specifies whether the object should block when processing input
+ //! \details Derived classes must implement Put2().
virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) =0;
//! \brief Input multiple bytes that may be modified by callee.
- //! \param inString the byte array to process.
+ //! \param inString the byte buffer to process.
//! \param length the size of the string, in bytes.
- //! \param messageEnd means how many filters to signal \p MessageEnd to, including this one.
+ //! \param messageEnd means how many filters to signal MessageEnd() to, including this one.
//! \param blocking specifies whether the object should block when processing input.
- //! \details Internally, \p PutModifiable2() calls \p Put2().
+ //! \details Internally, PutModifiable2() calls Put2().
virtual size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking)
{return Put2(inString, length, messageEnd, blocking);}
@@ -1223,18 +1344,17 @@ public:
{BlockingInputOnly(const std::string &s) : NotImplemented(s + ": Nonblocking input is not implemented by this object.") {}};
//@}
- //! \section
//! \name WAITING
//@{
//! \brief Retrieves the maximum number of waitable objects
unsigned int GetMaxWaitObjectCount() const;
//! \brief Retrieves waitable objects
- //! \param container the wait container to receive the references to the objects.
- //! \param callStack \p CallStack object used to select waitable objects
- //! \details \p GetWaitObjects is usually called in one of two ways. First, it can
+ //! \param container the wait container to receive the references to the objects
+ //! \param callStack CallStack object used to select waitable objects
+ //! \details GetWaitObjects is usually called in one of two ways. First, it can
//! be called like <tt>something.GetWaitObjects(c, CallStack("my func after X", 0));</tt>.
- //! Second, if in an outer \p GetWaitObjects() method that itself takes a callStack
+ //! Second, if in an outer GetWaitObjects() method that itself takes a callStack
//! parameter, it can be called like
//! <tt>innerThing.GetWaitObjects(c, CallStack("MyClass::GetWaitObjects at X", &callStack));</tt>.
void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
@@ -1244,16 +1364,16 @@ public:
//@{
//! \brief Initialize or reinitialize this object, without signal propagation
- //! \param parameters a set of \p NameValuePairs used to initialize this object
+ //! \param parameters a set of NameValuePairs used to initialize this object
//! \throws NotImplemented
- //! \details \p IsolatedInitialize is used to initialize or reinitialize an object using a variable
+ //! \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable
//! number of arbitrarily typed arguments. The function avoids the need for multiple constuctors providing
//! all possible combintations of configurable parameters.
- //! \details \p IsolatedInitialize does not call \p Initialize on attached transformations. If initialization
- //! should be propagated, then use the \p Initialize function.
- //! \details Setting \p propagation to <tt>-1</tt> means unlimited propagation.
- //! \details If a derived class does not override \p IsolatedInitialize, then the base class throws
- //! \p NotImplemented.
+ //! \details IsolatedInitialize() does not call Initialize() on attached transformations. If initialization
+ //! should be propagated, then use the Initialize() function.
+ //! \details Setting propagation to <tt>-1</tt> means unlimited propagation.
+ //! \details If a derived class does not override IsolatedInitialize(), then the base class throws
+ //! NotImplemented.
virtual void IsolatedInitialize(const NameValuePairs &parameters) {
CRYPTOPP_UNUSED(parameters);
throw NotImplemented("BufferedTransformation: this object can't be reinitialized");
@@ -1262,7 +1382,7 @@ public:
//! \brief Flushes data buffered by this object, without signal propagation
//! \param hardFlush indicates whether all data should be flushed
//! \param blocking specifies whether the object should block when processing input
- //! \note \p hardFlush must be used with care
+ //! \note hardFlush must be used with care
virtual bool IsolatedFlush(bool hardFlush, bool blocking) =0;
//! \brief Marks the end of a series of messages, without signal propagation
@@ -1272,26 +1392,26 @@ public:
{CRYPTOPP_UNUSED(blocking); return false;}
//! \brief Initialize or reinitialize this object, with signal propagation
- //! \param parameters a set of \p NameValuePairs used to initialize or reinitialize this object
+ //! \param parameters a set of NameValuePairs used to initialize or reinitialize this object
//! and attached transformations
- //! \param propagation the number of attached transformations the \p Initialize() signal should be passed
- //! \details \p Initialize is used to initialize or reinitialize an object using a variable number of
+ //! \param propagation the number of attached transformations the Initialize() signal should be passed
+ //! \details Initialize() is used to initialize or reinitialize an object using a variable number of
//! arbitrarily typed arguments. The function avoids the need for multiple constuctors providing
//! all possible combintations of configurable parameters.
- //! \details \p propagation count includes this object. Setting \p propagation to <tt>1</tt> means this
- //! object only. Setting \p propagation to <tt>-1</tt> means unlimited propagation.
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
//! \brief Flush buffered input and/or output, with signal propagation
//! \param hardFlush is used to indicate whether all data should be flushed
- //! \param propagation the number of attached transformations the \p Flush() signal should be passed
+ //! \param propagation the number of attached transformations the Flush() signal should be passed
//! \param blocking specifies whether the object should block when processing input
- //! \details \p propagation count includes this object. Setting \p propagation to <tt>1</tt> means this
- //! object only. Setting \p propagation to <tt>-1</tt> means unlimited propagation.
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
//! \note Hard flushes must be used with care. It means try to process and output everything, even if
- //! there may not be enough data to complete the action. For example, hard flushing a \p HexDecoder
+ //! there may not be enough data to complete the action. For example, hard flushing a HexDecoder
//! would cause an error if you do it after inputing an odd number of hex encoded characters.
- //! \note For some types of filters, like \p ZlibDecompressor, hard flushes can only
+ //! \note For some types of filters, like ZlibDecompressor, hard flushes can only
//! be done at "synchronization points". These synchronization points are positions in the data
//! stream that are created by hard flushes on the corresponding reverse filters, in this
//! example ZlibCompressor. This is useful when zlib compressed data is moved across a
@@ -1299,19 +1419,19 @@ public:
virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
//! \brief Marks the end of a series of messages, with signal propagation
- //! \param propagation the number of attached transformations the \p MessageSeriesEnd() signal should be passed
+ //! \param propagation the number of attached transformations the MessageSeriesEnd() signal should be passed
//! \param blocking specifies whether the object should block when processing input
//! \details Each object that receives the signal will perform its processing, decrement
- //! \p propagation, and then pass the signal on to attached transformations if the value is not 0.
- //! \details \p propagation count includes this object. Setting \p propagation to <tt>1</tt> means this
- //! object only. Setting \p propagation to <tt>-1</tt> means unlimited propagation.
- //! \note There should be a \p MessageEnd immediately before \p MessageSeriesEnd.
+ //! propagation, and then pass the signal on to attached transformations if the value is not 0.
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
+ //! \note There should be a MessageEnd() immediately before MessageSeriesEnd().
virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
//! \brief Set propagation of automatically generated and transferred signals
//! \param propagation then new value
- //! \details Setting \p propagation to <tt>0</tt> means do not automaticly generate signals. Setting
- //! \p propagation to <tt>-1</tt> means unlimited propagation.
+ //! \details Setting propagation to <tt>0</tt> means do not automaticly generate signals. Setting
+ //! propagation to <tt>-1</tt> means unlimited propagation.
virtual void SetAutoSignalPropagation(int propagation)
{CRYPTOPP_UNUSED(propagation);}
@@ -1330,107 +1450,107 @@ public:
//! \brief Provides the number of bytes ready for retrieval
//! \returns the number of bytes ready for retrieval
//! \details All retrieval functions return the actual number of bytes retrieved, which is
- //! the lesser of the request number and \p MaxRetrievable()
+ //! the lesser of the request number and MaxRetrievable()
virtual lword MaxRetrievable() const;
//! \brief Determines whether bytes are ready for retrieval
- //! \returns \p true if bytes are available for retrieval, false otherwise
+ //! \returns true if bytes are available for retrieval, false otherwise
virtual bool AnyRetrievable() const;
//! \brief Retrieve a 8-bit byte
//! \param outByte the 8-bit value to be retrieved
//! \returns the number of bytes consumed during the call.
- //! \details Use the return value of \p Get to detect short reads.
+ //! \details Use the return value of Get to detect short reads.
virtual size_t Get(byte &outByte);
//! \brief Retrieve a block of bytes
//! \param outString a block of bytes
- //! \param getMax the number of bytes to \p Get
+ //! \param getMax the number of bytes to Get
//! \returns the number of bytes consumed during the call.
- //! \details Use the return value of \p Get to detect short reads.
+ //! \details Use the return value of Get to detect short reads.
virtual size_t Get(byte *outString, size_t getMax);
//! \brief Peek a 8-bit byte
//! \param outByte the 8-bit value to be retrieved
//! \returns the number of bytes read during the call.
- //! \details \p Peek does not remove bytes from the object. Use the return value of
- //! \p Get to detect short reads.
+ //! \details Peek does not remove bytes from the object. Use the return value of
+ //! Get to detect short reads.
virtual size_t Peek(byte &outByte) const;
//! \brief Peek a block of bytes
//! \param outString a block of bytes
- //! \param peekMax the number of bytes to \p Peek
+ //! \param peekMax the number of bytes to Peek
//! \returns the number of bytes read during the call.
- //! \details \p Peek does not remove bytes from the object. Use the return value of
- //! \p Get to detect short reads.
+ //! \details Peek does not remove bytes from the object. Use the return value of
+ //! Get to detect short reads.
virtual size_t Peek(byte *outString, size_t peekMax) const;
//! \brief Retrieve a 16-bit word
//! \param value the 16-bit value to be retrieved
- //! \param order the \p ByteOrder in which the word should be retrieved
+ //! \param order the ByteOrder in which the word should be retrieved
//! \returns the number of bytes consumed during the call.
- //! \details Use the return value of \p GetWord16 to detect short reads.
+ //! \details Use the return value of GetWord16 to detect short reads.
size_t GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER);
//! \brief Retrieve a 32-bit word
//! \param value the 32-bit value to be retrieved
- //! \param order the \p ByteOrder in which the word should be retrieved
+ //! \param order the ByteOrder in which the word should be retrieved
//! \returns the number of bytes consumed during the call.
- //! \details Use the return value of \p GetWord16 to detect short reads.
+ //! \details Use the return value of GetWord16 to detect short reads.
size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER);
//! \brief Peek a 16-bit word
//! \param value the 16-bit value to be retrieved
- //! \param order the \p ByteOrder in which the word should be retrieved
+ //! \param order the ByteOrder in which the word should be retrieved
//! \returns the number of bytes consumed during the call.
- //! \details \p Peek does not consume bytes in the stream. Use the return value
- //! of \p GetWord16 to detect short reads.
+ //! \details Peek does not consume bytes in the stream. Use the return value
+ //! of GetWord16 to detect short reads.
size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
//! \brief Peek a 32-bit word
//! \param value the 32-bit value to be retrieved
- //! \param order the \p ByteOrder in which the word should be retrieved
+ //! \param order the ByteOrder in which the word should be retrieved
//! \returns the number of bytes consumed during the call.
- //! \details \p Peek does not consume bytes in the stream. Use the return value
- //! of \p GetWord16 to detect short reads.
+ //! \details Peek does not consume bytes in the stream. Use the return value
+ //! of GetWord16 to detect short reads.
size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
//! move transferMax bytes of the buffered output to target as input
- //! \brief Transfer bytes from this object to another \p BufferedTransformation
- //! \param target the destination \p BufferedTransformation
+ //! \brief Transfer bytes from this object to another BufferedTransformation
+ //! \param target the destination BufferedTransformation
//! \param transferMax the number of bytes to transfer
//! \param channel the channel on which the transfer should occur
//! \returns the number of bytes transferred during the call.
- //! \details \p TransferTo removes bytes from this object and moves them to the destination.
- //! \details The function always returns \p transferMax. If an accurate count is needed, then use \p TransferTo2.
+ //! \details TransferTo removes bytes from this object and moves them to the destination.
+ //! \details The function always returns transferMax. If an accurate count is needed, then use TransferTo2.
lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL)
{TransferTo2(target, transferMax, channel); return transferMax;}
- //! \brief Discard \p skipMax bytes from the output buffer
+ //! \brief Discard skipMax bytes from the output buffer
//! \param skipMax the number of bytes to discard
- //! \details \p Skip always returns \p skipMax.
+ //! \details Skip always returns skipMax.
virtual lword Skip(lword skipMax=LWORD_MAX);
//! copy copyMax bytes of the buffered output to target as input
- //! \brief Copy bytes from this object to another \p BufferedTransformation
- //! \param target the destination \p BufferedTransformation
+ //! \brief Copy bytes from this object to another BufferedTransformation
+ //! \param target the destination BufferedTransformation
//! \param copyMax the number of bytes to copy
//! \param channel the channel on which the transfer should occur
//! \returns the number of bytes copied during the call.
- //! \details \p CopyTo copies bytes from this object to the destination. The bytes are not removed from this object.
- //! \details The function always returns \p copyMax. If an accurate count is needed, then use \p CopyRangeTo2.
+ //! \details CopyTo copies bytes from this object to the destination. The bytes are not removed from this object.
+ //! \details The function always returns copyMax. If an accurate count is needed, then use CopyRangeTo2.
lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const
{return CopyRangeTo(target, 0, copyMax, channel);}
- //! \brief Copy bytes from this object using an index to another \p BufferedTransformation
- //! \param target the destination \p BufferedTransformation
+ //! \brief Copy bytes from this object using an index to another BufferedTransformation
+ //! \param target the destination BufferedTransformation
//! \param position the 0-based index of the byte stream to begin the copying
//! \param copyMax the number of bytes to copy
//! \param channel the channel on which the transfer should occur
//! \returns the number of bytes copied during the call.
- //! \details \p CopyTo copies bytes from this object to the destination. The bytes remain in this
+ //! \details CopyTo copies bytes from this object to the destination. The bytes remain in this
//! object. Copying begins at the index position in the current stream, and not from an absolute
//! position in the stream.
//! \details The function returns the new position in the stream after transferring the bytes starting at the index.
@@ -1448,30 +1568,52 @@ public:
//! \brief Provides the number of bytes ready for retrieval
//! \returns the number of bytes ready for retrieval
virtual lword TotalBytesRetrievable() const;
-
+
//! \brief Provides the number of meesages processed by this object
//! \returns the number of meesages processed by this object
- //! \details \p NumberOfMessages returns number of times \p MessageEnd() has been
+ //! \details NumberOfMessages returns number of times MessageEnd() has been
//! received minus messages retrieved or skipped
virtual unsigned int NumberOfMessages() const;
//! \brief Determines if any messages are available for retrieval
- //! \returns \p true if <tt>NumberOfMessages() &gt; 0</tt>, \p false otherwise
- //! \details \p AnyMessages returns true if <tt>NumberOfMessages() &gt; 0</tt>
+ //! \returns true if <tt>NumberOfMessages() &gt; 0</tt>, false otherwise
+ //! \details AnyMessages returns true if <tt>NumberOfMessages() &gt; 0</tt>
virtual bool AnyMessages() const;
- //! start retrieving the next message
- /*!
- Returns false if no more messages exist or this message
- is not completely retrieved.
- */
+ //! \brief Start retrieving the next message
+ //! \returns true if a message is ready for retrieval
+ //! \details GetNextMessage() returns true if a message is ready for retrieval; false
+ //! if no more messages exist or this message is not completely retrieved.
virtual bool GetNextMessage();
- //! skip count number of messages
+
+ //! \brief Skip a number of meessages
+ //! \returns 0 if the requested number of messages was skipped, non-0 otherwise
+ //! \details SkipMessages() skips count number of messages. If there is an AttachedTransformation()
+ //! then SkipMessages() is called on the attached transformation. If there is no attached
+ //! transformation, then count number of messages are sent to TheBitBucket() using TransferMessagesTo().
virtual unsigned int SkipMessages(unsigned int count=UINT_MAX);
- //!
+
+ //! \brief Transfer messages from this object to another BufferedTransformation
+ //! \param target the destination BufferedTransformation
+ //! \param count the number of messages to transfer
+ //! \param channel the channel on which the transfer should occur
+ //! \returns the number of bytes that remain in the current transfer block (i.e., bytes not transferred)
+ //! \details TransferMessagesTo2 removes messages from this object and moves them to the destination.
+ //! If all bytes are not transferred for a message, then processing stops and the number of remaining
+ //! bytes is returned. TransferMessagesTo() does not proceed to the next message.
+ //! \details A return value of 0 indicates all messages were successfully transferred.
unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL)
{TransferMessagesTo2(target, count, channel); return count;}
- //!
+
+ //! \brief Copies messages from this object to another BufferedTransformation
+ //! \param target the destination BufferedTransformation
+ //! \param count the number of messages to transfer
+ //! \param channel the channel on which the transfer should occur
+ //! \returns the number of bytes that remain in the current transfer block (i.e., bytes not transferred)
+ //! \details CopyMessagesTo copies messages from this object and copies them to the destination.
+ //! If all bytes are not transferred for a message, then processing stops and the number of remaining
+ //! bytes is returned. CopyMessagesTo() does not proceed to the next message.
+ //! \details A return value of 0 indicates all messages were successfully copied.
unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const;
//!
@@ -1493,59 +1635,59 @@ public:
// upon return, byteCount contains number of bytes that have finished being transfered,
// and returns the number of bytes left in the current transfer block
- //! \brief Transfer bytes from this object to another \p BufferedTransformation
- //! \param target the destination \p BufferedTransformation
+ //! \brief Transfer bytes from this object to another BufferedTransformation
+ //! \param target the destination BufferedTransformation
//! \param byteCount the number of bytes to transfer
//! \param channel the channel on which the transfer should occur
//! \param blocking specifies whether the object should block when processing input
//! \returns the number of bytes that remain in the transfer block (i.e., bytes not transferred)
- //! \details \p TransferTo removes bytes from this object and moves them to the destination.
+ //! \details TransferTo removes bytes from this object and moves them to the destination.
//! Transfer begins at the index position in the current stream, and not from an absolute
//! position in the stream.
- //! \details \p byteCount is an \a IN and \a OUT parameter. When the call is made,
- //! \p byteCount is the requested size of the transfer. When the call returns, \p byteCount is
+ //! \details byteCount is an \a IN and \a OUT parameter. When the call is made,
+ //! byteCount is the requested size of the transfer. When the call returns, byteCount is
//! the number of bytes that were transferred.
virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) =0;
// upon return, begin contains the start position of data yet to be finished copying,
// and returns the number of bytes left in the current transfer block
- //! \brief Copy bytes from this object to another \p BufferedTransformation
- //! \param target the destination \p BufferedTransformation
+ //! \brief Copy bytes from this object to another BufferedTransformation
+ //! \param target the destination BufferedTransformation
//! \param begin the 0-based index of the first byte to copy in the stream
//! \param end the 0-based index of the last byte to copy in the stream
//! \param channel the channel on which the transfer should occur
//! \param blocking specifies whether the object should block when processing input
//! \returns the number of bytes that remain in the copy block (i.e., bytes not copied)
- //! \details \p CopyRangeTo2 copies bytes from this object to the destination. The bytes are not
+ //! \details CopyRangeTo2 copies bytes from this object to the destination. The bytes are not
//! removed from this object. Copying begins at the index position in the current stream, and
//! not from an absolute position in the stream.
- //! \details \p begin is an \a IN and \a OUT parameter. When the call is made, \p begin is the
- //! starting position of the copy. When the call returns, \p begin is the position of the first
- //! byte that was \a not copied (which may be different tahn \p end). \p begin can be used for
- //! subsequent calls to \p CopyRangeTo2.
+ //! \details begin is an \a IN and \a OUT parameter. When the call is made, begin is the
+ //! starting position of the copy. When the call returns, begin is the position of the first
+ //! byte that was \a not copied (which may be different tahn end). begin can be used for
+ //! subsequent calls to CopyRangeTo2.
virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const =0;
// upon return, messageCount contains number of messages that have finished being transfered,
// and returns the number of bytes left in the current transfer block
- //! \brief Transfer messages from this object to another \p BufferedTransformation
- //! \param target the destination \p BufferedTransformation
+ //! \brief Transfer messages from this object to another BufferedTransformation
+ //! \param target the destination BufferedTransformation
//! \param messageCount the number of messages to transfer
//! \param channel the channel on which the transfer should occur
//! \param blocking specifies whether the object should block when processing input
//! \returns the number of bytes that remain in the current transfer block (i.e., bytes not transferred)
- //! \details \p TransferMessagesTo2 removes messages from this object and moves them to the destination.
+ //! \details TransferMessagesTo2 removes messages from this object and moves them to the destination.
size_t TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
// returns the number of bytes left in the current transfer block
- //! \brief Transfer all bytes from this object to another \p BufferedTransformation
- //! \param target the destination \p BufferedTransformation
+ //! \brief Transfer all bytes from this object to another BufferedTransformation
+ //! \param target the destination BufferedTransformation
//! \param channel the channel on which the transfer should occur
//! \param blocking specifies whether the object should block when processing input
//! \returns the number of bytes that remain in the current transfer block (i.e., bytes not transferred)
- //! \details \p TransferMessagesTo2 removes messages from this object and moves them to the destination.
+ //! \details TransferMessagesTo2 removes messages from this object and moves them to the destination.
size_t TransferAllTo2(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
//@}
@@ -1567,9 +1709,9 @@ public:
size_t ChannelPut(const std::string &channel, byte inByte, bool blocking=true)
{return ChannelPut(channel, &inByte, 1, blocking);}
- //! \brief Input a byte array for processing on a channel
+ //! \brief Input a byte buffer for processing on a channel
//! \param channel the channel to process the data
- //! \param inString the byte array to process
+ //! \param inString the byte buffer to process
//! \param length the size of the string, in bytes
//! \param blocking specifies whether the object should block when processing input
//! \returns 0 indicates all bytes were processed during the call. Non-0 indicates the
@@ -1579,7 +1721,7 @@ public:
//! \brief Input multiple bytes that may be modified by callee on a channel
//! \param channel the channel to process the data.
- //! \param inString the byte array to process
+ //! \param inString the byte buffer to process
//! \param length the size of the string, in bytes
//! \param blocking specifies whether the object should block when processing input
//! \returns 0 indicates all bytes were processed during the call. Non-0 indicates the
@@ -1590,7 +1732,7 @@ public:
//! \brief Input a 16-bit word for processing on a channel.
//! \param channel the channel to process the data.
//! \param value the 16-bit value to be processed.
- //! \param order the \p ByteOrder in which the word should be processed.
+ //! \param order the ByteOrder in which the word should be processed.
//! \param blocking specifies whether the object should block when processing input.
//! \returns 0 indicates all bytes were processed during the call. Non-0 indicates the
//! number of bytes that were \a not processed.
@@ -1599,7 +1741,7 @@ public:
//! \brief Input a 32-bit word for processing on a channel.
//! \param channel the channel to process the data.
//! \param value the 32-bit value to be processed.
- //! \param order the \p ByteOrder in which the word should be processed.
+ //! \param order the ByteOrder in which the word should be processed.
//! \param blocking specifies whether the object should block when processing input.
//! \returns 0 indicates all bytes were processed during the call. Non-0 indicates the
//! number of bytes that were \a not processed.
@@ -1607,74 +1749,74 @@ public:
//! \brief Signal the end of a message
//! \param channel the channel to process the data.
- //! \param propagation the number of attached transformations the \p ChannelMessageEnd() signal should be passed
+ //! \param propagation the number of attached transformations the ChannelMessageEnd() signal should be passed
//! \param blocking specifies whether the object should block when processing input
//! \returns 0 indicates all bytes were processed during the call. Non-0 indicates the
//! number of bytes that were \a not processed.
- //! \details \p propagation count includes this object. Setting \p propagation to <tt>1</tt> means this
- //! object only. Setting \p propagation to <tt>-1</tt> means unlimited propagation.
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true)
{return !!ChannelPut2(channel, NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);}
//! \brief Input multiple bytes for processing and signal the end of a message
//! \param channel the channel to process the data.
- //! \param inString the byte array to process
+ //! \param inString the byte buffer to process
//! \param length the size of the string, in bytes
- //! \param propagation the number of attached transformations the \p ChannelPutMessageEnd() signal should be passed
+ //! \param propagation the number of attached transformations the ChannelPutMessageEnd() signal should be passed
//! \param blocking specifies whether the object should block when processing input
//! \returns 0 indicates all bytes were processed during the call. Non-0 indicates the
//! number of bytes that were \a not processed.
- //! \details \p propagation count includes this object. Setting \p propagation to <tt>1</tt> means this
- //! object only. Setting \p propagation to <tt>-1</tt> means unlimited propagation.
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
size_t ChannelPutMessageEnd(const std::string &channel, const byte *inString, size_t length, int propagation=-1, bool blocking=true)
{return ChannelPut2(channel, inString, length, propagation < 0 ? -1 : propagation+1, blocking);}
- //! \brief Request space which can be written into by the caller, and then used as input to \p Put
+ //! \brief Request space which can be written into by the caller
//! \param channel the channel to process the data
//! \param size the requested size of the buffer
//! \details The purpose of this method is to help avoid extra memory allocations.
- //! \details \p size is an \a IN and \a OUT parameter and used as a hint. When the call is made,
- //! \p size is the requested size of the buffer. When the call returns, \p size is the size of
+ //! \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made,
+ //! size is the requested size of the buffer. When the call returns, size is the size of
//! the array returned to the caller.
- //! \details The base class implementation sets \p size to 0 and returns \p NULL.
- //! \note Some objects, like \p ArraySink, cannot create a space because its fixed. In the case of
- //! an \p ArraySink, the pointer to the array is returned and the \p size is remaining size.
+ //! \details The base class implementation sets size to 0 and returns NULL.
+ //! \note Some objects, like ArraySink, cannot create a space because its fixed. In the case of
+ //! an ArraySink, the pointer to the array is returned and the size is remaining size.
virtual byte * ChannelCreatePutSpace(const std::string &channel, size_t &size);
//! \brief Input multiple bytes for processing on a channel.
//! \param channel the channel to process the data.
- //! \param inString the byte array to process.
+ //! \param inString the byte buffer to process.
//! \param length the size of the string, in bytes.
- //! \param messageEnd means how many filters to signal \p MessageEnd to, including this one.
+ //! \param messageEnd means how many filters to signal MessageEnd() to, including this one.
//! \param blocking specifies whether the object should block when processing input.
virtual size_t ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking);
//! \brief Input multiple bytes that may be modified by callee on a channel
//! \param channel the channel to process the data
- //! \param inString the byte array to process
+ //! \param inString the byte buffer to process
//! \param length the size of the string, in bytes
- //! \param messageEnd means how many filters to signal \p MessageEnd to, including this one
- //! \param blocking specifies whether the object should block when processing input.
+ //! \param messageEnd means how many filters to signal MessageEnd() to, including this one
+ //! \param blocking specifies whether the object should block when processing input
virtual size_t ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking);
//! \brief Flush buffered input and/or output on a channel
//! \param channel the channel to flush the data
//! \param hardFlush is used to indicate whether all data should be flushed
- //! \param propagation the number of attached transformations the \p ChannelFlush() signal should be passed
+ //! \param propagation the number of attached transformations the ChannelFlush() signal should be passed
//! \param blocking specifies whether the object should block when processing input
- //! \details \p propagation count includes this object. Setting \p propagation to <tt>1</tt> means this
- //! object only. Setting \p propagation to <tt>-1</tt> means unlimited propagation.
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true);
//! \brief Marks the end of a series of messages on a channel
//! \param channel the channel to signal the end of a series of messages
- //! \param propagation the number of attached transformations the \p ChannelMessageSeriesEnd() signal should be passed
+ //! \param propagation the number of attached transformations the ChannelMessageSeriesEnd() signal should be passed
//! \param blocking specifies whether the object should block when processing input
//! \details Each object that receives the signal will perform its processing, decrement
- //! \p propagation, and then pass the signal on to attached transformations if the value is not 0.
- //! \details \p propagation count includes this object. Setting \p propagation to <tt>1</tt> means this
- //! object only. Setting \p propagation to <tt>-1</tt> means unlimited propagation.
- //! \note There should be a \p MessageEnd immediately before \p MessageSeriesEnd.
+ //! propagation, and then pass the signal on to attached transformations if the value is not 0.
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
+ //! \note There should be a MessageEnd() immediately before MessageSeriesEnd().
virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true);
//! \brief Sets the default retrieval channel
@@ -1684,8 +1826,8 @@ public:
//@}
//! \name ATTACHMENT
- /*! Some \p BufferedTransformation objects (e.g. Filter objects)
- allow other \p BufferedTransformation objects to be attached. When
+ /*! Some BufferedTransformation objects (e.g. Filter objects)
+ allow other BufferedTransformation objects to be attached. When
this is done, the first object instead of buffering its output,
sends that output to the attached object as input. The entire
attachment chain is deleted when the anchor object is destructed.
@@ -1693,29 +1835,32 @@ public:
//@{
//! \brief Determines whether the object allows attachment
//! \returns true if the object allows an attachment, false otherwise
- //! \details \p Sources and \p Filters will return \p true, while \p Sinks and other objects will return \p false.
+ //! \details Sources and Filters will return true, while Sinks and other objects will return false.
virtual bool Attachable() {return false;}
//! \brief Returns the object immediately attached to this object
- //! \details \p AttachedTransformation returns \p NULL if there is no attachment
+ //! \details AttachedTransformation returns NULL if there is no attachment
virtual BufferedTransformation *AttachedTransformation() {assert(!Attachable()); return 0;}
//! \brief Returns the object immediately attached to this object
- //! \details \p AttachedTransformation returns \p NULL if there is no attachment
+ //! \details AttachedTransformation returns NULL if there is no attachment
virtual const BufferedTransformation *AttachedTransformation() const
{return const_cast<BufferedTransformation *>(this)->AttachedTransformation();}
//! \brief Delete the current attachment chain and attach a new one
- //! \param newAttachment the new \p BufferedTransformation to attach
+ //! \param newAttachment the new BufferedTransformation to attach
//! \throws NotImplemented
- //! \details \p Detach delete the current attachment chain and replace it with an optional \p newAttachment
- //! \details If a derived class does not override \p Detach, then the base class throws
- //! \p NotImplemented.
+ //! \details Detach delete the current attachment chain and replace it with an optional newAttachment
+ //! \details If a derived class does not override Detach, then the base class throws
+ //! NotImplemented.
virtual void Detach(BufferedTransformation *newAttachment = 0) {
CRYPTOPP_UNUSED(newAttachment); assert(!Attachable());
throw NotImplemented("BufferedTransformation: this object is not attachable");
}
- //! add newAttachment to the end of attachment chain
+
+ //! \brief Add newAttachment to the end of attachment chain
+ //! \param newAttachment the attachment to add to the end of the chain
+
virtual void Attach(BufferedTransformation *newAttachment);
//@}
@@ -1725,7 +1870,7 @@ public:
protected:
//! \brief Decrements the propagation count while clamping at 0
- //! \returns the decremented \p propagation or 0
+ //! \returns the decremented propagation or 0
static int DecrementPropagation(int propagation)
{return propagation != 0 ? propagation - 1 : 0;}
@@ -1733,7 +1878,7 @@ private:
byte m_buf[4]; // for ChannelPutWord16 and ChannelPutWord32, to ensure buffer isn't deallocated before non-blocking operation completes
};
-//! \brief An input discarding \p BufferedTransformation
+//! \brief An input discarding BufferedTransformation
//! \returns a reference to a BufferedTransformation object that discards all input
CRYPTOPP_DLL BufferedTransformation & TheBitBucket();
@@ -1754,9 +1899,9 @@ public:
virtual void AssignFrom(const NameValuePairs &source) =0;
//! \brief Check this object for errors
- //! \param rng a \p RandomNumberGenerator for objects which use randominzed testing
+ //! \param rng a RandomNumberGenerator for objects which use randominzed testing
//! \param level the level of thoroughness
- //! \returns \p true if the tests succeed, \p false otherwise
+ //! \returns true if the tests succeed, false otherwise
//! \details There are four levels of thoroughness:
//! <ul>
//! <li>0 - using this object won't cause a crash or exception
@@ -1764,35 +1909,35 @@ public:
//! <li>2 - ensure this object will function correctly, and perform reasonable security checks
//! <li>3 - perform reasonable security checks, and do checks that may take a long time
//! </ul>
- //! \details Level 0 does not require a \p RandomNumberGenerator. A \p NullRNG () can be used for level 0.
+ //! \details Level 0 does not require a RandomNumberGenerator. A NullRNG () can be used for level 0.
//! \details Level 1 may not check for weak keys and such.
//! \details Levels 2 and 3 are recommended.
virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0;
//! \brief Check this object for errors
- //! \param rng a \p RandomNumberGenerator for objects which use randominzed testing
+ //! \param rng a RandomNumberGenerator for objects which use randominzed testing
//! \param level the level of thoroughness
//! \throws InvalidMaterial
- //! \details Internally, \p ThrowIfInvalid() calls \p Validate() and throws \p InvalidMaterial if validation fails.
+ //! \details Internally, ThrowIfInvalid() calls Validate() and throws InvalidMaterial if validation fails.
virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const
{if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");}
- //! \brief Saves a key to a \p BufferedTransformation
- //! \param bt the destination \p BufferedTransformation
+ //! \brief Saves a key to a BufferedTransformation
+ //! \param bt the destination BufferedTransformation
//! \throws NotImplemented
- //! \details \p Save writes the material to a \p BufferedTransformation.
+ //! \details Save writes the material to a BufferedTransformation.
//! \details If the material is a key, then the key is written with ASN.1 DER encoding. The key
- //! includes an object identifier with an algorthm id, like a \p subjectPublicKeyInfo.
- //! \details A "raw" key without the "key info" can be saved using a key's \p DEREncode method.
- //! \details If a derived class does not override \p Save, then the base class throws
- //! \p NotImplemented.
+ //! includes an object identifier with an algorthm id, like a subjectPublicKeyInfo.
+ //! \details A "raw" key without the "key info" can be saved using a key's DEREncode method.
+ //! \details If a derived class does not override Save, then the base class throws
+ //! NotImplemented.
virtual void Save(BufferedTransformation &bt) const
{CRYPTOPP_UNUSED(bt); throw NotImplemented("CryptoMaterial: this object does not support saving");}
- //! \brief Loads a key from a \p BufferedTransformation
- //! \param bt the source \p BufferedTransformation
+ //! \brief Loads a key from a BufferedTransformation
+ //! \param bt the source BufferedTransformation
//! \throws KeyingErr
- //! \details \p Load attempts to read material from a \p BufferedTransformation. If the
+ //! \details Load attempts to read material from a BufferedTransformation. If the
//! material is a key that was generated outside the library, then the following
//! usually applies:
//! <ul>
@@ -1800,9 +1945,9 @@ public:
//! <li>the key should be a "key info"
//! </ul>
//! \details "key info" means the key should have an object identifier with an algorthm id,
- //! like a \p subjectPublicKeyInfo.
- //! \details To read a "raw" key without the "key info", then call the key's \p BERDecode method.
- //! \note \p Load generally does not check that the key is valid. Call Validate(), if needed.
+ //! like a subjectPublicKeyInfo.
+ //! \details To read a "raw" key without the "key info", then call the key's BERDecode method.
+ //! \note Load generally does not check that the key is valid. Call Validate(), if needed.
virtual void Load(BufferedTransformation &bt)
{CRYPTOPP_UNUSED(bt); throw NotImplemented("CryptoMaterial: this object does not support loading");}
@@ -1813,10 +1958,10 @@ public:
//! \brief Perform precomputation
//! \param precomputationStorage the suggested number of objects for the precompute table
//! \throws NotImplemented
- //! \details The exact semantics of \p Precompute() varies, but it typically means calculate
- //! a table of \p n objects that can be used later to speed up computation.
- //! \details If a derived class does not override \p Precompute, then the base class throws
- //! \p NotImplemented.
+ //! \details The exact semantics of Precompute() varies, but it typically means calculate
+ //! a table of n objects that can be used later to speed up computation.
+ //! \details If a derived class does not override Precompute, then the base class throws
+ //! NotImplemented.
virtual void Precompute(unsigned int precomputationStorage) {
CRYPTOPP_UNUSED(precomputationStorage); assert(!SupportsPrecomputation());
throw NotImplemented("CryptoMaterial: this object does not support precomputation");
@@ -1849,21 +1994,21 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GeneratableCryptoMaterial : virtual public
public:
//! \brief Generate a random key or crypto parameters
- //! \param rng a \p RandomNumberGenerator to produce keying material
+ //! \param rng a RandomNumberGenerator to produce keying material
//! \param params additional initialization parameters
//! \throws KeyingErr if a key can't be generated or algorithm parameters are invalid
- //! \details If a derived class does not override \p GenerateRandom, then the base class throws
- //! \p NotImplemented.
+ //! \details If a derived class does not override GenerateRandom, then the base class throws
+ //! NotImplemented.
virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params = g_nullNameValuePairs) {
CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(params);
throw NotImplemented("GeneratableCryptoMaterial: this object does not support key/parameter generation");
}
//! \brief Generate a random key or crypto parameters
- //! \param rng a \p RandomNumberGenerator to produce keying material
+ //! \param rng a RandomNumberGenerator to produce keying material
//! \param keySize the size of the key, in bits
//! \throws KeyingErr if a key can't be generated or algorithm parameters are invalid
- //! \details \p GenerateRandomWithKeySize calls \p GenerateRandom with a \p NameValuePairs
+ //! \details GenerateRandomWithKeySize calls GenerateRandom with a NameValuePairs
//! object with only "KeySize"
void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize);
@@ -2009,8 +2154,8 @@ public:
};
//! encrypt a byte string
- /*! \pre CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long)
- \pre size of ciphertext == CiphertextLength(plaintextLength)
+ /*! re CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long)
+ re size of ciphertext == CiphertextLength(plaintextLength)
*/
virtual void Encrypt(RandomNumberGenerator &rng,
const byte *plaintext, size_t plaintextLength,
@@ -2030,7 +2175,7 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Decryptor : public PK_CryptoSystem, pub
{
public:
//! decrypt a byte string, and return the length of plaintext
- /*! \pre size of plaintext == MaxPlaintextLength(ciphertextLength) bytes.
+ /*! re size of plaintext == MaxPlaintextLength(ciphertextLength) bytes.
\returns the actual length of the plaintext, indication that decryption failed.
*/
virtual DecodingResult Decrypt(RandomNumberGenerator &rng,
@@ -2139,25 +2284,25 @@ public:
virtual void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const =0;
//! sign and delete messageAccumulator (even in case of exception thrown)
- /*! \pre size of signature == MaxSignatureLength()
+ /*! re size of signature == MaxSignatureLength()
\returns actual signature length
*/
virtual size_t Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const;
//! sign and restart messageAccumulator
- /*! \pre size of signature == MaxSignatureLength()
+ /*! re size of signature == MaxSignatureLength()
\returns actual signature length
*/
virtual size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const =0;
//! sign a message
- /*! \pre size of signature == MaxSignatureLength()
+ /*! re size of signature == MaxSignatureLength()
\returns actual signature length
*/
virtual size_t SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const;
//! sign a recoverable message
- /*! \pre size of signature == MaxSignatureLength(recoverableMessageLength)
+ /*! re size of signature == MaxSignatureLength(recoverableMessageLength)
\returns actual signature length
*/
virtual size_t SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength,
@@ -2195,17 +2340,17 @@ public:
const byte *signature, size_t signatureLength) const;
//! recover a message from its signature
- /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
+ /*! re size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
*/
virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const;
//! recover a message from its signature
- /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
+ /*! re size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
*/
virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0;
//! recover a message from its signature
- /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
+ /*! re size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
*/
virtual DecodingResult RecoverMessage(byte *recoveredMessage,
const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength,
@@ -2232,19 +2377,19 @@ public:
//! return length of public keys in this domain
virtual unsigned int PublicKeyLength() const =0;
//! generate private key
- /*! \pre size of privateKey == PrivateKeyLength() */
+ /*! re size of privateKey == PrivateKeyLength() */
virtual void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
//! generate public key
- /*! \pre size of publicKey == PublicKeyLength() */
+ /*! re size of publicKey == PublicKeyLength() */
virtual void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
//! generate private/public key pair
/*! \note equivalent to calling GeneratePrivateKey() and then GeneratePublicKey() */
virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
//! derive agreed value from your private key and couterparty's public key, return false in case of failure
/*! \note If you have previously validated the public key, use validateOtherPublicKey=false to save time.
- \pre size of agreedValue == AgreedValueLength()
- \pre length of privateKey == PrivateKeyLength()
- \pre length of otherPublicKey == PublicKeyLength()
+ re size of agreedValue == AgreedValueLength()
+ re length of privateKey == PrivateKeyLength()
+ re length of otherPublicKey == PublicKeyLength()
*/
virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0;
@@ -2275,10 +2420,10 @@ public:
//! return length of static public keys in this domain
virtual unsigned int StaticPublicKeyLength() const =0;
//! generate static private key
- /*! \pre size of privateKey == PrivateStaticKeyLength() */
+ /*! re size of privateKey == PrivateStaticKeyLength() */
virtual void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
//! generate static public key
- /*! \pre size of publicKey == PublicStaticKeyLength() */
+ /*! re size of publicKey == PublicStaticKeyLength() */
virtual void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
//! generate private/public key pair
/*! \note equivalent to calling GenerateStaticPrivateKey() and then GenerateStaticPublicKey() */
@@ -2289,10 +2434,10 @@ public:
//! return length of ephemeral public keys in this domain
virtual unsigned int EphemeralPublicKeyLength() const =0;
//! generate ephemeral private key
- /*! \pre size of privateKey == PrivateEphemeralKeyLength() */
+ /*! re size of privateKey == PrivateEphemeralKeyLength() */
virtual void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
//! generate ephemeral public key
- /*! \pre size of publicKey == PublicEphemeralKeyLength() */
+ /*! re size of publicKey == PublicEphemeralKeyLength() */
virtual void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
//! generate private/public key pair
/*! \note equivalent to calling GenerateEphemeralPrivateKey() and then GenerateEphemeralPublicKey() */
@@ -2301,11 +2446,11 @@ public:
//! derive agreed value from your private keys and couterparty's public keys, return false in case of failure
/*! \note The ephemeral public key will always be validated.
If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time.
- \pre size of agreedValue == AgreedValueLength()
- \pre length of staticPrivateKey == StaticPrivateKeyLength()
- \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength()
- \pre length of staticOtherPublicKey == StaticPublicKeyLength()
- \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength()
+ re size of agreedValue == AgreedValueLength()
+ re length of staticPrivateKey == StaticPrivateKeyLength()
+ re length of ephemeralPrivateKey == EphemeralPrivateKeyLength()
+ re length of staticOtherPublicKey == StaticPublicKeyLength()
+ re length of ephemeralOtherPublicKey == EphemeralPublicKeyLength()
*/
virtual bool Agree(byte *agreedValue,
const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
@@ -2436,7 +2581,7 @@ public:
};
#endif
-//! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation
+//! \brief Exception thrown when an ASN1 BER decoing error is encountered
class CRYPTOPP_DLL BERDecodeErr : public InvalidArgument
{
public:
@@ -2445,16 +2590,28 @@ public:
};
//! \brief Interface for encoding and decoding ASN1 objects
+//! \details Each class that derives from ASN1Object should provide a serialization format
+//! that controls subobject layout. Most of the time the serialization format is
+//! taken from a standard, like P1363 or an RFC.
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1Object
{
public:
virtual ~ASN1Object() {}
- //! decode this object from a BufferedTransformation, using BER (Basic Encoding Rules)
+
+ //! \brief Decode this object from a BufferedTransformation
+ //! \param bt BufferedTransformation object
+ //! \details Uses Basic Encoding Rules (BER)
virtual void BERDecode(BufferedTransformation &bt) =0;
- //! encode this object into a BufferedTransformation, using DER (Distinguished Encoding Rules)
+
+ //! \brief Encode this object into a BufferedTransformation
+ //! \param bt BufferedTransformation object
+ //! \details Uses Distinguished Encoding Rules (DER)
virtual void DEREncode(BufferedTransformation &bt) const =0;
- //! encode this object into a BufferedTransformation, using BER
- /*! this may be useful if DEREncode() would be too inefficient */
+
+ //! \brief Encode this object into a BufferedTransformation
+ //! \param bt BufferedTransformation object
+ //! \details Uses Basic Encoding Rules (BER).
+ //! \details This may be useful if DEREncode() would be too inefficient.
virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);}
};
diff --git a/datatest.cpp b/datatest.cpp
index 2c838cfd..b4656541 100644
--- a/datatest.cpp
+++ b/datatest.cpp
@@ -23,6 +23,10 @@
# pragma strict_gs_check (on)
#endif
+#if defined(__COVERITY__)
+extern "C" void __coverity_tainted_data_sanitize__(void *);
+#endif
+
USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)
@@ -579,7 +583,7 @@ void TestDigestOrMAC(TestData &v, bool testDigest)
{
int digestSize = -1;
if (test == "VerifyTruncated")
- pairs.GetIntValue(Name::DigestSize(), digestSize);
+ digestSize = pairs.GetIntValueWithDefault(Name::DigestSize(), digestSize);
HashVerificationFilter verifierFilter(*pHash, NULL, HashVerificationFilter::HASH_AT_BEGIN, digestSize);
PutDecodedDatumInto(v, digestName, verifierFilter);
PutDecodedDatumInto(v, "Message", verifierFilter);
@@ -628,6 +632,12 @@ bool GetField(std::istream &is, std::string &name, std::string &value)
{
name.resize(0); // GCC workaround: 2.95.3 doesn't have clear()
is >> name;
+
+#if defined(__COVERITY__)
+ // The datafile being read is in /usr/share, and it protected by filesystem ACLs
+ // __coverity_tainted_data_sanitize__(reinterpret_cast<void*>(&name));
+#endif
+
if (name.empty())
return false;
diff --git a/default.h b/default.h
index 4224a450..b4897e72 100644
--- a/default.h
+++ b/default.h
@@ -1,3 +1,9 @@
+// default.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile default.h
+//! \brief Classes for DefaultEncryptor, DefaultEncryptorWithMAC and decryptors
+
#ifndef CRYPTOPP_DEFAULT_H
#define CRYPTOPP_DEFAULT_H
diff --git a/des.h b/des.h
index a6aaa79d..92f3da7c 100644
--- a/des.h
+++ b/des.h
@@ -1,9 +1,12 @@
+// des.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile des.h
+//! \brief Classes for DES, 2-key and 3-key Triple-DES
+
#ifndef CRYPTOPP_DES_H
#define CRYPTOPP_DES_H
-/** \file
-*/
-
#include "seckey.h"
#include "secblock.h"
diff --git a/dh.cpp b/dh.cpp
index b0b2e7c8..1862f5df 100644
--- a/dh.cpp
+++ b/dh.cpp
@@ -8,11 +8,13 @@
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void DH_TestInstantiations()
{
DH dh1;
DH dh2(NullRNG(), 10);
}
+#endif
NAMESPACE_END
diff --git a/dh.h b/dh.h
index 399ff040..fc23e9fb 100644
--- a/dh.h
+++ b/dh.h
@@ -1,9 +1,12 @@
+// dh.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile dh.h
+//! \brief Classes for Diffie-Hellman key exchange
+
#ifndef CRYPTOPP_DH_H
#define CRYPTOPP_DH_H
-/** \file
-*/
-
#include "cryptlib.h"
#include "gfpcrypt.h"
diff --git a/dh2.cpp b/dh2.cpp
index 4a292af3..faa5429c 100644
--- a/dh2.cpp
+++ b/dh2.cpp
@@ -5,10 +5,12 @@
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void DH2_TestInstantiations()
{
DH2 dh(*(SimpleKeyAgreementDomain*)NULL);
}
+#endif
bool DH2::Agree(byte *agreedValue,
const byte *staticSecretKey, const byte *ephemeralSecretKey,
diff --git a/dh2.h b/dh2.h
index e5191156..3de79e18 100644
--- a/dh2.h
+++ b/dh2.h
@@ -1,9 +1,12 @@
+// dh2.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile dh2.h
+//! \brief Classes for Diffie-Hellman authenticated key exchange
+
#ifndef CRYPTOPP_DH2_H
#define CRYPTOPP_DH2_H
-/** \file
-*/
-
#include "cryptlib.h"
NAMESPACE_BEGIN(CryptoPP)
diff --git a/dll.h b/dll.h
index bd860941..3f103fda 100644
--- a/dll.h
+++ b/dll.h
@@ -1,3 +1,9 @@
+// dll.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile dll.h
+//! \brief Functions and definitions required for building the FIPS-140 DLL on Windows
+
#ifndef CRYPTOPP_DLL_H
#define CRYPTOPP_DLL_H
diff --git a/dmac.h b/dmac.h
index 52c36a9c..59713511 100644
--- a/dmac.h
+++ b/dmac.h
@@ -1,3 +1,9 @@
+// dmac.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile dmac.h
+//! \brief Classes for DMAC message authentication code
+
#ifndef CRYPTOPP_DMAC_H
#define CRYPTOPP_DMAC_H
@@ -14,7 +20,7 @@ public:
CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE)
- DMAC_Base() {}
+ DMAC_Base() : m_subkeylength(0), m_counter(0) {}
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
void Update(const byte *input, size_t length);
diff --git a/dsa.h b/dsa.h
index 9c9b50cb..3b530f27 100644
--- a/dsa.h
+++ b/dsa.h
@@ -1,9 +1,12 @@
+// dsa.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile dsa.h
+//! \brief Classes for DSA signature algorithm
+
#ifndef CRYPTOPP_DSA_H
#define CRYPTOPP_DSA_H
-/** \file
-*/
-
#include "cryptlib.h"
NAMESPACE_BEGIN(CryptoPP)
diff --git a/eax.h b/eax.h
index 128d0790..c9e3cf4e 100644
--- a/eax.h
+++ b/eax.h
@@ -1,3 +1,9 @@
+// eax.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile eax.h
+//! \brief EAX block cipher mode of operation
+
#ifndef CRYPTOPP_EAX_H
#define CRYPTOPP_EAX_H
@@ -7,7 +13,9 @@
NAMESPACE_BEGIN(CryptoPP)
-//! .
+//! \class EAX_Base
+//! \brief EAX block cipher mode of operation
+//! \details Implementations and overrides in \p EAX_Base apply to both \p ENCRYPTION and \p DECRYPTION directions
class CRYPTOPP_NO_VTABLE EAX_Base : public AuthenticatedSymmetricCipherBase
{
public:
@@ -59,7 +67,13 @@ protected:
CTR_Mode_ExternalCipher::Encryption m_ctr;
};
-//! .
+//! \class EAX_Final
+//! \brief Class specific methods used to operate the cipher.
+//! \tparam T_BlockCipher block cipher
+//! \tparam T_IsEncryption direction in which to operate the cipher
+//! \details Implementations and overrides in \p GCM_Final apply to either
+//! \p ENCRYPTION or \p DECRYPTION, depending on the template parameter \p T_IsEncryption.
+//! \details \p EAX_Final does not use inner classes \p Enc and \p Dec.
template <class T_BlockCipher, bool T_IsEncryption>
class EAX_Final : public EAX_Base
{
@@ -78,7 +92,14 @@ private:
#undef EAX
#endif
-/// <a href="http://www.cryptolounge.org/wiki/EAX">EAX</a>
+//! \class EAX
+//! \brief The EAX block cipher mode of operation
+//! \details EAX is an Authenticated Encryption with Associated Data (AEAD) block
+//! cipher mode of operation designed to simultaneously provide both authentication
+//! and privacy of the message.
+//! \tparam T_BlockCipher block cipher
+//! \details \p EAX provides the \p Encryption and \p Decryption typedef.
+//! \sa <a href="http://www.cryptolounge.org/wiki/EAX">EAX</a> at the Crypto Lounge
template <class T_BlockCipher>
struct EAX : public AuthenticatedSymmetricCipherDocumentation
{
diff --git a/ec2n.h b/ec2n.h
index c9cc8c88..826b2e43 100644
--- a/ec2n.h
+++ b/ec2n.h
@@ -1,3 +1,10 @@
+// ec2n.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile ec2n.h
+//! \brief Classes for Elliptic Curves over binary fields
+
+
#ifndef CRYPTOPP_EC2N_H
#define CRYPTOPP_EC2N_H
diff --git a/eccrypto.cpp b/eccrypto.cpp
index 039005fa..3ac4f194 100644
--- a/eccrypto.cpp
+++ b/eccrypto.cpp
@@ -31,6 +31,7 @@
NAMESPACE_BEGIN(CryptoPP)
#if 0
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
static void ECDSA_TestInstantiations()
{
ECDSA<EC2N>::Signer t1;
@@ -43,6 +44,7 @@ static void ECDSA_TestInstantiations()
ECMQV<ECP>::Domain t8;
}
#endif
+#endif
// VC60 workaround: complains when these functions are put into an anonymous namespace
static Integer ConvertToInteger(const PolynomialMod2 &x)
diff --git a/eccrypto.h b/eccrypto.h
index 3487793f..1d7eab65 100644
--- a/eccrypto.h
+++ b/eccrypto.h
@@ -299,7 +299,7 @@ struct ECIES
virtual ~ECIES() {}
#endif
-#if (CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20800)
+#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 30000)
} __attribute__((deprecated ("ECIES will be changing in the near future due to (1) an implementation bug and (2) an interop issue.")));
#elif (CRYPTOPP_GCC_VERSION )
} __attribute__((deprecated));
diff --git a/ecp.cpp b/ecp.cpp
index fe01ba28..8c821304 100644
--- a/ecp.cpp
+++ b/ecp.cpp
@@ -8,6 +8,7 @@
#include "asn.h"
#include "integer.h"
#include "nbtheory.h"
+#include "modarith.h"
#include "filters.h"
#include "algebra.cpp"
diff --git a/ecp.h b/ecp.h
index 19de0868..92cb5a1a 100644
--- a/ecp.h
+++ b/ecp.h
@@ -1,3 +1,9 @@
+// ecp.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile ecp.h
+//! \brief Classes for Elliptic Curves over prime fields
+
#ifndef CRYPTOPP_ECP_H
#define CRYPTOPP_ECP_H
diff --git a/elgamal.cpp b/elgamal.cpp
index ff0a1dcc..2deb6004 100644
--- a/elgamal.cpp
+++ b/elgamal.cpp
@@ -7,11 +7,13 @@
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void ElGamal_TestInstantiations()
{
ElGamalEncryptor test1(1, 1, 1);
ElGamalDecryptor test2(NullRNG(), 123);
ElGamalEncryptor test3(test2);
}
+#endif
NAMESPACE_END
diff --git a/esign.cpp b/esign.cpp
index e9525c04..9b68d97a 100644
--- a/esign.cpp
+++ b/esign.cpp
@@ -18,6 +18,7 @@
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void ESIGN_TestInstantiations()
{
ESIGN<SHA>::Verifier x1(1, 1);
@@ -31,6 +32,7 @@ void ESIGN_TestInstantiations()
x3 = ESIGN<SHA>::Verifier(x2);
x4 = x2.GetKey();
}
+#endif
void ESIGNFunction::BERDecode(BufferedTransformation &bt)
{
diff --git a/esign.h b/esign.h
index 1e74fce5..e9969d3e 100644
--- a/esign.h
+++ b/esign.h
@@ -45,7 +45,8 @@ public:
void SetPublicExponent(const Integer &e) {m_e = e;}
protected:
- unsigned int GetK() const {return m_n.BitCount()/3-1;}
+ // Covertiy finding on overflow. The library allows small values for research purposes.
+ unsigned int GetK() const {return SaturatingSubtract(m_n.BitCount()/3, 1U);}
Integer m_n, m_e;
};
diff --git a/files.cpp b/files.cpp
index aaffffc2..5ac45c6c 100644
--- a/files.cpp
+++ b/files.cpp
@@ -10,7 +10,7 @@
NAMESPACE_BEGIN(CryptoPP)
-#ifndef NDEBUG
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void Files_TestInstantiations()
{
FileStore f0;
diff --git a/files.h b/files.h
index 31742383..d17c5dd8 100644
--- a/files.h
+++ b/files.h
@@ -23,11 +23,11 @@ public:
class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileStore: error opening file for reading: " + filename) {}};
class ReadErr : public Err {public: ReadErr() : Err("FileStore: error reading file") {}};
- FileStore() : m_stream(NULL) {}
- FileStore(std::istream &in)
+ FileStore() : m_stream(NULL), m_space(NULL), m_len(0), m_waiting(0) {}
+ FileStore(std::istream &in) : m_stream(NULL), m_space(NULL), m_len(0), m_waiting(0)
{StoreInitialize(MakeParameters(Name::InputStreamPointer(), &in));}
- FileStore(const char *filename)
- {StoreInitialize(MakeParameters(Name::InputFileName(), filename));}
+ FileStore(const char *filename) : m_stream(NULL), m_space(NULL), m_len(0), m_waiting(0)
+ {StoreInitialize(MakeParameters(Name::InputFileName(), filename ? filename : ""));}
#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400
//! specify file with Unicode name. On non-Windows OS, this function assumes that setlocale() has been called.
FileStore(const wchar_t *filename)
diff --git a/filters.cpp b/filters.cpp
index 76394f9e..6b09a02a 100644
--- a/filters.cpp
+++ b/filters.cpp
@@ -18,10 +18,9 @@
#include "fltrimpl.h"
#include "argnames.h"
#include "smartptr.h"
+#include "stdcpp.h"
#include "misc.h"
-#include <functional>
-
NAMESPACE_BEGIN(CryptoPP)
Filter::Filter(BufferedTransformation *attachment)
@@ -83,9 +82,12 @@ bool Filter::Flush(bool hardFlush, int propagation, bool blocking)
case 0:
if (IsolatedFlush(hardFlush, blocking))
return true;
+ // fall through
case 1:
if (OutputFlush(1, hardFlush, propagation, blocking))
return true;
+ // fall through
+ default: ;;
}
return false;
}
@@ -97,9 +99,12 @@ bool Filter::MessageSeriesEnd(int propagation, bool blocking)
case 0:
if (IsolatedMessageSeriesEnd(blocking))
return true;
+ // fall through
case 1:
if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking))
return true;
+ // fall through
+ default: ;;
}
return false;
}
@@ -434,7 +439,8 @@ size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length
m_firstInputDone = false;
m_queue.ResetQueue(1, m_firstSize);
- Output(1, NULL, 0, messageEnd, blocking);
+ // Cast to void to supress Coverity finding
+ (void)Output(1, NULL, 0, messageEnd, blocking);
}
return 0;
}
@@ -581,8 +587,8 @@ size_t ArrayXorSink::Put2(const byte *begin, size_t length, int messageEnd, bool
// *************************************************************
StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool allowAuthenticatedSymmetricCipher)
- : FilterWithBufferedInput(attachment)
- , m_cipher(c)
+ : FilterWithBufferedInput(attachment)
+ , m_cipher(c), m_padding(DEFAULT_PADDING), m_optimalBufferSize(0)
{
assert(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize());
@@ -755,7 +761,8 @@ void StreamTransformationFilter::LastPut(const byte *inString, size_t length)
// *************************************************************
HashFilter::HashFilter(HashTransformation &hm, BufferedTransformation *attachment, bool putMessage, int truncatedDigestSize, const std::string &messagePutChannel, const std::string &hashPutChannel)
- : m_hashModule(hm), m_putMessage(putMessage), m_messagePutChannel(messagePutChannel), m_hashPutChannel(hashPutChannel)
+ : m_hashModule(hm), m_putMessage(putMessage), m_digestSize(0), m_space(NULL)
+ , m_messagePutChannel(messagePutChannel), m_hashPutChannel(hashPutChannel)
{
m_digestSize = truncatedDigestSize < 0 ? m_hashModule.DigestSize() : truncatedDigestSize;
Detach(attachment);
@@ -790,7 +797,7 @@ size_t HashFilter::Put2(const byte *inString, size_t length, int messageEnd, boo
HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment, word32 flags, int truncatedDigestSize)
: FilterWithBufferedInput(attachment)
- , m_hashModule(hm)
+ , m_hashModule(hm), m_flags(0), m_digestSize(0), m_verified(false)
{
IsolatedInitialize(MakeParameters(Name::HashVerificationFilterFlags(), flags)(Name::TruncatedDigestSize(), truncatedDigestSize));
}
@@ -980,7 +987,7 @@ size_t SignerFilter::Put2(const byte *inString, size_t length, int messageEnd, b
SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment, word32 flags)
: FilterWithBufferedInput(attachment)
- , m_verifier(verifier)
+ , m_verifier(verifier), m_flags(0), m_verified(0)
{
IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags));
}
diff --git a/filters.h b/filters.h
index 58027683..e6aaf0bb 100644
--- a/filters.h
+++ b/filters.h
@@ -1,3 +1,9 @@
+// filters.h - written and placed in the public domain by Wei Dai
+
+//! \file filters.h
+//! \brief Implementation of BufferedTransformation's attachment interface in cryptlib.h.
+//! \nosubgrouping
+
#ifndef CRYPTOPP_FILTERS_H
#define CRYPTOPP_FILTERS_H
@@ -21,24 +27,55 @@
NAMESPACE_BEGIN(CryptoPP)
-/// provides an implementation of BufferedTransformation's attachment interface
+//! \class Filter
+//! \brief Implementation of BufferedTransformation's attachment interface
+//! \details Filter is a cornerstone of the Pipeline trinitiy. Data flows from
+//! Sources, through Filters, and then terminates in Sinks. The difference
+//! between a Source and Filter is a Source \a pumps data, while a Filter does
+//! not. The difference between a Filter and a Sink is a Filter allows an
+//! attached transformation, while a Sink does not.
+//! \details See the discussion of BufferedTransformation in cryptlib.h for
+//! more details.
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Filter : public BufferedTransformation, public NotCopyable
{
public:
+ //! \brief Construct a Filter
+ //! \param attachment the filter's attached transformation
+ //! \details attachment can be \p NULL.
Filter(BufferedTransformation *attachment = NULL);
+ //! \brief Determine if attachable
+ //! \returns \p true if the object allows attached transformations, \p false otherwise.
+ //! \note Source and Filter offer attached transformations; while Sink does not.
bool Attachable() {return true;}
+
+ //! \brief Retrieve attached transformation
+ //! \returns pointer to a BufferedTransformation if there is an attached transformation, \p NULL otherwise.
BufferedTransformation *AttachedTransformation();
+
+ //! \brief Retrieve attached transformation
+ //! \returns pointer to a BufferedTransformation if there is an attached transformation, \p NULL otherwise.
const BufferedTransformation *AttachedTransformation() const;
+
+ //! \brief Replace an attached transformation
+ //! \param newAttachment pointer to a new BufferedTransformation
+ //! \details newAttachment cab ne a single filter, a chain of filters or \p NULL.
+ //! Pass \p NULL to remove an existing BufferedTransformation or chain of filters
void Detach(BufferedTransformation *newAttachment = NULL);
-
+
+ // See the documentation for BufferedTransformation in cryptlib.h
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
+ // See the documentation for BufferedTransformation in cryptlib.h
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
+#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
+ virtual ~Filter() {}
+#endif
+
protected:
virtual BufferedTransformation * NewDefaultAttachment() const;
void Insert(Filter *nextFilter); // insert filter after this one
@@ -48,10 +85,65 @@ protected:
void PropagateInitialize(const NameValuePairs &parameters, int propagation);
+ //! \brief Forward processed data on to attached transformation
+ //! \param outputSite unknown, system crash between keyboard and chair...
+ //! \param inString the byte buffer to process
+ //! \param length the size of the string, in bytes
+ //! \param messageEnd means how many filters to signal MessageEnd() to, including this one
+ //! \param blocking specifies whether the object should block when processing input
+ //! \param channel the channel to process the data
+ //! \returns 0 indicates all bytes were processed during the call. Non-0 indicates the
+ //! number of bytes that were \a not processed.
size_t Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
+
+ //! \brief Output multiple bytes that may be modified by callee.
+ //! \param outputSite unknown, system crash between keyboard and chair...
+ //! \param inString the byte buffer to process
+ //! \param length the size of the string, in bytes
+ //! \param messageEnd means how many filters to signal MessageEnd() to, including this one
+ //! \param blocking specifies whether the object should block when processing input
+ //! \param channel the channel to process the data
+ //! \returns 0 indicates all bytes were processed during the call. Non-0 indicates the
+ //! number of bytes that were \a not processed
size_t OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
+
+ //! \brief Signals the end of messages to the object
+ //! \param outputSite unknown, system crash between keyboard and chair...
+ //! \param propagation the number of attached transformations the MessageEnd() signal should be passed
+ //! \param blocking specifies whether the object should block when processing input
+ //! \param channel the channel to process the data
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
+
+ //! \brief Flush buffered input and/or output, with signal propagation
+ //! \param outputSite unknown, system crash between keyboard and chair...
+ //! \param hardFlush is used to indicate whether all data should be flushed
+ //! \param propagation the number of attached transformations the Flush() signal should be passed
+ //! \param blocking specifies whether the object should block when processing input
+ //! \param channel the channel to process the data
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
+ //! \note Hard flushes must be used with care. It means try to process and output everything, even if
+ //! there may not be enough data to complete the action. For example, hard flushing a HexDecoder
+ //! would cause an error if you do it after inputing an odd number of hex encoded characters.
+ //! \note For some types of filters, like ZlibDecompressor, hard flushes can only
+ //! be done at "synchronization points". These synchronization points are positions in the data
+ //! stream that are created by hard flushes on the corresponding reverse filters, in this
+ //! example ZlibCompressor. This is useful when zlib compressed data is moved across a
+ //! network in packets and compression state is preserved across packets, as in the SSH2 protocol.
bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
+
+ //! \brief Marks the end of a series of messages, with signal propagation
+ //! \param outputSite unknown, system crash between keyboard and chair...
+ //! \param propagation the number of attached transformations the MessageSeriesEnd() signal should be passed
+ //! \param blocking specifies whether the object should block when processing input
+ //! \param channel the channel to process the data
+ //! \details Each object that receives the signal will perform its processing, decrement
+ //! propagation, and then pass the signal on to attached transformations if the value is not 0.
+ //! \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
+ //! object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
+ //! \note There should be a MessageEnd() immediately before MessageSeriesEnd().
bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
private:
@@ -62,6 +154,8 @@ protected:
int m_continueAt;
};
+//! \struct FilterPutSpaceHelper
+
struct CRYPTOPP_DLL FilterPutSpaceHelper
{
// desiredSize is how much to ask target, bufferSize is how much to allocate in m_tempSpace
@@ -112,7 +206,7 @@ public:
byte * CreatePutSpace(size_t &size)
{return AttachedTransformation()->CreatePutSpace(size);}
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking);
bool IsolatedMessageSeriesEnd(bool blocking);
@@ -275,18 +369,35 @@ protected:
ByteQueue m_inQueue;
};
+//! \struct BlockPaddingSchemeDef
+//! \detils Padding schemes used for block ciphers.
struct BlockPaddingSchemeDef
{
- enum BlockPaddingScheme {NO_PADDING, ZEROS_PADDING, PKCS_PADDING, ONE_AND_ZEROS_PADDING, DEFAULT_PADDING};
+ //! \enum BlockPaddingScheme
+ //! \detils Padding schemes used for block ciphers.
+ //! \details DEFAULT_PADDING means PKCS_PADDING if <tt>cipher.MandatoryBlockSize() > 1 &&
+ //! cipher.MinLastBlockSize() == 0</tt>, which holds for ECB or CBC mode. Otherwise,
+ //! NO_PADDING for modes like OFB, CFB, CTR, CBC-CTS.
+ //! \sa <A HREF="http://www.weidai.com/scan-mirror/csp.html">Block Cipher Padding</A> for
+ //! additional details.
+ enum BlockPaddingScheme {
+ //! \brief No padding added to a block
+ NO_PADDING,
+ //! \brief 0's padding added to a block
+ ZEROS_PADDING,
+ //! \brief PKCS #5 padding added to a block
+ PKCS_PADDING,
+ //! \brief 1 and 0's padding added to a block
+ ONE_AND_ZEROS_PADDING,
+ //! \brief Default padding acheme
+ DEFAULT_PADDING
+ };
};
//! Filter Wrapper for StreamTransformation, optionally handling padding/unpadding when needed
class CRYPTOPP_DLL StreamTransformationFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef, private FilterPutSpaceHelper
{
public:
- /*! DEFAULT_PADDING means PKCS_PADDING if c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0 (e.g. ECB or CBC mode),
- otherwise NO_PADDING (OFB, CFB, CTR, CBC-CTS modes).
- See http://www.weidai.com/scan-mirror/csp.html for details of the padding schemes. */
StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULL, BlockPaddingScheme padding = DEFAULT_PADDING, bool allowAuthenticatedSymmetricCipher = false);
std::string AlgorithmName() const {return m_cipher.AlgorithmName();}
@@ -317,7 +428,7 @@ public:
std::string AlgorithmName() const {return m_hashModule.AlgorithmName();}
void IsolatedInitialize(const NameValuePairs &parameters);
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
byte * CreatePutSpace(size_t &size) {return m_hashModule.CreateUpdateSpace(size);}
private:
@@ -415,7 +526,7 @@ public:
std::string AlgorithmName() const {return m_signer.AlgorithmName();}
void IsolatedInitialize(const NameValuePairs &parameters);
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
private:
RandomNumberGenerator &m_rng;
@@ -463,11 +574,17 @@ typedef SignatureVerificationFilter VerifierFilter; // for backwards compatibili
class CRYPTOPP_DLL Redirector : public CustomSignalPropagation<Sink>
{
public:
+ //! \brief Controls signal propagation behavior
enum Behavior
{
+ //! \brief Pass data only
DATA_ONLY = 0x00,
+ //! \brief Pass signals
PASS_SIGNALS = 0x01,
+ //! \brief Pass wait events
PASS_WAIT_OBJECTS = 0x02,
+ //! \brief Pass everything
+ //! \details PASS_EVERYTHING is default
PASS_EVERYTHING = PASS_SIGNALS | PASS_WAIT_OBJECTS
};
@@ -491,8 +608,8 @@ public:
void Initialize(const NameValuePairs &parameters, int propagation);
byte * CreatePutSpace(size_t &size)
{return m_target ? m_target->CreatePutSpace(size) : (byte *)(size=0, NULL);}
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
- {return m_target ? m_target->Put2(begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
+ {return m_target ? m_target->Put2(inString, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
{return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;}
bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
@@ -530,8 +647,8 @@ public:
byte * CreatePutSpace(size_t &size)
{return m_owner.AttachedTransformation()->CreatePutSpace(size);}
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
- {return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
+ {return m_owner.AttachedTransformation()->Put2(inString, length, m_passSignal ? messageEnd : 0, blocking);}
size_t PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
@@ -616,7 +733,7 @@ public:
void IsolatedInitialize(const NameValuePairs &parameters)
{if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");}
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
{
CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking);
if (length > 0)
@@ -624,7 +741,7 @@ public:
typename T::size_type size = m_output->size();
if (length < size && size + length > m_output->capacity())
m_output->reserve(2*size);
- m_output->append((const char_type *)begin, (const char_type *)begin+length);
+ m_output->append((const char_type *)inString, (const char_type *)inString+length);
}
return 0;
}
@@ -648,7 +765,7 @@ public:
: m_rng(&rng) {}
void IsolatedInitialize(const NameValuePairs &parameters);
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
private:
RandomNumberGenerator *m_rng;
@@ -668,7 +785,7 @@ public:
void IsolatedInitialize(const NameValuePairs &parameters);
byte * CreatePutSpace(size_t &size);
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
protected:
byte *m_buf;
@@ -683,7 +800,7 @@ public:
ArrayXorSink(byte *buf, size_t size)
: ArraySink(buf, size) {}
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
byte * CreatePutSpace(size_t &size) {return BufferedTransformation::CreatePutSpace(size);}
};
@@ -750,13 +867,25 @@ private:
lword m_size;
};
-//! A Filter that pumps data into its attachment as input
+//! \class Source
+//! \brief Implementation of BufferedTransformation's attachment interface
+//! \details Source is a cornerstone of the Pipeline trinitiy. Data flows from
+//! Sources, through Filters, and then terminates in Sinks. The difference
+//! between a Source and Filter is a Source \a pumps data, while a Filter does
+//! not. The difference between a Filter and a Sink is a Filter allows an
+//! attached transformation, while a Sink does not.
+//! \details See the discussion of BufferedTransformation in cryptlib.h for
+//! more details.
+//! \sa Store and SourceTemplate
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Source : public InputRejecting<Filter>
{
public:
Source(BufferedTransformation *attachment = NULL)
{Source::Detach(attachment);}
+ //! \name PIPELINE
+ //@{
+
lword Pump(lword pumpMax=size_t(SIZE_MAX))
{Pump2(pumpMax); return pumpMax;}
unsigned int PumpMessages(unsigned int count=UINT_MAX)
@@ -768,6 +897,12 @@ public:
virtual size_t PumpAll2(bool blocking=true);
virtual bool SourceExhausted() const =0;
+ //@}
+
+#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
+ virtual ~Source() {}
+#endif
+
protected:
void SourceInitialize(bool pumpAll, const NameValuePairs &parameters)
{
@@ -777,7 +912,9 @@ protected:
}
};
-//! Turn a Store into a Source
+//! \class SourceTemplate
+//! \brief Transform a Store into a Source
+//! \tparam T the class or type
template <class T>
class SourceTemplate : public Source
{
@@ -803,7 +940,8 @@ protected:
T m_store;
};
-//! string-based implementation of Source interface
+//! \class SourceTemplate
+//! \brief String-based implementation of the Source interface
class CRYPTOPP_DLL StringSource : public SourceTemplate<StringStore>
{
public:
diff --git a/gcm.cpp b/gcm.cpp
index 2c694733..4acb0c56 100644
--- a/gcm.cpp
+++ b/gcm.cpp
@@ -145,7 +145,8 @@ void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const
#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
if (HasCLMUL())
{
- params.GetIntValue(Name::TableSize(), tableSize); // avoid "parameter not used" error
+ // Avoid "parameter not used" error and suppress Coverity finding
+ (void)params.GetIntValue(Name::TableSize(), tableSize);
tableSize = s_clmulTableSizeInBlocks * REQUIRED_BLOCKSIZE;
}
else
@@ -579,7 +580,7 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
#ifdef __GNUC__
__asm__ __volatile__
(
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
#elif defined(CRYPTOPP_GENERATE_X64_MASM)
ALIGN 8
GCM_AuthenticateBlocks_2K PROC FRAME
@@ -683,7 +684,13 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
AS2( pxor xmm5, xmm2 )
AS2( psrldq xmm0, 15 )
- AS2( movd WORD_REG(di), xmm0 )
+#if defined(CRYPTOPP_APPLE_CLANG_VERSION)
+ AS2( mov WORD_REG(di), xmm0 )
+#elif defined(CRYPTOPP_CLANG_VERSION)
+ AS2( movd edi, xmm0 )
+#else
+ AS2( movd WORD_REG(di), xmm0 )
+#endif
AS2( movzx eax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
AS2( shl eax, 8 )
@@ -692,21 +699,33 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
AS2( pxor xmm4, xmm5 )
AS2( psrldq xmm1, 15 )
- AS2( movd WORD_REG(di), xmm1 )
+#if defined(CRYPTOPP_APPLE_CLANG_VERSION)
+ AS2( mov WORD_REG(di), xmm1 )
+#elif defined(CRYPTOPP_CLANG_VERSION)
+ AS2( movd edi, xmm1 )
+#else
+ AS2( movd WORD_REG(di), xmm1 )
+#endif
AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
AS2( shl eax, 8 )
AS2( psrldq xmm0, 15 )
- AS2( movd WORD_REG(di), xmm0 )
+#if defined(CRYPTOPP_APPLE_CLANG_VERSION)
+ AS2( mov WORD_REG(di), xmm0 )
+#elif defined(CRYPTOPP_CLANG_VERSION)
+ AS2( movd edi, xmm0 )
+#else
+ AS2( movd WORD_REG(di), xmm0 )
+#endif
AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
AS2( movd xmm0, eax )
AS2( pxor xmm0, xmm4 )
- AS2( add WORD_REG(cx), 16 )
- AS2( sub WORD_REG(dx), 1 )
+ AS2( add WORD_REG(cx), 16 )
+ AS2( sub WORD_REG(dx), 1 )
ASJ( jnz, 0, b )
- AS2( movdqa [WORD_REG(si)], xmm0 )
+ AS2( movdqa [WORD_REG(si)], xmm0 )
#if CRYPTOPP_BOOL_X32
AS1(pop rbp)
@@ -717,7 +736,7 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
#endif
#ifdef __GNUC__
- ".att_syntax prefix;"
+ ATT_PREFIX
:
: "c" (data), "d" (len/16), "S" (hashBuffer), "D" (s_reductionTable)
: "memory", "cc", "%eax"
@@ -740,7 +759,7 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
#ifdef __GNUC__
__asm__ __volatile__
(
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
#elif defined(CRYPTOPP_GENERATE_X64_MASM)
ALIGN 8
GCM_AuthenticateBlocks_64K PROC FRAME
@@ -794,7 +813,7 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len)
AS2( movdqa [WORD_REG(si)], xmm0 )
#ifdef __GNUC__
- ".att_syntax prefix;"
+ ATT_PREFIX
:
: "c" (data), "d" (len/16), "S" (hashBuffer)
: "memory", "cc", "%edi", "%eax"
diff --git a/gcm.h b/gcm.h
index 0b32524f..8889d919 100644
--- a/gcm.h
+++ b/gcm.h
@@ -1,3 +1,9 @@
+// gcm.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile gcm.h
+//! \brief GCM block cipher mode of operation
+
#ifndef CRYPTOPP_GCM_H
#define CRYPTOPP_GCM_H
@@ -6,10 +12,13 @@
NAMESPACE_BEGIN(CryptoPP)
-//! .
+//! \enum GCM_TablesOption
+//! \brief Use either 2K or 64K size tables.
enum GCM_TablesOption {GCM_2K_Tables, GCM_64K_Tables};
-//! .
+//! \class GCM_Base
+//! \brief CCM block cipher mode of operation.
+//! \details Implementations and overrides in \p GCM_Base apply to both \p ENCRYPTION and \p DECRYPTION directions
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase
{
public:
@@ -77,7 +86,14 @@ protected:
enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16};
};
-//! .
+//! \class GCM_Final
+//! \brief Class specific methods used to operate the cipher.
+//! \tparam T_BlockCipher block cipher
+//! \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables
+//! \tparam T_IsEncryption direction in which to operate the cipher
+//! \details Implementations and overrides in \p GCM_Final apply to either
+//! \p ENCRYPTION or \p DECRYPTION, depending on the template parameter \p T_IsEncryption.
+//! \details \p GCM_Final does not use inner classes \p Enc and \p Dec.
template <class T_BlockCipher, GCM_TablesOption T_TablesOption, bool T_IsEncryption>
class GCM_Final : public GCM_Base
{
@@ -93,7 +109,12 @@ private:
typename T_BlockCipher::Encryption m_cipher;
};
-//! <a href="http://www.cryptolounge.org/wiki/GCM">GCM</a>
+//! \class GCM
+//! \brief The GCM mode of operation
+//! \tparam T_BlockCipher block cipher
+//! \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables
+//! \details \p GCM provides the \p Encryption and \p Decryption typedef.
+//! \sa <a href="http://www.cryptolounge.org/wiki/GCM">GCM</a> at the Crypto Lounge
template <class T_BlockCipher, GCM_TablesOption T_TablesOption=GCM_2K_Tables>
struct GCM : public AuthenticatedSymmetricCipherDocumentation
{
diff --git a/gf2n.cpp b/gf2n.cpp
index a7f2fa0a..e5cf9a50 100644
--- a/gf2n.cpp
+++ b/gf2n.cpp
@@ -7,10 +7,11 @@
#include "cryptlib.h"
#include "algebra.h"
-#include "words.h"
#include "randpool.h"
#include "filters.h"
#include "smartptr.h"
+#include "words.h"
+#include "misc.h"
#include "gf2n.h"
#include "asn.h"
#include "oids.h"
@@ -324,6 +325,11 @@ PolynomialMod2 PolynomialMod2::Modulo(const PolynomialMod2 &b) const
PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n)
{
+#if !defined(NDEBUG)
+ int x; CRYPTOPP_UNUSED(x);
+ assert(SafeConvert(n,x));
+#endif
+
if (!reg.size())
return *this;
@@ -352,8 +358,8 @@ PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n)
return *this;
}
- int shiftWords = n / WORD_BITS;
- int shiftBits = n % WORD_BITS;
+ const int shiftWords = n / WORD_BITS;
+ const int shiftBits = n % WORD_BITS;
if (shiftBits)
{
@@ -369,8 +375,10 @@ PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n)
if (carry)
{
- reg.Grow(reg.size()+shiftWords+1);
- reg[reg.size()-1] = carry;
+ // Thanks to Apatryda, http://github.com/weidai11/cryptopp/issues/64
+ const size_t carryIndex = reg.size();
+ reg.Grow(reg.size()+shiftWords+!!shiftBits);
+ reg[carryIndex] = carry;
}
else
reg.Grow(reg.size()+shiftWords);
@@ -677,6 +685,8 @@ const GF2NT::Element& GF2NT::MultiplicativeInverse(const Element &a) const
b[i] = b[i+1];
b[BitsToWords(m)-1] = 0;
+ // TODO: the shift by "t1+j" (64-bits) is being flagged as potential UB
+ // temp ^= ((temp >> j) & 1) << ((t1 + j) & (sizeof(temp)*8-1));
if (t1 < WORD_BITS)
for (unsigned int j=0; j<WORD_BITS-t1; j++)
temp ^= ((temp >> j) & 1) << (t1 + j);
@@ -703,10 +713,18 @@ const GF2NT::Element& GF2NT::MultiplicativeInverse(const Element &a) const
ShiftWordsRightByBits(b, BitsToWords(m), k);
if (t1 < WORD_BITS)
+ {
for (unsigned int j=0; j<WORD_BITS-t1; j++)
+ {
+ // Coverity finding on shift amount of 'word x << (t1+j)'.
+ assert(t1+j < WORD_BITS);
temp ^= ((temp >> j) & 1) << (t1 + j);
+ }
+ }
else
+ {
b[t1/WORD_BITS-1] ^= temp << t1%WORD_BITS;
+ }
if (t1 % WORD_BITS)
b[t1/WORD_BITS] ^= temp >> (WORD_BITS - t1%WORD_BITS);
diff --git a/gf2n.h b/gf2n.h
index 2dd91d7d..5418377c 100644
--- a/gf2n.h
+++ b/gf2n.h
@@ -112,7 +112,7 @@ public:
byte GetByte(size_t n) const;
//! the zero polynomial will return a degree of -1
- signed int Degree() const {return BitCount()-1;}
+ signed int Degree() const {return (signed int)(BitCount()-1U);}
//! degree + 1
unsigned int CoefficientCount() const {return BitCount();}
//! return coefficient for x^i
diff --git a/gfpcrypt.cpp b/gfpcrypt.cpp
index 5ef17314..84fe17b7 100644
--- a/gfpcrypt.cpp
+++ b/gfpcrypt.cpp
@@ -11,14 +11,16 @@
#ifndef CRYPTOPP_IMPORTS
#include "gfpcrypt.h"
-#include "integer.h"
#include "nbtheory.h"
+#include "modarith.h"
+#include "integer.h"
#include "asn.h"
#include "oids.h"
#include "misc.h"
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void TestInstantiations_gfpcrypt()
{
GDSA<SHA>::Signer test;
@@ -30,6 +32,7 @@ void TestInstantiations_gfpcrypt()
DLIES<>::Encryptor test6;
DLIES<>::Decryptor test7;
}
+#endif
void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
{
diff --git a/gfpcrypt.h b/gfpcrypt.h
index 75d260d1..114fe8da 100644
--- a/gfpcrypt.h
+++ b/gfpcrypt.h
@@ -524,7 +524,9 @@ public:
ConstByteArrayParameter encodingParameters;
parameters.GetValue(Name::EncodingParameters(), encodingParameters);
- xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
+ if (plaintextLength) // Coverity finding
+ xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
+
MAC mac(macKey);
mac.Update(ciphertext, plaintextLength);
mac.Update(encodingParameters.begin(), encodingParameters.size());
@@ -566,7 +568,9 @@ public:
if (!mac.Verify(ciphertext + plaintextLength))
return DecodingResult();
- xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
+ if (plaintextLength) // Coverity finding
+ xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
+
return DecodingResult(plaintextLength);
}
diff --git a/gzip.cpp b/gzip.cpp
index c646ed53..836f63cf 100644
--- a/gzip.cpp
+++ b/gzip.cpp
@@ -37,7 +37,7 @@ void Gzip::WritePoststreamTail()
// *************************************************************
Gunzip::Gunzip(BufferedTransformation *attachment, bool repeat, int propagation)
- : Inflator(attachment, repeat, propagation)
+ : Inflator(attachment, repeat, propagation), m_length(0)
{
}
diff --git a/gzip.h b/gzip.h
index 01a4c960..98d6e26b 100644
--- a/gzip.h
+++ b/gzip.h
@@ -13,9 +13,9 @@ class Gzip : public Deflator
{
public:
Gzip(BufferedTransformation *attachment=NULL, unsigned int deflateLevel=DEFAULT_DEFLATE_LEVEL, unsigned int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true)
- : Deflator(attachment, deflateLevel, log2WindowSize, detectUncompressible) {}
+ : Deflator(attachment, deflateLevel, log2WindowSize, detectUncompressible), m_totalLen(0) {}
Gzip(const NameValuePairs &parameters, BufferedTransformation *attachment=NULL)
- : Deflator(parameters, attachment) {}
+ : Deflator(parameters, attachment), m_totalLen(0) {}
protected:
enum {MAGIC1=0x1f, MAGIC2=0x8b, // flags for the header
diff --git a/hrtimer.h b/hrtimer.h
index 2d22ffa6..c184c01b 100644
--- a/hrtimer.h
+++ b/hrtimer.h
@@ -19,7 +19,9 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TimerBase
{
public:
enum Unit {SECONDS = 0, MILLISECONDS, MICROSECONDS, NANOSECONDS};
- TimerBase(Unit unit, bool stuckAtZero) : m_timerUnit(unit), m_stuckAtZero(stuckAtZero), m_started(false) {}
+ TimerBase(Unit unit, bool stuckAtZero)
+ : m_timerUnit(unit), m_stuckAtZero(stuckAtZero), m_started(false)
+ , m_start(0), m_last(0) {}
virtual TimerWord GetCurrentTimerValue() =0; // GetCurrentTime is a macro in MSVC 6.0
virtual TimerWord TicksPerSecond() =0; // this is not the resolution, just a conversion factor into seconds
diff --git a/ida.h b/ida.h
index 1e97a4b9..8e15c69f 100644
--- a/ida.h
+++ b/ida.h
@@ -18,7 +18,8 @@ class RawIDA : public AutoSignaling<Unflushable<Multichannel<Filter> > >
{
public:
RawIDA(BufferedTransformation *attachment=NULL)
- {Detach(attachment);}
+ : m_threshold (0), m_channelsReady(0), m_channelsFinished(0)
+ {Detach(attachment);}
unsigned int GetThreshold() const {return m_threshold;}
void AddOutputChannel(word32 channelId);
@@ -100,7 +101,7 @@ class InformationDispersal : public CustomFlushPropagation<Filter>
{
public:
InformationDispersal(int threshold, int nShares, BufferedTransformation *attachment=NULL, bool addPadding=true)
- : m_ida(new OutputProxy(*this, true))
+ : m_ida(new OutputProxy(*this, true)), m_pad(false), m_nextChannel(0)
{
Detach(attachment);
IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding));
@@ -121,7 +122,7 @@ class InformationRecovery : public RawIDA
{
public:
InformationRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true)
- : RawIDA(attachment)
+ : RawIDA(attachment), m_pad(false)
{IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));}
void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
@@ -138,7 +139,7 @@ class PaddingRemover : public Unflushable<Filter>
{
public:
PaddingRemover(BufferedTransformation *attachment=NULL)
- : m_possiblePadding(false) {Detach(attachment);}
+ : m_possiblePadding(false), m_zeroCount(0) {Detach(attachment);}
void IsolatedInitialize(const NameValuePairs &parameters)
{CRYPTOPP_UNUSED(parameters); m_possiblePadding = false;}
diff --git a/integer.cpp b/integer.cpp
index 6136d50e..e50f3714 100644
--- a/integer.cpp
+++ b/integer.cpp
@@ -19,12 +19,12 @@
#include "secblock.h"
#include "modarith.h"
#include "nbtheory.h"
-#include "filters.h"
#include "smartptr.h"
+#include "algparam.h"
+#include "filters.h"
#include "asn.h"
#include "oids.h"
#include "words.h"
-#include "algparam.h"
#include "pubkey.h" // for P1363_KDF2
#include "sha.h"
#include "cpu.h"
@@ -44,23 +44,41 @@
#pragma message("You do not seem to have the Visual C++ Processor Pack installed, so use of SSE2 instructions will be disabled.")
#endif
-#define CRYPTOPP_INTEGER_SSE2 (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86 || (CRYPTOPP_BOOL_X32 && !defined(CRYPTOPP_DISABLE_INTEGER_ASM))))
+// "Inline assembly operands don't work with .intel_syntax",
+// http://llvm.org/bugs/show_bug.cgi?id=24232
+#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_INTEL_ASM)
+# undef CRYPTOPP_X86_ASM_AVAILABLE
+# undef CRYPTOPP_X32_ASM_AVAILABLE
+# undef CRYPTOPP_X64_ASM_AVAILABLE
+# undef CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+# undef CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
+# define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0
+# define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 0
+#else
+# define CRYPTOPP_INTEGER_SSE2 (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86)
+#endif
NAMESPACE_BEGIN(CryptoPP)
-// Debian QEMU/ARMEL issue in MultiplyTop; see https://github.com/weidai11/cryptopp/issues/31.
-// The symptoms speak to undefined behavior, but we have not been able to locate it. It could
-// also be a compiler or linker issue (very possible because it only surfaces for ARMEL and
-// GCC 5.2, and not other Debian cross-compilers, like ARM64 and ARMHF).
-// TODO: revisit this in the future
+// Debian QEMU/ARMEL issue in MultiplyTop; see http://github.com/weidai11/cryptopp/issues/31.
#if __ARMEL__ && (CRYPTOPP_GCC_VERSION >= 50200) && (CRYPTOPP_GCC_VERSION < 50300) && __OPTIMIZE__
# define WORKAROUND_ARMEL_BUG 1
#endif
-
+
+// Debian QEMU/ARM64 issue in Integer or ModularArithmetic; see http://github.com/weidai11/cryptopp/issues/61.
+#if (__aarch64__ || __AARCH64EL__) && (CRYPTOPP_GCC_VERSION >= 50200) && (CRYPTOPP_GCC_VERSION < 50300)
+# define WORKAROUND_ARM64_BUG 1
+#endif
+
#if WORKAROUND_ARMEL_BUG
# pragma GCC push_options
# pragma GCC optimize("O1")
#endif
+
+#if WORKAROUND_ARM64_BUG
+# pragma GCC push_options
+# pragma GCC optimize("no-devirtualize")
+#endif
bool AssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt)
{
@@ -197,13 +215,20 @@ static word AtomicInverseModPower2(word A)
class DWord
{
public:
+ // Converity finding on default ctor. We've isntrumented the code,
+ // and cannot uncover a case where it affects a result.
+#if (defined(__COVERITY__) || !defined(NDEBUG)) && defined(CRYPTOPP_NATIVE_DWORD_AVAILABLE)
+ // Repeating pattern of 1010 for debug builds to break things...
+ DWord() : m_whole(0) {memset(&m_whole, 0xa, sizeof(m_whole));}
+#elif (defined(__COVERITY__) || !defined(NDEBUG)) && !defined(CRYPTOPP_NATIVE_DWORD_AVAILABLE)
+ // Repeating pattern of 1010 for debug builds to break things...
+ DWord() : m_halfs() {memset(&m_halfs, 0xa, sizeof(m_halfs));}
+#else
DWord() {}
+#endif
#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
- explicit DWord(word low)
- {
- m_whole = low;
- }
+ explicit DWord(word low) : m_whole(low) {}
#else
explicit DWord(word low)
{
@@ -225,6 +250,8 @@ public:
r.m_whole = (dword)a * b;
#elif defined(MultiplyWordsLoHi)
MultiplyWordsLoHi(r.m_halfs.low, r.m_halfs.high, a, b);
+ #else
+ assert(0);
#endif
return r;
}
@@ -322,17 +349,19 @@ private:
class Word
{
public:
+ // Converity finding on default ctor. We've isntrumented the code,
+ // and cannot uncover a case where it affects a result.
+#if defined(__COVERITY__)
+ Word() : m_whole(0) {}
+#elif !defined(NDEBUG)
+ // Repeating pattern of 1010 for debug builds to break things...
+ Word() : m_whole(0) {memset(&m_whole, 0xa, sizeof(m_whole));}
+#else
Word() {}
+#endif
- Word(word value)
- {
- m_whole = value;
- }
-
- Word(hword low, hword high)
- {
- m_whole = low | (word(high) << (WORD_BITS/2));
- }
+ Word(word value) : m_whole(value) {}
+ Word(hword low, hword high) : m_whole(low | (word(high) << (WORD_BITS/2))) {}
static Word Multiply(hword a, hword b)
{
@@ -469,13 +498,13 @@ inline word DWord::operator%(word a)
// ********************************************************
-// use some tricks to share assembly code between MSVC and GCC
+// Use some tricks to share assembly code between MSVC and GCC
#if defined(__GNUC__)
#define AddPrologue \
int result; \
__asm__ __volatile__ \
( \
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
#define AddEpilogue \
".att_syntax prefix;" \
: "=a" (result)\
@@ -563,7 +592,7 @@ int Baseline_Add(size_t N, word *C, const word *A, const word *B)
word result;
__asm__ __volatile__
(
- ".intel_syntax;"
+ INTEL_NOPREFIX
AS1( neg %1)
ASJ( jz, 1, f)
AS2( mov %0,[%3+8*%1])
@@ -582,7 +611,7 @@ int Baseline_Add(size_t N, word *C, const word *A, const word *B)
ASL(1)
AS2( mov %0, 0)
AS2( adc %0, %0)
- ".att_syntax;"
+ ATT_NOPREFIX
: "=&r" (result), "+c" (N)
: "r" (C+N), "r" (A+N), "r" (B+N)
: "memory", "cc"
@@ -595,7 +624,7 @@ int Baseline_Sub(size_t N, word *C, const word *A, const word *B)
word result;
__asm__ __volatile__
(
- ".intel_syntax;"
+ INTEL_NOPREFIX
AS1( neg %1)
ASJ( jz, 1, f)
AS2( mov %0,[%3+8*%1])
@@ -614,7 +643,7 @@ int Baseline_Sub(size_t N, word *C, const word *A, const word *B)
ASL(1)
AS2( mov %0, 0)
AS2( adc %0, %0)
- ".att_syntax;"
+ ATT_NOPREFIX
: "=&r" (result), "+c" (N)
: "r" (C+N), "r" (A+N), "r" (B+N)
: "memory", "cc"
@@ -3446,8 +3475,8 @@ std::ostream& operator<<(std::ostream& out, const Integer &a)
static const char lower[]="0123456789abcdef";
const char* vec = (out.flags() & std::ios::uppercase) ? upper : lower;
- unsigned i=0;
- SecBlock<char> s(a.BitCount() / (BitPrecision(base)-1) + 1);
+ unsigned int i=0;
+ SecBlock<char> s(a.BitCount() / (SaturatingSubtract1(BitPrecision(base),1U)) + 1);
while (!!temp1)
{
@@ -3463,6 +3492,7 @@ std::ostream& operator<<(std::ostream& out, const Integer &a)
// if (i && !(i%block))
// out << ",";
}
+
return out << suffix;
}
@@ -4271,10 +4301,104 @@ const Integer& MontgomeryRepresentation::MultiplicativeInverse(const Integer &a)
return m_result;
}
+// Specialization declared in misc.h to allow us to print integers
+// with additional control options, like arbirary bases and uppercase.
+template <> CRYPTOPP_DLL
+std::string IntToString<Integer>(Integer value, unsigned int base)
+{
+ // Hack... set the high bit for uppercase. Set the next bit fo a suffix.
+ static const unsigned int BIT_32 = (1U << 31);
+ const bool UPPER = !!(base & BIT_32);
+ static const unsigned int BIT_31 = (1U << 30);
+ const bool BASE = !!(base & BIT_31);
+
+ const char CH = UPPER ? 'A' : 'a';
+ base &= ~(BIT_32|BIT_31);
+ assert(base >= 2 && base <= 32);
+
+ if (value == 0)
+ return "0";
+
+ bool negative = false, zero = false;
+ if (value.IsNegative())
+ {
+ negative = true;
+ value.Negate();
+ }
+
+ if (!value)
+ zero = true;
+
+ SecBlock<char> s(value.BitCount() / (SaturatingSubtract1(BitPrecision(base),1U)) + 1);
+ Integer temp;
+
+ unsigned int i=0;
+ while (!!value)
+ {
+ word digit;
+ Integer::Divide(digit, temp, value, word(base));
+ s[i++]=char((digit < 10 ? '0' : (CH - 10)) + digit);
+ value.swap(temp);
+ }
+
+ std::string result;
+ result.reserve(i+2);
+
+ if (negative)
+ result += '-';
+
+ if (zero)
+ result += '0';
+
+ while (i--)
+ result += s[i];
+
+ if (BASE)
+ {
+ if (base == 10)
+ result += '.';
+ else if (base == 16)
+ result += 'h';
+ else if (base == 8)
+ result += 'o';
+ else if (base == 2)
+ result += 'b';
+ }
+
+ return result;
+}
+
+// Specialization declared in misc.h to avoid Coverity findings.
+template <> CRYPTOPP_DLL
+std::string IntToString<unsigned long long>(unsigned long long value, unsigned int base)
+{
+ // Hack... set the high bit for uppercase.
+ static const unsigned int HIGH_BIT = (1U << 31);
+ const char CH = !!(base & HIGH_BIT) ? 'A' : 'a';
+ base &= ~HIGH_BIT;
+
+ assert(base >= 2);
+ if (value == 0)
+ return "0";
+
+ std::string result;
+ while (value > 0)
+ {
+ unsigned long long digit = value % base;
+ result = char((digit < 10 ? '0' : (CH - 10)) + digit) + result;
+ value /= base;
+ }
+ return result;
+}
+
NAMESPACE_END
#if WORKAROUND_ARMEL_BUG
# pragma GCC pop_options
#endif
+
+#if WORKAROUND_ARM64_BUG
+# pragma GCC pop_options
+#endif
#endif
diff --git a/integer.h b/integer.h
index 4241ec33..858b1cdb 100644
--- a/integer.h
+++ b/integer.h
@@ -5,174 +5,262 @@
#include "cryptlib.h"
#include "secblock.h"
+#include "stdcpp.h"
#include <iosfwd>
-#include <algorithm>
-
-#if CRYPTOPP_BOOL_X32
-# define CRYPTOPP_DISABLE_INTEGER_ASM
-#endif
NAMESPACE_BEGIN(CryptoPP)
-struct InitializeInteger // used to initialize static variables
+//! \struct InitializeInteger
+//! Performs static intialization of the Integer class
+struct InitializeInteger
{
InitializeInteger();
};
typedef SecBlock<word, AllocatorWithCleanup<word, CRYPTOPP_BOOL_X86> > IntegerSecBlock;
-//! multiple precision integer and basic arithmetics
-/*! This class can represent positive and negative integers
- with absolute value less than (256**sizeof(word)) ** (256**sizeof(int)).
- \nosubgrouping
-*/
+//! \brief Multiple precision integer with arithmetic operations
+//! \details The Integer class can represent positive and negative integers
+//! with absolute value less than (256**sizeof(word))<sup>(256**sizeof(int))</sup>.
+//! \details Internally, the library uses a sign magnitude representation, and the class
+//! has two data members. The first is a IntegerSecBlock (a SecBlock<word>) and it i
+//! used to hold the representation. The second is a Sign, and its is used to track
+//! the sign of the Integer.
+//! \nosubgrouping
class CRYPTOPP_DLL Integer : private InitializeInteger, public ASN1Object
{
public:
//! \name ENUMS, EXCEPTIONS, and TYPEDEFS
//@{
- //! division by zero exception
+ //! \brief Exception thrown when division by 0 is encountered
class DivideByZero : public Exception
{
public:
DivideByZero() : Exception(OTHER_ERROR, "Integer: division by zero") {}
};
- //!
+ //! \brief Exception thrown when a random number cannot be found that
+ //! satisfies the condition
class RandomNumberNotFound : public Exception
{
public:
RandomNumberNotFound() : Exception(OTHER_ERROR, "Integer: no integer satisfies the given parameters") {}
};
- //!
- enum Sign {POSITIVE=0, NEGATIVE=1};
-
- //!
+ //! \enum Sign
+ //! \brief Used internally to represent the integer
+ //! \details Sign is used internally to represent the integer. It is also used in a few API functions.
+ //! \sa Signedness
+ enum Sign {
+ //! \brief the value is positive or 0
+ POSITIVE=0,
+ //! \brief the value is negative
+ NEGATIVE=1};
+
+ //! \enum Signedness
+ //! \brief Used when importing and exporting integers
+ //! \details Signedness is usually used in API functions.
+ //! \sa Sign
enum Signedness {
- //!
+ //! \brief an unsigned value
UNSIGNED,
- //!
+ //! \brief a signed value
SIGNED};
- //!
+ //! \enum RandomNumberType
+ //! \brief Properties of a random integer
enum RandomNumberType {
- //!
+ //! \brief a number with no special properties
ANY,
- //!
+ //! \brief a number which is probabilistically prime
PRIME};
//@}
//! \name CREATORS
//@{
- //! creates the zero integer
+ //! \brief Creates the zero integer
Integer();
//! copy constructor
Integer(const Integer& t);
- //! convert from signed long
+ //! \brief Convert from signed long
Integer(signed long value);
- //! convert from lword
- Integer(Sign s, lword value);
-
- //! convert from two words
- Integer(Sign s, word highWord, word lowWord);
-
- //! convert from string
- /*! str can be in base 2, 8, 10, or 16. Base is determined by a
- case insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10.
- */
+ //! \brief Convert from lword
+ //! \param sign enumeration indicating Sign
+ //! \param value the long word
+ Integer(Sign sign, lword value);
+
+ //! \brief Convert from two words
+ //! \param sign enumeration indicating Sign
+ //! \param highWord the high word
+ //! \param lowWord the low word
+ Integer(Sign sign, word highWord, word lowWord);
+
+ //! \brief Convert from a C-string
+ //! \param str C-string value
+ //! \details \p str can be in base 2, 8, 10, or 16. Base is determined by a case
+ //! insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10.
explicit Integer(const char *str);
+
+ //! \brief Convert from a wide C-string
+ //! \param str wide C-string value
+ //! \details \p str can be in base 2, 8, 10, or 16. Base is determined by a case
+ //! insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10.
explicit Integer(const wchar_t *str);
- //! convert from big-endian byte array
- Integer(const byte *encodedInteger, size_t byteCount, Signedness s=UNSIGNED);
+ //! \brief Convert from a big-endian byte array
+ //! \param encodedInteger big-endian byte array
+ //! \param byteCount length of the byte array
+ //! \param sign enumeration indicating Signedness
+ Integer(const byte *encodedInteger, size_t byteCount, Signedness sign=UNSIGNED);
- //! convert from big-endian form stored in a BufferedTransformation
- Integer(BufferedTransformation &bt, size_t byteCount, Signedness s=UNSIGNED);
+ //! \brief Convert from a big-endian array
+ //! \param bt BufferedTransformation object with big-endian byte array
+ //! \param byteCount length of the byte array
+ //! \param sign enumeration indicating Signedness
+ Integer(BufferedTransformation &bt, size_t byteCount, Signedness sign=UNSIGNED);
- //! convert from BER encoded byte array stored in a BufferedTransformation object
+ //! \brief Convert from a BER encoded byte array
+ //! \param bt BufferedTransformation object with BER encoded byte array
explicit Integer(BufferedTransformation &bt);
- //! create a random integer
- /*! The random integer created is uniformly distributed over [0, 2**bitcount). */
- Integer(RandomNumberGenerator &rng, size_t bitcount);
+ //! \brief Create a random integer
+ //! \param rng RandomNumberGenerator used to generate material
+ //! \param bitCount the number of bits in the resulting integer
+ //! \details The random integer created is uniformly distributed over <tt>[0, 2<sup>bitCount</sup>]</tt>.
+ Integer(RandomNumberGenerator &rng, size_t bitCount);
- //! avoid calling constructors for these frequently used integers
+ //! \brief Integer representing 0
+ //! \returns an Integer representing 0
+ //! \details Zero() avoids calling constructors for frequently used integers
static const Integer & CRYPTOPP_API Zero();
- //! avoid calling constructors for these frequently used integers
+ //! \brief Integer representing 1
+ //! \returns an Integer representing 1
+ //! \details One() avoids calling constructors for frequently used integers
static const Integer & CRYPTOPP_API One();
- //! avoid calling constructors for these frequently used integers
+ //! \brief Integer representing 2
+ //! \returns an Integer representing 2
+ //! \details Two() avoids calling constructors for frequently used integers
static const Integer & CRYPTOPP_API Two();
- //! create a random integer of special type
- /*! Ideally, the random integer created should be uniformly distributed
- over {x | min <= x <= max and x is of rnType and x % mod == equiv}.
- However the actual distribution may not be uniform because sequential
- search is used to find an appropriate number from a random starting
- point.
- May return (with very small probability) a pseudoprime when a prime
- is requested and max > lastSmallPrime*lastSmallPrime (lastSmallPrime
- is declared in nbtheory.h).
- \throw RandomNumberNotFound if the set is empty.
- */
+ //! \brief Create a random integer of special form
+ //! \param rng RandomNumberGenerator used to generate material
+ //! \param min the minimum value
+ //! \param max the maximum value
+ //! \param rnType RandomNumberType to specify the type
+ //! \param equiv the equivalence class based on the parameter \p mod
+ //! \param mod the modulus used to reduce the equivalence class
+ //! \throw RandomNumberNotFound if the set is empty.
+ //! \details Ideally, the random integer created should be uniformly distributed
+ //! over <tt>{x | min \<= x \<= max</tt> and \p x is of rnType and <tt>x \% mod == equiv}</tt>.
+ //! However the actual distribution may not be uniform because sequential
+ //! search is used to find an appropriate number from a random starting
+ //! point.
+ //! \details May return (with very small probability) a pseudoprime when a prime
+ //! is requested and <tt>max \> lastSmallPrime*lastSmallPrime</tt>. \p lastSmallPrime
+ //! is declared in nbtheory.h.
Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One());
- //! return the integer 2**e
+ //! \brief Exponentiates to a power of 2
+ //! \returns the Integer 2<sup>e</sup>
+ //! \sa a_times_b_mod_c() and a_exp_b_mod_c()
static Integer CRYPTOPP_API Power2(size_t e);
//@}
//! \name ENCODE/DECODE
//@{
- //! minimum number of bytes to encode this integer
- /*! MinEncodedSize of 0 is 1 */
- size_t MinEncodedSize(Signedness=UNSIGNED) const;
- //! encode in big-endian format
- /*! unsigned means encode absolute value, signed means encode two's complement if negative.
- if outputLen < MinEncodedSize, the most significant bytes will be dropped
- if outputLen > MinEncodedSize, the most significant bytes will be padded
- */
- void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const;
- //!
- void Encode(BufferedTransformation &bt, size_t outputLen, Signedness=UNSIGNED) const;
-
- //! encode using Distinguished Encoding Rules, put result into a BufferedTransformation object
+ //! \brief The minimum number of bytes to encode this integer
+ //! \param sign enumeration indicating Signedness
+ //! \note The MinEncodedSize() of 0 is 1.
+ size_t MinEncodedSize(Signedness sign=UNSIGNED) const;
+
+ //! \brief Encode in big-endian format
+ //! \param output big-endian byte array
+ //! \param outputLen length of the byte array
+ //! \param sign enumeration indicating Signedness
+ //! \details Unsigned means encode absolute value, signed means encode two's complement if negative.
+ //! \details outputLen can be used to ensure an Integer is encoded to an exact size (rather than a
+ //! minimum size). An exact size is useful, for example, when encoding to a field element size.
+ void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const;
+
+ //! \brief Encode in big-endian format
+ //! \param bt BufferedTransformation object
+ //! \param outputLen length of the encoding
+ //! \param sign enumeration indicating Signedness
+ //! \details Unsigned means encode absolute value, signed means encode two's complement if negative.
+ //! \details outputLen can be used to ensure an Integer is encoded to an exact size (rather than a
+ //! minimum size). An exact size is useful, for example, when encoding to a field element size.
+ void Encode(BufferedTransformation &bt, size_t outputLen, Signedness sign=UNSIGNED) const;
+
+ //! \brief Encode in DER format
+ //! \param bt BufferedTransformation object
+ //! \details Encodes the Integer using Distinguished Encoding Rules
+ //! The result is placed into a BufferedTransformation object
void DEREncode(BufferedTransformation &bt) const;
//! encode absolute value as big-endian octet string
+ //! \param bt BufferedTransformation object
+ //! \param length the number of mytes to decode
void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const;
- //! encode absolute value in OpenPGP format, return length of output
+ //! \brief Encode absolute value in OpenPGP format
+ //! \param output big-endian byte array
+ //! \param bufferSize length of the byte array
+ //! \returns length of the output
+ //! \details OpenPGPEncode places result into a BufferedTransformation object and returns the
+ //! number of bytes used for the encoding
size_t OpenPGPEncode(byte *output, size_t bufferSize) const;
- //! encode absolute value in OpenPGP format, put result into a BufferedTransformation object
+
+ //! \brief Encode absolute value in OpenPGP format
+ //! \param bt BufferedTransformation object
+ //! \returns length of the output
+ //! \details OpenPGPEncode places result into a BufferedTransformation object and returns the
+ //! number of bytes used for the encoding
size_t OpenPGPEncode(BufferedTransformation &bt) const;
- //!
- void Decode(const byte *input, size_t inputLen, Signedness=UNSIGNED);
- //!
- //* Precondition: bt.MaxRetrievable() >= inputLen
- void Decode(BufferedTransformation &bt, size_t inputLen, Signedness=UNSIGNED);
-
- //!
+ //! \brief Decode from big-endian byte array
+ //! \param input big-endian byte array
+ //! \param inputLen length of the byte array
+ //! \param sign enumeration indicating Signedness
+ void Decode(const byte *input, size_t inputLen, Signedness sign=UNSIGNED);
+
+ //! \brief Decode nonnegative value from big-endian byte array
+ //! \param bt BufferedTransformation object
+ //! \param inputLen length of the byte array
+ //! \param sign enumeration indicating Signedness
+ //! \note <tt>bt.MaxRetrievable() \>= inputLen</tt>.
+ void Decode(BufferedTransformation &bt, size_t inputLen, Signedness sign=UNSIGNED);
+
+ //! \brief Decode from BER format
+ //! \param input big-endian byte array
+ //! \param inputLen length of the byte array
void BERDecode(const byte *input, size_t inputLen);
- //!
+
+ //! \brief Decode from BER format
+ //! \param bt BufferedTransformation object
void BERDecode(BufferedTransformation &bt);
- //! decode nonnegative value as big-endian octet string
+ //! \brief Decode nonnegative value from big-endian octet string
+ //! \param bt BufferedTransformation object
+ //! \param length length of the byte array
void BERDecodeAsOctetString(BufferedTransformation &bt, size_t length);
+ //! \brief Exception thrown when an error is encountered decoding an OpenPGP integer
class OpenPGPDecodeErr : public Exception
{
public:
OpenPGPDecodeErr() : Exception(INVALID_DATA_FORMAT, "OpenPGP decode error") {}
};
- //!
+ //! \brief Decode from OpenPGP format
+ //! \param input big-endian byte array
+ //! \param inputLen length of the byte array
void OpenPGPDecode(const byte *input, size_t inputLen);
- //!
+ //! \brief Decode from OpenPGP format
+ //! \param bt BufferedTransformation object
void OpenPGPDecode(BufferedTransformation &bt);
//@}
@@ -225,14 +313,17 @@ public:
//!
Integer& operator-=(const Integer& t);
//!
+ //! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator*=(const Integer& t) {return *this = Times(t);}
//!
Integer& operator/=(const Integer& t) {return *this = DividedBy(t);}
//!
+ //! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator%=(const Integer& t) {return *this = Modulo(t);}
//!
Integer& operator/=(word t) {return *this = DividedBy(t);}
//!
+ //! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator%=(word t) {return *this = Integer(POSITIVE, 0, Modulo(t));}
//!
@@ -240,12 +331,35 @@ public:
//!
Integer& operator>>=(size_t);
- //!
- void Randomize(RandomNumberGenerator &rng, size_t bitcount);
- //!
+ //! \brief Set this Integer to random integer
+ //! \param rng RandomNumberGenerator used to generate material
+ //! \param bitCount the number of bits in the resulting integer
+ //! \details The random integer created is uniformly distributed over <tt>[0, 2<sup>bitCount</sup>]</tt>.
+ void Randomize(RandomNumberGenerator &rng, size_t bitCount);
+
+ //! \brief Set this Integer to random integer
+ //! \param rng RandomNumberGenerator used to generate material
+ //! \param min the minimum value
+ //! \param max the maximum value
+ //! \details The random integer created is uniformly distributed over <tt>[min, max]</tt>.
void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max);
- //! set this Integer to a random element of {x | min <= x <= max and x is of rnType and x % mod == equiv}
- /*! returns false if the set is empty */
+
+ //! \brief Set this Integer to random integer of special form
+ //! \param rng RandomNumberGenerator used to generate material
+ //! \param min the minimum value
+ //! \param max the maximum value
+ //! \param rnType RandomNumberType to specify the type
+ //! \param equiv the equivalence class based on the parameter \p mod
+ //! \param mod the modulus used to reduce the equivalence class
+ //! \throw RandomNumberNotFound if the set is empty.
+ //! \details Ideally, the random integer created should be uniformly distributed
+ //! over <tt>{x | min \<= x \<= max</tt> and \p x is of rnType and <tt>x \% mod == equiv}</tt>.
+ //! However the actual distribution may not be uniform because sequential
+ //! search is used to find an appropriate number from a random starting
+ //! point.
+ //! \details May return (with very small probability) a pseudoprime when a prime
+ //! is requested and <tt>max \> lastSmallPrime*lastSmallPrime</tt>. \p lastSmallPrime
+ //! is declared in nbtheory.h.
bool Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv=Zero(), const Integer &mod=One());
bool GenerateRandomNoThrow(RandomNumberGenerator &rng, const NameValuePairs &params = g_nullNameValuePairs);
@@ -255,19 +369,24 @@ public:
throw RandomNumberNotFound();
}
- //! set the n-th bit to value
+ //! \brief Set the n-th bit to value
+ //! \details 0-based numbering.
void SetBit(size_t n, bool value=1);
- //! set the n-th byte to value
+
+ //! \brief Set the n-th byte to value
+ //! \details 0-based numbering.
void SetByte(size_t n, byte value);
- //!
+ //! \brief Reverse the Sign of the Integer
void Negate();
- //!
+
+ //! \brief Sets the Integer to positive
void SetPositive() {sign = POSITIVE;}
- //!
+
+ //! \brief Sets the Integer to negative
void SetNegative() {if (!!(*this)) sign = NEGATIVE;}
- //!
+ //! \brief Swaps this Integer with another Integer
void swap(Integer &a);
//@}
@@ -291,11 +410,11 @@ public:
//! \name BINARY OPERATORS
//@{
- //! signed comparison
- /*! \retval -1 if *this < a
- \retval 0 if *this = a
- \retval 1 if *this > a
- */
+ //! \brief Perform signed comparison
+ //! \param a the Integer to comapre
+ //! \retval -1 if <tt>*this < a</tt>
+ //! \retval 0 if <tt>*this = a</tt>
+ //! \retval 1 if <tt>*this > a</tt>
int Compare(const Integer& a) const;
//!
@@ -303,14 +422,17 @@ public:
//!
Integer Minus(const Integer &b) const;
//!
+ //! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer Times(const Integer &b) const;
//!
Integer DividedBy(const Integer &b) const;
//!
+ //! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer Modulo(const Integer &b) const;
//!
Integer DividedBy(word b) const;
//!
+ //! \sa a_times_b_mod_c() and a_exp_b_mod_c()
word Modulo(word b) const;
//!
@@ -326,6 +448,7 @@ public:
//!
Integer Doubled() const {return Plus(*this);}
//!
+ //! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer Squared() const {return Times(*this);}
//! extract square root, if negative return 0, else return floor of square root
Integer SquareRoot() const;
@@ -337,11 +460,6 @@ public:
//! return inverse if 1 or -1, otherwise return 0
Integer MultiplicativeInverse() const;
- //! modular multiplication
- CRYPTOPP_DLL friend Integer CRYPTOPP_API a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m);
- //! modular exponentiation
- CRYPTOPP_DLL friend Integer CRYPTOPP_API a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m);
-
//! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d))
static void CRYPTOPP_API Divide(Integer &r, Integer &q, const Integer &a, const Integer &d);
//! use a faster division algorithm when divisor is short
@@ -353,34 +471,59 @@ public:
//! greatest common divisor
static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n);
//! calculate multiplicative inverse of *this mod n
+ //! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer InverseMod(const Integer &n) const;
//!
+ //! \sa a_times_b_mod_c() and a_exp_b_mod_c()
word InverseMod(word n) const;
//@}
//! \name INPUT/OUTPUT
//@{
- //!
+ //! \brief Extraction operator
+ //! \param in a reference to a std::istream
+ //! \param a a reference to an Integer
+ //! \returns a reference to a std::istream reference
friend CRYPTOPP_DLL std::istream& CRYPTOPP_API operator>>(std::istream& in, Integer &a);
//!
+ //! \brief Insertion operator
+ //! \param out a reference to a std::ostream
+ //! \param a a constant reference to an Integer
+ //! \returns a reference to a std::ostream reference
+ //! \details The output integer responds to std::hex, std::oct, std::hex, std::upper and
+ //! std::lower. The output includes the suffix \a \b h (for hex), \a \b . (\a \b dot, for dec)
+ //! and \a \b o (for octal). There is currently no way to supress the suffix.
+ //! \details If you want to print an Integer without the suffix or using an arbitrary base, then
+ //! use IntToString<Integer>().
+ //! \sa IntToString<Integer>
friend CRYPTOPP_DLL std::ostream& CRYPTOPP_API operator<<(std::ostream& out, const Integer &a);
//@}
+
+#ifndef CRYPTOPP_DOXYGEN_PROCESSING
+ //! modular multiplication
+ CRYPTOPP_DLL friend Integer CRYPTOPP_API a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m);
+ //! modular exponentiation
+ CRYPTOPP_DLL friend Integer CRYPTOPP_API a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m);
+#endif
private:
+
+ Integer(word value, size_t length);
+ int PositiveCompare(const Integer &t) const;
+
+ IntegerSecBlock reg;
+ Sign sign;
+
+#ifndef CRYPTOPP_DOXYGEN_PROCESSING
friend class ModularArithmetic;
friend class MontgomeryRepresentation;
friend class HalfMontgomeryRepresentation;
- Integer(word value, size_t length);
-
- int PositiveCompare(const Integer &t) const;
friend void PositiveAdd(Integer &sum, const Integer &a, const Integer &b);
friend void PositiveSubtract(Integer &diff, const Integer &a, const Integer &b);
friend void PositiveMultiply(Integer &product, const Integer &a, const Integer &b);
friend void PositiveDivide(Integer &remainder, Integer &quotient, const Integer &dividend, const Integer &divisor);
-
- IntegerSecBlock reg;
- Sign sign;
+#endif
};
//!
@@ -400,14 +543,17 @@ inline CryptoPP::Integer operator+(const CryptoPP::Integer &a, const CryptoPP::I
//!
inline CryptoPP::Integer operator-(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Minus(b);}
//!
+//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
inline CryptoPP::Integer operator*(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Times(b);}
//!
inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.DividedBy(b);}
//!
+//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
inline CryptoPP::Integer operator%(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Modulo(b);}
//!
inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, CryptoPP::word b) {return a.DividedBy(b);}
//!
+//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
inline CryptoPP::word operator%(const CryptoPP::Integer &a, CryptoPP::word b) {return a.Modulo(b);}
NAMESPACE_END
diff --git a/iterhash.cpp b/iterhash.cpp
index 9c290630..f13825d2 100644
--- a/iterhash.cpp
+++ b/iterhash.cpp
@@ -18,7 +18,7 @@ template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte
if (m_countHi < oldCountHi || SafeRightShift<2*8*sizeof(HashWordType)>(len) != 0)
throw HashInputTooLong(this->AlgorithmName());
- unsigned int blockSize = this->BlockSize();
+ const unsigned int blockSize = this->BlockSize();
unsigned int num = ModPowerOf2(oldCountLo, blockSize);
T* dataBuf = this->DataBuf();
diff --git a/luc.cpp b/luc.cpp
index 5849798e..17a2e32b 100644
--- a/luc.cpp
+++ b/luc.cpp
@@ -10,12 +10,14 @@
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void LUC_TestInstantiations()
{
LUC_HMP<SHA>::Signer t1;
LUCFunction t2;
InvertibleLUCFunction t3;
}
+#endif
void DL_Algorithm_LUC_HMP::Sign(const DL_GroupParameters<Integer> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
{
diff --git a/md5.cpp b/md5.cpp
index 11035b77..c7015f14 100644
--- a/md5.cpp
+++ b/md5.cpp
@@ -9,10 +9,12 @@
NAMESPACE_BEGIN(CryptoPP)
namespace Weak1 {
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void MD5_TestInstantiations()
{
MD5 x;
}
+#endif
void MD5::InitState(HashWordType *state)
{
diff --git a/misc.cpp b/misc.cpp
index a7f609c0..2c5c35d3 100644
--- a/misc.cpp
+++ b/misc.cpp
@@ -11,18 +11,24 @@
#include "misc.h"
#include "words.h"
-#include <new>
+#include "words.h"
+#include "stdcpp.h"
+#include "integer.h"
+// for memalign
#if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX)
-#include <malloc.h>
+# include <malloc.h>
#endif
NAMESPACE_BEGIN(CryptoPP)
void xorbuf(byte *buf, const byte *mask, size_t count)
{
- size_t i;
+ assert(buf != NULL);
+ assert(mask != NULL);
+ assert(count > 0);
+ size_t i=0;
if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
{
if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask))
@@ -51,8 +57,11 @@ void xorbuf(byte *buf, const byte *mask, size_t count)
void xorbuf(byte *output, const byte *input, const byte *mask, size_t count)
{
- size_t i;
+ assert(output != NULL);
+ assert(input != NULL);
+ assert(count > 0);
+ size_t i=0;
if (IsAligned<word32>(output) && IsAligned<word32>(input) && IsAligned<word32>(mask))
{
if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(output) && IsAligned<word64>(input) && IsAligned<word64>(mask))
@@ -83,7 +92,11 @@ void xorbuf(byte *output, const byte *input, const byte *mask, size_t count)
bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count)
{
- size_t i;
+ assert(buf != NULL);
+ assert(mask != NULL);
+ assert(count > 0);
+
+ size_t i=0;
byte acc8 = 0;
if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
@@ -139,7 +152,9 @@ void CallNewHandler()
void * AlignedAllocate(size_t size)
{
byte *p;
-#ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
+#if defined(CRYPTOPP_APPLE_ALLOC_AVAILABLE)
+ while ((p = (byte *)calloc(1, size)) == NULL)
+#elif defined(CRYPTOPP_MM_MALLOC_AVAILABLE)
while ((p = (byte *)_mm_malloc(size, 16)) == NULL)
#elif defined(CRYPTOPP_MEMALIGN_AVAILABLE)
while ((p = (byte *)memalign(16, size)) == NULL)
diff --git a/misc.h b/misc.h
index 6525b81a..4132d806 100644
--- a/misc.h
+++ b/misc.h
@@ -1,14 +1,15 @@
// misc.h - written and placed in the public domain by Wei Dai
-/*! \file
- \headerfile misc.h file contains utility functions for the library.
-*/
+
+//! \file misc.h
+//! \brief Utility functions for the Crypto++ library.
#ifndef CRYPTOPP_MISC_H
#define CRYPTOPP_MISC_H
#include "config.h"
-//! \if 0
+#if !CRYPTOPP_DOXYGEN_PROCESSING
+
#if CRYPTOPP_MSC_VERSION
# pragma warning(push)
# pragma warning(disable: 6326)
@@ -54,24 +55,48 @@
#include <byteswap.h>
#endif
+#endif // CRYPTOPP_DOXYGEN_PROCESSING
+
+#if CRYPTOPP_DOXYGEN_PROCESSING
+//! \brief The maximum value of a machine word
+//! \details SIZE_MAX provides the maximum value of a machine word. The value is
+//! \p 0xffffffff on 32-bit machines, and \p 0xffffffffffffffff on 64-bit machines.
+//! Internally, SIZE_MAX is defined as __SIZE_MAX__ if __SIZE_MAX__ is defined. If not
+//! defined, then SIZE_T_MAX is tried. If neither __SIZE_MAX__ nor SIZE_T_MAX is
+//! is defined, the library uses std::numeric_limits<size_t>::max(). The library
+//! prefers __SIZE_MAX__ because its a constexpr that is optimized well
+//! by all compilers. std::numeric_limits<size_t>::max() is \a not a constexpr,
+//! and it is \a not always optimized well.
+# define SIZE_MAX ...
+#else
// Its amazing portability problems still plague this simple concept in 2015.
// http://stackoverflow.com/questions/30472731/which-c-standard-header-defines-size-max
// Avoid NOMINMAX macro on Windows. http://support.microsoft.com/en-us/kb/143208
#ifndef SIZE_MAX
-# ifdef __SIZE_MAX__
+# if defined(__SIZE_MAX__)
# define SIZE_MAX __SIZE_MAX__
+# elif defined(SIZE_T_MAX)
+# define SIZE_MAX SIZE_T_MAX
# else
# define SIZE_MAX ((std::numeric_limits<size_t>::max)())
# endif
#endif
-//! \endif
+#endif // CRYPTOPP_DOXYGEN_PROCESSING
NAMESPACE_BEGIN(CryptoPP)
+
+// Forward declaration for IntToString specialization
+class Integer;
// ************** compile-time assertion ***************
-//! \if 0
+#if CRYPTOPP_DOXYGEN_PROCESSING
+//! \brief Compile time assertion
+//! \param expr the expression to evaluate
+//! \details Asserts the expression expr though a dummy struct.
+#define CRYPTOPP_COMPILE_ASSERT(expr) ...
+#else // CRYPTOPP_DOXYGEN_PROCESSING
template <bool b>
struct CompileAssert
{
@@ -95,10 +120,23 @@ struct CompileAssert
#endif
#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
-
+
+#endif // CRYPTOPP_DOXYGEN_PROCESSING
+
// ************** count elements in an array ***************
-// VS2005 added _countof, fails on pointers (desired)
+#if CRYPTOPP_DOXYGEN_PROCESSING
+//! \brief Counts elements in an array
+//! \param arr an array of elements
+//! \details COUNTOF counts elements in an array. On Windows COUNTOF(x) is deinfed
+//! to _countof(x) to ensure correct results for pointers. Since the library code is
+//! cross-platform, Windows will ensure the safety on non-Windows platforms.
+//! \note COUNTOF does not produce correct results with pointers, and an array must be used.
+//! The library ensures correct application of COUNTOF by enlisting _countof on Windows
+//! platforms. Microsoft's _countof fails to compile using pointers.
+# define COUNTOF(arr)
+#else
+// VS2005 added _countof
#ifndef COUNTOF
# if defined(_MSC_VER) && (_MSC_VER >= 1400)
# define COUNTOF(x) _countof(x)
@@ -106,25 +144,30 @@ struct CompileAssert
# define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
# endif
#endif // COUNTOF
+#endif // CRYPTOPP_DOXYGEN_PROCESSING
// ************** misc classes ***************
+#if !CRYPTOPP_DOXYGEN_PROCESSING
class CRYPTOPP_DLL Empty
{
};
-//! _
template <class BASE1, class BASE2>
class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2
{
};
-//! _
template <class BASE1, class BASE2, class BASE3>
class CRYPTOPP_NO_VTABLE ThreeBases : public BASE1, public BASE2, public BASE3
{
};
+#endif // CRYPTOPP_DOXYGEN_PROCESSING
+//! \class ObjectHolder
+//! \tparam the class or type
+//! \brief Uses encapsulation to hide an object in derived classes
+//! \details The object T is declared as protected.
template <class T>
class ObjectHolder
{
@@ -132,6 +175,12 @@ protected:
T m_object;
};
+//! \class NotCopyable
+//! \brief Ensures an object is not copyable
+//! \details NotCopyable ensures an object is not copyable by making the
+//! copy constructor and assignment operator private. Deleters are not
+//! used under C++11.
+//! \sa Clonable class
class NotCopyable
{
public:
@@ -141,12 +190,25 @@ private:
void operator=(const NotCopyable &);
};
+//! \class NewObject
+//! \brief An object factory function
+//! \details NewObject overloads operator()().
template <class T>
struct NewObject
{
T* operator()() const {return new T;}
};
+#if CRYPTOPP_DOXYGEN_PROCESSING
+//! \brief A memory barrier
+//! \details MEMORY_BARRIER attempts to ensure reads and writes are completed
+//! in the absence of a language synchronization point. It is used by the
+//! Singleton class if the compiler supports it. The use is provided at the
+//! customary check points in a double-checked initialization.
+//! \details Internally, MEMORY_BARRIER uses <tt>intrinsic(_ReadWriteBarrier)</tt>,
+//! <tt>_ReadWriteBarrier()</tt> or <tt>__asm__("" ::: "memory")</tt>.
+#define MEMORY_BARRIER ...
+#else
#if defined(_MSC_VER)
# pragma intrinsic(_ReadWriteBarrier)
# define MEMORY_BARRIER() _ReadWriteBarrier()
@@ -157,9 +219,16 @@ struct NewObject
#else
// # error "Unknown compiler"
#endif
+#endif // CRYPTOPP_DOXYGEN_PROCESSING
//! \brief Restricts the instantiation of a class to one static object without locks
-//! \details This class safely initializes a static object in a multithreaded environment without using locks (for portability). Note that if two threads call Ref() at the same time, they may get back different references, and one object may end up being memory leaked. This is by design.
+//! \tparam T the class or type
+//! \tparam F the object factory for T
+//! \tparam instance the initiali instance count
+//! \details This class safely initializes a static object in a multithreaded environment
+//! without using locks (for portability). Note that if two threads call Ref() at the same
+//! time, they may get back different references, and one object may end up being memory
+//! leaked. This is by design.
template <class T, class F = NewObject<T>, int instance=0>
class Singleton
{
@@ -173,6 +242,9 @@ private:
F m_objectFactory;
};
+//! \brief Return a reference to the inner Singleton object
+//! \details Ref() is used to create the object using the object factory. The
+//! object is only created once with the limitations discussed in the class documentation.
template <class T, class F, int instance>
const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
{
@@ -201,23 +273,33 @@ const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
// ************** misc functions ***************
-#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) && !(defined(__MINGW__) || defined(__MINGW32__))
+#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) || defined(CRYPTOPP_WANT_SECURE_LIB)
-//! \brief Bounds checking replacement for \p memcpy
+//! \brief Bounds checking replacement for memcpy()
//! \param dest pointer to the desination memory block
//! \param sizeInBytes the size of the desination memory block, in bytes
//! \param src pointer to the source memory block
//! \param count the size of the source memory block, in bytes
//! \throws InvalidArgument
-//! \details ISO/IEC TR-24772 provides bounds checking interfaces for potentially unsafe functions like \p memcpy, \p strcpy and \p memmove. However, not all standard libraries provides them, like Glibc. The library's \p memcpy_s is a near-drop in replacement. Its only a near-replacement because the library's version throws an \p InvalidArgument on a bounds violation.
-//! \note \p memcpy_s will \p assert the pointers \p src and \p dest are not \p NULL in debug builds. Passing \p NULL for either pointer is undefined behavior.
+//! \details ISO/IEC TR-24772 provides bounds checking interfaces for potentially
+//! unsafe functions like memcpy(), strcpy() and memmove(). However,
+//! not all standard libraries provides them, like Glibc. The library's
+//! memcpy_s() is a near-drop in replacement. Its only a near-replacement
+//! because the library's version throws an InvalidArgument on a bounds violation.
+//! \details memcpy_s() and memmove_s() are guarded by __STDC_WANT_SECURE_LIB__.
+//! If __STDC_WANT_SECURE_LIB__ is \a not defined or defined to 0, then the library
+//! makes memcpy_s() and memmove_s() available. The library will also optionally
+//! make the symbols available if <tt>CRYPTOPP_WANT_SECURE_LIB</tt> is defined.
+//! <tt>CRYPTOPP_WANT_SECURE_LIB</tt> is in config.h, but it is disabled by default.
+//! \details memcpy_s() will assert the pointers src and dest are not NULL
+//! in debug builds. Passing NULL for either pointer is undefined behavior.
inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
{
// Safer functions on Windows for C&A, http://github.com/weidai11/cryptopp/issues/55
// Pointers must be valid; otherwise undefined behavior
assert(dest != NULL); assert(src != NULL);
- // Desitnation buffer must be large enough to satsify request
+ // Destination buffer must be large enough to satsify request
assert(sizeInBytes >= count);
if (count > sizeInBytes)
throw InvalidArgument("memcpy_s: buffer overflow");
@@ -232,21 +314,31 @@ inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t cou
#endif
}
-//! \brief Bounds checking replacement for \p memmove
+//! \brief Bounds checking replacement for memmove()
//! \param dest pointer to the desination memory block
//! \param sizeInBytes the size of the desination memory block, in bytes
//! \param src pointer to the source memory block
//! \param count the size of the source memory block, in bytes
//! \throws InvalidArgument
-//! \details ISO/IEC TR-24772 provides bounds checking interfaces for potentially unsafe functions like \p memcpy, \p strcpy and \p memmove. However, not all standard libraries provides them, like Glibc. The library's \p memmove_s is a near-drop in replacement. Its only a near-replacement because the library's version throws an \p InvalidArgument on a bounds violation.
-//! \note \p memcmove_s will \p assert the pointers \p src and \p dest are not \p NULL in debug builds. Passing \p NULL for either pointer is undefined behavior.
+//! \details ISO/IEC TR-24772 provides bounds checking interfaces for potentially
+//! unsafe functions like memcpy(), strcpy() and memmove(). However,
+//! not all standard libraries provides them, like Glibc. The library's
+//! memmove_s() is a near-drop in replacement. Its only a near-replacement
+//! because the library's version throws an InvalidArgument on a bounds violation.
+//! \details memcpy_s() and memmove_s() are guarded by __STDC_WANT_SECURE_LIB__.
+//! If __STDC_WANT_SECURE_LIB__ is \a not defined or defined to 0, then the library
+//! makes memcpy_s() and memmove_s() available. The library will also optionally
+//! make the symbols available if <tt>CRYPTOPP_WANT_SECURE_LIB</tt> is defined.
+//! <tt>CRYPTOPP_WANT_SECURE_LIB</tt> is in config.h, but it is disabled by default.
+//! \details memmove_s() will assert the pointers src and dest are not NULL
+//! in debug builds. Passing NULL for either pointer is undefined behavior.
inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
{
// Safer functions on Windows for C&A, http://github.com/weidai11/cryptopp/issues/55
// Pointers must be valid; otherwise undefined behavior
assert(dest != NULL); assert(src != NULL);
- // Desitnation buffer must be large enough to satsify request
+ // Destination buffer must be large enough to satsify request
assert(sizeInBytes >= count);
if (count > sizeInBytes)
throw InvalidArgument("memmove_s: buffer overflow");
@@ -273,7 +365,8 @@ inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t co
//! \param ptr pointer to the memory block being written
//! \param value the integer value to write for each byte
//! \param num the size of the source memory block, in bytes
-//! \details Internally the function calls \p memset with the value \p value, and receives the return value from \p memset as a <tt>volatile</tt> pointer.
+//! \details Internally the function calls memset with the value value, and receives the
+//! return value from memset as a <tt>volatile</tt> pointer.
inline void * memset_z(void *ptr, int value, size_t num)
{
// avoid extranous warning on GCC 4.3.2 Ubuntu 8.10
@@ -285,21 +378,21 @@ inline void * memset_z(void *ptr, int value, size_t num)
return const_cast<void*>(x);
}
-//! \brief Replacement function for \p std::min
+//! \brief Replacement function for std::min
//! \param a the first value
//! \param b the second value
-//! \returns the minimum value based on a comparison of <tt>b < a</tt> using <tt>operator&lt;</tt>
-//! \details \p STDMIN was provided because the library could not use \p std::min or \p std::max in MSVC60 or Cygwin 1.1.0
+//! \returns the minimum value based on a comparison of <tt>b \< a</tt> using <tt>operator\<</tt>
+//! \details STDMIN was provided because the library could not use std::min or std::max in MSVC60 or Cygwin 1.1.0
template <class T> inline const T& STDMIN(const T& a, const T& b)
{
return b < a ? b : a;
}
-//! \brief Replacement function for \p std::max
+//! \brief Replacement function for std::max
//! \param a the first value
//! \param b the second value
-//! \returns the minimum value based on a comparison of <tt>a < b</tt> using <tt>operator&lt;</tt>
-//! \details \p STDMAX was provided because the library could not use \p std::min or \p std::max in MSVC60 or Cygwin 1.1.0
+//! \returns the minimum value based on a comparison of <tt>a \< b</tt> using <tt>operator\<</tt>
+//! \details STDMAX was provided because the library could not use std::min or std::max in MSVC60 or Cygwin 1.1.0
template <class T> inline const T& STDMAX(const T& a, const T& b)
{
// can't use std::min or std::max in MSVC60 or Cygwin 1.1.0
@@ -314,7 +407,7 @@ template <class T> inline const T& STDMAX(const T& a, const T& b)
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wsign-compare"
-# if (CRYPTOPP_CLANG_VERSION >= 20900)
+# if (CRYPTOPP_CLANG_VERSION >= 20800) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000)
# pragma GCC diagnostic ignored "-Wtautological-compare"
# elif (CRYPTOPP_GCC_VERSION >= 40300)
# pragma GCC diagnostic ignored "-Wtype-limits"
@@ -324,8 +417,8 @@ template <class T> inline const T& STDMAX(const T& a, const T& b)
//! \brief Safe comparison of values that could be neagtive and incorrectly promoted
//! \param a the first value
//! \param b the second value
-//! \returns the minimum value based on a comparison \p a and \p b using <tt>operator&lt;</tt>.
-//! \details The comparison <tt>b < a</tt> is performed and the value returned is \p a's type \p T1.
+//! \returns the minimum value based on a comparison a and b using <tt>operator&lt;</tt>.
+//! \details The comparison <tt>b \< a</tt> is performed and the value returned is a's type T1.
template <class T1, class T2> inline const T1 UnsignedMin(const T1& a, const T2& b)
{
CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0));
@@ -335,10 +428,10 @@ template <class T1, class T2> inline const T1 UnsignedMin(const T1& a, const T2&
return (T1)b < a ? (T1)b : a;
}
-//! \brief Tests whether a conversion \p from → \p to is safe to perform
+//! \brief Tests whether a conversion from → to is safe to perform
//! \param from the first value
//! \param to the second value
-//! \returns true if its safe to convert \p from into \p to, false otherwise.
+//! \returns true if its safe to convert from into to, false otherwise.
template <class T1, class T2>
inline bool SafeConvert(T1 from, T2 &to)
{
@@ -351,10 +444,15 @@ inline bool SafeConvert(T1 from, T2 &to)
//! \brief Converts a value to a string
//! \param value the value to convert
//! \param base the base to use during the conversion
-//! \returns the \p string representation of \p value in \p base.
+//! \returns the string representation of value in base.
template <class T>
std::string IntToString(T value, unsigned int base = 10)
{
+ // Hack... set the high bit for uppercase.
+ static const unsigned int HIGH_BIT = (1U << 31);
+ const char CH = !!(base & HIGH_BIT) ? 'A' : 'a';
+ base &= ~HIGH_BIT;
+
assert(base >= 2);
if (value == 0)
return "0";
@@ -369,7 +467,7 @@ std::string IntToString(T value, unsigned int base = 10)
while (value > 0)
{
T digit = value % base;
- result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
+ result = char((digit < 10 ? '0' : (CH - 10)) + digit) + result;
value /= base;
}
if (negate)
@@ -377,6 +475,38 @@ std::string IntToString(T value, unsigned int base = 10)
return result;
}
+//! \brief Converts an unsigned value to a string
+//! \param value the value to convert
+//! \param base the base to use during the conversion
+//! \returns the string representation of value in base.
+//! \details this template function specialization was added to suppress
+//! Coverity findings on IntToString() with unsigned types.
+template <> CRYPTOPP_DLL
+std::string IntToString<unsigned long long>(unsigned long long value, unsigned int base);
+
+//! \brief Converts an Integer to a string
+//! \param value the Integer to convert
+//! \param base the base to use during the conversion
+//! \returns the string representation of value in base.
+//! \details This is a template specialization of IntToString(). Use it
+//! like IntToString():
+//! <pre>
+//! // Print integer in base 10
+//! Integer n...
+//! std::string s = IntToString(n, 10);
+//! </pre>
+//! \details The string is presented with lowercase letters by default. A
+//! hack is available to switch to uppercase letters without modifying
+//! the function signature.sha
+//! <pre>
+//! // Print integer in base 10, uppercase letters
+//! Integer n...
+//! const unsigned int UPPER = (1 << 31);
+//! std::string s = IntToString(n, (UPPER | 10));
+//! </pre>
+template <> CRYPTOPP_DLL
+std::string IntToString<Integer>(Integer value, unsigned int base);
+
#if CRYPTOPP_MSC_VERSION
# pragma warning(pop)
#endif
@@ -416,7 +546,6 @@ unsigned int BytePrecision(const T &value)
return 0;
unsigned int l=0, h=8*sizeof(value);
-
while (h-l > 8)
{
unsigned int t = (l+h)/2;
@@ -454,8 +583,9 @@ unsigned int BitPrecision(const T &value)
//! Determines the number of trailing 0-bits in a value
//! \param v the 32-bit value to test
-//! \returns the number of trailing 0-bits in \p v, starting at the least significant bit position
-//! \details \p TrailingZeros returns the number of trailing 0-bits in \p v, starting at the least significant bit position. The return value is undefined if there are no 1-bits set in the value \p v.
+//! \returns the number of trailing 0-bits in v, starting at the least significant bit position
+//! \details TrailingZeros returns the number of trailing 0-bits in v, starting at the least
+//! significant bit position. The return value is undefined if there are no 1-bits set in the value v.
//! \note The function does \a not return 0 if no 1-bits are set because 0 collides with a 1-bit at the 0-th position.
inline unsigned int TrailingZeros(word32 v)
{
@@ -479,8 +609,9 @@ inline unsigned int TrailingZeros(word32 v)
//! Determines the number of trailing 0-bits in a value
//! \param v the 64-bit value to test
-//! \returns the number of trailing 0-bits in \p v, starting at the least significant bit position
-//! \details \p TrailingZeros returns the number of trailing 0-bits in \p v, starting at the least significant bit position. The return value is undefined if there are no 1-bits set in the value \p v.
+//! \returns the number of trailing 0-bits in v, starting at the least significant bit position
+//! \details TrailingZeros returns the number of trailing 0-bits in v, starting at the least
+//! significant bit position. The return value is undefined if there are no 1-bits set in the value v.
//! \note The function does \a not return 0 if no 1-bits are set because 0 collides with a 1-bit at the 0-th position.
inline unsigned int TrailingZeros(word64 v)
{
@@ -499,8 +630,10 @@ inline unsigned int TrailingZeros(word64 v)
//! \brief Truncates the value to the specified number of bits.
//! \param value the value to truncate or mask
//! \param bits the number of bits to truncate or mask
-//! \returns the value truncated to the specified number of bits, starting at the least significant bit position
-//! \details This function masks the low-order bits of value and returns the result. The mask is created with <tt>(1 << bits) - 1</tt>.
+//! \returns the value truncated to the specified number of bits, starting at the least
+//! significant bit position
+//! \details This function masks the low-order bits of value and returns the result. The
+//! mask is created with <tt>(1 << bits) - 1</tt>.
template <class T>
inline T Crop(T value, size_t bits)
{
@@ -513,7 +646,7 @@ inline T Crop(T value, size_t bits)
//! \brief Returns the number of 8-bit bytes or octets required for the specified number of bits
//! \param bitCount the number of bits
//! \returns the minimum number of 8-bit bytes or octets required by bitCount
-//! \details \p BitsToBytes is effectively a ceiling function based on 8-bit bytes.
+//! \details BitsToBytes is effectively a ceiling function based on 8-bit bytes.
inline size_t BitsToBytes(size_t bitCount)
{
return ((bitCount+7)/(8));
@@ -522,7 +655,8 @@ inline size_t BitsToBytes(size_t bitCount)
//! \brief Returns the number of words required for the specified number of bytes
//! \param byteCount the number of bytes
//! \returns the minimum number of words required by byteCount
-//! \details \p BytesToWords is effectively a ceiling function based on <tt>WORD_SIZE</tt>. <tt>WORD_SIZE</tt> is defined in config.h
+//! \details BytesToWords is effectively a ceiling function based on <tt>WORD_SIZE</tt>.
+//! <tt>WORD_SIZE</tt> is defined in config.h
inline size_t BytesToWords(size_t byteCount)
{
return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
@@ -531,7 +665,8 @@ inline size_t BytesToWords(size_t byteCount)
//! \brief Returns the number of words required for the specified number of bits
//! \param bitCount the number of bits
//! \returns the minimum number of words required by bitCount
-//! \details \p BitsToWords is effectively a ceiling function based on <tt>WORD_BITS</tt>. <tt>WORD_BITS</tt> is defined in config.h
+//! \details BitsToWords is effectively a ceiling function based on <tt>WORD_BITS</tt>.
+//! <tt>WORD_BITS</tt> is defined in config.h
inline size_t BitsToWords(size_t bitCount)
{
return ((bitCount+WORD_BITS-1)/(WORD_BITS));
@@ -540,7 +675,8 @@ inline size_t BitsToWords(size_t bitCount)
//! \brief Returns the number of double words required for the specified number of bits
//! \param bitCount the number of bits
//! \returns the minimum number of double words required by bitCount
-//! \details \p BitsToDwords is effectively a ceiling function based on <tt>2*WORD_BITS</tt>. <tt>WORD_BITS</tt> is defined in config.h
+//! \details BitsToDwords is effectively a ceiling function based on <tt>2*WORD_BITS</tt>.
+//! <tt>WORD_BITS</tt> is defined in config.h
inline size_t BitsToDwords(size_t bitCount)
{
return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS));
@@ -550,7 +686,8 @@ inline size_t BitsToDwords(size_t bitCount)
//! \param buf the buffer to XOR with the mask
//! \param mask the mask to XOR with the buffer
//! \param count the size of the buffers, in bytes
-//! \details The function effectively visits each element in the buffers and performs <tt>buf[i] ^= mask[i]</tt>. \p buf and \p mask must be of equal size.
+//! \details The function effectively visits each element in the buffers and performs
+//! <tt>buf[i] ^= mask[i]</tt>. buf and mask must be of equal size.
CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count);
//! Performs an XOR of an input buffer with a mask and stores the result in an output buffer
@@ -558,20 +695,25 @@ CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count)
//! \param input the source buffer to XOR with the mask
//! \param mask the mask buffer to XOR with the input buffer
//! \param count the size of the buffers, in bytes
-//! \details The function effectively visits each element in the buffers and performs <tt>output[i] = input[i] ^ mask[i]</tt>. \p output, \p input and \p mask must be of equal size.
+//! \details The function effectively visits each element in the buffers and performs
+//! <tt>output[i] = input[i] ^ mask[i]</tt>. output, input and mask must be of equal size.
CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count);
//! \brief Performs a near constant-time comparison of two equally sized buffers
//! \param buf1 the first buffer
//! \param buf2 the second buffer
//! \param count the size of the buffers, in bytes
-//! \details The function effectively Performs an XOR of the elements in two equally sized buffers and retruns a result based on the XOR operation. The function is near constant-time because CPU micro-code timings could affect the "constant-ness". Calling code is responsible for mitigating timing attacks if the buffers are \a not equally sized.
+//! \details The function effectively performs an XOR of the elements in two equally sized buffers
+//! and retruns a result based on the XOR operation. The function is near constant-time because
+//! CPU micro-code timings could affect the "constant-ness". Calling code is responsible for
+//! mitigating timing attacks if the buffers are \a not equally sized.
CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count);
//! \brief Tests whether a value is a power of 2
//! \param value the value to test
-//! \returns true if \p value is a power of 2, false otherwise
-//! \details The function effectively creates a mask of <tt>value - 1</tt> and returns the result of an AND operation compared to 0. If \p value is 0 or less than 0, then the function freturns \p false.
+//! \returns true if value is a power of 2, false otherwise
+//! \details The function creates a mask of <tt>value - 1</tt> and returns the result of
+//! an AND operation compared to 0. If value is 0 or less than 0, then the function returns false.
template <class T>
inline bool IsPowerOf2(const T &value)
{
@@ -581,8 +723,9 @@ inline bool IsPowerOf2(const T &value)
//! \brief Tests whether the residue of a value is a power of 2
//! \param a the value to test
//! \param b the value to use to reduce \a to its residue
-//! \returns true if <tt>a%b</tt> is a power of 2, false otherwise
-//! \details The function effectively creates a mask of <tt>b - 1</tt> and returns the result of an AND operation compared to 0. \b must be a power of 2 or the result is undefined.
+//! \returns true if <tt>a\%b</tt> is a power of 2, false otherwise
+//! \details The function effectively creates a mask of <tt>b - 1</tt> and returns the result of an
+//! AND operation compared to 0. b must be a power of 2 or the result is undefined.
template <class T1, class T2>
inline T2 ModPowerOf2(const T1 &a, const T2 &b)
{
@@ -594,7 +737,8 @@ inline T2 ModPowerOf2(const T1 &a, const T2 &b)
//! \param n the value to reduce
//! \param m the value to reduce \n to to a multiple
//! \returns the possibly unmodified value \n
-//! \details \p RoundDownToMultipleOf is effectively a floor function based on \p m. The function returns the value <tt>n - n%m</tt>. If \p n is a multiple of \p m, then the original value is returned.
+//! \details RoundDownToMultipleOf is effectively a floor function based on m. The function returns
+//! the value <tt>n - n\%m</tt>. If n is a multiple of m, then the original value is returned.
template <class T1, class T2>
inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m)
{
@@ -608,7 +752,9 @@ inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m)
//! \param n the value to reduce
//! \param m the value to reduce \n to to a multiple
//! \returns the possibly unmodified value \n
-//! \details \p RoundUpToMultipleOf is effectively a ceiling function based on \p m. The function returns the value <tt>n + n%m</tt>. If \p n is a multiple of \p m, then the original value is returned. If the value \p n would overflow, then an \p InvalidArgument exception is thrown.
+//! \details RoundUpToMultipleOf is effectively a ceiling function based on m. The function
+//! returns the value <tt>n + n\%m</tt>. If n is a multiple of m, then the original value is
+//! returned. If the value n would overflow, then an InvalidArgument exception is thrown.
template <class T1, class T2>
inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
{
@@ -620,7 +766,10 @@ inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
//! \brief Returns the minimum alignment requirements of a type
//! \param dummy an unused Visual C++ 6.0 workaround
//! \returns the minimum alignment requirements of a type, in bytes
-//! \details Internally the function calls C++11's \p alignof if available. If not available, the the function uses compiler specific extensions such as \p __alignof and \p _alignof_. \p sizeof(T) is used if the others are not available. In all cases, if \p CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is defined, then the function returns 1.
+//! \details Internally the function calls C++11's alignof if available. If not available, the
+//! function uses compiler specific extensions such as __alignof and _alignof_. sizeof(T)
+//! is used if the others are not available. In all cases, if CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
+//! is defined, then the function returns 1.
template <class T>
inline unsigned int GetAlignmentOf(T *dummy=NULL) // VC60 workaround
{
@@ -643,21 +792,22 @@ inline unsigned int GetAlignmentOf(T *dummy=NULL) // VC60 workaround
#endif
}
-//! \brief Determines whether \p ptr is aligned to a minimum value
+//! \brief Determines whether ptr is aligned to a minimum value
//! \param ptr the pointer being checked for alignment
//! \param alignment the alignment value to test the pointer against
-//! \returns true if \p ptr is aligned on at least \p align boundary
-//! \details Internally the function tests whether \p alignment is 1. If so, the function returns true. If not, then the function effectively performs a modular reduction and returns \p true if the residue is 0
+//! \returns true if ptr is aligned on at least align boundary
+//! \details Internally the function tests whether alignment is 1. If so, the function returns true.
+//! If not, then the function effectively performs a modular reduction and returns true if the residue is 0
inline bool IsAlignedOn(const void *ptr, unsigned int alignment)
{
return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2((size_t)ptr, alignment) == 0 : (size_t)ptr % alignment == 0);
}
-//! \brief Determines whether \p ptr is minimally aligned
+//! \brief Determines whether ptr is minimally aligned
//! \param ptr the pointer to check for alignment
//! \param dummy an unused Visual C++ 6.0 workaround
-//! \returns true if \p ptr follows native byte ordering, false otherwise
-//! \details Internally the function calls \p IsAlignedOn with a second parameter of \p GetAlignmentOf<T>
+//! \returns true if ptr follows native byte ordering, false otherwise
+//! \details Internally the function calls IsAlignedOn with a second parameter of GetAlignmentOf<T>
template <class T>
inline bool IsAligned(const void *ptr, T *dummy=NULL) // VC60 workaround
{
@@ -673,38 +823,63 @@ inline bool IsAligned(const void *ptr, T *dummy=NULL) // VC60 workaround
# error "Unable to determine endian-ness"
#endif
-//! \brief Returns \p NativeByteOrder as an enumerated \p ByteOrder value
-//! \returns \p LittleEndian if the native byte order is little-endian, and \p BigEndian if the native byte order is big-endian
-//! \details \p NativeByteOrder is a typedef depending on the platform. If \p IS_LITTLE_ENDIAN is set in \headerfile config.h, then \p GetNativeByteOrder returns \p LittleEndian. If \p IS_BIG_ENDIAN is set, then \p GetNativeByteOrder returns \p BigEndian.
-//! \note There are other byte orders besides little- and big-endian, and they include bi-endian and PDP-endian. If a system is neither little-endian nor big-endian, then a compile time error occurs.
+//! \brief Returns NativeByteOrder as an enumerated ByteOrder value
+//! \returns LittleEndian if the native byte order is little-endian, and BigEndian if the
+ //! native byte order is big-endian
+//! \details NativeByteOrder is a typedef depending on the platform. If IS_LITTLE_ENDIAN is
+ //! set in \headerfile config.h, then GetNativeByteOrder returns LittleEndian. If
+ //! IS_BIG_ENDIAN is set, then GetNativeByteOrder returns BigEndian.
+//! \note There are other byte orders besides little- and big-endian, and they include bi-endian
+ //! and PDP-endian. If a system is neither little-endian nor big-endian, then a compile time error occurs.
inline ByteOrder GetNativeByteOrder()
{
return NativeByteOrder::ToEnum();
}
-//! \brief Determines whether \p order follows native byte ordering
+//! \brief Determines whether order follows native byte ordering
//! \param order the ordering being tested against native byte ordering
-//! \returns true if \p order follows native byte ordering, false otherwise
+//! \returns true if order follows native byte ordering, false otherwise
inline bool NativeByteOrderIs(ByteOrder order)
{
return order == GetNativeByteOrder();
}
-//! \brief Performs a saturating subtract.
+//! \brief Performs a saturating subtract clamped at 0
//! \param a the minuend
//! \param b the subtrahend
//! \returns the difference produced by the saturating subtract
//! \details Saturating arithmetic restricts results to a fixed range. Results that are less than 0 are clamped at 0.
+//! \details Use of saturating arithmetic in places can be advantageous because it can
+//! avoid a branch by using an instruction like a conditional move (<tt>CMOVE</tt>).
template <class T1, class T2>
inline T1 SaturatingSubtract(const T1 &a, const T2 &b)
{
+ // Generated ASM of a typical clamp, http://gcc.gnu.org/ml/gcc-help/2014-10/msg00112.html
return T1((a > b) ? (a - b) : 0);
}
+//! \brief Performs a saturating subtract clamped at 1
+//! \param a the minuend
+//! \param b the subtrahend
+//! \returns the difference produced by the saturating subtract
+//! \details Saturating arithmetic restricts results to a fixed range. Results that are less than 1 are clamped at 1.
+//! \details Use of saturating arithmetic in places can be advantageous because it can
+//! avoid a branch by using an instruction like a conditional move (<tt>CMOVE</tt>).
+template <class T1, class T2>
+inline T1 SaturatingSubtract1(const T1 &a, const T2 &b)
+{
+ // Generated ASM of a typical clamp, http://gcc.gnu.org/ml/gcc-help/2014-10/msg00112.html
+ return T1((a > b) ? (a - b) : 1);
+}
+
//! \brief Returns the direction the cipher is being operated
//! \param obj the cipher object being queried
-//! \returns /p ENCRYPTION if the cipher \p obj is being operated in its forward direction, \p DECRYPTION otherwise
-//! \details ciphers can be operated in a "forward" direction (encryption) and a "reverse" direction (decryption). The operations do not have to be symmetric, meaning a second application of the transformation does not necessariy return the original message. That is, <tt>E(D(m))</tt> may not equal <tt>E(E(m))</tt>; and <tt>D(E(m))</tt> may not equal <tt>D(D(m))</tt>.
+//! \returns /p ENCRYPTION if the cipher obj is being operated in its forward direction,
+//! DECRYPTION otherwise
+//! \details ciphers can be operated in a "forward" direction (encryption) and a "reverse"
+//! direction (decryption). The operations do not have to be symmetric, meaning a second application
+//! of the transformation does not necessariy return the original message. That is, <tt>E(D(m))</tt>
+//! may not equal <tt>E(E(m))</tt>; and <tt>D(E(m))</tt> may not equal <tt>D(D(m))</tt>.
template <class T>
inline CipherDir GetCipherDir(const T &obj)
{
@@ -713,14 +888,20 @@ inline CipherDir GetCipherDir(const T &obj)
//! \brief Attempts to reclaim unused memory
//! \throws bad_alloc
-//! \details In the normal course of running a program, a request for memory normally succeeds. If a call to \p AlignedAllocate or \p UnalignedAllocate fails, then \p CallNewHandler is called in an effort to recover. Internally, \p CallNewHandler calls \p set_new_handler(NULL) in an effort to free memory. There is no guarantee \p CallNewHandler will be able to procure more memory so an allocation succeeds. If the call to \p set_new_handler fails, then \p CallNewHandler throws a \p bad_alloc exception.
+//! \details In the normal course of running a program, a request for memory normally succeeds. If a
+//! call to AlignedAllocate or UnalignedAllocate fails, then CallNewHandler is called in
+//! an effort to recover. Internally, CallNewHandler calls set_new_handler(NULL) in an effort
+//! to free memory. There is no guarantee CallNewHandler will be able to procure more memory so
+//! an allocation succeeds. If the call to set_new_handler fails, then CallNewHandler throws
+//! a bad_alloc exception.
CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler();
//! \brief Performs an addition with carry on a block of bytes
//! \param inout the byte block
//! \param size the size of the block, in bytes
-//! \details Performs an addition with carry by adding 1 on a block of bytes starting at the least significant byte. Once \p carry is 0, the function terminates and returns to the caller.
-//! \note The function is not constant time because it stops processing when the \p carry is 0.
+//! \details Performs an addition with carry by adding 1 on a block of bytes starting at the least
+//! significant byte. Once carry is 0, the function terminates and returns to the caller.
+//! \note The function is not constant time because it stops processing when the carry is 0.
inline void IncrementCounterByOne(byte *inout, unsigned int size)
{
assert(inout != NULL); assert(size < INT_MAX);
@@ -732,7 +913,8 @@ inline void IncrementCounterByOne(byte *inout, unsigned int size)
//! \param output the destination block of bytes
//! \param input the source block of bytes
//! \param size the size of the block
-//! \details Performs an addition with carry on a block of bytes starting at the least significant byte. Once \p carry is 0, the remaining bytes from \p input are copied to \p output using \p memcpy.
+//! \details Performs an addition with carry on a block of bytes starting at the least significant
+//! byte. Once carry is 0, the remaining bytes from input are copied to output using memcpy.
//! \details The function is \a close to near-constant time because it operates on all the bytes in the blocks.
inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int size)
{
@@ -744,7 +926,7 @@ inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int
memcpy_s(output, size, input, i+1);
}
-//! \brief Performs a branchless swap of values \p a and \p b if condition \p c is true
+//! \brief Performs a branchless swap of values a and b if condition c is true
//! \param c the condition to perform the swap
//! \param a the first value
//! \param b the second value
@@ -756,7 +938,7 @@ inline void ConditionalSwap(bool c, T &a, T &b)
b ^= t;
}
-//! \brief Performs a branchless swap of pointers \p a and \p b if condition \p c is true
+//! \brief Performs a branchless swap of pointers a and b if condition c is true
//! \param c the condition to perform the swap
//! \param a the first pointer
//! \param b the second pointer
@@ -865,13 +1047,18 @@ inline void SecureWipeArray(T *buf, size_t n)
SecureWipeBuffer((byte *)buf, n * sizeof(T));
}
-//! \brief Converts a wide character C-string to a multibyte \p string
+//! \brief Converts a wide character C-string to a multibyte string
//! \param str a C-string consiting of wide characters
-//! \param throwOnError specifies the function should throw an \p InvalidArgument exception on error
-//! \returns \p str converted to a multibyte string or an empty string.
-//! \details This function converts a wide string to a string using C++ \p wcstombs under the executing thread's locale. A locale must be set before using this function, and it can be set with \p setlocale.
-//! Upon success, the converted string is returned. Upon failure with \p throwOnError as \p false, the function returns an empty string. Upon failure with \p throwOnError as \p true, the function throws InvalidArgument exception.
-//! \note If you try to convert, say, the Chinese character for "bone" from UTF-16 (0x9AA8) to UTF-8 (0xE9 0xAA 0xA8), then you should ensure the locales are available. If the locales are not available, then a 0x21 error is returned which eventually results in an \p InvalidArgument exception
+//! \param throwOnError specifies the function should throw an InvalidArgument exception on error
+//! \returns str converted to a multibyte string or an empty string.
+//! \details This function converts a wide string to a string using C++ wcstombs under the executing
+//! thread's locale. A locale must be set before using this function, and it can be set with setlocale.
+//! Upon success, the converted string is returned. Upon failure with throwOnError as false, the
+//! function returns an empty string. Upon failure with throwOnError as true, the function throws
+//! InvalidArgument exception.
+//! \note If you try to convert, say, the Chinese character for "bone" from UTF-16 (0x9AA8) to UTF-8
+//! (0xE9 0xAA 0xA8), then you should ensure the locales are available. If the locales are not available,
+//! then a 0x21 error is returned which eventually results in an InvalidArgument exception
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
static inline std::string StringNarrow(const wchar_t *str, bool throwOnError = true)
#else
@@ -936,13 +1123,18 @@ CONVERSION_ERROR:
//! \brief Allocates a buffer on 16-byte boundary
//! \param size the size of the buffer
-//! \details \p AlignedAllocate is primarily used when the data will be proccessed by MMX and SSE2 instructions. The assembly language routines rely on the alignment. If the alignment is not respected, then a \p SIGBUS is generated under Unix and an \p EXCEPTION_DATATYPE_MISALIGNMENT is generated under Windows.
-//! \note \p AlignedAllocate and \p AlignedDeallocate are available when \p CRYPTOPP_BOOL_ALIGN16 is defined. \p CRYPTOPP_BOOL_ALIGN16 is defined in config.h
+//! \details AlignedAllocate is primarily used when the data will be proccessed by MMX and SSE2
+//! instructions. The assembly language routines rely on the alignment. If the alignment is not
+//! respected, then a SIGBUS is generated under Unix and an EXCEPTION_DATATYPE_MISALIGNMENT
+//! is generated under Windows.
+//! \note AlignedAllocate and AlignedDeallocate are available when CRYPTOPP_BOOL_ALIGN16 is
+//! defined. CRYPTOPP_BOOL_ALIGN16 is defined in config.h
CRYPTOPP_DLL void* CRYPTOPP_API AlignedAllocate(size_t size);
-//! \brief Frees a buffer allocated with \p AlignedAllocate
+//! \brief Frees a buffer allocated with AlignedAllocate
//! \param ptr the buffer to free
-//! \note \p AlignedAllocate and \p AlignedDeallocate are available when \p CRYPTOPP_BOOL_ALIGN16 is defined. \p CRYPTOPP_BOOL_ALIGN16 is defined in config.h
+//! \note AlignedAllocate and AlignedDeallocate are available when CRYPTOPP_BOOL_ALIGN16 is
+//! defined. CRYPTOPP_BOOL_ALIGN16 is defined in config.h
CRYPTOPP_DLL void CRYPTOPP_API AlignedDeallocate(void *ptr);
#endif // CRYPTOPP_DOXYGEN_PROCESSING
@@ -956,7 +1148,7 @@ CRYPTOPP_DLL void CRYPTOPP_API AlignedDeallocate(void *ptr);
//! \param size the size of the buffer
CRYPTOPP_DLL void * CRYPTOPP_API UnalignedAllocate(size_t size);
-//! \brief Frees a buffer allocated with \p UnalignedAllocate
+//! \brief Frees a buffer allocated with UnalignedAllocate
//! \param ptr the buffer to free
CRYPTOPP_DLL void CRYPTOPP_API UnalignedDeallocate(void *ptr);
@@ -965,9 +1157,12 @@ CRYPTOPP_DLL void CRYPTOPP_API UnalignedDeallocate(void *ptr);
//! \brief Performs a left rotate
//! \param x the value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
-//! \details \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior. Use \p rotlMod if the rotate amount \p y is outside the range.
-//! \note \p rotlFixed attempts to enlist a <tt>rotate IMM</tt> instruction because its often faster than a <tt>rotate REG</tt>. Immediate rotates can be up to three times faster than their register counterparts.
+//! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits.
+//! \details y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! Use rotlMod if the rotate amount y is outside the range.
+//! \note rotlFixed attempts to enlist a <tt>rotate IMM</tt> instruction because its often faster
+//! than a <tt>rotate REG</tt>. Immediate rotates can be up to three times faster than their register
+//! counterparts.
template <class T> inline T rotlFixed(T x, unsigned int y)
{
// Portable rotate that reduces to single instruction...
@@ -985,9 +1180,12 @@ template <class T> inline T rotlFixed(T x, unsigned int y)
//! \brief Performs a right rotate
//! \param x the value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
-//! \details \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior. Use \p rotlMod if the rotate amount \p y is outside the range.
-//! \note \p rotrFixed attempts to enlist a <tt>rotate IMM</tt> instruction because its often faster than a <tt>rotate REG</tt>. Immediate rotates can be up to three times faster than their register counterparts.
+//! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits.
+//! \details y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! Use rotrMod if the rotate amount y is outside the range.
+//! \note rotrFixed attempts to enlist a <tt>rotate IMM</tt> instruction because its often faster
+//! than a <tt>rotate REG</tt>. Immediate rotates can be up to three times faster than their register
+//! counterparts.
template <class T> inline T rotrFixed(T x, unsigned int y)
{
// Portable rotate that reduces to single instruction...
@@ -1003,9 +1201,12 @@ template <class T> inline T rotrFixed(T x, unsigned int y)
//! \brief Performs a left rotate
//! \param x the value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
-//! \details \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior. Use \p rotlMod if the rotate amount \p y is outside the range.
-//! \note \p rotlVariable will use either <tt>rotate IMM</tt> or <tt>rotate REG</tt>.
+//! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits.
+//! \details y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! Use rotlMod if the rotate amount y is outside the range.
+//! \note rotlVariable attempts to enlist a <tt>rotate IMM</tt> instruction because its often faster
+//! than a <tt>rotate REG</tt>. Immediate rotates can be up to three times faster than their register
+//! counterparts.
template <class T> inline T rotlVariable(T x, unsigned int y)
{
static const unsigned int THIS_SIZE = sizeof(T)*8;
@@ -1017,9 +1218,12 @@ template <class T> inline T rotlVariable(T x, unsigned int y)
//! \brief Performs a right rotate
//! \param x the value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
-//! \details \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior. Use \p rotlMod if the rotate amount \p y is outside the range.
-//! \note \p rotrVariable will use either <tt>rotate IMM</tt> or <tt>rotate REG</tt>.
+//! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits.
+//! \details y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! Use rotrMod if the rotate amount y is outside the range.
+//! \note rotrVariable attempts to enlist a <tt>rotate IMM</tt> instruction because its often faster
+//! than a <tt>rotate REG</tt>. Immediate rotates can be up to three times faster than their register
+//! counterparts.
template <class T> inline T rotrVariable(T x, unsigned int y)
{
static const unsigned int THIS_SIZE = sizeof(T)*8;
@@ -1031,9 +1235,9 @@ template <class T> inline T rotrVariable(T x, unsigned int y)
//! \brief Performs a left rotate
//! \param x the value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
-//! \details \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
-//! \note \p rotrVariable will use either <tt>rotate IMM</tt> or <tt>rotate REG</tt>.
+//! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits.
+//! \details y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \note rotrVariable will use either <tt>rotate IMM</tt> or <tt>rotate REG</tt>.
template <class T> inline T rotlMod(T x, unsigned int y)
{
static const unsigned int THIS_SIZE = sizeof(T)*8;
@@ -1044,9 +1248,9 @@ template <class T> inline T rotlMod(T x, unsigned int y)
//! \brief Performs a right rotate
//! \param x the value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
-//! \details \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
-//! \note \p rotrVariable will use either <tt>rotate IMM</tt> or <tt>rotate REG</tt>.
+//! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits.
+//! \details y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \note rotrVariable will use either <tt>rotate IMM</tt> or <tt>rotate REG</tt>.
template <class T> inline T rotrMod(T x, unsigned int y)
{
static const unsigned int THIS_SIZE = sizeof(T)*8;
@@ -1059,8 +1263,10 @@ template <class T> inline T rotrMod(T x, unsigned int y)
//! \brief Performs a left rotate
//! \param x the 32-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
-//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
+//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 32-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \note rotlFixed will assert in Debug builds if is outside the allowed range.
template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
{
// Uses Microsoft <stdlib.h> call, bound to C/C++ language rules.
@@ -1071,8 +1277,10 @@ template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
//! \brief Performs a right rotate
//! \param x the 32-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
-//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
+//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 32-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \note rotrFixed will assert in Debug builds if is outside the allowed range.
template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
{
// Uses Microsoft <stdlib.h> call, bound to C/C++ language rules.
@@ -1083,8 +1291,10 @@ template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
//! \brief Performs a left rotate
//! \param x the 32-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
-//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
+//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 32-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \note rotlVariable will assert in Debug builds if is outside the allowed range.
template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
{
assert(y < 8*sizeof(x));
@@ -1094,8 +1304,10 @@ template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
//! \brief Performs a right rotate
//! \param x the 32-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
-//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
+//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 32-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \note rotrVariable will assert in Debug builds if is outside the allowed range.
template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
{
assert(y < 8*sizeof(x));
@@ -1105,7 +1317,9 @@ template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
//! \brief Performs a left rotate
//! \param x the 32-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 32-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
{
y %= 8*sizeof(x);
@@ -1115,7 +1329,9 @@ template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
//! \brief Performs a right rotate
//! \param x the 32-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 32-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
{
y %= 8*sizeof(x);
@@ -1130,8 +1346,10 @@ template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
//! \brief Performs a left rotate
//! \param x the 64-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
-//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
+//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 64-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \note rotrFixed will assert in Debug builds if is outside the allowed range.
template<> inline word64 rotlFixed<word64>(word64 x, unsigned int y)
{
// Uses Microsoft <stdlib.h> call, bound to C/C++ language rules.
@@ -1142,8 +1360,10 @@ template<> inline word64 rotlFixed<word64>(word64 x, unsigned int y)
//! \brief Performs a right rotate
//! \param x the 64-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
-//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
+//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 64-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \note rotrFixed will assert in Debug builds if is outside the allowed range.
template<> inline word64 rotrFixed<word64>(word64 x, unsigned int y)
{
// Uses Microsoft <stdlib.h> call, bound to C/C++ language rules.
@@ -1154,8 +1374,10 @@ template<> inline word64 rotrFixed<word64>(word64 x, unsigned int y)
//! \brief Performs a left rotate
//! \param x the 64-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
-//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
+//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 64-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \note rotlVariable will assert in Debug builds if is outside the allowed range.
template<> inline word64 rotlVariable<word64>(word64 x, unsigned int y)
{
assert(y < 8*sizeof(x));
@@ -1165,8 +1387,10 @@ template<> inline word64 rotlVariable<word64>(word64 x, unsigned int y)
//! \brief Performs a right rotate
//! \param x the 64-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
-//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
+//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 64-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \note rotrVariable will assert in Debug builds if is outside the allowed range.
template<> inline word64 rotrVariable<word64>(word64 x, unsigned int y)
{
assert(y < 8*sizeof(x));
@@ -1176,7 +1400,9 @@ template<> inline word64 rotrVariable<word64>(word64 x, unsigned int y)
//! \brief Performs a left rotate
//! \param x the 64-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 64-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
template<> inline word64 rotlMod<word64>(word64 x, unsigned int y)
{
assert(y < 8*sizeof(x));
@@ -1186,7 +1412,9 @@ template<> inline word64 rotlMod<word64>(word64 x, unsigned int y)
//! \brief Performs a right rotate
//! \param x the 64-bit value to rotate
//! \param y the number of bit positions to rotate the value
-//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
+//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile
+//! <stdlib.h>. The value x to be rotated is 64-bits. y must be in the range
+//! <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
template<> inline word64 rotrMod<word64>(word64 x, unsigned int y)
{
assert(y < 8*sizeof(x));
@@ -1305,7 +1533,7 @@ template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
// ************** endian reversal ***************
//! \brief Gets a byte from a value
-//! \param order the \p ByteOrder of the value
+//! \param order the ByteOrder of the value
//! \param value the value to retrieve the byte
//! \param index the location of the byte to retrieve
template <class T>
@@ -1319,7 +1547,7 @@ inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
//! \brief Reverses bytes in a 8-bit value
//! \param value the 8-bit value to reverse
-//! \note \p ByteReverse returns the value passed to it since there is nothing to reverse
+//! \note ByteReverse returns the value passed to it since there is nothing to reverse
inline byte ByteReverse(byte value)
{
return value;
@@ -1328,7 +1556,7 @@ inline byte ByteReverse(byte value)
//! \brief Reverses bytes in a 16-bit value
//! \brief Performs an endian reversal
//! \param value the 16-bit value to reverse
-//! \details \p ByteReverse calls \p bswap if available. Otherwise the function performs a 8-bit rotate on the \p word16
+//! \details ByteReverse calls bswap if available. Otherwise the function performs a 8-bit rotate on the word16
inline word16 ByteReverse(word16 value)
{
#ifdef CRYPTOPP_BYTESWAP_AVAILABLE
@@ -1343,7 +1571,7 @@ inline word16 ByteReverse(word16 value)
//! \brief Reverses bytes in a 32-bit value
//! \brief Performs an endian reversal
//! \param value the 32-bit value to reverse
-//! \details \p ByteReverse calls \p bswap if available. Otherwise the function uses a combination of rotates on the \p word32
+//! \details ByteReverse calls bswap if available. Otherwise the function uses a combination of rotates on the word32
inline word32 ByteReverse(word32 value)
{
#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)
@@ -1368,7 +1596,7 @@ inline word32 ByteReverse(word32 value)
//! \brief Reverses bytes in a 64-bit value
//! \brief Performs an endian reversal
//! \param value the 64-bit value to reverse
-//! \details \p ByteReverse calls \p bswap if available. Otherwise the function uses a combination of rotates on the \p word64
+//! \details ByteReverse calls bswap if available. Otherwise the function uses a combination of rotates on the word64
inline word64 ByteReverse(word64 value)
{
#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__)
@@ -1389,7 +1617,7 @@ inline word64 ByteReverse(word64 value)
//! \brief Reverses bits in a 8-bit value
//! \param value the 8-bit value to reverse
-//! \details \p BitReverse performs a combination of shifts on the \p byte
+//! \details BitReverse performs a combination of shifts on the byte
inline byte BitReverse(byte value)
{
value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
@@ -1399,7 +1627,7 @@ inline byte BitReverse(byte value)
//! \brief Reverses bits in a 16-bit value
//! \param value the 16-bit value to reverse
-//! \details \p BitReverse performs a combination of shifts on the \p word16
+//! \details BitReverse performs a combination of shifts on the word16
inline word16 BitReverse(word16 value)
{
value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
@@ -1410,7 +1638,7 @@ inline word16 BitReverse(word16 value)
//! \brief Reverses bits in a 32-bit value
//! \param value the 32-bit value to reverse
-//! \details \p BitReverse performs a combination of shifts on the \p word32
+//! \details BitReverse performs a combination of shifts on the word32
inline word32 BitReverse(word32 value)
{
value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
@@ -1421,7 +1649,7 @@ inline word32 BitReverse(word32 value)
//! \brief Reverses bits in a 64-bit value
//! \param value the 64-bit value to reverse
-//! \details \p BitReverse performs a combination of shifts on the \p word64
+//! \details BitReverse performs a combination of shifts on the word64
inline word64 BitReverse(word64 value)
{
#if CRYPTOPP_BOOL_SLOW_WORD64
@@ -1436,7 +1664,10 @@ inline word64 BitReverse(word64 value)
//! \brief Reverses bits in a value
//! \param value the value to reverse
-//! \details The template overload of \p BitReverse operates on signed and unsigned values. Internally the size of \p T is checked, and then \p value is cast to a \p byte, \p word16, \p word32 or \p word64. After the cast, the appropriate \p BitReverse overload is called.
+//! \details The template overload of BitReverse operates on signed and unsigned values.
+//! Internally the size of T is checked, and then value is cast to a byte,
+//! word16, word32 or word64. After the cast, the appropriate BitReverse
+//! overload is called.
template <class T>
inline T BitReverse(T value)
{
@@ -1454,15 +1685,30 @@ inline T BitReverse(T value)
}
//! \brief Reverses bytes in a value depending upon endianess
-//! \param order the \p ByteOrder the data is represented
+//! \tparam T the class or type
+//! \param order the ByteOrder the data is represented
//! \param value the value to conditionally reverse
-//! \details Internally, the \p ConditionalByteReverse calls \p NativeByteOrderIs. If \p order matches native byte order, then the original \p value is returned. If not, then \p ByteReverse is called on the value before returning to the caller.
+//! \details Internally, the ConditionalByteReverse calls NativeByteOrderIs.
+//! If order matches native byte order, then the original value is returned.
+//! If not, then ByteReverse is called on the value before returning to the caller.
template <class T>
inline T ConditionalByteReverse(ByteOrder order, T value)
{
return NativeByteOrderIs(order) ? value : ByteReverse(value);
}
+//! \brief Reverses bytes in an element among an array of elements
+//! \tparam T the class or type
+//! \param out the output array of elements
+//! \param in the input array of elements
+//! \param byteCount the byte count of the arrays
+//! \details Internally, ByteReverse visits each element in the in array
+//! calls ByteReverse on it, and writes the result to out.
+//! \details ByteReverse does not process tail byes, or bytes that are
+//! \a not part of a full element. If T is int (and int is 4 bytes), then
+//! <tt>byteCount = 10</tt> means only the first 8 bytes are reversed.
+//! \note ByteReverse uses the number of bytes in the arrays, and not the count
+//! of elements in the arrays.
template <class T>
void ByteReverse(T *out, const T *in, size_t byteCount)
{
@@ -1472,6 +1718,19 @@ void ByteReverse(T *out, const T *in, size_t byteCount)
out[i] = ByteReverse(in[i]);
}
+//! \brief Reverses bytes in an element among an array of elements depending upon endianess
+//! \tparam T the class or type
+//! \param order the ByteOrder the data is represented
+//! \param out the output array of elements
+//! \param in the input array of elements
+//! \param byteCount the byte count of the arrays
+//! \details Internally, ByteReverse visits each element in the in array
+//! calls ByteReverse on it, and writes the result to out.
+//! \details ByteReverse does not process tail byes, or bytes that are
+//! \a not part of a full element. If T is int (and int is 4 bytes), then
+//! <tt>byteCount = 10</tt> means only the first 8 bytes are reversed.
+//! \note ByteReverse uses the number of bytes in the arrays, and not the count
+//! of elements in the arrays.
template <class T>
inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount)
{
diff --git a/modarith.h b/modarith.h
index 7caf1b96..bde1bbe6 100644
--- a/modarith.h
+++ b/modarith.h
@@ -1,3 +1,8 @@
+// modarith.h - written and placed in the public domain by Wei Dai
+
+//! \file modarith.h
+//! \brief Class file for performing modular arithmetic.
+
#ifndef CRYPTOPP_MODARITH_H
#define CRYPTOPP_MODARITH_H
@@ -15,8 +20,10 @@ CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup<Integer>;
CRYPTOPP_DLL_TEMPLATE_CLASS AbstractRing<Integer>;
CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain<Integer>;
-//! ring of congruence classes modulo n
-/*! \note this implementation represents each congruence class as the smallest non-negative integer in that class */
+//! \class ModularArithmetic
+//! \brief Ring of congruence classes modulo n
+//! \note this implementation represents each congruence class as the smallest
+//! non-negative integer in that class
class CRYPTOPP_DLL ModularArithmetic : public AbstractRing<Integer>
{
public:
@@ -25,10 +32,9 @@ public:
typedef Integer Element;
ModularArithmetic(const Integer &modulus = Integer::One())
- : m_modulus(modulus), m_result((word)0, modulus.reg.size()) {}
-
+ : AbstractRing<Integer>(), m_modulus(modulus), m_result((word)0, modulus.reg.size()) {}
ModularArithmetic(const ModularArithmetic &ma)
- : AbstractRing<Integer>(ma), m_modulus(ma.m_modulus), m_result((word)0, m_modulus.reg.size()) {}
+ : AbstractRing<Integer>(), m_modulus(ma.m_modulus), m_result((word)0, ma.m_modulus.reg.size()) {}
ModularArithmetic(BufferedTransformation &bt); // construct from BER encoded parameters
@@ -40,7 +46,8 @@ public:
void BERDecodeElement(BufferedTransformation &in, Element &a) const;
const Integer& GetModulus() const {return m_modulus;}
- void SetModulus(const Integer &newModulus) {m_modulus = newModulus; m_result.reg.resize(m_modulus.reg.size());}
+ void SetModulus(const Integer &newModulus)
+ {m_modulus = newModulus; m_result.reg.resize(m_modulus.reg.size());}
virtual bool IsMontgomeryRepresentation() const {return false;}
@@ -110,6 +117,10 @@ public:
{return m_modulus == rhs.m_modulus;}
static const RandomizationParameter DefaultRandomizationParameter ;
+
+#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
+ virtual ~ModularArithmetic() {}
+#endif
protected:
Integer m_modulus;
@@ -119,8 +130,10 @@ protected:
// const ModularArithmetic::RandomizationParameter ModularArithmetic::DefaultRandomizationParameter = 0 ;
-//! do modular arithmetics in Montgomery representation for increased speed
-/*! \note the Montgomery representation represents each congruence class [a] as a*r%n, where r is a convenient power of 2 */
+//! \class MontgomeryRepresentation
+//! \brief Performs modular arithmetic in Montgomery representation for increased speed
+//! \details The Montgomery representation represents each congruence class <tt>[a]</tt> as
+//! <tt>a*r%n</tt>, where r is a convenient power of 2.
class CRYPTOPP_DLL MontgomeryRepresentation : public ModularArithmetic
{
public:
@@ -150,6 +163,10 @@ public:
void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
{AbstractRing<Integer>::SimultaneousExponentiate(results, base, exponents, exponentsCount);}
+#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
+ virtual ~MontgomeryRepresentation() {}
+#endif
+
private:
Integer m_u;
mutable IntegerSecBlock m_workspace;
diff --git a/modes.cpp b/modes.cpp
index c81f2907..23f6afb1 100644
--- a/modes.cpp
+++ b/modes.cpp
@@ -13,7 +13,7 @@
NAMESPACE_BEGIN(CryptoPP)
-#ifndef NDEBUG
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void Modes_TestInstantiations()
{
CFB_Mode<DES>::Encryption m0;
@@ -35,20 +35,24 @@ void CipherModeBase::ResizeBuffers()
void CFB_ModePolicy::Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount)
{
+ assert(input);
+ assert(output);
assert(m_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
assert(m_feedbackSize == BlockSize());
- unsigned int s = BlockSize();
+ const unsigned int s = BlockSize();
if (dir == ENCRYPTION)
{
m_cipher->ProcessAndXorBlock(m_register, input, output);
- m_cipher->AdvancedProcessBlocks(output, input+s, output+s, (iterationCount-1)*s, 0);
+ if (iterationCount > 1)
+ m_cipher->AdvancedProcessBlocks(output, input+s, output+s, (iterationCount-1)*s, 0);
memcpy(m_register, output+(iterationCount-1)*s, s);
}
else
{
memcpy(m_temp, input+(iterationCount-1)*s, s); // make copy first in case of in-place decryption
- m_cipher->AdvancedProcessBlocks(input, input+s, output+s, (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection);
+ if (iterationCount > 1)
+ m_cipher->AdvancedProcessBlocks(input, input+s, output+s, (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection);
m_cipher->ProcessAndXorBlock(m_register, input, output);
memcpy(m_register, m_temp, s);
}
diff --git a/modes.h b/modes.h
index cfbbdbd7..df773116 100644
--- a/modes.h
+++ b/modes.h
@@ -1,9 +1,11 @@
+// modes.h - written and placed in the public domain by Wei Dai
+
+//! \file modes.h
+//! \brief Class file for modes of operation.
+
#ifndef CRYPTOPP_MODES_H
#define CRYPTOPP_MODES_H
-/*! \file
-*/
-
#include "cryptlib.h"
#include "secblock.h"
#include "misc.h"
@@ -13,17 +15,18 @@
NAMESPACE_BEGIN(CryptoPP)
-//! Cipher modes documentation. See NIST SP 800-38A for definitions of these modes. See AuthenticatedSymmetricCipherDocumentation for authenticated encryption modes.
-
-/*! Each class derived from this one defines two types, Encryption and Decryption,
- both of which implement the SymmetricCipher interface.
- For each mode there are two classes, one of which is a template class,
- and the other one has a name that ends in "_ExternalCipher".
- The "external cipher" mode objects hold a reference to the underlying block cipher,
- instead of holding an instance of it. The reference must be passed in to the constructor.
- For the "cipher holder" classes, the CIPHER template parameter should be a class
- derived from BlockCipherDocumentation, for example DES or AES.
-*/
+//! \class CipherModeDocumentation
+//! \brief Classes for operating block cipher modes of operation
+//! \details Each class derived from this one defines two types, Encryption and Decryption,
+//! both of which implement the SymmetricCipher interface.
+//! For each mode there are two classes, one of which is a template class,
+//! and the other one has a name that ends in "_ExternalCipher".
+//! The "external cipher" mode objects hold a reference to the underlying block cipher,
+//! instead of holding an instance of it. The reference must be passed in to the constructor.
+//! For the "cipher holder" classes, the CIPHER template parameter should be a class
+//! derived from BlockCipherDocumentation, for example DES or AES.
+//! \details See NIST SP 800-38A for definitions of these modes. See
+//! AuthenticatedSymmetricCipherDocumentation for authenticated encryption modes.
struct CipherModeDocumentation : public SymmetricCipherDocumentation
{
};
@@ -292,7 +295,9 @@ public:
{return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();}
};
-//! _
+//! \class CipherModeFinalTemplate_ExternalCipher
+//! \tparam BASE CipherModeFinalTemplate_CipherHolder class
+//! \brief OFB block cipher mode of operation.
template <class BASE>
class CipherModeFinalTemplate_ExternalCipher : public BASE
{
@@ -311,7 +316,8 @@ CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAb
CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
-//! CFB mode
+//! \class CFB_Mode
+//! \brief CFB block cipher mode of operation.
template <class CIPHER>
struct CFB_Mode : public CipherModeDocumentation
{
@@ -319,14 +325,17 @@ struct CFB_Mode : public CipherModeDocumentation
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
};
-//! CFB mode, external cipher
+//! \class CFB_Mode_ExternalCipher
+//! \brief CFB mode, external cipher.
struct CFB_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
};
-//! CFB mode FIPS variant, requiring full block plaintext according to FIPS 800-38A
+//! \class CFB_FIPS_Mode
+//! \brief CFB block cipher mode of operation providing FIPS validated cryptography.
+//! \details Requires full block plaintext according to FIPS 800-38A
template <class CIPHER>
struct CFB_FIPS_Mode : public CipherModeDocumentation
{
@@ -334,7 +343,9 @@ struct CFB_FIPS_Mode : public CipherModeDocumentation
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Decryption;
};
-//! CFB mode FIPS variant, requiring full block plaintext according to FIPS 800-38A, external cipher
+//! \class CFB_FIPS_Mode_ExternalCipher
+//! \brief CFB mode, external cipher, providing FIPS validated cryptography.
+//! \details Requires full block plaintext according to FIPS 800-38A
struct CFB_FIPS_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Encryption;
@@ -343,7 +354,8 @@ struct CFB_FIPS_Mode_ExternalCipher : public CipherModeDocumentation
CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> >;
-//! OFB mode
+//! \class OFB_Mode
+//! \brief OFB block cipher mode of operation.
template <class CIPHER>
struct OFB_Mode : public CipherModeDocumentation
{
@@ -351,7 +363,8 @@ struct OFB_Mode : public CipherModeDocumentation
typedef Encryption Decryption;
};
-//! OFB mode, external cipher
+//! \class OFB_Mode_ExternalCipher
+//! \brief OFB mode, external cipher.
struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
@@ -361,7 +374,8 @@ struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> >;
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > >;
-//! CTR mode
+//! \class CTR_Mode
+//! \brief CTR block cipher mode of operation.
template <class CIPHER>
struct CTR_Mode : public CipherModeDocumentation
{
@@ -369,14 +383,16 @@ struct CTR_Mode : public CipherModeDocumentation
typedef Encryption Decryption;
};
-//! CTR mode, external cipher
+//! \class CTR_Mode_ExternalCipher
+//! \brief CTR mode, external cipher.
struct CTR_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
typedef Encryption Decryption;
};
-//! ECB mode
+//! \class ECB_Mode
+//! \brief ECB block cipher mode of operation.
template <class CIPHER>
struct ECB_Mode : public CipherModeDocumentation
{
@@ -386,7 +402,8 @@ struct ECB_Mode : public CipherModeDocumentation
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ECB_OneWay>;
-//! ECB mode, external cipher
+//! \class ECB_Mode_ExternalCipher
+//! \brief ECB mode, external cipher.
struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption;
@@ -422,7 +439,8 @@ struct CBC_CTS_Mode : public CipherModeDocumentation
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption>;
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption>;
-//! CBC mode with ciphertext stealing, external cipher
+//! \class CBC_CTS_Mode_ExternalCipher
+//! \brief CBC mode with ciphertext stealing, external cipher
struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption;
diff --git a/mqv.cpp b/mqv.cpp
index a290945a..84a6af03 100644
--- a/mqv.cpp
+++ b/mqv.cpp
@@ -5,9 +5,11 @@
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void TestInstantiations_MQV()
{
MQV mqv;
}
+#endif
NAMESPACE_END
diff --git a/mqv.h b/mqv.h
index 1dd389f0..2f06c518 100644
--- a/mqv.h
+++ b/mqv.h
@@ -6,6 +6,7 @@
#include "cryptlib.h"
#include "gfpcrypt.h"
+#include "modarith.h"
#include "integer.h"
#include "misc.h"
diff --git a/oids.h b/oids.h
index d3636d1f..4ce6546d 100644
--- a/oids.h
+++ b/oids.h
@@ -1,3 +1,9 @@
+// oids.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile oids.h
+//! \brief Object identifiers for algorthms and schemes
+
#ifndef CRYPTOPP_OIDS_H
#define CRYPTOPP_OIDS_H
diff --git a/panama.cpp b/panama.cpp
index 66419e3b..12ba1c45 100644
--- a/panama.cpp
+++ b/panama.cpp
@@ -47,7 +47,7 @@ void CRYPTOPP_NOINLINE Panama_SSE2_Pull(size_t count, word32 *state, word32 *z,
#if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
asm __volatile__
(
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
AS_PUSH_IF86( bx)
#else
AS2( mov AS_REG_1, count)
@@ -297,7 +297,7 @@ void CRYPTOPP_NOINLINE Panama_SSE2_Pull(size_t count, word32 *state, word32 *z,
#if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
AS_POP_IF86( bx)
- ".att_syntax prefix;"
+ ATT_PREFIX
:
#if CRYPTOPP_BOOL_X64
: "D" (count), "S" (state), "d" (z), "c" (y)
diff --git a/pch.h b/pch.h
index 765ebde9..206d4c3b 100644
--- a/pch.h
+++ b/pch.h
@@ -1,12 +1,15 @@
+// pch.h - written and placed in the public domain by Wei Dai
+
+//! \headerfile pch.h
+//! \brief Precompiled header file
+
#ifndef CRYPTOPP_PCH_H
#define CRYPTOPP_PCH_H
-#ifdef CRYPTOPP_GENERATE_X64_MASM
-
+# ifdef CRYPTOPP_GENERATE_X64_MASM
#include "cpu.h"
-#else
-
+# else
#include "config.h"
#ifdef USE_PRECOMPILED_HEADERS
@@ -14,8 +17,8 @@
#include "secblock.h"
#include "misc.h"
#include "smartptr.h"
+ #include "stdcpp.h"
#endif
+# endif
-#endif
-
-#endif
+#endif // CRYPTOPP_PCH_H
diff --git a/pkcspad.h b/pkcspad.h
index 096a9237..6a15b496 100644
--- a/pkcspad.h
+++ b/pkcspad.h
@@ -1,3 +1,8 @@
+// pkcspad.h - written and placed in the public domain by Wei Dai
+
+//! \headerfile pkcspad.h
+//! \brief Classes for PKCS padding schemes
+
#ifndef CRYPTOPP_PKCSPAD_H
#define CRYPTOPP_PKCSPAD_H
diff --git a/polynomi.h b/polynomi.h
index 13e01adb..e76b9765 100644
--- a/polynomi.h
+++ b/polynomi.h
@@ -1,3 +1,10 @@
+// polynomi.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile polynomi.h
+//! \brief Classes for polynomial basis and operations
+
+
#ifndef CRYPTOPP_POLYNOMI_H
#define CRYPTOPP_POLYNOMI_H
diff --git a/pssr.cpp b/pssr.cpp
index bbaa3fd5..f1c2fbfd 100644
--- a/pssr.cpp
+++ b/pssr.cpp
@@ -77,7 +77,8 @@ void PSSR_MEM_Base::ComputeMessageRepresentative(RandomNumberGenerator &rng,
GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize, false);
byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1;
xorStart[0] ^= 1;
- xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength);
+ if (recoverableMessage && recoverableMessageLength)
+ xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength);
xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size());
if (hashIdentifier.first && hashIdentifier.second)
{
@@ -114,7 +115,9 @@ DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative(
size_t &recoverableMessageLength = result.messageLength;
valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid;
- valid = VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid;
+
+ if (hashIdentifier.first && hashIdentifier.second)
+ valid = VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid;
GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize);
if (representativeBitLength % 8 != 0)
diff --git a/pssr.h b/pssr.h
index dd847c92..a7047d30 100644
--- a/pssr.h
+++ b/pssr.h
@@ -1,3 +1,9 @@
+// pssr.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile pssr.h
+//! \brief Classes for probablistic signature schemes
+
#ifndef CRYPTOPP_PSSR_H
#define CRYPTOPP_PSSR_H
diff --git a/pubkey.h b/pubkey.h
index 2a08e5d8..82769a27 100644
--- a/pubkey.h
+++ b/pubkey.h
@@ -56,23 +56,61 @@
NAMESPACE_BEGIN(CryptoPP)
-//! _
+//! \class TrapdoorFunctionBounds
+//! \brief Provides range for plaintext and ciphertext lengths
+//! \details A trapdoor function is a function that is easy to compute in one direction,
+//! but difficult to compute in the opposite direction without special knowledge.
+//! The special knowledge is usually the private key.
+//! \details Trapdoor functions only handle messages of a limited length or size.
+//! \p MaxPreimage is the plaintext's maximum length, and \p MaxImage is the
+//! ciphertext's maximum length.
+//! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
+//! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
{
public:
virtual ~TrapdoorFunctionBounds() {}
+ //! \brief Returns the maximum size of a message before the trapdoor function is applied
+ //! \returns the maximum size of a message before the trapdoor function is applied
+ //! \details Derived classes must implement \p PreimageBound().
virtual Integer PreimageBound() const =0;
+ //! \brief Returns the maximum size of a message after the trapdoor function is applied
+ //! \returns the maximum size of a message after the trapdoor function is applied
+ //! \details Derived classes must implement \p ImageBound().
virtual Integer ImageBound() const =0;
+ //! \brief Returns the maximum size of a message before the trapdoor function is applied bound to a public key
+ //! \returns the maximum size of a message before the trapdoor function is applied bound to a public key
+ //! \details The default implementation returns <tt>PreimageBound() - 1</tt>.
virtual Integer MaxPreimage() const {return --PreimageBound();}
+ //! \brief Returns the maximum size of a message after the trapdoor function is applied bound to a public key
+ //! \returns the the maximum size of a message after the trapdoor function is applied bound to a public key
+ //! \details The default implementation returns <tt>ImageBound() - 1</tt>.
virtual Integer MaxImage() const {return --ImageBound();}
};
-//! _
+//! \class RandomizedTrapdoorFunction
+//! \brief Applies the trapdoor function, using random data if required
+//! \details \p ApplyFunction() is the foundation for encrypting a message under a public key.
+//! Derived classes will override it at some point.
+//! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
+//! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
{
public:
+
+ //! \brief Applies the trapdoor function, using random data if required
+ //! \param rng a \p RandomNumberGenerator derived class
+ //! \param x the message on which the encryption function is applied
+ //! \returns the message \p x encrypted under the public key
+ //! \details \p ApplyRandomizedFunction is a generalization of encryption under a public key
+ //! cryptosystem. The \p RandomNumberGenerator may (or may not) be required.
+ //! Derived classes must implement it.
virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
+
+ //! \brief Determines if the encryption algorithm is randomized
+ //! \returns \p true if the encryption algorithm is randominzed, \p false otherwise
+ //! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
virtual bool IsRandomized() const {return true;}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
@@ -80,40 +118,87 @@ public:
#endif
};
-//! _
+//! \class TrapdoorFunction
+//! \brief Applies the trapdoor function
+//! \details \p ApplyFunction() is the foundation for encrypting a message under a public key.
+//! Derived classes will override it at some point.
+//! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
+//! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
{
public:
-
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~TrapdoorFunction() { }
#endif
+ //! \brief Applies the trapdoor function
+ //! \param rng a \p RandomNumberGenerator derived class
+ //! \param x the message on which the encryption function is applied
+ //! \details \p ApplyRandomizedFunction is a generalization of encryption under a public key
+ //! cryptosystem. The \p RandomNumberGenerator may (or may not) be required.
+ //! \details Internally, \p ApplyRandomizedFunction() calls \p ApplyFunction() \a
+ //! without the \p RandomNumberGenerator.
Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
{CRYPTOPP_UNUSED(rng); return ApplyFunction(x);}
bool IsRandomized() const {return false;}
+ //! \brief Applies the trapdoor
+ //! \param x the message on which the encryption function is applied
+ //! \returns the message \p x encrypted under the public key
+ //! \details \p ApplyFunction is a generalization of encryption under a public key
+ //! cryptosystem. Derived classes must implement it.
virtual Integer ApplyFunction(const Integer &x) const =0;
};
-//! _
+//! \class RandomizedTrapdoorFunctionInverse
+//! \brief Applies the inverse of the trapdoor function, using random data if required
+//! \details \p CalculateInverse() is the foundation for decrypting a message under a private key
+//! in a public key cryptosystem. Derived classes will override it at some point.
+//! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
+//! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
{
public:
virtual ~RandomizedTrapdoorFunctionInverse() {}
+ //! \brief Applies the inverse of the trapdoor function, using random data if required
+ //! \param rng a \p RandomNumberGenerator derived class
+ //! \param x the message on which the decryption function is applied
+ //! \returns the message \p x decrypted under the private key
+ //! \details \p CalculateRandomizedInverse is a generalization of decryption using the private key
+ //! The \p RandomNumberGenerator may (or may not) be required. Derived classes must implement it.
virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
+
+ //! \brief Determines if the decryption algorithm is randomized
+ //! \returns \p true if the decryption algorithm is randominzed, \p false otherwise
+ //! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
virtual bool IsRandomized() const {return true;}
};
-//! _
+//! \class TrapdoorFunctionInverse
+//! \brief Applies the inverse of the trapdoor function
+//! \details \p CalculateInverse() is the foundation for decrypting a message under a private key
+//! in a public key cryptosystem. Derived classes will override it at some point.
+//! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
+//! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
{
public:
virtual ~TrapdoorFunctionInverse() {}
+ //! \brief Applies the inverse of the trapdoor function
+ //! \param rng a \p RandomNumberGenerator derived class
+ //! \param x the message on which the decryption function is applied
+ //! \returns the message \p x decrypted under the private key
+ //! \details \p CalculateRandomizedInverse is a generalization of decryption using the private key
+ //! \details Internally, \p CalculateRandomizedInverse() calls \p CalculateInverse() \a
+ //! without the \p RandomNumberGenerator.
Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
{return CalculateInverse(rng, x);}
+
+ //! \brief Determines if the decryption algorithm is randomized
+ //! \returns \p true if the decryption algorithm is randominzed, \p false otherwise
+ //! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
bool IsRandomized() const {return false;}
virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
@@ -121,7 +206,8 @@ public:
// ********************************************************
-//! message encoding method for public key encryption
+//! \class PK_EncryptionMessageEncodingMethod
+//! \brief Message encoding method for public key encryption
class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
{
public:
@@ -140,7 +226,10 @@ public:
// ********************************************************
-//! _
+//! \class TF_Base
+//! \brief The base for trapdoor based cryptosystems
+//! \tparam TFI trapdoor function interface derived class
+//! \tparam MEI message encoding interface derived class
template <class TFI, class MEI>
class CRYPTOPP_NO_VTABLE TF_Base
{
@@ -160,7 +249,9 @@ protected:
// ********************************************************
-//! _
+//! \class PK_FixedLengthCryptoSystemImpl
+//! \brief Public key trapdoor function base class
+//! \tparam BASE public key cryptosystem with a fixed length
template <class BASE>
class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
{
@@ -178,7 +269,10 @@ public:
#endif
};
-//! _
+//! \class TF_CryptoSystemBase
+//! \brief Trapdoor function cryptosystem base class
+//! \tparam INTERFACE public key cryptosystem base interface
+//! \tparam BASE public key cryptosystem implementation base
template <class INTERFACE, class BASE>
class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE
{
@@ -189,14 +283,16 @@ public:
protected:
size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
- size_t PaddedBlockBitLength() const {return this->GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;}
+ // Coverity finding on potential overflow/underflow.
+ size_t PaddedBlockBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().PreimageBound().BitCount(),1U);}
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
virtual ~TF_CryptoSystemBase() { }
#endif
};
-//! _
+//! \class TF_DecryptorBase
+//! \brief Trapdoor function cryptosystems decryption base class
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
{
public:
@@ -207,7 +303,8 @@ public:
#endif
};
-//! _
+//! \class TF_DecryptorBase
+//! \brief Trapdoor function cryptosystems encryption base class
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
{
public:
@@ -222,7 +319,12 @@ public:
typedef std::pair<const byte *, size_t> HashIdentifier;
-//! interface for message encoding method for public key signature schemes
+//! \class PK_SignatureMessageEncodingMethod
+//! \brief Interface for message encoding method for public key signature schemes.
+//! \details \p PK_SignatureMessageEncodingMethod provides interfaces for message
+//! encoding method for public key signature schemes. The methods support both
+//! trapdoor functions (<tt>TF_*</tt>) and discrete logarithm (<tt>DL_*</tt>)
+//! based schemes.
class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
{
public:
@@ -295,6 +397,10 @@ public:
};
};
+//! \class PK_DeterministicSignatureMessageEncodingMethod
+//! \brief Interface for message encoding method for public key signature schemes.
+//! \details \p PK_DeterministicSignatureMessageEncodingMethod provides interfaces
+//! for message encoding method for public key signature schemes.
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
{
public:
@@ -303,6 +409,10 @@ public:
byte *representative, size_t representativeBitLength) const;
};
+//! \class PK_RecoverableSignatureMessageEncodingMethod
+//! \brief Interface for message encoding method for public key signature schemes.
+//! \details \p PK_RecoverableSignatureMessageEncodingMethod provides interfaces
+//! for message encoding method for public key signature schemes.
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
{
public:
@@ -311,6 +421,10 @@ public:
byte *representative, size_t representativeBitLength) const;
};
+//! \class DL_SignatureMessageEncodingMethod_DSA
+//! \brief Interface for message encoding method for public key signature schemes.
+//! \details \p DL_SignatureMessageEncodingMethod_DSA provides interfaces
+//! for message encoding method for DSA.
class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod
{
public:
@@ -320,6 +434,10 @@ public:
byte *representative, size_t representativeBitLength) const;
};
+//! \class DL_SignatureMessageEncodingMethod_NR
+//! \brief Interface for message encoding method for public key signature schemes.
+//! \details \p DL_SignatureMessageEncodingMethod_NR provides interfaces
+//! for message encoding method for Nyberg-Rueppel.
class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod
{
public:
@@ -329,6 +447,10 @@ public:
byte *representative, size_t representativeBitLength) const;
};
+//! \class PK_MessageAccumulatorBase
+//! \brief Interface for message encoding method for public key signature schemes.
+//! \details \p PK_MessageAccumulatorBase provides interfaces
+//! for message encoding method.
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
{
public:
@@ -347,6 +469,10 @@ public:
bool m_empty;
};
+//! \class PK_MessageAccumulatorImpl
+//! \brief Interface for message encoding method for public key signature schemes.
+//! \details \p PK_MessageAccumulatorBase provides interfaces
+//! for message encoding method.
template <class HASH_ALGORITHM>
class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
{
@@ -379,7 +505,8 @@ public:
protected:
size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
- size_t MessageRepresentativeBitLength() const {return this->GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;}
+ // Coverity finding on potential overflow/underflow.
+ size_t MessageRepresentativeBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().ImageBound().BitCount(),1U);}
virtual HashIdentifier GetHashIdentifier() const =0;
virtual size_t GetDigestSize() const =0;
};
diff --git a/queue.cpp b/queue.cpp
index 9a0f82c3..8d9f183b 100644
--- a/queue.cpp
+++ b/queue.cpp
@@ -132,7 +132,7 @@ public:
ByteQueue::ByteQueue(size_t nodeSize)
: Bufferless<BufferedTransformation>(), m_autoNodeSize(!nodeSize), m_nodeSize(nodeSize)
- , m_head(NULL), m_tail(NULL), m_lazyString(NULL), m_lazyLength(0)
+ , m_head(NULL), m_tail(NULL), m_lazyString(NULL), m_lazyLength(0), m_lazyStringModifiable(false)
{
SetNodeSize(nodeSize);
m_head = m_tail = new ByteQueueNode(m_nodeSize);
diff --git a/queue.h b/queue.h
index 6364fec9..570a26d9 100644
--- a/queue.h
+++ b/queue.h
@@ -1,4 +1,8 @@
-// specification file for an unlimited queue for storing bytes
+// queue.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile queue.h
+//! \brief Classes for an unlimited queue to store bytes
#ifndef CRYPTOPP_QUEUE_H
#define CRYPTOPP_QUEUE_H
@@ -66,7 +70,8 @@ public:
{
public:
Walker(const ByteQueue &queue)
- : m_queue(queue) {Initialize();}
+ : m_queue(queue), m_node(NULL), m_position(0), m_offset(0), m_lazyString(NULL), m_lazyLength(0)
+ {Initialize();}
lword GetCurrentPosition() {return m_position;}
diff --git a/rabin.h b/rabin.h
index 8d738315..4da48b12 100644
--- a/rabin.h
+++ b/rabin.h
@@ -1,9 +1,12 @@
+// rabin.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile rabin.h
+//! \brief Classes Rabin encryption and signature schemes
+
#ifndef CRYPTOPP_RABIN_H
#define CRYPTOPP_RABIN_H
-/** \file
-*/
-
#include "cryptlib.h"
#include "oaep.h"
#include "pssr.h"
diff --git a/rc2.h b/rc2.h
index d9dce7ab..fa2f3253 100644
--- a/rc2.h
+++ b/rc2.h
@@ -1,16 +1,18 @@
+// rc2.h - written and placed in the public domain by Wei Dai
+//! \file rc2.h
+//! \brief Class file for the RC2 stream cipher
+
#ifndef CRYPTOPP_RC2_H
#define CRYPTOPP_RC2_H
-/** \file
-*/
-
#include "seckey.h"
#include "secblock.h"
#include "algparam.h"
NAMESPACE_BEGIN(CryptoPP)
-//! _
+//! \class RC2_Info
+//! \brief The RC2 cipher's key, iv, block size and name information.
struct RC2_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 1, 128>
{
CRYPTOPP_CONSTANT(DEFAULT_EFFECTIVE_KEYLENGTH = 1024)
@@ -18,9 +20,14 @@ struct RC2_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 1, 128>
static const char *StaticAlgorithmName() {return "RC2";}
};
-/// <a href="http://www.weidai.com/scan-mirror/cs.html#RC2">RC2</a>
+//! \class RC2
+//! \brief The RC2 stream cipher
+//! \sa <a href="http://www.weidai.com/scan-mirror/cs.html#RC2">RC2</a> on the Crypto Lounge.
class RC2 : public RC2_Info, public BlockCipherDocumentation
{
+ //! \class Base
+ //! \brief Class specific methods used to operate the cipher.
+ //! \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions
class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<RC2_Info>
{
public:
@@ -31,12 +38,18 @@ class RC2 : public RC2_Info, public BlockCipherDocumentation
FixedSizeSecBlock<word16, 64> K; // expanded key table
};
+ //! \class Enc
+ //! \brief Class specific methods used to operate the cipher in the forward direction.
+ //! \details Implementations and overrides in \p Enc apply to \p ENCRYPTION.
class CRYPTOPP_NO_VTABLE Enc : public Base
{
public:
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
};
+ //! \class Dec
+ //! \brief Class specific methods used to operate the cipher in the reverse direction.
+ //! \details Implementations and overrides in \p Dec apply to \p DECRYPTION.
class CRYPTOPP_NO_VTABLE Dec : public Base
{
public:
@@ -44,6 +57,10 @@ class RC2 : public RC2_Info, public BlockCipherDocumentation
};
public:
+
+ //! \class Encryption
+ //! \brief Class specific methods used to operate the cipher in the forward direction.
+ //! \details Implementations and overrides in \p Encryption apply to \p ENCRYPTION.
class Encryption : public BlockCipherFinal<ENCRYPTION, Enc>
{
public:
@@ -54,6 +71,9 @@ public:
{SetKey(key, keyLen, MakeParameters("EffectiveKeyLength", effectiveKeyLen));}
};
+ //! \class Decryption
+ //! \brief Class specific methods used to operate the cipher in the reverse direction.
+ //! \details Implementations and overrides in \p Decryption apply to \p DECRYPTION.
class Decryption : public BlockCipherFinal<DECRYPTION, Dec>
{
public:
diff --git a/rijndael.cpp b/rijndael.cpp
index 4a359a56..934b6884 100644
--- a/rijndael.cpp
+++ b/rijndael.cpp
@@ -617,7 +617,7 @@ CRYPTOPP_NAKED void CRYPTOPP_FASTCALL Rijndael_Enc_AdvancedProcessBlocks(void *l
#elif defined(__GNUC__)
__asm__ __volatile__
(
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
#if CRYPTOPP_BOOL_X64
AS2( mov L_REG, rcx)
#endif
@@ -972,7 +972,7 @@ CRYPTOPP_NAKED void CRYPTOPP_FASTCALL Rijndael_Enc_AdvancedProcessBlocks(void *l
Rijndael_Enc_AdvancedProcessBlocks ENDP
#endif
#ifdef __GNUC__
- ".att_syntax prefix;"
+ ATT_PREFIX
:
: "c" (locals), "d" (k), "S" (Te), "D" (g_cacheLineSize)
: "memory", "cc", "%eax"
diff --git a/rijndael.h b/rijndael.h
index fa64e866..56843e6f 100644
--- a/rijndael.h
+++ b/rijndael.h
@@ -1,9 +1,12 @@
+// rijndael.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile rijndael.h
+//! \brief Classes for Rijndael encryption algorithm
+
#ifndef CRYPTOPP_RIJNDAEL_H
#define CRYPTOPP_RIJNDAEL_H
-/** \file
-*/
-
#include "seckey.h"
#include "secblock.h"
diff --git a/rng.h b/rng.h
index 5a5a6e56..1190aeab 100644
--- a/rng.h
+++ b/rng.h
@@ -1,4 +1,10 @@
-// rng.h - misc RNG related classes, see also osrng.h, randpool.h
+//! rng.h - written and placed in the public domain by Wei Dai
+
+//! \file rng.h
+//! \brief Miscellaneous classes for RNGs
+//! \details This file contains miscellaneous classes for RNGs, including LC_RNG(),
+//! X917RNG() and MaurerRandomnessTest()
+//! \sa osrng.h, randpool.h
#ifndef CRYPTOPP_RNG_H
#define CRYPTOPP_RNG_H
@@ -47,10 +53,12 @@ private:
SecByteBlock randseed, m_lastBlock, m_deterministicTimeVector;
};
-/** This class implements Maurer's Universal Statistical Test for Random Bit Generators
- it is intended for measuring the randomness of *PHYSICAL* RNGs.
- For more details see his paper in Journal of Cryptology, 1992. */
-
+//! \class MaurerRandomnessTest
+//! \brief Maurer's Universal Statistical Test for Random Bit Generators
+//! \details This class implements Maurer's Universal Statistical Test for
+//! Random Bit Generators. It is intended for measuring the randomness of
+//! *PHYSICAL* RNGs.
+//! \details For more details see Maurer's paper in Journal of Cryptology, 1992.
class MaurerRandomnessTest : public Bufferless<Sink>
{
public:
diff --git a/rsa.cpp b/rsa.cpp
index 9ec1163d..1b71e268 100644
--- a/rsa.cpp
+++ b/rsa.cpp
@@ -3,14 +3,14 @@
#include "pch.h"
#include "rsa.h"
#include "asn.h"
+#include "sha.h"
#include "oids.h"
#include "modarith.h"
#include "nbtheory.h"
-#include "sha.h"
#include "algparam.h"
#include "fips140.h"
-#if !defined(NDEBUG) && !defined(CRYPTOPP_IS_DLL)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) && !defined(CRYPTOPP_IS_DLL)
#include "pssr.h"
NAMESPACE_BEGIN(CryptoPP)
void RSA_TestInstantiations()
@@ -108,11 +108,13 @@ void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const Nam
int modulusSize = 2048;
alg.GetIntValue(Name::ModulusSize(), modulusSize) || alg.GetIntValue(Name::KeySize(), modulusSize);
+ assert(modulusSize >= 16);
if (modulusSize < 16)
throw InvalidArgument("InvertibleRSAFunction: specified modulus size is too small");
m_e = alg.GetValueWithDefault(Name::PublicExponent(), Integer(17));
+ assert(m_e >= 3); assert(!m_e.IsEven());
if (m_e < 3 || m_e.IsEven())
throw InvalidArgument("InvertibleRSAFunction: invalid public exponent");
diff --git a/rsa.h b/rsa.h
index 625a257f..f89e01ab 100644
--- a/rsa.h
+++ b/rsa.h
@@ -1,11 +1,13 @@
+// rsa.h - written and placed in the public domain by Wei Dai
+
+//! \file rsa.h
+//! \brief Classes for the RSA cryptosystem
+//! \details This file contains classes that implement the RSA
+//! ciphers and signature schemes as defined in PKCS #1 v2.0.
+
#ifndef CRYPTOPP_RSA_H
#define CRYPTOPP_RSA_H
-/** \file
- This file contains classes that implement the RSA
- ciphers and signature schemes as defined in PKCS #1 v2.0.
-*/
-
#include "cryptlib.h"
#include "pubkey.h"
#include "integer.h"
diff --git a/rw.cpp b/rw.cpp
index e9a56d63..6fb06c10 100644
--- a/rw.cpp
+++ b/rw.cpp
@@ -4,8 +4,9 @@
#include "rw.h"
#include "asn.h"
-#include "nbtheory.h"
#include "integer.h"
+#include "nbtheory.h"
+#include "modarith.h"
#ifndef CRYPTOPP_IMPORTS
diff --git a/rw.h b/rw.h
index 37875e31..aaaef6f9 100644
--- a/rw.h
+++ b/rw.h
@@ -1,10 +1,12 @@
+// rw.h - written and placed in the public domain by Wei Dai
+
+//! \file rw.h
+//! \brief Classes for Rabin-Williams signature schemes
+//! \details Rabin-Williams signature schemes as defined in IEEE P1363.
+
#ifndef CRYPTOPP_RW_H
#define CRYPTOPP_RW_H
-/** \file
- This file contains classes that implement the
- Rabin-Williams signature schemes as defined in IEEE P1363.
-*/
#include "cryptlib.h"
#include "pubkey.h"
diff --git a/salsa.cpp b/salsa.cpp
index ed9fdab5..d13e4e4d 100644
--- a/salsa.cpp
+++ b/salsa.cpp
@@ -16,19 +16,28 @@
# pragma warning(disable: 4702 4740)
#endif
-// TODO: work around GCC 4.9+ issue with SSE2 ASM until the exact details are known
+// TODO: work around GCC 4.8+ issue with SSE2 ASM until the exact details are known
// and fix is released. Duplicate with "valgrind ./cryptest.exe tv salsa"
-#if (CRYPTOPP_GCC_VERSION >= 40900)
+// Clang due to "Inline assembly operands don't work with .intel_syntax"
+// https://llvm.org/bugs/show_bug.cgi?id=24232
+#if defined(CRYPTOPP_DISABLE_SALSA_ASM)
+# undef CRYPTOPP_X86_ASM_AVAILABLE
+# undef CRYPTOPP_X32_ASM_AVAILABLE
+# undef CRYPTOPP_X64_ASM_AVAILABLE
# undef CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+# undef CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
# define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0
+# define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 0
#endif
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void Salsa20_TestInstantiations()
{
Salsa20::Encryption x;
}
+#endif
void Salsa20_Policy::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
{
@@ -66,7 +75,7 @@ void Salsa20_Policy::SeekToIteration(lword iterationCount)
m_state[5] = (word32)SafeRightShift<32>(iterationCount);
}
-#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64
+#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_SALSA_ASM)
unsigned int Salsa20_Policy::GetAlignment() const
{
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
@@ -164,7 +173,7 @@ void Salsa20_Policy::OperateKeystream(KeystreamOperation operation, byte *output
#ifdef __GNUC__
__asm__ __volatile__
(
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
AS_PUSH_IF86( bx)
#else
void *s = m_state.data();
@@ -472,7 +481,7 @@ void Salsa20_Policy::OperateKeystream(KeystreamOperation operation, byte *output
AS_POP_IF86( bp)
#ifdef __GNUC__
AS_POP_IF86( bx)
- ".att_syntax prefix;"
+ ATT_PREFIX
#if CRYPTOPP_BOOL_X64
: "+r" (input), "+r" (output), "+r" (iterationCount)
: "r" (m_rounds), "r" (m_state.m_ptr), "r" (workspace)
diff --git a/salsa.h b/salsa.h
index c2ab7059..df3ab32b 100644
--- a/salsa.h
+++ b/salsa.h
@@ -1,14 +1,26 @@
// salsa.h - written and placed in the public domain by Wei Dai
+//! \file
+//! \headerfile salsa.h
+//! \brief Classes for Salsa encryption scheme
+
#ifndef CRYPTOPP_SALSA_H
#define CRYPTOPP_SALSA_H
#include "strciphr.h"
#include "secblock.h"
+// TODO: work around GCC 4.8+ issue with SSE2 ASM until the exact details are known
+// and fix is released. Duplicate with "valgrind ./cryptest.exe tv salsa"
+// "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232
+#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_INTEL_ASM) || (CRYPTOPP_GCC_VERSION >= 40800)
+# define CRYPTOPP_DISABLE_SALSA_ASM
+#endif
+
NAMESPACE_BEGIN(CryptoPP)
-//! _
+//! \class Salsa20_Info
+//! \brief Salsa block cipher information
struct Salsa20_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8>
{
static const char *StaticAlgorithmName() {return "Salsa20";}
@@ -22,7 +34,7 @@ protected:
void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
bool CipherIsRandomAccess() const {return true;}
void SeekToIteration(lword iterationCount);
-#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64
+#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_SALSA_ASM)
unsigned int GetAlignment() const;
unsigned int GetOptimalBlockSize() const;
#endif
@@ -31,14 +43,18 @@ protected:
int m_rounds;
};
-/// <a href="http://www.cryptolounge.org/wiki/Salsa20">Salsa20</a>, variable rounds: 8, 12 or 20 (default 20)
+// <a href="http://www.cryptolounge.org/wiki/Salsa20">Salsa20</a>, variable rounds: 8, 12 or 20 (default 20)
+//! \class Salsa20
+//! \brief Salsa20 block cipher information
+//! \details Salsa20 provides a variable number of rounds: 8, 12 or 20. The default number of rounds is 20.
struct Salsa20 : public Salsa20_Info, public SymmetricCipherDocumentation
{
typedef SymmetricCipherFinal<ConcretePolicyHolder<Salsa20_Policy, AdditiveCipherTemplate<> >, Salsa20_Info> Encryption;
typedef Encryption Decryption;
};
-//! _
+//! \class XSalsa20_Info
+//! \brief XSalsa20 block cipher information
struct XSalsa20_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 24>
{
static const char *StaticAlgorithmName() {return "XSalsa20";}
@@ -54,7 +70,10 @@ protected:
FixedSizeSecBlock<word32, 8> m_key;
};
-/// <a href="http://www.cryptolounge.org/wiki/XSalsa20">XSalsa20</a>, variable rounds: 8, 12 or 20 (default 20)
+// <a href="http://www.cryptolounge.org/wiki/XSalsa20">XSalsa20</a>, variable rounds: 8, 12 or 20 (default 20)
+//! \class XSalsa20
+//! \brief XSalsa20 block cipher information
+//! \details XSalsa20 provides a variable number of rounds: 8, 12 or 20. The default number of rounds is 20.
struct XSalsa20 : public XSalsa20_Info, public SymmetricCipherDocumentation
{
typedef SymmetricCipherFinal<ConcretePolicyHolder<XSalsa20_Policy, AdditiveCipherTemplate<> >, XSalsa20_Info> Encryption;
diff --git a/seal.cpp b/seal.cpp
index b68ce629..da0d2e15 100644
--- a/seal.cpp
+++ b/seal.cpp
@@ -10,10 +10,12 @@
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void SEAL_TestInstantiations()
{
SEAL<>::Encryption x;
}
+#endif
struct SEAL_Gamma
{
diff --git a/seal.h b/seal.h
index bcc6a8c1..805d40fc 100644
--- a/seal.h
+++ b/seal.h
@@ -1,3 +1,9 @@
+// seal.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile seal.h
+//! \brief Classes for SEAL encryption scheme
+
#ifndef CRYPTOPP_SEAL_H
#define CRYPTOPP_SEAL_H
diff --git a/secblock.h b/secblock.h
index af052a5d..4a29c763 100644
--- a/secblock.h
+++ b/secblock.h
@@ -1,7 +1,7 @@
// secblock.h - written and placed in the public domain by Wei Dai
//! \file secblock.h
-//! \brief Helper classes and functions for secure memory allocations.
+//! \brief Classes and functions for secure memory allocations.
#ifndef CRYPTOPP_SECBLOCK_H
#define CRYPTOPP_SECBLOCK_H
@@ -20,8 +20,8 @@ NAMESPACE_BEGIN(CryptoPP)
// ************** secure memory allocation ***************
//! \class AllocatorBase
-//! \brief Base class for all secure memory allocation
-//! \tparam T the allocator's class or type
+//! \brief Base class for all allocators used by SecBlock
+//! \tparam T the class or type
template<class T>
class AllocatorBase
{
@@ -45,7 +45,7 @@ public:
//! \brief Returns the maximum number of elements the allocator can provide
//! \returns the maximum number of elements the allocator can provide
- //! \details Internally, preprocessor macros are used rather than \p std::numeric_limits
+ //! \details Internally, preprocessor macros are used rather than std::numeric_limits
//! because the latter is \a not a \a constexpr. Some compilers, like Clang, do not
//! optimize it well under all circumstances. Compilers like GCC, ICC and MSVC appear
//! to optimize it well in either form.
@@ -56,16 +56,16 @@ public:
//! \brief Constructs a new U using variadic arguments
//! \tparam U the type to be forwarded
//! \tparam Args the arguments to be forwarded
- //! \param ptr pointer to type \p U
+ //! \param ptr pointer to type U
//! \param args variadic arguments
- //! \details This is a C++11 feature. It is available when \p CRYPTOPP_CXX11_VARIADIC_TEMPLATES
+ //! \details This is a C++11 feature. It is available when CRYPTOPP_CXX11_VARIADIC_TEMPLATES
//! is defined. The define is controlled by compiler versions detected in config.h.
template<typename U, typename... Args>
void construct(U* ptr, Args&&... args) {::new ((void*)ptr) U(std::forward<Args>(args)...);}
//! \brief Destroys an U constructed with variadic arguments
//! \tparam U the type to be forwarded
- //! \details This is a C++11 feature. It is available when \p CRYPTOPP_CXX11_VARIADIC_TEMPLATES
+ //! \details This is a C++11 feature. It is available when CRYPTOPP_CXX11_VARIADIC_TEMPLATES
//! is defined. The define is controlled by compiler versions detected in config.h.
template<typename U>
void destroy(U* ptr) {if(ptr) ptr->~U();}
@@ -77,14 +77,14 @@ protected:
//! \brief Verifies the allocator can satisfy a request based on size
//! \param size the number of elements
//! \throws InvalidArgument
- //! \details \p CheckSize verifies the number of elements requested is valid.
- //! \details If \p size is greater than \p max_size(), then \p InvalidArgument is thrown.
- //! The library throws \p InvalidArgument if the size is too large to satisfy.
- //! \details Internally, preprocessor macros are used rather than \p std::numeric_limits
+ //! \details CheckSize verifies the number of elements requested is valid.
+ //! \details If size is greater than max_size(), then InvalidArgument is thrown.
+ //! The library throws InvalidArgument if the size is too large to satisfy.
+ //! \details Internally, preprocessor macros are used rather than std::numeric_limits
//! because the latter is \a not a \a constexpr. Some compilers, like Clang, do not
//! optimize it well under all circumstances. Compilers like GCC, ICC and MSVC appear
//! to optimize it well in either form.
- //! \note \p size is the count of elements, and not the number of bytes
+ //! \note size is the count of elements, and not the number of bytes
static void CheckSize(size_t size)
{
// C++ throws std::bad_alloc (C++03) or std::bad_array_new_length (C++11) here.
@@ -110,7 +110,7 @@ typedef typename AllocatorBase<T>::const_reference const_reference;
//! \param oldSize the size of the previous allocation
//! \param newSize the new, requested size
//! \param preserve flag that indicates if the old allocation should be preserved
-//! \note \p oldSize and \p newSize are the count of elements, and not the
+//! \note oldSize and newSize are the count of elements, and not the
//! number of bytes.
template <class T, class A>
typename A::pointer StandardReallocate(A& alloc, T *oldPtr, typename A::size_type oldSize, typename A::size_type newSize, bool preserve)
@@ -139,11 +139,11 @@ typename A::pointer StandardReallocate(A& alloc, T *oldPtr, typename A::size_typ
//! \brief Allocates a block of memory with cleanup
//! \tparam T class or type
//! \tparam T_Align16 boolean that determines whether allocations should be aligned on 16-byte boundaries
-//! \details If \p T_Align16 is \p true, then \p AllocatorWithCleanup calls \p AlignedAllocate()
-//! for memory allocations. If \p T_Align16 is \p false, then \p AllocatorWithCleanup() calls
-//! \p UnalignedAllocate() for memory allocations.
-//! \details Template parameter \p T_Align16 is effectively controlled by cryptlib.h and mirrors
-//! \p CRYPTOPP_BOOL_ALIGN16. \p CRYPTOPP_BOOL_ALIGN16 is often used as the template parameter.
+//! \details If T_Align16 is true, then AllocatorWithCleanup calls AlignedAllocate()
+//! for memory allocations. If T_Align16 is false, then AllocatorWithCleanup() calls
+//! UnalignedAllocate() for memory allocations.
+//! \details Template parameter T_Align16 is effectively controlled by cryptlib.h and mirrors
+//! CRYPTOPP_BOOL_ALIGN16. CRYPTOPP_BOOL_ALIGN16 is often used as the template parameter.
template <class T, bool T_Align16 = false>
class AllocatorWithCleanup : public AllocatorBase<T>
{
@@ -155,16 +155,16 @@ public:
//! \param size the size of the allocation
//! \returns a memory block
//! \throws InvalidArgument
- //! \details \p allocate() first checks the size of the request. If it is non-0
+ //! \details allocate() first checks the size of the request. If it is non-0
//! and less than max_size(), then an attempt is made to fulfill the request using either
//! AlignedAllocate() or UnalignedAllocate().
- //! \details \p AlignedAllocate() is used if \p T_Align16 is \p true.
- //! \p UnalignedAllocate() used if \p T_Align16 is \p false.
- //! \details This is the C++ *Placement New* operator. \p ptr is not used, and the function
- //! asserts in Debug builds if \p ptr is \p non-NULL.
- //! \sa \p CallNewHandler() for the methods used to recover from a failed
+ //! \details AlignedAllocate() is used if T_Align16 is true.
+ //! UnalignedAllocate() used if T_Align16 is false.
+ //! \details This is the C++ *Placement New* operator. ptr is not used, and the function
+ //! asserts in Debug builds if ptr is non-NULL.
+ //! \sa CallNewHandler() for the methods used to recover from a failed
//! allocation attempt.
- //! \note \p size is the count of elements, and not the number of bytes
+ //! \note size is the count of elements, and not the number of bytes
pointer allocate(size_type size, const void *ptr = NULL)
{
CRYPTOPP_UNUSED(ptr); assert(ptr == NULL);
@@ -173,6 +173,7 @@ public:
return NULL;
#if CRYPTOPP_BOOL_ALIGN16
+ // TODO: should this need the test 'size*sizeof(T) >= 16'?
if (T_Align16 && size*sizeof(T) >= 16)
return (pointer)AlignedAllocate(size*sizeof(T));
#endif
@@ -183,11 +184,11 @@ public:
//! \brief Deallocates a block of memory
//! \param ptr the size of the allocation
//! \param size the size of the allocation
- //! \details Internally, \p SecureWipeArray() is called before deallocating the memory.
- //! Once the memory block is wiped or zeroized, \p AlignedDeallocate() or
- //! \p UnalignedDeallocate() is called.
- //! \details \p AlignedDeallocate() is used if \p T_Align16 is \p true.
- //! \p UnalignedDeallocate() used if \p T_Align16 is \p false.
+ //! \details Internally, SecureWipeArray() is called before deallocating the memory.
+ //! Once the memory block is wiped or zeroized, AlignedDeallocate() or
+ //! UnalignedDeallocate() is called.
+ //! \details AlignedDeallocate() is used if T_Align16 is true.
+ //! UnalignedDeallocate() used if T_Align16 is false.
void deallocate(void *ptr, size_type size)
{
assert((ptr && size) || !(ptr || size));
@@ -207,12 +208,12 @@ public:
//! \param newSize the new, requested size
//! \param preserve flag that indicates if the old allocation should be preserved
//! \returns pointer to the new memory block
- //! \details Internally, \p reallocate() calls \p StandardReallocate().
- //! \details If \p preserve is \p true, then index 0 is used to begin copying the
+ //! \details Internally, reallocate() calls StandardReallocate().
+ //! \details If preserve is true, then index 0 is used to begin copying the
//! old memory block to the new one. If the block grows, then the old array
- //! is copied in its entirety. If the block shrinks, then only \p newSize
+ //! is copied in its entirety. If the block shrinks, then only newSize
//! elements are copied from the old block to the new one.
- //! \note \p oldSize and \p newSize are the count of elements, and not the
+ //! \note oldSize and newSize are the count of elements, and not the
//! number of bytes.
pointer reallocate(T *oldPtr, size_type oldSize, size_type newSize, bool preserve)
{
@@ -240,11 +241,11 @@ CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word, true>; // for Integer
//! \class NullAllocator
//! \brief NULL allocator
//! \tparam T class or type
-//! \details A \p NullAllocator is useful for fixed-size, stack based allocations
-//! (i.e., static arrays used by \p FixedSizeAllocatorWithCleanup).
-//! \details A \p NullAllocator always returns 0 for max_size(), and always returns
-//! \p NULL for allocation requests. Though the allocator does not allocate, it
-//! does perform a secure wipe or zeroization during cleanup.
+//! \details A NullAllocator is useful for fixed-size, stack based allocations
+//! (i.e., static arrays used by FixedSizeAllocatorWithCleanup).
+//! \details A NullAllocator always returns 0 for max_size(), and always returns
+//! NULL for allocation requests. Though the allocator does not allocate at
+//! runtime, it does perform a secure wipe or zeroization during cleanup.
template <class T>
class NullAllocator : public AllocatorBase<T>
{
@@ -273,11 +274,11 @@ public:
//! \brief Static secure memory block with cleanup
//! \tparam T class or type
//! \tparam S fixed-size of the stack-based memory block
-//! \tparam A \p AllocatorBase derived class for allocation and cleanup
-//! \details \p FixedSizeAllocatorWithCleanup provides a fixed-size, stack-
+//! \tparam A AllocatorBase derived class for allocation and cleanup
+//! \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack-
//! based allocation at compile time. The class can grow its memory
-//! block at runtime if a suitable allocator is available. If \p size
-//! grows beyond \p S and a suitable allocator is available, then the
+//! block at runtime if a suitable allocator is available. If size
+//! grows beyond S and a suitable allocator is available, then the
//! statically allocated array is obsoleted.
//! \note This allocator can't be used with standard collections because
//! they require that all objects of the same allocator type are equivalent.
@@ -287,22 +288,22 @@ class FixedSizeAllocatorWithCleanup : public AllocatorBase<T>
public:
CRYPTOPP_INHERIT_ALLOCATOR_TYPES
- //! \brief Constructs a \p FixedSizeAllocatorWithCleanup
+ //! \brief Constructs a FixedSizeAllocatorWithCleanup
FixedSizeAllocatorWithCleanup() : m_allocated(false) {}
//! \brief Allocates a block of memory
//! \param size size of the memory block
- //! \details \p FixedSizeAllocatorWithCleanup provides a fixed-size, stack-
- //! based allocation at compile time. If \p size is less than or equal to
- //! \p S, then a pointer to the static array is returned.
+ //! \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack-
+ //! based allocation at compile time. If size is less than or equal to
+ //! S, then a pointer to the static array is returned.
//! \details The class can grow its memory block at runtime if a suitable
- //! allocator is available. If \p size grows beyond \p S and a suitable
+ //! allocator is available. If size grows beyond S and a suitable
//! allocator is available, then the statically allocated array is
//! obsoleted. If a suitable allocator is \a not available, as with a
- //! \p NullAllocator, then the function returns \p NULL and a runtime error
+ //! NullAllocator, then the function returns NULL and a runtime error
//! eventually occurs.
- //! \note \p size is the count of elements, and not the number of bytes.
- //! \sa \p reallocate(), \p SecBlockWithHint
+ //! \note size is the count of elements, and not the number of bytes.
+ //! \sa reallocate(), SecBlockWithHint
pointer allocate(size_type size)
{
assert(IsAlignedOn(m_array, 8));
@@ -319,17 +320,17 @@ public:
//! \brief Allocates a block of memory
//! \param size size of the memory block
//! \param hint an unused hint
- //! \details \p FixedSizeAllocatorWithCleanup provides a fixed-size, stack-
- //! based allocation at compile time. If \p size is less than or equal to
- //! \p S, then a pointer to the static array is returned.
+ //! \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack-
+ //! based allocation at compile time. If size is less than or equal to
+ //! S, then a pointer to the static array is returned.
//! \details The class can grow its memory block at runtime if a suitable
- //! allocator is available. If \p size grows beyond \p S and a suitable
+ //! allocator is available. If size grows beyond S and a suitable
//! allocator is available, then the statically allocated array is
//! obsoleted. If a suitable allocator is \a not available, as with a
- //! \p NullAllocator, then the function returns \p NULL and a runtime error
+ //! NullAllocator, then the function returns NULL and a runtime error
//! eventually occurs.
- //! \note \p size is the count of elements, and not the number of bytes.
- //! \sa \p reallocate(), \p SecBlockWithHint
+ //! \note size is the count of elements, and not the number of bytes.
+ //! \sa reallocate(), SecBlockWithHint
pointer allocate(size_type size, const void *hint)
{
if (size <= S && !m_allocated)
@@ -368,17 +369,17 @@ public:
//! \param newSize the new, requested size
//! \param preserve flag that indicates if the old allocation should be preserved
//! \returns pointer to the new memory block
- //! \details \p FixedSizeAllocatorWithCleanup provides a fixed-size, stack-
- //! based allocation at compile time. If \p size is less than or equal to
- //! \p S, then a pointer to the static array is returned.
+ //! \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack-
+ //! based allocation at compile time. If size is less than or equal to
+ //! S, then a pointer to the static array is returned.
//! \details The class can grow its memory block at runtime if a suitable
- //! allocator is available. If \p size grows beyond \p S and a suitable
+ //! allocator is available. If size grows beyond S and a suitable
//! allocator is available, then the statically allocated array is
//! obsoleted. If a suitable allocator is \a not available, as with a
- //! \p NullAllocator, then the function returns \p NULL and a runtime error
+ //! NullAllocator, then the function returns NULL and a runtime error
//! eventually occurs.
- //! \note \p size is the count of elements, and not the number of bytes.
- //! \sa \p reallocate(), \p SecBlockWithHint
+ //! \note size is the count of elements, and not the number of bytes.
+ //! \sa reallocate(), SecBlockWithHint
pointer reallocate(pointer oldPtr, size_type oldSize, size_type newSize, bool preserve)
{
if (oldPtr == GetAlignedArray() && newSize <= S)
@@ -416,7 +417,7 @@ private:
//! \class SecBlock
//! \brief Secure memory block with allocator and cleanup
//! \tparam T a class or type
-//! \tparam A \p AllocatorWithCleanup derived class for allocation and cleanup
+//! \tparam A AllocatorWithCleanup derived class for allocation and cleanup
template <class T, class A = AllocatorWithCleanup<T> >
class SecBlock
{
@@ -426,11 +427,11 @@ public:
typedef typename A::const_pointer const_iterator;
typedef typename A::size_type size_type;
- //! \brief Construct a SecBlock with space for \p size elements.
+ //! \brief Construct a SecBlock with space for size elements.
//! \param size the number of elements in the allocation
//! \throws std::bad_alloc
//! \details The elements are not initialized.
- //! \note \p size is the count of elements, and not the number of bytes
+ //! \note size is the count of elements, and not the number of bytes
explicit SecBlock(size_type size=0)
: m_size(size), m_ptr(m_alloc.allocate(size, NULL)) { }
@@ -447,10 +448,10 @@ public:
//! \param ptr a pointer to an array of T
//! \param len the number of elements in the memory block
//! \throws std::bad_alloc
- //! \details If <tt>ptr!=NULL</tt> and <tt>len!=0</tt>, then the block is initialized from the pointer \p ptr.
+ //! \details If <tt>ptr!=NULL</tt> and <tt>len!=0</tt>, then the block is initialized from the pointer ptr.
//! If <tt>ptr==NULL</tt> and <tt>len!=0</tt>, then the block is initialized to 0.
//! Otherwise, the block is empty and uninitialized.
- //! \note \p size is the count of elements, and not the number of bytes
+ //! \note size is the count of elements, and not the number of bytes
SecBlock(const T *ptr, size_type len)
: m_size(len), m_ptr(m_alloc.allocate(len, NULL)) {
assert((!m_ptr && !m_size) || (m_ptr && m_size));
@@ -502,12 +503,12 @@ public:
//! \returns constant pointer to the first element in the memory block
typename A::const_pointer data() const {return m_ptr;}
- //! \brief Provides the count of elements in the \p SecBlock
+ //! \brief Provides the count of elements in the SecBlock
//! \returns number of elements in the memory block
//! \note the return value is the count of elements, and not the number of bytes
size_type size() const {return m_size;}
- //! \brief Determines if the \p SecBlock is empty
- //! \returns \p true if number of elements in the memory block is 0, \p false otherwise
+ //! \brief Determines if the SecBlock is empty
+ //! \returns true if number of elements in the memory block is 0, false otherwise
bool empty() const {return m_size == 0;}
//! \brief Provides a byte pointer to the first element in the memory block
@@ -516,7 +517,7 @@ public:
//! \brief Return a byte pointer to the first element in the memory block
//! \returns constant byte pointer to the first element in the memory block
const byte * BytePtr() const {return (const byte *)m_ptr;}
- //! \brief Provides the number of bytes in the \p SecBlock
+ //! \brief Provides the number of bytes in the SecBlock
//! \return the number of bytes in the memory block
//! \note the return value is the number of bytes, and not count of elements.
size_type SizeInBytes() const {return m_size*sizeof(T);}
@@ -533,8 +534,8 @@ public:
}
//! \brief Copy contents from another SecBlock
- //! \param t the other \p SecBlock
- //! \details \p Assign checks for self assignment.
+ //! \param t the other SecBlock
+ //! \details Assign checks for self assignment.
//! \details If the memory block is reduced in size, then the unused area is set to 0.
void Assign(const SecBlock<T, A> &t)
{
@@ -547,8 +548,8 @@ public:
}
//! \brief Assign contents from another SecBlock
- //! \param t the other \p SecBlock
- //! \details Internally, \p operator=() calls \p Assign().
+ //! \param t the other SecBlock
+ //! \details Internally, operator=() calls Assign().
//! \details If the memory block is reduced in size, then the unused area is set to 0.
SecBlock<T, A>& operator=(const SecBlock<T, A> &t)
{
@@ -558,8 +559,8 @@ public:
}
//! \brief Append contents from another SecBlock
- //! \param t the other \p SecBlock
- //! \details Internally, \p this \p SecBlock calls \p Grow and then copies the new content.
+ //! \param t the other SecBlock
+ //! \details Internally, this SecBlock calls Grow and then copies the new content.
//! \details If the memory block is reduced in size, then the unused area is set to 0.
SecBlock<T, A>& operator+=(const SecBlock<T, A> &t)
{
@@ -577,11 +578,11 @@ public:
}
//! \brief Concatenate contents from another SecBlock
- //! \param t the other \p SecBlock
- //! \returns a newly constructed \p SecBlock that is a conacentation of \p this and \p t
- //! \details Internally, a temporary \p SecBlock is created and the content from \p this
- //! \p SecBlock and the other \p SecBlock are concatenated. The temporary
- //! \p SecBlock is returned to the caller.
+ //! \param t the other SecBlock
+ //! \returns a newly constructed SecBlock that is a conacentation of this and t
+ //! \details Internally, a temporary SecBlock is created and the content from this
+ //! SecBlock and the other SecBlock are concatenated. The temporary
+ //! SecBlock is returned to the caller.
SecBlock<T, A> operator+(const SecBlock<T, A> &t)
{
assert((!m_ptr && !m_size) || (m_ptr && m_size));
@@ -595,10 +596,10 @@ public:
}
//! \brief Bitwise compare two SecBlocks
- //! \param t the other \p SecBlock
- //! \returns \p true if the size and bits are equal, \p false otherwise
+ //! \param t the other SecBlock
+ //! \returns true if the size and bits are equal, false otherwise
//! \details Uses a constant time compare if the arrays are equal size. The constant time
- //! compare is \p VerifyBufsEqual() found in misc.h.
+ //! compare is VerifyBufsEqual() found in misc.h.
//! \sa operator!=()
bool operator==(const SecBlock<T, A> &t) const
{
@@ -606,11 +607,11 @@ public:
}
//! \brief Bitwise compare two SecBlocks
- //! \param t the other \p SecBlock
- //! \returns \p true if the size and bits are equal, \p false otherwise
+ //! \param t the other SecBlock
+ //! \returns true if the size and bits are equal, false otherwise
//! \details Uses a constant time compare if the arrays are equal size. The constant time
- //! compare is \p VerifyBufsEqual() found in misc.h.
- //! \details Internally, \p operator!=() returns the inverse of operator==().
+ //! compare is VerifyBufsEqual() found in misc.h.
+ //! \details Internally, operator!=() returns the inverse of operator==().
//! \sa operator==()
bool operator!=(const SecBlock<T, A> &t) const
{
@@ -622,7 +623,7 @@ public:
//! \details Old content is \a not preserved. If the memory block is reduced in size,
//! then the unused content is set to 0. If the memory block grows in size, then
//! all content is uninitialized.
- //! \details Internally, \p this \p SecBlock calls \p reallocate().
+ //! \details Internally, this SecBlock calls reallocate().
//! \sa New(), CleanNew(), Grow(), CleanGrow(), resize()
void New(size_type newSize)
{
@@ -634,7 +635,7 @@ public:
//! \param newSize the new size of the memory block
//! \details Old content is not preserved. If the memory block is reduced in size,
//! then the unused content is set to 0. Existing and new content is set to 0.
- //! \details Internally, \p this \p SecBlock calls \p reallocate().
+ //! \details Internally, this SecBlock calls reallocate().
//! \sa New(), CleanNew(), Grow(), CleanGrow(), resize()
void CleanNew(size_type newSize)
{
@@ -644,13 +645,12 @@ public:
//! \brief Change size and preserve contents
//! \param newSize the new size of the memory block
- //! \details Internally, \p this \p SecBlock calls \p reallocate().
//! \details Old content is preserved. If the memory block grows in size, then
//! all content is uninitialized.
- //! \details Internally, \p this \p SecBlock calls \p reallocate().
- //! \note \p reallocate() is called if the size increases. If the size does not
- //! increase, then \p Grow does not take action. If the size must change,
- //! then use \p resize().
+ //! \details Internally, this SecBlock calls reallocate().
+ //! \note reallocate() is called if the size increases. If the size does not
+ //! increase, then Grow does not take action. If the size must change,
+ //! then use resize().
//! \sa New(), CleanNew(), Grow(), CleanGrow(), resize()
void Grow(size_type newSize)
{
@@ -663,14 +663,13 @@ public:
//! \brief Change size and preserve contents
//! \param newSize the new size of the memory block
- //! \details Internally, \p this \p SecBlock calls \p reallocate().
//! \details Old content is preserved. If the memory block is reduced in size,
//! then the unused content is set to 0. If the memory block grows in size,
//! then the new content is uninitialized.
- //! \details Internally, \p this \p SecBlock calls \p reallocate().
- //! \note \p reallocate() is called if the size increases. If the size does not
- //! increase, then \p Grow does not take action. If the size must change,
- //! then use \p resize().
+ //! \details Internally, this SecBlock calls reallocate().
+ //! \note reallocate() is called if the size increases. If the size does not
+ //! increase, then Grow does not take action. If the size must change,
+ //! then use resize().
//! \sa New(), CleanNew(), Grow(), CleanGrow(), resize()
void CleanGrow(size_type newSize)
{
@@ -684,13 +683,12 @@ public:
//! \brief Change size and preserve contents
//! \param newSize the new size of the memory block
- //! \details Internally, \p this \p SecBlock calls \p reallocate().
//! \details Old content is preserved. If the memory block grows in size, then
//! all content is uninitialized.
- //! \details Internally, \p this \p SecBlock calls \p reallocate().
- //! \note \p reallocate() is called if the size increases. If the size does not
- //! increase, then \p Grow does not take action. If the size must change,
- //! then use \p resize().
+ //! \details Internally, this SecBlock calls reallocate().
+ //! \note reallocate() is called if the size increases. If the size does not
+ //! increase, then Grow does not take action. If the size must change,
+ //! then use resize().
//! \sa New(), CleanNew(), Grow(), CleanGrow(), resize()
void resize(size_type newSize)
{
@@ -700,10 +698,10 @@ public:
//! \brief Swap contents with another SecBlock
//! \param b the other SecBlock
- //! \details Internally, \p std::swap() is called on \p m_alloc, \p m_size and \p m_ptr.
+ //! \details Internally, std::swap() is called on m_alloc, m_size and m_ptr.
void swap(SecBlock<T, A> &b)
{
- // TODO: research the swap on the Allocator, and remove it if not needed.
+ // Swap must occur on the allocator in case its FixedSize that spilled into the heap.
std::swap(m_alloc, b.m_alloc);
std::swap(m_size, b.m_size);
std::swap(m_ptr, b.m_ptr);
@@ -738,7 +736,7 @@ typedef SecBlock<byte, AllocatorWithCleanup<byte, true> > AlignedSecByteBlock;
//! \brief Fixed size stack-based SecBlock
//! \tparam T class or type
//! \tparam S fixed-size of the stack-based memory block
-//! \tparam A \p AllocatorBase derived class for allocation and cleanup
+//! \tparam A AllocatorBase derived class for allocation and cleanup
template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S> >
class FixedSizeSecBlock : public SecBlock<T, A>
{
@@ -751,7 +749,7 @@ public:
//! \brief Fixed size stack-based SecBlock with 16-byte alignment
//! \tparam T class or type
//! \tparam S fixed-size of the stack-based memory block
-//! \tparam A \p AllocatorBase derived class for allocation and cleanup
+//! \tparam A AllocatorBase derived class for allocation and cleanup
template <class T, unsigned int S, bool T_Align16 = true>
class FixedSizeAlignedSecBlock : public FixedSizeSecBlock<T, S, FixedSizeAllocatorWithCleanup<T, S, NullAllocator<T>, T_Align16> >
{
@@ -761,7 +759,7 @@ class FixedSizeAlignedSecBlock : public FixedSizeSecBlock<T, S, FixedSizeAllocat
//! \brief Stack-based SecBlock that grows into the heap
//! \tparam T class or type
//! \tparam S fixed-size of the stack-based memory block
-//! \tparam A \p AllocatorBase derived class for allocation and cleanup
+//! \tparam A AllocatorBase derived class for allocation and cleanup
template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S, AllocatorWithCleanup<T> > >
class SecBlockWithHint : public SecBlock<T, A>
{
diff --git a/seckey.h b/seckey.h
index 7457bc42..64ef0c63 100644
--- a/seckey.h
+++ b/seckey.h
@@ -1,7 +1,7 @@
// seckey.h - written and placed in the public domain by Wei Dai
//! \file
-//! \brief Contains helper classes and functions for implementing secret key algorithms.
+//! \brief Classes and functions for implementing secret key algorithms.
#ifndef CRYPTOPP_SECKEY_H
#define CRYPTOPP_SECKEY_H
@@ -20,7 +20,7 @@ NAMESPACE_BEGIN(CryptoPP)
//! \brief Inverts the cipher's direction
//! \param dir the cipher's direction
-//! \returns \p DECRYPTION if \p dir is ENCRYPTION, \p DECRYPTION otherwise
+//! \returns DECRYPTION if dir is ENCRYPTION, DECRYPTION otherwise
inline CipherDir ReverseCipherDir(CipherDir dir)
{
return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION;
@@ -68,26 +68,31 @@ public:
//! \brief The default number of rounds for the cipher based on key length
//! provided by a static function.
//! \param keylength the size of the key, in bytes
- //! \details \p keylength is unused in the default implementation.
+ //! \details keylength is unused in the default implementation.
static unsigned int StaticGetDefaultRounds(size_t keylength)
{CRYPTOPP_UNUSED(keylength); return DEFAULT_ROUNDS;}
protected:
- //! \brief Validates the number of \p rounds for a cipher.
- //! \param rounds the canddiate number of \p rounds
- //! \param alg an \p Algorithm object used if the number of \p rounds are invalid
- //! \throws InvalidRounds if the number of \p rounds are invalid
+ //! \brief Validates the number of rounds for a cipher.
+ //! \param rounds the canddiate number of rounds
+ //! \param alg an Algorithm object used if the number of rounds are invalid
+ //! \throws InvalidRounds if the number of rounds are 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() : "VariableRounds", rounds);
+#else
if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS)
throw InvalidRounds(alg ? alg->AlgorithmName() : "VariableRounds", rounds);
+#endif
}
- //! \brief Validates the number of \p rounds for a cipher
- //! \param param the canddiate number of \p rounds
- //! \param alg an \p Algorithm object used if the number of \p rounds are invalid
+ //! \brief Validates the number of rounds for a cipher
+ //! \param param the canddiate number of rounds
+ //! \param alg an Algorithm object used if the number of rounds are invalid
//! \returns the number of rounds for the cipher
- //! \throws InvalidRounds if the number of \p rounds are invalid
+ //! \throws InvalidRounds if the number of rounds are invalid
inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs &param, const Algorithm *alg)
{
int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS);
@@ -101,34 +106,34 @@ protected:
//! \class FixedKeyLength
//! \brief Inherited by keyed algorithms with fixed key length
//! \tparam N Default key length, in bytes
-//! \tparam IV_REQ The IV requirements. See \p IV_Requirement in cryptlib.h for allowed values
+//! \tparam IV_REQ The IV requirements. See IV_Requirement in cryptlib.h for allowed values
//! \tparam IV_L Default IV length, in bytes
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 cipher provided as a constant
- //! \details \p KEYLENGTH is provided in bytes, not bits
+ //! \details KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(KEYLENGTH=N)
//! \brief The minimum key length used by the cipher provided as a constant
- //! \details \p MIN_KEYLENGTH is provided in bytes, not bits
+ //! \details MIN_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N)
//! \brief The maximum key length used by the cipher provided as a constant
- //! \details \p MAX_KEYLENGTH is provided in bytes, not bits
+ //! \details MAX_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(MAX_KEYLENGTH=N)
//! \brief The default key length used by the cipher provided as a constant
- //! \details \p DEFAULT_KEYLENGTH is provided in bytes, not bits
+ //! \details DEFAULT_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=N)
//! \brief The default IV requirements for the cipher provided as a constant
- //! \details The default value is \p NOT_RESYNCHRONIZABLE. See \p IV_Requirement
+ //! \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 cipher provided as a constant
- //! \details \p IV_LENGTH is provided in bytes, not bits. The default implementation uses \p 0.
+ //! \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 cipher provided by a static function.
//! \param keylength the size of the key, in bytes
- //! \details The default implementation returns \p KEYLENGTH. \p keylength is unused
+ //! \details The default implementation returns KEYLENGTH. keylength is unused
//! in the default implementation.
static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
{CRYPTOPP_UNUSED(keylength); return KEYLENGTH;}
@@ -140,7 +145,7 @@ public:
//! \tparam N Minimum key length, in bytes
//! \tparam M Maximum key length, in bytes
//! \tparam M Default key length multiple, in bytes. The default multiple is 1.
-//! \tparam IV_REQ The IV requirements. See \p IV_Requirement in cryptlib.h for allowed values
+//! \tparam IV_REQ The IV requirements. See IV_Requirement in cryptlib.h for allowed values
//! \tparam IV_L Default IV length, in bytes. The default length is 0.
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
@@ -155,37 +160,40 @@ class VariableKeyLength
public:
//! \brief The minimum key length used by the cipher provided as a constant
- //! \details \p MIN_KEYLENGTH is provided in bytes, not bits
+ //! \details MIN_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N)
//! \brief The maximum key length used by the cipher provided as a constant
- //! \details \p MAX_KEYLENGTH is provided in bytes, not bits
+ //! \details MAX_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(MAX_KEYLENGTH=M)
//! \brief The default key length used by the cipher provided as a constant
- //! \details \p DEFAULT_KEYLENGTH is provided in bytes, not bits
+ //! \details DEFAULT_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=D)
//! \brief The key length multiple used by the cipher provided as a constant
- //! \details \p MAX_KEYLENGTH is provided in bytes, not bits
+ //! \details MAX_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(KEYLENGTH_MULTIPLE=Q)
//! \brief The default IV requirements for the cipher provided as a constant
- //! \details The default value is \p NOT_RESYNCHRONIZABLE. See \p IV_Requirement
+ //! \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 cipher provided as a constant
- //! \details \p IV_LENGTH is provided in bytes, not bits. The default implementation uses \p 0.
+ //! \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 cipher provided by a static function.
//! \param keylength the size of the key, in bytes
- //! \details If \p keylength is less than \p MIN_KEYLENGTH, then the function returns
- //! \p MIN_KEYLENGTH. If \p keylength is greater than \p MAX_KEYLENGTH, then the function
- //! returns \p MAX_KEYLENGTH. If \p keylength is a multiple of \p KEYLENGTH_MULTIPLE,
- //! then \p keylength is returned. Otherwise, the function returns \p keylength rounded
- //! \a down to the next smaller multiple of \p KEYLENGTH_MULTIPLE.
- //! \details \p keylength is provided in bytes, not bits.
+ //! \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.
static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
{
+#if MIN_KEYLENGTH > 0
if (keylength < (size_t)MIN_KEYLENGTH)
return MIN_KEYLENGTH;
- else if (keylength > (size_t)MAX_KEYLENGTH)
+ else
+#endif
+ if (keylength > (size_t)MAX_KEYLENGTH)
return (size_t)MAX_KEYLENGTH;
else
{
@@ -197,37 +205,37 @@ public:
//! \class SameKeyLengthAs
//! \brief Provides key lengths based on another class's key length
-//! \tparam T another \p FixedKeyLength or \p VariableKeyLength class
-//! \tparam IV_REQ The IV requirements. See \p IV_Requirement in cryptlib.h for allowed values
+//! \tparam T another FixedKeyLength or VariableKeyLength class
+//! \tparam IV_REQ The IV requirements. See IV_Requirement in cryptlib.h for allowed values
//! \tparam IV_L Default IV length, in bytes
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 cipher provided as a constant
- //! \details \p MIN_KEYLENGTH is provided in bytes, not bits
+ //! \details MIN_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(MIN_KEYLENGTH=T::MIN_KEYLENGTH)
//! \brief The maximum key length used by the cipher provided as a constant
- //! \details \p MIN_KEYLENGTH is provided in bytes, not bits
+ //! \details MIN_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(MAX_KEYLENGTH=T::MAX_KEYLENGTH)
//! \brief The default key length used by the cipher provided as a constant
- //! \details \p MIN_KEYLENGTH is provided in bytes, not bits
+ //! \details MIN_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH)
//! \brief The default IV requirements for the cipher provided as a constant
- //! \details The default value is \p NOT_RESYNCHRONIZABLE. See \p IV_Requirement
+ //! \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 cipher provided as a constant
- //! \details \p IV_LENGTH is provided in bytes, not bits. The default implementation uses \p 0.
+ //! \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 cipher provided by a static function.
//! \param keylength the size of the key, in bytes
- //! \details If \p keylength is less than \p MIN_KEYLENGTH, then the function returns
- //! \p MIN_KEYLENGTH. If \p keylength is greater than \p MAX_KEYLENGTH, then the function
- //! returns \p MAX_KEYLENGTH. If \p keylength is a multiple of \p KEYLENGTH_MULTIPLE,
- //! then \p keylength is returned. Otherwise, the function returns \p keylength rounded
- //! \a down to the next smaller multiple of \p KEYLENGTH_MULTIPLE.
- //! \details \p keylength is provided in bytes, not bits.
+ //! \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.
static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
{return T::StaticGetValidKeyLength(keylength);}
};
@@ -256,21 +264,21 @@ public:
//! \brief Provides a valid key length for the cipher
//! \param keylength the size of the key, in bytes
- //! \details \p keylength is provided in bytes, not bits. If \p keylength is less than \p MIN_KEYLENGTH,
- //! then the function returns \p MIN_KEYLENGTH. If \p keylength is greater than \p MAX_KEYLENGTH,
- //! then the function returns \p MAX_KEYLENGTH. if If \p keylength is a multiple of \p KEYLENGTH_MULTIPLE,
- //! then \p keylength is returned. Otherwise, the function returns a \a lower multiple of
- //! \p KEYLENGTH_MULTIPLE.
+ //! \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 cipher
- //! \details The default value is \p NOT_RESYNCHRONIZABLE. See \p IV_Requirement
+ //! \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
//! in cryptlib.h for allowed values.
SimpleKeyingInterface::IV_Requirement IVRequirement() const
{return (SimpleKeyingInterface::IV_Requirement)INFO::IV_REQUIREMENT;}
//! \brief The default initialization vector length for the cipher
- //! \details \p IVSize is provided in bytes, not bits. The default implementation uses \p IV_LENGTH, which is 0.
+ //! \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;}
};
@@ -283,7 +291,8 @@ template <class INFO, class BASE = BlockCipher>
class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > >
{
public:
- //! \brief The block size of the cipher
+ //! Provides the block size of the cipher
+ //! \returns the block size of the cipher, in bytes
unsigned int BlockSize() const {return this->BLOCKSIZE;}
};
@@ -298,30 +307,34 @@ 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 \p key must be at least \p DEFAULT_KEYLENGTH in length. Internally, the function calls
- //! \p SimpleKeyingInterface::SetKey.
+ //! \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 \p key must be at least \p DEFAULT_KEYLENGTH in length. Internally, the function calls
- //! \p SimpleKeyingInterface::SetKey.
+ //! \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 \p key must be at least \p DEFAULT_KEYLENGTH in length. Internally, the function calls
- //! \p SimpleKeyingInterface::SetKeyWithRounds.
+ //! \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
- //! \returns \p true if \p DIR is \p ENCRYPTION, \p false otherwise
+ //! \returns true if DIR is ENCRYPTION, false otherwise
+ //! \sa IsForwardTransformation(), IsPermutation(), GetCipherDirection()
bool IsForwardTransformation() const {return DIR == ENCRYPTION;}
};
@@ -347,15 +360,15 @@ public:
MessageAuthenticationCodeFinal() {}
//! \brief Construct a BlockCipherFinal
//! \param key a byte array used to key the cipher
- //! \details \p key must be at least \p DEFAULT_KEYLENGTH in length. Internally, the function calls
- //! \p SimpleKeyingInterface::SetKey.
+ //! \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 cipher
//! \param length the length of the byte array
- //! \details \p key must be at least \p DEFAULT_KEYLENGTH in length. Internally, the function calls
- //! \p SimpleKeyingInterface::SetKey.
+ //! \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);}
};
@@ -363,7 +376,7 @@ public:
// ************** documentation ***************
//! \class BlockCipherDocumentation
-//! \brief Provides \p Encryption and \p Decryption typedefs used by derived classes to
+//! \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,
@@ -377,7 +390,7 @@ struct BlockCipherDocumentation
};
//! \class SymmetricCipherDocumentation
-//! \brief Provides \p Encryption and \p Decryption typedefs used by derived classes to
+//! \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
@@ -393,7 +406,7 @@ struct SymmetricCipherDocumentation
};
//! \class AuthenticatedSymmetricCipherDocumentation
-//! \brief Provides \p Encryption and \p Decryption typedefs used by derived classes to
+//! \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.
diff --git a/seed.h b/seed.h
index 0267d8b3..eb658f9e 100644
--- a/seed.h
+++ b/seed.h
@@ -1,9 +1,12 @@
+// seed.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile seed.h
+//! \brief Classes for SEED encryption scheme
+
#ifndef CRYPTOPP_SEED_H
#define CRYPTOPP_SEED_H
-/** \file
-*/
-
#include "seckey.h"
#include "secblock.h"
diff --git a/sha.cpp b/sha.cpp
index bbd3572c..8ac6368a 100644
--- a/sha.cpp
+++ b/sha.cpp
@@ -257,7 +257,7 @@ static void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32
#if CRYPTOPP_BOOL_X64
"lea %4, %%r8;"
#endif
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
#elif defined(CRYPTOPP_GENERATE_X64_MASM)
ALIGN 8
X86_SHA256_HashBlocks PROC FRAME
@@ -437,7 +437,7 @@ static void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32
#endif
#ifdef __GNUC__
- ".att_syntax prefix;"
+ ATT_PREFIX
:
: "c" (state), "d" (data), "S" (SHA256_K+48), "D" (len)
#if CRYPTOPP_BOOL_X64
@@ -688,7 +688,7 @@ CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state
#ifdef __GNUC__
__asm__ __volatile__
(
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
AS_PUSH_IF86( bx)
AS2( mov ebx, eax)
#else
@@ -864,7 +864,7 @@ CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state
#if defined(__GNUC__)
AS_POP_IF86( bx)
- ".att_syntax prefix;"
+ ATT_PREFIX
:
: "a" (SHA512_K), "c" (state), "d" (data)
: "%esi", "%edi", "memory", "cc"
diff --git a/sha.h b/sha.h
index 85d21c41..90ff1ab0 100644
--- a/sha.h
+++ b/sha.h
@@ -1,11 +1,14 @@
+// sha.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile sha.h
+//! \brief Classes for SHA-1 and SHA-2 family of message digests
+
#ifndef CRYPTOPP_SHA_H
#define CRYPTOPP_SHA_H
#include "config.h"
#include "iterhash.h"
-#include "secblock.h"
-
-#define SHA_BOOL_ALIGN (CRYPTOPP_BOOL_ALIGN || CRYPTOPP_BOOL_ALIGN16)
NAMESPACE_BEGIN(CryptoPP)
@@ -21,10 +24,10 @@ public:
typedef SHA1 SHA; // for backwards compatibility
//! implements the SHA-256 standard
-class CRYPTOPP_DLL SHA256 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SHA256, 32, SHA_BOOL_ALIGN>
+class CRYPTOPP_DLL SHA256 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SHA256, 32, true>
{
public:
-#if (defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X32_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_SHA_ASM)
+#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X32_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE) && !defined(CRYPTOPP_DISABLE_SHA_ASM)
size_t HashMultipleBlocks(const word32 *input, size_t length);
#endif
static void CRYPTOPP_API InitState(HashWordType *state);
@@ -33,10 +36,10 @@ public:
};
//! implements the SHA-224 standard
-class CRYPTOPP_DLL SHA224 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SHA224, 28, SHA_BOOL_ALIGN>
+class CRYPTOPP_DLL SHA224 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SHA224, 28, true>
{
public:
-#if (defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X32_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_SHA_ASM)
+#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X32_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE) && !defined(CRYPTOPP_DISABLE_SHA_ASM)
size_t HashMultipleBlocks(const word32 *input, size_t length);
#endif
static void CRYPTOPP_API InitState(HashWordType *state);
@@ -45,7 +48,7 @@ public:
};
//! implements the SHA-512 standard
-class CRYPTOPP_DLL SHA512 : public IteratedHashWithStaticTransform<word64, BigEndian, 128, 64, SHA512, 64, SHA_BOOL_ALIGN>
+class CRYPTOPP_DLL SHA512 : public IteratedHashWithStaticTransform<word64, BigEndian, 128, 64, SHA512, 64, (CRYPTOPP_BOOL_X86|CRYPTOPP_BOOL_X32)>
{
public:
static void CRYPTOPP_API InitState(HashWordType *state);
@@ -54,7 +57,7 @@ public:
};
//! implements the SHA-384 standard
-class CRYPTOPP_DLL SHA384 : public IteratedHashWithStaticTransform<word64, BigEndian, 128, 64, SHA384, 48, SHA_BOOL_ALIGN>
+class CRYPTOPP_DLL SHA384 : public IteratedHashWithStaticTransform<word64, BigEndian, 128, 64, SHA384, 48, (CRYPTOPP_BOOL_X86|CRYPTOPP_BOOL_X32)>
{
public:
static void CRYPTOPP_API InitState(HashWordType *state);
diff --git a/sha3.cpp b/sha3.cpp
index 7db82c19..9ab24ec8 100644
--- a/sha3.cpp
+++ b/sha3.cpp
@@ -251,17 +251,23 @@ static void KeccakF1600(word64 *state)
void SHA3::Update(const byte *input, size_t length)
{
+ assert((input && length) || !(input || length));
+ if (!length)
+ return;
+
size_t spaceLeft;
while (length >= (spaceLeft = r() - m_counter))
{
- xorbuf(m_state.BytePtr() + m_counter, input, spaceLeft);
+ if (spaceLeft)
+ xorbuf(m_state.BytePtr() + m_counter, input, spaceLeft);
KeccakF1600(m_state);
input += spaceLeft;
length -= spaceLeft;
m_counter = 0;
}
- xorbuf(m_state.BytePtr() + m_counter, input, length);
+ if (length)
+ xorbuf(m_state.BytePtr() + m_counter, input, length);
m_counter += (unsigned int)length;
}
diff --git a/sha3.h b/sha3.h
index 232bae56..83d8432e 100644
--- a/sha3.h
+++ b/sha3.h
@@ -1,5 +1,9 @@
// sha3.h - written and placed in the public domain by Wei Dai
+//! \file
+//! \headerfile sha3.h
+//! \brief Classes for SHA-3 message digests
+
#ifndef CRYPTOPP_SHA3_H
#define CRYPTOPP_SHA3_H
diff --git a/shark.h b/shark.h
index 2caad07e..33f3c4ad 100644
--- a/shark.h
+++ b/shark.h
@@ -1,9 +1,12 @@
+// shark.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile shark.h
+//! \brief Classes for SHARK encryption scheme
+
#ifndef CRYPTOPP_SHARK_H
#define CRYPTOPP_SHARK_H
-/** \file
-*/
-
#include "config.h"
#include "seckey.h"
#include "secblock.h"
diff --git a/simple.h b/simple.h
index 5d4df344..347dabac 100644
--- a/simple.h
+++ b/simple.h
@@ -1,7 +1,7 @@
// simple.h - written and placed in the public domain by Wei Dai
-/*! \file
- Simple non-interface classes derived from classes in cryptlib.h.
-*/
+
+//! \file simple.h
+//! \brief Classes providing simple keying interfaces.
#ifndef CRYPTOPP_SIMPLE_H
#define CRYPTOPP_SIMPLE_H
@@ -18,7 +18,10 @@
NAMESPACE_BEGIN(CryptoPP)
-//! _
+//! \class ClonableImpl
+//! \brief Base class for identifying alogorithm
+//! \tparam BASE base class from which to derive
+//! \tparam DERIVED class which to clone
template <class DERIVED, class BASE>
class CRYPTOPP_NO_VTABLE ClonableImpl : public BASE
{
@@ -26,7 +29,11 @@ public:
Clonable * Clone() const {return new DERIVED(*static_cast<const DERIVED *>(this));}
};
-//! _
+//! \class AlgorithmImpl
+//! \brief Base class for identifying alogorithm
+//! \tparam BASE an Algorithm derived class
+//! \tparam ALGORITHM_INFO an Algorithm derived class
+//! \details AlgorithmImpl provides StaticAlgorithmName from the template parameter BASE
template <class BASE, class ALGORITHM_INFO=BASE>
class CRYPTOPP_NO_VTABLE AlgorithmImpl : public BASE
{
@@ -35,14 +42,16 @@ public:
std::string AlgorithmName() const {return ALGORITHM_INFO::StaticAlgorithmName();}
};
-//! _
+//! \class InvalidKeyLength
+//! \brief Exception thrown when an invalid key length is encountered
class CRYPTOPP_DLL InvalidKeyLength : public InvalidArgument
{
public:
explicit InvalidKeyLength(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid key length") {}
};
-//! _
+//! \class InvalidRounds
+//! \brief Exception thrown when an invalid number of rounds is encountered
class CRYPTOPP_DLL InvalidRounds : public InvalidArgument
{
public:
@@ -51,7 +60,9 @@ public:
// *****************************
-//! _
+//! \class Bufferless
+//! \brief Base class for bufferless filters
+//! \tparam T the class or type
template <class T>
class CRYPTOPP_NO_VTABLE Bufferless : public T
{
@@ -60,7 +71,9 @@ public:
{CRYPTOPP_UNUSED(hardFlush); CRYPTOPP_UNUSED(blocking); return false;}
};
-//! _
+//! \class Unflushable
+//! \brief Base class for unflushable filters
+//! \tparam T the class or type
template <class T>
class CRYPTOPP_NO_VTABLE Unflushable : public T
{
@@ -84,7 +97,10 @@ protected:
virtual bool InputBufferIsEmpty() const {return false;}
};
-//! _
+//! \class InputRejecting
+//! \brief Base class for input rejecting filters
+//! \tparam T the class or type
+//! \details T should be a BufferedTransformation derived class
template <class T>
class CRYPTOPP_NO_VTABLE InputRejecting : public T
{
@@ -92,32 +108,56 @@ public:
struct InputRejected : public NotImplemented
{InputRejected() : NotImplemented("BufferedTransformation: this object doesn't allow input") {}};
- // shouldn't be calling these functions on this class
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
- {CRYPTOPP_UNUSED(begin); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); throw InputRejected();}
+ //! \name INPUT
+ //@{
+
+ //! \brief Input a byte array for processing
+ //! \param inString the byte array to process
+ //! \param length the size of the string, in bytes
+ //! \param messageEnd means how many filters to signal MessageEnd() to, including this one
+ //! \param blocking specifies whether the object should block when processing input
+ //! \throws InputRejected
+ //! \returns the number of bytes that remain in the block (i.e., bytes not processed)
+ //! \details Internally, the default implmentation throws InputRejected.
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
+ {CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); throw InputRejected();}
+ //@}
+
+ //! \name SIGNALS
+ //@{
bool IsolatedFlush(bool hardFlush, bool blocking)
{CRYPTOPP_UNUSED(hardFlush); CRYPTOPP_UNUSED(blocking); return false;}
bool IsolatedMessageSeriesEnd(bool blocking)
{CRYPTOPP_UNUSED(blocking); throw InputRejected();}
- size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
- {CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(begin); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); throw InputRejected();}
+ size_t ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking)
+ {CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); throw InputRejected();}
bool ChannelMessageSeriesEnd(const std::string& channel, int messageEnd, bool blocking)
{CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); throw InputRejected();}
+ //@}
};
-//! _
+//! \class CustomFlushPropagation
+//! \brief Provides interface for custom flush signals
+//! \tparam T the class or type
+//! \details T should be a BufferedTransformation derived class
template <class T>
class CRYPTOPP_NO_VTABLE CustomFlushPropagation : public T
{
public:
+ //! \name SIGNALS
+ //@{
virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) =0;
+ //@}
private:
bool IsolatedFlush(bool hardFlush, bool blocking)
{CRYPTOPP_UNUSED(hardFlush); CRYPTOPP_UNUSED(blocking); assert(false); return false;}
};
-//! _
+//! \class CustomSignalPropagation
+//! \brief Provides interface for initialization of derived filters
+//! \tparam T the class or type
+//! \details T should be a BufferedTransformation derived class
template <class T>
class CRYPTOPP_NO_VTABLE CustomSignalPropagation : public CustomFlushPropagation<T>
{
@@ -129,7 +169,10 @@ private:
{CRYPTOPP_UNUSED(parameters); assert(false);}
};
-//! _
+//! \class Multichannel
+//! \brief Provides multiple channels support for custom flush signal processing
+//! \tparam T the class or type
+//! \details T should be a BufferedTransformation derived class
template <class T>
class CRYPTOPP_NO_VTABLE Multichannel : public CustomFlushPropagation<T>
{
@@ -140,8 +183,8 @@ public:
{return this->ChannelMessageSeriesEnd(DEFAULT_CHANNEL, propagation, blocking);}
byte * CreatePutSpace(size_t &size)
{return this->ChannelCreatePutSpace(DEFAULT_CHANNEL, size);}
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
- {return this->ChannelPut2(DEFAULT_CHANNEL, begin, length, messageEnd, blocking);}
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
+ {return this->ChannelPut2(DEFAULT_CHANNEL, inString, length, messageEnd, blocking);}
size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking)
{return this->ChannelPutModifiable2(DEFAULT_CHANNEL, inString, length, messageEnd, blocking);}
@@ -159,7 +202,10 @@ public:
virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true) =0;
};
-//! _
+//! \class AutoSignaling
+//! \brief Provides auto signaling support
+//! \tparam T the class or type
+//! \details T should be a BufferedTransformation derived class
template <class T>
class CRYPTOPP_NO_VTABLE AutoSignaling : public T
{
@@ -175,7 +221,10 @@ private:
int m_autoSignalPropagation;
};
-//! A BufferedTransformation that only contains pre-existing data as "output"
+//! \class Store
+//! \brief Acts as a Source for pre-existing, static data
+//! \tparam T the class or type
+//! \details A BufferedTransformation that only contains pre-existing data as "output"
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Store : public AutoSignaling<InputRejecting<BufferedTransformation> >
{
public:
@@ -197,7 +246,16 @@ protected:
bool m_messageEnd;
};
-//! A BufferedTransformation that doesn't produce any retrievable output
+//! \class Sink
+//! \brief Implementation of BufferedTransformation's attachment interface
+//! \details Sink is a cornerstone of the Pipeline trinitiy. Data flows from
+//! Sources, through Filters, and then terminates in Sinks. The difference
+//! between a Source and Filter is a Source \a pumps data, while a Filter does
+//! not. The difference between a Filter and a Sink is a Filter allows an
+//! attached transformation, while a Sink does not.
+//! \details A Sink doesnot produce any retrievable output.
+//! \details See the discussion of BufferedTransformation in cryptlib.h for
+//! more details.
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Sink : public BufferedTransformation
{
public:
@@ -207,14 +265,19 @@ public:
{CRYPTOPP_UNUSED(target); CRYPTOPP_UNUSED(begin); CRYPTOPP_UNUSED(end); CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(blocking); return 0;}
};
+//! \class BitBucket
+//! \brief Acts as an input discarding Filter or Sink
+//! \tparam T the class or type
+//! \details The BitBucket discards all input and returns 0 to the caller
+//! to indicate all data was processed.
class CRYPTOPP_DLL BitBucket : public Bufferless<Sink>
{
public:
std::string AlgorithmName() const {return "BitBucket";}
void IsolatedInitialize(const NameValuePairs &params)
{CRYPTOPP_UNUSED(params);}
- size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
- {CRYPTOPP_UNUSED(begin); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); return 0;}
+ size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
+ {CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); return 0;}
};
NAMESPACE_END
diff --git a/skipjack.h b/skipjack.h
index 8f35f57c..f22390f8 100644
--- a/skipjack.h
+++ b/skipjack.h
@@ -1,9 +1,11 @@
+// skipjack.h - written and placed in the public domain by Wei Dai
+
+//! \file skipjack.h
+//! \brief Classes for Skipjack encryption algorithm
+
#ifndef CRYPTOPP_SKIPJACK_H
#define CRYPTOPP_SKIPJACK_H
-/** \file
-*/
-
#include "seckey.h"
#include "secblock.h"
diff --git a/smartptr.h b/smartptr.h
index 068ab52c..cbacb79f 100644
--- a/smartptr.h
+++ b/smartptr.h
@@ -1,3 +1,9 @@
+// smartptr.h - written and placed in the public domain by Wei Dai
+
+//! \file
+//! \headerfile smartptr.h
+//! \brief Classes for automatic resource management
+
#ifndef CRYPTOPP_SMARTPTR_H
#define CRYPTOPP_SMARTPTR_H
@@ -6,6 +12,11 @@
NAMESPACE_BEGIN(CryptoPP)
+//! \class simple_ptr
+//! \brief Manages resources for a single object
+//! \tparam T class or type
+//! \details \p simple_ptr is used frequently in the library to manage resources and
+//! ensure cleanup under the RAII pattern (Resource Acquisition Is Initialization).
template <class T> class simple_ptr
{
public:
@@ -19,7 +30,12 @@ public:
T *m_p;
};
-// Expanded use of member_ptr due to https://github.com/weidai11/cryptopp/issues/48
+//! \class member_ptr
+//! \brief Pointer that overloads operator→
+//! \tparam T class or type
+//! \details member_ptr is used frequently in the library to avoid the issues related to
+//! std::auto_ptr in C++11 (deprecated) and std::unique_ptr in C++03 (non-existent).
+//! \bug <a href="http://github.com/weidai11/cryptopp/issues/48">Issue 48: "Use of auto_ptr causes dirty compile under C++11"</a>
template <class T> class member_ptr
{
public:
@@ -57,6 +73,9 @@ template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;}
// ********************************************************
+//! \class value_ptr
+//! \brief Value pointer
+//! \tparam T class or type
template<class T> class value_ptr : public member_ptr<T>
{
public:
@@ -82,6 +101,10 @@ template <class T> value_ptr<T>& value_ptr<T>::operator=(const value_ptr<T>& rhs
// ********************************************************
+//! \class clonable_ptr
+//! \brief A pointer which can be copied and cloned
+//! \tparam T class or type
+//! \details \p T should adhere to the \p Clonable interface
template<class T> class clonable_ptr : public member_ptr<T>
{
public:
@@ -103,8 +126,11 @@ template <class T> clonable_ptr<T>& clonable_ptr<T>::operator=(const clonable_pt
// ********************************************************
-//! reference counted pointer
-//! /details users should declare \p m_referenceCount as `std::atomic<unsigned>` under C++ 11
+//! \class counted_ptr
+//! \brief Reference counted pointer
+//! \tparam T class or type
+//! \details users should declare \p m_referenceCount as <tt>std::atomic<unsigned></tt>
+//! (or similar) under C++ 11
template<class T> class counted_ptr
{
public:
@@ -194,10 +220,18 @@ template <class T> counted_ptr<T> & counted_ptr<T>::operator=(const counted_ptr<
// ********************************************************
-//! Manages the resource of an vector of T.
+//! \class vector_ptr
+//! \brief Manages resources for an array of objects
+//! \tparam T class or type
+//! \details \p vector_ptr is used frequently in the library to avoid large stack allocations,
+//! and manage resources and ensure cleanup under the RAII pattern (Resource Acquisition
+//! Is Initialization).
template <class T> class vector_ptr
{
public:
+ //! Construct an arry of \p T
+ //! \param size the size of the array, in elements
+ //! \details If \p T is a Plain Old Dataype (POD), then the array is uninitialized.
vector_ptr(size_t size=0)
: m_size(size), m_ptr(new T[m_size]) {}
~vector_ptr()
@@ -244,9 +278,15 @@ private:
// ********************************************************
+//! \class vector_member_ptrs
+//! \brief Manages resources for an array of objects
+//! \tparam T class or type
template <class T> class vector_member_ptrs
{
public:
+ //! Construct an arry of \p T
+ //! \param size the size of the array, in elements
+ //! \details If \p T is a Plain Old Dataype (POD), then the array is uninitialized.
vector_member_ptrs(size_t size=0)
: m_size(size), m_ptr(new member_ptr<T>[size]) {}
~vector_member_ptrs()
diff --git a/sosemanuk.cpp b/sosemanuk.cpp
index 6e32d767..4b3bd0fe 100644
--- a/sosemanuk.cpp
+++ b/sosemanuk.cpp
@@ -90,7 +90,7 @@ void SosemanukPolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv,
extern "C" {
word32 s_sosemanukMulTables[512] = {
-#if CRYPTOPP_BOOL_X86 || (CRYPTOPP_BOOL_X32 && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM)) || CRYPTOPP_BOOL_X64
+#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM)
0x00000000, 0xE19FCF12, 0x6B973724, 0x8A08F836,
0xD6876E48, 0x3718A15A, 0xBD10596C, 0x5C8F967E,
0x05A7DC90, 0xE4381382, 0x6E30EBB4, 0x8FAF24A6,
@@ -288,7 +288,7 @@ word32 s_sosemanukMulTables[512] = {
};
}
-#if CRYPTOPP_BOOL_X86 || (CRYPTOPP_BOOL_X32 && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM)) || CRYPTOPP_BOOL_X64
+#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM)
unsigned int SosemanukPolicy::GetAlignment() const
{
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM)
@@ -321,7 +321,7 @@ unsigned int SosemanukPolicy::GetOptimalBlockSize() const
#ifdef CRYPTOPP_X64_MASM_AVAILABLE
extern "C" {
void Sosemanuk_OperateKeystream(size_t iterationCount, const byte *input, byte *output, word32 *state);
-}
+}
#endif
void SosemanukPolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
@@ -358,7 +358,7 @@ void SosemanukPolicy::OperateKeystream(KeystreamOperation operation, byte *outpu
#endif
__asm__ __volatile__
(
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
AS_PUSH_IF86( bx)
#else
word32 *state = m_state;
@@ -385,7 +385,7 @@ void SosemanukPolicy::OperateKeystream(KeystreamOperation operation, byte *outpu
#define SSE2_stateCopy SSE2_workspace + 8*WORD_SZ
#define SSE2_uvStart SSE2_stateCopy + 12*4
-#if CRYPTOPP_BOOL_X86 || (CRYPTOPP_BOOL_X32 && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM))
+#if (CRYPTOPP_BOOL_X86) && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM)
AS_PUSH_IF86( bp)
AS2( mov AS_REG_6, esp)
AS2( and esp, -16)
@@ -599,7 +599,7 @@ void SosemanukPolicy::OperateKeystream(KeystreamOperation operation, byte *outpu
#ifdef __GNUC__
AS_POP_IF86( bx)
- ".att_syntax prefix;"
+ ATT_PREFIX
:
: "a" (m_state.m_ptr), "c" (iterationCount), "S" (s_sosemanukMulTables), "D" (output), "d" (input)
#if CRYPTOPP_BOOL_X64
@@ -625,7 +625,7 @@ void SosemanukPolicy::OperateKeystream(KeystreamOperation operation, byte *outpu
#endif
#ifndef CRYPTOPP_GENERATE_X64_MASM
{
-#if CRYPTOPP_BOOL_X86 || (CRYPTOPP_BOOL_X32 && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM)) || CRYPTOPP_BOOL_X64
+#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM)
#define MUL_A(x) (x = rotlFixed(x, 8), x ^ s_sosemanukMulTables[byte(x)])
#else
#define MUL_A(x) (((x) << 8) ^ s_sosemanukMulTables[(x) >> 24])
diff --git a/sosemanuk.h b/sosemanuk.h
index 5ea8c72c..d1025c20 100644
--- a/sosemanuk.h
+++ b/sosemanuk.h
@@ -4,7 +4,9 @@
#include "strciphr.h"
#include "secblock.h"
-#if CRYPTOPP_BOOL_X32
+// Clang due to "Inline assembly operands don't work with .intel_syntax"
+// https://llvm.org/bugs/show_bug.cgi?id=24232
+#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_INTEL_ASM)
# define CRYPTOPP_DISABLE_SOSEMANUK_ASM
#endif
@@ -24,7 +26,7 @@ protected:
void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length);
bool CipherIsRandomAccess() const {return false;}
-#if CRYPTOPP_BOOL_X86 || (CRYPTOPP_BOOL_X32 && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM)) || CRYPTOPP_BOOL_X64
+#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM)
unsigned int GetAlignment() const;
unsigned int GetOptimalBlockSize() const;
#endif
diff --git a/square.h b/square.h
index b1340a70..7ad8352e 100644
--- a/square.h
+++ b/square.h
@@ -1,9 +1,11 @@
+// square.h - written and placed in the public domain by Wei Dai
+
+//! \file square.h
+//! \brief Classes for SQUARE encryption algorithm
+
#ifndef CRYPTOPP_SQUARE_H
#define CRYPTOPP_SQUARE_H
-/** \file
-*/
-
#include "seckey.h"
#include "secblock.h"
diff --git a/stdcpp.h b/stdcpp.h
index 7b6b8fe4..b7384f29 100644
--- a/stdcpp.h
+++ b/stdcpp.h
@@ -10,29 +10,19 @@
#include <memory>
#include <exception>
#include <typeinfo>
+#include <algorithm>
#include <functional>
#include <utility>
#include <vector>
-#include <deque>
#include <limits>
+#include <deque>
+#include <list>
#include <map>
#include <new>
-// GCC began indirectly including wmmintrin.h via <algorithm>. Or, maybe it was
-// doing it all along, but we did not experience issues.
-// The net result is a number of C++11 compile failures on the _mm_* intrinsics
-// from cpu.h. The _mm_* collisions are on AES and PCLMUL intrinsics (they
-// are the only intrinsics in the file).
-// TODO: perhaps use a namespace to resolve the symbol collisions. That
-// needs to occur when symbols can change, which is a major bump.
-#if defined(__GNUC__) && defined(CRYPTOPP_CXX11) && (CRYPTOPP_GCC_VERSION >= 40300)
-# pragma push_macro("_WMMINTRIN_H_INCLUDED")
-# undef _WMMINTRIN_H_INCLUDED
-# define _WMMINTRIN_H_INCLUDED
-# include <algorithm>
-# pragma pop_macro("_WMMINTRIN_H_INCLUDED")
-#else
-# include <algorithm>
+#if _MSC_VER >= 1600
+// for make_unchecked_array_iterator
+#include <iterator>
#endif
#include <cstdlib>
@@ -49,9 +39,9 @@
// for alloca
#if defined(CRYPTOPP_BSD_AVAILABLE)
#include <stdlib.h>
-#elif defined(CRYPTOPP_UNIX_AVAILABLE) || defined(__sun)
+#elif defined(CRYPTOPP_UNIX_AVAILABLE) || defined(__sun) || defined(QNX)
#include <alloca.h>
-#elif defined(CRYPTOPP_WIN32_AVAILABLE) || defined(__MINGW32__) || defined(__BORLANDC__)
+#elif defined(CRYPTOPP_WIN32_AVAILABLE) || defined(__MINGW32__) || defined(__BORLANDC__)
#include <malloc.h>
#endif
diff --git a/test.cpp b/test.cpp
index 07e37bb9..53ea7bab 100644
--- a/test.cpp
+++ b/test.cpp
@@ -25,9 +25,11 @@
#include "validate.h"
#include "bench.h"
+#include <algorithm>
#include <iostream>
+#include <sstream>
#include <string>
-#include <algorithm>
+#include <locale>
#include <time.h>
#ifdef CRYPTOPP_WIN32_AVAILABLE
@@ -106,6 +108,7 @@ void FIPS140_SampleApplication();
void FIPS140_GenerateRandomFiles();
bool Validate(int, bool, const char *);
+void PrintSeedAndThreads(const std::string& seed);
int (*AdhocTest)(int argc, char *argv[]) = NULL;
@@ -115,21 +118,6 @@ RandomNumberGenerator & GlobalRNG()
return dynamic_cast<RandomNumberGenerator&>(s_globalRNG);
}
-void PrintSeedAndThreads(const std::string& seed)
-{
- cout << "Using seed: " << seed << endl;
-
-#ifdef _OPENMP
- int tc = 0;
- #pragma omp parallel
- {
- tc = omp_get_num_threads();
- }
-
- std::cout << "Using " << tc << " OMP " << (tc == 1 ? "thread" : "threads") << std::endl;
-#endif
-}
-
int CRYPTOPP_API main(int argc, char *argv[])
{
#ifdef _CRTDBG_LEAK_CHECK_DF
@@ -144,14 +132,12 @@ int CRYPTOPP_API main(int argc, char *argv[])
#endif
try
- {
+ {
RegisterFactories();
- std::string seed = IntToString(time(NULL));
-
- // Some editors have problems with the '\0' character from redirected output. Leave the trailing '\0' for debugging.
- seed.resize(16);
- std::replace(seed.begin(), seed.end() -1, '\0', ' ');
+ // Some editors have problems with the '\0' character when redirecting output.
+ std::string seed = IntToString(time(NULL));
+ seed.resize(16, ' ');
OFB_Mode<AES>::Encryption& prng = dynamic_cast<OFB_Mode<AES>::Encryption&>(GlobalRNG());
prng.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data());
@@ -343,20 +329,20 @@ int CRYPTOPP_API main(int argc, char *argv[])
cout << "\nRandom Seed: ";
ws(cin);
cin.getline(thisSeed, 1024);
- SecretShareFile(atoi(argv[2]), atoi(argv[3]), argv[4], thisSeed);
+ SecretShareFile(StringToValue<int, true>(argv[2]), StringToValue<int, true>(argv[3]), argv[4], thisSeed);
}
else if (command == "sr")
SecretRecoverFile(argc-3, argv[2], argv+3);
else if (command == "id")
- InformationDisperseFile(atoi(argv[2]), atoi(argv[3]), argv[4]);
+ InformationDisperseFile(StringToValue<int, true>(argv[2]), StringToValue<int, true>(argv[3]), argv[4]);
else if (command == "ir")
InformationRecoverFile(argc-3, argv[2], argv+3);
else if (command == "v" || command == "vv")
- return !Validate(argc>2 ? atoi(argv[2]) : 0, argv[1][1] == 'v', argc>3 ? argv[3] : NULL);
+ return !Validate(argc>2 ? StringToValue<int, true>(argv[2]) : 0, argv[1][1] == 'v', argc>3 ? argv[3] : NULL);
else if (command == "b")
- BenchmarkAll(argc<3 ? 1 : atof(argv[2]), argc<4 ? 0 : atof(argv[3])*1e9);
+ BenchmarkAll(argc<3 ? 1 : StringToValue<float, true>(argv[2]), argc<4 ? 0 : StringToValue<float, true>(argv[3])*1e9);
else if (command == "b2")
- BenchmarkAll2(argc<3 ? 1 : atof(argv[2]), argc<4 ? 0 : atof(argv[3])*1e9);
+ BenchmarkAll2(argc<3 ? 1 : StringToValue<float, true>(argv[2]), argc<4 ? 0 : StringToValue<float, true>(argv[3])*1e9);
else if (command == "z")
GzipFile(argv[3], argv[4], argv[2][0]-'0');
else if (command == "u")
@@ -423,6 +409,52 @@ void FIPS140_GenerateRandomFiles()
#endif
}
+template <class T, bool NON_NEGATIVE>
+T StringToValue(const std::string& str) {
+ std::istringstream iss(str);
+ T value;
+ iss >> value;
+
+ // Use fail(), not bad()
+ if (iss.fail())
+ throw InvalidArgument("cryptest.exe: '" + str +"' is not a value");
+
+#if NON_NEGATIVE
+ if (value < 0)
+ throw InvalidArgument("cryptest.exe: '" + str +"' is negative");
+#endif
+
+ return value;
+}
+
+template<>
+int StringToValue<int, true>(const std::string& str)
+{
+ Integer n(str.c_str());
+ long l = n.ConvertToLong();
+
+ int r;
+ if(!SafeConvert(l, r))
+ throw InvalidArgument("cryptest.exe: '" + str +"' is not an integer value");
+
+ return r;
+}
+
+void PrintSeedAndThreads(const std::string& seed)
+{
+ cout << "Using seed: " << seed << endl;
+
+#ifdef _OPENMP
+ int tc = 0;
+ #pragma omp parallel
+ {
+ tc = omp_get_num_threads();
+ }
+
+ std::cout << "Using " << tc << " OMP " << (tc == 1 ? "thread" : "threads") << std::endl;
+#endif
+}
+
SecByteBlock HexDecodeString(const char *hex)
{
StringSource ss(hex, true, new HexDecoder);
@@ -585,7 +617,9 @@ void DecryptFile(const char *in, const char *out, const char *passPhrase)
void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed)
{
- assert(nShares<=1000);
+ assert(nShares >= 1 && nShares<=1000);
+ if (nShares < 1 || nShares > 1000)
+ throw InvalidArgument("SecretShareFile: " + IntToString(nShares) + " is not in range [1, 1000]");
RandomPool rng;
rng.IncorporateEntropy((byte *)seed, strlen(seed));
@@ -604,7 +638,7 @@ void SecretShareFile(int threshold, int nShares, const char *filename, const cha
fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));
channel = WordToString<word32>(i);
- fileSinks[i]->Put((byte *)channel.data(), 4);
+ fileSinks[i]->Put((const byte *)channel.data(), 4);
channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
}
@@ -613,7 +647,9 @@ void SecretShareFile(int threshold, int nShares, const char *filename, const cha
void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
{
- assert(threshold<=1000);
+ assert(threshold >= 1 && threshold <=1000);
+ if (threshold < 1 || threshold > 1000)
+ throw InvalidArgument("SecretRecoverFile: " + IntToString(threshold) + " is not in range [1, 1000]");
SecretRecovery recovery(threshold, new FileSink(outFilename));
@@ -638,7 +674,9 @@ void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFi
void InformationDisperseFile(int threshold, int nShares, const char *filename)
{
- assert(nShares<=1000);
+ assert(threshold >= 1 && threshold <=1000);
+ if (threshold < 1 || threshold > 1000)
+ throw InvalidArgument("InformationDisperseFile: " + IntToString(nShares) + " is not in range [1, 1000]");
ChannelSwitch *channelSwitch;
FileSource source(filename, false, new InformationDispersal(threshold, nShares, channelSwitch = new ChannelSwitch));
@@ -654,7 +692,7 @@ void InformationDisperseFile(int threshold, int nShares, const char *filename)
fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));
channel = WordToString<word32>(i);
- fileSinks[i]->Put((byte *)channel.data(), 4);
+ fileSinks[i]->Put((const byte *)channel.data(), 4);
channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
}
@@ -664,6 +702,8 @@ void InformationDisperseFile(int threshold, int nShares, const char *filename)
void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
{
assert(threshold<=1000);
+ if (threshold < 1 || threshold > 1000)
+ throw InvalidArgument("InformationRecoverFile: " + IntToString(threshold) + " is not in range [1, 1000]");
InformationRecovery recovery(threshold, new FileSink(outFilename));
@@ -755,8 +795,12 @@ void ForwardTcpPort(const char *sourcePortName, const char *destinationHost, con
sockListen.Create();
sockListen.Bind(sourcePort);
- setsockopt(sockListen, IPPROTO_TCP, TCP_NODELAY, "\x01", 1);
-
+
+ int err = setsockopt(sockListen, IPPROTO_TCP, TCP_NODELAY, "\x01", 1);
+ assert(err == 0);
+ if(err != 0)
+ throw Socket::Err(sockListen, "setsockopt", sockListen.GetLastError());
+
cout << "Listing on port " << sourcePort << ".\n";
sockListen.Listen();
@@ -810,11 +854,10 @@ bool Validate(int alg, bool thorough, const char *seedInput)
{
bool result;
- std::string seed = seedInput ? std::string(seedInput) : IntToString(time(NULL));
-
- // Some editors have problems with the '\0' character from redirected output. Leave the trailing '\0' for debugging.
- seed.resize(16);
- std::replace(seed.begin(), seed.end() -1, '\0', ' ');
+ // Some editors have problems with the '\0' character when redirecting output.
+ // seedInput is argv[3] when issuing 'cryptest.exe v all <seed>'
+ std::string seed = (seedInput ? seedInput : IntToString(time(NULL)));
+ seed.resize(16, ' ');
OFB_Mode<AES>::Encryption& prng = dynamic_cast<OFB_Mode<AES>::Encryption&>(GlobalRNG());
prng.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data());
diff --git a/tiger.cpp b/tiger.cpp
index bf662ce6..534337f8 100644
--- a/tiger.cpp
+++ b/tiger.cpp
@@ -40,7 +40,7 @@ void Tiger::Transform (word64 *digest, const word64 *X)
#ifdef __GNUC__
__asm__ __volatile__
(
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
AS_PUSH_IF86(bx)
#else
#if _MSC_VER < 1300
@@ -205,7 +205,7 @@ void Tiger::Transform (word64 *digest, const word64 *X)
#ifdef __GNUC__
AS_POP_IF86(bx)
- ".att_syntax prefix;"
+ ATT_PREFIX
:
: "a" (digest), "S" (X), "d" (table)
: "%ecx", "%edi", "memory", "cc"
diff --git a/trdlocal.cpp b/trdlocal.cpp
index cff44a72..3c450d6a 100644
--- a/trdlocal.cpp
+++ b/trdlocal.cpp
@@ -28,10 +28,13 @@ ThreadLocalStorage::ThreadLocalStorage()
{
#ifdef HAS_WINTHREADS
m_index = TlsAlloc();
+ assert(m_index != TLS_OUT_OF_INDEXES);
if (m_index == TLS_OUT_OF_INDEXES)
throw Err("TlsAlloc", GetLastError());
#else
+ m_index = 0;
int error = pthread_key_create(&m_index, NULL);
+ assert(!error);
if (error)
throw Err("pthread_key_create", error);
#endif
@@ -82,9 +85,14 @@ void *ThreadLocalStorage::GetValue() const
{
#ifdef HAS_WINTHREADS
void *result = TlsGetValue(m_index);
- if (!result && GetLastError() != NO_ERROR)
- throw Err("TlsGetValue", GetLastError());
+ const DWORD dwRet = GetLastError();
+
+ assert(result || (!result && (dwRet == NO_ERROR)));
+ if (!result && dwRet != NO_ERROR)
+ throw Err("TlsGetValue", dwRet);
#else
+ // Null is a valid return value. Posix does not provide a way to
+ // check for a "good" Null vs a "bad" Null (errno is not set).
void *result = pthread_getspecific(m_index);
#endif
return result;
diff --git a/ttmac.cpp b/ttmac.cpp
index 6b4e8bfe..98954370 100644
--- a/ttmac.cpp
+++ b/ttmac.cpp
@@ -43,10 +43,10 @@ void TTMAC_Base::TruncatedFinal(byte *hash, size_t size)
{
case 16:
m_digest[3] += m_digest[1] + m_digest[4];
-
+ // fall through
case 12:
m_digest[2] += m_digest[0] + t3;
-
+ // fall through
case 8:
m_digest[0] += m_digest[1] + t3;
m_digest[1] += m_digest[4] + t2;
diff --git a/validat1.cpp b/validat1.cpp
index 478199f5..29747889 100644
--- a/validat1.cpp
+++ b/validat1.cpp
@@ -64,8 +64,18 @@ bool ValidateAll(bool thorough)
bool pass=TestSettings();
pass=TestOS_RNG() && pass;
pass=TestAutoSeeded() && pass;
+
+#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
pass=TestRDRAND() && pass;
pass=TestRDSEED() && pass;
+#else
+
+#endif
+
+#if !defined(NDEBUG) && !defined(CRYPTOPP_IMPORTS)
+ // http://github.com/weidai11/cryptopp/issues/64
+ pass=TestPolynomialMod2() && pass;
+#endif
pass=ValidateCRC32() && pass;
pass=ValidateAdler32() && pass;
@@ -145,6 +155,11 @@ bool ValidateAll(bool thorough)
bool TestSettings()
{
+ // Thanks to IlyaBizyaev and Zireael-N, http://github.com/weidai11/cryptopp/issues/28
+#if defined(__MINGW__)
+ using CryptoPP::memcpy_s;
+#endif
+
bool pass = true;
cout << "\nTesting Settings...\n\n";
@@ -262,9 +277,6 @@ bool TestSettings()
bool hasSSSE3 = HasSSSE3();
bool isP4 = IsP4();
int cacheLineSize = GetCacheLineSize();
-
- // Hack to avoid changing CPU.h and CPU.cpp at the moment. Eventually, a hasRDRAND will be available.
- RDRAND rdrand; RDSEED rdseed;
if ((isP4 && (!hasMMX || !hasSSE2)) || (hasSSE2 && !hasMMX) || (cacheLineSize < 16 || cacheLineSize > 256 || !IsPowerOf2(cacheLineSize)))
{
@@ -274,7 +286,7 @@ bool TestSettings()
else
cout << "passed: ";
- cout << "hasMMX == " << hasMMX << ", hasISSE == " << hasISSE << ", hasSSE2 == " << hasSSE2 << ", hasSSSE3 == " << hasSSSE3 << ", hasAESNI == " << HasAESNI() << ", hasRDRAND == " << rdrand.Available() << ", hasRDSEED == " << rdseed.Available() << ", hasCLMUL == " << HasCLMUL() << ", isP4 == " << isP4 << ", cacheLineSize == " << cacheLineSize;
+ cout << "hasMMX == " << hasMMX << ", hasISSE == " << hasISSE << ", hasSSE2 == " << hasSSE2 << ", hasSSSE3 == " << hasSSSE3 << ", hasAESNI == " << HasAESNI() << ", hasRDRAND == " << HasRDRAND() << ", hasRDSEED == " << HasRDSEED() << ", hasCLMUL == " << HasCLMUL() << ", isP4 == " << isP4 << ", cacheLineSize == " << cacheLineSize;
cout << ", AESNI_INTRINSICS == " << CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE << endl;
#endif
@@ -443,13 +455,12 @@ bool TestAutoSeeded()
}
#endif // NO_OS_DEPENDENCE
+#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
bool TestRDRAND()
-{
+{
RDRAND rdrand;
-
-#if defined(CRYPTOPP_BOOL_X86) || defined(CRYPTOPP_BOOL_X32) || defined(CRYPTOPP_BOOL_X64)
bool generate = true, discard = true;
- if (rdrand.Available())
+ if (HasRDRAND())
{
cout << "\nTesting RDRAND generator...\n\n";
@@ -484,49 +495,20 @@ bool TestRDRAND()
cout << "\nRDRAND generator not available, skipping test." << endl;
return generate && discard;
-#else
- bool available = true, generate = true;
- if (rdrand.Available())
- {
- available = false; /* failed */
- cout << "FAILED:";
- }
- else
- cout << "passed:";
- cout << " RDRAND generator availability." << endl;
-
- try
- {
- SecByteBlock unused(32);
- rdrand.GenerateBlock(unused, unused.size());
- }
- catch(const RDRAND_Err&)
- {
- generate = false; /* failed */
- }
-
- if (!pass)
- cout << "FAILED:";
- else
- cout << "passed:";
- cout << " GenerateBlock and exception." << endl;
-
- return available && generate;
-#endif
}
+#endif
+#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
bool TestRDSEED()
-{
- RDSEED rdrand;
-
-#if defined(CRYPTOPP_BOOL_X86) || defined(CRYPTOPP_BOOL_X32) || defined(CRYPTOPP_BOOL_X64)
+{
+ RDSEED rdseed;
bool generate = true, discard = true;
- if (rdrand.Available())
+ if (HasRDSEED())
{
cout << "\nTesting RDSEED generator...\n\n";
MeterFilter meter(new Redirector(TheBitBucket()));
- RandomNumberSource test(rdrand, 100000, true, new Deflator(new Redirector(meter)));
+ RandomNumberSource test(rdseed, 100000, true, new Deflator(new Redirector(meter)));
if (meter.GetTotalBytes() < 100000)
{
@@ -539,7 +521,7 @@ bool TestRDSEED()
try
{
- rdrand.DiscardBytes(100000);
+ rdseed.DiscardBytes(100000);
}
catch(const Exception&)
{
@@ -555,37 +537,9 @@ bool TestRDSEED()
else
cout << "\nRDSEED generator not available, skipping test." << endl;
- return generate && discard;
-#else
- bool available = true, generate = true;
- if (rdrand.Available())
- {
- available = false; /* failed */
- cout << "FAILED:";
- }
- else
- cout << "passed:";
- cout << " RDSEED generator availability." << endl;
-
- try
- {
- SecByteBlock unused(32);
- rdrand.GenerateBlock(unused, unused.size());
- }
- catch(const RDSEED_Err&)
- {
- generate = false; /* failed */
- }
-
- if (!pass)
- cout << "FAILED:";
- else
- cout << "passed:";
- cout << " GenerateBlock and exception." << endl;
-
- return available && generate;
-#endif
+ return generate && discard;
}
+#endif
// VC50 workaround
typedef auto_ptr<BlockTransformation> apbt;
diff --git a/validat2.cpp b/validat2.cpp
index 496eaaa7..2faeaa51 100644
--- a/validat2.cpp
+++ b/validat2.cpp
@@ -24,6 +24,7 @@
#include "rw.h"
#include "eccrypto.h"
#include "integer.h"
+#include "gf2n.h"
#include "ecp.h"
#include "ec2n.h"
#include "asn.h"
@@ -35,6 +36,7 @@
#include "smartptr.h"
#include <iostream>
+#include <sstream>
#include <iomanip>
#include "validate.h"
@@ -275,7 +277,7 @@ bool ValidateRSA()
{
const char *plain = "Everyone gets Friday off.";
- byte *signature = (byte *)
+ static const byte signature[] =
"\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84"
"\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21"
"\x69\x94\xac\x04\xf3\x41\xb5\x7d\x05\x20\x2d\x42\x8f\xb2\xa2\x7b"
@@ -321,12 +323,12 @@ bool ValidateRSA()
{
byte *plain = (byte *)
"\x54\x85\x9b\x34\x2c\x49\xea\x2a";
- byte *encrypted = (byte *)
+ static const byte encrypted[] =
"\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
"\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
"\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
"\x62\x51";
- byte *oaepSeed = (byte *)
+ static const byte oaepSeed[] =
"\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2"
"\xf0\x6c\xb5\x8f";
ByteQueue bq;
@@ -549,6 +551,120 @@ bool ValidateBlumGoldwasser()
}
*/
+#if !defined(NDEBUG) && !defined(CRYPTOPP_IMPORTS)
+// Issue 64: "PolynomialMod2::operator<<=", http://github.com/weidai11/cryptopp/issues/64
+bool TestPolynomialMod2()
+{
+ bool pass1 = true, pass2 = true, pass3 = true;
+
+ cout << "\nTesting PolynomialMod2 bit operations...\n\n";
+
+ static const unsigned int start = 0;
+ static const unsigned int stop = 4 * WORD_BITS + 1;
+
+ for (unsigned int i=start; i < stop; i++)
+ {
+ PolynomialMod2 p(1);
+ p <<= i;
+
+ Integer n(Integer::One());
+ n <<= i;
+
+ std::ostringstream oss1;
+ oss1 << p;
+
+ std::string str1, str2;
+
+ // str1 needs the commas removed used for grouping
+ str1 = oss1.str();
+ str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
+
+ // str1 needs the trailing 'b' removed
+ str1.erase(str1.end() - 1);
+
+ // str2 is fine as-is
+ str2 = IntToString(n, 2);
+
+ pass1 &= (str1 == str2);
+ }
+
+ for (unsigned int i=start; i < stop; i++)
+ {
+ const word w(SIZE_MAX);
+
+ PolynomialMod2 p(w);
+ p <<= i;
+
+ Integer n(Integer::POSITIVE, static_cast<lword>(w));
+ n <<= i;
+
+ std::ostringstream oss1;
+ oss1 << p;
+
+ std::string str1, str2;
+
+ // str1 needs the commas removed used for grouping
+ str1 = oss1.str();
+ str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
+
+ // str1 needs the trailing 'b' removed
+ str1.erase(str1.end() - 1);
+
+ // str2 is fine as-is
+ str2 = IntToString(n, 2);
+
+ pass2 &= (str1 == str2);
+ }
+
+ RandomNumberGenerator& prng = GlobalRNG();
+ for (unsigned int i=start; i < stop; i++)
+ {
+ word w; // Cast to lword due to Visual Studio
+ prng.GenerateBlock((byte*)&w, sizeof(w));
+
+ PolynomialMod2 p(w);
+ p <<= i;
+
+ Integer n(Integer::POSITIVE, static_cast<lword>(w));
+ n <<= i;
+
+ std::ostringstream oss1;
+ oss1 << p;
+
+ std::string str1, str2;
+
+ // str1 needs the commas removed used for grouping
+ str1 = oss1.str();
+ str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
+
+ // str1 needs the trailing 'b' removed
+ str1.erase(str1.end() - 1);
+
+ // str2 is fine as-is
+ str2 = IntToString(n, 2);
+
+ if (str1 != str2)
+ {
+ cout << " Oops..." << "\n";
+ cout << " random: " << std::hex << n << std::dec << "\n";
+ cout << " str1: " << str1 << "\n";
+ cout << " str2: " << str2 << "\n";
+ }
+
+ pass3 &= (str1 == str2);
+ }
+
+ cout << (!pass1 ? "FAILED" : "passed") << " " << "1 shifted over range [0," << 2 * WORD_BITS + 1 << "]" << "\n";
+ cout << (!pass2 ? "FAILED" : "passed") << " " << "0x" << hex << word(SIZE_MAX) << " shifted over range [0," << dec << 2 * WORD_BITS + 1 << "]" << "\n";
+ cout << (!pass3 ? "FAILED" : "passed") << " " << "random values shifted over range [0," << dec << 2 * WORD_BITS + 1 << "]" << "\n";
+
+ if (!(pass1 && pass2 && pass3))
+ cout.flush();
+
+ return pass1 && pass2 && pass3;
+}
+#endif
+
bool ValidateECP()
{
cout << "\nECP validation suite running...\n\n";
@@ -668,7 +784,7 @@ bool ValidateECDSA()
Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH");
Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H");
- byte sig[]="\x03\x8e\x5a\x11\xfb\x55\xe4\xc6\x54\x71\xdc\xd4\x99\x84\x52\xb1\xe0\x2d\x8a\xf7\x09\x9b\xb9\x30"
+ static const byte sig[]="\x03\x8e\x5a\x11\xfb\x55\xe4\xc6\x54\x71\xdc\xd4\x99\x84\x52\xb1\xe0\x2d\x8a\xf7\x09\x9b\xb9\x30"
"\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e";
Integer r(sig, 24);
Integer s(sig+24, 24);
@@ -703,8 +819,8 @@ bool ValidateESIGN()
bool pass = true, fail;
- const char *plain = "test";
- const byte *signature = (byte *)
+ static const char plain[] = "test";
+ static const byte signature[] =
"\xA3\xE3\x20\x65\xDE\xDA\xE7\xEC\x05\xC1\xBF\xCD\x25\x79\x7D\x99\xCD\xD5\x73\x9D\x9D\xF3\xA4\xAA\x9A\xA4\x5A\xC8\x23\x3D\x0D\x37\xFE\xBC\x76\x3F\xF1\x84\xF6\x59"
"\x14\x91\x4F\x0C\x34\x1B\xAE\x9A\x5C\x2E\x2E\x38\x08\x78\x77\xCB\xDC\x3C\x7E\xA0\x34\x44\x5B\x0F\x67\xD9\x35\x2A\x79\x47\x1A\x52\x37\x71\xDB\x12\x67\xC1\xB6\xC6"
"\x66\x73\xB3\x40\x2E\xD6\xF2\x1A\x84\x0A\xB6\x7B\x0F\xEB\x8B\x88\xAB\x33\xDD\xE4\x83\x21\x90\x63\x2D\x51\x2A\xB1\x6F\xAB\xA7\x5C\xFD\x77\x99\xF2\xE1\xEF\x67\x1A"
diff --git a/validat3.cpp b/validat3.cpp
index 137ad62f..2ab2d624 100644
--- a/validat3.cpp
+++ b/validat3.cpp
@@ -30,6 +30,7 @@
#include "smartptr.h"
#include <iostream>
+#include <sstream>
#include <iomanip>
#include "validate.h"
@@ -60,6 +61,10 @@ bool HashModuleTest(HashTransformation &md, const HashTestTuple *testSet, unsign
bool pass=true, fail;
SecByteBlock digest(md.DigestSize());
+ // Coverity finding (http://stackoverflow.com/a/30968371 does not squash the finding)
+ std::ostringstream out;
+ out.copyfmt(cout);
+
for (unsigned int i=0; i<testSetSize; i++)
{
unsigned j;
@@ -70,15 +75,16 @@ bool HashModuleTest(HashTransformation &md, const HashTestTuple *testSet, unsign
fail = memcmp(digest, testSet[i].output, md.DigestSize()) != 0;
pass = pass && !fail;
- cout << (fail ? "FAILED " : "passed ");
+ out << (fail ? "FAILED " : "passed ");
for (j=0; j<md.DigestSize(); j++)
- cout << setw(2) << setfill('0') << hex << (int)digest[j];
- cout << " \"" << (char *)testSet[i].input << '\"';
+ out << setw(2) << setfill('0') << hex << (int)digest[j];
+ out << " \"" << (char *)testSet[i].input << '\"';
if (testSet[i].repeatTimes != 1)
- cout << " repeated " << dec << testSet[i].repeatTimes << " times";
- cout << endl;
+ out << " repeated " << dec << testSet[i].repeatTimes << " times";
+ out << endl;
}
+ cout << out.str();
return pass;
}
diff --git a/validate.h b/validate.h
index 7be0fe50..1dfda737 100644
--- a/validate.h
+++ b/validate.h
@@ -7,10 +7,13 @@ bool ValidateAll(bool thorough);
bool TestSettings();
bool TestOS_RNG();
bool TestAutoSeeded();
+
+#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
bool TestRDRAND();
bool TestRDSEED();
-bool ValidateBaseCode();
+#endif
+bool ValidateBaseCode();
bool ValidateCRC32();
bool ValidateAdler32();
bool ValidateMD2();
@@ -79,7 +82,19 @@ bool ValidateEC2N();
bool ValidateECDSA();
bool ValidateESIGN();
+#if !defined(NDEBUG)
+bool TestPolynomialMod2();
+#endif
+
+// Coverity findings
+template <class T, bool NON_NEGATIVE>
+T StringToValue(const std::string& str);
+template<>
+int StringToValue<int, true>(const std::string& str);
+
+// Functions that need a RNG; uses AES inf CFB mode with Seed.
CryptoPP::RandomNumberGenerator & GlobalRNG();
+
bool RunTestDataFile(const char *filename, const CryptoPP::NameValuePairs &overrideParameters=CryptoPP::g_nullNameValuePairs, bool thorough=true);
#endif
diff --git a/vmac.cpp b/vmac.cpp
index 249ea788..45c3d851 100644
--- a/vmac.cpp
+++ b/vmac.cpp
@@ -176,7 +176,7 @@ VMAC_Base::VHASH_Update_SSE2(const word64 *data, size_t blocksRemainingInWord64,
(
AS2( mov %%ebx, %0)
AS2( mov %1, %%ebx)
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
#else
#if _MSC_VER < 1300 || defined(__INTEL_COMPILER)
char isFirstBlock = m_isFirstBlock;
@@ -451,7 +451,7 @@ VMAC_Base::VHASH_Update_SSE2(const word64 *data, size_t blocksRemainingInWord64,
AS_POP_IF86( bp)
AS1( emms)
#ifdef __GNUC__
- ".att_syntax prefix;"
+ ATT_PREFIX
AS2( mov %0, %%ebx)
: "=m" (temp)
: "m" (L1KeyLength), "c" (blocksRemainingInWord64), "S" (data), "D" (nhK+tagPart*2), "d" (m_isFirstBlock), "a" (polyS+tagPart*4)
diff --git a/vmac.h b/vmac.h
index 2f9a8000..996457f8 100644
--- a/vmac.h
+++ b/vmac.h
@@ -11,7 +11,8 @@
NAMESPACE_BEGIN(CryptoPP)
-/// .
+//! \class VMAC_Base
+//! \brief Class specific methods used to operate the MAC.
class VMAC_Base : public IteratedHashBase<word64, MessageAuthenticationCode>
{
public:
@@ -44,6 +45,10 @@ protected:
void VHASH_Update_Template(const word64 *data, size_t blockRemainingInWord128);
void VHASH_Update(const word64 *data, size_t blocksRemainingInWord128);
+#if CRYPTOPP_DOXYGEN_PROCESSING
+ private: // hide from documentation
+#endif
+
CRYPTOPP_BLOCK_1(polyState, word64, 4*(m_is128+1))
CRYPTOPP_BLOCK_2(nhKey, word64, m_L1KeyLength/sizeof(word64) + 2*m_is128)
CRYPTOPP_BLOCK_3(data, byte, m_L1KeyLength)
@@ -56,7 +61,14 @@ protected:
int m_L1KeyLength;
};
-/// <a href="http://www.cryptolounge.org/wiki/VMAC">VMAC</a>
+//! \class VMAC
+//! \brief The VMAC message authentication code
+//! \details VMAC is a block cipher-based message authentication code algorithm
+//! using a universal hash proposed by Ted Krovetz and Wei Dai in April 2007. The
+//! algorithm was designed for high performance backed by a formal analysis.
+//! \tparam T_BlockCipher block cipher
+//! \tparam T_DigestBitSize digest size, in bits
+//! \sa <a href="http://www.cryptolounge.org/wiki/VMAC">VMAC</a> at the Crypto Lounge.
template <class T_BlockCipher, int T_DigestBitSize = 128>
class VMAC : public SimpleKeyingInterfaceImpl<VMAC_Base, SameKeyLengthAs<T_BlockCipher, SimpleKeyingInterface::UNIQUE_IV, T_BlockCipher::BLOCKSIZE> >
{
diff --git a/wait.cpp b/wait.cpp
index 6306ae40..43a6c275 100644
--- a/wait.cpp
+++ b/wait.cpp
@@ -32,7 +32,7 @@ unsigned int WaitObjectContainer::MaxWaitObjects()
}
WaitObjectContainer::WaitObjectContainer(WaitObjectsTracer* tracer)
- : m_tracer(tracer), m_eventTimer(Timer::MILLISECONDS)
+ : m_tracer(tracer), m_eventTimer(Timer::MILLISECONDS), m_lastResult(0)
, m_sameResultCount(0), m_noWaitTimer(Timer::MILLISECONDS)
{
Clear();
diff --git a/wake.cpp b/wake.cpp
index ac270ab3..4a9bc340 100644
--- a/wake.cpp
+++ b/wake.cpp
@@ -7,11 +7,13 @@
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void WAKE_TestInstantiations()
{
WAKE_OFB<>::Encryption x2;
WAKE_OFB<>::Decryption x4;
}
+#endif
inline word32 WAKE_Base::M(word32 x, word32 y)
{
diff --git a/whrlpool.cpp b/whrlpool.cpp
index bf20aee4..087966fa 100644
--- a/whrlpool.cpp
+++ b/whrlpool.cpp
@@ -74,12 +74,23 @@
#include "misc.h"
#include "cpu.h"
+// "Inline assembly operands don't work with .intel_syntax",
+// http://llvm.org/bugs/show_bug.cgi?id=24232
+#if defined(CRYPTOPP_DISABLE_INTEL_ASM)
+# undef CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
+# undef CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
+# define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0
+# define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 0
+#endif
+
NAMESPACE_BEGIN(CryptoPP)
+#if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
void Whirlpool_TestInstantiations()
{
Whirlpool x;
}
+#endif
void Whirlpool::InitState(HashWordType *state)
{
@@ -407,7 +418,7 @@ void Whirlpool::Transform(word64 *digest, const word64 *block)
#endif
__asm__ __volatile__
(
- ".intel_syntax noprefix;"
+ INTEL_NOPREFIX
AS_PUSH_IF86( bx)
AS2( mov AS_REG_6, WORD_REG(ax))
#else
@@ -579,7 +590,7 @@ void Whirlpool::Transform(word64 *digest, const word64 *block)
AS_POP_IF86( bx)
#endif
#ifdef __GNUC__
- ".att_syntax prefix;"
+ ATT_PREFIX
:
: "a" (Whirlpool_C), "c" (digest), "d" (block)
#if CRYPTOPP_BOOL_X64
@@ -656,8 +667,9 @@ void Whirlpool::Transform(word64 *digest, const word64 *block)
int r=0;
while (true)
{
- word64 w0, w1, w2, w3, w4, w5, w6, w7; // temporary storage
- word32 t;
+ // Added initialization due to Coverity findings.
+ word64 w0=0, w1=0, w2=0, w3=0, w4=0, w5=0, w6=0, w7=0;
+ word32 t=0;
KSL(0, 4, 3, 2, 1, 0)
KSL(0, 0, 7, 6, 5, 4)
diff --git a/xtr.cpp b/xtr.cpp
index 897f96e0..31d76028 100644
--- a/xtr.cpp
+++ b/xtr.cpp
@@ -5,6 +5,7 @@
#include "xtr.h"
#include "nbtheory.h"
#include "integer.h"
+#include "modarith.h"
#include "algebra.cpp"
NAMESPACE_BEGIN(CryptoPP)
diff --git a/xtrcrypt.cpp b/xtrcrypt.cpp
index b06d839f..9f60a951 100644
--- a/xtrcrypt.cpp
+++ b/xtrcrypt.cpp
@@ -1,11 +1,13 @@
// xtrcrypt.cpp - written and placed in the public domain by Wei Dai
#include "pch.h"
+
+#include "asn.h"
+#include "integer.h"
#include "xtrcrypt.h"
#include "nbtheory.h"
-#include "integer.h"
+#include "modarith.h"
#include "argnames.h"
-#include "asn.h"
NAMESPACE_BEGIN(CryptoPP)
diff --git a/zdeflate.cpp b/zdeflate.cpp
index a9e0405a..fea6025c 100644
--- a/zdeflate.cpp
+++ b/zdeflate.cpp
@@ -7,19 +7,14 @@
#include "pch.h"
#include "zdeflate.h"
+#include "stdcpp.h"
#include "misc.h"
-#include <functional>
-
-#if _MSC_VER >= 1600
-// for make_unchecked_array_iterator
-#include <iterator>
-#endif
-
NAMESPACE_BEGIN(CryptoPP)
LowFirstBitWriter::LowFirstBitWriter(BufferedTransformation *attachment)
- : Filter(attachment), m_counting(false), m_buffer(0), m_bitsBuffered(0), m_bytesBuffered(0)
+ : Filter(attachment), m_counting(false), m_bitCount(0), m_buffer(0)
+ , m_bitsBuffered(0), m_bytesBuffered(0)
{
}
@@ -94,6 +89,12 @@ HuffmanEncoder::HuffmanEncoder(const unsigned int *codeBits, unsigned int nCodes
struct HuffmanNode
{
+ // Coverity finding on uninitalized 'symbol' member
+ HuffmanNode()
+ : symbol(0), parent(0) {}
+ HuffmanNode(const HuffmanNode& rhs)
+ : symbol(rhs.symbol), parent(rhs.parent) {}
+
size_t symbol;
union {size_t parent; unsigned depth, freq;};
};
@@ -148,7 +149,6 @@ void HuffmanEncoder::GenerateCodeLengths(unsigned int *codeBits, unsigned int ma
std::fill(blCount.begin(), blCount.end(), 0);
for (i=treeBegin; i<nCodes; i++)
{
- // Valgrind finding: unintialized read. Expanding the expression clears it.
const size_t n = tree[i].parent;
const size_t depth = STDMIN(maxCodeBits, tree[n].depth + 1);
blCount[depth]++;
@@ -264,7 +264,9 @@ void Deflator::IsolatedInitialize(const NameValuePairs &parameters)
m_matchBuffer.New(DSIZE/2);
Reset(true);
- SetDeflateLevel(parameters.GetIntValueWithDefault("DeflateLevel", DEFAULT_DEFLATE_LEVEL));
+ const int deflateLevel = parameters.GetIntValueWithDefault("DeflateLevel", DEFAULT_DEFLATE_LEVEL);
+ assert(deflateLevel >= MIN_DEFLATE_LEVEL /*0*/ && deflateLevel <= MAX_DEFLATE_LEVEL /*9*/);
+ SetDeflateLevel(deflateLevel);
bool detectUncompressible = parameters.GetValueWithDefault("DetectUncompressible", true);
m_compressibleDeflateLevel = detectUncompressible ? m_deflateLevel : 0;
}
@@ -345,10 +347,13 @@ unsigned int Deflator::FillWindow(const byte *str, size_t length)
assert(m_blockStart >= DSIZE);
m_blockStart -= DSIZE;
- unsigned int i;
+ // These are set to the same value in IsolatedInitialize(). If they
+ // are the same, then we can clear a Coverity false alarm.
+ assert(DSIZE == HSIZE);
+ unsigned int i;
for (i=0; i<HSIZE; i++)
- m_head[i] = SaturatingSubtract(m_head[i], DSIZE);
+ m_head[i] = SaturatingSubtract(m_head[i], HSIZE); // was DSIZE???
for (i=0; i<DSIZE; i++)
m_prev[i] = SaturatingSubtract(m_prev[i], DSIZE);
@@ -574,12 +579,16 @@ void Deflator::MatchFound(unsigned int distance, unsigned int length)
283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285};
- static const unsigned int lengthBases[] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258};
+ static const unsigned int lengthBases[] =
+ {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,
+ 227,258};
static const unsigned int distanceBases[30] =
- {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
+ {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,
+ 4097,6145,8193,12289,16385,24577};
+ assert(m_matchBufferEnd < m_matchBuffer.size());
EncodedMatch &m = m_matchBuffer[m_matchBufferEnd++];
- assert(length >= 3);
+ assert(length >= 3 && length < COUNTOF(lengthCodes));
unsigned int lengthCode = lengthCodes[length-3];
m.literalCode = lengthCode;
m.literalExtra = length - lengthBases[lengthCode-257];
diff --git a/zinflate.cpp b/zinflate.cpp
index 7fba7d3b..b0117ce9 100644
--- a/zinflate.cpp
+++ b/zinflate.cpp
@@ -113,9 +113,11 @@ void HuffmanDecoder::Initialize(const unsigned int *codeBits, unsigned int nCode
nextCode[i] = code;
}
- if (code > (1 << m_maxCodeBits) - blCount[m_maxCodeBits])
+ // MAX_CODE_BITS is 32, m_maxCodeBits may be smaller.
+ const unsigned long long shiftedMaxCode = (1ULL << m_maxCodeBits);
+ if (code > shiftedMaxCode - blCount[m_maxCodeBits])
throw Err("codes oversubscribed");
- else if (m_maxCodeBits != 1 && code < (1 << m_maxCodeBits) - blCount[m_maxCodeBits])
+ else if (m_maxCodeBits != 1 && code < shiftedMaxCode - blCount[m_maxCodeBits])
throw Err("codes incomplete");
// compute a vector of <code, length, value> triples sorted by code
@@ -141,8 +143,10 @@ void HuffmanDecoder::Initialize(const unsigned int *codeBits, unsigned int nCode
m_normalizedCacheMask = NormalizeCode(m_cacheMask, m_cacheBits);
assert(m_normalizedCacheMask == BitReverse(m_cacheMask));
- if (m_cache.size() != size_t(1) << m_cacheBits)
- m_cache.resize(1 << m_cacheBits);
+ const unsigned long long shiftedCache = (1ULL << m_cacheBits);
+ assert(shiftedCache <= SIZE_MAX);
+ if (m_cache.size() != shiftedCache)
+ m_cache.resize((size_t)shiftedCache);
for (i=0; i<m_cache.size(); i++)
m_cache[i].type = 0;
@@ -204,7 +208,9 @@ inline unsigned int HuffmanDecoder::Decode(code_t code, /* out */ value_t &value
bool HuffmanDecoder::Decode(LowFirstBitReader &reader, value_t &value) const
{
- reader.FillBuffer(m_maxCodeBits);
+ bool result = reader.FillBuffer(m_maxCodeBits);
+ if(!result) return false;
+
unsigned int codeBits = Decode(reader.PeekBuffer(), value);
if (codeBits > reader.BitsBuffered())
return false;
@@ -216,7 +222,9 @@ bool HuffmanDecoder::Decode(LowFirstBitReader &reader, value_t &value) const
Inflator::Inflator(BufferedTransformation *attachment, bool repeat, int propagation)
: AutoSignaling<Filter>(propagation)
- , m_state(PRE_STREAM), m_repeat(repeat), m_reader(m_inQueue)
+ , m_state(PRE_STREAM), m_repeat(repeat), m_eof(0), m_wrappedAround(0)
+ , m_blockType(0xff), m_storedLen(0xffff), m_nextDecode(), m_literal(0)
+ , m_distance(0), m_reader(m_inQueue), m_current(0), m_lastFlush(0)
{
Detach(attachment);
}
@@ -552,6 +560,9 @@ bool Inflator::DecodeBody()
OutputPast(m_literal, m_distance);
}
}
+ break;
+ default:
+ assert(0);
}
}
if (blockEnd)
diff --git a/zinflate.h b/zinflate.h
index a14f83c9..8c08ed08 100644
--- a/zinflate.h
+++ b/zinflate.h
@@ -2,9 +2,9 @@
#define CRYPTOPP_ZINFLATE_H
#include "cryptlib.h"
-#include "filters.h"
#include "secblock.h"
-#include <vector>
+#include "filters.h"
+#include "stdcpp.h"
NAMESPACE_BEGIN(CryptoPP)
@@ -14,7 +14,6 @@ class LowFirstBitReader
public:
LowFirstBitReader(BufferedTransformation &store)
: m_store(store), m_buffer(0), m_bitsBuffered(0) {}
-// unsigned long BitsLeft() const {return m_store.MaxRetrievable() * 8 + m_bitsBuffered;}
unsigned int BitsBuffered() const {return m_bitsBuffered;}
unsigned long PeekBuffer() const {return m_buffer;}
bool FillBuffer(unsigned int length);
@@ -40,8 +39,10 @@ public:
class Err : public Exception {public: Err(const std::string &what) : Exception(INVALID_DATA_FORMAT, "HuffmanDecoder: " + what) {}};
- HuffmanDecoder() {}
- HuffmanDecoder(const unsigned int *codeBitLengths, unsigned int nCodes) {Initialize(codeBitLengths, nCodes);}
+ HuffmanDecoder() : m_maxCodeBits(0), m_cacheBits(0), m_cacheMask(0), m_normalizedCacheMask(0) {}
+ HuffmanDecoder(const unsigned int *codeBitLengths, unsigned int nCodes)
+ : m_maxCodeBits(0), m_cacheBits(0), m_cacheMask(0), m_normalizedCacheMask(0)
+ {Initialize(codeBitLengths, nCodes);}
void Initialize(const unsigned int *codeBitLengths, unsigned int nCodes);
unsigned int Decode(code_t code, /* out */ value_t &value) const;
@@ -96,9 +97,10 @@ public:
class UnexpectedEndErr : public Err {public: UnexpectedEndErr() : Err(INVALID_DATA_FORMAT, "Inflator: unexpected end of compressed block") {}};
class BadBlockErr : public Err {public: BadBlockErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in compressed block") {}};
- /*! \param repeat decompress multiple compressed streams in series
- \param autoSignalPropagation 0 to turn off MessageEnd signal
- */
+ //! \brief RFC 1951 Decompressor
+ //! \param attachment the filter's attached transformation
+ //! \param repeat decompress multiple compressed streams in series
+ //! \param autoSignalPropagation 0 to turn off MessageEnd signal
Inflator(BufferedTransformation *attachment = NULL, bool repeat = false, int autoSignalPropagation = -1);
void IsolatedInitialize(const NameValuePairs &parameters);
diff --git a/zlib.cpp b/zlib.cpp
index fd310858..bba4dc8e 100644
--- a/zlib.cpp
+++ b/zlib.cpp
@@ -49,7 +49,7 @@ unsigned int ZlibCompressor::GetCompressionLevel() const
// *************************************************************
ZlibDecompressor::ZlibDecompressor(BufferedTransformation *attachment, bool repeat, int propagation)
- : Inflator(attachment, repeat, propagation)
+ : Inflator(attachment, repeat, propagation), m_log2WindowSize(0)
{
}