Skip to content

Commit f60de60

Browse files
authored
Merge pull request #465 from danielinux/azure-keyvault-docs
Added documentation for signing with Azure Key Vault
2 parents 918fdc5 + 06c5280 commit f60de60

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

docs/Signing.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,7 @@ openssl pkeyutl -sign -keyform der -inkey my_key.der -in test-app/image_v1_diges
280280
tools/bin-assemble/bin-assemble factory.bin 0x0 wolfboot.bin \
281281
0xc0000 test-app/image_v1_signed.bin
282282
```
283+
284+
### Signing Firmware with Azure Key Vault
285+
286+
See [docs/azure_keyvault.md](/docs/azure_keyvault.md).

docs/azure_keyvault.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
## Signing firmware using Microsoft Azure Key Vault
2+
3+
Microsoft offers secure key management and provisioning tools, using keys stored
4+
in HSMs. This mechanisms helps to centralize key management for several purposes,
5+
including the support for signing payloads using the managed keys, which can be
6+
used in combination with wolfBoot for provisioning public keys in a fleet of
7+
devices.
8+
9+
10+
### Preparing the keystore
11+
12+
wolfBoot can import public keys in the keystore using the `keygen` command line
13+
tool provided. `keygen` supports both raw ECC keys and ASN.1 format (.der).
14+
15+
Azure allows to download the public keys in ASN.1 format to provision the device.
16+
To retrieve each public key to use for firmware authentication in wolfBoot, use:
17+
18+
```sh
19+
az keyvault key download --vault-name <vault-name> -n test-signing-key-1 -e DER -f public-key-1.der
20+
```
21+
22+
A keystore can now be created importing the public keys and with `keygen`'s `-i`
23+
(import) option. The option may be repeated multiple times to add more keys to
24+
the keystore.
25+
26+
```sh
27+
./tools/keytools/keygen --ecc256 -i public-key-1.der [-i public-key-2.der ...]
28+
```
29+
30+
### Signing the firmware image for wolfBoot
31+
32+
The signing operation using any external HSM is performed through three-steps,
33+
as described in the relevant section in [Signing.md](signing.md).
34+
In this section we describe the procedure to sign the firmware image using Azure key vault.
35+
36+
37+
#### Obtaining the SHA256 digest
38+
39+
Step 1 consists in calling the `./sign` tool with the extra `--sha-only` argument,
40+
to generate the digest to sign. The public key associated to the selected signing
41+
key in the vault needs to be provided:
42+
43+
```sh
44+
./tools/keytools/sign --ecc256 --sha-only --sha256 test-app/image.bin public-key-1.der 1
45+
```
46+
47+
To fit in a https REST request, the digest obtained must be encoded using base64:
48+
49+
```sh
50+
DIGEST=$(cat test-app/image_v1_digest.bin | base64url_encode)
51+
```
52+
53+
The variable `DIGEST` now contains a printable encoding of the key, which can be
54+
attached to the request.
55+
56+
#### HTTPS request for signing the digest with the Key Vault
57+
58+
59+
To prepare the request, first get an access token from the vault and store it in a variable:
60+
61+
```sh
62+
ACCESS_TOKEN=$(az account get-access-token --resource "https://vault.azure.net" --query "accessToken" -o tsv)
63+
```
64+
65+
Use the URL associated to the selected key vault:
66+
67+
```sh
68+
KEY_IDENTIFIER="https://<vault-name>.vault.azure.net/keys/test-signing-key"
69+
```
70+
71+
Perform the request using cURL, and store the result in a variable:
72+
73+
```sh
74+
SIGNING_RESULT=$(curl -X POST \
75+
-s "${KEY_IDENTIFIER}/sign?api-version=7.4" \
76+
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
77+
-H "Content-Type:application/json" \
78+
-H "Accept:application/json" \
79+
-d "{\"alg\":\"ES256\",\"value\":\"${DIGEST}\"}")
80+
echo $SIGNING_RESULT
81+
```
82+
83+
The field `.value` in the result contains the (base64 encoded) signature.
84+
To extract the signature from the response, you can use a JSON parser:
85+
86+
```sh
87+
SIGNATURE=$(jq -jn "$SIGNING_RESULT|.value")
88+
```
89+
90+
The signature can now be decoded from base64 into a binary, so the
91+
`sign` tool can incorporate the signature into the manifest header.
92+
93+
```sh
94+
echo $SIGNATURE| base64url_decode > test-app/image_v1_digest.sig
95+
```
96+
97+
#### Final step: create the signed firmware image
98+
99+
The 'third step' in the HSM three-steps procedure requires the `--manual-sign` option and the
100+
signature obtained through the Azure REST API.
101+
102+
103+
```
104+
./tools/keytools/sign --ecc256 --sha256 --manual-sign test-app/image.bin test-signin-key_pub.der 1 test-app/image_v1_digest.sig
105+
```
106+
107+
The resulting binary file `image_v1_signed.bin` will now contain a signed firmware
108+
image that can be authenticated and staged by wolfBoot.
109+

0 commit comments

Comments
 (0)