ingest.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include <pthread.h>
  2. #include "Enclave_t.h"
  3. #include "utils.hpp"
  4. #include "config.hpp"
  5. #include "route.hpp"
  6. #include "ingest.hpp"
  7. Ingestion g_ing;
  8. bool ecall_ingest_msgbundle(clientid_t cid, unsigned char *msgbundle,
  9. uint32_t num_msgs)
  10. {
  11. bool ret;
  12. ret = g_ing.processMsgBundle(cid, msgbundle, num_msgs);
  13. return ret;
  14. }
  15. bool ecall_ingestion_authenticate(clientid_t cid, unsigned char *auth_message)
  16. {
  17. bool ret;
  18. ret = g_ing.authenticate(cid, auth_message);
  19. return ret;
  20. }
  21. void Ingestion::initialize(uint32_t num, uint32_t start,
  22. sgx_aes_gcm_128bit_key_t &ESK) {
  23. cnum = num;
  24. cstart = start;
  25. clients = new IngClient[cnum];
  26. generateClientKeys(ESK);
  27. if(g_teems_config.token_channel) {
  28. max_buffer_size = g_teems_config.m_token_out * cnum;
  29. } else {
  30. max_buffer_size = g_teems_config.m_id_out * cnum;
  31. }
  32. buffer = &(route_state.ingbuf);
  33. }
  34. bool Ingestion::authenticate(clientid_t cid, unsigned char *auth_message)
  35. {
  36. uint32_t num_ing_nodes = g_teems_config.num_ingestion_nodes;
  37. uint32_t lcid = cid / num_ing_nodes;
  38. const sgx_aes_gcm_128bit_key_t *ckey = &(clients[lcid].key);
  39. return authenticateClient(auth_message, ckey);
  40. }
  41. bool Ingestion::processMsgBundle(clientid_t cid, unsigned char *msgbundle,
  42. uint32_t num_msgs) {
  43. // Fetch corresponding client key
  44. uint32_t num_ing_nodes = g_teems_config.num_ingestion_nodes;
  45. uint32_t num_stg_nodes = g_teems_config.num_storage_nodes;
  46. clientid_t lcid = cid / num_ing_nodes;
  47. clientid_t global_client_id =
  48. ((cid % num_stg_nodes) << DEST_UID_BITS) + (cid / num_stg_nodes);
  49. sgx_aes_gcm_128bit_key_t *ckey = &(clients[lcid].key);
  50. unsigned char *iv = msgbundle;
  51. msgbundle += SGX_AESGCM_IV_SIZE;
  52. uint16_t msg_size = g_teems_config.msg_size;
  53. uint32_t msgbundle_size;
  54. if(g_teems_config.token_channel) {
  55. msgbundle_size = num_msgs * (msg_size + TOKEN_SIZE);
  56. } else {
  57. msgbundle_size = num_msgs * msg_size;
  58. }
  59. unsigned char *dec_msgbundle = (unsigned char *) malloc (msgbundle_size);
  60. sgx_aes_gcm_128bit_tag_t *tag =
  61. (sgx_aes_gcm_128bit_tag_t*) (msgbundle + msgbundle_size);
  62. sgx_status_t ret = sgx_rijndael128GCM_decrypt(ckey, msgbundle,
  63. msgbundle_size, dec_msgbundle, iv, SGX_AESGCM_IV_SIZE,
  64. NULL, 0, tag);
  65. if(ret!=SGX_SUCCESS) {
  66. printf("Ingestion::processMsgBundle FAIL\n");
  67. printf("Error code: %d", (uint32_t) ret);
  68. free(dec_msgbundle);
  69. return false;
  70. }
  71. // Force the sender ids to be set properly.
  72. // In reality, we would also set the priorities here, but for the
  73. // benchmark, we'll let the clients choose them arbitrarily.
  74. unsigned char *sid_ptr = dec_msgbundle + sizeof(clientid_t);
  75. if (!g_teems_config.token_channel) {
  76. // Leave room for the priority
  77. sid_ptr += sizeof(uint32_t);
  78. }
  79. for (uint32_t k =0; k < num_msgs; k++) {
  80. *(clientid_t*)sid_ptr = global_client_id;
  81. sid_ptr += msg_size;
  82. }
  83. // Verify the tokens from end of the msgbundle
  84. if (g_teems_config.token_channel) {
  85. unsigned char token_body[TOKEN_SIZE];
  86. const sgx_aes_gcm_128bit_key_t *pTSK = &(g_teems_config.TSK);
  87. unsigned char *dm_ptr = dec_msgbundle;
  88. unsigned char *tkn_ptr = dm_ptr + (msg_size * num_msgs);
  89. sgx_cmac_128bit_tag_t token;
  90. for (uint32_t k = 0; k < num_msgs; k++) {
  91. ret = SGX_SUCCESS;
  92. memset(token_body, 0, TOKEN_SIZE);
  93. memcpy(token_body, dm_ptr, sizeof(clientid_t) * 2);
  94. memcpy(token_body + sizeof(clientid_t) * 2,
  95. (uint8_t*) &ingestion_epoch, sizeof(ingestion_epoch));
  96. ret = sgx_rijndael128_cmac_msg(pTSK, token_body, TOKEN_SIZE,
  97. (sgx_cmac_128bit_tag_t*) &token);
  98. if(ret!=SGX_SUCCESS) {
  99. printf("Ingestion::processMsgBundle: Token recreation FAIL\n");
  100. printf("ret = %x", ret);
  101. return false;
  102. }
  103. /*
  104. printf("Received token:\n");
  105. for(int l=0; l<SGX_CMAC_MAC_SIZE; l++) {
  106. printf("%x", tkn_ptr[l]);
  107. }
  108. printf("Verify created token:\n");
  109. for(int l=0; l<SGX_CMAC_MAC_SIZE; l++) {
  110. printf("%x", token[l]);
  111. }
  112. */
  113. int diff = memcmp(token, tkn_ptr, SGX_CMAC_MAC_SIZE);
  114. if(diff!=0) {
  115. printf("Ingestion::processMsgBundle: Tokens do not match FAIL\n");
  116. return false;
  117. }
  118. dm_ptr+= msg_size;
  119. tkn_ptr+=SGX_CMAC_MAC_SIZE;
  120. }
  121. }
  122. // Append msgbundle to g_ing.buffer
  123. MsgBuffer &msg_queue = *(g_ing.buffer);
  124. pthread_mutex_lock(&msg_queue.mutex);
  125. uint32_t head = msg_queue.reserved;
  126. if (head + num_msgs > g_ing.max_buffer_size) {
  127. pthread_mutex_unlock(&msg_queue.mutex);
  128. printf("Ingestions: Max %u messages exceeded\n",
  129. g_ing.max_buffer_size);
  130. return false;
  131. }
  132. msg_queue.reserved += num_msgs;
  133. pthread_mutex_unlock(&msg_queue.mutex);
  134. memmove(msg_queue.buf + head * msg_size,
  135. dec_msgbundle, num_msgs * msg_size);
  136. pthread_mutex_lock(&msg_queue.mutex);
  137. msg_queue.inserted += num_msgs;
  138. pthread_mutex_unlock(&msg_queue.mutex);
  139. free(dec_msgbundle);
  140. return true;
  141. }
  142. void Ingestion::generateClientKeys(sgx_aes_gcm_128bit_key_t &ESK)
  143. {
  144. //printf("In Ingestion::genCK, num_clients = %d, client_start = %d, client_end = %d\n",
  145. // cnum, cstart, cnum + cstart);
  146. uint32_t num_ing_nodes = g_teems_config.num_ingestion_nodes;
  147. for(uint32_t i=0; i<cnum; i++)
  148. {
  149. unsigned char zeroes[SGX_AESGCM_KEY_SIZE];
  150. unsigned char iv[SGX_AESGCM_IV_SIZE];
  151. sgx_aes_gcm_128bit_tag_t tag;
  152. memset(zeroes, 0, SGX_AESGCM_KEY_SIZE);
  153. memset(iv, 0, SGX_AESGCM_IV_SIZE);
  154. uint32_t client_num = cstart + (i * num_ing_nodes);
  155. memcpy(iv, (uint8_t*) (&client_num), sizeof(client_num));
  156. sgx_status_t ret = SGX_SUCCESS;
  157. ret = sgx_rijndael128GCM_encrypt((const sgx_aes_gcm_128bit_key_t *) (ESK),
  158. zeroes, SGX_AESGCM_KEY_SIZE, (uint8_t*) (clients[i].key), iv,
  159. SGX_AESGCM_IV_SIZE, NULL, 0, &tag);
  160. if(ret!=SGX_SUCCESS) {
  161. printf("Ingestion::GCM FAIL\n");
  162. }
  163. /*
  164. printf("Client %d Ingestion: (after Gen) ", client_num);
  165. for(int j=0;j<SGX_AESGCM_KEY_SIZE;j++) {
  166. printf("%x", (clients[i].key)[j]);
  167. }
  168. printf("\n");
  169. */
  170. }
  171. }
  172. sgx_aes_gcm_128bit_key_t* Ingestion::getClientKey(uint32_t lcid)
  173. {
  174. return(&(clients[lcid].key));
  175. }