Dos and Don’ts (but mostly Don’ts) for Secure Transport Protocol Designers

Everybody tells you: don’t invent your own crypto. Nevertheless, you fell the need to design a protocol for your own, a passion. Why? Because it’s fun, and because by failing you will learn a lot. And you will never forg124_ssh_fig03_lget the lesson. So this time I encourage you to invent your own secure transport protocol, like TLS, SCIMP, SSH or OTR. I would nevertheless recommend you not to actually use your protocol in production code until it’s been analyzed by the crypto community.

Since I’m no cryptography expert, I can’t tell you what you shoutls-mee-diagram-486ld do (and if I do, then it won’t be your protocol, won’t it?). So I collected a list of things not to do, with a few exceptions. The recommendations were taken from the literature and actual vulnerabilities discovered in the standard protocols. Note that my intention was that each advise would be as short as possible, so you can use it as a checklist.

  1.  Don’t use insecure encryption/MAC functions, such as CRC32. [SSH 1.0 Attack]
  2.  Don’t use CBC block chaining. [BEAST attack]. But if you do, make sure that the attacker cannot do a chosen-plaintext-attack (CPA). A good solution is to check authentication before decryption.
  3.  Don’t compress data [CRIME attack]. But if you do make sure that the attacker cannot do a chosen-plaintext-attack (CPA). You can allow the protocol to switch on and off compression as per packet basis.
  4.  Don’t do read, interpret or branch on the decrypted ciphertext before verifying the associated MAC. [SSH 2.0 CBC Attack, Lucky13 Attack]. This includes encrypted padding and encrypted message length. But if you do, then make sure you’re are either:
      1. Using a secure stream cipher
      2. Using CTR mode
  5.  If you do interpret the decrypted ciphertext before verifying the associated MAC and you use CBC mode for message encryption, then make sure blocks interpreted before the MAC is verified cannot be replaced by the remaining blocks, since the attacker may be able to use your interpretation of the decrypted blocks as an oracle. Use a different encryption key for each block interpreted before the MAC is verified.
  6.  Don’t use the same keys for MAC and encryption (except you’re using an authenticated encryption method)
  7.  Don’t use the same keys for input/output streams [Replay attack]
  8.  Don’t derive the MAC key from the encryption key or vice-versa (unless you have a good reason to do so). Derive the encryption/MAC keys from the shared secret, using a KDF.
  9.  Don’t use the shared secret as the encryption or MAC keys, derive them from the shared secret. If you don not do so, then the shared secret may not be long enought to provide enough data for all the required keys (MAC-in, MAC-out encryption-in, encryption-out).
  10. Don’t reuse IVs. Make them dependent on the session id or securely derived from the shared secret.
  11.  Don’t forget to verify all handshake messages after the handshake is over using the MAC. [Version downgrade attack]
  12.  If you your protocol allows session resumption, and so reuses previously authenticated secrets, don’t forget to use random nonces provided by the client and the server to derive a new master secret to avoid session replays. [Session replay]
  13.  If your application allows many authentication schemes (such as DH, RSA, DSA or passwords) to derive a shared secret, don’t assume the output of the authentication stage is always an unique random byte string since some of the schemes may be deterministic: add to the handshaking messages to exchange additional nonces to compose additional inputs to the master secret derivation function. [Session replay in SRTP/S-Mime-protected SDES]
  14.  Don’t use long-term RSA keys to encrypt a secret (without DH) to send to the other party. But if you do, take into account you may not be able to provide forward secrecy.
  15.  If the authentication of the session includes a pre-shared secret, don’t commit to the pre-shared secret nor encrypt the pre-shared secret, make the pre shared-secret an input to the new derived master secret. [Man-in-the-middle attack]
  16.  If the authentication of the session includes cached secrets for key continuity, is preferable to verify that the shared secrets are equal before doing expensive operations (like RSA,DH exponentiation). [Denial of service protection]
  17. If you are using cached secrets to authenticate, don’t invalidate the cache if the other party, trying to impersonate a known user, fails to authenticate. [ZRTP impersonation attack][SCIMP also falls here]. Check that cached secrets agree in a way not to reveal them, and disallowing the handshake messages used to proof the facts to be reused on another session. This can be done by committing to the cached secrets along with a bit string derived by nonces provided by both parties. Also it can be done by the EKE method.
  18.  If you are using cached secrets to authenticate, and you don’t have a cached secret for a peer, use a random string instead, to prevent leaking that fact. [SCIMP idea]
  19.  You can use long term RSA/DSA keys to sign the DH pairs to derive a shared secret, without loosing the forward secrecy property.
  20.  Don’t keep the MAC key secret after the protocol is over, publish it. If you don’t you may not be able to provide deniability (also called repudiable authentication). [idea in OTR]
  21.  If a short authentication string will be used (SAS), then make the second party who sends the DH secret commit to it first, by sending the commitment before the other party sends the first DH secret. This thwarts the possibility of off-line searching for collisions in the SAS. [idea of SCIMP]
  22.  If you allow the renegotiation of a connection parameters over an existing established connection, make sure parties involved can distinguish between a new connection and a renegotiation. One way is by making the new master secret derive also by the previous master secret. Other possible way is by specifying the previous session id during the handshake and making the master secret also dependent of the handshake messages. [SSL Session Prefix attack]
  23.  Include a special message to inform that a party is willing to close the session (or a half) , to allow applications to differentiate between closing the session or accidental disconnection.
  24.  If you want to provide forward secrecy at the byte level, use the HC modes of encryption, and encrypt every byte in a block.
  25.  If you want to provide forward secrecy at the block level, use the HC modes of encryption.
  26.  If you want to provide forward secrecy at the message level, cycle the encryption key by hashing the previous key, along with some secret derived from the master secret.
  27.  If you want to provide forward secrecy at the session level, repeat the DH handshake for each session or use prior session keys to derive new keys in one-way.
  28.  Don’t fill padding with random data if you want to protect from covert channels. Use always pseudo-random data that is derived from the session id.
  29.  Don’t use packet lengths that depend of user interaction timing (keyboard key press) if you want to protect against traffic analysis. To provide such protection, do not send packets with length less than a minimum size, enough to hide any timing pattern.
  30.  Don’t use packet lengths that depend of any secret length, if you want to protect against traffic analysis. It is difficult to provide proven protection against traffic analysis, but some common measures are:
    -Wait to receive a minimum amount of bytes and send them at regular time slots.
    -Allow the parties to send dummy packets that are fully verified, but are discarded.
    -Send dummy packets of random size at all time or
    -Send dummy packets of random size at random intervals.
  31. Prepare for versioning, adding authentication schemes, adding ciphersuites, providing cryptographic agility and phasing out obsolete ciphersuites and protocols.
  32. If your protocol authentication relies on a password with low entropy, don’t commit to it by a MAC, HASH or using the password as key for encryption, because you’ll be open to dictionary attacks. Use an Encrypted key exchange such as EKE.

So that’s it. Only 32 checks. Note that the correct implementation of your protocol is as important as the protocol design, but that would be another checklist.

Feedback regarding my advises or ideas for adding new advises are welcomed!


, , , , ,

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: