This is an old revision of the document!
#include <stdio.h>
#include <sys/types.h> /* open */
#include <sys/stat.h> /* open */
#include <fcntl.h> /* O_CREAT, O_RDONLY */
#include <unistd.h> /* close, lseek, read, write */
#include "Enclave_u.h"
#include "sgx_urts.h"
#include "sgx_utils/sgx_utils.h"
/* Global Enclave ID */
sgx_enclave_id_t global_eid;
/* OCall implementations */
void ocall_print(const char* str) {
printf("%s\n", str);
}
void ocall_write_file(const char* filename, const char* buf, size_t buf_len) {
int fd;
ssize_t wr_bytes;
fd = open(filename, O_RDWR | O_CREAT, 0644);
wr_bytes = write(fd, buf, buf_len);
close(fd);
}
void ocall_read_file(const char* filename, char* buf, size_t buf_len) {
int fd;
ssize_t no_bytes;
fd = open(filename, O_RDWR | O_CREAT, 0644);
no_bytes = read(fd, buf, buf_len);
buf[no_bytes] = '\0';
close(fd);
}
int main(int argc, char const *argv[]) {
int sum_result;
unsigned int rand_no;
sgx_status_t status;
/* Enclave Initialization */
if (initialize_enclave(&global_eid, "enclave.token", "enclave.signed.so") < 0) {
printf("Fail to initialize enclave.\n");
return 1;
}
/* Call a simple method inside enclave */
status = get_sum(global_eid, &sum_result, 3, 4);
if (status != SGX_SUCCESS) {
printf("ECall failed.\n");
return 1;
}
printf("Sum from enclave: %d\n", sum_result);
seal_secret(global_eid);
unseal_secret(global_eid);
/* TODO: Using an ECALL that generates a random unsigned int,
get a random number between 3 and 42. */
status = generate_random_number(global_eid, &rand_no);
printf("Rand no from enclave: %u\n", rand_no);
return 0;
}
#include "sgx_trts.h"
#include "sgx_tseal.h"
#include "string.h"
#include "Enclave_t.h"
#include<stdio.h>
#define SECRET_FILE "enclave_secret"
int get_sum(int a, int b) {
/* TODO: Call OCALL that prints a debug message */
return a + b;
}
void printf(const char *fmt, ...)
{
char buf[BUFSIZ] = {'\0'};
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, BUFSIZ, fmt, ap);
va_end(ap);
ocall_print(buf);
}
unsigned int generate_random_number() {
unsigned int rand_number = 0;
sgx_status_t status = sgx_read_rand((unsigned char*)(&rand_number), sizeof(rand_number));
if (SGX_SUCCESS != status) {
return -42;
}
return rand_number%42 + 1;
}
void unseal_secret(){
char sealed_data[1024];
char secret[1024];
uint32_t text_size = sizeof(secret);
ocall_read_file(SECRET_FILE, sealed_data, text_size);
sgx_unseal_data((sgx_sealed_data_t *)sealed_data, NULL, NULL, (uint8_t*)secret, &text_size);
printf("Unsealed secret: %s\n", secret);
}
void seal_secret() {
char* secret = (char*)malloc(10);
sgx_status_t status = sgx_read_rand((unsigned char*)secret, sizeof(secret));
printf("Generated secret: %s\n", secret);
uint32_t text_size = sizeof(secret);
uint32_t sealed_size = sgx_calc_sealed_data_size(0,text_size);
sgx_sealed_data_t *sealed_data = (sgx_sealed_data_t *)malloc(sealed_size);
sgx_seal_data(0, NULL, text_size, (uint8_t*)secret, sealed_size, sealed_data);
ocall_write_file(SECRET_FILE, (char *)sealed_data, sealed_size);
}
enclave {
//from "Sealing/Sealing.edl" import *;
trusted {
/* define ECALLs here. */
public int get_sum(int a, int b);
public unsigned int generate_random_number(void);
public void seal_secret(void);
public void unseal_secret(void);
};
untrusted {
/* define OCALLs here. */
void ocall_print([in, string]const char* str);
void ocall_write_file([in, string]const char* filename, [in, size=buf_len]const char* buf, size_t buf_len);
void ocall_read_file([in, string]const char* filename, [out, size=buf_len]char* buf, size_t buf_len);
};
};
#include <cstdio>
#include <cstring>
#include "sgx_urts.h"
#include "sgx_utils.h"
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
/* Check error conditions for loading enclave */
void print_error_message(sgx_status_t ret) {
printf("SGX error code: %d\n", ret);
}
/* Initialize the enclave:
* Step 1: try to retrieve the launch token saved by last transaction
* Step 2: call sgx_create_enclave to initialize an enclave instance
* Step 3: save the launch token if it is updated
*/
int initialize_enclave(sgx_enclave_id_t* eid, const std::string& launch_token_path, const std::string& enclave_name) {
const char* token_path = launch_token_path.c_str();
sgx_launch_token_t token = {0};
sgx_status_t ret = SGX_ERROR_UNEXPECTED;
int updated = 0;
/* Step 1: try to retrieve the launch token saved by last transaction
* if there is no token, then create a new one.
*/
/* try to get the token saved in $HOME */
FILE* fp = fopen(token_path, "rb");
if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
}
if (fp != NULL) {
/* read the token from saved file */
size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
/* if token is invalid, clear the buffer */
memset(&token, 0x0, sizeof(sgx_launch_token_t));
printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
}
}
/* Step 2: call sgx_create_enclave to initialize an enclave instance */
/* Debug Support: set 2nd parameter to 1 */
ret = sgx_create_enclave(enclave_name.c_str(), SGX_DEBUG_FLAG, &token, &updated, eid, NULL);
if (ret != SGX_SUCCESS) {
print_error_message(ret);
if (fp != NULL) fclose(fp);
return -1;
}
/* Step 3: save the launch token if it is updated */
if (updated == FALSE || fp == NULL) {
/* if the token is not updated, or file handler is invalid, do not perform saving */
if (fp != NULL) fclose(fp);
return 0;
}
/* reopen the file with write capablity */
fp = freopen(token_path, "wb", fp);
if (fp == NULL) return 0;
size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
if (write_num != sizeof(sgx_launch_token_t))
printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
fclose(fp);
return 0;
}
bool is_ecall_successful(sgx_status_t sgx_status, const std::string& err_msg,
sgx_status_t ecall_return_value) {
if (sgx_status != SGX_SUCCESS || ecall_return_value != SGX_SUCCESS) {
printf("%s\n", err_msg.c_str());
print_error_message(sgx_status);
print_error_message(ecall_return_value);
return false;
}
return true;
}