ingest.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. void displayMessage(unsigned char *msg, uint16_t msg_size) {
  9. clientid_t sid, rid;
  10. unsigned char *ptr = msg;
  11. sid = *((clientid_t*) ptr);
  12. ptr+=sizeof(sid);
  13. rid = *((clientid_t*) ptr);
  14. ptr+=sizeof(rid);
  15. printf("Sender ID: %d, Receiver ID: %d, Token: N/A\n", sid, rid );
  16. printf("Message: ");
  17. for(int j = 0; j<msg_size - sizeof(sid)*2; j++) {
  18. printf("%x", (*ptr));
  19. ptr++;
  20. }
  21. printf("\n");
  22. }
  23. void displayEncMessageBundle(unsigned char *bundle, uint16_t priv_out, uint16_t msg_size) {
  24. unsigned char *ptr = bundle;
  25. printf("IV: ");
  26. for(int i=0; i<SGX_AESGCM_IV_SIZE; i++) {
  27. printf("%x", ptr[i]);
  28. }
  29. printf("\n");
  30. ptr+= SGX_AESGCM_IV_SIZE;
  31. for(int i=0; i<priv_out; i++) {
  32. displayMessage(ptr, msg_size);
  33. ptr+=msg_size;
  34. }
  35. printf("MAC: ");
  36. for(int i=0; i<SGX_AESGCM_MAC_SIZE; i++) {
  37. printf("%x", ptr[i]);
  38. }
  39. printf("\n");
  40. }
  41. bool ecall_ingest_msgbundle(clientid_t cid, unsigned char *msgbundle,
  42. uint32_t num_msgs)
  43. {
  44. bool ret;
  45. ret = g_ing.processMsgBundle(cid, msgbundle, num_msgs);
  46. return ret;
  47. }
  48. bool ecall_ingestion_authenticate(clientid_t cid, unsigned char *auth_message)
  49. {
  50. bool ret;
  51. ret = g_ing.authenticate(cid, auth_message);
  52. return ret;
  53. }
  54. void Ingestion::initialize(uint32_t num, uint32_t start, sgx_aes_gcm_128bit_key_t &ESK) {
  55. cnum = num;
  56. cstart = start;
  57. clients = new IngClient[cnum];
  58. generateClientKeys(ESK);
  59. if(g_teems_config.private_routing) {
  60. max_buffer_size = g_teems_config.m_priv_out * cnum;
  61. } else {
  62. max_buffer_size = g_teems_config.m_pub_out * cnum;
  63. }
  64. buffer = &(route_state.ingbuf);
  65. }
  66. bool Ingestion::authenticate(clientid_t cid, unsigned char *auth_message)
  67. {
  68. uint32_t num_ing_nodes = g_teems_config.num_ingestion_nodes;
  69. uint32_t lcid = cid / num_ing_nodes;
  70. const sgx_aes_gcm_128bit_key_t *ckey = &(clients[lcid].key);
  71. return(authenticateClient(auth_message, ckey));
  72. }
  73. bool Ingestion::processMsgBundle(clientid_t cid, unsigned char *msgbundle,
  74. uint32_t num_msgs) {
  75. // Fetch corresponding client key
  76. uint32_t num_ing_nodes = g_teems_config.num_ingestion_nodes;
  77. clientid_t lcid = cid / num_ing_nodes;
  78. sgx_aes_gcm_128bit_key_t *ckey = &(clients[lcid].key);
  79. unsigned char *iv = msgbundle;
  80. msgbundle += SGX_AESGCM_IV_SIZE;
  81. uint16_t msg_size = g_teems_config.msg_size;
  82. uint32_t msgbundle_size;
  83. if(g_teems_config.private_routing) {
  84. msgbundle_size = num_msgs * (msg_size + TOKEN_SIZE);
  85. } else {
  86. msgbundle_size = num_msgs * msg_size;
  87. }
  88. unsigned char *dec_msgbundle = (unsigned char *) malloc (msgbundle_size);
  89. sgx_aes_gcm_128bit_tag_t *tag = (sgx_aes_gcm_128bit_tag_t*) (msgbundle + msgbundle_size);
  90. sgx_status_t ret = sgx_rijndael128GCM_decrypt(ckey, msgbundle, msgbundle_size,
  91. dec_msgbundle, iv, SGX_AESGCM_IV_SIZE, NULL, 0, tag);
  92. if(ret!=SGX_SUCCESS) {
  93. printf("Ingestion::processMsgBundle FAIL\n");
  94. printf("Error code: %d", (uint32_t) ret);
  95. free(dec_msgbundle);
  96. return false;
  97. }
  98. // TODO: Verify the tokens from end of the msgbundle
  99. // before appending them into the MsgBuffer
  100. bool verified = true;
  101. if(g_teems_config.private_routing) {
  102. unsigned char token_body[TOKEN_SIZE];
  103. const sgx_aes_gcm_128bit_key_t *pTSK = &(g_teems_config.TSK);
  104. unsigned char *dm_ptr = dec_msgbundle;
  105. unsigned char *tkn_ptr = dm_ptr + (msg_size * num_msgs);
  106. sgx_cmac_state_handle_t cmac_handle;
  107. sgx_cmac_128bit_tag_t token;
  108. for(int k =0; k < num_msgs; k++)
  109. {
  110. ret = SGX_SUCCESS;
  111. memset(token_body, 0, TOKEN_SIZE);
  112. memcpy(token_body, dm_ptr, sizeof(clientid_t) * 2);
  113. memcpy(token_body + sizeof(clientid_t) * 2, (uint8_t*) &ingestion_epoch, sizeof(ingestion_epoch));
  114. ret = sgx_rijndael128_cmac_msg(pTSK, token_body, TOKEN_SIZE,
  115. (sgx_cmac_128bit_tag_t*) &token);
  116. if(ret!=SGX_SUCCESS) {
  117. printf("Ingestion::processMsgBundle: Token recreation FAIL\n");
  118. printf("ret = %x", ret);
  119. return false;
  120. }
  121. /*
  122. printf("Received token:\n");
  123. for(int l=0; l<SGX_CMAC_MAC_SIZE; l++) {
  124. printf("%x", tkn_ptr[l]);
  125. }
  126. printf("Verify created token:\n");
  127. for(int l=0; l<SGX_CMAC_MAC_SIZE; l++) {
  128. printf("%x", token[l]);
  129. }
  130. */
  131. int diff = memcmp(token, tkn_ptr, SGX_CMAC_MAC_SIZE);
  132. if(diff!=0) {
  133. printf("Ingestion::processMsgBundle: Tokens do not match FAIL\n");
  134. return false;
  135. }
  136. dm_ptr+= msg_size;
  137. tkn_ptr+=SGX_CMAC_MAC_SIZE;
  138. }
  139. }
  140. if(verified) {
  141. // Append msgbundle to g_ing.buffer;
  142. MsgBuffer &msg_queue = *(g_ing.buffer);
  143. pthread_mutex_lock(&msg_queue.mutex);
  144. uint32_t head = msg_queue.reserved;
  145. if (head + num_msgs > g_ing.max_buffer_size) {
  146. pthread_mutex_unlock(&msg_queue.mutex);
  147. printf("Ingestions: Max %u messages exceeded\n",
  148. g_ing.max_buffer_size);
  149. return false;
  150. }
  151. msg_queue.reserved += num_msgs;
  152. pthread_mutex_unlock(&msg_queue.mutex);
  153. memmove(msg_queue.buf + head * msg_size,
  154. dec_msgbundle, num_msgs * msg_size);
  155. pthread_mutex_lock(&msg_queue.mutex);
  156. msg_queue.inserted += num_msgs;
  157. pthread_mutex_unlock(&msg_queue.mutex);
  158. free(dec_msgbundle);
  159. return true;
  160. }
  161. return false;
  162. }
  163. void Ingestion::generateClientKeys(sgx_aes_gcm_128bit_key_t &ESK)
  164. {
  165. //printf("In Ingestion::genCK, num_clients = %d, client_start = %d, client_end = %d\n",
  166. // cnum, cstart, cnum + cstart);
  167. uint32_t num_ing_nodes = g_teems_config.num_ingestion_nodes;
  168. for(uint32_t i=0; i<cnum; i++)
  169. {
  170. unsigned char zeroes[SGX_AESGCM_KEY_SIZE];
  171. unsigned char iv[SGX_AESGCM_IV_SIZE];
  172. sgx_aes_gcm_128bit_tag_t tag;
  173. memset(zeroes, 0, SGX_AESGCM_KEY_SIZE);
  174. memset(iv, 0, SGX_AESGCM_IV_SIZE);
  175. uint32_t client_num = cstart + (i * num_ing_nodes);
  176. memcpy(iv, (uint8_t*) (&client_num), sizeof(client_num));
  177. sgx_status_t ret = SGX_SUCCESS;
  178. ret = sgx_rijndael128GCM_encrypt((const sgx_aes_gcm_128bit_key_t *) (ESK),
  179. zeroes, SGX_AESGCM_KEY_SIZE, (uint8_t*) (clients[i].key), iv,
  180. SGX_AESGCM_IV_SIZE, NULL, 0, &tag);
  181. if(ret!=SGX_SUCCESS) {
  182. printf("Ingestion::GCK FAIL\n");
  183. }
  184. /*
  185. printf("Client %d Ingestion: (after Gen) ", client_num);
  186. for(int j=0;j<SGX_AESGCM_KEY_SIZE;j++) {
  187. printf("%x", (clients[i].key)[j]);
  188. }
  189. printf("\n");
  190. */
  191. }
  192. }
  193. sgx_aes_gcm_128bit_key_t* Ingestion::getClientKey(uint32_t lcid)
  194. {
  195. return(&(clients[lcid].key));
  196. }