Skip to content

Commit 7fee423

Browse files
committed
rpifwcrpto: Describe exit/usage codes and make it easier to copy and paste CLI examples
1 parent c8fab06 commit 7fee423

1 file changed

Lines changed: 129 additions & 31 deletions

File tree

rpifwcrypto/README.md

Lines changed: 129 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,98 @@ Although this service can be used via raw vcmailbox commands the
1616
recommended API is either the command line rpi-fw-crypto application
1717
or the librpifwcrypto.so shared library.
1818

19-
**Build Instructions**
20-
Install prerequisites with "sudo apt install cmake libgnutls28-dev"" - you need at least version 3.10.
21-
22-
- *mkdir build*
23-
- *cd build*
24-
- *cmake ..*
25-
- *make*
26-
- *sudo make install*
27-
28-
**Usage**
29-
30-
* rpi-fw-crypto -h (Displays usage instructions for all operations)
31-
* rpi-fw-crypto get-num-otp-keys (Returns the number of OTP key slots)
32-
* rpi-fw-crypto sign --in message.bin --key-id 1 --alg ec --out sig.bin (Signs message.bin with the device unique OTP key (id 1))
33-
* rpi-fw-crypto get-key-status 1 (Gets the status of key-id 1)
34-
* rpi-fw-crypto set-key-status 1 LOCKED (Blocks the raw OTP read API on this key until the device is rebooted)
35-
* rpi-fw-crypto get-key-usage 1 (Gets the usage of key-id 1)
36-
* rpi-fw-crypto set-key-usage 1 0x1 (Sets the usage of key-id 1 to RPI_CONNECT in OTP)
37-
* rpi-fw-crypto hmac --in message.bin --key-id 1 --out hmac.bin (Generates the SHA256 HMAC of message.bin and OTP key id 1)
38-
* rpi-fw-crypto pubkey --key-id 1 --out device-pub.der (Derives and retrieves the corresponding public key for the specified device private ECDSA P256 key)
39-
* rpi-fw-crypto privkey --key-id 1 --out device-priv.der (Retrieves the device private key - in DER form - will error if key status is locked)
40-
* rpi-fw-crypto genkey --key-id 1 --alg ec (Generates an ECDSA P256 key-pair and writes the private key to the OTP)
41-
42-
**Locking the device private key**
19+
## Build Instructions
20+
21+
Install prerequisites with `sudo apt install cmake libgnutls28-dev` - you need at least version 3.10.
22+
23+
```
24+
mkdir build
25+
cd build
26+
cmake ..
27+
make
28+
sudo make install
29+
```
30+
31+
## Usage
32+
33+
Display usage instructions for all operations:
34+
35+
```
36+
rpi-fw-crypto -h
37+
```
38+
39+
Return the number of OTP key slots:
40+
41+
```
42+
rpi-fw-crypto get-num-otp-keys
43+
```
44+
45+
Sign message.bin with the device unique OTP key (id 1):
46+
47+
```
48+
rpi-fw-crypto sign --in message.bin --key-id 1 --alg ec --out sig.bin
49+
```
50+
51+
Get the status of key-id 1:
52+
53+
```
54+
rpi-fw-crypto get-key-status 1
55+
```
56+
57+
Block the raw OTP read API on key-id 1 until the device is rebooted:
58+
59+
```
60+
rpi-fw-crypto set-key-status 1 LOCKED
61+
```
62+
63+
Get the usage of key-id 1:
64+
65+
```
66+
rpi-fw-crypto get-key-usage 1
67+
```
68+
69+
Set the usage of key-id 1 to RPI_CONNECT in OTP:
70+
71+
```
72+
rpi-fw-crypto set-key-usage 1 0x1
73+
```
74+
75+
The key usage is stored in OTP and records what the key is used for
76+
(`RPI_FW_CRYPTO_KEY_USAGE` in `rpifwcrypto.h`):
77+
78+
| Value | Usage | Description |
79+
|-------|-------|-------------|
80+
| 0x0 | `UNDEFINED` | Key usage has not been set |
81+
| 0x1 | `RPI_CONNECT` | Raspberry Pi Connect device key |
82+
| 0x2 - 0x7 | `RPI_RESERVED_0` - `RPI_RESERVED_5` | Reserved for use by Raspberry Pi |
83+
| 0x8 - 0xE | `USER_DEFINED_0` - `USER_DEFINED_6` | Available for user-defined purposes |
84+
| 0xF | `INVALID` | Invalid / not usable |
85+
86+
Generate the SHA256 HMAC of message.bin and OTP key id 1:
87+
88+
```
89+
rpi-fw-crypto hmac --in message.bin --key-id 1 --out hmac.bin
90+
```
91+
92+
Derive and retrieve the corresponding public key for the specified device private ECDSA P256 key:
93+
94+
```
95+
rpi-fw-crypto pubkey --key-id 1 --out device-pub.der
96+
```
97+
98+
Retrieve the device private key in DER form - will error if key status is locked:
99+
100+
```
101+
rpi-fw-crypto privkey --key-id 1 --out device-priv.der
102+
```
103+
104+
Generate an ECDSA P256 key-pair and write the private key to the OTP:
105+
106+
```
107+
rpi-fw-crypto genkey --key-id 1 --alg ec
108+
```
109+
110+
## Locking the device private key
43111

44112
Access to the device private key can be locked by default at boot by setting
45113
`lock_device_private_key=1` in config.txt. This blocks the raw OTP read API
@@ -50,7 +118,7 @@ The contents of config.txt (within boot.img) is authenticated by the firmware
50118
if secure-boot is enabled and `lock_device_private_key=1` should always be
51119
specified if secure-boot is enabled.
52120

53-
**OpenSSL equivalents**
121+
## OpenSSL equivalents
54122

55123
The firmware uses MbedTLS to implement the cryptographic operations. For
56124
reference / test, here are the OpenSSL equivalents. In these examples
@@ -62,22 +130,37 @@ rpi-fw-crypto privkey --key-id 1 --out device-priv.der
62130
openssl ec -inform DER -in device-priv.der -outform PEM -out private_key.pem
63131
```
64132

133+
**sign** - SHA256 hash of the input, ECDSA P-256 signature in DER form:
134+
65135
```
66-
# sign - SHA256 hash of the input, ECDSA P-256 signature in DER form
67136
openssl pkeyutl -sign -inkey private_key.pem -rawin -in message.bin -out sig.bin
137+
```
138+
139+
**verify** - check a signature with the device public key:
140+
141+
```
68142
openssl pkeyutl -verify -pubin -inkey device-pub.der -sigfile sig.bin -rawin -in message.bin
143+
```
144+
145+
**hmac** - HMAC-SHA256 keyed with the raw 32-byte OTP key value:
69146

70-
# hmac - HMAC-SHA256 keyed with the raw 32-byte OTP key value
147+
```
71148
openssl dgst -sha256 -mac HMAC -macopt hexkey:"$(rpi-otp-private-key)" message.bin
149+
```
72150

73-
# pubkey - DER (SubjectPublicKeyInfo) public key derived from the private key
151+
**pubkey** - DER (SubjectPublicKeyInfo) public key derived from the private key:
152+
153+
```
74154
openssl ec -in private_key.pem -pubout -outform DER -out device-pub.der
155+
```
156+
157+
**genkey** - ECDSA P-256 (prime256v1) key-pair generation:
75158

76-
# genkey - ECDSA P-256 (prime256v1) key-pair generation
159+
```
77160
openssl ecparam -name prime256v1 -genkey -noout -out private_key.pem
78161
```
79162

80-
**Error handling and debug**
163+
## Error handling and debug
81164

82165
If the firmware reports an error then `rpi-fw-crypto` prints the error
83166
e.g. `Last crypto error: 4 (Key locked)` and sets the exit code to the
@@ -87,7 +170,22 @@ Since shells report exit codes as an unsigned byte this appears as
87170

88171
The firmware logs can be viewed with `sudo vclog -m` for additional debug.
89172

90-
** Notes **
173+
| Code | Status | Description |
174+
|------|--------|-------------|
175+
| 0 | `RPI_FW_CRYPTO_SUCCESS` | Success |
176+
| 1 | `RPI_FW_CRYPTO_ERROR_UNKNOWN` | Unknown error |
177+
| 2 | `RPI_FW_CRYPTO_EINVAL` | Invalid argument errors e.g. zero length etc |
178+
| 3 | `RPI_FW_CRYPTO_KEY_NOT_FOUND` | No key for the given key-id |
179+
| 4 | `RPI_FW_CRYPTO_KEY_LOCKED` | Requested operation for that key is locked |
180+
| 5 | `RPI_FW_CRYPTO_KEY_OTP_ERROR` | OTP read error |
181+
| 6 | `RPI_FW_CRYPTO_KEY_NOT_SET` | Key is all zeros |
182+
| 7 | `RPI_FW_CRYPTO_KEY_INVALID` | Invalid key type/format |
183+
| 8 | `RPI_FW_CRYPTO_NOT_SUPPORTED` | Requested operation is not supported |
184+
| 9 | `RPI_FW_CRYPTO_OPERATION_FAILED` | Crypto algorithm error |
185+
| 10 | `RPI_FW_CRYPTO_KEY_NOT_BLANK` | Key slot is not blank |
186+
187+
## Notes
188+
91189
The device unique private key can also be provisioned with the `rpi-otp-private-key` utility.
92190
This MUST be a raw ECDSA P-256 key and not just a random number.
93191

0 commit comments

Comments
 (0)