[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

This commit is contained in:
Sascha Tommasone 2024-07-08 11:06:13 +02:00
parent 341d128b27
commit 7224e46946
Signed by: saschato
GPG key ID: 751068A86FCAA217
36 changed files with 0 additions and 0 deletions

View 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.*

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

View 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

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

View 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

View 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();
}

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

View 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

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

View 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

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

View 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

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

View 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>

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

View 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_ */

View file

@ -0,0 +1,10 @@
enclave.so
{
global:
g_global_data_sim;
g_global_data;
enclave_entry;
g_peak_heap_used;
local:
*;
};

View file

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

View file

@ -0,0 +1,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

View 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."