Преглед изворни кода

[Pal/Linux-SGX] Reimplement local attestation for process creation

Chia-Che Tsai пре 5 година
родитељ
комит
2e13503624

+ 0 - 3
Pal/lib/pal_crypto.h

@@ -26,9 +26,6 @@
 
 #define SHA256_DIGEST_LEN 32
 
-#define AES_CMAC_KEY_LEN    16
-#define AES_CMAC_DIGEST_LEN 32
-
 #ifdef CRYPTO_USE_WOLFSSL
 #define CRYPTO_PROVIDER_SPECIFIED
 

+ 122 - 100
Pal/src/host/Linux-SGX/db_process.c

@@ -131,42 +131,99 @@ int register_trusted_child(const char * uri, const char * mrenclave_str)
     return 0;
 }
 
-struct proc_attestation_data {
-    sgx_arch_mac_t  keyhash_mac;
-    uint8_t         reserved[PAL_ATTESTATION_DATA_SIZE - sizeof(sgx_arch_mac_t)];
-} __attribute__((packed));
-
-struct check_child_param {
-    PAL_MAC_KEY     mac_key;
-    const char *    uri;
+/*
+ * For SGX, the creation of a child process requires a clean enclave and a secure channel
+ * between the parent and child processes (enclaves). The establishment of the secure
+ * channel must be resilient to a host-level, root-privilege adversary. Such an adversary
+ * can either create arbitrary enclaves, or intercept the handshake protocol between the
+ * parent and child enclaves to launch a man-in-the-middle attack.
+ *
+ * Prerequisites of a secure channel:
+ * (1) A session key needs to be shared only between the parent and child enclaves.
+ *
+ *       See the implementation in _DkStreamKeyExchange().
+ *       When initializing an RPC stream, both ends of the stream needs to use
+ *       Diffie-Hellman to exchange a session key. The key will be used to both identify
+ *       the connection (to prevent man-in-the-middle attack) and for future encryption.
+ *
+ * (2) Both the parent and child enclaves need to be proven by the Intel CPU.
+ *
+ *       See the implementation in _DkStreamReportRequest() and _DkStreamReportRespond().
+ *       The two ends of the RPC stream need to exchange local attestation reports
+ *       signed by the Intel CPUs to prove themselves to be running inside enclaves
+ *       on the same platform. The local attestation reports contain no secret information
+ *       and can be verified cryptographically, and can be sent on an unencrypted channel.
+ *
+ *       The flow of local attestation is as follows:
+ *         - Parent: Send targetinfo(Parent) to Child
+ *         - Child:  Generate report(Child -> Parent) and send to Parent
+ *         - Parent: Verify report(Child -> Parent)
+ *         - Parent: Extract targetinfo(Child) from report(Child -> Parent)
+ *                   and then generate report(Parent -> Child)
+ *         - Child:  Verify report(Parent -> Child)
+ *
+ * (3) Both the parent and child enclaves need to have a white-listed measurement.
+ *
+ *       See the implementation in check_child_mrenclave() and check_parent_mrenclave().
+ *       For a child process, we check if the child's mrenclave is listed as
+ *       "sgx.trusted_children.xxx = ..." in the manifest.
+ *       For a parent process, we currently don't check its mrenclave in the child.
+ *       This is a limitation because listing the parent's mrenclave in the child's
+ *       manifest will change the child's mrenclave, which then needs to be updated
+ *       in the parent's manifest, and eventually falls into a loop of updating both
+ *       manifest files.
+ *
+ * (4) The two parties who create the session key need to be the ones proven by the CPU
+ *     (for preventing man-in-the-middle attacks).
+ *
+ *       See the implementation in check_child_mrenclave() and check_parent_mrenclave().
+ *       The local reports from both sides will contain a MAC, generated by hashing
+ *       the unique enclave ID (a 64-bit integer) using AES-CMAC with the session key.
+ *       Because both the enclave ID and the session key are randomly created for each
+ *       enclave, no report can be reused even from an enclave with the same mrenclave.
+ */
+
+struct proc_data {
+    sgx_arch_mac_t eid_mac;
 };
 
-static int check_child_mrenclave (sgx_arch_hash_t * mrenclave,
-                                  void * signed_data, void * check_param)
-{
-    struct pal_enclave_state * remote_state = signed_data;
-    struct proc_attestation_data * data = (void *) &remote_state->data;
+static int generate_sign_data(const PAL_SESSION_KEY* session_key, uint64_t enclave_id,
+                              sgx_sign_data_t* sign_data) {
+    struct proc_data data;
+    int ret = lib_AESCMAC((uint8_t*)session_key,   sizeof(*session_key),
+                          (uint8_t*)&enclave_id,   sizeof(enclave_id),
+                          (uint8_t*)&data.eid_mac, sizeof(data.eid_mac));
+    if (ret < 0)
+        return ret;
+
+    SGX_DBG(DBG_P|DBG_S, "Enclave identifier: %016lx -> %s\n", enclave_id,
+            ALLOCA_BYTES2HEXSTR(data.eid_mac));
+
+    /* Copy proc_data into sgx_sign_data_t */
+    assert(sizeof(data) <= sizeof(*sign_data));
+    memset(sign_data, 0, sizeof(*sign_data));
+    memcpy(sign_data, &data, sizeof(data));
+    return 0;
+}
 
+static int check_child_mrenclave(PAL_HANDLE child, sgx_arch_hash_t* mrenclave,
+                                 struct pal_enclave_state* remote_state) {
     /* the process must be a clean process */
     if (remote_state->enclave_flags & PAL_ENCLAVE_INITIALIZED)
         return 1;
 
-    struct check_child_param * param = check_param;
+    sgx_sign_data_t sign_data;
+    int ret = generate_sign_data(&child->process.session_key, remote_state->enclave_id,
+                                 &sign_data);
+    if (ret < 0)
+        return ret;
 
     /* must make sure the signer of the report is also the owner of the key,
        in order to prevent man-in-the-middle attack */
-    struct proc_attestation_data check_data;
-    memset(&check_data, 0, sizeof(struct proc_attestation_data));
-
-    lib_AESCMAC((void *) &param->mac_key, AES_CMAC_KEY_LEN,
-                remote_state->enclave_identifier,
-                sizeof(remote_state->enclave_identifier),
-                check_data.keyhash_mac, sizeof(check_data.keyhash_mac));
-
-    if (memcmp(data, &check_data, sizeof(struct proc_attestation_data)))
+    if (memcmp(&remote_state->enclave_data, &sign_data, sizeof(sign_data)))
         return 1;
 
-    /* always accept our own as child */
+    /* Always accept the same mrenclave as child process */
     if (!memcmp(mrenclave, pal_sec.mrenclave, sizeof(sgx_arch_hash_t))) {
         SGX_DBG(DBG_S, "trusted child: <forked>\n");
         return 0;
@@ -175,6 +232,7 @@ static int check_child_mrenclave (sgx_arch_hash_t * mrenclave,
     struct trusted_child * tc;
     _DkSpinLock(&trusted_children_lock);
 
+    /* Try to find a matching mrenclave from the manifest */
     LISTP_FOR_EACH_ENTRY(tc, &trusted_children, list) {
         if (!memcmp(mrenclave, tc->mrenclave, sizeof(sgx_arch_hash_t))) {
             _DkSpinUnlock(&trusted_children_lock);
@@ -201,79 +259,54 @@ int _DkProcessCreate (PAL_HANDLE * handle, const char * uri, const char ** args)
         for (const char ** a = args ; *a ; a++)
             nargs++;
 
-    ret = ocall_create_process(uri, nargs, args,
-                               proc_fds,
-                               &child_pid);
-    if (IS_ERR(ret))
-        return unix_to_pal_error(ERRNO(ret));
-
-    PAL_HANDLE proc = malloc(HANDLE_SIZE(process));
-    SET_HANDLE_TYPE(proc, process);
-    HANDLE_HDR(proc)->flags |= RFD(0)|WFD(1)|RFD(2)|WFD(2)|WRITABLE(1)|WRITABLE(2);
-    proc->process.stream_in  = proc_fds[0];
-    proc->process.stream_out = proc_fds[1];
-    proc->process.cargo      = proc_fds[2];
-    proc->process.pid = child_pid;
-    proc->process.nonblocking = PAL_FALSE;
-
-    PAL_SESSION_KEY session_key;
-    ret = _DkStreamKeyExchange(proc, &session_key);
+    ret = ocall_create_process(uri, nargs, args, proc_fds, &child_pid);
     if (ret < 0)
         return ret;
 
-    struct check_child_param param;
-    session_key_to_mac_key(&session_key, &param.mac_key);
-    param.uri = uri;
-
-    struct proc_attestation_data data;
-    memset(&data, 0, sizeof(struct proc_attestation_data));
+    PAL_HANDLE child = malloc(HANDLE_SIZE(process));
+    SET_HANDLE_TYPE(child, process);
+    HANDLE_HDR(child)->flags |= RFD(0)|WFD(1)|RFD(2)|WFD(2)|WRITABLE(1)|WRITABLE(2);
+    child->process.stream_in  = proc_fds[0];
+    child->process.stream_out = proc_fds[1];
+    child->process.cargo      = proc_fds[2];
+    child->process.pid = child_pid;
+    child->process.nonblocking = PAL_FALSE;
 
-    lib_AESCMAC((void *) &param.mac_key, AES_CMAC_KEY_LEN,
-                pal_enclave_state.enclave_identifier,
-                sizeof(pal_enclave_state.enclave_identifier),
-                data.keyhash_mac, sizeof(data.keyhash_mac));
+    ret = _DkStreamKeyExchange(child, &child->process.session_key);
+    if (ret < 0)
+        goto failed;
 
-    SGX_DBG(DBG_P|DBG_S, "Attestation data: %s\n",
-            ALLOCA_BYTES2HEXSTR(data.keyhash_mac));
+    sgx_sign_data_t sign_data;
+    ret = generate_sign_data(&child->process.session_key, pal_enclave_state.enclave_id,
+                             &sign_data);
+    if (ret < 0)
+        goto failed;
 
-    ret = _DkStreamAttestationRequest(proc, &data,
-                                      &check_child_mrenclave, &param);
+    ret = _DkStreamReportRequest(child, &sign_data, &check_child_mrenclave);
     if (ret < 0)
-        return ret;
+        goto failed;
 
-    *handle = proc;
+    *handle = child;
     return 0;
-}
 
-struct check_parent_param {
-    PAL_MAC_KEY     mac_key;
-};
+failed:
+    free(child);
+    return ret;
+}
 
-static int check_parent_mrenclave (sgx_arch_hash_t * mrenclave,
-                                   void * signed_data, void * check_param)
-{
+static int check_parent_mrenclave(PAL_HANDLE parent, sgx_arch_hash_t* mrenclave,
+                                  struct pal_enclave_state* remote_state) {
     __UNUSED(mrenclave);
+    sgx_sign_data_t sign_data;
+    int ret = generate_sign_data(&parent->process.session_key, remote_state->enclave_id,
+                                 &sign_data);
+    if (ret < 0)
+        return ret;
 
-    struct pal_enclave_state * remote_state = signed_data;
-    struct proc_attestation_param * data = (void *) &remote_state->data;
-
-    struct check_parent_param * param = check_param;
-
-    /* must make sure the signer of the report is also the owner of the key,
-       in order to prevent man-in-the-middle attack */
-    struct proc_attestation_data check_data;
-    memset(&check_data, 0, sizeof(struct proc_attestation_data));
-
-    lib_AESCMAC((void *) &param->mac_key, AES_CMAC_KEY_LEN,
-                remote_state->enclave_identifier,
-                sizeof(remote_state->enclave_identifier),
-                check_data.keyhash_mac, sizeof(check_data.keyhash_mac));
-
-    if (memcmp(data, &check_data, sizeof(struct proc_attestation_data)))
+    if (memcmp(&remote_state->enclave_data, &sign_data, sizeof(sign_data)))
         return 1;
 
-    /* for now, we will accept any enclave as a parent, but eventually
-       we should check parent, maybe using crypto challenge */
+    /* XXX: For now, accept any enclave, but eventually should challenge the parent process */
     return 0;
 }
 
@@ -289,28 +322,17 @@ int init_child_process (PAL_HANDLE * parent_handle)
     parent->process.pid        = pal_sec.ppid;
     parent->process.nonblocking = PAL_FALSE;
 
-    PAL_SESSION_KEY session_key;
-    int ret = _DkStreamKeyExchange(parent, &session_key);
+    int ret = _DkStreamKeyExchange(parent, &parent->process.session_key);
     if (ret < 0)
         return ret;
 
-    struct check_parent_param param;
-    session_key_to_mac_key(&session_key, &param.mac_key);
-
-    struct proc_attestation_data data;
-    memset(&data, 0, sizeof(struct proc_attestation_data));
-
-    lib_AESCMAC((void *) &param.mac_key, AES_CMAC_KEY_LEN,
-                pal_enclave_state.enclave_identifier,
-                sizeof(pal_enclave_state.enclave_identifier),
-                data.keyhash_mac, sizeof(data.keyhash_mac));
-
-    SGX_DBG(DBG_P|DBG_S, "Attestation data: %s\n",
-            ALLOCA_BYTES2HEXSTR(data.keyhash_mac));
+    sgx_sign_data_t sign_data;
+    ret = generate_sign_data(&parent->process.session_key, pal_enclave_state.enclave_id,
+                             &sign_data);
+    if (ret < 0)
+        return ret;
 
-    ret = _DkStreamAttestationRespond(parent, &data,
-                                      &check_parent_mrenclave,
-                                      &param);
+    ret = _DkStreamReportRespond(parent, &sign_data, &check_parent_mrenclave);
     if (ret < 0)
         return ret;
 

+ 216 - 178
Pal/src/host/Linux-SGX/enclave_framework.c

@@ -88,24 +88,27 @@ uint64_t sgx_copy_to_enclave(const void* ptr, uint64_t maxsize, const void* uptr
     return usize;
 }
 
-int sgx_get_report (sgx_arch_hash_t * mrenclave,
-                    sgx_arch_attributes_t * attributes,
-                    void * enclave_data,
-                    sgx_arch_report_t * report)
-{
-    sgx_arch_targetinfo_t targetinfo;
+static sgx_arch_key128_t enclave_key;
 
-    memset(&targetinfo, 0, sizeof(sgx_arch_targetinfo_t));
-    memcpy(targetinfo.mrenclave, mrenclave, sizeof(sgx_arch_hash_t));
-    memcpy(&targetinfo.attributes, attributes, sizeof(sgx_arch_attributes_t));
+#define KEYBUF_SIZE ((sizeof(sgx_arch_key128_t) * 2) + 1)
 
+/*
+ * sgx_get_report() obtains a CPU-signed report for local attestation
+ * @target_info:  the enclave target info
+ * @data:         the data to be included and signed in the report
+ * @report:       a buffer for storing the report
+ */
+static int sgx_get_report(sgx_arch_targetinfo_t* target_info, sgx_sign_data_t* data,
+                          sgx_arch_report_t* report) {
     struct pal_enclave_state state;
-    memcpy(&state, &pal_enclave_state, sizeof(struct pal_enclave_state));
-    memcpy(&state.data, enclave_data, PAL_ATTESTATION_DATA_SIZE);
+    memcpy(&state, &pal_enclave_state, sizeof(state));
+    memcpy(&state.enclave_data, data, sizeof(*data));
 
-    int ret = sgx_report(&targetinfo, &state, report);
-    if (ret)
-        return -PAL_ERROR_INVAL;
+    int ret = sgx_report(target_info, &state, report);
+    if (ret) {
+        SGX_DBG(DBG_E, "sgx_report failed: ret = %d)\n", ret);
+        return -PAL_ERROR_DENIED;
+    }
 
     SGX_DBG(DBG_S, "Generated report:\n");
     SGX_DBG(DBG_S, "    cpusvn:           %08lx %08lx\n", report->cpusvn[0],
@@ -123,9 +126,6 @@ int sgx_get_report (sgx_arch_hash_t * mrenclave,
     return 0;
 }
 
-static sgx_arch_key128_t enclave_key;
-
-#define KEYBUF_SIZE ((sizeof(sgx_arch_key128_t) * 2) + 1)
 int sgx_verify_report (sgx_arch_report_t * report)
 {
     sgx_arch_keyrequest_t keyrequest;
@@ -133,14 +133,34 @@ int sgx_verify_report (sgx_arch_report_t * report)
     keyrequest.keyname = REPORT_KEY;
     memcpy(keyrequest.keyid, report->keyid, sizeof(keyrequest.keyid));
 
-    int ret = sgx_getkey(&keyrequest, &enclave_key);
+    sgx_arch_key128_t report_key;
+    memset(&report_key, 0, sizeof(report_key));
+
+    int ret = sgx_getkey(&keyrequest, &report_key);
     if (ret) {
-        SGX_DBG(DBG_S, "Can't get report key\n");
+        SGX_DBG(DBG_E, "Can't get report key\n");
         return -PAL_ERROR_DENIED;
     }
 
-    SGX_DBG(DBG_S, "Get report key for verification: %s\n",
-            ALLOCA_BYTES2HEXSTR(enclave_key));
+    SGX_DBG(DBG_S, "Get report key for verification: %s\n", ALLOCA_BYTES2HEXSTR(report_key));
+
+    sgx_arch_mac_t check_mac;
+    memset(&check_mac, 0, sizeof(check_mac));
+
+    lib_AESCMAC((uint8_t*)&report_key, sizeof(report_key),
+                (uint8_t*)report, offsetof(sgx_arch_report_t, keyid),
+                (uint8_t*)&check_mac, sizeof(check_mac));
+
+    memset(&report_key, 0, sizeof(report_key));
+
+    SGX_DBG(DBG_S, "Verify report:\n");
+    SGX_DBG(DBG_S, "    expected:         %s\n", ALLOCA_BYTES2HEXSTR(report->mac));
+    SGX_DBG(DBG_S, "    mac:              %s\n", ALLOCA_BYTES2HEXSTR(check_mac));
+
+    if (memcmp(&check_mac, &report->mac, sizeof(check_mac))) {
+        SGX_DBG(DBG_E, "Report verification failed\n");
+        return -PAL_ERROR_DENIED;
+    }
 
     return 0;
 }
@@ -148,16 +168,16 @@ int sgx_verify_report (sgx_arch_report_t * report)
 int init_enclave_key (void)
 {
     sgx_arch_keyrequest_t keyrequest;
-    memset(&keyrequest, 0, sizeof(sgx_arch_keyrequest_t));
+    memset(&keyrequest, 0, sizeof(keyrequest));
     keyrequest.keyname = SEAL_KEY;
 
     int ret = sgx_getkey(&keyrequest, &enclave_key);
     if (ret) {
-        SGX_DBG(DBG_S, "Can't get report key\n");
+        SGX_DBG(DBG_E, "Can't get seal key\n");
         return -PAL_ERROR_DENIED;
     }
 
-    SGX_DBG(DBG_S, "Get sealing key: %s\n", ALLOCA_BYTES2HEXSTR(enclave_key));
+    SGX_DBG(DBG_S, "Seal key: %s\n", ALLOCA_BYTES2HEXSTR(enclave_key));
     return 0;
 }
 
@@ -227,7 +247,7 @@ static bool path_is_equal_or_subpath(const struct trusted_file* tf,
  * sizeptr:  size pointer
  * create:   this file is newly created or not
  *
- * return:  0 succeed
+ * Returns 0 if succeeded, or an error code otherwise.
  */
 int load_trusted_file (PAL_HANDLE file, sgx_stub_t ** stubptr,
                        uint64_t * sizeptr, int create)
@@ -337,8 +357,7 @@ int load_trusted_file (PAL_HANDLE file, sgx_stub_t ** stubptr,
          * AES-CMAC, and then update the SHA256 digest. */
         uint64_t mapping_size = MIN(tf->size - offset, TRUSTED_STUB_SIZE);
         LIB_AESCMAC_CONTEXT aes_cmac;
-        ret = lib_AESCMACInit(&aes_cmac, (uint8_t *) &enclave_key,
-                              AES_CMAC_KEY_LEN);
+        ret = lib_AESCMACInit(&aes_cmac, (uint8_t*)&enclave_key, sizeof(enclave_key));
         if (ret < 0)
             goto failed;
 
@@ -489,7 +508,7 @@ int copy_and_verify_trusted_file (const char * path, const void * umem,
         /* Check one chunk at a time. */
         uint64_t checking_size = MIN(total_size - checking, TRUSTED_STUB_SIZE);
         uint64_t checking_end = checking + checking_size;
-        uint8_t hash[AES_CMAC_DIGEST_LEN];
+        sgx_checksum_t hash;
 
         if (checking >= offset && checking_end <= offset + size) {
             /* If the checking chunk completely overlaps with the region
@@ -499,17 +518,15 @@ int copy_and_verify_trusted_file (const char * path, const void * umem,
                    checking_size);
 
             /* Storing the checksum (using AES-CMAC) inside hash. */
-            ret = lib_AESCMAC((uint8_t *) &enclave_key,
-                              AES_CMAC_KEY_LEN,
+            ret = lib_AESCMAC((uint8_t*)&enclave_key, sizeof(enclave_key),
                               buffer + checking - offset, checking_size,
-                              hash, sizeof(hash));
+                              (uint8_t*)&hash, sizeof(hash));
         } else {
             /* If the checking chunk only partially overlaps with the region,
              * read the file content in smaller chunks and only copy the part
              * needed by the caller. */
             LIB_AESCMAC_CONTEXT aes_cmac;
-            ret = lib_AESCMACInit(&aes_cmac, (uint8_t *) &enclave_key,
-                                  AES_CMAC_KEY_LEN);
+            ret = lib_AESCMACInit(&aes_cmac, (uint8_t*)&enclave_key, sizeof(enclave_key));
             if (ret < 0)
                 goto failed;
 
@@ -547,7 +564,7 @@ int copy_and_verify_trusted_file (const char * path, const void * umem,
             }
 
             /* Storing the checksum (using AES-CMAC) inside hash. */
-            ret = lib_AESCMACFinish(&aes_cmac, hash, sizeof(hash));
+            ret = lib_AESCMACFinish(&aes_cmac, (uint8_t*)&hash, sizeof(hash));
         }
 
         if (ret < 0)
@@ -562,7 +579,7 @@ int copy_and_verify_trusted_file (const char * path, const void * umem,
          *
          * XXX: Maybe we should zero the buffer after denying the access?
          */
-        if (memcmp(s, hash, sizeof(sgx_stub_t))) {
+        if (memcmp(s, &hash, sizeof(sgx_stub_t))) {
             SGX_DBG(DBG_E, "Accesing file:%s is denied. Does not match with MAC"
                     " at chunk starting at %lu-%lu.\n",
                     path, checking, checking_end);
@@ -958,7 +975,7 @@ int init_enclave (void)
 
     ret = lib_RSAGenerateKey(rsa, RSA_KEY_SIZE, RSA_E);
     if (ret < 0) {
-        SGX_DBG(DBG_S, "lib_RSAGenerateKey failed: %d\n", ret);
+        SGX_DBG(DBG_E, "lib_RSAGenerateKey failed: %d\n", ret);
         return ret;
     }
 
@@ -966,39 +983,38 @@ int init_enclave (void)
 #endif
 
     /*
-     * The enclave identifier is uniquely created for each enclave as a token
+     * The enclave id is uniquely created for each enclave as a token
      * for authenticating the enclave as the sender of attestation.
-     * TODO: documenting the inter-enclave attestation protocol.
+     * See 'host/Linux-SGX/db_process.c' for further explanation.
      */
-    _DkRandomBitsRead(&pal_enclave_state.enclave_identifier,
-                      sizeof(pal_enclave_state.enclave_identifier));
-
-    SGX_DBG(DBG_S, "enclave (software) key hash: %s\n",
-            ALLOCA_BYTES2HEXSTR(pal_enclave_state.enclave_identifier));
+    ret = _DkRandomBitsRead(&pal_enclave_state.enclave_id,
+                            sizeof(pal_enclave_state.enclave_id));
+    if (ret < 0) {
+        SGX_DBG(DBG_E, "Failed to generate a random id: %d\n", ret);
+        return ret;
+    }
 
     return 0;
 }
 
-int _DkStreamKeyExchange (PAL_HANDLE stream, PAL_SESSION_KEY * keyptr)
-{
-    uint8_t session_key[sizeof(PAL_SESSION_KEY)]
-        __attribute__((aligned(sizeof(PAL_SESSION_KEY))));
+int _DkStreamKeyExchange(PAL_HANDLE stream, PAL_SESSION_KEY* key) {
     uint8_t pub[DH_SIZE]   __attribute__((aligned(DH_SIZE)));
     uint8_t agree[DH_SIZE] __attribute__((aligned(DH_SIZE)));
     PAL_NUM pubsz, agreesz;
     LIB_DH_CONTEXT context;
-    int ret;
+    int64_t bytes;
+    int64_t ret;
 
     ret = lib_DhInit(&context);
     if (ret < 0) {
-        SGX_DBG(DBG_S, "Key Exchange: DH Init failed: %d\n", ret);
+        SGX_DBG(DBG_E, "Key Exchange: DH Init failed: %ld\n", ret);
         goto out_no_final;
     }
 
     pubsz = sizeof pub;
     ret = lib_DhCreatePublic(&context, pub, &pubsz);
     if (ret < 0) {
-        SGX_DBG(DBG_S, "Key Exchange: DH CreatePublic failed: %d\n", ret);
+        SGX_DBG(DBG_E, "Key Exchange: DH CreatePublic failed: %ld\n", ret);
         goto out;
     }
 
@@ -1012,37 +1028,56 @@ int _DkStreamKeyExchange (PAL_HANDLE stream, PAL_SESSION_KEY * keyptr)
         memset(pub, 0, DH_SIZE - pubsz);
     }
 
-    ret = _DkStreamWrite(stream, 0, DH_SIZE, pub, NULL, 0);
-    if (ret != DH_SIZE) {
-        SGX_DBG(DBG_S, "Key Exchange: DkStreamWrite failed: %d\n", ret);
-        goto out;
+    for (bytes = 0, ret = 0; bytes < DH_SIZE; bytes += ret) {
+        ret = _DkStreamWrite(stream, 0, DH_SIZE - bytes, pub + bytes, NULL, 0);
+        if (ret < 0) {
+            if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) {
+                ret = 0;
+                continue;
+            }
+            SGX_DBG(DBG_E, "Failed to exchange the secret key via RPC: %ld\n", ret);
+            goto out;
+        }
     }
 
-    ret = _DkStreamRead(stream, 0, DH_SIZE, pub, NULL, 0);
-    if (ret != DH_SIZE) {
-        SGX_DBG(DBG_S, "Key Exchange: DkStreamRead failed: %d\n", ret);
-        goto out;
+    for (bytes = 0, ret = 0 ; bytes < DH_SIZE ; bytes += ret) {
+        ret = _DkStreamRead(stream, 0, DH_SIZE - bytes, pub + bytes, NULL, 0);
+        if (ret < 0) {
+            if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) {
+                ret = 0;
+                continue;
+            }
+            SGX_DBG(DBG_E, "Failed to exchange the secret key via RPC: %ld\n", ret);
+            goto out;
+        }
     }
 
     agreesz = sizeof agree;
     ret = lib_DhCalcSecret(&context, pub, DH_SIZE, agree, &agreesz);
     if (ret < 0) {
-        SGX_DBG(DBG_S, "Key Exchange: DH CalcSecret failed: %d\n", ret);
+        SGX_DBG(DBG_E, "Key Exchange: DH CalcSecret failed: %ld\n", ret);
         goto out;
     }
 
     assert(agreesz > 0 && agreesz <= sizeof agree);
-    // TODO(security): use a real KDF
-    memset(session_key, 0, sizeof(session_key));
-    for (uint32_t i = 0 ; i < agreesz ; i++)
-        session_key[i % sizeof(session_key)] ^= agree[i];
 
-    SGX_DBG(DBG_S, "key exchange: (%p) %s\n", session_key,
-            ALLOCA_BYTES2HEXSTR(session_key));
+    /*
+     * Using SHA256 as a KDF to convert the 128-byte DH secret to a 256-bit AES key.
+     * According to the NIST recommendation:
+     * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Cr1.pdf,
+     * a key derivation function (KDF) can be a secure hash function (e.g., SHA-256),
+     * HMAC, or KMAC.
+     */
+    LIB_SHA256_CONTEXT sha;
+    if ((ret = lib_SHA256Init(&sha)) < 0 ||
+        (ret = lib_SHA256Update(&sha, agree, agreesz)) < 0 ||
+        (ret = lib_SHA256Final(&sha, (uint8_t*)key)) < 0) {
+        SGX_DBG(DBG_E, "Failed to derive the session key: %ld\n", ret);
+        goto out;
+    }
 
-    if (keyptr)
-        memcpy(keyptr, session_key, sizeof(PAL_SESSION_KEY));
 
+    SGX_DBG(DBG_S, "Key exchange succeeded: %s\n", ALLOCA_BYTES2HEXSTR(*key));
     ret = 0;
 out:
     lib_DhFinal(&context);
@@ -1050,101 +1085,98 @@ out_no_final:
     return ret;
 }
 
-struct attestation_request {
-    sgx_arch_hash_t       mrenclave;
-    sgx_arch_attributes_t attributes;
-};
-
-struct attestation {
-    sgx_arch_hash_t       mrenclave;
-    sgx_arch_attributes_t attributes;
-    sgx_arch_report_t     report;
-};
-
-int _DkStreamAttestationRequest (PAL_HANDLE stream, void * data,
-                                 int (*check_mrenclave) (sgx_arch_hash_t *,
-                                                         void *, void *),
-                                 void * check_param)
-{
-    struct attestation_request req;
-    struct attestation att;
-    size_t bytes;
-    int ret;
+/*
+ * Initalize the request of local report exchange.
+ *
+ * We refer to this enclave as A and to the other enclave as B, e.g., A is this
+ * parent enclave and B is the child enclave in the fork case (for more info,
+ * see comments in db_process.c).
+ */
+int _DkStreamReportRequest(PAL_HANDLE stream, sgx_sign_data_t* data,
+                           check_mrenclave_t check_mrenclave) {
+    sgx_arch_targetinfo_t target_info;
+    sgx_arch_report_t report;
+    uint64_t bytes;
+    int64_t ret;
 
-    memcpy(req.mrenclave, pal_sec.mrenclave, sizeof(sgx_arch_hash_t));
-    memcpy(&req.attributes, &pal_sec.enclave_attributes,
+    /* A -> B: targetinfo[A] */
+    memset(&target_info, 0, sizeof(target_info));
+    memcpy(&target_info.mrenclave,  &pal_sec.mrenclave, sizeof(sgx_arch_hash_t));
+    memcpy(&target_info.attributes, &pal_sec.enclave_attributes,
            sizeof(sgx_arch_attributes_t));
 
-    SGX_DBG(DBG_S, "Sending attestation request ... (mrenclave = %s)\n",\
-            ALLOCA_BYTES2HEXSTR(req.mrenclave));
-
-    for (bytes = 0, ret = 0 ; bytes < sizeof(req) ; bytes += ret) {
-        ret = _DkStreamWrite(stream, 0, sizeof(req) - bytes,
-                             ((void *) &req) + bytes, NULL, 0);
+    for (bytes = 0, ret = 0; bytes < SGX_TARGETINFO_FILLED_SIZE; bytes += ret) {
+        ret = _DkStreamWrite(stream, 0, SGX_TARGETINFO_FILLED_SIZE - bytes,
+                             ((void*)&target_info) + bytes, NULL, 0);
         if (ret < 0) {
-            SGX_DBG(DBG_S, "Attestation Request: DkStreamWrite failed: %d\n", ret);
+            if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) {
+                ret = 0;
+                continue;
+            }
+            SGX_DBG(DBG_E, "Failed to send target info via RPC: %ld\n", ret);
             goto out;
         }
     }
 
-    for (bytes = 0, ret = 0 ; bytes < sizeof(att) ; bytes += ret) {
-        ret = _DkStreamRead(stream, 0, sizeof(att) - bytes,
-                            ((void *) &att) + bytes, NULL, 0);
+    /* B -> A: report[B -> A] */
+    for (bytes = 0, ret = 0 ; bytes < sizeof(report) ; bytes += ret) {
+        ret = _DkStreamRead(stream, 0, sizeof(report) - bytes,
+                            ((void*)&report) + bytes, NULL, 0);
         if (ret < 0) {
-            SGX_DBG(DBG_S, "Attestation Request: DkStreamRead failed: %d\n", ret);
+            if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) {
+                ret = 0;
+                continue;
+            }
+            SGX_DBG(DBG_E, "Failed to receive local report via RPC: %ld\n", ret);
             goto out;
         }
     }
 
-    SGX_DBG(DBG_S, "Received attestation (mrenclave = %s)\n",
-            ALLOCA_BYTES2HEXSTR(att.mrenclave));
+    SGX_DBG(DBG_S, "Received local report (mrenclave = %s)\n",
+            ALLOCA_BYTES2HEXSTR(report.mrenclave));
 
-    ret = sgx_verify_report(&att.report);
+    /* Verify report[B -> A] */
+    ret = sgx_verify_report(&report);
     if (ret < 0) {
-        SGX_DBG(DBG_S, "Attestation Request: sgx_verify_report failed: %d\n", ret);
+        SGX_DBG(DBG_E, "Failed to verify local report: %ld\n", ret);
         goto out;
     }
 
-    if (ret == 1) {
-        SGX_DBG(DBG_S, "Remote attestation not signed by SGX!\n");
-        ret = -PAL_ERROR_DENIED;
-        goto out;
-    }
-
-    ret = check_mrenclave(&att.report.mrenclave, &att.report.report_data,
-                          check_param);
+    struct pal_enclave_state* remote_state = (void*)&report.report_data;
+    ret = check_mrenclave(stream, &report.mrenclave, remote_state);
     if (ret < 0) {
-        SGX_DBG(DBG_S, "Attestation Request: check_mrenclave failed: %d\n", ret);
+        SGX_DBG(DBG_E, "Failed to check local report: %ld\n", ret);
         goto out;
     }
 
     if (ret == 1) {
-        SGX_DBG(DBG_S, "Not an allowed enclave (mrenclave = %s). Maybe missing 'sgx.trusted_children' in the manifest file?\n",
-                ALLOCA_BYTES2HEXSTR(att.mrenclave));
+        SGX_DBG(DBG_E, "Not an allowed enclave (mrenclave = %s). Maybe missing 'sgx.trusted_children' in the manifest file?\n",
+                ALLOCA_BYTES2HEXSTR(report.mrenclave));
         ret = -PAL_ERROR_DENIED;
         goto out;
     }
 
-    SGX_DBG(DBG_S, "Remote attestation succeed!\n");
+    SGX_DBG(DBG_S, "Local attestation succeeded!\n");
+
+    /* A -> B: report[A -> B] */
+    memcpy(&target_info.mrenclave , &report.mrenclave,  sizeof(sgx_arch_hash_t));
+    memcpy(&target_info.attributes, &report.attributes, sizeof(sgx_arch_attributes_t));
 
-    ret = sgx_get_report(&att.mrenclave, &att.attributes, data, &att.report);
+    ret = sgx_get_report(&target_info, data, &report);
     if (ret < 0) {
-        SGX_DBG(DBG_S, "Attestation Request: sgx_get_report failed: %d\n", ret);
+        SGX_DBG(DBG_E, "Failed to get local report from CPU: %ld\n", ret);
         goto out;
     }
 
-    memcpy(att.mrenclave, pal_sec.mrenclave, sizeof(sgx_arch_hash_t));
-    memcpy(&att.attributes, &pal_sec.enclave_attributes,
-           sizeof(sgx_arch_attributes_t));
-
-    SGX_DBG(DBG_S, "Sending attestation ... (mrenclave = %s)\n",
-            ALLOCA_BYTES2HEXSTR(att.mrenclave));
-
-    for (bytes = 0, ret = 0 ; bytes < sizeof(att) ; bytes += ret) {
-        ret = _DkStreamWrite(stream, 0, sizeof(att) - bytes,
-                             ((void *) &att) + bytes, NULL, 0);
+    for (bytes = 0, ret = 0 ; bytes < sizeof(report) ; bytes += ret) {
+        ret = _DkStreamWrite(stream, 0, sizeof(report) - bytes,
+                             ((void*)&report) + bytes, NULL, 0);
         if (ret < 0) {
-            SGX_DBG(DBG_S, "Attestation Request: DkStreamWrite failed: %d\n", ret);
+            if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) {
+                ret = 0;
+                continue;
+            }
+            SGX_DBG(DBG_E, "Failed to send local report via RPC: %ld\n", ret);
             goto out;
         }
     }
@@ -1156,88 +1188,94 @@ out:
     return ret;
 }
 
-int _DkStreamAttestationRespond (PAL_HANDLE stream, void * data,
-                                 int (*check_mrenclave) (sgx_arch_hash_t *,
-                                                         void *, void *),
-                                 void * check_param)
-{
-    struct attestation_request req;
-    struct attestation att;
-    size_t bytes;
-    int ret;
-
-    for (bytes = 0, ret = 0 ; bytes < sizeof(req) ; bytes += ret) {
-        ret = _DkStreamRead(stream, 0, sizeof(req) - bytes,
-                            ((void *) &req) + bytes, NULL, 0);
+/*
+ * Respond to the request of local report exchange.
+ *
+ * We refer to this enclave as B and to the other enclave as A, e.g., B is this
+ * child enclave and A is the parent enclave in the fork case (for more info,
+ * see comments in db_process.c).
+ */
+int _DkStreamReportRespond(PAL_HANDLE stream, sgx_sign_data_t* data,
+                           check_mrenclave_t check_mrenclave) {
+    sgx_arch_targetinfo_t target_info;
+    sgx_arch_report_t report;
+    uint64_t bytes;
+    int64_t ret;
+    memset(&target_info, 0, sizeof(target_info));
+
+    /* A -> B: targetinfo[A] */
+    for (bytes = 0, ret = 0 ; bytes < SGX_TARGETINFO_FILLED_SIZE ; bytes += ret) {
+        ret = _DkStreamRead(stream, 0, SGX_TARGETINFO_FILLED_SIZE - bytes,
+                            ((void*)&target_info) + bytes, NULL, 0);
         if (ret < 0) {
-            SGX_DBG(DBG_S, "Attestation Respond: DkStreamRead failed: %d\n", ret);
+            if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) {
+                ret = 0;
+                continue;
+            }
+            SGX_DBG(DBG_E, "Failed to receive target info via RPC: %ld\n", ret);
             goto out;
         }
     }
 
-    SGX_DBG(DBG_S, "Received attestation request ... (mrenclave = %s)\n",
-            ALLOCA_BYTES2HEXSTR(req.mrenclave));
-
-    ret = sgx_get_report(&req.mrenclave, &req.attributes, data, &att.report);
+    /* B -> A: report[B -> A] */
+    ret = sgx_get_report(&target_info, data, &report);
     if (ret < 0) {
-        SGX_DBG(DBG_S, "Attestation Respond: sgx_get_report failed: %d\n", ret);
+        SGX_DBG(DBG_E, "Failed to get local report from CPU: %ld\n", ret);
         goto out;
     }
 
-    memcpy(att.mrenclave, pal_sec.mrenclave, sizeof(sgx_arch_hash_t));
-    memcpy(&att.attributes, &pal_sec.enclave_attributes,
-           sizeof(sgx_arch_attributes_t));
-
-    SGX_DBG(DBG_S, "Sending attestation ... (mrenclave = %s)\n",
-            ALLOCA_BYTES2HEXSTR(att.mrenclave));
-
-    for (bytes = 0, ret = 0 ; bytes < sizeof(att) ; bytes += ret) {
-        ret = _DkStreamWrite(stream, 0, sizeof(att) - bytes,
-                             ((void *) &att) + bytes, NULL, 0);
+    for (bytes = 0, ret = 0 ; bytes < sizeof(report) ; bytes += ret) {
+        ret = _DkStreamWrite(stream, 0, sizeof(report) - bytes,
+                             ((void*)&report) + bytes, NULL, 0);
         if (ret < 0) {
-            SGX_DBG(DBG_S, "Attestation Respond: DkStreamWrite failed: %d\n", ret);
+            if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) {
+                ret = 0;
+                continue;
+            }
+            SGX_DBG(DBG_E, "Failed to send local report via PRC: %ld\n", ret);
             goto out;
         }
     }
 
-    for (bytes = 0, ret = 0 ; bytes < sizeof(att) ; bytes += ret) {
-        ret = _DkStreamRead(stream, 0, sizeof(att) - bytes,
-                            ((void *) &att) + bytes, NULL, 0);
+    /* A -> B: report[A -> B] */
+    for (bytes = 0, ret = 0 ; bytes < sizeof(report) ; bytes += ret) {
+        ret = _DkStreamRead(stream, 0, sizeof(report) - bytes,
+                            ((void*)&report) + bytes, NULL, 0);
         if (ret < 0) {
-            SGX_DBG(DBG_S, "Attestation Respond: DkStreamRead failed: %d\n", ret);
+            if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) {
+                ret = 0;
+                continue;
+            }
+            SGX_DBG(DBG_E, "Failed to receive local report via RPC: %ld\n", ret);
             goto out;
         }
     }
 
-    SGX_DBG(DBG_S, "Received attestation (mrenclave = %s)\n",
-            ALLOCA_BYTES2HEXSTR(att.mrenclave));
+    SGX_DBG(DBG_S, "Received local report (mrenclave = %s)\n",
+            ALLOCA_BYTES2HEXSTR(report.mrenclave));
 
-    ret = sgx_verify_report(&att.report);
+    /* Verify report[A -> B] */
+    ret = sgx_verify_report(&report);
     if (ret < 0) {
-        SGX_DBG(DBG_S, "Attestation Respond: sgx_verify_report failed: %d\n", ret);
-        goto out;
-    }
-
-    if (ret == 1) {
-        SGX_DBG(DBG_S, "Remote attestation not signed by SGX!\n");
+        SGX_DBG(DBG_E, "Failed to verify local report: %ld\n", ret);
         goto out;
     }
 
-    ret = check_mrenclave(&att.report.mrenclave, &att.report.report_data,
-                          check_param);
+    struct pal_enclave_state* remote_state = (void*)&report.report_data;
+    ret = check_mrenclave(stream, &report.mrenclave, remote_state);
     if (ret < 0) {
-        SGX_DBG(DBG_S, "Attestation Request: check_mrenclave failed: %d\n", ret);
+        SGX_DBG(DBG_E, "Failed to check mrenclave: %ld\n", ret);
         goto out;
     }
 
     if (ret == 1) {
-        SGX_DBG(DBG_S, "Not an allowed enclave (mrenclave = %s). Maybe missing 'sgx.trusted_children' in the manifest file?\n",
-                ALLOCA_BYTES2HEXSTR(att.mrenclave));
+        SGX_DBG(DBG_E, "Not an allowed enclave (mrenclave = %s). Maybe missing 'sgx.trusted_children' in the manifest file?\n",
+                ALLOCA_BYTES2HEXSTR(report.mrenclave));
         ret = -PAL_ERROR_DENIED;
         goto out;
     }
 
-    SGX_DBG(DBG_S, "Remote attestation succeeded!\n");
+    SGX_DBG(DBG_S, "Local attestation succeeded!\n");
     return 0;
 
 out:

+ 2 - 5
Pal/src/host/Linux-SGX/enclave_ocalls.c

@@ -486,11 +486,8 @@ int ocall_wake_thread (void * tcs)
     return sgx_ocall(OCALL_WAKE_THREAD, tcs);
 }
 
-int ocall_create_process (const char * uri,
-                          int nargs, const char ** args,
-                          int procfds[3],
-                          unsigned int * pid)
-{
+int ocall_create_process(const char* uri, int nargs, const char** args, int procfds[3],
+                         unsigned int* pid) {
     int retval = 0;
     int ulen = uri ? strlen(uri) + 1 : 0;
     ms_ocall_create_process_t * ms;

+ 2 - 4
Pal/src/host/Linux-SGX/enclave_ocalls.h

@@ -80,10 +80,8 @@ int ocall_sock_shutdown (int sockfd, int how);
 
 int ocall_wake_thread (void * tcs);
 
-int ocall_create_process (const char * uri,
-                          int nargs, const char ** args,
-                          int procfds[3],
-                          unsigned int * pid);
+int ocall_create_process(const char* uri, int nargs, const char** args, int procfds[3],
+                         unsigned int* pid);
 
 int ocall_futex(int* uaddr, int op, int val, int64_t timeout_us);
 

+ 4 - 0
Pal/src/host/Linux-SGX/pal_host.h

@@ -76,6 +76,9 @@ struct pal_handle_thread {
     void * param;
 };
 
+/* RPC streams are encrypted with 256-bit AES keys */
+typedef uint8_t PAL_SESSION_KEY[32];
+
 typedef struct pal_handle
 {
     /*
@@ -149,6 +152,7 @@ typedef struct pal_handle
             PAL_IDX cargo;
             PAL_IDX pid;
             PAL_BOL nonblocking;
+            PAL_SESSION_KEY session_key;
         } process;
 
         struct {

+ 29 - 32
Pal/src/host/Linux-SGX/pal_linux.h

@@ -135,44 +135,39 @@ int copy_and_verify_trusted_file (const char * path, const void * umem,
 int init_trusted_children (void);
 int register_trusted_child (const char * uri, const char * mrenclave_str);
 
-/* if a stream is encrypted, its key is 256 bit */
-typedef uint8_t PAL_SESSION_KEY [32];
-typedef uint8_t PAL_MAC_KEY [16];
-
-static inline
-void session_key_to_mac_key (PAL_SESSION_KEY * session_key,
-                             PAL_MAC_KEY * mac_key)
-{
-    uint8_t * s = (void *) session_key;
-    uint8_t * m = (void *) mac_key;
-    for (int i = 0 ; i < 16 ; i++)
-        m[i] = s[i] ^ s[16 + i];
-}
-
 /* exchange and establish a 256-bit session key */
-int _DkStreamKeyExchange (PAL_HANDLE stream, PAL_SESSION_KEY * key);
-
-/* request and respond for remote attestation */
-int _DkStreamAttestationRequest (PAL_HANDLE stream, void * data,
-                                 int (*check_mrenclave) (sgx_arch_hash_t *,
-                                                         void *, void *),
-                                 void * check_param);
-int _DkStreamAttestationRespond (PAL_HANDLE stream, void * data,
-                                 int (*check_mrenclave) (sgx_arch_hash_t *,
-                                                         void *, void *),
-                                 void * check_param);
+int _DkStreamKeyExchange(PAL_HANDLE stream, PAL_SESSION_KEY* key);
 
-/* enclave state used for generating report */
-#define PAL_ATTESTATION_DATA_SIZE   24
+typedef uint8_t sgx_sign_data_t[48];
 
+/* enclave state used for generating report */
 extern struct pal_enclave_state {
-    uint64_t enclave_flags;         /* flags to specify the state of the
-                                       enclave */
-    uint8_t  data[PAL_ATTESTATION_DATA_SIZE];
-                                    /* reserved for filling other data */
-    sgx_arch_hash_t enclave_identifier;  /* unique identifier of the enclave */
+    uint64_t        enclave_flags;      // Reserved for flags
+    uint64_t        enclave_id;         // Unique identifier for authentication
+    sgx_sign_data_t enclave_data;       // Reserved for signing other data
 } __attribute__((packed, aligned (128))) pal_enclave_state;
 
+/*
+ * sgx_verify_report: verify a CPU-signed report from another local enclave
+ * @report: the buffer storing the report to verify
+ */
+int sgx_verify_report(sgx_arch_report_t* report);
+
+typedef int (*check_mrenclave_t)(PAL_HANDLE, sgx_arch_hash_t*, struct pal_enclave_state*);
+
+/*
+ * _DkStreamReportRequest, _DkStreamReportRespond:
+ * Request and respond a local report on an RPC stream
+ *
+ * @stream:          stream handle for sending and receiving messages
+ * @data:            data to sign in the outbound message
+ * @check_mrenclave: callback function for checking the measurement of the other end
+ */
+int _DkStreamReportRequest(PAL_HANDLE stream, sgx_sign_data_t* data,
+                           check_mrenclave_t check_mrenclave);
+int _DkStreamReportRespond(PAL_HANDLE stream, sgx_sign_data_t* data,
+                           check_mrenclave_t check_mrenclave);
+
 #include "sgx_arch.h"
 
 #define PAL_ENCLAVE_INITIALIZED     0x0001ULL
@@ -187,6 +182,8 @@ extern struct pal_enclave_config {
 
 #else
 
+int sgx_create_process(const char* uri, int nargs, const char** args, int* retfds);
+
 #ifdef DEBUG
 # ifndef SIGCHLD
 #  define SIGCHLD  17

+ 0 - 8
Pal/src/host/Linux-SGX/sgx_api.h

@@ -32,14 +32,6 @@ void sgx_reset_ustack(void);
 bool sgx_copy_ptr_to_enclave(void** ptr, void* uptr, uint64_t size);
 uint64_t sgx_copy_to_enclave(const void* ptr, uint64_t maxsize, const void* uptr, uint64_t usize);
 
-
-int sgx_get_report (sgx_arch_hash_t * mrenclave,
-                    sgx_arch_attributes_t * attributes,
-                    void * enclave_data,
-                    sgx_arch_report_t * report);
-
-int sgx_verify_report (sgx_arch_report_t * report);
-
 /*
  * sgx_report:
  * Generate SGX hardware signed report.

+ 3 - 0
Pal/src/host/Linux-SGX/sgx_arch.h

@@ -237,6 +237,9 @@ typedef struct {
     uint8_t  reserved[464];
 } __attribute__((packed, aligned(512))) sgx_arch_targetinfo_t;
 
+#define SGX_TARGETINFO_FILLED_SIZE  (sizeof(sgx_arch_hash_t) + \
+                                     sizeof(sgx_arch_attributes_t))
+
 typedef struct {
     uint16_t keyname;
     uint16_t keypolicy;

+ 2 - 7
Pal/src/host/Linux-SGX/sgx_enclave.c

@@ -237,17 +237,12 @@ static int sgx_ocall_wake_thread(void * pms)
     return pms ? interrupt_thread(pms) : clone_thread();
 }
 
-int sgx_create_process (const char * uri,
-                        int nargs, const char ** args,
-                        int * retfds);
-
 static int sgx_ocall_create_process(void * pms)
 {
     ms_ocall_create_process_t * ms = (ms_ocall_create_process_t *) pms;
     ODEBUG(OCALL_CREATE_PROCESS, ms);
-    int ret = sgx_create_process(ms->ms_uri, ms->ms_nargs, ms->ms_args,
-                                 ms->ms_proc_fds);
-    if (IS_ERR(ret))
+    int ret = sgx_create_process(ms->ms_uri, ms->ms_nargs, ms->ms_args, ms->ms_proc_fds);
+    if (ret < 0)
         return ret;
     ms->ms_pid = ret;
     return 0;

+ 1 - 3
Pal/src/host/Linux-SGX/sgx_process.c

@@ -80,9 +80,7 @@ vfork_exec(int pipe_input, int proc_fds[3], const char** argv)
     return 0;
 }
 
-int sgx_create_process (const char * uri, int nargs, const char ** args,
-                        int * retfds)
-{
+int sgx_create_process(const char* uri, int nargs, const char** args, int * retfds) {
     int ret, rete, child;
     int fds[6] = { -1, -1, -1, -1, -1, -1 };