Browse Source

pass iv to AES Encrypt/Decrypt directly. aes-test added

pull/2136/head
orignal 4 days ago
parent
commit
f23a7f569b
  1. 32
      libi2pd/Crypto.cpp
  2. 18
      libi2pd/Crypto.h
  3. 12
      libi2pd/Garlic.cpp
  4. 1
      libi2pd/Garlic.h
  5. 12
      libi2pd/NTCP2.cpp
  6. 3
      libi2pd/TransitTunnel.cpp
  7. 3
      libi2pd/TunnelConfig.cpp
  8. 7
      tests/CMakeLists.txt
  9. 5
      tests/Makefile
  10. 69
      tests/test-aes.cpp

32
libi2pd/Crypto.cpp

@ -442,9 +442,8 @@ namespace crypto @@ -442,9 +442,8 @@ namespace crypto
// encrypt
CBCEncryption encryption;
encryption.SetKey (shared);
encryption.SetIV (iv);
encrypted[257] = 0;
encryption.Encrypt (m, 256, encrypted + 258);
encryption.Encrypt (m, 256, iv, encrypted + 258);
EC_POINT_free (p);
BN_CTX_end (ctx);
BN_CTX_free (ctx);
@ -477,8 +476,7 @@ namespace crypto @@ -477,8 +476,7 @@ namespace crypto
uint8_t m[256];
CBCDecryption decryption;
decryption.SetKey (shared);
decryption.SetIV (iv);
decryption.Decrypt (encrypted + 258, 256, m);
decryption.Decrypt (encrypted + 258, 256, iv, m);
// verify and copy
uint8_t hash[32];
SHA256 (m + 33, 222, hash);
@ -560,7 +558,6 @@ namespace crypto @@ -560,7 +558,6 @@ namespace crypto
CBCEncryption::CBCEncryption ()
{
m_Ctx = EVP_CIPHER_CTX_new ();
//memset ((uint8_t *)m_LastBlock, 0, 16);
}
CBCEncryption::~CBCEncryption ()
@ -569,10 +566,10 @@ namespace crypto @@ -569,10 +566,10 @@ namespace crypto
EVP_CIPHER_CTX_free (m_Ctx);
}
void CBCEncryption::Encrypt (const uint8_t * in, std::size_t len, uint8_t * out)
void CBCEncryption::Encrypt (const uint8_t * in, size_t len, const uint8_t * iv, uint8_t * out)
{
// len/16
EVP_EncryptInit_ex (m_Ctx, EVP_aes_256_cbc(), NULL, m_Key, m_IV);
EVP_EncryptInit_ex (m_Ctx, EVP_aes_256_cbc(), NULL, m_Key, iv);
EVP_CIPHER_CTX_set_padding (m_Ctx, 0);
int l;
EVP_EncryptUpdate (m_Ctx, out, &l, in, len);
@ -582,7 +579,6 @@ namespace crypto @@ -582,7 +579,6 @@ namespace crypto
CBCDecryption::CBCDecryption ()
{
m_Ctx = EVP_CIPHER_CTX_new ();
//memset ((uint8_t *)m_IV, 0, 16);
}
CBCDecryption::~CBCDecryption ()
@ -591,10 +587,10 @@ namespace crypto @@ -591,10 +587,10 @@ namespace crypto
EVP_CIPHER_CTX_free (m_Ctx);
}
void CBCDecryption::Decrypt (const uint8_t * in, std::size_t len, uint8_t * out)
void CBCDecryption::Decrypt (const uint8_t * in, size_t len, const uint8_t * iv, uint8_t * out)
{
// len/16
EVP_DecryptInit_ex (m_Ctx, EVP_aes_256_cbc(), NULL, m_Key, m_IV);
EVP_DecryptInit_ex (m_Ctx, EVP_aes_256_cbc(), NULL, m_Key, iv);
EVP_CIPHER_CTX_set_padding (m_Ctx, 0);
int l;
EVP_DecryptUpdate (m_Ctx, out, &l, in, len);
@ -603,18 +599,18 @@ namespace crypto @@ -603,18 +599,18 @@ namespace crypto
void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out)
{
m_IVEncryption.Encrypt (in, out); // iv
m_LayerEncryption.SetIV (out);
m_LayerEncryption.Encrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
m_IVEncryption.Encrypt (out, out); // double iv
uint8_t iv[16];
m_IVEncryption.Encrypt (in, iv); // iv
m_LayerEncryption.Encrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, iv, out + 16); // data
m_IVEncryption.Encrypt (iv, out); // double iv
}
void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out)
{
m_IVDecryption.Decrypt (in, out); // iv
m_LayerDecryption.SetIV (out);
m_LayerDecryption.Decrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
m_IVDecryption.Decrypt (out, out); // double iv
uint8_t iv[16];
m_IVDecryption.Decrypt (in, iv); // iv
m_LayerDecryption.Decrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, iv, out + 16); // data
m_IVDecryption.Decrypt (iv, out); // double iv
}
// AEAD/ChaCha20/Poly1305

18
libi2pd/Crypto.h

@ -93,7 +93,7 @@ namespace crypto @@ -93,7 +93,7 @@ namespace crypto
ECBEncryption ();
~ECBEncryption ();
void SetKey (const AESKey& key) { m_Key = key; };
void SetKey (const uint8_t * key) { m_Key = key; };
void Encrypt(const uint8_t * in, uint8_t * out);
private:
@ -109,7 +109,7 @@ namespace crypto @@ -109,7 +109,7 @@ namespace crypto
ECBDecryption ();
~ECBDecryption ();
void SetKey (const AESKey& key) { m_Key = key; };
void SetKey (const uint8_t * key) { m_Key = key; };
void Decrypt (const uint8_t * in, uint8_t * out);
private:
@ -125,15 +125,12 @@ namespace crypto @@ -125,15 +125,12 @@ namespace crypto
CBCEncryption ();
~CBCEncryption ();
void SetKey (const AESKey& key) { m_Key = key; }; // 32 bytes
void SetIV (const uint8_t * iv) { m_IV = iv; }; // 16 bytes
void Encrypt (const uint8_t * in, std::size_t len, uint8_t * out);
void SetKey (const uint8_t * key) { m_Key = key; }; // 32 bytes
void Encrypt (const uint8_t * in, size_t len, const uint8_t * iv, uint8_t * out);
private:
AESKey m_Key;
i2p::data::Tag<16> m_IV;
EVP_CIPHER_CTX * m_Ctx;
};
@ -144,15 +141,12 @@ namespace crypto @@ -144,15 +141,12 @@ namespace crypto
CBCDecryption ();
~CBCDecryption ();
void SetKey (const AESKey& key) { m_Key = key; }; // 32 bytes
void SetIV (const uint8_t * iv) { m_IV = iv; }; // 16 bytes
void Decrypt (const uint8_t * in, std::size_t len, uint8_t * out);
void SetKey (const uint8_t * key) { m_Key = key; }; // 32 bytes
void Decrypt (const uint8_t * in, size_t len, const uint8_t * iv, uint8_t * out);
private:
AESKey m_Key;
i2p::data::Tag<16> m_IV;
EVP_CIPHER_CTX * m_Ctx;
};

12
libi2pd/Garlic.cpp

@ -160,7 +160,7 @@ namespace garlic @@ -160,7 +160,7 @@ namespace garlic
uint8_t iv[32]; // IV is first 16 bytes
SHA256(elGamal.preIV, 32, iv);
m_Destination->Encrypt ((uint8_t *)&elGamal, buf);
m_Encryption.SetIV (iv);
m_IV = iv;
buf += 514;
len += 514;
}
@ -170,7 +170,7 @@ namespace garlic @@ -170,7 +170,7 @@ namespace garlic
memcpy (buf, tag, 32);
uint8_t iv[32]; // IV is first 16 bytes
SHA256(tag, 32, iv);
m_Encryption.SetIV (iv);
m_IV = iv;
buf += 32;
len += 32;
}
@ -210,7 +210,7 @@ namespace garlic @@ -210,7 +210,7 @@ namespace garlic
size_t rem = blockSize % 16;
if (rem)
blockSize += (16-rem); //padding
m_Encryption.Encrypt(buf, blockSize, buf);
m_Encryption.Encrypt(buf, blockSize, m_IV, buf);
return blockSize;
}
@ -514,8 +514,7 @@ namespace garlic @@ -514,8 +514,7 @@ namespace garlic
{
uint8_t iv[32]; // IV is first 16 bytes
SHA256(buf, 32, iv);
decryption->SetIV (iv);
decryption->Decrypt (buf + 32, length - 32, buf + 32);
decryption->Decrypt (buf + 32, length - 32, iv, buf + 32);
HandleAESBlock (buf + 32, length - 32, decryption, msg->from);
found = true;
}
@ -533,8 +532,7 @@ namespace garlic @@ -533,8 +532,7 @@ namespace garlic
auto decryption = std::make_shared<AESDecryption>(elGamal.sessionKey);
uint8_t iv[32]; // IV is first 16 bytes
SHA256(elGamal.preIV, 32, iv);
decryption->SetIV (iv);
decryption->Decrypt(buf + 514, length - 514, buf + 514);
decryption->Decrypt(buf + 514, length - 514, iv, buf + 514);
HandleAESBlock (buf + 514, length - 514, decryption, msg->from);
}
else if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD))

1
libi2pd/Garlic.h

@ -205,6 +205,7 @@ namespace garlic @@ -205,6 +205,7 @@ namespace garlic
std::map<uint32_t, std::unique_ptr<UnconfirmedTags> > m_UnconfirmedTagsMsgs; // msgID->tags
i2p::crypto::CBCEncryption m_Encryption;
i2p::data::Tag<16> m_IV;
public:

12
libi2pd/NTCP2.cpp

@ -120,8 +120,7 @@ namespace transport @@ -120,8 +120,7 @@ namespace transport
// encrypt X
i2p::crypto::CBCEncryption encryption;
encryption.SetKey (m_RemoteIdentHash);
encryption.SetIV (m_IV);
encryption.Encrypt (GetPub (), 32, m_SessionRequestBuffer); // X
encryption.Encrypt (GetPub (), 32, m_IV, m_SessionRequestBuffer); // X
memcpy (m_IV, m_SessionRequestBuffer + 16, 16); // save last block as IV for SessionCreated
// encryption key for next block
if (!KDF1Alice ()) return false;
@ -161,8 +160,7 @@ namespace transport @@ -161,8 +160,7 @@ namespace transport
// encrypt Y
i2p::crypto::CBCEncryption encryption;
encryption.SetKey (i2p::context.GetIdentHash ());
encryption.SetIV (m_IV);
encryption.Encrypt (GetPub (), 32, m_SessionCreatedBuffer); // Y
encryption.Encrypt (GetPub (), 32, m_IV, m_SessionCreatedBuffer); // Y
// encryption key for next block (m_K)
if (!KDF2Bob ()) return false;
uint8_t options[16];
@ -208,8 +206,7 @@ namespace transport @@ -208,8 +206,7 @@ namespace transport
// decrypt X
i2p::crypto::CBCDecryption decryption;
decryption.SetKey (i2p::context.GetIdentHash ());
decryption.SetIV (i2p::context.GetNTCP2IV ());
decryption.Decrypt (m_SessionRequestBuffer, 32, GetRemotePub ());
decryption.Decrypt (m_SessionRequestBuffer, 32, i2p::context.GetNTCP2IV (), GetRemotePub ());
memcpy (m_IV, m_SessionRequestBuffer + 16, 16); // save last block as IV for SessionCreated
// decryption key for next block
if (!KDF1Bob ())
@ -268,8 +265,7 @@ namespace transport @@ -268,8 +265,7 @@ namespace transport
// decrypt Y
i2p::crypto::CBCDecryption decryption;
decryption.SetKey (m_RemoteIdentHash);
decryption.SetIV (m_IV);
decryption.Decrypt (m_SessionCreatedBuffer, 32, GetRemotePub ());
decryption.Decrypt (m_SessionCreatedBuffer, 32, m_IV, GetRemotePub ());
// decryption key for next block (m_K)
if (!KDF2Alice ())
{

3
libi2pd/TransitTunnel.cpp

@ -434,8 +434,7 @@ namespace tunnel @@ -434,8 +434,7 @@ namespace tunnel
else
{
encryption.SetKey (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET);
encryption.SetIV (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET);
encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply);
encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, reply);
}
}
return true;

3
libi2pd/TunnelConfig.cpp

@ -79,8 +79,7 @@ namespace tunnel @@ -79,8 +79,7 @@ namespace tunnel
uint8_t * record = records + index*TUNNEL_BUILD_RECORD_SIZE;
i2p::crypto::CBCDecryption decryption;
decryption.SetKey (replyKey);
decryption.SetIV (replyIV);
decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record);
decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, replyIV, record);
}
void ECIESTunnelHopConfig::EncryptECIES (const uint8_t * plainText, size_t len, uint8_t * encrypted)

7
tests/CMakeLists.txt

@ -65,6 +65,10 @@ set(test-eddsa_SRCS @@ -65,6 +65,10 @@ set(test-eddsa_SRCS
test-eddsa.cpp
)
set(test-aes_SRCS
test-aes.cpp
)
add_executable(test-http-merge_chunked ${test-http-merge_chunked_SRCS})
add_executable(test-http-req ${test-http-req_SRCS})
add_executable(test-http-res ${test-http-res_SRCS})
@ -77,6 +81,7 @@ add_executable(test-aeadchacha20poly1305 ${test-aeadchacha20poly1305_SRCS}) @@ -77,6 +81,7 @@ add_executable(test-aeadchacha20poly1305 ${test-aeadchacha20poly1305_SRCS})
add_executable(test-blinding ${test-blinding_SRCS})
add_executable(test-elligator ${test-elligator_SRCS})
add_executable(test-eddsa ${test-eddsa_SRCS})
add_executable(test-aes ${test-aes_SRCS})
set(LIBS
libi2pd
@ -101,6 +106,7 @@ target_link_libraries(test-aeadchacha20poly1305 ${LIBS}) @@ -101,6 +106,7 @@ target_link_libraries(test-aeadchacha20poly1305 ${LIBS})
target_link_libraries(test-blinding ${LIBS})
target_link_libraries(test-elligator ${LIBS})
target_link_libraries(test-eddsa ${LIBS})
target_link_libraries(test-aes ${LIBS})
add_test(test-http-merge_chunked ${TEST_PATH}/test-http-merge_chunked)
add_test(test-http-req ${TEST_PATH}/test-http-req)
@ -114,3 +120,4 @@ add_test(test-aeadchacha20poly1305 ${TEST_PATH}/test-aeadchacha20poly1305) @@ -114,3 +120,4 @@ add_test(test-aeadchacha20poly1305 ${TEST_PATH}/test-aeadchacha20poly1305)
add_test(test-blinding ${TEST_PATH}/test-blinding)
add_test(test-elligator ${TEST_PATH}/test-elligator)
add_test(test-eddsa ${TEST_PATH}/test-eddsa)
add_test(test-aes ${TEST_PATH}/test-aes)

5
tests/Makefile

@ -8,7 +8,7 @@ LIBI2PD = ../libi2pd.a @@ -8,7 +8,7 @@ LIBI2PD = ../libi2pd.a
TESTS = \
test-http-merge_chunked test-http-req test-http-res test-http-url test-http-url_decode \
test-gost test-gost-sig test-base-64 test-aeadchacha20poly1305 test-blinding \
test-elligator test-eddsa
test-elligator test-eddsa test-aes
ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS)))
CXXFLAGS += -DWIN32_LEAN_AND_MEAN
@ -56,6 +56,9 @@ test-elligator: test-elligator.cpp $(LIBI2PD) @@ -56,6 +56,9 @@ test-elligator: test-elligator.cpp $(LIBI2PD)
test-eddsa: test-eddsa.cpp $(LIBI2PD)
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
test-aes: test-aes.cpp $(LIBI2PD)
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
run: $(TESTS)
@for TEST in $(TESTS); do echo Running $$TEST; ./$$TEST ; done

69
tests/test-aes.cpp

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
#include <cassert>
#include <inttypes.h>
#include <string.h>
#include "Crypto.h"
uint8_t ecb_key1[32] =
{
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
};
uint8_t ecb_plain1[16] =
{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a
};
uint8_t ecb_cipher1[16] =
{
0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8
};
uint8_t cbc_key1[32] =
{
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
};
uint8_t cbc_iv1[16] =
{
0xF5, 0x8C, 0x4C, 0x04, 0xD6, 0xE5, 0xF1, 0xBA, 0x77, 0x9E, 0xAB, 0xFB, 0x5F, 0x7B, 0xFB, 0xD6
};
uint8_t cbc_plain1[16] =
{
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51
};
uint8_t cbc_cipher1[16] =
{
0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d
};
int main ()
{
// ECB encrypt test1
i2p::crypto::ECBEncryption ecbencryption;
ecbencryption.SetKey (ecb_key1);
uint8_t out[16];
ecbencryption.Encrypt (ecb_plain1, out);
assert (memcmp (ecb_cipher1, out, 16) == 0);
// ECB decrypt test1
i2p::crypto::ECBDecryption ecbdecryption;
ecbdecryption.SetKey (ecb_key1);
ecbdecryption.Decrypt (ecb_cipher1, out);
assert (memcmp (ecb_plain1, out, 16) == 0);
// CBC encrypt test
i2p::crypto::CBCEncryption cbcencryption;
cbcencryption.SetKey (cbc_key1);
cbcencryption.Encrypt (cbc_plain1, 16, cbc_iv1, out);
assert (memcmp (cbc_cipher1, out, 16) == 0);
// CBC decrypt test
i2p::crypto::CBCDecryption cbcdecryption;
cbcdecryption.SetKey (cbc_key1);
cbcdecryption.Decrypt (cbc_cipher1, 16, cbc_iv1, out);
assert (memcmp (cbc_plain1, out, 16) == 0);
}
Loading…
Cancel
Save