123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469 |
- #include "pal_defs.h"
- #include "pal_linux_defs.h"
- #include "pal.h"
- #include "pal_internal.h"
- #include "pal_linux.h"
- #include "pal_debug.h"
- #include "pal_error.h"
- #include "pal_security.h"
- #include "pal_crypto.h"
- #include "api.h"
- #include <linux/sched.h>
- #include <linux/types.h>
- #include <linux/fs.h>
- typedef __kernel_pid_t pid_t;
- #include <asm/fcntl.h>
- DEFINE_LIST(trusted_child);
- struct trusted_child {
- LIST_TYPE(trusted_child) list;
- sgx_arch_hash_t mrenclave;
- char uri[];
- };
- DEFINE_LISTP(trusted_child);
- static LISTP_TYPE(trusted_child) trusted_children = LISTP_INIT;
- static struct spinlock trusted_children_lock = LOCK_INIT;
- int register_trusted_child(const char * uri, const char * mrenclave_str)
- {
- struct trusted_child * tc = NULL, * new;
- int uri_len = strlen(uri);
- _DkSpinLock(&trusted_children_lock);
- listp_for_each_entry(tc, &trusted_children, list) {
- if (!memcmp(tc->uri, uri, uri_len + 1)) {
- _DkSpinUnlock(&trusted_children_lock);
- return 0;
- }
- }
- _DkSpinUnlock(&trusted_children_lock);
- new = malloc(sizeof(struct trusted_child) + uri_len);
- if (!new)
- return -PAL_ERROR_NOMEM;
- INIT_LIST_HEAD(new, list);
- memcpy(new->uri, uri, uri_len + 1);
- char mrenclave_text[sizeof(sgx_arch_hash_t) * 2 + 1] = "\0";
- int nbytes = 0;
- for (; nbytes < sizeof(sgx_arch_hash_t) ; nbytes++) {
- char byte1 = mrenclave_str[nbytes * 2];
- char byte2 = mrenclave_str[nbytes * 2 + 1];
- unsigned char val = 0;
- if (byte1 == 0 || byte2 == 0) {
- break;
- }
- if (!(byte1 >= '0' && byte1 <= '9') &&
- !(byte1 >= 'a' && byte1 <= 'f')) {
- break;
- }
- if (!(byte2 >= '0' && byte2 <= '9') &&
- !(byte2 >= 'a' && byte2 <= 'f')) {
- break;
- }
- if (byte1 >= '0' && byte1 <= '9')
- val = byte1 - '0';
- if (byte1 >= 'a' && byte1 <= 'f')
- val = byte1 - 'a' + 10;
- val *= 16;
- if (byte2 >= '0' && byte2 <= '9')
- val += byte2 - '0';
- if (byte2 >= 'a' && byte2 <= 'f')
- val += byte2 - 'a' + 10;
- new->mrenclave[nbytes] = val;
- snprintf(mrenclave_text + nbytes * 2, 3, "%02x", val);
- }
- if (nbytes < sizeof(sgx_arch_hash_t)) {
- free(new);
- return -PAL_ERROR_INVAL;
- }
- SGX_DBG(DBG_S, "trusted: %s %s\n", mrenclave_text, new->uri);
- _DkSpinLock(&trusted_children_lock);
- listp_for_each_entry(tc, &trusted_children, list) {
- if (!memcmp(tc->uri, uri, uri_len + 1)) {
- _DkSpinUnlock(&trusted_children_lock);
- free(new);
- return 0;
- }
- }
- listp_add_tail(new, &trusted_children, list);
- _DkSpinUnlock(&trusted_children_lock);
- 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;
- };
- 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;
-
- if (remote_state->enclave_flags & PAL_ENCLAVE_INITIALIZED)
- return 1;
- struct check_child_param * param = check_param;
-
- struct proc_attestation_data check_data;
- memset(&check_data, 0, sizeof(struct proc_attestation_data));
- lib_AESCMAC((void *) ¶m->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)))
- return 1;
-
- if (!memcmp(mrenclave, pal_sec.mrenclave, sizeof(sgx_arch_hash_t))) {
- SGX_DBG(DBG_S, "trusted child: <forked>\n");
- return 0;
- }
- struct trusted_child * tc;
- _DkSpinLock(&trusted_children_lock);
- listp_for_each_entry(tc, &trusted_children, list) {
- if (!memcmp(mrenclave, tc->mrenclave, sizeof(sgx_arch_hash_t))) {
- _DkSpinUnlock(&trusted_children_lock);
- SGX_DBG(DBG_S, "trusted child: %s\n", tc->uri);
- return 0;
- }
- }
- _DkSpinUnlock(&trusted_children_lock);
- return 1;
- }
- int _DkProcessCreate (PAL_HANDLE * handle, const char * uri,
- int flags, const char ** args)
- {
-
- if (!strpartcmp_static(uri, "file:"))
- return -PAL_ERROR_INVAL;
- unsigned int child_pid;
- int proc_fds[3];
- int nargs = 0, ret;
- if (args)
- for (const char ** a = args ; *a ; a++)
- nargs++;
- ret = ocall_create_process(uri, nargs, args,
- proc_fds,
- &child_pid);
- if (ret < 0)
- return 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)|WRITEABLE(1)|WRITEABLE(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);
- if (ret < 0)
- return ret;
- struct check_child_param param;
- session_key_to_mac_key(&session_key, ¶m.mac_key);
- param.uri = uri;
- struct proc_attestation_data data;
- memset(&data, 0, sizeof(struct proc_attestation_data));
- lib_AESCMAC((void *) ¶m.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));
- ret = _DkStreamAttestationRequest(proc, &data,
- &check_child_mrenclave, ¶m);
- if (ret < 0)
- return ret;
- *handle = proc;
- return 0;
- }
- struct check_parent_param {
- PAL_MAC_KEY mac_key;
- };
- static int check_parent_mrenclave (sgx_arch_hash_t * mrenclave,
- void * signed_data, void * check_param)
- {
- struct pal_enclave_state * remote_state = signed_data;
- struct proc_attestation_param * data = (void *) &remote_state->data;
- struct check_parent_param * param = check_param;
-
- struct proc_attestation_data check_data;
- memset(&check_data, 0, sizeof(struct proc_attestation_data));
- lib_AESCMAC((void *) ¶m->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)))
- return 1;
-
- return 0;
- }
- int init_child_process (PAL_HANDLE * parent_handle)
- {
- PAL_HANDLE parent = malloc(HANDLE_SIZE(process));
- SET_HANDLE_TYPE(parent, process);
- HANDLE_HDR(parent)->flags |= RFD(0)|WFD(1)|RFD(2)|WFD(2)|WRITEABLE(1)|WRITEABLE(2);
- parent->process.stream_in = pal_sec.proc_fds[0];
- parent->process.stream_out = pal_sec.proc_fds[1];
- parent->process.cargo = pal_sec.proc_fds[2];
- parent->process.pid = pal_sec.ppid;
- parent->process.nonblocking = PAL_FALSE;
- PAL_SESSION_KEY session_key;
- int ret = _DkStreamKeyExchange(parent, &session_key);
- if (ret < 0)
- return ret;
- struct check_parent_param param;
- session_key_to_mac_key(&session_key, ¶m.mac_key);
- struct proc_attestation_data data;
- memset(&data, 0, sizeof(struct proc_attestation_data));
- lib_AESCMAC((void *) ¶m.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));
- ret = _DkStreamAttestationRespond(parent, &data,
- &check_parent_mrenclave,
- ¶m);
- if (ret < 0)
- return ret;
- *parent_handle = parent;
- return 0;
- }
- void print_alloced_pages (void);
- void _DkProcessExit (int exitcode)
- {
- #if PRINT_ENCLAVE_STAT
- print_alloced_pages();
- #endif
- if (exitcode)
- SGX_DBG(DBG_I, "DkProcessExit: Returning exit code %d\n", exitcode);
- ocall_exit(exitcode);
- }
- int _DkProcessSandboxCreate (const char * manifest, int flags)
- {
- return -PAL_ERROR_NOTIMPLEMENTED;
- }
- static int64_t proc_read (PAL_HANDLE handle, uint64_t offset, uint64_t count,
- void * buffer)
- {
- if (count >= (1ULL << (sizeof(unsigned int) * 8)))
- return -PAL_ERROR_INVAL;
- return ocall_read(handle->process.stream_in, buffer, count);
- }
- static int64_t proc_write (PAL_HANDLE handle, uint64_t offset, uint64_t count,
- const void * buffer)
- {
- if (count >= (1ULL << (sizeof(unsigned int) * 8)))
- return -PAL_ERROR_INVAL;
- int bytes = ocall_write(handle->process.stream_out, buffer, count);
- if (bytes == -PAL_ERROR_TRYAGAIN)
- HANDLE_HDR(handle)->flags &= ~WRITEABLE(1);
- if (bytes < 0)
- return bytes;
- if (bytes == count)
- HANDLE_HDR(handle)->flags |= WRITEABLE(1);
- else
- HANDLE_HDR(handle)->flags &= ~WRITEABLE(1);
- return bytes;
- }
- static int proc_close (PAL_HANDLE handle)
- {
- if (handle->process.stream_in != PAL_IDX_POISON) {
- ocall_close(handle->process.stream_in);
- handle->process.stream_in = PAL_IDX_POISON;
- }
- if (handle->process.stream_out != PAL_IDX_POISON) {
- ocall_close(handle->process.stream_out);
- handle->process.stream_out = PAL_IDX_POISON;
- }
- if (handle->process.cargo != PAL_IDX_POISON) {
- ocall_close(handle->process.cargo);
- handle->process.cargo = PAL_IDX_POISON;
- }
- return 0;
- }
- static int proc_delete (PAL_HANDLE handle, int access)
- {
- int shutdown;
- switch (access) {
- case 0:
- shutdown = SHUT_RDWR;
- break;
- case PAL_DELETE_RD:
- shutdown = SHUT_RD;
- break;
- case PAL_DELETE_WR:
- shutdown = SHUT_WR;
- break;
- default:
- return -PAL_ERROR_INVAL;
- }
- if (access != PAL_DELETE_WR &&
- handle->process.stream_in != PAL_IDX_POISON) {
- ocall_close(handle->process.stream_in);
- handle->process.stream_in = PAL_IDX_POISON;
- }
- if (access != PAL_DELETE_RD &&
- handle->process.stream_out != PAL_IDX_POISON) {
- ocall_close(handle->process.stream_out);
- handle->process.stream_out = PAL_IDX_POISON;
- }
- if (handle->process.cargo != PAL_IDX_POISON)
- ocall_sock_shutdown(handle->process.cargo, shutdown);
- return 0;
- }
- static int proc_attrquerybyhdl (PAL_HANDLE handle, PAL_STREAM_ATTR * attr)
- {
- if (handle->process.stream_in == PAL_IDX_POISON)
- return -PAL_ERROR_BADHANDLE;
- int ret = ocall_fionread(handle->process.stream_in);
- if (ret < 0)
- return -ret;
- memset(attr, 0, sizeof(PAL_STREAM_ATTR));
- attr->pending_size = ret;
- attr->disconnected = HANDLE_HDR(handle)->flags & (ERROR(0)|ERROR(1));
- attr->readable = (attr->pending_size > 0);
- attr->writeable = HANDLE_HDR(handle)->flags & WRITEABLE(1);
- attr->nonblocking = handle->process.nonblocking;
- return 0;
- }
- static int proc_attrsetbyhdl (PAL_HANDLE handle, PAL_STREAM_ATTR * attr)
- {
- if (handle->process.stream_in == PAL_IDX_POISON)
- return -PAL_ERROR_BADHANDLE;
- if (attr->nonblocking != handle->process.nonblocking) {
- int ret = ocall_fsetnonblock(handle->process.stream_in,
- handle->process.nonblocking);
- if (ret < 0)
- return ret;
- handle->process.nonblocking = attr->nonblocking;
- }
- return 0;
- }
- struct handle_ops proc_ops = {
- .read = &proc_read,
- .write = &proc_write,
- .close = &proc_close,
- .delete = &proc_delete,
- .attrquerybyhdl = &proc_attrquerybyhdl,
- .attrsetbyhdl = &proc_attrsetbyhdl,
- };
|