Browse Source

Got decryption of client data working. Yet to encrypt client-data back to the Apache. Refactored decryptor client data decryption functions in trusted and untrusted code. Added in a new base64 decoding function (CommonOpensslCode was intended to contain base64 function and it was supposed to be linkable by both trusted, untrusted code, but couldnot get the app to link against the same version of openssl as intel-sgx-ssl.

dettanym 5 years ago
parent
commit
a27c0b3ca8
7 changed files with 658 additions and 675 deletions
  1. 95 129
      App/systemLA.cpp
  2. 401 0
      CommonOpensslCode/Openssl_crypto.cpp
  3. 135 124
      Decryptor/Decryptor.cpp
  4. 3 2
      Decryptor/Decryptor.edl
  5. 0 404
      Decryptor/Openssl_crypto.cpp
  6. 6 4
      Include/Openssl_crypto.h
  7. 18 12
      Makefile

+ 95 - 129
App/systemLA.cpp

@@ -15,6 +15,7 @@ using namespace google::protobuf::io;
 #include "../Decryptor/Decryptor_u.h"
 #include "sgx_tcrypto.h"
 #include <iostream>
+#include "Openssl_crypto.h"
 
 // TODO: Make these private functions
 int apache_fd;
@@ -46,7 +47,7 @@ int read_protobuf_msg_from_fd(int accept_fd, google::protobuf::MessageLite& mess
   }
   coded_input->PopLimit(limit);
   delete raw_input;
-  delete coded_input; 
+  delete coded_input;
   return 0;
 }
 
@@ -113,7 +114,7 @@ int local_attestation_initiator(int port, uint32_t own_enclave_id)
   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; 
+  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.
@@ -121,8 +122,8 @@ int local_attestation_initiator(int port, uint32_t own_enclave_id)
   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; 
+  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)
@@ -143,7 +144,7 @@ int local_attestation_initiator(int port, uint32_t own_enclave_id)
         printf("Error in accepting %d", errno);
         return -1;
   }
-  printf("Accepted fd\n"); fflush(stdout); 
+  printf("Accepted fd\n"); fflush(stdout);
 
   if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg1)!=0)
     return -1;
@@ -159,12 +160,12 @@ int local_attestation_initiator(int port, uint32_t own_enclave_id)
 
   if(write_protobuf_msg_to_fd(accept_fd, protobuf_msg3)!=0)
     return -1;
-//  read_or_write=0;  
+//  read_or_write=0;
 
-  printf("Here\n"); fflush(stdout); 
+  printf("Here\n"); fflush(stdout);
   if(read_or_write)
-  {  
-  	bytes_read_post_la=read(accept_fd, encrypted_apache_mrsigner_and_tag, 32); 
+  {
+  	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;
@@ -177,46 +178,46 @@ int local_attestation_initiator(int port, uint32_t own_enclave_id)
   	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); 
+  	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("Error in decryption: 0x%x\n", sgx_ret); fflush(stdout); return sgx_ret;
 	  }
-	  printf("Successful decryption\n"); fflush(stdout); 
-	
+	  printf("Successful decryption\n"); fflush(stdout);
+
 
   }
-  else 
+  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];	
+	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; 
+	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); 
+	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); 
+
+	printf("Plaintext signature: \n"); fflush(stdout);
         for(count=0;count<32;count++)
         {
                 printf("%02x", plaintext_sign_data_and_sign[count+96]);
@@ -244,8 +245,8 @@ Decryptor_decrypt_verifiers_message_set_apache_mrsigner(own_enclave_id, &sgx_ret
                 printf("%02x ", sig2.y[count]);
         }
         printf("\n"); fflush(stdout);
-        
-	protobuf_encrypted_msg.set_msg((void*)encrypted_sign_data_and_sign_and_tag, 176); 
+
+	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;
@@ -253,9 +254,9 @@ Decryptor_decrypt_verifiers_message_set_apache_mrsigner(own_enclave_id, &sgx_ret
 	unsigned char op_plaintext[160];
 	do {
 //	sleep(100);
-	decrypt_client_data_wrapper(op_plaintext, own_enclave_id); 
-//	sleep(100); 
-	} while(true); 
+	decrypt_client_data_wrapper(op_plaintext, own_enclave_id);
+//	sleep(100);
+	} while(true);
 
 
   }
@@ -263,130 +264,95 @@ Decryptor_decrypt_verifiers_message_set_apache_mrsigner(own_enclave_id, &sgx_ret
         printf("Successfully done Local attestation\n");
         fflush(stdout);
         return 0;
-      
+
 }
 
 
-// decrypt_client_data function that does a read-then-write loop 
+// 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. 
+////// 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 
+////// 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_encrypted_msg; uint32_t sgx_ret_status;
+  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();
 
-        printf("Reading msg from apache"); fflush(stdout); 
-        if(read_protobuf_msg_from_fd(apache_fd, protobuf_encrypted_msg)!=0)
-        {
-                printf("Not all of the Apache's message was read\n"); fflush(stdout); return 0xfe; 
-        }
-   
-        std::string protobuf_encrypted_msg_string(protobuf_encrypted_msg.msg());
-//	printf("%s\n", protobuf_encrypted_msg_string.c_str()); fflush(stdout);
-	const char* temp_array = protobuf_encrypted_msg_string.c_str();
+  std::string protobuf_encrypted_msg_string(protobuf_msg_from_apache.msg());
 	int counter;
-	for(counter=0;counter<protobuf_encrypted_msg_string.length();counter++)
-		printf("%d ",temp_array[counter]);
-	printf("\n"); fflush(stdout); 
-
-        unsigned char client_data_from_apache[160+64]; //protobuf_encrypted_msg_string.size());      // set a large limit for "size" for third argument - client data - of 160 - so 160+64
-	memset(client_data_from_apache, 0, 160+64); 
-	unsigned char* protobuf_string = (unsigned char*) protobuf_encrypted_msg_string.c_str(); 
-//        client_data_from_apache = (unsigned char*) protobuf_encrypted_msg_string.c_str(); //temp_array;//(unsigned char*)&(std::vector<char> (protobuf_encrypted_msg_string.begin(), protobuf_encrypted_msg_string.end()))[0]; // This shit eats up 8 starting bytes - sets them to 0s
-	for(counter=0;counter<protobuf_encrypted_msg_string.length();counter++)
-		client_data_from_apache[counter]=*(protobuf_string+counter);
-
-	uint32_t ciphertext_length = protobuf_encrypted_msg_string.length()-64; // we hope it's greater than 0 
-
-        printf("Key in big endian form:\n"); fflush(stdout); 
-        for(counter=0; counter<64; counter++)
-                printf("0x%02x ", *(client_data_from_apache + counter)); 
-        printf("\n"); fflush(stdout); 
-
-	unsigned char client_data_to_apache[160+64]; //ciphertext_length); 
-	// Just so that the ciphertext is returned back to Apache in case decrypt_client_data fails. 
-	for(counter=0;counter<ciphertext_length;counter++)
-		client_data_to_apache[counter]=client_data_from_apache[counter+64];
-	uint8_t clen;
-	Decryptor_decrypt_client_data(own_enclave_id, &sgx_ret_status, client_data_from_apache, ciphertext_length, client_data_from_apache + 64, client_data_to_apache, &clen); 
+
+  memset(client_keys_and_data_encrypted_to_enclave, 0, 160+64);
+  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];
+
+  printf("Key in big endian form:\n"); fflush(stdout);
+  for(counter=0; counter<64; counter++)
+    printf("0x%02x ", *(client_keys_and_data_encrypted_to_enclave + counter));
+  printf("\n"); fflush(stdout);
+
+	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_keys_and_data_encrypted_to_enclave + 64, 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; 
+		printf("decrypt_client_data returned :0x%x\n", sgx_ret_status); fflush(stdout); //return sgx_ret_status;
+//		client_data_encrypted_to_apache_length = client_data_encrypted_to_enclave_length;
 	}
+//	else
+//	  	client_data_encrypted_to_apache_length = clen;
+	if(clen != 0)
+		client_data_encrypted_to_apache_length = clen; 
 
-	// TODO: REMOVE THIS -
-//	for(counter=0;counter<ciphertext_length;counter++)
-//		client_data_to_apache[counter]=0x46;//client_data_from_apache[counter+64];
-	// TODO: Print the bytesize of the message. should be ciphertext_length=4 + more bytes for protobuf packing. 
 	printf("About to write the following bytes to the apache\n"); fflush(stdout);
-	for(counter=0;counter<ciphertext_length;counter++)
-		printf("0x%02x ", client_data_to_apache[counter]);
+	for(counter=0;counter<client_data_encrypted_to_apache_length;counter++)
+		printf("%d,", client_data_encrypted_to_apache[counter]);
 	printf("\n"); fflush(stdout);
-	printf("Following shared secret was established.\n"); 
-	for(counter=ciphertext_length;counter<32+ciphertext_length;counter++)
-                printf("0x%02x ", client_data_to_apache[counter]);
-        printf("\n"); fflush(stdout);
-        printf("Following key was derived.\n"); 
-        for(counter=ciphertext_length+32;counter<64+ciphertext_length;counter++)
-                printf("0x%02x ", client_data_to_apache[counter]);
+/*  printf("Following key was derived.\n");
+  for(counter=client_data_encrypted_to_enclave_length+32;counter<64+client_data_encrypted_to_enclave_length;counter++)
+    printf("0x%02x ", client_data_encrypted_to_apache[counter]);
 	printf("\n"); fflush(stdout);
-	printf("Ciphertext for the string Miti \n"); 
-        for(counter=ciphertext_length+64;counter<64+ciphertext_length + 4;counter++)
-		printf("%d ", client_data_to_apache[counter]);
-        printf("\n"); fflush(stdout); 
-        printf("Tag for the string Miti \n"); 
-        for(counter=ciphertext_length+64+4;counter<80+ciphertext_length + 4;counter++)
-		printf("%d ", client_data_to_apache[counter]);
-        printf("\n"); fflush(stdout); 
-
-
-        protobuf_encrypted_msg.set_msg((void*)  client_data_to_apache, ciphertext_length);// Is this message set tho?
-	if(write_protobuf_msg_to_fd(apache_fd, protobuf_encrypted_msg)!=0)
+*/
+/*	printf("Plaintext: \n");
+    for(counter=client_data_encrypted_to_enclave_length+64;counter<64+client_data_encrypted_to_enclave_length + clen;counter++)
+  printf("%d ", client_data_encrypted_to_apache[counter]);
+  printf("\n"); fflush(stdout);
+*/
+//  client_data_encrypted_to_apache_length = clen;
+  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_encrypted_msg.ByteSize());fflush(stdout);
-	return 0; 
+	printf("Wrote data to Apache of length %d \n", protobuf_msg_from_apache.ByteSize());fflush(stdout);
+	return 0;
 }
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 

+ 401 - 0
CommonOpensslCode/Openssl_crypto.cpp

@@ -0,0 +1,401 @@
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/ecdh.h>
+#include <string.h>
+
+EVP_CIPHER_CTX* ctx;
+
+int generate_sha256_hash(const unsigned char *message, size_t message_len, unsigned char *digest)
+{
+	EVP_MD_CTX *mdctx; unsigned int digest_len;
+
+	if((mdctx = EVP_MD_CTX_create()) == NULL)
+		return 0x1;
+
+	if(EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL) != 1)
+		return 0x2;
+
+  if(EVP_DigestUpdate(mdctx, message, message_len) != 1)
+		return 0x3;
+
+	if(EVP_DigestFinal_ex(mdctx, digest, &digest_len) != 1)
+		return 0x4;
+
+	if(digest_len != 32)
+		return 0x5;
+
+	EVP_MD_CTX_destroy(mdctx);
+	return 0;
+}
+
+int ecdh_key_gen(unsigned char* public_key_x, unsigned char* public_key_y, unsigned char* private_key)
+{
+	EC_KEY * keypair = NULL;
+	EC_GROUP* ecdh_group = NULL;
+	const EC_POINT *public_key_point = NULL;
+	const BIGNUM *private_key_bignum = NULL;
+	BIGNUM *public_key_x_bignum = NULL;
+	BIGNUM *public_key_y_bignum = NULL;
+	int ret;
+
+	keypair = EC_KEY_new();
+	if (NULL == keypair) {
+		return 0x42;
+	}
+
+	ecdh_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+	if (NULL == ecdh_group) {
+		EC_KEY_free(keypair);
+		return 0x0f;
+	}
+
+	if (0 == EC_KEY_set_group (keypair, ecdh_group)) {
+		EC_KEY_free(keypair);
+		EC_GROUP_free(ecdh_group);
+		return 0x43;
+	}
+
+	// TODO: Check return values.
+	EC_KEY_set_asn1_flag(keypair, OPENSSL_EC_NAMED_CURVE);
+
+	// Generating keypair
+	if (EC_KEY_generate_key(keypair) == 0) {
+		EC_KEY_free(keypair);
+		EC_GROUP_free(ecdh_group);
+    return 0x01;
+	}
+
+	// Extracting public key point from keypair. TODO: Note that it seems that this pointer does not need to be freed separately from the keypair pointer.
+	public_key_point = EC_KEY_get0_public_key(keypair);
+	if (NULL == public_key_point)
+	{
+		EC_KEY_free(keypair);
+		EC_GROUP_free(ecdh_group);
+		return 0x04;
+	}
+
+	// Extracting private key bignum from keypair. TODO: Note that it seems that this pointer does not need to be freed separately from the keypair pointer.
+	private_key_bignum = EC_KEY_get0_private_key(keypair);
+	if (NULL == private_key_bignum)
+	{
+		EC_KEY_free(keypair);
+		EC_GROUP_free(ecdh_group);
+		return 0x05;
+	}
+
+	// Converting private key bignum to string (in big-endian format).
+  if(!BN_bn2bin(private_key_bignum, private_key))
+  {
+    EC_KEY_free(keypair);
+		EC_GROUP_free(ecdh_group);
+		return 0x06;
+  }
+
+  public_key_x_bignum = BN_new();
+  public_key_y_bignum = BN_new();
+  if (NULL ==  public_key_x_bignum || NULL == public_key_y_bignum) {
+		EC_KEY_free(keypair);
+		EC_GROUP_free(ecdh_group);
+    return 0x42;//SGX_ERROR_OUT_OF_MEMORY;
+  }
+
+	// Extracting public key bignums from public key points.
+	if (!EC_POINT_get_affine_coordinates_GFp(ecdh_group, public_key_point, public_key_x_bignum, public_key_y_bignum, NULL))
+	{
+		BN_clear_free(public_key_x_bignum);
+		BN_clear_free(public_key_y_bignum);
+		EC_KEY_free(keypair);
+		EC_GROUP_free(ecdh_group);
+		return 0x07;
+	}
+
+	// Converting public key x bignum to string (in big-endian format) and setting first output argument.
+	ret = BN_bn2bin(public_key_x_bignum, public_key_x);
+	BN_clear_free(public_key_x_bignum);
+	if(ret == 0)
+	{
+		BN_clear_free(public_key_y_bignum);
+    EC_KEY_free(keypair);
+	  EC_GROUP_free(ecdh_group);
+		return 0x08;
+	}
+
+	// Converting public key y bignum to string (in big-endian format) and setting second output argument.
+	ret = BN_bn2bin(public_key_y_bignum, public_key_y);
+	BN_clear_free(public_key_y_bignum);
+	EC_KEY_free(keypair);
+	EC_GROUP_free(ecdh_group);
+
+	if(ret == 0)
+  		return 0x09;
+
+	return 0;
+}
+
+unsigned long check_ecdh_public_key(unsigned char* public_key_x, unsigned char* public_key_y) //, unsigned char* priv_key, unsigned char* shared_key_x, unsigned char* shared_key_y)
+{
+	EC_GROUP *ec_group = NULL;
+	EC_POINT *public_key_point = NULL;
+	BIGNUM *public_key_x_bignum = NULL;
+	BIGNUM *public_key_y_bignum = NULL;
+
+	ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+  if (NULL == ec_group) {
+    return 0x0f;
+  }
+
+	public_key_point = EC_POINT_new(ec_group);
+	if (NULL == public_key_point) {
+		EC_GROUP_free(ec_group);
+		return 0x42;
+	}
+
+	public_key_x_bignum = BN_bin2bn(public_key_x, 32, NULL);
+	if (NULL == public_key_x_bignum) {
+		EC_POINT_free(public_key_point);
+		EC_GROUP_free(ec_group);
+		return 0xfd;
+	}
+
+	// converts the y value of the point, represented as positive integer in big-endian into a BIGNUM
+	public_key_y_bignum = BN_bin2bn(public_key_y, 32, NULL);
+	if (NULL == public_key_y_bignum) {
+		BN_clear_free(public_key_x_bignum);
+		EC_POINT_free(public_key_point);
+		EC_GROUP_free(ec_group);
+		return 0xfe;
+	}
+
+	// sets point based on x,y coordinates
+	int ret = EC_POINT_set_affine_coordinates_GFp(ec_group, public_key_point, public_key_x_bignum, public_key_y_bignum, NULL);
+	BN_clear_free(public_key_x_bignum);
+	BN_clear_free(public_key_y_bignum);
+	if (1 != ret) {
+		EC_POINT_free(public_key_point);
+		EC_GROUP_free(ec_group);
+		return ERR_get_error();
+	}
+
+	// checks if point is on curve
+	//
+	int ret_point_on_curve = EC_POINT_is_on_curve(ec_group, public_key_point, NULL);
+	EC_POINT_free(public_key_point);
+	EC_GROUP_free(ec_group);
+	if (1 != ret_point_on_curve) {
+		return ret_point_on_curve << 4; //ret_point_on_curve;//	break;
+	}
+
+  return 0;
+}
+
+unsigned long compute_ecdh_shared_key(unsigned char* given_public_key_x, unsigned char* given_public_key_y, unsigned char* own_private_key, unsigned char* derived_key)
+{
+	unsigned long long_ret = 0;
+	EC_GROUP *ec_group = NULL;
+	EC_POINT *given_public_key_point = NULL;
+	BIGNUM *given_public_key_x_bignum = NULL;
+	BIGNUM *given_public_key_y_bignum = NULL;
+	EC_KEY *own_keypair = NULL;
+	BIGNUM *own_private_key_bignum = NULL;
+	int shared_key_len = 32;
+	unsigned char shared_key[32];
+
+	ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+  if (NULL == ec_group) {
+    return 0x0f;
+  }
+
+	given_public_key_point = EC_POINT_new(ec_group);
+	if (NULL == given_public_key_point) {
+		EC_GROUP_free(ec_group);
+		return 0x42;
+	}
+
+	given_public_key_x_bignum = BN_bin2bn(given_public_key_x, 32, NULL);
+	if (NULL == given_public_key_x_bignum) {
+		EC_POINT_free(given_public_key_point);
+		EC_GROUP_free(ec_group);
+		return 0xfd;
+	}
+
+	// converts the y value of the point, represented as positive integer in big-endian into a BIGNUM
+	given_public_key_y_bignum = BN_bin2bn(given_public_key_y, 32, NULL);
+	if (NULL == given_public_key_y_bignum) {
+		BN_clear_free(given_public_key_x_bignum); // TODO: You should probably not be freeing it here - since ya dont own it?
+		EC_POINT_free(given_public_key_point);
+		EC_GROUP_free(ec_group);
+		return 0xfe;
+	}
+
+	// sets point based on x,y coordinates
+	int ret = EC_POINT_set_affine_coordinates_GFp(ec_group, given_public_key_point, given_public_key_x_bignum, given_public_key_y_bignum, NULL);
+	BN_clear_free(given_public_key_x_bignum);
+	BN_clear_free(given_public_key_y_bignum);
+	if (1 != ret) {
+		EC_POINT_free(given_public_key_point);
+		EC_GROUP_free(ec_group);
+		return ERR_get_error();
+	}
+
+	// checks if point is on curve
+	//
+	int ret_point_on_curve = EC_POINT_is_on_curve(ec_group, given_public_key_point, NULL);
+	if (1 != ret_point_on_curve) {
+		EC_POINT_free(given_public_key_point);
+		EC_GROUP_free(ec_group);
+		return ret_point_on_curve << 4; //ret_point_on_curve;//	break;
+	}
+
+	// create empty shared key BN
+	//
+	own_keypair = EC_KEY_new();
+	if (own_keypair == NULL) {
+		EC_POINT_free(given_public_key_point);
+		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_POINT_free(given_public_key_point);
+		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_POINT_free(given_public_key_point);
+		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_POINT_free(given_public_key_point);
+		EC_GROUP_free(ec_group);
+		EC_KEY_free(own_keypair);
+		return ERR_get_error();
+	}
+
+	// calculate shared dh key
+	//
+	shared_key_len = ECDH_compute_key(shared_key, 32, given_public_key_point, own_keypair, NULL);
+	if (shared_key_len <= 0) {
+		long_ret = ERR_get_error();
+	}
+	else
+		long_ret = generate_sha256_hash(shared_key, 32, derived_key);
+
+	EC_POINT_free(given_public_key_point);
+	EC_GROUP_free(ec_group);
+	EC_KEY_free(own_keypair);
+	return long_ret;
+}
+
+// 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, int plaintext_len, unsigned char *ciphertext,  int* op_ciphertext_len, unsigned char* tag)
+{
+	int len;
+	int ciphertext_len;
+	int reset_return;
+	if(ctx == NULL)
+	{
+		// Create and initialise the context //
+		if(!(ctx = EVP_CIPHER_CTX_new())) { return 0x1; }
+	}
+
+
+	// Initialise the encryption operation. //
+	if(1 != EVP_CipherInit_ex(ctx, EVP_aes_256_gcm(), NULL, key, iv, enc))
+	{
+		reset_return = EVP_CIPHER_CTX_reset(ctx);
+		if(reset_return != 1)
+			return 0xf2;
+		return 0x2;
+	}
+	// Provide the message to be encrypted, and obtain the encrypted output.	 * EVP_EncryptUpdate can be called multiple times if necessary
+	 //
+	if(1 != EVP_CipherUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
+	{
+                reset_return = EVP_CIPHER_CTX_reset(ctx);
+	        if(1 != reset_return)
+			return 0xF3;
+		return 0x3;
+	}
+	ciphertext_len = len;
+
+	if(enc == 0)
+        {
+                if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
+                {
+                       reset_return = EVP_CIPHER_CTX_reset(ctx);
+                       if(1 != reset_return)
+                                return 0xF5;
+                        return 0x5;
+                }
+        }
+
+
+	// Finalise the encryption. Normally ciphertext bytes may be written at  this stage, but this does not occur in GCM mode
+	 //
+	// TODO: ^^^ Why the heck does it not occur in GCM mode ?
+	if(1 != EVP_CipherFinal_ex(ctx, ciphertext + len, &len))
+	{
+		reset_return = EVP_CIPHER_CTX_reset(ctx);
+                if(1 != reset_return)
+                        return 0xF4;
+                return 0x4;
+	}
+	ciphertext_len += len;
+
+	// Get the tag
+	if(enc == 1)
+	{
+		if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
+		{
+                	reset_return = EVP_CIPHER_CTX_reset(ctx);
+                	if(1 != reset_return)
+                        	return 0xF5;
+	                return 0x5;
+		}
+	}
+
+	// Clean up //
+	if(1 != EVP_CIPHER_CTX_reset(ctx))
+	{
+		return 0xF0;
+	}
+
+	*op_ciphertext_len=ciphertext_len;
+		//EVP_CIPHER_CTX_free(ctx); // TODO: memory leaks here - need to free this for erroneous cases too.
+	return 0;
+}
+
+uint32_t base64_decoding_wrapper(unsigned char* src, unsigned char* dest, uint32_t length)
+{
+	int length_with_padding = EVP_DecodeBlock(dest, src, length);
+	if(length_with_padding == -1)
+		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; 
+	}
+	
+	return length_with_padding;	      
+}
+

+ 135 - 124
Decryptor/Decryptor.cpp

@@ -52,41 +52,41 @@
 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]; 
+extern uint8_t apache_key[16];
+extern uint8_t verifier_key[16];
 
 
-//uint32_t client_iv=0; 
+//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); 
+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_internal_call(uint8_t* ip_ciphertext, uint32_t ip_ciphertext_len, uint8_t* ip_key, uint8_t* ip_iv, uint8_t* tag, uint8_t* op_plaintext, uint32_t enc);
 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 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);
+//static void reverse_byte_array(uint8_t *array, size_t size);
 
 
-uint32_t one_la_done=0; 
+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]; 
+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; 
+//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)
 {
@@ -100,47 +100,47 @@ extern "C" uint32_t verify_peer_enclave_trust(__attribute__((unused))  sgx_dh_se
 //		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" 
+		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}; 
+		// 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 ENCLAVE_TRUST_ERROR;
 		}
 	}
 	return SGX_SUCCESS;
 }
 
-// increments last 4 bytes (in big-endian order) 
+// 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(iv[counter] == 0xff)
 		{
 			if(counter - 1 == 7)
-				return 0xff; 
+				return 0xff;
 			iv[counter-1] = 0x01;
-			iv[counter] = 0x0;  
+			iv[counter] = 0x0;
 		}
 		else
-			iv[counter] += 1; 
+			iv[counter] += 1;
 	}
-	return 0; 
+	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 
+// 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 internal_ret_status= aes_gcm_internal_call(ciphertext, 32, verifier_key, verifier_iv , tag, (uint8_t*) &(apache_mr_signer.m), 0);
@@ -152,18 +152,18 @@ uint32_t create_and_encrypt_mitigator_header_value(uint8_t* plaintext_sign_data_
 
 {
 	uint32_t count;
-	uint8_t sign_data_and_sign[160]; 
+	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]; 
+		*(plaintext_sign_data_and_sign+count)=sign_data_and_sign[count];
 
-	ret_status = aes_gcm_internal_call(sign_data_and_sign, 160, apache_key, apache_iv, tag, encrypted_sign_data_and_sign, 1); 
-//	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; 
+	ret_status = aes_gcm_internal_call(sign_data_and_sign, 160, apache_key, apache_iv, tag, encrypted_sign_data_and_sign, 1);
+//	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;
 }
 
 
@@ -207,7 +207,7 @@ void serialize_key_pair_to_string(sgx_ec256_public_t* pub_key, sgx_ec256_private
      {
        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];
-     } 
+     }
   }
 }
 
@@ -215,10 +215,10 @@ void serialize_key_pair_to_string(sgx_ec256_public_t* pub_key, sgx_ec256_private
 // 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 
+  if(private_public_key_string != NULL) // nowhere to deserialize from
   {
     uint32_t counter;
-    if(signing_priv_key != NULL) 
+    if(signing_priv_key != NULL)
     {
 
      for(counter=2*SGX_ECP256_KEY_SIZE;counter<3*SGX_ECP256_KEY_SIZE; counter++)
@@ -245,24 +245,24 @@ uint32_t create_and_seal_ecdsa_signing_key_pair(__attribute__((unused))   sgx_ec
     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]; 
+	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); 
+    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); 
+    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); 
+	*(sealed_data+counter)=*(sealed_data2+counter);
     free(sealed_data2);
-    free(private_key_string);  //free(private_key);  
+    free(private_key_string);  //free(private_key);
     free(private_public_key_string);
 
-    return ret_status; // SGX_SUCCESS; 
+    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)
@@ -272,10 +272,10 @@ uint32_t unseal_and_restore_sealed_signing_key_pair(__attribute__((unused)) sgx_
   if(expected_plaintext_msg_length == 0xffffffff)
     return 0xFFFFFFFF;
 
-  uint8_t* sealed_data2 = (uint8_t*) malloc(*sgx_sealed_data_length); 
+  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); 
+	*(sealed_data2+counter)=*(sealed_data+counter);
   }
 
   temp_plaintext = (uint8_t*)malloc( expected_plaintext_msg_length );
@@ -286,74 +286,74 @@ uint32_t unseal_and_restore_sealed_signing_key_pair(__attribute__((unused)) sgx_
     return ret_status;
   }
   deserialize_string_to_key_pair(temp_plaintext, pub_key, &signing_priv_key);
-  free(temp_plaintext); free(sealed_data2);  
+  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. 
+	// 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 = ec_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 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; 
+           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. 
+		*(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; 
+	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. 
+	// 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]; 
+		*(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_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) 
+	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; 
+		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)); 
+                	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); 
+                	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; 
+	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; 
+	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]; 
+		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));
@@ -374,54 +374,54 @@ uint32_t verify_mitigator_header_value(uint8_t* signature_data, uint8_t* signatu
         if(ret_status != SGX_SUCCESS || ret_status2 != SGX_SUCCESS)
                 return 0xFFFFFFFF;
 	if(verification_result != SGX_EC_VALID)
-		return 0xee; 
+		return 0xee;
         return 0;
 }
 
 uint32_t derive_shared_secret_for_client(uint8_t* pub_key, uint8_t* shared_key)
 {
-	return 0; 
+	return 0;
 
 
 }
 
-uint32_t calculate_sealed_data_size( uint32_t input_size) 
+uint32_t calculate_sealed_data_size( uint32_t input_size)
 {
-//      *op_size=sgx_calc_sealed_data_size(0, 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. 
+// ip_key will always be within the enclave.
 // enc = 1 for encryption and 0 for decryption, like openssl api
-uint32_t aes_gcm_internal_call(uint8_t* ip_ciphertext, uint32_t ip_ciphertext_len, uint8_t* ip_key, uint8_t* ip_iv, uint8_t* tag, uint8_t* op_plaintext, uint32_t enc) 
+uint32_t aes_gcm_internal_call(uint8_t* ip_ciphertext, uint32_t ip_ciphertext_len, uint8_t* ip_key, uint8_t* ip_iv, uint8_t* tag, uint8_t* op_plaintext, uint32_t enc)
 {
 	uint32_t counter;
 	if(ip_ciphertext == NULL)
-		return 0x33; 
+		return 0x33;
 	if(tag == NULL)
 		return 0x34;
-	if(op_plaintext == NULL) 
-		return 0x36; 
-	if(ip_key == NULL) 
+	if(op_plaintext == NULL)
+		return 0x36;
+	if(ip_key == NULL)
 		return 0x35;
 	if(ip_iv == NULL)
-		return 0x37; 
+		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* 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); 
+		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);	
+	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)
 	{
@@ -430,61 +430,72 @@ uint32_t aes_gcm_internal_call(uint8_t* ip_ciphertext, uint32_t ip_ciphertext_le
 	                memcpy_equivalent_copy(tag, tag_in_enclave, 16);
 	}
 
-	free(ip_ciphertext_in_enclave); free(op_plaintext_in_enclave); 	
-	
-	return internal_ret_status; 
+	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;	
+	uint32_t counter;
 	for(counter=0; counter<length; counter++)
-		*(dest + counter) = *(src + counter); 
+		*(dest + counter) = *(src + counter);
 }
 
-uint32_t decrypt_client_data(__attribute__((unused)) unsigned char* ip_client_pub_key, uint32_t ciphertext_length, unsigned char* ip_user_data, unsigned char* op_client_data_to_apache, uint8_t* clen)
+uint32_t decrypt_client_data(unsigned char* ip_client_pub_key, unsigned char* ip_base64_encrypted_client_data, uint32_t base64_encrypted_client_data_length, unsigned char* op_client_data_to_apache, uint8_t* clen)
 {
-	int counter;
-	for(counter=0;counter<ciphertext_length;counter++)
-		op_client_data_to_apache[counter]=ip_user_data[counter]; 
-
-	// TODO: Shared key is only needed for testing/verification manually. 
-	unsigned char shared_key[32];
-	unsigned char derived_key[32]; 
-	unsigned long check_ret = compute_shared_ECDHE_key(ip_client_pub_key, ip_client_pub_key + 32, short_term_private_key_arr, shared_key, derived_key);
+	unsigned int counter; unsigned long check_ret; uint32_t ret; int ret2;
+	unsigned char derived_key[32];
+	unsigned char* ip_encrypted_client_data;
+	int ip_encrypted_client_data_length;
+	unsigned char* plaintext_client_data;
+	unsigned char client_iv[12]={0,0,0,0, 0,0,0,0, 0,0,0,0};
+	int op_encrypted_client_data_length; // As the internal enclave aes gcm function wont work with external pointers
+
+	for(counter=0;counter<base64_encrypted_client_data_length;counter++)
+		op_client_data_to_apache[counter]=ip_base64_encrypted_client_data[counter];
+	*clen = (uint8_t) base64_encrypted_client_data_length; 
+
+	check_ret = compute_ecdh_shared_key(ip_client_pub_key, ip_client_pub_key + 32, short_term_private_key_arr, derived_key);
 	if(check_ret != 0)
-		return check_ret; 
+		return check_ret;
 
-	// TODO: For debugging only. 
-	for(counter=0;counter<32;counter++)
+	// TODO: For debugging only.
+//	for(counter=0;counter<32;counter++)
+//		op_client_data_to_apache[counter + base64_encrypted_client_data_length + 32] = derived_key[counter];
+
+	ip_encrypted_client_data = (unsigned char*) malloc(base64_encrypted_client_data_length*3/4); // ciphertext length will be a multiple of 4; this is the maximum length.
+	ip_encrypted_client_data_length = base64_decoding_wrapper(ip_base64_encrypted_client_data, ip_encrypted_client_data, base64_encrypted_client_data_length);
+	if(ip_encrypted_client_data_length == -1)
 	{
-		op_client_data_to_apache[counter+ciphertext_length] = shared_key[counter];
-		op_client_data_to_apache[counter+ciphertext_length + 32] = derived_key[counter];
+		free(ip_encrypted_client_data);
+		return 0x33; //ret;
 	}
 
-	unsigned char miti[4] = {'M', 'i', 't', 'i'};
-	unsigned char ciphertext1[16];
-	unsigned char tag[16];
-	uint8_t client_iv2[12] = {0,0,0,0, 0,0,0,0, 0,0,0,0};
+        for(counter=0; counter<ip_encrypted_client_data_length; counter++)
+                op_client_data_to_apache[counter] = ip_encrypted_client_data[counter];
+	*clen = (uint8_t) ip_encrypted_client_data_length;
 
-	int clen1;  
-	int result = aes_gcm(1, derived_key, client_iv2, miti , 4, ciphertext1,  &clen1, tag);
-	*clen = (uint8_t) clen1; 
-	for(counter=0;counter<clen1;counter++)
+	plaintext_client_data = (unsigned char*) malloc(ip_encrypted_client_data_length);
+	check_ret = aes_gcm(0, derived_key, client_iv, ip_encrypted_client_data, ip_encrypted_client_data_length - 16, plaintext_client_data, &op_encrypted_client_data_length, ip_encrypted_client_data + (ip_encrypted_client_data_length - 16));
+	if(check_ret != 0)
 	{
-		op_client_data_to_apache[counter+ciphertext_length+64] = ciphertext1[counter];
+		free(ip_encrypted_client_data);
+		free(plaintext_client_data);
+		return check_ret;
 	}
-        for(counter=0;counter<16;counter++)
-        {
-                op_client_data_to_apache[counter+ciphertext_length+64+clen1] = tag[counter];
-        }
 
-
-	
+	// TODO: Encryption here - with aes128bit gcm to apache.
+	for(counter=0; counter<op_encrypted_client_data_length; counter++)
+		op_client_data_to_apache[counter] = plaintext_client_data[counter];
+	*clen = (uint8_t) op_encrypted_client_data_length;
+	free(ip_encrypted_client_data);
+	free(plaintext_client_data);
 
 	return 0;//result;
 }
 
+/*
 static void reverse_byte_array(uint8_t *array, size_t size)
 {
     size_t i = 0;
@@ -495,4 +506,4 @@ static void reverse_byte_array(uint8_t *array, size_t size)
         array[size - i - 1] = temp;
     }
 }
-
+*/

+ 3 - 2
Decryptor/Decryptor.edl

@@ -43,10 +43,10 @@ enclave {
 
 	public uint32_t create_and_seal_ecdsa_signing_key_pair([out]sgx_ec256_public_t* pub_key, [in] uint32_t* sealed_data_length, [out, size=SEALED_SIZE] uint8_t* sealed_data);
         public uint32_t unseal_and_restore_sealed_signing_key_pair([out] sgx_ec256_public_t* pub_key, [in, size=SEALED_SIZE] uint8_t* sealed_data, [in] size_t* sealed_data_length);
-        public uint32_t calculate_sealed_data_size(uint32_t input_size); 
+        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, uint32_t ciphertext_length, [in, size=160] unsigned char* user_data, [out, size=160] unsigned char* client_data_to_apache, [out, size=1] uint8_t* clen);
+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);
 
 
@@ -54,3 +54,4 @@ public uint32_t decrypt_client_data([in, size=64] unsigned char* client_pub_key,
 
 };
 };
+

+ 0 - 404
Decryptor/Openssl_crypto.cpp

@@ -1,404 +0,0 @@
-#include <openssl/ec.h>
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-#include <openssl/ecdh.h>
-#include <stdio.h>
-
-int generate_sha256_hash(const unsigned char *message, size_t message_len, unsigned char *digest);
-
-int ec_key_gen(unsigned char* pub_key_x, unsigned char* pub_key_y, unsigned char* priv_key)
-{
-//	unsigned char entropy_buf[ADD_ENTROPY_SIZE] = {0};
-
-//	RAND_add(entropy_buf, sizeof(entropy_buf), ADD_ENTROPY_SIZE);
-//	RAND_seed(entropy_buf, sizeof(entropy_buf));
-
-	EC_KEY * ec_key = NULL;
-    
-		ec_key = EC_KEY_new();
-		if (NULL == ec_key) {
-			return 0x42;
-		}
-
-	EC_GROUP* ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);	
-	if (NULL == ec_group) {
-		//EC_KEY_free(ec_key); 
-		return 0x0f;
-	}
-
-			if (0 == EC_KEY_set_group (ec_key, ec_group)) {
-			EC_KEY_free(ec_key); 
-			EC_GROUP_free(ec_group);
-			return 0x43; //break;
-		}
-
-
-	EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE);
-
-	int ret = EC_KEY_generate_key(ec_key);
-	if (!ret) {
-//        printf("EC_KEY_generate_key failure\n");
-	    return 0x01;
-	}
-	///////////////////////// Openssl code ////////////
-	const EC_POINT *public_k = NULL;
-	const BIGNUM *private_k = NULL;
-	public_k = EC_KEY_get0_public_key(ec_key);
-	if (NULL == public_k) 
-	{
-		EC_KEY_free(ec_key);
-		return 0x04;
-	}
-
-	private_k = EC_KEY_get0_private_key(ec_key);
-	if (NULL == private_k) 
-	{
-		EC_KEY_free(ec_key);
-		return 0x05;
-	}
-
-        if(!BN_bn2bin(private_k, priv_key))
-        {
-                EC_KEY_free(ec_key); 
-		return 0x06;
-        }
-
-
-        BIGNUM *pub_k_x = NULL;
-        BIGNUM *pub_k_y = NULL;
-        pub_k_x = BN_new();
-        pub_k_y = BN_new();
-        if (NULL ==  pub_k_x || NULL == pub_k_y) {
-                return 0x42;//SGX_ERROR_OUT_OF_MEMORY;
-        }
-
-	// extract two BNs representing the public key
-	//
-	if (!EC_POINT_get_affine_coordinates_GFp(ec_group, public_k, pub_k_x, pub_k_y, NULL)) 
-	//EC_KEY_free(ec_key); 
-	{
-		//printf("%ld\n", ERR_get_error());
-		BN_clear_free(pub_k_x); BN_clear_free(pub_k_y);	
-		EC_KEY_free(ec_key);
-		EC_GROUP_free(ec_group);
-		return 0x07;
-	}
-
-	ret = BN_bn2bin(pub_k_x, pub_key_x); 
-	BN_clear_free(pub_k_x); 
-	if(ret == 0)
-	{
-		BN_clear_free(pub_k_y); 
-        	EC_KEY_free(ec_key);
-	        EC_GROUP_free(ec_group);
-		return 0x08; 
-	}
-
-	ret = BN_bn2bin(pub_k_y, pub_key_y);
-
-	BN_clear_free(pub_k_y);
-	EC_KEY_free(ec_key);        
-	EC_GROUP_free(ec_group);
-
-	if(ret == 0)
-  		return 0x09; 
-
-	return 0;
-}
-
-unsigned long check_key(unsigned char* given_key_x, unsigned char* given_key_y) //, unsigned char* priv_key, unsigned char* shared_key_x, unsigned char* shared_key_y)
-{
-        EC_GROUP* ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);  
-        if (NULL == ec_group) {
-                //EC_KEY_free(ec_key); 
-                return 0x0f;
-        }
-	EC_POINT *ec_point = NULL;
-	BIGNUM *b_x = NULL;
-	BIGNUM *b_y = NULL;
-
-	ec_point = EC_POINT_new(ec_group);
-	if (NULL == ec_point) {
-			return 0x42; //retval = SGX_ERROR_OUT_OF_MEMORY;
-//			break;
-	}
-
-	// converts the x value of the point, represented as positive integer in big-endian into a BIGNUM
-	b_x = BN_bin2bn(given_key_x, 32, NULL);
-	if (NULL == b_x) {
-		EC_POINT_free(ec_point);
-		// return ERR_get_error(); 
-		return 0xfd;
-	}
-
-	// converts the y value of the point, represented as positive integer in big-endian into a BIGNUM
-	b_y = BN_bin2bn(given_key_y, 32, NULL);
-	if (NULL == b_y) {
-		BN_clear_free(b_x); 
-		EC_POINT_free(ec_point); 
-		return 0xfe;
-	}
-
-	// sets point based on x,y coordinates
-	int ret = EC_POINT_set_affine_coordinates_GFp(ec_group, ec_point, b_x, b_y, NULL);
-	if (1 != ret) {
-		BN_clear_free(b_x);
-		BN_clear_free(b_y);
-		EC_POINT_free(ec_point);
-		return ERR_get_error();	
-	}
-
-	// checks if point is on curve
-	//
-	int ret_point_on_curve = EC_POINT_is_on_curve(ec_group, ec_point, NULL);
-	if (1 != ret_point_on_curve) {
-	        EC_POINT_free(ec_point);
-		BN_clear_free(b_x);
-		BN_clear_free(b_y);
-		return ret_point_on_curve << 4; //ret_point_on_curve;//	break;
-	}
-	
-        BN_clear_free(b_x);
-        BN_clear_free(b_y);
-	EC_POINT_free(ec_point);
-	return 0;
-}
-
-unsigned long compute_shared_ECDHE_key(unsigned char* given_key_x, unsigned char* given_key_y, unsigned char* priv_key, unsigned char* shared_key, unsigned char* derived_key)
-{
-//	int valid_point = check_key(given_key_x, given_key_y);
-//	if(valid_point != 0)
-//		return valid_point;
-	unsigned long long_ret = 0; 
-	EC_GROUP* ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);  
-        if (NULL == ec_group) {
-                return 0x0f;
-        }
-        EC_POINT *given_point = NULL;
-        BIGNUM *b_x = NULL;
-        BIGNUM *b_y = NULL;
-	EC_KEY *private_key = NULL;
-
-        given_point = EC_POINT_new(ec_group);
-        if (NULL == given_point) {
-                        return 0x42; //retval = SGX_ERROR_OUT_OF_MEMORY;
-//                      break;
-        }
-
-        // converts the x value of the point, represented as positive integer in big-endian into a BIGNUM
-        b_x = BN_bin2bn(given_key_x, 32, NULL);
-        if (NULL == b_x) {
-                EC_POINT_free(given_point);
-                return 0xfd;
-        }
-
-        // converts the y value of the point, represented as positive integer in big-endian into a BIGNUM
-        b_y = BN_bin2bn(given_key_y, 32, NULL);
-        if (NULL == b_y) {
-                EC_POINT_free(given_point); 
-	        BN_clear_free(b_x); 
-                return 0xfe;
-        }
-
-        // sets point based on x,y coordinates
-        int ret = EC_POINT_set_affine_coordinates_GFp(ec_group, given_point, b_x, b_y, NULL);
-        if (1 != ret) {
-                EC_POINT_free(given_point);
-                BN_clear_free(b_x); 
-                BN_clear_free(b_y);
-		return ERR_get_error(); 
-        }
-
-        // checks if point is on curve
-        //
-        int ret_point_on_curve = EC_POINT_is_on_curve(ec_group, given_point, NULL);
-        if (1 != ret_point_on_curve) {
-                EC_POINT_free(given_point);
-		BN_clear_free(b_x);
-		BN_clear_free(b_y); 
-		if(ret_point_on_curve == 0)
-			return 0x43;
-		else 
-			return ERR_get_error(); 
-	}
-
-	
-	// create empty shared key BN
-	//
-	private_key = EC_KEY_new();
-	if (private_key == NULL) {
-		EC_POINT_free(given_point);
-                BN_clear_free(b_x); 
-                BN_clear_free(b_y);
-		return 0x42;//ret = SGX_ERROR_OUT_OF_MEMORY;
-	}
-
-	// init private key group (set curve)
-	//
-	if (EC_KEY_set_group (private_key, ec_group) != 1) {
-		EC_POINT_free(given_point); 
-		EC_KEY_free(private_key); 
-                BN_clear_free(b_x); 
-                BN_clear_free(b_y);
-		return ERR_get_error(); //break;
-	}
-
-	// init private key with BN value
-	//
-	BIGNUM *BN_dh_privB = NULL; 
-	BN_dh_privB = BN_bin2bn(priv_key, 32, NULL);
-	if(BN_dh_privB == NULL) {
-		EC_POINT_free(given_point); 
-                EC_KEY_free(private_key); 
-                BN_clear_free(b_x); 
-                BN_clear_free(b_y);
-		return 0x44;
-	}
-
-	if (EC_KEY_set_private_key(private_key, BN_dh_privB) != 1) {
-		EC_POINT_free(given_point);
-		EC_KEY_free(private_key); 
-        	BN_clear_free(b_x); 
-	        BN_clear_free(b_y);
-		BN_clear_free(BN_dh_privB); 
-		return ERR_get_error(); 
-	}
-
-	// calculate shared dh key
-	//
-	int shared_key_len = 32; //sizeof(sgx_ec256_dh_shared_t);
-	shared_key_len = ECDH_compute_key(shared_key, 32, given_point, private_key, NULL);
-	if (shared_key_len <= 0) {
-		long_ret = ERR_get_error(); 
-	}
-	else 
-		long_ret = generate_sha256_hash(shared_key, 32, derived_key); 
-
-	BN_clear_free(BN_dh_privB);
-	BN_clear_free(b_x); 
-	BN_clear_free(b_y);
-	EC_POINT_free(given_point);
-	EC_KEY_free(private_key); 
-	return long_ret; 
-}
-
-int generate_sha256_hash(const unsigned char *message, size_t message_len, unsigned char *digest)
-{
-	EVP_MD_CTX *mdctx; unsigned int digest_len;
-
-	if((mdctx = EVP_MD_CTX_create()) == NULL)
-	{
-		//printf("EVP_MD_CTX_create returned NULL - could not create context\n"); fflush(stdout); 
-		return 0x1; 
-	}
-
-	if(EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL) != 1)
-	{
-                //printf("EVP_DigestInit_ex returned 0 - could not initialize hash with SHA256\n"); fflush(stdout); 
-		return 0x2; 
-	}
-
-        if(EVP_DigestUpdate(mdctx, message, message_len) != 1)        
-        {
-                //printf("EVP_DigestUpdate returned 0 - could not compute SHA256 hash\n"); fflush(stdout); 
-		return 0x3; 
-        }
-
-	if(1 != EVP_DigestFinal_ex(mdctx, digest, &digest_len))     
-        {
-                //printf("EVP_DigestFinal_ex returned 0 - could not finalize SHA256 hash\n"); fflush(stdout); 
-		return 0x4; 
-        }
-
-	if(digest_len != 32) 
-	{
-//		printf("EVP_DigestFinal_ex returned a digest length of 0x%x instead of 0x20\n", digest_len); fflush(stdout); 
-	return 0x5; 
-	}
-	EVP_MD_CTX_destroy(mdctx);
-	return 0; 
-}
-EVP_CIPHER_CTX* ctx; 
-
-// 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, int plaintext_len, unsigned char *ciphertext,  int* op_ciphertext_len, unsigned char* tag)
-{
-	int len;
-	int ciphertext_len;
-	int reset_return;
-	if(ctx == NULL)
-	{
-		// Create and initialise the context //
-		if(!(ctx = EVP_CIPHER_CTX_new())) { return 0x1; }
-	}
-
-
-	// Initialise the encryption operation. //
-	if(1 != EVP_CipherInit_ex(ctx, EVP_aes_256_gcm(), NULL, key, iv, enc))
-	{
-		reset_return = EVP_CIPHER_CTX_reset(ctx);
-		if(reset_return != 1)
-			return 0xf2;
-		return 0x2;
-	}
-	// Provide the message to be encrypted, and obtain the encrypted output.	 * EVP_EncryptUpdate can be called multiple times if necessary
-	 //
-	if(1 != EVP_CipherUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
-	{
-                reset_return = EVP_CIPHER_CTX_reset(ctx);
-	        if(1 != reset_return)
-			return 0xF3;
-		return 0x3;
-	}
-	ciphertext_len = len;
-
-	if(enc == 0)
-        {
-                if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
-                {
-                       reset_return = EVP_CIPHER_CTX_reset(ctx);
-                       if(1 != reset_return) 
-                                return 0xF5;
-                        return 0x5;
-                }
-        }
-
-
-	// Finalise the encryption. Normally ciphertext bytes may be written at  this stage, but this does not occur in GCM mode
-	 //
-	// TODO: ^^^ Why the heck does it not occur in GCM mode ? 
-	if(1 != EVP_CipherFinal_ex(ctx, ciphertext + len, &len)) 
-	{
-		reset_return = EVP_CIPHER_CTX_reset(ctx);
-                if(1 != reset_return)
-                        return 0xF4;
-                return 0x4;
-	}
-	ciphertext_len += len;
-
-	// Get the tag 
-	if(enc == 1)
-	{
-		if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
-		{
-                	reset_return = EVP_CIPHER_CTX_reset(ctx);
-                	if(1 != reset_return) 
-                        	return 0xF5;
-	                return 0x5;
-		}
-	}
-
-	// Clean up //
-	if(1 != EVP_CIPHER_CTX_reset(ctx))
-	{
-		return 0xF0; 
-	}
-
-	*op_ciphertext_len=ciphertext_len; 
-		//EVP_CIPHER_CTX_free(ctx); // TODO: memory leaks here - need to free this for erroneous cases too.
-	return 0;
-}
-

+ 6 - 4
Include/Openssl_crypto.h

@@ -1,5 +1,7 @@
-int ec_key_gen(unsigned char* pub_key_x, unsigned char* pub_key_y, unsigned char* priv_key);
-unsigned long check_key(unsigned char* given_key_x, unsigned char* given_key_y);
-unsigned long compute_shared_ECDHE_key(unsigned char* given_key_x, unsigned char* given_key_y, unsigned char* priv_key, unsigned char* shared_key, unsigned char* derived_key);
+int ecdh_key_gen(unsigned char* pub_key_x, unsigned char* pub_key_y, unsigned char* priv_key);
+unsigned long check_ecdh_public_key(unsigned char* given_key_x, unsigned char* given_key_y);
+unsigned long compute_ecdh_shared_key(unsigned char* given_key_x, unsigned char* given_key_y, unsigned char* priv_key, unsigned char* derived_key);
 int generate_sha256_hash(const unsigned char *message, size_t message_len, unsigned char *digest);
-int aes_gcm(int enc, unsigned char *key, unsigned char *iv, unsigned char* plaintext, int plaintext_len, unsigned char *ciphertext,  int* op_ciphertext_len, unsigned char* tag); 
+int aes_gcm(int enc, unsigned char *key, unsigned char *iv, unsigned char* plaintext, int plaintext_len, unsigned char *ciphertext,  int* op_ciphertext_len, unsigned char* tag);
+int base64_decoding_wrapper(unsigned char* src, unsigned char* dest, uint32_t length);
+

+ 18 - 12
Makefile

@@ -75,6 +75,7 @@ endif
 #PHPTrustLib_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector  $(TrustLib_Include_Paths)
 #PHPTrustLib_Compile_Cxx_Flags :=  -std=c++11 -nostdinc++
 OPENSSL_LIBRARY_PATH := /home/m2mazmud/old_stuff/intel-sgx-ssl/Linux/package/lib64/
+OPENSSL_BAREBONES_LIBRARY_PATH := /home/m2mazmud/old_stuff/intel-sgx-ssl/openssl_source/openssl-1.1.0h/
 OpenSSL_Crypto_Library_Name := sgx_tsgxssl_crypto
 SGXSSL_Library_Name := sgx_tsgxssl
 SgxSSL_Link_Libraries := -L$(OPENSSL_LIBRARY_PATH) -Wl,--whole-archive -l$(SGXSSL_Library_Name) -Wl,--no-whole-archive -l$(OpenSSL_Crypto_Library_Name)
@@ -87,7 +88,7 @@ Trust_Lib_Name := libLocalAttestation_Trusted.a
 TrustLib_Cpp_Files := $(wildcard LocalAttestationCode/*.cpp)
 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  
+TrustLib_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector  $(TrustLib_Include_Paths) -Wall
 TrustLib_Compile_Cxx_Flags :=  -std=c++11 -nostdinc++
 
 #UnTrustLib_Name := libLocalAttestation_unTrusted.a
@@ -107,7 +108,7 @@ endif
 App_Cpp_Files := $(wildcard App/*.cpp)
 App_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/ippcp -I./Include -I./LocalAttestationCode
 
-App_Compile_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) -Wall 
+App_Compile_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) -Wall
 # Three configuration modes - Debug, prerelease, release
 #   Debug - Macro DEBUG enabled.
 #   Prerelease - Macro NDEBUG and EDEBUG enabled.
@@ -121,7 +122,7 @@ else
 endif
 
 #App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -L. -lpthread -lprotobuf
-App_Link_Flags := $(SGX_COMMON_CFLAGS) $(Security_Link_Flags) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lsgx_uae_service -L$(OPENSSL_LIBRARY_PATH) -lsgx_usgxssl -lpthread  -lprotobuf
+App_Link_Flags := $(SGX_COMMON_CFLAGS) $(Security_Link_Flags) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lsgx_uae_service -L$(OPENSSL_LIBRARY_PATH) -lsgx_usgxssl -lpthread  -lprotobuf #-L$(OPENSSL_BAREBONES_LIBRARY_PATH) -lcrypto
 
 ifneq ($(SGX_MODE), HW)
 	App_Link_Flags += -lsgx_uae_service_sim
@@ -146,13 +147,13 @@ endif
 Crypto_Library_Name := sgx_tcrypto
 
 Enclave_Cpp_Files_2 := $(wildcard Decryptor/*.cpp)
-Enclave_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx -I./LocalAttestationCode -I./Include 
+Enclave_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx -I./LocalAttestationCode -I./Include
 
 CC_BELOW_4_9 := $(shell expr "`$(CC) -dumpversion`" \< "4.9")
 ifeq ($(CC_BELOW_4_9), 1)
-	Enclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector -Wno-unused-variable -Wall 
+	Enclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector -Wno-unused-variable -Wall
 else
-	Enclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector-strong -Wno-unused-variable -Wall 
+	Enclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector-strong -Wno-unused-variable -Wall
 endif
 
 Enclave_Compile_Flags += $(Enclave_Include_Paths)
@@ -241,6 +242,10 @@ $(Trust_Lib_Name): LocalAttestationCode/LocalAttestationCode_t.o $(TrustLib_Cpp_
 	@$(AR) rcs $@ $^
 	@echo "GEN  =>  $@"
 
+CommonOpensslCode/Openssl_crypto.o: CommonOpensslCode/Openssl_crypto.cpp
+	@$(CXX) -std=c++11 -nostdinc++ $(Enclave_Compile_Flags) -I$(OPENSSL_INCLUDES)  -c $< -o $@
+	@echo "CXX  <=  $<"
+
 #Untrusted_LocalAttestation/%.o: Untrusted_LocalAttestation/%.cpp
 #	@$(CXX) $(UnTrustLib_Compile_Flags) -c $< -o $@
 #	@echo "CC   <=  $<"
@@ -280,12 +285,12 @@ Decryptor/Decryptor.o: Decryptor/Decryptor.cpp
 	@$(CXX) -std=c++11 -nostdinc++ $(Enclave_Compile_Flags)  -c $< -o $@
 	@echo "CXX  <=  $<"
 
-Decryptor/Openssl_crypto.o: Decryptor/Openssl_crypto.cpp
-	@$(CXX) -std=c++11 -nostdinc++ $(Enclave_Compile_Flags) -I$(OPENSSL_INCLUDES)  -c $< -o $@
-	@echo "CXX  <=  $<"
+#CommonOpensslCode/Openssl_crypto.o: CommonOpensslCode/Openssl_crypto.cpp
+#	@$(CXX) -std=c++11 -nostdinc++ $(Enclave_Compile_Flags) -I$(OPENSSL_INCLUDES)  -c $< -o $@
+#	@echo "CXX  <=  $<"
 
-Decryptor.so: Decryptor/Decryptor_t.o Decryptor/Decryptor.o Decryptor/Openssl_crypto.o $(Trust_Lib_Name)
-	@$(CXX)  Decryptor/Decryptor_t.o $(Enclave_Cpp_Objects_2) -o $@ $(Decryptor_Link_Flags)
+Decryptor.so: Decryptor/Decryptor_t.o Decryptor/Decryptor.o CommonOpensslCode/Openssl_crypto.o $(Trust_Lib_Name)
+	@$(CXX)  Decryptor/Decryptor_t.o $(Enclave_Cpp_Objects_2) CommonOpensslCode/Openssl_crypto.o -o $@ $(Decryptor_Link_Flags)
 	@echo "LINK =>  $@"
 
 $(Enclave_Name_2): Decryptor.so
@@ -296,4 +301,5 @@ $(Enclave_Name_2): Decryptor.so
 .PHONY: clean
 
 clean:
-	@rm -rf .config_* $(App_Name) *.so *.a App/*.o Decryptor/*.o Decryptor/*_t.* Decryptor/*_u.* LocalAttestationCode/*.o LocalAttestationCode/*_t.* 
+	@rm -rf .config_* $(App_Name) *.so *.a App/*.o Decryptor/*.o Decryptor/*_t.* Decryptor/*_u.* LocalAttestationCode/*.o LocalAttestationCode/*_t.*
+