Systemsicherheit/Assignment 7 - SGX Hands-on/SGX101_sample_code-master/PasswordWallet/enclave/enclave.cpp

404 lines
9.4 KiB
C++
Raw Normal View History

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