Skip to content

Latest commit

 

History

History
184 lines (136 loc) · 6.75 KB

sdk_cmake_targets_readme.md

File metadata and controls

184 lines (136 loc) · 6.75 KB

Open Enclave SDK CMake Package

This CMake Config-file package is provided for use with CMake's find_package command.

In a CMake project which is using the Open Enclave SDK, you find the package by using the following in your CMakeLists.txt:

find_package(OpenEnclave CONFIG REQUIRED)

This will bring in the Open Enclave targets under the openenclave:: namespace.

The targets relevant to users of the SDK are:

Executables

  • openenclave::oeedger8r
  • openenclave::oesign
  • openenclave::oeapkman (only on Linux)

Libraries

  • openenclave::oeenclave
  • openenclave::oelibc
  • openenclave::oelibcxx
  • openenclave::oehost

The remaining targets in openenclave-targets.cmake are automatically included when needed by the above.

The package will also search for (and requires) the Threads package.

However, the libraries crypto and dl will also need to be available on the system, but due to an outstanding issue, the failure will happen at link-time if they are unavailable.

Examples

Running oeedger8r

The openenclave::oeedger8r target is an executable that generates trusted and untrusted C bindings from an Enclave Definition Language file. Example usage is:

# Trusted bindings for the enclave
add_custom_command(OUTPUT example_t.h example_t.c example_args.h
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/example.edl
  COMMAND openenclave::oeedger8r --trusted ${CMAKE_CURRENT_SOURCE_DIR}/example.edl)

# Untrusted bindings for the host
add_custom_command(OUTPUT example_u.h example_u.c example_args.h
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/example.edl
  COMMAND openenclave::oeedger8r --untrusted ${CMAKE_CURRENT_SOURCE_DIR}/example.edl)

Note that oeedger8r emits files in the current working directory, which is ${CMAKE_CURRENT_BINARY_DIR} by default, but this can be changed with the WORKING_DIRECTORY argument to add_custom_command.

To trigger the generation of the OUTPUT files, you will need to specify them as input source files to another target (such as an enclave and a host).

Because both the enclave(s) and host need files generated by oeedger8r, you probably want to use two separate commands with just the --trusted and --untrusted flags respectively, even though they can be given simultaneously. This is because the output of a CMake custom command can only be used as an input to a CMake target in the same CMakeLists.txt, and your enclave and host targets are probably in separate folders. See our samples for a complete build structure example.

There is a special case where the example_args.h file is not generated, but it is exceedingly rare. If the only functions specified in the EDL are of the form void fn() (no arguments and a void return type), then no arguments header will be generated.

Creating an unsigned enclave

Enclave targets in CMake should use add_executable, link to both openenclave::oeenclave and openenclave::oelibc, and include the trusted EDL code if oeedger8r was used. An example is:

add_executable(example_enclave example.c example_t.c)
target_link_libraries(example_enclave openenclave::oeenclave openenclave::oelibc)

Technically, the openenclave::oelibc dependency is optional. That is, if you don't use anything from the C library (such as #include <stdio.h> etc.), you can exclude it, but this is very unlikely.

If the enclave uses C++ code, it must link to both openenclave::oeenclave and openenclave::oelibcxx:

add_executable(example_cpp_enclave example.cpp example_t.c)
target_link_libraries(example_cpp_enclave openenclave::oeenclave openenclave::oelibcxx)

Because openenclave:oelibccxx depends on openenclave::oelibc, you don't have to specify both. The latter is brought in automatically by the former. However, openenclave:oeenclave depends on neither of these libraries, so it must always be included.

Note that to opt-in to our latest API version, you should also use:

target_compile_definitions(example_enclave OE_API_VERSION=2)

Signing an enclave

The openenclave::oesign target is an executable that takes an unsigned enclave, an enclave configuration file, and a private key, and outputs a signed enclave. Example usage is:

# NOTE: This is a self-signed certificate only for demonstration.
add_custom_command(OUTPUT private.pem public.pem
  COMMAND openssl genrsa -out private.pem -3 3072
  COMMAND openssl rsa -in private.pem -pubout -out public.pem)

add_custom_command(OUTPUT example_enclave.signed
  DEPENDS example_enclave example.conf private.pem
  COMMAND openenclave::oesign sign -e $<TARGET_FILE:example_enclave> -c ${CMAKE_CURRENT_SOURCE_DIR}/example.conf -k private.pem)

Since oesign is unaware of CMake information, the CMake Generator Expression $<TARGET_FILE:example_enclave> is used. Given that example_enclave is a valid CMake target, the generator expression will replace itself with the absolute path to the output file of that build target.

Note that oesign emits the signed enclave next to the unsigned enclave, which typically is in the build directory corresponding to the source directory of the enclave. The current working directory does not affect it.

Because this is a custom command, you will need to depend on example_enclave.signed from a custom target.

add_custom_target(signed_example_enclave ALL
  DEPENDS example_enclave.signed)

This adds a default target to the build (by the use of ALL) which ensures the signing takes place. You do not want to use add_custom_target(COMMAND ...) instead of add_custom_command because the former would run on every build, but the latter sets up a dependency where it only signs if the enclave is rebuilt.

Creating a host

Host targets in CMake should use add_executable, link to openenclave::oehost, and include the untrusted EDL code if oeedger8r was used. An example is:

add_executable(example_host host.cpp example_u.c)
target_link_libraries(example_host openenclave::oehost)

Running the enclave

Finally, you can run the enclave with:

./example_host /path/to/example_enclave.signed

Running oeapkman

On Linux, Alpine Linux static libraries can be installed for use within enclaves as follows:

oeapkman add sqlite-static sqlite-dev

For a complete walkthrough of using oeapkman refer to apkman sample.