Everyone knows that ECB operation mode with a block cipher should be avoided because of clear and obvious weaknesses. But little attention is given to comparison of the other modes in the context of security, and people instead appear to simply prefer the oldest mode: CBC.

Are there security caveats with respect to other common operation modes? This is specifically in the context of stream encryption rather than special-purpose functions that might have very specific operational requirements (i.e. TrueCrypt et.al.).

For example, the simplicity of OFB mode is appealing as it completely masks the nature of the underlying block cipher, turning into an easy-to-use stream cipher. But the fact that the cipher "output" is directly XORed with the plaintext to produce the ciphertext is vaguely unsettling, and smells like there's room for a chosen plaintext vulnerability.

Of the common operation modes, are there any that we should avoid for stream encryption, or situations in which we should avoid any given one of them, or reasons to prefer one over another? Besides ECB, of course.

Specifically, CBC, OFB, and CFB operation modes, as those are nearly universally supported. And possibly CTR 'cause everyone knows what it is.

  • 1
    Is there any aspect in which OFB is better than CTR? – CodesInChaos Jan 9 '13 at 18:41
  • @CodesInChaos only in availability. CTR mode isn't as widely supported. OpenSSL (on my Ubuntu box) doesn't support it, for example. – tylerl Jan 9 '13 at 21:24
  • 1
    @tylerl that's really surprising, I reviewed OpenSSL for a project back in 2008, using CTR mode. How is (was?) your package so horridly out of date? – AviD Dec 29 '15 at 11:58
  • @AviD I just checked; the OpenSSL build supplied by Ubuntu 12.04 LTS (1.0.1-4ubuntu5.32) doesn't support CTR. That doesn't mean that the code for it doesn't exist, but rather that it's not in the default build. – tylerl Dec 29 '15 at 23:20

OFB and CTR turn the block cipher into a stream cipher. This means that care must be taken when using them, like for RC4; reusing the same stream for encrypting two distinct messages is a deadly sin. OFB is more "delicate" in that matter. Since OFB consists in encrypting the same value repeatedly, it is, in practice, an exploration of a permutation cycle: the IV selects a point and OFB walks the cycles which contains this point. For a block cipher with block size n bits, the average size of a cycle should be around 2n/2, and if you encrypt more than that, then you begin to repeat a previous segment of the stream, and that's bad. This can be a big issue when n = 64 (e.g. you use 3DES). Moreover, this is an average: you can, out of (bad) luck, hit a smaller cycle; also, if you encrypt two messages with the same key but distinct IV, you could (there again if unlucky) hit the same cycle than previously (only at a different point).

The bad point of OFB is that it is hard to test for these occurrences (if the implementation includes the necessary code, it can test whether these unwanted situations occur, but this cannot be done in advance, only when part of the encryption has already been done). For CTR, things are easier: CTR is encryption of successive counter values; trouble begins when a counter value is reused. But a counter behaviour is easy to predict (it is, after all, a counter) hence it is much easier to ensure that successive messages encrypted with the same key use distinct ranges of counter values.

Also, when encrypting with CTR, the output begins to be distinguishable from pure random after about 2n/2 blocks, but that's rarely lethal. It is a worry and is sufficient to warrant use of block ciphers with big blocks (e.g. AES with 128-bit blocks instead of 3DES and its 64-bit blocks), but that's a more graceful degradation of security than what occurs with OFB.

To sum up, don't use OFB; use CTR instead. This does not make CTR easy to use safely, just easier. To avoid botching it, you should try to use one if the nifty authenticated encryption modes which do things properly and include integrity check, a necessary but often overlooked component. EAX and GCM are my preferred AE modes (EAX will be faster on small architectures with limited L1 cache, GCM will be faster on modern x86, especially those with the AES opcodes which were defined just for that).

To my knowledge, CFB does not suffer as greatly as OFB from the cycle length issues, but encrypting a long sequence of zeros with CFB is equivalent to OFB; therefore, it seems safer to prefer CTR over CFB as well.

Almost all block cipher modes of operation have trouble when reaching the 2n/2 barrier, hence it is wise to use 128-bit blocks anyway.

Note: CFB and OFB have an optional "feedback length". Usually, we use full-block feedback, because that's what ensures the maximum performance (production of n bits of ciphertext per invocation of the block cipher). Modes with smaller feedback have also been defined, e.g. CFB-8 which encrypts only one byte at a time (so it is 8 times slower than full-block CFB when using a 64-bit block cipher). Such modes are not as well supported by existing libraries; also, small feedback loops make the OFB issues worse. Therefore, I do not recommend using CFB or OFB will less than full block feedback.

As pointed out by @Rook: CBC mode, like ECB but unlike CFB, OFB and CTR, processes only full blocks, therefore needs padding. Padding can imply padding oracle attacks, which is bad (arguably, a padding oracle attack is possible only if no MAC is used, or is badly applied; the proper way being encrypt-then-MAC). For this reason, padding-less modes are preferable over CBC.

This leads us to a clear victory of CTR over other modes, CFB being second, then CBC and OFB in a tie, then ECB (this is a bit subjective, of course). But, really, use EAX or GCM.

  • "average size of a cycle should be around $2^{n/2}$" are you sure about that? I thought it's $2^{n-1}$ because a block cipher is a permutation not a random function. – CodesInChaos Jul 5 '15 at 8:26
  • Mmh... indeed, for a random permutation, the average length of the cycle containing a given random element is (1+2^n)/2, which is close to 2^(n-1). It is OFB with partial feedback that leads to 2^(n/2) cycles. However, a random permutation will still have a few short cycles that lead to ungraceful security degradation. – Thomas Pornin Jul 5 '15 at 12:30

The mode of operation entirely depends on how the data is being used. Let your threats define the solution.

For example, authenticated modes like GCM and CCM are really elegant and I use them in my designs to avoid Cryptographic Oracles. But you don't always need an authenticated mode. For example if you need to store many small records in the database, and modification of cipher text really isn't a concern then an authenticated mode is not the right tool.

Many databases rely upon ECB mode, and this isn't always a vulnerability. For example, if you are storing only a single block, and that block always contains a random value like a Session ID or password reset token, then the attacks on ECB mode don't come into play. By using ECB mode the database can make look ups much faster, because you know there is always a 1:1 relationship between plaintext and cipher text.

Also note, by using ECB mode you don't fall prey to the CBC-R and Padding Oracle attacks that affect CBC mode! By using CBC mode over ECB you can make a system less secure. It just so happens in many cases ECB mode is probably the wrong choice.

  • Isn't Padding Oracle impossible if you use explicit IV? – Pacerier Dec 26 '16 at 4:55
  • @Pacerier Decryption oracles, Encryption oracles, and Padding oracles can be created from any decryption routine that fails to prevent a chosen-cipher text attack. An IV is a useful tool to prevent attacks that rely upon key-reuse, but an "explicit" IV can still fall to an IV reuse attack. – rook Dec 26 '16 at 17:32

Yes. The best answer to this question is to unask the question. For most situations, you should not be using crypto in a way that forces you to choose your own mode of operation; if you do that, there are too many ways you can screw up. For instance, many folks who do that forget to authenticate the data properly, which is a problem.

Instead, it is generally better to use a high-level tool or library. To quote from my answer elsewhere:

Your best case is to use a high-level well-vetted scheme: for communication security, use TLS (or SSL); for data at rest, use GPG (or PGP). If you can't do that, use a high-level crypto library, like cryptlib, GPGME, Keyczar, or NaCL, instead of a low-level one, like OpenSSL, CryptoAPI, JCE, etc.

  • 8
    You understand, though, that using a high-level library doesn't really imply a solution to this problem. TLS and GPG (for example) are defined over multiple ciphers and operation modes, and any given implementation requires you to select a preferred order. And using a given cipher and mode just because it's the default in your library is not necessarily the wisest possible choice. – tylerl Jan 10 '13 at 3:27
  • @tylerl, I understand, but usually they will also make sure that they provide sensible combinations, and the defaults are usually pretty sensible. For instance, TLS doesn't provide bare OFB mode (not even as an option); all of its modes use authenticated encryption, key separation, and other good practices. Not a panacea, but it helps avoid some common mistakes. – D.W. Jan 10 '13 at 6:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.