chipsalliance / caliptra-sw

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

Add replay attack protection for cryptographic mailbox contexts #1761

Open swenson opened 3 weeks ago

swenson commented 3 weeks ago

For some commands, replaying contexts may lead to potential attacks.

(For instance, with AES GCM, submitting a context with the same CMID but a new plaintext could reveal other plaintext that was submitted with that context and CMID, if the attacker had a copy of the ciphertext.)

We need to add some replay protection mechanisms for these contexts.

bluegate010 commented 3 weeks ago

In the cryptographic mailbox use-case, the holder of the CMID and context also holds the plaintext being encrypted. We could stipulate that clients should not leak their CMID, since it could be misused. We could also bind CMIDs to the PAUSER which created them, so leaking CMIDs across hardware boundaries would not cause any issues.

We could also go even further. Taking inspiration from DICE Protection Environment, we could try and make all CMIDs and contexts single-use. When invoking commands like CM_HMAC_INIT we would get back a new CMID which refers to the same key we just passed in, since the old CMID would be invalidated.

As discussed in other comments and noted in https://github.com/chipsalliance/caliptra-sw/issues/1753, we can go in a direction where CMIDs hold their own key material, which would let us avoid consuming any state within Caliptra when making a CMID. Replay protection would go the other direction, again consuming space in Caliptra DCCM.

We wouldn't necessarily need to hold all the keys in DCCM though. We could bind each extant CMID / context to a fixed-size random nonce. I think 64 bits would be fine, since Caliptra would be generating these nonces and we don't expect there to be many extant CMIDs / contexts at once. Caliptra DCCM would just hold a list of currently-valid nonces, and each command that accepts a CMID or context would rotate or erase one of those nonces. This would not have the same fragmentation problem as the current design, because the nonces are fixed-length and movable, so we can compact the list when we erase an entry in the middle.

We would need a mechanism for reclaiming DCCM space in case CMIDs or contexts get dropped on the floor by the caller. One potentially ugly option that doesn't require any work on the client side is, we could internally tag each nonce with the time-since-boot that it was created, and then if we run out of space we just stamp over the oldest nonce.

Edit - I might have gone too far when I suggested we do this for both CMIDs and contexts. If we scope this only to contexts and leave CMIDs alone, we further reduce DCCM usage, and avoid the need to support long-lived nonces because contexts are only intended to live within a given cryptographic operation.