Skip to content

Commit

Permalink
pass iv to AES Encrypt/Decrypt directly. aes-test added
Browse files Browse the repository at this point in the history
  • Loading branch information
orignal committed Dec 8, 2024
1 parent 48b6234 commit f23a7f5
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 50 deletions.
32 changes: 14 additions & 18 deletions libi2pd/Crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -560,7 +558,6 @@ namespace crypto
CBCEncryption::CBCEncryption ()
{
m_Ctx = EVP_CIPHER_CTX_new ();
//memset ((uint8_t *)m_LastBlock, 0, 16);
}

CBCEncryption::~CBCEncryption ()
Expand All @@ -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);
Expand All @@ -582,7 +579,6 @@ namespace crypto
CBCDecryption::CBCDecryption ()
{
m_Ctx = EVP_CIPHER_CTX_new ();
//memset ((uint8_t *)m_IV, 0, 16);
}

CBCDecryption::~CBCDecryption ()
Expand All @@ -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);
Expand All @@ -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
Expand Down
18 changes: 6 additions & 12 deletions libi2pd/Crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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;
};

Expand All @@ -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;
};

Expand Down
12 changes: 5 additions & 7 deletions libi2pd/Garlic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand All @@ -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))
Expand Down
1 change: 1 addition & 0 deletions libi2pd/Garlic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
12 changes: 4 additions & 8 deletions libi2pd/NTCP2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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 ())
Expand Down Expand Up @@ -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 ())
{
Expand Down
3 changes: 1 addition & 2 deletions libi2pd/TransitTunnel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 1 addition & 2 deletions libi2pd/TunnelConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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 changes: 4 additions & 1 deletion tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
69 changes: 69 additions & 0 deletions tests/test-aes.cpp
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit f23a7f5

Please sign in to comment.