[continued from part III]
Covert channels for public-key signatures
For reasons described earlier, it is difficult to hide the existence of a private-key on a card— because the associated public-key is often retrievable without any authentication. For example both the PIV and GIDS standards allow retrieving certificates from the card without supplying a PIN. By convention when a certificate exists for a given slot, say the 9C slot designated for “signature key” in PIV, the card contains the corresponding private key. Similarly public-key encryption formats such as CMS and GPG contain hints about the identity of the public key that a given message was encrypted to. This rules out the earlier approach used for symmetric keys, namely creating plausible deniability about the very existence of a specific key on the card.
If we focus on digital signatures and lower the bar to allow online verification, indistinguishability for duress PIN can be restored. In this model the card is allowed to output a correct result— namely, a valid digital signature computed with the private key on board. We punt responsibility for detecting use of duress PIN to a remote system responsible for verifying that output. This clearly does not work for decryption since the adversary would not need any assistance from a remote peer to make use of the output. Nor would it work for scenarios where signature verification is performed by parties outside the control of the user. That includes blockchains: bitcoin miners are happy to include any transaction with a valid signature that meets consensus rules in the next block without further inspection. Instead we need to look at closed ecosystems where the signatures are only intended for a system that is closely affiliated with the cardholder and working in conjunction to detect duress signals.
Somewhat realistic scenarios exist for enterprise authentication. Imagine a company with a VPN for remote access, website that implements TLS client authentication or Linux servers accessed using SSH. For all three scenarios authentication is ideally implemented using public-key cryptography with private keys stored on cryptographic hardware such as a smart-card or USB token. Common denominator for these use-cases is the card signing a challenge that is created during protocol execution and this signature being verified by the server to confirm that the person on the other side is in possession of the correct public key. Depending on exactly which signature algorithms are used, a duress PIN can be implemented by piggy-backing on subliminal channels.
Subliminal channels are a type of covert channel present in some digital signature algorithms, allowing the signer to convey additional information in the signature. Broadly speaking this is possible when the signature scheme is randomized: there is more than one valid signature for a given message. While the theoretical constructions assume that the signer will randomly pick one of those with uniform probability, a crafty signer in cahoots with a verifier can do something more subtle: instead of choosing randomly, use the freedom to choose for signaling additional information to the verifier.
This is best exemplified with RSA-PSS where PSS stands for “probabilistic signature scheme.” (PSS can be thought of as the counterpart of OAEP which is a probabilistic padding scheme for RSA encryption.) PSS signing starts out with a choice of a random salt, which is used to generate a mask that is combined with the message hash using a series of concatenation and xor operations. The important point is that this salt is fully recoverable by the verifier. That means it is trivial to use the salt to convey additional information. In our case we only need to get 1 bit of information across, namely the answer to a true/false question: did the card-holder enter a duress PIN?
Care must be taken in how that information is encoded. Recall that anyone in possession of the public-key can verify the signature and therefore recover the salt. The adversary is also assumed to have access to that public-key; otherwise they could not check when the card is outputting bogus results, and we would have no need for this level of stealth. A simple encoding scheme such as setting the last bit of the salt to 0 or 1 will not fly; adversary can read that information too.
Indeed no scheme that can be publicly verified is safe, no matter how complicated. Suppose we decide to obfuscate matter by encoding the boolean value in the hash of the salt. Choose a salt such that its SHA256 hash ends in 0 bit to convey “false” (as in, correct PIN entered) and “true” otherwise (duress PIN used.) The flaw in this design is relying on security-through-obscurity. If the adversary knows the covert channel, they can also run the same SHA256 computation and learn the result.
Creating a more robust scheme calls for a shared secret negotiated between the card and the remote server ahead of time. Given that secret, we can compute one-bit as the output of some psuedo-random function of the salt. For example:
- Start with a randomly generated salt
- Run all but one bit of that salt through HMAC-SHA256 with the shared key
- Take the least significant bit of HMAC output
- Depending on whether we want to convey 0 or 1, either use that bit verbatim or flip it to determine the final salt bit
The server can repeat the same HMAC computation on the other side to infer whether the signer conveyed 0 or 1.
Some care is necessary to implement this without side-channel leaks from the card applet. In particular, one would need a similar trick as earlier design, with a collection of multiple PIN slots and associated 0/1 signal bits for each slot based on whether that PIN corresponds to a duress scenario. Salt generation always proceeds the same way, using the HMAC scheme described above and the shared key, which is identical for slots. The only difference is that last bit is xored with a value of 0 or 1 drawn from the specific slot that validated against the supplied PIN. As before, PINs are checked against all slots are in a different, randomly chosen order each time.
Stepping back to review our assumptions: how realistic is it to find RSA-PSS or some other probabilistic signature scheme in existing real-world protocols? After all it is much easier to tweak an existing server-side logic run additional checks on an otherwise valid signature compared to deploying a whole new protocol from scratch. Using the original three scenarios as benchmark, we are batting two out of three, with some caveats.
- TLS: PSS was not supported in TLS1.2 but the latest version of the protocol as of this writing includes RSA-PSS variants in the list of recognized signature schemes. While the signature scheme selected is subject to negotiation between client and server based on comparing their respective lists, TLS 1.3 has an unambiguous preference for PSS:
RSA signatures MUST use an RSASSA-PSS algorithm, regardless of whether RSASSA-PKCS1-v1_5 algorithms appear in “signature_algorithms”
Bottom line: provided the smart-card native implements RSA-PSS and associated middleware delegates padding to the card—as opposed to selecting its own padding and invoking a raw RSA private-key operation, which is how some PKCS#11 providers implement PSS— a duress signal can be carried transparently through TLS1.3 connections.
- VPN: There is no single “VPN protocol” but instead a variety of open-source and proprietary options with different cryptographic designs. Luckily a large class of VPNs are based on TLS, and this case reduces to the first bullet point. For example OpenVPN and Cisco AnyConnect are all built on TLS client authentication. By using TLS1.3 for the handshake, RSA-PSS becomes accessible for creating a covert channel.
- SSH: While OpenSSH has been aggressive in pushing for EdDSA and ECDSA keys, on the subject of RSA signatures the implementors are surprisingly conservative. Even the latest RFC favors PKCSv1.5 padding over PSS:
“This document prescribes RSASSA-PKCS1-v1_5 signature padding because […]
(1) RSASSA-PSS is not universally available to all implementations;”
This rules out RSA-PSS padding are ruled out for SSH, that is not the end of the story. Recall that the property we relied on is freedom in choosing from a large collection of possible valid signatures for a given message. ECDSA clearly fits the bill. While EdDSA is deterministic in principle, the difficulty of verifying that property externally can also be leveraged for a covert channel, albeit with some qualifications. The final post in this series will sketch ways of signaling a duress PIN over SSH.