| # Open Profile for DICE | |
| This repository contains the specification for the | |
| [Open Profile for DICE](docs/specification.md) along with production-quality | |
| code. This profile is a specialization of the | |
| [Hardware Requirements for a Device Identifier Composition Engine](https://trustedcomputinggroup.org/resource/hardware-requirements-for-a-device-identifier-composition-engine/) | |
| and | |
| [DICE Layering Architecture](https://trustedcomputinggroup.org/resource/dice-layering-architecture/) | |
| specifications published by the Trusted Computing Group (TCG). For readers | |
| already familiar with those specs, notable distinctives of this profile include: | |
| * Separate CDIs for attestation and sealing use cases | |
| * Categorized inputs, including values related to verified boot | |
| * Certified UDS values | |
| * X.509 or CBOR certificates | |
| ## Mailing List | |
| You can find us (and join us!) at | |
| https://groups.google.com/g/open-profile-for-dice. We're happy to answer | |
| questions and discuss proposed changes or features. | |
| ## Specification | |
| The specification can be found [here](docs/specification.md). It is versioned | |
| using a major.minor scheme. Compatibility is maintained across minor versions | |
| but not necessarily across major versions. | |
| ## Code | |
| Production quality, portable C code is included. The main code is in | |
| [dice.h](include/dice/dice.h) and [dice.c](src/dice.c). Cryptographic and | |
| certificate generation operations are injected via a set of callbacks. Multiple | |
| implementations of these operations are provided, all equally acceptable. | |
| Integrators should choose just one of these, or write their own. | |
| Tests are included for all code and the build files in this repository can be | |
| used to build and run these tests. | |
| Disclaimer: This is not an officially supported Google product. | |
| ### Thirdparty Dependencies | |
| Different implementations use different third party libraries. The third\_party | |
| directory contains build files and git submodules for each of these. The | |
| submodules must be initialized once after cloning the repo, using `git submodule | |
| update --init`, and updated after pulling commits that roll the submodules using | |
| `git submodule update`. | |
| ### Building and Running Tests | |
| #### Quick setup | |
| To setup the build environment the first time: | |
| ```bash | |
| $ git submodule update --init --recursive | |
| $ source bootstrap.sh | |
| $ gn gen out | |
| ``` | |
| To build and run tests: | |
| ```bash | |
| $ ninja -C out | |
| ``` | |
| #### More details | |
| The easiest way, and currently the only supported way, to build and run tests is | |
| from a [Pigweed](https://pigweed.googlesource.com/pigweed/pigweed/) environment | |
| on Linux. Pigweed does support other host platforms so it shouldn't be too hard | |
| to get this running on Windows for example, but we use Linux. | |
| There are two scripts to help set this up: | |
| * [bootstrap.sh](bootstrap.sh) will initialize submodules, bootstrap a Pigweed | |
| environment, and generate build files. This can take some time and may | |
| download on the order of 1GB of dependencies so the normal workflow is to | |
| just do this once. | |
| * [activate.sh](activate.sh) quickly reactivates an environment that has been | |
| previously bootstrapped. | |
| These scripts must be sourced into the current session: `source activate.sh`. | |
| In the environment, from the base directory of the dice-profile checkout, run | |
| `ninja -C out` to build everything and run all tests. You can also run `pw | |
| watch` which will build, run tests, and continue to watch for changes. | |
| This will build and run tests on the host using the clang toolchain. Pigweed | |
| makes it easy to configure other targets and toolchains. See | |
| [toolchains/BUILD.gn](toolchains/BUILD.gn) and the Pigweed documentation. | |
| ### Porting | |
| The code is designed to be portable and should work with a variety of modern | |
| toolchains and in a variety of environments. The main code in dice.h and dice.c | |
| is C99; it uses uint8\_t, size\_t, and memcpy from the C standard library. The | |
| various ops implementations are as portable as their dependencies (often not C99 | |
| but still very portable). Notably, this code uses designated initializers for | |
| readability. This is a feature available in C since C99 but missing from C++ | |
| until C++20 where it appears in a stricter form. | |
| ### Style | |
| The [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) | |
| is used. A `.clang-format` file is provided for convenience. | |
| ### Incorporating | |
| To incorporate the code into another project, there are a few options: | |
| * Copy only the necessary code. For example: | |
| 1. Take the main code as is: [include/dice/dice.h](include/dice/dice.h), | |
| [src/dice.c](src/dice.c) | |
| 1. Choose an implementation for crypto and certificate generation or choose | |
| to write your own. If you choose the boringssl implementation, for | |
| example, take [include/dice/utils.h](include/dice/utils.h), | |
| [include/dice/boringssl_ops.h](include/dice/boringssl_ops.h), | |
| [src/utils.c](src/utils.c), and | |
| [src/boringssl_ops.c](src/boringssl_ops.c). Taking a look at the library | |
| targets in BUILD.gn may be helpful. | |
| * Add this repository as a git submodule and integrate into the project build, | |
| optionally using the gn library targets provided. | |
| * Integrate into a project already using Pigweed using the gn build files | |
| provided. | |
| ### Size Reports | |
| The build reports code size using | |
| [Bloaty McBloatface](https://github.com/google/bloaty) via the pw\_bloat Pigweed | |
| module. There are two reports generated: | |
| * Library sizes - This report includes just the library code in this | |
| repository. It shows the baseline DICE code with no ops selected, and it | |
| shows the delta introduced by choosing various ops implementations. This | |
| report **does not** include the size of the third party dependencies. | |
| * Executable sizes - This report includes sizes for the library code in this | |
| repository plus all dependencies linked into a simple main function which | |
| makes a single DICE call with all-zero input. It shows the baseline DICE | |
| code with no ops (and therefore no dependencies other than libc), and it | |
| shows the delta introduced by choosing various ops implementations. This | |
| report **does** include the size of the third party dependencies. Note that | |
| rows specialized from 'Boringssl Ops' use that as a baseline for sizing. | |
| The reports will be in the build output, but you can also find the reports in | |
| `.txt` files in the build output. For example, `cat out/host_optimized/gen/*.txt | |
| | less` will display all reports. | |
| ### Thread Safety | |
| This code does not itself use mutable global variables, or any other type of | |
| shared data structure so there is no thread-safety concerns. However, additional | |
| care is needed to ensure dependencies are configured to be thread-safe. For | |
| example, the current boringssl configuration defines | |
| OPENSSL\_NO\_THREADS\_CORRUPT\_MEMORY\_AND\_LEAK\_SECRETS\_IF\_THREADED, and | |
| that would need to be changed before running in a threaded environment. | |
| ### Clearing Sensitive Data | |
| This code makes a reasonable effort to clear memory holding sensitive data. This | |
| may help with a broader strategy to clear sensitive data but it is not | |
| sufficient on its own. Here are a few things to consider. | |
| * The caller of this code is responsible for buffers they own (of course). | |
| * The ops implementations need to clear any copies they make of sensitive | |
| data. Both boringssl and mbedtls attempt to zeroize but this may need | |
| additional care to integrate correctly. For example, boringssl skips | |
| optimization prevention when OPENSSL\_NO\_ASM is defined (and it is | |
| currently defined). | |
| * Sensitive data may remain in cache. | |
| * Sensitive data may have been swapped out. | |
| * Sensitive data may be included in a crash dump. |