prevent the 'static initialization order fiasco' for crypto constants

This commit is contained in:
cpubug 2014-06-18 22:30:53 +04:00
parent 170da1c903
commit fbaf09ff2b
10 changed files with 58 additions and 35 deletions

View file

@ -5,7 +5,7 @@ namespace i2p
{ {
namespace crypto namespace crypto
{ {
const uint8_t elgp_[256]= static const uint8_t elgp_[256]=
{ {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
@ -25,10 +25,19 @@ namespace crypto
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
}; };
const CryptoPP::Integer elgp (elgp_, 256); const CryptoPP::Integer& elgp()
const CryptoPP::Integer elgg (2); {
static CryptoPP::Integer value(elgp_, 256);
return value;
}
const uint8_t dsap_[128]= const CryptoPP::Integer& elgg()
{
static CryptoPP::Integer value(2);
return value;
}
static const uint8_t dsap_[128]=
{ {
0x9c, 0x05, 0xb2, 0xaa, 0x96, 0x0d, 0x9b, 0x97, 0xb8, 0x93, 0x19, 0x63, 0xc9, 0xcc, 0x9e, 0x8c, 0x9c, 0x05, 0xb2, 0xaa, 0x96, 0x0d, 0x9b, 0x97, 0xb8, 0x93, 0x19, 0x63, 0xc9, 0xcc, 0x9e, 0x8c,
0x30, 0x26, 0xe9, 0xb8, 0xed, 0x92, 0xfa, 0xd0, 0xa6, 0x9c, 0xc8, 0x86, 0xd5, 0xbf, 0x80, 0x15, 0x30, 0x26, 0xe9, 0xb8, 0xed, 0x92, 0xfa, 0xd0, 0xa6, 0x9c, 0xc8, 0x86, 0xd5, 0xbf, 0x80, 0x15,
@ -40,13 +49,13 @@ namespace crypto
0x28, 0x5d, 0x4c, 0xf2, 0x95, 0x38, 0xd9, 0xe3, 0xb6, 0x05, 0x1f, 0x5b, 0x22, 0xcc, 0x1c, 0x93 0x28, 0x5d, 0x4c, 0xf2, 0x95, 0x38, 0xd9, 0xe3, 0xb6, 0x05, 0x1f, 0x5b, 0x22, 0xcc, 0x1c, 0x93
}; };
const uint8_t dsaq_[20]= static const uint8_t dsaq_[20]=
{ {
0xa5, 0xdf, 0xc2, 0x8f, 0xef, 0x4c, 0xa1, 0xe2, 0x86, 0x74, 0x4c, 0xd8, 0xee, 0xd9, 0xd2, 0x9d, 0xa5, 0xdf, 0xc2, 0x8f, 0xef, 0x4c, 0xa1, 0xe2, 0x86, 0x74, 0x4c, 0xd8, 0xee, 0xd9, 0xd2, 0x9d,
0x68, 0x40, 0x46, 0xb7 0x68, 0x40, 0x46, 0xb7
}; };
const uint8_t dsag_[128]= static const uint8_t dsag_[128]=
{ {
0x0c, 0x1f, 0x4d, 0x27, 0xd4, 0x00, 0x93, 0xb4, 0x29, 0xe9, 0x62, 0xd7, 0x22, 0x38, 0x24, 0xe0, 0x0c, 0x1f, 0x4d, 0x27, 0xd4, 0x00, 0x93, 0xb4, 0x29, 0xe9, 0x62, 0xd7, 0x22, 0x38, 0x24, 0xe0,
0xbb, 0xc4, 0x7e, 0x7c, 0x83, 0x2a, 0x39, 0x23, 0x6f, 0xc6, 0x83, 0xaf, 0x84, 0x88, 0x95, 0x81, 0xbb, 0xc4, 0x7e, 0x7c, 0x83, 0x2a, 0x39, 0x23, 0x6f, 0xc6, 0x83, 0xaf, 0x84, 0x88, 0x95, 0x81,
@ -58,9 +67,24 @@ namespace crypto
0xb3, 0xdb, 0xb1, 0x4a, 0x90, 0x5e, 0x7b, 0x2b, 0x3e, 0x93, 0xbe, 0x47, 0x08, 0xcb, 0xcc, 0x82 0xb3, 0xdb, 0xb1, 0x4a, 0x90, 0x5e, 0x7b, 0x2b, 0x3e, 0x93, 0xbe, 0x47, 0x08, 0xcb, 0xcc, 0x82
}; };
const CryptoPP::Integer dsap (dsap_, 128); const CryptoPP::Integer& dsap()
const CryptoPP::Integer dsaq (dsaq_, 20); {
const CryptoPP::Integer dsag (dsag_, 128); static CryptoPP::Integer value(dsap_, 128);
return value;
}
const CryptoPP::Integer& dsaq()
{
static CryptoPP::Integer value(dsaq_, 20);
return value;
}
const CryptoPP::Integer& dsag()
{
static CryptoPP::Integer value(dsag_, 128);
return value;
}
} }
} }

View file

@ -8,14 +8,13 @@ namespace i2p
namespace crypto namespace crypto
{ {
// DH // DH
extern const CryptoPP::Integer elgp; const CryptoPP::Integer& elgp();
extern const CryptoPP::Integer elgg; const CryptoPP::Integer& elgg();
// DSA // DSA
extern const CryptoPP::Integer dsap; const CryptoPP::Integer& dsap();
extern const CryptoPP::Integer dsaq; const CryptoPP::Integer& dsaq();
extern const CryptoPP::Integer dsag; const CryptoPP::Integer& dsag();
} }
} }

View file

@ -18,8 +18,8 @@ namespace crypto
public: public:
ElGamalEncryption (const uint8_t * key): ElGamalEncryption (const uint8_t * key):
y (key, 256), k (rnd, CryptoPP::Integer::One(), elgp-1), y (key, 256), k (rnd, CryptoPP::Integer::One(), elgp() - 1),
a (a_exp_b_mod_c (elgg, k, elgp)), b1 (a_exp_b_mod_c (y, k, elgp)) a (a_exp_b_mod_c (elgg(), k, elgp())), b1 (a_exp_b_mod_c (y, k, elgp()))
{ {
} }
@ -30,7 +30,7 @@ namespace crypto
m[0] = 0xFF; m[0] = 0xFF;
memcpy (m+33, data, len); memcpy (m+33, data, len);
CryptoPP::SHA256().CalculateDigest(m+1, m+33, 222); CryptoPP::SHA256().CalculateDigest(m+1, m+33, 222);
CryptoPP::Integer b (a_times_b_mod_c (b1, CryptoPP::Integer (m, 255), elgp)); CryptoPP::Integer b (a_times_b_mod_c (b1, CryptoPP::Integer (m, 255), elgp()));
// copy a and b // copy a and b
if (zeroPadding) if (zeroPadding)
@ -60,7 +60,7 @@ namespace crypto
CryptoPP::Integer x(key, 256), a(zeroPadding? encrypted +1 : encrypted, 256), CryptoPP::Integer x(key, 256), a(zeroPadding? encrypted +1 : encrypted, 256),
b(zeroPadding? encrypted + 258 :encrypted + 256, 256); b(zeroPadding? encrypted + 258 :encrypted + 256, 256);
uint8_t m[255], hash[32]; uint8_t m[255], hash[32];
a_times_b_mod_c (b, a_exp_b_mod_c (a, elgp - x - 1, elgp), elgp).Encode (m, 255); a_times_b_mod_c (b, a_exp_b_mod_c (a, elgp() - x - 1, elgp()), elgp()).Encode (m, 255);
CryptoPP::SHA256().CalculateDigest(hash, m+33, 222); CryptoPP::SHA256().CalculateDigest(hash, m+33, 222);
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
if (hash[i] != m[i+1]) if (hash[i] != m[i+1])

View file

@ -52,13 +52,13 @@ namespace data
CryptoPP::AutoSeededRandomPool rnd; CryptoPP::AutoSeededRandomPool rnd;
// encryption // encryption
CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg); CryptoPP::DH dh (i2p::crypto::elgp(), i2p::crypto::elgg());
dh.GenerateKeyPair(rnd, keys.privateKey, keys.publicKey); dh.GenerateKeyPair(rnd, keys.privateKey, keys.publicKey);
// signing // signing
CryptoPP::DSA::PrivateKey privateKey; CryptoPP::DSA::PrivateKey privateKey;
CryptoPP::DSA::PublicKey publicKey; CryptoPP::DSA::PublicKey publicKey;
privateKey.Initialize (rnd, i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag); privateKey.Initialize (rnd, i2p::crypto::dsap(), i2p::crypto::dsaq(), i2p::crypto::dsag());
privateKey.MakePublicKey (publicKey); privateKey.MakePublicKey (publicKey);
privateKey.GetPrivateExponent ().Encode (keys.signingPrivateKey, 20); privateKey.GetPrivateExponent ().Encode (keys.signingPrivateKey, 20);
publicKey.GetPublicElement ().Encode (keys.signingKey, 128); publicKey.GetPublicElement ().Encode (keys.signingKey, 128);
@ -70,7 +70,7 @@ namespace data
{ {
if (!keys) return; if (!keys) return;
CryptoPP::AutoSeededRandomPool rnd; CryptoPP::AutoSeededRandomPool rnd;
CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg); CryptoPP::DH dh (i2p::crypto::elgp(), i2p::crypto::elgg());
dh.GenerateKeyPair(rnd, keys->privateKey, keys->publicKey); dh.GenerateKeyPair(rnd, keys->privateKey, keys->publicKey);
} }

View file

@ -50,7 +50,7 @@ namespace data
// verify // verify
CryptoPP::DSA::PublicKey pubKey; CryptoPP::DSA::PublicKey pubKey;
pubKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, pubKey.Initialize (i2p::crypto::dsap(), i2p::crypto::dsaq(), i2p::crypto::dsag(),
CryptoPP::Integer (m_Identity.signingKey, 128)); CryptoPP::Integer (m_Identity.signingKey, 128));
CryptoPP::DSA::Verifier verifier (pubKey); CryptoPP::DSA::Verifier verifier (pubKey);
if (!verifier.VerifyMessage (buf, leases - buf, leases, 40)) if (!verifier.VerifyMessage (buf, leases - buf, leases, 40))

View file

@ -33,7 +33,7 @@ namespace ntcp
void NTCPSession::CreateAESKey (uint8_t * pubKey, uint8_t * aesKey) void NTCPSession::CreateAESKey (uint8_t * pubKey, uint8_t * aesKey)
{ {
CryptoPP::DH dh (elgp, elgg); CryptoPP::DH dh (elgp(), elgg());
uint8_t sharedKey[256]; uint8_t sharedKey[256];
if (!dh.Agree (sharedKey, m_DHKeysPair->privateKey, pubKey)) if (!dh.Agree (sharedKey, m_DHKeysPair->privateKey, pubKey))
{ {
@ -303,7 +303,7 @@ namespace ntcp
s.tsB = tsB; s.tsB = tsB;
CryptoPP::DSA::PublicKey pubKey; CryptoPP::DSA::PublicKey pubKey;
pubKey.Initialize (dsap, dsaq, dsag, CryptoPP::Integer (m_RemoteRouterInfo.GetRouterIdentity ().signingKey, 128)); pubKey.Initialize (dsap(), dsaq(), dsag(), CryptoPP::Integer (m_RemoteRouterInfo.GetRouterIdentity ().signingKey, 128));
CryptoPP::DSA::Verifier verifier (pubKey); CryptoPP::DSA::Verifier verifier (pubKey);
if (!verifier.VerifyMessage ((uint8_t *)&s, sizeof(s), m_Phase3.signature, 40)) if (!verifier.VerifyMessage ((uint8_t *)&s, sizeof(s), m_Phase3.signature, 40))
{ {
@ -370,7 +370,7 @@ namespace ntcp
s.tsB = m_Phase2.encrypted.timestamp; s.tsB = m_Phase2.encrypted.timestamp;
CryptoPP::DSA::PublicKey pubKey; CryptoPP::DSA::PublicKey pubKey;
pubKey.Initialize (dsap, dsaq, dsag, CryptoPP::Integer (m_RemoteRouterInfo.GetRouterIdentity ().signingKey, 128)); pubKey.Initialize (dsap(), dsaq(), dsag(), CryptoPP::Integer (m_RemoteRouterInfo.GetRouterIdentity ().signingKey, 128));
CryptoPP::DSA::Verifier verifier (pubKey); CryptoPP::DSA::Verifier verifier (pubKey);
if (!verifier.VerifyMessage ((uint8_t *)&s, sizeof(s), m_Phase4.signature, 40)) if (!verifier.VerifyMessage ((uint8_t *)&s, sizeof(s), m_Phase4.signature, 40))
{ {

View file

@ -19,7 +19,7 @@ namespace i2p
void RouterContext::CreateNewRouter () void RouterContext::CreateNewRouter ()
{ {
m_Keys = i2p::data::CreateRandomKeys (); m_Keys = i2p::data::CreateRandomKeys ();
m_SigningPrivateKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, m_SigningPrivateKey.Initialize (i2p::crypto::dsap(), i2p::crypto::dsaq(), i2p::crypto::dsag(),
CryptoPP::Integer (m_Keys.signingPrivateKey, 20)); CryptoPP::Integer (m_Keys.signingPrivateKey, 20));
UpdateRouterInfo (); UpdateRouterInfo ();
} }
@ -76,7 +76,7 @@ namespace i2p
if (!fk.is_open ()) return false; if (!fk.is_open ()) return false;
fk.read ((char *)&m_Keys, sizeof (m_Keys)); fk.read ((char *)&m_Keys, sizeof (m_Keys));
m_SigningPrivateKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, m_SigningPrivateKey.Initialize (i2p::crypto::dsap(), i2p::crypto::dsaq(), i2p::crypto::dsag(),
CryptoPP::Integer (m_Keys.signingPrivateKey, 20)); CryptoPP::Integer (m_Keys.signingPrivateKey, 20));
m_RouterInfo = i2p::data::RouterInfo (i2p::util::filesystem::GetFullPath (ROUTER_INFO).c_str ()); // TODO m_RouterInfo = i2p::data::RouterInfo (i2p::util::filesystem::GetFullPath (ROUTER_INFO).c_str ()); // TODO

View file

@ -66,7 +66,7 @@ namespace data
ReadFromStream (str); ReadFromStream (str);
// verify signature // verify signature
CryptoPP::DSA::PublicKey pubKey; CryptoPP::DSA::PublicKey pubKey;
pubKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, CryptoPP::Integer (m_RouterIdentity.signingKey, 128)); pubKey.Initialize (i2p::crypto::dsap(), i2p::crypto::dsaq(), i2p::crypto::dsag(), CryptoPP::Integer (m_RouterIdentity.signingKey, 128));
CryptoPP::DSA::Verifier verifier (pubKey); CryptoPP::DSA::Verifier verifier (pubKey);
int l = m_BufferLen - 40; int l = m_BufferLen - 40;
if (!verifier.VerifyMessage ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l, 40)) if (!verifier.VerifyMessage ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l, 40))

View file

@ -31,7 +31,7 @@ namespace ssu
void SSUSession::CreateAESandMacKey (const uint8_t * pubKey) void SSUSession::CreateAESandMacKey (const uint8_t * pubKey)
{ {
CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg); CryptoPP::DH dh (i2p::crypto::elgp(), i2p::crypto::elgg());
uint8_t sharedKey[256]; uint8_t sharedKey[256];
if (!dh.Agree (sharedKey, m_DHKeysPair->privateKey, pubKey)) if (!dh.Agree (sharedKey, m_DHKeysPair->privateKey, pubKey))
{ {
@ -211,7 +211,7 @@ namespace ssu
m_SessionKeyDecryption.Decrypt (payload, 48, payload); m_SessionKeyDecryption.Decrypt (payload, 48, payload);
// verify // verify
CryptoPP::DSA::PublicKey pubKey; CryptoPP::DSA::PublicKey pubKey;
pubKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, CryptoPP::Integer (m_RemoteRouter->GetRouterIdentity ().signingKey, 128)); pubKey.Initialize (i2p::crypto::dsap(), i2p::crypto::dsaq(), i2p::crypto::dsag(), CryptoPP::Integer (m_RemoteRouter->GetRouterIdentity ().signingKey, 128));
CryptoPP::DSA::Verifier verifier (pubKey); CryptoPP::DSA::Verifier verifier (pubKey);
if (!verifier.VerifyMessage (signedData, 532, payload, 40)) if (!verifier.VerifyMessage (signedData, 532, payload, 40))
LogPrint ("SSU signature verification failed"); LogPrint ("SSU signature verification failed");

View file

@ -336,9 +336,9 @@ namespace stream
m_Keys = i2p::data::CreateRandomKeys (); m_Keys = i2p::data::CreateRandomKeys ();
m_IdentHash = m_Keys.pub.Hash (); m_IdentHash = m_Keys.pub.Hash ();
m_SigningPrivateKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, m_SigningPrivateKey.Initialize (i2p::crypto::dsap(), i2p::crypto::dsaq(), i2p::crypto::dsag(),
CryptoPP::Integer (m_Keys.signingPrivateKey, 20)); CryptoPP::Integer (m_Keys.signingPrivateKey, 20));
CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg); CryptoPP::DH dh (i2p::crypto::elgp(), i2p::crypto::elgg());
dh.GenerateKeyPair(i2p::context.GetRandomNumberGenerator (), m_EncryptionPrivateKey, m_EncryptionPublicKey); dh.GenerateKeyPair(i2p::context.GetRandomNumberGenerator (), m_EncryptionPrivateKey, m_EncryptionPublicKey);
m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (*this); m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (*this);
} }
@ -352,9 +352,9 @@ namespace stream
LogPrint ("Can't open file ", fullPath); LogPrint ("Can't open file ", fullPath);
m_IdentHash = m_Keys.pub.Hash (); m_IdentHash = m_Keys.pub.Hash ();
m_SigningPrivateKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, m_SigningPrivateKey.Initialize (i2p::crypto::dsap(), i2p::crypto::dsaq(), i2p::crypto::dsag(),
CryptoPP::Integer (m_Keys.signingPrivateKey, 20)); CryptoPP::Integer (m_Keys.signingPrivateKey, 20));
CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg); CryptoPP::DH dh (i2p::crypto::elgp(), i2p::crypto::elgg());
dh.GenerateKeyPair(i2p::context.GetRandomNumberGenerator (), m_EncryptionPrivateKey, m_EncryptionPublicKey); dh.GenerateKeyPair(i2p::context.GetRandomNumberGenerator (), m_EncryptionPrivateKey, m_EncryptionPublicKey);
m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (*this); m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (*this);
} }