From 57796c25acb1ab96fffaf947970b5678032c7548 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Wed, 3 Jul 2024 19:46:00 +0200 Subject: [PATCH 1/2] Added documentation for signing with Azure Key Vault --- docs/azure_keyvault.md | 110 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 docs/azure_keyvault.md diff --git a/docs/azure_keyvault.md b/docs/azure_keyvault.md new file mode 100644 index 000000000..894779206 --- /dev/null +++ b/docs/azure_keyvault.md @@ -0,0 +1,110 @@ +## Signing firmware using Microsoft Azure Keyvault + +Microsoft offer secure key management and provisioning tools, using keys stored +in HSMs. This mechanisms helps to centralize key management for several purposes, +including the support for signing payloads using the managed keys, which can be +used in combination with wolfBoot for provisioning public keys in a fleet of +devices. + + +### Preparing the keystore + +wolfBoot can import public keys in the keystore using the `keygen` command line +tool provided. `keygen` supports both raw ECC keys and ASN.1 format (.der). + +Azure allows to download the public keys in ASN.1 format to provision the device. +To retrieve each pukey to use for firmware authentication in wolfBoot, use: + +``` +az keyvault key download --vault-name -n test-signing-key-1 -e DER -f public-key-1.der +``` + +A keystore can now be created importing the public keys and with `keygen`'s `-i` +(import) option. The option may be repeated multiple times to add more keys to +the keystore. + +``` +tools/keytools/keygen --ecc256 -i public-key-1.der [-i public-key-2.der ...] +``` + +### Signing the firmware image for wolfBoot + +The signing operation using any external HSM is performed through three-steps, +as described in the relevant section in [Signing.md](signing.md). +In this section we describe the procedure to sign the firmware image using Azure key vault. + + +#### Obtaining the SHA256 digest + +Step 1 consists in calling the `./sign` tool with the extra `--sha-only` argument, +to generate the digest to sign. The public key associated to the selected signing +key in the vault needs to be provided: + +``` +./sign --ecc256 --sha-only --sha256 test-app/image.bin public-keyi-1.der 1 +``` + +To fit in a https REST request, the digest obtained must be encoded using base64: + +``` +DIGEST=$(cat test-app/image_v1_digest.bin | base64url_encode) + +``` + +The variable `DIGEST` now contains a printable encoding of the key, which can be +attached to the request. + +#### HTTPS request for signing the digest with the Key Vault + + +To prepare the request, first get an access token from the vault and store it in a variable: + +``` +ACCESS_TOKEN=$(az account get-access-token --resource "https://vault.azure.net" --query "accessToken" -o tsv) +``` + +Use the URL associated to the selected key vault: + +``` +KEY_IDENTIFIER="https://.vault.azure.net/keys/test-signing-key" +``` + +Perform the request using cURL, and store the result in a variable: + +``` +SIGNING_RESULT=$(curl -X POST \ + -s "${KEY_IDENTIFIER}/sign?api-version=7.4" \ + -H "Authorization: Bearer ${ACCESS_TOKEN}" \ + -H "Content-Type:application/json" \ + -H "Accept:application/json" \ + -d "{\"alg\":\"ES256\",\"value\":\"${DIGEST}\"}") +echo $SIGNING_RESULT +``` + +The field `.value` in the result contains the (base64 encoded) signature. +To extract the signature from the response, you can use a JSON parser: + +``` +SIGNATURE=$(jq -jn "$SIGNING_RESULT|.value") +``` + +The signature can now be decoded from base64 into a binary, so the +`sign` tool can incorporate the signature into the manifest header. + +``` +echo $SIGNATURE| base64url_decode > test-app/image_v1_digest.sig +``` + +#### Final step: create the signed firmware image + +The 'third step' in the HSM three-steps procedure requires the `--manual-sign` option and the +signature obtained through the Azure REST API. + + +``` +./sign --ecc256 --sha256 --manual-sign test-app/image.bin test-signin-key_pub.der 1 test-app/image_v1_digest.sig +``` + +The resulting binary file `image_v1_signed.bin` will now contain a signed firmware +image that can be authenticated and staged by wolfBoot. + From 06c52802112799ef1b3ed4387ad08db997cfd837 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 3 Jul 2024 11:37:41 -0700 Subject: [PATCH 2/2] Minor doc fixes. --- docs/Signing.md | 4 ++++ docs/azure_keyvault.md | 39 +++++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/docs/Signing.md b/docs/Signing.md index f0b73d7b5..728d27840 100644 --- a/docs/Signing.md +++ b/docs/Signing.md @@ -280,3 +280,7 @@ openssl pkeyutl -sign -keyform der -inkey my_key.der -in test-app/image_v1_diges tools/bin-assemble/bin-assemble factory.bin 0x0 wolfboot.bin \ 0xc0000 test-app/image_v1_signed.bin ``` + +### Signing Firmware with Azure Key Vault + +See [docs/azure_keyvault.md](/docs/azure_keyvault.md). diff --git a/docs/azure_keyvault.md b/docs/azure_keyvault.md index 894779206..d9f2c40de 100644 --- a/docs/azure_keyvault.md +++ b/docs/azure_keyvault.md @@ -1,6 +1,6 @@ -## Signing firmware using Microsoft Azure Keyvault +## Signing firmware using Microsoft Azure Key Vault -Microsoft offer secure key management and provisioning tools, using keys stored +Microsoft offers secure key management and provisioning tools, using keys stored in HSMs. This mechanisms helps to centralize key management for several purposes, including the support for signing payloads using the managed keys, which can be used in combination with wolfBoot for provisioning public keys in a fleet of @@ -13,18 +13,18 @@ wolfBoot can import public keys in the keystore using the `keygen` command line tool provided. `keygen` supports both raw ECC keys and ASN.1 format (.der). Azure allows to download the public keys in ASN.1 format to provision the device. -To retrieve each pukey to use for firmware authentication in wolfBoot, use: +To retrieve each public key to use for firmware authentication in wolfBoot, use: -``` +```sh az keyvault key download --vault-name -n test-signing-key-1 -e DER -f public-key-1.der ``` A keystore can now be created importing the public keys and with `keygen`'s `-i` -(import) option. The option may be repeated multiple times to add more keys to +(import) option. The option may be repeated multiple times to add more keys to the keystore. -``` -tools/keytools/keygen --ecc256 -i public-key-1.der [-i public-key-2.der ...] +```sh +./tools/keytools/keygen --ecc256 -i public-key-1.der [-i public-key-2.der ...] ``` ### Signing the firmware image for wolfBoot @@ -40,15 +40,14 @@ Step 1 consists in calling the `./sign` tool with the extra `--sha-only` argumen to generate the digest to sign. The public key associated to the selected signing key in the vault needs to be provided: -``` -./sign --ecc256 --sha-only --sha256 test-app/image.bin public-keyi-1.der 1 +```sh +./tools/keytools/sign --ecc256 --sha-only --sha256 test-app/image.bin public-key-1.der 1 ``` To fit in a https REST request, the digest obtained must be encoded using base64: -``` +```sh DIGEST=$(cat test-app/image_v1_digest.bin | base64url_encode) - ``` The variable `DIGEST` now contains a printable encoding of the key, which can be @@ -59,19 +58,19 @@ attached to the request. To prepare the request, first get an access token from the vault and store it in a variable: -``` +```sh ACCESS_TOKEN=$(az account get-access-token --resource "https://vault.azure.net" --query "accessToken" -o tsv) ``` Use the URL associated to the selected key vault: -``` +```sh KEY_IDENTIFIER="https://.vault.azure.net/keys/test-signing-key" ``` Perform the request using cURL, and store the result in a variable: -``` +```sh SIGNING_RESULT=$(curl -X POST \ -s "${KEY_IDENTIFIER}/sign?api-version=7.4" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ @@ -84,27 +83,27 @@ echo $SIGNING_RESULT The field `.value` in the result contains the (base64 encoded) signature. To extract the signature from the response, you can use a JSON parser: -``` +```sh SIGNATURE=$(jq -jn "$SIGNING_RESULT|.value") ``` The signature can now be decoded from base64 into a binary, so the `sign` tool can incorporate the signature into the manifest header. -``` +```sh echo $SIGNATURE| base64url_decode > test-app/image_v1_digest.sig ``` #### Final step: create the signed firmware image -The 'third step' in the HSM three-steps procedure requires the `--manual-sign` option and the +The 'third step' in the HSM three-steps procedure requires the `--manual-sign` option and the signature obtained through the Azure REST API. -``` -./sign --ecc256 --sha256 --manual-sign test-app/image.bin test-signin-key_pub.der 1 test-app/image_v1_digest.sig +``` +./tools/keytools/sign --ecc256 --sha256 --manual-sign test-app/image.bin test-signin-key_pub.der 1 test-app/image_v1_digest.sig ``` The resulting binary file `image_v1_signed.bin` will now contain a signed firmware image that can be authenticated and staged by wolfBoot. - +