Browse Source

Works for deployment stage for both apache, verifier.
Returns a header.
Added an ecall to process a list of client data fields.
Yet to test runtime decryption of client data.

dettanym 4 years ago
parent
commit
5ec6682c84
6 changed files with 134 additions and 53 deletions
  1. 2 0
      App/MainLogic.cpp
  2. 23 10
      App/PostLAMessaging.cpp
  3. 85 8
      Decryptor/Decryptor.cpp
  4. 5 34
      Decryptor/Decryptor.edl
  5. 9 1
      Decryptor/Decryptor.h
  6. 10 0
      Decryptor/DecryptorWrapper.cpp

+ 2 - 0
App/MainLogic.cpp

@@ -174,6 +174,7 @@ int MainLogic::run_deployment_runtime_stage_logic() {
     }
     else if(child_pid == 0) // Child process - returns headers.
     {
+        printf("Lol in child process.\n"); fflush(stdout);
         ret_status = 0;
         do
         {
@@ -183,6 +184,7 @@ int MainLogic::run_deployment_runtime_stage_logic() {
     }
     else // Parent process - decrypts client data.
     {
+        printf("Lol in parent process.\n"); fflush(stdout);
         ret_status = 0;
         do
         {

+ 23 - 10
App/PostLAMessaging.cpp

@@ -14,21 +14,24 @@ int PostLAMessaging::process_target_data_msg(extension_to_decryptor_msg& incomin
     std::string client_public_key_string, field_string;
     uint32_t sgx_ret_status, client_public_key_length, field_counter, byte_counter, field_size, no_of_fields, total_input_length, field_size_accumulator;
 
-    // Initialize the client public key as an input to the decryptor ecall
+    // Initialize the client public key
     client_public_key_string = incomingMsg.ciphertext_client_public_key();
     client_public_key_length = client_public_key_string.length();
     // client_public_key = (uint8_t*) malloc(client_public_key_length);
     client_public_key = client_public_key_string.c_str();
 
-    // Initialize an array of sizes of each of the incoming ciphertext fields (again an input arg. to the ecall).
+    // Initialize an array of sizes - first element is the length of the public key
+    // and rest are sizes of each of the incoming ciphertext fields (an input arg. to the ecall).
     // Initialize an array to store the sizes of the *outgoing* fields too.
     no_of_fields = incomingMsg.fields_size();
-    input_field_sizes = (uint32_t*) malloc(no_of_fields);
-    output_field_sizes = (uint32_t*) malloc(no_of_fields);
-    total_input_length = 0;
-    for(field_counter=0; field_counter<no_of_fields; field_counter++)
+    input_field_sizes = (uint32_t*) malloc(no_of_fields + 1); // extra one for public key.
+    output_field_sizes = (uint32_t*) malloc(no_of_fields + 1); // Made them the same as the edl file doesnt support fns of input args as sizes.
+    total_input_length = client_public_key_length;
+
+    input_field_sizes[0] = client_public_key_length;
+    for(field_counter=1; field_counter<no_of_fields+1; field_counter++)
     {
-        input_field_sizes[field_counter] = incomingMsg.fields(field_counter).field().length();
+        input_field_sizes[field_counter] = incomingMsg.fields(field_counter-1).field().length();
         total_input_length+=input_field_sizes[field_counter];
     }
 
@@ -36,7 +39,14 @@ int PostLAMessaging::process_target_data_msg(extension_to_decryptor_msg& incomin
     // The number of bytes in any given ciphertext field will be determined by the above array.
     // Also initialize an array to store the outgoing bytes for all ciphertext fields.
     incoming_client_data = (uint8_t*) malloc(total_input_length);
+    // Did not tighten the upper bound for the length of the output data as the edl file cant handle functions of input arguments as the sizes.
     outgoing_client_data = (uint8_t*) malloc(total_input_length);
+    for(byte_counter=0; byte_counter<client_public_key_length; byte_counter++)
+    {
+        incoming_client_data[byte_counter] = client_public_key[byte_counter];
+    }
+    field_size_accumulator=client_public_key_length;
+
     for(field_counter=0; field_counter<no_of_fields; field_counter++)
     {
         field_size = input_field_sizes[field_counter];
@@ -49,9 +59,8 @@ int PostLAMessaging::process_target_data_msg(extension_to_decryptor_msg& incomin
     }
 
     sgx_ret_status=0;
-    // TODO: Fix enclave ecall.
-    // Ecall into the enclave to obtain the fields to be sent to the target enclave in response.
-    // Decryptor_functionX(enclave_id, &sgx_ret_status, client_public_key, incoming_client_data, no_of_fields, input_field_sizes,  outgoing_client_data, output_field_sizes);
+    Decryptor_decrypt_client_data_wrapper(enclave_id, &sgx_ret_status, incoming_client_data, input_field_sizes,
+            no_of_fields, total_input_length,  outgoing_client_data, output_field_sizes);
     free(input_field_sizes);
     free(incoming_client_data);
     if(sgx_ret_status!=0)
@@ -146,6 +155,10 @@ int PostLAMessaging::read_and_write_header()
         fflush(stdout);
         return sgx_ret_status;
     }
+    uint32_t counter;
+    for(counter=0;counter<value_length;counter++)
+        printf("%02x ", header_value[counter]);
+    printf("\n"); fflush(stdout);
 
     headerMsg.set_name("Mitigator-Public-Key:", 21);
     headerMsg.set_value(header_value, value_length);

+ 85 - 8
Decryptor/Decryptor.cpp

@@ -54,13 +54,11 @@
     return 0;
   }
 
-  // TODO: FIX DUMMY HEADER. 
-  // EXTERNAL ECALL.
   uint32_t Decryptor::create_and_encrypt_mitigator_header_H(uint8_t* ciphertext_token_H_plus_tag, uint32_t* op_length)
   {
       uint32_t temp_ciphertext_token_H_iv_tag_length;
-    	uint32_t internal_return_status;
-        uint8_t plaintext_mitigator_header_H[ECDH_PUBLIC_KEY_SIZE + 32 + 64] = {0x42};
+      uint32_t internal_return_status;
+      uint8_t plaintext_mitigator_header_H[ECDH_PUBLIC_KEY_SIZE + 32 + 64] = {0x42};
 
       if(successful_la_count != 2)
         return 0x33;
@@ -70,8 +68,8 @@
         return internal_return_status;
 
       internal_return_status = symmetricEncryptionBoxApache.encrypt_decrypt(1, plaintext_mitigator_header_H, ECDH_PUBLIC_KEY_SIZE + 32 + 64, ciphertext_token_H_plus_tag, &temp_ciphertext_token_H_iv_tag_length);
-	*op_length = temp_ciphertext_token_H_iv_tag_length;
-    	return internal_return_status;
+      *op_length = temp_ciphertext_token_H_iv_tag_length;
+      return internal_return_status;
     }
 
   // INTERNAL. done. But there might be one more return statement for the case when get_keypair returns sth (it is non void).
@@ -86,7 +84,9 @@
     return 0;
   }
 
+
   // INTERNAL.
+  // TODO: Edit to process a list of fields.
   uint32_t Decryptor::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)
   {
     uint8_t* ciphertext_plus_tag;
@@ -208,8 +208,85 @@
         return 0;
   }
 
-  // EXTERNAL. DONE.
-  uint32_t Decryptor::process_apache_message_generate_response(uint8_t* input_ciphertext, uint32_t input_ciphertext_plus_tag_length, uint8_t* output_ciphertext_plus_tag, uint32_t* output_ciphertext_plus_tag_length)
+    uint32_t Decryptor::encrypt_decrypt_fields_list(SymmetricEncryptionBox &symmetricEncryptionBox , uint32_t encrypt_decrypt,
+            uint8_t *input_fields_list, uint32_t *input_field_sizes,
+                                                    uint32_t no_of_fields,
+                                                    uint8_t *output_fields_list,
+                                                    uint32_t *output_field_sizes, uint32_t* total_output_length) {
+      // Enc-dec loops over no_of_fields.
+      uint32_t field_counter, input_byte_accumulator=0, byte_counter, field_size, output_byte_accumulator=0;
+      uint8_t* input_field, *output_field;
+      uint32_t input_field_length, output_field_length, internal_return_status;
+
+      output_field = output_fields_list;
+      for(field_counter=0; field_counter< no_of_fields; field_counter++)
+      {
+          input_field_length = input_field_sizes[field_counter];
+          input_field = input_fields_list + input_byte_accumulator;
+          output_field = output_fields_list + output_byte_accumulator;
+
+          internal_return_status = symmetricEncryptionBox.encrypt_decrypt(encrypt_decrypt, input_field, input_field_length, output_field, &output_field_length);
+          if(internal_return_status != 0)
+              return internal_return_status;
+
+          output_field_sizes[field_counter] = output_field_length;
+          input_byte_accumulator += input_field_length;
+          output_byte_accumulator += output_field_length;
+      }
+      *total_output_length = output_byte_accumulator;
+      return 0;
+  }
+
+  uint32_t Decryptor::decrypt_client_data(uint8_t *input_fields_list, uint32_t *input_field_sizes,
+                                          uint32_t no_of_fields, uint32_t total_input_size,
+                                          uint8_t *output_fields_list,
+                                          uint32_t *output_field_sizes) {
+
+      uint8_t *intermediate_fields_list, *plaintext_fields_list;
+      uint32_t *intermediate_fields_sizes, *plaintext_fields_sizes;
+      uint32_t internal_return_status, total_intermediate_fields_length;
+      uint32_t total_plaintext_fields_length, total_output_fields_length;
+      // List of symmetric decryption outputs - will get rid of 12 bytes of IV and 16 bytes of tag.
+      intermediate_fields_list = (uint8_t*) malloc(total_input_size - (28 * no_of_fields));
+      intermediate_fields_sizes = (uint32_t*) malloc(no_of_fields);
+
+      // Remove outermost layer of decryption, namely the one with the target enclave.
+      internal_return_status = encrypt_decrypt_fields_list(symmetricEncryptionBoxApache, 0, input_fields_list,
+              input_field_sizes, no_of_fields,
+              intermediate_fields_list, intermediate_fields_sizes, &total_intermediate_fields_length);
+      if(internal_return_status != 0)
+          return internal_return_status;
+
+      // Establish a symmetric encryption key with the client, using the client's public key.
+      // TODO: Change this function to take in the key length.
+      internal_return_status = hybridEncryptionBoxClient.initialize_symmetric_key(intermediate_fields_list);
+      if(internal_return_status != 0)
+          return internal_return_status;
+
+      // The public key, which was the first element of the output list above, has been processed.
+      // Do not attempt to decrypt it one more time.
+      intermediate_fields_list += intermediate_fields_sizes[0];
+      intermediate_fields_sizes += 1;
+      no_of_fields -= 1;
+      total_intermediate_fields_length -= intermediate_fields_sizes[0];
+
+      // Initializing lists for the plaintext data.
+      plaintext_fields_list = (uint8_t*) malloc(total_intermediate_fields_length);
+      plaintext_fields_sizes = (uint32_t*) malloc(no_of_fields);
+
+      // Obtain plaintext data by decrypting with the above newly-established key with the client.
+      internal_return_status = encrypt_decrypt_fields_list(hybridEncryptionBoxClient, 0,
+              intermediate_fields_list, intermediate_fields_sizes, no_of_fields,
+              plaintext_fields_list, plaintext_fields_sizes, &total_plaintext_fields_length);
+      if(internal_return_status != 0)
+          return internal_return_status;
+
+      // Finally, encrypt the plaintext back to the target enclave.
+      return encrypt_decrypt_fields_list(symmetricEncryptionBoxApache, 1, plaintext_fields_list, plaintext_fields_sizes,
+              no_of_fields, output_fields_list, output_field_sizes, &total_output_fields_length);
+  }
+
+uint32_t Decryptor::process_apache_message_generate_response(uint8_t* input_ciphertext, uint32_t input_ciphertext_plus_tag_length, uint8_t* output_ciphertext_plus_tag, uint32_t* output_ciphertext_plus_tag_length)
   {
       uint32_t first_decryption_output_length, plaintext_client_data_length;
       uint32_t internal_return_status;

+ 5 - 34
Decryptor/Decryptor.edl

@@ -1,35 +1,3 @@
-/*
- * 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.
- *
- */
-
-
 enclave {
     include "sgx_eid.h"
     include "sgx_tcrypto.h"
@@ -44,8 +12,11 @@ enclave {
       // Apache mrsigner = 32 bytes + tag on encryption = 16 bytes.
       // public uint32_t decrypt_verifiers_message_set_apache_mrsigner_wrapper([in, size=60] 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=4100] uint8_t* input_ciphertext, uint32_t input_ciphertext_plus_tag_length, [out, size=4100] uint8_t* output_ciphertext, [out,size=4] uint32_t* output_ciphertext_plus_tag_length);
+      public uint32_t decrypt_client_data_wrapper([in, size=total_input_size] uint8_t *input_fields_list, [in, size=no_of_fields] uint32_t *input_field_sizes,
+                                              uint32_t no_of_fields, uint32_t total_input_size,
+                                              [out, size=total_input_size] uint8_t *output_fields_list,
+                                              [out, size=no_of_fields] uint32_t *output_field_sizes);
+public uint32_t process_apache_message_generate_response_wrapper([in, size=4100] uint8_t* input_ciphertext, uint32_t input_ciphertext_plus_tag_length, [out, size=4100] uint8_t* output_ciphertext, [out,size=4] uint32_t* output_ciphertext_plus_tag_length);
       public uint32_t process_verifiers_message_wrapper([in, size=60] uint8_t* input_ciphertext, uint32_t length);
       public        void get_verifier_mrenclave_apache_mrsigner_wrapper([out, size=64] uint8_t* output);
 	public void get_short_term_public_key_wrapper([out, size=64] uint8_t* output); 

+ 9 - 1
Decryptor/Decryptor.h

@@ -19,7 +19,11 @@ class Decryptor {
   static uint32_t create_mitigator_header_H(uint8_t* signature_data_and_signature);
   static uint32_t create_long_term_signing_keypair(uint8_t* private_public_key_string);
   static 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);
-  public:
+    static uint32_t encrypt_decrypt_fields_list(SymmetricEncryptionBox &symmetricEncryptionBox, uint32_t encrypt_decrypt, uint8_t *input_fields_list,
+                                                uint32_t *input_field_sizes, uint32_t no_of_fields,
+                                                uint8_t *output_fields_list, uint32_t *output_field_sizes, uint32_t* total_output_length);
+
+public:
     static void calculate_sealed_keypair_size(uint32_t* output_length); 
     static uint32_t verify_peer_enclave_trust(uint8_t* given_mr_enclave, uint8_t* given_mr_signer, uint8_t* dhaek);
     static uint32_t create_and_seal_long_term_signing_key_pair(uint32_t* sealed_data_length, uint8_t* sealed_data);
@@ -27,6 +31,10 @@ class Decryptor {
     static uint32_t unseal_and_restore_long_term_signing_key_pair(uint8_t* sealed_data, uint32_t* sgx_sealed_data_length);
     static uint32_t decrypt_verifiers_message_set_apache_mrsigner(uint8_t* ciphertext_plus_tag);
     static 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);
+    static uint32_t decrypt_client_data(uint8_t *input_fields_list, uint32_t *input_field_sizes,
+                                        uint32_t no_of_fields, uint32_t total_input_size,
+                                        uint8_t *output_fields_list,
+                                        uint32_t *output_field_sizes);
     static uint32_t process_verifiers_message(uint8_t* input_ciphertext, uint32_t length);
 	static  void testing_get_verifier_mrenclave_apache_mrsigner(uint8_t* output); 
 	static void testing_get_short_term_public_key(uint8_t* output); 

+ 10 - 0
Decryptor/DecryptorWrapper.cpp

@@ -51,3 +51,13 @@ void get_apache_iv(uint8_t* op)
 {
 	Decryptor::testing_get_apache_iv(op);
 }
+
+uint32_t decrypt_client_data_wrapper(uint8_t *input_fields_list, uint32_t *input_field_sizes,
+                                        uint32_t no_of_fields, uint32_t total_input_size,
+                                        uint8_t *output_fields_list,
+                                        uint32_t *output_field_sizes)
+{
+    return Decryptor::decrypt_client_data(input_fields_list, input_field_sizes,
+            no_of_fields, total_input_size,
+            output_fields_list, output_field_sizes);
+    }