storage.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. #include "utils.hpp"
  2. #include "config.hpp"
  3. #include "ORExpand.hpp"
  4. #include "sort.hpp"
  5. #include "storage.hpp"
  6. #include "client.hpp"
  7. #define PROFILE_STORAGE
  8. static std::vector<StgClient> clients;
  9. static uint8_t *epoch_tokens;
  10. static uint8_t *epoch_mailboxes;
  11. static struct {
  12. uint32_t max_users;
  13. uint32_t my_storage_node_id;
  14. // A local storage buffer, used when we need to do non-in-place
  15. // sorts of the messages that have arrived
  16. MsgBuffer stg_buf;
  17. // The destination vector for ORExpand
  18. std::vector<uint32_t> dest;
  19. // The selected array for compaction during public routing
  20. // Need a bool array for compaction, and std:vector<bool> lacks .data()
  21. bool *pub_selected;
  22. } storage_state;
  23. static bool storage_generateClientKeys(uint32_t num_clients,
  24. uint32_t my_stg_no) {
  25. clients.resize(num_clients);
  26. for(uint32_t i =0; i < num_clients; i++) {
  27. uint32_t mid = storage_state.my_storage_node_id + i;
  28. clients[i].my_id = mid;
  29. clients[i].priv_friends.resize(g_teems_config.m_priv_out);
  30. // Initialize this client's private channel friends as themself
  31. for(int j = 0; j < g_teems_config.m_priv_out; j++) {
  32. (clients[i].priv_friends)[j] = mid;
  33. }
  34. }
  35. uint32_t num_stg_nodes = g_teems_config.num_storage_nodes;
  36. uint32_t c_simid = my_stg_no;
  37. for (uint32_t i=0; i<num_clients; i++) {
  38. const sgx_aes_gcm_128bit_key_t *pESK = &(g_teems_config.ESK);
  39. unsigned char zeroes[SGX_AESGCM_KEY_SIZE];
  40. unsigned char iv[SGX_AESGCM_IV_SIZE];
  41. sgx_aes_gcm_128bit_tag_t tag;
  42. memset(zeroes, 0, SGX_AESGCM_KEY_SIZE);
  43. memset(iv, 0, SGX_AESGCM_IV_SIZE);
  44. memcpy(iv, (uint8_t*) (&c_simid), sizeof(c_simid));
  45. memcpy(iv + sizeof(c_simid), "STG", sizeof("STG"));
  46. sgx_status_t ret = SGX_SUCCESS;
  47. ret = sgx_rijndael128GCM_encrypt(pESK, zeroes, SGX_AESGCM_KEY_SIZE,
  48. (uint8_t*) (clients[i].key), iv, SGX_AESGCM_IV_SIZE,
  49. NULL, 0, &tag);
  50. if(ret!=SGX_SUCCESS) {
  51. printf("stg_generateClientKeys FAIL\n");
  52. return false;
  53. }
  54. /*
  55. if(c_simid % 10 == 0) {
  56. printf("Storage: c_simid = %d, Key:", c_simid);
  57. for (int k = 0; k<SGX_AESGCM_KEY_SIZE; k++) {
  58. printf("%x", (clients[i].key)[k]);
  59. }
  60. printf("\n");
  61. }
  62. */
  63. c_simid+=num_stg_nodes;
  64. }
  65. return true;
  66. }
  67. struct UserRange {
  68. uint32_t start, num;
  69. bool ret;
  70. };
  71. static void* generate_all_tokens_launch(void *voidargs)
  72. {
  73. UserRange *args = (UserRange *)voidargs;
  74. uint32_t pt_tokens_size = (g_teems_config.m_priv_out * SGX_CMAC_MAC_SIZE);
  75. uint32_t enc_tokens_size = pt_tokens_size +
  76. SGX_AESGCM_IV_SIZE + SGX_AESGCM_MAC_SIZE;
  77. unsigned char token_body[pt_tokens_size];
  78. uint32_t user_start = args->start;
  79. uint32_t user_end = args->start + args->num;
  80. const sgx_aes_gcm_128bit_key_t *pTSK = &(g_teems_config.TSK);
  81. for(uint32_t lcid=user_start; lcid < user_end; lcid++) {
  82. unsigned char *tkn_iv_ptr = epoch_tokens + enc_tokens_size * lcid;
  83. unsigned char *tkn_ptr = tkn_iv_ptr + SGX_AESGCM_IV_SIZE;
  84. unsigned char *tkn_tag = tkn_ptr + pt_tokens_size;
  85. // We construct the plaintext [S|R|Epoch] underlying the token in
  86. // the correct location for this client in the epoch_tokens buffer
  87. // The tokens ( i.e., CMAC over S|R|Epoch) is stored in token_body
  88. // Then encrypt token_body with the client's storage key and overwrite
  89. // the correct location in epoch_tokens
  90. memset(token_body, 0, pt_tokens_size);
  91. memset(tkn_iv_ptr, 0, SGX_AESGCM_IV_SIZE);
  92. // IV = epoch_no, for encrypting the token bundle
  93. // epoch_no used is for the next epoch
  94. unsigned long epoch_val = storage_epoch + 1;
  95. memcpy(tkn_iv_ptr, &epoch_val, sizeof(epoch_val));
  96. sgx_status_t ret = SGX_SUCCESS;
  97. unsigned char *ptr = tkn_ptr;
  98. unsigned char *tkn_body_ptr = token_body;
  99. for(int i = 0; i<g_teems_config.m_priv_out; i++)
  100. {
  101. memcpy(ptr, (&(clients[lcid].my_id)), sizeof(clientid_t));
  102. memcpy(ptr + sizeof(clientid_t),
  103. (&(clients[lcid].priv_friends[i])), sizeof(clientid_t));
  104. memcpy(ptr + 2 * sizeof(clientid_t),
  105. &epoch_val, sizeof(epoch_val));
  106. ret = sgx_rijndael128_cmac_msg(pTSK, ptr, pt_tokens_size,
  107. (sgx_cmac_128bit_tag_t*) tkn_body_ptr);
  108. if(ret!=SGX_SUCCESS) {
  109. printf("generate_tokens: Creating token FAIL\n");
  110. args->ret = false;
  111. return NULL;
  112. }
  113. ptr+=SGX_CMAC_MAC_SIZE;
  114. tkn_body_ptr+=SGX_CMAC_MAC_SIZE;
  115. }
  116. /*
  117. if(lcid == 0) {
  118. printf("Checking generated token_body:");
  119. for(uint32_t i = 0; i < pt_tokens_size; i++) {
  120. printf("%x", token_body[i]);
  121. }
  122. printf("\n");
  123. }
  124. */
  125. unsigned char *cl_iv = clients[lcid].iv;
  126. ret = (sgx_rijndael128GCM_encrypt(&(clients[lcid].key),
  127. token_body, pt_tokens_size,
  128. (uint8_t*) tkn_ptr, cl_iv, SGX_AESGCM_IV_SIZE, NULL, 0,
  129. (sgx_aes_gcm_128bit_tag_t*) tkn_tag));
  130. if(ret!=SGX_SUCCESS) {
  131. printf("generate_tokens: Encrypting token FAIL\n");
  132. args->ret = false;
  133. return NULL;
  134. }
  135. memcpy(tkn_iv_ptr, cl_iv, SGX_AESGCM_IV_SIZE);
  136. // Update IV
  137. uint64_t *iv_ctr = (uint64_t*) cl_iv;
  138. (*iv_ctr)+=1;
  139. /*
  140. if(lcid == 0) {
  141. printf("Encrypted client token bundle:");
  142. for(uint32_t i = 0; i < enc_tokens_size; i++) {
  143. printf("%x", tkn_iv_ptr[i]);
  144. }
  145. printf("\n");
  146. }
  147. */
  148. }
  149. args->ret = true;
  150. return NULL;
  151. }
  152. static bool launch_all_users(void *(*launch)(void *)) {
  153. threadid_t nthreads = g_teems_config.nthreads;
  154. // Special-case nthread=1 for efficiency
  155. if (nthreads <= 1) {
  156. UserRange args = { 0, storage_state.max_users, false };
  157. return launch(&args);
  158. }
  159. UserRange args[nthreads];
  160. uint32_t inc = storage_state.max_users / nthreads;
  161. uint32_t extra = storage_state.max_users % nthreads;
  162. uint32_t last = 0;
  163. for (threadid_t i=0; i<nthreads; ++i) {
  164. uint32_t num = inc + (i < extra);
  165. args[i] = { last, num, false };
  166. last += num;
  167. }
  168. // Launch all but the first section into other threads
  169. for (threadid_t i=1; i<nthreads; ++i) {
  170. threadpool_dispatch(g_thread_id+i, launch, args+i);
  171. }
  172. // Do the first section ourselves
  173. launch(args);
  174. // Join the threads
  175. for (threadid_t i=1; i<nthreads; ++i) {
  176. threadpool_join(g_thread_id+i, NULL);
  177. }
  178. bool ret = true;
  179. for (threadid_t i=0; i<nthreads; ++i) {
  180. ret &= args[i].ret;
  181. }
  182. return ret;
  183. }
  184. bool generate_all_tokens() {
  185. return launch_all_users(generate_all_tokens_launch);
  186. }
  187. // Obliviously sanitize the given message by setting everything to 0
  188. // except the sender and receiver id, which are set to 0xffffffff,
  189. // if it is a padding message (the low DEST_UID_BITS of the receiver id
  190. // are all 1). The function is oblivious as to whether the message is a
  191. // padding message. msg_size must be a multiple of 16.
  192. // sender_id_offset should be set to 4 for private routine, or 8 for
  193. // public routing.
  194. static inline void padding_sanitize_msg(unsigned char *msg,
  195. size_t msg_size, size_t sender_id_offset)
  196. {
  197. static const uint32_t uid_mask = (1<<DEST_UID_BITS)-1;
  198. // The first 4 bytes of the message are the receiver id
  199. uint32_t receiver_id = *(uint32_t*)msg;
  200. // The message is padding if receiver_id & uid_mask == uid_mask, or
  201. // equivalently, (~receiver_id) & uid_mask == 0.
  202. // So !((~receiver_id) & uid_mask) is 1 if this is a padding
  203. // message, and 0 if not. Then (!((~receiver_id) & uid_mask))-1 is
  204. // 0 if this is a padding message, and -1 (0xffffffffffffffff) if
  205. // not. ANDing this mask with the body will do what we want: keep
  206. // it unchanged if this is not padding, and set it to 0 if it is
  207. // padding
  208. uint64_t content_mask = (!((~receiver_id) & uid_mask))-1;
  209. // Mask the first 16 bytes, which includes the 8 or 12 byte header
  210. // (depending on private or public routing). The first 4 bytes are
  211. // the destination id; set those to 0xffffffff if this is a padding
  212. // message. Set the rest of the first 16 bytes to 0 if this is a
  213. // padding message (all obliviously).
  214. *(uint32_t*)(msg) |= uint32_t(~content_mask);
  215. *(uint32_t*)(msg+4) &= uint32_t(content_mask);
  216. *(uint64_t*)(msg+8) &= content_mask;
  217. // Set the sender id to 0xffffffff if this is a padding message
  218. *(uint32_t*)(msg+sender_id_offset) |= uint32_t(~content_mask);
  219. // Set the rest of the message to 0 if this is a padding message
  220. unsigned char *msgend = msg + msg_size;
  221. for (msg = msg+16; msg<msgend; msg += 16) {
  222. *(uint64_t*)(msg) &= content_mask;
  223. *(uint64_t*)(msg+8) &= content_mask;
  224. }
  225. }
  226. /* processMsgs
  227. - Take all the messages in storage_state.stg_buf
  228. - Encrypt them all with their corresponding client key and IV and store into
  229. epoch_mailboxes
  230. */
  231. static void *processMsgs_launch(void *voidargs) {
  232. UserRange *args = (UserRange *)voidargs;
  233. uint32_t user_start = args->start;
  234. uint32_t user_end = args->start + args->num;
  235. uint32_t msg_size = g_teems_config.msg_size;
  236. uint32_t mailbox_size;
  237. size_t sender_id_offset;
  238. if (g_teems_config.private_routing) {
  239. mailbox_size = g_teems_config.m_priv_in * msg_size;
  240. sender_id_offset = 4;
  241. } else {
  242. mailbox_size = g_teems_config.m_pub_in * msg_size;
  243. sender_id_offset = 8;
  244. }
  245. uint32_t enc_mailbox_size = mailbox_size + SGX_AESGCM_IV_SIZE +
  246. SGX_AESGCM_MAC_SIZE;
  247. unsigned char *epoch_buf_ptr = epoch_mailboxes +
  248. enc_mailbox_size * user_start;
  249. unsigned char *stg_buf_ptr = storage_state.stg_buf.buf +
  250. mailbox_size * user_start;
  251. sgx_status_t ret = SGX_SUCCESS;
  252. unsigned char *epoch_buf_ct_ptr = epoch_buf_ptr + SGX_AESGCM_IV_SIZE;
  253. unsigned char *epoch_buf_tag_ptr = epoch_buf_ct_ptr + mailbox_size;
  254. for(uint32_t lcid = user_start; lcid < user_end; lcid++) {
  255. memcpy(epoch_buf_ptr, clients[lcid].iv, SGX_AESGCM_IV_SIZE);
  256. unsigned char *stg_buf_end = stg_buf_ptr + mailbox_size;
  257. for (unsigned char *msg = stg_buf_ptr; msg < stg_buf_end;
  258. msg += msg_size) {
  259. padding_sanitize_msg(msg, msg_size, sender_id_offset);
  260. }
  261. ret = sgx_rijndael128GCM_encrypt(&(clients[lcid].key), stg_buf_ptr,
  262. mailbox_size, (uint8_t*) epoch_buf_ct_ptr, epoch_buf_ptr,
  263. SGX_AESGCM_IV_SIZE, NULL, 0,
  264. (sgx_aes_gcm_128bit_tag_t*) epoch_buf_tag_ptr);
  265. if(ret!=SGX_SUCCESS) {
  266. printf("processMsgs: Encrypting msgs FAIL\n");
  267. args->ret = false;
  268. return NULL;
  269. }
  270. // Update IV
  271. uint64_t *iv_ctr = (uint64_t*) clients[lcid].iv;
  272. (*iv_ctr)+=1;
  273. /*
  274. if(lcid==0) {
  275. printf("\n\nMessage for lcid 0, S, R = %d, %d\n\n\n",
  276. *((uint32_t*) stg_buf_ptr),
  277. *((uint32_t*) (stg_buf_ptr + 4)));
  278. }
  279. */
  280. stg_buf_ptr+=mailbox_size;
  281. epoch_buf_ptr+=enc_mailbox_size;
  282. epoch_buf_ct_ptr+=enc_mailbox_size;
  283. epoch_buf_tag_ptr+=enc_mailbox_size;
  284. }
  285. args->ret = true;
  286. return NULL;
  287. }
  288. bool processMsgs() {
  289. return launch_all_users(processMsgs_launch);
  290. }
  291. // route_init will call this function; no one else should call it
  292. // explicitly. The parameter is the number of messages that can fit in
  293. // the storage-side MsgBuffer. Returns true on success, false on
  294. // failure.
  295. bool storage_init(uint32_t max_users, uint32_t msg_buf_size)
  296. {
  297. storage_state.max_users = max_users;
  298. storage_state.stg_buf.alloc(msg_buf_size);
  299. storage_state.dest.resize(msg_buf_size);
  300. storage_state.pub_selected = new bool[msg_buf_size];
  301. uint32_t my_storage_node_id = 0;
  302. uint32_t my_stg_pos = 0;
  303. for (nodenum_t i=0; i<g_teems_config.num_nodes; ++i) {
  304. if (g_teems_config.roles[i] & ROLE_STORAGE) {
  305. if (i == g_teems_config.my_node_num) {
  306. storage_state.my_storage_node_id =
  307. my_storage_node_id << DEST_UID_BITS;
  308. my_stg_pos = my_storage_node_id;
  309. } else {
  310. ++my_storage_node_id;
  311. }
  312. }
  313. }
  314. storage_generateClientKeys(max_users, my_stg_pos);
  315. return true;
  316. }
  317. void storage_close() {
  318. delete[] storage_state.pub_selected;
  319. }
  320. // Handle the messages received by a storage node. Pass a _locked_
  321. // MsgBuffer. This function will itself reset and unlock it when it's
  322. // done with it.
  323. void storage_received(MsgBuffer &storage_buf)
  324. {
  325. uint16_t msg_size = g_teems_config.msg_size;
  326. nodenum_t my_node_num = g_teems_config.my_node_num;
  327. const uint8_t *msgs = storage_buf.buf;
  328. uint32_t num_msgs = storage_buf.inserted;
  329. uint32_t real = 0, padding = 0;
  330. uint32_t uid_mask = (1 << DEST_UID_BITS) - 1;
  331. uint32_t nid_mask = ~uid_mask;
  332. #ifdef PROFILE_STORAGE
  333. unsigned long start_received =
  334. printf_with_rtclock("begin storage_received (%u)\n",
  335. storage_buf.inserted);
  336. #endif
  337. // It's OK to test for errors in a way that's non-oblivous if
  338. // there's an error (but it should be oblivious if there are no
  339. // errors)
  340. for (uint32_t i=0; i<num_msgs; ++i) {
  341. uint32_t uid = *(const uint32_t*)(storage_buf.buf+(i*msg_size));
  342. bool ok = ((((uid & nid_mask) == storage_state.my_storage_node_id)
  343. & ((uid & uid_mask) < storage_state.max_users))
  344. | ((uid & uid_mask) == uid_mask));
  345. if (!ok) {
  346. printf("Received bad uid: %08x\n", uid);
  347. assert(ok);
  348. }
  349. }
  350. // Testing: report how many real and dummy messages arrived
  351. printf("Storage server received %u messages:\n", num_msgs);
  352. for (uint32_t i=0; i<num_msgs; ++i) {
  353. uint32_t dest_addr = *(const uint32_t*)msgs;
  354. nodenum_t dest_node =
  355. g_teems_config.storage_map[dest_addr >> DEST_UID_BITS];
  356. if (dest_node != my_node_num) {
  357. char hexbuf[2*msg_size + 1];
  358. for (uint32_t j=0;j<msg_size;++j) {
  359. snprintf(hexbuf+2*j, 3, "%02x", msgs[j]);
  360. }
  361. printf("Misrouted message: %s\n", hexbuf);
  362. } else if ((dest_addr & uid_mask) == uid_mask) {
  363. ++padding;
  364. } else {
  365. ++real;
  366. }
  367. msgs += msg_size;
  368. }
  369. printf("%u real, %u padding\n", real, padding);
  370. /*
  371. for (uint32_t i=0;i<num_msgs; ++i) {
  372. printf("%3d: %08x %08x\n", i,
  373. *(uint32_t*)(storage_buf.buf+(i*msg_size)),
  374. *(uint32_t*)(storage_buf.buf+(i*msg_size+4)));
  375. }
  376. */
  377. // Sort the received messages by userid into the
  378. // storage_state.stg_buf MsgBuffer.
  379. #ifdef PROFILE_STORAGE
  380. unsigned long start_sort =
  381. printf_with_rtclock("begin oblivious sort (%u)\n",
  382. storage_buf.inserted);
  383. #endif
  384. sort_mtobliv<UidKey>(g_teems_config.nthreads, storage_buf.buf,
  385. msg_size, storage_buf.inserted, storage_buf.bufsize,
  386. storage_state.stg_buf.buf);
  387. #ifdef PROFILE_STORAGE
  388. printf_with_rtclock_diff(start_sort, "end oblivious sort (%u)\n",
  389. storage_buf.inserted);
  390. #endif
  391. // For public routing, remove excess per-user messages by making them
  392. // padding, and then compact non-padding messages.
  393. if (!g_teems_config.private_routing) {
  394. uint8_t *msg = storage_state.stg_buf.buf;
  395. uint32_t uid;
  396. uint32_t prev_uid = uid_mask; // initialization technically unnecessary
  397. uint32_t num_user_msgs = 0; // number of messages to the user
  398. uint8_t sel;
  399. for (uint32_t i=0; i<num_msgs; ++i) {
  400. uid = (*(uint32_t*) msg) & uid_mask;
  401. num_user_msgs = oselect_uint32_t(1, num_user_msgs+1,
  402. uid == prev_uid);
  403. // Select if messages per user not exceeded and msg is not padding
  404. sel = ((uint8_t) ((num_user_msgs <= g_teems_config.m_pub_in))) &
  405. ((uint8_t) uid != uid_mask);
  406. storage_state.pub_selected[i] = (bool) sel;
  407. // Make padding if not selected
  408. *(uint32_t *) msg = (*(uint32_t *) msg) & nid_mask;
  409. *(uint32_t *) msg += oselect_uint32_t(uid_mask, uid, sel);
  410. msg += msg_size;
  411. prev_uid = uid;
  412. }
  413. #ifdef PROFILE_STORAGE
  414. unsigned long start_compaction =
  415. printf_with_rtclock("begin public-channel compaction (%u)\n",
  416. num_msgs);
  417. #endif
  418. TightCompact_parallel<OSWAP_16X>(
  419. (unsigned char *) storage_state.stg_buf.buf,
  420. num_msgs, msg_size, storage_state.pub_selected,
  421. g_teems_config.nthreads);
  422. #ifdef PROFILE_STORAGE
  423. printf_with_rtclock_diff(start_compaction,
  424. "end public-channel compaction (%u)\n", num_msgs);
  425. #endif
  426. }
  427. /*
  428. for (uint32_t i=0;i<num_msgs; ++i) {
  429. printf("%3d: %08x %08x\n", i,
  430. *(uint32_t*)(storage_state.stg_buf.buf+(i*msg_size)),
  431. *(uint32_t*)(storage_state.stg_buf.buf+(i*msg_size+4)));
  432. }
  433. */
  434. #ifdef PROFILE_STORAGE
  435. unsigned long start_dest =
  436. printf_with_rtclock("begin setting dests (%u)\n",
  437. storage_state.stg_buf.bufsize);
  438. #endif
  439. // Obliviously set the dest array
  440. uint32_t *dests = storage_state.dest.data();
  441. uint32_t stg_size = storage_state.stg_buf.bufsize;
  442. uint8_t *buf = storage_state.stg_buf.buf;
  443. uint32_t m_in = g_teems_config.private_routing ?
  444. g_teems_config.m_priv_in : g_teems_config.m_pub_in;
  445. uint32_t uid = *(uint32_t*)(buf);
  446. uid &= uid_mask;
  447. // num_msgs is not a private value
  448. if (num_msgs > 0) {
  449. dests[0] = oselect_uint32_t(uid * m_in, 0xffffffff,
  450. uid == uid_mask);
  451. }
  452. uint32_t prev_uid = uid;
  453. for (uint32_t i=1; i<num_msgs; ++i) {
  454. uid = *(uint32_t*)(buf + i*msg_size);
  455. uid &= uid_mask;
  456. uint32_t next = oselect_uint32_t(uid * m_in, dests[i-1]+1,
  457. uid == prev_uid);
  458. dests[i] = oselect_uint32_t(next, 0xffffffff, uid == uid_mask);
  459. prev_uid = uid;
  460. }
  461. for (uint32_t i=num_msgs; i<stg_size; ++i) {
  462. dests[i] = 0xffffffff;
  463. *(uint32_t*)(buf + i*msg_size) = 0xffffffff;
  464. }
  465. #ifdef PROFILE_STORAGE
  466. printf_with_rtclock_diff(start_dest, "end setting dests (%u)\n", stg_size);
  467. #endif
  468. /*
  469. for (uint32_t i=0;i<stg_size; ++i) {
  470. printf("%3d: %08x %08x %08x %08x %u\n", i,
  471. *(uint32_t*)(storage_state.stg_buf.buf+(i*msg_size)),
  472. *(uint32_t*)(storage_state.stg_buf.buf+(i*msg_size+4)),
  473. *(uint32_t*)(storage_state.stg_buf.buf+(i*msg_size+8)),
  474. *(uint32_t*)(storage_state.stg_buf.buf+(i*msg_size+12)),
  475. dests[i]);
  476. }
  477. */
  478. #ifdef PROFILE_STORAGE
  479. unsigned long start_expand =
  480. printf_with_rtclock("begin ORExpand (%u)\n", stg_size);
  481. #endif
  482. ORExpand_parallel<OSWAP_16X>(storage_state.stg_buf.buf, dests,
  483. msg_size, stg_size, g_teems_config.nthreads);
  484. #ifdef PROFILE_STORAGE
  485. printf_with_rtclock_diff(start_expand, "end ORExpand (%u)\n", stg_size);
  486. #endif
  487. /*
  488. for (uint32_t i=0;i<stg_size; ++i) {
  489. printf("%3d: %08x %08x %08x %08x %u\n", i,
  490. *(uint32_t*)(storage_state.stg_buf.buf+(i*msg_size)),
  491. *(uint32_t*)(storage_state.stg_buf.buf+(i*msg_size+4)),
  492. *(uint32_t*)(storage_state.stg_buf.buf+(i*msg_size+8)),
  493. *(uint32_t*)(storage_state.stg_buf.buf+(i*msg_size+12)),
  494. dests[i]);
  495. }
  496. */
  497. // You can do more processing after these lines, as long as they
  498. // don't touch storage_buf. They _can_ touch the backing buffer
  499. // storage_state.stg_buf.
  500. storage_buf.reset();
  501. pthread_mutex_unlock(&storage_buf.mutex);
  502. if (g_teems_config.private_routing) {
  503. generate_all_tokens();
  504. }
  505. processMsgs();
  506. storage_epoch++;
  507. storage_state.stg_buf.reset();
  508. #ifdef PROFILE_STORAGE
  509. printf_with_rtclock_diff(start_received,
  510. "end storage_received (%u)\n", storage_buf.inserted);
  511. #endif
  512. }
  513. bool ecall_storage_authenticate(clientid_t cid, unsigned char *auth_message)
  514. {
  515. bool ret = false;
  516. uint32_t lcid = cid / g_teems_config.num_storage_nodes;
  517. const sgx_aes_gcm_128bit_key_t *ckey = &(clients[lcid].key);
  518. ret = authenticateClient(auth_message, ckey);
  519. if(!ret) {
  520. printf("Storage authentication FAIL\n");
  521. }
  522. return ret;
  523. }
  524. void ecall_supply_storage_buffers(unsigned char *mailboxes,
  525. uint32_t mailboxes_size, unsigned char *tokens, uint32_t tokens_size)
  526. {
  527. epoch_mailboxes = mailboxes;
  528. epoch_tokens = tokens;
  529. }