diff --git a/sw/device/silicon_creator/manuf/base/BUILD b/sw/device/silicon_creator/manuf/base/BUILD index e081457541f54..17cae39381718 100644 --- a/sw/device/silicon_creator/manuf/base/BUILD +++ b/sw/device/silicon_creator/manuf/base/BUILD @@ -408,7 +408,7 @@ filegroup( ":ft_fw_bundle_{}".format(sku): "bundle", }, changes_otp = True, - data = config["ca_data"], + data = [config["ca_data"]], needs_jtag = True, otp = "//hw/ip/otp_ctrl/data/earlgrey_skus/emulation:otp_img_test_locked0_manuf_initialized", owner_slot_b = OWNER_SLOTS["b"], @@ -435,7 +435,7 @@ filegroup( ":ft_fw_bundle_{}".format(sku): "bundle", }, changes_otp = True, - data = config["ca_data"], + data = [config["ca_data"]], interface = "teacup", needs_jtag = True, owner_slot_b = OWNER_SLOTS["b"], diff --git a/sw/device/silicon_creator/manuf/base/provisioning_inputs.bzl b/sw/device/silicon_creator/manuf/base/provisioning_inputs.bzl index 36124bf15192c..dcdb02bdd468a 100644 --- a/sw/device/silicon_creator/manuf/base/provisioning_inputs.bzl +++ b/sw/device/silicon_creator/manuf/base/provisioning_inputs.bzl @@ -24,7 +24,7 @@ EARLGREY_SKUS = { "emulation": { "otp": "emulation", "ca_config": "//sw/device/silicon_creator/manuf/keys/fake:ca_config.json", - "ca_data": ["//sw/device/silicon_creator/manuf/keys/fake:ca_data"], + "ca_data": "//sw/device/silicon_creator/manuf/keys/fake:ca_data", "dice_libs": ["//sw/device/silicon_creator/lib/cert:dice"], "host_ext_libs": ["@provisioning_exts//:default_ft_ext_lib"], "device_ext_libs": ["@provisioning_exts//:default_perso_fw_ext"], @@ -38,7 +38,7 @@ EARLGREY_SKUS = { "emulation_dice_cwt": { "otp": "emulation", "ca_config": "//sw/device/silicon_creator/manuf/keys/fake:ca_config.json", - "ca_data": ["//sw/device/silicon_creator/manuf/keys/fake:ca_data"], + "ca_data": "//sw/device/silicon_creator/manuf/keys/fake:ca_data", "dice_libs": ["//sw/device/silicon_creator/lib/cert:dice_cwt"], "host_ext_libs": ["@provisioning_exts//:default_ft_ext_lib"], "device_ext_libs": ["@provisioning_exts//:default_perso_fw_ext"], @@ -52,7 +52,7 @@ EARLGREY_SKUS = { "emulation_tpm": { "otp": "emulation", "ca_config": "//sw/device/silicon_creator/manuf/keys/fake:ca_config.json", - "ca_data": ["//sw/device/silicon_creator/manuf/keys/fake:ca_data"], + "ca_data": "//sw/device/silicon_creator/manuf/keys/fake:ca_data", "dice_libs": ["//sw/device/silicon_creator/lib/cert:dice"], "host_ext_libs": ["@provisioning_exts//:default_ft_ext_lib"], "device_ext_libs": [ @@ -68,7 +68,7 @@ EARLGREY_SKUS = { "sival": { "otp": "sival", "ca_config": "//sw/device/silicon_creator/manuf/keys/sival:ca_config.json", - "ca_data": ["//sw/device/silicon_creator/manuf/keys/sival:ca_data"], + "ca_data": "//sw/device/silicon_creator/manuf/keys/sival:ca_data", "dice_libs": ["//sw/device/silicon_creator/lib/cert:dice"], "host_ext_libs": ["@provisioning_exts//:default_ft_ext_lib"], "device_ext_libs": ["@provisioning_exts//:default_perso_fw_ext"], diff --git a/sw/device/silicon_creator/manuf/keys/BUILD b/sw/device/silicon_creator/manuf/keys/BUILD new file mode 100644 index 0000000000000..8a15129980b68 --- /dev/null +++ b/sw/device/silicon_creator/manuf/keys/BUILD @@ -0,0 +1,20 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +load( + "//sw/device/silicon_creator/manuf/base:provisioning_inputs.bzl", + "EARLGREY_SKUS", +) + +package(default_visibility = ["//visibility:public"]) + +exports_files(glob(["**"])) + +filegroup( + name = "ca_data_all", + srcs = depset([ + config["ca_data"] + for _, config in EARLGREY_SKUS.items() + ]).to_list(), +) diff --git a/sw/device/silicon_creator/manuf/keys/README.md b/sw/device/silicon_creator/manuf/keys/README.md new file mode 100644 index 0000000000000..103f7ea3264c8 --- /dev/null +++ b/sw/device/silicon_creator/manuf/keys/README.md @@ -0,0 +1,120 @@ +# CA Endorsement Keys + +Certificate Authority endorsement keys are are used to endorse the following +certificate chains during personalization: +1. DICE attestation certificate chains, and +2. SKU specific certificate chains. + +## Fake Keys + +The fake keys stored here are used for testing purposes only. +The fake keys have been generated using OpenSSL, and the private portion of +the key has been checked into the repository. + +## Real Keys + +The real (private) keys used for the SIVAL SKU are stored on offline HSMs. +The matching public keys and certificates are checked into the repository. + +To use the private keys to endorse the certificates in benchtop provisioning +flow, one must set the following envars: + - `PKCS11_MODULE_PATH`: to point to the PKCS#11 shared library for the + hardware token or HSM they are using, and + - `PKCS11_TOKEN_PIN`: to the PIN used for hardware token / HSM authentication. + +For example, if the SIVAL private keys are stored on a Nitrokey, and you wanted +to test the SIVAL FT provisioning flow, you would issue the following Bazel +command: +```sh +bazel test --test_output=streamed \ + //sw/device/silicon_creator/manuf/base:ft_provision_sival_fpga_hyper310_rom_with_fake_keys \ + --action_env=PKCS11_MODULE_PATH=/opt/nitrokey/lib/libsc-hsm-pkcs11.so \ + --action_env=PKCS11_TOKEN_PIN=123456 +``` + +Note: you may also use `opensc-pkcs11.so` for the `PKCS11_MODULE_PATH`. The +debian package `opensc-pkcs11` installs it as +`/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so`. + +# Generating CA Keys and Root Certificates + +## Generating fake keys and certificates with OpenSSL +### Generating an ECC P256 Keypair with OpenSSL +To generate additional fake keys for testing using OpenSSL, follow these steps: +```sh +# Generate the curve: +$ openssl ecparam -out curve.pem -name prime256v1 + +# Generate the ECC private key in SEC1 PEM format: +$ openssl ecparam -in curve.pem -genkey -out sk.pem + +# Convert the ECC private key from SEC1 format to PKCS8 (we do this because +# the Rust elliptic-curve crate is able to load PKCS8 keys with less additional +# crates): +$ openssl pkcs8 -in sk.pem -topk8 -nocrypt -out sk.pkcs8.der -outform DER + +# Show the ECC public key (not required, but helps confirm the above worked): +$ openssl ec -in sk.pem -text -noout +``` + +### Generating a Root CA Certificate + +To generate a Root CA certificate using the earlier generated private EC key, +you can use the CSR (Certificate Signing Request) configuration file checked in +to this repo (`dice_ca.conf` or `ext_ca.conf`) as in input to the following +OpenSSL commands: +```sh +# Generate the CSR: +$ openssl req -new -key sk.pem -out dice_ca.csr -config ../dice_ca.conf + +# Generate the X.509 certificate in PEM format: +$ openssl x509 -req -in dice_ca.csr -signkey sk.pem -out dice_ca.pem \ + -days 3650 -extfile ../dice_ca.conf -extensions v3_ca + +# Examine the generated certificate: +$ openssl x509 -in dice_ca.pem -text +``` + +## Generating a root CA certificate from a real hardware token held key + +To generate a Root CA certificate from a public key held on a hardware token, +e.g., Nitrokey, you may use the CSR (Certificate Signing Request) configuration +file checked in to this repo (`dice_ca.conf`) as in input to the following +commands: +```sh +# Set the PKCS11_MODULE_PATH envar to point to the shared library for the +# hardware token you are using, e.g.: +export PKCS11_MODULE_PATH=/opt/nitrokey/lib/libsc-hsm-pkcs11.so +export HW_TOKEN_PIN=123456 + +# Generate the CSR: +openssl req -new -engine pkcs11 -keyform engine -config ../dice_ca.conf -out dice_ca.csr \ + -key "pkcs11:pin-value=${HW_TOKEN_PIN};object=sv00-earlgrey-a1-ca-dice-0" + +# Generate the X.509 certificate in PEM format: +openssl x509 -req -engine pkcs11 -keyform engine -in dice_ca.csr -out dice_ca.pem \ + -days 3650 -extfile ../dice_ca.conf -extensions v3_ca \ + -signkey "pkcs11:pin-value=${HW_TOKEN_PIN};object=sv00-earlgrey-a1-ca-dice-0" + +# Examine the generated certificate: +openssl x509 -in dice_ca.pem -text +``` + +# Generating the RMA unlock token encryption keypair with OpenSSL + +The RMA unlock token encryption keypair is an RSA-3072 key used to encrypt the +RMA unlock token generated during provisioning. + +The fake keys (used for testing) in this subdirectory were generated with `openssl`. + +``` +### Generate the RSA keypair: +$ openssl genrsa -out rma_unlock_enc_rsa3072.pem 3072 + +### Extract the public key to a separate file: +$ openssl rsa -in rma_unlock_enc_rsa3072.pem -pubout -out rma_unlock_enc_rsa3072.pub.pem + +### Convert the PEM files to DER files: +$ openssl rsa -in rma_unlock_enc_rsa3072.pem -outform der -out rma_unlock_enc_rsa3072.der +$ openssl rsa -pubin -in rma_unlock_enc_rsa3072.pub.pem -outform der -out rma_unlock_enc_rsa3072.pub.der +``` diff --git a/sw/device/silicon_creator/manuf/keys/fake/README.md b/sw/device/silicon_creator/manuf/keys/fake/README.md deleted file mode 100644 index 66fbb798c8a8c..0000000000000 --- a/sw/device/silicon_creator/manuf/keys/fake/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# CA Endorsement Keys - -Certificate Authority endorsement keys are are used to endorse the following -certificate chains during personalization: -1. DICE attestation certificate chains, and -2. SKU specific certificate chains. - -The fake keys stored here are used for testing purposes only. -These fake keys have been generated using OpenSSL, and the private portion of -the key has been checked into the repository. - -# Generating CA Keys and a Root Certificate with OpenSSL - -## Generating an ECC P256 Keypair with OpenSSL -To generate additional fake keys for testing using OpenSSL, follow these steps: -```sh -# Generate the curve: -$ openssl ecparam -out curve.pem -name prime256v1 - -# Generate the ECC private key in SEC1 PEM format: -$ openssl ecparam -in curve.pem -genkey -out sk.pem - -# Convert the ECC private key from SEC1 format to PKCS8 (we do this because -# the Rust elliptic-curve crate is able to load PKCS8 keys with less additional -# crates): -$ openssl pkcs8 -in sk.pem -topk8 -nocrypt -out sk.pkcs8.der -outform DER - -# Show the ECC public key (not required, but helps confirm the above worked): -$ openssl ec -in sk.pem -text -noout -``` - -## Generating a Root CA Certificate - -To generate a Root CA certificate using the earlier generated private EC key, -you can use the CSR (Certificate Signing Request) configuration file checked in -to this repo (`dice_ca.conf` or `ext_ca.conf`) as in input to the following -OpenSSL commands: -```sh -# Generate the CSR: -$ openssl req -new -key sk.pem -out dice_ca.csr -config ../dice_ca.conf - -# Generate the X.509 certificate in PEM format: -$ openssl x509 -req -in dice_ca.csr -signkey sk.pem -out dice_ca.pem \ - -days 3650 -extfile ../dice_ca.conf -extensions v3_ca - -# Examine the generated certificate: -$ openssl x509 -in dice_ca.pem -text -``` - -# Generating the RMA unlock token encryption keypair with OpenSSL - -The RMA unlock token encryption keypair is an RSA-3072 key used to encrypt the -RMA unlock token generated during provisioning. - -The fake keys (used for testing) in this subdirectory were generated with `openssl`. - -``` -### Generate the RSA keypair: -$ openssl genrsa -out rma_unlock_enc_rsa3072.pem 3072 - -### Extract the public key to a separate file: -$ openssl rsa -in rma_unlock_enc_rsa3072.pem -pubout -out rma_unlock_enc_rsa3072.pub.pem - -### Convert the PEM files to DER files: -$ openssl rsa -in rma_unlock_enc_rsa3072.pem -outform der -out rma_unlock_enc_rsa3072.der -$ openssl rsa -pubin -in rma_unlock_enc_rsa3072.pub.pem -outform der -out rma_unlock_enc_rsa3072.pub.der -``` diff --git a/sw/device/silicon_creator/manuf/keys/sival/BUILD b/sw/device/silicon_creator/manuf/keys/sival/BUILD index 1c0ec1be0de75..946cf93e862c0 100644 --- a/sw/device/silicon_creator/manuf/keys/sival/BUILD +++ b/sw/device/silicon_creator/manuf/keys/sival/BUILD @@ -12,6 +12,7 @@ filegroup( ":ca_config.json", ":dice_ca.pem", ":rma_unlock_enc_rsa3072.pub.der", + # The fake RMA unlock token wrapping key is used for FPGA testing. "//sw/device/silicon_creator/manuf/keys/fake:rma_unlock_enc_rsa3072.pub.der", ], ) diff --git a/sw/device/silicon_creator/manuf/keys/sival/README.md b/sw/device/silicon_creator/manuf/keys/sival/README.md deleted file mode 100644 index e3972009ad630..0000000000000 --- a/sw/device/silicon_creator/manuf/keys/sival/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# CA Endorsement Keys - -Certificate Authority endorsement keys are are used to endorse the following -certificate chains during personalization: -1. DICE attestation certificate chains, and -2. SKU specific certificate chains. - -The real (private) keys used for the SIVAL SKU are stored on offline HSMs. The -matching public keys and certificates are checked into the repository. - -To use the private keys to endorse the certificates in benchtop provisioning -flow, one must set the following envars: - - `PKCS11_MODULE_PATH`: to point to the PKCS#11 shared library for the - hardware token they are using, and - - `PKCS11_TOKEN_PIN`: to the PIN used for hardware token authentication. - -For example, if the SIVAL private keys are stored on a Nitrokey, and you wanted -to test the SIVAL FT provisioning flow, you would issue the following Bazel -command: -```sh -bazel test --test_output=streamed \ - //sw/device/silicon_creator/manuf/base:ft_provision_sival_fpga_hyper310_rom_with_fake_keys \ - --action_env=PKCS11_MODULE_PATH=/opt/nitrokey/lib/libsc-hsm-pkcs11.so \ - --action_env=PKCS11_TOKEN_PIN= -``` - -Note: you may also use `opensc-pkcs11.so` for the `PKCS11_MODULE_PATH`. The -debian package `opensc-pkcs11` installs it as -`/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so`. - -## Generating a Root CA Certificate from a Token Held ECDSA Key - -To generate a Root CA certificate from a public key held on a hardware token, -e.g., Nitrokey, you may use the CSR (Certificate Signing Request) configuration -file checked in to this repo (`dice_ca.conf`) as in input to the following -commands: -```sh -# Set the PKCS11_MODULE_PATH envar to point to the shared library for the -# hardware token you are using, e.g.: -export PKCS11_MODULE_PATH=/opt/nitrokey/lib/libsc-hsm-pkcs11.so - -# Generate the CSR: -openssl req -new -engine pkcs11 -keyform engine -config ../dice_ca.conf -out dice_ca.csr \ - -key "pkcs11:pin-value=;object=sv00-earlgrey-a1-ca-dice-0" - -# Generate the X.509 certificate in PEM format: -openssl x509 -req -engine pkcs11 -keyform engine -in dice_ca.csr -out dice_ca.pem \ - -days 3650 -extfile ../dice_ca.conf -extensions v3_ca \ - -signkey "pkcs11:pin-value=694201;object=sv00-earlgrey-a1-ca-dice-0" - -# Examine the generated certificate: -openssl x509 -in dice_ca.pem -text -``` diff --git a/sw/host/provisioning/orchestrator/src/BUILD b/sw/host/provisioning/orchestrator/src/BUILD index 86e76f52f9448..13a705dc1cd82 100644 --- a/sw/host/provisioning/orchestrator/src/BUILD +++ b/sw/host/provisioning/orchestrator/src/BUILD @@ -76,8 +76,7 @@ filegroup( "//sw/device/silicon_creator/manuf/base:ft_personalize_all", "//sw/device/silicon_creator/manuf/base:sram_cp_provision", "//sw/device/silicon_creator/manuf/base:sram_ft_individualize_all", - "//sw/device/silicon_creator/manuf/keys/fake:ca_data", - "//sw/device/silicon_creator/manuf/keys/sival:ca_data", + "//sw/device/silicon_creator/manuf/keys:ca_data_all", "//sw/host/provisioning/cp", "//sw/host/provisioning/ft:ft_all", "//sw/host/provisioning/orchestrator/configs/skus:sku_all",