NitroKeys are a personal security token used to hold the signing keys for TEST and DEV devices. NitroKeys can be used to sign tests and binaries for devices in the TEST or DEV lifecycle states.
In order to sign with a NitroKey, you need to configure a profile for your NitroKey. The profile is defined by the keyset you want to use for signing. The configuration should map the profile name to the specific token holding the private key material for the named keyset.
For example, a configuration for //sw/device/silicon_creator/rom/keys/real/rsa:keyset
might look like the following:
Locate this file in $HOME/.config/hsmtool/profiles.json and set the file mode to 600.
{
"earlgrey_a0": {
"token": "earlgrey_a0_000",
"user": "user",
"pin": "xxxxxx"
}
}
Once a profile configuration is in place, you can build binaries signed by the keyset by telling bazel that you want to use a token.
In the example below, we instruct bazel to use a NitroKey as the token
and to sign with the key specified by the rsa_key
attribute of the target
(or the target's exec_env
).
bazel build --//signing:token=//signing/tokens:nitrokey //label-of-target
To sign with an alternate key, you can override the key label via the
keyset in question. For silicon_creator
code, the keyset is
//sw/device/silicon_creator/rom/keys/real/rsa:keyset
.
bazel build \
--//signing:token=//signing/tokens:nitrokey \
--//sw/device/silicon_creator/rom/keys/real/rsa:keyset=earlgrey_a0_dev_0 \
//label-of-target
The production SiVAL ROM_EXT expects a signing key held in Google's cloud-kms service.
You need an hsmtool profile that maps to the cloud-kms token. Add an entry to your profiles confiuration file:
Locate this file in $HOME/.config/hsmtool/profiles.json and set the file mode to 600.
{
"earlgrey_z0_sival": {
"token": "ot-earlgrey-z0-sival",
"user": "user"
}
}
The configuration file may contain more than one token configuration, for example:
{
"earlgrey_a0": {
"token": "earlgrey_a0_000",
"user": "user",
"pin": "XXXXXX"
},
"earlgrey_z0_sival": {
"token": "ot-earlgrey-z0-sival",
"user": "user"
}
}
In order to sign with the cloud-kms key, you need to authenticate to Google cloud using your opentitan.org account.
See additional instructions on how to install the
google-cloud-cli
package for various OS distributions: https://cloud.google.com/sdk/docs/install.You may also want to consider using the snap package in Debian distributions: https://cloud.google.com/sdk/docs/downloads-snap
The
gcloud auth login
andgcloud auth application-default login
commands should open a webpage to select the account you want to use to login. The page may take a while to load, and in some cases you may have to copy paste the URL printed by the CLI into a browser to start the login process.Make sure to use your opentitan.org account to login.
# Install the Google cloud CLI if you don't already have it.
sudo apt install -y google-cloud-cli
# Log into GCP using your opentitan.org credentials
gcloud auth login
# Application default authentication
gcloud auth application-default login
Once authenticated to Google cloud, you can build and sign SiVAL tests
by requesting the cloud_kms
token:
You may have to update the permissions on the KMS configuration file as follows:
chmod 600 signing/tokens/earlgrey_z1_sival.yaml
bazel build --//signing:token=//signing/tokens:cloud_kms //label-of-target
This demonstration of the offline signing flow does not use an HSM. It uses opentitantool to generate the image digests and to create the detached signatures. Finally, it attaches the signatures to the binaries and emits signed artifacts.
Generating the pre-signing artifacts builds the requested targets and updates the manifest and public key. Then, SHA256 digests are computed for each binary.
bazel build //signing/examples:digests
The bazel offline_presigning_artifacts
rule updates the binary with
a supplied manifest and public key:
opentitantool \
image manifest update \
--manifest=<manifest file> \
--key-file=<public key file> \
--output=<pre-signed binary> \
<original binary>
Having updated the manifest and public key, the rule then generates the SHA256 digest to be signed:
opentitantool \
image digest \
--bin=<sha256 digest> \
<pre-signed binary>
Normally, in this step, the pre-signing artifacts would be taken to the secure facility and a signing ceremony would be performed to create the detached signatures.
bazel build //signing/examples:fake
The bazel offline_fake_sign
rule performs the same RSA signing
operation as the HSM would perform, but public test keys are used
instead of the real keys:
opentitantool \
rsa sign \
--input=<sha256 digest> \
--output=<signed digest> \
<private key file>
Normally, in this step, the signatures created in the signing ceremony would be copied into the target directory.
cp -f bazel-bin/signing/examples/*.sig signing/examples/signatures/
The detached signatures are attached to the pre-signing binaries and final signed binaries are produced.
bazel build //signing/examples:signed
The bazel offline_signature_attach
rule takes the signed digests and
attaches them to the pre-signed binaries, thus producing signed binaries
that can be verified by the ROM.
opentitantool \
image manifest update \
--signature-file=<signed digest> \
--output=<final signed binary> \
<pre-signed binary>
cd $REPO_TOP
bazel run //sw/host/opentitantool -- \
image manifest show \
$PWD/bazel-bin/signing/examples/hello_world_fpga_cw310.signed.bin