From fabcd2e7a7bce7190ffc5de4596f706fd6888462 Mon Sep 17 00:00:00 2001 From: Xuejun Yang Date: Thu, 30 Jul 2020 02:28:18 +0000 Subject: [PATCH 1/3] Generate TLS certificate and private key Skip generating tls certificate in sw mode --- src/enclave/enclave_cert.c | 237 ++++++++++++++++++++++++ src/enclave/enclave_cert_user.c | 42 +++++ src/enclave/enclave_init.c | 25 +++ src/include/enclave/enclave_cert.h | 13 ++ src/include/enclave/enclave_cert_user.h | 15 ++ 5 files changed, 332 insertions(+) create mode 100644 src/enclave/enclave_cert.c create mode 100644 src/enclave/enclave_cert_user.c create mode 100644 src/include/enclave/enclave_cert.h create mode 100644 src/include/enclave/enclave_cert_user.h diff --git a/src/enclave/enclave_cert.c b/src/enclave/enclave_cert.c new file mode 100644 index 000000000..d6cd27332 --- /dev/null +++ b/src/enclave/enclave_cert.c @@ -0,0 +1,237 @@ +#include "enclave/enclave_cert.h" +#include +#include +#include +#include "openenclave/corelibc/oemalloc.h" +#include "openenclave/corelibc/oestring.h" + +static oe_result_t _generate_key_pair( + uint8_t** public_key_out, + size_t* public_key_size_out, + uint8_t** private_key_out, + size_t* private_key_size_out) +{ + oe_result_t result = OE_FAILURE; + oe_result_t ret; + oe_asymmetric_key_params_t params; + char user_data[] = "__USER_DATA__"; + size_t user_data_size = sizeof(user_data) - 1; + uint8_t* public_key = NULL; + size_t public_key_size = 0; + uint8_t* private_key = NULL; + size_t private_key_size = 0; + + *public_key_out = NULL; + *public_key_size_out = 0; + *private_key_out = NULL; + *private_key_size_out = 0; + + memset(¶ms, 0, sizeof(params)); + params.type = OE_ASYMMETRIC_KEY_EC_SECP256P1; + params.format = OE_ASYMMETRIC_KEY_PEM; + params.user_data = user_data; + params.user_data_size = user_data_size; + + if ((ret = oe_get_public_key_by_policy( + OE_SEAL_POLICY_UNIQUE, + ¶ms, + &public_key, + &public_key_size, + NULL, + NULL)) != OE_OK) + { + result = ret; + goto done; + } + + if ((ret = oe_get_private_key_by_policy( + OE_SEAL_POLICY_UNIQUE, + ¶ms, + &private_key, + &private_key_size, + NULL, + NULL)) != OE_OK) + { + result = ret; + goto done; + } + + *private_key_out = private_key; + *private_key_size_out = private_key_size; + private_key = NULL; + + *public_key_out = public_key; + *public_key_size_out = public_key_size; + public_key = NULL; + + result = OE_OK; + +done: + + if (private_key) + oe_free(private_key); + + if (public_key) + oe_free(public_key); + + return result; +} + +static oe_result_t _generate_cert_and_private_key( + const char* common_name, + uint8_t** cert_out, + size_t* cert_size_out, + uint8_t** private_key_out, + size_t* private_key_size_out) +{ + oe_result_t result = OE_FAILURE; + oe_result_t ret; + uint8_t* cert = NULL; + size_t cert_size; + uint8_t* private_key = NULL; + size_t private_key_size; + uint8_t* public_key = NULL; + size_t public_key_size; + + *cert_out = NULL; + *cert_size_out = 0; + *private_key_out = NULL; + *private_key_size_out = 0; + + if ((ret = _generate_key_pair( + &public_key, &public_key_size, &private_key, &private_key_size)) != + OE_OK) + { + result = ret; + goto done; + } + + if ((ret = oe_generate_attestation_certificate( + (unsigned char*)common_name, + private_key, + private_key_size, + public_key, + public_key_size, + &cert, + &cert_size)) != OE_OK) + { + result = ret; + goto done; + } + + *private_key_out = private_key; + *private_key_size_out = private_key_size; + private_key = NULL; + + *cert_out = cert; + *cert_size_out = cert_size; + cert = NULL; + + result = OE_OK; + +done: + + if (private_key) + oe_free_key(private_key, private_key_size, NULL, 0); + + if (public_key) + oe_free_key(public_key, public_key_size, NULL, 0); + + if (cert) + oe_free_attestation_certificate(cert); + + return result; +} + +int enclave_generate_tls_credentials( + uint8_t** cert_out, + size_t* cert_size_out, + uint8_t** private_key_out, + size_t* private_key_size_out) +{ + int ret = -1; + uint8_t* cert = NULL; + size_t cert_size; + uint8_t* private_key = NULL; + size_t private_key_size; + const char* common_name = "CN=Open Enclave SDK,O=OESDK TLS,C=US"; + + if (cert_out) + *cert_out = NULL; + + if (cert_size_out) + *cert_size_out = 0; + + if (private_key_out) + *private_key_out = NULL; + + if (private_key_size_out) + *private_key_size_out = 0; + + if (!cert_out || !cert_size_out || !private_key_out || + !private_key_size_out) + { + goto done; + } + + /* Generate the attested certificate and private key */ + if (_generate_cert_and_private_key( + common_name, &cert, &cert_size, &private_key, &private_key_size) != + OE_OK) + { + goto done; + } + +#if DEBUG + /* Verify that the certificate can be parsed as DER */ + { + mbedtls_x509_crt crt; + mbedtls_x509_crt_init(&crt); + + if (mbedtls_x509_crt_parse_der(&crt, cert, cert_size) != 0) + { + mbedtls_x509_crt_free(&crt); + goto done; + } + + mbedtls_x509_crt_free(&crt); + } + + /* Verify that the private key can be parsed as PEM */ + { + mbedtls_pk_context pk; + mbedtls_pk_init(&pk); + + if (mbedtls_pk_parse_key(&pk, private_key, private_key_size, NULL, 0) != + 0) + { + mbedtls_pk_free(&pk); + goto done; + } + + mbedtls_pk_free(&pk); + } +#endif + + *cert_out = cert; + cert = NULL; + *cert_size_out = cert_size; + *private_key_out = private_key; + private_key = NULL; + *private_key_size_out = private_key_size; + + ret = 0; + +done: + + if (cert) + oe_free_key(cert, cert_size, NULL, 0); + + if (private_key) + oe_free_key(private_key, private_key_size, NULL, 0); + + if (cert) + oe_free_attestation_certificate(cert); + + return ret; +} diff --git a/src/enclave/enclave_cert_user.c b/src/enclave/enclave_cert_user.c new file mode 100644 index 000000000..5fbfdf759 --- /dev/null +++ b/src/enclave/enclave_cert_user.c @@ -0,0 +1,42 @@ +#include "enclave/enclave_cert_user.h" +#include +#include + +// This function and its caller should be moved to +// user space once we have a clean separation. +int sgxlkl_write_tls_credentials( + uint8_t* cert, + size_t cert_size, + uint8_t* private_key, + size_t private_key_size, + const char* cert_path, + const char* pkey_path) +{ + int ret = -1; + + FILE* os1 = NULL; + FILE* os2 = NULL; + + if (!(os1 = fopen(cert_path, "wb"))) + goto done; + + if (!(os2 = fopen(pkey_path, "wb"))) + goto done; + + if (fwrite(cert, 1, cert_size, os1) != cert_size) + goto done; + + if (fwrite(private_key, 1, private_key_size, os2) != private_key_size) + goto done; + + ret = 0; + +done: + if (os1) + fclose(os1); + + if (os2) + fclose(os2); + + return ret; +} \ No newline at end of file diff --git a/src/enclave/enclave_init.c b/src/enclave/enclave_init.c index 0cfdea8ae..9f2648b01 100644 --- a/src/enclave/enclave_init.c +++ b/src/enclave/enclave_init.c @@ -5,6 +5,8 @@ #include "openenclave/corelibc/oemalloc.h" #include "openenclave/corelibc/oestring.h" +#include "enclave/enclave_cert.h" +#include "enclave/enclave_cert_user.h" #include "enclave/enclave_mem.h" #include "enclave/enclave_oe.h" #include "enclave/enclave_util.h" @@ -13,6 +15,9 @@ #include "enclave/wireguard_util.h" #include "shared/env.h" +#define SGXLKL_TLS_CERT_PATH "/run/sgxlkl_cert.der" +#define SGXLKL_TLS_PRIVATE_KEY_PATH "/run/sgxlkl_private_key.pem" + extern struct mpmcq __scheduler_queue; _Noreturn void __dls3(elf64_stack_t* conf, void* tos); @@ -90,12 +95,22 @@ static void init_wireguard() static int startmain(void* args) { + uint8_t* cert; + size_t cert_size; + uint8_t* private_key; + size_t private_key_size; + __libc_start_init(); a_barrier(); /* Indicate that libc initialization has finished */ sgxlkl_enclave_state.libc_state = libc_initialized; + /* In hw mode, ask OE to generate TLS certificate and private key */ + if (!sgxlkl_in_sw_debug_mode()) + enclave_generate_tls_credentials( + &cert, &cert_size, &private_key, &private_key_size); + /* Setup LKL (hd, net, memory) and start kernel */ /* SGX-LKL lthreads inherit names from their parent. Set this to "kernel" @@ -107,6 +122,16 @@ static int startmain(void* args) init_wireguard(); find_and_mount_disks(); + /* Save TLS certificate and private key to files. */ + if (!sgxlkl_in_sw_debug_mode()) + sgxlkl_write_tls_credentials( + cert, + cert_size, + private_key, + private_key_size, + SGXLKL_TLS_CERT_PATH, + SGXLKL_TLS_PRIVATE_KEY_PATH); + /* Launch stage 3 dynamic linker, passing in top of stack to overwrite. * The dynamic linker will then load the application proper; here goes! */ __dls3(&sgxlkl_enclave_state.elf64_stack, __builtin_frame_address(0)); diff --git a/src/include/enclave/enclave_cert.h b/src/include/enclave/enclave_cert.h new file mode 100644 index 000000000..ebb2cb91b --- /dev/null +++ b/src/include/enclave/enclave_cert.h @@ -0,0 +1,13 @@ +#ifndef _ENCLAVE_CERT_H +#define _ENCLAVE_CERT_H + +#include +#include + +int enclave_generate_tls_credentials( + uint8_t** cert_out, + size_t* cert_size_out, + uint8_t** private_key_out, + size_t* private_key_size_out); + +#endif /* _ENCLAVE_CERT_H */ diff --git a/src/include/enclave/enclave_cert_user.h b/src/include/enclave/enclave_cert_user.h new file mode 100644 index 000000000..9faee6071 --- /dev/null +++ b/src/include/enclave/enclave_cert_user.h @@ -0,0 +1,15 @@ +#ifndef _ENCLAVE_CERT_USER_H +#define _ENCLAVE_CERT_USER_H + +#include +#include + +int sgxlkl_write_tls_credentials( + uint8_t* cert, + size_t cert_size, + uint8_t* private_key, + size_t private_key_size, + const char* cert_path, + const char* pkey_path); + +#endif /* _ENCLAVE_CERT_USER_H */ From d835986dcd4444673f545fa29c9475c78b90c5ca Mon Sep 17 00:00:00 2001 From: Xuejun Yang Date: Fri, 7 Aug 2020 19:50:11 +0000 Subject: [PATCH 2/3] Generate certificate with eeid plugin --- src/enclave/enclave_cert.c | 12 +++++++++++- src/enclave/enclave_init.c | 7 ++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/enclave/enclave_cert.c b/src/enclave/enclave_cert.c index d6cd27332..753a3dab1 100644 --- a/src/enclave/enclave_cert.c +++ b/src/enclave/enclave_cert.c @@ -2,9 +2,13 @@ #include #include #include +#include +#include #include "openenclave/corelibc/oemalloc.h" #include "openenclave/corelibc/oestring.h" +oe_result_t oe_sgx_eeid_attester_initialize(void); + static oe_result_t _generate_key_pair( uint8_t** public_key_out, size_t* public_key_size_out, @@ -92,6 +96,7 @@ static oe_result_t _generate_cert_and_private_key( size_t private_key_size; uint8_t* public_key = NULL; size_t public_key_size; + const oe_uuid_t format = {OE_FORMAT_UUID_SGX_EEID_ECDSA_P256}; *cert_out = NULL; *cert_size_out = 0; @@ -106,7 +111,12 @@ static oe_result_t _generate_cert_and_private_key( goto done; } - if ((ret = oe_generate_attestation_certificate( + // Initialize built-in OE attesters and the eeid attester. + oe_attester_initialize(); + oe_sgx_eeid_attester_initialize(); + + if ((ret = oe_get_attestation_certificate_with_evidence( + &format, (unsigned char*)common_name, private_key, private_key_size, diff --git a/src/enclave/enclave_init.c b/src/enclave/enclave_init.c index 9f2648b01..dedb5b985 100644 --- a/src/enclave/enclave_init.c +++ b/src/enclave/enclave_init.c @@ -122,7 +122,12 @@ static int startmain(void* args) init_wireguard(); find_and_mount_disks(); - /* Save TLS certificate and private key to files. */ + /* Save TLS certificate and private key to files. + * TODO 1: once we have kernel/user separation, pass the cert and private + * key to user space through stack, and move this call to user space. + * TODO 2: make file paths customizable by users. + */ + if (!sgxlkl_in_sw_debug_mode()) sgxlkl_write_tls_credentials( cert, From 9084fcfc80bf30776b2ec9c124ed41cecffd9261 Mon Sep 17 00:00:00 2001 From: Xuejun Yang Date: Fri, 7 Aug 2020 21:30:41 +0000 Subject: [PATCH 3/3] Fixed a crash due triggered by syscall --- src/enclave/enclave_init.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/enclave/enclave_init.c b/src/enclave/enclave_init.c index dedb5b985..34f2faa09 100644 --- a/src/enclave/enclave_init.c +++ b/src/enclave/enclave_init.c @@ -106,11 +106,6 @@ static int startmain(void* args) /* Indicate that libc initialization has finished */ sgxlkl_enclave_state.libc_state = libc_initialized; - /* In hw mode, ask OE to generate TLS certificate and private key */ - if (!sgxlkl_in_sw_debug_mode()) - enclave_generate_tls_credentials( - &cert, &cert_size, &private_key, &private_key_size); - /* Setup LKL (hd, net, memory) and start kernel */ /* SGX-LKL lthreads inherit names from their parent. Set this to "kernel" @@ -122,13 +117,17 @@ static int startmain(void* args) init_wireguard(); find_and_mount_disks(); - /* Save TLS certificate and private key to files. - * TODO 1: once we have kernel/user separation, pass the cert and private - * key to user space through stack, and move this call to user space. - * TODO 2: make file paths customizable by users. + /* Generate TLS certificate and private key and save them to files. + * Once we have kernel/user separation, pass the cert and private + * key to user space through the stack, and move + * sgxlkl_write_tls_credentials to user space. */ if (!sgxlkl_in_sw_debug_mode()) + { + enclave_generate_tls_credentials( + &cert, &cert_size, &private_key, &private_key_size); + sgxlkl_write_tls_credentials( cert, cert_size, @@ -136,6 +135,7 @@ static int startmain(void* args) private_key_size, SGXLKL_TLS_CERT_PATH, SGXLKL_TLS_PRIVATE_KEY_PATH); + } /* Launch stage 3 dynamic linker, passing in top of stack to overwrite. * The dynamic linker will then load the application proper; here goes! */