|
@@ -7,7 +7,11 @@
|
|
#include "boost/property_tree/json_parser.hpp"
|
|
#include "boost/property_tree/json_parser.hpp"
|
|
#include <boost/asio.hpp>
|
|
#include <boost/asio.hpp>
|
|
#include <boost/thread.hpp>
|
|
#include <boost/thread.hpp>
|
|
|
|
+#include "gcm.h"
|
|
|
|
+#include "sgx_tcrypto.h"
|
|
|
|
+#include "clients.hpp"
|
|
|
|
|
|
|
|
+#define CEILDIV(x,y) (((x)+(y)-1)/(y))
|
|
|
|
|
|
// Split a hostport string like "127.0.0.1:12000" at the rightmost colon
|
|
// Split a hostport string like "127.0.0.1:12000" at the rightmost colon
|
|
// into a host part "127.0.0.1" and a port part "12000".
|
|
// into a host part "127.0.0.1" and a port part "12000".
|
|
@@ -59,7 +63,6 @@ static bool hextobuf(unsigned char *buf, const char *str, size_t len)
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
bool config_parse(Config &config, const std::string configstr,
|
|
bool config_parse(Config &config, const std::string configstr,
|
|
std::vector<NodeConfig> &ingestion_nodes,
|
|
std::vector<NodeConfig> &ingestion_nodes,
|
|
std::vector<NodeConfig> &storage_nodes)
|
|
std::vector<NodeConfig> &storage_nodes)
|
|
@@ -88,9 +91,9 @@ bool config_parse(Config &config, const std::string configstr,
|
|
} else if (!pentry.first.compare("pub_in")) {
|
|
} else if (!pentry.first.compare("pub_in")) {
|
|
config.m_pub_in = pentry.second.get_value<uint8_t>();
|
|
config.m_pub_in = pentry.second.get_value<uint8_t>();
|
|
// Currently hardcoding an AES key for client -> server communication
|
|
// Currently hardcoding an AES key for client -> server communication
|
|
- } else if (!pentry.first.compare("client_aes_key")) {
|
|
|
|
|
|
+ } else if (!pentry.first.compare("master_secret")) {
|
|
std::string hex_key = pentry.second.data();
|
|
std::string hex_key = pentry.second.data();
|
|
- memcpy(config.client_aes_key, hex_key.c_str(), SGX_AESGCM_KEY_SIZE);
|
|
|
|
|
|
+ memcpy(config.master_secret, hex_key.c_str(), SGX_AESGCM_KEY_SIZE);
|
|
|
|
|
|
} else {
|
|
} else {
|
|
std::cerr << "Unknown field in params: " <<
|
|
std::cerr << "Unknown field in params: " <<
|
|
@@ -155,6 +158,74 @@ static void usage(const char *argv0)
|
|
exit(1);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+
|
|
|
|
+ Generate ESK (Encryption master Secret Key) and TSK (Token master Secret Key)
|
|
|
|
+
|
|
|
|
+*/
|
|
|
|
+int generateMasterKeys(sgx_aes_gcm_128bit_key_t master_secret,
|
|
|
|
+ aes_key &ESK, aes_key &TSK )
|
|
|
|
+{
|
|
|
|
+ unsigned char zeroes[SGX_AESGCM_KEY_SIZE];
|
|
|
|
+ unsigned char iv[SGX_AESGCM_IV_SIZE];
|
|
|
|
+ unsigned char mac[SGX_AESGCM_MAC_SIZE];
|
|
|
|
+ memset(iv, 0, SGX_AESGCM_IV_SIZE);
|
|
|
|
+ memset(zeroes, 0, SGX_AESGCM_KEY_SIZE);
|
|
|
|
+ memcpy(iv, "Encryption", sizeof("Encryption"));
|
|
|
|
+
|
|
|
|
+ if (sizeof(zeroes) != gcm_encrypt(zeroes, SGX_AESGCM_KEY_SIZE, NULL, 0,
|
|
|
|
+ master_secret, iv, SGX_AESGCM_IV_SIZE, ESK, mac)) {
|
|
|
|
+ printf("Client: generateMasterKeys FAIL\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ printf("Encryption Master Key: ");
|
|
|
|
+ for(int i=0;i<SGX_AESGCM_KEY_SIZE;i++) {
|
|
|
|
+ printf("%x", ESK[i]);
|
|
|
|
+ }
|
|
|
|
+ printf("\n\n");
|
|
|
|
+
|
|
|
|
+ memset(iv, 0, SGX_AESGCM_IV_SIZE);
|
|
|
|
+ memcpy(iv, "Token", sizeof("Token"));
|
|
|
|
+ if (sizeof(zeroes) != gcm_encrypt(zeroes, SGX_AESGCM_KEY_SIZE, NULL, 0,
|
|
|
|
+ master_secret, iv, SGX_AESGCM_IV_SIZE, TSK, mac)) {
|
|
|
|
+ printf("generateMasterKeys failed\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ printf("Token Master Key: ");
|
|
|
|
+ for(int i=0;i<SGX_AESGCM_KEY_SIZE;i++) {
|
|
|
|
+ printf("%x", TSK[i]);
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ Takes the client_number, the master aes_key for generating client encryption keys,
|
|
|
|
+ and the client aes_key to be generated.
|
|
|
|
+*/
|
|
|
|
+int generateClientEncryptionKey(clientid_t client_number, aes_key &ESK, aes_key &client_key)
|
|
|
|
+{
|
|
|
|
+ unsigned char zeroes[SGX_AESGCM_KEY_SIZE];
|
|
|
|
+ unsigned char mac[SGX_AESGCM_MAC_SIZE];
|
|
|
|
+ unsigned char iv[SGX_AESGCM_IV_SIZE];
|
|
|
|
+ memset(zeroes, 0, SGX_AESGCM_KEY_SIZE);
|
|
|
|
+ memset(iv, 0, SGX_AESGCM_IV_SIZE);
|
|
|
|
+ memcpy(iv, (unsigned char*) (&client_number), sizeof(client_number));
|
|
|
|
+
|
|
|
|
+ // GCM-encrypt, using the chunk key as the associated data
|
|
|
|
+ if (sizeof(zeroes) != gcm_encrypt(zeroes, SGX_AESGCM_KEY_SIZE, NULL, 0, ESK,
|
|
|
|
+ iv, SGX_AESGCM_IV_SIZE, client_key, mac)) {
|
|
|
|
+ printf("generateClientEncryptionKey failed\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
int main(int argc, char **argv)
|
|
{
|
|
{
|
|
@@ -186,6 +257,8 @@ int main(int argc, char **argv)
|
|
std::getline(std::cin, configstr);
|
|
std::getline(std::cin, configstr);
|
|
|
|
|
|
Config config;
|
|
Config config;
|
|
|
|
+ aes_key ESK, TSK;
|
|
|
|
+ Client *clients = new Client[config.user_count];
|
|
|
|
|
|
if (!config_parse(config, configstr, ingestion_nodes, storage_nodes)) {
|
|
if (!config_parse(config, configstr, ingestion_nodes, storage_nodes)) {
|
|
exit(1);
|
|
exit(1);
|
|
@@ -194,6 +267,24 @@ int main(int argc, char **argv)
|
|
printf("Number of ingestion_nodes = %ld, Number of storage_node = %ld\n",
|
|
printf("Number of ingestion_nodes = %ld, Number of storage_node = %ld\n",
|
|
ingestion_nodes.size(), storage_nodes.size());
|
|
ingestion_nodes.size(), storage_nodes.size());
|
|
|
|
|
|
|
|
+ generateMasterKeys(config.master_secret, ESK, TSK);
|
|
|
|
+
|
|
|
|
+ uint32_t clients_per_ing = CEILDIV(config.user_count, ingestion_nodes.size());
|
|
|
|
+ aes_key client_key;
|
|
|
|
+
|
|
|
|
+ for(uint32_t i=0; i<config.user_count; i++) {
|
|
|
|
+ generateClientEncryptionKey(i, ESK, client_key);
|
|
|
|
+ clients[i].setKey(client_key);
|
|
|
|
+
|
|
|
|
+ printf("Client %d key: ", i);
|
|
|
|
+ for(int i=0;i<SGX_AESGCM_KEY_SIZE;i++) {
|
|
|
|
+ printf("%x", client_key[i]);
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /*
|
|
// Attempt sending a data packet to one of the ingestion servers
|
|
// Attempt sending a data packet to one of the ingestion servers
|
|
boost::asio::io_context io_context;
|
|
boost::asio::io_context io_context;
|
|
boost::system::error_code err;
|
|
boost::system::error_code err;
|
|
@@ -217,6 +308,28 @@ int main(int argc, char **argv)
|
|
nodenum_t node_num = 7;
|
|
nodenum_t node_num = 7;
|
|
boost::asio::write(nodesock,
|
|
boost::asio::write(nodesock,
|
|
boost::asio::buffer(&node_num, sizeof(node_num)));
|
|
boost::asio::buffer(&node_num, sizeof(node_num)));
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ int randfd = open("/dev/urandom", O_RDONLY);
|
|
|
|
+ if (randfd < 0) {
|
|
|
|
+ throw std::runtime_error("Cannot open /dev/urandom");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ unsigned char zeroes[config.msg_size];
|
|
|
|
+ unsigned char buffer[config.msg_size+4+12+16];
|
|
|
|
+ memset(zeroes, 0, sizeof(zeroes));
|
|
|
|
+ // An AES key for constructing and verifying the _plaintext_ of the blocks
|
|
|
|
+ // so that we can ensure that the blocks come out unaltered
|
|
|
|
+ unsigned char datakey[16];
|
|
|
|
+ read(randfd, datakey, 16);
|
|
|
|
+
|
|
|
|
+ // GCM-encrypt, using the chunk key as the associated data
|
|
|
|
+ if (sizeof(zeroes) != gcm_encrypt(zeroes, sizeof(zeroes), buffer, 4, datakey,
|
|
|
|
+ buffer+4, 12, buffer+4+12, buffer+4+12+sizeof(zeroes))) {
|
|
|
|
+ printf("Inner encryption failed\n");
|
|
|
|
+ }
|
|
|
|
+ */
|
|
|
|
|
|
/*
|
|
/*
|
|
Spin config.user_client actual clients. Each client:
|
|
Spin config.user_client actual clients. Each client:
|
|
@@ -226,5 +339,5 @@ int main(int argc, char **argv)
|
|
4) Repeat from 1)
|
|
4) Repeat from 1)
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+ delete [] clients;
|
|
}
|
|
}
|
|
-
|
|
|