├── .dockerignore ├── .envrc ├── .gitignore ├── .gitmodules ├── .travis.yml ├── COPYING ├── Dockerfile ├── Makefile ├── README.md ├── README.old.md ├── apps ├── helloworld │ ├── Makefile │ ├── README.md │ └── helloworld.c ├── jvm │ └── helloworld-java │ │ ├── HelloWorld.java │ │ ├── Makefile │ │ ├── buildenv.sh │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── github │ │ └── lsds │ │ └── sgx-lkl │ │ └── helloworld │ │ └── HelloWorld.java ├── miniroot │ ├── Makefile │ ├── README.md │ └── buildenv.sh └── nix │ ├── TODO.md │ ├── aesni.py │ ├── apps_graphs.py │ ├── bench_memcpy.py │ ├── bind_nic.py │ ├── bind_nvme.py │ ├── build-image.nix │ ├── busybox-mlock.patch │ ├── dd.py │ ├── default.nix │ ├── dummy.nix │ ├── fio-pool-size.patch │ ├── fio.py │ ├── graph_utils.py │ ├── graphene │ ├── default.nix │ ├── graphene.nix │ ├── run-graphene.nix │ ├── run-graphene.py │ └── shebang-bypass.patch │ ├── graphs.py │ ├── hdparm.py │ ├── helpers.py │ ├── iotest-image.nix │ ├── iperf-optimizations.py │ ├── iperf.py │ ├── iperf │ ├── 0001-iperf-add-multi-threading-server.patch │ └── default.nix │ ├── latency-test │ ├── default.nix │ └── main.c │ ├── memcpy-test │ ├── default.nix │ ├── main.c │ ├── memcpy-avx2.S │ └── memcpy_org.s │ ├── micro_bench_plots.py │ ├── musl_uintptr.patch │ ├── mysql-5.5.x.nix │ ├── mysql.patch │ ├── mysql.py │ ├── netdb-defines.patch │ ├── network-test-bs.py │ ├── network-test │ ├── Makefile │ ├── default.nix │ └── main.c │ ├── network.py │ ├── nginx.py │ ├── parallel-iperf.py │ ├── plot.py │ ├── process_wrk.py │ ├── pthread-socket │ ├── default.nix │ └── main.c │ ├── python-scripts │ ├── default.nix │ └── introspect-blocks.py │ ├── redis.py │ ├── run-image.nix │ ├── run-image.py │ ├── scone │ ├── default.nix │ └── sgx-musl.conf │ ├── setup.cfg │ ├── sgx-lkl │ └── default.nix │ ├── simpleio.py │ ├── simpleio │ ├── Makefile │ ├── default.nix │ ├── gethostname.c │ ├── main.c │ └── udp-send.c │ ├── smp.py │ ├── spdk-zerocopy.py │ ├── sqlite.py │ ├── storage.py │ ├── syscall-perf.py │ ├── tests.py │ ├── wrk_args.json │ └── ycsb │ └── default.nix ├── config.mak ├── default.nix ├── gdb ├── README.md ├── gdb-sgx-plugin │ ├── gdb_sgx_cmd │ ├── gdb_sgx_plugin.py │ ├── load_symbol_cmd.py │ ├── readelf.py │ └── sgx_emmt.py ├── gdb.py ├── inspect-backtrace.py ├── ptrace │ ├── Makefile │ ├── README.md │ ├── arch.h │ ├── inst.h │ ├── se_cdefs.h │ ├── se_memory.c │ ├── se_memory.h │ ├── se_ptrace.c │ ├── se_trace.c │ ├── se_trace.h │ ├── se_types.h │ ├── sgx.h │ ├── sgx_attributes.h │ ├── sgx_defs.h │ ├── sgx_error.h │ ├── sgx_key.h │ ├── sgx_report.h │ ├── sgx_tcrypto.h │ ├── thread_data.h │ └── util.h └── setup.sh ├── martha.env ├── reproduce.py ├── sgx-lkl-docker.sh ├── src ├── Makefile ├── attestation │ ├── aesm.c │ └── attest_ias.c ├── ctl │ ├── default_ias_sign_ca_cert.c │ ├── sgxlkl_ctl.c │ ├── verify_report.c │ └── verify_report.h ├── dpdk │ └── override │ │ ├── defconfig │ │ └── uint.h ├── host │ ├── sgx_hostcall_interface.c │ └── sgx_hostcalls.c ├── include │ ├── aesm.h │ ├── attest.h │ ├── attest_ias.h │ ├── base64.h │ ├── bitops.h │ ├── dpdk.h │ ├── dpdk_config.h │ ├── dpdk_internal.h │ ├── enclave_cmd.h │ ├── enclave_mem.h │ ├── enclave_signal.h │ ├── ias-ra.h │ ├── json_util.h │ ├── lkl │ │ ├── disk.h │ │ ├── dpdk.h │ │ ├── iomem.h │ │ ├── jmp_buf.h │ │ ├── posix-host.h │ │ ├── setup.h │ │ ├── spdk.h │ │ ├── virtio.h │ │ ├── virtio_net.h │ │ └── virtio_queue.h │ ├── lthread.h │ ├── lthread_int.h │ ├── mpmc_queue.h │ ├── pcap.h │ ├── ping.h │ ├── platform_info_blob.h │ ├── queue.h │ ├── sgx_enclave_config.h │ ├── sgx_enclave_report.h │ ├── sgx_hostcall_interface.h │ ├── sgx_hostcalls.h │ ├── sgxlkl_app_config.h │ ├── sgxlkl_debug.h │ ├── sgxlkl_util.h │ ├── spdk_bench.h │ ├── spdk_context.h │ ├── ticketlock.h │ ├── tree.h │ ├── userpci.h │ ├── wireguard.h │ └── wireguard_util.h ├── lkl │ ├── disk.c │ ├── disk_mem.c │ ├── dpdk.c │ ├── jmp_buf.c │ ├── ls.h │ ├── override │ │ ├── defconfig │ │ └── include │ │ │ ├── stdint.h │ │ │ └── uapi │ │ │ └── asm-generic │ │ │ └── stat.h │ ├── pcap.c │ ├── ping.c │ ├── posix-host.c │ ├── setup.c │ ├── spdk.c │ ├── virtio_net.c │ └── virtio_queue.c ├── main │ ├── dpdk.c │ ├── load_elf.c │ ├── load_elf.h │ ├── meminfo.c │ ├── meminfo.h │ ├── sgxlkl_config.c │ ├── sgxlkl_config.h │ ├── sgxlkl_host_debug.h │ ├── sgxlkl_run.c │ ├── spdk_hugetbl.c │ ├── spdk_hugetbl.h │ └── userpci.c ├── sched │ ├── debug.c │ ├── futex.c │ └── lthread.c ├── sgx-lkl-userpci │ ├── dpdk.c │ ├── dpdk.h │ └── main.c ├── sgx-lkl-virt2phy │ └── main.c ├── sgx │ ├── enclave_cmd.c │ ├── enclave_mem.c │ ├── enclave_signal.c │ ├── gdb_hook.c │ ├── include │ │ ├── elf.h │ │ ├── isgx_user.h │ │ ├── libsgx.h │ │ └── sgx.h │ ├── libs │ │ ├── lible.a │ │ └── lible.o │ ├── proto │ │ └── sgxlkl_ctl.proto │ ├── sgx.c │ ├── sgx_enclave_config.c │ ├── sgx_enclave_report.c │ ├── sgx_sign.c │ ├── sgxlkl_app_config.c │ ├── sgxlkl_debug.c │ ├── sgxlkl_sign.c │ ├── sgxlkl_sign_cmdline.c │ └── sgxlkl_sign_cmdline.h ├── shared │ ├── base64.c │ ├── json_util.c │ ├── mpmc_queue.c │ ├── ring_buff.c │ ├── ring_buff.h │ ├── sgxlkl_util.c │ ├── spdk_bench.c │ └── spdk_context.c ├── spdk │ └── override │ │ └── config.mk └── wireguard │ ├── wireguard.c │ └── wireguard_util.c ├── third_party ├── Makefile ├── cryptsetup-override │ └── lib │ │ ├── luks1 │ │ └── af.c │ │ ├── luks2 │ │ └── luks2_disk_metadata.c │ │ └── utils_crypt.c ├── linux-sgx │ ├── README.md │ ├── common │ │ └── inc │ │ │ ├── epid │ │ │ └── common │ │ │ │ └── types.h │ │ │ ├── internal │ │ │ ├── arch.h │ │ │ ├── inst.h │ │ │ ├── se_cdefs.h │ │ │ ├── se_memcpy.h │ │ │ ├── se_quote_internal.h │ │ │ ├── se_types.h │ │ │ ├── trts_inst.h │ │ │ └── util.h │ │ │ ├── sgx.h │ │ │ ├── sgx_attributes.h │ │ │ ├── sgx_defs.h │ │ │ ├── sgx_eid.h │ │ │ ├── sgx_error.h │ │ │ ├── sgx_key.h │ │ │ ├── sgx_quote.h │ │ │ ├── sgx_report.h │ │ │ ├── sgx_tcrypto.h │ │ │ ├── sgx_uae_service.h │ │ │ └── sgx_urts.h │ └── psw │ │ └── ae │ │ └── common │ │ └── proto │ │ └── messages.proto ├── mbedtls │ ├── asn1parse.c │ ├── bignum.c │ ├── include │ │ └── mbedtls │ │ │ ├── aes.h │ │ │ ├── aesni.h │ │ │ ├── asn1.h │ │ │ ├── bignum.h │ │ │ ├── bn_mul.h │ │ │ ├── check_config.h │ │ │ ├── cipher.h │ │ │ ├── config.h │ │ │ ├── ctr_drbg.h │ │ │ ├── dhm.h │ │ │ ├── ecdsa.h │ │ │ ├── ecp.h │ │ │ ├── entropy.h │ │ │ ├── entropy_poll.h │ │ │ ├── md.h │ │ │ ├── md5.h │ │ │ ├── md_internal.h │ │ │ ├── net.h │ │ │ ├── oid.h │ │ │ ├── padlock.h │ │ │ ├── pk.h │ │ │ ├── platform.h │ │ │ ├── platform_time.h │ │ │ ├── platform_util.h │ │ │ ├── ripemd160.h │ │ │ ├── rsa.h │ │ │ ├── rsa_internal.h │ │ │ ├── sha1.h │ │ │ ├── sha256.h │ │ │ ├── sha512.h │ │ │ ├── threading.h │ │ │ ├── timing.h │ │ │ └── x509.h │ ├── md.c │ ├── md5.c │ ├── md_wrap.c │ ├── oid.c │ ├── platform.c │ ├── platform_util.c │ ├── ripemd160.c │ ├── rsa.c │ ├── rsa_internal.c │ ├── sha1.c │ ├── sha256.c │ ├── sha512.c │ └── threading.c ├── protobuf-c-rpc │ ├── config.h │ ├── gsklistmacros.h │ ├── gskrbtreemacros.h │ ├── protobuf-c-rpc-client.c │ ├── protobuf-c-rpc-data-buffer.c │ ├── protobuf-c-rpc-data-buffer.h │ ├── protobuf-c-rpc-dispatch.c │ ├── protobuf-c-rpc-dispatch.h │ ├── protobuf-c-rpc-server.c │ └── protobuf-c-rpc.h ├── protobufc.patch └── sys-queue │ └── include │ └── sys │ └── queue.h └── tools ├── build_linux_4.17_x86_crypto_modules.sh ├── check-hugepages-allocations.py ├── find-gcc-headers.sh ├── gen_enclave_key.sh ├── gen_init_array.py ├── generate_syscall_remap.py ├── kmod-set-fsgsbase ├── .gitignore ├── Makefile └── mod_set_cr4_fsgsbase.c ├── libsgxlkl.ld ├── linux_4.17_x86_crypto_modules.config ├── lkl_bits.c ├── lkl_syscalls.c ├── ncore.sh ├── sgx-lkl-disk ├── sgx-lkl-java ├── sgx-lkl.ld └── sgx_lkl_sign_options.ggo /.dockerignore: -------------------------------------------------------------------------------- 1 | ** 2 | !/build/** 3 | !/apps/jvm/helloworld-java/** 4 | !/apps/miniroot/** 5 | !/tools/** 6 | !/enclave_rootfs.img 7 | **/*.o 8 | **/*.h 9 | **/*.c 10 | **/*.a 11 | **/*.lo 12 | **/*.cmd 13 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | use nix 2 | 3 | mkdir -p build .extra-cmds 4 | 5 | regex='([0-9]+)\.([0-9]+)' 6 | [[ $(uname -r) =~ $regex ]] 7 | ln -sf \ 8 | $(command -v sudo) \ 9 | $(command -v perf) \ 10 | $(command -v perf_${BASH_REMATCH[1]}.${BASH_REMATCH[2]}) \ 11 | .extra-cmds 12 | 13 | export PATH=$PATH:$(realpath gdb):$(realpath .extra-cmds) 14 | 15 | # ignore system paths 16 | export PATH=$(p=$(echo $PATH | tr ":" "\n" | grep -Ev "^(/bin|/sbin|/usr/bin|/usr/sbin|/usr/local/bin|/usr/local/sbin)" | tr "\n" ":"); echo ${p%:}) 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | results/ 3 | .extra-cmds 4 | *.pyc 5 | *.csv 6 | *.img 7 | *.tmp 8 | *.tar.gz 9 | *.class 10 | *.log 11 | *.tmp 12 | *.img 13 | *.img.enc 14 | *.img.enc.vrt 15 | *.img.vrt 16 | *.img.enc.int 17 | *.img.int 18 | *.key 19 | *.roothash 20 | *.hashoffset 21 | .gdb_history 22 | /.ccls-cache 23 | /.clangd 24 | gdb/ptrace/*.o 25 | gdb/ptrace/*.so 26 | gdb/sgx-lkl-gdb 27 | third_party/cryptsetup/ 28 | third_party/devicemapper/ 29 | third_party/util-linux/ 30 | third_party/popt/ 31 | third_party/json-c/ 32 | third_party/mbedtls/*.o 33 | third_party/mbedtls/*.a 34 | third_party/wireguard/ 35 | third_party/protobuf-c/ 36 | third_party/protobuf-c-rpc/*.o 37 | third_party/protobuf-c-rpc/*.a 38 | *.pb-c.c 39 | *.pb-c.h 40 | src/lkl/x86mods 41 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lkl"] 2 | path = lkl 3 | url = https://github.com/Mic92/linux.git 4 | [submodule "host-musl"] 5 | path = host-musl 6 | url = https://github.com/Mic92/musl.git 7 | [submodule "sgx-lkl-musl"] 8 | path = sgx-lkl-musl 9 | url = https://github.com/Mic92/sgx-lkl-musl.git 10 | [submodule "dpdk"] 11 | path = dpdk 12 | url = https://github.com/Mic92/dpdk 13 | [submodule "spdk"] 14 | path = spdk 15 | url = https://github.com/Mic92/spdk.git 16 | [submodule "apps/fstest"] 17 | path = apps/fstest 18 | url = https://github.com/Mic92/fstest 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | git: 4 | submodules: false 5 | 6 | matrix: 7 | include: 8 | - name: "Hardware Release" 9 | env: 10 | - TARGET= 11 | - DEBUG=false 12 | - name: "Hardware Debug" 13 | env: 14 | - TARGET= 15 | - DEBUG=true 16 | - name: "Simulation Release" 17 | env: 18 | - TARGET=sim 19 | - DEBUG=false 20 | - name: "Simulation Debug" 21 | env: 22 | - TARGET=sim 23 | - DEBUG=true 24 | - name: "Release" 25 | env: 26 | - TARGET= 27 | - DEBUG=false 28 | - RELEASE=true 29 | dist: xenial 30 | compiler: gcc 31 | before_install: 32 | - travis_wait 45 git submodule update --init --recursive 33 | - sudo apt-get install make gcc g++ bc python xutils-dev bison flex libgcrypt20-dev libjson-c-dev autopoint pkgconf autoconf libtool libcurl4-openssl-dev libprotobuf-dev libprotobuf-c-dev protobuf-compiler protobuf-c-compiler libssl-dev -y 34 | script: make $TARGET DEBUG=$DEBUG RELEASE=$RELEASE 35 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright 2016, 2017, 2018 Imperial College London 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # was ubuntu:16.04 2 | FROM phusion/baseimage as builder 3 | 4 | ARG UID=1000 5 | ARG GID=1000 6 | 7 | WORKDIR /sgx-lkl 8 | 9 | RUN apt-get update && apt-get install -y \ 10 | build-essential \ 11 | curl \ 12 | wget \ 13 | pv \ 14 | make gcc g++ bc python xutils-dev flex bison autogen libgcrypt20-dev libjson-c-dev autopoint pkgconf autoconf libtool libcurl4-openssl-dev libprotobuf-dev libprotobuf-c-dev protobuf-compiler protobuf-c-compiler libssl-dev \ 15 | sudo \ 16 | git 17 | 18 | RUN useradd --create-home -u ${UID} -s /bin/bash user && \ 19 | adduser user sudo && \ 20 | echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers 21 | 22 | USER user 23 | ENV USER=user 24 | 25 | FROM phusion/baseimage as deploy 26 | 27 | WORKDIR /sgx-lkl 28 | 29 | RUN apt-get update && apt-get install -y \ 30 | curl \ 31 | openjdk-8-jdk-headless \ 32 | sudo \ 33 | make \ 34 | && rm -rf /var/lib/apt/lists/* 35 | 36 | RUN useradd --create-home -s /bin/bash user && \ 37 | adduser user sudo && \ 38 | echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers 39 | 40 | USER user 41 | ENV USER=user 42 | 43 | COPY --chown=user:user build build/ 44 | COPY --chown=user:user apps apps/ 45 | COPY --chown=user:user tools tools/ 46 | 47 | # Start from a Bash prompt 48 | CMD ["/bin/bash"] 49 | 50 | # Building mimimum image that only contains SGX-LKL 51 | 52 | FROM phusion/baseimage as min-deploy 53 | 54 | WORKDIR /sgx-lkl 55 | 56 | RUN apt-get update && apt-get install -y \ 57 | sudo \ 58 | iproute2 iptables net-tools \ 59 | && rm -rf /var/lib/apt/lists/* 60 | 61 | RUN useradd --create-home -s /bin/bash user && \ 62 | adduser user sudo && \ 63 | echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers 64 | 65 | USER user 66 | ENV USER=user 67 | 68 | ARG binary_cmd 69 | ENV env_binary_cmd="${binary_cmd}" 70 | ARG binary_args 71 | ENV env_binary_args=${binary_args} 72 | 73 | COPY --chown=user:user build build/ 74 | COPY --chown=user:user enclave_rootfs.img . 75 | 76 | # Start from a Bash prompt 77 | CMD ["/bin/bash", "-c", "sudo ip tuntap add dev sgxlkl_tap0 mode tap user user \ 78 | && sudo ip link set dev sgxlkl_tap0 up \ 79 | && sudo ip addr add dev sgxlkl_tap0 10.0.1.254/24 \ 80 | && sudo iptables -I FORWARD -m state -s 10.0.1.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT \ 81 | && sudo iptables -I FORWARD -m state -d 10.0.1.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT \ 82 | && sudo iptables -t nat -A POSTROUTING -s 10.0.1.0/24 ! -d 10.0.1.0/24 -j MASQUERADE \ 83 | && sudo sysctl -w net.ipv4.ip_forward=1 \ 84 | && sudo chown user /dev/net/tun \ 85 | && SGXLKL_TAP=sgxlkl_tap0 SGXLKL_HEAP=2500M /sgx-lkl/build/sgx-lkl-run /sgx-lkl/enclave_rootfs.img ${env_binary_cmd} ${env_binary_args}"] 86 | -------------------------------------------------------------------------------- /apps/helloworld/Makefile: -------------------------------------------------------------------------------- 1 | PROG=helloworld 2 | PROG_NONPIE=$(PROG)-nonpie 3 | PROG_C=$(PROG).c 4 | 5 | MOUNTPOINT=/media/ext4disk 6 | 7 | DISK=sgxlkl-disk.img 8 | 9 | LOOP_DEVICE=loop9 10 | IMAGE_SIZE_MB=100 11 | 12 | ESCALATE_CMD=sudo 13 | 14 | .DELETE_ON_ERROR: 15 | .PHONY: all clean 16 | 17 | all: $(DISK) 18 | 19 | clean: 20 | rm -f $(DISK) $(PROG) 21 | 22 | $(PROG): $(PROG_C) 23 | ../../build/host-musl/bin/musl-gcc -fPIE -pie -o $@ $(PROG_C) 24 | 25 | $(PROG_NONPIE): $(PROG_C) 26 | ../../build/host-musl/bin/musl-gcc -fno-pie -no-pie -o $@ $(PROG_C) 27 | 28 | $(DISK): $(PROG) $(PROG_NONPIE) 29 | dd if=/dev/zero of="$@" count=$(IMAGE_SIZE_MB) bs=1M 30 | mkfs.ext4 "$@" 31 | $(ESCALATE_CMD) bash -euxo pipefail -c '\ 32 | mkdir -p $(MOUNTPOINT); \ 33 | mount -t ext4 -o loop "$@" $(MOUNTPOINT); \ 34 | mkdir -p $(MOUNTPOINT)/app; \ 35 | echo "Hello World!" > $(MOUNTPOINT)/app/helloworld.txt; \ 36 | cp $(PROG) $(MOUNTPOINT)/app; \ 37 | cp $(PROG_NONPIE) $(MOUNTPOINT)/app; \ 38 | umount $(MOUNTPOINT); \ 39 | chown $(USER) "$@"; \ 40 | ' 41 | 42 | test: $(DISK) 43 | ../../build/sgx-lkl-run $(DISK) app/$(PROG) 44 | 45 | test-nonpie: $(DISK) 46 | SGXLKL_NON_PIE=1 ../../build/sgx-lkl-run $(DISK) app/$(PROG_NONPIE) 47 | -------------------------------------------------------------------------------- /apps/helloworld/README.md: -------------------------------------------------------------------------------- 1 | This is a simple Hello World example of how to cross-compile a C application for running with SGX-LKL. To build and run the example simply run 2 | 3 | ```make test``` 4 | 5 | or alternatively build and run the example separately: 6 | 7 | ``` 8 | make sgxlkl-disk.img 9 | ../../build/sgx-lkl-run sgxlkl-disk.img /app/helloworld 10 | ``` 11 | -------------------------------------------------------------------------------- /apps/helloworld/helloworld.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define HW_FILE "/app/helloworld.txt" 7 | 8 | int main(int argc, char **argv) 9 | { 10 | char buf[100]; 11 | FILE *f = fopen(HW_FILE, "r"); 12 | if (!f) { 13 | fprintf(stderr, "Could not open file %s: %s\n", HW_FILE, strerror(errno)); 14 | exit(1); 15 | } 16 | 17 | // Prints first line of file /app/helloworld.txt (max 100 characters) 18 | if (fgets(buf, sizeof(buf), f) == buf) { 19 | printf("%s", buf); 20 | } else { 21 | fprintf(stderr, "Could not read first line of file %s: %s\n", HW_FILE, strerror(errno)); 22 | exit(1); 23 | } 24 | 25 | return 0; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /apps/jvm/helloworld-java/HelloWorld.java: -------------------------------------------------------------------------------- 1 | public class HelloWorld 2 | { 3 | public static void main(String[] args) 4 | { 5 | System.out.println("Hello world!"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /apps/jvm/helloworld-java/Makefile: -------------------------------------------------------------------------------- 1 | ALPINE_MAJOR=3.9 2 | ALPINE_VERSION=3.9.0 3 | ALPINE_ARCH=x86_64 4 | 5 | ALPINE_TAR=alpine-minirootfs.tar.gz 6 | 7 | ROOT_FS=sgxlkl-java-fs.img 8 | MOUNTPOINT=/media/ext4disk 9 | IMAGE_SIZE_MB=400 10 | 11 | ESCALATE_CMD=sudo 12 | 13 | .DELETE_ON_ERROR: 14 | .PHONY: all clean 15 | 16 | all: $(ROOT_FS) 17 | 18 | clean: 19 | test -f HelloWorld.class && rm HelloWorld.class || true 20 | test -f $(ROOT_FS) && rm $(ROOT_FS) || true 21 | 22 | $(ALPINE_TAR): 23 | curl -L -o "$@" "https://nl.alpinelinux.org/alpine/v$(ALPINE_MAJOR)/releases/$(ALPINE_ARCH)/alpine-minirootfs-$(ALPINE_VERSION)-$(ALPINE_ARCH).tar.gz" 24 | 25 | HelloWorld.class: HelloWorld.java 26 | javac HelloWorld.java 27 | 28 | $(ROOT_FS): $(ALPINE_TAR) buildenv.sh HelloWorld.class 29 | dd if=/dev/zero of="$@" count=$(IMAGE_SIZE_MB) bs=1M 30 | mkfs.ext4 "$@" 31 | $(ESCALATE_CMD) /bin/bash -euxo pipefail -c '\ 32 | mkdir -p $(MOUNTPOINT); \ 33 | mount -t ext4 -o loop "$@" $(MOUNTPOINT); \ 34 | tar -C $(MOUNTPOINT) -xvf $(ALPINE_TAR); \ 35 | cp /etc/resolv.conf $(MOUNTPOINT)/etc/resolv.conf; \ 36 | install buildenv.sh $(MOUNTPOINT)/usr/sbin; \ 37 | mkdir -p $(MOUNTPOINT)/app; \ 38 | cp HelloWorld.class $(MOUNTPOINT)/app; \ 39 | mkdir -p $(MOUNTPOINT)/opt; \ 40 | chroot $(MOUNTPOINT) /bin/sh /usr/sbin/buildenv.sh; \ 41 | umount $(MOUNTPOINT); \ 42 | chown $(USER) "$@"; \ 43 | ' 44 | 45 | test: $(ROOT_FS) 46 | echo "Running java Hello World example:" 47 | ${CURDIR}/../../../tools/sgx-lkl-java ${CURDIR}/$(ROOT_FS) HelloWorld 48 | 49 | -------------------------------------------------------------------------------- /apps/jvm/helloworld-java/buildenv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ex 4 | 5 | apk update 6 | apk add iputils iproute2 unzip libstdc++ openjdk8-jre nss 7 | -------------------------------------------------------------------------------- /apps/jvm/helloworld-java/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.github.lsds.sgx-lkl.helloworld 5 | hello-world 6 | 1.0-SNAPSHOT 7 | 8 | -------------------------------------------------------------------------------- /apps/jvm/helloworld-java/src/main/java/com/github/lsds/sgx-lkl/helloworld/HelloWorld.java: -------------------------------------------------------------------------------- 1 | ../../../../../../../../HelloWorld.java -------------------------------------------------------------------------------- /apps/miniroot/Makefile: -------------------------------------------------------------------------------- 1 | ALPINE_MAJOR=3.8 2 | ALPINE_VERSION=3.8.0 3 | ALPINE_ARCH=x86_64 4 | 5 | ROOT_FS=sgxlkl-miniroot-fs.img 6 | ALPINE_TAR=alpine-minirootfs.tar.gz 7 | MOUNTPOINT=/media/ext4disk 8 | IMAGE_SIZE_MB=500 9 | 10 | ESCALATE_CMD=sudo 11 | 12 | .DELETE_ON_ERROR: 13 | .PHONY: all clean 14 | 15 | all: $(ROOT_FS) 16 | 17 | clean: 18 | test -f $(ROOT_FS) && rm $(ROOT_FS) || true 19 | 20 | $(ALPINE_TAR): 21 | curl -L -o "$@" "https://nl.alpinelinux.org/alpine/v$(ALPINE_MAJOR)/releases/$(ALPINE_ARCH)/alpine-minirootfs-$(ALPINE_VERSION)-$(ALPINE_ARCH).tar.gz" 22 | 23 | $(ROOT_FS): $(ALPINE_TAR) buildenv.sh 24 | dd if=/dev/zero of="$@" count=$(IMAGE_SIZE_MB) bs=1M 25 | mkfs.ext4 "$@" 26 | $(ESCALATE_CMD) mkdir -p $(MOUNTPOINT) 27 | $(ESCALATE_CMD) mount -t ext4 -o loop "$@" $(MOUNTPOINT) 28 | $(ESCALATE_CMD) tar -C $(MOUNTPOINT) -xvf $(ALPINE_TAR) 29 | $(ESCALATE_CMD) cp /etc/resolv.conf $(MOUNTPOINT)/etc/resolv.conf 30 | $(ESCALATE_CMD) install buildenv.sh $(MOUNTPOINT)/usr/sbin 31 | $(ESCALATE_CMD) chroot $(MOUNTPOINT) /bin/sh /usr/sbin/buildenv.sh 32 | $(ESCALATE_CMD) umount $(MOUNTPOINT) 33 | $(ESCALATE_CMD) chown $(USER) "$@" 34 | -------------------------------------------------------------------------------- /apps/miniroot/README.md: -------------------------------------------------------------------------------- 1 | miniroot 2 | ======== 3 | 4 | miniroot is a quick way of building a small Alpine disk image, appropriate for 5 | use with sgx-musl. 6 | 7 | There is a small set of packages which are installed by default at build time. 8 | This package set is customizable by editing the buildenv.sh file located in 9 | this directory and rebuilding. 10 | 11 | Building 12 | -------- 13 | 14 | To build `sgxlkl-miniroot-fs.img`, simply run `make` in this directory. 15 | You'll need a working internet connection to install the packages. 16 | 17 | If you've added more packages to `buildenv.sh`, you may need to increase the 18 | size of `IMAGE_SIZE_MB` defined inside the Makefile, or the packages might 19 | not fit inside the created disk image. 20 | 21 | Running 22 | ------- 23 | 24 | Using Redis as an example running on top of SGX-LKL: 25 | 26 | ```sh 27 | SGXLKL_TAP=sgxlkl_tap0 ../../build/sgx-lkl-run ./sgxlkl-miniroot-fs.img /usr/bin/redis-server --bind 10.0.1.1 28 | ``` 29 | 30 | Once you see the ASCII-art Redis logo, you can talk to Redis using: 31 | 32 | ```sh 33 | # On the host 34 | redis-cli -h 10.0.1.1 35 | ``` 36 | 37 | as long as you have the Redis utilities installed. Install it with `sudo 38 | apt-get install redis-tools` if needed. 39 | 40 | -------------------------------------------------------------------------------- /apps/miniroot/buildenv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ex 4 | 5 | PATH=/usr/sbin:/sbin:/usr/bin:/bin 6 | 7 | cd /home 8 | apk update 9 | apk add iputils iproute2 unzip libstdc++ 10 | apk add redis 11 | 12 | -------------------------------------------------------------------------------- /apps/nix/TODO.md: -------------------------------------------------------------------------------- 1 | # Benchmark TODO: 2 | 3 | ## Introduction 4 | - [ ] dd: 5 | - [ ] native 6 | - [ ] sgx-lkl 7 | - [ ] SCONE 8 | - [ ] sgx-io 9 | - [x] iperf 10 | - [x] native 11 | - [x] sgx-lkl 12 | - [x] SCONE 13 | - [x] sgx-io 14 | 15 | # Other 16 | - [x] fio 17 | - [x] native 18 | - [x] sgx-lkl 19 | - [x] SCONE 20 | - [x] sgx-io 21 | 22 | 23 | ## Applications 24 | 25 | - [ ] Nginx: 26 | - [ ] native 27 | - [ ] sgx-lkl 28 | - [ ] sgx-io 29 | - [ ] Redis: 30 | - [ ] native 31 | - [ ] sgx-lkl 32 | - [ ] sgx-io 33 | - [ ] MySQL: 34 | - [ ] native 35 | - [ ] sgx-lkl 36 | - [ ] sgx-io 37 | - [ ] Sqlite: 38 | - [ ] native 39 | - [ ] sgx-lkl 40 | - [ ] sgx-io 41 | -------------------------------------------------------------------------------- /apps/nix/aesni.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import signal 4 | from typing import Dict, List, Optional 5 | import subprocess 6 | import pandas as pd 7 | 8 | from helpers import ( 9 | NOW, 10 | create_settings, 11 | nix_build, 12 | read_stats, 13 | write_stats, 14 | ) 15 | from storage import Storage, StorageKind 16 | 17 | 18 | def benchmark_simpleio( 19 | storage: Storage, 20 | type: str, 21 | attr: str, 22 | directory: str, 23 | stats: Dict[str, List], 24 | extra_env: Dict[str, str] = {}, 25 | do_write: bool = True, 26 | ) -> None: 27 | env = dict(SGXLKL_CWD=directory) 28 | env.update(extra_env) 29 | env.update(SGXLKL_ENABLE_SGXIO="1") 30 | env.update(SGXLKL_ETHREADS="1") 31 | env.update(extra_env) 32 | simpleio = nix_build(attr) 33 | stdout: Optional[int] = subprocess.PIPE 34 | if os.environ.get("SGXLKL_ENABLE_GDB", "0") == "1": 35 | stdout = None 36 | 37 | size = str(2 * 1024 * 1024 * 1024) # 2G 38 | 39 | env_string = [] 40 | for k, v in env.items(): 41 | env_string.append(f"{k}={v}") 42 | report = "" 43 | in_results = False 44 | env = os.environ.copy() 45 | env.update(extra_env) 46 | 47 | cmd = [ 48 | simpleio, 49 | "bin/simpleio", 50 | f"{directory}/file", 51 | size, 52 | "0", 53 | "0" if do_write else "1", 54 | str(128 * 4096), 55 | ] 56 | print(f"$ {' '.join(env_string)} {' '.join(cmd)}") 57 | proc = subprocess.Popen(cmd, stdout=stdout, text=True, env=env) 58 | try: 59 | assert proc.stdout is not None 60 | for line in proc.stdout: 61 | print(f"stdout: {line}", end="") 62 | if line == "\n": 63 | in_results = True 64 | elif in_results and line == "\n": 65 | break 66 | elif in_results: 67 | report = line 68 | finally: 69 | proc.send_signal(signal.SIGINT) 70 | jsondata = json.loads(report) 71 | stats["type"].append(type) 72 | stats["bytes"].append(jsondata["bytes"]) 73 | stats["time"].append(jsondata["time"]) 74 | stats["workload"].append("write" if do_write else "read") 75 | 76 | 77 | def benchmark_sgx_io(storage: Storage, stats: Dict[str, List], x86_acc: bool = False) -> None: 78 | mount = storage.setup(StorageKind.SPDK) 79 | 80 | with mount as mnt: 81 | extra_env = mount.extra_env() 82 | extra_env["SGXLKL_X86_ACC"] = "1" if x86_acc else "0" 83 | benchmark_simpleio( 84 | storage, "x86_acc" if x86_acc else "no_x86_acc", "simpleio-sgx-io", mnt, stats, extra_env=extra_env 85 | ) 86 | 87 | 88 | def main() -> None: 89 | stats = read_stats("aesni.json") 90 | storage = Storage(create_settings()) 91 | 92 | if "x86_acc" not in stats["type"]: 93 | benchmark_sgx_io(storage, stats, x86_acc=True) 94 | else: 95 | print("skip x86_acc") 96 | if "no_x86_acc" not in stats["type"]: 97 | benchmark_sgx_io(storage, stats, x86_acc=False) 98 | else: 99 | print("skip no_x86_acc") 100 | write_stats("aesni.json", stats) 101 | 102 | csv = f"aesni-{NOW}.tsv" 103 | print(csv) 104 | df = pd.DataFrame(stats) 105 | df.to_csv(csv, index=False, sep="\t") 106 | df.to_csv("aesni-latest.tsv", index=False, sep="\t") 107 | 108 | 109 | if __name__ == "__main__": 110 | main() 111 | -------------------------------------------------------------------------------- /apps/nix/bench_memcpy.py: -------------------------------------------------------------------------------- 1 | import json 2 | import subprocess 3 | from collections import defaultdict 4 | from typing import Dict, List, DefaultDict, Optional, Any 5 | import pandas as pd 6 | 7 | from helpers import ( 8 | NOW, 9 | nix_build, 10 | read_stats, 11 | write_stats, 12 | ) 13 | 14 | KINDS = { 15 | "avx": "0", 16 | "old": "1", 17 | "libc": "2", 18 | } 19 | 20 | 21 | def bench_memcpy(kind: str, stats: Dict[str, List]) -> None: 22 | memcpy = nix_build("memcpy-test-sgx-io") 23 | stdout: Optional[int] = subprocess.PIPE 24 | 25 | proc = subprocess.Popen([memcpy, "bin/memcpy-test", KINDS[kind]], stdout=stdout, text=True) 26 | try: 27 | if proc.stdout is None: 28 | proc.wait() 29 | else: 30 | for line in proc.stdout: 31 | print(line) 32 | try: 33 | data = json.loads(line) 34 | for i in data: 35 | stats["memcpy-kind"].append(f"memcpy-test-{kind}") 36 | stats["memcpy-size"].append(i) 37 | stats["memcpy-time"].append(data[i]) 38 | except Exception as e: 39 | continue 40 | finally: 41 | pass 42 | 43 | 44 | def bench_avx_memcpy(stats: Dict[str, List]) -> None: 45 | bench_memcpy("avx", stats) 46 | 47 | 48 | def bench_old_memcpy(stats: Dict[str, List]) -> None: 49 | bench_memcpy("old", stats) 50 | 51 | 52 | def bench_libc_memcpy(stats: Dict[str, List]) -> None: 53 | bench_memcpy("libc", stats) 54 | 55 | 56 | def main() -> None: 57 | stats: DefaultDict[str, List] = defaultdict(list) 58 | 59 | benchmarks = { 60 | "avx_memcpy": bench_avx_memcpy, 61 | "new_memcpy": bench_old_memcpy, 62 | "libc_memcpy": bench_libc_memcpy 63 | } 64 | 65 | for name, benchmark in benchmarks.items(): 66 | benchmark(stats) 67 | 68 | csv = f"memcpy-bench-{NOW}.tsv" 69 | memcpy_df = pd.DataFrame(stats) 70 | memcpy_df.to_csv(csv, index=False, sep="\t") 71 | memcpy_df.to_csv("memcpy-bench-latest.tsv", index=False, sep="\t") 72 | 73 | if __name__=="__main__": 74 | main() 75 | -------------------------------------------------------------------------------- /apps/nix/bind_nic.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from helpers import create_settings 4 | from network import Network, NetworkKind 5 | 6 | 7 | def main() -> None: 8 | if len(sys.argv) < 2: 9 | print(f"USAGE: {sys.argv[0]} (native|dpdk|tap|client-native)", file=sys.stderr) 10 | sys.exit(1) 11 | kinds = { 12 | "native": NetworkKind.NATIVE, 13 | "client-native": NetworkKind.CLIENT_NATIVE, 14 | "dpdk": NetworkKind.DPDK, 15 | "tap": NetworkKind.TAP, 16 | } 17 | kind = kinds.get(sys.argv[1], None) 18 | if kind is None: 19 | print( 20 | f"Unsupported option '{sys.argv[1]}', valid options are native, client-native, dpdk or tap", 21 | file=sys.stderr, 22 | ) 23 | sys.exit(1) 24 | settings = create_settings() 25 | Network(settings).setup(kind) 26 | 27 | 28 | if __name__ == "__main__": 29 | main() 30 | -------------------------------------------------------------------------------- /apps/nix/bind_nvme.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from helpers import create_settings 4 | from storage import Storage, StorageKind 5 | 6 | 7 | def main() -> None: 8 | if len(sys.argv) < 2: 9 | print(f"USAGE: {sys.argv[0]} (native|spdk|lkl)", file=sys.stderr) 10 | sys.exit(1) 11 | kinds = dict(native=StorageKind.NATIVE, 12 | spdk=StorageKind.SPDK, 13 | lkl=StorageKind.LKL, 14 | scone=StorageKind.SCONE) 15 | kind = kinds.get(sys.argv[1], None) 16 | if kind is None: 17 | print( 18 | f"Unsupported option '{sys.argv[1]}', valid options are native, spdk or lkl", 19 | file=sys.stderr, 20 | ) 21 | sys.exit(1) 22 | settings = create_settings() 23 | mount = Storage(settings).setup(kind) 24 | mount.mount() 25 | print(mount.dev) 26 | 27 | 28 | if __name__ == "__main__": 29 | main() 30 | -------------------------------------------------------------------------------- /apps/nix/build-image.nix: -------------------------------------------------------------------------------- 1 | { stdenv, stdenvAdapters, closureInfo 2 | , pkgsMusl, e2fsprogs, lkl, enableDebugging 3 | , lib, scone ? null 4 | }: 5 | 6 | { pkg 7 | , extraFiles ? {} 8 | , extraCommands ? "" 9 | , debugSymbols ? true 10 | , diskSize ? "1G" 11 | , sconeEncryptedDir ? null 12 | }: 13 | let 14 | piePkg = enableDebugging (pkg.overrideAttrs (old: { 15 | hardeningEnable = [ "pie" ] ++ (old.hardeningEnable or []); 16 | })); 17 | 18 | finalPkg = piePkg.override { 19 | stdenv = if debugSymbols then 20 | stdenvAdapters.keepDebugInfo piePkg.stdenv 21 | else 22 | piePkg.stdenv; 23 | }; 24 | closure = closureInfo { rootPaths = [ finalPkg ]; }; 25 | files = { 26 | "etc/group" = '' 27 | root:x:0: 28 | nogroup:x:65534: 29 | ''; 30 | "etc/passwd" = '' 31 | root:x:0:0:Root:/:/bin/sh 32 | nobody:x:65534:65534:Nobody:/:/noshell 33 | ''; 34 | "etc/hosts" = '' 35 | 127.0.0.1 localhost 36 | ::1 localhost 37 | ''; 38 | } // extraFiles; 39 | in stdenv.mkDerivation { 40 | name = "image"; 41 | nativeBuildInputs = [ e2fsprogs lkl ] ++ lib.optional (sconeEncryptedDir != null) scone; 42 | dontUnpack = true; 43 | 44 | passthru.pkg = finalPkg; 45 | 46 | installPhase = '' 47 | mkdir -p root/{nix/store,tmp,etc} 48 | # Filter out musl libc since, 49 | # sgx-musl will provide its own version. 50 | # Also filter gcc because it is included in debug symbols. 51 | root=$(readlink -f root) 52 | grep -v '${pkgsMusl.musl}' ${closure}/store-paths | grep -v '${pkgsMusl.gcc-unwrapped}' \ 53 | | xargs cp -r -t "$root/nix/store" 54 | 55 | ${lib.concatMapStrings (file: '' 56 | 57 | dir="$root/$(dirname ${file})" 58 | if [ ! -d "$dir" ]; then 59 | mkdir -p "$dir" 60 | fi 61 | ${if builtins.isString files.${file} then '' 62 | cat > "$root/${file}" <<'EOF' 63 | ${files.${file}} 64 | EOF 65 | '' else '' 66 | install -D ${files.${file}.path} "$root/${file}" 67 | ''} 68 | '') (lib.attrNames files)} 69 | 70 | ${extraCommands} 71 | 72 | ${lib.optionalString (sconeEncryptedDir != null) '' 73 | mkdir cryptroot 74 | # creates empty .scone/state.env 75 | export HOME=$TMPDIR/scone 76 | 77 | pushd cryptroot 78 | scone fspf create fspf.pb 79 | 80 | scone fspf addr fspf.pb / --kernel / --not-protected 81 | scone fspf addr fspf.pb ${sconeEncryptedDir} --encrypted --kernel ${sconeEncryptedDir} 82 | scone fspf addf fspf.pb ${sconeEncryptedDir} "$root" . 83 | scone fspf encrypt fspf.pb > .scone-keytag 84 | root=$(readlink -f .) 85 | popd 86 | ''} 87 | 88 | # FIXME calculate storage requirement 89 | truncate -s ${diskSize} $out 90 | mkfs.ext4 $out 91 | cptofs -t ext4 -i $out $root/* $root/.* / 92 | ''; 93 | } 94 | -------------------------------------------------------------------------------- /apps/nix/busybox-mlock.patch: -------------------------------------------------------------------------------- 1 | diff -Naur --strip-trailing-cr busybox-1.29.3.org/miscutils/hdparm.c busybox-1.29.3/miscutils/hdparm.c 2 | --- busybox-1.29.3.org/miscutils/hdparm.c 2018-07-02 13:23:06.000000000 +0200 3 | +++ busybox-1.29.3/miscutils/hdparm.c 2019-03-18 17:47:10.535956314 +0100 4 | @@ -1505,8 +1505,10 @@ 5 | unsigned total_MB; 6 | char *buf = xmalloc(TIMING_BUF_BYTES); 7 | 8 | +#if 0 9 | if (mlock(buf, TIMING_BUF_BYTES)) 10 | bb_perror_msg_and_die("mlock"); 11 | +#endif 12 | 13 | /* Clear out the device request queues & give them time to complete. 14 | * NB: *small* delay. User is expected to have a clue and to not run 15 | -------------------------------------------------------------------------------- /apps/nix/dd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import json 3 | import os 4 | import getpass 5 | import subprocess 6 | import tempfile 7 | import time 8 | from collections import defaultdict 9 | from typing import Any, DefaultDict, Dict, List, Union 10 | import re 11 | import signal 12 | import pandas as pd 13 | 14 | from helpers import ( 15 | NOW, 16 | ROOT, 17 | Chdir, 18 | Settings, 19 | create_settings, 20 | nix_build, 21 | run, 22 | spawn, 23 | flamegraph_env, 24 | read_stats, 25 | write_stats 26 | ) 27 | from storage import Storage, StorageKind 28 | 29 | def benchmark_dd( 30 | storage: Storage, 31 | system: str, 32 | attr: str, 33 | device: str, 34 | stats: Dict[str, List], 35 | extra_env: Dict[str, str] = {}, 36 | ) -> None: 37 | env = os.environ.copy() 38 | env.update(extra_env) 39 | dd = nix_build(attr) 40 | 41 | print(f"###### {system} >> ######") 42 | proc = subprocess.Popen([dd], env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 43 | 44 | try: 45 | if proc.stdout is None: 46 | proc.wait() 47 | else: 48 | stats["system"].append(system) 49 | for line in proc.stdout: 50 | data = line.split(',') 51 | if len(data) == 2: 52 | stats["latency"].append(data[0]) 53 | stats["Throughput"].append(data[1]) 54 | finally: 55 | pass 56 | 57 | print(f"###### {system} << ######") 58 | 59 | def benchmark_native_dd(storage: Storage, stats: Dict[str, List]) -> None: 60 | mnt = storage.setup(StorageKind.NATIVE) 61 | subprocess.run(["sudo", "chown", getpass.getuser(), mnt.dev]) 62 | benchmark_dd(storage, "native", "dd-native", mnt.dev, stats) 63 | 64 | def benchmark_sgx_lkl_dd(storage: Storage, stats: Dict[str, List]) -> None: 65 | storage.setup(StorageKind.LKL) 66 | benchmark_dd( 67 | storage, 68 | "sgx-lkl", 69 | "dd-sgx-lkl", 70 | "/dev/vdb", 71 | stats, 72 | extra_env=dict(SGXLKL_HDS="/dev/nvme0n1:/mnt/nvme"), 73 | ) 74 | 75 | def benchmark_sgx_io_dd(storage: Storage, stats: Dict[str, List]) -> None: 76 | storage.setup(StorageKind.SPDK) 77 | benchmark_dd(storage, "sgx-io", "dd-sgx-io", "/dev/spdk0", stats) 78 | 79 | def main() -> None: 80 | stats = read_stats("dd.json") 81 | settings = create_settings() 82 | storage = Storage(settings) 83 | 84 | # provide nix expressions for native and sgx_lkl case 85 | benchmarks = { 86 | #"native": benchmark_native_dd, 87 | #"sgx-lkl": benchmark_sgx_lkl_dd, 88 | "sgx-io": benchmark_sgx_io_dd, 89 | } 90 | 91 | system = set(stats["system"]) 92 | 93 | for name, benchmark in benchmarks.items(): 94 | if name in system: 95 | print(f"skip {name} benchmark") 96 | continue 97 | benchmark(storage, stats) 98 | write_stats("dd.json", stats) 99 | 100 | csv = f"dd-test-{NOW}.tsv" 101 | df = pd.DataFrame(stats) 102 | df.to_csv(csv, index=False, sep="\t") 103 | df.to_csv("dd-test-latest.tsv", index=False, sep="\t") 104 | 105 | if __name__=="__main__": 106 | main() 107 | -------------------------------------------------------------------------------- /apps/nix/dummy.nix: -------------------------------------------------------------------------------- 1 | { stdenv }: 2 | 3 | stdenv.mkDerivation { 4 | name = "dummy-pkg"; 5 | unpackPhase = ":"; 6 | installPhase = "touch $out"; 7 | } 8 | -------------------------------------------------------------------------------- /apps/nix/fio-pool-size.patch: -------------------------------------------------------------------------------- 1 | diff --git a/smalloc.c b/smalloc.c 2 | index a2ad25a0..c8508982 100644 3 | --- a/smalloc.c 4 | +++ b/smalloc.c 5 | @@ -18,7 +18,7 @@ 6 | #define SMALLOC_BPI (sizeof(unsigned int) * 8) 7 | #define SMALLOC_BPL (SMALLOC_BPB * SMALLOC_BPI) 8 | 9 | -#define INITIAL_SIZE 16*1024*1024 /* new pool size */ 10 | +#define INITIAL_SIZE 1*1024*1024 /* new pool size */ 11 | #define INITIAL_POOLS 8 /* maximum number of pools to setup */ 12 | 13 | #define MAX_POOLS 16 14 | -------------------------------------------------------------------------------- /apps/nix/graphene/default.nix: -------------------------------------------------------------------------------- 1 | { python3, callPackage }: 2 | 3 | rec { 4 | graphene = callPackage ./graphene.nix {}; 5 | runGraphene = python3.pkgs.callPackage ./run-graphene.nix { 6 | graphene = callPackage ./graphene.nix {}; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /apps/nix/graphene/run-graphene.nix: -------------------------------------------------------------------------------- 1 | { stdenv, lib, python, writeScript, graphene, buildPythonApplication, mypy, glibc }: 2 | { command, pkg, ports ? [] }: 3 | 4 | let 5 | run-graphene = stdenv.mkDerivation rec { 6 | name = "run-graphene"; 7 | src = ./.; 8 | 9 | buildInputs = [ python ]; 10 | nativeBuildInputs = [ mypy ]; 11 | installPhase = '' 12 | install -D -m755 run-graphene.py $out/bin/run-graphene 13 | ''; 14 | }; 15 | 16 | pkg' = pkg.overrideAttrs (old: { 17 | # We cannot set RPATH or we break graphen. 18 | # Therefor we have to manually export our libraries to make ld during the build happy 19 | LD_LIBRARY_PATH = stdenv.lib.makeLibraryPath (old.buildInputs or []); 20 | NIX_DONT_SET_RPATH = "1"; 21 | NIX_NO_SELF_RPATH = "1"; 22 | NIX_DEBUG = "1"; 23 | dontPatchELF = true; 24 | }); 25 | in writeScript "run-graphene" '' 26 | #!/usr/bin/env bash 27 | 28 | set -xeu -o pipefail 29 | 30 | export TMPDIR=/tmp 31 | export PATH=${lib.makeBinPath [ graphene ]}:$PATH 32 | export LD_LIBRARY_PATH=${pkg'.LD_LIBRARY_PATH}:${glibc}/lib:${pkg}/lib 33 | 34 | if [[ $# -eq 0 ]]; then 35 | cmd="${toString command}" 36 | else 37 | cmd=$1 38 | shift 39 | fi 40 | 41 | exec ${python.interpreter} ${run-graphene}/bin/run-graphene ${lib.optionalString (ports != []) "--ports"} ${lib.concatStringsSep "," (map toString ports)} ${graphene}/share/graphene/Runtime -- ${pkg'}/$cmd "$@" 42 | '' 43 | -------------------------------------------------------------------------------- /apps/nix/graphene/shebang-bypass.patch: -------------------------------------------------------------------------------- 1 | diff --git a/Pal/lib/Makefile b/Pal/lib/Makefile 2 | index 8b0f86f1..c5b150b8 100644 3 | --- a/Pal/lib/Makefile 4 | +++ b/Pal/lib/Makefile 5 | @@ -90,7 +90,7 @@ crypto/mbedtls/CMakeLists.txt: crypto/$(MBEDTLS_SRC) crypto/$(MBEDCRYPTO_SRC) cr 6 | mv crypto/mbedtls/mbed-crypto-mbedcrypto-3.1.0 crypto/mbedtls/crypto 7 | cd crypto/mbedtls && patch -p1 < ../mbedtls-$(MBEDTLS_VERSION).diff || exit 255 8 | mkdir crypto/mbedtls/install 9 | - cd crypto/mbedtls && ./scripts/config.pl set MBEDTLS_CMAC_C && make CFLAGS="" SHARED=1 DESTDIR=install install . 10 | + cd crypto/mbedtls && perl ./scripts/config.pl set MBEDTLS_CMAC_C && make CFLAGS="" SHARED=1 DESTDIR=install install . 11 | $(RM) crypto/mbedtls/include/mbedtls/config.h 12 | $(RM) crypto/mbedtls/crypto/include/mbedtls/config.h 13 | 14 | -------------------------------------------------------------------------------- /apps/nix/hdparm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import json 3 | import os 4 | import getpass 5 | import subprocess 6 | import tempfile 7 | import time 8 | from collections import defaultdict 9 | from typing import Any, DefaultDict, Dict, List, Union 10 | import re 11 | import signal 12 | import pandas as pd 13 | 14 | from helpers import ( 15 | NOW, 16 | ROOT, 17 | Chdir, 18 | Settings, 19 | create_settings, 20 | nix_build, 21 | run, 22 | spawn, 23 | flamegraph_env, 24 | read_stats, 25 | write_stats 26 | ) 27 | from storage import Storage, StorageKind 28 | 29 | 30 | def benchmark_hdparm( 31 | storage: Storage, 32 | system: str, 33 | attr: str, 34 | device: str, 35 | stats: Dict[str, List], 36 | extra_env: Dict[str, str] = {}, 37 | ) -> None: 38 | env = os.environ.copy() 39 | env.update(flamegraph_env(f"hdparm-{system}-{NOW}")) 40 | env.update(extra_env) 41 | hdparm = nix_build(attr) 42 | print(f"###### {system} >> ######") 43 | proc = subprocess.Popen(["sudo", hdparm, "bin/hdparm", "-Tt", device], env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 44 | try: 45 | if proc.stdout is None: 46 | proc.wait() 47 | else: 48 | stats["system"].append(system) 49 | for line in proc.stdout: 50 | print(line) 51 | match = re.match(r"(.*):\s+(.*) = (.*)", line) 52 | if match: 53 | stats[match.group(1)].append(match.group(3)) 54 | finally: 55 | #proc.send_signal(signal.SIGINT) 56 | pass 57 | print(f"###### {system} << ######") 58 | 59 | 60 | def benchmark_hdparm_native(storage: Storage, stats: Dict[str, List]) -> None: 61 | mnt = storage.setup(StorageKind.NATIVE) 62 | subprocess.run(["sudo", "chown", getpass.getuser(), mnt.dev]) 63 | benchmark_hdparm(storage, "native", "hdparm-native", mnt.dev, stats) 64 | 65 | 66 | def benchmark_hdparm_sgx_lkl(storage: Storage, stats: Dict[str, List]) -> None: 67 | storage.setup(StorageKind.LKL) 68 | benchmark_hdparm( 69 | storage, 70 | "sgx-lkl", 71 | "hdparm-sgx-lkl", 72 | "/dev/vdb", 73 | stats, 74 | extra_env=dict(SGXLKL_HDS="/dev/nvme0n1:/mnt/nvme"), 75 | ) 76 | 77 | 78 | def benchmark_hdparm_sgx_io(storage: Storage, stats: Dict[str, List]) -> None: 79 | storage.setup(StorageKind.SPDK) 80 | benchmark_hdparm(storage, "sgx-io", "hdparm-sgx-io", "/dev/spdk0", stats) 81 | 82 | 83 | def main() -> None: 84 | stats = read_stats("hdparm.json") 85 | settings = create_settings() 86 | storage = Storage(settings) 87 | 88 | benchmarks = { 89 | "native": benchmark_hdparm_native, 90 | "sgx-lkl": benchmark_hdparm_sgx_lkl, 91 | "sgx-io": benchmark_hdparm_sgx_io, 92 | } 93 | 94 | system = set(stats["system"]) 95 | for name, benchmark in benchmarks.items(): 96 | if name in system: 97 | print(f"skip {name} benchmark") 98 | continue 99 | benchmark(storage, stats) 100 | write_stats("hdparm.json", stats) 101 | 102 | csv = f"hdparm-test-{NOW}.tsv" 103 | print(csv) 104 | df = pd.DataFrame(stats) 105 | df.to_csv(csv, index=False, sep="\t") 106 | df.to_csv("hdparm-test-latest.tsv", index=False, sep="\t") 107 | 108 | 109 | if __name__ == "__main__": 110 | main() 111 | -------------------------------------------------------------------------------- /apps/nix/iperf-optimizations.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import json 5 | import subprocess 6 | import time 7 | import signal 8 | from functools import lru_cache 9 | from typing import Any, Dict, List 10 | 11 | import pandas as pd 12 | from helpers import ( 13 | read_stats, 14 | write_stats, 15 | NOW, 16 | Settings, 17 | create_settings, 18 | flamegraph_env, 19 | nix_build, 20 | spawn, 21 | RemoteCommand 22 | ) 23 | from network import Network, NetworkKind, setup_remote_network 24 | 25 | from iperf import _postprocess_iperf, Benchmark 26 | 27 | 28 | def run_variant(name: str, benchmark: Benchmark, extra_env: Dict[str, str]) -> None: 29 | stats_file = f"iperf-{name}.json" 30 | stats = read_stats(stats_file) 31 | system = set(stats["system"]) 32 | if "sgx-io" in system: 33 | print(f"skip {name} benchmark") 34 | else: 35 | extra_env.update(benchmark.network.setup(NetworkKind.DPDK)) 36 | benchmark.run("iperf-sgx-io", "sgx-io", stats, extra_env=extra_env) 37 | write_stats(stats_file, stats) 38 | 39 | csv = f"iperf-{name}-latest.tsv" 40 | print(csv) 41 | pd.DataFrame(stats).to_csv(csv, index=False, sep="\t") 42 | 43 | 44 | def main() -> None: 45 | settings = create_settings() 46 | setup_remote_network(settings) 47 | benchmark = Benchmark(settings) 48 | run_variant("all-on", benchmark, extra_env={}) 49 | run_variant("offload_off", benchmark, extra_env=dict(SGXLKL_GSO_OFFLOAD="0", SGXLKL_CHKSUM_OFFLOAD="0")) 50 | run_variant("zerocopy_off", benchmark, extra_env=dict(SGXLKL_DPDK_ZEROCOPY="0")) 51 | 52 | if __name__ == "__main__": 53 | main() 54 | -------------------------------------------------------------------------------- /apps/nix/iperf/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, fetchFromGitHub 2 | , enableStatic ? false 3 | , enableGraphene ? false 4 | , openssl 5 | , pkg-config 6 | }: 7 | stdenv.mkDerivation { 8 | name = "iperf-3.7"; 9 | #src = ../iperf-3.7; 10 | src = fetchFromGitHub { 11 | owner = "Mic92"; 12 | repo = "iperf-3.7"; 13 | rev = "d99abdfedc4ff70746a81e3eb2e20133a6478f77"; 14 | sha256 = "1cmfcbc87a3g0lafspqsw0sigw05506zqfq0cdhjckwyr1qx51l0"; 15 | }; 16 | buildInputs = [ 17 | (openssl.override { 18 | stdenv = stdenv; 19 | static = enableStatic; 20 | }) 21 | ]; 22 | nativeBuildInputs = [ pkg-config ]; 23 | iperf3_cv_header_tcp_congestion = "no"; 24 | configureFlags = [ "--disable-profiling" ] ++ stdenv.lib.optionals (enableStatic) [ 25 | "--disable-shared" 26 | "--enable-static" 27 | ]; 28 | } 29 | -------------------------------------------------------------------------------- /apps/nix/latency-test/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv }: 2 | 3 | stdenv.mkDerivation { 4 | name = "latency-test"; 5 | src = ./.; 6 | installPhase = '' 7 | mkdir -p $out/bin 8 | gcc -O2 -o $out/bin/latency-test main.c 9 | ''; 10 | } 11 | -------------------------------------------------------------------------------- /apps/nix/memcpy-test/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv }: 2 | 3 | stdenv.mkDerivation { 4 | name = "memcpy-test"; 5 | src = ./.; 6 | installPhase = '' 7 | mkdir -p $out/bin 8 | gcc -o $out/bin/memcpy-test main.c memcpy_org.s memcpy-avx2.S 9 | ''; 10 | } 11 | -------------------------------------------------------------------------------- /apps/nix/memcpy-test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define NUM_PTS 9 7 | #define ITERS 1000000 8 | 9 | void *memcpy_avx(void *dest, const void *src, size_t n); 10 | void *__memcpy_fwd(void *dest, const void *src, size_t n); 11 | 12 | static int test_sizes[] = {4, 8, 16, 32, 64, 128, 256, 512, 1024}; 13 | 14 | static void* (*memcpy_funcs[3])(void *dest, const void *src, size_t n) = { 15 | memcpy_avx, 16 | __memcpy_fwd, 17 | memcpy, 18 | }; 19 | 20 | static double get_time() { 21 | struct timeval tv; 22 | gettimeofday(&tv, NULL); 23 | double ret = tv.tv_usec; 24 | ret = (ret/1000); 25 | ret += (tv.tv_sec * 1000); 26 | 27 | return ret; 28 | } 29 | 30 | static double bench_memcpy(int mem_size, int no){ 31 | double total_time = 0; 32 | void *src, *dest; 33 | src = malloc(mem_size*1024); 34 | dest = malloc(mem_size*1024); 35 | 36 | double start_t, end_t; 37 | start_t = get_time(); 38 | for(int i=0; i 3 | Date: Wed Mar 29 15:22:38 2017 -0300 4 | 5 | include: Check for previous declaration of uintptr_t 6 | 7 | Adding a extra check before declaring uintptr_t. Currently musl uses 8 | macro __DEFINED_uintptr_t once it defines uintptr_t type. Checking 9 | this macro before defining it, and, defining it when uintptr_t is 10 | defined. 11 | 12 | Signed-off-by: Breno Leitao 13 | 14 | diff --git a/third_party/cmocka/cmocka.h b/third_party/cmocka/cmocka.h 15 | index 303d0ae..a2bfc40 100644 16 | --- a/third_party/cmocka/cmocka.h 17 | +++ b/third_party/cmocka/cmocka.h 18 | @@ -110,7 +110,7 @@ 19 | ((LargestIntegralType)(value)) 20 | 21 | /* Smallest integral type capable of holding a pointer. */ 22 | -#if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED) 23 | +#if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED) && !defined(__DEFINED_uintptr_t) 24 | # if defined(_WIN32) 25 | /* WIN32 is an ILP32 platform */ 26 | typedef unsigned int uintptr_t; 27 | @@ -136,6 +136,8 @@ 28 | 29 | # define _UINTPTR_T 30 | # define _UINTPTR_T_DEFINED 31 | +# define __DEFINED_uintptr_t 32 | + 33 | #endif /* !defined(_UINTPTR_T) || !defined(_UINTPTR_T_DEFINED) */ 34 | 35 | /* Perform an unsigned cast to uintptr_t. */ 36 | -------------------------------------------------------------------------------- /apps/nix/mysql-5.5.x.nix: -------------------------------------------------------------------------------- 1 | { stdenv, fetchpatch, fetchurl, cmake, bison, ncurses 2 | , readline, zlib, perl, lib 3 | , enableStatic ? false 4 | }: 5 | 6 | # Note: zlib is not required; MySQL can use an internal zlib. 7 | 8 | stdenv.mkDerivation rec { 9 | name = "mysql-${version}"; 10 | version = "5.5.62"; 11 | 12 | src = fetchurl { 13 | url = "mirror://mysql/MySQL-5.5/${name}.tar.gz"; 14 | sha256 = "1mwrzwk9ap09s430fpdkyhvx5j2syd3xj2hyfzvanjphq4xqbrxi"; 15 | }; 16 | 17 | patches = [ 18 | ./mysql.patch 19 | ] ++ 20 | # Minor type error that is a build failure as of clang 6. 21 | stdenv.lib.optional stdenv.cc.isClang (fetchpatch { 22 | url = "https://svn.freebsd.org/ports/head/databases/mysql55-server/files/patch-sql_sql_partition.cc?rev=469888"; 23 | extraPrefix = ""; 24 | sha256 = "09sya27z3ir3xy5mrv3x68hm274594y381n0i6r5s627x71jyszf"; 25 | }); 26 | 27 | buildInputs = [ 28 | ((ncurses.override { 29 | inherit enableStatic; 30 | }).overrideAttrs (old: { 31 | inherit stdenv; 32 | })) 33 | (readline.overrideAttrs (old: { 34 | inherit stdenv; 35 | })) 36 | 37 | ((zlib.override { 38 | static = enableStatic; 39 | shared = !enableStatic; 40 | splitStaticOutput = enableStatic; 41 | }).overrideAttrs (old: { 42 | inherit stdenv; 43 | })) 44 | ]; 45 | nativeBuildInputs = [ cmake bison ]; 46 | 47 | enableParallelBuilding = true; 48 | 49 | cmakeFlags = [ 50 | "-DBUILD_SHARED_LIBRARIES=OFF" 51 | "-DWITH_SSL=yes" 52 | "-DWITH_READLINE=yes" 53 | "-DWITH_EMBEDDED_SERVER=yes" 54 | "-DWITH_ZLIB=yes" 55 | "-DHAVE_IPV6=yes" 56 | "-DMYSQL_UNIX_ADDR=/run/mysqld/mysqld.sock" 57 | "-DMYSQL_DATADIR=/var/lib/mysql" 58 | "-DINSTALL_SYSCONFDIR=etc/mysql" 59 | "-DINSTALL_INFODIR=share/mysql/docs" 60 | "-DINSTALL_MANDIR=share/man" 61 | "-DINSTALL_PLUGINDIR=lib/mysql/plugin" 62 | "-DINSTALL_SCRIPTDIR=bin" 63 | "-DINSTALL_INCLUDEDIR=include/mysql" 64 | "-DINSTALL_DOCREADMEDIR=share/mysql" 65 | "-DINSTALL_SUPPORTFILESDIR=share/mysql" 66 | "-DINSTALL_MYSQLSHAREDIR=share/mysql" 67 | "-DINSTALL_DOCDIR=share/mysql/docs" 68 | "-DINSTALL_SHAREDIR=share/mysql" 69 | "-DINSTALL_MYSQLTESTDIR=" 70 | "-DINSTALL_SQLBENCHDIR=" 71 | ]; 72 | 73 | NIX_CFLAGS_COMPILE = 74 | stdenv.lib.optionals stdenv.cc.isGNU [ "-fpermissive" ] # since gcc-7 75 | ++ stdenv.lib.optionals stdenv.cc.isClang [ "-Wno-c++11-narrowing" ]; # since clang 6 76 | 77 | NIX_LDFLAGS = stdenv.lib.optionalString (stdenv.isLinux && !enableStatic) "-lgcc_s"; 78 | 79 | prePatch = '' 80 | sed -i -e "s|/usr/bin/libtool|libtool|" cmake/libutils.cmake 81 | ''; 82 | postInstall = '' 83 | sed -i -e "s|basedir=\"\"|basedir=\"$out\"|" $out/bin/mysql_install_db 84 | rm -r $out/data "$out"/lib/*.a 85 | ''; 86 | } 87 | -------------------------------------------------------------------------------- /apps/nix/mysql.patch: -------------------------------------------------------------------------------- 1 | diff -Naur --strip-trailing-cr -r mysql-5.5.62.org/sql/mysqld.cc mysql-5.5.62/sql/mysqld.cc 2 | --- mysql-5.5.62.org/sql/mysqld.cc 2018-08-28 23:12:51.000000000 +0200 3 | +++ mysql-5.5.62/sql/mysqld.cc 2019-04-25 16:51:54.059075571 +0200 4 | @@ -4505,7 +4505,7 @@ 5 | if (init_common_variables()) 6 | unireg_abort(1); // Will do exit 7 | 8 | - init_signals(); 9 | + //init_signals(); 10 | #if defined(__ia64__) || defined(__ia64) 11 | /* 12 | Peculiar things with ia64 platforms - it seems we only have half the 13 | -------------------------------------------------------------------------------- /apps/nix/netdb-defines.patch: -------------------------------------------------------------------------------- 1 | diff --git a/nsswitch/wins.c b/nsswitch/wins.c 2 | index dccb6dd..bb24acb 100644 3 | --- a/nsswitch/wins.c 4 | +++ b/nsswitch/wins.c 5 | @@ -39,6 +39,14 @@ static pthread_mutex_t wins_nss_mutex = PTHREAD_MUTEX_INITIALIZER; 6 | #define INADDRSZ 4 7 | #endif 8 | 9 | +#ifndef NETDB_INTERNAL 10 | +#define NETDB_INTERNAL -1 11 | +#endif 12 | + 13 | +#ifndef NETDB_SUCCESS 14 | +#define NETDB_SUCCESS 0 15 | +#endif 16 | + 17 | NSS_STATUS _nss_wins_gethostbyname_r(const char *hostname, 18 | struct hostent *he, 19 | char *buffer, 20 | -------------------------------------------------------------------------------- /apps/nix/network-test/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | $(CC) -Wall -O2 -g -o network-test main.c 3 | 4 | install: 5 | install -D network-test $(PREFIX)/bin/network-test 6 | -------------------------------------------------------------------------------- /apps/nix/network-test/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv }: 2 | 3 | stdenv.mkDerivation { 4 | name = "network-test"; 5 | src = ./.; 6 | installPhase = '' 7 | mkdir -p $out/bin 8 | gcc -o $out/bin/network-test main.c 9 | ''; 10 | } 11 | -------------------------------------------------------------------------------- /apps/nix/network-test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | //char buf[1 << 16]; 12 | #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) 13 | 14 | int main(int argc, char** argv) { 15 | if (argc != 5) { 16 | fprintf(stderr, "%s read|write num_bytes batch_size\n", argv[0]); 17 | exit(EXIT_FAILURE); 18 | } 19 | 20 | 21 | int read_socket = strcmp(argv[1], "read") == 0; 22 | 23 | in_addr_t addr = inet_addr(argv[2]); 24 | if (addr == INADDR_NONE) { 25 | fprintf(stderr, "Invalid address\n"); 26 | exit(EXIT_FAILURE); 27 | } 28 | 29 | long num_bytes = strtol(argv[3], NULL, 10); 30 | long batch_size = strtol(argv[4], NULL, 10); 31 | 32 | size_t total_sent = 0; 33 | clock_t start; 34 | 35 | struct sockaddr_in servaddr = {}; 36 | servaddr.sin_family = AF_INET; 37 | servaddr.sin_addr.s_addr = addr; 38 | servaddr.sin_port = htons(8888); 39 | 40 | char *buf = (char*) malloc(batch_size*sizeof(char)); 41 | memset(buf, 'a', batch_size); 42 | 43 | for (;;) { 44 | int fd = socket(AF_INET, SOCK_STREAM, 0); 45 | for (;;) { 46 | int ret = connect(fd, (struct sockaddr*)&servaddr, sizeof(servaddr)); 47 | if (ret != -1) break; 48 | perror("connect"); 49 | usleep(2000000); 50 | } 51 | 52 | start = clock(); 53 | 54 | while(total_sent < num_bytes) { 55 | int to_send = MIN(batch_size, num_bytes - total_sent); 56 | int ret; 57 | if (read_socket) { 58 | ret = read(fd, buf, to_send); 59 | if (ret <= 0) { 60 | perror("read"); 61 | break; 62 | } 63 | } else { 64 | ret = write(fd, buf, to_send); 65 | if (ret == -1) { 66 | perror("write"); 67 | break; 68 | } 69 | } 70 | 71 | total_sent += to_send; 72 | } 73 | 74 | printf("{\"bytes\": %ld, \"time\": %lf}\n", total_sent, ((double)clock() - start)/CLOCKS_PER_SEC); 75 | close(fd); 76 | 77 | break; 78 | } 79 | 80 | free(buf); 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /apps/nix/parallel-iperf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import json 5 | import subprocess 6 | import sys 7 | from threading import Condition, Thread 8 | from typing import Any, Dict, List 9 | 10 | IPERF3_DEFAULT_PORT = 5201 11 | 12 | 13 | def run_iperf( 14 | condition: Condition, 15 | iperf_cmd: List[str], 16 | results: List[Dict[str, Any]], 17 | index: int, 18 | ) -> None: 19 | with condition: 20 | condition.wait() 21 | # DEBUG 22 | print(f"$ {' '.join(iperf_cmd)}", file=sys.stderr) 23 | proc = subprocess.run(iperf_cmd, stdout=subprocess.PIPE) 24 | print(proc.stdout.decode("utf-8"), file=sys.stderr) 25 | results[index] = json.loads(proc.stdout.decode("utf-8")) 26 | 27 | 28 | def main() -> None: 29 | parser = argparse.ArgumentParser(description="Run iperf3 instances in parallel") 30 | parser.add_argument("instances", type=int, help="number of parallel instances") 31 | args, base_iperf_cmd = parser.parse_known_args() 32 | condition = Condition() 33 | threads = [] 34 | results: List[Dict[str, Any]] = [{} for i in range(args.instances)] 35 | for i in range(args.instances): 36 | iperf_cmd = base_iperf_cmd + ["-p", str(IPERF3_DEFAULT_PORT + i)] 37 | thread_args = (condition, iperf_cmd, results, i) 38 | thread = Thread(target=run_iperf, args=thread_args) 39 | thread.start() 40 | threads.append(thread) 41 | 42 | with condition: 43 | condition.notify_all() 44 | 45 | for thread in threads: 46 | thread.join() 47 | 48 | instances = [] 49 | for i, result in enumerate(results): 50 | instances.append(dict(port=IPERF3_DEFAULT_PORT + 1, result=result)) 51 | json.dump(dict(instances=instances), sys.stdout) 52 | 53 | 54 | if __name__ == "__main__": 55 | main() 56 | -------------------------------------------------------------------------------- /apps/nix/plot.py: -------------------------------------------------------------------------------- 1 | # workaround to select Agg as backend consistenly 2 | import matplotlib as mpl # type: ignore 3 | import matplotlib.pyplot as plt # type: ignore 4 | import matplotlib.ticker as ticker 5 | import seaborn as sns # type: ignore 6 | from typing import Any 7 | 8 | mpl.use("Agg") 9 | mpl.rcParams["text.latex.preamble"] = r"\usepackage{amsmath}" 10 | mpl.rcParams["pdf.fonttype"] = 42 11 | mpl.rcParams["ps.fonttype"] = 42 12 | 13 | # plt.rc('text', usetex=True) 14 | # plt.figure(figsize=(2.5, 2.5)) 15 | sns.set(rc={'figure.figsize':(5,5)}) 16 | sns.set_style("whitegrid") 17 | sns.set_style("ticks", {"xtick.major.size": 8, "ytick.major.size": 8}) 18 | # sns.set_context(font_scale=1.5) 19 | sns.set_context("paper", rc={"font.size":5,"axes.titlesize":5,"axes.labelsize":8}) 20 | sns.set_palette(sns.color_palette(palette="gray", n_colors=2)) 21 | 22 | def catplot(**kwargs: Any) -> Any: 23 | kwargs.setdefault("palette", "Greys") 24 | g = sns.catplot(**kwargs) 25 | g.despine(top=False, right=False) 26 | plt.autoscale() 27 | plt.subplots_adjust(top=0.98) 28 | return g 29 | 30 | 31 | def apply_hatch(groups: int, g: Any, legend: bool) -> None: 32 | hatch_list = ['', '///', '---', '\\'] 33 | if len(g.ax.patches) == groups: 34 | for i, bar in enumerate(g.ax.patches): 35 | hatch = hatch_list[i] 36 | bar.set_hatch(hatch) 37 | else: 38 | for i, bar in enumerate(g.ax.patches): 39 | hatch = hatch_list[int(i / groups)] 40 | bar.set_hatch(hatch) 41 | if legend: 42 | g.ax.legend(loc='best', fontsize='small') 43 | 44 | 45 | def rescale_barplot_width(ax: Any, factor: float = 0.6) -> None: 46 | for bar in ax.patches: 47 | x = bar.get_x() 48 | new_width = bar.get_width() * factor 49 | center = x + bar.get_width() / 2.0 50 | bar.set_width(new_width) 51 | bar.set_x(center - new_width / 2.0) 52 | 53 | 54 | def alternate_bar_color(graph: Any) -> None: 55 | for i, patch in enumerate(graph.axes[0][0].patches): 56 | if i % 2 == 0: 57 | patch.set_facecolor( 58 | (0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 1.0) 59 | ) 60 | else: 61 | patch.set_facecolor( 62 | (0.6666666666666666, 0.6666666666666666, 0.6666666666666666, 1.0) 63 | ) 64 | -------------------------------------------------------------------------------- /apps/nix/pthread-socket/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv }: 2 | 3 | stdenv.mkDerivation { 4 | name = "pthread-socket"; 5 | src = ./.; 6 | installPhase = '' 7 | mkdir -p $out/bin 8 | gcc -o $out/bin/pthread-socket -pthread main.c 9 | ''; 10 | } 11 | -------------------------------------------------------------------------------- /apps/nix/pthread-socket/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void *socket_test(void *unused) { 8 | char hostname[256]; 9 | socket(AF_INET, SOCK_STREAM, 0); 10 | 11 | fprintf(stderr, "%s(): socket established: %s\n", __func__, hostname); 12 | return NULL; 13 | } 14 | 15 | int main() { 16 | int i; 17 | pthread_t ids[3]; 18 | 19 | socket(AF_INET, SOCK_STREAM, 0); 20 | 21 | for (i = 0; i < 1; i++) { 22 | pthread_create(&ids[i], NULL, socket_test, NULL); 23 | } 24 | 25 | for (i = 0; i < 1; i++) { 26 | pthread_join(ids[i], NULL); 27 | } 28 | 29 | fprintf(stderr, "finished\n"); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /apps/nix/python-scripts/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, python3Minimal, enableDebugging }: 2 | 3 | let 4 | python = enableDebugging (python3Minimal.overrideAttrs (old: { 5 | hardeningEnable = [ "pie" ] ++ (old.hardeningEnable or []); 6 | })); 7 | in stdenv.mkDerivation { 8 | name = "python-scripts"; 9 | buildInputs = [ python ]; 10 | src = ./.; 11 | passthru = { 12 | inherit (python) interpreter; 13 | }; 14 | installPhase = '' 15 | install -D --target $out/bin *.py 16 | ''; 17 | } 18 | -------------------------------------------------------------------------------- /apps/nix/python-scripts/introspect-blocks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import glob 3 | import os 4 | 5 | 6 | def dump_files(dir_path: str): 7 | print(dir_path) 8 | for tuneable in os.listdir(dir_path): 9 | path = os.path.join(dir_path, tuneable) 10 | if os.path.isdir(path): 11 | dump_files(path) 12 | else: 13 | try: 14 | with open(path) as file: 15 | print(f"{tuneable}: {file.read()}", end="") 16 | except OSError: 17 | pass 18 | 19 | 20 | def main() -> None: 21 | for queue in glob.glob("/sys/block/*/queue"): 22 | dump_files(queue) 23 | 24 | 25 | if __name__ == '__main__': 26 | main() 27 | -------------------------------------------------------------------------------- /apps/nix/run-image.nix: -------------------------------------------------------------------------------- 1 | { runtimeShell, python3, lib, flamegraph, pkgsMusl, writeScript, buildImage }: 2 | 3 | { pkg 4 | , command 5 | , extraFiles ? {} 6 | , interpreter ? null 7 | , sgx-lkl-run ? "sgx-lkl-run" 8 | , extraCommands ? "" 9 | , debugSymbols ? true 10 | , diskSize ? "1G" 11 | , native ? false 12 | }: 13 | 14 | let 15 | image = buildImage { 16 | inherit pkg extraFiles extraCommands debugSymbols diskSize; 17 | }; 18 | in (writeScript "run-lkl" '' 19 | #!/usr/bin/env bash 20 | 21 | set -eu -o pipefail 22 | 23 | export TMPDIR=/tmp 24 | export PATH=${lib.makeBinPath [ flamegraph ]}:$PATH 25 | 26 | if [[ $# -eq 0 ]]; then 27 | cmd="${toString command}" 28 | else 29 | cmd=$1 30 | shift 31 | fi 32 | ${if native then '' 33 | if [[ -n "''${SGXLKL_CWD:-}" ]]; then 34 | cd "$SGXLKL_CWD" 35 | fi 36 | '' else ""} 37 | 38 | set -x 39 | exec ${python3.interpreter} ${./run-image.py} ${sgx-lkl-run} ${if native then "NONE" else image} ${toString interpreter} ${image.pkg}/$cmd "$@" 40 | '').overrideAttrs (old: { 41 | passthru.pkg = pkg; 42 | }) 43 | -------------------------------------------------------------------------------- /apps/nix/scone/default.nix: -------------------------------------------------------------------------------- 1 | { buildPackages 2 | , runCommand 3 | , stdenv 4 | , skopeo 5 | , oci-image-tool 6 | , cacert 7 | , lib 8 | , autoPatchelfHook 9 | , buildFHSUserEnv 10 | , gcc7 11 | , libredirect 12 | , makeWrapper 13 | , zlib 14 | , gcc 15 | , glibc 16 | , utillinux 17 | , wrapCCWith 18 | , wrapBintoolsWith 19 | , binutils-unwrapped 20 | , overrideCC 21 | , fetchurl 22 | }: 23 | let 24 | ociImage = fetchurl { 25 | #sudo skopeo copy --insecure-policy docker-daemon:sconecuratedimages/crosscompilers:ubuntu oci:image:1.0.0 26 | name = "scone.tar"; 27 | url = "https://cloudflare-ipfs.com/ipfs/QmYbr1iESCCKHCS7iJjZw81jig73yHfBc5ruAhPx9YodV8"; 28 | sha256 = "1jgi3qlwq9bfjqqmcd5rrg68q0a3jbirziff5gzsnlwq12lkpqhk"; 29 | }; 30 | scone-image = runCommand "scone-image" { 31 | nativeBuildInputs = [ oci-image-tool ]; 32 | } '' 33 | tar -xf ${ociImage} 34 | oci-image-tool unpack -ref name=scone image $out 35 | ''; 36 | gcc-nolibc = wrapCCWith { 37 | inherit (gcc) cc; 38 | bintools = wrapBintoolsWith { 39 | bintools = binutils-unwrapped; 40 | libc = null; 41 | }; 42 | extraBuildCommands = '' 43 | sed -i '2i if ! [[ $@ == *'musl-gcc.specs'* ]]; then exec ${gcc}/bin/gcc -L${glibc}/lib -L${glibc.static}/lib "$@"; fi' \ 44 | $out/bin/gcc 45 | 46 | sed -i '2i if ! [[ $@ == *'musl-gcc.specs'* ]]; then exec ${gcc}/bin/g++ -L${glibc}/lib -L${glibc.static}/lib "$@"; fi' \ 47 | $out/bin/g++ 48 | 49 | sed -i '2i if ! [[ $@ == *'musl-gcc.spec'* ]]; then exec ${gcc}/bin/cpp "$@"; fi' \ 50 | $out/bin/cpp 51 | ''; 52 | }; 53 | in rec { 54 | scone-unwrapped = stdenv.mkDerivation { 55 | name = "scone-unwrapped"; 56 | dontUnpack = true; 57 | 58 | passthru = { 59 | isGNU = true; 60 | hardeningUnsupportedFlags = [ "pie" ]; 61 | }; 62 | 63 | installPhase = '' 64 | mkdir -p $out/{opt,usr/lib/,bin} 65 | cp -r ${scone-image}/opt/scone $out/opt/scone 66 | chmod -R +w $out/opt/scone 67 | 68 | for path in $(grep -I -l -R /opt/scone "$out/opt/scone" | xargs readlink -f | sort -u); do 69 | substituteInPlace "$path" \ 70 | --replace "/opt/scone" "$out/opt/scone" 71 | done 72 | 73 | for i in gcc cc cpp; do 74 | makeWrapper $out/opt/scone/bin/scone-gcc $out/bin/$i \ 75 | --set REALGCC ${gcc-nolibc}/bin/gcc \ 76 | --prefix PATH : ${utillinux}/bin 77 | done 78 | for i in g++ c++; do 79 | makeWrapper $out/opt/scone/bin/scone-g++ $out/bin/$i \ 80 | --set REALGCC ${gcc-nolibc}/bin/gcc \ 81 | --prefix PATH : ${utillinux}/bin 82 | done 83 | 84 | ln -s $out/opt/scone/cross-compiler/x86_64-linux-musl/lib $out/lib 85 | ln -s $out/opt/scone/bin/scone $out/bin/scone 86 | ''; 87 | nativeBuildInputs = [ 88 | autoPatchelfHook makeWrapper 89 | ]; 90 | }; 91 | scone = wrapCCWith { 92 | cc = scone-unwrapped; 93 | bintools = wrapBintoolsWith { 94 | bintools = binutils-unwrapped; 95 | libc = scone-unwrapped; 96 | }; 97 | }; 98 | sconeStdenv = overrideCC stdenv scone; 99 | 100 | # for nix-shell 101 | sconeEnv = sconeStdenv.mkDerivation { 102 | name = "scone-env"; 103 | hardeningDisable = [ "all" ]; 104 | }; 105 | } 106 | -------------------------------------------------------------------------------- /apps/nix/scone/sgx-musl.conf: -------------------------------------------------------------------------------- 1 | Q 2 2 | e 0 0 0 3 | s 1 0 0 4 | e 2 1 0 5 | s 3 1 0 6 | s 4 0 0 7 | s 5 1 0 8 | s 6 0 0 9 | s 7 1 0 10 | s 8 0 0 11 | s 9 1 0 12 | s 10 0 0 13 | s 11 1 0 14 | s 12 0 0 15 | s 13 1 0 16 | s 14 0 0 17 | s 15 1 0 18 | -------------------------------------------------------------------------------- /apps/nix/setup.cfg: -------------------------------------------------------------------------------- 1 | [pycodestyle] 2 | max-line-length = 88 3 | ignore = E501,E741,W503 4 | 5 | [flake8] 6 | max-line-length = 88 7 | ignore = E501,E741,W503 8 | exclude = .git,__pycache__,docs/source/conf.py,old,build,dist 9 | 10 | [mypy] 11 | warn_redundant_casts = true 12 | disallow_untyped_calls = true 13 | disallow_untyped_defs = true 14 | no_implicit_optional = true 15 | 16 | [mypy-pandas.*] 17 | ignore_missing_imports = True 18 | 19 | [isort] 20 | profile = black 21 | -------------------------------------------------------------------------------- /apps/nix/simpleio/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | $(CC) -Wall -O2 -g -o simpleio main.c 3 | $(CC) -Wall -O2 -g -o udp-send udp-send.c 4 | $(CC) -Wall -O2 -g -o gethostname gethostname.c 5 | 6 | install: 7 | install -D --target $(PREFIX)/bin simpleio udp-send gethostname 8 | -------------------------------------------------------------------------------- /apps/nix/simpleio/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv }: 2 | 3 | stdenv.mkDerivation { 4 | name = "simpleio"; 5 | src = ./.; 6 | installFlags = [ "PREFIX=$(out)" ]; 7 | } 8 | -------------------------------------------------------------------------------- /apps/nix/simpleio/gethostname.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | struct thread_ctx { 11 | pthread_t id; 12 | int calls; 13 | }; 14 | char buf[4096 * 128] = {}; 15 | 16 | void *hostname_thread(void *_args) { 17 | struct thread_ctx *ctx = (struct thread_ctx*)_args; 18 | FILE *f = tmpfile(); 19 | for (unsigned i = 0; i < ctx->calls; i++) { 20 | pwrite(fileno(f), buf, sizeof(buf), 0); 21 | } 22 | fclose(f); 23 | return NULL; 24 | } 25 | 26 | int main(int argc, char** argv) { 27 | if (argc < 2) { 28 | fprintf(stderr, "USAGE: %s calls", argv[0]); 29 | return 1; 30 | } 31 | #define PTHREAD_NUM 8 32 | struct thread_ctx contexts[PTHREAD_NUM] = {}; 33 | int calls = atoi(argv[1]); 34 | 35 | printf("\n"); 36 | for (unsigned threads = 1; threads <= PTHREAD_NUM; threads++) { 37 | clock_t start = clock(); 38 | for (unsigned i = 0; i < threads; i++) { 39 | struct thread_ctx *ctx = &contexts[i]; 40 | contexts[i].calls = calls / threads; 41 | pthread_create(&ctx->id, NULL, hostname_thread, ctx); 42 | } 43 | 44 | for (unsigned i = 0; i < threads; i++) { 45 | 46 | struct thread_ctx *ctx = &contexts[i]; 47 | pthread_join(ctx->id, NULL); 48 | } 49 | 50 | double total_time = ((double)clock() - start)/CLOCKS_PER_SEC; 51 | printf("{\"total_time\": %lf, \"calls\": %d, \"time_per_syscall\": %lf, \"threads\": %u}\n", 52 | total_time, calls, total_time / calls, threads); 53 | } 54 | printf("\n"); 55 | fflush(stdout); 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /apps/nix/simpleio/udp-send.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | struct thread_ctx { 11 | pthread_t id; 12 | int socket; 13 | int packets; 14 | int size; 15 | struct sockaddr_in addr; 16 | }; 17 | char buf[1472]; 18 | 19 | void *send_thread(void *_args) { 20 | struct thread_ctx *ctx = (struct thread_ctx*)_args; 21 | for (unsigned i = 0; i < ctx->packets; i++) { 22 | int res = sendto(ctx->socket, buf, ctx->size, 0, (struct sockaddr *) &ctx->addr, sizeof(ctx->addr)); 23 | if (res == -1) { 24 | perror("sendto()"); 25 | break; 26 | } 27 | } 28 | return NULL; 29 | } 30 | 31 | int main(int argc, char** argv) { 32 | if (argc < 2) { 33 | fprintf(stderr, "USAGE: %s host packets", argv[0]); 34 | return 1; 35 | } 36 | #define PTHREAD_NUM 8 37 | struct thread_ctx contexts[PTHREAD_NUM] = {}; 38 | char *host = argv[1]; 39 | int packets = atoi(argv[2]); 40 | 41 | contexts[0].addr.sin_family = AF_INET; 42 | contexts[0].addr.sin_port = htons(1); 43 | 44 | if (inet_aton(host, &contexts[0].addr.sin_addr) == 0) { 45 | fprintf(stderr, "inet_aton() failed\n"); 46 | return 1; 47 | } 48 | contexts[0].socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 49 | if (contexts[0].socket == -1) { 50 | perror("socket"); 51 | return 1; 52 | } 53 | for (int i = 1; i < PTHREAD_NUM; i *= 2) { 54 | memcpy(&contexts[i], &contexts[0], sizeof(contexts)); 55 | contexts[i].socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 56 | if (contexts[i].socket == -1) { 57 | perror("socket"); 58 | return 1; 59 | } 60 | } 61 | 62 | unsigned sizes[6] = { 32, 128, 512, 1024, 1472, 0 }; 63 | printf("\n"); 64 | for (unsigned *size = sizes; *size; size++) { 65 | for (unsigned threads = 1; threads <= PTHREAD_NUM; threads *= 2) { 66 | clock_t start = clock(); 67 | for (unsigned i = 0; i < threads; i++) { 68 | struct thread_ctx *ctx = &contexts[i]; 69 | ctx->packets = packets / threads; 70 | ctx->size = *size; 71 | pthread_create(&ctx->id, NULL, send_thread, ctx); 72 | } 73 | 74 | for (unsigned i = 0; i < threads; i++) { 75 | struct thread_ctx *ctx = &contexts[i]; 76 | pthread_join(ctx->id, NULL); 77 | } 78 | 79 | double total_time = ((double)clock() - start)/CLOCKS_PER_SEC; 80 | printf("{\"total_time\": %lf, \"data_size\": %d, \"time_per_syscall\": %lf, \"threads\": %u, \"packets_per_thread\": %u}\n", 81 | total_time, 82 | *size, 83 | total_time / packets, 84 | threads, 85 | packets / threads); 86 | } 87 | } 88 | printf("\n"); 89 | fflush(stdout); 90 | 91 | for (int i = 1; i < PTHREAD_NUM; i *= 2) { 92 | close(contexts[i].socket); 93 | } 94 | 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /apps/nix/spdk-zerocopy.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import signal 4 | from typing import Dict, List, Optional 5 | import subprocess 6 | import pandas as pd 7 | 8 | from helpers import ( 9 | NOW, 10 | create_settings, 11 | nix_build, 12 | read_stats, 13 | write_stats, 14 | ) 15 | from storage import Storage, StorageKind 16 | 17 | 18 | def benchmark_simpleio( 19 | storage: Storage, 20 | type: str, 21 | attr: str, 22 | directory: str, 23 | stats: Dict[str, List], 24 | extra_env: Dict[str, str] = {}, 25 | ) -> None: 26 | env = dict(SGXLKL_CWD=directory) 27 | env.update(extra_env) 28 | env.update(SGXLKL_ENABLE_SGXIO="1") 29 | env.update(SGXLKL_ETHREADS="1") 30 | env.update(extra_env) 31 | simpleio = nix_build(attr) 32 | stdout: Optional[int] = subprocess.PIPE 33 | if os.environ.get("SGXLKL_ENABLE_GDB", "0") == "1": 34 | stdout = None 35 | size = str(10 * 1024 * 1024 * 1024) # 2G 36 | 37 | env_string = [] 38 | for k, v in env.items(): 39 | env_string.append(f"{k}={v}") 40 | report = "" 41 | in_results = False 42 | env = os.environ.copy() 43 | env.update(extra_env) 44 | 45 | cmd = [ 46 | simpleio, 47 | "bin/simpleio", 48 | "/dev/mapper/spdk0", 49 | size, 50 | "0", 51 | "1", 52 | str(128 * 4096), 53 | ] 54 | print(f"$ {' '.join(env_string)} {' '.join(cmd)}") 55 | proc = subprocess.Popen(cmd, stdout=stdout, text=True, env=env) 56 | try: 57 | assert proc.stdout is not None 58 | for line in proc.stdout: 59 | print(f"stdout: {line}", end="") 60 | if line == "\n": 61 | in_results = True 62 | elif in_results and line == "\n": 63 | break 64 | elif in_results: 65 | report = line 66 | finally: 67 | proc.send_signal(signal.SIGINT) 68 | jsondata = json.loads(report) 69 | stats["type"].append(type) 70 | stats["bytes"].append(jsondata["bytes"]) 71 | stats["time"].append(jsondata["time"]) 72 | 73 | 74 | def main() -> None: 75 | stats = read_stats("spdk-zerocopy.json") 76 | storage = Storage(create_settings()) 77 | 78 | mount = storage.setup(StorageKind.SPDK) 79 | with mount as mnt: 80 | extra_env1 = mount.extra_env() 81 | extra_env1["SGXLKL_SPDK_ZEROCOPY"] = "1" 82 | benchmark_simpleio( 83 | storage, "optimized", "simpleio-sgx-io", mnt, stats, extra_env=extra_env1 84 | ) 85 | import time 86 | time.sleep(5) 87 | extra_env2 = mount.extra_env() 88 | extra_env2["SGXLKL_SPDK_ZEROCOPY"] = "0" 89 | benchmark_simpleio( 90 | storage, "not-optimized", "simpleio-sgx-io", mnt, stats, extra_env=extra_env2 91 | ) 92 | write_stats("spdk-zerocopy.json", stats) 93 | 94 | csv = f"spdk-zerocopy-{NOW}.tsv" 95 | print(csv) 96 | df = pd.DataFrame(stats) 97 | df.to_csv(csv, index=False, sep="\t") 98 | df.to_csv("spdk-zerocopy-latest.tsv", index=False, sep="\t") 99 | 100 | 101 | if __name__ == "__main__": 102 | main() 103 | -------------------------------------------------------------------------------- /apps/nix/tests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import hashlib 4 | import subprocess 5 | 6 | from helpers import Settings, create_settings, nix_build, spawn, ROOT 7 | 8 | 9 | def test_nginx(settings: Settings) -> None: 10 | nginx = nix_build("nginx") 11 | remote_curl = settings.remote_command(nix_build("curl-remote")) 12 | with spawn(nginx.strip()): 13 | for _ in range(10): 14 | try: 15 | curl_args = ["curl", "-s", settings.local_dpdk_ip + "/test/file-3mb"] 16 | proc = remote_curl.run("bin/curl", curl_args) 17 | sha256 = hashlib.sha256(proc.stdout).hexdigest() 18 | expected = ( 19 | "259da4e49b1d0932c5a16a9809113cf3ea6c7292e827298827e020aa7361f98d" 20 | ) 21 | assert sha256 == expected, f"{hash} == {expected}" 22 | break 23 | except subprocess.CalledProcessError: 24 | pass 25 | 26 | 27 | def test_fstest() -> None: 28 | fstest = ROOT.joinpath("..", "fstest") 29 | subprocess.run(["make", "-C", fstest, "check"]) 30 | 31 | 32 | def main() -> None: 33 | settings = create_settings() 34 | test_nginx(settings) 35 | test_fstest() 36 | 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /apps/nix/wrk_args.json: -------------------------------------------------------------------------------- 1 | { 2 | "-t":"12", 3 | "-c": "400", 4 | "-d": "30s" 5 | } -------------------------------------------------------------------------------- /apps/nix/ycsb/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, fetchurl, python2, jre, makeWrapper }: 2 | 3 | stdenv.mkDerivation rec { 4 | pname = "ycsb"; 5 | version = "0.17.0"; 6 | 7 | src = fetchurl { 8 | url = "https://github.com/harshanavkis/YCSB/releases/download/1/ycsb-0.17.0.tar.gz"; 9 | sha256 = "0l4npcw1wcm2glj2i71p8c8w585bbgh1kj74kayby7xrg3zp9kx1"; 10 | }; 11 | 12 | buildInputs = [ python2 ]; 13 | nativeBuildInputs = [ makeWrapper ]; 14 | 15 | installPhase = '' 16 | mkdir -p $out/{bin,share/ycsb} 17 | cp -r * $out/share/ycsb 18 | makeWrapper $out/share/ycsb/bin/ycsb $out/bin/ycsb \ 19 | --prefix PATH : ${stdenv.lib.makeBinPath [ jre ]} 20 | ''; 21 | } 22 | -------------------------------------------------------------------------------- /gdb/README.md: -------------------------------------------------------------------------------- 1 | Create the SGX-LKL gdb wrapper (sgx-lkl-run), by running the following: 2 | 3 | ./setup.sh 4 | -------------------------------------------------------------------------------- /gdb/gdb-sgx-plugin/gdb_sgx_cmd: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2011-2018 Intel Corporation. All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # * Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # * Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in 12 | # the documentation and/or other materials provided with the 13 | # distribution. 14 | # * Neither the name of Intel Corporation nor the names of its 15 | # contributors may be used to endorse or promote products derived 16 | # from this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | # 30 | # 31 | 32 | # the path can be specified by directory command 33 | define hook-detach 34 | detach_enclaves 35 | end 36 | -------------------------------------------------------------------------------- /gdb/gdb-sgx-plugin/readelf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright (C) 2011-2018 Intel Corporation. All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without 6 | # modification, are permitted provided that the following conditions 7 | # are met: 8 | # 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in 13 | # the documentation and/or other materials provided with the 14 | # distribution. 15 | # * Neither the name of Intel Corporation nor the names of its 16 | # contributors may be used to endorse or promote products derived 17 | # from this software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | # 31 | # 32 | 33 | import gdb, subprocess 34 | def ReadElf(EnclaveFile): 35 | prefix = gdb.execute("get_tc_prefix", False, True) 36 | readelf_cmd = 'readelf' 37 | 38 | if prefix.strip() != 'None': 39 | readelf_cmd = prefix.strip() + 'readelf' 40 | try: 41 | text = subprocess.check_output([readelf_cmd, 42 | '-W', 43 | '-S', 44 | EnclaveFile], 45 | universal_newlines=True 46 | ) 47 | except subprocess.CalledProcessError as e: 48 | text = None 49 | 50 | return text 51 | -------------------------------------------------------------------------------- /gdb/inspect-backtrace.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import pandas as pd 3 | 4 | 5 | def main(): 6 | if len(sys.argv) < 2: 7 | print(f"USAGE: {sys.argv[0]} file") 8 | sys.exit(1) 9 | df = pd.read_csv(sys.argv[1]) 10 | 11 | unscheduled = df[~df.backtrace.str.contains("__schedule")] 12 | for _, row in unscheduled.iterrows(): 13 | print(row.backtrace) 14 | 15 | breakpoint() 16 | 17 | for idx, row in df.iterrows(): 18 | print(row.backtrace) 19 | traces = list(df.backtrace) 20 | 21 | print(traces[0]) 22 | 23 | if __name__ == '__main__': 24 | main() 25 | -------------------------------------------------------------------------------- /gdb/ptrace/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LDFLAGS = -ldl 3 | CFLAGS = -D_GNU_SOURCE -fPIC 4 | SRC := se_ptrace.c se_memory.c se_trace.c 5 | OBJ := se_ptrace.o se_memory.o se_trace.o 6 | TARGET := libsgx_ptrace.so 7 | 8 | .PHONY: all clean 9 | all: $(TARGET) 10 | 11 | $(TARGET): $(OBJ) 12 | $(CC) $(CFLAGS) -shared $^ -o $@ $(LDFLAGS) 13 | 14 | $(OBJ): %.o: %.c 15 | $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) 16 | 17 | clean: 18 | rm -f $(OBJ) $(TARGET) 19 | -------------------------------------------------------------------------------- /gdb/ptrace/README.md: -------------------------------------------------------------------------------- 1 | The code in this directory is based on the ptrace code from the official Intel 2 | SGX SDK repository (https://github.com/intel/linux-sgx), based on commit 3 | 0f45cad401e974bee57704f3fb0ff185146bbde2. 4 | 5 | Original copyright information is provided as part of the header in the 6 | individual source files. 7 | -------------------------------------------------------------------------------- /gdb/ptrace/inst.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2018 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SE_ARCH_H_ 33 | # error "never include inst.h directly; use arch.h instead." 34 | #endif 35 | 36 | 37 | #ifndef _SE_INST_H_ 38 | #define _SE_INST_H_ 39 | 40 | #define ENCLU 0xd7010f 41 | 42 | typedef enum { 43 | SE_EREPORT = 0x0, 44 | SE_EGETKEY, 45 | SE_EENTER, 46 | SE_ERESUME, 47 | SE_EEXIT, 48 | SE_EACCEPT, 49 | SE_LAST_RING3, 50 | 51 | SE_ECREATE = 0x0, 52 | SE_EADD, 53 | SE_EINIT, 54 | SE_EREMOVE, 55 | SE_EDBGRD, 56 | SE_EDBGWR, 57 | SE_EEXTEND, 58 | SE_LAST_RING0 59 | } se_opcode_t; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /gdb/ptrace/se_trace.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2018 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | 33 | #include "se_trace.h" 34 | #include 35 | int se_trace_internal(int debug_level, const char *fmt, ...) 36 | { 37 | va_list args; 38 | int ret = 0; 39 | 40 | va_start(args, fmt); 41 | if(SE_TRACE_NOTICE == debug_level) 42 | ret = vfprintf(stdout, fmt, args); 43 | else 44 | ret = vfprintf(stderr, fmt, args); 45 | va_end(args); 46 | 47 | return ret; 48 | } 49 | -------------------------------------------------------------------------------- /gdb/ptrace/se_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2018 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | /* 33 | * This file is to define some types that is platform independent. 34 | */ 35 | 36 | #ifndef _SE_TYPE_H_ 37 | #define _SE_TYPE_H_ 38 | #include "se_cdefs.h" 39 | 40 | #ifdef SE_DRIVER 41 | 42 | typedef INT8 int8_t; 43 | typedef UINT8 uint8_t; 44 | typedef INT16 int16_t; 45 | typedef UINT16 uint16_t; 46 | typedef INT32 int32_t; 47 | typedef UINT32 uint32_t; 48 | typedef INT64 int64_t; 49 | typedef UINT64 uint64_t; 50 | 51 | #else 52 | 53 | #include 54 | #include 55 | 56 | #ifndef TRUE 57 | #define TRUE 1 58 | #endif 59 | 60 | #ifndef FALSE 61 | #define FALSE 0 62 | #endif 63 | 64 | #endif 65 | 66 | #if defined(SE_64) 67 | 68 | #define PADDED_POINTER(t, p) t* p 69 | #define PADDED_DWORD(d) uint64_t d 70 | #define PADDED_LONG(l) int64_t l 71 | #define REG(name) r##name 72 | #ifdef SE_SIM_EXCEPTION 73 | #define REG_ALIAS(name) R##name 74 | #endif 75 | #define REGISTER(name) uint64_t REG(name) 76 | 77 | #else /* !defined(SE_64) */ 78 | 79 | #define PADDED_POINTER(t, p) t* p; void* ___##p##_pad_to64_bit 80 | #define PADDED_DWORD(d) uint32_t d; uint32_t ___##d##_pad_to64_bit 81 | #define PADDED_LONG(l) int32_t l; int32_t ___##l##_pad_to64_bit 82 | 83 | #define REG(name) e##name 84 | 85 | #ifdef SE_SIM_EXCEPTION 86 | #define REG_ALIAS(name) E##name 87 | #endif 88 | 89 | #define REGISTER(name) uint32_t REG(name); uint32_t ___##e##name##_pad_to64_bit 90 | 91 | #endif /* !defined(SE_64) */ 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /gdb/ptrace/sgx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2018 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SGX_H_ 33 | #define _SGX_H_ 34 | 35 | #include "sgx_error.h" 36 | #include "sgx_attributes.h" 37 | #include "sgx_key.h" 38 | #include "sgx_report.h" 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /gdb/ptrace/sgx_attributes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2018 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SGX_ATTRIBUTES_H_ 33 | #define _SGX_ATTRIBUTES_H_ 34 | 35 | #include 36 | 37 | /* Enclave Flags Bit Masks */ 38 | #define SGX_FLAGS_INITTED 0x0000000000000001ULL /* If set, then the enclave is initialized */ 39 | #define SGX_FLAGS_DEBUG 0x0000000000000002ULL /* If set, then the enclave is debug */ 40 | #define SGX_FLAGS_MODE64BIT 0x0000000000000004ULL /* If set, then the enclave is 64 bit */ 41 | #define SGX_FLAGS_PROVISION_KEY 0x0000000000000010ULL /* If set, then the enclave has access to provision key */ 42 | #define SGX_FLAGS_EINITTOKEN_KEY 0x0000000000000020ULL /* If set, then the enclave has access to EINITTOKEN key */ 43 | #define SGX_FLAGS_RESERVED (~(SGX_FLAGS_INITTED | SGX_FLAGS_DEBUG | SGX_FLAGS_MODE64BIT | SGX_FLAGS_PROVISION_KEY | SGX_FLAGS_EINITTOKEN_KEY)) 44 | 45 | /* XSAVE Feature Request Mask */ 46 | #define SGX_XFRM_LEGACY 0x0000000000000003ULL /* Legacy XFRM which includes the basic feature bits required by SGX, x87 state(0x01) and SSE state(0x02) */ 47 | #define SGX_XFRM_AVX 0x0000000000000006ULL /* AVX XFRM which includes AVX state(0x04) and SSE state(0x02) required by AVX */ 48 | #define SGX_XFRM_AVX512 0x00000000000000E6ULL /* AVX-512 XFRM - not supported */ 49 | #define SGX_XFRM_MPX 0x0000000000000018ULL /* MPX XFRM - not supported */ 50 | 51 | #define SGX_XFRM_RESERVED (~(SGX_XFRM_LEGACY | SGX_XFRM_AVX)) 52 | 53 | typedef struct _attributes_t 54 | { 55 | uint64_t flags; 56 | uint64_t xfrm; 57 | } sgx_attributes_t; 58 | 59 | /* define MISCSELECT - all bits are currently reserved */ 60 | typedef uint32_t sgx_misc_select_t; 61 | 62 | typedef struct _sgx_misc_attribute_t { 63 | sgx_attributes_t secs_attr; 64 | sgx_misc_select_t misc_select; 65 | } sgx_misc_attribute_t; 66 | 67 | #endif/* _SGX_ATTRIBUTES_H_ */ 68 | -------------------------------------------------------------------------------- /gdb/ptrace/sgx_defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2018 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SGX_DEFS_H_ 33 | #define _SGX_DEFS_H_ 34 | 35 | /* The following macros are for GCC only */ 36 | 37 | # define SGXAPI 38 | 39 | # ifdef linux 40 | # undef linux 41 | # endif 42 | # define SGX_CXX_NATIVE_HEADER(header) 43 | 44 | # define SGX_CDECL 45 | # define SGX_STDCALL 46 | # define SGX_FASTCALL 47 | 48 | # define SGX_DLLIMPORT 49 | # define SGX_UBRIDGE(attr, fname, args...) attr fname args 50 | 51 | # define SGX_DEPRECATED __attribute__((deprecated)) 52 | 53 | 54 | #define SGX_NOCONVENTION /* Empty. No calling convention specified. */ 55 | 56 | #endif /* !_SGX_DEFS_H_ */ 57 | -------------------------------------------------------------------------------- /gdb/setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | pushd ptrace 6 | make 7 | popd 8 | 9 | SGX_LIBRARY_PATH=$(readlink -f ./ptrace) 10 | GDB_SGX_PLUGIN_PATH=$(readlink -f ./gdb-sgx-plugin) 11 | GDB_PLUGIN=$(readlink -f ./gdb.py) 12 | 13 | cat > sgx-lkl-gdb < 5 | #include "attest_ias.h" 6 | 7 | void get_quote_from_report(const uint8_t* report /* in */, 8 | const int report_len /* in */, 9 | sgx_quote_t* quote); 10 | 11 | int verify_quote(sgx_quote_t *quote, const char *mrenclave_hex, const char *mrsigner_hex); 12 | int verify_report(int strict, const char *ias_sign_ca_cert_pem, attestation_verification_report_t *attn_report, 13 | const char *mrenclave, const char *mrsigner, uint64_t nonce); 14 | #endif 15 | -------------------------------------------------------------------------------- /src/dpdk/override/uint.h: -------------------------------------------------------------------------------- 1 | typedef unsigned uint; 2 | 3 | static __inline void 4 | outw_p (unsigned short int __value, unsigned short int __port) 5 | { 6 | __asm__ __volatile__ ("outw %w0,%w1\noutb %%al,$0x80": :"a" (__value), 7 | "Nd" (__port)); 8 | } 9 | 10 | static __inline void 11 | outl_p (unsigned int __value, unsigned short int __port) 12 | { 13 | __asm__ __volatile__ ("outl %0,%w1\noutb %%al,$0x80": :"a" (__value), 14 | "Nd" (__port)); 15 | } 16 | 17 | static __inline void 18 | outb_p (unsigned char __value, unsigned short int __port) 19 | { 20 | __asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80": :"a" (__value), 21 | "Nd" (__port)); 22 | } 23 | -------------------------------------------------------------------------------- /src/include/aesm.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define AESM_SOCKET_PATH "/var/run/aesmd/aesm.socket" 7 | 8 | sgx_quote_t *aesm_alloc_quote(uint32_t *sz); 9 | 10 | int aesm_init_quote( 11 | sgx_target_info_t *target_info, // out 12 | sgx_epid_group_id_t *gid // out 13 | ); 14 | 15 | int aesm_get_quote( 16 | sgx_spid_t *spid, // in 17 | sgx_quote_sign_type_t quote_type, // in 18 | sgx_report_t* report, // in 19 | sgx_quote_t* quote, // out 20 | uint32_t quote_size 21 | ); 22 | -------------------------------------------------------------------------------- /src/include/attest.h: -------------------------------------------------------------------------------- 1 | #ifndef _ATTEST_H_ 2 | #define _ATTEST_H_ 3 | 4 | #include 5 | 6 | struct sgxlkl_report_data { 7 | uint8_t wg_public_key[32]; 8 | uint64_t nonce; 9 | uint8_t reserved[24]; 10 | }; 11 | 12 | struct attestation_config { 13 | sgx_spid_t spid; 14 | sgx_quote_sign_type_t quote_type; 15 | const char *ias_key_file; 16 | const char *ias_cert_file; 17 | /* Domain name/IP and port, e.g., 18 | test-as.sgx.trustedservices.intel.com:443 */ 19 | const char *ias_server; 20 | }; 21 | #endif /* _ATTEST_H_ */ 22 | -------------------------------------------------------------------------------- /src/include/attest_ias.h: -------------------------------------------------------------------------------- 1 | #ifndef ATTEST_IAS_H 2 | #define ATTEST_IAS_H 3 | 4 | #include 5 | #include "attest.h" 6 | 7 | typedef struct { 8 | uint8_t ias_report[2*1024]; 9 | uint32_t ias_report_len; 10 | uint8_t ias_sign_ca_cert[2*1024]; 11 | uint32_t ias_sign_ca_cert_len; 12 | uint8_t ias_sign_cert[2*1024]; 13 | uint32_t ias_sign_cert_len; 14 | uint8_t ias_report_signature[2*1024]; 15 | uint32_t ias_report_signature_len; 16 | } attestation_verification_report_t; 17 | 18 | 19 | int ias_get_attestation_verification_report( 20 | const sgx_quote_t* quote, 21 | const uint32_t quote_size, 22 | const struct attestation_config* attestation_config, 23 | attestation_verification_report_t* attn_report, 24 | int verbose 25 | ); 26 | #endif /* ATTEST_IAS_H */ 27 | -------------------------------------------------------------------------------- /src/include/base64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | unsigned char *sgxlkl_base64_encode(const unsigned char *src, size_t len, 7 | unsigned char *out, size_t *out_len); 8 | unsigned char *sgxlkl_base64_decode(const unsigned char *src, size_t len, 9 | unsigned char *out, size_t *out_len); 10 | 11 | bool sgxlkl_base64_validate(const unsigned char *src, size_t len); 12 | -------------------------------------------------------------------------------- /src/include/dpdk.h: -------------------------------------------------------------------------------- 1 | #ifndef _DPDK_H 2 | #define _DPDK_H 3 | 4 | #include 5 | 6 | #include "sgx_enclave_config.h" 7 | 8 | int dpdk_initialize_iface(enclave_config_t *encl, const char *ifparams); 9 | struct dpdk_context *dpdk_initialize_context(); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/include/dpdk_config.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define DPDK_MAX_PKT_BURST 16 4 | #define DPDK_MEMPOOL_CACHE_SZ 256 5 | /* assuming MTU == 1500 */ 6 | #define DPDK_MBUF_NUM (512 * 4) /* vmxnet3 requires 1024 */ 7 | #define DPDK_NUMDESC 512 /* nb_min on vmxnet3 is 512 */ 8 | // we only can support one queue at the moment 9 | #define DPDK_NUM_TX_QUEUE 1 10 | 11 | #define DPDK_MAX_PACKET_SZ (65535 - (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)) 12 | //#define DPDK_MAX_PACKET_SZ (1500 - (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)) 13 | #define DPDK_MBUF_SIZ \ 14 | (DPDK_MAX_PACKET_SZ + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) 15 | 16 | -------------------------------------------------------------------------------- /src/include/dpdk_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef _DPDK_INTERNAL_H 2 | #define _DPDK_INTERNAL_H 3 | 4 | #include 5 | #include 6 | 7 | struct dpdk_context { 8 | struct rte_eth_dev *devices; 9 | struct rte_config *config; 10 | struct lcore_config *lcore_config; 11 | struct internal_config *internal_config; 12 | }; 13 | void dpdk_init_array(); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/include/enclave_cmd.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCLAVE_CMD_H 2 | #define ENCLAVE_CMD_H 3 | 4 | #include 5 | #include 6 | #include "sgxlkl_app_config.h" 7 | #ifdef SGXLKL_HW 8 | #include "sgx_enclave_config.h" 9 | #include "attest_ias.h" 10 | #endif /* SGXLKL_HW */ 11 | 12 | typedef struct cmd_server_config { 13 | struct sockaddr_in addr; /* IP and port the server will listen on. */ 14 | sgxlkl_app_config_t *app_config; /* If not NULL the server will wait for an 15 | incoming run request, fill app_config 16 | and signal the receipt via signal to 17 | run_cv. Only one run request will be 18 | accepted. */ 19 | pthread_mutex_t *run_mtx; /* Mutex to protect run_cv */ 20 | pthread_cond_t *run_cv; /* Condition variable used to signal the 21 | receipt of a run command. */ 22 | int attest_only; /* If specified, this instance should only 23 | respond to attest requests. */ 24 | #ifdef SGXLKL_HW 25 | attestation_info_t *att_info; /* Attestation info (quote and 26 | (optionally) IAS attestation report for 27 | the current enclave. */ 28 | #endif 29 | } cmd_server_config_t; 30 | 31 | void enclave_cmd_server_run(cmd_server_config_t *config); 32 | void enclave_cmd_servers_stop(void); 33 | 34 | #endif /* ENCLAVE_CMD_H */ 35 | -------------------------------------------------------------------------------- /src/include/enclave_mem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #ifndef ENCLAVE_MEM_H 6 | #define ENCLAVE_MEM_H 7 | 8 | #define ENCLAVE_MMAP_FILES_NONE 0 9 | #define ENCLAVE_MMAP_FILES_PRIVATE 1 10 | #define ENCLAVE_MMAP_FILES_SHARED 2 11 | 12 | void enclave_mman_init(void *base, size_t num_pages, int topdown, int _mmap_files); 13 | void* enclave_mmap(void *addr, size_t length, int mmap_fixed); 14 | int enclave_munmap(void *addr, size_t length); 15 | void* enclave_mremap(void *old_addr, size_t old_length, void *new_addr, size_t new_length, int mremap_fixed); 16 | int enclave_mmap_flags_supported(int flags, int fd); 17 | 18 | #endif /* ENCLAVE_MEM_H */ 19 | -------------------------------------------------------------------------------- /src/include/enclave_signal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #ifndef ENCLAVE_SIGNAL_H 6 | #define ENCLAVE_SIGNAL_H 7 | 8 | #include "sgx_enclave_config.h" 9 | 10 | /* Enclave signal info */ 11 | typedef struct { 12 | int signum; 13 | void *arg; 14 | } enclave_signal_info_t; 15 | 16 | void __enclave_signal_handler(gprsgx_t *regs, enclave_signal_info_t *siginfo); 17 | 18 | #endif /* ENCLAVE_SIGNAL_H */ 19 | -------------------------------------------------------------------------------- /src/include/ias-ra.h: -------------------------------------------------------------------------------- 1 | #ifndef _IAS_RA__H_ 2 | #define _IAS_RA_H_ 3 | 4 | #include 5 | #include "attest.h" 6 | 7 | typedef struct { 8 | uint8_t ias_report[2*1024]; 9 | uint32_t ias_report_len; 10 | uint8_t ias_sign_ca_cert[2*1024]; 11 | uint32_t ias_sign_ca_cert_len; 12 | uint8_t ias_sign_cert[2*1024]; 13 | uint32_t ias_sign_cert_len; 14 | uint8_t ias_report_signature[2*1024]; 15 | uint32_t ias_report_signature_len; 16 | } attestation_verification_report_t; 17 | 18 | 19 | void ias_get_attestation_verification_report( 20 | const sgx_quote_t* quote, 21 | const uint32_t quote_size, 22 | const struct attestation_config* attestation_config, 23 | attestation_verification_report_t* attn_report 24 | ); 25 | #endif 26 | -------------------------------------------------------------------------------- /src/include/json_util.h: -------------------------------------------------------------------------------- 1 | #ifndef JSON_UTIL_H 2 | #define JSON_UTIL_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define JSON_OBJECT_FOREACH(it, obj, key, value) \ 9 | for ((it) = json_object_iter_begin(obj); \ 10 | (it).opaque_ != json_object_iter_end(obj).opaque_ && \ 11 | ((key) = json_object_iter_peek_name(&(it))) && \ 12 | ((value) = json_object_iter_peek_value(&(it))); \ 13 | json_object_iter_next(&(it))) 14 | 15 | typedef int (*parse_json_callback)(const char*, struct json_object*, void*); 16 | 17 | int my_callback(const char* key, struct json_object* value, void* userarg); 18 | int parse_json(struct json_object *jobj, parse_json_callback cb, void *userarg); 19 | int parse_json_from_str(char *str, parse_json_callback cb, void *userarg, char **err); 20 | int parse_json_from_file(char *path, parse_json_callback cb, void *userarg, char **err); 21 | #endif /* JSON_UTIL_H */ 22 | -------------------------------------------------------------------------------- /src/include/lkl/disk.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #ifndef _MUSLKL_DISK_H 6 | #define _MUSLKL_DISK_H 7 | 8 | #include 9 | 10 | extern struct lkl_dev_blk_ops sgxlkl_dev_plaintext_blk_ops; 11 | extern struct lkl_dev_blk_ops sgxlkl_dev_cipher_blk_ops; 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /src/include/lkl/dpdk.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Imperial College London 3 | */ 4 | 5 | #ifndef _MUSLKL_DPDK_H 6 | #define _MUSLKL_DPDK_H 7 | 8 | #include "sgx_enclave_config.h" 9 | 10 | /** 11 | * lkl_register_netdev_dpdk - a dpdk device as a NIC 12 | */ 13 | 14 | int sgxlkl_register_dpdk_device(struct enclave_dpdk_config *dev); 15 | int sgxlkl_register_dpdk_context(struct dpdk_context *context); 16 | void sgxlkl_register_dpdk_dma_memory(struct enclave_dpdk_dma_memory* ctx); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/include/lkl/iomem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #ifndef _LKL_LIB_IOMEM_H 6 | #define _LKL_LIB_IOMEM_H 7 | 8 | struct lkl_iomem_ops { 9 | int (*read)(void *data, int offset, void *res, int size); 10 | int (*write)(void *data, int offset, void *value, int size); 11 | }; 12 | 13 | void* register_iomem(void *data, int size, const struct lkl_iomem_ops *ops); 14 | void unregister_iomem(void *iomem_base); 15 | void *lkl_ioremap(long addr, int size); 16 | int lkl_iomem_access(const volatile void *addr, void *res, int size, int write); 17 | 18 | #endif /* _LKL_LIB_IOMEM_H */ 19 | -------------------------------------------------------------------------------- /src/include/lkl/jmp_buf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #ifndef _MUSLKL_LIB_JMP_BUF_H 6 | #define _MUSLKL_LIB_JMP_BUF_H 7 | 8 | void sgxlkl_jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void)); 9 | void sgxlkl_jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/include/lkl/posix-host.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #ifndef _MUSLKL_POSIX_HOST_H 6 | #define _MUSLKL_POSIX_HOST_H 7 | 8 | #include 9 | 10 | extern struct lkl_host_operations sgxlkl_host_ops; 11 | extern struct lkl_dev_blk_ops sgxlkl_dev_blk_ops; 12 | extern struct lkl_dev_blk_ops sgxlkl_dev_blk_mem_ops; 13 | #endif 14 | -------------------------------------------------------------------------------- /src/include/lkl/setup.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #include "sgx_enclave_config.h" 6 | 7 | #define DEFAULT_LKL_CMDLINE "" 8 | 9 | void lkl_start_init(enclave_config_t* encl); 10 | void lkl_exit(); 11 | void lkl_mount_disks(struct enclave_disk_config* disks, size_t num_disks, const char *cwd); 12 | 13 | -------------------------------------------------------------------------------- /src/include/lkl/spdk.h: -------------------------------------------------------------------------------- 1 | #ifndef _MUSLKL_SPDK_H 2 | #define _MUSLKL_SPDK_H 3 | 4 | #include 5 | #include 6 | 7 | struct spdk_dev { 8 | // filled out by the caller 9 | struct spdk_ns_entry ns_entry; 10 | // set by sgxlkl_register_spdk_device 11 | lkl_thread_t poll_tid; 12 | bool stop_polling; 13 | int dev_id; 14 | }; 15 | 16 | int sgxlkl_spdk_initialize(void); 17 | int sgxlkl_register_spdk_device(struct spdk_dev *dev); 18 | void sgxlkl_unregister_spdk_device(struct spdk_dev *dev); 19 | void sgxlkl_register_spdk_dma_memory(struct spdk_dma_memory *ctx); 20 | int sgxlkl_stop_spdk(void); 21 | int sgxlkl_debug_spdk(void); 22 | 23 | void *sgxlkl_spdk_malloc(size_t size); 24 | void sgxlkl_spdk_free(void *ptr); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/include/lkl/virtio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #ifndef _LKL_LIB_VIRTIO_H 6 | #define _LKL_LIB_VIRTIO_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | /* The following are copied from skbuff.h */ 13 | #if (65536/PAGE_SIZE + 1) < 16 14 | #define MAX_SKB_FRAGS 16UL 15 | #else 16 | #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 1) 17 | #endif 18 | 19 | #define VIRTIO_REQ_MAX_BUFS (MAX_SKB_FRAGS + 2) 20 | 21 | struct virtio_req { 22 | uint16_t buf_count; 23 | struct iovec buf[VIRTIO_REQ_MAX_BUFS]; 24 | uint32_t total_len; 25 | }; 26 | 27 | struct virtio_dev; 28 | 29 | struct virtio_dev_ops { 30 | int (*check_features)(struct virtio_dev *dev); 31 | /** 32 | * enqueue - queues the request for processing 33 | * 34 | * Note that the curret implementation assumes that the requests are 35 | * processed synchronous and, as such, @virtio_req_complete must be 36 | * called by from this function. 37 | * 38 | * @dev - virtio device 39 | * @q - queue index 40 | * 41 | * @returns a negative value if the request has not been queued for 42 | * processing in which case the virtio device is resposible for 43 | * restaring the queue processing by calling @virtio_process_queue at a 44 | * later time; 0 or a positive value means that the request has been 45 | * queued for processing 46 | */ 47 | int (*enqueue)(struct virtio_dev *dev, int q, struct virtio_req *req); 48 | /* 49 | * Acquire/release a lock on the specified queue. Only implemented by 50 | * netdevs, all other devices have NULL acquire/release function 51 | * pointers. 52 | */ 53 | void (*acquire_queue)(struct virtio_dev *dev, int queue_idx); 54 | void (*release_queue)(struct virtio_dev *dev, int queue_idx); 55 | 56 | // low level alternative to enqueue in order to allow asynchronous processing 57 | void (*process_queue)(struct virtio_dev *dev, int queue_idx); 58 | }; 59 | 60 | struct virtio_dev { 61 | uint32_t device_id; 62 | uint32_t vendor_id; 63 | uint64_t device_features; 64 | uint32_t device_features_sel; 65 | uint64_t driver_features; 66 | uint32_t driver_features_sel; 67 | uint32_t queue_sel; 68 | struct virtio_queue *queue; 69 | uint32_t queue_notify; 70 | uint32_t int_status; 71 | uint32_t status; 72 | uint32_t config_gen; 73 | 74 | struct virtio_dev_ops *ops; 75 | int irq; 76 | void *config_data; 77 | int config_len; 78 | void *base; 79 | uint32_t virtio_mmio_id; 80 | }; 81 | 82 | int virtio_dev_setup(struct virtio_dev *dev, int queues, int num_max); 83 | int virtio_dev_cleanup(struct virtio_dev *dev); 84 | uint32_t virtio_get_num_bootdevs(void); 85 | /** 86 | * virtio_req_complete - complete a virtio request 87 | * 88 | * @req - the request to be completed 89 | * @len - the total size in bytes of the completed request 90 | */ 91 | void virtio_req_complete(struct virtio_req *req, uint32_t len); 92 | void virtio_process_queue(struct virtio_dev *dev, uint32_t qidx); 93 | void virtio_set_queue_max_merge_len(struct virtio_dev *dev, int q, int len); 94 | 95 | #define container_of(ptr, type, member) \ 96 | (type *)((char *)(ptr) - __builtin_offsetof(type, member)) 97 | 98 | #endif /* _LKL_LIB_VIRTIO_H */ 99 | -------------------------------------------------------------------------------- /src/include/lkl/virtio_net.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #ifndef _MUSLKL_VIRTIO_NET_H 6 | #define _MUSLKL_VIRTIO_NET_H 7 | 8 | struct ifreq; 9 | 10 | /** 11 | * lkl_register_netdev_linux_fdnet - register a file descriptor-based network 12 | * device as a NIC 13 | * 14 | * @fd - a POSIX file descriptor number for input/output 15 | * @sync_io - 1 if I/O should be synchronous, i.e. threads should busy wait for 16 | * I/O to complete. 17 | * @returns a struct lkl_netdev_linux_fdnet entry for virtio-net 18 | */ 19 | struct lkl_netdev* sgxlkl_register_netdev_fd(int fd, int sync_io); 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /src/include/lkl/virtio_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef _LKL_LIB_VIRTIO_QUEUE_H 2 | #define _LKL_LIB_VIRTIO_QUEUE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "lkl/virtio.h" 9 | 10 | struct _virtio_req { 11 | struct virtio_req req; 12 | struct virtio_dev *dev; 13 | struct virtio_queue *q; 14 | uint16_t idx; 15 | }; 16 | 17 | void async_virtio_process_queue(struct virtio_dev *dev, uint32_t qidx); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/include/lthread_int.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Lthread 3 | * Copyright (C) 2012, Hasan Alayli 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 | * SUCH DAMAGE. 25 | * 26 | * lthread_int.c 27 | */ 28 | 29 | 30 | #ifndef LTHREAD_INT_H 31 | #define LTHREAD_INT_H 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #define LT_MAX_EVENTS (1024) 41 | #define MAX_STACK_SIZE (512*1024) /* 512k */ 42 | 43 | #define BIT(x) (1 << (x)) 44 | #define CLEARBIT(x) ~(1 << (x)) 45 | #define WAIT_LIMITLESS ~((uint64_t)0) 46 | #define WAIT_TIMEOUT (WAIT_LIMITLESS - 1) 47 | 48 | struct lthread; 49 | struct lthread_sched; 50 | 51 | int _lthread_sched_init(size_t stack_size); 52 | int _lthread_resume(struct lthread *lt); 53 | void _lthread_renice(struct lthread *lt); 54 | void _lthread_yield(struct lthread *lt); 55 | void _lthread_yield_cb(struct lthread *lt, void (*f)(void*), void *arg); 56 | void _lthread_yield_and_resched(struct lthread *lt); 57 | void _lthread_free(struct lthread *lt); 58 | void _lthread_desched_sleep(struct lthread *lt); 59 | //void _lthread_sched_sleep(struct lthread *lt, uint64_t msecs); 60 | 61 | int _save_exec_state(struct lthread *lt); 62 | void print_timestamp(char *); 63 | 64 | static inline uint64_t _lthread_timespec_to_usec(const struct timespec *ts) { 65 | return (ts->tv_sec * 1000000) + ts->tv_nsec / 1000; 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/include/mpmc_queue.h: -------------------------------------------------------------------------------- 1 | /** Lock-free Multiple-Producer Multiple-consumer (MPMC) queue. 2 | * 3 | * Based on Dmitry Vyukov#s Bounded MPMC queue: 4 | * http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue 5 | * 6 | * @author Steffen Vogel 7 | * @copyright 2016 Steffen Vogel 8 | * @copyright 2017 Imperial College London 9 | * @license BSD 2-Clause License 10 | * 11 | * All rights reserved. 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modiffication, are permitted provided that the following conditions are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright notice, this 17 | * list of conditions and the following disclaimer. 18 | * 19 | * * Redistributions in binary form must reproduce the above copyright notice, 20 | * this list of conditions and the following disclaimer in the documentation 21 | * and/or other materials provided with the distribution. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | #ifndef MPMC_QUEUE_H 35 | #define MPMC_QUEUE_H 36 | 37 | struct cell_t { 38 | size_t seq; 39 | void *data; 40 | }; 41 | 42 | struct mpmcq { 43 | char pad0[128]; 44 | struct cell_t *buffer; 45 | size_t buffer_mask; 46 | char pad1[128]; 47 | size_t enqueue_pos; 48 | char pad2[128]; 49 | size_t dequeue_pos; 50 | char pad3[128]; 51 | } __attribute__((aligned(64))); 52 | 53 | 54 | 55 | int mpmc_enqueue(volatile struct mpmcq *q, void *data); 56 | int newmpmcq(struct mpmcq *q, size_t buffer_bytesize, void *buffer); 57 | int mpmc_dequeue(volatile struct mpmcq *q, void **data); 58 | 59 | #endif /* MPMC_QUEUE_H */ 60 | -------------------------------------------------------------------------------- /src/include/pcap.h: -------------------------------------------------------------------------------- 1 | #ifndef _PCAP_H 2 | #define _PCAP_H 3 | 4 | #include "stddef.h" 5 | 6 | #ifdef DEBUG 7 | int write_pcap_file(const char* filename, void* pkt, size_t len); 8 | int write_pcap_filev(const char *filename, struct iovec *pkts, size_t len); 9 | #endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/include/ping.h: -------------------------------------------------------------------------------- 1 | #ifndef _PING_H 2 | #define _PING_H 3 | 4 | #include 5 | 6 | // useful for debugging 7 | int send_ping(int portid, struct rte_mempool* txpool); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/include/sgx_enclave_report.h: -------------------------------------------------------------------------------- 1 | #ifndef SGX_ENCLAVE_REPORT_H 2 | #define SGX_ENCLAVE_REPORT_H 3 | 4 | #include 5 | 6 | void enclave_report( 7 | sgx_target_info_t* target_info, 8 | sgx_report_data_t* report_data, 9 | sgx_report_t* report 10 | ); 11 | 12 | #endif /* SGX_ENCLAVE_REPORT_H */ 13 | -------------------------------------------------------------------------------- /src/include/sgx_hostcall_interface.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SGX_HOSTCALL_INTERFACE_H 3 | #define SGX_HOSTCALL_INTERFACE_H 4 | #include "sgx_enclave_config.h" 5 | 6 | struct mpmcq *__syscall_queue; 7 | struct mpmcq *__return_queue; 8 | 9 | struct Arena 10 | { 11 | uint8_t *mem; 12 | size_t size; 13 | size_t allocated; 14 | }; 15 | typedef struct Arena Arena; 16 | 17 | int hostsyscallclient_init(enclave_config_t *encl); 18 | syscall_t *getsyscallslot(Arena **a); 19 | size_t allocslot(struct lthread *lt); 20 | void freeslot(size_t slotno); 21 | void threadswitch(syscall_t *sc); 22 | struct lthread *slottolthread(size_t s); 23 | 24 | void arena_new(Arena *, size_t); 25 | syscall_t *arena_ensure(Arena *, size_t, syscall_t *); 26 | void *arena_alloc(Arena *, size_t); 27 | void arena_free(Arena *); 28 | void arena_destroy(Arena *); 29 | 30 | size_t deepsizeiovec(const struct iovec *dst); 31 | int deepinitiovec(struct Arena *a, struct iovec *dst, const struct iovec *src); 32 | void deepcopyiovec(struct iovec *dst, const struct iovec *src); 33 | 34 | #endif /* SGX_HOSTCALL_INTERFACE_H */ 35 | 36 | -------------------------------------------------------------------------------- /src/include/sgx_hostcalls.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SGX_HOSTCALLS_H 3 | #define SGX_HOSTCALLS_H 4 | #define _GNU_SOURCE 5 | #define _BSD_SOURCE 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "sgx_hostcall_interface.h" 17 | 18 | /* 19 | * sgx_hostcalls.c must include ksigaction.h before including this header. 20 | */ 21 | typedef struct k_sigaction k_sigaction_t; 22 | 23 | int host_syscall_SYS_clock_gettime(clockid_t clk_id, struct timespec *tp); 24 | int host_syscall_SYS_close(int fd); 25 | int host_syscall_SYS_fcntl(int fd, intptr_t cmd, intptr_t arg); 26 | int host_syscall_SYS_fdatasync(int fd); 27 | int host_syscall_SYS_fstat(int fd, struct stat *buf); 28 | pid_t host_syscall_SYS_gettid(void); 29 | int host_syscall_SYS_ioctl(int fd, unsigned long request, void *arg); 30 | void *host_syscall_SYS_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); 31 | int host_syscall_SYS_mprotect(void *addr, size_t len, int prot); 32 | void *host_syscall_SYS_mremap(void *old_address, size_t old_size, size_t new_size, int flags, void *new_address); 33 | int host_syscall_SYS_munmap(void *addr, size_t length); 34 | int host_syscall_SYS_msync(void *addr, size_t length, int flags); 35 | int host_syscall_SYS_nanosleep(const struct timespec *req, struct timespec *rem); 36 | ssize_t host_syscall_SYS_read(int fd, void *buf, size_t count); 37 | ssize_t host_syscall_SYS_readv(int fd, struct iovec *iov, int iovcnt); 38 | int host_syscall_SYS_pipe(int pipefd[2]); 39 | int host_syscall_SYS_poll(struct pollfd *fds, nfds_t nfds, int timeout); 40 | ssize_t host_syscall_SYS_pread64(int fd, void *buf, size_t count, off_t offset); 41 | ssize_t host_syscall_SYS_pwrite64(int fd, const void *buf, size_t count, off_t offset); 42 | int host_syscall_SYS_rt_sigaction(int signum, struct sigaction *act, struct sigaction *oldact, unsigned long nsig); 43 | int host_syscall_SYS_rt_sigpending(sigset_t *set, unsigned long nsig); 44 | int host_syscall_SYS_rt_sigprocmask(int how, void *set, sigset_t *oldset, unsigned long nsig); 45 | int host_syscall_SYS_rt_sigsuspend(const sigset_t *mask, unsigned long nsig); 46 | int host_syscall_SYS_rt_sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout, unsigned long nsig); 47 | int host_syscall_SYS_tkill(int tid, int sig); 48 | ssize_t host_syscall_SYS_write(int fd, const void *buf, size_t count); 49 | ssize_t host_syscall_SYS_writev(int fd, const struct iovec *iov, int iovcnt); 50 | 51 | /* Handled within enclave */ 52 | /* TODO: Move declarations to separate headers */ 53 | int syscall_SYS_futex(int *uaddr, int op, int val, const struct timespec *timeout, int *uaddr2, int val3); 54 | void *syscall_SYS_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); 55 | void *syscall_SYS_mremap(void *old_address, size_t old_size, size_t new_size, int flags, void *new_address); 56 | int syscall_SYS_msync(void *addr, size_t length, int flags); 57 | int syscall_SYS_munmap(void *addr, size_t length); 58 | int syscall_SYS_sysinfo(struct sysinfo* info); 59 | 60 | /* Some host system calls are only needed for debug purposed. Don't include 61 | * them in a non-debug build. */ 62 | #if DEBUGMOUNT 63 | int host_syscall_SYS_open(const char *pathname, int flags, mode_t mode); 64 | #endif /* DEBUGMOUNT */ 65 | 66 | #endif /* SGX_HOSTCALLS_H */ 67 | -------------------------------------------------------------------------------- /src/include/sgxlkl_app_config.h: -------------------------------------------------------------------------------- 1 | #ifndef SGXLKL_APP_CONFIG_H 2 | #define SGXLKL_APP_CONFIG_H 3 | 4 | #include "sgx_enclave_config.h" 5 | 6 | typedef struct sgxlkl_app_config { 7 | const char *run; /* Will ultimately point at the same location as argv[0] */ 8 | const char *cwd; /* Working directory */ 9 | int argc; 10 | char **argv; /* Array of application arguments of length argc */ 11 | char **envp; /* Null-terminated array of environment variables */ 12 | size_t num_disks; 13 | enclave_disk_config_t *disks; /* Array of disk configurations of length num_disks */ 14 | size_t num_peers; 15 | enclave_wg_peer_config_t *peers; /* Array of wireguard peer configurations of length num_peers */ 16 | } sgxlkl_app_config_t; 17 | 18 | int parse_sgxlkl_app_config_from_str(char *str, sgxlkl_app_config_t *conf, char **err); 19 | 20 | #endif /* SGXLKL_APP_CONFIG_H */ 21 | -------------------------------------------------------------------------------- /src/include/sgxlkl_debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #ifndef _SGXLKL_DEBUG_INCLUDE 6 | #define _SGXLKL_DEBUG_INCLUDE 7 | 8 | #define SGXLKL_LKL_SYSCALL 1 9 | #define SGXLKL_INTERNAL_SYSCALL 3 10 | 11 | void log_sgxlkl_syscall(int type, long n, long res, int params_len, ...); 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | extern int sgxlkl_verbose; 21 | 22 | #define SGXLKL_VERBOSE(x, ...) if (sgxlkl_verbose) {sgxlkl_debug_printf("[ SGX-LKL ] " x, ##__VA_ARGS__);} 23 | 24 | #define LKL_STDERR_FILENO 2 25 | #define DEBUG_TRACE_BUF_SIZE 512 26 | 27 | static int sgxlkl_debug_vprintf(const char *fmt, va_list args) { 28 | static char buf[DEBUG_TRACE_BUF_SIZE]; 29 | int n; 30 | char *buffer; 31 | va_list copy; 32 | 33 | va_copy(copy, args); 34 | n = vsnprintf(NULL, 0, fmt, copy); 35 | va_end(copy); 36 | 37 | if (n < DEBUG_TRACE_BUF_SIZE) { 38 | buffer = (char*) &buf; 39 | } else { 40 | buffer = malloc(n + 1); 41 | } 42 | 43 | if (!buffer) 44 | return -1; 45 | 46 | vsnprintf(buffer, n + 1, fmt, args); 47 | 48 | size_t curr_index = 0; 49 | while (curr_index < n) { 50 | curr_index += write(LKL_STDERR_FILENO, buffer + curr_index, n - curr_index); 51 | } 52 | 53 | if (buffer != (char*) &buf) { 54 | free(buffer); 55 | } 56 | return n; 57 | } 58 | 59 | static int sgxlkl_debug_printf(const char *fmt, ...) { 60 | int n; 61 | va_list args; 62 | 63 | va_start(args, fmt); 64 | n = sgxlkl_debug_vprintf(fmt, args); 65 | va_end(args); 66 | return n; 67 | } 68 | 69 | #ifdef DEBUG 70 | 71 | extern int sgxlkl_trace_thread; 72 | extern int sgxlkl_trace_mmap; 73 | extern int sgxlkl_trace_lkl_syscall; 74 | extern int sgxlkl_trace_internal_syscall; 75 | 76 | #define SGXLKL_TRACE_THREAD(x, ...) if (sgxlkl_trace_thread) {sgxlkl_debug_printf("[ THREAD ] " x, ##__VA_ARGS__);} 77 | #define SGXLKL_TRACE_MMAP(x, ...) if (sgxlkl_trace_mmap) {sgxlkl_debug_printf("[ MMAP ] " x, ##__VA_ARGS__);} 78 | #define SGXLKL_TRACE_SYSCALL(type, x, ...) if ((sgxlkl_trace_lkl_syscall && type == SGXLKL_LKL_SYSCALL) || (sgxlkl_trace_internal_syscall && type == SGXLKL_INTERNAL_SYSCALL)) { \ 79 | sgxlkl_debug_printf(type == SGXLKL_LKL_SYSCALL ? "[ LKL SYSCALL ] " x : \ 80 | "[INTRNL SYSCALL] " x, ##__VA_ARGS__);} 81 | #else 82 | #define SGXLKL_TRACE_THREAD(x, ...) 83 | #define SGXLKL_TRACE_MMAP(x, ...) 84 | #define SGXLKL_TRACE_SYSCALL(x, ...) 85 | #endif /* DEBUG */ 86 | 87 | #endif /* _SGXLKL_DEBUG_INCLUDE*/ 88 | -------------------------------------------------------------------------------- /src/include/sgxlkl_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | #ifndef _SGXLKL_UTIL_INCLUDE 5 | #define _SGXLKL_UTIL_INCLUDE 6 | 7 | #include 8 | #include 9 | 10 | void sgxlkl_fail(char *msg, ...); 11 | void sgxlkl_err(char *msg, ...); 12 | void sgxlkl_warn(char *msg, ...); 13 | void sgxlkl_info(char *msg, ...); 14 | 15 | uint64_t size_str_to_uint64(const char *str, uint64_t def, uint64_t max); 16 | uint64_t getenv_uint64(const char *var, uint64_t def, uint64_t max); 17 | char *getenv_str(const char *var, const char *def); 18 | int getenv_bool(const char *var, int def); 19 | 20 | uint64_t next_pow2(uint64_t x); 21 | ssize_t hex_to_bytes(const char *hex, char **result); 22 | 23 | #endif /* _SGXLKL_UTIL_INCLUDE*/ 24 | -------------------------------------------------------------------------------- /src/include/spdk_bench.h: -------------------------------------------------------------------------------- 1 | #ifndef SPDK_BENCH_H 2 | #define SPDK_BENCH_H 3 | 4 | #include 5 | 6 | void run_spdk_bench(struct spdk_ns_entry *ns_entry); 7 | 8 | #endif /* SPDK_BENCH_H */ 9 | -------------------------------------------------------------------------------- /src/include/spdk_context.h: -------------------------------------------------------------------------------- 1 | #ifndef _SPDK_CONTEXT_H 2 | #define _SPDK_CONTEXT_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | struct spdk_ctrlr_entry { 9 | struct spdk_nvme_ctrlr *ctrlr; 10 | struct spdk_ctrlr_entry *next; 11 | char name[1024]; 12 | }; 13 | 14 | struct spdk_ns_entry { 15 | struct spdk_nvme_ctrlr *ctrlr; 16 | struct spdk_nvme_ns *ns; 17 | struct spdk_ns_entry *next; 18 | struct spdk_nvme_qpair **qpairs; 19 | size_t qpairs_num; 20 | int ctl_fd; 21 | }; 22 | 23 | struct spdk_context { 24 | struct spdk_ctrlr_entry *controllers; 25 | struct spdk_ns_entry *namespaces; 26 | void *spdk_nvme_driver; 27 | char* key; 28 | size_t key_len; 29 | int attach_error; 30 | int skip_unmount; 31 | pthread_t ctrlr_thread_id; 32 | }; 33 | 34 | struct spdk_dma_memory { 35 | size_t nr_allocations; 36 | void **allocations; 37 | struct spdk_mempool *data_pool; 38 | size_t data_pool_size; 39 | }; 40 | 41 | int spdk_initialize(struct spdk_context *ctx, bool primary); 42 | void spdk_context_detach(struct spdk_context *ctx); 43 | void spdk_context_free(struct spdk_context *ctx); 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/include/ticketlock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #ifndef TICKETLOCK_H 6 | #define TICKETLOCK_H 7 | 8 | #include "atomic.h" 9 | 10 | #if DEBUG 11 | #include "lthread.h" 12 | #endif /* DEBUG */ 13 | 14 | struct ticketlock { 15 | union { 16 | uint64_t u; 17 | struct 18 | { 19 | uint32_t ticket; 20 | uint32_t users; 21 | } s; 22 | }; 23 | #if DEBUG 24 | struct lthread* lt; // Thread that is holding the lock. 25 | #endif /* DEBUG */ 26 | }; 27 | 28 | static void ticket_lock(struct ticketlock *t) { 29 | uint32_t me = a_fetch_add_uint(&t->s.users, 1); 30 | while (t->s.ticket != me) a_spin(); 31 | #if DEBUG 32 | t->lt = lthread_self(); 33 | #endif /* DEBUG */ 34 | } 35 | 36 | static void ticket_unlock(struct ticketlock *t) { 37 | a_barrier(); 38 | t->s.ticket++; 39 | #if DEBUG 40 | t->lt = NULL; 41 | #endif /* DEBUG */ 42 | } 43 | 44 | static int ticket_trylock(struct ticketlock *t) { 45 | uint32_t me = t->s.users; 46 | uint32_t menew = me + 1; 47 | uint64_t cmp = ((uint64_t) me << 32) + me; 48 | uint64_t cmpnew = ((uint64_t) menew << 32) + me; 49 | 50 | if (a_cas_64(&t->u, cmp, cmpnew) == cmp) { 51 | #if DEBUG 52 | t->lt = lthread_self(); 53 | #endif /* DEBUG */ 54 | return 0; 55 | } 56 | 57 | return EBUSY; 58 | } 59 | 60 | #endif /* TICKETLOCK_H */ 61 | -------------------------------------------------------------------------------- /src/include/userpci.h: -------------------------------------------------------------------------------- 1 | #ifndef _USERPCI_H 2 | #define _USERPCI_H 3 | 4 | int spawn_lkl_userpci(int *pipe_fd); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/include/wireguard.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ 2 | /* 3 | * Copyright (C) 2015-2018 Jason A. Donenfeld . All Rights Reserved. 4 | */ 5 | 6 | #ifndef WIREGUARD_H 7 | #define WIREGUARD_H 8 | 9 | #define _GNU_SOURCE // Needed for IFNAMSIZ definition in net/if.h 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | typedef uint8_t wg_key[32]; 18 | typedef char wg_key_b64_string[((sizeof(wg_key) + 2) / 3) * 4 + 1]; 19 | 20 | typedef struct wg_allowedip { 21 | uint16_t family; 22 | union { 23 | struct in_addr ip4; 24 | struct in6_addr ip6; 25 | }; 26 | uint8_t cidr; 27 | struct wg_allowedip *next_allowedip; 28 | } wg_allowedip; 29 | 30 | enum wg_peer_flags { 31 | WGPEER_REMOVE_ME = 1U << 0, 32 | WGPEER_REPLACE_ALLOWEDIPS = 1U << 1, 33 | WGPEER_HAS_PUBLIC_KEY = 1U << 2, 34 | WGPEER_HAS_PRESHARED_KEY = 1U << 3, 35 | WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4 36 | }; 37 | 38 | typedef struct wg_peer { 39 | enum wg_peer_flags flags; 40 | 41 | wg_key public_key; 42 | wg_key preshared_key; 43 | 44 | union { 45 | struct sockaddr addr; 46 | struct sockaddr_in addr4; 47 | struct sockaddr_in6 addr6; 48 | } endpoint; 49 | 50 | struct timespec last_handshake_time; 51 | uint64_t rx_bytes, tx_bytes; 52 | uint16_t persistent_keepalive_interval; 53 | 54 | struct wg_allowedip *first_allowedip, *last_allowedip; 55 | struct wg_peer *next_peer; 56 | } wg_peer; 57 | 58 | enum wg_device_flags { 59 | WGDEVICE_REPLACE_PEERS = 1U << 0, 60 | WGDEVICE_HAS_PRIVATE_KEY = 1U << 1, 61 | WGDEVICE_HAS_PUBLIC_KEY = 1U << 2, 62 | WGDEVICE_HAS_LISTEN_PORT = 1U << 3, 63 | WGDEVICE_HAS_FWMARK = 1U << 4 64 | }; 65 | 66 | typedef struct wg_device { 67 | char name[IFNAMSIZ]; 68 | uint32_t ifindex; 69 | 70 | enum wg_device_flags flags; 71 | 72 | wg_key public_key; 73 | wg_key private_key; 74 | 75 | uint32_t fwmark; 76 | uint16_t listen_port; 77 | 78 | struct wg_peer *first_peer, *last_peer; 79 | } wg_device; 80 | 81 | #define wg_for_each_device_name(__names, __name, __len) for ((__name) = (__names), (__len) = 0; ((__len) = strlen(__name)); (__name) += (__len) + 1) 82 | #define wg_for_each_peer(__dev, __peer) for ((__peer) = (__dev)->first_peer; (__peer); (__peer) = (__peer)->next_peer) 83 | #define wg_for_each_allowedip(__peer, __allowedip) for ((__allowedip) = (__peer)->first_allowedip; (__allowedip); (__allowedip) = (__allowedip)->next_allowedip) 84 | 85 | int wg_set_device(wg_device *dev); 86 | int wg_get_device(wg_device **dev, const char *device_name); 87 | int wg_add_device(const char *device_name); 88 | int wg_del_device(const char *device_name); 89 | void wg_free_device(wg_device *dev); 90 | char *wg_list_device_names(void); /* first\0second\0third\0forth\0last\0\0 */ 91 | void wg_key_to_base64(wg_key_b64_string base64, const wg_key key); 92 | int wg_key_from_base64(wg_key key, const wg_key_b64_string base64); 93 | bool wg_key_is_zero(const wg_key key); 94 | void wg_generate_public_key(wg_key public_key, const wg_key private_key); 95 | void wg_generate_private_key(wg_key private_key); 96 | void wg_generate_preshared_key(wg_key preshared_key); 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /src/include/wireguard_util.h: -------------------------------------------------------------------------------- 1 | #ifndef WIREGUARD_UTIL_H 2 | #define WIREGUARD_UTIL_H 3 | 4 | #include 5 | #include 6 | #include "sgx_enclave_config.h" 7 | #include "wireguard.h" 8 | 9 | bool wgu_parse_ip(wg_allowedip *allowedip, const char *value); 10 | bool wgu_parse_allowedips(wg_peer *peer, wg_allowedip **last_allowedip, const char *value); 11 | bool wgu_parse_endpoint(struct sockaddr *endpoint, const char *value); 12 | int wgu_add_peers(wg_device *dev, enclave_wg_peer_config_t *peers, size_t num_peers, bool set_device); 13 | int wgu_add_peer(wg_device *dev, wg_peer *new_peer, bool set_device); 14 | void wgu_list_devices(void); 15 | 16 | #endif /* WIREGUARD_UTIL_H */ 17 | -------------------------------------------------------------------------------- /src/lkl/disk.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | #include "lkl/disk.h" 5 | #include 6 | #include 7 | #include 8 | #include "syscall.h" 9 | 10 | #include "sgx_enclave_config.h" 11 | #include "sgxlkl_util.h" 12 | 13 | extern size_t num_disks; 14 | extern struct enclave_disk_config *disks; 15 | 16 | static struct enclave_disk_config *get_disk_config(int fd) { 17 | for (int i = 0; i < num_disks; i++) { 18 | if (disks[i].fd == fd) 19 | return &disks[i]; 20 | } 21 | return NULL; 22 | } 23 | 24 | static int fd_get_capacity(struct lkl_disk disk, unsigned long long *res) { 25 | off_t off; 26 | 27 | struct enclave_disk_config *disk_config; 28 | if (disk_config = get_disk_config(disk.fd)) { 29 | *res = disk_config->capacity; 30 | return 0; 31 | } 32 | return -1; 33 | } 34 | 35 | // Reads and write requests sent to the following functions are always sector- 36 | // aligned (on 512 bytes). Unaligned requests are fixed by the virtio backend. 37 | 38 | static int do_plain_rw(ssize_t (*fn)(), struct lkl_disk disk, struct lkl_blk_req *req) { 39 | off_t off = req->sector * 512; 40 | char *addr; 41 | int len; 42 | int i; 43 | int ret = 0; 44 | for (i = 0; i < req->count; i++) { 45 | addr = req->buf[i].iov_base; 46 | len = req->buf[i].iov_len; 47 | 48 | struct lthread *lt = lthread_self(); 49 | // Remember old state of lthread 50 | int lt_old_state = lt->attr.state; 51 | // Pin lthread 52 | struct enclave_disk_config *disk_config; 53 | if ((disk_config = get_disk_config(disk.fd)) != NULL && disk_config->wait_on_io) 54 | lt->attr.state = lt->attr.state | BIT(LT_ST_PINNED); 55 | 56 | do { 57 | ret = fn(disk.fd, addr, len, off); 58 | if (ret <= 0) { 59 | // Restore lthread state 60 | lt->attr.state = lt_old_state; 61 | return ret; 62 | } 63 | addr += ret; 64 | len -= ret; 65 | off += ret; 66 | } while (len > 0); 67 | 68 | // Restore lthread state 69 | lt->attr.state = lt_old_state; 70 | } 71 | return ret; 72 | } 73 | 74 | static int blk_request(struct lkl_disk disk, struct lkl_blk_req *req) { 75 | int err = 0; 76 | switch (req->type) { 77 | case LKL_DEV_BLK_TYPE_READ: 78 | err = do_plain_rw(&host_syscall_SYS_pread64, disk, req); 79 | break; 80 | case LKL_DEV_BLK_TYPE_WRITE: 81 | err = do_plain_rw(&host_syscall_SYS_pwrite64, disk, req); 82 | break; 83 | case LKL_DEV_BLK_TYPE_FLUSH: 84 | case LKL_DEV_BLK_TYPE_FLUSH_OUT: 85 | err = host_syscall_SYS_fdatasync(disk.fd); 86 | break; 87 | default: 88 | return LKL_DEV_BLK_STATUS_UNSUP; 89 | } 90 | 91 | if (err < 0) 92 | return LKL_DEV_BLK_STATUS_IOERR; 93 | return LKL_DEV_BLK_STATUS_OK; 94 | } 95 | 96 | struct lkl_dev_blk_ops sgxlkl_dev_blk_ops = { 97 | .get_capacity = fd_get_capacity, 98 | .request = blk_request, 99 | }; 100 | 101 | -------------------------------------------------------------------------------- /src/lkl/disk_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | #include "lkl/disk.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "syscall.h" 10 | 11 | #include "sgx_enclave_config.h" 12 | 13 | extern size_t num_disks; 14 | extern struct enclave_disk_config *disks; 15 | 16 | static struct enclave_disk_config *get_disk_config(int fd) { 17 | for (int i = 0; i < num_disks; i++) { 18 | if (disks[i].fd == fd) 19 | return &disks[i]; 20 | } 21 | return NULL; 22 | } 23 | 24 | static int fd_get_capacity(struct lkl_disk disk, unsigned long long *res) { 25 | off_t off; 26 | 27 | struct enclave_disk_config *disk_config; 28 | if (disk_config = get_disk_config(disk.fd)) { 29 | *res = disk_config->capacity; 30 | return 0; 31 | } 32 | return -1; 33 | } 34 | 35 | // Reads and write requests sent to the following functions are always sector- 36 | // aligned (on 512 bytes). Unaligned requests are fixed by the virtio backend. 37 | 38 | static int do_read(struct lkl_disk disk, struct lkl_blk_req *req) { 39 | off_t off = req->sector * 512; 40 | struct enclave_disk_config *disk_config = get_disk_config(disk.fd); 41 | if (!disk_config) { 42 | errno = EINVAL; 43 | return -1; 44 | } 45 | for (int i = 0; i < req->count; i++) { 46 | char *addr = req->buf[i].iov_base; 47 | int len = req->buf[i].iov_len; 48 | memcpy(addr, &disk_config->mmap[off], len); 49 | } 50 | return 0; 51 | } 52 | 53 | static int do_write(struct lkl_disk disk, struct lkl_blk_req *req) { 54 | off_t off = req->sector * 512; 55 | struct enclave_disk_config *disk_config = get_disk_config(disk.fd); 56 | if (!disk_config) { 57 | errno = EINVAL; 58 | return -1; 59 | } 60 | for (int i = 0; i < req->count; i++) { 61 | char *addr = req->buf[i].iov_base; 62 | int len = req->buf[i].iov_len; 63 | memcpy(&disk_config->mmap[off], addr, len); 64 | } 65 | return 0; 66 | } 67 | 68 | static int blk_request(struct lkl_disk disk, struct lkl_blk_req *req) { 69 | int err = 0; 70 | struct enclave_disk_config *disk_config; 71 | switch (req->type) { 72 | case LKL_DEV_BLK_TYPE_READ: 73 | err = do_read(disk, req); 74 | break; 75 | case LKL_DEV_BLK_TYPE_WRITE: 76 | err = do_write(disk, req); 77 | break; 78 | case LKL_DEV_BLK_TYPE_FLUSH: 79 | case LKL_DEV_BLK_TYPE_FLUSH_OUT: 80 | disk_config = get_disk_config(disk.fd); 81 | if (disk_config) { 82 | void *addr = disk_config->mmap; 83 | size_t len = disk_config->capacity; 84 | err = host_syscall_SYS_msync(addr, len, MS_SYNC); 85 | } else 86 | err = -EINVAL; 87 | break; 88 | default: 89 | return LKL_DEV_BLK_STATUS_UNSUP; 90 | } 91 | 92 | if (err < 0) 93 | return LKL_DEV_BLK_STATUS_IOERR; 94 | return LKL_DEV_BLK_STATUS_OK; 95 | } 96 | 97 | struct lkl_dev_blk_ops sgxlkl_dev_blk_mem_ops = { 98 | .get_capacity = fd_get_capacity, 99 | .request = blk_request, 100 | }; 101 | 102 | -------------------------------------------------------------------------------- /src/lkl/jmp_buf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | void sgxlkl_jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void)) 9 | { 10 | if (!setjmp(*((jmp_buf *)jmpb->buf))) 11 | f(); 12 | } 13 | 14 | void sgxlkl_jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val) 15 | { 16 | longjmp(*((jmp_buf *)jmpb->buf), val); 17 | } 18 | -------------------------------------------------------------------------------- /src/lkl/ls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Debug helper function to list file system content 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | static void listdir(const char* path) { 10 | int err; 11 | struct lkl_dir *dir = lkl_opendir(path, &err); 12 | 13 | fprintf(stderr, "listdir(\"%s\")\n", path); 14 | if (dir == NULL || err != 0) { 15 | fprintf(stderr, "Error: unable to opendir(%s)\n", dir); 16 | exit(err == 0 ? 1 : err); 17 | } 18 | 19 | struct lkl_linux_dirent64 *dirent = NULL; 20 | while ((dirent = lkl_readdir(dir)) != NULL) { 21 | fprintf(stderr, "%s\n", dirent->d_name); 22 | } 23 | err = lkl_errdir(dir); 24 | if (err != 0) { 25 | fprintf(stderr, "Error: lkl_readdir(%s) = %d\n", dir, err); 26 | exit(err); 27 | } 28 | 29 | lkl_closedir(dir); 30 | } 31 | -------------------------------------------------------------------------------- /src/lkl/override/include/stdint.h: -------------------------------------------------------------------------------- 1 | #ifndef __LKL_STDINT_H__ 2 | #define __LKL_STDINT_H__ 3 | 4 | #include 5 | #include 6 | 7 | #define UINT8_C(c) c 8 | #define UINT16_C(c) c 9 | #define UINT32_C(c) c ## U 10 | #define UINT64_C(c) c ## UL 11 | #define UINT16_MAX U16_MAX 12 | #undef abs 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/lkl/pcap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "sgx_hostcalls.h" 8 | 9 | typedef struct __attribute__((packed)) pcap_hdr_s { 10 | uint32_t magic_number; /* magic number */ 11 | uint16_t version_major; /* major version number */ 12 | uint16_t version_minor; /* minor version number */ 13 | int32_t thiszone; /* GMT to local correction */ 14 | uint32_t sigfigs; /* accuracy of timestamps */ 15 | uint32_t snaplen; /* max length of captured packets, in octets */ 16 | uint32_t network; /* data link type */ 17 | } pcap_hdr_t; 18 | 19 | typedef struct __attribute__((packed)) pcaprec_hdr_s { 20 | uint32_t ts_sec; /* timestamp seconds */ 21 | uint32_t ts_usec; /* timestamp microseconds */ 22 | uint32_t incl_len; /* number of octets of packet saved in file */ 23 | uint32_t orig_len; /* actual length of packet */ 24 | } pcaprec_hdr_t; 25 | 26 | #ifdef DEBUG 27 | 28 | int write_pcap_filev(const char *filename, struct iovec *pkts, size_t len) { 29 | int snaplen = 0; 30 | int fd = host_syscall_SYS_open(filename, O_WRONLY | O_CREAT, 0); 31 | if (fd < 0) { 32 | return -errno; 33 | } 34 | 35 | for (int i = 0; i < len; i++) { 36 | snaplen += pkts[i].iov_len; 37 | } 38 | 39 | pcap_hdr_t pcap_hdr = {.magic_number = 0xa1b2c3d4, 40 | .version_major = 2, 41 | .version_minor = 4, 42 | .thiszone = 0, 43 | .sigfigs = 0, 44 | .snaplen = snaplen, 45 | .network = 1}; 46 | 47 | if (host_syscall_SYS_write(fd, &pcap_hdr, sizeof(pcap_hdr_t)) < 0) { 48 | host_syscall_SYS_close(fd); 49 | return -errno; 50 | }; 51 | 52 | for (int i = 0; i < len; i++) { 53 | struct iovec *pkt = &pkts[i]; 54 | pcaprec_hdr_t pcaprec_hdr = {.ts_sec = i, 55 | .ts_usec = 0, 56 | .incl_len = pkt->iov_len, 57 | .orig_len = pkt->iov_len}; 58 | struct iovec iov[2] = {{ 59 | .iov_base = &pcaprec_hdr, 60 | .iov_len = sizeof(pcaprec_hdr_t), 61 | }, 62 | { 63 | .iov_base = pkt->iov_base, 64 | .iov_len = pkt->iov_len, 65 | }}; 66 | if (host_syscall_SYS_writev(fd, iov, 3) < 0) { 67 | host_syscall_SYS_close(fd); 68 | return -errno; 69 | }; 70 | } 71 | 72 | return host_syscall_SYS_close(fd); 73 | } 74 | 75 | int write_pcap_file(const char *filename, void *pkt, size_t len) { 76 | struct iovec pkt_vec = { 77 | .iov_base = pkt, 78 | .iov_len = len, 79 | }; 80 | return write_pcap_filev(filename, &pkt_vec, 1); 81 | } 82 | 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/main/dpdk.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "dpdk.h" 12 | #include "dpdk_internal.h" 13 | 14 | static struct dpdk_context dpdk_context; 15 | 16 | int dpdk_initialize_iface(enclave_config_t* encl, const char *ifparams) 17 | { 18 | char poolname[RTE_MEMZONE_NAMESIZE]; 19 | 20 | if (!encl->num_dpdk_ifaces) { 21 | fprintf(stderr, "dpdk: no interface found, skip initialization\n"); 22 | return 0; 23 | } 24 | 25 | struct enclave_dpdk_config *iface = &encl->dpdk_ifaces[encl->num_dpdk_ifaces - 1]; 26 | iface->portid = encl->num_dpdk_ifaces - 1; 27 | 28 | snprintf(poolname, RTE_MEMZONE_NAMESIZE, "tx-%s", ifparams); 29 | iface->txpool = rte_mempool_lookup(poolname); 30 | if (!iface->txpool) { 31 | fprintf(stderr, "dpdk: failed to lookup tx pool: %s\n", poolname); 32 | return -ENOENT; 33 | } 34 | return 0; 35 | } 36 | 37 | struct dpdk_context *dpdk_initialize_context() 38 | { 39 | dpdk_context.devices = &rte_eth_devices; 40 | dpdk_context.config = rte_eal_get_configuration(); 41 | dpdk_context.lcore_config = &lcore_config; 42 | dpdk_context.internal_config = &internal_config; 43 | return &dpdk_context; 44 | } 45 | -------------------------------------------------------------------------------- /src/main/load_elf.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct encl_map_info { 4 | void* base; 5 | size_t size; 6 | void* entry_point; 7 | } encl_map_info; 8 | 9 | void load_elf(char* file_to_map, void *base_addr, encl_map_info* result); 10 | -------------------------------------------------------------------------------- /src/main/meminfo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | /* Parse the contents of /proc/meminfo (in buf), return value of "name" 10 | * (example: MemTotal) */ 11 | static long get_entry(const char* name, const char* buf) { 12 | char* hit = strstr(buf, name); 13 | if (hit == NULL) { 14 | return -1; 15 | } 16 | 17 | errno = 0; 18 | long val = strtol(hit + strlen(name), NULL, 10); 19 | if (errno != 0) { 20 | perror("get_entry: strtol() failed"); 21 | return -1; 22 | } 23 | return val; 24 | } 25 | 26 | int parse_hugetbl_size(size_t *hugetbl_size) { 27 | // we cannot get the size upfront. Let's hope this enough 28 | char buf[4096]; 29 | int r = 0; 30 | int fd = 0; 31 | struct stat stat_buf; 32 | 33 | r = open("/proc/meminfo", O_RDONLY); 34 | if (r < 0) { 35 | perror("parse_hugetbl_size(): open(\"/proc/meminfo\") failed"); 36 | goto cleanup; 37 | } 38 | fd = r; 39 | 40 | r = read(fd, buf, sizeof(buf)); 41 | if (r < 0) { 42 | perror("parse_hugetbl_size(): read(\"/proc/meminfo\") failed"); 43 | goto cleanup; 44 | } 45 | 46 | long size = get_entry("Hugetlb:", buf); 47 | if (size < 0) { 48 | fprintf(stderr, "%s() at %s:%d\n", __func__, __FILE__, __LINE__); 49 | return -ENOMEM; 50 | } 51 | // convert kb to bytes. 52 | *hugetbl_size = size * 1024; 53 | 54 | return 0; 55 | 56 | cleanup: 57 | if (fd) { 58 | close(fd); 59 | } 60 | return r; 61 | } 62 | -------------------------------------------------------------------------------- /src/main/meminfo.h: -------------------------------------------------------------------------------- 1 | #ifndef SGXLKL_MEMINFO_H 2 | #define SGXLKL_MEMINFO_H 3 | int parse_hugetbl_size(size_t *hugetbl_size); 4 | 5 | #endif /* SGXLKL_MEMINFO_H */ 6 | -------------------------------------------------------------------------------- /src/main/spdk_hugetbl.c: -------------------------------------------------------------------------------- 1 | #include "spdk_hugetbl.h" 2 | 3 | #include "meminfo.h" 4 | 5 | #include 6 | 7 | void spdk_free_dma_memory(struct spdk_dma_memory *ctx) { 8 | if (ctx->data_pool) { 9 | spdk_mempool_free(ctx->data_pool); 10 | ctx->data_pool = NULL; 11 | ctx->data_pool_size = 0; 12 | } 13 | for (size_t i = 0; i < ctx->nr_allocations; i++) { 14 | if (ctx->allocations[i]) { 15 | spdk_dma_free(ctx->allocations[i]); 16 | } 17 | } 18 | free(ctx->allocations); 19 | } 20 | 21 | int spdk_alloc_dma_memory(struct spdk_dma_memory *ctx) { 22 | size_t hugetbl_size = 0; 23 | const size_t gigabyte = 1024 * 1024 * 1024; 24 | int r = parse_hugetbl_size(&hugetbl_size); 25 | 26 | if (r < 0) { 27 | fprintf(stderr, "spdk: Could not get hugetbl information: %s\n", strerror(-r)); 28 | return r; 29 | } 30 | 31 | if (hugetbl_size < (2 * gigabyte)) { 32 | fprintf(stderr, "spdk: Less then two gigabyte hugetbl memory found!" 33 | " Allocate more by writing to /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\n"); 34 | return -ENOMEM; 35 | } 36 | 37 | ctx->data_pool_size = SPDK_QUEUE_DEPTH; 38 | ctx->data_pool = spdk_mempool_create("spdk-pool", 39 | ctx->data_pool_size, 40 | SPDK_DATA_POOL_MAX_SIZE, 41 | 0, 42 | SPDK_ENV_SOCKET_ID_ANY); 43 | if (!ctx->data_pool) { 44 | fprintf(stderr, "spdk: could not allocate data pool\n"); 45 | goto alloc_failed; 46 | } 47 | 48 | // leave two gigabyte for DPDK 49 | size_t gigabytes = (hugetbl_size - 4 * gigabyte) / gigabyte; 50 | 51 | void** allocations = calloc(gigabytes, sizeof(void*)); 52 | ctx->nr_allocations = gigabytes; 53 | ctx->allocations = allocations; 54 | 55 | for (size_t i = 0; i < gigabytes; i++) { 56 | // Allocations bigger then 1GB might fail. 57 | allocations[i] = spdk_dma_malloc(gigabyte, 0x1000, NULL); 58 | if (!allocations[i]) { 59 | fprintf(stderr, "spdk: could not allocate hugetable memory, only got %lu GB\n", i); 60 | goto alloc_failed; 61 | } 62 | } 63 | 64 | // useful to debug SPDK mappings 65 | //char buf[1024]; 66 | //const char* cmd_templ = "cat /proc/%d/maps > /tmp/proc-maps-final.log"; 67 | //snprintf(buf, sizeof(buf), cmd_templ, getpid()); 68 | //system(buf); 69 | //exit(1); 70 | 71 | return 0; 72 | 73 | alloc_failed: 74 | spdk_free_dma_memory(ctx); 75 | return -ENOMEM; 76 | } 77 | 78 | int dpdk_allocate_dma_memory(struct enclave_dpdk_dma_memory *mem) { 79 | // is 127 MB enough? 80 | const size_t size = 1 << 27; 81 | void *addr = spdk_dma_malloc(size, 0x1000, NULL); 82 | if (!addr) { 83 | return -ENOMEM; 84 | } 85 | mem->memory_start = addr; 86 | mem->memory_end = mem->memory_start + size; 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /src/main/spdk_hugetbl.h: -------------------------------------------------------------------------------- 1 | #ifndef SGXLKL_SPDK_HUGETBL_H 2 | #define SGXLKL_SPDK_HUGETBL_H 3 | 4 | #include 5 | #include 6 | 7 | // TODO seem to be the maximum size 8 | #define SPDK_DATA_POOL_MAX_SIZE (1048576 * 2) 9 | 10 | // define TODO get the queue depth from 11 | // spdk_nvme_ctrlr_get_default_io_qpair_opts 12 | // and using io_queue_size from spdk_nvme_io_qpair_opts 13 | #define SPDK_QUEUE_DEPTH 1023 14 | 15 | int spdk_alloc_dma_memory(struct spdk_dma_memory *ctx); 16 | void spdk_free_dma_memory(struct spdk_dma_memory *ctx); 17 | int dpdk_allocate_dma_memory(struct enclave_dpdk_dma_memory *mem); 18 | 19 | 20 | #endif /* SGXLKL_SPDK_HUGETBL_H */ 21 | -------------------------------------------------------------------------------- /src/sched/debug.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "linux/types.h" 3 | #include "sgx_enclave_config.h" 4 | 5 | #ifdef SGXLKL_HW 6 | static int check_address(uintptr_t addr) { 7 | uintptr_t start = get_enclave_parms()->base; 8 | uintptr_t end = start + get_enclave_parms()->heap_size; 9 | return addr >= start && addr < end; 10 | } 11 | 12 | // copy and paste example to persist the backtrace. 13 | //#define NR_CPUS 4 14 | //void* bt_per_cpu[NR_CPUS][4][10]; 15 | //static void save_backtrace(void **frame, void *bt_per_cpu[10]) { 16 | // size_t i; 17 | // for (i = 0; i < sizeof(*bt_per_cpu); i++) { 18 | // // Ensure that the current frame is safe to access. 19 | // if (!check_address((uintptr_t)frame)) 20 | // break; 21 | // 22 | // // Ensure that the return address is valid. 23 | // if (!check_address((uintptr_t)frame[1])) 24 | // break; 25 | // 26 | // bt_per_cpu[i] = frame[1]; 27 | // if (frame == *frame) { 28 | // break; 29 | // } 30 | // 31 | // // Store address and move to previous frame. 32 | // frame = (void**)*frame; 33 | // 34 | // if ((uintptr_t)frame < 0x1000) { 35 | // break; 36 | // } 37 | // } 38 | //} 39 | 40 | void lthread_print_backtrace(void) { 41 | void **frame = __builtin_frame_address(0); 42 | for (;;) { 43 | // Ensure that the current frame is safe to access. 44 | if (!frame || !check_address((uintptr_t)frame)) 45 | break; 46 | 47 | // Ensure that the return address is valid. 48 | if (!frame[1] || !check_address((uintptr_t)frame[1])) 49 | break; 50 | printf("%p ", frame[1]); 51 | if (frame == *frame) { 52 | break; 53 | } 54 | 55 | // Store address and move to previous frame. 56 | frame = (void**)*frame; 57 | 58 | // sgx-lkl also maps the first page, which cannot be accessed. 59 | if ((uintptr_t)frame < 0x1000) { 60 | break; 61 | } 62 | } 63 | puts("\n"); 64 | } 65 | #else 66 | void lthread_print_backtrace(void) {} 67 | #endif 68 | -------------------------------------------------------------------------------- /src/sgx-lkl-userpci/dpdk.h: -------------------------------------------------------------------------------- 1 | #ifndef DPDK_USERPCI_DPDK 2 | #include 3 | 4 | int setup_iface(int portid, size_t mtu, size_t queues); 5 | #endif DPDK_USERPCI_DPDK 6 | 7 | -------------------------------------------------------------------------------- /src/sgx-lkl-userpci/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "dpdk.h" 12 | #include "spdk_context.h" 13 | 14 | int main(int argc, char **argv) { 15 | if (argc < 3) { 16 | fprintf(stderr, "USAGE: %s ready-fd finished-fd uid\n", argv[0]); 17 | return 1; 18 | } 19 | int ready_fd = atoi(argv[1]); 20 | int finished_fd = atoi(argv[2]); 21 | int uid = atoi(argv[3]); 22 | int exitcode = 0; 23 | char *mtustr = getenv("SGXLKL_DPDK_MTU"); 24 | char *queues_str = getenv("SGXLKL_DPDK_RX_QUEUES"); 25 | int mtu = 1500; 26 | size_t rx_queues = 1; 27 | 28 | if (mtustr) { 29 | mtu = atoi(mtustr); 30 | } 31 | if (queues_str) { 32 | rx_queues = atoi(queues_str); 33 | } 34 | 35 | // create files with world-writeable permissions (i.e. in /dev/hugepages) 36 | umask(0); 37 | 38 | // use stderr for logging 39 | rte_openlog_stream(stderr); 40 | 41 | struct spdk_context ctx = {}; 42 | if (spdk_initialize(&ctx, true) < 0) { 43 | goto error; 44 | }; 45 | 46 | size_t port_num = rte_eth_dev_count_avail(); 47 | for (int portid = 0; portid < port_num; portid++) { 48 | int r = setup_iface(portid, mtu, rx_queues); 49 | if (r < 0) { 50 | goto error; 51 | } 52 | } 53 | 54 | const static char* ready_msg = "OK"; 55 | int r = write(ready_fd, ready_msg, strlen(ready_msg) + 1); 56 | if (r < 0) { 57 | fprintf(stderr, "%s: failed to write to ready pipe: %s\n", argv[0], strerror(r)); 58 | goto error; 59 | } 60 | close(ready_fd); 61 | 62 | // child will eventually close this 63 | char byte; 64 | r = read(finished_fd, &byte, 1); 65 | if (r >= 0) { 66 | fprintf(stderr, "%s: Got unexpected data result on finished pipe: %d\n", argv[0], r); 67 | goto error; 68 | } 69 | goto cleanup; 70 | 71 | error: 72 | close(ready_fd); 73 | exitcode = 1; 74 | cleanup: 75 | spdk_context_detach(&ctx); 76 | spdk_context_free(&ctx); 77 | close(finished_fd); 78 | fprintf(stderr, "%s: stop setuid-helper\n", argv[0]); 79 | return exitcode; 80 | } 81 | -------------------------------------------------------------------------------- /src/sgx-lkl-virt2phy/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define PFN_MASK_SIZE 8 10 | 11 | void *virt2phy(int fd, const void *virtaddr) { 12 | int page_size = getpagesize(); 13 | unsigned long virt_pfn = (unsigned long)virtaddr / page_size; 14 | off_t offset = sizeof(uint64_t) * virt_pfn; 15 | if (lseek(fd, offset, SEEK_SET) == (off_t) -1) { 16 | fprintf(stderr, "%s(): seek error in /proc/self/pagemap: %s\n", 17 | __func__, strerror(errno)); 18 | return NULL; 19 | } 20 | 21 | uint64_t page; 22 | int retval = read(fd, &page, PFN_MASK_SIZE); 23 | if (retval < 0) { 24 | fprintf(stderr, "%s(): cannot read /proc/self/pagemap: %s\n", 25 | __func__, strerror(errno)); 26 | return NULL; 27 | } else if (retval != PFN_MASK_SIZE) { 28 | fprintf(stderr, "%s(): read %d bytes from /proc/self/pagemap " 29 | "but expected %d:\n", 30 | __func__, retval, PFN_MASK_SIZE); 31 | return NULL; 32 | } 33 | 34 | /* 35 | * the pfn (page frame number) are bits 0-54 (see 36 | * pagemap.txt in linux Documentation) 37 | */ 38 | if ((page & 0x7fffffffffffffULL) == 0) 39 | return NULL; 40 | 41 | uint64_t physaddr = ((page & 0x7fffffffffffffULL) * page_size) 42 | + ((unsigned long)virtaddr % page_size); 43 | return (void*)physaddr; 44 | } 45 | 46 | int main(int argc, char** argv) { 47 | int fd; 48 | int page_size; 49 | 50 | if (argc < 2) { 51 | fprintf(stderr, "USAGE: %s PID\n", argv[0]); 52 | return 1; 53 | } 54 | 55 | unsigned long pid = strtoul(argv[1], NULL, 0); 56 | 57 | char buf[256]; 58 | int n = snprintf(buf, sizeof(buf), "/proc/%lu/pagemap", pid); 59 | 60 | if (n > sizeof(buf)) { 61 | fprintf(stderr, "%s(): buf too small\n", __func__); 62 | return 1; 63 | } 64 | 65 | fd = open(buf, O_RDONLY); 66 | if (fd < 0) { 67 | fprintf(stderr, "%s(): cannot open %s: %s\n", __func__, buf, strerror(errno)); 68 | return 1; 69 | } 70 | 71 | char * line = NULL; 72 | size_t len = 0; 73 | ssize_t read; 74 | 75 | while ((read = getline(&line, &len, stdin)) != -1) { 76 | const void *virtaddr = (void *)strtoul(line, NULL, 0); 77 | void *phyaddr = virt2phy(fd, virtaddr); 78 | if (!phyaddr) { 79 | close(fd); 80 | return 1; 81 | } 82 | printf("%ld\n", (uint64_t)phyaddr); 83 | fflush(stdout); 84 | } 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /src/sgx/gdb_hook.c: -------------------------------------------------------------------------------- 1 | void __gdb_hook_init_done() {__asm__ volatile("nop");} 2 | -------------------------------------------------------------------------------- /src/sgx/include/libsgx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #ifndef LIBSGX_H 6 | #define LIBSGX_H 7 | #include 8 | #include "sgx.h" 9 | 10 | #define PAGE_READ 0x1 11 | #define PAGE_WRITE 0x2 12 | #define PAGE_EXEC 0x4 13 | #define PAGE_TCS 0x8 14 | #define PAGE_NOEXTEND 0x10 15 | 16 | #define ECREATE_NO_FIXED_ADDR (void*)-1 17 | 18 | /* Initialize libsgx */ 19 | int init_sgx(); 20 | /* Free EPC pages */ 21 | void destroy_enclave(); 22 | void execute_instructions(); 23 | 24 | /* SGX instructions wrappers */ 25 | uint64_t ecreate(size_t npages, int ssaSize, const void* sigstruct, void* baseaddr); 26 | int einit(uintptr_t base, void* sigstruct); 27 | void eenter(uint64_t tcs, uint64_t* rdi, uint64_t* rsi); 28 | void eresume(uint64_t tcs_id); 29 | int add_page(uint64_t base, uint64_t offset, uint64_t prot, const void* page); 30 | 31 | /* High-level API */ 32 | void enclave_sign(char* path, char* key, size_t heap, size_t stack, int tcs, int heap_first); 33 | uint64_t create_enclave_mem(char* p, int base_zero, void *base_zero_max, int map_heap_first); 34 | void enter_enclave(int tcs_id, uint64_t call_id, void* arg, uint64_t* ret); 35 | int get_free_tcs_id(); 36 | int get_tcs_num(); 37 | #endif 38 | -------------------------------------------------------------------------------- /src/sgx/libs/lible.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mic92/rkt-io/07f54d750a86cbb4302025b42c525911c2191729/src/sgx/libs/lible.a -------------------------------------------------------------------------------- /src/sgx/libs/lible.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mic92/rkt-io/07f54d750a86cbb4302025b42c525911c2191729/src/sgx/libs/lible.o -------------------------------------------------------------------------------- /src/sgx/proto/sgxlkl_ctl.proto: -------------------------------------------------------------------------------- 1 | package sgxlkl; 2 | 3 | enum Error { 4 | SUCCESS = 0; 5 | INVALID_ARGUMENT = 1; 6 | INTERNAL = 3; /* Internal server error */ 7 | NOT_PERMITTED = 4; /* Command not permitted, e.g. because the server binds to an untrusted interface/is configured to only respond to attestation requests. */ 8 | SIM_MODE = 5; /* Not running in SGX hardware mode */ 9 | REP_NOT_AVAILABLE = 6; /* Quote and attestation report are not available */ 10 | APP_RUNNING = 7; /* Application is already running */ 11 | PARSE = 8; /* Error parsing a configuration string */ 12 | } 13 | 14 | /* Requests the enclave quote and potentially an IAS attestation verification 15 | * report. The IAS report is only available when sgx-lkl-run is run with the 16 | * corresponding SGXLKL_IAS_* configuration options to obtain an IAS report. 17 | */ 18 | message AttestRequest {} 19 | 20 | /* Possible errors: 21 | * SIM_MODE: SGX-LKL is run in simulation mode and can't generate an 22 | * enclave report. 23 | * REP_NOT_AVAILABLE: No enclave report/quote available. 24 | */ 25 | message AttestResult { 26 | required Error err = 1; 27 | required bytes quote = 2; 28 | required bytes ias_report = 3; 29 | required bytes ias_sign_ca_cert = 4; 30 | required bytes ias_sign_cert = 5; 31 | required bytes ias_report_signature = 6; 32 | } 33 | 34 | 35 | /* Requests SGX-LKL to run an executable. The path to the executable, 36 | * application arguments, and environment variables are specified as part of a 37 | * JSON application configuration. The configuration can also include disk 38 | * encryption keys and root hashes if required. 39 | */ 40 | message RunRequest { 41 | required string json_config = 1; 42 | } 43 | 44 | /* Possible errors: 45 | * NOT_PERMITTED: This request is not permitted as this is an attest-only 46 | * endpoint. 47 | * APP_RUNNING: An application is already running. 48 | * INTERNAL: Internal server error. 49 | * PARSE: The provided JSON configuration could not be parsed 50 | * correctly. 51 | */ 52 | message RunResult { 53 | required Error err = 1; 54 | optional string err_msg = 2; 55 | } 56 | 57 | 58 | message Peer { 59 | required string key = 1; 60 | required string allowed_ips = 2; 61 | required string endpoint = 3; 62 | } 63 | 64 | /* Request a new Wireguard peer to be added. */ 65 | message AddPeersRequest { 66 | repeated Peer peers = 1; 67 | } 68 | 69 | /* Possible errors: 70 | * NOT_PERMITTED: This request is not permitted as this is an attest-only 71 | * endpoint. 72 | * INTERNAL: Internal server error. 73 | */ 74 | message AddPeersResult { 75 | required Error err = 1; 76 | optional string err_msg = 2; 77 | } 78 | 79 | /* Remote control service of an SGX-LKL instance. */ 80 | service Control { 81 | rpc Run (RunRequest) returns (RunResult); 82 | rpc Attest (AttestRequest) returns (AttestResult); 83 | rpc AddPeers (AddPeersRequest) returns (AddPeersResult); 84 | } 85 | -------------------------------------------------------------------------------- /src/sgx/sgx_enclave_report.c: -------------------------------------------------------------------------------- 1 | #ifdef SGXLKL_HW 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include // ROUND_TO macro 10 | #include 11 | 12 | #include "sgx_enclave_config.h" 13 | #include "sgxlkl_util.h" 14 | 15 | void enclave_report( 16 | sgx_target_info_t* target_info, 17 | sgx_report_data_t* report_data, 18 | sgx_report_t* report 19 | ) 20 | { 21 | assert(target_info != NULL); 22 | assert(report_data != NULL); 23 | assert(report != NULL); 24 | 25 | /* This code is adapted from SDK's sgx_create_report() in 26 | * sgx_create_report.cpp */ 27 | size_t size = ROUND_TO(sizeof(sgx_target_info_t), TARGET_INFO_ALIGN_SIZE) + 28 | ROUND_TO(sizeof(sgx_report_data_t), REPORT_DATA_ALIGN_SIZE) + 29 | ROUND_TO(sizeof(sgx_report_t), REPORT_ALIGN_SIZE); 30 | size += MAX(MAX(TARGET_INFO_ALIGN_SIZE, REPORT_DATA_ALIGN_SIZE), REPORT_ALIGN_SIZE) - 1; 31 | 32 | void *buffer = malloc(size); 33 | if (!buffer) 34 | sgxlkl_fail("Unable to allocate memory for enclave report.\n"); 35 | 36 | memset(buffer, 0, size); 37 | size_t buf_ptr = (size_t) (buffer); 38 | 39 | buf_ptr = ROUND_TO(buf_ptr, REPORT_ALIGN_SIZE); 40 | sgx_report_t *tmp_report = (sgx_report_t*) (buf_ptr); 41 | buf_ptr += sizeof(*tmp_report); 42 | 43 | buf_ptr = ROUND_TO(buf_ptr, TARGET_INFO_ALIGN_SIZE); 44 | sgx_target_info_t *tmp_target_info = (sgx_target_info_t*) (buf_ptr); 45 | buf_ptr += sizeof(*tmp_target_info); 46 | 47 | buf_ptr = ROUND_TO(buf_ptr, REPORT_DATA_ALIGN_SIZE); 48 | sgx_report_data_t *tmp_report_data = (sgx_report_data_t*) (buf_ptr); 49 | 50 | // Copy data from user buffer to the aligned memory 51 | memcpy_s(tmp_target_info, sizeof(*tmp_target_info), target_info, sizeof(*target_info)); 52 | memcpy_s(tmp_report_data, sizeof(*tmp_report_data), report_data, sizeof(*report_data)); 53 | 54 | ereport((void *)tmp_target_info, (char *)tmp_report_data, (char *)tmp_report); 55 | memcpy_s(report, sizeof(*report), tmp_report, sizeof(*tmp_report)); 56 | 57 | free(buffer); 58 | } 59 | 60 | #endif /* SGXLKL_HW */ 61 | -------------------------------------------------------------------------------- /src/sgx/sgxlkl_sign.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, 2017, 2018 Imperial College London 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "sgxlkl_sign_cmdline.h" 10 | #include "libsgx.h" 11 | 12 | #define DIV_ROUNDUP(x, y) (((x)+((y)-1))/(y)) 13 | 14 | int main(int argc, char** argv) { 15 | struct gengetopt_args_info args_info; 16 | if (cmdline_parser (argc, argv, &args_info) != 0) 17 | exit(1); 18 | 19 | long heapsize = args_info.heapsize_arg; 20 | long stacksize = DIV_ROUNDUP(args_info.stacksize_arg, sysconf(_SC_PAGESIZE)); 21 | long threads = args_info.threads_arg; 22 | char* key = args_info.key_arg; 23 | char* libpath = args_info.file_arg; 24 | int support_non_pie = args_info.support_non_pie_arg; 25 | 26 | enclave_sign(libpath, key, heapsize, stacksize, threads, support_non_pie); 27 | cmdline_parser_free(&args_info); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /src/spdk/override/config.mk: -------------------------------------------------------------------------------- 1 | CONFIG_PREFIX="${PREFIX}" 2 | CONFIG_DEBUG=n 3 | CONFIG_LOG_BACKTRACE=n 4 | CONFIG_WERROR=n 5 | CONFIG_LTO=n 6 | CONFIG_PGO_CAPTURE=n 7 | CONFIG_PGO_USE=n 8 | CONFIG_COVERAGE=n 9 | CONFIG_ASAN=n 10 | CONFIG_UBSAN=n 11 | CONFIG_TSAN=n 12 | CONFIG_TESTS=n 13 | CONFIG_ENV=$(SPDK_ROOT_DIR)/lib/env_dpdk 14 | CONFIG_DPDK_DIR=$(SPDK_ROOT_DIR)/../build/dpdk-native 15 | CONFIG_FIO_PLUGIN=n 16 | CONFIG_FIO_SOURCE_DIR= 17 | CONFIG_RDMA=n 18 | CONFIG_RDMA_SEND_WITH_INVAL=n 19 | CONFIG_RBD=n 20 | CONFIG_VIRTIO=y 21 | CONFIG_PMDK=n 22 | CONFIG_PMDK_DIR= 23 | CONFIG_REDUCE=n 24 | CONFIG_VPP=n 25 | CONFIG_VPP_DIR= 26 | CONFIG_ISCSI_INITIATOR=n 27 | CONFIG_CRYPTO=n 28 | CONFIG_SHARED=n 29 | CONFIG_VTUNE=n 30 | CONFIG_VTUNE_DIR= 31 | CONFIG_IGB_UIO_DRIVER=n 32 | CONFIG_FTL=n 33 | CONFIG_IPSEC_MB=n 34 | CONFIG_OCF=n 35 | CONFIG_OCF_PATH= 36 | CONFIG_CUSTOMOCF=n 37 | CONFIG_ISAL=n 38 | CONFIG_AIO=n 39 | CONFIG_EXAMPLES=n 40 | CONFIG_APP=n 41 | -------------------------------------------------------------------------------- /third_party/linux-sgx/README.md: -------------------------------------------------------------------------------- 1 | Header files required for communication with AESMD and report generation/attestation. Taken from https://github.com/intel/linux-sgx, tag sgx_2.0. 2 | -------------------------------------------------------------------------------- /third_party/linux-sgx/common/inc/internal/inst.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2017 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SE_ARCH_H_ 33 | # error "never include inst.h directly; use arch.h instead." 34 | #endif 35 | 36 | 37 | #ifndef _SE_INST_H_ 38 | #define _SE_INST_H_ 39 | 40 | #define ENCLU 0xd7010f 41 | 42 | typedef enum { 43 | SE_EREPORT = 0x0, 44 | SE_EGETKEY, 45 | SE_EENTER, 46 | SE_ERESUME, 47 | SE_EEXIT, 48 | SE_EACCEPT, 49 | SE_LAST_RING3, 50 | 51 | SE_ECREATE = 0x0, 52 | SE_EADD, 53 | SE_EINIT, 54 | SE_EREMOVE, 55 | SE_EDBGRD, 56 | SE_EDBGWR, 57 | SE_EEXTEND, 58 | SE_LAST_RING0 59 | } se_opcode_t; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /third_party/linux-sgx/common/inc/internal/se_memcpy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2017 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SE_MEMCPY_H_ 33 | #define _SE_MEMCPY_H_ 34 | 35 | #include 36 | 37 | 38 | /* memcpy_s always return 0 under Linux */ 39 | 40 | #ifndef _ERRNO_T_DEFINED 41 | #define _ERRNO_T_DEFINED 42 | typedef int errno_t; 43 | #endif 44 | 45 | static inline errno_t memcpy_s(void *dest, size_t numberOfElements, const void *src, size_t count) 46 | { 47 | if(numberOfElements 54 | #include 55 | 56 | #ifndef TRUE 57 | #define TRUE 1 58 | #endif 59 | 60 | #ifndef FALSE 61 | #define FALSE 0 62 | #endif 63 | 64 | #endif 65 | 66 | #if defined(SE_64) 67 | 68 | #define PADDED_POINTER(t, p) t* p 69 | #define PADDED_DWORD(d) uint64_t d 70 | #define PADDED_LONG(l) int64_t l 71 | #define REG(name) r##name 72 | #ifdef SE_SIM_EXCEPTION 73 | #define REG_ALIAS(name) R##name 74 | #endif 75 | #define REGISTER(name) uint64_t REG(name) 76 | 77 | #else /* !defined(SE_64) */ 78 | 79 | #define PADDED_POINTER(t, p) t* p; void* ___##p##_pad_to64_bit 80 | #define PADDED_DWORD(d) uint32_t d; uint32_t ___##d##_pad_to64_bit 81 | #define PADDED_LONG(l) int32_t l; int32_t ___##l##_pad_to64_bit 82 | 83 | #define REG(name) e##name 84 | 85 | #ifdef SE_SIM_EXCEPTION 86 | #define REG_ALIAS(name) E##name 87 | #endif 88 | 89 | #define REGISTER(name) uint32_t REG(name); uint32_t ___##e##name##_pad_to64_bit 90 | 91 | #endif /* !defined(SE_64) */ 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /third_party/linux-sgx/common/inc/internal/trts_inst.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2017 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _TRTS_INST_H_ 33 | #define _TRTS_INST_H_ 34 | 35 | #include "sgx.h" 36 | #include "arch.h" 37 | 38 | /* Attention: 39 | * if the following alignment requirement changes, go to selib to 40 | * review the memory allocation of sgx_create_report and sgx_get_key. 41 | */ 42 | #define TARGET_INFO_ALIGN_SIZE 512 43 | #define REPORT_DATA_ALIGN_SIZE 128 44 | #define REPORT_ALIGN_SIZE 512 45 | #define KEY_REQUEST_ALIGN_SIZE 512 46 | #define KEY_ALIGN_SIZE 16 47 | 48 | #define BIT_ERROR(x) (1 << (x)) 49 | 50 | typedef enum _egetkey_status_t 51 | { 52 | EGETKEY_SUCCESS = 0, 53 | EGETKEY_INVALID_ATTRIBUTE = BIT_ERROR(1), 54 | EGETKEY_INVALID_CPUSVN = BIT_ERROR(5), 55 | EGETKEY_INVALID_ISVSVN = BIT_ERROR(6), 56 | EGETKEY_INVALID_KEYNAME = BIT_ERROR(8), 57 | } egetkey_status_t; 58 | 59 | struct ms_tcs 60 | { 61 | void * ptcs; 62 | }; 63 | 64 | #ifdef __cplusplus 65 | extern "C" { 66 | #endif 67 | 68 | int sgx_accept_forward(si_flags_t sfl, size_t lo, size_t hi); 69 | void do_ereport(const sgx_target_info_t *target_info, const sgx_report_data_t *report_data, sgx_report_t *report); 70 | int do_egetkey(const sgx_key_request_t *key_request, sgx_key_128bit_t *key); 71 | uint32_t do_rdrand(uint32_t *rand); 72 | int do_eaccept(const sec_info_t *, size_t); 73 | int do_emodpe(const sec_info_t*, size_t); 74 | int apply_EPC_pages(void *start_address, size_t page_number); 75 | int apply_pages_within_exception(void *start_address, size_t page_count); 76 | int trim_EPC_pages(void *start_address, size_t page_number); 77 | sgx_status_t SGXAPI sgx_trts_mprotect(size_t start, size_t size, uint64_t perms); 78 | sgx_status_t do_add_thread(void *ms); 79 | int is_dynamic_thread(void *tcs); 80 | uint32_t get_dynamic_stack_max_page(void); 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /third_party/linux-sgx/common/inc/sgx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2017 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SGX_H_ 33 | #define _SGX_H_ 34 | 35 | #include "sgx_error.h" 36 | #include "sgx_attributes.h" 37 | #include "sgx_key.h" 38 | #include "sgx_report.h" 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /third_party/linux-sgx/common/inc/sgx_defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2017 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SGX_DEFS_H_ 33 | #define _SGX_DEFS_H_ 34 | 35 | /* The following macros are for GCC only */ 36 | 37 | # define SGXAPI 38 | 39 | # ifdef linux 40 | # undef linux 41 | # endif 42 | # define SGX_CXX_NATIVE_HEADER(header) 43 | 44 | # define SGX_CDECL 45 | # define SGX_STDCALL 46 | # define SGX_FASTCALL 47 | 48 | # define SGX_DLLIMPORT 49 | # define SGX_UBRIDGE(attr, fname, args...) attr fname args 50 | 51 | # define SGX_DEPRECATED __attribute__((deprecated)) 52 | 53 | 54 | #define SGX_NOCONVENTION /* Empty. No calling convention specified. */ 55 | 56 | #endif /* !_SGX_DEFS_H_ */ 57 | -------------------------------------------------------------------------------- /third_party/linux-sgx/common/inc/sgx_eid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2017 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SGX_EID_H_ 33 | #define _SGX_EID_H_ 34 | 35 | #include 36 | 37 | typedef uint64_t sgx_enclave_id_t; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /third_party/linux-sgx/common/inc/sgx_urts.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2017 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | 33 | 34 | #ifndef _SGX_URTS_H_ 35 | #define _SGX_URTS_H_ 36 | 37 | #include "sgx_attributes.h" 38 | #include "sgx_error.h" 39 | #include "sgx_eid.h" 40 | #include "sgx_defs.h" 41 | #include "sgx_key.h" 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | typedef uint8_t sgx_launch_token_t[1024]; 48 | 49 | /* Convenient macro to be passed to sgx_create_enclave(). */ 50 | #if !defined(NDEBUG) || defined(EDEBUG) 51 | #define SGX_DEBUG_FLAG ((int)1) 52 | #else 53 | #define SGX_DEBUG_FLAG ((int)0) 54 | #endif 55 | 56 | sgx_status_t SGXAPI sgx_create_enclave(const char *file_name, const int debug, sgx_launch_token_t *launch_token, int *launch_token_updated, sgx_enclave_id_t *enclave_id, sgx_misc_attribute_t *misc_attr); 57 | 58 | sgx_status_t SGXAPI sgx_destroy_enclave(const sgx_enclave_id_t enclave_id); 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /third_party/mbedtls/include/mbedtls/net.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file net.h 3 | * 4 | * \brief Deprecated header file that includes net_sockets.h 5 | * 6 | * \deprecated Superseded by mbedtls/net_sockets.h 7 | */ 8 | /* 9 | * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 13 | * not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * 24 | * This file is part of mbed TLS (https://tls.mbed.org) 25 | */ 26 | 27 | #if !defined(MBEDTLS_DEPRECATED_REMOVED) 28 | #include "net_sockets.h" 29 | #if defined(MBEDTLS_DEPRECATED_WARNING) 30 | #warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" 31 | #endif /* MBEDTLS_DEPRECATED_WARNING */ 32 | #endif /* !MBEDTLS_DEPRECATED_REMOVED */ 33 | -------------------------------------------------------------------------------- /third_party/mbedtls/include/mbedtls/platform_time.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file platform_time.h 3 | * 4 | * \brief mbed TLS Platform time abstraction 5 | */ 6 | /* 7 | * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved 8 | * SPDX-License-Identifier: Apache-2.0 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 11 | * not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 18 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | * 22 | * This file is part of mbed TLS (https://tls.mbed.org) 23 | */ 24 | #ifndef MBEDTLS_PLATFORM_TIME_H 25 | #define MBEDTLS_PLATFORM_TIME_H 26 | 27 | #if !defined(MBEDTLS_CONFIG_FILE) 28 | #include "config.h" 29 | #else 30 | #include MBEDTLS_CONFIG_FILE 31 | #endif 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /** 38 | * \name SECTION: Module settings 39 | * 40 | * The configuration options you can set for this module are in this section. 41 | * Either change them in config.h or define them on the compiler command line. 42 | * \{ 43 | */ 44 | 45 | /* 46 | * The time_t datatype 47 | */ 48 | #if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) 49 | typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; 50 | #else 51 | /* For time_t */ 52 | #include 53 | typedef time_t mbedtls_time_t; 54 | #endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ 55 | 56 | /* 57 | * The function pointers for time 58 | */ 59 | #if defined(MBEDTLS_PLATFORM_TIME_ALT) 60 | extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); 61 | 62 | /** 63 | * \brief Set your own time function pointer 64 | * 65 | * \param time_func the time function implementation 66 | * 67 | * \return 0 68 | */ 69 | int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); 70 | #else 71 | #if defined(MBEDTLS_PLATFORM_TIME_MACRO) 72 | #define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO 73 | #else 74 | #define mbedtls_time time 75 | #endif /* MBEDTLS_PLATFORM_TIME_MACRO */ 76 | #endif /* MBEDTLS_PLATFORM_TIME_ALT */ 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif /* platform_time.h */ 83 | -------------------------------------------------------------------------------- /third_party/protobufc.patch: -------------------------------------------------------------------------------- 1 | diff -urN protobuf-c-old/configure protobuf-c/configure 2 | --- protobuf-c-old/configure 2018-08-14 05:25:28.000000000 +0100 3 | +++ protobuf-c/configure 2019-03-21 16:45:19.674033764 +0000 4 | @@ -17613,26 +17613,6 @@ 5 | proto3_supported=yes 6 | fi 7 | 8 | - save_CPPFLAGS="$CPPFLAGS" 9 | - CPPFLAGS="$save_CPPFLAGS $protobuf_CFLAGS" 10 | - 11 | -for ac_header in google/protobuf/compiler/command_line_interface.h 12 | -do : 13 | - ac_fn_cxx_check_header_mongrel "$LINENO" "google/protobuf/compiler/command_line_interface.h" "ac_cv_header_google_protobuf_compiler_command_line_interface_h" "$ac_includes_default" 14 | -if test "x$ac_cv_header_google_protobuf_compiler_command_line_interface_h" = xyes; then : 15 | - cat >>confdefs.h <<_ACEOF 16 | -#define HAVE_GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H 1 17 | -_ACEOF 18 | - 19 | -else 20 | - as_fn_error $? "required protobuf header file not found" "$LINENO" 5 21 | -fi 22 | - 23 | -done 24 | - 25 | - CPPFLAGS="$save_CPPFLAGS" 26 | - 27 | - 28 | # Extract the first word of "protoc", so it can be a program name with args. 29 | set dummy protoc; ac_word=$2 30 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 31 | diff -urN protobuf-c-old/configure.ac protobuf-c/configure.ac 32 | --- protobuf-c-old/configure.ac 2018-08-14 05:24:20.000000000 +0100 33 | +++ protobuf-c/configure.ac 2019-03-21 16:35:43.172970003 +0000 34 | @@ -83,13 +83,6 @@ 35 | [PKG_CHECK_MODULES([protobuf], [protobuf >= 2.6.0])] 36 | ) 37 | 38 | - save_CPPFLAGS="$CPPFLAGS" 39 | - CPPFLAGS="$save_CPPFLAGS $protobuf_CFLAGS" 40 | - AC_CHECK_HEADERS([google/protobuf/compiler/command_line_interface.h], 41 | - [], 42 | - [AC_MSG_ERROR([required protobuf header file not found])]) 43 | - CPPFLAGS="$save_CPPFLAGS" 44 | - 45 | AC_ARG_VAR([PROTOC], [protobuf compiler command]) 46 | AC_PATH_PROG([PROTOC], [protoc], [], 47 | [`$PKG_CONFIG --variable=exec_prefix protobuf`/bin:$PATH]) 48 | diff -urN protobuf-c-old/Makefile.am protobuf-c/Makefile.am 49 | --- protobuf-c-old/Makefile.am 2018-08-14 03:11:41.000000000 +0100 50 | +++ protobuf-c/Makefile.am 2019-03-21 16:35:14.833310969 +0000 51 | @@ -98,8 +98,7 @@ 52 | protoc-c/c_service.cc \ 53 | protoc-c/c_service.h \ 54 | protoc-c/c_string_field.cc \ 55 | - protoc-c/c_string_field.h \ 56 | - protoc-c/main.cc 57 | + protoc-c/c_string_field.h 58 | protoc_c_protoc_gen_c_CXXFLAGS = \ 59 | $(AM_CXXFLAGS) \ 60 | $(protobuf_CFLAGS) 61 | diff -urN protobuf-c-old/protoc-c/main.cc protobuf-c/protoc-c/main.cc 62 | --- protobuf-c-old/protoc-c/main.cc 2017-08-05 22:43:57.000000000 +0100 63 | +++ protobuf-c/protoc-c/main.cc 1970-01-01 01:00:00.000000000 +0100 64 | @@ -1,22 +0,0 @@ 65 | -#include 66 | - 67 | -#include 68 | -#include 69 | -#include 70 | - 71 | -int main(int argc, char* argv[]) { 72 | - google::protobuf::compiler::c::CGenerator c_generator; 73 | - 74 | - std::string invocation_name = argv[0]; 75 | - std::string invocation_basename = invocation_name.substr(invocation_name.find_last_of("/") + 1); 76 | - const std::string legacy_name = "protoc-c"; 77 | - 78 | - if (invocation_basename == legacy_name) { 79 | - google::protobuf::compiler::CommandLineInterface cli; 80 | - cli.RegisterGenerator("--c_out", &c_generator, "Generate C/H files."); 81 | - cli.SetVersionInfo(PACKAGE_STRING); 82 | - return cli.Run(argc, argv); 83 | - } 84 | - 85 | - return google::protobuf::compiler::PluginMain(argc, argv, &c_generator); 86 | -} 87 | -------------------------------------------------------------------------------- /tools/check-hugepages-allocations.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import os 5 | 6 | 7 | def check_hugepages_are_continous(path: str) -> None: 8 | previous = None 9 | previous_cols = None 10 | gaps = 0 11 | with open(path) as f: 12 | buf = f.read() 13 | lines = buf.split("\n") 14 | for line in lines: 15 | columns = line.split() 16 | if len(columns) < 6: 17 | continue 18 | if columns[5].startswith("/dev/hugepages"): 19 | lower, upper = columns[0].split("-") 20 | if previous is not None: 21 | if lower != previous: 22 | print(f"The following two allocations have a gap: {previous_cols[5]} <-> {columns[5]}!") 23 | gaps += 1 24 | previous = upper 25 | previous_cols = columns 26 | #print(columns[0]) 27 | if gaps == 0: 28 | print("No gaps found") 29 | 30 | def main(): 31 | if len(sys.argv) < 2: 32 | print("USAGE: PID_OR_MAPS_FILE", file=sys.stderr) 33 | sys.exit(1) 34 | if os.path.exists(sys.argv[1]): 35 | path = sys.argv[1] 36 | else: 37 | path = int(sys.argv[1]) 38 | check_hugepages_are_continous(path) 39 | 40 | 41 | if __name__ == "__main__": 42 | main() 43 | -------------------------------------------------------------------------------- /tools/find-gcc-headers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | headerfile=$(echo "#include " | \ 5 | ${CPP:-cpp} - | \ 6 | awk '/x86intrin.h/ {gsub(/"/, "", $3); print $3; exit 0 }') 7 | 8 | if [[ -z "$headerfile" ]]; then 9 | echo "x86intrin.h not found" >&2 10 | exit 1 11 | fi 12 | 13 | dirname "$headerfile" 14 | -------------------------------------------------------------------------------- /tools/gen_enclave_key.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | #set -x 5 | 6 | KEY_LENGTH=3072 7 | KEY_LENGTH_HEX=768 8 | 9 | usage() { 10 | echo "Usage: $0 path-to-new-key-file" 11 | exit 1 12 | } 13 | 14 | pad() { 15 | text=$1 16 | length=$2 17 | while [ ${#text} -lt ${length} ]; do 18 | text="0"${text} 19 | done 20 | echo ${text} 21 | } 22 | 23 | get_key_component() { 24 | key=$1 25 | comp=$2 26 | 27 | openssl rsa -in ${key} -noout -text | sed 's/^\([a-z].*\)/\f\1/' | awk 'BEGIN { RS="\f" } /'"${comp}"':/ { print toupper($0)}' | tail -n +2 | tr -d '[:space:]:'| sed 's/^0*//' 28 | } 29 | 30 | if [ $# -ne 1 ] ; then 31 | usage 32 | exit 1 33 | fi 34 | 35 | key_file=$1 36 | key_file_tmp=${key_file}.tmp 37 | 38 | echo "Generating ${KEY_LENGTH}-bit RSA key ${key_file_tmp}..." 39 | openssl genrsa -3 -out ${key_file_tmp} ${KEY_LENGTH} 40 | 41 | echo "\nGenerating enclave key file ${key_file}..." 42 | 43 | PUB_MODULUS=$( pad $( get_key_component ${key_file_tmp} "modulus" ) ${KEY_LENGTH_HEX} ) 44 | PUB_EXPONENT=$( pad "3" ${KEY_LENGTH_HEX} ) 45 | PRIV_EXPONENT=$( pad $( get_key_component ${key_file_tmp} "privateExponent" ) ${KEY_LENGTH_HEX} ) 46 | PRIME1=$( pad $( get_key_component ${key_file_tmp} "prime1" ) ${KEY_LENGTH_HEX} ) 47 | PRIME2=$( pad $( get_key_component ${key_file_tmp} "prime2" ) ${KEY_LENGTH_HEX} ) 48 | 49 | echo "#Generated by sgx-lkl/tools/gen_enclave_key.sh" > ${key_file} 50 | echo "PUBKEY: ${PUB_MODULUS}" >> ${key_file} 51 | echo "SECKEY: ${PRIV_EXPONENT}" >> ${key_file} 52 | echo "P: ${PRIME1}" >> ${key_file} 53 | echo "Q: ${PRIME2}" >> ${key_file} 54 | echo "E: ${PUB_EXPONENT}" >> ${key_file} 55 | 56 | echo "Deleting temporary key file ${key_file_tmp}..." 57 | rm ${key_file_tmp} 58 | 59 | echo "Done." 60 | -------------------------------------------------------------------------------- /tools/generate_syscall_remap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # This script is used to generate the fixup table mapping x86-64 syscalls 4 | # onto their LKL equivalents. 5 | # 6 | # The output is part of src/misc/syscall.c in sgx-musl-lkl 7 | 8 | LKL_UNISTD_PATH="../lkl/tools/lkl/include/lkl/asm-generic/unistd.h" 9 | NATIVE_TBL_PATH="../lkl/arch/x86/entry/syscalls/syscall_64.tbl" 10 | 11 | LKL_PREFIX='#define __lkl__NR_' 12 | 13 | class Syscall: 14 | def __init__(self, name): 15 | self.name = name 16 | self.lkl_num = None 17 | self.native_num = None 18 | 19 | def __repr__(self): 20 | return '<{}: lkl{}, native{}>'.format(self.name, self.lkl_num, self.native_num) 21 | 22 | 23 | def parse_table(f, syscall_tab, attr): 24 | for ln in f: 25 | ln = ln.strip() 26 | if ln.startswith('#') or len(ln) == 0: 27 | continue 28 | num, abi, name, *extra = ln.split() 29 | if not abi == "common" and not abi == "64": 30 | continue 31 | num = int(num) 32 | if name not in syscall_tab: 33 | syscall_tab[name] = Syscall(name) 34 | setattr(syscall_tab[name], attr, num) 35 | 36 | 37 | def parse_unistd(f, prefix, syscall_tab, attr): 38 | for ln in f: 39 | if not ln.startswith(LKL_PREFIX): 40 | continue 41 | name, _, num = ln[len(LKL_PREFIX):].strip().partition(' ') 42 | if name == 'syscalls': 43 | # this is the syscall count! 44 | continue 45 | try: 46 | num = int(num) 47 | except ValueError: 48 | # we've probably reached the end... 49 | break 50 | if name not in syscall_tab: 51 | syscall_tab[name] = Syscall(name) 52 | setattr(syscall_tab[name], attr, num) 53 | 54 | 55 | syscall_tab = {} 56 | with open(LKL_UNISTD_PATH, 'r') as f: 57 | parse_unistd(f, LKL_PREFIX, syscall_tab, 'lkl_num') 58 | with open(NATIVE_TBL_PATH, 'r') as f: 59 | parse_table(f, syscall_tab, 'native_num') 60 | 61 | syscall_nums = [f for f in syscall_tab.values() if f.native_num is not None and f.lkl_num is not None] 62 | syscall_nums.sort(key=lambda f: f.native_num) 63 | 64 | print("static const short syscall_remap_len = {};".format(syscall_nums[-1].native_num)) 65 | print("static const short syscall_remap[] = {") 66 | x = 0 67 | for n in range(syscall_nums[-1].native_num+1): 68 | if syscall_nums[x].native_num != n: 69 | print("\t-1, /* not implemented in x86-64 */") 70 | continue 71 | e = syscall_nums[x] 72 | print("\t{}, /* {} - x86-64 syscall: {} */".format(e.lkl_num, e.name, e.native_num)) 73 | x += 1 74 | print("};") 75 | -------------------------------------------------------------------------------- /tools/kmod-set-fsgsbase/.gitignore: -------------------------------------------------------------------------------- 1 | .mod_set_cr4_fsgsbase.*.cmd 2 | .tmp_versions/ 3 | Module.symvers 4 | mod_set_cr4_fsgsbase.ko 5 | mod_set_cr4_fsgsbase.mod.* 6 | mod_set_cr4_fsgsbase.o 7 | modules.order 8 | -------------------------------------------------------------------------------- /tools/kmod-set-fsgsbase/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += mod_set_cr4_fsgsbase.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | 9 | set-cr4-fsgsbase: all 10 | sudo insmod ./mod_set_cr4_fsgsbase.ko val=1 11 | sudo rmmod mod_set_cr4_fsgsbase 12 | sudo dmesg | tail -n 10 13 | 14 | unset-cr4-fsgsbase: all 15 | sudo insmod ./mod_set_cr4_fsgsbase.ko val=0 16 | sudo rmmod mod_set_cr4_fsgsbase 17 | sudo dmesg | tail -n 10 18 | -------------------------------------------------------------------------------- /tools/kmod-set-fsgsbase/mod_set_cr4_fsgsbase.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | MODULE_LICENSE("Dual BSD/GPL"); 6 | MODULE_AUTHOR("Imperial College London"); 7 | MODULE_DESCRIPTION("Module to set CR4.FSGSBASE control register bit in order to allow enclave code to use WRFSBASE instruction."); 8 | 9 | static int val; 10 | module_param(val, int, 0000); 11 | MODULE_PARM_DESC(val, "New value of CR4.FSGSBASE (0 or 1)."); 12 | 13 | #define SET_RAX_BIT16_0 "and $0xFFFFFFFFFFFEFFFF, %%rax;\n\t" 14 | #define SET_RAX_BIT16_1 " or $(1 << 16), %%rax;\n\t" 15 | 16 | #define SETFSGSBASE(val) { \ 17 | __asm__ __volatile__ ( \ 18 | "mov %%cr4, %%rax;\n\t" \ 19 | "mov %%rax, %0;\n\t" \ 20 | SET_RAX_BIT16_##val \ 21 | "mov %%rax, %%cr4;\n\t" \ 22 | "wbinvd\n\t" \ 23 | "mov %%cr4, %%rax;\n\t" \ 24 | "mov %%rax, %1;\n\t" \ 25 | : "=g" (cr4before), "=g" (cr4after) \ 26 | : /* no input */ \ 27 | : "%rax" \ 28 | );} 29 | 30 | 31 | void set_cr4_fsgsbase(void *_) { 32 | u64 cr4before, cr4after; 33 | 34 | val = val >= 1 ? 1 : 0; 35 | if (val) { 36 | SETFSGSBASE(1); 37 | } else { 38 | SETFSGSBASE(0); 39 | }; 40 | printk(KERN_ALERT "SGX-LKL: Successfully set CR4.FSGSBASE to %d on CPU #%d, CR4 before: 0x%8.8llx, after: 0x%8.8llx.\n", val, smp_processor_id(), cr4before, cr4after); 41 | } 42 | 43 | int init_module(void) { 44 | #ifdef __x86_64__ 45 | printk(KERN_ALERT "SGX-LKL: Setting CR4.FSGSBASE to %d...\n", val); 46 | set_cr4_fsgsbase(NULL); 47 | smp_call_function(&set_cr4_fsgsbase, NULL, 0); 48 | #else 49 | printk(KERN_ALERT "SGX-LKL: Cannot set CR4.FSGSBASE. Platform is not x86-64.\n"); 50 | #endif /* __x86_64__ */ 51 | 52 | return 0; 53 | } 54 | void cleanup_module(void) { 55 | // Nothing to do. 56 | } 57 | -------------------------------------------------------------------------------- /tools/ncore.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Thanks to the Fuchsia Authors for this! 4 | 5 | case `uname` in 6 | Linux) 7 | _N=`cat /proc/cpuinfo | grep processor | wc -l` 8 | N=`expr $_N + $_N` 9 | ;; 10 | Darwin) 11 | N=`sysctl -n hw.ncpu` 12 | ;; 13 | FreeBSD) 14 | N=`sysctl -n hw.ncpu` 15 | ;; 16 | *) 17 | N=8 18 | ;; 19 | esac 20 | 21 | echo $N 22 | -------------------------------------------------------------------------------- /tools/sgx-lkl-java: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BASE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" 4 | 5 | ENCLAVE_HEAP_SIZE=${SGXLKL_HEAP:-256M} 6 | ENCLAVE_DEBUG_KEY=${SGXLKL_KEY:-${BASE_DIR}/build/config/enclave_debug.key} 7 | 8 | SGX_LKL_RUN_EXEC=${BASE_DIR}/build/sgx-lkl-run 9 | SGX_LKL_OPTIONS="\ 10 | SGXLKL_MMAP_FILES=${SGXLKL_MMAP_FILES:-Shared} \ 11 | SGXLKL_STHREADS=${SGXLKL_STHREADS:-4} \ 12 | SGXLKL_ETHREADS=${SGXLKL_ETHREADS:-4} \ 13 | SGXLKL_HEAP=${ENCLAVE_HEAP_SIZE} \ 14 | SGXLKL_KEY=${ENCLAVE_DEBUG_KEY}" 15 | 16 | JRE_LIB_PATH="/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64:/usr/lib/jvm/java-1.8-openjdk/jre/../lib/amd64:/usr/lib/jvm/java-1.8-openjdk/lib/amd64/jli" 17 | DEFAULT_JRE_ARGS="\ 18 | -Xms2000k \ 19 | -XX:InitialCodeCacheSize=2000k \ 20 | -XX:ReservedCodeCacheSize=4000K \ 21 | -XX:CompressedClassSpaceSize=4000K \ 22 | -XX:+UseCompressedClassPointers \ 23 | -XX:+PerfDisableSharedMem \ 24 | -XX:+UseMembar \ 25 | -Dsun.zip.disableMemoryMapping=true \ 26 | -cp /app" 27 | 28 | DISK_IMAGE=$1 29 | ARGS="${@:2}" 30 | 31 | env LD_LIBRARY_PATH=${JRE_LIB_PATH} ${SGX_LKL_OPTIONS} ${SGX_LKL_RUN_EXEC} ${DISK_IMAGE} /usr/bin/java ${DEFAULT_JRE_ARGS} ${ARGS} 32 | 33 | -------------------------------------------------------------------------------- /tools/sgx_lkl_sign_options.ggo: -------------------------------------------------------------------------------- 1 | # Generate src/sign/cmdline.c/*.h by running: 2 | # gengetopt --input sgx_lkl_sign_options.ggo --output-dir ../src/sgx --file-name sgxlkl_sign_cmdline 3 | 4 | package "sgx-lkl-sign" 5 | version "1.0" 6 | purpose "Use this program to sign libsgxlkl.so before loading it into an enclave via sgx-lkl-run." 7 | 8 | option "file" f "Path to libsgxlkl.so that should get signed." string required 9 | option "key" k "Path to enclave key file." string required 10 | option "stacksize" s "Size of the stack in bytes. Will be rounded up to align \ 11 | with the size of a page." long default="32768" optional 12 | option "heapsize" h "Size of the heap in bytes. If set to zero the heap will \ 13 | occupy the remaining space of the EPC. Setting this value to a value larger \ 14 | than the EPC is allowed but might result in EPC paging." long default="0" optional 15 | option "threads" t "Maximum number of enclave threads. This determines the number \ 16 | of TCS. This does not restrict the number of user-level threads used by an \ 17 | application." long default="8" optional 18 | option "support-non-pie" n "Specify this if sgx-lkl-run needs to run with \ 19 | SGXLKL_NON_PIE=1." int default="0" optional 20 | --------------------------------------------------------------------------------