github.com/google/trillian-examples@v0.0.0-20240520080811-0d40d35cef0e/binary_transparency/firmware/README.md (about) 1 Firmware Transparency 2 ===================== 3 4 This directory contains a demonstration of applying transparency patterns and 5 principles to the problem of firmware updates. In particular it will focus on 6 making firmware updates for a small compute platform discoverable. 7 8 See below for implementation status. 9 10 Background 11 ---------- 12 13 **Firmware is ubiquitous**; it's in your phone, watch, TV, alarm clock, baby 14 monitor, WiFi devices, possibly even your lightbulbs if you have LED lamps. In 15 any given desktop PC there's the BIOS/UEFI type firmware that many people are 16 familiar with, but there are also scores of other hidden firmware _blobs_ 17 running on small controllers which power things like management engines, 18 keyboards, network cards, hard-disks/SSDs. The list goes on. 19 20 **Firmware is powerful**, it runs at the highest privilege level possible and 21 is often the bedrock on which the security story of the devices it powers 22 depends. 23 24 It is also often almost entirely invisible and inscrutable, and in many cases 25 has been 26 [shown to be insecure and vulnerable](https://eclypsium.com/2020/2/18/unsigned-peripheral-firmware). 27 28 Today, the best-in-class vendors who supply the firmware also provide an update 29 framework which verifies the integrity and authenticity of firmware updates 30 before allowing them to be installed. 31 32 Even in this _best case_, how do we know that the signed firmware is not 33 faulty, or even malicious? What if the signing identity used to assert 34 authenticity of the firmware is somehow used to sign unintended updates 35 (whether through outright compromise as in the 36 [Realtek identity used to sign the Stuxnet worm](https://arstechnica.com/information-technology/2017/11/evasive-code-signed-malware-flourished-before-stuxnet-and-still-does/), 37 or, perhaps, more subtly via some form of insider risk - be it malicious or 38 otherwise)? 39 40 How will the _publisher themselves_ even know this has happened? If they have 41 been compromised, can they trust their key protection or audit logging? 42 43 How will the consumer of the update know whether they're being given the same 44 update as all the other devices, or one especially crafted for just a small 45 subset of folks? 46 47 Firmware Transparency and Discoverability 48 ----------------------------------------- 49 50 Firmware Transparency is a mechanism to ensure that all firmware is 51 _discoverable_. 52 This means that the _same list_ of published firmware is visible to the 53 publisher, the devices which will be updated, and to folks like security 54 researchers who can use state-of-the-art static analysis and inspection tooling 55 to analyse them. 56 57 ### Outline 58 59 The goal is to have a system where firmware updates can not be {installed/booted} 60 unless they have been made discoverable via a verifiable log. 61 62 - [X] Define a [claimant model](https://github.com/google/trillian/tree/master/docs/claimantmodel) 63 description: [FT Claimant Model](./docs/design/README.md#claimant-model) 64 - [X] Specify/document a system architecture for that model. 65 - [X] Come up with some metadata format: [FirmwareMetadata](./api/firmware_metadata.go) 66 - [X] Build a simple personality around that format. 67 - [X] Extend personality to also store firmware images. 68 - [X] Build a simple tool to create metadata given a "boot" image (e.g. Linux 69 Kernel, WASM binary, etc.), and log it via the personality. 70 - [X] Figure out a way to package the metadata with the bootable image. 71 - [X] Build a noddy "device" emulator which enforces logging requirements, and refuses to boot 72 an image unless all of the following are true: 73 - [X] the metadata is present. 74 - [X] the metadata has a "valid" signature 75 - [X] the boot-image hash matches the one committed do in the metadata. 76 - [X] a valid STH and inclusion proof for the metatdata is available and 77 verifies correctly. 78 - [X] Build a simple "flash" tool which refuses to flash an image to a device 79 unless all of the boot-time requirements above are satisfied, in 80 addition to requesting and validating a valid consistency proof between 81 the previously seen STH and the new STH. 82 - [X] Flash stores "proof bundle" on device for validation at boot time. 83 - [X] Build simple monitor to tail the log and dump info from meta-data in realtime. 84 - [X] Monitor is extended to validate firmware images hash 85 - [X] Integrated STH Witness support, as an optional feature 86 87 Planned future enhancements: 88 - [ ] Add support for emulated and real hardware, e.g. via QEmu. 89 90 Running the Demo 91 ---------------- 92 In running this demo you will take on the role of several different actors within the ecosystem 93 to see how making firmware discoverable works in practice. You will then take the role of an 94 attacker trying to install malicious code onto a device, and see how the application of 95 transparency has made this attack much more expensive. 96 97 During the demo flow you will open several different terminals. It's far easier to use a terminal 98 that supports tabs in order to do this. The terminals simply make your life easier as different 99 logical actors have their own terminals in which to perform their actions. 100 101 Prerequisites: 102 * Install Docker and docker-compose 103 * Install Go (1.15+) 104 * Checkout: 105 * [Trillian](https://github.com/google/trillian) 106 * [Firmware Transparency (trillian-examples)](https://github.com/google/trillian-examples) 107 108 #### Terminal 1 - Set up Services: 109 * Open terminal in a directory that you're happy to check out code to: 110 111 ```bash 112 git checkout https://github.com/google/trillian 113 git checkout https://github.com/google/trillian-examples 114 docker-compose -f trillian/examples/deployment/docker-compose.yml -f trillian-examples/binary_transparency/firmware/docker-compose.override.yml up -d personality 115 ``` 116 117 Trillian and the FT server will start in the background and provision a new log. 118 119 #### Terminal 2 - FT monitor 120 > The monitor "tails" the log, fetching each of the added entries and checking 121 > for inconsistencies in the structure and unexpected or malicious entries. 122 123 For our demo, we'll scan each firmware binary for the word `H4x0r3d` 124 and consider that any binary containing that string is a bad one. 125 126 * Open a terminal in the `binary_transparency/firmware` directory, and run 127 the command below to start a monitor: 128 129 ```bash 130 go run ./cmd/ft_monitor/ --logtostderr --keyword="H4x0r3d" --state_file=/tmp/ftmon.state 131 ``` 132 133 #### Terminal 3 - Firmware Vendor 134 The vendor is going to publish a new, legitimate, firmware now. 135 136 * cd to the root of `binary_transparency/firmware` for the following steps: 137 * We're going to log a new "firmware" build, as the vendor would: 138 139 ```bash 140 go run cmd/publisher/publish.go --logtostderr --v=2 --timestamp="2020-10-10T15:30:20.10Z" --binary_path=./testdata/firmware/dummy_device/example.wasm --output_path=/tmp/update.ota --device=dummy 141 ``` 142 143 This creates and submits a new firmware manifest to the log, waits for it to be 144 included, and then builds a firmware update package ("OTA") and writes it out to local disk. 145 146 > :mag_right: Very shortly you should see that the new firmware entry has 147 > been spotted by the `FT monitor` above. 148 > 149 > This is important! If the `Firmware Vendor` is paying attention to the 150 > contents of the log, they can check that every piece of firmware 151 > they see logged there is expected and corresponds to a legitimate and 152 > known-good build. If they spot something _unexpected_ then they're 153 > now aware that there is a problem which needs investigation... 154 155 #### Terminal 4 - Device owner 156 Through the power of scripted narrative, the owner of the target device now 157 has a firmware update to install (we'll re-use the `/tmp/update.ota` file created 158 in the last step). 159 160 1. cd to the root of `binary_transparency/firmware` for the following steps: 161 162 Now that we have an update package for our new firmware, we can try flashing 163 it to a device. 164 165 > :frog: The repo contains a "dummy device" which uses the local disk 166 > to store the device's state. You'll need to choose and create a directory 167 > where this dummy device state will live - the instructions below assume 168 > that is `/tmp/dummy_device', change the path if you're using something different. 169 > 170 > ```bash 171 > mkdir /tmp/dummy_device 172 > ``` 173 174 We'll use the `cmd/flash_tool` to do this flashing. 175 176 > :warning: Note that the first time you do this the "dummy device" will 177 > have no state and the flashing process will fail. 178 > It will also fail if you've previously flashed firmware onto the device 179 > from a different log. 180 > In both of these cases, you can use the `--force` flag on the `flash_tool`. 181 182 ```bash 183 go run ./cmd/flash_tool/ --logtostderr --update_file=/tmp/update.ota --device_storage=/tmp/dummy_device --device=dummy # --force if it's the first time 184 ``` 185 186 2. Boot the device. 187 188 We'll boot the device emulator to check that everything is working ok. 189 The "ROM" on the dummy device verifies the integrity of the firmware and 190 proofs stored on the device. 191 192 ```bash 193 go run ./cmd/emulator/dummy --logtostderr --dummy_storage_dir=/tmp/dummy_device 194 ``` 195 196 > :frog: Because both the `flash_tool` and the device itself verifies the 197 > correctness of the inclusion proofs, they are convinced that the firmware 198 > is now _discoverable_ - anybody looking at the contents of the log _also_ 199 > knows about its existence: this doesn't guarantee that the firmware is 200 > _"good"_, but we know at least that it can't be a covert targeted attack, _and_ 201 > we can assume that the `Firmware vendor` is aware of it too. 202 203 #### Terminal 666 - The Hacker :shipit::computer: 204 _"Nice system you've got there. Let's test it..."_ 205 206 * cd to the root of `binary_transparency/firmware` for the following steps. 207 208 :firecracker: The hacker has a malicious firmware they want to install on our 209 device. It's in `testdata/firmware/dummy_device/hacked.wasm`. 210 211 1. Write malicious firmware directly onto the device. 212 213 Let's imagine the hacker has access to our device, they're going to write their 214 malicious firmware directly over the top of our device's firmware: 215 216 ```bash 217 cp testdata/firmware/dummy_device/hacked.wasm /tmp/dummy_device/firmware.bin 218 echo "mwuhahahaha :eyes:" 219 ``` 220 221 Let's watch as the device owner turns on their device in the next step... 222 223 #### Terminal 4 - Device owner 224 The device owner wants to use their device, however, unbeknownst to them it's 225 been HACKED! 226 227 Start up the device: 228 229 ```bash 230 go run ./cmd/emulator/dummy --logtostderr --dummy_storage_dir=/tmp/dummy_device 231 ``` 232 233 We should see that the device refuses to boot, with an error similar to this: 234 235 ``` 236 dummy_emu.go:41] ROM: "failed to verify bundle: firmware measurement does not match metadata (0xefb19feba9ea0e0d5de73ac16d8aa9c4ceb092ecd13eab5548f49a61e85c367a2f2c8ce1eb36b67e1407148406705e67663dc5b6d3f05a45475f6e4a2b69e285 != 0xbf2f21936b66a0665883716ea4b1ceda609304ad76dd48f6423128bc36d4cb0fb5effaa9c1f2e328a5cfc25d2cb89a337d4285a8bc3e22dbb99bddbed19e7095)" 237 ``` 238 239 > :frog: This happened because the device _measured_ the firmware and compared that 240 > with what the firmware manifest claimed the expected measurement should be. 241 > Since the device firmware had been overwritten, they didn't match and the 242 > device refused to boot. 243 > 244 > Back to the drawing board, hacker! 245 246 #### Terminal 666 - The Hacker :shipit::computer: 247 248 We need to update the manifest on the device with the correct measurement for our hacked firmware. 249 Run the following command: 250 251 ```bash 252 go run ./cmd/hacker/modify_bundle \ 253 --device dummy \ 254 --binary ./testdata/firmware/dummy_device/hacked.wasm \ 255 --input /tmp/dummy_device/bundle.json \ 256 --output /tmp/dummy_device/bundle.json \ 257 --sign=false 258 ``` 259 260 Let's watch as the device owner turns on their device in the next step... 261 262 #### Terminal 4 - Device owner 263 264 Start the device: 265 266 ```bash 267 go run ./cmd/emulator/dummy --logtostderr --dummy_storage_dir=/tmp/dummy_device 268 ``` 269 270 and _again_, even though the device now gets past the firmware measurement check 271 we should see that the device still refuses to boot, with an error similar to: 272 273 ``` 274 F1215 17:47:06.449540 1724707 dummy_emu.go:41] ROM: "failed to verify bundle: failed to verify signature on SignedStatement: failed to verify signature crypto/rsa: verification error" 275 exit status 1 276 ``` 277 278 #### Terminal 666 - The Hacker :shipit::computer: 279 280 Ok, this time we'll "steal" the key and use it to sign our malicious firmware. 281 This is equivalent to the status-quo today. 282 283 Run the following command: 284 285 ```bash 286 go run ./cmd/hacker/modify_bundle \ 287 --device dummy \ 288 --binary ./testdata/firmware/dummy_device/hacked.wasm \ 289 --input /tmp/dummy_device/bundle.json \ 290 --output /tmp/dummy_device/bundle.json \ 291 --sign=true 292 ``` 293 294 Let's watch as the device owner turns on their device in the next step... 295 296 #### Terminal 4 - Device owner 297 298 Start the device: 299 300 ```bash 301 go run ./cmd/emulator/dummy --logtostderr --dummy_storage_dir=/tmp/dummy_device 302 ``` 303 304 We've got past the signature check, but now there's another error: 305 306 ``` 307 dummy_emu.go:41] ROM: "failed to verify bundle: invalid inclusion proof in bundle: calculated root:\n[202 202 214 35 92 129 74 43 92 63 27 232 69 79 93 26 187 86 24 174 32 49 53 19 122 252 252 241 139 226 122 79]\n does not match expected root:\n[186 61 229 40 73 60 245 168 87 2 6 107 225 25 186 169 85 12 74 158 126 168 255 168 27 149 245 138 27 211 67 234]" 308 exit status 1 309 ``` 310 311 > :frog: This message indicates that the device was unable to verify that the 312 > firmware manifest was included in the log using the inclusion proof and checkpoint 313 > which are present in the `bundle.json`. 314 > This makes sense - the modified firmware manifest _hasn't_ been included! 315 > 316 > Think again, hacker! 317 318 #### Terminal 666 - The Hacker :shipit::computer: 319 320 The *only* way we're going to get the hacked firmware onto the device 321 is to have a valid inclusion proof and checkpoint from the log which 322 covers the new firmware manifest. 323 324 Let's have the hacker break into the firmware vendor's offices and 325 add their modified manifest+firmware to the log... 326 327 ```bash 328 go run cmd/publisher/publish.go --logtostderr --v=2 --timestamp="2020-10-10T23:00:00.00Z" --binary_path=./testdata/firmware/dummy_device/hacked.wasm --output_path=/tmp/bad_update.ota --device=dummy 329 ``` 330 331 > :frog: However, notice that the `FT Monitor` has spotted the firmware! 332 > Now the firmware vendor knows they have been compromised and can take action. :police: 333 > 334 > If the firmware vendor is complicit in the attack, then all is still not lost... 335 > Notice that the FT monitor has detected the malware in the new firmware too: 336 > ``` 337 > Malware detected matched pattern H4x0r3d 338 > ``` 339 > 340 > Anybody else running a monitor also knows that malicious firmware has been 341 > logged and can raise the alarm. 342 343 344 Further Work: Annotations and Verifiable Summaries 345 -------------------------------------------------- 346 347 We have seen how to publish firmware and its metadata to a log, and how this can be used by firmware readers: clients flashing the firmware, and monitors scanning the firmware. 348 Having all parties seeing the same view of the available data sets the foundation for a secure system, but making clients aware of bad firmware cannot be done only with the tools we have above. 349 350 The [ftmap README](fmd/../cmd/ftmap/README.md) outlines a verifiable solution to this problem. 351 There are 2 key changes from the solution above: 352 * In addition to firmware & metadata, the log also accepts annotations about firmware already in the log 353 * A Verifiable Map is built from the log, which aggregates each piece of firmware with the annotations for it 354 355 Clients can then use this verifiable map to efficiently discover all annotations about a piece of firmware before they rely on it.