#include "utils.hpp" #include "config.hpp" #include "ORExpand.hpp" #include "sort.hpp" #include "storage.hpp" #include "client.hpp" #define PROFILE_STORAGE StgClient *clients; uint8_t *epoch_tokens; uint8_t *epoch_mailboxes; static struct { uint32_t max_users; uint32_t my_storage_node_id; // A local storage buffer, used when we need to do non-in-place // sorts of the messages that have arrived MsgBuffer stg_buf; // The destination vector for ORExpand std::vector dest; } storage_state; bool storage_generateClientKeys(uint32_t num_clients, uint32_t my_stg_no) { uint16_t num_priv_channels = g_teems_config.m_priv_in; uint16_t msg_size = g_teems_config.msg_size; uint32_t pt_msgbundle_size = num_priv_channels * msg_size; clients = new StgClient[num_clients]; for(uint32_t i =0; i < num_clients; i++) { uint32_t mid = storage_state.my_storage_node_id + i; clients[i].my_id = mid; clients[i].priv_friends = new clientid_t[g_teems_config.m_priv_out]; // Initialize this client's private channel friends as themself for(int j =0; j start; uint32_t user_end = args->start + args->num; const sgx_aes_gcm_128bit_key_t *pTSK = &(g_teems_config.TSK); for(uint32_t lcid=user_start; lcid < user_end; lcid++) { unsigned char *tkn_iv_ptr = epoch_tokens + enc_tokens_size * lcid; unsigned char *tkn_ptr = tkn_iv_ptr + SGX_AESGCM_IV_SIZE; unsigned char *tkn_tag = tkn_ptr + pt_tokens_size; // We construct the plaintext [S|R|Epoch] underlying the token in // the correct location for this client in the epoch_tokens buffer // The tokens ( i.e., CMAC over S|R|Epoch) is stored in token_body // Then encrypt token_body with the client's storage key and overwrite // the correct location in epoch_tokens memset(token_body, 0, pt_tokens_size); memset(tkn_iv_ptr, 0, SGX_AESGCM_IV_SIZE); // IV = epoch_no, for encrypting the token bundle // epoch_no used is for the next epoch unsigned long epoch_val = storage_epoch + 1; memcpy(tkn_iv_ptr, &epoch_val, sizeof(epoch_val)); sgx_status_t ret = SGX_SUCCESS; unsigned char *ptr = tkn_ptr; unsigned char *tkn_body_ptr = token_body; for(int i = 0; iret = false; return NULL; } ptr+=SGX_CMAC_MAC_SIZE; tkn_body_ptr+=SGX_CMAC_MAC_SIZE; } /* if(lcid == 0) { printf("Checking generated token_body:"); for(uint32_t i = 0; i < pt_tokens_size; i++) { printf("%x", token_body[i]); } printf("\n"); } */ unsigned char *cl_iv = clients[lcid].iv; ret = (sgx_rijndael128GCM_encrypt(&(clients[lcid].key), token_body, pt_tokens_size, (uint8_t*) tkn_ptr, cl_iv, SGX_AESGCM_IV_SIZE, NULL, 0, (sgx_aes_gcm_128bit_tag_t*) tkn_tag)); if(ret!=SGX_SUCCESS) { printf("generate_tokens: Encrypting token FAIL\n"); args->ret = false; return NULL; } memcpy(tkn_iv_ptr, cl_iv, SGX_AESGCM_IV_SIZE); // Update IV uint64_t *iv_ctr = (uint64_t*) cl_iv; (*iv_ctr)+=1; /* if(lcid == 0) { printf("Encrypted client token bundle:"); for(uint32_t i = 0; i < enc_tokens_size; i++) { printf("%x", tkn_iv_ptr[i]); } printf("\n"); } */ } args->ret = true; return NULL; } static bool launch_all_users(void *(*launch)(void *)) { threadid_t nthreads = g_teems_config.nthreads; // Special-case nthread=1 for efficiency if (nthreads <= 1) { UserRange args = { 0, storage_state.max_users }; return launch(&args); } UserRange args[nthreads]; uint32_t inc = storage_state.max_users / nthreads; uint32_t extra = storage_state.max_users % nthreads; uint32_t last = 0; for (threadid_t i=0; istart; uint32_t user_end = args->start + args->num; uint32_t mailbox_size = g_teems_config.m_priv_in * g_teems_config.msg_size; uint32_t enc_mailbox_size = mailbox_size + SGX_AESGCM_IV_SIZE + SGX_AESGCM_MAC_SIZE; unsigned char *epoch_buf_ptr = epoch_mailboxes + enc_mailbox_size * user_start; unsigned char *stg_buf_ptr = storage_state.stg_buf.buf + mailbox_size * user_start; sgx_status_t ret = SGX_SUCCESS; unsigned char *epoch_buf_ct_ptr = epoch_buf_ptr + SGX_AESGCM_IV_SIZE; unsigned char *epoch_buf_tag_ptr = epoch_buf_ct_ptr + mailbox_size; for(uint32_t lcid = user_start; lcid < user_end; lcid++) { memcpy(epoch_buf_ptr, clients[lcid].iv, SGX_AESGCM_IV_SIZE); ret = sgx_rijndael128GCM_encrypt(&(clients[lcid].key), stg_buf_ptr, mailbox_size, (uint8_t*) epoch_buf_ct_ptr, epoch_buf_ptr, SGX_AESGCM_IV_SIZE, NULL, 0, (sgx_aes_gcm_128bit_tag_t*) epoch_buf_tag_ptr); if(ret!=SGX_SUCCESS) { printf("processMsgs: Encrypting msgs FAIL\n"); args->ret = false; return NULL; } // Update IV uint64_t *iv_ctr = (uint64_t*) clients[lcid].iv; (*iv_ctr)+=1; /* if(lcid==0) { printf("\n\nMessage for lcid 0, S, R = %d, %d\n\n\n", *((uint32_t*) stg_buf_ptr), *((uint32_t*) (stg_buf_ptr + 4))); } */ stg_buf_ptr+=mailbox_size; epoch_buf_ptr+=enc_mailbox_size; epoch_buf_ct_ptr+=enc_mailbox_size; epoch_buf_tag_ptr+=enc_mailbox_size; } args->ret = true; return NULL; } bool processMsgs() { return launch_all_users(processMsgs_launch); } // route_init will call this function; no one else should call it // explicitly. The parameter is the number of messages that can fit in // the storage-side MsgBuffer. Returns true on success, false on // failure. bool storage_init(uint32_t max_users, uint32_t msg_buf_size) { storage_state.max_users = max_users; storage_state.stg_buf.alloc(msg_buf_size); storage_state.dest.resize(msg_buf_size); uint32_t my_storage_node_id = 0; uint32_t my_stg_pos = 0; for (nodenum_t i=0; i> DEST_UID_BITS]; if (dest_node != my_node_num) { char hexbuf[2*msg_size + 1]; for (uint32_t j=0;j(g_teems_config.nthreads, storage_buf.buf, msg_size, storage_buf.inserted, storage_buf.bufsize, storage_state.stg_buf.buf); #ifdef PROFILE_STORAGE printf_with_rtclock_diff(start_sort, "end oblivious sort (%u)\n", storage_buf.inserted); #endif /* for (uint32_t i=0;i 0) { dests[0] = oselect_uint32_t(uid * m_priv_in, 0xffffffff, uid == uid_mask); } uint32_t prev_uid = uid; for (uint32_t i=1; i(storage_state.stg_buf.buf, dests, msg_size, stg_size, g_teems_config.nthreads); #ifdef PROFILE_STORAGE printf_with_rtclock_diff(start_expand, "end ORExpand (%u)\n", stg_size); #endif /* for (uint32_t i=0;i