chipsalliance / caliptra-sw

Caliptra software (ROM, FMC, runtime firmware), and libraries/tools needed to build and test
Apache License 2.0
53 stars 39 forks source link

Postmortem: Incorrect rt-alias-key derivation in FMC #1550

Open korran opened 4 months ago

korran commented 4 months ago

The key derivation done by the FMC (label "rt_alias_cdi") is not conformant with the HMAC-SHA-384 specification. The HMAC computation only includes the first HMAC block, and is missing a second block which includes padding and a length suffix. This is not believed to be a security issue, as (by luck) all measurements are in the first block. If circumstances were slightly different, the consequences to these mistakes could have been a lot worse, so a post-mortem is necessary.

Background

Issue #1520 was filed, noting that the rt-alias public key differed between the RTL and the sw-emulator. This occurred because the driver/hardware was ignoring all blocks except for the first one in the derivation, but the sw-emulator implementation processed all blocks "correctly".

Causes

When consuming keys from the keyvault, the combination of the HMAC peripheral and driver only include the first 128-byte data block in the computation. The multi-block case is decently well tested by driver tests when operating on data and keys supplied and retrieved by the CPU, but when operating with keys supplied by (and result written to) the key-vault, the hardware clears the key after processing the first block, and subsequent blocks are ignored. This behavior was not called out in the hardware spec. I think folks assumed there would never be a need for multi-block HMAC for key derivation; and there wasn't, until somebody tweaked the derivation logic to use HKDF, which expanded the data beyond what would fit in a single block. I believe the systemic root causes are miscommunication between the hardware and firmware teams, and missing validation at several layers of the stack:

I have confirmed in PR #1528 that reloading the key from the keyvault and reprogramming the destination registers after each block works around this multi-block issue in the driver.

What went well?

What went wrong?

Where we got lucky

Action Plan

(Do not mark this bug completed until all tasks are complete)

jhand2 commented 4 months ago

Opened https://github.com/chipsalliance/caliptra-sw/issues/1552 to track task 4 above