Release engineering stuff for Cryptech Alpha board and support software.


The Makefiles and scripts in this repository attempt to automate the process of building packaged versions of the firmware and software for the Cryptech Alpha board. At a high level, this consists of two main phases:

  1. Building a firmware package (Verilog and C code which runs on the Alpha board itself, regardless the host system to which the Alpha is connected); and

  2. Building software packages (code which runs on the host to which the Alpha is connected).

Since the firmware is the same for any given version of the Cryptech source code, and since the process of building the firmware binaries is both time-consuming and involves tools like the XiLinx Verilog synthesis toolkit and cross-compilers for multiple CPUs (the Alpha's Cortex M4 ARM CPU and the Atmel AVR ATtiny828 MCU used to implement the anti-tampering logic for the master key memory), we include a signed tarball containing pre-built binaries for all the firmware as part of the source tarball for the software packages.

You are of course free to build all of this for yourself, with or without modification, the pre-built versions are just a convenience.

Source Tree

The source code itself, for both the firmware and the software, is in the source/ directory, with names corresponding to the canonical names of the relevant git repositories. At the time this document was written, a few of the repositories in question had not yet been promoted to their expected permanent homes in the core/ or sw/ trees, but we expect this to be temporary. Regardless, directory names within the source/ directory tree are intended to track the canonical names of the git repositories, whatever they may be at any given time.

Firmware Build Process

The firmware build process consists of five main phases:

  1. Building a "shadow" directory tree populated with symlinks back to the source tree. This allows us to preserve binaries between compilation runs where appropriate, without cluttering up the source tree with various intermediate files which don't belong there. In particular, this allows to skip the Verilog synthesis stage when nothing there has changed, which makes the overall build process run significantly faster.

  2. Synthesizing the Verilog source code into a bitstream. This phase generates a single bitstream file, suitable for loading into the Alpha's FPGA chip.

  3. Cross-compiling C code for the Alpha's ARM processor. This produces two images: the bootloader, and the HSM firmware itself.

  4. Cross compiling C code for the Alpha's AVR MCU. This produces a single image, which runs the tamper-response controller.

  5. Packaging all of the firmware created in the above steps into a tarball, with some meta-data describing the package, including SHA-2 digests of all of the firmware image files and a signature over the entire meta-data block.

The precise formats which show up in the firmware tarball are subject to change. At the moment, they consist of:

  • A raw bitstream (".bit" file) for the Xilinx Artix-7 FPGA.

  • ELF and raw binary image files for the Cortex M4 ARM CPU; we supply both .elf and .bin files because some tools want one format, some want the other.

  • A ".hex" image for the AVR MCU.

The overall packaging for the firmware tarball is intentionally pretty boring: tar, gzip, gpg, and JSON. The intent is that users be able to use our firmware tarball even if the scripts we provide are unsuitable for some reason.

The final result of the firmware build process is the firmware tarball, which is written into the source/ tree for inclusion by the software packaging phase.

Software Build Process

The software build process also consists of several phases, but is a bit more open-ended than the firmware build process. Phases in the current build process:

  1. Building a source tarball and Debian source package (".dsc"). The Debian and Ubuntu Linux distributions are our primary development platforms, so we need to produce packages for them in any case, and the process of producing a Debian-family source package produces a source tarball as one of its outputs, so we get that for free by doing this step first.

  2. Running pbuilder to generate clean binary packages for the "i386" and "amd64" architectures for Debian Jessie and Ubuntu Xenial.

  3. Loading all of the Debian and Ubuntu packages produced above into the staging instances of a set of APT repositories.

  4. Generation of a Homebrew formula and committing that formula to the staging instance of a Homebrew "tap" (git repository), using the tarball created during the Debian source package stage as the source package. The Homebrew formula is source-only (no "bottled" binary packages): creating binary packages would not be particularly difficult (one osxcross instance per version of OSX we want to support would do it), but Apple's Xcode SDK license doesn't permit this unless we run our build farm on Apple hardware.

  5. Uploading changes from the staging repositories to our public repositories.

In theory, it would also be possible to produce Windows binaries using the MinGW cross-compilation environment, but Windows is sufficiently different from all other platforms that even minimal Windows support would almost certainly require extensive source code changes, so we have not put any serious thought into build issues for Windows.