[Assignment-7] add SGX sample code from VM
All checks were successful
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (push) Successful in 1m2s
Latex Build / build-latex (Assignment 5 - Software Security - Teil 1) (push) Successful in 1m3s
Latex Build / build-latex (Assignment 6 - Software Security - Teil 2) (push) Successful in 1m0s
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (pull_request) Successful in 30s
Latex Build / build-latex (Assignment 5 - Software Security - Teil 1) (pull_request) Successful in 10s
Latex Build / build-latex (Assignment 6 - Software Security - Teil 2) (pull_request) Successful in 8s

This commit is contained in:
Paul Zinselmeyer 2024-06-29 17:55:44 +02:00
parent 5616ddc4e5
commit ba8e969470
Signed by: pfzetto
GPG key ID: B471A1AF06C895FD
163 changed files with 24030 additions and 0 deletions

View file

@ -0,0 +1,55 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# Apple .DS_Store files
.DS_Store

View file

@ -0,0 +1,209 @@
#
# Copyright (C) 2011-2016 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.
#
#
######## SGX SDK Settings ########
SGX_SDK ?= /opt/intel/sgxsdk
SGX_MODE ?= SIM
SGX_ARCH ?= x64
ifeq ($(shell getconf LONG_BIT), 32)
SGX_ARCH := x86
else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
SGX_ARCH := x86
endif
ifeq ($(SGX_ARCH), x86)
SGX_COMMON_CFLAGS := -m32
SGX_LIBRARY_PATH := $(SGX_SDK)/lib
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
else
SGX_COMMON_CFLAGS := -m64
SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
endif
ifeq ($(SGX_DEBUG), 1)
ifeq ($(SGX_PRERELEASE), 1)
$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
endif
endif
ifeq ($(SGX_DEBUG), 1)
SGX_COMMON_CFLAGS += -O0 -g
else
SGX_COMMON_CFLAGS += -O2
endif
######## App Settings ########
ifneq ($(SGX_MODE), HW)
Urts_Library_Name := sgx_urts_sim
else
Urts_Library_Name := sgx_urts
endif
App_Cpp_Files := app/app.cpp app/utils.cpp
App_Include_Paths := -Iapp -I$(SGX_SDK)/include -Iinclude -Itest
App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
# Three configuration modes - Debug, prerelease, release
# Debug - Macro DEBUG enabled.
# Prerelease - Macro NDEBUG and EDEBUG enabled.
# Release - Macro NDEBUG enabled.
ifeq ($(SGX_DEBUG), 1)
App_C_Flags += -DDEBUG -UNDEBUG -UEDEBUG
else ifeq ($(SGX_PRERELEASE), 1)
App_C_Flags += -DNDEBUG -DEDEBUG -UDEBUG
else
App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG
endif
App_Cpp_Flags := $(App_C_Flags) -std=c++11
App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread
ifneq ($(SGX_MODE), HW)
App_Link_Flags += -lsgx_uae_service_sim
else
App_Link_Flags += -lsgx_uae_service
endif
App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
App_Name := sgx-wallet
######## Enclave Settings ########
ifneq ($(SGX_MODE), HW)
Trts_Library_Name := sgx_trts_sim
Service_Library_Name := sgx_tservice_sim
else
Trts_Library_Name := sgx_trts
Service_Library_Name := sgx_tservice
endif
Crypto_Library_Name := sgx_tcrypto
Enclave_Cpp_Files := enclave/enclave.cpp enclave/sealing/sealing.cpp
Enclave_Include_Paths := -Ienclave -Iinclude -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport
Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths)
Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++03 -nostdinc++
Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
-Wl,--start-group -lsgx_tstdc -lsgx_tstdcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \
-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
-Wl,-pie,-eenclave_entry -Wl,--export-dynamic \
-Wl,--defsym,__ImageBase=0
# -Wl,--version-script=Enclave/Enclave.lds
Enclave_Cpp_Objects := $(Enclave_Cpp_Files:.cpp=.o)
Enclave_Name := enclave.so
Signed_Enclave_Name := enclave.signed.so
Enclave_Config_File := enclave/enclave.config.xml
ifeq ($(SGX_MODE), HW)
ifneq ($(SGX_DEBUG), 1)
ifneq ($(SGX_PRERELEASE), 1)
Build_Mode = HW_RELEASE
endif
endif
endif
.PHONY: all run
ifeq ($(Build_Mode), HW_RELEASE)
all: $(App_Name) $(Enclave_Name)
@echo "The project has been built in release hardware mode."
@echo "Please sign the $(Enclave_Name) first with your signing key before you run the $(App_Name) to launch and access the enclave."
@echo "To sign the enclave use the command:"
@echo " $(SGX_ENCLAVE_SIGNER) sign -key <your key> -enclave $(Enclave_Name) -out <$(Signed_Enclave_Name)> -config $(Enclave_Config_File)"
@echo "You can also sign the enclave using an external signing tool. See User's Guide for more details."
@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."
else
all: $(App_Name) $(Signed_Enclave_Name)
endif
run: all
ifneq ($(Build_Mode), HW_RELEASE)
@$(CURDIR)/$(App_Name)
@echo "RUN => $(App_Name) [$(SGX_MODE)|$(SGX_ARCH), OK]"
endif
######## App Objects ########
app/enclave_u.c: $(SGX_EDGER8R) enclave/enclave.edl
@cd app && $(SGX_EDGER8R) --untrusted ../enclave/enclave.edl --search-path ../enclave --search-path $(SGX_SDK)/include
@echo "GEN => $@"
app/enclave_u.o: app/enclave_u.c
@$(CC) $(App_C_Flags) -c $< -o $@
@echo "CC <= $<"
app/%.o: app/%.cpp
@$(CXX) $(App_Cpp_Flags) -c $< -o $@
@echo "CXX <= $<"
$(App_Name): app/enclave_u.o $(App_Cpp_Objects)
@$(CXX) $^ -o $@ $(App_Link_Flags)
@echo "LINK => $@"
######## Enclave Objects ########
enclave/enclave_t.c: $(SGX_EDGER8R) enclave/enclave.edl
@cd enclave && $(SGX_EDGER8R) --trusted ../enclave/enclave.edl --search-path ../enclave --search-path $(SGX_SDK)/include
@echo "GEN => $@"
enclave/enclave_t.o: enclave/enclave_t.c
@$(CC) $(Enclave_C_Flags) -c $< -o $@
@echo "CC <= $<"
enclave/%.o: enclave/%.cpp
@$(CXX) $(Enclave_Cpp_Flags) -c $< -o $@
@echo "CXX <= $<"
$(Enclave_Name): enclave/enclave_t.o $(Enclave_Cpp_Objects)
@$(CXX) $^ -o $@ $(Enclave_Link_Flags)
@echo "LINK => $@"
$(Signed_Enclave_Name): $(Enclave_Name)
@$(SGX_ENCLAVE_SIGNER) sign -key enclave/enclave_private.pem -enclave $(Enclave_Name) -out $@ -config $(Enclave_Config_File)
@echo "SIGN => $@"
.PHONY: clean
clean:
@rm -f $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) app/enclave_u.* $(Enclave_Cpp_Objects) enclave/enclave_t.*

View file

@ -0,0 +1,225 @@
#include "enclave_u.h"
#include "sgx_urts.h"
#include <cstring>
#include <fstream>
#include <getopt.h>
#include "app.h"
#include "utils.h"
#include "wallet.h"
#include "enclave.h"
using namespace std;
// OCALLs implementation
int ocall_save_wallet(const uint8_t* sealed_data, const size_t sealed_size) {
ofstream file(WALLET_FILE, ios::out | ios::binary);
if (file.fail()) {return 1;}
file.write((const char*) sealed_data, sealed_size);
file.close();
return 0;
}
int ocall_load_wallet(uint8_t* sealed_data, const size_t sealed_size) {
ifstream file(WALLET_FILE, ios::in | ios::binary);
if (file.fail()) {return 1;}
file.read((char*) sealed_data, sealed_size);
file.close();
return 0;
}
int ocall_is_wallet(void) {
ifstream file(WALLET_FILE, ios::in | ios::binary);
if (file.fail()) {return 0;} // failure means no wallet found
file.close();
return 1;
}
int main(int argc, char** argv) {
sgx_enclave_id_t eid = 0;
sgx_launch_token_t token = {0};
int updated, ret;
sgx_status_t ecall_status, enclave_status;
enclave_status = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, &eid, NULL);
if(enclave_status != SGX_SUCCESS) {
error_print("Fail to initialize enclave.");
return -1;
}
info_print("Enclave successfully initilised.");
const char* options = "hvn:p:c:sax:y:z:r:";
opterr=0; // prevent 'getopt' from printing err messages
char err_message[100];
int opt, stop=0;
int h_flag=0, v_flag=0, s_flag=0, a_flag=0;
char * n_value=NULL, *p_value=NULL, *c_value=NULL, *x_value=NULL, *y_value=NULL, *z_value=NULL, *r_value=NULL;
// read user input
while ((opt = getopt(argc, argv, options)) != -1) {
switch (opt) {
// help
case 'h':
h_flag = 1;
break;
// create new wallet
case 'n':
n_value = optarg;
break;
// master-password
case 'p':
p_value = optarg;
break;
// change master-password
case 'c':
c_value = optarg;
break;
// show wallet
case 's':
s_flag = 1;
break;
// add item
case 'a': // add item flag
a_flag = 1;
break;
case 'x': // item's title
x_value = optarg;
break;
case 'y': // item's username
y_value = optarg;
break;
case 'z': // item's password
z_value = optarg;
break;
// remove item
case 'r':
r_value = optarg;
break;
// exceptions
case '?':
if (optopt == 'n' || optopt == 'p' || optopt == 'c' || optopt == 'r' ||
optopt == 'x' || optopt == 'y' || optopt == 'z'
) {
sprintf(err_message, "Option -%c requires an argument.", optopt);
}
else if (isprint(optopt)) {
sprintf(err_message, "Unknown option `-%c'.", optopt);
}
else {
sprintf(err_message, "Unknown option character `\\x%x'.",optopt);
}
stop = 1;
error_print(err_message);
error_print("Program exiting.");
break;
default:
error_print("Unknown option.");
}
}
// perform actions
if (stop != 1) {
// show help
if (h_flag) {
show_help();
}
// create new wallet
else if(n_value!=NULL) {
ecall_status = ecall_create_wallet(eid, &ret, n_value);
if (ecall_status != SGX_SUCCESS || is_error(ret)) {
error_print("Fail to create new wallet.");
}
else {
info_print("Wallet successfully created.");
}
}
// change master-password
else if (p_value!=NULL && c_value!=NULL) {
ecall_status = ecall_change_master_password(eid, &ret, p_value, c_value);
if (ecall_status != SGX_SUCCESS || is_error(ret)) {
error_print("Fail change master-password.");
}
else {
info_print("Master-password successfully changed.");
}
}
// show wallet
else if(p_value!=NULL && s_flag) {
wallet_t* wallet = (wallet_t*)malloc(sizeof(wallet_t));
ecall_status = ecall_show_wallet(eid, &ret, p_value, wallet, sizeof(wallet_t));
if (ecall_status != SGX_SUCCESS || is_error(ret)) {
error_print("Fail to retrieve wallet.");
}
else {
info_print("Wallet successfully retrieved.");
print_wallet(wallet);
}
free(wallet);
}
// add item
else if (p_value!=NULL && a_flag && x_value!=NULL && y_value!=NULL && z_value!=NULL) {
item_t* new_item = (item_t*)malloc(sizeof(item_t));
strcpy(new_item->title, x_value);
strcpy(new_item->username, y_value);
strcpy(new_item->password, z_value);
ecall_status = ecall_add_item(eid, &ret, p_value, new_item, sizeof(item_t));
if (ecall_status != SGX_SUCCESS || is_error(ret)) {
error_print("Fail to add new item to wallet.");
}
else {
info_print("Item successfully added to the wallet.");
}
free(new_item);
}
// remove item
else if (p_value!=NULL && r_value!=NULL) {
char* p_end;
int index = (int)strtol(r_value, &p_end, 10);
if (r_value == p_end) {
error_print("Option -r requires an integer argument.");
}
else {
ecall_status = ecall_remove_item(eid, &ret, p_value, index);
if (ecall_status != SGX_SUCCESS || is_error(ret)) {
error_print("Fail to remove item.");
}
else {
info_print("Item successfully removed from the wallet.");
}
}
}
// display help
else {
error_print("Wrong inputs.");
show_help();
}
}
// destroy enclave
enclave_status = sgx_destroy_enclave(eid);
if(enclave_status != SGX_SUCCESS) {
error_print("Fail to destroy enclave.");
return -1;
}
info_print("Enclave successfully destroyed.");
info_print("Program exit success.");
return 0;
}

View file

@ -0,0 +1,13 @@
#ifndef APP_H_
#define APP_H_
/***************************************************
* config.
***************************************************/
#define APP_NAME "sgx-wallet"
#define ENCLAVE_FILE "enclave.signed.so"
#define WALLET_FILE "wallet.seal"
#endif // APP_H_

View file

@ -0,0 +1,101 @@
#include <stdio.h>
#include <cstring>
#include "utils.h"
#include "app.h"
#include "wallet.h"
#include "enclave.h"
void info_print(const char* str) {
printf("[INFO] %s\n", str);
}
void warning_print(const char* str) {
printf("[WARNING] %s\n", str);
}
void error_print(const char* str) {
printf("[ERROR] %s\n", str);
}
void print_wallet(const wallet_t* wallet) {
printf("\n-----------------------------------------\n\n");
printf("Simple password wallet based on Intel SGX.\n\n");
printf("Number of items: %lu\n\n", wallet->size);
for (int i = 0; i < wallet->size; ++i) {
printf("#%d -- %s\n", i, wallet->items[i].title);
printf("[username:] %s\n", wallet->items[i].username);
printf("[password:] %s\n", wallet->items[i].password);
printf("\n");
}
printf("\n------------------------------------------\n\n");
}
int is_error(int error_code) {
char err_message[100];
// check error case
switch(error_code) {
case RET_SUCCESS:
return 0;
case ERR_PASSWORD_OUT_OF_RANGE:
sprintf(err_message, "Password should be at least 8 characters long and at most %d.", MAX_ITEM_SIZE);
break;
case ERR_WALLET_ALREADY_EXISTS:
sprintf(err_message, "Wallet already exists: delete file '%s' first.", WALLET_FILE);
break;
case ERR_CANNOT_SAVE_WALLET:
strcpy(err_message, "Coud not save wallet.");
break;
case ERR_CANNOT_LOAD_WALLET:
strcpy(err_message, "Coud not load wallet.");
break;
case ERR_WRONG_MASTER_PASSWORD:
strcpy(err_message, "Wrong master password.");
break;
case ERR_WALLET_FULL:
sprintf(err_message, "Wallet full (maximum number of item: %d).", MAX_ITEMS);
break;
case ERR_ITEM_DOES_NOT_EXIST:
strcpy(err_message, "Item does not exist.");
break;
case ERR_ITEM_TOO_LONG:
sprintf(err_message, "Item too longth (maximum size: %d).", MAX_ITEM_SIZE);
break;
case ERR_FAIL_SEAL:
sprintf(err_message, "Fail to seal wallet.");
break;
case ERR_FAIL_UNSEAL:
sprintf(err_message, "Fail to unseal wallet.");
break;
default:
sprintf(err_message, "Unknown error.");
}
// print error message
error_print(err_message);
return 1;
}
void show_help() {
const char* command = "[-h Show this screen] [-v Show version] [-s Show wallet] " \
"[-n master-password] [-p master-password -c new-master-password]" \
"[-p master-password -a -x items_title -y items_username -z toitems_password]" \
"[-p master-password -r items_index]";
printf("\nusage: %s %s\n\n", APP_NAME, command);
}

View file

@ -0,0 +1,21 @@
#ifndef UTIL_H_
#define UTIL_H_
#include "wallet.h"
void info_print(const char* str);
void warning_print(const char* str);
void error_print(const char* str);
void print_wallet(const wallet_t* wallet);
int is_error(int error_code);
void show_help();
void show_version();
#endif // UTIL_H_

View file

@ -0,0 +1,12 @@
<!-- Please refer to User's Guide for the explanation of each field -->
<EnclaveConfiguration>
<ProdID>0</ProdID>
<ISVSVN>0</ISVSVN>
<StackMaxSize>0x40000</StackMaxSize>
<HeapMaxSize>0x100000</HeapMaxSize>
<TCSNum>10</TCSNum>
<TCSPolicy>1</TCSPolicy>
<DisableDebug>0</DisableDebug>
<MiscSelect>0</MiscSelect>
<MiscMask>0xFFFFFFFF</MiscMask>
</EnclaveConfiguration>

View file

@ -0,0 +1,403 @@
#include "enclave_t.h"
#include "string.h"
#include "enclave.h"
#include "wallet.h"
#include "sgx_tseal.h"
#include "sealing/sealing.h"
int ecall_create_wallet(const char* master_password) {
//
// OVERVIEW:
// 1. check password policy
// 2. [ocall] abort if wallet already exist
// 3. create wallet
// 4. seal wallet
// 5. [ocall] save wallet
// 6. exit enclave
//
//
sgx_status_t ocall_status, sealing_status;
int ocall_ret;
// 1. check passaword policy
if (strlen(master_password) < 8 || strlen(master_password)+1 > MAX_ITEM_SIZE) {
return ERR_PASSWORD_OUT_OF_RANGE;
}
// 2. abort if wallet already exist
ocall_status = ocall_is_wallet(&ocall_ret);
if (ocall_ret != 0) {
return ERR_WALLET_ALREADY_EXISTS;
}
// 3. create new wallet
wallet_t* wallet = (wallet_t*)malloc(sizeof(wallet_t));
wallet->size = 0;
strncpy(wallet->master_password, master_password, strlen(master_password)+1);
// 4. seal wallet
size_t sealed_size = sizeof(sgx_sealed_data_t) + sizeof(wallet_t);
uint8_t* sealed_data = (uint8_t*)malloc(sealed_size);
sealing_status = seal_wallet(wallet, (sgx_sealed_data_t*)sealed_data, sealed_size);
free(wallet);
if (sealing_status != SGX_SUCCESS) {
free(sealed_data);
return ERR_FAIL_SEAL;
}
// 5. save wallet
ocall_status = ocall_save_wallet(&ocall_ret, sealed_data, sealed_size);
free(sealed_data);
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
return ERR_CANNOT_SAVE_WALLET;
}
// 6. exit enclave
return RET_SUCCESS;
}
/**
* @brief Provides the wallet content. The sizes/length of
* pointers need to be specified, otherwise SGX will
* assume a count of 1 for all pointers.
*
*/
int ecall_show_wallet(const char* master_password, wallet_t* wallet, size_t wallet_size) {
//
// OVERVIEW:
// 1. [ocall] load wallet
// 2. unseal wallet
// 3. verify master-password
// 4. return wallet to app
// 5. exit enclave
//
//
sgx_status_t ocall_status, sealing_status;
int ocall_ret;
// 1. load wallet
size_t sealed_size = sizeof(sgx_sealed_data_t) + sizeof(wallet_t);
uint8_t* sealed_data = (uint8_t*)malloc(sealed_size);
ocall_status = ocall_load_wallet(&ocall_ret, sealed_data, sealed_size);
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
free(sealed_data);
return ERR_CANNOT_LOAD_WALLET;
}
// 2. unseal loaded wallet
uint32_t plaintext_size = sizeof(wallet_t);
wallet_t* unsealed_wallet = (wallet_t*)malloc(plaintext_size);
sealing_status = unseal_wallet((sgx_sealed_data_t*)sealed_data, unsealed_wallet, plaintext_size);
free(sealed_data);
if (sealing_status != SGX_SUCCESS) {
free(unsealed_wallet);
return ERR_FAIL_UNSEAL;
}
// 3. verify master-password
if (strcmp(unsealed_wallet->master_password, master_password) != 0) {
free(unsealed_wallet);
return ERR_WRONG_MASTER_PASSWORD;
}
// 4. return wallet to app
(* wallet) = *unsealed_wallet;
free(unsealed_wallet);
// 5. exit enclave
return RET_SUCCESS;
}
/**
* @brief Changes the wallet's master-password.
*
*/
int ecall_change_master_password(const char* old_password, const char* new_password) {
//
// OVERVIEW:
// 1. check password policy
// 2. [ocall] load wallet
// 3. unseal wallet
// 4. verify old password
// 5. update password
// 6. seal wallet
// 7. [ocall] save sealed wallet
// 8. exit enclave
//
//
sgx_status_t ocall_status, sealing_status;
int ocall_ret;
// 1. check passaword policy
if (strlen(new_password) < 8 || strlen(new_password)+1 > MAX_ITEM_SIZE) {
return ERR_PASSWORD_OUT_OF_RANGE;
}
// 2. load wallet
size_t sealed_size = sizeof(sgx_sealed_data_t) + sizeof(wallet_t);
uint8_t* sealed_data = (uint8_t*)malloc(sealed_size);
ocall_status = ocall_load_wallet(&ocall_ret, sealed_data, sealed_size);
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
free(sealed_data);
return ERR_CANNOT_LOAD_WALLET;
}
// 3. unseal wallet
uint32_t plaintext_size = sizeof(wallet_t);
wallet_t* wallet = (wallet_t*)malloc(plaintext_size);
sealing_status = unseal_wallet((sgx_sealed_data_t*)sealed_data, wallet, plaintext_size);
free(sealed_data);
if (sealing_status != SGX_SUCCESS) {
free(wallet);
return ERR_FAIL_UNSEAL;
}
// 4. verify master-password
if (strcmp(wallet->master_password, old_password) != 0) {
free(wallet);
return ERR_WRONG_MASTER_PASSWORD;
}
// 5. update password
strncpy(wallet->master_password, new_password, strlen(new_password)+1);
// 6. seal wallet
sealed_data = (uint8_t*)malloc(sealed_size);
sealing_status = seal_wallet(wallet, (sgx_sealed_data_t*)sealed_data, sealed_size);
free(wallet);
if (sealing_status != SGX_SUCCESS) {
free(wallet);
free(sealed_data);
return ERR_FAIL_SEAL;
}
// 7. save wallet
ocall_status = ocall_save_wallet(&ocall_ret, sealed_data, sealed_size);
free(sealed_data);
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
return ERR_CANNOT_SAVE_WALLET;
}
// 6. exit enclave
return RET_SUCCESS;
}
/**
* @brief Adds an item to the wallet. The sizes/length of
* pointers need to be specified, otherwise SGX will
* assume a count of 1 for all pointers.
*
*/
int ecall_add_item(const char* master_password, const item_t* item, const size_t item_size) {
//
// OVERVIEW:
// 1. [ocall] load wallet
// 2. unseal wallet
// 3. verify master-password
// 4. check input length
// 5. add item to the wallet
// 6. seal wallet
// 7. [ocall] save sealed wallet
// 8. exit enclave
//
//
sgx_status_t ocall_status, sealing_status;
int ocall_ret;
// 2. load wallet
size_t sealed_size = sizeof(sgx_sealed_data_t) + sizeof(wallet_t);
uint8_t* sealed_data = (uint8_t*)malloc(sealed_size);
ocall_status = ocall_load_wallet(&ocall_ret, sealed_data, sealed_size);
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
free(sealed_data);
return ERR_CANNOT_LOAD_WALLET;
}
// 3. unseal wallet
uint32_t plaintext_size = sizeof(wallet_t);
wallet_t* wallet = (wallet_t*)malloc(plaintext_size);
sealing_status = unseal_wallet((sgx_sealed_data_t*)sealed_data, wallet, plaintext_size);
free(sealed_data);
if (sealing_status != SGX_SUCCESS) {
free(wallet);
return ERR_FAIL_UNSEAL;
}
// 3. verify master-password
if (strcmp(wallet->master_password, master_password) != 0) {
free(wallet);
return ERR_WRONG_MASTER_PASSWORD;
}
// 4. check input length
if (strlen(item->title)+1 > MAX_ITEM_SIZE ||
strlen(item->username)+1 > MAX_ITEM_SIZE ||
strlen(item->password)+1 > MAX_ITEM_SIZE
) {
free(wallet);
return ERR_ITEM_TOO_LONG;
}
// 5. add item to the wallet
size_t wallet_size = wallet->size;
if (wallet_size >= MAX_ITEMS) {
free(wallet);
return ERR_WALLET_FULL;
}
wallet->items[wallet_size] = *item;
++wallet->size;
// 6. seal wallet
sealed_data = (uint8_t*)malloc(sealed_size);
sealing_status = seal_wallet(wallet, (sgx_sealed_data_t*)sealed_data, sealed_size);
free(wallet);
if (sealing_status != SGX_SUCCESS) {
free(wallet);
free(sealed_data);
return ERR_FAIL_SEAL;
}
// 7. save wallet
ocall_status = ocall_save_wallet(&ocall_ret, sealed_data, sealed_size);
free(sealed_data);
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
return ERR_CANNOT_SAVE_WALLET;
}
// 8. exit enclave
return RET_SUCCESS;
}
/**
* @brief Removes an item from the wallet. The sizes/length of
* pointers need to be specified, otherwise SGX will
* assume a count of 1 for all pointers.
*
*/
int ecall_remove_item(const char* master_password, const int index) {
//
// OVERVIEW:
// 1. check index bounds
// 2. [ocall] load wallet
// 3. unseal wallet
// 4. verify master-password
// 5. remove item from the wallet
// 6. seal wallet
// 7. [ocall] save sealed wallet
// 8. exit enclave
//
//
sgx_status_t ocall_status, sealing_status;
int ocall_ret;
// 1. check index bounds
if (index < 0 || index >= MAX_ITEMS) {
return ERR_ITEM_DOES_NOT_EXIST;
}
// 2. load wallet
size_t sealed_size = sizeof(sgx_sealed_data_t) + sizeof(wallet_t);
uint8_t* sealed_data = (uint8_t*)malloc(sealed_size);
ocall_status = ocall_load_wallet(&ocall_ret, sealed_data, sealed_size);
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
free(sealed_data);
return ERR_CANNOT_LOAD_WALLET;
}
// 3. unseal wallet
uint32_t plaintext_size = sizeof(wallet_t);
wallet_t* wallet = (wallet_t*)malloc(plaintext_size);
sealing_status = unseal_wallet((sgx_sealed_data_t*)sealed_data, wallet, plaintext_size);
free(sealed_data);
if (sealing_status != SGX_SUCCESS) {
free(wallet);
return ERR_FAIL_UNSEAL;
}
// 4. verify master-password
if (strcmp(wallet->master_password, master_password) != 0) {
free(wallet);
return ERR_WRONG_MASTER_PASSWORD;
}
// 5. remove item from the wallet
size_t wallet_size = wallet->size;
if (index >= wallet_size) {
free(wallet);
return ERR_ITEM_DOES_NOT_EXIST;
}
for (int i = index; i < wallet_size-1; ++i) {
wallet->items[i] = wallet->items[i+1];
}
--wallet->size;
// 6. seal wallet
sealed_data = (uint8_t*)malloc(sealed_size);
sealing_status = seal_wallet(wallet, (sgx_sealed_data_t*)sealed_data, sealed_size);
free(wallet);
if (sealing_status != SGX_SUCCESS) {
free(sealed_data);
return ERR_FAIL_SEAL;
}
// 7. save wallet
ocall_status = ocall_save_wallet(&ocall_ret, sealed_data, sealed_size);
free(sealed_data);
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
return ERR_CANNOT_SAVE_WALLET;
}
// 8. exit enclave
return RET_SUCCESS;
}

View file

@ -0,0 +1,53 @@
enclave {
// includes
include "wallet.h"
// define ECALLs
trusted {
public int ecall_create_wallet(
[in, string]const char* master_password
);
public int ecall_show_wallet(
[in, string]const char* master_password,
[out, size=wallet_size] wallet_t* wallet,
size_t wallet_size
);
public int ecall_change_master_password(
[in, string]const char* old_password,
[in, string]const char* new_password
);
public int ecall_add_item(
[in, string]const char* master_password,
[in, size=item_size]const item_t* item,
size_t item_size
);
public int ecall_remove_item(
[in, string]const char* master_password,
int index
);
};
// define OCALLs
untrusted {
int ocall_save_wallet(
[in, size=sealed_size]const uint8_t* sealed_data,
size_t sealed_size
);
int ocall_load_wallet(
[out, size=sealed_size]uint8_t* sealed_data,
size_t sealed_size
);
int ocall_is_wallet(void);
};
};

View file

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ
AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ
ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr
nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b
3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H
ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD
5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW
KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC
1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe
K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z
AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q
ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6
JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826
5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02
wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9
osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm
WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i
Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9
xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd
vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD
Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a
cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC
0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ
gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo
gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t
k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz
Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6
O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5
afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom
e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G
BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv
fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN
t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9
yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp
6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg
WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH
NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk=
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,15 @@
#include "enclave_t.h"
#include "sgx_trts.h"
#include "sgx_tseal.h"
#include "wallet.h"
#include "sealing.h"
sgx_status_t seal_wallet(const wallet_t* wallet, sgx_sealed_data_t* sealed_data, size_t sealed_size) {
return sgx_seal_data(0, NULL, sizeof(wallet_t), (uint8_t*)wallet, sealed_size, sealed_data);
}
sgx_status_t unseal_wallet(const sgx_sealed_data_t* sealed_data, wallet_t* plaintext, uint32_t plaintext_size) {
return sgx_unseal_data(sealed_data, NULL, NULL, (uint8_t*)plaintext, &plaintext_size);
}

View file

@ -0,0 +1,16 @@
#ifndef SEALING_H_
#define SEALING_H_
#include "sgx_trts.h"
#include "sgx_tseal.h"
#include "wallet.h"
sgx_status_t seal_wallet(const wallet_t* plaintext, sgx_sealed_data_t* sealed_data, size_t sealed_size);
sgx_status_t unseal_wallet(const sgx_sealed_data_t* sealed_data, wallet_t* plaintext, uint32_t plaintext_size);
#endif // SEALING_H_

View file

@ -0,0 +1,21 @@
#ifndef ENCLAVE_H_
#define ENCLAVE_H_
/***************************************************
* Enclave return codes
***************************************************/
#define RET_SUCCESS 0
#define ERR_PASSWORD_OUT_OF_RANGE 1
#define ERR_WALLET_ALREADY_EXISTS 2
#define ERR_CANNOT_SAVE_WALLET 3
#define ERR_CANNOT_LOAD_WALLET 4
#define ERR_WRONG_MASTER_PASSWORD 5
#define ERR_WALLET_FULL 6
#define ERR_ITEM_DOES_NOT_EXIST 7
#define ERR_ITEM_TOO_LONG 8
#define ERR_FAIL_SEAL 9
#define ERR_FAIL_UNSEAL 10
#endif // ENCLAVE_H_

View file

@ -0,0 +1,25 @@
#ifndef WALLET_H_
#define WALLET_H_
#define MAX_ITEMS 100
#define MAX_ITEM_SIZE 100
// item
struct Item {
char title[MAX_ITEM_SIZE];
char username[MAX_ITEM_SIZE];
char password[MAX_ITEM_SIZE];
};
typedef struct Item item_t;
// wallet
struct Wallet {
item_t items[MAX_ITEMS];
size_t size;
char master_password[MAX_ITEM_SIZE];
};
typedef struct Wallet wallet_t;
#endif // WALLET_H_