Browse Source

Clients authenticate with epoch number as IV. Client messages (both authenticate and message_bundles) no longer use headers

Sajin Sasy 1 year ago
parent
commit
c762dc289c
6 changed files with 72 additions and 122 deletions
  1. 21 56
      App/net.cpp
  2. 1 1
      App/net.hpp
  3. 1 1
      App/start.cpp
  4. 32 33
      Client/clients.cpp
  5. 10 26
      Client/clients.hpp
  6. 7 5
      Enclave/ingest.cpp

+ 21 - 56
App/net.cpp

@@ -176,12 +176,12 @@ void NodeIO::recv_commands(
     Receive clients dropped off messages, i.e. a CLIENT_MESSAGE_BUNDLE
 */
 
-void NetIO::receive_msgbundle(tcp::socket* csocket)
+void NetIO::receive_msgbundle(tcp::socket* csocket, clientid_t c_simid)
 {
-    // Read header (1 uint64_t) from the socket and extract the client ID
-    size_t *header = new size_t;
-    boost::asio::async_read(*csocket, boost::asio::buffer(header, sizeof(size_t)),
-        [this, csocket, header]
+    unsigned char *msgbundle = (unsigned char*) malloc(msgbundle_size);
+
+    boost::asio::async_read(*csocket, boost::asio::buffer(msgbundle, msgbundle_size),
+        [this, csocket, msgbundle, c_simid]
         (boost::system::error_code ec, std::size_t) {
         if (ec) {
             if(ec == boost::asio::error::eof) {
@@ -194,34 +194,12 @@ void NetIO::receive_msgbundle(tcp::socket* csocket)
             return;
         }
 
-        if((*header & 0xff) == CLIENT_MESSAGE_BUNDLE) {
-            clientid_t cid = (clientid_t)(*header >> 8);
-            // Read the authentication token
-            delete(header);
-            unsigned char *msgbundle = (unsigned char*) malloc(msgbundle_size);
-
-            boost::asio::async_read(*csocket, boost::asio::buffer(msgbundle, msgbundle_size),
-                [this, csocket, msgbundle, cid]
-                (boost::system::error_code ecc, std::size_t) {
-                if (ecc) {
-                    if(ecc == boost::asio::error::eof) {
-                        // Client connection terminated so we delete this socket
-                        delete(csocket);
-                    }
-                    else {
-                        printf("Error %s\n", ecc.message().c_str());
-                    }
-                    return;
-                }
-
-                //Ingest the message_bundle
-                bool ret = ecall_ingest_msgbundle(cid, msgbundle, apiparams.m_priv_out);
-                free(msgbundle);
-            });
+        //Ingest the message_bundle
+        bool ret = ecall_ingest_msgbundle(c_simid, msgbundle, apiparams.m_priv_out);
+        free(msgbundle);
 
         // Continue to async receive client message bundles
-        receive_msgbundle(csocket);
-        }
+        receive_msgbundle(csocket, c_simid);
     });
 }
 
@@ -241,11 +219,9 @@ void NetIO::authenticate_new_client(tcp::socket* csocket,
 #ifdef DEBUG_NET_CLIENTS
         printf("Accept handler success\n");
 #endif
-
-    // Read header (1 uint64_t) from the socket and extract the client ID
-    size_t *header = new size_t;
-    boost::asio::async_read(*csocket, boost::asio::buffer(header, sizeof(size_t)),
-        [this, csocket, header]
+    unsigned char* auth_message = (unsigned char*) malloc(auth_size);
+    boost::asio::async_read(*csocket, boost::asio::buffer(auth_message, auth_size),
+        [this, csocket, auth_message]
         (boost::system::error_code ec, std::size_t) {
         if (ec) {
             if(ec == boost::asio::error::eof) {
@@ -257,27 +233,15 @@ void NetIO::authenticate_new_client(tcp::socket* csocket,
             return;
         }
         else {
-            if((*header & 0xff) == CLIENT_AUTHENTICATE) {
-                clientid_t cid = (clientid_t)(*header >> 8);
-                // Read the authentication token
-                unsigned char* auth_string = (unsigned char*) malloc(auth_size);
-                delete(header);
-
-                boost::asio::async_read(*csocket, boost::asio::buffer(auth_string, auth_size),
-                    [this, csocket, auth_string, cid]
-                    (boost::system::error_code ecn, std::size_t) {
-                    if (ecn) {
-                        printf("Error %s\n", ecn.message().c_str());
-                        return;
-                    }
-
-                    bool ret = ecall_authenticate(cid, auth_string);
-                    free(auth_string);
-                });
+            clientid_t c_simid = *((clientid_t *)(auth_message));
+            // Read the authentication token
+            unsigned char *auth_ptr = auth_message + sizeof(clientid_t);
+            bool ret = ecall_authenticate(c_simid, auth_ptr);
+            free(auth_message);
 
             // Receive client message bundles on this socket
-            receive_msgbundle(csocket);
-            }
+            // for client sim_id c_simid
+            receive_msgbundle(csocket, c_simid);
         }
     });
     start_accept();
@@ -368,13 +332,14 @@ NetIO::NetIO(boost::asio::io_context &io_context, const Config &config)
 #endif
     }
 
+
     if(myconf.roles & ROLE_INGESTION) {
         client_acceptor = std::shared_ptr<tcp::acceptor>(
             new tcp::acceptor(io_context,
                 resolver.resolve(this->myconf.clistenhost,
                 this->myconf.clistenport)->endpoint()));
 
-        auth_size = SGX_AESGCM_MAC_SIZE;
+        auth_size = sizeof(clientid_t) + sizeof(unsigned long) + SGX_AESGCM_KEY_SIZE;
         msgbundle_size = SGX_AESGCM_IV_SIZE +
             (apiparams.m_priv_out * apiparams.msg_size) + SGX_AESGCM_MAC_SIZE;
         start_accept();

+ 1 - 1
App/net.hpp

@@ -131,7 +131,7 @@ class NetIO {
     std::deque<std::optional<NodeIO>> nodeios;
     std::shared_ptr<tcp::acceptor> client_acceptor;
 
-    void receive_msgbundle(tcp::socket* socket);
+    void receive_msgbundle(tcp::socket* socket, clientid_t c_simid);
     void authenticate_new_client(tcp::socket* socket,
         const boost::system::error_code& error);
     void start_accept();

+ 1 - 1
App/start.cpp

@@ -173,7 +173,7 @@ static void route_clients_test(NetIO &netio)
         printf("Epoch time: %lu.%06lu s\n", diff/1000000, diff%1000000);
 
         // Sleep for the rest of the epoch interval
-        if (diff < EPOCH_INTERVAL) {
+        if (diff < EPOCH_INTERVAL && i!=0) {
             usleep(EPOCH_INTERVAL - (useconds_t) diff);
         }
     }

+ 32 - 33
Client/clients.cpp

@@ -118,12 +118,11 @@ void displayEncMessageBundle(unsigned char *bundle, uint16_t priv_out, uint16_t
 }
 
 
-#define HEADER_SIZE 8
 static inline uint32_t encMsgBundleSize(uint16_t priv_out, uint16_t msg_size) {
-    return(HEADER_SIZE + SGX_AESGCM_IV_SIZE + (priv_out * msg_size) + SGX_AESGCM_MAC_SIZE);
+    return(SGX_AESGCM_IV_SIZE + (priv_out * msg_size) + SGX_AESGCM_MAC_SIZE);
 }
 static inline uint32_t ptMsgBundleSize(uint16_t priv_out, uint16_t msg_size) {
-    return(HEADER_SIZE + (priv_out * msg_size));
+    return((priv_out * msg_size));
 }
 
 bool config_parse(Config &config, const std::string configstr,
@@ -329,7 +328,7 @@ void Client::initializeSocket(boost::asio::io_context &ioc,
                 ing_server.clistenport), err);
         if (!err) break;
         std::cerr << "Connection to " << ing_server.name <<
-            " refused, will retry.\n";
+            " refused, will , epoch_noretry.\n";
         sleep(1);
     }
 }
@@ -346,11 +345,6 @@ void Client::generateMessageBundle(uint8_t priv_out, uint32_t msg_size,
     unsigned char *pt_msgbundle)
 {
     unsigned char *ptr = pt_msgbundle;
-    uint64_t header = (sim_id << 8) + CLIENT_MESSAGE_BUNDLE;
-
-    // Setup header
-    memcpy(ptr, (uint8_t*) &header, sizeof(header));
-    ptr+=sizeof(header);
 
     // Setup message pt_msgbundle
     for(uint32_t i = 0; i < priv_out; i++) {
@@ -370,23 +364,19 @@ void Client::generateMessageBundle(uint8_t priv_out, uint32_t msg_size,
 bool Client::encryptMessageBundle(uint32_t enc_bundle_size, unsigned char *pt_msgbundle,
     unsigned char *enc_msgbundle)
 {
-    // Copy the header
-    memcpy(enc_msgbundle, pt_msgbundle, HEADER_SIZE);
-
-    // Encrypt the rest of the pt_msgbundle
-    unsigned char *pt_msgbundle_start = pt_msgbundle + HEADER_SIZE;
-    unsigned char *enc_msgbundle_start = enc_msgbundle + HEADER_SIZE + SGX_AESGCM_IV_SIZE;
+    // Encrypt the pt_msgbundle
+    unsigned char *pt_msgbundle_start = pt_msgbundle;
+    unsigned char *enc_msgbundle_start = enc_msgbundle + SGX_AESGCM_IV_SIZE;
     unsigned char *enc_tag = enc_msgbundle + enc_bundle_size - SGX_AESGCM_MAC_SIZE;
-    size_t bytes_to_encrypt = enc_bundle_size - SGX_AESGCM_MAC_SIZE - HEADER_SIZE - SGX_AESGCM_IV_SIZE;
+    size_t bytes_to_encrypt = enc_bundle_size - SGX_AESGCM_MAC_SIZE - SGX_AESGCM_IV_SIZE;
     if (bytes_to_encrypt != gcm_encrypt(pt_msgbundle_start, bytes_to_encrypt,
         NULL, 0, key, iv, SGX_AESGCM_IV_SIZE, enc_msgbundle_start, enc_tag)) {
             printf("Client: encryptMessageBundle FAIL\n");
             return 0;
     }
 
-    // Copy the IV into the bundle
-    unsigned char *enc_msgbundle_iv = enc_msgbundle + HEADER_SIZE;
-    memcpy(enc_msgbundle_iv, iv, SGX_AESGCM_IV_SIZE);
+    // Copy IV into the bundle
+    memcpy(enc_msgbundle, iv, SGX_AESGCM_IV_SIZE);
 
     // Update IV
     uint64_t *iv_ctr = (uint64_t*) iv;
@@ -412,20 +402,21 @@ void Client::sendMessageBundle(uint16_t priv_out, uint16_t msg_size,
     displayPtMessageBundle(pt_msgbundle, priv_out, msg_size);
 #endif
 
-    //displayEncMessageBundle(enc_msgbundle, priv_out, msg_size);
-
     boost::asio::write(*ingestion_sock,
         boost::asio::buffer(enc_msgbundle, enc_bundle_size));
 }
 
-int Client::sendAuthMessage()
+int Client::sendAuthMessage(unsigned long epoch_no)
 {
-    uint32_t auth_size = sizeof(uint64_t) + SGX_AESGCM_KEY_SIZE;
-    unsigned char *auth_string = (unsigned char*) malloc(auth_size);
-    unsigned char *as_ptr = auth_string;
-    uint64_t header = (sim_id << 8) + CLIENT_AUTHENTICATE;
-    memcpy(as_ptr, &header, sizeof(header));
-    as_ptr+=sizeof(header);
+    uint32_t auth_size = sizeof(clientid_t) + sizeof(unsigned long) + SGX_AESGCM_KEY_SIZE;
+    unsigned char *auth_message = (unsigned char*) malloc(auth_size);
+    unsigned char *am_ptr = auth_message;
+
+    memcpy(am_ptr, &sim_id, sizeof(sim_id));
+    am_ptr+=sizeof(sim_id);
+
+    memcpy(am_ptr, &epoch_no, sizeof(unsigned long));
+    am_ptr+=sizeof(unsigned long);
 
     unsigned char zeroes[SGX_AESGCM_KEY_SIZE];
     unsigned char tag[SGX_AESGCM_MAC_SIZE];
@@ -434,7 +425,7 @@ int Client::sendAuthMessage()
     memset(tag, 0, SGX_AESGCM_KEY_SIZE);
 
     if (sizeof(zeroes) != gcm_encrypt(zeroes, SGX_AESGCM_KEY_SIZE, NULL, 0, key,
-            iv, SGX_AESGCM_IV_SIZE, as_ptr, tag)) {
+            (unsigned char*) &epoch_no, sizeof(epoch_no), am_ptr, tag)) {
         printf("generateClientEncryptionKey failed\n");
         return -1;
     }
@@ -444,15 +435,15 @@ int Client::sendAuthMessage()
     (*iv_ctr)+=1;
 
 #ifdef VERBOSE_CLIENT
-    printf("Client %d auth_string: \n", id);
+    printf("Client %d auth_message: \n", id);
     for(int i=0; i<auth_size; i++) {
-        printf("%x", auth_string[i]);
+        printf("%x", auth_message[i]);
     }
     printf("\n");
 #endif
 
     boost::asio::write(*ingestion_sock,
-        boost::asio::buffer(auth_string, auth_size));
+        boost::asio::buffer(auth_message, auth_size));
 
     return 1;
 }
@@ -479,7 +470,6 @@ void generateClients(boost::asio::io_context &io_context,
         clients[i].initClient(i, client_key, num_stg_nodes, storage_map);
 
         clients[i].initializeSocket(io_context, ingestion_nodes[ing_node_this_client]);
-        clients[i].sendAuthMessage();
 
         /*
         // Test that the keys generated match those generated within
@@ -493,6 +483,15 @@ void generateClients(boost::asio::io_context &io_context,
         printf("\n\n");
         */
     }
+
+    struct timespec ep;
+    clock_gettime(CLOCK_REALTIME_COARSE, &ep);
+    unsigned long ep_time = ep.tv_sec * 1000000 + ep.tv_nsec/1000;
+    unsigned long epoch_no = CEILDIV(ep_time, EPOCH_INTERVAL);
+
+    for(uint32_t i=cstart; i<cstop; i++) {
+        clients[i].sendAuthMessage(epoch_no);
+    }
 }
 
 

+ 10 - 26
Client/clients.hpp

@@ -7,32 +7,16 @@ typedef uint8_t aes_key[SGX_AESGCM_KEY_SIZE];
 
   Client -> Ingestion Server (C->I) communication protocols:
 
-  Each client has a 4-byte Client ID (id). Client(C) and ingestion servers(I)
-  are bootstrapped with a shared secret key (K). Clients messages to the
-  ingestion server have an 8-byte header followed by some data. There are
-  two types of client messages for C->I communications:
-
-  1) CLIENT_AUTHENTICATE:
-      Header: (0x00 + 4-byte Client ID)
-      Body: HMAC(K, epoch_number)
-      - where MAC is a Keyed MAC with the shared secret key K
-        over the epoch number.
-
-  2) CLIENT_MESSAGE_BUNDLE:
-      Header: (0x01 + 4-byte Client ID)
-      Body: CMP
-      - where CMP = Client Message Payload is
-        IV, AESGCM([CM_1], [CM_2], ..., [CM_k]), TAG
-        with k being the maximum number of messages a client can send in an
-        epoch, and IV and TAG are the AESGCM IV and TAG for that CMP.
-      - each CM = Client Message, has the format:
-        4-byte Sender ID , 4-byte Recipient ID, 16-byte Token,
-        <Upto msg_size - 24> - bytes of message data
-     -NOTE: This will eventually expand to accomodate Token manipulation
-      component of clients' messages as well.
-
-  Headers are stored as the low 5 bytes of a uint64_t.
+  1) Authentication
+     Format: Client sim_id, Epoch number, Authentication token
 
+  2) Messages
+     Format: IV, AESGCM([CM_1], [CM_2], ..., [CM_k]), TAG
+      - each CM = Client Message for private channel has the format :
+        4-byte Sender ID, 4-byte Recipient ID, 16-byte Token,
+        <Upto msg_size - 24> - bytes of message data
+        where the Sender ID and Recipient ID are the TEEMS client id
+        (and not sim_id)
 */
 
 
@@ -99,7 +83,7 @@ public:
 
     void initializeSocket(boost::asio::io_context &ioc, NodeConfig &ing_server);
 
-    int sendAuthMessage();
+    int sendAuthMessage(unsigned long epoch_no);
 
     void sendMessageBundle(uint16_t priv_out, uint16_t msg_size,
          unsigned char *pt_msgbundle, unsigned char *enc_msgbundle);

+ 7 - 5
Enclave/ingest.cpp

@@ -52,10 +52,10 @@ bool ecall_ingest_msgbundle(clientid_t cid, unsigned char *msgbundle,
     return ret;
 }
 
-bool ecall_authenticate(clientid_t cid, unsigned char *auth_string)
+bool ecall_authenticate(clientid_t cid, unsigned char *auth_message)
 {
     bool ret;
-    ret = g_ing.authenticate(cid, auth_string);
+    ret = g_ing.authenticate(cid, auth_message);
     return ret;
 }
 
@@ -70,9 +70,11 @@ void Ingestion::initialize(uint32_t cnum, uint32_t cstart, sgx_aes_gcm_128bit_ke
     buffer = &(route_state.ingbuf);
 }
 
-bool Ingestion::authenticate(clientid_t cid, unsigned char *auth_string)
+bool Ingestion::authenticate(clientid_t cid, unsigned char *auth_message)
 {
     int auth_success = 0;
+    unsigned long epoch_no = *((unsigned long*) auth_message);
+    auth_message+=(sizeof(unsigned long));
     // Fetch corresponding client key
     clientid_t lcid = cid - g_ing.clients.start;
     sgx_aes_gcm_128bit_key_t &ckey = (g_ing.clients).keys[lcid];
@@ -86,12 +88,12 @@ bool Ingestion::authenticate(clientid_t cid, unsigned char *auth_string)
     sgx_status_t ret = SGX_SUCCESS;
 
     ret = sgx_rijndael128GCM_encrypt(&ckey, zeroes, SGX_AESGCM_KEY_SIZE,
-        computed_auth, iv, SGX_AESGCM_IV_SIZE, NULL, 0, &mac);
+        computed_auth, (unsigned char*) (&epoch_no), sizeof(epoch_no), NULL, 0, &mac);
     if(ret!=SGX_SUCCESS) {
         return -1;
     }
 
-    auth_success = memcmp(auth_string, computed_auth, SGX_AESGCM_KEY_SIZE);
+    auth_success = memcmp(auth_message, computed_auth, SGX_AESGCM_KEY_SIZE);
 
     if(auth_success == 0) {
         return true;