99#include < vector>
1010
1111#include < boost/test/unit_test.hpp>
12- #include < openssl/aes.h>
13- #include < openssl/evp.h>
1412
1513BOOST_FIXTURE_TEST_SUITE (wallet_crypto, BasicTestingSetup)
1614
17- bool OldSetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char >& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod, unsigned char * chKey, unsigned char * chIV)
18- {
19- if (nRounds < 1 || chSalt.size () != WALLET_CRYPTO_SALT_SIZE)
20- return false ;
21-
22- int i = 0 ;
23- if (nDerivationMethod == 0 )
24- i = EVP_BytesToKey (EVP_aes_256_cbc (), EVP_sha512 (), &chSalt[0 ],
25- (unsigned char *)&strKeyData[0 ], strKeyData.size (), nRounds, chKey, chIV);
26-
27- if (i != (int )WALLET_CRYPTO_KEY_SIZE)
28- {
29- memory_cleanse (chKey, WALLET_CRYPTO_KEY_SIZE);
30- memory_cleanse (chIV, WALLET_CRYPTO_IV_SIZE);
31- return false ;
32- }
33- return true ;
34- }
35-
36- bool OldEncrypt (const CKeyingMaterial& vchPlaintext, std::vector<unsigned char > &vchCiphertext, const unsigned char chKey[32 ], const unsigned char chIV[16 ])
37- {
38- // max ciphertext len for a n bytes of plaintext is
39- // n + AES_BLOCK_SIZE - 1 bytes
40- int nLen = vchPlaintext.size ();
41- int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0 ;
42- vchCiphertext = std::vector<unsigned char > (nCLen);
43-
44- EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
45-
46- if (!ctx) return false ;
47-
48- bool fOk = true ;
49-
50- EVP_CIPHER_CTX_init (ctx);
51- if (fOk ) fOk = EVP_EncryptInit_ex (ctx, EVP_aes_256_cbc (), nullptr , chKey, chIV) != 0 ;
52- if (fOk ) fOk = EVP_EncryptUpdate (ctx, &vchCiphertext[0 ], &nCLen, &vchPlaintext[0 ], nLen) != 0 ;
53- if (fOk ) fOk = EVP_EncryptFinal_ex (ctx, (&vchCiphertext[0 ]) + nCLen, &nFLen) != 0 ;
54- EVP_CIPHER_CTX_cleanup (ctx);
55-
56- EVP_CIPHER_CTX_free (ctx);
57-
58- if (!fOk ) return false ;
59-
60- vchCiphertext.resize (nCLen + nFLen);
61- return true ;
62- }
63-
64- bool OldDecrypt (const std::vector<unsigned char >& vchCiphertext, CKeyingMaterial& vchPlaintext, const unsigned char chKey[32 ], const unsigned char chIV[16 ])
65- {
66- // plaintext will always be equal to or lesser than length of ciphertext
67- int nLen = vchCiphertext.size ();
68- int nPLen = nLen, nFLen = 0 ;
69-
70- vchPlaintext = CKeyingMaterial (nPLen);
71-
72- EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
73-
74- if (!ctx) return false ;
75-
76- bool fOk = true ;
77-
78- EVP_CIPHER_CTX_init (ctx);
79- if (fOk ) fOk = EVP_DecryptInit_ex (ctx, EVP_aes_256_cbc (), nullptr , chKey, chIV) != 0 ;
80- if (fOk ) fOk = EVP_DecryptUpdate (ctx, &vchPlaintext[0 ], &nPLen, &vchCiphertext[0 ], nLen) != 0 ;
81- if (fOk ) fOk = EVP_DecryptFinal_ex (ctx, (&vchPlaintext[0 ]) + nPLen, &nFLen) != 0 ;
82- EVP_CIPHER_CTX_cleanup (ctx);
83-
84- EVP_CIPHER_CTX_free (ctx);
85-
86- if (!fOk ) return false ;
87-
88- vchPlaintext.resize (nPLen + nFLen);
89- return true ;
90- }
91-
9215class TestCrypter
9316{
9417public:
9518static void TestPassphraseSingle (const std::vector<unsigned char >& vchSalt, const SecureString& passphrase, uint32_t rounds,
9619 const std::vector<unsigned char >& correctKey = std::vector<unsigned char >(),
9720 const std::vector<unsigned char >& correctIV=std::vector<unsigned char >())
9821{
99- unsigned char chKey[WALLET_CRYPTO_KEY_SIZE];
100- unsigned char chIV[WALLET_CRYPTO_IV_SIZE];
101-
10222 CCrypter crypt;
10323 crypt.SetKeyFromPassphrase (passphrase, vchSalt, rounds, 0 );
10424
105- OldSetKeyFromPassphrase (passphrase, vchSalt, rounds, 0 , chKey, chIV);
106-
107- BOOST_CHECK_MESSAGE (memcmp (chKey, crypt.vchKey .data (), crypt.vchKey .size ()) == 0 , \
108- HexStr (chKey, chKey+sizeof (chKey)) + std::string (" != " ) + HexStr (crypt.vchKey ));
109- BOOST_CHECK_MESSAGE (memcmp (chIV, crypt.vchIV .data (), crypt.vchIV .size ()) == 0 , \
110- HexStr (chIV, chIV+sizeof (chIV)) + std::string (" != " ) + HexStr (crypt.vchIV ));
111-
11225 if (!correctKey.empty ())
113- BOOST_CHECK_MESSAGE (memcmp (chKey, & correctKey[ 0 ], sizeof (chKey )) == 0 , \
114- HexStr (chKey, chKey+ sizeof (chKey )) + std::string (" != " ) + HexStr (correctKey.begin (), correctKey.end ()));
26+ BOOST_CHECK_MESSAGE (memcmp (crypt. vchKey . data (), correctKey. data (), crypt. vchKey . size ( )) == 0 , \
27+ HexStr (crypt. vchKey . begin (), crypt. vchKey . end ( )) + std::string (" != " ) + HexStr (correctKey.begin (), correctKey.end ()));
11528 if (!correctIV.empty ())
116- BOOST_CHECK_MESSAGE (memcmp (chIV, & correctIV[ 0 ], sizeof (chIV )) == 0 ,
117- HexStr (chIV, chIV+ sizeof (chIV )) + std::string (" != " ) + HexStr (correctIV.begin (), correctIV.end ()));
29+ BOOST_CHECK_MESSAGE (memcmp (crypt. vchIV . data (), correctIV. data (), crypt. vchIV . size ( )) == 0 ,
30+ HexStr (crypt. vchIV . begin (), crypt. vchIV . end ( )) + std::string (" != " ) + HexStr (correctIV.begin (), correctIV.end ()));
11831}
11932
12033static void TestPassphrase (const std::vector<unsigned char >& vchSalt, const SecureString& passphrase, uint32_t rounds,
@@ -126,50 +39,26 @@ static void TestPassphrase(const std::vector<unsigned char>& vchSalt, const Secu
12639 TestPassphraseSingle (vchSalt, SecureString (i, passphrase.end ()), rounds);
12740}
12841
129-
13042static void TestDecrypt (const CCrypter& crypt, const std::vector<unsigned char >& vchCiphertext, \
13143 const std::vector<unsigned char >& vchPlaintext = std::vector<unsigned char >())
13244{
133- CKeyingMaterial vchDecrypted1;
134- CKeyingMaterial vchDecrypted2;
135- int result1, result2;
136- result1 = crypt.Decrypt (vchCiphertext, vchDecrypted1);
137- result2 = OldDecrypt (vchCiphertext, vchDecrypted2, crypt.vchKey .data (), crypt.vchIV .data ());
138- BOOST_CHECK (result1 == result2);
139-
140- // These two should be equal. However, OpenSSL 1.0.1j introduced a change
141- // that would zero all padding except for the last byte for failed decrypts.
142- // This behavior was reverted for 1.0.1k.
143- if (vchDecrypted1 != vchDecrypted2 && vchDecrypted1.size () >= AES_BLOCK_SIZE && SSLeay () == 0x100010afL )
144- {
145- for (CKeyingMaterial::iterator it = vchDecrypted1.end () - AES_BLOCK_SIZE; it != vchDecrypted1.end () - 1 ; it++)
146- *it = 0 ;
147- }
148-
149- BOOST_CHECK_MESSAGE (vchDecrypted1 == vchDecrypted2, HexStr (vchDecrypted1.begin (), vchDecrypted1.end ()) + " != " + HexStr (vchDecrypted2.begin (), vchDecrypted2.end ()));
150-
45+ CKeyingMaterial vchDecrypted;
46+ crypt.Decrypt (vchCiphertext, vchDecrypted);
15147 if (vchPlaintext.size ())
152- BOOST_CHECK (CKeyingMaterial (vchPlaintext.begin (), vchPlaintext.end ()) == vchDecrypted2 );
48+ BOOST_CHECK (CKeyingMaterial (vchPlaintext.begin (), vchPlaintext.end ()) == vchDecrypted );
15349}
15450
15551static void TestEncryptSingle (const CCrypter& crypt, const CKeyingMaterial& vchPlaintext,
15652 const std::vector<unsigned char >& vchCiphertextCorrect = std::vector<unsigned char >())
15753{
158- std::vector<unsigned char > vchCiphertext1;
159- std::vector<unsigned char > vchCiphertext2;
160- int result1 = crypt.Encrypt (vchPlaintext, vchCiphertext1);
161-
162- int result2 = OldEncrypt (vchPlaintext, vchCiphertext2, crypt.vchKey .data (), crypt.vchIV .data ());
163- BOOST_CHECK (result1 == result2);
164- BOOST_CHECK (vchCiphertext1 == vchCiphertext2);
54+ std::vector<unsigned char > vchCiphertext;
55+ crypt.Encrypt (vchPlaintext, vchCiphertext);
16556
16657 if (!vchCiphertextCorrect.empty ())
167- BOOST_CHECK (vchCiphertext2 == vchCiphertextCorrect);
58+ BOOST_CHECK (vchCiphertext == vchCiphertextCorrect);
16859
16960 const std::vector<unsigned char > vchPlaintext2 (vchPlaintext.begin (), vchPlaintext.end ());
170-
171- if (vchCiphertext1 == vchCiphertext2)
172- TestDecrypt (crypt, vchCiphertext1, vchPlaintext2);
61+ TestDecrypt (crypt, vchCiphertext, vchPlaintext2);
17362}
17463
17564static void TestEncrypt (const CCrypter& crypt, const std::vector<unsigned char >& vchPlaintextIn, \
0 commit comments