Browse Source

Refactored code - to make it easier to set up encryption to enclaves and to the client

dettanym 5 years ago
parent
commit
b9991f04ab

+ 36 - 21
App/App.cpp

@@ -47,7 +47,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#include "systemLA.h"
+#include "LocalAttestationUntrusted.h"
 
 //#define UNUSED(val) (void)(val)
 #define TCHAR   char
@@ -149,7 +149,6 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
     // For sgx setup
     int launch_token_updated;
     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;
 
     size_t sealed_msg_length_in_file;
@@ -161,7 +160,7 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
     }
     printf("\nDecryptor - EnclaveID %" PRIx64, e2_enclave_id);
     fflush(stdout);
-    
+
     int sealed_signing_key_fd = open("sealed_signing_key.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
     if(sealed_signing_key_fd == -1)
     {
@@ -207,9 +206,7 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
 //      fflush(stdout);
     }
     else {
-//      start = lseek(sealed_signing_key_fd, 0, SEEK_CUR);
-  //    if(actual_sealed_msg_length == 0)
-  //      actual_sealed_msg_length = size; // - start;
+
       ret_status = unseal_signing_key_pair_from_disk(sealed_signing_key_fd, &pub_key, &sealed_msg_length_in_file);
       if(ret_status != SGX_SUCCESS)
       {
@@ -229,33 +226,51 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
     }
 
     close(sealed_signing_key_fd);
-  
-    // LA with the verifier 
-    ret_status=local_attestation_initiator(3824, e2_enclave_id);
-    if(ret_status!=0)
+
+    int server_fd;
+    server_fd = prepare_local_attestation_as_responder_fd_and_msg1(own_enclave_id, 3824);
+    if(server_fd <=0)
     {
-        printf("local attestation - with the verifier - did not successfully return: %x\n", ret_status); fflush(stdout);     sgx_destroy_enclave(e2_enclave_id);
-        return 0xFFFFFFFF;
+      printf("Error in setting up server socket."); fflush(stdout);
+      sgx_destroy_enclave(e2_enclave_id);
+      return server_fd;
     }
+    printf("Successfully set up a socket to communicate with the Apache enclave.\n");
+    fflush(stdout);
 
-	// Does decryption too - should probs rename it 
-    ret_status=local_attestation_initiator(3825, e2_enclave_id);
+    // LA with the verifier
+    ret_status = local_attestation_as_responder_msg2_msg3(e2_enclave_id);
     if(ret_status!=0)
     {
-        printf("local attestation - with the apache - did not successfully return: %x\n", ret_status); fflush(stdout);     sgx_destroy_enclave(e2_enclave_id);
-        return 0xFFFFFFFF;
+      printf("local attestation - with the verifier - did not successfully return: %x\n", ret_status); fflush(stdout);
+      sgx_destroy_enclave(e2_enclave_id);
+      return 0xFFFFFFFF;
     }
 
+    ret_status = post_local_attestation_with_verifier(e2_enclave_id);
+    if(ret_status!=0)
+    {
+      printf("post local attestation - with the verifier - did not successfully return: %x\n", ret_status); fflush(stdout);
+      sgx_destroy_enclave(e2_enclave_id);
+      return 0xFFFFFF01;
+    }
 
-/*    // LA with the apache - currently set to return failure - should change it to success when the code to send the mrsigner from the verifier to the decryptor is added- TODO: <--- that 
-    ret_status=local_attestation_initiator(3826, e2_enclave_id); // TODO: Change port or sth
+    ret_status = local_attestation_as_responder_msg2_msg3(e2_enclave_id);
     if(ret_status!=0)
     {
-        printf("local attestation - with apache - did not successfully return: %x\n", ret_status); fflush(stdout);     sgx_destroy_enclave(e2_enclave_id);
-return 0xFFFFFFFF;
+      printf("local attestation - with the verifier - did not successfully return: %x\n", ret_status); fflush(stdout);
+      sgx_destroy_enclave(e2_enclave_id);
+      return 0xFFFFFFFF;
+    }
 
+    ret_status = post_local_attestation_with_apache(e2_enclave_id);
+    if(ret_status!=0)
+    {
+      printf("post local attestation - with the verifier - did not successfully return: %x\n", ret_status); fflush(stdout);
+      sgx_destroy_enclave(e2_enclave_id);
+      return 0xFFFFFF01;
     }
-*/    // TODO: Continue with other msgs - send sign(enc | verifier mr_enclave)
+
     sgx_destroy_enclave(e2_enclave_id);
 
     return 0;

+ 283 - 0
App/LocalAttestationUntrusted.cpp

@@ -0,0 +1,283 @@
+// Knows only protobuf_sgx objects, protobuf header.
+// For socket programming
+#include <sys/socket.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "ProtobufLAMessages.pb.h"
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+using namespace google::protobuf::io;
+#include "protobufLAInitiator.h"
+#include "../Decryptor/Decryptor_u.h"
+#include <iostream>
+
+class LocalAttestationUntrusted {
+  int server_fd;
+  int accept_fd;
+  uint32_t session_id;
+  protobuf_sgx_dh_msg1_t protobuf_msg1;
+
+  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);
+    delete raw_input;
+    delete coded_input;
+    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;
+  }
+
+  // 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;
+  }
+
+  uint32_t local_attestation_msg2_msg3(uint32_t own_enclave_id, int accept_fd)
+  {
+    uint32_t protobuf_sgx_ret;
+    protobuf_sgx_dh_msg2_t protobuf_msg2;
+    protobuf_sgx_dh_msg3_t protobuf_msg3;
+
+    if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg1)!=0)
+      return 0x1;
+
+    if(read_protobuf_msg_from_fd(accept_fd, protobuf_msg2)!=0)
+      return 0x2;
+
+    // TODO: Edit function signature in the definition: last argument read_or_write is used to control the flow of the untrusted program:
+    // no point in doing this as it is untrusted. Have an attribute in its class for it..
+    protobuf_sgx_ret = process_protobuf_dh_msg2_generate_protobuf_dh_msg3(own_enclave_id, protobuf_msg2, protobuf_msg3, &session_id);
+    if(protobuf_sgx_ret != 0)
+    {
+        printf("Error in generate_protobuf_dh_msg2: 0x%x", protobuf_sgx_ret); fflush(stdout); return protobuf_sgx_ret;
+    }
+
+    if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg3)!=0)
+      return 0x3;
+
+    return 0;
+  }
+
+  int decrypt_client_data_wrapper(uint32_t own_enclave_id, int apache_fd)
+  {
+    protobuf_post_LA_encrypted_msg_t protobuf_msg;
+    unsigned char* protobuf_msg_ptr;
+    uint32_t sgx_ret_status;
+    // TODO: THIS SHOULD BE WAYYYY GREATER THAN 144 -> CLIENTS PUBLIC KEY (64)+ ENCRYPTION TAG (16)+ SIGNATURE (64) + CLIENT DATA
+    // 144 + client data length
+    uint8_t* input_ciphertext_plus_tag;
+    uint32_t input_ciphertext_plus_tag_length;
+  	uint8_t* output_ciphertext_plus_tag;
+    uint32_t output_ciphertext_plus_tag_length;
+    int counter;
+
+    if(read_protobuf_msg_from_fd(apache_fd, protobuf_msg)!=0)
+      return 0xfe;
+
+    input_ciphertext_plus_tag_length = protobuf_msg.msg().length();
+    // TODO: MAKE SURE THIS IS NOT 0XFFFFFFFF.
+    input_ciphertext_plus_tag = (uint8_t*) malloc(input_ciphertext_plus_tag_length);
+    output_ciphertext_plus_tag = (uint8_t*) malloc(input_ciphertext_plus_tag_length - 128 + 10);
+    protobuf_msg_ptr = (uint8_t*) protobuf_msg.msg().c_str();
+
+    for(counter=0; counter<input_ciphertext_plus_tag_length; counter++)
+      input_ciphertext_plus_tag[counter] = *(protobuf_msg_ptr + counter);
+
+    // Just so that the ciphertext - client data - is returned back to Apache in case decrypt_client_data fails.
+    // client data is after public key (64 bytes) + signature (64 bytes) = 128 bytes.
+    for(counter=0; counter<input_ciphertext_plus_tag_length; counter++)
+  		output_ciphertext_plus_tag[counter] = input_ciphertext_plus_tag[counter+128];
+
+    // We assume that the output is not changed unless it is successful throughout.
+    // Return value is not sent back..
+    Decryptor_process_apache_message_generate_response(own_enclave_id, &sgx_ret_status, input_ciphertext_plus_tag, input_ciphertext_plus_tag_length, output_ciphertext, &output_ciphertext_plus_tag_length);
+    free(input_ciphertext_plus_tag);
+    protobuf_msg.set_msg((void*)  output_ciphertext_plus_tag, output_ciphertext_plus_tag_length);
+    free(output_ciphertext_plus_tag);
+  	if(write_protobuf_msg_to_fd(apache_fd, protobuf_msg)!=0)
+  	  return 0xfc;
+
+  	return 0;
+  }
+
+  public:
+    int prepare_local_attestation_as_responder_fd_and_msg1(uint32_t own_enclave_id, int port)
+    {
+      struct sockaddr_in own_addr;
+      uint32_t protobuf_sgx_ret;
+      int temp_server_fd=0;
+      protobuf_sgx_ret = generate_protobuf_dh_msg1(own_enclave_id, protobuf_msg1, session_id);
+      if(protobuf_sgx_ret != 0)
+      {
+        printf("Error in generate_protobuf_dh_msg1: 0x%x", protobuf_sgx_ret); fflush(stdout); return -protobuf_sgx_ret;
+      }
+
+      temp_server_fd=set_up_socket(port, &own_addr);
+      if(temp_server_fd>0)
+        server_fd = temp_server_fd;
+      return temp_server_fd;
+    }
+
+    // TODO: CHANGED SIGNATURE.
+    int local_attestation_as_responder_msg2_msg3(uint32_t own_enclave_id, int server_fd)
+    {
+      //   protobuf_post_LA_encrypted_msg_t protobuf_encrypted_msg;
+      uint32_t protobuf_sgx_ret;
+      struct sockaddr_storage apache_addr;
+      socklen_t apache_addr_size = sizeof(apache_addr);
+
+      int temp_accept_fd;
+      temp_accept_fd = accept(server_fd, (struct sockaddr *)&apache_addr,&apache_addr_size);
+      if (temp_accept_fd <0)
+      {
+        printf("Error in accepting %d", errno); fflush(stdout);
+        return temp_accept_fd;
+      }
+      accept_fd=temp_accept_fd;
+
+      protobuf_sgx_ret = local_attestation_msg2_msg3(own_enclave_id, accept_fd);
+      return protobuf_sgx_ret;
+    }
+
+    int post_local_attestation_with_verifier(uint32_t own_enclave_id)
+    {
+      uint32_t protobuf_sgx_ret;
+      uint8_t encrypted_apache_mrsigner_and_tag[48];
+      size_t bytes_read;
+
+      printf("Here\n"); fflush(stdout);
+      bytes_read=read(accept_fd, encrypted_apache_mrsigner_and_tag, 48);
+    	if(bytes_read_post_la!=48)
+     	{
+           	printf("Not all of the encrypted apache's mrsigner was read from the verifier.\n"); fflush(stdout);
+            close(accept_fd);
+            return 0xfe;
+     	}
+
+      for(count=0;count<48;count++)
+    	  printf("0x%02x ", encrypted_apache_mrsigner_and_tag[count]);
+      printf("\n");fflush(stdout);
+
+      Decryptor_decrypt_verifiers_message_set_apache_mrsigner(own_enclave_id, &sgx_ret, encrypted_apache_mrsigner_and_tag);
+      if(sgx_ret!=0)
+    	{
+        printf("Error in decryption: 0x%x\n", sgx_ret); fflush(stdout);
+        close(accept_fd);
+        return sgx_ret;
+    	}
+
+      printf("Successful decryption\n"); fflush(stdout);
+      close(accept_fd);
+      return 0;
+    }
+
+    int post_local_attestation_with_apache(uint32_t own_enclave_id)
+    {
+      protobuf_post_LA_encrypted_msg_t protobuf_encrypted_msg;
+      uint8_t encrypted_sign_data_and_sign_and_tag[176];
+      int apache_fd=accept_fd;
+  	  memset(encrypted_sign_data_and_sign_and_tag,0x0,176);
+
+      Decryptor_create_and_encrypt_mitigator_header_H(own_enclave_id, &sgx_ret, encrypted_sign_data_and_sign_and_tag);
+    	if(sgx_ret!=0)
+    	{
+    		printf("Error in generating encrypted mitigator header:0x%x\n", sgx_ret); fflush(stdout);
+        close(accept_fd);
+        return 0xf3;
+    	}
+
+    	for(count=0;count<176;count++)
+    	{
+    		printf("0x%02x ", encrypted_sign_data_and_sign_and_tag[count]);
+    	}
+    	printf("\n"); fflush(stdout);
+
+    	protobuf_encrypted_msg.set_msg((void*)encrypted_sign_data_and_sign_and_tag, 176);
+    	if(write_protobuf_msg_to_fd(apache_fd, protobuf_encrypted_msg) != 0)
+      {
+        printf("Not all of the mitigator token H was written to the Apache.\n"); fflush(stdout);
+        close(accept_fd);
+        return 0xfe;
+      }
+
+  	  do {
+      	internal_return_status = decrypt_client_data_wrapper(own_enclave_id, apache_fd);
+      } while(internal_return_status==0);
+      close(accept_fd);
+      return internal_return_status;
+    }
+}

+ 7 - 15
App/protobufLAInitiator.cpp

@@ -14,16 +14,14 @@ int generate_protobuf_dh_msg1(uint32_t own_enclave_id, protobuf_sgx_dh_msg1_t& p
   uint32_t ret_status;
   Decryptor_session_request(own_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;
-  }
+    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);
+  //print_initialized_msg1(protobuf_msg1, &dh_msg1);
   return 0;
 }
 
+// TODO: Edit this to remove the read argument and edit the ecall too.
 int process_protobuf_dh_msg2_generate_protobuf_dh_msg3(uint32_t own_enclave_id, protobuf_sgx_dh_msg2_t& protobuf_msg2, protobuf_sgx_dh_msg3_t& protobuf_msg3, uint32_t* session_id, uint8_t* read)
 {
   uint32_t ret_status;
@@ -36,19 +34,13 @@ int process_protobuf_dh_msg2_generate_protobuf_dh_msg3(uint32_t own_enclave_id,
 
   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(own_enclave_id, &ret_status, &dh_msg2, &dh_msg3, session_id, read);
+  Decryptor_exchange_report(own_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;
-  }
+
   // 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);
   return 0;
 }

+ 0 - 341
App/systemLA.cpp

@@ -1,341 +0,0 @@
-// Knows only protobuf_sgx objects, protobuf header.
-// For socket programming
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <errno.h>
-#include<unistd.h>
-#include <stdio.h>
-#include "ProtobufLAMessages.pb.h"
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-using namespace google::protobuf::io;
-#include "protobufLAInitiator.h"
-#include "../Decryptor/Decryptor_u.h"
-#include "sgx_tcrypto.h"
-#include <iostream>
-#include "Openssl_crypto.h"
-
-// TODO: Make these private functions
-int apache_fd;
-int decrypt_client_data_wrapper(unsigned char* op_plaintext , uint32_t own_enclave_id);
-
-
-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);
-  delete raw_input;
-  delete coded_input;
-  return 0;
-}
-
-// TODO: private functions
-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;
-}
-
-// 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(int port, uint32_t own_enclave_id)
-{
-  // declare msg1, msg2, msg3 protobuf objects
-  protobuf_sgx_dh_msg1_t protobuf_msg1;
-  protobuf_sgx_dh_msg2_t protobuf_msg2;
-  protobuf_sgx_dh_msg3_t protobuf_msg3;
-  protobuf_post_LA_encrypted_msg_t protobuf_encrypted_msg;
-  uint32_t protobuf_sgx_ret; uint32_t sgx_ret;
-
-  // For socket to listen to the Apache enclave.
-  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);
-  uint32_t session_id;  uint8_t read_or_write;
-  size_t bytes_read_post_la; uint8_t encrypted_apache_mrsigner_and_tag[48];
-  size_t bytes_written_post_la;
-  //  int counter;
-  server_fd=set_up_socket(port, &own_addr);
-  if(server_fd==-1)
-      return -1;
-  printf("Successfully set up a socket to communicate with the Apache enclave.\n");
-  fflush(stdout);
-
-  protobuf_sgx_ret = generate_protobuf_dh_msg1(own_enclave_id, protobuf_msg1, &session_id);
-  if(protobuf_sgx_ret != 0)
-  {
-    printf("Error in generate_protobuf_dh_msg1: 0x%x", protobuf_sgx_ret); fflush(stdout); return protobuf_sgx_ret;
-  }
-
-
-  accept_fd = accept(server_fd, (struct sockaddr *)&apache_addr,&apache_addr_size);
-  if (accept_fd <0)
-  {
-        printf("Error in accepting %d", errno);
-        return -1;
-  }
-  printf("Accepted fd\n"); fflush(stdout);
-
-  if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg1)!=0)
-    return -1;
-
-  if(read_protobuf_msg_from_fd(accept_fd, protobuf_msg2)!=0)
-    return -1;
-
-  protobuf_sgx_ret = process_protobuf_dh_msg2_generate_protobuf_dh_msg3(own_enclave_id, protobuf_msg2, protobuf_msg3, &session_id, &read_or_write);
-  if(protobuf_sgx_ret != 0)
-  {
-      printf("Error in generate_protobuf_dh_msg2: 0x%x", protobuf_sgx_ret); fflush(stdout); return protobuf_sgx_ret;
-  }
-
-  if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg3)!=0)
-    return -1;
-//  read_or_write=0;
-
-  printf("Here\n"); fflush(stdout);
-  if(read_or_write)
-  {
-  	bytes_read_post_la=read(accept_fd, encrypted_apache_mrsigner_and_tag, 32);
-	  if(bytes_read_post_la!=32)
- 	 {
-       	printf("Not all of the encrypted apache's mrsigner was read from the verifier.\n"); fflush(stdout); return 0xfe;
- 	 }
-	  bytes_read_post_la=read(accept_fd, encrypted_apache_mrsigner_and_tag+32, 16);
-	  if(bytes_read_post_la!=16)
-	  {
-       printf("Not all of the encrypted apache's mrsigner **tag** was read from the verifier.\n"); fflush(stdout); return 0xfe;
-  	}
-  	uint32_t count;
-  	for(count=0;count<48;count++)
-		printf("0x%02x ", encrypted_apache_mrsigner_and_tag[count]);
-  	printf("\n");fflush(stdout);
-//  sgx_ret=decrypt_wrapper(own_enclave_id, encrypted_apache_mrsigner_and_tag, 32, encrypted_apache_mrsigner_and_tag+32 , plaintext);
-Decryptor_decrypt_verifiers_message_set_apache_mrsigner(own_enclave_id, &sgx_ret, encrypted_apache_mrsigner_and_tag, encrypted_apache_mrsigner_and_tag+32);
- 	 if(sgx_ret!=0)
-	  {
-	printf("Error in decryption: 0x%x\n", sgx_ret); fflush(stdout); return sgx_ret;
-	  }
-	  printf("Successful decryption\n"); fflush(stdout);
-
-
-  }
-  else
-  {
-
-	apache_fd=accept_fd;
-	uint8_t encrypted_sign_data_and_sign_and_tag[176];
-	memset(encrypted_sign_data_and_sign_and_tag,0x0,176);
-	uint8_t plaintext_sign_data_and_sign[160];
-	uint8_t plaintext_priv_key[32];
-	sgx_ec256_signature_t sig2;
-	Decryptor_create_and_encrypt_mitigator_header_value(own_enclave_id, &sgx_ret, plaintext_sign_data_and_sign, encrypted_sign_data_and_sign_and_tag , encrypted_sign_data_and_sign_and_tag+160, plaintext_priv_key,&sig2);
-	if(sgx_ret!=0)
-	{
-		printf("Error in generating encrypted mitigator header:0x%x\n", sgx_ret); fflush(stdout); return 0xf3;
-	}
-	uint32_t count;
-	for(count=0;count<160;count++)
-	{
-		printf("0x%02x ", encrypted_sign_data_and_sign_and_tag[count]);
-	}
-	printf("\n"); fflush(stdout);
-	printf("Plaintext Signature data:\n"); fflush(stdout);
-        for(count=0;count<96;count++)
-        {
-                printf("0x%02x ", plaintext_sign_data_and_sign[count]);
-
-        }
-	printf("\n"); fflush(stdout);
-
-	printf("Plaintext signature: \n"); fflush(stdout);
-        for(count=0;count<32;count++)
-        {
-                printf("%02x", plaintext_sign_data_and_sign[count+96]);
-        }
-	printf("\n"); fflush(stdout);
-        for(count=32;count<64;count++)
-        {
-                printf("%02x", plaintext_sign_data_and_sign[count+96]);
-
-        }
-
-        printf("\n"); fflush(stdout);
-	printf("Heres the private key used to sign this \n"); // TODO: Remove this printf and the private key parts to the ecall
-	for(count=0;count<32;count++)
-		printf("%02x", plaintext_priv_key[31-count]);
-        printf("\n"); fflush(stdout);
-	for(count=0;count<8;count++)
-	{
-		printf("%02x ", sig2.x[count]);
-	}
-	printf("\n"); fflush(stdout);
-
-        for(count=0;count<8;count++)
-        {
-                printf("%02x ", sig2.y[count]);
-        }
-        printf("\n"); fflush(stdout);
-
-	protobuf_encrypted_msg.set_msg((void*)encrypted_sign_data_and_sign_and_tag, 176);
-	if(write_protobuf_msg_to_fd(apache_fd, protobuf_encrypted_msg) != 0)
-         {
-        printf("Not all of the decryptor's signature was written to the Apache.\n"); fflush(stdout); return 0xfe;
-         }
-	unsigned char op_plaintext[160];
-	do {
-//	sleep(100);
-	decrypt_client_data_wrapper(op_plaintext, own_enclave_id);
-//	sleep(100);
-	} while(true);
-
-
-  }
-
-        printf("Successfully done Local attestation\n");
-        fflush(stdout);
-        return 0;
-
-}
-
-
-// decrypt_client_data function that does a read-then-write loop
-// say msg length amount of bytes are read
-////// TODO: first need to decrypt all data received with the aes-gcm apache_iv
-////// Decryptor.cpp function gets the first 64 bytes as first arg and the rest of ciphertext as 2nd arg.
-// then need to call the sgx's compute_shared_key fn for ECDH key - on first 64 bytes.
-// print this key
-// call sha256 on it
-// TODO: decrypt rest of msglength - 64 bytes using this key. (set IV in crypto function)
-////// TODO: then encrypt all user data with apache's key
-////// return here
-/// write data.
-int decrypt_client_data_wrapper(unsigned char* op_plaintext , uint32_t own_enclave_id)
-{
-  protobuf_post_LA_encrypted_msg_t protobuf_msg_from_apache;
-  unsigned char* msg_from_apache;
-  unsigned int protobuf_msg_from_apache_length;
-  uint32_t sgx_ret_status;
-  unsigned char client_keys_and_data_encrypted_to_enclave[160+64];
-  unsigned int client_data_encrypted_to_enclave_length;
-	unsigned char client_data_encrypted_to_apache[160+64];
-  unsigned int client_data_encrypted_to_apache_length;
-
-  printf("Reading msg from apache"); fflush(stdout);
-  if(read_protobuf_msg_from_fd(apache_fd, protobuf_msg_from_apache)!=0)
-  {
-    printf("Not all of the Apache's message was read\n"); fflush(stdout); return 0xfe;
-  }
-  protobuf_msg_from_apache_length = protobuf_msg_from_apache.msg().length();
-  msg_from_apache = (unsigned char*) protobuf_msg_from_apache.msg().c_str();
-
-  std::string protobuf_encrypted_msg_string(protobuf_msg_from_apache.msg());
-	int counter;
-
-  memset(client_keys_and_data_encrypted_to_enclave, 0, 160+64);
- 
-  printf("Read the following from Apache: \n"); fflush(stdout);
-  for(counter=0;counter<protobuf_msg_from_apache_length;counter++)
-  {
-  	client_keys_and_data_encrypted_to_enclave[counter]=*(msg_from_apache+counter);
-		printf("%d ",msg_from_apache[counter]);
-  }
-	printf("\n"); fflush(stdout);
-
-	client_data_encrypted_to_enclave_length = protobuf_msg_from_apache_length-64; // TODO: we hope it's greater than 0
-  // Just so that the ciphertext is returned back to Apache in case decrypt_client_data fails.
-	for(counter=0;counter<client_data_encrypted_to_enclave_length;counter++)
-		client_data_encrypted_to_apache[counter]=client_keys_and_data_encrypted_to_enclave[counter+64];
-
-	client_data_encrypted_to_apache_length = client_data_encrypted_to_enclave_length;
-	uint8_t clen; 
-	Decryptor_decrypt_client_data(own_enclave_id, &sgx_ret_status, client_keys_and_data_encrypted_to_enclave, client_data_encrypted_to_enclave_length, client_data_encrypted_to_apache, &clen);
-	if(sgx_ret_status != 0)
-	{
-		printf("decrypt_client_data returned :0x%x\n", sgx_ret_status); fflush(stdout); //return sgx_ret_status;
-	}
-	if(clen != 0)
-		client_data_encrypted_to_apache_length = clen; 
-
-	printf("About to write the following bytes to the apache\n"); fflush(stdout);
-	for(counter=0;counter<client_data_encrypted_to_apache_length;counter++)
-		printf("%d,", client_data_encrypted_to_apache[counter]);
-	printf("\n"); fflush(stdout);
-  protobuf_msg_from_apache.set_msg((void*)  client_data_encrypted_to_apache, client_data_encrypted_to_apache_length);// Is this message set tho?
-	if(write_protobuf_msg_to_fd(apache_fd, protobuf_msg_from_apache)!=0)
-	{
-		printf("Not all of the protobuf message was written to Apache.\n"); fflush(stdout); return 0xfe;
-	}
-	printf("Wrote data to Apache of length %d \n", protobuf_msg_from_apache.ByteSize());fflush(stdout);
-	return 0;
-}
-

+ 90 - 8
CommonOpensslCode/Openssl_crypto.cpp

@@ -303,8 +303,91 @@ unsigned long compute_ecdh_shared_key(unsigned char* given_public_key_x, unsigne
 	return long_ret;
 }
 
+int compute_ecdsa_signature(unsigned char* signature_data, uint32_t signature_data_length, unsigned char* own_private_key, unsigned char* signature)
+{
+		unsigned long long_ret = 0;
+		EC_GROUP *ec_group = NULL;
+		EC_POINT *given_public_key_point = NULL;
+		EC_KEY *own_keypair = NULL;
+		BIGNUM *own_private_key_bignum = NULL;
+		unsigned char effective_signature_data[32];
+		ECDSA_SIG *openssl_signature;
+		unsigned char** temp = NULL;
+		uint32_t signature_length;
+		// &signature_length will not be NULL
+
+		ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+	  if (NULL == ec_group) {
+	    return 0x0f;
+	  }
+
+		own_keypair = EC_KEY_new();
+		if (own_keypair == NULL) {
+			EC_GROUP_free(ec_group);
+			return 0x42;//ret = SGX_ERROR_OUT_OF_MEMORY;
+		}
+
+		// init private key group (set curve)
+		//
+		if (EC_KEY_set_group (own_keypair, ec_group) != 1) {
+			EC_KEY_free(own_keypair);
+			EC_GROUP_free(ec_group);
+			return ERR_get_error(); //break;
+		}
+
+		// init private key with BN value
+		//
+		own_private_key_bignum = BN_bin2bn(own_private_key, 32, NULL);
+		if(own_private_key_bignum == NULL) {
+			EC_GROUP_free(ec_group);
+			EC_KEY_free(own_keypair);
+			return 0x44;
+		}
+
+		long_ret = EC_KEY_set_private_key(own_keypair, own_private_key_bignum);
+		BN_clear_free(own_private_key_bignum);
+		if (long_ret != 1) {
+			EC_GROUP_free(ec_group);
+			EC_KEY_free(own_keypair);
+			return ERR_get_error();
+		}
+
+		long_ret = generate_sha256_hash(signature_data, signature_data_length, effective_signature_data);
+		if(long_ret != 0)
+		{
+			EC_GROUP_free(ec_group);
+			EC_KEY_free(own_keypair);
+			return long_ret;
+		}
+
+		openssl_signature = ECDSA_do_sign(effective_signature_data, 32, own_keypair);
+		if(openssl_signature==NULL)
+		{
+			EC_GROUP_free(ec_group);
+			EC_KEY_free(own_keypair);
+			return 0x64;
+		}
+
+		signature_length = i2d_ECDSA_SIG(openssl_signature, temp);
+		if(signature_length==0)
+		{
+			EC_GROUP_free(ec_group);
+			EC_KEY_free(own_keypair);
+			return 0x77;
+		}
+
+		signature_length=i2d_ECDSA_SIG(openssl_signature, &signature);
+		if(signature_length==0)
+		{
+			EC_GROUP_free(ec_group);
+			EC_KEY_free(own_keypair);
+			return 0x79;
+		}
+		return 0;
+}
+
 // Code adapted from here: https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption
-int aes_gcm(int enc, unsigned char *key, unsigned char *iv, unsigned char* plaintext, uint32_t plaintext_len, unsigned char *ciphertext,  uint32_t* op_ciphertext_len, unsigned char* tag)
+int aes_gcm_256(int enc, unsigned char *key, unsigned char *iv, unsigned char* plaintext, uint32_t plaintext_len, unsigned char *ciphertext,  uint32_t* op_ciphertext_len, unsigned char* tag)
 {
 	int len;
 	int ciphertext_len;
@@ -386,16 +469,15 @@ uint32_t base64_decoding_wrapper(unsigned char* src, unsigned char* dest, uint32
 {
 	int length_with_padding = EVP_DecodeBlock(dest, src, length);
 	if(length_with_padding == -1)
-		return length_with_padding; 
+		return length_with_padding;
 	char* first_equals_character = strstr((char*)src, "=");
 	if(first_equals_character != NULL)
 	{
 		if(first_equals_character == (char*)src + length - 1) // the first equals character is also the last character in the string ==> Only one equals ==> 2 valid bytes, only 1 padding 0
-			length_with_padding -= 1; 
-		else //if(first_equals_character == src + 38) // assuming that the base64 string is valid (EVP_DecodeBlock would have thrown an error in that case), then first_equals_character == src + 38 ==> Another equals at +29 ==> 1 valid bytes, 2 padding 0s 
-			length_with_padding -= 2; 
+			length_with_padding -= 1;
+		else //if(first_equals_character == src + 38) // assuming that the base64 string is valid (EVP_DecodeBlock would have thrown an error in that case), then first_equals_character == src + 38 ==> Another equals at +29 ==> 1 valid bytes, 2 padding 0s
+			length_with_padding -= 2;
 	}
-	
-	return length_with_padding;	      
-}
 
+	return length_with_padding;
+}

+ 226 - 513
Decryptor/Decryptor.cpp

@@ -1,4 +1,4 @@
-/*
+localAttestation.verifier_mr_enclave/*
  * Copyright (C) 2011-2017 Intel Corporation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,532 +44,245 @@
 #include "sgx_tseal.h"
 #include "Openssl_crypto.h"
 
+#include "sgx_tseal.h"
+
 
+static class Decryptor {
+  uint8_t apache_mrsigner[32];
+  ECDSASignatureBox signatureBox;
+  HybridEncryptionBox hybridEncryptionBoxClient;
+	LocalAttestationTrusted localAttestation;
 
+  uint32_t create_mitigator_token_M(uint8_t* token)
+  {
+    uint32_t internal_return_status;
+    uint32_t counter;
 
+    // create short-term ECDH key pair
+    internal_return_status = hybridEncryptionBoxClient.generate_keypair();
+    if(internal_return_status == NULL)
+      return 0xff;
+    hybridEncryptionBoxClient.get_public_key(token);
+
+    // create token: concatenate short-term keypair with verifiers mrenclave.
+    for(counter=0;counter<32;counter++)
+      *(token + counter + hybridEncryptionBoxClient.ECDH_PUBLIC_KEY_SIZE) = *(localAttestation.verifier_mr_enclave[counter]);
+
+    return 0;
+  }
 
-//extern dh_session_t global_session_info;
-uint8_t apache_iv[12] = {0,0,0,0, 0,0,0,0, 0,0,0,0};
-uint8_t client_iv[12] = {0,0,0,0, 0,0,0,0, 0,0,0,0};
-uint8_t verifier_iv[12] = {0,0,0,0, 0,0,0,0, 0,0,0,0};
-extern uint8_t apache_key[16];
-extern uint8_t verifier_key[16];
-
-
-//uint32_t client_iv=0;
-
-// internal-internal
-uint32_t create_ec_key_pair(sgx_ec256_public_t* pub_key, sgx_ec256_private_t* priv_key);
-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);
-void deserialize_string_to_key_pair(uint8_t* private_public_key_string, sgx_ec256_public_t* pub_key, sgx_ec256_private_t* priv_key);
-uint32_t create_mitigator_header_value(__attribute__((unused)) uint8_t* signature_data, __attribute__((unused)) uint8_t* signature, __attribute__((unused)) uint8_t* private_key,  __attribute__((unused)) sgx_ec256_signature_t* sig2);
-uint32_t aes_gcm_192_call(uint32_t enc, uint8_t* ip_key, uint8_t* ip_iv, uint8_t* ip_ciphertext, uint32_t ip_ciphertext_len, uint8_t* op_plaintext, uint32_t* op_plaintext_length, uint8_t* tag);
-
-
-//uint32_t aes_gcm_internal_call(uint32_t enc, uint8_t* ip_ciphertext, uint32_t ip_ciphertext_len, uint8_t* ip_key, uint8_t* ip_iv, uint8_t* op_plaintext, uint8_t* tag);
-void memcpy_equivalent_copy(uint8_t* dest, uint8_t* src, uint32_t length);
-
-uint32_t verify_mitigator_header_value(uint8_t* signature_data, uint8_t* signature, sgx_ec256_public_t* pub_key);
-
-uint32_t calculate_sealed_data_size( uint32_t input_size) ;
-uint32_t create_and_seal_ecdsa_signing_key_pair(__attribute__((unused))   sgx_ec256_public_t* pub_key, __attribute__((unused))  uint32_t* sealed_data_length,  __attribute__((unused)) uint8_t* sealed_data);
-uint32_t unseal_and_restore_sealed_signing_key_pair(__attribute__((unused)) sgx_ec256_public_t* pub_key, uint8_t* sealed_data, size_t* sgx_sealed_data_length);
-
-uint32_t decrypt_verifiers_message_set_apache_mrsigner(uint8_t* ciphertext, uint8_t* tag);
-uint32_t create_and_encrypt_mitigator_header_value(uint8_t* plaintext_sign_data_and_sign, uint8_t* encrypted_sign_data_and_sign, uint8_t* tag, uint8_t* signing_private_key, __attribute__((unused)) sgx_ec256_signature_t* sig2);
-//static void reverse_byte_array(uint8_t *array, size_t size);
-
-
-uint32_t one_la_done=0;
-static sgx_ec256_public_t short_term_pub_key;
-static sgx_ec256_private_t short_term_priv_key;
-unsigned char short_term_private_key_arr[32];
-unsigned char short_term_public_key_arr[64];
-
-//sgx_ec256_signature_t generated_signature; // TODO: remove
-sgx_measurement_t apache_mr_signer; // TODO: remove
-sgx_measurement_t verifier_mr_enclave; // TODO: remove
-static sgx_ec256_private_t signing_priv_key;
-
-extern "C" uint32_t verify_peer_enclave_trust(__attribute__((unused))  sgx_dh_session_enclave_identity_t* peer_enclave_identity)
-{
-	uint32_t count;
-	if(!peer_enclave_identity)
-	{
-		return INVALID_PARAMETER_ERROR;
-	}
-	if(one_la_done==0)
-	{
-//		return 0x55;
-		//sgx_measurement_t local_mr_enclave;
-		verifier_mr_enclave = peer_enclave_identity->mr_enclave;
-		memset(&(apache_mr_signer.m),0x0,SGX_HASH_SIZE); // "initialization"
-		one_la_done=1;
-
-	}
-	else // apache enclave
-	{
-		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++)
-		{
-			if( actual_mr_signer.m[count] != apache_mr_signer.m[count] )
-				return ENCLAVE_TRUST_ERROR;
-		}
-	}
-	return SGX_SUCCESS;
-}
-
-// increments last 4 bytes (in big-endian order)
-uint32_t aes_gcm_increment_iv_internal_call(uint8_t* iv)
-{
-	uint32_t counter;
-	for(counter=11;counter>7;counter--)
-	{
-		if(iv[counter] == 0xff)
-		{
-			if(counter - 1 == 7)
-				return 0xff;
-			iv[counter-1] = 0x01;
-			iv[counter] = 0x0;
-		}
-		else
-			iv[counter] += 1;
-	}
-	return 0;
-}
-
-// TODO: change global_session_info to two different dh_sessions
-// This needs to be called after the first local attestation is successful - otherwise, the internal apache_mr_signer.m will not be set properly for the comparison of the mrsigner for the 2nd LA in verify_peer_enclave_trust.
-// (I.e. if it is not called then DoS
-uint32_t decrypt_verifiers_message_set_apache_mrsigner(uint8_t* ciphertext, uint8_t* tag)
-{
-	uint32_t length;
-	uint32_t internal_ret_status= aes_gcm_192_call(0, verifier_key, verifier_iv, ciphertext, 32, (uint8_t*) &(apache_mr_signer.m), &length, tag);
-	return internal_ret_status;
-}
-
-// signature_data - 96 bytes, encrypted_signature assumed to be at least 64 bytes, tag - at least 16 bytes
-uint32_t create_and_encrypt_mitigator_header_value(uint8_t* plaintext_sign_data_and_sign, uint8_t* encrypted_sign_data_and_sign, uint8_t* tag, uint8_t* signing_private_key, __attribute__((unused)) sgx_ec256_signature_t* sig2)
-
-{
-	uint32_t count; uint32_t length; 
-	uint8_t sign_data_and_sign[160];
-	uint32_t ret_status=create_mitigator_header_value(sign_data_and_sign, sign_data_and_sign+96, signing_private_key, sig2);
-	if(ret_status != SGX_SUCCESS)
-        	return 0xFFFFFFDD;
-	// TODO: Remove - just for troubleshooting
-	for(count=0; count<160; count++)
-		*(plaintext_sign_data_and_sign+count)=sign_data_and_sign[count];
-
-	ret_status = aes_gcm_192_call(1, apache_key, apache_iv, sign_data_and_sign, 160, encrypted_sign_data_and_sign, &length, tag);
-//	ret_status = encrypt_internal(sign_data_and_sign, 160, tag, encrypted_sign_data_and_sign);
-	aes_gcm_increment_iv_internal_call(apache_iv);
-	return ret_status;
-}
-
-
-
-
-uint32_t create_ec_key_pair(sgx_ec256_public_t* pub_key, sgx_ec256_private_t* priv_key)
-{
-  sgx_status_t se_ret; sgx_status_t se_ret2;
-  //create ECC context
-  sgx_ecc_state_handle_t ecc_state = NULL;
-  se_ret = sgx_ecc256_open_context(&ecc_state);
-  if(SGX_SUCCESS != se_ret)
-    return se_ret;
-
-  // generate private key and public key
-  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.
-    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_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
+  uint32_t create_mitigator_header_H(uint8_t* signature_data, uint8_t* signature)
   {
-     uint32_t counter;
-     if(pub_key != NULL)  // public key to serialize
-     {
-        for(counter=0;counter<SGX_ECP256_KEY_SIZE; counter++)
-          *(private_public_key_string+counter)=pub_key->gx[counter];
-
-        for(counter=SGX_ECP256_KEY_SIZE;counter<2*SGX_ECP256_KEY_SIZE; counter++)
-           *(private_public_key_string+counter)=pub_key->gy[counter-SGX_ECP256_KEY_SIZE];
-     }
-
-     if(signing_priv_key != NULL) // private key to serialize
-     {
-       for(counter=2*SGX_ECP256_KEY_SIZE;counter<3*SGX_ECP256_KEY_SIZE; counter++)
-          *(private_public_key_string+counter)=signing_priv_key->r[counter - 2*SGX_ECP256_KEY_SIZE];
-     }
+    uint32_t internal_return_status;
+    uint8_t local_signature[64];
+    uint8_t local_signature_data[hybridEncryptionBoxClient.ECDH_PUBLIC_KEY_SIZE + 32];
+    // Otherwise: DoS or possible bypass (fake verifier does LA  but real verifier mrenclave is given out by decryptor) - signature with junk verifier mrenclave  or whatever is in the memory.
+    if(one_la_done < 1)
+      return 0xde;  //  This needs to be called at any point after the first local attestation is done - else, a junk verifier mrenclave will be included in the signature
+    internal_return_status = generate_mitigator_token(local_signature_data);
+    if(internal_return_status != 0x0)
+      return internal_return_status;
+
+    internal_return_status = signatureBox.sign(local_signature_data, signatureBox.ECDH_PUBLIC_KEY_SIZE + 32, local_signature);
+    if(internal_return_status != 0x0)
+      return internal_return_status;
+    for(counter=0;counter<hybridEncryptionBoxClient.ECDH_PUBLIC_KEY_SIZE + 32;counter++)
+      signature_data[counter] = local_signature_data[counter];
+    for(counter=0;counter<64;counter++)
+      signature[counter] = local_signature[counter];
+    return 0;
   }
-}
 
+  // done. But there might be one more return statement for the case when get_keypair returns sth (it is non void).
+  uint32_t create_long_term_signing_keypair(uint8_t* private_public_key_string)
+  {
+    uint32_t internal_return_status;
+    internal_return_status = signatureBox.generate_keypair();
+    if(internal_return_status != 0)
+      return internal_return_status;
+
+    private_public_key_string = (uint8_t*) malloc(signatureBox.ECDH_PUBLIC_KEY_SIZE + signatureBox.ECDH_PRIVATE_KEY_SIZE);
+    if(private_public_key_string == NULL)
+      return 0xff;
+    signatureBox.get_keypair(private_public_key_string);
+    return 0;
+  }
 
-// todo: set to private
-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
+  uint32_t initialize_symmetric_key_decrypt_client_data(uint8_t* plaintext_client_public_key_plus_encrypted_data_plus_tag, uint32_t total_length, uint8_t* plaintext_client_data, uint32_t* plaintext_client_data_length)
   {
-    uint32_t counter;
-    if(signing_priv_key != NULL)
+    uint8_t* ciphertext;
+    uint32_t ciphertext_length;
+    uint8_t* tag;
+    // and now I will derive a shared key from the plaintext_client_public_key
+    internal_return_status = hybridEncryptionBoxClient.initialize_symmetric_key(plaintext_client_public_key_plus_encrypted_data_plus_tag);
+    if(internal_return_status != 0)
+      return internal_return_status;
+
+    // and then I will decrypt the rest of the client data with that key.
+    ciphertext = plaintext_client_public_key_plus_encrypted_data_plus_tag + hybridEncryptionBoxClient.ECDH_PUBLIC_KEY_SIZE;
+    ciphertext_length = total_length - hybridEncryptionBoxClient.ECDH_PUBLIC_KEY_SIZE - 16;
+    tag = ciphertext + ciphertext_length;
+
+    internal_return_status = hybridEncryptionBoxClient.encrypt_decrypt(ciphertext, ciphertext_length, plaintext_client_data, &plaintext_client_data_length, tag);
+    return internal_return_status;
+  }
+
+  public:
+    Decryptor(): signatureBox(), hybridEncryptionBoxClient(), localAttestation();
+    ~Decryptor();
+
+    // DONE.
+    uint32_t create_and_seal_long_term_signing_key_pair(uint32_t* sealed_data_length, uint8_t* sealed_data)
     {
+        uint32_t sgx_libcall_status;
+        uint32_t internal_return_status;
+        uint32_t temp_sealed_data_length;
+        uint8_t* temp_sealed_data, private_public_key_string;
+        uint32_t counter;
+
+        temp_sealed_data_length = sgx_calc_sealed_data_size(0, signatureBox.ECDH_PUBLIC_KEY_SIZE + signatureBox.ECDH_PRIVATE_KEY_SIZE);
+        if(temp_sealed_data_length == 0xFFFFFFFF)
+          return 0x01;
+
+        internal_return_status = create_long_term_signing_keypair(private_public_key_string);
+
+    		temp_sealed_data = (uint8_t*) malloc(*temp_sealed_data_length);
+        sgx_libcall_status = sgx_seal_data(0, NULL, 3*SGX_ECP256_KEY_SIZE, private_public_key_string, *temp_sealed_data_length, (sgx_sealed_data_t*) temp_sealed_data);
+        free(private_public_key_string); // first_decryption_output data - don't need it anymore, whether the call succeeds or fails.
+        if(sgx_libcall_status != SGX_SUCCESS)
+        {
+          free(temp_sealed_data);
+          return sgx_libcall_status;
+        }
+
+        for(counter=0;counter<temp_sealed_data_length;counter++)
+    			*(sealed_data + counter)=*(temp_sealed_data + counter);
+        free(temp_sealed_data);
+        return 0;
+    }
 
-     for(counter=2*SGX_ECP256_KEY_SIZE;counter<3*SGX_ECP256_KEY_SIZE; counter++)
-       signing_priv_key->r[counter-2*SGX_ECP256_KEY_SIZE]=*(private_public_key_string+counter);
+    // DONE.
+    uint32_t create_and_encrypt_mitigator_header_H(uint8_t* ciphertext_token_H_plus_tag)
+    {
+    	uint32_t counter;
+    	uint8_t sign_data_and_sign[signatureBox.ECDH_PUBLIC_KEY_SIZE + 32 + 64];
+      uint8_t temp_ciphertext_token_H[signatureBox.ECDH_PUBLIC_KEY_SIZE + 32 + 64 + 10];
+      uint8_t temp_tag[16];
+      uint32_t temp_ciphertext_token_H_length;
+    	uint32_t internal_return_status;
+
+      internal_return_status = create_mitigator_header_value(token_H, sign_data_and_sign + signatureBox.ECDH_PUBLIC_KEY_SIZE + 32);
+    	if(internal_return_status != 0)
+      	return internal_return_status;
+
+      internal_return_status = localAttestation.symmetricEncryptionBoxApache.encrypt_decrypt(1, sign_data_and_sign, signatureBox.ECDH_PUBLIC_KEY_SIZE + 32 + 64, temp_ciphertext_token_H, &temp_ciphertext_token_H_length, temp_tag);
+      if(internal_return_status != 0)
+        return internal_return_status;
+
+      if(temp_ciphertext_token_H_length != 160)
+        return 0x45;
+
+      for(counter=0; counter<160; counter++)
+      {
+        *(ciphertext_token_H_plus_tag + counter) = *(temp_ciphertext_token_H + counter);
+      }
+      for(counter=0; counter<16; counter++)
+      {
+        *(ciphertext_token_H_plus_tag + counter) = *(temp_tag + counter);
+      }
+
+    	return 0;
     }
 
-    if(pub_key != NULL)
+    // DONE.
+    uint32_t unseal_and_restore_long_term_signing_key_pair(uint8_t* sealed_data, uint32_t* sgx_sealed_data_length)
     {
-      for(counter=0;counter<SGX_ECP256_KEY_SIZE; counter++)
-        	pub_key->gx[counter]=*(private_public_key_string+counter);
+      uint32_t temp_plaintext_length;
+      uint8_t* temp_plaintext;
+      uint32_t counter;
+      uint32_t ret_status;
+      uint8_t* temp_sealed_data ;
+
+      temp_sealed_data = (uint8_t*) malloc(*sgx_sealed_data_length);
+      for(counter=0;counter<*sgx_sealed_data_length;counter++)
+        *(temp_sealed_data+counter)=*(sealed_data+counter);
+
+      temp_plaintext_length = sgx_get_encrypt_txt_len((sgx_sealed_data_t*)sealed_data);
+      if(temp_plaintext_length == 0xffffffff)
+        return 0xFFFFFFFF;
+      temp_plaintext = (uint8_t*)malloc( temp_plaintext_length );
+
+      ret_status = sgx_unseal_data((sgx_sealed_data_t*)temp_sealed_data, NULL, 0, temp_plaintext, &temp_plaintext_length);
+      free(temp_sealed_data);
+      if(ret_status != SGX_SUCCESS)
+      {
+        free(temp_plaintext);
+        return ret_status;
+      }
+
+      signatureBox.set_keypair(temp_plaintext);
+      free(temp_plaintext);
+      return 0;
+    }
 
-      for(counter=SGX_ECP256_KEY_SIZE;counter<2*SGX_ECP256_KEY_SIZE; counter++)
-  	pub_key->gy[counter-SGX_ECP256_KEY_SIZE]=*(private_public_key_string+counter);
+    // DONE.
+    uint32_t decrypt_verifiers_message_set_apache_mrsigner(uint8_t* ciphertext_plus_tag)
+    {
+      uint8_t temp_apache_mrsigner[32+10];
+      uint32_t temp_apache_mrsigner_length;
+      uint32_t internal_return_status;
+      uint32_t counter;
+      uint8_t* tag;
+
+      tag = ciphertext_plus_tag + 32;
+      internal_return_status = localAttestation.symmetricEncryptionBoxVerifier.encrypt_decrypt(0, ciphertext_plus_tag, 32, temp_apache_mrsigner, &temp_apache_mrsigner_length, tag);
+      if(internal_return_status != 0)
+        return internal_return_status;
+      if(temp_apache_mrsigner_length != 32)
+        return 0x33;
+
+      for(counter=0; counter<32; counter++)
+      {
+        apache_mr_signer[counter] = *(temp_apache_mrsigner + counter);
+      }
+      return 0;
     }
-  }
-}
-
-
-uint32_t create_and_seal_ecdsa_signing_key_pair(__attribute__((unused))   sgx_ec256_public_t* pub_key, __attribute__((unused))  uint32_t* sealed_data_length,
- __attribute__((unused)) uint8_t* sealed_data)
-{
-    uint32_t ret_status; sgx_ec256_private_t private_key;  uint32_t counter;
-    ret_status=create_ec_key_pair(pub_key, &private_key);
-    if(ret_status!=SGX_SUCCESS)
-       return ret_status;
-    for(counter=0;counter<SGX_ECP256_KEY_SIZE; counter++)
-	signing_priv_key.r[counter]=private_key.r[counter];
-    // generating the entire string as there is no SGX function to generate the public key from the private one.
-    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_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];
-//    return *sealed_data_length;
-    ret_status = sgx_seal_data(0, NULL, 3*SGX_ECP256_KEY_SIZE, private_public_key_string, *sealed_data_length, (sgx_sealed_data_t*) sealed_data2);
-    for(counter=0;counter<*sealed_data_length;counter++)
-	*(sealed_data+counter)=*(sealed_data2+counter);
-    free(sealed_data2);
-    free(private_key_string);  //free(private_key);
-    free(private_public_key_string);
-
-    return ret_status; // SGX_SUCCESS;
-}
-
-uint32_t unseal_and_restore_sealed_signing_key_pair(__attribute__((unused)) sgx_ec256_public_t* pub_key, uint8_t* sealed_data, size_t* sgx_sealed_data_length)
-{
-  uint32_t expected_plaintext_msg_length; uint8_t* temp_plaintext; uint32_t counter; uint32_t ret_status;
-  expected_plaintext_msg_length = sgx_get_encrypt_txt_len((sgx_sealed_data_t*)sealed_data);
-  if(expected_plaintext_msg_length == 0xffffffff)
-    return 0xFFFFFFFF;
-
-  uint8_t* sealed_data2 = (uint8_t*) malloc(*sgx_sealed_data_length);
-  for(counter=0;counter<*sgx_sealed_data_length;counter++)
-  {
-	*(sealed_data2+counter)=*(sealed_data+counter);
-  }
 
-  temp_plaintext = (uint8_t*)malloc( expected_plaintext_msg_length );
-  ret_status = sgx_unseal_data((sgx_sealed_data_t*)sealed_data2, NULL, 0, temp_plaintext, &expected_plaintext_msg_length);
-  if(ret_status != SGX_SUCCESS)
-  {
-    free(temp_plaintext);free(sealed_data2);
-    return ret_status;
-  }
-  deserialize_string_to_key_pair(temp_plaintext, pub_key, &signing_priv_key);
-  free(temp_plaintext); free(sealed_data2);
-  return SGX_SUCCESS;
-}
-
-uint32_t create_mitigator_header_value(__attribute__((unused)) uint8_t* signature_data, __attribute__((unused)) uint8_t* signature, __attribute__((unused)) uint8_t* private_key, __attribute__((unused)) sgx_ec256_signature_t* sig2)
-{
-	// Otherwise: DoS or possible bypass (fake verifier does LA  but real verifier mrenclave is given out by decryptor) - signature with junk verifier mrenclave  or whatever is in the memory.
-	if(one_la_done < 1)
-		return 0xde;  //  This needs to be called at any point after the first local attestation is done - else, a junk verifier mrenclave will be included in the signature
-
-	// create key pair
-	uint32_t ret_status = ecdh_key_gen(short_term_public_key_arr, short_term_public_key_arr + 32, short_term_private_key_arr); //create_ec_key_pair(&short_term_pub_key, &short_term_priv_key);
-	uint32_t counter;
-	uint32_t ret_status2;
-        if(ret_status!=0)
-           return ret_status;
-	for(counter=0;counter<32;counter++)
-	{
-		*(signature_data + counter) = short_term_public_key_arr[counter]; // public key -> x component
-		*(signature_data + counter + 32) = short_term_public_key_arr[counter + 32]; // public key -> y component
-		*(signature_data + counter + 64) = 0x55; // verifier mr_enclave // TODO: fix this.
-	}
-
-	// 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;
-
-	// TODO: For testing/checking purposes only.
-	for(counter=0;counter<32;counter++)
-		*(private_key+counter)=short_term_private_key_arr[counter];  //short_term_priv_key.r[counter];
-
-	//// 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(signature_data, 96, &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)
-	{	// this only works for Little-endian architectures - need to do byte-wise swapping of the bytes obtained on RHS
-		uint8_t *current_sig_byte = (uint8_t*)(&(local_signature.x));
-	        uint32_t ecdsa_sig_count;
-        	for(ecdsa_sig_count=0;ecdsa_sig_count<32;ecdsa_sig_count++)
-                	signature[31-ecdsa_sig_count]=*(current_sig_byte+ecdsa_sig_count);
-	        current_sig_byte = (uint8_t*)(&(local_signature.y));
-        	for(ecdsa_sig_count=0;ecdsa_sig_count<32;ecdsa_sig_count++)
-                	signature[63-ecdsa_sig_count]=*(current_sig_byte+ecdsa_sig_count);
-		for(ecdsa_sig_count=0;ecdsa_sig_count<8;ecdsa_sig_count++)
-			sig2->x[ecdsa_sig_count]=local_signature.x[ecdsa_sig_count];
-                for(ecdsa_sig_count=0;ecdsa_sig_count<8;ecdsa_sig_count++)
-                        sig2->y[ecdsa_sig_count]=local_signature.y[ecdsa_sig_count];
-
-	}
-	if(ret_status != SGX_SUCCESS || ret_status2 != SGX_SUCCESS)
-		return 0xFFFFFFFF;
-	return 0;
-}
-
-uint32_t verify_mitigator_header_value(uint8_t* signature_data, uint8_t* signature, sgx_ec256_public_t* pub_key)
-{
-	sgx_ec256_public_t local_pub_key;	uint32_t counter;  uint32_t ret_status; uint32_t ret_status2;
-	for(counter=0;counter<SGX_ECP256_KEY_SIZE;counter++)
-	{
-		local_pub_key.gx[counter] = pub_key->gx[counter];
-		local_pub_key.gy[counter] = pub_key->gy[counter];
-	}
-	sgx_ec256_signature_t local_signature; sgx_ecc_state_handle_t ecc_handle;
-	uint8_t *current_sig_byte = (uint8_t*)(&(local_signature.x));
-	uint32_t ecdsa_sig_count; uint8_t verification_result;
-        for(ecdsa_sig_count=0;ecdsa_sig_count<32;ecdsa_sig_count++)
-        	*(current_sig_byte+ecdsa_sig_count)=signature[ecdsa_sig_count];
-	current_sig_byte = (uint8_t*)(&(local_signature.y));
-	for(ecdsa_sig_count=0;ecdsa_sig_count<32;ecdsa_sig_count++)
-		*(current_sig_byte+ecdsa_sig_count)=signature[ecdsa_sig_count+32];
-
-	//// opening context for signature
-        ret_status = sgx_ecc256_open_context(&ecc_handle);
-        if(ret_status != SGX_SUCCESS)
-                return ret_status;
-
-        ret_status = sgx_ecdsa_verify(signature_data,3*SGX_ECP256_KEY_SIZE, &local_pub_key, &local_signature, &verification_result, ecc_handle);
-        ret_status2 = sgx_ecc256_close_context(ecc_handle);
-        if(ret_status != SGX_SUCCESS || ret_status2 != SGX_SUCCESS)
-                return 0xFFFFFFFF;
-	if(verification_result != SGX_EC_VALID)
-		return 0xee;
-        return 0;
-}
-
-uint32_t derive_shared_secret_for_client(uint8_t* pub_key, uint8_t* shared_key)
-{
-	return 0;
-
-
-}
-
-uint32_t calculate_sealed_data_size( uint32_t input_size)
-{
-//      *op_size=sgx_calc_sealed_data_size(0, input_size);
-        return sgx_calc_sealed_data_size(0, input_size);
-
-}
-
-
-// ip_key will always be within the enclave.
-// enc = 1 for encryption and 0 for decryption, like openssl api
-// TODO: Rename this - it's actually 128 bit encryption. 
-uint32_t aes_gcm_192_call(uint32_t enc, uint8_t* ip_key, uint8_t* ip_iv, uint8_t* ip_ciphertext, uint32_t ip_ciphertext_len, uint8_t* op_plaintext, uint32_t* op_plaintext_length, uint8_t* tag)
-{
-	uint32_t counter;
-	if(ip_ciphertext == NULL)
-		return 0x33;
-	if(tag == NULL)
-		return 0x34;
-	if(op_plaintext == NULL)
-		return 0x36;
-	if(ip_key == NULL)
-		return 0x35;
-	if(ip_iv == NULL)
-		return 0x37;
-
-	uint8_t* ip_ciphertext_in_enclave = (uint8_t*) malloc(ip_ciphertext_len);
-	memcpy_equivalent_copy(ip_ciphertext_in_enclave, ip_ciphertext, ip_ciphertext_len);
-
-	uint8_t tag_in_enclave [16];
-	if(!enc)
-		memcpy_equivalent_copy(tag_in_enclave, tag, 16);
-
-	uint8_t* op_plaintext_in_enclave = (uint8_t*) malloc(ip_ciphertext_len);
-	uint32_t internal_ret_status;
-	if(enc)
-		internal_ret_status = sgx_rijndael128GCM_encrypt((sgx_key_128bit_t*) ip_key, ip_ciphertext_in_enclave, ip_ciphertext_len, op_plaintext_in_enclave, ip_iv, 0xc, NULL, 0, (sgx_aes_gcm_128bit_tag_t*)tag_in_enclave);
-	else
-		internal_ret_status = sgx_rijndael128GCM_decrypt((sgx_key_128bit_t*) ip_key, ip_ciphertext_in_enclave, ip_ciphertext_len, op_plaintext_in_enclave, ip_iv, 0xc, NULL, 0, (sgx_aes_gcm_128bit_tag_t*)tag_in_enclave);
-
-	if(internal_ret_status == 0)
-	{
-		memcpy_equivalent_copy(op_plaintext, op_plaintext_in_enclave, ip_ciphertext_len);
-		if(enc)
-	                memcpy_equivalent_copy(tag, tag_in_enclave, 16);
-		*op_plaintext_length = ip_ciphertext_len;
-	}
-
-	free(ip_ciphertext_in_enclave); free(op_plaintext_in_enclave);
-
-	return internal_ret_status;
-}
-
-void memcpy_equivalent_copy(uint8_t* dest, uint8_t* src, uint32_t length)
-{
-	uint32_t counter;
-	for(counter=0; counter<length; counter++)
-		*(dest + counter) = *(src + counter);
-}
-
-// Output buffer should be of length at least equal to the second argument. 
-uint32_t decrypt_client_data(unsigned char* ip_encrypted_client_pub_key_and_data, uint32_t ip_encrypted_client_pub_key_and_data_length, unsigned char* op_client_data, uint8_t* clen)
-{
-	unsigned int counter; unsigned long check_ret; uint32_t ret; 
-	unsigned char derived_key[32];
-	unsigned char* plaintext_client_public_key;
-	unsigned char* plaintext_client_data; 
-	unsigned char* client_data_encrypted_to_decryptor; 
-	uint32_t client_data_encrypted_to_decryptor_length;
-	unsigned char* tag_for_client_data_encrypted_to_decryptor;
-	unsigned char* client_data_encrypted_to_apache; 
-	uint32_t client_data_encrypted_to_apache_length;
-	unsigned char tag_for_client_data_encrypted_to_apache[16];
-	unsigned char* temp_array; 
-	uint32_t temp_array_valid_length;
-	unsigned char client_iv[12]={0,0,0,0, 0,0,0,0, 0,0,0,0};
-
-	for(counter=64;counter<ip_encrypted_client_pub_key_and_data_length;counter++)
-		op_client_data[counter]=ip_encrypted_client_pub_key_and_data[counter];
-	*clen = (uint8_t) ip_encrypted_client_pub_key_and_data_length; 
-
-	temp_array = (unsigned char*) malloc(ip_encrypted_client_pub_key_and_data_length); 
-/*
-	// TODO: Remove aes_gcm_internal_call function - upgrade to using openssl's aesgcm 192 bit enc 
-	// TODO: Change the returned 2nd length o/p to be incoming length - tag length for decryption and incoming length + 16 for encryption
-	ret = aes_gcm_192_call(0, apache_key, apache_iv, ip_encrypted_client_pub_key_and_data, ip_encrypted_client_pub_key_and_data_length, temp_array, &temp_array_valid_length, ip_encrypted_client_pub_key_and_data + ip_encrypted_client_pub_key_and_data_length - 16);
-	if(ret != 0)
-	{
-		free(temp_array);
-		return ret; 
-	}
-	
-	for(counter=0; counter<temp_array_valid_length; counter++)
-        	op_client_data[counter] = temp_array[counter];
-	*clen = temp_array_valid_length;
-	free(temp_array); 
-	return 0;
-*/
-
-	// Temp_array = {X component of public key (32 bytes), Y component of public key (32 bytes), client data encrypted to decryptor (x), tag for client data encrypted to decryptor (16 bytes)
-	// therefore, length x = temp_array_valid_length - 64 (for public key) - 16 (for own tag) 
-	plaintext_client_public_key = ip_encrypted_client_pub_key_and_data; // temp_array; 
-	client_data_encrypted_to_decryptor = ip_encrypted_client_pub_key_and_data + 64; 
-	client_data_encrypted_to_decryptor_length = ip_encrypted_client_pub_key_and_data_length; // temp_array_valid_length - 64 - 16; 
-	tag_for_client_data_encrypted_to_decryptor = ip_encrypted_client_pub_key_and_data + 64 + ip_encrypted_client_pub_key_and_data_length; //temp_array + 64 + client_data_encrypted_to_decryptor_length; 
-
-	check_ret = compute_ecdh_shared_key(plaintext_client_public_key, plaintext_client_public_key + 32, short_term_private_key_arr, derived_key);
-	if(check_ret != 0)
-	{
-		plaintext_client_public_key = NULL;
-		client_data_encrypted_to_decryptor = NULL;
-		tag_for_client_data_encrypted_to_decryptor = NULL;
-		free(temp_array); 
-		return check_ret;
-	}
-/*
-	check_ret = aes_gcm(0, derived_key, client_iv, client_data_encrypted_to_decryptor, client_data_encrypted_to_decryptor_length, temp_array, &temp_array_valid_length, tag_for_client_data_encrypted_to_decryptor);
-	if(check_ret != 0)
-	{
-	        plaintext_client_public_key = NULL;
-                client_data_encrypted_to_decryptor = NULL;
-                tag_for_client_data_encrypted_to_decryptor = NULL;
-                free(temp_array); 
-		return check_ret;
-	}
-*/
-	for(counter=0;counter<32;counter++)
-		op_client_data[counter]=derived_key[counter]; 
-
-//	for(counter=0; counter<temp_array_valid_length; counter++)
-//		op_client_data[counter] = temp_array[counter];
-//	for(counter=0; counter<16; counter++)
-//		op_client_data[temp_array_valid_length + counter] = tag_for_client_data_encrypted_to_decryptor[counter];
-
-//	*clen = temp_array_valid_length + 16; 
-	*clen = 32; 
-	return 0;
-/*
-	// Temp_array = {X component of public key (32 bytes), Y component of public key (32 bytes), client data encrypted to decryptor (x), tag for client data encrypted to decryptor (16 bytes)
-	// therefore, length x = temp_array_valid_length - 64 (for public key) - 16 (for own tag) 
-	plaintext_client_public_key = temp_array; 
-	client_data_encrypted_to_decryptor = temp_array + 64; 
-	client_data_encrypted_to_decryptor_length = temp_array_valid_length - 64 - 16; 
-	tag_for_client_data_encrypted_to_decryptor = temp_array + 64 + client_data_encrypted_to_decryptor_length; 
-
-	check_ret = compute_ecdh_shared_key(plaintext_client_public_key, plaintext_client_public_key + 32, short_term_private_key_arr, derived_key);
-	if(check_ret != 0)
-	{
-		plaintext_client_public_key = NULL;
-		client_data_encrypted_to_decryptor = NULL;
-		tag_for_client_data_encrypted_to_decryptor = NULL;
-		free(temp_array); 
-		return check_ret;
-	}
-
-	check_ret = aes_gcm(0, derived_key, client_iv, client_data_encrypted_to_decryptor, client_data_encrypted_to_decryptor_length, temp_array, &temp_array_valid_length, tag_for_client_data_encrypted_to_decryptor);
-	if(check_ret != 0)
-	{
-	        plaintext_client_public_key = NULL;
-                client_data_encrypted_to_decryptor = NULL;
-                tag_for_client_data_encrypted_to_decryptor = NULL;
-                free(temp_array); 
-		return check_ret;
-	}
-
-	client_data_encrypted_to_apache = (uint8_t*) malloc(temp_array_valid_length); 
-	ret = aes_gcm_192_call(1, apache_key, apache_iv, temp_array, temp_array_valid_length, client_data_encrypted_to_apache, &client_data_encrypted_to_apache_length, tag_for_client_data_encrypted_to_apache); 
-	if(ret == 0)
-	{
-		for(counter=0; counter<client_data_encrypted_to_apache_length; counter++)
-			op_client_data[counter] = client_data_encrypted_to_apache[counter];
-		for(counter=0; counter<16; counter++) // TODO: This overwrites the first 16 bytes of the array written in the line above (WTF is going on) 
-			op_client_data[counter] = tag_for_client_data_encrypted_to_apache[counter]; 
-		*clen = (uint8_t) client_data_encrypted_to_apache_length + 16; // Need to give in the total wire length
-	}
-
-	plaintext_client_public_key = NULL;
-	client_data_encrypted_to_decryptor = NULL;
-        tag_for_client_data_encrypted_to_decryptor = NULL;
-        free(temp_array); 
-	free(client_data_encrypted_to_apache); 
-
-        return ret; 
-*/
-}
+    // DONE.
+    uint32_t process_apache_message_generate_response(uint8_t* input_ciphertext, uint32_t input_ciphertext_plus_tag_length, uint8_t* output_ciphertext, uint32_t* output_ciphertext_plus_tag_length)
+    {
+      uint8_t* first_decryption_output, plaintext_client_data, temp_output_ciphertext;
+      uint32_t first_decryption_output_length, plaintext_client_data_length, temp_output_ciphertext_plus_tag_length, internal_return_status;
+      uint8_t temp_output_tag[16];
+      // TODO: May be have temporary variables for input ciphertext as they can't be passed directly to functions?
+      first_decryption_output = (uint8_t*) malloc(input_ciphertext_length + 10);
+      internal_return_status = localAttestation.symmetricEncryptionBoxApache.encrypt_decrypt(0, input_ciphertext, input_ciphertext_length, first_decryption_output, &first_decryption_output_length, input_ciphertext + input_ciphertext_length - 16);
+      if(internal_return_status != 0)
+      {
+        free(first_decryption_output);
+        return internal_return_status;
+      }
+
+      plaintext_client_data = (uint8_t*) malloc(first_decryption_output_length); // you will need less than this coz public key size.
+      internal_return_status = initialize_symmetric_key_decrypt_client_data(first_decryption_output, first_decryption_output_length, plaintext_client_data, &plaintext_client_data_length);
+      free(first_decryption_output);
+      if(internal_return_status != 0)
+        return internal_return_status;
+
+      temp_output_ciphertext = (uint8_t*) malloc(plaintext_client_data_length + 20);
+      // then I will encrypt the resulting first_decryption_output to the apache enclave.
+      internal_return_status = localAttestation.symmetricEncryptionBoxApache.encrypt_decrypt(1, plaintext_client_data, plaintext_client_data_length, temp_output_ciphertext, &temp_output_ciphertext_length, temp_output_tag);
+      free(plaintext_client_data);
+      if(internal_return_status != 0)
+      {
+        free(temp_output_ciphertext);
+        return internal_return_status;
+      }
+
+      for(counter=0; counter<temp_output_ciphertext_length; counter++)
+        output_ciphertext[counter] = temp_output_ciphertext[counter];
+      *output_ciphertext_length = temp_output_ciphertext_length + 16;
+      free(temp_output_ciphertext);
+      return 0;
+    }
+  };

+ 11 - 21
Decryptor/Decryptor.edl

@@ -35,24 +35,14 @@ enclave {
     include "sgx_tcrypto.h"
     from "../LocalAttestationCode/LocalAttestationCode.edl" import *;
     from "/home/m2mazmud/old_stuff/intel-sgx-ssl/Linux/package/include/sgx_tsgxssl.edl" import * ;
-    trusted{
-    #define SEALED_SIZE 768  // 656 // =0x300 (0x290 is the size of the sealed message when both the public(0x40) and private key(0x20) are included)
-// TODO: refine this to avoid crashes
-    #define MAX_POST_LA_MSG_SIZE 32 // 32 bytes for the mrsigner from the verifier that will be sent to the apache enclave BUT possibly much more for decrypted content
-
-
-	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);
-        public uint32_t calculate_sealed_data_size(uint32_t input_size);
-public uint32_t decrypt_verifiers_message_set_apache_mrsigner([in, size=32] uint8_t* ciphertext, [in, size=16] uint8_t* tag);
-public uint32_t create_and_encrypt_mitigator_header_value([out, size=160] uint8_t* plaintext_sign_data_and_sign, [out, size=160] uint8_t* encrypted_sign_data_and_sign, [out, size=16] uint8_t* tag, [out, size=32] uint8_t* signing_private_key, [out] sgx_ec256_signature_t* sig2);
-//public uint32_t decrypt_client_data([in, size=64] unsigned char* client_pub_key, [in, size=160] unsigned char* user_data, uint32_t ciphertext_length, [out, size=160] unsigned char* client_data_to_apache, [out, size=1] uint8_t* clen);
-//public uint32_t ec_key_gen([out, size=32] unsigned char* pub_key_x, [out, size=32] unsigned char* pub_key_y, [out, size=32] unsigned char* priv_key);
-public uint32_t decrypt_client_data([in, size=224] unsigned char* ip_encrypted_client_pub_key_and_data, uint32_t ip_encrypted_client_pub_key_and_data_length, [out,size=224] unsigned char* op_client_data_to_apache, [out, size=1] uint8_t* clen); 
-// 224=160+64
-
-
-
-};
-};
-
+    trusted {
+      #define SEALED_SIZE 768  // 656 // =0x300 (0x290 is the size of the sealed message when both the public(0x40) and private key(0x20) are included)
+      public uint32_t create_and_seal_long_term_signing_key_pair_wrapper([out] uint32_t* sealed_data_length, [out,size=SEALED_SIZE] uint8_t* sealed_data);
+      public uint32_t unseal_and_restore_long_term_signing_key_pair_wrapper([in, size=SEALED_SIZE] uint8_t* sealed_data, [in] uint32_t* sgx_sealed_data_length);
+      public uint32_t create_and_encrypt_mitigator_header_H_wrapper([out, size=176] uint8_t* ciphertext_token_H_plus_tag);
+      // Apache mrsigner = 32 bytes + tag on encryption = 16 bytes.
+      public uint32_t decrypt_verifiers_message_set_apache_mrsigner_wrapper([in, size=48] uint8_t* ciphertext_plus_tag);
+      // NEED AT LEAST: 64 bytes for public key of client, plus 64 bytes of signature over it, plus 16 bytes of tag over any encryption = 144 bytes. Msg length = 144 bytes + Length of form field
+      public uint32_t process_apache_message_generate_response_wrapper([in, size=256] uint8_t* input_ciphertext, uint32_t input_ciphertext_plus_tag_length, [out, size=256] uint8_t* output_ciphertext, [out,size=4] uint32_t* output_ciphertext_plus_tag_length);
+    };
+  };

+ 29 - 0
Decryptor/DecryptorWrapper.cpp

@@ -0,0 +1,29 @@
+uint32_t process_apache_message_generate_response_wrapper(uint8_t* input_ciphertext, uint32_t input_ciphertext_plus_tag_length, uint8_t* output_ciphertext, uint32_t* output_ciphertext_plus_tag_length)
+{
+  return Decryptor::process_apache_message_generate_response(input_ciphertext, input_ciphertext_plus_tag_length, output_ciphertext, output_ciphertext_plus_tag_length);
+}
+
+uint32_t decrypt_verifiers_message_set_apache_mrsigner_wrapper(uint8_t* ciphertext_plus_tag)
+{
+  return Decryptor::decrypt_verifiers_message_set_apache_mrsigner(ciphertext_plus_tag);
+}
+
+uint32_t unseal_and_restore_long_term_signing_key_pair_wrapper(uint8_t* sealed_data, uint32_t* sgx_sealed_data_length)
+{
+  return Decryptor::unseal_and_restore_long_term_signing_key_pair(sealed_data, sgx_sealed_data_length);
+}
+
+uint32_t unseal_and_restore_long_term_signing_key_pair_wrapper(uint8_t* sealed_data, uint32_t* sgx_sealed_data_length);
+{
+  return Decryptor::unseal_and_restore_long_term_signing_key_pair_wrapper(uint8_t* sealed_data, uint32_t* sgx_sealed_data_length);
+}
+
+uint32_t create_and_encrypt_mitigator_header_H_wrapper(uint8_t* ciphertext_token_H_plus_tag);
+{
+  return Decryptor::create_and_encrypt_mitigator_header_H(ciphertext_token_H_plus_tag);
+}
+
+uint32_t create_and_seal_long_term_signing_key_pair_wrapper(uint32_t* sealed_data_length, uint8_t* sealed_data);
+{
+  return Decryptor::create_and_seal_long_term_signing_key_pair(sealed_data_length, sealed_data);
+}

+ 16 - 0
Decryptor/ECDHKeypair.cpp

@@ -0,0 +1,16 @@
+#include"Openssl_crypto.h"
+class ECDHKeypair {
+  uint8_t* private_key;
+  uint8_t* public_key;
+  static const int ECDH_PUBLIC_KEY_SIZE=2*SGX_ECP256_KEY_SIZE;
+  static const int ECDH_PRIVATE_KEY_SIZE=SGX_ECP256_KEY_SIZE;
+public:
+  ECDHKeypair(): private_key(new int(ECDH_PRIVATE_KEY_SIZE)), public_key(new int(ECDH_PUBLIC_KEY_SIZE));
+  uint32_t generate_keypair();
+
+  uint32_t generate_keypair()
+  {
+    return ecdh_key_gen(public_key, public_key+SGX_ECP256_KEY_SIZE, private_key);
+  }
+
+}

+ 20 - 0
Decryptor/HybridEncryptionBox.cpp

@@ -0,0 +1,20 @@
+#include "Openssl_crypto.h"
+class HybridEncryptionBox : public ECDHKeypair, public SymmetricEncryptionBox {
+  public:
+    HybridEncryptionBox(): ECDHKeypair(), SymmetricEncryptionBox();
+    uint32_t get_public_key(uint8_t* blank_key);
+    unsigned long initialize_symmetric_key(uint8_t* given_public_key);
+
+    void get_public_key(uint8_t* blank_key)
+    {
+      uint32_t counter=0;
+      for(counter=0; counter<ECDH_PUBLIC_KEY_SIZE; counter++)
+        blank_key[counter] = public_key[counter];
+    }
+
+    unsigned long initialize_symmetric_key(uint8_t* given_public_key)
+    {
+      return compute_ecdh_shared_key(given_public_key, given_public_key + ECDH_PUBLIC_KEY_SIZE/2, private_key, symmetric_key);
+    }
+
+}

+ 42 - 0
Decryptor/SymmetricEncryptionBox.cpp

@@ -0,0 +1,42 @@
+#include "Openssl_crypto.h"
+class SymmetricEncryptionBox {
+  uint8_t iv[12];
+  uint8_t symmetric_key[32]; // SHA256 used with ECDHE -> or AES whatever symmetric_key.
+  // increments last 4 bytes (in big-endian order)
+  uint32_t aes_gcm_increment_iv_internal_call(uint8_t* iv)  {
+  	uint32_t counter;
+  	for(counter=11;counter>7;counter--)
+  	{
+  		if(iv[counter] == 0xff)
+  		{
+  			if(counter - 1 == 7)
+  				return 0xff;
+  			iv[counter-1] = 0x01;
+  			iv[counter] = 0x0;
+  		}
+  		else
+  			iv[counter] += 1;
+  	}
+  	return 0;
+  }
+
+public:
+  SymmetricEncryptionBox();
+  uint32_t set_symmetric_key(uint8_t* given_key);
+  uint32_t encrypt_decrypt(int enc, uint8_t* plaintext, uint32_t plaintext_length, uint8_t* ciphertext, uint32_t* ciphertext_length, uint8_t* tag);
+
+  uint32_t set_symmetric_key(uint8_t* given_key)
+  {
+    uint32_t counter;
+    for(counter=0; counter<32; counter++)
+      symmetric_key[counter] = given_key[counter];
+  }
+
+  // TODO: IMPORTANT - CHECK IF WE NEED TO DO THIS FOR DECRYPTION TOO.
+  uint32_t encrypt_decrypt(int enc, uint8_t* plaintext, uint32_t plaintext_length, uint8_t* ciphertext, uint32_t* ciphertext_length, uint8_t* tag)
+  {
+    uint32_t return_status = aes_gcm(enc, symmetric_key, iv, plaintext, plaintext_length, ciphertext, ciphertext_length, tag);
+    if(return_status == 0)
+      aes_gcm_increment_iv_internal_call(iv);
+  }
+}

+ 33 - 0
Include/LocalAttestationUntrusted.h

@@ -0,0 +1,33 @@
+#include <sys/socket.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "ProtobufLAMessages.pb.h"
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+using namespace google::protobuf::io;
+#include "protobufLAInitiator.h"
+#include "../Decryptor/Decryptor_u.h"
+#include <iostream>
+
+
+class LocalAttestationUntrusted {
+  int server_fd;
+  int accept_fd;
+  uint32_t session_id;
+  protobuf_sgx_dh_msg1_t protobuf_msg1;
+
+  int decrypt_client_data_wrapper(uint32_t own_enclave_id, int apache_fd);
+  uint32_t local_attestation_msg2_msg3(uint32_t own_enclave_id, int accept_fd);
+  int write_protobuf_msg_to_fd(int accept_fd, google::protobuf::MessageLite& message);
+  int read_protobuf_msg_from_fd(int accept_fd, google::protobuf::MessageLite& message);
+  int set_up_socket(int port,   sockaddr_in* address);
+public:
+  int prepare_local_attestation_as_responder_fd_and_msg1(uint32_t own_enclave_id, int port);
+  int local_attestation_as_responder_msg2_msg3(uint32_t own_enclave_id, int server_fd);
+  int post_local_attestation_with_verifier(uint32_t own_enclave_id);
+  int post_local_attestation_with_apache(uint32_t own_enclave_id);
+};

+ 1 - 2
Include/protobufLAInitiator.h

@@ -1,3 +1,2 @@
-int process_protobuf_dh_msg2_generate_protobuf_dh_msg3(uint32_t own_enclave_id, protobuf_sgx_dh_msg2_t& protobuf_msg2, protobuf_sgx_dh_msg3_t& protobuf_msg3, uint32_t* session_id, uint8_t* read);
+int process_protobuf_dh_msg2_generate_protobuf_dh_msg3(uint32_t own_enclave_id, protobuf_sgx_dh_msg2_t& protobuf_msg2, protobuf_sgx_dh_msg3_t& protobuf_msg3, uint32_t* session_id);
 int generate_protobuf_dh_msg1(uint32_t own_enclave_id, protobuf_sgx_dh_msg1_t& protobuf_msg1, uint32_t* session_id);
-

+ 0 - 1
Include/systemLA.h

@@ -1 +0,0 @@
-int local_attestation_initiator(int port, uint32_t own_enclave_id);

+ 0 - 238
LocalAttestationCode/EnclaveMessageExchange.cpp

@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2011-2017 Intel Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in
- *     the documentation and/or other materials provided with the
- *     distribution.
- *   * Neither the name of Intel Corporation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include "sgx_trts.h"
-#include "sgx_utils.h"
-#include "EnclaveMessageExchange.h"
-#include "sgx_eid.h"
-#include "error_codes.h"
-#include "sgx_ecp_types.h"
-#include "sgx_thread.h"
-#include <map>
-#include "dh_session_protocol.h"
-#include "sgx_dh.h"
-#include "sgx_tcrypto.h"
-#include "LocalAttestationCode_t.h"
-#include "sgx_tseal.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-uint32_t verify_peer_enclave_trust(sgx_dh_session_enclave_identity_t* peer_enclave_identity);
-#ifdef __cplusplus
-}
-#endif
- 
-#define MAX_SESSION_COUNT  16
-
-ATTESTATION_STATUS generate_session_id(uint32_t *session_id);
-ATTESTATION_STATUS end_session();
-
-uint32_t one_successful_la_done;
-sgx_ecc_state_handle_t ecc_state;
-
-
-uint32_t session_ids[MAX_SESSION_COUNT];
-
-// Our enclave will not be doing LA with more than 1 decryptor enclave at a time.
-// We should not need this.
-//std::map<int, dh_session_t>g_dest_session_info_map;
-dh_session_t global_session_info;
-// TODO: May be we need to store all previously assigned session IDs instead of just the counter; to prevent replay attacks -
-uint32_t global_session_id=0;
-uint8_t apache_key[16]; 
-uint8_t verifier_key[16]; 
-
-
-//Handle the request from Source Enclave for a session
-ATTESTATION_STATUS session_request(sgx_dh_msg1_t *dh_msg1,
-                          uint32_t *session_id )
-{
- //   dh_session_t session_info;
-    sgx_dh_session_t sgx_dh_session;
-    sgx_status_t status = SGX_SUCCESS;
-
-    if(!session_id || !dh_msg1)
-    {
-        return INVALID_PARAMETER_ERROR;
-    }
-
-    //Intialize the session as a session responder
-    status = sgx_dh_init_session(SGX_DH_SESSION_RESPONDER, &sgx_dh_session);
-    if(SGX_SUCCESS != status)
-    {
-        return status;
-    }
-
-    *session_id=1;
-
-    global_session_info.status = IN_PROGRESS;
-
-    //Generate Message1 that will be returned to Source Enclave
-    status = sgx_dh_responder_gen_msg1((sgx_dh_msg1_t*)dh_msg1, &sgx_dh_session);
-    if(SGX_SUCCESS != status)
-    {
-        global_session_id--;
-        // SAFE_FREE(g_session_id_tracker[*session_id]);
-        return status;
-    }
-    memcpy(&global_session_info.in_progress.dh_session, &sgx_dh_session, sizeof(sgx_dh_session_t));
-    //return sgx_seal_data(0, NULL, 0, NULL, 0, NULL); 
-    //Store the session information under the correspoding source enlave id key
-    //    g_dest_session_info_map.insert(std::pair<sgx_enclave_id_t, dh_session_t>(src_enclave_id, session_info));
-
-    return status;
-}
-
-//Verify Message 2, generate Message3 and exchange Message 3 with Source Enclave
-ATTESTATION_STATUS exchange_report(
-                          sgx_dh_msg2_t *dh_msg2,
-                          sgx_dh_msg3_t *dh_msg3,
-                          uint32_t* session_id, uint8_t* read_or_write)
-{
-
-    sgx_key_128bit_t dh_aek;   // Session key
-//    dh_session_t session_info;
-    ATTESTATION_STATUS status = SUCCESS;
-    sgx_dh_session_t sgx_dh_session;
-    sgx_dh_session_enclave_identity_t initiator_identity;
-
-    if(!dh_msg2 || !dh_msg3)
-    {
-        return INVALID_PARAMETER_ERROR;
-    }
-
-    memset(&dh_aek,0, sizeof(sgx_key_128bit_t));
-// Why is there a do-while loop anyway? It seems like there is no successful exit ... 
-//    do
-//    {
-      // TODO: Make sure that this works - pointers
-//        session_info = global_session_info;
-
-        if(global_session_info.status != IN_PROGRESS)
-        {
-            status = INVALID_SESSION;
-            end_session(); 
-        }
-
-        memcpy(&sgx_dh_session, &global_session_info.in_progress.dh_session, sizeof(sgx_dh_session_t));
-
-        dh_msg3->msg3_body.additional_prop_length = 0;
-        //Process message 2 from source enclave and obtain message 3
-        sgx_status_t se_ret = sgx_dh_responder_proc_msg2(dh_msg2,
-                                                       dh_msg3,
-                                                       &sgx_dh_session,
-                                                       &dh_aek,
-                                                       &initiator_identity);
-        if(SGX_SUCCESS != se_ret)
-        {
-            status = se_ret;
-            end_session();
-        }
-	uint32_t hash_count; 
-        // THIS IS WHERE THE DECRYPTOR VERIFIES THE APACHE'S MRSIGNER IS THE PUBLIC KEY GIVEN AFTER THE LOCAL ATTESTATION WITH THE VERIFIER.
-        //Verify source enclave's trust
-	uint32_t verify_return=verify_peer_enclave_trust(&initiator_identity); 
-	if(verify_return!=0)
-		return verify_return; 
-	if(one_successful_la_done == 0) 
-	{
-		one_successful_la_done = 1; *read_or_write=1;
-	        memcpy(verifier_key, &dh_aek, 16);
-	}
-	else
-	{
-		one_successful_la_done=2; *read_or_write=0; 
-		memcpy(apache_key, &dh_aek, 16);
-	} 
-
-	// 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;
-        global_session_info.status = ACTIVE;
-        global_session_info.active.counter = 0;
-        memcpy(&global_session_info.active.AEK, &dh_aek, sizeof(sgx_key_128bit_t));
-        memset(&dh_aek,0, sizeof(sgx_key_128bit_t));
-
-    return status;
-}
-
-uint32_t calculate_sealed_data_size( uint32_t input_size) 
-{
-//	*op_size=sgx_calc_sealed_data_size(0, input_size); 
-	return sgx_calc_sealed_data_size(0, input_size);
-
-}
-
-
-
-
-
-
-
-
-
-// TODO: Fix this.
-//Respond to the request from the Source Enclave to close the session
-ATTESTATION_STATUS end_session(/**/)
-{
-  return SUCCESS;
-}
-/*
-// Session_id is set to the first index of the pointer array that is non-null.(Not sure how it is ensured that all of them point to NULL at the start)
-// Why can't it just keep a counter that is incremented? What are the values of g_session_id_tracker array?
-//Returns a new sessionID for the source destination session
-ATTESTATION_STATUS generate_session_id(uint32_t *session_id)
-{
-    ATTESTATION_STATUS status = SUCCESS;
-
-    if(!session_id)
-    {
-        return INVALID_PARAMETER_ERROR;
-    }
-    //if the session structure is untintialized, set that as the next session ID
-    for (int i = 0; i < MAX_SESSION_COUNT; i++)
-    {
-        if (g_session_id_tracker[i] == NULL)
-        {
-            *session_id = i;
-            return status;
-        }
-    }
-
-    status = NO_AVAILABLE_SESSION_ERROR;
-
-    return status;
-*/
-  // *session_id=++global_session_id;
-//}

+ 2 - 9
LocalAttestationCode/LocalAttestationCode.edl

@@ -32,16 +32,9 @@
 enclave  {
     include "sgx_eid.h"
     include "datatypes.h"
-//    include "sgx_tcrypto.h" // For some reason, this is not being detected - macros are not being resolved!
-//    #define SEALED_SIZE 768  // 656 // =0x300 (0x290 is the size of the sealed message when both the public(0x40) and private key(0x20) are included) 
-// TODO: refine this to avoid crashes 
-//    #define MAX_POST_LA_MSG_SIZE 32 // 32 bytes for the mrsigner from the verifier that will be sent to the apache enclave BUT possibly much more for decrypted content
     include "../Include/dh_session_protocol.h"
     trusted{
-        public uint32_t session_request([out] sgx_dh_msg1_t *dh_msg1, [out] uint32_t *session_id);
-        public uint32_t exchange_report([in] sgx_dh_msg2_t *dh_msg2, [out] sgx_dh_msg3_t *dh_msg3, [in] uint32_t *session_id, [out] uint8_t* read);
-        public uint32_t end_session();
-    };
-    untrusted{
+        public uint32_t session_request_wrapper([out] sgx_dh_msg1_t *dh_msg1, [out] uint32_t *session_id);
+        public uint32_t exchange_report_wrapper([in] sgx_dh_msg2_t *dh_msg2, [out] sgx_dh_msg3_t *dh_msg3, [in] uint32_t *session_id);
     };
 };

+ 164 - 0
LocalAttestationCode/LocalAttestationTrusted.cpp

@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2011-2017 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include "sgx_trts.h"
+#include "sgx_utils.h"
+#include "EnclaveMessageExchange.h"
+#include "sgx_eid.h"
+#include "error_codes.h"
+#include "sgx_ecp_types.h"
+#include "sgx_thread.h"
+#include "dh_session_protocol.h"
+#include "sgx_dh.h"
+#include "sgx_tcrypto.h"
+#include "LocalAttestationCode_t.h"
+#include "sgx_tseal.h"
+
+static class LocalAttestationTrusted{
+  dh_session_t global_session_info;
+  uint32_t global_session_id=0;
+  uint32_t one_successful_la_done;
+  sgx_ecc_state_handle_t ecc_state;
+  uint8_t verifier_mr_enclave[32];
+  SymmetricEncryptionBox symmetricEncryptionBoxApache;
+  SymmetricEncryptionBox symmetricEncryptionBoxVerifier;
+
+  extern "C" uint32_t verify_peer_enclave_trust(sgx_dh_session_enclave_identity_t* peer_enclave_identity)
+  {
+  	uint32_t count; sgx_measurement_t given_mr_signer ;
+  	if(!peer_enclave_identity)
+  	{
+  		return INVALID_PARAMETER_ERROR;
+  	}
+  	if(one_successful_la_done==0)
+  	{
+  		// TODO: Set this attribute in the decryptor object.
+  		verifier_mr_enclave = peer_enclave_identity->mr_enclave;
+  		memset(&(apache_mr_signer.m),0x0,SGX_HASH_SIZE); // "initialization"
+  		one_successful_la_done=1;
+  	}
+  	else // apache enclave
+  	{
+  		given_mr_signer = peer_enclave_identity->mr_signer;
+  		int count;
+  		for(count=0; count<SGX_HASH_SIZE; count++)
+  		{
+  			if( given_mr_signer.m[count] != apache_mr_signer.m[count] )
+  				return ENCLAVE_TRUST_ERROR;
+  		}
+      one_successful_la_done ++;
+  	}
+  	return SGX_SUCCESS;
+  }
+
+  public:
+    //Handle the request from Source Enclave for a session
+    ATTESTATION_STATUS session_request(sgx_dh_msg1_t *dh_msg1, uint32_t *session_id)
+    {
+        sgx_dh_session_t sgx_dh_session;
+        sgx_status_t status = SGX_SUCCESS;
+
+        if(!session_id || !dh_msg1)
+        {
+            return INVALID_PARAMETER_ERROR;
+        }
+
+        //Intialize the session as a session responder
+        status = sgx_dh_init_session(SGX_DH_SESSION_RESPONDER, &sgx_dh_session);
+        if(SGX_SUCCESS != status)
+        {
+            return status;
+        }
+
+        *session_id=1;
+
+        global_session_info.status = IN_PROGRESS;
+
+        //Generate Message1 that will be returned to Source Enclave
+        status = sgx_dh_responder_gen_msg1((sgx_dh_msg1_t*)dh_msg1, &sgx_dh_session);
+        if(SGX_SUCCESS != status)
+          return status;
+
+        memcpy(&global_session_info.in_progress.dh_session, &sgx_dh_session, sizeof(sgx_dh_session_t));
+
+        return 0;
+    }
+
+    // TODO: Hope to edit the sgx_dh_responder_proc_msg2 call to return 32 byte key.
+    //Verify Message 2, generate Message3 and exchange Message 3 with Source Enclave
+    ATTESTATION_STATUS exchange_report(sgx_dh_msg2_t *dh_msg2, sgx_dh_msg3_t *dh_msg3, uint32_t* session_id)
+    {
+        sgx_key_128bit_t dh_aek;
+        sgx_status_t status = SUCCESS;
+        sgx_dh_session_t sgx_dh_session;
+        sgx_dh_session_enclave_identity_t initiator_identity;
+        uint32_t verify_return;
+        memset(&dh_aek,0, sizeof(sgx_key_128bit_t));
+
+        if(!dh_msg2 || !dh_msg3)
+          return INVALID_PARAMETER_ERROR;
+
+        if(global_session_info.status != IN_PROGRESS)
+          return INVALID_SESSION; // end_session(); // TODO: DA FUQ RETURN STH HERE.
+
+        memcpy(&sgx_dh_session, &global_session_info.in_progress.dh_session, sizeof(sgx_dh_session_t));
+
+        dh_msg3->msg3_body.additional_prop_length = 0;
+
+        //Process message 2 from source enclave and obtain message 3
+        status = sgx_dh_responder_proc_msg2(dh_msg2, dh_msg3, &sgx_dh_session, &dh_aek, &initiator_identity);
+        if(SGX_SUCCESS != status)
+          return status;
+
+        //Verify source enclave's trust
+    	  verify_return = verify_peer_enclave_trust(&initiator_identity);
+        if(verify_return != 0)
+         return verify_return;
+
+    	  if(one_successful_la_done == 1)
+          symmetricEncryptionBoxVerifier.set_symmetric_key(dh_aek);
+      	else
+          symmetricEncryptionBoxApache.set_symmetric_key(dh_aek);
+        /*
+        //save the session ID, status and initialize the session nonce
+        global_session_info.session_id = *session_id;
+        global_session_info.status = ACTIVE; // This means that you can't keep calling exchange_report over and over again.
+        global_session_info.active.counter = 0;
+        memcpy(&global_session_info.active.AEK, &dh_aek, sizeof(sgx_key_128bit_t));
+        memset(&dh_aek,0, sizeof(sgx_key_128bit_t));
+        */
+        return status;
+    }
+
+  public:
+    LocalAttestationTrusted(): symmetricEncryptionBoxApache(), symmetricEncryptionBoxVerifier();
+};

+ 9 - 0
LocalAttestationCode/LocalAttestationTrustedWrapper.cpp

@@ -0,0 +1,9 @@
+uint32_t session_request_wrapper([out] sgx_dh_msg1_t *dh_msg1, [out] uint32_t *session_id)
+{
+  return LocalAttestationTrusted::session_request_wrapper(dh_msg1, session_id);
+}
+
+uint32_t exchange_report_wrapper(dh_msg2, dh_msg3, session_id)
+{
+  return LocalAttestationTrusted::exchange_report_wrapper(dh_msg2, dh_msg3, session_id);
+}

+ 4 - 5
Makefile

@@ -1,4 +1,4 @@
-#
+LocalAttestationUntrusted#
 # Copyright (C) 2011-2017 Intel Corporation. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -85,7 +85,7 @@ OPENSSL_INCLUDES := /home/m2mazmud/old_stuff/intel-sgx-ssl/Linux/package/include
 
 
 Trust_Lib_Name := libLocalAttestation_Trusted.a
-TrustLib_Cpp_Files := $(wildcard LocalAttestationCode/*.cpp)
+TrustLib_Cpp_Files := LocalAttestationCode/LocalAttestationTrustedWrapper.cpp LocalAttestationCode/LocalAttestationTrusted.cpp LocalAttestationCode_t.c
 TrustLib_Cpp_Objects := $(TrustLib_Cpp_Files:.cpp=.o)
 TrustLib_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx -I$(SGX_SDK)/include/epid -I./Include
 TrustLib_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector  $(TrustLib_Include_Paths) -Wall
@@ -130,7 +130,7 @@ else
 	App_Link_Flags += -lsgx_uae_service
 endif
 
-App_Cpp_Objects := App/App.o App/systemLA.o App/protobufLAInitiator.o App/protobufSgxLATransformsInitiator.o App/ProtobufLAMessages.pb.o #$(App_Cpp_Files:.cpp=.o)
+App_Cpp_Objects := App/App.o App/LocalAttestationUntrusted.o App/protobufLAInitiator.o App/protobufSgxLATransformsInitiator.o App/ProtobufLAMessages.pb.o #$(App_Cpp_Files:.cpp=.o)
 App_Name := app
 
 ######## Enclave Settings ########
@@ -281,7 +281,7 @@ Decryptor/Decryptor_t.o: Decryptor/Decryptor_t.c
 	@$(CC) $(Enclave_Compile_Flags) -c $< -o $@
 	@echo "CC   <=  $<"
 
-Decryptor/Decryptor.o: Decryptor/Decryptor.cpp
+Decryptor/Decryptor.o: Decryptor/DecryptorWrapper.cpp Decryptor/Decryptor.cpp
 	@$(CXX) -std=c++11 -nostdinc++ $(Enclave_Compile_Flags)  -c $< -o $@
 	@echo "CXX  <=  $<"
 
@@ -302,4 +302,3 @@ $(Enclave_Name_2): Decryptor.so
 
 clean:
 	@rm -rf .config_* $(App_Name) *.so *.a App/*.o Decryptor/*.o Decryptor/*_t.* Decryptor/*_u.* LocalAttestationCode/*.o LocalAttestationCode/*_t.*
-