[Assignmnt-7] rename directory
Some checks failed
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (push) Successful in 1m0s
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) Has been cancelled
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (pull_request) Successful in 35s
Latex Build / build-latex (Assignment 5 - Software Security - Teil 1) (pull_request) Successful in 8s
Latex Build / build-latex (Assignment 6 - Software Security - Teil 2) (pull_request) Successful in 1m3s
Some checks failed
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (push) Successful in 1m0s
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) Has been cancelled
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (pull_request) Successful in 35s
Latex Build / build-latex (Assignment 5 - Software Security - Teil 1) (pull_request) Successful in 8s
Latex Build / build-latex (Assignment 6 - Software Security - Teil 2) (pull_request) Successful in 1m3s
This commit is contained in:
parent
341d128b27
commit
7224e46946
36 changed files with 0 additions and 0 deletions
249
Assignment 7 - SGX Hands-on/src/Makefile
Normal file
249
Assignment 7 - SGX Hands-on/src/Makefile
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
#
|
||||
# Copyright (C) 2011-2018 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 ?= HW
|
||||
SGX_ARCH ?= x64
|
||||
SGX_DEBUG ?= 1
|
||||
|
||||
ifeq ($(shell getconf LONG_BIT), 32)
|
||||
SGX_ARCH := x86
|
||||
else ifeq ($(findstring -m32, $(CCFLAGS)), -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_C_Files := app/main.c app/proxy.c app/proxysetup.c app/employee.c app/util.c app/embedded_device.c
|
||||
App_Include_Paths := -IInclude -Iapp -I$(SGX_SDK)/include -I/usr/local/openssl-3.3.1/include
|
||||
|
||||
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
|
||||
|
||||
OPENSSL := -Wl,-Bstatic -L/usr/local/openssl-3.3.1/lib64 -lssl -lcrypto -Wl,-Bdynamic -ldl
|
||||
App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread -lsgx_urts $(OPENSSL)
|
||||
|
||||
ifneq ($(SGX_MODE), HW)
|
||||
App_Link_Flags += -lsgx_uae_service_sim
|
||||
else
|
||||
App_Link_Flags += -lsgx_uae_service
|
||||
endif
|
||||
|
||||
App_C_Objects := $(App_C_Files:.c=.o)
|
||||
|
||||
App_Name := signatureproxy
|
||||
|
||||
|
||||
######## 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_C_Files := enclave/enclave.c
|
||||
Enclave_Include_Paths := -IInclude -Ienclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx
|
||||
|
||||
CC_BELOW_4_9 := $(shell expr "`$(CC) -dumpversion`" \< "4.9")
|
||||
ifeq ($(CC_BELOW_4_9), 1)
|
||||
Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector
|
||||
else
|
||||
Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections -fstack-protector-strong
|
||||
endif
|
||||
|
||||
Enclave_C_Flags += $(Enclave_Include_Paths)
|
||||
|
||||
|
||||
# To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries:
|
||||
# 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options,
|
||||
# so that the whole content of trts is included in the enclave.
|
||||
# 2. For other libraries, you just need to pull the required symbols.
|
||||
# Use `--start-group' and `--end-group' to link these libraries.
|
||||
# Do NOT move the libraries linked with `--start-group' and `--end-group' within `--whole-archive' and `--no-whole-archive' options.
|
||||
# Otherwise, you may get some undesirable errors.
|
||||
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_tcxx -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,--gc-sections \
|
||||
-Wl,--version-script=enclave/enclave.lds \
|
||||
|
||||
Enclave_C_Objects := $(Enclave_C_Files:.c=.o)
|
||||
|
||||
Enclave_Name := enclave.so
|
||||
Signed_Enclave_Name := enclave.signed.so
|
||||
Enclave_Config_File := enclave/enclave.config.xml
|
||||
|
||||
ifeq ($(SGX_MODE), HW)
|
||||
ifeq ($(SGX_DEBUG), 1)
|
||||
Build_Mode = HW_DEBUG
|
||||
else ifeq ($(SGX_PRERELEASE), 1)
|
||||
Build_Mode = HW_PRERELEASE
|
||||
else
|
||||
Build_Mode = HW_RELEASE
|
||||
endif
|
||||
else
|
||||
ifeq ($(SGX_DEBUG), 1)
|
||||
Build_Mode = SIM_DEBUG
|
||||
else ifeq ($(SGX_PRERELEASE), 1)
|
||||
Build_Mode = SIM_PRERELEASE
|
||||
else
|
||||
Build_Mode = SIM_RELEASE
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: all run
|
||||
|
||||
ifeq ($(Build_Mode), HW_RELEASE)
|
||||
all: .config_$(Build_Mode)_$(SGX_ARCH) $(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."
|
||||
@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: .config_$(Build_Mode)_$(SGX_ARCH) $(App_Name) $(Signed_Enclave_Name)
|
||||
ifeq ($(Build_Mode), HW_DEBUG)
|
||||
@echo "The project has been built in debug hardware mode."
|
||||
else ifeq ($(Build_Mode), SIM_DEBUG)
|
||||
@echo "The project has been built in debug simulation mode."
|
||||
else ifeq ($(Build_Mode), HW_PRERELEASE)
|
||||
@echo "The project has been built in pre-release hardware mode."
|
||||
else ifeq ($(Build_Mode), SIM_PRERELEASE)
|
||||
@echo "The project has been built in pre-release simulation mode."
|
||||
else
|
||||
@echo "The project has been built in release simulation mode."
|
||||
endif
|
||||
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/%.c
|
||||
@$(CC) $(App_C_Flags) -c $< -o $@
|
||||
@echo "CC <= $<"
|
||||
|
||||
$(App_Name): app/enclave_u.o $(App_C_Objects)
|
||||
@$(CC) $^ -o $@ $(App_Link_Flags)
|
||||
@echo "LINK => $@"
|
||||
|
||||
.config_$(Build_Mode)_$(SGX_ARCH):
|
||||
@rm -f .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_C_Objects) app/enclave_u.* $(Enclave_C_Objects) enclave/enclave_t.*
|
||||
@touch .config_$(Build_Mode)_$(SGX_ARCH)
|
||||
|
||||
######## 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/%.c
|
||||
@$(CC) $(Enclave_C_Flags) -c $< -o $@
|
||||
@echo "CC <= $<"
|
||||
|
||||
$(Enclave_Name): enclave/enclave_t.o $(Enclave_C_Objects)
|
||||
@$(CC) $^ -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 .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_C_Objects) app/enclave_u.* $(Enclave_C_Objects) enclave/enclave_t.*
|
||||
143
Assignment 7 - SGX Hands-on/src/app/embedded_device.c
Normal file
143
Assignment 7 - SGX Hands-on/src/app/embedded_device.c
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "util.h"
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/core_names.h>
|
||||
|
||||
#include "embedded_device.h"
|
||||
|
||||
#define BUFSIZE 16384
|
||||
|
||||
typedef struct {
|
||||
uint8_t *firmware_path;
|
||||
uint8_t *public_key_path;
|
||||
} embedded_device_args;
|
||||
|
||||
char *embedded_device_syntax(void) {
|
||||
return
|
||||
"embedded mock up implementation of a embedded device\n"
|
||||
" -ppub <path> file path of the PEM encoded public key of the proxy\n"
|
||||
" -firm <path> path of to firmware binary\n";
|
||||
}
|
||||
|
||||
/*
|
||||
* read secp256r1 public key and return it as EVP_PKEY*
|
||||
*/
|
||||
static EVP_PKEY *read_public_key(char *public_key_file_path, EVP_PKEY **key) {
|
||||
if(public_key_file_path == NULL) {
|
||||
fprintf(stderr, "public_key_file_path is a null pointer!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE *fd = fopen(public_key_file_path, "rb");
|
||||
if(fd == NULL) {
|
||||
fprintf(stderr, "failed to open public key file!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*key = PEM_read_PUBKEY(fd, key, NULL, NULL);
|
||||
fclose(fd);
|
||||
|
||||
return *key;
|
||||
}
|
||||
|
||||
/*
|
||||
* hash the firmware
|
||||
*/
|
||||
static void hash_firmware(uint8_t *firmware_path, EVP_MD_CTX **ctx) {
|
||||
if(firmware_path == NULL) {
|
||||
fprintf(stderr, "firmware_path is a null pointer!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *fd = fopen(firmware_path, "rb");
|
||||
if(fd == NULL) {
|
||||
fprintf(stderr, "failed to open firmware!\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
size_t size;
|
||||
uint8_t buf[BUFSIZE];
|
||||
while((size = fread(buf, 1, BUFSIZE, fd)) != 0) {
|
||||
EVP_DigestVerifyUpdate(*ctx, buf, size);
|
||||
}
|
||||
|
||||
exit: fclose(fd);
|
||||
}
|
||||
|
||||
int handle_embedded_device(int argc, char **argv) {
|
||||
uint8_t status = EXIT_SUCCESS;
|
||||
embedded_device_args args = {
|
||||
.firmware_path = NULL,
|
||||
.public_key_path = NULL
|
||||
};
|
||||
|
||||
// parse parameters
|
||||
for(int i = 0; i < argc; i += 2) {
|
||||
if((strcmp(argv[i], "-ppub") == 0) && (argc - i >= 2)) {
|
||||
args.public_key_path = argv[i+1];
|
||||
} else if((strcmp(argv[i], "-firm") == 0) && (argc - i >= 2)) {
|
||||
args.firmware_path = argv[i+1];
|
||||
} else {
|
||||
syntax_exit();
|
||||
}
|
||||
}
|
||||
|
||||
// handle invalid parameters
|
||||
if((args.firmware_path == NULL) || (args.public_key_path == NULL)) {
|
||||
fprintf(stderr, "failed to parse arguments");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// read the public key of the enclave
|
||||
// normally, key would be hardcoded during production
|
||||
EVP_PKEY *key = NULL;
|
||||
if(read_public_key(args.public_key_path, &key) == NULL) {
|
||||
fprintf(stderr, "failed to import public key");
|
||||
status = EXIT_FAILURE;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
// initialize the context
|
||||
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
|
||||
if (EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, key) != 1) {
|
||||
fprintf(stderr, "failed to initialize context\n");
|
||||
status = EXIT_FAILURE;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
// read the firmwares signature
|
||||
uint8_t signature[BUFSIZE] = {0};
|
||||
size_t signature_size = read(0, signature, BUFSIZE);
|
||||
if(signature_size < 70) {
|
||||
fprintf(stderr, "failed to read firmware signature\n");
|
||||
status = EXIT_FAILURE;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
// hash the firmware and verify the signature
|
||||
hash_firmware(args.firmware_path, &ctx);
|
||||
if (EVP_DigestVerifyFinal(ctx, signature, signature_size) != 1) {
|
||||
fprintf(stderr, "failed to verify firmware signature or signature invalid\n");
|
||||
status = EXIT_FAILURE;
|
||||
}else {
|
||||
printf("Firmware is valid! Update starts in 5 4 3...\n");
|
||||
}
|
||||
|
||||
// cleanup
|
||||
clean: ;
|
||||
if(key != NULL)
|
||||
EVP_PKEY_free(key);
|
||||
if(ctx != NULL)
|
||||
EVP_MD_CTX_free(ctx);
|
||||
|
||||
return status;
|
||||
}
|
||||
23
Assignment 7 - SGX Hands-on/src/app/embedded_device.h
Normal file
23
Assignment 7 - SGX Hands-on/src/app/embedded_device.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef EMBEDDED_DEVICE_H
|
||||
#define EMBEDDED_DEVICE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* @brief getter for embedded subcommand syntax string
|
||||
*
|
||||
* @returns null-terminated syntax string
|
||||
*/
|
||||
char *embedded_device_syntax(void);
|
||||
|
||||
/*
|
||||
* @brief CLI implementation for the "embedded" subcommand
|
||||
*
|
||||
* @param argc number of arguments with command and subcommand stripped
|
||||
* @param argv arguments with command and subcommand stripped
|
||||
*
|
||||
* @returns 0 on success, else error with output on stderr
|
||||
*/
|
||||
int handle_embedded_device(int argc, char **argv);
|
||||
|
||||
#endif
|
||||
135
Assignment 7 - SGX Hands-on/src/app/employee.c
Normal file
135
Assignment 7 - SGX Hands-on/src/app/employee.c
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
#include <errno.h>
|
||||
#include <sgx_urts.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "employee.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#define HASH_BYTES 32
|
||||
#define HASH_CHUNK_BYTES 32
|
||||
#define KEY_BYTES 32
|
||||
|
||||
struct EmployeeArgs {
|
||||
char* key_path;
|
||||
char* firmware_path;
|
||||
};
|
||||
|
||||
char* employee_syntax(void) {
|
||||
return
|
||||
"employee mock up implementation of the employee binary\n"
|
||||
" outputs signature on stdout\n"
|
||||
" WARNING: output is in binary format, may mess up terminal\n"
|
||||
" -ekey <path> file path of the PEM encoded private key of the employee\n"
|
||||
" -firm <path> path of the firmware\n";
|
||||
}
|
||||
|
||||
int handle_employee(int argc, char** argv) {
|
||||
struct EmployeeArgs args = {
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
FILE* key_file = NULL;
|
||||
uint8_t* firmware_buf;
|
||||
size_t firmware_len;
|
||||
EVP_PKEY* key = NULL;
|
||||
EVP_MD_CTX *mdctx = NULL;
|
||||
size_t sig_len;
|
||||
unsigned char* sig = NULL;
|
||||
|
||||
/*
|
||||
* Parse Input
|
||||
*/
|
||||
|
||||
int i = 0;
|
||||
while(i < argc) {
|
||||
if(strcmp(argv[i], "-ekey")==0 && argc-i >=2){
|
||||
args.key_path = argv[i+1];
|
||||
i += 2;
|
||||
}else if(strcmp(argv[i], "-firm")==0 && argc-i >=2){
|
||||
args.firmware_path = argv[i+1];
|
||||
i += 2;
|
||||
}else
|
||||
syntax_exit();
|
||||
}
|
||||
|
||||
if(args.key_path == NULL)
|
||||
syntax_exit();
|
||||
|
||||
/*
|
||||
* Load Signing Key
|
||||
*/
|
||||
|
||||
key_file = fopen(args.key_path, "rb");
|
||||
if(key_file == NULL){
|
||||
perror("Error opening key file");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
key = PEM_read_PrivateKey(key_file, &key, NULL, NULL);
|
||||
if(key == NULL) {
|
||||
fprintf(stderr, "failed to read key\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fclose(key_file);
|
||||
|
||||
/*
|
||||
* Sign Firmware
|
||||
*/
|
||||
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
if (EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, key) != 1) {
|
||||
fprintf(stderr, "Message digest initialization failed.\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (load_file(args.firmware_path, &firmware_buf, &firmware_len) != 0) {
|
||||
fprintf(stderr, "failed to read firmware\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (EVP_DigestSignUpdate(mdctx, firmware_buf, firmware_len) != 1) {
|
||||
printf("Message digest update failed.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
free(firmware_buf);
|
||||
|
||||
// call with empty sig to get length
|
||||
if (EVP_DigestSignFinal(mdctx, NULL, &sig_len) != 1) {
|
||||
printf("Message digest finalization failed.\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// allocate signature buffer
|
||||
sig = malloc(sizeof(unsigned char) * sig_len);
|
||||
if(sig == NULL){
|
||||
perror("could not initialize digest buffer");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// load signature into buffer
|
||||
if (EVP_DigestSignFinal(mdctx, sig, &sig_len) != 1) {
|
||||
printf("Message digest finalization failed.\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fwrite(sig, sig_len, 1, stdout);
|
||||
if (ferror(stdout) != 0) {
|
||||
fprintf(stdout, "failed to write signature to stdout\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
// free all allocated resources
|
||||
free(sig);
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
EVP_PKEY_free(key);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
23
Assignment 7 - SGX Hands-on/src/app/employee.h
Normal file
23
Assignment 7 - SGX Hands-on/src/app/employee.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _APP_INTERMEDIARY_H_
|
||||
#define _APP_INTERMEDIARY_H_
|
||||
|
||||
|
||||
/*
|
||||
* @brief getter for employee subcommand syntax string
|
||||
*
|
||||
* @returns null-terminated syntax string
|
||||
*/
|
||||
char* employee_syntax(void);
|
||||
|
||||
/*
|
||||
* @brief CLI implementation for the "employee" subcommand
|
||||
*
|
||||
* @param argc number of arguments with command and subcommand stripped
|
||||
* @param argv arguments with command and subcommand stripped
|
||||
*
|
||||
* @returns 0 on success, else error with output on stderr
|
||||
*/
|
||||
int handle_employee(int argc, char** argv);
|
||||
|
||||
|
||||
#endif
|
||||
33
Assignment 7 - SGX Hands-on/src/app/main.c
Normal file
33
Assignment 7 - SGX Hands-on/src/app/main.c
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "embedded_device.h"
|
||||
#include "employee.h"
|
||||
#include "proxy.h"
|
||||
#include "proxysetup.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
/*
|
||||
* main method of the binary calls the implementation of the specified subcommand
|
||||
*/
|
||||
int main(int argc, char** argv) {
|
||||
if(argc < 1)
|
||||
syntax_exit();
|
||||
set_bin_name(argv[0]);
|
||||
if(argc < 2)
|
||||
syntax_exit();
|
||||
|
||||
char* command = argv[1];
|
||||
|
||||
if(strcmp(command, "employee")==0)
|
||||
handle_employee(argc-2, argv+2);
|
||||
else if (strcmp(command, "proxy")==0)
|
||||
handle_proxy(argc-2, argv+2);
|
||||
else if (strcmp(command, "proxysetup")==0)
|
||||
handle_proxysetup(argc-2, argv+2);
|
||||
else if (strcmp(command, "embedded")==0)
|
||||
handle_embedded_device(argc-2, argv+2);
|
||||
else
|
||||
syntax_exit();
|
||||
}
|
||||
435
Assignment 7 - SGX Hands-on/src/app/proxy.c
Normal file
435
Assignment 7 - SGX Hands-on/src/app/proxy.c
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
#include <errno.h>
|
||||
#include <sgx_urts.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/param_build.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#include <sgx_tcrypto.h>
|
||||
|
||||
#include "enclave_u.h"
|
||||
#include "proxy.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
struct ProxyArgs {
|
||||
char* sealed_key_file_path;
|
||||
char* sgx_token_path;
|
||||
char* employee_public_key_path;
|
||||
char* firmware_path;
|
||||
};
|
||||
|
||||
char* proxy_syntax(void) {
|
||||
return
|
||||
"proxy implementation of the enclave-powered SignatureProxy\n"
|
||||
" expects intermediary signature on stdin\n"
|
||||
" outputs proxied signature on stdout\n"
|
||||
" WARNING: output is binary format, may mess up terminal\n"
|
||||
" -pkey <path> file path of the sealed proxy key\n"
|
||||
" -epub <path> path of the PEM encoded employee public key\n"
|
||||
" -firm <path> path of the firmware\n"
|
||||
" -token <path> (optional) file path of the sgx token\n";
|
||||
}
|
||||
|
||||
static EVP_PKEY *sgx_public_to_EVP_PKEY(const sgx_ec256_public_t *p_public)
|
||||
{
|
||||
EVP_PKEY *evp_key = NULL;
|
||||
EVP_PKEY_CTX *pkey_ctx = NULL;
|
||||
BIGNUM *bn_pub_x = NULL;
|
||||
BIGNUM *bn_pub_y = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
EC_GROUP* group = NULL;
|
||||
OSSL_PARAM_BLD *params_build = NULL;
|
||||
OSSL_PARAM *params = NULL;
|
||||
const char *curvename = NULL;
|
||||
int nid = 0;
|
||||
size_t key_len;
|
||||
unsigned char pub_key[SGX_ECP256_KEY_SIZE+4];
|
||||
|
||||
group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
|
||||
if (group == NULL)
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
// converts the x value of public key, represented as positive integer in little-endian into a BIGNUM
|
||||
bn_pub_x = BN_lebin2bn((unsigned char*)p_public->gx, sizeof(p_public->gx), bn_pub_x);
|
||||
if (NULL == bn_pub_x) {
|
||||
break;
|
||||
}
|
||||
// converts the y value of public key, represented as positive integer in little-endian into a BIGNUM
|
||||
bn_pub_y = BN_lebin2bn((unsigned char*)p_public->gy, sizeof(p_public->gy), bn_pub_y);
|
||||
if (NULL == bn_pub_y) {
|
||||
break;
|
||||
}
|
||||
// creates new point and assigned the group object that the point relates to
|
||||
point = EC_POINT_new(group);
|
||||
if (NULL == point) {
|
||||
break;
|
||||
}
|
||||
|
||||
// sets point based on public key's x,y coordinates
|
||||
if (1 != EC_POINT_set_affine_coordinates(group, point, bn_pub_x, bn_pub_y, NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// check point if the point is on curve
|
||||
if (1 != EC_POINT_is_on_curve(group, point, NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// convert point to octet string
|
||||
key_len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, pub_key, sizeof(pub_key), NULL);
|
||||
if (key_len == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// build OSSL_PARAM
|
||||
params_build = OSSL_PARAM_BLD_new();
|
||||
if (NULL == params_build) {
|
||||
break;
|
||||
}
|
||||
nid = EC_GROUP_get_curve_name(group);
|
||||
if (nid == NID_undef) {
|
||||
break;
|
||||
}
|
||||
curvename = OBJ_nid2sn(nid);
|
||||
if (curvename == NULL) {
|
||||
break;
|
||||
}
|
||||
if (1 != OSSL_PARAM_BLD_push_utf8_string(params_build, "group", curvename, 0)) {
|
||||
break;
|
||||
}
|
||||
if (1 != OSSL_PARAM_BLD_push_octet_string(params_build, OSSL_PKEY_PARAM_PUB_KEY, pub_key, key_len)) {
|
||||
break;
|
||||
}
|
||||
params = OSSL_PARAM_BLD_to_param(params_build);
|
||||
if (NULL == params) {
|
||||
break;
|
||||
}
|
||||
|
||||
// get pkey from params
|
||||
pkey_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
|
||||
if (NULL == pkey_ctx) {
|
||||
break;
|
||||
}
|
||||
if (1 != EVP_PKEY_fromdata_init(pkey_ctx)) {
|
||||
break;
|
||||
}
|
||||
if (1 != EVP_PKEY_fromdata(pkey_ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params)) {
|
||||
EVP_PKEY_free(evp_key);
|
||||
evp_key = NULL;
|
||||
}
|
||||
} while(0);
|
||||
|
||||
BN_clear_free(bn_pub_x);
|
||||
BN_clear_free(bn_pub_y);
|
||||
EC_POINT_clear_free(point);
|
||||
OSSL_PARAM_free(params);
|
||||
OSSL_PARAM_BLD_free(params_build);
|
||||
EVP_PKEY_CTX_free(pkey_ctx);
|
||||
EC_GROUP_free(group);
|
||||
|
||||
return evp_key;
|
||||
}
|
||||
|
||||
static int EVP_PKEY_to_sgx_public(EVP_PKEY* ecdsa_key, sgx_ec256_public_t* sgx_public) {
|
||||
EC_GROUP* group = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
BIGNUM* pub_x = NULL;
|
||||
BIGNUM* pub_y = NULL;
|
||||
size_t ec_key_buf_len = 0;
|
||||
unsigned char ec_key_buf[1024];
|
||||
int ret;
|
||||
int retval;
|
||||
|
||||
group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
|
||||
if (group == NULL)
|
||||
return 1;
|
||||
|
||||
point = EC_POINT_new(group);
|
||||
if (point == NULL)
|
||||
return 2;
|
||||
|
||||
ret = EVP_PKEY_get_octet_string_param(ecdsa_key, OSSL_PKEY_PARAM_PUB_KEY, ec_key_buf, 1024, &ec_key_buf_len);
|
||||
if (ret != 1)
|
||||
return 3;
|
||||
|
||||
ret = EC_POINT_oct2point(group, point, ec_key_buf, ec_key_buf_len, NULL);
|
||||
if (ret != 1){
|
||||
retval = 4;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
pub_x = BN_new();
|
||||
pub_y = BN_new();
|
||||
|
||||
ret = EC_POINT_get_affine_coordinates(group, point, pub_x, pub_y, NULL);
|
||||
if (ret != 1){
|
||||
retval = 5;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = BN_bn2lebinpad(pub_x, sgx_public->gx, SGX_ECP256_KEY_SIZE);
|
||||
if (ret == -1){
|
||||
retval = 6;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = BN_bn2lebinpad(pub_y, sgx_public->gy, SGX_ECP256_KEY_SIZE);
|
||||
if (ret == -1){
|
||||
retval = 7;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
|
||||
cleanup:
|
||||
if (pub_x != NULL)
|
||||
BN_clear_free(pub_x);
|
||||
if (pub_y != NULL)
|
||||
BN_clear_free(pub_y);
|
||||
if (point != NULL)
|
||||
EC_POINT_clear_free(point);
|
||||
if (group != NULL)
|
||||
EC_GROUP_free(group);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static int ECDSA_SIG_to_sgx_signature(ECDSA_SIG* ecdsa_sig, sgx_ec256_signature_t* sgx_signature) {
|
||||
const BIGNUM* r = NULL;
|
||||
const BIGNUM* s = NULL;
|
||||
int ret;
|
||||
|
||||
r = ECDSA_SIG_get0_r(ecdsa_sig);
|
||||
s = ECDSA_SIG_get0_s(ecdsa_sig);
|
||||
|
||||
ret = BN_bn2lebinpad(r, (unsigned char*)sgx_signature->x, SGX_ECP256_KEY_SIZE);
|
||||
if (ret == -1)
|
||||
return (1);
|
||||
|
||||
ret = BN_bn2lebinpad(s, (unsigned char*)sgx_signature->y, SGX_ECP256_KEY_SIZE);
|
||||
if (ret == -1)
|
||||
return (2);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is a modified version of the `sgx_ecdsa_verify_hash` function in the [Intel SGX crypto library](https://github.com/intel/linux-sgx/blob/main/sdk/tlibcrypto/sgxssl/sgx_ecc256_ecdsa.cpp).
|
||||
* The specified License applies.
|
||||
*/
|
||||
static int sgx_signature_to_ECDSA_SIG(sgx_ec256_signature_t* sgx_signature, ECDSA_SIG** ecdsa_signature) {
|
||||
BIGNUM *bn_r = NULL;
|
||||
BIGNUM *bn_s = NULL;
|
||||
|
||||
// converts the x value of the signature, represented as positive integer in little-endian into a BIGNUM
|
||||
//
|
||||
bn_r = BN_lebin2bn((unsigned char*)sgx_signature->x, sizeof(sgx_signature->x), 0);
|
||||
if (bn_r == NULL)
|
||||
return (1);
|
||||
|
||||
|
||||
// converts the y value of the signature, represented as positive integer in little-endian into a BIGNUM
|
||||
//
|
||||
bn_s = BN_lebin2bn((unsigned char*)sgx_signature->y, sizeof(sgx_signature->y), 0);
|
||||
if (NULL == bn_s) {
|
||||
if (bn_r != NULL)
|
||||
BN_clear_free(bn_r);
|
||||
|
||||
return (2);
|
||||
}
|
||||
|
||||
|
||||
// allocates a new ECDSA_SIG structure (note: this function also allocates the BIGNUMs) and initialize it
|
||||
//
|
||||
*ecdsa_signature = ECDSA_SIG_new();
|
||||
if (NULL == *ecdsa_signature) {
|
||||
if (bn_r != NULL)
|
||||
BN_clear_free(bn_r);
|
||||
if (bn_s != NULL)
|
||||
BN_clear_free(bn_s);
|
||||
|
||||
return (3);
|
||||
}
|
||||
|
||||
// setes the r and s values of ecdsa_sig
|
||||
// calling this function transfers the memory management of the values to the ECDSA_SIG object,
|
||||
// and therefore the values that have been passed in should not be freed directly after this function has been called
|
||||
//
|
||||
if (1 != ECDSA_SIG_set0(*ecdsa_signature, bn_r, bn_s)) {
|
||||
ECDSA_SIG_free(*ecdsa_signature);
|
||||
*ecdsa_signature = NULL;
|
||||
|
||||
if (bn_r != NULL)
|
||||
BN_clear_free(bn_r);
|
||||
|
||||
if (bn_s != NULL)
|
||||
BN_clear_free(bn_s);
|
||||
|
||||
return (4);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int handle_proxy(int argc, char** argv) {
|
||||
struct ProxyArgs args = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
uint8_t* sealed;
|
||||
size_t sealed_len;
|
||||
uint8_t* firmware;
|
||||
size_t firmware_len;
|
||||
unsigned char* ecdsa_signature_data;
|
||||
size_t ecdsa_signature_size = 0;
|
||||
uint8_t signature[70];
|
||||
sgx_status_t ret;
|
||||
ECDSA_SIG* ecdsa_signature;
|
||||
sgx_ec256_signature_t sgx_signature;
|
||||
|
||||
/*
|
||||
* Parse Input
|
||||
*/
|
||||
|
||||
int i = 0;
|
||||
while(i < argc) {
|
||||
if(strcmp(argv[i], "-pkey")==0 && argc-i >=2){
|
||||
args.sealed_key_file_path = argv[i+1];
|
||||
i += 2;
|
||||
}else if(strcmp(argv[i], "-token")==0 && argc-i >=2){
|
||||
args.sgx_token_path = argv[i+1];
|
||||
i += 2;
|
||||
}else if(strcmp(argv[i], "-epub")==0 && argc-i >=2){
|
||||
args.employee_public_key_path = argv[i+1];
|
||||
i += 2;
|
||||
}else if(strcmp(argv[i], "-firm")==0 && argc-i >=2){
|
||||
args.firmware_path = argv[i+1];
|
||||
i += 2;
|
||||
}else
|
||||
syntax_exit();
|
||||
}
|
||||
|
||||
if(args.sealed_key_file_path == NULL || args.employee_public_key_path == NULL || args.firmware_path == NULL)
|
||||
syntax_exit();
|
||||
|
||||
/*
|
||||
* Read And Parse Signature Input
|
||||
*/
|
||||
|
||||
ecdsa_signature_data = malloc(1024);
|
||||
if (ecdsa_signature_data == NULL) {
|
||||
perror("failed to allocate signature");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ecdsa_signature_size = fread(ecdsa_signature_data, 1, 1024, stdin);
|
||||
|
||||
if (ferror(stdin) != 0) {
|
||||
fprintf(stderr, "failed to read signature from stdin\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ecdsa_signature = ECDSA_SIG_new();
|
||||
ecdsa_signature = d2i_ECDSA_SIG(&ecdsa_signature, (const unsigned char**)&ecdsa_signature_data, ecdsa_signature_size);
|
||||
ecdsa_signature_data = NULL;
|
||||
if (ecdsa_signature == NULL) {
|
||||
fprintf(stderr, "failed to read signature\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (ECDSA_SIG_to_sgx_signature(ecdsa_signature, &sgx_signature) != 0) {
|
||||
fprintf(stderr, "failed to transform signature\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
ECDSA_SIG_free(ecdsa_signature);
|
||||
ecdsa_signature = NULL;
|
||||
|
||||
|
||||
// Initialize SGX Enclave
|
||||
if (initialize_enclave(args.sgx_token_path) != 0)
|
||||
exit(1);
|
||||
|
||||
/*
|
||||
* Read Employee Public Key
|
||||
*/
|
||||
|
||||
EVP_PKEY* key = NULL;
|
||||
FILE* key_file = fopen(args.employee_public_key_path, "rb");
|
||||
if(key_file == NULL){
|
||||
perror("Error opening employee public key file");
|
||||
exit(1);
|
||||
}
|
||||
key = PEM_read_PUBKEY(key_file, &key, NULL, NULL);
|
||||
if(key == NULL) {
|
||||
fprintf(stderr, "failed to read employee public key\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
fclose(key_file);
|
||||
|
||||
sgx_ec256_public_t sgx_public;
|
||||
if (EVP_PKEY_to_sgx_public(key, &sgx_public) != 0) {
|
||||
fprintf(stderr, "failed transform employee public key\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
//Read Sealed Proxy Keypair
|
||||
if (load_file(args.sealed_key_file_path, &sealed, &sealed_len)!=0){
|
||||
fprintf(stderr, "failed to read sealed key\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Read Firmware
|
||||
if (load_file(args.firmware_path, &firmware, &firmware_len)!=0){
|
||||
fprintf(stderr, "failed to read firmware\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use Enclave To Resign the Firmware
|
||||
*/
|
||||
|
||||
sign_firmware(get_global_eid(), &ret, firmware, firmware_len, sealed, sealed_len, (uint8_t*)&sgx_public, (uint8_t*)&sgx_signature);
|
||||
if (ret != SGX_SUCCESS) {
|
||||
sgx_print_error_message(ret);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
free(sealed);
|
||||
free(firmware);
|
||||
|
||||
/*
|
||||
* Output Signature
|
||||
*/
|
||||
if (sgx_signature_to_ECDSA_SIG(&sgx_signature, &ecdsa_signature) != 0) {
|
||||
fprintf(stderr, "could not convert signature\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ecdsa_signature_data = NULL;
|
||||
ecdsa_signature_size = i2d_ECDSA_SIG(ecdsa_signature, &ecdsa_signature_data);
|
||||
if (ecdsa_signature_size <= 0) {
|
||||
fprintf(stderr, "could not convert signature\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fwrite(ecdsa_signature_data, ecdsa_signature_size, 1, stdout);
|
||||
|
||||
if (ferror(stdout) != 0) {
|
||||
fprintf(stderr, "could not write signature to stdout\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
free(ecdsa_signature_data);
|
||||
ECDSA_SIG_free(ecdsa_signature);
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
23
Assignment 7 - SGX Hands-on/src/app/proxy.h
Normal file
23
Assignment 7 - SGX Hands-on/src/app/proxy.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _APP_PROXY_H_
|
||||
#define _APP_PROXY_H_
|
||||
|
||||
|
||||
/*
|
||||
* @brief getter for proxy subcommand syntax string
|
||||
*
|
||||
* @returns null-terminated syntax string
|
||||
*/
|
||||
char* proxy_syntax(void);
|
||||
|
||||
/*
|
||||
* @brief CLI implementation for the "proxy" subcommand
|
||||
*
|
||||
* @param argc number of arguments with command and subcommand stripped
|
||||
* @param argv arguments with command and subcommand stripped
|
||||
*
|
||||
* @returns 0 on success, else error with output on stderr
|
||||
*/
|
||||
int handle_proxy(int argc, char** argv);
|
||||
|
||||
|
||||
#endif
|
||||
237
Assignment 7 - SGX Hands-on/src/app/proxysetup.c
Normal file
237
Assignment 7 - SGX Hands-on/src/app/proxysetup.c
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
#include <errno.h>
|
||||
#include <sgx_urts.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/param_build.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#include <sgx_tcrypto.h>
|
||||
|
||||
#include "enclave_u.h"
|
||||
#include "proxysetup.h"
|
||||
#include "util.h"
|
||||
|
||||
struct ProxysetupArgs {
|
||||
char* sealed_key_file_path;
|
||||
char* sgx_token_path;
|
||||
};
|
||||
|
||||
char* proxysetup_syntax(void) {
|
||||
return
|
||||
"proxysetup implementation of the enclave-powered SignatureProxy\n"
|
||||
" outputs public key on stdout\n"
|
||||
" -pkey <path> file path of the sealed proxy key\n"
|
||||
" -token <path> (optional) file path of the sgx token\n";
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is a modified version of the `get_pub_key_from_coords` function in the [Intel SGX crypto library](https://github.com/intel/linux-sgx/blob/c1ceb4fe146e0feb1097dee81c7e89925443e43c/sdk/tlibcrypto/sgxssl/sgx_ecc256.cpp).
|
||||
* The specified License applies.
|
||||
*/
|
||||
static EVP_PKEY *sgx_public_to_EVP_PKEY(const sgx_ec256_public_t *p_public)
|
||||
{
|
||||
EVP_PKEY *evp_key = NULL;
|
||||
EVP_PKEY_CTX *pkey_ctx = NULL;
|
||||
BIGNUM *bn_pub_x = NULL;
|
||||
BIGNUM *bn_pub_y = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
EC_GROUP* group = NULL;
|
||||
OSSL_PARAM_BLD *params_build = NULL;
|
||||
OSSL_PARAM *params = NULL;
|
||||
const char *curvename = NULL;
|
||||
int nid = 0;
|
||||
size_t key_len;
|
||||
unsigned char pub_key[SGX_ECP256_KEY_SIZE+4];
|
||||
|
||||
group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
|
||||
if (group == NULL)
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
// converts the x value of public key, represented as positive integer in little-endian into a BIGNUM
|
||||
bn_pub_x = BN_lebin2bn((unsigned char*)p_public->gx, sizeof(p_public->gx), bn_pub_x);
|
||||
if (NULL == bn_pub_x) {
|
||||
break;
|
||||
}
|
||||
// converts the y value of public key, represented as positive integer in little-endian into a BIGNUM
|
||||
bn_pub_y = BN_lebin2bn((unsigned char*)p_public->gy, sizeof(p_public->gy), bn_pub_y);
|
||||
if (NULL == bn_pub_y) {
|
||||
break;
|
||||
}
|
||||
// creates new point and assigned the group object that the point relates to
|
||||
point = EC_POINT_new(group);
|
||||
if (NULL == point) {
|
||||
break;
|
||||
}
|
||||
|
||||
// sets point based on public key's x,y coordinates
|
||||
if (1 != EC_POINT_set_affine_coordinates(group, point, bn_pub_x, bn_pub_y, NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// check point if the point is on curve
|
||||
if (1 != EC_POINT_is_on_curve(group, point, NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// convert point to octet string
|
||||
key_len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, pub_key, sizeof(pub_key), NULL);
|
||||
if (key_len == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// build OSSL_PARAM
|
||||
params_build = OSSL_PARAM_BLD_new();
|
||||
if (NULL == params_build) {
|
||||
break;
|
||||
}
|
||||
nid = EC_GROUP_get_curve_name(group);
|
||||
if (nid == NID_undef) {
|
||||
break;
|
||||
}
|
||||
curvename = OBJ_nid2sn(nid);
|
||||
if (curvename == NULL) {
|
||||
break;
|
||||
}
|
||||
if (1 != OSSL_PARAM_BLD_push_utf8_string(params_build, "group", curvename, 0)) {
|
||||
break;
|
||||
}
|
||||
if (1 != OSSL_PARAM_BLD_push_octet_string(params_build, OSSL_PKEY_PARAM_PUB_KEY, pub_key, key_len)) {
|
||||
break;
|
||||
}
|
||||
params = OSSL_PARAM_BLD_to_param(params_build);
|
||||
if (NULL == params) {
|
||||
break;
|
||||
}
|
||||
|
||||
// get pkey from params
|
||||
pkey_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
|
||||
if (NULL == pkey_ctx) {
|
||||
break;
|
||||
}
|
||||
if (1 != EVP_PKEY_fromdata_init(pkey_ctx)) {
|
||||
break;
|
||||
}
|
||||
if (1 != EVP_PKEY_fromdata(pkey_ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params)) {
|
||||
EVP_PKEY_free(evp_key);
|
||||
evp_key = NULL;
|
||||
}
|
||||
} while(0);
|
||||
|
||||
BN_clear_free(bn_pub_x);
|
||||
BN_clear_free(bn_pub_y);
|
||||
EC_POINT_clear_free(point);
|
||||
OSSL_PARAM_free(params);
|
||||
OSSL_PARAM_BLD_free(params_build);
|
||||
EVP_PKEY_CTX_free(pkey_ctx);
|
||||
EC_GROUP_free(group);
|
||||
|
||||
return evp_key;
|
||||
}
|
||||
|
||||
int handle_proxysetup(int argc, char** argv) {
|
||||
struct ProxysetupArgs args = {
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
FILE* sealed_file;
|
||||
int sealed_size;
|
||||
uint8_t* sealed;
|
||||
sgx_ec256_public_t sgx_public_key;
|
||||
EVP_PKEY* public_key;
|
||||
sgx_status_t sgx_ret;
|
||||
|
||||
/*
|
||||
* Parse Input
|
||||
*/
|
||||
|
||||
int i = 0;
|
||||
while(i < argc) {
|
||||
if(strcmp(argv[i], "-pkey")==0 && argc-i >=2){
|
||||
args.sealed_key_file_path = argv[i+1];
|
||||
i += 2;
|
||||
}else if(strcmp(argv[i], "-token")==0 && argc-i >=2){
|
||||
args.sgx_token_path = argv[i+1];
|
||||
i += 2;
|
||||
}else
|
||||
syntax_exit();
|
||||
}
|
||||
|
||||
if(args.sealed_key_file_path == NULL)
|
||||
syntax_exit();
|
||||
|
||||
/*
|
||||
* Initialize SGX Enclave
|
||||
*/
|
||||
|
||||
if (initialize_enclave(args.sgx_token_path) != 0)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
/*
|
||||
* Setup Sealed Keypair
|
||||
*/
|
||||
|
||||
sealed_file = fopen(args.sealed_key_file_path, "wb");
|
||||
if(sealed_file == NULL){
|
||||
perror("Error opening sealed_key_file file");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
sgx_ret = get_sealed_size(get_global_eid(), &sealed_size);
|
||||
if (sgx_ret != SGX_SUCCESS) {
|
||||
sgx_print_error_message(sgx_ret);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
sealed = malloc(sizeof(uint8_t)*sealed_size);
|
||||
if (sealed == NULL) {
|
||||
fprintf(stderr, "failed to allocate for sealed key");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use Enclave To Generate Keypair
|
||||
*/
|
||||
|
||||
generate_key_pair(get_global_eid(), &sgx_ret, sealed, sealed_size);
|
||||
if (sgx_ret != SGX_SUCCESS) {
|
||||
sgx_print_error_message(sgx_ret);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Store Sealed Keypair
|
||||
*/
|
||||
|
||||
if (fwrite(sealed, sealed_size, 1, sealed_file) != 1 || ferror(sealed_file) != 0) {
|
||||
fprintf(stderr, "failed to write sealed key");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
fflush(sealed_file);
|
||||
fclose(sealed_file);
|
||||
|
||||
/*
|
||||
* Fetch Public Key From Enclave And Print
|
||||
*/
|
||||
|
||||
get_public_key(get_global_eid(), &sgx_ret, sealed, sealed_size, (uint8_t*)&sgx_public_key);
|
||||
if (sgx_ret != SGX_SUCCESS) {
|
||||
sgx_print_error_message(sgx_ret);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
public_key = sgx_public_to_EVP_PKEY(&sgx_public_key);
|
||||
if (PEM_write_PUBKEY(stdout, public_key) != 1) {
|
||||
fprintf(stderr, "could not write publickey\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
EVP_PKEY_free(public_key);
|
||||
free(sealed);
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
23
Assignment 7 - SGX Hands-on/src/app/proxysetup.h
Normal file
23
Assignment 7 - SGX Hands-on/src/app/proxysetup.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _APP_PROXYSETUP_H_
|
||||
#define _APP_PROXYSETUP_H_
|
||||
|
||||
|
||||
/*
|
||||
* @brief getter for proxysetup subcommand syntax string
|
||||
*
|
||||
* @returns null-terminated syntax string
|
||||
*/
|
||||
char* proxysetup_syntax(void);
|
||||
|
||||
/*
|
||||
* @brief CLI implementation for the "proxysetup" subcommand
|
||||
*
|
||||
* @param argc number of arguments with command and subcommand stripped
|
||||
* @param argv arguments with command and subcommand stripped
|
||||
*
|
||||
* @returns 0 on success, else error with output on stderr
|
||||
*/
|
||||
int handle_proxysetup(int argc, char** argv);
|
||||
|
||||
|
||||
#endif
|
||||
247
Assignment 7 - SGX Hands-on/src/app/util.c
Normal file
247
Assignment 7 - SGX Hands-on/src/app/util.c
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "embedded_device.h"
|
||||
#include "employee.h"
|
||||
#include "util.h"
|
||||
#include "proxy.h"
|
||||
#include "proxysetup.h"
|
||||
|
||||
|
||||
static char* BIN_NAME = "SignatureProxy";
|
||||
|
||||
static sgx_enclave_id_t global_eid = 0;
|
||||
|
||||
void syntax_exit(void) {
|
||||
char* syntax =
|
||||
"SignatureProxy Version 0.0.0\n"
|
||||
"Syntax: %s <command> <arguments>\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
"%s"
|
||||
"\n"
|
||||
"%s"
|
||||
"\n"
|
||||
"%s"
|
||||
"\n"
|
||||
"%s";
|
||||
|
||||
printf(syntax, BIN_NAME, proxysetup_syntax(), employee_syntax(), proxy_syntax(), embedded_device_syntax());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void set_bin_name(char* bin_name) {
|
||||
BIN_NAME = bin_name;
|
||||
}
|
||||
/*
|
||||
* This definition is copied from the provided SGX Examples.
|
||||
* The specified License applies.
|
||||
*/
|
||||
typedef struct _sgx_errlist_t {
|
||||
sgx_status_t err;
|
||||
const char *msg;
|
||||
const char *sug; /* Suggestion */
|
||||
} sgx_errlist_t;
|
||||
|
||||
/*
|
||||
* This definition is copied from the provided SGX Examples.
|
||||
* The specified License applies.
|
||||
*/
|
||||
/* Error code returned by sgx_create_enclave */
|
||||
static sgx_errlist_t sgx_errlist[] = {
|
||||
{
|
||||
SGX_ERROR_UNEXPECTED,
|
||||
"Unexpected error occurred.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_INVALID_PARAMETER,
|
||||
"Invalid parameter.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_OUT_OF_MEMORY,
|
||||
"Out of memory.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_ENCLAVE_LOST,
|
||||
"Power transition occurred.",
|
||||
"Please refer to the sample \"PowerTransition\" for details."
|
||||
},
|
||||
{
|
||||
SGX_ERROR_INVALID_ENCLAVE,
|
||||
"Invalid enclave image.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_INVALID_ENCLAVE_ID,
|
||||
"Invalid enclave identification.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_INVALID_SIGNATURE,
|
||||
"Invalid enclave signature.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_OUT_OF_EPC,
|
||||
"Out of EPC memory.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_NO_DEVICE,
|
||||
"Invalid SGX device.",
|
||||
"Please make sure SGX module is enabled in the BIOS, and install SGX driver afterwards."
|
||||
},
|
||||
{
|
||||
SGX_ERROR_MEMORY_MAP_CONFLICT,
|
||||
"Memory map conflicted.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_INVALID_METADATA,
|
||||
"Invalid enclave metadata.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_DEVICE_BUSY,
|
||||
"SGX device was busy.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_INVALID_VERSION,
|
||||
"Enclave version was invalid.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_INVALID_ATTRIBUTE,
|
||||
"Enclave was not authorized.",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
SGX_ERROR_ENCLAVE_FILE_ACCESS,
|
||||
"Can't open enclave file.",
|
||||
NULL
|
||||
},
|
||||
};
|
||||
/*
|
||||
* This Method is copied from the provided SGX Examples.
|
||||
* The specified License applies.
|
||||
*/
|
||||
/* Check error conditions for loading enclave */
|
||||
void sgx_print_error_message(sgx_status_t ret)
|
||||
{
|
||||
size_t idx = 0;
|
||||
size_t ttl = sizeof sgx_errlist/sizeof sgx_errlist[0];
|
||||
|
||||
for (idx = 0; idx < ttl; idx++) {
|
||||
if(ret == sgx_errlist[idx].err) {
|
||||
if(NULL != sgx_errlist[idx].sug)
|
||||
printf("Info: %s\n", sgx_errlist[idx].sug);
|
||||
printf("Error: %s\n", sgx_errlist[idx].msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == ttl)
|
||||
printf("Error code is 0x%X. Please refer to the \"Intel SGX SDK Developer Reference\" for more details.\n", ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This Method is copied from the provided SGX Examples.
|
||||
* The specified License applies.
|
||||
*/
|
||||
int initialize_enclave(char* token_path) {
|
||||
FILE* sgx_token_file = NULL;
|
||||
sgx_launch_token_t token = {0};
|
||||
sgx_status_t ret;
|
||||
int updated = 0;
|
||||
|
||||
if (token_path != NULL) {
|
||||
sgx_token_file = fopen(token_path, "rb");
|
||||
}
|
||||
|
||||
if(sgx_token_file == NULL){
|
||||
if (errno != ENOENT && token_path != NULL) {
|
||||
perror("Error opening sgx token file");
|
||||
exit(1);
|
||||
}
|
||||
}else{
|
||||
size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), sgx_token_file);
|
||||
if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
|
||||
fprintf(stderr, "sgx token file is corrupted");
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
ret = sgx_create_enclave("enclave.signed.so", SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL);
|
||||
if (ret != SGX_SUCCESS) {
|
||||
sgx_print_error_message(ret);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (updated && token_path != NULL) {
|
||||
sgx_token_file = freopen(token_path, "wb", sgx_token_file);
|
||||
if(sgx_token_file == NULL){
|
||||
perror("Error opening sgx token file");
|
||||
return (1);
|
||||
}
|
||||
size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), sgx_token_file);
|
||||
if (write_num != sizeof(sgx_launch_token_t)){
|
||||
fprintf(stderr,"Warning: Failed to save launch token to \"%s\".\n", token_path);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
sgx_enclave_id_t get_global_eid(void){
|
||||
return global_eid;
|
||||
}
|
||||
|
||||
int load_file(const char* path, uint8_t** data, size_t* data_len) {
|
||||
FILE* file;
|
||||
size_t file_size;
|
||||
uint8_t* buf;
|
||||
|
||||
int file_des = open(path, O_RDWR);
|
||||
if(file_des == 0)
|
||||
return (1);
|
||||
|
||||
struct stat stat;
|
||||
if (fstat(file_des, &stat) != 0){
|
||||
close(file_des);
|
||||
return (2);
|
||||
}
|
||||
|
||||
close(file_des);
|
||||
|
||||
file_size = stat.st_size;
|
||||
buf = malloc(file_size);
|
||||
if (buf == NULL)
|
||||
return (3);
|
||||
|
||||
file = fopen(path, "rb");
|
||||
if(file == NULL){
|
||||
free(buf);
|
||||
return (4);
|
||||
}
|
||||
|
||||
if (fread(buf, file_size, 1, file) != 1 || ferror(file) != 0) {
|
||||
free(buf);
|
||||
fclose(file);
|
||||
return (5);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
*data = buf;
|
||||
*data_len = file_size;
|
||||
return (0);
|
||||
}
|
||||
33
Assignment 7 - SGX Hands-on/src/app/util.h
Normal file
33
Assignment 7 - SGX Hands-on/src/app/util.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef _APP_UTIL_H_
|
||||
#define _APP_UTIL_H_
|
||||
|
||||
#include <sgx_urts.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* @brief prints the command syntax and exits with EXIT_FAILURE
|
||||
*/
|
||||
void syntax_exit(void);
|
||||
|
||||
void set_bin_name(char* bin_name);
|
||||
|
||||
void sgx_print_error_message(sgx_status_t ret);
|
||||
|
||||
int initialize_enclave(char* token_path);
|
||||
|
||||
sgx_enclave_id_t get_global_eid(void);
|
||||
|
||||
/*
|
||||
* @brief loads a file completely into the HEAP
|
||||
*
|
||||
* Loads a File into HEAP and returns a dynamically allocated buffer.
|
||||
*
|
||||
* @param path path of the file
|
||||
* @param data allocated buffer output
|
||||
* @param data_len length of the allocated buffer
|
||||
* @returns 0 on success, non zero on error
|
||||
*/
|
||||
int load_file(const char* path, uint8_t** data, size_t* data_len);
|
||||
|
||||
#endif
|
||||
343
Assignment 7 - SGX Hands-on/src/enclave/enclave.c
Normal file
343
Assignment 7 - SGX Hands-on/src/enclave/enclave.c
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
* Copyright (C) 2011-2018 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h> /* vsnprintf */
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "enclave.h"
|
||||
#include "enclave_t.h"
|
||||
#include <sgx_tseal.h>
|
||||
#include <sgx_error.h>
|
||||
#include <sgx_tcrypto.h>
|
||||
|
||||
|
||||
#ifndef SK_SIZE
|
||||
#define SK_SIZE SGX_ECP256_KEY_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef PK_SIZE
|
||||
#define PK_SIZE 2*SK_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef DG_SIZE
|
||||
#define DG_SIZE SK_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef SI_SIZE
|
||||
#define SI_SIZE 2*SK_SIZE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Bobs and Alices public keys
|
||||
*/
|
||||
const sgx_ec256_public_t authorized[2] = {
|
||||
{
|
||||
.gx = {
|
||||
0x9c, 0x72, 0x2b, 0x52, 0x0e, 0xff, 0x07, 0xdc,
|
||||
0x7a, 0x32, 0x19, 0xbb, 0xd8, 0x41, 0x94, 0x2c,
|
||||
0xee, 0x17, 0xb2, 0xf6, 0x2e, 0x08, 0x61, 0xab,
|
||||
0xbc, 0x50, 0xaf, 0xb6, 0x2e, 0xf9, 0x2c, 0xee
|
||||
},
|
||||
.gy = {
|
||||
0x8c, 0x84, 0x2f, 0xb5, 0x94, 0xca, 0x60, 0x94,
|
||||
0xb0, 0xdc, 0x8a, 0xcf, 0x17, 0x91, 0xd3, 0xab,
|
||||
0x29, 0x0e, 0x81, 0x8c, 0xf6, 0x95, 0xc6, 0x92,
|
||||
0x87, 0x0e, 0x1d, 0x76, 0x56, 0xba, 0x51, 0xbb
|
||||
}
|
||||
},
|
||||
{
|
||||
.gx = {
|
||||
0x8d, 0x96, 0xa3, 0x4f, 0x1a, 0x18, 0x10, 0x00,
|
||||
0x72, 0xb5, 0x42, 0x4f, 0x1c, 0xfb, 0xb6, 0xd0,
|
||||
0x29, 0x4f, 0x5f, 0xd2, 0xef, 0x29, 0x49, 0x1c,
|
||||
0xea, 0x2b, 0xf5, 0x61, 0x5e, 0x50, 0xe5, 0x76
|
||||
},
|
||||
.gy = {
|
||||
0xb2, 0x58, 0xa6, 0xf9, 0xf3, 0xc4, 0xb5, 0xdf,
|
||||
0xa0, 0x4b, 0xb6, 0xad, 0xdd, 0xb1, 0x04, 0xec,
|
||||
0x93, 0x2e, 0x2f, 0xce, 0x34, 0x71, 0x7d, 0xf4,
|
||||
0x9d, 0xa4, 0xa5, 0xf1, 0x47, 0x0a, 0xba, 0xa1
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int get_digest_size() {
|
||||
return DG_SIZE;
|
||||
}
|
||||
|
||||
int get_sealed_size() {
|
||||
return sgx_calc_sealed_data_size(PK_SIZE, SK_SIZE);
|
||||
}
|
||||
|
||||
int get_signature_size() {
|
||||
return SI_SIZE;
|
||||
}
|
||||
|
||||
int get_public_key_size() {
|
||||
return PK_SIZE;
|
||||
}
|
||||
|
||||
int get_private_key_size() {
|
||||
return SK_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* seals a key pair
|
||||
*/
|
||||
static sgx_status_t seal_key_pair(const sgx_ec256_private_t *private, const sgx_ec256_public_t *public, uint8_t **sealed) {
|
||||
// allocate temporary buffers on stack
|
||||
uint8_t pk[PK_SIZE] = {0};
|
||||
uint8_t sk[SK_SIZE] = {0};
|
||||
|
||||
// copy key pair into buffers
|
||||
memcpy(pk, public->gx, PK_SIZE);
|
||||
memcpy(sk, private->r, SK_SIZE);
|
||||
|
||||
// seal keypair
|
||||
return sgx_seal_data(PK_SIZE, (const uint8_t *)pk, SK_SIZE, (const uint8_t *)sk, get_sealed_size(), (sgx_sealed_data_t *) *sealed);
|
||||
}
|
||||
|
||||
/*
|
||||
* unseals a key pair
|
||||
*/
|
||||
static sgx_status_t unseal_key_pair(const uint8_t *sealed, sgx_ec256_private_t *private, sgx_ec256_public_t *public) {
|
||||
// invalid parameter handling
|
||||
if(sealed == NULL) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// allocate temporary buffers on stack
|
||||
uint8_t pk[PK_SIZE] = {0};
|
||||
uint8_t sk[SK_SIZE] = {0};
|
||||
|
||||
// calculate public_key size and return error for unexpected results
|
||||
uint32_t pk_size = sgx_get_add_mac_txt_len((const sgx_sealed_data_t *)sealed);
|
||||
uint32_t sk_size = sgx_get_encrypt_txt_len((const sgx_sealed_data_t *)sealed);
|
||||
if ((pk_size != PK_SIZE) || (sk_size != SK_SIZE)) {
|
||||
return SGX_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// unseal ecc key pair
|
||||
sgx_status_t status = sgx_unseal_data((const sgx_sealed_data_t *)sealed, pk, &pk_size, sk, &sk_size);
|
||||
if (status != SGX_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// copy buffers into key structs
|
||||
if(public != NULL) {
|
||||
memcpy(public->gx, pk, PK_SIZE);
|
||||
}
|
||||
if (private != NULL) {
|
||||
memcpy(private->r, sk, SK_SIZE);
|
||||
}
|
||||
|
||||
// return success
|
||||
return status;
|
||||
}
|
||||
|
||||
sgx_status_t generate_key_pair(uint8_t *sealed, uint32_t sealed_size) {
|
||||
// invalid parameter handling
|
||||
if((sealed == NULL) || (sealed_size != get_sealed_size())) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// declare needed structs
|
||||
sgx_ecc_state_handle_t ecc_handle;
|
||||
sgx_ec256_private_t private;
|
||||
sgx_ec256_public_t public;
|
||||
sgx_status_t status;
|
||||
|
||||
// open ecc handle
|
||||
if((status = sgx_ecc256_open_context(&ecc_handle)) != SGX_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// create ecc key pair
|
||||
if((status = sgx_ecc256_create_key_pair(&private, &public, ecc_handle)) != SGX_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// seal key pair
|
||||
status = seal_key_pair(&private, &public, &sealed);
|
||||
|
||||
exit: ;
|
||||
sgx_ecc256_close_context(ecc_handle);
|
||||
return status;
|
||||
}
|
||||
|
||||
sgx_status_t get_public_key(const uint8_t *sealed, uint32_t sealed_size, uint8_t *public) {
|
||||
// invalid parameter handling
|
||||
if((sealed == NULL) || (sealed_size != get_sealed_size())) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;
|
||||
} else if(public == NULL) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// unseal public key
|
||||
sgx_status_t status;
|
||||
if((status = unseal_key_pair(sealed, NULL, (sgx_ec256_public_t *)public)) != SGX_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// return success
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* verifies an ecdsa signature
|
||||
*/
|
||||
static sgx_status_t verify_signature(const uint8_t *firmware, uint32_t firmware_size, const sgx_ec256_public_t *public, const sgx_ec256_signature_t* ecc_signature) {
|
||||
// invalid parameter handling
|
||||
if((firmware == NULL) || (firmware_size == 0) || (public == NULL) || (ecc_signature == NULL)) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// declare needed structure
|
||||
sgx_ecc_state_handle_t ecc_handle;
|
||||
|
||||
// open ecc handle
|
||||
sgx_status_t status;
|
||||
if((status = sgx_ecc256_open_context(&ecc_handle)) != SGX_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// verify signature
|
||||
uint8_t result;
|
||||
sgx_status_t verification_status = sgx_ecdsa_verify(firmware, firmware_size, public, ecc_signature, &result, ecc_handle);
|
||||
|
||||
// handle failed verification process
|
||||
if(verification_status != SGX_SUCCESS) {
|
||||
result = verification_status;
|
||||
}
|
||||
|
||||
// close context and return valid signature
|
||||
sgx_ecc256_close_context(ecc_handle);
|
||||
return result;
|
||||
}
|
||||
|
||||
sgx_status_t sign_firmware(const uint8_t *firmware, uint32_t firmware_size, const uint8_t *sealed, uint32_t sealed_size, uint8_t *public_key, uint8_t *signature) {
|
||||
// invalid parameter handling
|
||||
if((firmware == NULL) || (firmware_size == 0)) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;
|
||||
} else if((public_key == NULL) || (signature == NULL)) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;
|
||||
} else if((sealed == NULL) || (sealed_size != get_sealed_size())) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// verify public key
|
||||
for(size_t i = 0; i < sizeof(authorized)/sizeof(authorized[0]); i++) {
|
||||
if(memcmp(public_key, authorized[i].gx, PK_SIZE) == 0) {
|
||||
goto sign;
|
||||
}
|
||||
}
|
||||
return SGX_ERROR_UNEXPECTED;
|
||||
|
||||
sign: ;
|
||||
|
||||
// declare need structures
|
||||
sgx_ec256_signature_t ecc_signature;
|
||||
sgx_ecc_state_handle_t ecc_handle;
|
||||
sgx_ec256_private_t private;
|
||||
|
||||
// open ecc handle
|
||||
sgx_status_t status;
|
||||
if((status = sgx_ecc256_open_context(&ecc_handle)) != SGX_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// verify request
|
||||
if((status = verify_signature(firmware, firmware_size, (const sgx_ec256_public_t *)public_key, (const sgx_ec256_signature_t *)signature)) != SGX_EC_VALID) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// try unseal keypair
|
||||
if(status = unseal_key_pair(sealed, &private, (sgx_ec256_public_t *)public_key) != SGX_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// create signature
|
||||
if((status = sgx_ecdsa_sign(firmware, firmware_size, &private, &ecc_signature, ecc_handle)) != SGX_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// copy signature to return buffer
|
||||
memcpy(signature, ecc_signature.x, SI_SIZE);
|
||||
|
||||
// close ecc handle and return success
|
||||
exit: ;
|
||||
sgx_ecc256_close_context(ecc_handle);
|
||||
return status;
|
||||
}
|
||||
|
||||
sgx_status_t verify_firmware(const uint8_t *firmware, uint32_t firmware_size, const uint8_t *sealed, uint32_t sealed_size, const uint8_t *public_key, const uint8_t *signature) {
|
||||
// invalid parameter handling
|
||||
if((firmware == NULL) || (firmware_size == 0) || (signature == NULL)) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;
|
||||
} else if((sealed == NULL) && (public_key == NULL)) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;
|
||||
} else if((sealed != NULL) && (public_key != NULL)) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;
|
||||
} else if((sealed_size != get_sealed_size()) && (public_key == NULL)) {
|
||||
return SGX_ERROR_INVALID_PARAMETER;;
|
||||
}
|
||||
|
||||
// declare needed structures
|
||||
sgx_ec256_public_t public;
|
||||
sgx_status_t status;
|
||||
|
||||
// verify signature from staff or enclave
|
||||
if(public_key != NULL) {
|
||||
// verification only with authorized public keys
|
||||
for(size_t i = 0; i < sizeof(authorized)/sizeof(authorized[0]); i++) {
|
||||
if(memcmp(public_key, authorized[i].gx, PK_SIZE) == 0) {
|
||||
goto verify;
|
||||
}
|
||||
}
|
||||
return SGX_ERROR_UNEXPECTED;
|
||||
|
||||
verify: ;
|
||||
// copy public key into struct
|
||||
memcpy(public.gx, public_key, PK_SIZE);
|
||||
} else {
|
||||
// unseal public key
|
||||
if((status = unseal_key_pair(sealed, NULL, &public)) != SGX_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
// verify signature and return result
|
||||
return verify_signature(firmware, firmware_size, &public, (const sgx_ec256_signature_t *)signature);
|
||||
}
|
||||
12
Assignment 7 - SGX Hands-on/src/enclave/enclave.config.xml
Normal file
12
Assignment 7 - SGX Hands-on/src/enclave/enclave.config.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<EnclaveConfiguration>
|
||||
<ProdID>0</ProdID>
|
||||
<ISVSVN>0</ISVSVN>
|
||||
<StackMaxSize>0x400000</StackMaxSize>
|
||||
<HeapMaxSize>0x1000000</HeapMaxSize>
|
||||
<TCSNum>10</TCSNum>
|
||||
<TCSPolicy>1</TCSPolicy>
|
||||
<!-- Recommend changing 'DisableDebug' to 1 to make the enclave undebuggable for enclave release -->
|
||||
<DisableDebug>0</DisableDebug>
|
||||
<MiscSelect>0</MiscSelect>
|
||||
<MiscMask>0xFFFFFFFF</MiscMask>
|
||||
</EnclaveConfiguration>
|
||||
62
Assignment 7 - SGX Hands-on/src/enclave/enclave.edl
Normal file
62
Assignment 7 - SGX Hands-on/src/enclave/enclave.edl
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2011-2018 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Enclave.edl - Top EDL file. */
|
||||
|
||||
enclave {
|
||||
|
||||
/* Import ECALL/OCALL from sub-directory EDLs.
|
||||
* [from]: specifies the location of EDL file.
|
||||
* [import]: specifies the functions to import,
|
||||
* [*]: implies to import all functions.
|
||||
*/
|
||||
|
||||
trusted {
|
||||
public int get_sealed_size();
|
||||
public int get_digest_size();
|
||||
public int get_signature_size();
|
||||
public int get_public_key_size();
|
||||
public int get_private_key_size();
|
||||
public sgx_status_t generate_key_pair([out, size=sealed_size]uint8_t *sealed, uint32_t sealed_size);
|
||||
public sgx_status_t get_public_key([in, size=sealed_size]const uint8_t *sealed, uint32_t sealed_size, [out, size=64]uint8_t *public_key);
|
||||
public sgx_status_t sign_firmware([in, size=firmware_size]const uint8_t *firmware, uint32_t firmware_size, [in, size=sealed_size]const uint8_t *sealed, uint32_t sealed_size, [in, out, size=64]uint8_t *public_key, [in, out, size=64]uint8_t *signature);
|
||||
public sgx_status_t verify_firmware([in, size=firmware_size]const uint8_t *firmware, uint32_t firmware_size, [in, size=sealed_size]const uint8_t *sealed, uint32_t sealed_size, [in, size=64]const uint8_t *public_key, [in, size=64]const uint8_t *signature);
|
||||
};
|
||||
|
||||
/*
|
||||
* ocall_print_string - invokes OCALL to display string buffer inside the enclave.
|
||||
* [in]: copy the string buffer to App outside.
|
||||
* [string]: specifies 'str' is a NULL terminated buffer.
|
||||
*/
|
||||
untrusted {
|
||||
|
||||
};
|
||||
};
|
||||
113
Assignment 7 - SGX Hands-on/src/enclave/enclave.h
Normal file
113
Assignment 7 - SGX Hands-on/src/enclave/enclave.h
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright (C) 2011-2018 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ENCLAVE_H_
|
||||
#define _ENCLAVE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sgx_error.h>
|
||||
|
||||
/*
|
||||
* returns the size of the sealed key pair
|
||||
*/
|
||||
int get_sealed_size();
|
||||
|
||||
/*
|
||||
* returns the length of the hash used in the signature
|
||||
*/
|
||||
int get_digest_size();
|
||||
|
||||
/*
|
||||
* returns the size of the signature created by the enclave
|
||||
*/
|
||||
int get_signature_size();
|
||||
|
||||
/*
|
||||
* returns the size of the public key
|
||||
*/
|
||||
int get_public_key_size();
|
||||
|
||||
/*
|
||||
* returns the size of the private key
|
||||
*/
|
||||
int get_private_key_size();
|
||||
|
||||
/*
|
||||
* @brief generates a secp256r1 key pair and returns it sealed by the TEE
|
||||
*
|
||||
* @param sealed buffer to hold the sealed key pair
|
||||
* @param sealed_size size of the sealed key pair
|
||||
*
|
||||
* @returns SGX_SUCCESS on success, else sgx error code
|
||||
*/
|
||||
sgx_status_t generate_key_pair(uint8_t *sealed, uint32_t sealed_size);
|
||||
|
||||
/*
|
||||
* @brief returns the public key of the sealed key pair provided to the enclave
|
||||
*
|
||||
* @param sealed buffer containing the sealed key pair
|
||||
* @param sealed_size size of the sealed key pair
|
||||
* @param public_key buffer to hold the public key
|
||||
*
|
||||
* @returns SGX_SUCCESS on success, SGX_ERROR_INVALID_PARAMETER for invalid parameters, else sgx error code
|
||||
*/
|
||||
sgx_status_t get_public_key(const uint8_t *sealed, const uint32_t sealed_size, uint8_t *public_key);
|
||||
|
||||
/*
|
||||
* @brief signs the firmware provided by an authorized employee
|
||||
*
|
||||
* @param firmware buffer containing the firmware
|
||||
* @param firmware_size size of the sealed key pair
|
||||
* @param sealed buffer containing the sealed key pair
|
||||
* @param sealed_size size of the sealed key pair
|
||||
* @param public_key buffer with the employees public key; holds enclaves public key after successful signing
|
||||
* @param signature buffer with the employees signature; holds the enclaves signature after successful signing
|
||||
*
|
||||
* @returns SGX_SUCCESS on success, SGX_ERROR_INVALID_PARAMETER for invalid parameters, else sgx error code
|
||||
*/
|
||||
sgx_status_t sign_firmware(const uint8_t *firmware, uint32_t firmware_size, const uint8_t *sealed, uint32_t sealed_size, uint8_t *public_key, uint8_t *signature);
|
||||
|
||||
/*
|
||||
* @brief verifies a firmware signature provided by an authorized employee or enclave
|
||||
*
|
||||
* @param firmware buffer containing the firmware
|
||||
* @param firmware_size size of the sealed key pair or NULL
|
||||
* @param sealed buffer containing the sealed key pair
|
||||
* @param sealed_size size of the sealed key pair
|
||||
* @param public_key buffer with the employees public key or NULL
|
||||
* @param signature buffer with the employees signature
|
||||
*
|
||||
* @returns SGX_EC_VALID on success, SGX_EC_INVALID for invalid signatures, SGX_ERROR_INVALID_PARAMETER for invalid parameters, else sgx error code
|
||||
*/
|
||||
sgx_status_t verify_firmware(const uint8_t *firmware, uint32_t firmware_size, const uint8_t *sealed, uint32_t sealed_size, const uint8_t *public_key, const uint8_t *signature);
|
||||
|
||||
#endif /* !_ENCLAVE_H_ */
|
||||
10
Assignment 7 - SGX Hands-on/src/enclave/enclave.lds
Normal file
10
Assignment 7 - SGX Hands-on/src/enclave/enclave.lds
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
enclave.so
|
||||
{
|
||||
global:
|
||||
g_global_data_sim;
|
||||
g_global_data;
|
||||
enclave_entry;
|
||||
g_peak_heap_used;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
39
Assignment 7 - SGX Hands-on/src/enclave/enclave_private.pem
Normal file
39
Assignment 7 - SGX Hands-on/src/enclave/enclave_private.pem
Normal 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-----
|
||||
16
Assignment 7 - SGX Hands-on/src/setup
Executable file
16
Assignment 7 - SGX Hands-on/src/setup
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
# download latest release
|
||||
wget -O /tmp/openssl-3.3.1.tar.gz https://github.com/openssl/openssl/releases/download/openssl-3.3.1/openssl-3.3.1.tar.gz
|
||||
|
||||
# unpack source
|
||||
tar -xzvf /tmp/openssl-3.3.1.tar.gz -C /home/syssec/
|
||||
cd /home/syssec/openssl-3.3.1
|
||||
|
||||
# build from source with static linking options
|
||||
./config --prefix=/usr/local/openssl-3.3.1 --static -static -fPIC
|
||||
make -j6
|
||||
|
||||
# install openssl
|
||||
sudo make install
|
||||
|
||||
74
Assignment 7 - SGX Hands-on/src/simulate
Executable file
74
Assignment 7 - SGX Hands-on/src/simulate
Executable file
|
|
@ -0,0 +1,74 @@
|
|||
#!/usr/bin/env sh
|
||||
set -u
|
||||
|
||||
# colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m'
|
||||
|
||||
# helper function
|
||||
print_and_execute() {
|
||||
local color=$1
|
||||
shift
|
||||
echo "⚡ ${color}$@${NC}"
|
||||
eval "$@"
|
||||
return $?
|
||||
}
|
||||
|
||||
# setup
|
||||
TMP=/tmp/signatureproxy
|
||||
KEYDIR=../employee_keys
|
||||
mkdir -p $TMP
|
||||
|
||||
########### Disclaimer #################
|
||||
# Die Story wurde von ChatGPT erstellt #
|
||||
########################################
|
||||
|
||||
# simulation
|
||||
print_and_execute "$GREEN" "./signatureproxy proxysetup -pkey $TMP/proxy_private.bin > $TMP/proxy_public.pem"
|
||||
|
||||
echo "At Embedded Solutions Inc., security was paramount. The company specialized in creating firmware for a wide range of embedded devices used in critical industries, from medical equipment to automotive systems. To protect their firmware, they had implemented a sophisticated signature proxy system using Intel's SGX enclave technology."
|
||||
echo "One bright morning, Alice, a senior engineer known for her meticulous work, arrived at her desk. She was tasked with signing the latest stable version of a critical medical device firmware that she had finished the previous night."
|
||||
|
||||
echo "With the proxy ready, Alice compiled their latest stable version. This firmware would soon run on life-saving medical devices, a fact that weighed heavily on her as she meticulously checked every detail."
|
||||
print_and_execute "$GREEN" "dd if=/dev/urandom of=$TMP/firmware.bin bs=1M count=1 2> /dev/null"
|
||||
|
||||
echo "Once satisfied with the build, Alice signed the firmware with her private key as an assurance to the company that the firmware came from a trusted source."
|
||||
print_and_execute "$GREEN" "./signatureproxy employee -ekey $KEYDIR/alice_private.pem -firm $TMP/firmware.bin > $TMP/signature_alice.der"
|
||||
|
||||
echo "The firmware, along with Alice's signature, was then sent to the signature proxy. The proxy, acting as a vigilant guardian, verified Alice's signature against a list of authorized keys. Her identity confirmed, the proxy resigned the firmware with its own private key."
|
||||
print_and_execute "$GREEN" "cat $TMP/signature_alice.der | ./signatureproxy proxy -pkey $TMP/proxy_private.bin -epub $KEYDIR/alice_public.pem -firm $TMP/firmware.bin > $TMP/signature_for_alice.der"
|
||||
|
||||
echo "The final step was crucial: verifying the signed firmware to ensure it was ready for deployment. The team couldn't afford any mistakes, knowing the firmware's destination were life-saving medical devices."
|
||||
print_and_execute "$GREEN" "cat $TMP/signature_for_alice.der | ./signatureproxy embedded -ppub $TMP/proxy_public.pem -firm $TMP/firmware.bin > /dev/null"
|
||||
|
||||
echo "\nMeanwhile, in a dark corner of the tech world, Oskar, a disgruntled former employee, was plotting his revenge. He had managed to get his hands on an old private key. With malicious intent, he set out to sign a modified version of the firmware, hoping to bypass the security measures."
|
||||
|
||||
echo "Oskar, driven by his vendetta, signed the firmware with his old private key, intending to trick the system and cause havoc."
|
||||
print_and_execute "$RED" "./signatureproxy employee -ekey $KEYDIR/oskar_private.pem -firm $TMP/firmware.bin > $TMP/signature_oskar.der"
|
||||
|
||||
echo "With a smug grin, he tried to pass his signed firmware through the proxy. But the system was built to withstand such threats. The proxy, ever vigilant, scrutinized the incoming data."
|
||||
print_and_execute "$RED" "cat $TMP/signature_oskar.der | ./signatureproxy proxy -pkey $TMP/proxy_private.bin -epub $KEYDIR/oskar_public.pem -firm $TMP/firmware.bin > $TMP/signature_for_oskar.der"
|
||||
status=$?
|
||||
if [ $status -eq 0 ]; then
|
||||
echo "Oskar's firmware signing attempt seemed successful. :("
|
||||
exit 1
|
||||
else
|
||||
echo "The proxy detected Oskar's unauthorized key and rejected the firmware. His malicious intent was thwarted, and the firmware remained secure."
|
||||
fi
|
||||
|
||||
echo "With Oskar's attempt foiled, Embedded Solutions could breathe a sigh of relief. The integrity of their firmware was intact, safeguarded by the robust security measures of their signature proxy system. Alice and her team could continue their work with confidence, knowing that their systems were safe from internal and external threats."
|
||||
|
||||
echo "\nIn the meantime, Bob, another trusted engineer, was working on a firmware update for the automotive sector. This update was equally critical and needed the same level of security scrutiny."
|
||||
print_and_execute "$GREEN" "dd if=/dev/urandom of=$TMP/firmware2.bin bs=1M count=1 2> /dev/null"
|
||||
|
||||
echo "Bob finished his work and, following the security protocols, signed the new firmware with his private key."
|
||||
print_and_execute "$GREEN" "./signatureproxy employee -ekey $KEYDIR/bob_private.pem -firm $TMP/firmware2.bin > $TMP/signature_bob.der"
|
||||
|
||||
echo "The signed firmware was then sent to the signature proxy. As expected, the proxy verified Bob's signature and signed the firmware with its private key, ensuring the update's authenticity."
|
||||
print_and_execute "$GREEN" "cat $TMP/signature_bob.der | ./signatureproxy proxy -pkey $TMP/proxy_private.bin -epub $KEYDIR/bob_public.pem -firm $TMP/firmware2.bin > $TMP/signature_for_bob.der"
|
||||
|
||||
echo "The final verification process confirmed that Bob's firmware update was secure and ready for deployment."
|
||||
print_and_execute "$GREEN" "cat $TMP/signature_for_bob.der | ./signatureproxy embedded -ppub $TMP/proxy_public.pem -firm $TMP/firmware2.bin > /dev/null"
|
||||
|
||||
echo "This concludes the story of Alice, Oskar, Bob, and the secure firmware signing process at Embedded Solutions Inc. Through the diligent efforts of trusted employees and advanced security technology, the integrity and safety of their embedded devices were preserved."
|
||||
Loading…
Add table
Add a link
Reference in a new issue