Skip to content

Commit

Permalink
encrypt PBFT request and response messages (#1034)
Browse files Browse the repository at this point in the history
  • Loading branch information
ashamis authored Apr 6, 2020
1 parent 59a4a90 commit f9b1d78
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 31 deletions.
113 changes: 91 additions & 22 deletions src/consensus/pbft/pbft.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,15 @@ namespace pbft
}
}

bool should_encrypt(int tag)
{
#ifdef USE_NULL_ENCRYPTOR
return false;
#else
return tag == Request_tag || tag == Reply_tag;
#endif
}

std::vector<uint8_t> serialized_msg;

public:
Expand Down Expand Up @@ -193,16 +202,19 @@ namespace pbft
struct SendAuthenticatedMsg
{
SendAuthenticatedMsg(
bool should_encrypt_,
std::vector<uint8_t> data_,
PbftEnclaveNetwork* self_,
ccf::NodeMsgType type_,
pbft::NodeId to_) :
should_encrypt(should_encrypt_),
data(std::move(data_)),
self(self_),
type(type_),
to(to_)
{}

bool should_encrypt;
std::vector<uint8_t> data;
ccf::NodeMsgType type;
pbft::NodeId to;
Expand All @@ -212,8 +224,18 @@ namespace pbft
static void send_authenticated_msg_cb(
std::unique_ptr<enclave::Tmsg<SendAuthenticatedMsg>> msg)
{
msg->data.self->n2n_channels->send_authenticated(
msg->data.type, msg->data.to, msg->data.data);
if (msg->data.should_encrypt)
{
PbftHeader hdr = {PbftMsgType::encrypted_pbft_message,
msg->data.self->id};
msg->data.self->n2n_channels->send_encrypted(
ccf::NodeMsgType::consensus_msg, msg->data.to, msg->data.data, hdr);
}
else
{
msg->data.self->n2n_channels->send_authenticated(
msg->data.type, msg->data.to, msg->data.data);
}
}

int Send(Message* msg, IPrincipal& principal) override
Expand Down Expand Up @@ -245,15 +267,27 @@ namespace pbft
return msg->size();
}

PbftHeader hdr = {PbftMsgType::pbft_message, id};
auto space = (sizeof(PbftHeader) + msg->size());
serialized_msg.resize(space);
auto data_ = serialized_msg.data();
serialized::write<PbftHeader>(data_, space, hdr);
serialize_message(data_, space, msg);
bool encrypt = should_encrypt(msg->tag());
if (encrypt)
{
size_t space = msg->size();
serialized_msg.resize(space);
auto data_ = serialized_msg.data();
serialize_message(data_, space, msg);
}
else
{
PbftHeader hdr = {PbftMsgType::pbft_message, id};
auto space = (sizeof(PbftHeader) + msg->size());
serialized_msg.resize(space);
auto data_ = serialized_msg.data();
serialized::write<PbftHeader>(data_, space, hdr);
serialize_message(data_, space, msg);
}

auto tmsg = std::make_unique<enclave::Tmsg<SendAuthenticatedMsg>>(
&send_authenticated_msg_cb,
encrypt,
std::move(serialized_msg),
this,
ccf::NodeMsgType::consensus_msg,
Expand Down Expand Up @@ -580,12 +614,16 @@ namespace pbft
struct RecvAuthenticatedMsg
{
RecvAuthenticatedMsg(
OArray&& d_, Pbft<LedgerProxy, ChannelProxy>* self_) :
bool should_decrypt_,
OArray&& d_,
Pbft<LedgerProxy, ChannelProxy>* self_) :
should_decrypt(should_decrypt_),
d(std::move(d_)),
self(self_),
result(false)
{}

bool should_decrypt;
OArray d;
Pbft<LedgerProxy, ChannelProxy>* self;
bool result;
Expand All @@ -594,21 +632,40 @@ namespace pbft
static void recv_authenticated_msg_cb(
std::unique_ptr<enclave::Tmsg<RecvAuthenticatedMsg>> msg)
{
try
if (msg->data.should_decrypt)
{
auto r = msg->data.self->channels
->template recv_authenticated_with_load<PbftHeader>(
msg->data.d.data(), msg->data.d.size());
msg->data.d.data() = r.p;
msg->data.d.size() = r.n;
msg->data.result = true;
std::pair<PbftHeader, std::vector<uint8_t>> r;
try
{
r = msg->data.self->channels->template recv_encrypted<PbftHeader>(
msg->data.d.data(), msg->data.d.size());
OArray decrypted(std::move(r.second));
msg->data.d = std::move(decrypted);
}
catch (const std::logic_error& err)
{
LOG_FAIL_FMT("Invalid encrypted pbft message: {}", err.what());
return;
}
}
catch (const std::logic_error& err)
else
{
LOG_FAIL_FMT("Invalid pbft message: {}", err.what());
return;
try
{
auto r = msg->data.self->channels
->template recv_authenticated_with_load<PbftHeader>(
msg->data.d.data(), msg->data.d.size());
msg->data.d.data() = r.p;
msg->data.d.size() = r.n;
}
catch (const std::logic_error& err)
{
LOG_FAIL_FMT("Invalid pbft message: {}", err.what());
return;
}
}

msg->data.result = true;
enclave::ThreadMessaging::ChangeTmsgCallback(
msg, &recv_authenticated_msg_process_cb);
if (enclave::ThreadMessaging::thread_count > 1)
Expand Down Expand Up @@ -638,13 +695,25 @@ namespace pbft
PbftHeader hdr = serialized::peek<PbftHeader>(data, size);
switch (hdr.msg)
{
case encrypted_pbft_message:
case pbft_message:
{
bool should_decrypt = (hdr.msg == encrypted_pbft_message);
auto tmsg = std::make_unique<enclave::Tmsg<RecvAuthenticatedMsg>>(
&recv_authenticated_msg_cb, std::move(d), this);
&recv_authenticated_msg_cb, should_decrypt, std::move(d), this);

auto recv_nonce = channels->template get_recv_nonce<PbftHeader>(
tmsg->data.d.data(), tmsg->data.d.size());
ccf::RecvNonce recv_nonce(0);
if (should_decrypt)
{
recv_nonce =
channels->template get_encrypted_recv_nonce<PbftHeader>(
tmsg->data.d.data(), tmsg->data.d.size());
}
else
{
recv_nonce = channels->template get_recv_nonce<PbftHeader>(
tmsg->data.d.data(), tmsg->data.d.size());
}

if (enclave::ThreadMessaging::thread_count > 1)
{
Expand Down
1 change: 1 addition & 0 deletions src/consensus/pbft/pbft_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace pbft
enum PbftMsgType : Node2NodeMsg
{
pbft_message = 1000,
encrypted_pbft_message,
pbft_append_entries
};

Expand Down
2 changes: 1 addition & 1 deletion src/node/channels.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ namespace ccf
key->encrypt(header.get_iv(), nullb, aad, nullptr, header.tag);
}

RecvNonce get_nonce(const GcmHdr& header)
static RecvNonce get_nonce(const GcmHdr& header)
{
return RecvNonce(header.get_iv_int());
}
Expand Down
18 changes: 13 additions & 5 deletions src/node/node_to_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,15 @@ namespace ccf
const auto& t = serialized::overlay<T>(data, size);
serialized::skip(data, size, (size - sizeof(GcmHdr)));
const auto& hdr = serialized::overlay<GcmHdr>(data, size);
auto& n2n_channel = channels->get(t.from_node);
return ccf::Channel::get_nonce(hdr);
}

return n2n_channel.get_nonce(hdr);
template <class T>
RecvNonce get_encrypted_recv_nonce(const uint8_t* data, size_t size)
{
const auto& t = serialized::overlay<T>(data, size);
const auto& hdr = serialized::overlay<GcmHdr>(data, size);
return ccf::Channel::get_nonce(hdr);
}

template <class T>
Expand Down Expand Up @@ -156,7 +162,10 @@ namespace ccf

template <class T>
bool send_encrypted(
NodeId to, const std::vector<uint8_t>& data, const T& msg_hdr)
const NodeMsgType& msg_type,
NodeId to,
const std::vector<uint8_t>& data,
const T& msg_hdr)
{
auto& n2n_channel = channels->get(to);
if (!try_established_channel(to, n2n_channel))
Expand All @@ -168,8 +177,7 @@ namespace ccf
std::vector<uint8_t> cipher(data.size());
n2n_channel.encrypt(hdr, asCb(msg_hdr), data, cipher);

to_host->write(
node_outbound, to, NodeMsgType::forwarded_msg, msg_hdr, hdr, cipher);
to_host->write(node_outbound, to, msg_type, msg_hdr, hdr, cipher);

return true;
}
Expand Down
6 changes: 4 additions & 2 deletions src/node/rpc/forwarder.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ namespace ccf

ForwardedHeader msg = {ForwardedMsg::forwarded_cmd, self};

return n2n_channels->send_encrypted(to, plain, msg);
return n2n_channels->send_encrypted(
NodeMsgType::forwarded_msg, to, plain, msg);
}

std::optional<std::tuple<std::shared_ptr<enclave::RpcContext>, NodeId>>
Expand Down Expand Up @@ -130,7 +131,8 @@ namespace ccf

ForwardedHeader msg = {ForwardedMsg::forwarded_response, self};

return n2n_channels->send_encrypted(from_node, plain, msg);
return n2n_channels->send_encrypted(
NodeMsgType::forwarded_msg, from_node, plain, msg);
}

std::optional<std::pair<size_t, std::vector<uint8_t>>>
Expand Down
5 changes: 4 additions & 1 deletion src/node/test/channel_stub.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ namespace ccf

template <class T>
bool send_encrypted(
NodeId to, const std::vector<uint8_t>& data, const T& msg)
const NodeMsgType& msg_type,
NodeId to,
const std::vector<uint8_t>& data,
const T& msg)
{
sent_encrypted_messages.push_back(data);
return true;
Expand Down

0 comments on commit f9b1d78

Please sign in to comment.