typedef uint8_t token[SGX_AESGCM_MAC_SIZE]; typedef uint8_t aes_key[SGX_AESGCM_KEY_SIZE]; // #define VERBOSE_CLIENT /* 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, - 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. */ /* Structure for capture each individual simulated client's state */ class Client { private: // Clients' have a simulator ID sim_id used for: // (i) the simulator to divvy up clients across threads // (ii) the simulator and ingestion servers to align simulated clients // and their pre-established shared-secrets clientid_t sim_id; // The actual client id used by TEEMS is id. // Format: the first DEST_STORAGE_NODE_BITS bits store the storage node // number and the userid at that storage node in the last DEST_UID_BITS clientid_t id; aes_key key; unsigned char iv[SGX_AESGCM_IV_SIZE]; boost::asio::ip::tcp::socket *ingestion_sock = NULL; void generateAuthenticationMessage(); void generateMessageBundle(uint8_t priv_out, uint32_t msg_size, unsigned char *pt_msgbundle); bool encryptMessageBundle(uint32_t bundle_size, unsigned char *pt_msgbundle, unsigned char* enc_msgbundle); public: Client () { memset(key, 0, SGX_AESGCM_KEY_SIZE); memset(iv, 0, SGX_AESGCM_IV_SIZE); } void initClient(clientid_t cid, aes_key ckey, uint16_t num_storage_nodes, std::vector &storage_map) { sim_id = cid; uint16_t stg_no = cid % num_storage_nodes; uint16_t stg_id = storage_map[stg_no]; id = stg_id << DEST_UID_BITS; id += (cid/num_storage_nodes); printf("Client sim_id = %d, stg_id = %d, cid = %d\n", sim_id, stg_id, id); memcpy(key, ckey, SGX_AESGCM_KEY_SIZE); } bool socketReady(){ return(ingestion_sock!=NULL); } clientid_t getid(){ return id; } unsigned char* getKey(){ return ((unsigned char*) key); } void initializeSocket(boost::asio::io_context &ioc, NodeConfig &ing_server); int sendAuthMessage(); void sendMessageBundle(uint16_t priv_out, uint16_t msg_size, unsigned char *pt_msgbundle, unsigned char *enc_msgbundle); };