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; }