Browse Source

Refactored LA code that is outside the enclave

dettanym 5 years ago
parent
commit
74ba6f2f7f

+ 69 - 622
App/App.cpp

@@ -28,22 +28,22 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.challa
  *
  */
-
+/*
 #define SGX_DH_MAC_SIZE 16
 #define SGX_TARGET_INFO_RESERVED1_BYTES 4
 #define SGX_TARGET_INFO_RESERVED2_BYTES 456
 #define SGX_ECP256_KEY_SIZE 32
 #define SGX_CPUSVN_SIZE 16
 #define SGX_REPORT_DATA_SIZE 64
-#define SGX_MAC_SIZE 16 /* Message Authentication Code - 16 bytes */
+#define SGX_MAC_SIZE 16 // Message Authentication Code - 16 bytes 
 #define SGX_KEYID_SIZE 32
-#define SGX_HASH_SIZE 32 /* SHA256 */
+#define SGX_HASH_SIZE 32 // SHA256 
 
 #define SGX_REPORT_BODY_RESERVED1 28
 #define SGX_REPORT_BODY_RESERVED2 32
 #define SGX_REPORT_BODY_RESERVED3 96
 #define SGX_REPORT_BODY_RESERVED4 60
-
+*/
 // App.cpp : Defines the entry point for the console application.
 #include <stdio.h>
 #include <map>
@@ -56,19 +56,13 @@
 // for sealing - sgx_calc_sealed_data_size
 #include "sgx_tseal.h"
 
-// For socket programming
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <errno.h>
-#include<unistd.h>
+
 
 // For reading from/writing to file -sealing.
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-
+/*
 // For google proto buffers
 #include "dhmsgs.pb.h"
 #include <inttypes.h>
@@ -76,8 +70,8 @@
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include "SgxProtobufLATransforms_initiator.h"
 using namespace google::protobuf::io;
-
-
+*/
+#include "systemLA.h"
 
 //#define UNUSED(val) (void)(val)
 #define TCHAR   char
@@ -90,460 +84,15 @@ using namespace google::protobuf::io;
 
 sgx_enclave_id_t e2_enclave_id = 0;
 #define Decryptor_PATH "libDecryptor.so"
-////////////////////////////////////////////////// 
-
+//////////////////////////////////////////////////
 
-
-
-// For google proto buffers
-#include "dhmsgs.pb.h"
-#include <inttypes.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-using namespace google::protobuf::io;
 #include <stdio.h>
-//#include "sgx_eid.h"
-//#include "sgx_urts.h"
-
-
-
-int fit_32_into_uint8_t(google::protobuf::uint32 temp32, uint8_t* temp8)
-{
- if(temp32 > UINT8_MAX)
-	 return -1;
- else
- {
-	 //		 *temp8 = *(uint8_t*)&temp32; // Probably works irrespective of endianness but not sure.
-	 *temp8 = (uint8_t)temp32;
-	 return 0;
- }
-}
-
-int fit_32_into_uint16_t(google::protobuf::uint32 temp32, uint16_t* temp16)
-{
- if(temp32 > UINT16_MAX)
-	 return -1;
- else
- {
-	 //		 *temp8 = *(uint8_t*)&temp32; // Probably works irrespective of endianness but not sure.
-	 *temp16 = (uint16_t)temp32;
-	 return 0;
- }
-}
-
-void encode_ec256_public_key_to_protobuf(protobuf_sgx_ec256_public_t* protobuf_g_a , sgx_ec256_public_t* g_a)
-{
-	int counter; google::protobuf::uint32 temp32;
-	for(counter=0;counter<SGX_ECP256_KEY_SIZE;counter++)
-	{
-		temp32 = g_a->gx[counter];
-		protobuf_g_a->add_gx(temp32);
-		temp32 = g_a->gy[counter];
-		protobuf_g_a->add_gy(temp32);
-	}
-}
-
-int decode_ec256_public_key_from_protobuf(protobuf_sgx_ec256_public_t* protobuf_g_a , sgx_ec256_public_t* g_a)
-{
-  printf("\n ec256 pub key\n");
-	int counter; google::protobuf::uint32 temp32;
-	for(counter=0;counter<SGX_ECP256_KEY_SIZE;counter++)
-	{
-		temp32 = protobuf_g_a->gx(counter);
-		if(fit_32_into_uint8_t(temp32, &(g_a->gx[counter]))!=0)
-		 return -1;
-    printf("%d ",g_a->gx[counter]);
-		temp32 = protobuf_g_a->gy(counter);
-		if(fit_32_into_uint8_t(temp32, &(g_a->gy[counter]))!=0)
-		 return -1;
-    printf("%d ",g_a->gy[counter]);
-	}
-  return 0;
-}
-
-void encode_attributes_to_protobuf(protobuf_sgx_attributes_t* protobuf_attributes, sgx_attributes_t* attributes)
-{
-	protobuf_attributes->set_flags(attributes->flags); // 64 bit
-	protobuf_attributes->set_xfrm(attributes->xfrm); // 64 bit
-}
-
-int decode_attributes_from_protobuf(protobuf_sgx_attributes_t* protobuf_attributes, sgx_attributes_t* attributes)
-{
-	attributes->flags = protobuf_attributes->flags();
-  printf("\n flags %" PRIu64 " \n", attributes->flags);
-	attributes->xfrm = protobuf_attributes->xfrm();
-  printf("\n xfrm %" PRIu64 " \n", attributes->xfrm);
-	return 0;
-}
-
-void encode_report_to_protobuf(protobuf_sgx_report_t* protobuf_report, sgx_report_t* report)
-{
-	int counter; google::protobuf::uint32 temp32;
-	for(counter=0;counter<SGX_KEYID_SIZE;counter++)
-	{
-		temp32=report->key_id.id[counter];
-		protobuf_report->add_key_id(temp32);
-	}
-
-	for(counter=0;counter<SGX_MAC_SIZE;counter++)
-	{
-		temp32=report->mac[counter];
-		protobuf_report->add_mac(temp32);
-	}
-
-	protobuf_report->mutable_body()->set_misc_select(report->body.misc_select); // 32 bit
-	protobuf_report->mutable_body()->set_isv_svn(report->body.isv_svn); // 16 bit
-	protobuf_report->mutable_body()->set_isv_prod_id(report->body.isv_prod_id); // 16 bit
-	encode_attributes_to_protobuf(protobuf_report->mutable_body()->mutable_attributes(), &(report->body.attributes));
-
-	for(counter=0;counter<SGX_CPUSVN_SIZE;counter++)
-	{
-		temp32=report->body.cpu_svn.svn[counter];
-		protobuf_report->mutable_body()->add_cpu_svn(temp32);
-	}
-
-	for(counter=0;counter<SGX_REPORT_BODY_RESERVED1;counter++)
-	{
-		temp32=report->body.reserved1[counter]; // TODO: Could be optimized out - if these are determined to be 0s.
-		protobuf_report->mutable_body()->add_reserved1(temp32);
- 	}
-
-	for(counter=0;counter<SGX_REPORT_BODY_RESERVED2;counter++)
-	{
-		temp32=report->body.reserved2[counter]; // TODO: Could be optimized out - if these are determined to be 0s.
-		protobuf_report->mutable_body()->add_reserved2(temp32);
-	}
-
-	for(counter=0;counter<SGX_REPORT_BODY_RESERVED3;counter++)
-	{
-		temp32=report->body.reserved3[counter]; // TODO: Could be optimized out - if these are determined to be 0s.
-		protobuf_report->mutable_body()->add_reserved3(temp32);
- 	}
-
-	for(counter=0;counter<SGX_REPORT_BODY_RESERVED4;counter++)
-	{
-		temp32=report->body.reserved4[counter]; // TODO: Could be optimized out - if these are determined to be 0s.
-		protobuf_report->mutable_body()->add_reserved4(temp32);
- 	}
-
-	for(counter=0;counter<SGX_HASH_SIZE;counter++)
-	{
-		temp32=report->body.mr_enclave.m[counter];
-		protobuf_report->mutable_body()->add_mr_enclave(temp32);
- 	}
-
-	for(counter=0;counter<SGX_HASH_SIZE;counter++)
-	{
-		temp32=report->body.mr_signer.m[counter];
-		protobuf_report->mutable_body()->add_mr_signer(temp32);
- 	}
-
-	for(counter=0;counter<SGX_REPORT_DATA_SIZE;counter++)
-	{
-		temp32=report->body.report_data.d[counter];
-		protobuf_report->mutable_body()->add_report_data(temp32);
- 	}
-}
-
-int decode_report_from_protobuf(protobuf_sgx_report_t* protobuf_report, sgx_report_t* report)
-{
-  int counter; google::protobuf::uint32 temp32;
-
-  printf("\nreport body keyid\n");
-  for(counter=0;counter<SGX_KEYID_SIZE;counter++)
-  {
-    temp32=protobuf_report->key_id(counter);
-    if(fit_32_into_uint8_t(temp32, &(report->key_id.id[counter]))!=0)
-		  return -1;
-    printf("%d ", report->key_id.id[counter]);
-  }
-
-  printf("\nreport mac\n");
-  for(counter=0;counter<SGX_MAC_SIZE;counter++)
-  {
-    temp32=protobuf_report->mac(counter);
-    if(fit_32_into_uint8_t(temp32, &(report->mac[counter]))!=0)
-      return -1;
-    printf("%d ", report->mac[counter]);
-  }
-
-  report->body.misc_select=protobuf_report->mutable_body()->misc_select(); // 32 bit
-  temp32=protobuf_report->mutable_body()->isv_svn();
-  if(fit_32_into_uint16_t(temp32, &(report->body.isv_svn))!=0)
-   return -1;
-  printf("\nmisc select %d \n", report->body.misc_select);
-
-  temp32=protobuf_report->mutable_body()->isv_prod_id();
-   if(fit_32_into_uint16_t(temp32, &(report->body.isv_prod_id))!=0)
-    return -1;
-  printf("\nprod id %d \n", report->body.isv_prod_id);
-
-  decode_attributes_from_protobuf(protobuf_report->mutable_body()->mutable_attributes(), &(report->body.attributes));
-
-  printf("\n cpu svn\n");
-  for(counter=0;counter<SGX_CPUSVN_SIZE;counter++)
-  {
-    temp32=protobuf_report->mutable_body()->cpu_svn(counter);
-    if(fit_32_into_uint8_t(temp32, &(report->body.cpu_svn.svn[counter]))!=0)
-      return -1;
-    printf("%d ", report->body.cpu_svn.svn[counter]);
-
-  }
-
-  printf("\n reserved1 \n");
-  for(counter=0;counter<SGX_REPORT_BODY_RESERVED1;counter++)
-  {
-    temp32=protobuf_report->mutable_body()->reserved1(counter);
-    if(fit_32_into_uint8_t(temp32, &(report->body.reserved1[counter]))!=0)
-      return -1;
-    printf("%d ", report->body.reserved1[counter]);
-  }
-
-  printf("\n reserved2 \n");
-  for(counter=0;counter<SGX_REPORT_BODY_RESERVED2;counter++)
-  {
-    temp32=protobuf_report->mutable_body()->reserved2(counter);
-    if(fit_32_into_uint8_t(temp32, &(report->body.reserved2[counter]))!=0)
-      return -1;
-    printf("%d ", report->body.reserved2[counter]);
-  }
-
-  printf("\n reserved3 \n");
-  for(counter=0;counter<SGX_REPORT_BODY_RESERVED3;counter++)
-  {
-    temp32=protobuf_report->mutable_body()->reserved3(counter);
-    if(fit_32_into_uint8_t(temp32, &(report->body.reserved3[counter]))!=0)
-      return -1;
-    printf("%d ", report->body.reserved3[counter]);
-  }
-
-  printf("\n reserved4 \n");
-  for(counter=0;counter<SGX_REPORT_BODY_RESERVED4;counter++)
-  {
-    temp32=protobuf_report->mutable_body()->reserved4(counter);
-    if(fit_32_into_uint8_t(temp32, &(report->body.reserved4[counter]))!=0)
-      return -1;
-    printf("%d ", report->body.reserved4[counter]);
-
-  }
-
-  printf("\n mrenclave \n");
-  for(counter=0;counter<SGX_HASH_SIZE;counter++)
-  {
-    temp32=protobuf_report->mutable_body()->mr_enclave(counter);
-    if(fit_32_into_uint8_t(temp32, &(report->body.mr_enclave.m[counter]))!=0)
-      return -1;
-    printf("%x ", report->body.mr_enclave.m[counter]);
-  }
-
-  printf("\n mrsigner \n");
-  for(counter=0;counter<SGX_HASH_SIZE;counter++)
-  {
-    temp32=protobuf_report->mutable_body()->mr_signer(counter);
-    if(fit_32_into_uint8_t(temp32, &(report->body.mr_signer.m[counter]))!=0)
-      return -1;
-    printf("%x ", report->body.mr_signer.m[counter]);
-  }
-
-  printf("\n report data\n");
-  for(counter=0;counter<SGX_REPORT_DATA_SIZE;counter++)
-  {
-    temp32=protobuf_report->mutable_body()->report_data(counter);
-    if(fit_32_into_uint8_t(temp32, &(report->body.report_data.d[counter]))!=0)
-      return -1;
-    printf("%d ", report->body.report_data.d[counter]);
-  }
-	return 0;
-}
-
-void encode_msg1_to_protobuf( protobuf_sgx_dh_msg1_t& protobuf_dhmsg1, sgx_dh_msg1_t* native_dhmsg1)
-{
-   int counter; google::protobuf::uint32 temp32; // google::protobuf::uint64 temp64;
-
-   encode_ec256_public_key_to_protobuf(protobuf_dhmsg1.mutable_g_a(), &(native_dhmsg1->g_a));
-
-   for(counter=0;counter<SGX_HASH_SIZE;counter++)
-   {
-     temp32=native_dhmsg1->target.mr_enclave.m[counter];
-     protobuf_dhmsg1.mutable_target()->add_mr_enclave(temp32);
-   }
-
-   for(counter=0;counter<SGX_TARGET_INFO_RESERVED1_BYTES;counter++)
-   {
-     temp32=native_dhmsg1->target.reserved1[counter];
-     protobuf_dhmsg1.mutable_target()->add_reserved1(temp32);
-   }
-
-   for(counter=0;counter<SGX_TARGET_INFO_RESERVED2_BYTES;counter++)
-   {
-     temp32=native_dhmsg1->target.reserved2[counter];
-     protobuf_dhmsg1.mutable_target()->add_reserved2(temp32);
-   }
-
-   encode_attributes_to_protobuf(protobuf_dhmsg1.mutable_target()->mutable_attributes(), &(native_dhmsg1->target.attributes));
-
-   temp32=native_dhmsg1->target.misc_select ;
-   protobuf_dhmsg1.mutable_target()->set_misc_select(temp32);
-}
-
-void encode_msg3_to_protobuf(protobuf_sgx_dh_msg3_t& protobuf_dhmsg3, sgx_dh_msg3_t* native_dhmsg3)
-{
-  int counter; google::protobuf::uint32 temp32;
-  for(counter=0;counter<SGX_DH_MAC_SIZE;counter++)
-	{
-		temp32=native_dhmsg3->cmac[counter];
-		protobuf_dhmsg3.add_cmac(temp32);
-	}
-
-  encode_report_to_protobuf(protobuf_dhmsg3.mutable_msg3_body()->mutable_report(), &(native_dhmsg3->msg3_body.report));
-  int max_counter=native_dhmsg3->msg3_body.additional_prop_length;
-  unsigned char*temp;
-  for(counter=0,temp=native_dhmsg3->msg3_body.additional_prop;counter<max_counter;counter++,temp++)
-  {
-    protobuf_dhmsg3.mutable_msg3_body()->add_additional_prop(*temp);
-  }
-}
-
-int decode_msg2_from_protobuf(protobuf_sgx_dh_msg2_t& protobuf_dhmsg2, sgx_dh_msg2_t* native_dhmsg2)
-{
-  int counter; google::protobuf::uint32 temp32; //google::protobuf::uint64 temp64;
-  printf("\ncmac\n");
-  for(counter=0;counter<SGX_DH_MAC_SIZE;counter++)
-  {
-    temp32=protobuf_dhmsg2.cmac(counter);
-    if(fit_32_into_uint8_t(temp32, &(native_dhmsg2->cmac[counter]))!=0)
-     return -1;
-    printf("%d ",native_dhmsg2->cmac[counter]);
-  }
-
-  if(decode_ec256_public_key_from_protobuf(protobuf_dhmsg2.mutable_g_b(), &(native_dhmsg2->g_b)) !=0)
-	return -1;
-
-  if(decode_report_from_protobuf(protobuf_dhmsg2.mutable_report(), &(native_dhmsg2->report)) !=0)
-	return -1;
-
-  return 0;
-}
-
-int print_initialized_msg1( protobuf_sgx_dh_msg1_t& protobuf_dhmsg1, sgx_dh_msg1_t* native_dhmsg1)
-{
-   int counter;
-	 printf("gx\n");
-   for(counter=0;counter<SGX_ECP256_KEY_SIZE;counter++)
-   {
-      printf("%d ", protobuf_dhmsg1.g_a().gx(counter));
-      printf("%d ", native_dhmsg1->g_a.gx[counter]);
-   }
-   printf("\ngy\n");
-   for(counter=0;counter<SGX_ECP256_KEY_SIZE;counter++)
-   {
-      printf("%d ", protobuf_dhmsg1.g_a().gy(counter));
-      printf("%d ", native_dhmsg1->g_a.gy[counter]);
-   }
-
-   printf("\nmrenclave in target\n");
-   for(counter=0;counter<SGX_HASH_SIZE;counter++)
-   {
-      printf("%" PRIu32 " ", protobuf_dhmsg1.target().mr_enclave(counter));
-      printf("%d ", native_dhmsg1->target.mr_enclave.m[counter]);
-
-   }
-   printf("\nreserved1 in target\n");
-   for(counter=0;counter<SGX_TARGET_INFO_RESERVED1_BYTES;counter++)
-   {
-      printf("%" PRIu32 " ", protobuf_dhmsg1.target().reserved1(counter));
-      printf("%d ", native_dhmsg1->target.reserved1[counter]);
-
-   }
-   printf("\nreserved2 in target\n");
-   for(counter=0;counter<SGX_TARGET_INFO_RESERVED2_BYTES;counter++)
-   {
-      printf("%" PRIu32 " ", protobuf_dhmsg1.target().reserved2(counter));
-      printf("%d ", native_dhmsg1->target.reserved2[counter]);
-   }
-
-   printf("\n %" PRIu64 "\n", native_dhmsg1->target.attributes.flags);
-   printf("\n %" PRIu64 "\n", protobuf_dhmsg1.target().attributes().flags());
-   printf("\n %" PRIu64 "\n", native_dhmsg1->target.attributes.xfrm);
-   printf("\n %" PRIu64 "\n", protobuf_dhmsg1.target().attributes().xfrm());
-   printf("\n %" PRIu32 "\n", native_dhmsg1->target.misc_select);
-   printf("\n %" PRIu32 "\n", protobuf_dhmsg1.target().misc_select());
-
-	return 0;
-}
-
-int read_protobuf_msg_from_fd(int accept_fd, google::protobuf::MessageLite& message)
-{
-  ZeroCopyInputStream* raw_input;
-  CodedInputStream* coded_input;
-  uint32_t size;
-  CodedInputStream::Limit limit;
-  raw_input = new FileInputStream(accept_fd);
-  coded_input = new CodedInputStream(raw_input);
-  if(!coded_input->ReadVarint32(&size))
-  {
-    printf("Error in reading size of msg");
-    fflush(stdout);
-    return -1;
-  }
-  //printf("size of msg was read to be %" PRIu32 " \n", size);
-  fflush(stdout);
-  limit = coded_input->PushLimit(size);
-  if(!message.ParseFromCodedStream(coded_input))
-  {
-    printf("Error in parsing msg");
-    fflush(stdout);
-    return -1;
-  }
-  coded_input->PopLimit(limit);
-  return 0;
-}
-
-int write_protobuf_msg_to_fd(int accept_fd, google::protobuf::MessageLite& message)
-{
-  ZeroCopyOutputStream* raw_output = new FileOutputStream(accept_fd);
-  CodedOutputStream* coded_output  = new CodedOutputStream(raw_output);
-  coded_output->WriteVarint32(message.ByteSize());
-  if(!message.SerializeToCodedStream(coded_output))
-  {
-    printf("SerializeToCodedStream failed");
-    fflush(stdout);
-    return -1;
-  }
-  // As per this - https://stackoverflow.com/questions/22881876/protocol-buffers-how-to-serialize-and-deserialize-multiple-messages-into-a-file?noredirect=1&lq=1
-  // 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)
-  delete coded_output;
-  delete raw_output;
-  fflush(stdout);
-  return 0;
-}
-
-
-
-
-
-
-
-
-
-
-
-///////////// TRY TO INCLUDE RIGHT SGX HEADERS IN SGX_PROTOBUF CPP
-
-
-
-
-
-
-
-
-
 
 
 uint32_t write_to_fd(int fd, uint8_t* msg, uint32_t* expected_msg_length)
 {
-  lseek(fd, 0, SEEK_SET); 
-  ssize_t bytes_written; 
+  lseek(fd, 0, SEEK_SET);
+  ssize_t bytes_written;
   bytes_written = write(fd, msg, *expected_msg_length);
   if(bytes_written <= 0)
     return 0xFFFFFFFF;
@@ -560,156 +109,28 @@ uint32_t read_from_fd(int fd, uint8_t* msg, size_t* expected_msg_length)
   bytes_read = read(fd, msg, *expected_msg_length);
   if(bytes_read <= 0)
     return 0xFFFFFFFF;
-  *expected_msg_length = bytes_read; 
+  *expected_msg_length = bytes_read;
   return 0;
 }
 
-// Sets up a socket to bind and listen to the given port. Returns FD of the socket on success, -1 on failure (and prints a msg to stdout with the errno)
-int set_up_socket(int port,   sockaddr_in* address)
-{
-  int server_fd = 0;
-
-  // Creating socket file descriptor for listening for attestation requests.
-  server_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
-  if (server_fd == -1)
-  {
-     printf("Error in creating a socket - %d", errno);
-      return -1;
-  }
-
-  // Preparing the address struct for binding
-  address->sin_family = AF_INET;
-  address->sin_addr.s_addr = INADDR_ANY; // Todo: should this be localhost?
-  address->sin_port = htons(port);
-  //  memset(address->sin_zero,0,sizeof(address->sin_zero));
-
-  socklen_t addrlen = sizeof(*address);
-  // Binding
-  if (bind(server_fd, (sockaddr*)address, addrlen)<0)
-  {
-      printf("Error in binding %d - port was %d - ", errno, port);
-      return -1;
-  }
-
-  // Listening
-  if (listen(server_fd, 128) < 0)
-  {
-      printf("Error in listening %d", errno);
-      return -1;
-  }
-
-  return server_fd;
-}
-
-int local_attestation_initiator(__attribute__((unused))   uint8_t* expected_mr_signer)
-{
-  // declare msg1, msg2, msg3 protobuf objects and native SGX structs
-  protobuf_sgx_dh_msg1_t protobuf_msg1;
-  protobuf_sgx_dh_msg2_t protobuf_msg2;
-  protobuf_sgx_dh_msg3_t protobuf_msg3;
-  // For sgx - ecalls and storing msgs rcvd from pipes for processing.
-  uint32_t session_id;
-  sgx_dh_msg1_t dh_msg1;            //Diffie-Hellman Message 1
-  sgx_dh_msg2_t dh_msg2;            //Diffie-Hellman Message 2
-  sgx_dh_msg3_t dh_msg3;            //Diffie-Hellman Message 3
-  sgx_key_128bit_t dh_aek;        // Session Key
-  // initializing native sgx structs
-  memset(&dh_aek,0, sizeof(sgx_key_128bit_t));
-  memset(&dh_msg1, 0, sizeof(sgx_dh_msg1_t));
-  memset(&dh_msg2, 0, sizeof(sgx_dh_msg2_t));
-  memset(&dh_msg3, 0, sizeof(sgx_dh_msg3_t));
-
-  // For socket to listen to the Apache enclave.
-      int apache_port = 3825; int server_fd=0; int accept_fd = 0;
-      struct sockaddr_in own_addr;
-      struct sockaddr_storage apache_addr; socklen_t apache_addr_size = sizeof(apache_addr);
-    //  int counter;
-
-      server_fd=set_up_socket(apache_port, &own_addr);
-      if(server_fd==-1)
-        return -1;
-      printf("Successfully set up a socket to communicate with the Apache enclave.");
-      fflush(stdout);
-
-      uint32_t ret_status;
-      Decryptor_session_request(e2_enclave_id, &ret_status, &dh_msg1, &session_id); // TODO: Check Return status
-      if(ret_status != SGX_SUCCESS) 
-      {
-	printf("session request returned failure\n");  fflush(stdout); return 0xffffffff;
-      }
-      encode_msg1_to_protobuf(protobuf_msg1, &dh_msg1);
-      print_initialized_msg1(protobuf_msg1, &dh_msg1);
-      printf("Done initialization with session id 0x%x", session_id);
-      fflush(stdout);
-
-      int no_of_msgs_xchanged=0;
-      accept_fd = accept(server_fd, (struct sockaddr *)&apache_addr,&apache_addr_size);
-      if (accept_fd <0)
-      {
-        printf("Error in accepting %d", errno);
-        return -1;
-      }
-      do
-      {
-        if(no_of_msgs_xchanged==0){
-          if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg1)!=0)
-  		      return -1;
-        }
-        else
-        {
-          printf("about to read msg2\n");
-  	      fflush(stdout);
-          // read msg2 -
-          if(read_protobuf_msg_from_fd(accept_fd, protobuf_msg2)!=0)
-  		      return -1;
-          if(decode_msg2_from_protobuf(protobuf_msg2, &dh_msg2)!=0)
-  		      return -1;
-          printf("Done reading and decoding msg2\n");
-          // process msg2 and generate msg3
-          Decryptor_exchange_report(e2_enclave_id, &ret_status, &dh_msg2, &dh_msg3, &session_id);
-          if(ret_status!=SGX_SUCCESS)
-  	      {
-            fflush(stdout);
-            printf("exchange report failed:%x\n", ret_status);
-            fflush(stdout);
-            return -1;
-          }
-          printf("return status %d", ret_status);
-          fflush(stdout);
-          // convert msg3 sgx_dh_msg3_t object to a protobuf msg3 object.
-          encode_msg3_to_protobuf(protobuf_msg3, &dh_msg3);
-          printf("about to write msg3\n");
-          fflush(stdout);
-          // write msg3 -
-          if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg3)!=0)
-            return -1;
-          no_of_msgs_xchanged+=1;
-        }
-        no_of_msgs_xchanged++;
-      }
-      while(no_of_msgs_xchanged!=3);
-  	printf("Out of while loop\n");
-  	fflush(stdout);
-	return 0;
-}
 
 uint32_t unseal_signing_key_pair_from_disk(int fd, __attribute__((unused))  sgx_ec256_public_t* pub_key, size_t* actual_sealed_msg_length)
 {
   uint32_t ret_status;
   uint8_t* sgx_sealed_msg;
-  printf("expected read 0x%ld\n", *actual_sealed_msg_length); 
-  sgx_sealed_msg = (uint8_t*) malloc(0x300); // malloc(*actual_sealed_msg_length); (0x300 for EDL) 
+  printf("expected read 0x%ld\n", *actual_sealed_msg_length);
+  sgx_sealed_msg = (uint8_t*) malloc(0x300); // malloc(*actual_sealed_msg_length); (0x300 for EDL)
   ret_status = read_from_fd(fd, sgx_sealed_msg, actual_sealed_msg_length);
   if(ret_status != 0)
   {
     free(sgx_sealed_msg);
     return 0xFFFFFFFF;
   }
-  printf("actual read 0x%ld and ret_status 0x%x\n", *actual_sealed_msg_length, ret_status);  fflush(stdout); 
-  size_t counter; 
+  printf("actual read 0x%ld and ret_status 0x%x\n", *actual_sealed_msg_length, ret_status);  fflush(stdout);
+  size_t counter;
   for(counter=0;counter<*actual_sealed_msg_length;counter++)
 	printf("%x ", *(sgx_sealed_msg+counter));
-  printf("\n");  fflush(stdout); 
+  printf("\n");  fflush(stdout);
   Decryptor_unseal_and_restore_sealed_signing_key_pair(e2_enclave_id, &ret_status, pub_key, sgx_sealed_msg, actual_sealed_msg_length);
   free(sgx_sealed_msg);
   return ret_status;
@@ -719,29 +140,29 @@ uint32_t create_and_seal_signing_key_pair_to_disk( __attribute__((unused))  int
 {
   uint32_t ret_status;
   // Generating a signing ECDSA key to sign the encryption key.
-  uint32_t length; 
+  uint32_t length;
   Decryptor_calculate_sealed_data_size(e2_enclave_id, &length, 3*SGX_ECP256_KEY_SIZE); // sgx_calc_sealed_data_size(0,3*SGX_ECP256_KEY_SIZE);
   if(length == 0xFFFFFFFF)
     return 0xFFFFFFFF;
-  printf("0x%x input msg, 0x%x bytes for sealed msg in parameter value\n", 3*SGX_ECP256_KEY_SIZE, length); fflush(stdout); 
+  printf("0x%x input msg, 0x%x bytes for sealed msg in parameter value\n", 3*SGX_ECP256_KEY_SIZE, length); fflush(stdout);
   uint8_t* sealed_data=(uint8_t*) malloc(0x300);
-  printf("Made call to sgx_calc_sealed_data_size\n");  fflush(stdout); 
+  printf("Made call to sgx_calc_sealed_data_size\n");  fflush(stdout);
   Decryptor_create_and_seal_ecdsa_signing_key_pair(e2_enclave_id, &ret_status, pub_key, &length, sealed_data);
   if(ret_status != SGX_SUCCESS)
   {
-    printf("create_and_seal called returned an error: %x", ret_status); 
+    printf("create_and_seal called returned an error: %x", ret_status);
     free(sealed_data);
     return 0xFFFFFFFF;
   }
   printf("It returned sgx_success\n"); fflush(stdout); // *actual_sealed_msg_length=length;
-    
+
   ret_status = write_to_fd(fd, sealed_data, &length);
-  free(sealed_data); 
+  free(sealed_data);
 //  if(ret_status > 0)
-//	  *actual_sealed_msg_length = ret_status; 
+//	  *actual_sealed_msg_length = ret_status;
 //  return 0;
 
-return ret_status; 
+return ret_status;
 }
 
 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
@@ -753,10 +174,8 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
     sgx_launch_token_t launch_token;
 //    uint8_t* pub_key = (uint8_t*) malloc(2*SGX_ECP256_KEY_SIZE);
     sgx_ec256_public_t pub_key;  uint32_t counter;
-    
 
-//    long int actual_sealed_msg_length;
-    size_t sealed_msg_length_in_file; 
+    size_t sealed_msg_length_in_file;
     status = sgx_create_enclave(Decryptor_PATH, SGX_DEBUG_FLAG, &launch_token, &launch_token_updated, &e2_enclave_id, NULL);
     if(status != SGX_SUCCESS)
     {
@@ -765,13 +184,8 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
     }
     printf("\nDecryptor - EnclaveID %" PRIx64, e2_enclave_id);
     fflush(stdout);
-/*    ret_status=local_attestation_initiator(NULL); 
-    if(ret_status!=0)
-    {
-	printf("local attestation did not successfully return: %x\n", ret_status); fflush(stdout); return 0xFFFFFFFF; 
-
-    }
-  */  int sealed_signing_key_fd = open("sealed_signing_key.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+    
+    int sealed_signing_key_fd = open("sealed_signing_key.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
     if(sealed_signing_key_fd == -1)
     {
       perror("\nError in opening the file sealed_signing_key.txt - ");
@@ -783,14 +197,14 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
 //    int start = lseek(sealed_signing_key_fd, 0, SEEK_SET);
 //    int end = lseek(sealed_signing_key_fd, 0, SEEK_END);
       struct stat st; ret_status = fstat(sealed_signing_key_fd, &st);
-     //sealed_msg_length_in_file = st.st_size; 
+     //sealed_msg_length_in_file = st.st_size;
       if(ret_status != 0)
       {
 	perror("error in finding the file size. -  ");
-        fflush(stderr); 
+        fflush(stderr);
 	return 0xffffffff;
 
-      }      
+      }
       sealed_msg_length_in_file = st.st_size;
     if(sealed_msg_length_in_file == 0) //if(start == end && start != -1)
     {
@@ -800,7 +214,8 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
       if(ret_status != 0)
       {
         printf("\n error in generating the ecdsa signing key pair \n");
-        fflush(stdout);
+        fflush(stdout);    sgx_destroy_enclave(e2_enclave_id);
+
         return 0xFFFFFFFF;
       }
 	fflush(stdout);
@@ -812,8 +227,7 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
                 printf("0x%x ",pub_key.gy[counter]);
       printf("\n");
       fflush(stdout);
-
-      fflush(stdout);
+//      fflush(stdout);
     }
     else {
 //      start = lseek(sealed_signing_key_fd, 0, SEEK_CUR);
@@ -823,7 +237,8 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
       if(ret_status != SGX_SUCCESS)
       {
         printf("\n error in unsealing the ecdsa signing key pair:%d \n", ret_status);
-        fflush(stdout);
+        fflush(stdout);     sgx_destroy_enclave(e2_enclave_id);
+
         return 0xFFFFFFFF;
       }
       printf("\n Recovered the ecdsa key pair successfully - gx, gy\n");
@@ -835,7 +250,39 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
       printf("\n");
       fflush(stdout);
     }
-    close(sealed_signing_key_fd); 
+
+    close(sealed_signing_key_fd);
+
+    ret_status=local_attestation_initiator(3825, e2_enclave_id, NULL);
+    if(ret_status!=0)
+    {
+        printf("local attestation did not successfully return: %x\n", ret_status); fflush(stdout);     sgx_destroy_enclave(e2_enclave_id);
+return 0xFFFFFFFF;
+
+    }
+
+
+/*	sgx_ec256_public_t short_term_pub_key;
+	sgx_ec256_signature_t generated_signature;
+ Decryptor_create_and_sign_client_side_pub_key(e2_enclave_id, &ret_status,&short_term_pub_key, &generated_signature);
+if(ret_status != SGX_SUCCESS)
+{
+	printf("Could not generate or sign another keypair for client-side, error:%x.\n", ret_status); fflush(stdout);
+	return 0xFFFFFFFF;
+}
+printf("Generated signature and pub key.\n");fflush(stdout);
+for(counter=0; counter<SGX_ECP256_KEY_SIZE; counter++)
+                        printf("0x%x ", short_term_pub_key.gx[counter]); printf("\n"); fflush(stdout);
+                for(counter=0;counter<SGX_NISTP_ECP256_KEY_SIZE ; counter++)
+                {
+                        printf("0x%x", generated_signature.x[counter]);
+                        printf("0x%x", generated_signature.y[counter]);
+                }
+printf("\n"); fflush(stdout);
+*/
+
+
+
 
     // TODO: Continue with other msgs - send sign(enc | verifier mr_enclave)
     sgx_destroy_enclave(e2_enclave_id);

+ 13 - 10
Decryptor/Decryptor.cpp

@@ -235,28 +235,28 @@ uint32_t test_close_session(sgx_enclave_id_t src_enclave_id,
 */
 //Function that is used to verify the trust of the other enclave
 //Each enclave can have its own way verifying the peer enclave identity
-extern "C" uint32_t verify_peer_enclave_trust(sgx_dh_session_enclave_identity_t* peer_enclave_identity)
+extern "C" uint32_t verify_peer_enclave_trust(__attribute__((unused))  sgx_dh_session_enclave_identity_t* peer_enclave_identity)
 {
    if(!peer_enclave_identity)
     {
         return INVALID_PARAMETER_ERROR;
     }
 //  sgx_measurement_t actual_mr_enclave = peer_enclave_identity->mr_enclave;
-  sgx_measurement_t actual_mr_signer = peer_enclave_identity->mr_signer;
+//  sgx_measurement_t actual_mr_signer = peer_enclave_identity->mr_signer;
     // verifier's mrsigner 
-    uint8_t expected_mr_signer[32] ={0xdf, 0xd7, 0x3b, 0x93, 0xea, 0x39, 0x02, 0x02, 0x3c, 0xd0, 0x52, 0x1a, 0xbd, 0x00, 0xaf, 0xb9, 0xa6, 0x54, 0x57, 0x3e, 0xe5, 0xef, 0x36, 0xf4, 0x8c, 0xc2, 0x4d, 0x92, 0x70, 0xae, 0xd4, 0x7c}; 
-    int count;
-    for(count=0; count<SGX_HASH_SIZE; count++)
-  {
+//    uint8_t expected_mr_signer[32] ={0xdf, 0xd7, 0x3b, 0x93, 0xea, 0x39, 0x02, 0x02, 0x3c, 0xd0, 0x52, 0x1a, 0xbd, 0x00, 0xaf, 0xb9, 0xa6, 0x54, 0x57, 0x3e, 0xe5, 0xef, 0x36, 0xf4, 0x8c, 0xc2, 0x4d, 0x92, 0x70, 0xae, 0xd4, 0x7c}; 
+//    int count;
+//    for(count=0; count<SGX_HASH_SIZE; count++)
+ // {
 /*    if( actual_mr_enclave.m[count] != expected_mr_enclave[count] )
     {
         return ENCLAVE_TRUST_ERROR;
-    }*/
+    }
     if( actual_mr_signer.m[count] != expected_mr_signer[count] )
     {
         return ENCLAVE_TRUST_ERROR; // TODO: Different error here.
-    }
-  }
+    }*/
+ // }
 //#include "stdlib.h"
 //#include "string"
 //#include "sgx_tcrypto.h"
@@ -275,7 +275,10 @@ extern "C" uint32_t verify_peer_enclave_trust(sgx_dh_session_enclave_identity_t*
         ret_sgx=sgx_create_rsa_key_pair(384, 4, n, d, (unsigned char*)&e, p, q, dmp1, dmq1, iqmp);
         free(n); free(d); free(p); free(q); free(dmp1); free(dmq1); free(iqmp);
         return ret_sgx;
-*/ return SGX_SUCCESS;
+*/ 
+//	Decryptor_
+
+return SGX_SUCCESS;
 //}
 
 

+ 50 - 7
LocalAttestationCode/EnclaveMessageExchange.cpp

@@ -64,6 +64,9 @@ uint32_t verify_peer_enclave_trust(sgx_dh_session_enclave_identity_t* peer_encla
 ATTESTATION_STATUS generate_session_id(uint32_t *session_id);
 ATTESTATION_STATUS end_session();
 sgx_ec256_private_t signing_priv_key;
+sgx_ec256_private_t short_term_priv_key;
+sgx_ec256_public_t short_term_pub_key; // for testing only: to test verification of signature
+
 sgx_ecc_state_handle_t ecc_state;
 
  uint32_t session_ids[MAX_SESSION_COUNT];
@@ -168,8 +171,8 @@ ATTESTATION_STATUS exchange_report(
         if(ret != SUCCESS)
         {
             return ret; //INVALID_SESSION;
-        }
-	
+       }
+
 	// TODO: Verify that these changes will be lost on update. 
         //save the session ID, status and initialize the session nonce
         global_session_info.session_id = *session_id;
@@ -197,14 +200,14 @@ uint32_t create_ecdsa_key_pair(sgx_ec256_public_t* pub_key, sgx_ec256_private_t*
   se_ret = sgx_ecc256_create_key_pair(priv_key, pub_key, ecc_state);
   se_ret2 = sgx_ecc256_close_context(ecc_state);
 
-  if(SGX_SUCCESS != se_ret && se_ret2!= SGX_SUCCESS) // something weird has happened - couldn't shut it down.
+  if(SGX_SUCCESS != se_ret || se_ret2!= SGX_SUCCESS) // something weird has happened - couldn't shut it down.
     return 0xFFFFFFFF;
   return SGX_SUCCESS;
 }
 
 // todo: set to private
 // todo: assumes that the length of the keystring is at least 3*SGX_ECP256_KEY_SIZE
-void serialize_signing_key_pair_to_string(sgx_ec256_public_t* pub_key, sgx_ec256_private_t* signing_priv_key, uint8_t* private_public_key_string)
+void serialize_key_pair_to_string(sgx_ec256_public_t* pub_key, sgx_ec256_private_t* signing_priv_key, uint8_t* private_public_key_string)
 {
   if(private_public_key_string != NULL)  // nowhere to serialize to
   {
@@ -237,7 +240,7 @@ void serialize_signing_key_pair_to_string(sgx_ec256_public_t* pub_key, sgx_ec256
 
 
 // todo: set to private
-void deserialize_string_to_public_private_key_pair(uint8_t* private_public_key_string, sgx_ec256_public_t* pub_key, sgx_ec256_private_t* signing_priv_key)
+void deserialize_string_to_key_pair(uint8_t* private_public_key_string, sgx_ec256_public_t* pub_key, sgx_ec256_private_t* signing_priv_key)
 {
   if(private_public_key_string != NULL) // nowhere to deserialize from 
   {
@@ -273,7 +276,7 @@ uint32_t create_and_seal_ecdsa_signing_key_pair(__attribute__((unused))   sgx_ec
     uint8_t* private_public_key_string = (uint8_t*) malloc(3*SGX_ECP256_KEY_SIZE);
     uint8_t* sealed_data2 = (uint8_t*) malloc(*sealed_data_length);
     // serializing keypair to string
-    serialize_signing_key_pair_to_string(pub_key, &private_key, private_public_key_string);
+    serialize_key_pair_to_string(pub_key, &private_key, private_public_key_string);
     uint8_t* private_key_string = (uint8_t*) malloc(SGX_ECP256_KEY_SIZE); 
     for(counter=0;counter<SGX_ECP256_KEY_SIZE;counter++)
 	*(private_key_string+counter)=private_key.r[counter];
@@ -338,11 +341,51 @@ uint32_t unseal_and_restore_sealed_signing_key_pair(__attribute__((unused)) sgx_
     return ret_status;
   }
    
-  deserialize_string_to_public_private_key_pair(temp_plaintext, pub_key, &signing_priv_key);
+  deserialize_string_to_key_pair(temp_plaintext, pub_key, &signing_priv_key);
   free(temp_plaintext); free(sealed_data2);  
   return SGX_SUCCESS;
 }
 
+uint32_t create_and_sign_client_side_pub_key(sgx_measurement_t* mr_enclave,  sgx_ec256_public_t* generated_pub_key, sgx_ec256_signature_t* generated_signature)
+{
+	// create key pair
+	uint32_t ret_status = create_ecdsa_key_pair(&short_term_pub_key, &short_term_priv_key);  uint32_t counter;
+	uint32_t ret_status2;
+       if(ret_status!=SGX_SUCCESS)
+           return ret_status;
+	// serialize public key, append mr_enclave 
+	uint8_t* public_key_string = (uint8_t*) malloc(3*SGX_ECP256_KEY_SIZE); // for .edl file - size parameter for serialize is 96 and this fits coz we need to append the mr_enclave to the pub key 
+	serialize_key_pair_to_string(&short_term_pub_key, NULL, public_key_string);
+	for(counter=32*2; counter<32*3; counter++) // appending mr_enclave
+		*(public_key_string+counter)=mr_enclave->m[counter]; 
+	// retrieve long-term private key from global variable - apparently, need to create a local copy or it crashes
+	sgx_ec256_private_t long_term_priv_key;
+	for(counter=0; counter<SGX_ECP256_KEY_SIZE; counter++) 
+		long_term_priv_key.r[counter] = signing_priv_key.r[counter];  
+	// sign public key with long-term private key 
+	sgx_ec256_signature_t local_signature; sgx_ecc_state_handle_t ecc_handle; 
+	//// opening context for signature
+	ret_status = sgx_ecc256_open_context(&ecc_handle); 
+	if(ret_status != SGX_SUCCESS) 
+		return ret_status; 
+	ret_status = sgx_ecdsa_sign(public_key_string,2*SGX_ECP256_KEY_SIZE, &long_term_priv_key, &local_signature, ecc_handle);
+	ret_status2 = sgx_ecc256_close_context(ecc_handle); 
+	free(public_key_string); 
+	if(ret_status == SGX_SUCCESS) 
+	{
+		for(counter=0; counter<SGX_ECP256_KEY_SIZE; counter++) 
+			generated_pub_key->gx[counter] = short_term_pub_key.gx[counter]; 
+		for(counter=0;counter<SGX_NISTP_ECP256_KEY_SIZE	; counter++)
+		{
+			generated_signature->x[counter] = local_signature.x[counter]; 
+                        generated_signature->y[counter] = local_signature.y[counter]; 
+		}
+	}
+	if(ret_status != SGX_SUCCESS || ret_status2 != SGX_SUCCESS)
+		return 0xFFFFFFFF;
+	return 0; 
+}
+
 
 
 uint32_t calculate_sealed_data_size( uint32_t input_size) 

+ 4 - 2
LocalAttestationCode/LocalAttestationCode.edl

@@ -42,10 +42,12 @@ enclave  {
         public uint32_t create_and_seal_ecdsa_signing_key_pair([out]sgx_ec256_public_t* pub_key, [in] uint32_t* sealed_data_length, [out, size=SEALED_SIZE] uint8_t* sealed_data);
         public uint32_t unseal_and_restore_sealed_signing_key_pair([out] sgx_ec256_public_t* pub_key, [in, size=SEALED_SIZE] uint8_t* sealed_data, [in] size_t* sealed_data_length);
         uint32_t create_ecdsa_key_pair([out] sgx_ec256_public_t* pub_key, [out] sgx_ec256_private_t* priv_key);
-void serialize_signing_key_pair_to_string([in] sgx_ec256_public_t* pub_key, [in] sgx_ec256_private_t* signing_priv_key, [out, size=96] uint8_t* private_public_key_string);
-        void deserialize_string_to_public_private_key_pair([in, size=96] uint8_t* private_public_key_string, [out] sgx_ec256_public_t* pub_key, [out] sgx_ec256_private_t* priv_key); 
+void serialize_key_pair_to_string([in] sgx_ec256_public_t* pub_key, [in] sgx_ec256_private_t* signing_priv_key, [out, size=96] uint8_t* private_public_key_string);
+        void deserialize_string_to_key_pair([in, size=96] uint8_t* private_public_key_string, [out] sgx_ec256_public_t* pub_key, [out] sgx_ec256_private_t* priv_key); 
         public uint32_t end_session();
         public uint32_t calculate_sealed_data_size(uint32_t input_size); //, [out] uint32_t *opsize);
+//	public uint32_t create_and_sign_client_side_pub_key([out] sgx_ec256_public_t* generated_pub_key, [out] sgx_ec256_signature_t* generated_signature);
+public uint32_t create_and_sign_client_side_pub_key([in] sgx_measurement_t* mr_enclave, [out] sgx_ec256_public_t* generated_pub_key, [out] sgx_ec256_signature_t* generated_signature);
 
         // public uint32_t generate_response([in, size = req_message_size] secure_message_t* req_message, size_t req_message_size, size_t max_payload_size, [out, size=resp_message_size] secure_message_t* resp_message, size_t resp_message_size );
 //        public uint32_t end_session();

+ 3 - 3
Makefile

@@ -122,7 +122,7 @@ else
 	App_Link_Flags += -lsgx_uae_service
 endif
 
-App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
+App_Cpp_Objects := App/App.o App/systemLA.o App/protobufLAInitiator.o App/protobufSgxLATransformsInitiator.o App/dhmsgs.pb.o #$(App_Cpp_Files:.cpp=.o)
 App_Name := app
 
 ######## Enclave Settings ########
@@ -254,8 +254,8 @@ App/%.o: App/%.cpp Decryptor/Decryptor_u.h #Enclave3/Enclave3_u.h
 	@$(CXX) $(App_Compile_Flags) -c $< -o $@
 	@echo "CXX  <=  $<"
 
-$(App_Name): App/Decryptor_u.o $(App_Cpp_Objects)# $(UnTrustLib_Name)
-	@$(CXX) $^ -o $@ $(App_Link_Flags)
+$(App_Name): $(App_Cpp_Objects) App/Decryptor_u.o #$(App_Cpp_Objects)# $(UnTrustLib_Name)
+	@$(CXX) -Wl,--undefined --verbose -Wl,--verbose $^ -o $@ $(App_Link_Flags)
 	@echo "LINK =>  $@"