Browse Source

initial ecies interop w/go

cl-refactor
subtly 10 years ago
parent
commit
30e75e2659
  1. 16
      libdevcrypto/Common.cpp
  2. 2
      libdevcrypto/Common.h
  3. 18
      libdevcrypto/CryptoPP.cpp
  4. 30
      libp2p/Host.cpp
  5. 1
      libp2p/Host.h

16
libdevcrypto/Common.cpp

@ -82,6 +82,22 @@ bool dev::decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
return true;
}
void dev::encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher)
{
bytes io = _plain.toBytes();
s_secp256k1.encryptECIES(_k, io);
o_cipher = std::move(io);
}
bool dev::decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
{
bytes io = _cipher.toBytes();
if (!s_secp256k1.decryptECIES(_k, io))
return false;
o_plaintext = std::move(io);
return true;
}
void dev::encryptSym(Secret const& _k, bytesConstRef _plain, bytes& o_cipher)
{
// TOOD: @alex @subtly do this properly.

2
libdevcrypto/Common.h

@ -96,6 +96,8 @@ void encryptSym(Secret const& _k, bytesConstRef _plain, bytes& o_cipher);
/// Symmetric decryption.
bool decryptSym(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext);
void encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher);
bool decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext);
h128 encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_cipher);
h128 encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_cipher, h128 const& _iv);
bool decryptSymNoAuth(Secret const& _k, h128 const& _iv, bytesConstRef _cipher, bytes& o_plaintext);

18
libdevcrypto/CryptoPP.cpp

@ -90,16 +90,17 @@ void Secp256k1::encryptECIES(Public const& _k, bytes& io_cipher)
if (!cipherText.size())
return;
bytes msg(1 + Public::size + cipherText.size() + 32);
bytes msg(1 + Public::size + h128::size + cipherText.size() + 32);
msg[0] = 0x04;
r.pub().ref().copyTo(bytesRef(&msg).cropped(1, Public::size));
bytesRef msgCipherRef = bytesRef(&msg).cropped(1 + Public::size, cipherText.size());
bytesRef msgCipherRef = bytesRef(&msg).cropped(1 + Public::size + h128::size, cipherText.size());
bytesConstRef(&cipherText).copyTo(msgCipherRef);
// tag message
CryptoPP::HMAC<SHA256> ctx(mKey.data(), mKey.size());
ctx.Update(cipherText.data(), cipherText.size());
ctx.Final(msg.data() + 1 + Public::size + cipherText.size());
bytesConstRef cipherWithIV = bytesRef(&msg).cropped(1 + Public::size, h128::size + cipherText.size());
ctx.Update(cipherWithIV.data(), cipherWithIV.size());
ctx.Final(msg.data() + 1 + Public::size + cipherWithIV.size());
io_cipher.resize(msg.size());
io_cipher.swap(msg);
@ -114,7 +115,7 @@ bool Secp256k1::decryptECIES(Secret const& _k, bytes& io_text)
// invalid message: publickey
return false;
if (io_text.size() < (1 + Public::size + h256::size + 1))
if (io_text.size() < (1 + Public::size + h128::size + 1 + h256::size))
// invalid message: length
return false;
@ -126,13 +127,14 @@ bool Secp256k1::decryptECIES(Secret const& _k, bytes& io_text)
sha3(mKey, mKey);
bytes plain;
size_t cipherLen = io_text.size() - 1 - Public::size - h256::size;
bytesConstRef cipher(io_text.data() + 1 + Public::size, cipherLen);
size_t cipherLen = io_text.size() - 1 - Public::size - h128::size - h256::size;
bytesConstRef cipherWithIV(io_text.data() + 1 + Public::size, h128::size + cipherLen);
bytesConstRef cipher = cipherWithIV.cropped(h128::size, cipherLen);
bytesConstRef msgMac(cipher.data() + cipher.size(), h256::size);
// verify tag
CryptoPP::HMAC<SHA256> ctx(mKey.data(), mKey.size());
ctx.Update(cipher.data(), cipher.size());
ctx.Update(cipherWithIV.data(), cipherWithIV.size());
h256 mac;
ctx.Final(mac.data());
for (unsigned i = 0; i < h256::size; i++)

30
libp2p/Host.cpp

@ -408,7 +408,7 @@ void PeerHandshake::transition(boost::system::error_code _ech)
host->m_alias.pub().ref().copyTo(pubk);
this->nonce.ref().copyTo(nonce);
auth[auth.size() - 1] = 0x0;
encrypt(remote, &auth, authCipher);
encryptECIES(remote, &auth, authCipher);
ba::async_write(*socket, ba::buffer(authCipher), [this, self](boost::system::error_code ec, std::size_t)
{
@ -419,14 +419,21 @@ void PeerHandshake::transition(boost::system::error_code _ech)
{
clog(NetConnect) << "devp2p.connect.ingress recving auth";
// ingress: rx auth
authCipher.resize(279);
ba::async_read(*socket, ba::buffer(authCipher, 279), [this, self](boost::system::error_code ec, std::size_t)
authCipher.resize(321);
ba::async_read(*socket, ba::buffer(authCipher, 321), [this, self](boost::system::error_code ec, std::size_t)
{
if (ec)
transition(ec);
else
{
decrypt(host->m_alias.sec(), bytesConstRef(&authCipher), auth);
if (!decryptECIES(host->m_alias.sec(), bytesConstRef(&authCipher), auth))
{
clog(NetWarn) << "devp2p.connect.egress recving auth decrypt failed";
nextState = Error;
transition();
return;
}
bytesConstRef sig(&auth[0], Signature::size);
bytesConstRef hepubk(&auth[Signature::size], h256::size);
bytesConstRef pubk(&auth[Signature::size + h256::size], Public::size);
@ -450,14 +457,21 @@ void PeerHandshake::transition(boost::system::error_code _ech)
{
clog(NetConnect) << "devp2p.connect.egress recving ack";
// egress: rx ack
ackCipher.resize(182);
ba::async_read(*socket, ba::buffer(ackCipher, 182), [this, self](boost::system::error_code ec, std::size_t)
ackCipher.resize(225);
ba::async_read(*socket, ba::buffer(ackCipher, 225), [this, self](boost::system::error_code ec, std::size_t)
{
if (ec)
transition(ec);
else
{
decrypt(host->m_alias.sec(), bytesConstRef(&ackCipher), ack);
if (!decryptECIES(host->m_alias.sec(), bytesConstRef(&ackCipher), ack))
{
clog(NetWarn) << "devp2p.connect.egress recving ack decrypt failed";
nextState = Error;
transition();
return;
}
bytesConstRef(&ack).cropped(0, Public::size).copyTo(remoteEphemeral.ref());
bytesConstRef(&ack).cropped(Public::size, h256::size).copyTo(remoteNonce.ref());
transition();
@ -474,7 +488,7 @@ void PeerHandshake::transition(boost::system::error_code _ech)
ecdhe.pubkey().ref().copyTo(epubk);
this->nonce.ref().copyTo(nonce);
ack[ack.size() - 1] = 0x0;
encrypt(remote, &ack, ackCipher);
encryptECIES(remote, &ack, ackCipher);
ba::async_write(*socket, ba::buffer(ackCipher), [this, self](boost::system::error_code ec, std::size_t)
{
transition(ec);

1
libp2p/Host.h

@ -252,6 +252,7 @@ struct PeerHandshake: public std::enable_shared_from_this<PeerHandshake>
friend class Host;
enum State
{
Error = -1,
New, // New->AckAuth [egress: tx auth, ingress: rx auth]
AckAuth, // AckAuth->Authenticating [egress: rx ack, ingress: tx ack]
Authenticating, // Authenticating [tx caps, rx caps, authenticate]

Loading…
Cancel
Save