ProtobufLAInitiator.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // Knows only protobuf_sgx objects, protobuf header.
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<errno.h>
  5. #include<unistd.h>
  6. #include<stdio.h>
  7. #include"ProtobufLAMessages.pb.h"
  8. #include<google/protobuf/io/coded_stream.h>
  9. #include<google/protobuf/io/zero_copy_stream_impl.h>
  10. #include"SgxProtobufLAInitiator.h"
  11. #include"crypto.h"
  12. // For socket programming
  13. #include<arpa/inet.h>
  14. #include<sys/socket.h>
  15. #include<netinet/in.h>
  16. #include<queue>
  17. using namespace google::protobuf::io;
  18. int global_decryptor_fd;
  19. #define TOKEN_H_MAX_LENGTH 300
  20. uint8_t ciphertext_to_decryptor[4092];
  21. // TODO: Make these private functions
  22. int read_protobuf_msg_from_fd(int accept_fd, google::protobuf::MessageLite& message)
  23. {
  24. ZeroCopyInputStream* raw_input;
  25. CodedInputStream* coded_input;
  26. uint32_t size;
  27. CodedInputStream::Limit limit;
  28. raw_input = new FileInputStream(accept_fd);
  29. coded_input = new CodedInputStream(raw_input);
  30. if(!coded_input->ReadVarint32(&size))
  31. {
  32. printf("Error in reading size of msg\n");
  33. fflush(stdout);
  34. return -1;
  35. }
  36. // printf("size of msg was read to be %d \n", size);
  37. // fflush(stdout);
  38. limit = coded_input->PushLimit(size);
  39. if(!message.ParseFromCodedStream(coded_input))
  40. {
  41. printf("Error in parsing msg\n");
  42. fflush(stdout);
  43. return -1;
  44. }
  45. // printf("Done parsing msg\n"); fflush(stdout);
  46. coded_input->PopLimit(limit);
  47. return 0;
  48. }
  49. // TODO: private functions
  50. int write_protobuf_msg_to_fd(int accept_fd, google::protobuf::MessageLite& message)
  51. {
  52. ZeroCopyOutputStream* raw_output = new FileOutputStream(accept_fd);
  53. CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
  54. coded_output->WriteVarint32(message.ByteSize());
  55. if(!message.SerializeToCodedStream(coded_output))
  56. {
  57. printf("SerializeToCodedStream failed\n");
  58. fflush(stdout);
  59. return -1;
  60. }
  61. // As per this - https://stackoverflow.com/questions/22881876/protocol-buffers-how-to-serialize-and-deserialize-multiple-messages-into-a-file?noredirect=1&lq=1
  62. // TODO: There may be a better way to do this - 1) this happens with every accept now and 2) make it happen on the stack vs heap - destructor will be called on return from this function (main) and the items will then be written out. (We probably don't want that, actually)
  63. delete coded_output;
  64. delete raw_output;
  65. // fflush(stdout);
  66. return 0;
  67. }
  68. // Sets up a socket connected to the port passed as input - returns the socket FD on success and -1 on error.
  69. // Also prints the errno on error.
  70. int set_up_socket_connect(int port)
  71. {
  72. int sock = 0;
  73. if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  74. {
  75. printf("\n Error in socket call - errno is %d \n", errno);
  76. return -1;
  77. }
  78. struct sockaddr_in serv_addr;
  79. memset(&serv_addr, '0', sizeof(serv_addr));
  80. serv_addr.sin_family = AF_INET;
  81. serv_addr.sin_port = htons(port);
  82. // Convert IPv4 and IPv6 addresses from text to binary form
  83. if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
  84. {
  85. printf("\nError in inet_pton - errno is %d\n", errno);
  86. return -1;
  87. }
  88. if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
  89. {
  90. printf("\nError in connect - errno is %d \n", errno);
  91. return -1;
  92. }
  93. return sock;
  94. }
  95. int local_attestation_initiator(int port)
  96. {
  97. // declare msg1, msg2, msg3 protobuf objects
  98. protobuf_sgx_dh_msg1_t protobuf_msg1;
  99. protobuf_sgx_dh_msg2_t protobuf_msg2;
  100. protobuf_sgx_dh_msg3_t protobuf_msg3;
  101. uint32_t protobuf_sgx_ret;
  102. uint32_t session_id;
  103. int decryptor_fd;
  104. setbuf(stdout,NULL);
  105. decryptor_fd=set_up_socket_connect(port);
  106. if(decryptor_fd == -1)
  107. {
  108. perror("\nCould not set up the socket: had the following error: ");
  109. fflush(stderr);
  110. }
  111. global_decryptor_fd=decryptor_fd;
  112. // Reading msg 1 from decryptor enclave.
  113. if(read_protobuf_msg_from_fd(decryptor_fd, protobuf_msg1)!=0)
  114. return -1;
  115. // Generating message 2 given message 1 as input
  116. protobuf_sgx_ret = process_protobuf_dh_msg1_generate_protobuf_dh_msg2(protobuf_msg1, protobuf_msg2, &session_id);
  117. if(protobuf_sgx_ret != 0)
  118. {
  119. printf("Error in process_protobuf_dh_msg1_generate_protobuf_dh_msg2: 0x%x", protobuf_sgx_ret); fflush(stdout); return protobuf_sgx_ret;
  120. }
  121. // Writing msg 2 to decryptor enclave.
  122. if(write_protobuf_msg_to_fd(decryptor_fd, protobuf_msg2)!=0)
  123. return -1;
  124. // Reading msg3 from decryptor enclave
  125. if(read_protobuf_msg_from_fd(decryptor_fd, protobuf_msg3)!=0)
  126. return -1;
  127. // Process message 3
  128. protobuf_sgx_ret = process_protobuf_dh_msg3(protobuf_msg3, &session_id);
  129. if(protobuf_sgx_ret != 0)
  130. {
  131. printf("Error in process_protobuf_dh_msg3: 0x%x", protobuf_sgx_ret); fflush(stdout); return protobuf_sgx_ret;
  132. }
  133. return 0;
  134. }
  135. uint32_t post_local_attestation_get_mitigator_header(unsigned char* base64_encoded_token_H, uint32_t* base64_encoded_token_H_length)
  136. {
  137. unsigned char* encrypted_token_H_and_tag, *plaintext_token_H;
  138. uint32_t encrypted_token_H_and_tag_length, plaintext_token_H_length;
  139. protobuf_post_LA_encrypted_msg_t protobuf_encrypted_msg;
  140. uint32_t count;
  141. uint32_t internal_return_status;
  142. // Reading the encrypted token H from the
  143. if(read_protobuf_msg_from_fd(global_decryptor_fd, protobuf_encrypted_msg)!=0)
  144. {
  145. printf("Not all of the post-LA message was read\n"); fflush(stdout); return 0xfe;
  146. }
  147. std::string protobuf_encrypted_msg_string(protobuf_encrypted_msg.msg());
  148. encrypted_token_H_and_tag_length=protobuf_encrypted_msg_string.length();
  149. encrypted_token_H_and_tag = (unsigned char*) malloc(encrypted_token_H_and_tag_length);
  150. memcpy(encrypted_token_H_and_tag, protobuf_encrypted_msg_string.c_str(), protobuf_encrypted_msg_string.length());
  151. printf("Read the following encrypted token T and tag from the decryptor socket.\n"); fflush(stdout);
  152. printf("Encrypted data:\n");
  153. for(count=0; count<encrypted_token_H_and_tag_length; count++)
  154. printf("0x%02x ", encrypted_token_H_and_tag[count]);
  155. printf("\n"); fflush(stdout);
  156. plaintext_token_H=(unsigned char*) malloc(encrypted_token_H_and_tag_length);
  157. internal_return_status = aes_gcm_wrapper(0, encrypted_token_H_and_tag, encrypted_token_H_and_tag_length, plaintext_token_H, &plaintext_token_H_length);
  158. if(internal_return_status != 0)
  159. {
  160. free(encrypted_token_H_and_tag);
  161. free(plaintext_token_H);
  162. printf("Error in decryption 0x%x", internal_return_status); fflush(stdout); return internal_return_status;
  163. }
  164. printf("Decryptor's short-term public key\n");
  165. for(count=0;count<64;count++)
  166. printf("0x%02x ", plaintext_token_H[count]);
  167. printf("\n"); fflush(stdout);
  168. printf("Verifier mrenclave\n");
  169. for(count=64;count<96;count++)
  170. printf("0x%02x ", plaintext_token_H[count]);
  171. printf("\n"); fflush(stdout);
  172. *base64_encoded_token_H_length=base64_encoding_wrapper(base64_encoded_token_H, plaintext_token_H, plaintext_token_H_length);
  173. // TODO: Better return value handling.
  174. //if(!(base64_encoded_token_H_length <= 4 * Math.ceil(plaintext_token_H_length/3) && base64_encoded_token_H_length > 4 * (Math.ceil(plaintext_token_H_length/3) - 1)))
  175. //{
  176. // printf("Somehow not the entire token was encoded in base64:0x%x\n", base64_encoded_token_H_length); fflush(stdout); return 0x55;
  177. //}
  178. free(encrypted_token_H_and_tag);
  179. free(plaintext_token_H);
  180. fflush(stdout);
  181. return 0;
  182. }
  183. uint32_t base64_decoding_on_all_client_data(unsigned char* ip_base64_client_public_key_ciphertext,
  184. uint32_t ip_base64_client_public_key_ciphertext_length,
  185. unsigned char* op_client_public_key_ciphertext,
  186. uint32_t* op_client_public_key_ciphertext_length
  187. )
  188. {
  189. /* uint32_t openssl_ret_status;
  190. openssl_ret_status=base64_decoding_wrapper(ip_base64_client_public_key_ciphertext, op_client_public_key_ciphertext, ip_base64_client_public_key_ciphertext_length);
  191. if(openssl_ret_status == -1)
  192. return 0xfe;
  193. *op_client_public_key_ciphertext_length = openssl_ret_status;
  194. */
  195. return 0;
  196. }
  197. int decrypt_client_data_through_decryptor( unsigned char* ip_client_public_key_ciphertext,
  198. uint32_t ip_client_public_key_ciphertext_length,
  199. unsigned char* op_plaintext,
  200. uint32_t* op_plaintext_length
  201. )
  202. {
  203. uint32_t ciphertext_to_decryptor_length;
  204. uint32_t internal_return_status;
  205. protobuf_post_LA_encrypted_msg_t protobuf_encrypted_msg;
  206. std::string protobuf_encrypted_msg_string;
  207. uint32_t counter;
  208. // Encrypting to the decryptor enclave
  209. internal_return_status = aes_gcm_wrapper(1, ip_client_public_key_ciphertext, ip_client_public_key_ciphertext_length, ciphertext_to_decryptor, &ciphertext_to_decryptor_length );
  210. // Error checking on ciphertext that is to be sent to decryptor
  211. if(internal_return_status != 0)
  212. {
  213. printf("Error in encrypting content to the decryptor.\n"); fflush(stdout);
  214. return internal_return_status;
  215. }
  216. // write message to decryptor
  217. protobuf_encrypted_msg.set_msg( ciphertext_to_decryptor , ciphertext_to_decryptor_length );
  218. if(write_protobuf_msg_to_fd(global_decryptor_fd, protobuf_encrypted_msg)!=0)
  219. {
  220. printf("Not all of the client's pub key and ciphertext data was written\n"); fflush(stdout);
  221. return 0xfe;
  222. }
  223. // clear the message before setting it again
  224. protobuf_encrypted_msg.clear_msg();
  225. // read encrypted data
  226. if(read_protobuf_msg_from_fd(global_decryptor_fd, protobuf_encrypted_msg)!=0)
  227. {
  228. printf("Not all of the decryptor's message was read\n"); fflush(stdout);
  229. return 0xf3;
  230. }
  231. protobuf_encrypted_msg_string=std::string(protobuf_encrypted_msg.msg());
  232. // Decrypt data from decryptor
  233. internal_return_status = aes_gcm_wrapper(0, (unsigned char*) protobuf_encrypted_msg.msg().c_str(), protobuf_encrypted_msg_string.length(), op_plaintext, op_plaintext_length);
  234. return internal_return_status;
  235. }