corda/sgx-jvm
Chris Rankin 9411c223af Squashed commit of the following: (#15)
commit fabf4dd0cca19118c59c925f572a655d1d9c4092
Author: Joel Dice <joel.dice@gmail.com>
Date:   Sun Jul 9 17:36:06 2017 -0600

    reserve a little more stack space for worst-case lambda expressions

commit 24b95016dd6f62fa4a82312310fcb5c55cc22f93
Author: Joel Dice <joel.dice@gmail.com>
Date:   Sun Jul 9 17:33:39 2017 -0600

    support constructor references

commit a329416f4f37840d2a5d7976874585413cd4c6af
Author: Joel Dice <joel.dice@gmail.com>
Date:   Sun Jul 9 17:11:19 2017 -0600

    normalize class name in Classes.forName

    This fixes a Tomcat classloading issue when using the OpenJDK class library.

commit ecafdf40baf2f3cde4835620e9af4380b1081fe7
Author: Joel Dice <joel.dice@gmail.com>
Date:   Sun Jul 9 16:58:04 2017 -0600

    fix some lambda bugs

commit 552dfd779baf077cc6445b4042588e4b6e34f3d2
Merge: 63dda56 aa2f25d
Author: Joel Dice <joel.dice@gmail.com>
Date:   Sat Jul 8 10:57:59 2017 -0600

    Merge remote-tracking branch 'corda/chrisr3-invoking-extension'

commit 63dda560f8648a793bdb609879076ab729b17e19
Merge: 3ec983d e589f10
Author: Joel Dice <joel.dice@gmail.com>
Date:   Sat Jul 8 10:54:53 2017 -0600

    Merge pull request #538 from dicej/master

    avoid definePackage infinite recursion with OpenJDK class library

commit aa2f25da404b2fc168a672392df939b52ea250ab
Author: Chris Rankin <chris.rankin@r3.com>
Date:   Mon Jul 3 17:26:41 2017 +0100

    Add support for "invokevirtual" and "invokeinterface".
    The "invokeinterface" support seems to be broken for lambdas that require native types to be boxed/unboxed.

commit e589f105741ea36d07bba1e300c7ed69c33a22d1
Author: Joel Dice <joel.dice@gmail.com>
Date:   Sun Jul 2 19:43:36 2017 -0600

    avoid definePackage infinite recursion with OpenJDK class library

commit 3ec983dd82e01b36fb96411df345a54119a68181
Merge: 6f6bdd7 78881d4
Author: Joel Dice <joel.dice@gmail.com>
Date:   Tue Jun 13 09:50:49 2017 -0600

    Merge pull request #534 from lwahlmeier/fileGetParentFile

    fixed File.getParent when getting parent returns root

commit 78881d427cd474c14f5ce94484f5253de564074b
Author: Luke Wahlmeier <lwahlmeier@gmail.com>
Date:   Tue May 30 13:42:56 2017 -0600

    fixed File.getParent when getting parent returns root

commit 6f6bdd7d5c171e0c4c807d0a4f3aa676461307de
Merge: 8b694f9 b22343e
Author: Joel Dice <joel.dice@gmail.com>
Date:   Mon May 22 12:58:09 2017 -0600

    Merge pull request #529 from mikehearn/proguard-fixes

    Some fixes to the ProGuard files

commit 8b694f961496f2d47a377254f61153b0338335fd
Merge: dfae414 61c82e1
Author: Joel Dice <joel.dice@gmail.com>
Date:   Mon May 22 12:57:54 2017 -0600

    Merge pull request #531 from mikehearn/fileinputstream-compat

    FileInputStream has wrapped some more native methods

commit dfae414da8da57049076c16c43472cc32bdeb07c
Merge: 16dd804 d7a6f68
Author: Joel Dice <joel.dice@gmail.com>
Date:   Mon May 22 12:57:38 2017 -0600

    Merge pull request #532 from mikehearn/use-symlinks

    Symlink OpenJDK files rather than hardlink

commit d7a6f68235b2d42c03aba36f1bb48d173adb4fa6
Author: Mike Hearn <mike@plan99.net>
Date:   Sun May 14 21:42:06 2017 +0200

    Symlink OpenJDK files rather than hardlink

commit 61c82e1070d857bcdc7a4f086d13836d9608da00
Author: Mike Hearn <mike@plan99.net>
Date:   Sun May 14 21:40:52 2017 +0200

    FileInputStream has wrapped some more native methods in recent OpenJDK releases

commit b22343eb6731f1df2631635e2fcf9d51817273fe
Author: Mike Hearn <mike@plan99.net>
Date:   Sun May 14 21:38:09 2017 +0200

    Some fixes to the ProGuard files

commit 16dd804f392168497fa17ab682978f938e291bfb
Merge: e2d3270 19deadd
Author: Joel Dice <joel.dice@gmail.com>
Date:   Wed Mar 22 16:00:30 2017 -0600

    Merge pull request #526 from MaartenR/arrays-binsearch

    Added integer array binary search methods to Arrays class

commit e2d3270fe8e92203b6107b95f862ff5bd245c37a
Merge: dee99d6 545b9c8
Author: Joel Dice <joel.dice@gmail.com>
Date:   Wed Mar 22 16:00:20 2017 -0600

    Merge pull request #527 from MaartenR/integer-nolz

    Added numberOfLeadingZeros method to Integer class

commit 545b9c8732a6ea026285b1edf976a79eb541ef2e
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date:   Tue Mar 14 11:23:36 2017 +0100

    Tested more negative numbers

commit b45bcf09535daef99ed31451ae55db8bec83164c
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date:   Tue Mar 14 10:47:27 2017 +0100

    Added unit test for numberOfLeadingZeros method of the Integer class

commit 19deadd36bbfc02a8c13e6d91963e41f5125057f
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date:   Mon Mar 13 12:19:17 2017 +0100

    Fixed mistake with end index being exclusive

commit 7271c0b7077ae3bef473e036aa0f0298a9eb0601
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date:   Fri Mar 10 11:17:13 2017 +0100

    Added numberOfLeadingZeros method to Integer class

commit 023bb69acd071348f29cd43ff954d3dcf2856c7c
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date:   Thu Mar 9 13:43:03 2017 +0100

    Added integer array binary search methods to Arrays class

commit dee99d6dd60b743a870d1a2c58183649c8a6449c
Merge: f7a651d 6c90953
Author: Joel Dice <joel.dice@gmail.com>
Date:   Wed Mar 1 08:39:32 2017 -0700

    Merge pull request #525 from MaartenR/master

    Added functionality to HttpURLConnection for obtaining content length

commit 6c90953745be5451ac9a028639f94e3fcc43d7f3
Author: Maarten Raaphorst <raaphorst@serviceplanet.nl>
Date:   Wed Mar 1 14:19:51 2017 +0100

    Made http headers case insensitive

commit 2c3a82d2b387251a8932ddb6575e718c2c1785a7
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date:   Fri Feb 3 05:42:56 2017 -0800

    Added functionality to HttpURLConnection for obtaining content length
2017-07-10 17:01:56 +01:00
..
avian Squashed commit of the following: (#15) 2017-07-10 17:01:56 +01:00
dependencies sgx: Update dependencies 2017-06-15 18:41:58 +01:00
hsm-tool sgx: Fix hsm-tool CLI parsing, increase key generation timeout window, add IntelWhitelistFormInstructions.md 2017-06-15 15:11:46 +01:00
jvm-enclave sgx: Fix libprotobuf linking when SGX_USE_HARDWARE=TRUE, write pretty printed hsm sigstruct 2017-06-15 14:10:26 +01:00
linux-sgx Add sgx build, documentation, verify-enclave 2017-03-24 18:23:04 +00:00
noop-enclave README.md: add sentence on unsigned SIGSTRUCT blob 2017-06-19 17:32:09 +01:00
Makefile Add sgx build, documentation, verify-enclave 2017-03-24 18:23:04 +00:00
README.md HSM works 2017-06-15 11:17:11 +01:00

The build

Prerequisites

  • Install mercurial, gcc/g++(6), autoconf, automake, ocaml, opendjk(8), libtool, python(2.7)
  • Make sure JAVA_HOME points to your jdk 8 installation
  • Make sure CXX points to g++ (the project does NOT compile with other compilers like clang!)
  • If your hardware supports SGX and you want to use it directly you need to install and load the sgx kernel module (verify by running lsmod | grep isgx) and have the sgx service running (on a systemd setup verify by running systemctl status aesmd). Note that this is only required for actually running the binary, the build should work fine without.
  • The SGX SDK has a simulation mode that doesn't require hardware support. To use this edit sgx-jvm/jvm-enclave/CMakeLists.txt and change set(SGX_USE_HARDWARE TRUE) to FALSE

Toplevel Makefile targets

  • make will download all other dependencies and build the sgx_standalone_verify binary, residing at sgx-jvm/jvm-enclave/standalone/build/sgx\_standalone\_verify, as well as a JNI .so residing at sgx-jvm/jvm-enclave/jni/build/untrusted_corda_sgx.so
  • make clean will clean all build targets.
  • make distclean will clean all build targets and downloaded dependencies. Ordinarily you shouldn't need to run this.

Each project has its own build that may be run individually (check the toplevel Makefile to see how to invoke these)

At this point I suggest running make before reading further, it takes a while to download all dependencies.

Some reading

Before delving into the code it's strongly recommended to read up on SGX. Some links:

Corda SGX

The high level goal of the SGX work in Corda is to provide a secure way of verifying transactions. In order to do this we need to be able to run a JVM inside an enclave capable of running contract code. The design decision that contract verification code is without side-effects is imperative here.

The dream is to have a functioning JVM running inside SGX with as few limitations as possible. Clients would then be able to connect to the enclave, the TCB would attest that it is running the JVM image on secure hardware, after which the client can safely submit signed JARs for execution.

Corda would then be able to use this to submit contract code and transactions to run the contract code on.

This is the first iteration of the work, with a lot of limitations. The current JVM is based on Avian which can produce a standalone statically linked binary. The build statically links the enclavelet JAR into the static enclave binary (sgx-jvm/jvm-enclave/build/enclave/cordaenclave.so) which is then loaded and run by jvm/jvm-enclave/build/sgx\_experiments.

Breakdown of the build

The current SGX work in Corda is based on 4 semi-distinct projects:

  • The Avian JVM (in the sgx-jvm/avian subtree. Note this is our own fork)
  • The SGX linux sdk (in the sgx-jvm/linux-sgx subtree. Note this is our own fork)
  • The JVM enclave code itself, residing in sgx-jvm/jvm-enclave. This includes the untrusted and trusted part of the SGXified JVM, mostly C++.
  • Finally the Corda enclavelet. This is the JAR that will be loaded and run inside the enclave. (built by ./gradlew verify-enclave:jar

Avian

Avian has a code layout perfectly suited for SGX hacking. Each target platform (originally posix or windows) needs to implement a fairly straight-forward System interface providing OS-specific functionality like threading/synchronisation/memory/filesystem primitives. Check sgx-jvm/avian/src/system for code. We use this to implement an SGX "platform", which is basically a stripped down OS environment. Some additional #ifndef-ing was needed to strip some non-os-specific avian functionality that assumed the existence of a filesystem or networking. This work is maintained in a private fork, it is instructive to read through the diff, see https://bitbucket.org/R3-CEV/avian-sgx/.

SGX SDK

There are some modifications in the upstream SGX SDK that we require to run the JVM. An example would be the ability to make the heap executable for JIT compilation, or exposing hooks into malloc to detect OOM conditions. All of these should be mergeable, but we maintain a fork to speed up development on our side.

Corda Enclavelet

This is the JAR that will be run inside the enclave. Check verify-enclave/src/../Enclavelet.kt for the code.

Currently the JAR is not loaded at runtime, but is rather embedded statically into the enclave itself using Avian's binaryToObject utility. This basically does an objcopy and lets the linker do the embedding later. This will later be changed to dynamic loading of signed JARs.

The JVM enclave

This consists of two parts: the untrusted code that loads the enclave and provides the OCALLs (see sgx-jvm/jvm-enclave/main.cpp), and the trusted enclave that constructs the JVM using JNI and runs the enclavelet class. (see sgx-jvm/jvm-enclave/enclave/enclave.cpp).

Dynamic loading, linkage

Avian by default loads some JVM specific code dynamically, and looks up these symbols at runtime. We link these symbols statically and provide a simple binary search lookup at runtime to find the symbols corresponding to symbol name strings. To see how this is done check sgx-jvm/jvm-enclave/enclave/gen_dispatch_table.py.

Avian also statically links against system libraries providing usual OS functionality. We deal with this by stubbing all of the undefined symbols and implementing/mocking them as needed. The stub generation simply greps for undefined symbols when running make, check sgx-jvm/jvm-enclave/enclave/gen-stubsyms.sh for this. The implemented/mocked OS functions reside in sgx-jvm/jvm-enclave/enclave/os_support.cpp