Kaynağa Gözat

The enclave can generate a long-term identity key and persist the private key through sealing

Ian Goldberg 1 yıl önce
ebeveyn
işleme
1672a9efbe
9 değiştirilmiş dosya ile 280 ekleme ve 21 silme
  1. 72 6
      App/App.cpp
  2. 0 9
      Enclave/Enclave.cpp
  3. 19 1
      Enclave/Enclave.edl
  4. 74 0
      Enclave/comms.cpp
  5. 51 0
      Enclave/utils.cpp
  6. 12 0
      Enclave/utils.hpp
  7. 2 2
      Makefile
  8. 45 2
      Untrusted/Untrusted.cpp
  9. 5 1
      Untrusted/Untrusted.hpp

+ 72 - 6
App/App.cpp

@@ -1,19 +1,85 @@
 #include <cstdio>
 
 #include "sgx_urts.h"
+#include "sgx_tcrypto.h"
+#include "sgx_tseal.h"
 #include "Untrusted.hpp"
 
-int main(int argc, char **argv)
+static void dump(const char *label, void *p, size_t len)
+{
+    unsigned char *pc = (unsigned char *)p;
+    if (label) {
+        printf("%s: ", label);
+    }
+    for (size_t i=0; i<len; ++i) {
+        printf("%02x", pc[i]);
+    }
+    printf("\n");
+}
+
+static void genkey()
+{
+    size_t sealedprivsize =
+        sizeof(sgx_sealed_data_t) + sizeof(sgx_ec256_private_t) + 19;
+
+    sgx_ec256_public_t pubkey;
+    sgx_sealed_data_t *sealedprivkey =
+        (sgx_sealed_data_t *)malloc(sealedprivsize);
+
+    ecall_identity_key_new(&pubkey, sealedprivkey);
+
+    dump("Pubkey", &pubkey, sizeof(pubkey));
+    printf("Saving sealed private key\n");
+
+    sgx_destroy_enclave(global_eid);
+
+    FILE *sprivf = fopen("privkey.seal", "wb");
+    fwrite(sealedprivkey, sealedprivsize, 1, sprivf);
+    fclose(sprivf);
+
+    free(sealedprivkey);
+}
+
+static void loadkey(FILE *sprivf)
 {
-    char buf[30];
+    size_t sealedprivsize =
+        sizeof(sgx_sealed_data_t) + sizeof(sgx_ec256_private_t) + 19;
+
+    sgx_ec256_public_t pubkey;
+    sgx_sealed_data_t *sealedprivkey =
+        (sgx_sealed_data_t *)malloc(sealedprivsize);
+
+    if (fread(sealedprivkey, sealedprivsize, 1, sprivf) != 1) {
+        fprintf(stderr, "Could not read privkey.seal file\n");
+        exit(1);
+    }
+
+    bool res = ecall_identity_key_load(&pubkey, sealedprivkey);
+
+    if (!res) {
+        fprintf(stderr, "Key load failed\n");
+        exit(1);
+    }
+
+    printf("Loaded sealed private key\n");
+    dump("Pubkey", &pubkey, sizeof(pubkey));
 
+    free(sealedprivkey);
+}
+
+int main(int argc, char **argv)
+{
     if (initialize_enclave() < 0) {
         return -1;
     }
 
-    ecall_hello_enclave(buf, sizeof(buf));
-
-    puts(buf);
+    FILE *sprivf = fopen("privkey.seal", "rb");
+    if (sprivf) {
+        loadkey(sprivf);
+        fclose(sprivf);
+    } else {
+        genkey();
+    }
 
-    sgx_destroy_enclave(global_eid);
+    return 0;
 }

+ 0 - 9
Enclave/Enclave.cpp

@@ -1,9 +0,0 @@
-#include <cstring>
-
-#include "Enclave_t.h"
-
-void ecall_hello_enclave(char *buf, size_t len)
-{
-    strncpy(buf, "Hello, enclave!", len-1);
-    buf[len-1] = '\0';
-}

+ 19 - 1
Enclave/Enclave.edl

@@ -1,5 +1,23 @@
 enclave {
+    include "stdbool.h"
+    include "sgx_tcrypto.h"
+    include "sgx_tseal.h"
+
     trusted {
-        public void ecall_hello_enclave([user_check] char *str, size_t sz_);
+        public void ecall_identity_key_new(
+            [out] sgx_ec256_public_t *outpub,
+            [out,size=611] sgx_sealed_data_t *outsealedpriv);
+
+        public bool ecall_identity_key_load(
+            [out] sgx_ec256_public_t *outpub,
+            [in,size=611] const sgx_sealed_data_t *insealedpriv);
+    };
+
+    untrusted {
+        void ocall_print_string([in, string] const char *str);
+        unsigned long ocall_print_string_with_rtclock(
+            [in, string] const char *str);
+        unsigned long ocall_print_string_with_rtclock_diff(
+            [in, string] const char *str, unsigned long before);
     };
 };

+ 74 - 0
Enclave/comms.cpp

@@ -0,0 +1,74 @@
+#include <cstring>
+
+#include "sgx_tcrypto.h"
+#include "sgx_tseal.h"
+#include "Enclave_t.h"
+#include "utils.hpp"
+
+// Our public and private identity keys
+sgx_ec256_private_t g_privkey;
+sgx_ec256_public_t g_pubkey;
+
+// Generate a new identity signature key.  Output the public key and the
+// sealed private key.  outsealedpriv must point to
+// sizeof(sgx_sealed_data_t) + sizeof(sgx_ec256_private_t) + 19 bytes of
+// memory.
+void ecall_identity_key_new(sgx_ec256_public_t *outpub,
+    sgx_sealed_data_t *outsealedpriv)
+{
+    sgx_ecc_state_handle_t ecc_handle;
+
+    sgx_ecc256_open_context(&ecc_handle);
+
+    sgx_ecc256_create_key_pair(&g_privkey, &g_pubkey, ecc_handle);
+    memmove(outpub, &g_pubkey, sizeof(g_pubkey));
+
+    sgx_ecc256_close_context(ecc_handle);
+
+    sgx_seal_data(19, (const uint8_t*)"TEEMS Identity key",
+        sizeof(g_privkey), (const uint8_t*)&g_privkey,
+        sizeof(sgx_sealed_data_t) + sizeof(sgx_ec256_private_t) + 19,
+        outsealedpriv);
+}
+
+// Load an identity key from a sealed privkey.  Output the resulting
+// public key.  insealedpriv must point to sizeof(sgx_sealed_data_t) +
+// sizeof(sgx_ec256_private_t) bytes of memory.  Returns true for
+// success, false for failure.
+bool ecall_identity_key_load(sgx_ec256_public_t *outpub,
+    const sgx_sealed_data_t *insealedpriv)
+{
+    sgx_ecc_state_handle_t ecc_handle;
+
+    char aad[19];
+    uint32_t aadsize = sizeof(aad);
+    sgx_ec256_private_t privkey;
+    uint32_t privkeysize = sizeof(privkey);
+    sgx_status_t res = sgx_unseal_data(
+        insealedpriv, (uint8_t*)aad, &aadsize,
+        (uint8_t*)&privkey, &privkeysize);
+
+    if (res || aadsize != sizeof(aad) || privkeysize != sizeof(privkey)
+            || memcmp(aad, "TEEMS Identity key", sizeof(aad))) {
+        return false;
+    }
+
+    sgx_ecc256_open_context(&ecc_handle);
+
+    sgx_ec256_public_t pubkey;
+    int valid;
+    if (sgx_ecc256_calculate_pub_from_priv(&privkey, &pubkey) ||
+            sgx_ecc256_check_point(&pubkey, ecc_handle, &valid) ||
+            !valid) {
+        sgx_ecc256_close_context(ecc_handle);
+        return false;
+    }
+
+    sgx_ecc256_close_context(ecc_handle);
+
+    memmove(&g_pubkey, &pubkey, sizeof(pubkey));
+    memmove(&g_privkey, &privkey, sizeof(privkey));
+    memmove(outpub, &pubkey, sizeof(pubkey));
+
+    return true;
+}

+ 51 - 0
Enclave/utils.cpp

@@ -0,0 +1,51 @@
+#include "utils.hpp"
+
+/*
+ * printf:
+ *   Invokes OCALL to display the enclave buffer to the terminal.
+ */
+void printf(const char *fmt, ...)
+{
+    char buf[BUFSIZ] = {'\0'};
+    va_list ap;
+    va_start(ap, fmt);
+    vsnprintf(buf, BUFSIZ, fmt, ap);
+    va_end(ap);
+    ocall_print_string(buf);
+}
+
+/*
+ * printf_with_rtclock:
+ *   Invokes OCALL to display the enclave buffer to the terminal with a
+ *   timestamp and returns the timestamp.
+ */
+unsigned long printf_with_rtclock(const char *fmt, ...)
+{
+    unsigned long ret;
+    char buf[BUFSIZ] = {'\0'};
+    va_list ap;
+    va_start(ap, fmt);
+    vsnprintf(buf, BUFSIZ, fmt, ap);
+    va_end(ap);
+    ocall_print_string_with_rtclock(&ret, buf);
+    return ret;
+}
+
+/*
+ * printf_with_rtclock_diff:
+ *   Invokes OCALL to display the enclave buffer to the terminal with a
+ *   timestamp and returns the timestamp.  Also prints the difference from
+ *   the before timestamp.
+ */
+unsigned long printf_with_rtclock_diff(unsigned long before, const char *fmt, ...)
+{
+    unsigned long ret;
+    char buf[BUFSIZ] = {'\0'};
+    va_list ap;
+    va_start(ap, fmt);
+    vsnprintf(buf, BUFSIZ, fmt, ap);
+    va_end(ap);
+    ocall_print_string_with_rtclock_diff(&ret, buf, before);
+    return ret;
+}
+

+ 12 - 0
Enclave/utils.hpp

@@ -0,0 +1,12 @@
+#ifndef __UTILS_HPP__
+#define __UTILS_HPP__
+
+#include <stdio.h>
+#include "Enclave_t.h"
+
+void printf(const char *fmt, ...);
+unsigned long printf_with_rtclock(const char *fmt, ...);
+unsigned long printf_with_rtclock_diff(unsigned long before,
+    const char *fmt, ...);
+
+#endif

+ 2 - 2
Makefile

@@ -128,7 +128,7 @@ else
 endif
 Crypto_Library_Name := sgx_tcrypto
 
-Enclave_Cpp_Files := Enclave/Enclave.cpp $(wildcard Enclave/TrustedLibrary/*.cpp)
+Enclave_Cpp_Files := $(wildcard Enclave/*.cpp)
 Enclave_Include_Paths := -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/libcxx -I$(SGX_SDK)/include/tlibc 
 
 Enclave_C_Flags := -nostdinc -fvisibility=hidden -fpie -fstack-protector -fno-builtin-printf $(Enclave_Include_Paths)
@@ -262,7 +262,7 @@ $(Enclave_Name): Enclave/Enclave_t.o $(Enclave_Cpp_Objects)
 	@$(CXX) $^ -o $@ $(Enclave_Link_Flags)
 	@echo "LINK =>  $@"
 
-$(Signed_Enclave_Name): $(Enclave_Name)
+$(Signed_Enclave_Name): $(Enclave_Name) $(Enclave_Config_File)
 ifeq ($(wildcard $(Enclave_Test_Key)),)
 	@echo "There is no enclave test key<Enclave_private_test.pem>."
 	@echo "The project will generate a key<Enclave_private_test.pem> for test."

+ 45 - 2
Untrusted/Untrusted.cpp

@@ -35,6 +35,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
+#include <time.h>
 
 # include <unistd.h>
 # include <pwd.h>
@@ -44,6 +45,8 @@
 
 #include "sgx_error.h"
 #include "sgx_urts.h"
+#include "sgx_tcrypto.h"
+#include "sgx_tseal.h"
 #include "Untrusted.hpp"
 #include "Enclave_u.h"
 
@@ -177,7 +180,47 @@ int initialize_enclave(void)
     return 0;
 }
 
-void ecall_hello_enclave(char *str, size_t len)
+void ocall_print_string(const char *str) {
+    printf("%s", str);
+}
+
+/* Print the given string, prefixed with the current time, and return the
+ * current time. */
+unsigned long ocall_print_string_with_rtclock(const char *str) {
+    struct timespec tp;
+    clock_gettime(CLOCK_REALTIME_COARSE, &tp);
+    unsigned long now = tp.tv_sec * 1000000 + tp.tv_nsec/1000;
+
+    printf("%lu.%06lu: %s", tp.tv_sec, tp.tv_nsec/1000, str);
+
+    return now;
+}
+
+/* Print the given string, prefixed with the current time, and return the
+ * current time. Also print the time difference to the provided time. */
+unsigned long ocall_print_string_with_rtclock_diff(const char *str,
+	unsigned long before) {
+    struct timespec tp;
+    clock_gettime(CLOCK_REALTIME_COARSE, &tp);
+    unsigned long now = tp.tv_sec * 1000000 + tp.tv_nsec/1000;
+    unsigned long diff = now - before;
+
+    printf("%lu.%06lu: (%lu.%06lu) %s", tp.tv_sec, tp.tv_nsec/1000,
+        diff/1000000, diff%1000000, str);
+
+    return now;
+}
+
+void ecall_identity_key_new(sgx_ec256_public_t* outpub,
+    sgx_sealed_data_t* outsealedpriv)
+{
+    ecall_identity_key_new(global_eid, outpub, outsealedpriv);
+}
+
+bool ecall_identity_key_load(sgx_ec256_public_t* outpub,
+    const sgx_sealed_data_t* insealedpriv)
 {
-    ecall_hello_enclave(global_eid, str, len);
+    bool ret;
+    ecall_identity_key_load(global_eid, &ret, outpub, insealedpriv);
+    return ret;
 }

+ 5 - 1
Untrusted/Untrusted.hpp

@@ -9,6 +9,10 @@ extern sgx_enclave_id_t global_eid;
 
 int initialize_enclave();
 
-void ecall_hello_enclave(char *str, size_t len);
+void ecall_identity_key_new(sgx_ec256_public_t* outpub,
+    sgx_sealed_data_t* outsealedpriv);
+
+bool ecall_identity_key_load(sgx_ec256_public_t* outpub,
+    const sgx_sealed_data_t* insealedpriv);
 
 #endif