├── .gitignore ├── App ├── App.cpp └── ocalls.c ├── Enclave ├── Enclave.config.xml ├── Enclave.cpp ├── Enclave.edl ├── Enclave.lds ├── Enclave_private.pem ├── ocall_interface.c ├── sqlite3.c └── sqlite3.h ├── LICENSE ├── Makefile ├── README.md └── ocall_types.h /.gitignore: -------------------------------------------------------------------------------- 1 | .config_* 2 | 3 | app 4 | 5 | enclave.so 6 | enclave.signed.so 7 | 8 | App/App.o 9 | App/ocalls.o 10 | App/Enclave_u.* 11 | 12 | Enclave/Enclave.o 13 | Enclave/sqlite3.o 14 | Enclave/sqlite3.i 15 | Enclave/ocall_interface.o 16 | Enclave/ocall_interface.i 17 | Enclave/Enclave_t.* 18 | 19 | test.db 20 | test.db-journal 21 | -------------------------------------------------------------------------------- /App/App.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "sgx_urts.h" 4 | #include "Enclave_u.h" // Headers for untrusted part (autogenerated by edger8r) 5 | 6 | using namespace std; 7 | 8 | # define MAX_PATH FILENAME_MAX 9 | # define ENCLAVE_FILENAME "enclave.signed.so" 10 | 11 | // ocalls for printing string (C++ ocalls) 12 | void ocall_print_error(const char *str){ 13 | cerr << str << endl; 14 | } 15 | 16 | void ocall_print_string(const char *str){ 17 | cout << str; 18 | } 19 | 20 | void ocall_println_string(const char *str){ 21 | cout << str << endl; 22 | } 23 | 24 | // Application entry 25 | int main(int argc, char *argv[]){ 26 | if ( argc != 2 ){ 27 | cout << "Usage: " << argv[0] << " " << endl; 28 | return -1; 29 | } 30 | const char* dbname = argv[1]; 31 | 32 | sgx_enclave_id_t eid = 0; 33 | char token_path[MAX_PATH] = {'\0'}; 34 | sgx_launch_token_t token = {0}; 35 | sgx_status_t ret = SGX_ERROR_UNEXPECTED; // status flag for enclave calls 36 | int updated = 0; 37 | 38 | // Initialize the enclave 39 | ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &eid, NULL); 40 | if (ret != SGX_SUCCESS) { 41 | cerr << "Error: creating enclave" << endl; 42 | return -1; 43 | } 44 | cout << "Info: SQLite SGX enclave successfully created." << endl; 45 | 46 | 47 | // Open SQLite database 48 | ret = ecall_opendb(eid, dbname); 49 | if (ret != SGX_SUCCESS) { 50 | cerr << "Error: Making an ecall_open()" << endl; 51 | return -1; 52 | } 53 | 54 | cout << "Enter SQL statement to execute or 'quit' to exit: " << endl; 55 | string input; 56 | cout << "> "; 57 | while(getline(cin, input)) { 58 | if (input == "quit"){ 59 | break; 60 | } 61 | const char* sql = input.c_str(); 62 | ret = ecall_execute_sql(eid, sql); 63 | if (ret != SGX_SUCCESS) { 64 | cerr << "Error: Making an ecall_execute_sql()" << endl; 65 | return -1; 66 | } 67 | cout << "> "; 68 | } 69 | 70 | // Closing SQLite database inside enclave 71 | ret = ecall_closedb(eid); 72 | if (ret != SGX_SUCCESS) { 73 | cerr << "Error: Making an ecall_closedb()" << endl; 74 | return -1; 75 | } 76 | 77 | // Destroy the enclave 78 | sgx_destroy_enclave(eid); 79 | if (ret != SGX_SUCCESS) { 80 | cerr << "Error: destroying enclave" << endl; 81 | return -1; 82 | } 83 | 84 | cout << "Info: SQLite SGX enclave successfully returned." << endl; 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /App/ocalls.c: -------------------------------------------------------------------------------- 1 | // This is a real implementation of ocalls 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int ocall_lstat(const char *path, struct stat* buf){ 10 | //printf("Entering %s\n", __func__); 11 | return lstat(path, buf); 12 | } 13 | 14 | int ocall_stat(const char *path, struct stat* buf){ 15 | //printf("Entering %s\n", __func__); 16 | return stat(path, buf); 17 | } 18 | 19 | int ocall_fstat(int fd, struct stat* buf){ 20 | //printf("Entering %s\n", __func__); 21 | return fstat(fd, buf); 22 | } 23 | 24 | int ocall_ftruncate(int fd, off_t length){ 25 | //printf("Entering %s\n", __func__); 26 | return ftruncate(fd, length); 27 | } 28 | 29 | char* ocall_getcwd(char *buf, size_t size){ 30 | //printf("Entering %s\n", __func__); 31 | return getcwd(buf, size); 32 | } 33 | 34 | int ocall_getpid(void){ 35 | //printf("Entering %s\n", __func__); 36 | return getpid(); 37 | } 38 | 39 | int ocall_open64(const char *filename, int flags, mode_t mode){ 40 | //printf("Entering %s\n", __func__); 41 | return open(filename, flags, mode); // redirect it to open() instead of open64() 42 | } 43 | 44 | off_t ocall_lseek64(int fd, off_t offset, int whence){ 45 | //printf("Entering %s\n", __func__); 46 | return lseek(fd, offset, whence); // redirect it to lseek() instead of lseek64() 47 | } 48 | 49 | int ocall_read(int fd, void *buf, size_t count){ 50 | //printf("Entering %s\n", __func__); 51 | return read(fd, buf, count); 52 | } 53 | 54 | int ocall_write(int fd, const void *buf, size_t count){ 55 | //printf("Entering %s\n", __func__); 56 | return write(fd, buf, count); 57 | } 58 | 59 | int ocall_fcntl(int fd, int cmd, void* arg, size_t size){ 60 | //printf("Entering %s\n", __func__); 61 | return fcntl(fd, cmd, arg); 62 | } 63 | 64 | int ocall_close(int fd){ 65 | //printf("Entering %s\n", __func__); 66 | return close(fd); 67 | } 68 | 69 | int ocall_unlink(const char *pathname){ 70 | //printf("Entering %s\n", __func__); 71 | return unlink(pathname); 72 | } 73 | 74 | int ocall_getuid(void){ 75 | //printf("Entering %s\n", __func__); 76 | return getuid(); 77 | } 78 | 79 | char* ocall_getenv(const char *name){ 80 | //printf("Entering %s\n", __func__); 81 | return getenv(name); 82 | } 83 | 84 | int ocall_fsync(int fd){ 85 | //printf("Entering %s\n", __func__); 86 | return fsync(fd); 87 | } 88 | -------------------------------------------------------------------------------- /Enclave/Enclave.config.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 0x40000 5 | 0x100000 6 | 10 7 | 1 8 | 9 | 0 10 | 0 11 | 0xFFFFFFFF 12 | 13 | -------------------------------------------------------------------------------- /Enclave/Enclave.cpp: -------------------------------------------------------------------------------- 1 | #include "Enclave_t.h" // Headers for trusted part (autogenerated by edger8r) 2 | #include "sqlite3.h" 3 | #include 4 | 5 | sqlite3* db; // Database connection object 6 | 7 | // SQLite callback function for printing results 8 | static int callback(void *NotUsed, int argc, char **argv, char **azColName){ 9 | int i; 10 | for(i = 0; i < argc; i++){ 11 | std::string azColName_str = azColName[i]; 12 | std::string argv_str = (argv[i] ? argv[i] : "NULL"); 13 | ocall_print_string((azColName_str + " = " + argv_str + "\n").c_str()); 14 | } 15 | ocall_print_string("\n"); 16 | return 0; 17 | } 18 | 19 | void ecall_opendb(const char *dbname){ 20 | int rc; // For return status of SQLite 21 | rc = sqlite3_open(dbname, &db); // Opening database 22 | if (rc) { 23 | ocall_println_string("SQLite error - can't open database connection: "); 24 | ocall_println_string(sqlite3_errmsg(db)); 25 | return; 26 | } 27 | ocall_print_string("Enclave: Created database connection to "); 28 | ocall_println_string(dbname); 29 | } 30 | 31 | void ecall_execute_sql(const char *sql){ 32 | int rc; 33 | char *zErrMsg = 0; 34 | rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 35 | if (rc) { 36 | ocall_print_string("SQLite error: "); 37 | ocall_println_string(sqlite3_errmsg(db)); 38 | return; 39 | } 40 | } 41 | 42 | void ecall_closedb(){ 43 | sqlite3_close(db); 44 | ocall_println_string("Enclave: Closed database connection"); 45 | } 46 | -------------------------------------------------------------------------------- /Enclave/Enclave.edl: -------------------------------------------------------------------------------- 1 | enclave { 2 | from "sgx_tstdc.edl" import *; 3 | include "../ocall_types.h" // Need to import some type declartions from stdlib 4 | 5 | trusted { 6 | public void ecall_opendb([in, string] const char *dbname); // open SQLite connection to dbname 7 | public void ecall_execute_sql([in, string] const char *sql); // Execute SQL statement inside enclave 8 | public void ecall_closedb(void); // close SQLite db connection 9 | }; 10 | 11 | untrusted { 12 | void ocall_println_string([in, string] const char *str); 13 | void ocall_print_string([in, string] const char *str); 14 | void ocall_print_error([in, string] const char *str); 15 | 16 | int ocall_lstat([in, string] const char *path, [in, out, size=size] struct stat *buf, size_t size) propagate_errno; 17 | int ocall_stat([in, string] const char *path, [in, out, size=size] struct stat *buf, size_t size); 18 | int ocall_fstat(int fd, [in, out, size=size] struct stat* buf, size_t size); 19 | int ocall_ftruncate(int fd, off_t length); 20 | 21 | char* ocall_getcwd([out, size=size] char *buf, size_t size) propagate_errno; 22 | int ocall_getpid(void); 23 | int ocall_getuid(void); 24 | char* ocall_getenv([in, string] const char *name); 25 | 26 | int ocall_open64([in, string] const char *filename, int flags, mode_t mode); 27 | int ocall_close(int fd); 28 | off_t ocall_lseek64(int fd, off_t offset, int whence) propagate_errno; 29 | int ocall_read(int fd, [out, size=count] void *buf, size_t count) propagate_errno; 30 | int ocall_write(int fd, [in, size=count] const void *buf, size_t count) propagate_errno; 31 | int ocall_fsync(int fd); 32 | int ocall_fcntl(int fd, int cmd, [in, size=size] void* arg, size_t size) propagate_errno; 33 | int ocall_unlink([in, string] const char *pathname); 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /Enclave/Enclave.lds: -------------------------------------------------------------------------------- 1 | enclave.so 2 | { 3 | global: 4 | g_global_data_sim; 5 | g_global_data; 6 | enclave_entry; 7 | g_peak_heap_used; 8 | local: 9 | *; 10 | }; 11 | -------------------------------------------------------------------------------- /Enclave/Enclave_private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | 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 39 | -----END RSA PRIVATE KEY----- 40 | -------------------------------------------------------------------------------- /Enclave/ocall_interface.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include // for variable arguments functions 7 | #include 8 | #include 9 | 10 | // At this point we have already definitions needed for ocall interface, so: 11 | #define DO_NOT_REDEFINE_FOR_OCALL 12 | #include "Enclave_t.h" 13 | 14 | // For open64 need to define this 15 | #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) 16 | 17 | long int sysconf(int name){ 18 | char error_msg[256]; 19 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 20 | ocall_print_error(error_msg); 21 | return 0; 22 | } 23 | 24 | int open64(const char *filename, int flags, ...){ 25 | mode_t mode = 0; // file permission bitmask 26 | 27 | // Get the mode_t from arguments 28 | if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) { 29 | va_list valist; 30 | va_start(valist, flags); 31 | mode = va_arg(valist, mode_t); 32 | va_end(valist); 33 | } 34 | 35 | int ret; 36 | sgx_status_t status = ocall_open64(&ret, filename, flags, mode); 37 | if (status != SGX_SUCCESS) { 38 | char error_msg[256]; 39 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 40 | ocall_print_error(error_msg); 41 | } 42 | return ret; 43 | } 44 | 45 | off_t lseek64(int fd, off_t offset, int whence){ 46 | off_t ret; 47 | sgx_status_t status = ocall_lseek64(&ret, fd, offset, whence); 48 | if (status != SGX_SUCCESS) { 49 | char error_msg[256]; 50 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 51 | ocall_print_error(error_msg); 52 | } 53 | return ret; 54 | } 55 | 56 | int gettimeofday(struct timeval *tv, struct timezone *tz){ 57 | char error_msg[256]; 58 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 59 | ocall_print_error(error_msg); 60 | return 0; 61 | } 62 | 63 | unsigned int sleep(unsigned int seconds){ 64 | char error_msg[256]; 65 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 66 | ocall_print_error(error_msg); 67 | return 0; 68 | } 69 | 70 | void *dlopen(const char *filename, int flag){ 71 | char error_msg[256]; 72 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 73 | ocall_print_error(error_msg); 74 | } 75 | 76 | char *dlerror(void){ 77 | char error_msg[256]; 78 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 79 | ocall_print_error(error_msg); 80 | return 0; 81 | } 82 | 83 | void *dlsym(void *handle, const char *symbol){ 84 | char error_msg[256]; 85 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 86 | ocall_print_error(error_msg); 87 | 88 | } 89 | 90 | int dlclose(void *handle){ 91 | char error_msg[256]; 92 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 93 | ocall_print_error(error_msg); 94 | return 0; 95 | } 96 | 97 | int utimes(const char *filename, const struct timeval times[2]){ 98 | char error_msg[256]; 99 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 100 | ocall_print_error(error_msg); 101 | return 0; 102 | } 103 | 104 | struct tm *localtime(const time_t *timep){ 105 | char error_msg[256]; 106 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 107 | ocall_print_error(error_msg); 108 | return 0; 109 | } 110 | 111 | pid_t getpid(void){ 112 | int ret; 113 | sgx_status_t status = ocall_getpid(&ret); 114 | if (status != SGX_SUCCESS) { 115 | char error_msg[256]; 116 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 117 | ocall_print_error(error_msg); 118 | } 119 | return ret; 120 | } 121 | 122 | int fsync(int fd){ 123 | int ret; 124 | sgx_status_t status = ocall_fsync(&ret, fd); 125 | if (status != SGX_SUCCESS) { 126 | char error_msg[256]; 127 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 128 | ocall_print_error(error_msg); 129 | } 130 | return ret; 131 | } 132 | 133 | time_t time(time_t *t){ 134 | char error_msg[256]; 135 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 136 | ocall_print_error(error_msg); 137 | return 0; 138 | } 139 | 140 | int close(int fd){ 141 | int ret; 142 | sgx_status_t status = ocall_close(&ret, fd); 143 | if (status != SGX_SUCCESS) { 144 | char error_msg[256]; 145 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 146 | ocall_print_error(error_msg); 147 | } 148 | return ret; 149 | } 150 | 151 | int access(const char *pathname, int mode){ 152 | char error_msg[256]; 153 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 154 | ocall_print_error(error_msg); 155 | return 0; 156 | } 157 | 158 | char *getcwd(char *buf, size_t size){ 159 | char* ret; 160 | sgx_status_t status = ocall_getcwd(&ret, buf, size); 161 | if (status != SGX_SUCCESS) { 162 | char error_msg[256]; 163 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 164 | ocall_print_error(error_msg); 165 | } 166 | return ret; 167 | } 168 | 169 | int sgx_lstat(const char *path, struct stat *buf){ 170 | int ret; 171 | sgx_status_t status = ocall_lstat(&ret, path, buf, sizeof(struct stat)); 172 | if (status != SGX_SUCCESS) { 173 | char error_msg[256]; 174 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 175 | ocall_print_error(error_msg); 176 | } 177 | return ret; 178 | } 179 | 180 | int sgx_stat(const char *path, struct stat *buf){ 181 | int ret; 182 | sgx_status_t status = ocall_stat(&ret, path, buf, sizeof(struct stat)); 183 | if (status != SGX_SUCCESS) { 184 | char error_msg[256]; 185 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 186 | ocall_print_error(error_msg); 187 | } 188 | return ret; 189 | } 190 | 191 | int sgx_fstat(int fd, struct stat *buf){ 192 | int ret; 193 | sgx_status_t status = ocall_fstat(&ret, fd, buf, sizeof(struct stat)); 194 | if (status != SGX_SUCCESS) { 195 | char error_msg[256]; 196 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 197 | ocall_print_error(error_msg); 198 | } 199 | return ret; 200 | } 201 | 202 | int sgx_ftruncate(int fd, off_t length){ 203 | int ret; 204 | sgx_status_t status = ocall_ftruncate(&ret, fd, length); 205 | if (status != SGX_SUCCESS) { 206 | char error_msg[256]; 207 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 208 | ocall_print_error(error_msg); 209 | } 210 | return ret; 211 | } 212 | 213 | int fcntl(int fd, int cmd, ... /* arg */ ){ 214 | // Read one argument 215 | va_list valist; 216 | va_start(valist, cmd); 217 | void* arg = va_arg(valist, void*); 218 | va_end(valist); 219 | 220 | int ret; 221 | sgx_status_t status = ocall_fcntl(&ret, fd, cmd, arg, sizeof(void*)); 222 | if (status != SGX_SUCCESS) { 223 | char error_msg[256]; 224 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 225 | ocall_print_error(error_msg); 226 | } 227 | return ret; 228 | } 229 | 230 | ssize_t read(int fd, void *buf, size_t count){ 231 | int ret; 232 | sgx_status_t status = ocall_read(&ret, fd, buf, count); 233 | if (status != SGX_SUCCESS) { 234 | char error_msg[256]; 235 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 236 | ocall_print_error(error_msg); 237 | } 238 | return (ssize_t)ret; 239 | } 240 | 241 | ssize_t write(int fd, const void *buf, size_t count){ 242 | int ret; 243 | sgx_status_t status = ocall_write(&ret, fd, buf, count); 244 | if (status != SGX_SUCCESS) { 245 | char error_msg[256]; 246 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 247 | ocall_print_error(error_msg); 248 | } 249 | return (ssize_t)ret; 250 | } 251 | 252 | int fchmod(int fd, mode_t mode){ 253 | char error_msg[256]; 254 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 255 | ocall_print_error(error_msg); 256 | return 0; 257 | } 258 | 259 | int unlink(const char *pathname){ 260 | int ret; 261 | sgx_status_t status = ocall_unlink(&ret, pathname); 262 | if (status != SGX_SUCCESS) { 263 | char error_msg[256]; 264 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 265 | ocall_print_error(error_msg); 266 | } 267 | return ret; 268 | } 269 | 270 | int mkdir(const char *pathname, mode_t mode) { 271 | char error_msg[256]; 272 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 273 | ocall_print_error(error_msg); 274 | return 0; 275 | } 276 | 277 | int rmdir(const char *pathname){ 278 | char error_msg[256]; 279 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 280 | ocall_print_error(error_msg); 281 | return 0; 282 | } 283 | 284 | int fchown(int fd, uid_t owner, gid_t group){ 285 | char error_msg[256]; 286 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 287 | ocall_print_error(error_msg); 288 | return 0; 289 | } 290 | 291 | uid_t geteuid(void){ 292 | int ret; 293 | sgx_status_t status = ocall_getuid(&ret); 294 | if (status != SGX_SUCCESS) { 295 | char error_msg[256]; 296 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 297 | ocall_print_error(error_msg); 298 | } 299 | return (uid_t)ret; 300 | } 301 | 302 | char* getenv(const char *name){ 303 | char* ret = NULL; 304 | sgx_status_t status = ocall_getenv(&ret, name); 305 | if (status != SGX_SUCCESS) { 306 | char error_msg[256]; 307 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: when calling ocall_", __func__); 308 | ocall_print_error(error_msg); 309 | } 310 | return ret; 311 | } 312 | 313 | void *mmap64(void *addr, size_t len, int prot, int flags, int fildes, off_t off){ 314 | char error_msg[256]; 315 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 316 | ocall_print_error(error_msg); 317 | } 318 | 319 | int munmap(void *addr, size_t length){ 320 | char error_msg[256]; 321 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 322 | ocall_print_error(error_msg); 323 | return 0; 324 | } 325 | 326 | void *mremap(void *old_address, size_t old_size, size_t new_size, int flags, ... /* void *new_address */){ 327 | char error_msg[256]; 328 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 329 | ocall_print_error(error_msg); 330 | } 331 | 332 | ssize_t readlink(const char *path, char *buf, size_t bufsiz){ 333 | char error_msg[256]; 334 | snprintf(error_msg, sizeof(error_msg), "%s%s", "Error: no ocall implementation for ", __func__); 335 | ocall_print_error(error_msg); 336 | return 0; 337 | } 338 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ######## SGX SDK Settings ######## 2 | 3 | SGX_SDK ?= /opt/intel/sgxsdk # Intel SGX directory 4 | SGX_MODE ?= SW # HW or SW (Hardware or Simulation mode) 5 | SGX_ARCH ?= x64 # x64 or x86 6 | SGX_DEBUG ?= 1 # DEBUG MODE 7 | 8 | # Find out whether 32 or 64 bit 9 | ifeq ($(shell getconf LONG_BIT), 32) 10 | SGX_ARCH := x86 11 | else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32) 12 | SGX_ARCH := x86 13 | endif 14 | 15 | ifeq ($(SGX_ARCH), x86) 16 | SGX_COMMON_CFLAGS := -m32 # flag to compiler regarding 32 or 64 bit 17 | SGX_LIBRARY_PATH := $(SGX_SDK)/lib # SGX library path 18 | SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign # Tool for signing enclaves 19 | SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r # Tool to create bridge routines 20 | else 21 | SGX_COMMON_CFLAGS := -m64 22 | SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 23 | SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign 24 | SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r 25 | endif 26 | 27 | ifeq ($(SGX_DEBUG), 1) 28 | ifeq ($(SGX_PRERELEASE), 1) 29 | $(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!) 30 | endif 31 | endif 32 | 33 | ifeq ($(SGX_DEBUG), 1) 34 | SGX_COMMON_CFLAGS += -O0 -g # Add debug symbols, turn off optimisations 35 | else 36 | SGX_COMMON_CFLAGS += -O2 # turn on optimisations 37 | endif 38 | 39 | ######## App Settings ######## 40 | 41 | ifneq ($(SGX_MODE), HW) 42 | Urts_Library_Name := sgx_urts_sim 43 | else 44 | Urts_Library_Name := sgx_urts 45 | endif 46 | 47 | App_Cpp_Files := App/App.cpp 48 | App_Include_Paths := -IApp -I$(SGX_SDK)/include 49 | 50 | App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) 51 | 52 | # Three configuration modes - Debug, prerelease, release 53 | # Debug - Macro DEBUG enabled. 54 | # Prerelease - Macro NDEBUG and EDEBUG enabled. 55 | # Release - Macro NDEBUG enabled. 56 | ifeq ($(SGX_DEBUG), 1) 57 | App_C_Flags += -DDEBUG -UNDEBUG -UEDEBUG 58 | else ifeq ($(SGX_PRERELEASE), 1) 59 | App_C_Flags += -DNDEBUG -DEDEBUG -UDEBUG 60 | else 61 | App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG 62 | endif 63 | 64 | App_Cpp_Flags := $(App_C_Flags) -std=c++11 65 | App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread 66 | 67 | ifneq ($(SGX_MODE), HW) 68 | App_Link_Flags += -lsgx_uae_service_sim 69 | else 70 | App_Link_Flags += -lsgx_uae_service 71 | endif 72 | 73 | App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o) App/ocalls.o 74 | 75 | App_Name := app 76 | 77 | ######## Enclave Settings ######## 78 | 79 | ifneq ($(SGX_MODE), HW) 80 | Trts_Library_Name := sgx_trts_sim 81 | Service_Library_Name := sgx_tservice_sim 82 | else 83 | Trts_Library_Name := sgx_trts 84 | Service_Library_Name := sgx_tservice 85 | endif 86 | Crypto_Library_Name := sgx_tcrypto 87 | 88 | Enclave_Cpp_Files := Enclave/Enclave.cpp Enclave/sqlite3.c 89 | Enclave_Include_Paths := -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx 90 | 91 | Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector-strong 92 | Enclave_C_Flags += $(Enclave_Include_Paths) 93 | Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++ 94 | 95 | # To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries: 96 | # 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options, 97 | # so that the whole content of trts is included in the enclave. 98 | # 2. For other libraries, you just need to pull the required symbols. 99 | # Use `--start-group' and `--end-group' to link these libraries. 100 | # Do NOT move the libraries linked with `--start-group' and `--end-group' within `--whole-archive' and `--no-whole-archive' options. 101 | # Otherwise, you may get some undesirable errors. 102 | Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ 103 | -Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \ 104 | -Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \ 105 | -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ 106 | -Wl,-pie,-eenclave_entry -Wl,--export-dynamic \ 107 | -Wl,--defsym,__ImageBase=0 -Wl,--gc-sections \ 108 | -Wl,--version-script=Enclave/Enclave.lds 109 | 110 | Enclave_Cpp_Objects := Enclave/Enclave.o Enclave/sqlite3.o Enclave/ocall_interface.o 111 | 112 | Enclave_Name := enclave.so 113 | Signed_Enclave_Name := enclave.signed.so 114 | Enclave_Config_File := Enclave/Enclave.config.xml 115 | 116 | ifeq ($(SGX_MODE), HW) 117 | ifeq ($(SGX_DEBUG), 1) 118 | Build_Mode = HW_DEBUG 119 | else ifeq ($(SGX_PRERELEASE), 1) 120 | Build_Mode = HW_PRERELEASE 121 | else 122 | Build_Mode = HW_RELEASE 123 | endif 124 | else 125 | ifeq ($(SGX_DEBUG), 1) 126 | Build_Mode = SIM_DEBUG 127 | else ifeq ($(SGX_PRERELEASE), 1) 128 | Build_Mode = SIM_PRERELEASE 129 | else 130 | Build_Mode = SIM_RELEASE 131 | endif 132 | endif 133 | 134 | ##### TARGETS ##### 135 | 136 | .PHONY: all run 137 | 138 | # Default target "all" is to build 139 | ifeq ($(Build_Mode), HW_RELEASE) 140 | all: .config_$(Build_Mode)_$(SGX_ARCH) $(App_Name) $(Enclave_Name) 141 | @echo "The project has been built in release hardware mode." 142 | @echo "Please sign the $(Enclave_Name) first with your signing key before you run the $(App_Name) to launch and access the enclave." 143 | @echo "To sign the enclave use the command:" 144 | @echo " $(SGX_ENCLAVE_SIGNER) sign -key -enclave $(Enclave_Name) -out <$(Signed_Enclave_Name)> -config $(Enclave_Config_File)" 145 | @echo "You can also sign the enclave using an external signing tool." 146 | @echo "To build the project in simulation mode set SGX_MODE=SIM. To build the project in prerelease mode set SGX_PRERELEASE=1 and SGX_MODE=HW." 147 | else 148 | all: .config_$(Build_Mode)_$(SGX_ARCH) $(App_Name) $(Signed_Enclave_Name) 149 | ifeq ($(Build_Mode), HW_DEBUG) 150 | @echo "The project has been built in debug hardware mode." 151 | else ifeq ($(Build_Mode), SIM_DEBUG) 152 | @echo "The project has been built in debug simulation mode." 153 | else ifeq ($(Build_Mode), HW_PRERELEASE) 154 | @echo "The project has been built in pre-release hardware mode." 155 | else ifeq ($(Build_Mode), SIM_PRERELEASE) 156 | @echo "The project has been built in pre-release simulation mode." 157 | else 158 | @echo "The project has been built in release simulation mode." 159 | endif 160 | endif 161 | 162 | # Build and run project 163 | run: all 164 | ifneq ($(Build_Mode), HW_RELEASE) 165 | $(CURDIR)/$(App_Name) 166 | @echo "RUN => $(App_Name) [$(SGX_MODE)|$(SGX_ARCH), OK]" 167 | endif 168 | 169 | ######## App Objects ######## 170 | 171 | # Genereate untrusted brigde routines (Enclave_u.c and Enclave_u.h) using .edl file 172 | App/Enclave_u.c: $(SGX_EDGER8R) Enclave/Enclave.edl 173 | cd App && $(SGX_EDGER8R) --untrusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include 174 | @echo "GEN => $@" 175 | 176 | # Compile untrusted brigde routines 177 | App/Enclave_u.o: App/Enclave_u.c 178 | $(CC) $(App_C_Flags) -DSGX_UNTRUSTED -c $< -o $@ 179 | @echo "CC <= $<" 180 | 181 | # Compile ocalls 182 | App/ocalls.o: App/ocalls.c 183 | $(CC) $(App_C_Flags) -c $< -o $@ 184 | @echo "CC <= $<" 185 | 186 | # Compile untrusted Application 187 | App/%.o: App/%.cpp 188 | $(CXX) $(App_Cpp_Flags) -c $< -o $@ 189 | @echo "CXX <= $<" 190 | 191 | # Link and generate main Application executable 192 | $(App_Name): App/Enclave_u.o App/ocalls.o $(App_Cpp_Objects) 193 | $(CXX) $^ -o $@ $(App_Link_Flags) 194 | @echo "LINK => $@" 195 | 196 | .config_$(Build_Mode)_$(SGX_ARCH): 197 | rm -f .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) App/Enclave_u.* $(Enclave_Cpp_Objects) Enclave/Enclave_t.* 198 | @touch .config_$(Build_Mode)_$(SGX_ARCH) 199 | 200 | ######## Enclave Objects ######## 201 | 202 | # Genereate trusted brigde routines (Enclave_t.c and Enclave_t.h) using .edl file 203 | Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl 204 | cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include 205 | @echo "GEN => $@" 206 | 207 | # Compile trusted brigde routines 208 | Enclave/Enclave_t.o: Enclave/Enclave_t.c 209 | $(CC) $(Enclave_C_Flags) -c $< -o $@ 210 | @echo "CC <= $<" 211 | 212 | # Compile trusted Enclave 213 | Enclave/Enclave.o: Enclave/Enclave.cpp 214 | $(CXX) $(Enclave_Cpp_Flags) -c $< -o $@ 215 | @echo "CXX <= $<" 216 | 217 | # Preprocess sqlite3 218 | Enclave/sqlite3.i: Enclave/sqlite3.c 219 | $(CC) -I$(SGX_SDK)/include -DSQLITE_THREADSAFE=0 -E $< -o $@ 220 | @echo "CC-Preprocess <= $<" 221 | 222 | # Compile sqlite3 223 | Enclave/sqlite3.o: Enclave/sqlite3.i Enclave/sqlite3.c 224 | $(CC) $(Enclave_C_Flags) -DSQLITE_THREADSAFE=0 -c $< -o $@ 225 | @echo "CC <= $<" 226 | 227 | # Preprocess sqlite3 228 | Enclave/ocall_interface.i: Enclave/ocall_interface.c 229 | $(CC) -I$(SGX_SDK)/include -E $< -o $@ 230 | @echo "CC-Preprocess <= $<" 231 | 232 | # Compile ocall_interface 233 | Enclave/ocall_interface.o: Enclave/ocall_interface.i Enclave/Enclave_t.c 234 | $(CC) $(Enclave_C_Flags) -c $< -o $@ 235 | @echo "CC <= $<" 236 | 237 | # Link and generate Enclave shared library/executable 238 | $(Enclave_Name): Enclave/Enclave_t.o $(Enclave_Cpp_Objects) 239 | $(CXX) $^ -o $@ $(Enclave_Link_Flags) 240 | @echo "LINK => $@" 241 | 242 | $(Signed_Enclave_Name): $(Enclave_Name) 243 | $(SGX_ENCLAVE_SIGNER) sign -key Enclave/Enclave_private.pem -enclave $(Enclave_Name) -out $@ -config $(Enclave_Config_File) 244 | @echo "SIGN => $@" 245 | 246 | .PHONY: clean 247 | 248 | clean: 249 | rm -f .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) App/Enclave_u.* $(Enclave_Cpp_Objects) Enclave/Enclave_t.* Enclave/sqlite3.i Enclave/ocall_interface.i 250 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SGX_SQLite 2 | SQLite database inside a secure Intel SGX enclave (Linux). 3 | 4 | You can execute your SQL statements securely. The official SQLite library ("sqlite.c", "sqlite.h") is entirely loaded into an enclave. 5 | However, if you want to save your database (i.e. not in-memory database) it will save *.db file without any encryption yet. (need to implement data sealing in the future) 6 | 7 | SQLite Version - 3.19.3 8 | 9 | The project started from "SampleEnclave" provided by Intel SGX SDK. Later, I've added official SQLite library, and then redirected all system calls to ocalls (untrusted part). 10 | You can track the development from scratch by viewing all commits. 11 | 12 | This project may act as guide on how to port C applications inside Intel SGX enclave on Linux. 13 | 14 | # Prerequisites: 15 | * Ubuntu* Desktop-16.04-LTS 64bits 16 | * Intel SGX SDK, SGX Driver, SGX PSW from https://github.com/01org/linux-sgx 17 | * 6th Generation Intel(R) Core(TM) Processor or newer (only if you want to run it in hardware mode, otherwise run in software/simulation mode) 18 | 19 | # What's Included 20 | * **App/** - directory for untrusted part of the application 21 | * **App.cpp** - main file for our app 22 | * **ocalls.c** - implementations of untrusted ocalls in C 23 | * **Enclave/** - directory for trusted part of the application 24 | * **Enclave.config.xml** - enclave config file (same as in SampleEnclave from Intel) 25 | * **Enclave.cpp** - implementations of trusted ecalls in C++ 26 | * **Enclave.edl** - enclave interface file for declarations of all ecalls and ocalls 27 | * **Enclave.lds** - lds file (same as in SampleEnclave from Intel) 28 | * **Enclave_private.pem** - enclave private key (same as in SampleEnclave from Intel) 29 | * **ocall_interface.c** - implementations of redirected system calls from sqlite3.c (not all syscalls implemented) 30 | * **sqlite3.c** - official SQLite amalgamation (made minor changes to correctly redirect syscalls - see commit history) 31 | * **sqlite3.h** - official SQLite amalgamation (unchanged) 32 | * **ocall_types.h** - declarations of some stdlib types for need for edl file (since stlib is untrusted) 33 | 34 | # Building 35 | `make` for simple simulation mode (unsecure) 36 | 37 | `make SGX_MODE=HW SGX_DEBUG=0 SGX_PRERELEASE=1` for hardware mode in pre-release mode 38 | 39 | `make SGX_MODE=HW SGX_DEBUG=0 SGX_PRERELEASE=0` for hardware mode in a secure release mode (but you need to sign your enclave first) 40 | 41 | # Running 42 | `./app test.db` to create test.db 43 | -------------------------------------------------------------------------------- /ocall_types.h: -------------------------------------------------------------------------------- 1 | #ifndef _OCALL_TYPES_H_ 2 | #define _OCALL_TYPES_H_ 3 | 4 | // Divide system definitions into trusted and untrusted part for ocalls type declarations 5 | #ifdef SGX_UNTRUSTED 6 | // For untrusted part take standard library headers 7 | #include 8 | #include 9 | #include 10 | 11 | #else 12 | // For trusted part copy required standard library declarations from stdlib headers 13 | 14 | // For ocall_interface.c do not redefine these types, otherwise define 15 | #ifndef DO_NOT_REDEFINE_FOR_OCALL 16 | 17 | typedef unsigned long int __dev_t; 18 | typedef unsigned int __uid_t; 19 | typedef unsigned int __gid_t; 20 | typedef unsigned long int __ino_t; 21 | typedef unsigned long int __ino64_t; 22 | typedef unsigned int __mode_t; 23 | typedef unsigned int mode_t; 24 | typedef unsigned long int __nlink_t; 25 | typedef long int __off_t; 26 | typedef long int __off64_t; 27 | typedef int __pid_t; 28 | typedef long int __clock_t; 29 | typedef unsigned long int __rlim_t; 30 | typedef unsigned long int __rlim64_t; 31 | typedef unsigned int __id_t; 32 | typedef long int __time_t; 33 | typedef unsigned int __useconds_t; 34 | typedef long int __suseconds_t; 35 | typedef long int __blksize_t; 36 | typedef long int __blkcnt_t; 37 | typedef long int __blkcnt64_t; 38 | typedef __off_t off_t; 39 | typedef long int __syscall_slong_t; 40 | 41 | struct stat 42 | { 43 | __dev_t st_dev; 44 | __ino_t st_ino; 45 | __nlink_t st_nlink; 46 | __mode_t st_mode; 47 | __uid_t st_uid; 48 | __gid_t st_gid; 49 | int __pad0; 50 | __dev_t st_rdev; 51 | __off_t st_size; 52 | __blksize_t st_blksize; 53 | __blkcnt_t st_blocks; 54 | __time_t st_atim; 55 | __time_t st_mtim; 56 | __time_t st_ctim; 57 | __syscall_slong_t __glibc_reserved[3]; 58 | }; 59 | 60 | #endif // DO_NOT_REDEFINE_FOR_OCALL_INTERFACE 61 | 62 | #endif // SGX_UNTRUSTED 63 | 64 | #endif // _OCALL_TYPES_H_ 65 | --------------------------------------------------------------------------------