Currently, DEFAUT_CHANNEL and AAD_CHANNEL are strings allocated in
cryptlib.cpp and subject to all the translation unit rules regarding static
initialization. Its been pain point for me in the past, and I think Bizyaev
is experiencing it now.
I'd like to propose two subtle changes to help manage that initialization
issue without breaking user code. First is a static inline function that
creates a local static to force early initialization:
//***** cryptlib.h *****//
//! the default channel for BufferedTransformation, equal to the empty
string.
// New code should call the DefaultChannel() function.
extern CRYPTOPP_DLL const std::string DEFAULT_CHANNEL;
inline static const std::string& DefaultChannel() {
static const std::string ch = "";
return ch;
}
//! channel for additional authenticated data, equal to the string "AAD".
// New code should call AadChannel() function.
extern CRYPTOPP_DLL const std::string AAD_CHANNEL;
inline static const std::string& AadChannel() {
static const std::string ch = "AAD";
return ch;
}
The multiple copies should be folded into one by the optimizer (if multiple
copies are present).
And second:
//***** cryptlib.cpp *****//
const std::string DEFAULT_CHANNEL = DefaultChannel();
const std::string AAD_CHANNEL = AadChannel();
Finally, I'd like to try and get this into 5.6.3 since its one of those
annoying and hard to track down issues.
A patch for testing is below (and attached). It only modified
cryptlib.{h|cpp}, *test.cpp, and validat?.cpp.
Any comments or objections?
Jeff
********************
$ cat channels.diff
diff --git a/cryptlib.cpp b/cryptlib.cpp
index 43df08b..2ded98c 100644
--- a/cryptlib.cpp
+++ b/cryptlib.cpp
@@ -32,9 +32,8 @@ CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8);
CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word));
#endif
-const std::string DEFAULT_CHANNEL;
-const std::string AAD_CHANNEL = "AAD";
-const std::string &BufferedTransformation::NULL_CHANNEL = DEFAULT_CHANNEL;
+const std::string DEFAULT_CHANNEL = DefaultChannel();
+const std::string AAD_CHANNEL = AadChannel();
class NullNameValuePairs : public NameValuePairs
{
diff --git a/cryptlib.h b/cryptlib.h
index 207b1e6..dd52511 100644
--- a/cryptlib.h
+++ b/cryptlib.h
@@ -768,11 +768,21 @@ public:
bool Wait(unsigned long milliseconds, CallStack const& callStack);
};
-//! the default channel for BufferedTransformation, equal to the empty
std::string
+//! the default channel for BufferedTransformation, equal to the empty
string.
+// New code should call the DefaultChannel() function.
extern CRYPTOPP_DLL const std::string DEFAULT_CHANNEL;
+inline static const std::string& DefaultChannel() {
+ static const std::string ch = "";
+ return ch;
+}
-//! channel for additional authenticated data, equal to "AAD"
+//! channel for additional authenticated data, equal to the string "AAD".
+// New code should call AadChannel() function.
extern CRYPTOPP_DLL const std::string AAD_CHANNEL;
+inline static const std::string& AadChannel() {
+ static const std::string ch = "AAD";
+ return ch;
+}
//! interface for buffered transformations
@@ -803,8 +813,6 @@ extern CRYPTOPP_DLL const std::string AAD_CHANNEL;
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : public
Algorithm, public Waitable
{
public:
- // placed up here for CW8
- static const std::string &NULL_CHANNEL; // same as DEFAULT_CHANNEL,
for backwards compatibility
BufferedTransformation() : Algorithm(false) {}
@@ -929,18 +937,18 @@ public:
size_t PeekWord32(word32 &value, ByteOrder
order=BIG_ENDIAN_ORDER) const;
//! move transferMax bytes of the buffered output to target
as input
- lword TransferTo(BufferedTransformation &target, lword
transferMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL)
+ lword TransferTo(BufferedTransformation &target, lword
transferMax=LWORD_MAX, const std::string &channel=DefaultChannel())
{TransferTo2(target, transferMax, channel); return
transferMax;}
//! discard skipMax bytes from the output buffer
virtual lword Skip(lword skipMax=LWORD_MAX);
//! copy copyMax bytes of the buffered output to target as
input
- lword CopyTo(BufferedTransformation &target, lword
copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const
+ lword CopyTo(BufferedTransformation &target, lword
copyMax=LWORD_MAX, const std::string &channel=DefaultChannel()) const
{return CopyRangeTo(target, 0, copyMax, channel);}
//! copy copyMax bytes of the buffered output, starting at
position (relative to current position), to target as input
- lword CopyRangeTo(BufferedTransformation &target, lword
position, lword copyMax=LWORD_MAX, const std::string
&channel=DEFAULT_CHANNEL) const
+ lword CopyRangeTo(BufferedTransformation &target, lword
position, lword copyMax=LWORD_MAX, const std::string
&channel=DefaultChannel()) const
{lword i = position; CopyRangeTo2(target, i,
i+copyMax, channel); return i-position;}
#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
@@ -965,18 +973,18 @@ public:
//! skip count number of messages
virtual unsigned int SkipMessages(unsigned int
count=UINT_MAX);
//!
- unsigned int TransferMessagesTo(BufferedTransformation
&target, unsigned int count=UINT_MAX, const std::string
&channel=DEFAULT_CHANNEL)
+ unsigned int TransferMessagesTo(BufferedTransformation
&target, unsigned int count=UINT_MAX, const std::string
&channel=DefaultChannel())
{TransferMessagesTo2(target, count, channel);
return count;}
//!
- unsigned int CopyMessagesTo(BufferedTransformation &target,
unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL)
const;
+ unsigned int CopyMessagesTo(BufferedTransformation &target,
unsigned int count=UINT_MAX, const std::string &channel=DefaultChannel())
const;
//!
virtual void SkipAll();
//!
- void TransferAllTo(BufferedTransformation &target, const
std::string &channel=DEFAULT_CHANNEL)
+ void TransferAllTo(BufferedTransformation &target, const
std::string &channel=DefaultChannel())
{TransferAllTo2(target, channel);}
//!
- void CopyAllTo(BufferedTransformation &target, const
std::string &channel=DEFAULT_CHANNEL) const;
+ void CopyAllTo(BufferedTransformation &target, const
std::string &channel=DefaultChannel()) const;
virtual bool GetNextMessageSeries() {return false;}
virtual unsigned int NumberOfMessagesInThisSeries() const
{return NumberOfMessages();}
@@ -986,13 +994,13 @@ public:
//! \name NON-BLOCKING TRANSFER OF OUTPUT
//@{
//! upon return, byteCount contains number of bytes that
have finished being transfered, and returns the number of bytes left in the
current transfer block
- virtual size_t TransferTo2(BufferedTransformation &target,
lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool
blocking=true) =0;
+ virtual size_t TransferTo2(BufferedTransformation &target,
lword &byteCount, const std::string &channel=DefaultChannel(), 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
- virtual size_t CopyRangeTo2(BufferedTransformation &target,
lword &begin, lword end=LWORD_MAX, const std::string
&channel=DEFAULT_CHANNEL, bool blocking=true) const =0;
+ virtual size_t CopyRangeTo2(BufferedTransformation &target,
lword &begin, lword end=LWORD_MAX, const std::string
&channel=DefaultChannel(), 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
- size_t TransferMessagesTo2(BufferedTransformation &target,
unsigned int &messageCount, const std::string &channel=DEFAULT_CHANNEL,
bool blocking=true);
+ size_t TransferMessagesTo2(BufferedTransformation &target,
unsigned int &messageCount, const std::string &channel=DefaultChannel(),
bool blocking=true);
//! returns the number of bytes left in the current
transfer block
- size_t TransferAllTo2(BufferedTransformation &target, const
std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
+ size_t TransferAllTo2(BufferedTransformation &target, const
std::string &channel=DefaultChannel(), bool blocking=true);
//@}
//! \name CHANNELS
diff --git a/datatest.cpp b/datatest.cpp
index d0f69c6..5595c4a 100644
--- a/datatest.cpp
+++ b/datatest.cpp
@@ -61,7 +61,7 @@ const std::string & GetRequiredDatum(const TestData
&data, const char *name)
return i->second;
}
-void RandomizedTransfer(BufferedTransformation &source,
BufferedTransformation &target, bool finish, const std::string
&channel=DEFAULT_CHANNEL)
+void RandomizedTransfer(BufferedTransformation &source,
BufferedTransformation &target, bool finish, const std::string
&channel=DefaultChannel())
{
while (source.MaxRetrievable() > (finish ? 0 : 4096))
{
@@ -492,16 +492,16 @@ void TestAuthenticatedSymmetricCipher(TestData &v,
const NameValuePairs &overrid
if (macAtBegin)
RandomizedTransfer(sm, df, true);
- sh.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
+ sh.CopyTo(df, LWORD_MAX, AadChannel());
RandomizedTransfer(sc, df, true);
- sf.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
+ sf.CopyTo(df, LWORD_MAX, AadChannel());
if (!macAtBegin)
RandomizedTransfer(sm, df, true);
df.MessageEnd();
- RandomizedTransfer(sh, ef, true, AAD_CHANNEL);
+ RandomizedTransfer(sh, ef, true, AadChannel());
RandomizedTransfer(sp, ef, true);
- RandomizedTransfer(sf, ef, true, AAD_CHANNEL);
+ RandomizedTransfer(sf, ef, true, AadChannel());
ef.MessageEnd();
if (test == "Encrypt" && encrypted != ciphertext+mac)
diff --git a/gfpcrypt.h b/gfpcrypt.h
index 0590254..1537b31 100644
--- a/gfpcrypt.h
+++ b/gfpcrypt.h
@@ -454,7 +454,7 @@ public:
if (DHAES_MODE)
{
byte L[8] = {0,0,0,0};
- PutWord(false, BIG_ENDIAN_ORDER, L+4,
word32(encodingParameters.size()));
+ PutWord(false, BIG_ENDIAN_ORDER, L, word64(8 *
encodingParameters.size()));
mac.Update(L, 8);
}
mac.Final(ciphertext + plaintextLength);
@@ -483,7 +483,7 @@ public:
if (DHAES_MODE)
{
byte L[8] = {0,0,0,0};
- PutWord(false, BIG_ENDIAN_ORDER, L+4,
word32(encodingParameters.size()));
+ PutWord(false, BIG_ENDIAN_ORDER, L, word64(8 *
encodingParameters.size()));
mac.Update(L, 8);
}
if (!mac.Verify(ciphertext + plaintextLength))
diff --git a/test.cpp b/test.cpp
index b357119..7ad18d3 100644
--- a/test.cpp
+++ b/test.cpp
@@ -621,7 +621,7 @@ void SecretShareFile(int threshold, int nShares, const
char *filename, const cha
channel = WordToString<word32>(i);
fileSinks[i]->Put((byte *)channel.data(), 4);
- channelSwitch->AddRoute(channel, *fileSinks[i],
DEFAULT_CHANNEL);
+ channelSwitch->AddRoute(channel, *fileSinks[i],
DefaultChannel());
}
source.PumpAll();
@@ -671,7 +671,7 @@ void InformationDisperseFile(int threshold, int
nShares, const char *filename)
channel = WordToString<word32>(i);
fileSinks[i]->Put((byte *)channel.data(), 4);
- channelSwitch->AddRoute(channel, *fileSinks[i],
DEFAULT_CHANNEL);
+ channelSwitch->AddRoute(channel, *fileSinks[i],
DefaultChannel());
}
source.PumpAll();
--
--
You received this message because you are subscribed to the "Crypto++ Users"
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at
http://www.cryptopp.com.
---
You received this message because you are subscribed to the Google Groups
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/cryptlib.cpp b/cryptlib.cpp
index 43df08b..2ded98c 100644
--- a/cryptlib.cpp
+++ b/cryptlib.cpp
@@ -32,9 +32,8 @@ CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8);
CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word));
#endif
-const std::string DEFAULT_CHANNEL;
-const std::string AAD_CHANNEL = "AAD";
-const std::string &BufferedTransformation::NULL_CHANNEL = DEFAULT_CHANNEL;
+const std::string DEFAULT_CHANNEL = DefaultChannel();
+const std::string AAD_CHANNEL = AadChannel();
class NullNameValuePairs : public NameValuePairs
{
diff --git a/cryptlib.h b/cryptlib.h
index 207b1e6..dd52511 100644
--- a/cryptlib.h
+++ b/cryptlib.h
@@ -768,11 +768,21 @@ public:
bool Wait(unsigned long milliseconds, CallStack const& callStack);
};
-//! the default channel for BufferedTransformation, equal to the empty std::string
+//! the default channel for BufferedTransformation, equal to the empty string.
+// New code should call the DefaultChannel() function.
extern CRYPTOPP_DLL const std::string DEFAULT_CHANNEL;
+inline static const std::string& DefaultChannel() {
+ static const std::string ch = "";
+ return ch;
+}
-//! channel for additional authenticated data, equal to "AAD"
+//! channel for additional authenticated data, equal to the string "AAD".
+// New code should call AadChannel() function.
extern CRYPTOPP_DLL const std::string AAD_CHANNEL;
+inline static const std::string& AadChannel() {
+ static const std::string ch = "AAD";
+ return ch;
+}
//! interface for buffered transformations
@@ -803,8 +813,6 @@ extern CRYPTOPP_DLL const std::string AAD_CHANNEL;
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : public Algorithm, public Waitable
{
public:
- // placed up here for CW8
- static const std::string &NULL_CHANNEL; // same as DEFAULT_CHANNEL, for backwards compatibility
BufferedTransformation() : Algorithm(false) {}
@@ -929,18 +937,18 @@ public:
size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
//! move transferMax bytes of the buffered output to target as input
- lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL)
+ lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=DefaultChannel())
{TransferTo2(target, transferMax, channel); return transferMax;}
//! discard skipMax bytes from the output buffer
virtual lword Skip(lword skipMax=LWORD_MAX);
//! copy copyMax bytes of the buffered output to target as input
- lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const
+ lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DefaultChannel()) const
{return CopyRangeTo(target, 0, copyMax, channel);}
//! copy copyMax bytes of the buffered output, starting at position (relative to current position), to target as input
- lword CopyRangeTo(BufferedTransformation &target, lword position, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const
+ lword CopyRangeTo(BufferedTransformation &target, lword position, lword copyMax=LWORD_MAX, const std::string &channel=DefaultChannel()) const
{lword i = position; CopyRangeTo2(target, i, i+copyMax, channel); return i-position;}
#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
@@ -965,18 +973,18 @@ public:
//! skip count number of messages
virtual unsigned int SkipMessages(unsigned int count=UINT_MAX);
//!
- unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL)
+ unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DefaultChannel())
{TransferMessagesTo2(target, count, channel); return count;}
//!
- unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const;
+ unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DefaultChannel()) const;
//!
virtual void SkipAll();
//!
- void TransferAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL)
+ void TransferAllTo(BufferedTransformation &target, const std::string &channel=DefaultChannel())
{TransferAllTo2(target, channel);}
//!
- void CopyAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) const;
+ void CopyAllTo(BufferedTransformation &target, const std::string &channel=DefaultChannel()) const;
virtual bool GetNextMessageSeries() {return false;}
virtual unsigned int NumberOfMessagesInThisSeries() const {return NumberOfMessages();}
@@ -986,13 +994,13 @@ public:
//! \name NON-BLOCKING TRANSFER OF OUTPUT
//@{
//! upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block
- virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) =0;
+ virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DefaultChannel(), 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
- virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const =0;
+ virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DefaultChannel(), 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
- size_t TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
+ size_t TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=DefaultChannel(), bool blocking=true);
//! returns the number of bytes left in the current transfer block
- size_t TransferAllTo2(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
+ size_t TransferAllTo2(BufferedTransformation &target, const std::string &channel=DefaultChannel(), bool blocking=true);
//@}
//! \name CHANNELS
diff --git a/datatest.cpp b/datatest.cpp
index d0f69c6..5595c4a 100644
--- a/datatest.cpp
+++ b/datatest.cpp
@@ -61,7 +61,7 @@ const std::string & GetRequiredDatum(const TestData &data, const char *name)
return i->second;
}
-void RandomizedTransfer(BufferedTransformation &source, BufferedTransformation &target, bool finish, const std::string &channel=DEFAULT_CHANNEL)
+void RandomizedTransfer(BufferedTransformation &source, BufferedTransformation &target, bool finish, const std::string &channel=DefaultChannel())
{
while (source.MaxRetrievable() > (finish ? 0 : 4096))
{
@@ -492,16 +492,16 @@ void TestAuthenticatedSymmetricCipher(TestData &v, const NameValuePairs &overrid
if (macAtBegin)
RandomizedTransfer(sm, df, true);
- sh.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
+ sh.CopyTo(df, LWORD_MAX, AadChannel());
RandomizedTransfer(sc, df, true);
- sf.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
+ sf.CopyTo(df, LWORD_MAX, AadChannel());
if (!macAtBegin)
RandomizedTransfer(sm, df, true);
df.MessageEnd();
- RandomizedTransfer(sh, ef, true, AAD_CHANNEL);
+ RandomizedTransfer(sh, ef, true, AadChannel());
RandomizedTransfer(sp, ef, true);
- RandomizedTransfer(sf, ef, true, AAD_CHANNEL);
+ RandomizedTransfer(sf, ef, true, AadChannel());
ef.MessageEnd();
if (test == "Encrypt" && encrypted != ciphertext+mac)
diff --git a/gfpcrypt.h b/gfpcrypt.h
index 0590254..1537b31 100644
--- a/gfpcrypt.h
+++ b/gfpcrypt.h
@@ -454,7 +454,7 @@ public:
if (DHAES_MODE)
{
byte L[8] = {0,0,0,0};
- PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
+ PutWord(false, BIG_ENDIAN_ORDER, L, word64(8 * encodingParameters.size()));
mac.Update(L, 8);
}
mac.Final(ciphertext + plaintextLength);
@@ -483,7 +483,7 @@ public:
if (DHAES_MODE)
{
byte L[8] = {0,0,0,0};
- PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
+ PutWord(false, BIG_ENDIAN_ORDER, L, word64(8 * encodingParameters.size()));
mac.Update(L, 8);
}
if (!mac.Verify(ciphertext + plaintextLength))
diff --git a/test.cpp b/test.cpp
index b357119..7ad18d3 100644
--- a/test.cpp
+++ b/test.cpp
@@ -621,7 +621,7 @@ void SecretShareFile(int threshold, int nShares, const char *filename, const cha
channel = WordToString<word32>(i);
fileSinks[i]->Put((byte *)channel.data(), 4);
- channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
+ channelSwitch->AddRoute(channel, *fileSinks[i], DefaultChannel());
}
source.PumpAll();
@@ -671,7 +671,7 @@ void InformationDisperseFile(int threshold, int nShares, const char *filename)
channel = WordToString<word32>(i);
fileSinks[i]->Put((byte *)channel.data(), 4);
- channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
+ channelSwitch->AddRoute(channel, *fileSinks[i], DefaultChannel());
}
source.PumpAll();