Files
intel-linux-sgx/SampleCode/SealUnseal/App/App.cpp
Li, Xun 4589daddd5 Linux 2.9 Open Source Gold Release
Fixed bugs.

Signed-off-by: Li, Xun <xun.li@intel.com>
2020-03-10 12:47:50 +08:00

270 lines
7.9 KiB
C++

/*
* Copyright (C) 2011-2020 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.
*
*/
// App.cpp : Define the entry point for the console application.
//
#include <string.h>
#include <assert.h>
#include <fstream>
#include <thread>
#include <iostream>
#include "sgx_urts.h"
#include "Enclave_Seal_u.h"
#include "Enclave_Unseal_u.h"
#include "ErrorSupport.h"
#define ENCLAVE_NAME_SEAL "libenclave_seal.signed.so"
#define ENCLAVE_NAME_UNSEAL "libenclave_unseal.signed.so"
#define SEALED_DATA_FILE "sealed_data_blob.txt"
static size_t get_file_size(const char *filename)
{
std::ifstream ifs(filename, std::ios::in | std::ios::binary);
if (!ifs.good())
{
std::cout << "Failed to open the file \"" << filename << "\"" << std::endl;
return -1;
}
ifs.seekg(0, std::ios::end);
size_t size = (size_t)ifs.tellg();
return size;
}
static bool read_file_to_buf(const char *filename, uint8_t *buf, size_t bsize)
{
if (filename == NULL || buf == NULL || bsize == 0)
return false;
std::ifstream ifs(filename, std::ios::binary | std::ios::in);
if (!ifs.good())
{
std::cout << "Failed to open the file \"" << filename << "\"" << std::endl;
return false;
}
ifs.read(reinterpret_cast<char *> (buf), bsize);
if (ifs.fail())
{
std::cout << "Failed to read the file \"" << filename << "\"" << std::endl;
return false;
}
return true;
}
static bool write_buf_to_file(const char *filename, const uint8_t *buf, size_t bsize, long offset)
{
if (filename == NULL || buf == NULL || bsize == 0)
return false;
std::ofstream ofs(filename, std::ios::binary | std::ios::out);
if (!ofs.good())
{
std::cout << "Failed to open the file \"" << filename << "\"" << std::endl;
return false;
}
ofs.seekp(offset, std::ios::beg);
ofs.write(reinterpret_cast<const char*>(buf), bsize);
if (ofs.fail())
{
std::cout << "Failed to write the file \"" << filename << "\"" << std::endl;
return false;
}
return true;
}
/* Initialize the enclave:
* Call sgx_create_enclave to initialize an enclave instance
*/
static sgx_status_t initialize_enclave(const char* enclave_path, sgx_enclave_id_t *eid)
{
sgx_status_t ret = SGX_ERROR_UNEXPECTED;
/* Call sgx_create_enclave to initialize an enclave instance */
/* Debug Support: set 2nd parameter to 1 */
ret = sgx_create_enclave(enclave_path, SGX_DEBUG_FLAG, NULL, NULL, eid, NULL);
if (ret != SGX_SUCCESS) {
return ret;
}
return SGX_SUCCESS;
}
static bool seal_and_save_data()
{
sgx_enclave_id_t eid_seal = 0;
// Load the enclave for sealing
sgx_status_t ret = initialize_enclave(ENCLAVE_NAME_SEAL, &eid_seal);
if (ret != SGX_SUCCESS)
{
ret_error_support(ret);
return false;
}
// Get the sealed data size
uint32_t sealed_data_size = 0;
ret = get_sealed_data_size(eid_seal, &sealed_data_size);
if (ret != SGX_SUCCESS)
{
ret_error_support(ret);
sgx_destroy_enclave(eid_seal);
return false;
}
else if(sealed_data_size == UINT32_MAX)
{
sgx_destroy_enclave(eid_seal);
return false;
}
uint8_t *temp_sealed_buf = (uint8_t *)malloc(sealed_data_size);
if(temp_sealed_buf == NULL)
{
std::cout << "Out of memory" << std::endl;
sgx_destroy_enclave(eid_seal);
return false;
}
sgx_status_t retval;
ret = seal_data(eid_seal, &retval, temp_sealed_buf, sealed_data_size);
if (ret != SGX_SUCCESS)
{
ret_error_support(ret);
free(temp_sealed_buf);
sgx_destroy_enclave(eid_seal);
return false;
}
else if( retval != SGX_SUCCESS)
{
ret_error_support(retval);
free(temp_sealed_buf);
sgx_destroy_enclave(eid_seal);
return false;
}
// Save the sealed blob
if (write_buf_to_file(SEALED_DATA_FILE, temp_sealed_buf, sealed_data_size, 0) == false)
{
std::cout << "Failed to save the sealed data blob to \"" << SEALED_DATA_FILE << "\"" << std::endl;
free(temp_sealed_buf);
sgx_destroy_enclave(eid_seal);
return false;
}
free(temp_sealed_buf);
sgx_destroy_enclave(eid_seal);
std::cout << "Sealing data succeeded." << std::endl;
return true;
}
static bool read_and_unseal_data()
{
sgx_enclave_id_t eid_unseal = 0;
// Load the enclave for unsealing
sgx_status_t ret = initialize_enclave(ENCLAVE_NAME_UNSEAL, &eid_unseal);
if (ret != SGX_SUCCESS)
{
ret_error_support(ret);
return false;
}
// Read the sealed blob from the file
size_t fsize = get_file_size(SEALED_DATA_FILE);
if (fsize == (size_t)-1)
{
std::cout << "Failed to get the file size of \"" << SEALED_DATA_FILE << "\"" << std::endl;
sgx_destroy_enclave(eid_unseal);
return false;
}
uint8_t *temp_buf = (uint8_t *)malloc(fsize);
if(temp_buf == NULL)
{
std::cout << "Out of memory" << std::endl;
sgx_destroy_enclave(eid_unseal);
return false;
}
if (read_file_to_buf(SEALED_DATA_FILE, temp_buf, fsize) == false)
{
std::cout << "Failed to read the sealed data blob from \"" << SEALED_DATA_FILE << "\"" << std::endl;
free(temp_buf);
sgx_destroy_enclave(eid_unseal);
return false;
}
// Unseal the sealed blob
sgx_status_t retval;
ret = unseal_data(eid_unseal, &retval, temp_buf, fsize);
if (ret != SGX_SUCCESS)
{
ret_error_support(ret);
free(temp_buf);
sgx_destroy_enclave(eid_unseal);
return false;
}
else if(retval != SGX_SUCCESS)
{
ret_error_support(retval);
free(temp_buf);
sgx_destroy_enclave(eid_unseal);
return false;
}
free(temp_buf);
sgx_destroy_enclave(eid_unseal);
std::cout << "Unseal succeeded." << std::endl;
return true;
}
int main(int argc, char* argv[])
{
(void)argc, (void)argv;
// Enclave_Seal: seal the secret and save the data blob to a file
if (seal_and_save_data() == false)
{
std::cout << "Failed to seal the secret and save it to a file." << std::endl;
return -1;
}
// Enclave_Unseal: read the data blob from the file and unseal it.
if (read_and_unseal_data() == false)
{
std::cout << "Failed to unseal the data blob." << std::endl;
return -1;
}
return 0;
}