|
@@ -40,17 +40,48 @@
|
|
|
#include "sgx_thread.h"
|
|
|
#include "sgx_dh.h"
|
|
|
#include <map>
|
|
|
+#include "sgx_tcrypto.h"
|
|
|
+#include "LocalAttestationCode_t.h"
|
|
|
+#include "sgx_tseal.h"
|
|
|
+
|
|
|
+// internal-internal
|
|
|
+uint32_t create_ecdsa_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_and_sign_mitigator_header_value();
|
|
|
+
|
|
|
+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 create_and_sign_mitigator_header_value();
|
|
|
+uint32_t decrypt_verifiers_message_set_apache_mrsigner(uint8_t* ciphertext, uint8_t* tag);
|
|
|
+uint32_t encrypt_mitigator_header_to_apache(uint8_t* ciphertext, uint8_t* tag);
|
|
|
+
|
|
|
+
|
|
|
+uint32_t one_la_done=0;
|
|
|
+sgx_ec256_public_t short_term_pub_key;
|
|
|
+sgx_ec256_private_t short_term_priv_key;
|
|
|
+sgx_ec256_signature_t generated_signature;
|
|
|
+sgx_measurement_t apache_mr_signer;
|
|
|
+sgx_measurement_t verifier_mr_enclave;
|
|
|
+sgx_ec256_private_t signing_priv_key;
|
|
|
|
|
|
-//#define UNUSED(val) (void)(val)
|
|
|
-//Function that is used to verify the trust of the other enclave
|
|
|
-//Each enclave can have its own way verifying the peer enclave identity
|
|
|
-extern "C" uint32_t verify_peer_enclave_trust(__attribute__((unused)) sgx_dh_session_enclave_identity_t* peer_enclave_identity, sgx_measurement_t* expected_mr_signer)
|
|
|
+extern "C" uint32_t verify_peer_enclave_trust(__attribute__((unused)) sgx_dh_session_enclave_identity_t* peer_enclave_identity)
|
|
|
{
|
|
|
+ uint32_t count;
|
|
|
if(!peer_enclave_identity)
|
|
|
{
|
|
|
return INVALID_PARAMETER_ERROR;
|
|
|
}
|
|
|
- if(expected_mr_signer != NULL) // apache enclave
|
|
|
+ if(one_la_done==0)
|
|
|
+ {
|
|
|
+ for(count=0; count<SGX_HASH_SIZE; count++)
|
|
|
+ verifier_mr_enclave.m[count]=peer_enclave_identity->mr_enclave.m[count];
|
|
|
+ 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
|
|
@@ -58,20 +89,249 @@ extern "C" uint32_t verify_peer_enclave_trust(__attribute__((unused)) sgx_dh_se
|
|
|
int count;
|
|
|
for(count=0; count<SGX_HASH_SIZE; count++)
|
|
|
{
|
|
|
- if( actual_mr_signer.m[count] != expected_mr_signer->m[count] )
|
|
|
- return ENCLAVE_TRUST_ERROR; // TODO: Different error here.
|
|
|
+ if( actual_mr_signer.m[count] != apache_mr_signer.m[count] )
|
|
|
+ return ENCLAVE_TRUST_ERROR;
|
|
|
}
|
|
|
}
|
|
|
return SGX_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+// 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)
|
|
|
+{
|
|
|
+return decrypt(ciphertext, 32, tag, (uint8_t*) &(apache_mr_signer.m));
|
|
|
+// if(mrsigner_decryption_successful !=0)
|
|
|
+// return mrsigner_decryption_successful;
|
|
|
+}
|
|
|
+
|
|
|
+// ciphertext assumed to be at least 64 bytes, tag - at least 16 bytes
|
|
|
+uint32_t encrypt_mitigator_header_to_apache(uint8_t* ciphertext, uint8_t* tag)
|
|
|
+{
|
|
|
+ uint32_t ret_status=create_and_sign_mitigator_header_value();
|
|
|
+ if(ret_status != SGX_SUCCESS)
|
|
|
+ {
|
|
|
+ // printf("Could not generate or sign another keypair for client-side, error:%x.\n", ret_status); fflush(stdout);
|
|
|
+ return 0xFFFFFFDD;
|
|
|
+ }
|
|
|
+
|
|
|
+ // serializing the weird signature string
|
|
|
+ uint8_t mitigator_header_unencrypted[64];
|
|
|
+ uint8_t *current_sig_byte = (uint8_t*)(&(generated_signature.x));
|
|
|
+ uint32_t ecdsa_sig_count;
|
|
|
+ for(ecdsa_sig_count=0;ecdsa_sig_count<32;ecdsa_sig_count++)
|
|
|
+ mitigator_header_unencrypted[ecdsa_sig_count]=*(current_sig_byte+ecdsa_sig_count);
|
|
|
+ current_sig_byte = (uint8_t*)(&(generated_signature.y));
|
|
|
+ for(ecdsa_sig_count=0;ecdsa_sig_count<32;ecdsa_sig_count++)
|
|
|
+ mitigator_header_unencrypted[ecdsa_sig_count+32]=*(current_sig_byte+ecdsa_sig_count);
|
|
|
+
|
|
|
+ ret_status = encrypt_internal(mitigator_header_unencrypted, 64, tag, ciphertext);
|
|
|
+ return ret_status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+uint32_t create_ecdsa_key_pair(sgx_ec256_public_t* pub_key, sgx_ec256_private_t* priv_key)
|
|
|
+{
|
|
|
+ sgx_status_t se_ret; sgx_status_t se_ret2;
|
|
|
+ //create ECC context
|
|
|
+ sgx_ecc_state_handle_t ecc_state = NULL;
|
|
|
+ se_ret = sgx_ecc256_open_context(&ecc_state);
|
|
|
+ if(SGX_SUCCESS != se_ret)
|
|
|
+ return se_ret;
|
|
|
+
|
|
|
+ // generate private key and public key
|
|
|
+ se_ret = sgx_ecc256_create_key_pair(priv_key, pub_key, ecc_state);
|
|
|
+ se_ret2 = sgx_ecc256_close_context(ecc_state);
|
|
|
+
|
|
|
+ if(SGX_SUCCESS != se_ret || se_ret2!= SGX_SUCCESS) // something weird has happened - couldn't shut it down.
|
|
|
+ return 0xFFFFFFFF;
|
|
|
+ return SGX_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+// todo: set to private
|
|
|
+// todo: assumes that the length of the keystring is at least 3*SGX_ECP256_KEY_SIZE
|
|
|
+void serialize_key_pair_to_string(sgx_ec256_public_t* pub_key, sgx_ec256_private_t* signing_priv_key, uint8_t* private_public_key_string)
|
|
|
+{
|
|
|
+ if(private_public_key_string != NULL) // nowhere to serialize to
|
|
|
+ {
|
|
|
+ uint32_t counter;
|
|
|
+ if(pub_key != NULL) // public key to serialize
|
|
|
+ {
|
|
|
+ for(counter=0;counter<SGX_ECP256_KEY_SIZE; counter++)
|
|
|
+ *(private_public_key_string+counter)=pub_key->gx[counter];
|
|
|
+
|
|
|
+ for(counter=SGX_ECP256_KEY_SIZE;counter<2*SGX_ECP256_KEY_SIZE; counter++)
|
|
|
+ *(private_public_key_string+counter)=pub_key->gy[counter-SGX_ECP256_KEY_SIZE];
|
|
|
+ }
|
|
|
+
|
|
|
+ if(signing_priv_key != NULL) // private key to serialize
|
|
|
+ {
|
|
|
+ for(counter=2*SGX_ECP256_KEY_SIZE;counter<3*SGX_ECP256_KEY_SIZE; counter++)
|
|
|
+ *(private_public_key_string+counter)=signing_priv_key->r[counter - 2*SGX_ECP256_KEY_SIZE];
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// todo: set to private
|
|
|
+void deserialize_string_to_key_pair(uint8_t* private_public_key_string, sgx_ec256_public_t* pub_key, sgx_ec256_private_t* signing_priv_key)
|
|
|
+{
|
|
|
+ if(private_public_key_string != NULL) // nowhere to deserialize from
|
|
|
+ {
|
|
|
+ uint32_t counter;
|
|
|
+ if(signing_priv_key != NULL)
|
|
|
+ {
|
|
|
|
|
|
- /* if(peer_enclave_identity->isv_prod_id != 0 || !(peer_enclave_identity->attributes.flags & SGX_FLAGS_INITTED))
|
|
|
+ for(counter=2*SGX_ECP256_KEY_SIZE;counter<3*SGX_ECP256_KEY_SIZE; counter++)
|
|
|
+ signing_priv_key->r[counter-2*SGX_ECP256_KEY_SIZE]=*(private_public_key_string+counter);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(pub_key != NULL)
|
|
|
{
|
|
|
- return ENCLAVE_TRUST_ERROR;
|
|
|
+ for(counter=0;counter<SGX_ECP256_KEY_SIZE; counter++)
|
|
|
+ pub_key->gx[counter]=*(private_public_key_string+counter);
|
|
|
+
|
|
|
+ for(counter=SGX_ECP256_KEY_SIZE;counter<2*SGX_ECP256_KEY_SIZE; counter++)
|
|
|
+ pub_key->gy[counter-SGX_ECP256_KEY_SIZE]=*(private_public_key_string+counter);
|
|
|
}
|
|
|
- else
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+uint32_t create_and_seal_ecdsa_signing_key_pair(__attribute__((unused)) sgx_ec256_public_t* pub_key, __attribute__((unused)) uint32_t* sealed_data_length,
|
|
|
+ __attribute__((unused)) uint8_t* sealed_data)
|
|
|
+{
|
|
|
+ uint32_t ret_status; sgx_ec256_private_t private_key; uint32_t counter;
|
|
|
+ ret_status=create_ecdsa_key_pair(pub_key, &private_key);
|
|
|
+ if(ret_status!=SGX_SUCCESS)
|
|
|
+ return ret_status;
|
|
|
+ for(counter=0;counter<SGX_ECP256_KEY_SIZE; counter++)
|
|
|
+ signing_priv_key.r[counter]=private_key.r[counter];
|
|
|
+ // generating the entire string as there is no SGX function to generate the public key from the private one.
|
|
|
+ uint8_t* private_public_key_string = (uint8_t*) malloc(3*SGX_ECP256_KEY_SIZE);
|
|
|
+ uint8_t* sealed_data2 = (uint8_t*) malloc(*sealed_data_length);
|
|
|
+ // serializing keypair to string
|
|
|
+ serialize_key_pair_to_string(pub_key, &private_key, private_public_key_string);
|
|
|
+ uint8_t* private_key_string = (uint8_t*) malloc(SGX_ECP256_KEY_SIZE);
|
|
|
+ for(counter=0;counter<SGX_ECP256_KEY_SIZE;counter++)
|
|
|
+ *(private_key_string+counter)=private_key.r[counter];
|
|
|
+// return *sealed_data_length;
|
|
|
+ ret_status = sgx_seal_data(0, NULL, 3*SGX_ECP256_KEY_SIZE, private_public_key_string, *sealed_data_length, (sgx_sealed_data_t*) sealed_data2);
|
|
|
+ for(counter=0;counter<*sealed_data_length;counter++)
|
|
|
+ *(sealed_data+counter)=*(sealed_data2+counter);
|
|
|
+ free(sealed_data2);
|
|
|
+ free(private_key_string); //free(private_key);
|
|
|
+ free(private_public_key_string);
|
|
|
+
|
|
|
+ return ret_status; // SGX_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+uint32_t unseal_and_restore_sealed_signing_key_pair(__attribute__((unused)) sgx_ec256_public_t* pub_key, __attribute__((unused)) uint8_t* sealed_data, __attribute__((unused)) uint32_t* sgx_sealed_data_length)
|
|
|
+{
|
|
|
+ return SGX_SUCCESS;
|
|
|
+
|
|
|
+}*/
|
|
|
+
|
|
|
+uint32_t unseal_and_restore_sealed_signing_key_pair(__attribute__((unused)) sgx_ec256_public_t* pub_key, uint8_t* sealed_data, size_t* sgx_sealed_data_length)
|
|
|
+{
|
|
|
+ uint32_t expected_plaintext_msg_length; uint8_t* temp_plaintext; uint32_t counter; uint32_t ret_status;
|
|
|
+ expected_plaintext_msg_length = sgx_get_encrypt_txt_len((sgx_sealed_data_t*)sealed_data);
|
|
|
+ if(expected_plaintext_msg_length == 0xffffffff)
|
|
|
+ return 0xFFFFFFFF;
|
|
|
+
|
|
|
+// uint32_t return_status;
|
|
|
+ uint8_t* sealed_data2 = (uint8_t*) malloc(*sgx_sealed_data_length);
|
|
|
+ for(counter=0;counter<*sgx_sealed_data_length;counter++)
|
|
|
+ {
|
|
|
+ *(sealed_data2+counter)=*(sealed_data+counter);
|
|
|
+ }
|
|
|
+
|
|
|
+ temp_plaintext = (uint8_t*)malloc( expected_plaintext_msg_length );
|
|
|
+ ret_status = sgx_unseal_data((sgx_sealed_data_t*)sealed_data2, NULL, 0, temp_plaintext, &expected_plaintext_msg_length);
|
|
|
+ if(ret_status != SGX_SUCCESS)
|
|
|
+ {
|
|
|
+ free(temp_plaintext);free(sealed_data2);
|
|
|
+ switch(ret_status)
|
|
|
{
|
|
|
- return SUCCESS;
|
|
|
- }*/
|
|
|
-return SUCCESS; //ENCLAVE_TRUST_ERROR;
|
|
|
+ case SGX_ERROR_MAC_MISMATCH:
|
|
|
+ // MAC of the sealed data is incorrect. The sealed data has been tampered.
|
|
|
+ break;
|
|
|
+ case SGX_ERROR_INVALID_ATTRIBUTE:
|
|
|
+ // Indicates attribute field of the sealed data is incorrect.
|
|
|
+ break;
|
|
|
+ case SGX_ERROR_INVALID_ISVSVN:
|
|
|
+ // Indicates isv_svn field of the sealed data is greater than the enclave�s ISVSVN. This is a downgraded enclave.
|
|
|
+ break;
|
|
|
+ case SGX_ERROR_INVALID_CPUSVN:
|
|
|
+ // Indicates cpu_svn field of the sealed data is greater than the platform�s cpu_svn. enclave is on a downgraded platform.
|
|
|
+ break;
|
|
|
+ case SGX_ERROR_INVALID_KEYNAME:
|
|
|
+ // Indicates key_name field of the sealed data is incorrect.
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ // other errors
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return ret_status;
|
|
|
+ }
|
|
|
+
|
|
|
+ deserialize_string_to_key_pair(temp_plaintext, pub_key, &signing_priv_key);
|
|
|
+ free(temp_plaintext); free(sealed_data2);
|
|
|
+ return SGX_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+uint32_t create_and_sign_mitigator_header_value()
|
|
|
+{
|
|
|
+ // 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
|
|
|
+ // TODO: Comment this
|
|
|
+ memset(&(verifier_mr_enclave.m), 0x01, 32);
|
|
|
+
|
|
|
+ // create key pair
|
|
|
+ uint32_t ret_status = create_ecdsa_key_pair(&short_term_pub_key, &short_term_priv_key); uint32_t counter;
|
|
|
+ uint32_t ret_status2;
|
|
|
+ if(ret_status!=SGX_SUCCESS)
|
|
|
+ return ret_status;
|
|
|
+ // serialize public key, append mr_enclave
|
|
|
+ uint8_t* public_key_string = (uint8_t*) malloc(3*SGX_ECP256_KEY_SIZE); // for .edl file - size parameter for serialize is 96 and this fits coz we need to append the mr_enclave to the pub key
|
|
|
+ serialize_key_pair_to_string(&short_term_pub_key, NULL, public_key_string);
|
|
|
+ for(counter=32*2; counter<32*3; counter++) // appending mr_enclave
|
|
|
+ *(public_key_string+counter)=verifier_mr_enclave.m[counter];
|
|
|
+ // retrieve long-term private key from global variable - apparently, need to create a local copy or it crashes
|
|
|
+ sgx_ec256_private_t long_term_priv_key;
|
|
|
+ for(counter=0; counter<SGX_ECP256_KEY_SIZE; counter++)
|
|
|
+ long_term_priv_key.r[counter] = signing_priv_key.r[counter];
|
|
|
+ // sign public key with long-term private key
|
|
|
+ sgx_ec256_signature_t local_signature; sgx_ecc_state_handle_t ecc_handle;
|
|
|
+ //// opening context for signature
|
|
|
+ ret_status = sgx_ecc256_open_context(&ecc_handle);
|
|
|
+ if(ret_status != SGX_SUCCESS)
|
|
|
+ return ret_status;
|
|
|
+ ret_status = sgx_ecdsa_sign(public_key_string,2*SGX_ECP256_KEY_SIZE, &long_term_priv_key, &local_signature, ecc_handle);
|
|
|
+ ret_status2 = sgx_ecc256_close_context(ecc_handle);
|
|
|
+ free(public_key_string);
|
|
|
+ if(ret_status == SGX_SUCCESS)
|
|
|
+ {
|
|
|
+ for(counter=0;counter<SGX_NISTP_ECP256_KEY_SIZE/sizeof(uint32_t); counter++)
|
|
|
+ {
|
|
|
+ generated_signature.x[counter] = local_signature.x[counter];
|
|
|
+ generated_signature.y[counter] = local_signature.y[counter];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(ret_status != SGX_SUCCESS || ret_status2 != SGX_SUCCESS)
|
|
|
+ return 0xFFFFFFFF;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+uint32_t calculate_sealed_data_size( uint32_t input_size)
|
|
|
+{
|
|
|
+// *op_size=sgx_calc_sealed_data_size(0, input_size);
|
|
|
+ return sgx_calc_sealed_data_size(0, input_size);
|
|
|
+
|
|
|
}
|
|
|
|