Skip to content

Commit

Permalink
Add documentation and Cloud Build configs for releasing the bootloader.
Browse files Browse the repository at this point in the history
  • Loading branch information
jiggoha committed Jan 8, 2024
1 parent b0f8a23 commit 3ff2cf0
Show file tree
Hide file tree
Showing 4 changed files with 278 additions and 6 deletions.
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,19 @@ executing it.

## Firmware transparency

All ArmoredWitness firmware artefacts need to be added to a firmware transparency log,
including the bootloader.
All ArmoredWitness firmware artefacts need to be added to a firmware
transparency log, including the bootloader.

The provided `Makefile` has support for maintaining a local firmware transparency
log on disk. This is intended to be used for development only.
### Production log

The `release/` directory contains Cloud Build configs to build and release the
bootloader, and includes a step to add the release manifest to a log on GCP. See
more info in `release/README.md`.

### Local log

The provided `Makefile` has support for maintaining a local firmware
transparency log on disk. This is intended to be used for development only.

In order to use this functionality, a log key pair can be generated with the
following command:
Expand Down Expand Up @@ -81,8 +89,16 @@ make OS_PUBLIC_KEY1=armored-witness-boot-1.pub OS_PUBLIC_KEY2=armored-witness-bo

### Logging the Recovery image

The `Makefile` has support for fetching and logging a released version of the armory-ums
recovery image, too.
#### Production log

The `recovery/` directory contains Cloud Build configs to build and release the
recovery image, and includes a step to add the release manifest to a log on GCP.
See more info in `recovery/README.md`.

#### Local log

The `Makefile` has support for fetching and logging a released version of the
armory-ums recovery image, too.

Note that this uses `docker` under the covers.

Expand Down
50 changes: 50 additions & 0 deletions release/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Bootloader Release Process

## File structure

* The Dockerfile found in the root of the repo builds an image which installs
dependencies and compiles the bootloader with TamaGo. The version of
TamaGo to use can be specified with the Docker
[build arg](https://docs.docker.com/engine/reference/commandline/build/#build-arg)
`TAMAGO_VERSION`.
* Cloud Build triggers for the presubmit, continuous integration (CI)m and
prod environments are defined on the Cloud Build yaml files in this
directory.

## Build and Release Process

A
[Cloud Build trigger](https://cloud.google.com/build/docs/automating-builds/create-manage-triggers)
is defined by a yaml config file and is invoked when a new tag is published in
this repository.

The pipeline includes two main steps: building and making available the
bootloader imx, and writing the release metadata (Claimant Model Statement) to
the firmware transparency log.

1. Cloud Build builds the bootloader builder Docker image and uploads the
compiled bootloader imx file to a public Google Cloud Storage bucket.
1. Cloud Build runs the
[`manifest`](https://github.com/transparency-dev/armored-witness/tree/main/cmd/manifest)
tool to construct the Claimant Model Statement with arguments specific to
this release. It signs the Statement with the
[`sign`](https://github.com/transparency-dev/armored-witness/tree/main/cmd/sign)
tool and adds the resulting signed Statement as an entry to the public
firmware transparency log.

TODO: add links for the GCS buckets once public.

## Claimant Model

| Role | Description |
| ----------- | ----------- |
| **Claimant** | Transparency.dev team |
| **Claim** | <ol><li>The digest of the bootloader is derived from this source Github repository, and is reproducible.</li><li>The bootloader firmware is issued by the Transparency.dev team.</li></ol> |
| **Believer** | The [provision](https://github.com/transparency-dev/armored-witness/tree/main/cmd/provision) and [verify](https://github.com/transparency-dev/armored-witness/tree/main/cmd/verify) tools. |
| **Verifier** | <ol><li>For Claim #1: third party auditing the Transparency.dev team</li><li>For Claim #2: the Transparency.dev team</li></ol> |
| **Arbiter** | Log ecosystem participants and reliers |

The **Statement** is defined in
[https://github.com/transparency-dev/armored-witness-common/tree/main/release/firmware/ftlog/log_entries.go](https://github.com/transparency-dev/armored-witness-common/tree/main/release/firmware/ftlog/log_entries.go).
An example is available at
[https://github.com/transparency-dev/armored-witness-common/tree/main/release/firmware/ftlog//example_firmware_release.json](https://github.com/transparency-dev/armored-witness-common/tree/main/release/firmware/ftlog//example_firmware_release.json).
143 changes: 143 additions & 0 deletions release/cloudbuild_ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
steps:
### Build the bootloader binary and upload it to GCS.
# Use the dockerfile to build an image containing the bootloader artifact.
- name: gcr.io/cloud-builders/docker
args:
- build
- --build-arg
- TAMAGO_VERSION=${_TAMAGO_VERSION}
- --build-arg
- LOG_ORIGIN=${_ORIGIN}
- -t
- builder-image
- .
# Prepare a container with a copy of the artifacts.
- name: gcr.io/cloud-builders/docker
args:
- create
- --name
- builder_scratch
- builder-image
# Copy the artifacts from the container to the Cloud Build VM.
- name: gcr.io/cloud-builders/docker
args:
- cp
- builder_scratch:/build
- output
# List the artifacts.
- name: bash
args:
- ls
- output
# Copy the artifacts from the Cloud Build VM to GCS.
- name: gcr.io/cloud-builders/gcloud
entrypoint: bash
args:
- -c
- |
gcloud storage cp \
output/armored-witness-boot.imx \
gs://${_FIRMWARE_BUCKET}/$(sha256sum output/armored-witness-boot.imx | cut -f1 -d" ")
### Construct log entry / Claimant Model statement.
# This step needs to be a bash script in order to substitute the fake tag in
# the command args.
- name: golang
entrypoint: bash
args:
- -c
- |
go run github.com/transparency-dev/armored-witness/cmd/manifest@${_ARMORED_WITNESS_REPO_VERSION} \
create \
--git_tag=${_MANUAL_TAG} \
--git_commit_fingerprint=${COMMIT_SHA}
--firmware_file=output/armored-witness-boot.imx \
--firmware_type=BOOTLOADER \
--tamago_version=${_TAMAGO_VERSION} \
--raw \
--output_file=output/boot_manifest_unsigned.json
# Sign the log entry.
- name: golang
args:
- go
- run
- github.com/transparency-dev/armored-witness/cmd/sign@${_ARMORED_WITNESS_REPO_VERSION}
- --project_name=${PROJECT_ID}
- --release=ci
- --artefact=boot
- --manifest_file=output/boot_manifest_unsigned.json
- --output_file=output/boot_manifest
# Print the content of the signed manifest.
- name: bash
args:
- cat
- output/boot_manifest
### Write the firmware release to the transparency log.
# Copy the log entry to the sequence bucket, preparing to write to log.
#
# Use the SHA256 of the manifest as the name of the manifest. This allows
# multiple triggers to run without colliding.
- name: gcr.io/cloud-builders/gcloud
entrypoint: bash
args:
- -c
- |
gcloud storage cp output/boot_manifest \
gs://${_LOG_NAME}/${_ENTRIES_DIR}/$(sha256sum output/boot_manifest | cut -f1 -d" ")
# Sequence log entry.
- - name: gcr.io/cloud-builders/gcloud
args:
- functions
- call
- sequence
- '--data'
- >-
{
"entriesDir": "${_ENTRIES_DIR}",
"origin": "${_ORIGIN}",
"bucket": "${_LOG_NAME}",
"kmsKeyName": "ft-log-ci",
"kmsKeyRing": "firmware-release-ci",
"kmsKeyVersion": ${_KEY_VERSION},
"kmsKeyLocation": "global",
"noteKeyName": "transparency.dev-aw-ftlog-ci",
"checkpointCacheControl": "${_CHECKPOINT_CACHE}"
}
# Integrate log entry.
- name: gcr.io/cloud-builders/gcloud
args:
- functions
- call
- integrate
- --data
- >-
{
"origin": "${_ORIGIN}",
"bucket": "${_LOG_NAME}",
"kmsKeyName": "ft-log-ci",
"kmsKeyRing": "firmware-release-ci",
"kmsKeyVersion": ${_KEY_VERSION},
"kmsKeyLocation": "global",
"noteKeyName": "transparency.dev-aw-ftlog-ci",
"checkpointCacheControl": "${_CHECKPOINT_CACHE}"
}
# Clean up the file we added to the _ENTRIES_DIR bucket now that it's been
# integrated to the log.
- name: gcr.io/cloud-builders/gcloud
entrypoint: bash
args:
- -c
- |
gcloud storage rm \
gs://${_LOG_NAME}/${_ENTRIES_DIR}/$(sha256sum output/boot_manifest | cut -f1 -d" ")
substitutions:
# Build-related.
_FIRMWARE_BUCKET: armored-witness-firmware-ci-1
_MANUAL_TAG: 0.0.0
_TAMAGO_VERSION: '1.21.3'
# Log-related.
_ARMORED_WITNESS_REPO_VERSION: d37d6b19ec4dbd1cad3586ae8ba3ec913829d718
# This must correspond with the trailing number on the _FIRMWARE_BUCKET, _ORIGIN, _LOG_NAME values.
_KEY_VERSION: '1'
_LOG_NAME: armored-witness-firmware-log-ci-1
_ORIGIN: transparency.dev/armored-witness/firmware_transparency/ci/1
_CHECKPOINT_CACHE: 'public, max-age=30'
63 changes: 63 additions & 0 deletions release/cloudbuild_presubmit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
steps:
### Build the bootloader binary and upload it to GCS.
# Use the dockerfile to build an image containing the bootloader artifact.
- name: gcr.io/cloud-builders/docker
args:
- build
- --build-arg
- TAMAGO_VERSION=${_TAMAGO_VERSION}
- --build-arg
- LOG_ORIGIN=${_ORIGIN}
- -t
- builder-image
- .
# Prepare a container with a copy of the artifacts.
- name: gcr.io/cloud-builders/docker
args:
- create
- --name
- builder_scratch
- builder-image
# Copy the artifacts from the container to the Cloud Build VM.
- name: gcr.io/cloud-builders/docker
args:
- cp
- builder_scratch:/build
- output
# List the artifacts.
- name: bash
args:
- ls
- output
### Construct log entry / Claimant Model statement.
# This step needs to be a bash script in order to substitute the fake tag in
# the command args.
- name: golang
entrypoint: bash
args:
- -c
- |
go run github.com/transparency-dev/armored-witness/cmd/manifest@${_ARMORED_WITNESS_REPO_VERSION} \
create \
--git_tag=${_MANUAL_TAG} \
--git_commit_fingerprint=${COMMIT_SHA} \
--firmware_file=output/armored-witness-boot.imx \
--firmware_type=BOOTLOADER \
--tamago_version=${_TAMAGO_VERSION} \
--raw \
--output_file=output/boot_manifest_unsigned.json
# TODO: sign the log entry with github.com/transparency-dev/armored-witness/cmd/sign
# after we create presubmit keys.
#
# Print the content of the signed manifest.
- name: bash
args:
- cat
- output/boot_manifest_unsigned.json
substitutions:
# Build-related.
_MANUAL_TAG: 0.0.0
_TAMAGO_VERSION: '1.21.3'
_ORIGIN: transparency.dev/armored-witness/firmware_transparency/ci/1
# Log-related.
_ARMORED_WITNESS_REPO_VERSION: d37d6b19ec4dbd1cad3586ae8ba3ec913829d718

0 comments on commit 3ff2cf0

Please sign in to comment.