Browse Source

Post-LA encryption/decryption working

dettanym 5 years ago
parent
commit
17eb69029c
9 changed files with 251 additions and 30 deletions
  1. 9 0
      ProtobufLAInitiator.cpp
  2. 41 0
      SgxProtobufLAInitiator.cpp
  3. 173 21
      crypto.cpp
  4. 1 1
      include/ProtobufLAInitiator.h
  5. 1 0
      include/SgxProtobufLAInitiator.h
  6. 12 1
      include/crypto.h
  7. 0 0
      sealed_msg.txt
  8. 14 7
      systemMain.cpp
  9. BIN
      verifier

+ 9 - 0
ProtobufLAInitiator.cpp

@@ -142,6 +142,15 @@ int local_attestation_initiator(int port)
       printf("Error in process_protobuf_dh_msg3: 0x%x", protobuf_sgx_ret); fflush(stdout); return protobuf_sgx_ret;
   }
 
+  protobuf_sgx_ret=generate_encrypted_rsa_keypair_hash(); 
+  if(protobuf_sgx_ret==0)
+  {
+	printf("Done encryption of hash.\n"); fflush(stdout); 
+  }
+  else 
+	{
+		printf("Error in enc/dec of hash: 0x%x", protobuf_sgx_ret); fflush(stdout); 
+	}
 	printf("Successfully done Local attestation\n");
 	fflush(stdout);
 	return 0;

+ 41 - 0
SgxProtobufLAInitiator.cpp

@@ -18,6 +18,8 @@
 #define MAX_SESSION_COUNT  16
 #define SGX_CAST(type, item) ((type)(item))
 #include <string.h>
+#include "crypto.h"
+#include "stdio.h"
 
 dh_session_t global_session_info;
 
@@ -82,6 +84,45 @@ uint32_t process_protobuf_dh_msg3(protobuf_sgx_dh_msg3_t& protobuf_msg3, uint32_
   return 0;
 }
 
+uint32_t generate_encrypted_rsa_keypair_hash()
+{
+	uint8_t hash[32]; uint32_t return_status;
+	unsigned char key[16]; uint32_t count;
+	for(count=0;count<16;count++)
+		key[count]=global_session_info.active.AEK[count]; 
+	return_status=generate_rsa_keypair_hash(hash); 
+	if(return_status!=0)
+		return return_status; 
+	
+	uint8_t ciphertext[48]; uint8_t expected_plaintext[48]; 
+	uint8_t encryption_tag[16]; uint8_t decryption_tag[16]; 
+	int ciphertext_len=48; int plaintext_len=32;
+	uint8_t iv[12]; 
+	memset(ciphertext, 0, 48); memset(expected_plaintext, 0, 48); 
+	memset(iv, 0, 12);  memset(expected_plaintext, 0, 32); memset(encryption_tag, 0, 16); memset(decryption_tag, 0, 16); 
+	return_status=aes_cipher(1, key, iv, hash, 32, ciphertext,  &ciphertext_len, encryption_tag);
+	printf("ciphertext len: %d\n", ciphertext_len); fflush(stdout);
+	printf("Encryption return status: 0x%x", return_status);  fflush(stdout); 
+	return_status=aes_cipher(0, key, iv, ciphertext, ciphertext_len, expected_plaintext, &plaintext_len, encryption_tag); 
+//	for(count=0;count<16;count++)
+//	{
+//		if(encryption_tag[count]!=decryption_tag[count])
+//			return 0xFF;
+//		printf("0x%x 0x%x ", encryption_tag[count], decryption_tag[count]);
+//	}
+//	printf("\n");
+//	fflush(stdout); 
+	for(count=0;count<32;count++)
+	{
+		printf("0x%x 0x%x ", hash[count], expected_plaintext[count]);
+//		if(hash[count]!=expected_plaintext[count])
+//			return 0xFE;
+	}
+	fflush(stdout); 
+
+	return return_status;
+}
+
 // TODO: Private function
 uint32_t verify_peer_enclave_trust(sgx_dh_session_enclave_identity_t* peer_enclave_identity, uint8_t* expected_mr_enclave, uint8_t* expected_mr_signer)
 {

+ 173 - 21
crypto.cpp

@@ -2,25 +2,66 @@
 #include <string> 
 #include <memory>
 using std::unique_ptr;
-
+#include <openssl/err.h> 
 #include <openssl/bn.h>
 #include <openssl/rsa.h>
-#include <openssl/sha.h>
-using BN_ptr = std::unique_ptr<BIGNUM, decltype(&::BN_free)>;
-using RSA_ptr = std::unique_ptr<RSA, decltype(&::RSA_free)>;
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+//using BN_ptr = std::unique_ptr<BIGNUM, decltype(&::BN_free)>;
+//using RSA_ptr = std::unique_ptr<RSA, decltype(&::RSA_free)>;
+EVP_CIPHER_CTX *ctx;
+RSA* rsa;
+BIGNUM* bn;
+//RSA_ptr rsa_signing_keypair; //(RSA_new(), ::RSA_free);
+//BN_ptr rsa_bignum;
 
-uint32_t generate_rsa_key(std::string& priv_key_str, std::string& pub_key_str)
+// assumes that the digest is at least of length 256/8 bytes. 
+uint32_t generate_sha256_hash(const unsigned char *message, size_t message_len, unsigned char *digest)
 {
-    int rc;
+	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; 
+        }
 
-    RSA_ptr rsa(RSA_new(), ::RSA_free);
-    BN_ptr bn(BN_new(), ::BN_free);
+	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; 
+        }
 
-    rc = BN_set_word(bn.get(), 3);
+	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; 
+}
+
+//private: 
+//	RSA_ptr rsa(RSA_new(), ::RSA_free);
+//	BN_ptr bn(BN_new(), ::BN_free);
+uint32_t generate_rsa_keypair(FILE* fp, std::string& priv_key_str, std::string& pub_key_str) //, uint8_t* hash)
+{
+    int rc; 
+
+    rsa=RSA_new(); 
+    bn=BN_new();
+    rc = BN_set_word(bn, 3);
     if(rc != 1)
       return 0x1;
 
-    rc = RSA_generate_key_ex(rsa.get(), 3072, bn.get(), NULL);
+    rc = RSA_generate_key_ex(rsa, 3072, bn, NULL);
     if(rc != 1)
       return 0x2;
 	printf("Generated key\n"); fflush(stdout); 
@@ -40,9 +81,25 @@ uint32_t generate_rsa_key(std::string& priv_key_str, std::string& pub_key_str)
 //   priv_key_str=std::string(priv_key_der, priv_key_der_encoded_len); //, priv_key_der); 
 //   pub_key_str=std::string(pub_key_der, pub_key_der_encoded_len);  
 */
+//	BIO* bio_rsa;
+    rc = PEM_write_RSA_PUBKEY(fp, rsa); // doesn't work
+    if(rc != 1) 
+	return 0x3;
+    fflush(fp); 
+//    bio_rsa = BIO_new_file("apache_signature_keypair.pem", "w+");
+//    rc = PEM_write_bio_RSAPublicKey(bio_rsa, rsa.get());
+//    if(rc != 1)
+//	return 0x3;
+ //   BIO_flush(bio_rsa); free(bio_rsa); 
+
+  return 0; 
+}
 
+uint32_t generate_rsa_keypair_hash(uint8_t* hash)
+{
+     uint32_t return_internal;
     const BIGNUM* n_internal_bigendian_struct;
-    RSA_get0_key(rsa.get(), &n_internal_bigendian_struct, NULL, NULL);
+    RSA_get0_key(rsa, &n_internal_bigendian_struct, NULL, NULL);
     BIGNUM* n_bigendian_struct = BN_dup(n_internal_bigendian_struct); 
 
     uint32_t count; 
@@ -52,15 +109,110 @@ uint32_t generate_rsa_key(std::string& priv_key_str, std::string& pub_key_str)
     unsigned char* n_littleendian = (unsigned char*) malloc(length_bignum_le);
     for(count=0; count<length_bignum_le; count++)
 		n_littleendian[count] = n_bigendian[length_bignum_le-count-1]; 
-    unsigned char hash[SHA256_DIGEST_LENGTH];
-    SHA256_CTX sha256;
-    SHA256_Init(&sha256);
-    SHA256_Update(&sha256, n_littleendian, length_bignum_le);
-    SHA256_Final(hash, &sha256);
-// TODO: Return hash of the public key for now
-// TODO: Print public key 
-// TODO: Use EVP funs - https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestInit.html
-   free(n_bigendian); free(n_littleendian); 
-   return 0; //length_bignum_le; 
+    free(n_bigendian); 
+//    unsigned char hash[32];  
+    return_internal=generate_sha256_hash(n_littleendian, length_bignum_le, hash);
+    free(n_littleendian); 
+   if(return_internal != 0)
+   { 	 return return_internal ;  }// TODO: Memory leak here. 
+
+	for(count=0;count<32; count++)
+		printf("%x", hash[count]);
+	printf("\n");
+	fflush(stdout); 
+	return return_internal;
+//   return 0; //length_bignum_le; 
+}
+
+void crypto_cleanup()
+{
+	RSA_free(rsa); 
+	BN_free(bn); 
+	EVP_CIPHER_CTX_free(ctx); 
+}
+
+// Code adapted from here: https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption 
+int aes_cipher(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())) { ERR_print_errors_fp(stderr); fflush(stderr);return 0x1; }
+	}
+
+	/* Initialise the encryption operation. */
+	if(1 != EVP_CipherInit_ex(ctx, EVP_aes_128_gcm(), NULL, key, iv, enc))
+	{
+		reset_return = EVP_CIPHER_CTX_reset(ctx);
+		ERR_print_errors_fp(stderr);
+		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);
+                ERR_print_errors_fp(stderr);
+	        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);
+                       ERR_print_errors_fp(stderr); fflush(stderr);
+                       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);
+		ERR_print_errors_fp(stderr); fflush(stderr);
+                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);
+                	ERR_print_errors_fp(stderr); fflush(stderr);
+                	if(1 != reset_return) 
+                        	return 0xF5;
+	                return 0x5;
+		}
+	}
+
+	/* Clean up */
+	if(1 != EVP_CIPHER_CTX_reset(ctx))
+	{
+		ERR_print_errors_fp(stderr); fflush(stderr);
+		return 0xF0; 
+	}
+
+	*op_ciphertext_len=ciphertext_len; 
+	return 0;
 }
 

+ 1 - 1
include/ProtobufLAInitiator.h

@@ -1 +1 @@
-int local_attestation_initiator(int port);
+int local_attestation_initiator(int port); 

+ 1 - 0
include/SgxProtobufLAInitiator.h

@@ -1,2 +1,3 @@
 uint32_t process_protobuf_dh_msg1_generate_protobuf_dh_msg2(protobuf_sgx_dh_msg1_t& protobuf_msg1, protobuf_sgx_dh_msg2_t& protobuf_msg2, uint32_t* session_id);
 uint32_t process_protobuf_dh_msg3(protobuf_sgx_dh_msg3_t& protobuf_msg3, uint32_t* session_id);
+uint32_t generate_encrypted_rsa_keypair_hash();

+ 12 - 1
include/crypto.h

@@ -1 +1,12 @@
-uint32_t generate_rsa_key(std::string& priv_key_str, std::string& pub_key_str);
+//uint32_t generate_rsa_key(std::string& priv_key_str, std::string& pub_key_str);
+//class RSA_signing_keypair 
+//{ 
+//	private:
+//        	RSA_ptr rsa; 
+//        	BN_ptr bn; 
+//	public: 
+//		RSA_signing_keypair(); 
+		uint32_t generate_rsa_keypair(FILE* fp, std::string& priv_key_str, std::string& pub_key_str); //, uint8_t* hash); 
+		uint32_t generate_rsa_keypair_hash(uint8_t* hash);
+//}
+int aes_cipher(int enc, unsigned char *key, unsigned char *iv, unsigned char* plaintext, int plaintext_len, unsigned char *ciphertext,  int* op_ciphertext_len, unsigned char* tag); 

+ 0 - 0
sealed_msg.txt


+ 14 - 7
systemMain.cpp

@@ -6,11 +6,12 @@
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <stdio.h>
 
-
+#include "crypto.h"
 #include "ProtobufLAInitiator.h"
 #include "SealerWrapper.h"
-#include "crypto.h"
+//#include "crypto.h"
 using namespace std;
 
 #define DECRYPTOR_PORT 3825
@@ -21,19 +22,25 @@ int verify_apache(std::string& path, std::string& keypair) {return 0; }
 
 int main(int argc, char** argv)
 {
-  // TODO: Generation of keys used to sign Apache Enclave.
-  uint8_t expected_apache_mr_signer[SGX_HASH_SIZE] = {0x3};
+  uint8_t expected_apache_mr_signer[32] = {0};
   std::string apache_signature_keypair_private("1234567890");
   std::string apache_public_key;
   std::string apache_private_key2; 
-//  generate_rsa_key(apache_public_key, apache_private_key2); 
+//  generate_rsa_keypair(apache_public_key, apache_private_key2); 
 
 //  uint8_t decryptor_mr_enclave[SGX_HASH_SIZE] = {0x1};
 //  uint8_t decryptor_mr_signer[SGX_HASH_SIZE] = {0x2};
   uint32_t return_sgx; uint32_t return_internal;
   std::string recovered_plaintext;
   uint32_t expected_sealed_msg_size=0;
-  return_internal = generate_rsa_key(apache_public_key, apache_private_key2); 
+
+  FILE* fp = fopen("./apache_signature_keypair.pem", "w+");
+  if(fp == NULL)
+ {
+	perror("Could not create the file ./apache_signature_keypair.pem due to error: "); fflush(stderr); return 0xffffffff;
+  }
+//  RSA_signing_keypair rsa_signing_keypair();
+  return_internal = generate_rsa_keypair(fp, apache_public_key, apache_private_key2); //, expected_apache_mr_signer); 
   if(return_internal !=0)
   {
 	printf("Could not generate RSA keypair - error 0x%x\n", return_internal); fflush(stdout); return return_internal; 
@@ -61,7 +68,7 @@ int main(int argc, char** argv)
     fflush(stdout);
     return return_sgx;
   }
-  printf("\n Successfully sealed the plaintext %s to length 0x%x.\n", apache_signature_keypair_private.c_str(), expected_sealed_msg_size);
+  printf("\nSuccessfully sealed the plaintext %s to length 0x%x.\n", apache_signature_keypair_private.c_str(), expected_sealed_msg_size);
   fflush(stdout);
 
   return_sgx = local_attestation_initiator(DECRYPTOR_PORT);

BIN
verifier