517

Which of them are preferred in which circumstances?

I'd like to see the list of evaluation crtieria for the various modes, and maybe a discussion of the applicability of each criterion.

For example, I think one of the criteria is "size of the code" for encryption and decryption, which is important for micro-code embedded systems, like 802.11 network adapters. IF the code required to implement CBC is much smaller than that required for CTR (I don't know this is true, it's just an example), then I could understand why the mode with the smaller code would be preferred. But if I am writing an app that runs on a server, and the AES library I am using implements both CBC and CTR anyway, then this criterion is irrelevant.

See what I mean by "list of evaluation criteria and applicability of each criterion" ??

This isn't really programming related but it is algorithm related.

Cheeso
  • 180,104
  • 92
  • 446
  • 681

7 Answers7

446

Please consider long and hard if you can't get around implementing your own cryptography

The ugly truth of the matter is that if you are asking this question you will probably not be able to design and implement a secure system.

Let me illustrate my point: Imagine you are building a web application and you need to store some session data. You could assign each user a session ID and store the session data on the server in a hash map mapping session ID to session data. But then you have to deal with this pesky state on the server and if at some point you need more than one server things will get messy. So instead you have the idea to store the session data in a cookie on the client side. You will encrypt it of course so the user cannot read and manipulate the data. So what mode should you use? Coming here you read the top answer (sorry for singling you out myforwik). The first one covered - ECB - is not for you, you want to encrypt more than one block, the next one - CBC - sounds good and you don't need the parallelism of CTR, you don't need random access, so no XTS and patents are a PITA, so no OCB. Using your crypto library you realize that you need some padding because you can only encrypt multiples of the block size. You choose PKCS7 because it was defined in some serious cryptography standards. After reading somewhere that CBC is provably secure if used with a random IV and a secure block cipher, you rest at ease even though you are storing your sensitive data on the client side.

Years later after your service has indeed grown to significant size, an IT security specialist contacts you in a responsible disclosure. She's telling you that she can decrypt all your cookies using a padding oracle attack, because your code produces an error page if the padding is somehow broken.

This is not a hypothetical scenario: Microsoft had this exact flaw in ASP.NET until a few years ago.

The problem is there are a lot of pitfalls regarding cryptography and it is extremely easy to build a system that looks secure for the layman but is trivial to break for a knowledgeable attacker.

What to do if you need to encrypt data

For live connections use TLS (be sure to check the hostname of the certificate and the issuer chain). If you can't use TLS, look for the highest level API your system has to offer for your task and be sure you understand the guarantees it offers and more important what it does not guarantee. For the example above a framework like Play offers client side storage facilities, it does not invalidate the stored data after some time, though, and if you changed the client side state, an attacker can restore a previous state without you noticing.

If there is no high level abstraction available use a high level crypto library. A prominent example is NaCl and a portable implementation with many language bindings is Sodium. Using such a library you do not have to care about encryption modes etc. but you have to be even more careful about the usage details than with a higher level abstraction, like never using a nonce twice. For custom protocol building (say you want something like TLS, but not over TCP or UDP) there are frameworks like Noise and associated implementations that do most of the heavy lifting for you, but their flexibility also means there is a lot of room for error, if you don't understand in depth what all the components do.

If for some reason you cannot use a high level crypto library, for example because you need to interact with existing system in a specific way, there is no way around educating yourself thoroughly. I recommend reading Cryptography Engineering by Ferguson, Kohno and Schneier. Please don't fool yourself into believing you can build a secure system without the necessary background. Cryptography is extremely subtle and it's nigh impossible to test the security of a system.

Comparison of the modes

Encryption only:

  • Modes that require padding: Like in the example, padding can generally be dangerous because it opens up the possibility of padding oracle attacks. The easiest defense is to authenticate every message before decryption. See below.
    • ECB encrypts each block of data independently and the same plaintext block will result in the same ciphertext block. Take a look at the ECB encrypted Tux image on the ECB Wikipedia page to see why this is a serious problem. I don't know of any use case where ECB would be acceptable.
    • CBC has an IV and thus needs randomness every time a message is encrypted, changing a part of the message requires re-encrypting everything after the change, transmission errors in one ciphertext block completely destroy the plaintext and change the decryption of the next block, decryption can be parallelized / encryption can't, the plaintext is malleable to a certain degree - this can be a problem.
  • Stream cipher modes: These modes generate a pseudo random stream of data that may or may not depend the plaintext. Similarly to stream ciphers generally, the generated pseudo random stream is XORed with the plaintext to generate the ciphertext. As you can use as many bits of the random stream as you like you don't need padding at all. Disadvantage of this simplicity is that the encryption is completely malleable, meaning that the decryption can be changed by an attacker in any way he likes as for a plaintext p1, a ciphertext c1 and a pseudo random stream r and attacker can choose a difference d such that the decryption of a ciphertext c2=c1⊕d is p2 = p1⊕d, as p2 = c2⊕r = (c1 ⊕ d) ⊕ r = d ⊕ (c1 ⊕ r). Also the same pseudo random stream must never be used twice as for two ciphertexts c1=p1⊕r and c2=p2⊕r, an attacker can compute the xor of the two plaintexts as c1⊕c2=p1⊕r⊕p2⊕r=p1⊕p2. That also means that changing the message requires complete reencryption, if the original message could have been obtained by an attacker. All of the following steam cipher modes only need the encryption operation of the block cipher, so depending on the cipher this might save some (silicon or machine code) space in extremely constricted environments.
    • CTR is simple, it creates a pseudo random stream that is independent of the plaintext, different pseudo random streams are obtained by counting up from different nonces/IVs which are multiplied by a maximum message length so that overlap is prevented, using nonces message encryption is possible without per message randomness, decryption and encryption are completed parallelizable, transmission errors only effect the wrong bits and nothing more
    • OFB also creates a pseudo random stream independent of the plaintext, different pseudo random streams are obtained by starting with a different nonce or random IV for every message, neither encryption nor decryption is parallelizable, as with CTR using nonces message encryption is possible without per message randomness, as with CTR transmission errors only effect the wrong bits and nothing more
    • CFB's pseudo random stream depends on the plaintext, a different nonce or random IV is needed for every message, like with CTR and OFB using nonces message encryption is possible without per message randomness, decryption is parallelizable / encryption is not, transmission errors completely destroy the following block, but only effect the wrong bits in the current block
  • Disk encryption modes: These modes are specialized to encrypt data below the file system abstraction. For efficiency reasons changing some data on the disc must only require the rewrite of at most one disc block (512 bytes or 4kib). They are out of scope of this answer as they have vastly different usage scenarios than the other. Don't use them for anything except block level disc encryption. Some members: XEX, XTS, LRW.

Authenticated encryption:

To prevent padding oracle attacks and changes to the ciphertext, one can compute a message authentication code (MAC) on the ciphertext and only decrypt it if it has not been tampered with. This is called encrypt-then-mac and should be preferred to any other order. Except for very few use cases authenticity is as important as confidentiality (the latter of which is the aim of encryption). Authenticated encryption schemes (with associated data (AEAD)) combine the two part process of encryption and authentication into one block cipher mode that also produces an authentication tag in the process. In most cases this results in speed improvement.

  • CCM is a simple combination of CTR mode and a CBC-MAC. Using two block cipher encryptions per block it is very slow.
  • OCB is faster but encumbered by patents. For free (as in freedom) or non-military software the patent holder has granted a free license, though.
  • GCM is a very fast but arguably complex combination of CTR mode and GHASH, a MAC over the Galois field with 2^128 elements. Its wide use in important network standards like TLS 1.2 is reflected by a special instruction Intel has introduced to speed up the calculation of GHASH.

Recommendation:

Considering the importance of authentication I would recommend the following two block cipher modes for most use cases (except for disk encryption purposes): If the data is authenticated by an asymmetric signature use CBC, otherwise use GCM.

Perseids
  • 10,688
  • 5
  • 32
  • 62
  • 240
    "If you need to ask this question you probably don't know enough about cryptography to implement a secure system." - You are right, but you do realise that asking questions is how people learn? So maybe relax a little. – Robert MacLean Aug 06 '14 at 08:29
  • 76
    @RobertMacLean True, but in contrary to a lot of other fields in IT you won't get security right by try and error. Whereas with web design, application scalability etc you can actively check your requirements, testing security aspects ranges from hard to impossible. Unfortunately that is a lesson that is seldom taught. Most resources tell you how cryptography works and not the myriad ways it fails in practice without you even being aware of it. The only way out is to know a lot about the subject. And that's the morale of the post: – Perseids Aug 06 '14 at 09:06
  • 9
    Either invest enough time to get to know cryptography thoroughly or avoid it as far as possible and use strong abstractions. And in the theme of learning how cryptography breaks the first paragraph is much more on-topic than the description of the modes. – Perseids Aug 06 '14 at 09:17
  • 43
    Minus one: the starting headline is wrong; it should say "If you're asking this question you're going in the right direction, keep it up and you'll excel!" – Henrik Nov 30 '14 at 13:20
  • 1
    @Henrik and RobertMacLean: I've added an introduction. Is that better? – Perseids Nov 30 '14 at 15:35
  • 2
    @Perseids how many books do I need to read before I'm allowed to use a low-level library like JCA/JCE? – jordanpg Dec 23 '14 at 22:02
  • 3
    @jordanpg, I don't think that I can answer that question. It of course depends on what books you read. The java cryptography libraries are particularly low-level and the documentation is littered with legacy code and bad practices like `Cipher c1 = Cipher.getInstance("DES/ECB/PKCS5Padding");`. Thus you need a firm understanding of what essential primitives exist, what they are supposed to do and how they interact. More difficult to estimate is how much knowledge you have of how the cryptography can fail. – Perseids Jan 17 '15 at 19:31
  • 3
    I've heard good things about the [matasano crypto challenges](http://cryptopals.com/) as an introduction to breaking crypto. [Matthew Green](http://blog.cryptographyengineering.com/) has good blog posts of the more complex attacks like [BEAST](http://blog.cryptographyengineering.com/2011/09/brief-diversion-beast-attack-on-tlsssl.html). [Troy Hunt advocates hacking yourself first](http://www.troyhunt.com/2013/05/hack-yourself-first-how-to-go-on.html). @jordanpg – Perseids Jan 17 '15 at 19:43
  • 3
    Otherwise I would advise you to seek opinionated books and guides that not only tell you what is there, but also advises you which combinations to use. For that reason I like to recommend Cryptography Engineering, because it does a better job at that than most low level introductions. – Perseids Jan 17 '15 at 19:47
  • While I completely agree on what you said (you can never be sure your system is 100% secure), a server with a bit of security is better than a server with no security at all. So, copying and pasting from stackoverflow is OK for a bit of security, just don't relax thinking you are unbreakable. – Fermin Silva Jul 26 '16 at 16:18
  • 11
    @FerminSilva: True, but another aspect of the argument is that it is often *easier* to use true and tested solutions than to copy-paste crypto code. E.g. when all you want to do is talk with your server from a smartphone app, it is much more simple to set up an Apache reverse proxy with a Let's Encrypt TLS certificate and write `https://your.server` everywhere in your app, than to invent some key exchange protocol and get the cryptography libraries on both sides to work together smoothly. – Perseids Jul 26 '16 at 17:37
  • 3
    @FerminSilva: Furthermore, setting up an HTTPS endpoint is a competence that you will need time and time again, while debugging broken homegrown crypto is (hopefully) not. And trust me, the latter is no fun at all (error messages are few, mostly it just doesn't decrypt or authenticate at all. E.g. did you know that the PHP standard crypto library features a function sounding like AES256 (Rijndael 256) but is in fact an obscure variant that next to nobody else supports and that you actually need to use Rijndael 128 which internally switches codepaths based on the length of the key bytestream?). – Perseids Jul 26 '16 at 17:55
  • 2
    "If you need to ask this question, you probably don't know enough about cryptography to implement a secure system." That's a catch 22, if you know what you don't know and you ask, you're doing the right thing. On the subject of knowing enough, I've constantly found the documentation lacking. There is a habit of mistaking security with obscurity when it comes to encryption. You're helping with this but personally I would also add in bold: If in doubt, ask. Always test. – jgmjgm Oct 05 '16 at 19:08
  • "I don't know of any use case where ECB would be acceptable." Good example - whitening function in a TRNG. Silly (but feasible) example - OTP replacing the XOR operation with a block cipher. – Paul Uszak Aug 19 '17 at 21:19
  • @Perseids - " I don't know of any use case where ECB would be acceptable" .. how about the situation where you need the same ciphertext to appear for the same data? Say you have some sort of lookup table in the database with encrypted data. And you want to check that a certain plaintext string already has been encrypted before. Unless you decrypt every entry in that table and check for a match, you couldn't do that with CBC. – Lieuwe Feb 27 '18 at 14:41
  • 1
    @Lieuwe: Check out https://en.wikipedia.org/wiki/Convergent_encryption . For your scenario: Use an HMAC of the file as nonce. – Perseids Feb 27 '18 at 16:38
  • 1
    "If you need to ask this question, you probably don't know enough about cryptography to implement a secure system." - If you can't explain it, stop talking. We're all smart people here, you'll need to pose harder. – Michael Cole Jun 26 '18 at 00:19
  • What mode would you use if you were trying to create a cryptographically secure random number generator? My idea is to take input from the OS (/dev/random on POSIX-like systems, including Apple's assortment of OSes; CryptGenRandom on Windows) run AES-256 over it, mix it (probably with XoRoShiRo), re-AES it, then re-mix it again, and I'm not sure which mode would be best, and also, I can't see any obvious flaws with the idea, but I don't know a whole lot about cryptography so I'm not sure how good of an idea it is. – MarcusJ Apr 17 '19 at 20:37
  • 1
    @MarcusJ: Look at [NIST SP 800-90A](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf) 10.2.1: CTR_DRBG and instantiate it with AES. Adding anything on top is unnecessary given our current understanding of the security of AES. If you want to hedge your bets, use a completely different cryptographic primitive, like [Keccak](https://keccak.team/keccak.html) _with independent seeds_, and XOR it with your AES generated stream. **But if you optimize for security of the overall system, just trust the (fast) CRNG of your OS.** [1/2] – Perseids Apr 18 '19 at 09:19
  • 1
    Most security flaws occur in the implementation and not in the standardized algorithms. The CRNG of your OS is heavily reviewed. In contrast, the code most of us write on a daily basis will only ever been seen by a limited number of our colleagues, and seldom in a formalized review by security specialists. For example, Linux' `/dev/urandom` is not without its (theoretical) flaws, but anything exploitable will create huge waves in the IT press and will be fixed without your intervention as a software developer. (**Special warnings apply for CRNGs on embedded and virtualized systems.**) [2/2] – Perseids Apr 18 '19 at 09:34
  • @Perseids by "independent seeds" would using the data I got from /dev/random (before or after re-mixing it) as the key be a bad idea? Once again, I'm just trying to generate random numbers for testing, I'm not trying to decrypt the results at this stage or anything. – MarcusJ Apr 18 '19 at 19:23
  • 1
    @MarcusJ: No, that is fine, as long as you use data from different reads from `/dev/random` as seeds. – Perseids Apr 23 '19 at 11:04
  • Why do you prefer CBC over CTR when integrity is being done with a "asymmetric signature?" – jschultz410 Feb 27 '20 at 18:25
  • @jschultz410, CTR is fine if done correctly, but fails spectaculary when done imperfectly. Namely, when you fail to use a different nonce/IV, you can recover the plaintext of the messages using the same nonce/IV (because CTR emulates a stream cipher), whereas with CBC you just get the information how many blocks are identical in those messages using the same IV. – Perseids May 20 '20 at 18:22
  • On the other hand, in case you don't have good randomness, CBC falls flat, whereas CTR mode might work for you, but you have to store state with your key: the previously used counter range. In the end, a recommendation tells you as much about the assumed audience as about the cryptography itself. E.g. when I have very low end systems in mind, I would stress the issues of low quality randomness much more than on desktops or servers (where it is mostly a solved problem). – Perseids May 20 '20 at 18:39
  • "For live connections use TLS (be sure to check the hostname of the certificate and the issuer chain)." That parenthetical part is especially important. If you're in an application where it's not feasible to guarantee that the server will have a certificate issued by a CA trusted by the client and kept up-to-date, then **_don't_** use TLS. As the RFC explicitly points out, TLS' key negotiation scheme is _not_ secure against MitM attacks unless the client can authenticate the server's certificate. A MitM can just set up separate TLS connections with both server and client and they wouldn't know – reirab Jan 20 '21 at 00:32
  • This is why Wi-Fi doesn't use something like TLS, for example. Random Wi-Fi access points aren't going to have server certificates that an arbitrary Wi-Fi client will be able to verify, thus a completely different scheme based on a shared secret instead of PKI is used instead (at least as of WPA2, I'm not as familiar with the scheme in WPA3 yet.) – reirab Jan 20 '21 at 00:35
  • @reirab: I've your able to set up a pre-shared key between server and client, it should also be doable to store the root certificate of a private custom CA at your client. Even better, when you have control over server and client, you can also authenticate your client with client certificates, which makes key management much simpler if you have many different clients. Also: there are PSK authentication methods for TLS as well, https://en.wikipedia.org/wiki/TLS-PSK – Perseids Feb 11 '21 at 09:08
  • @Perseids In reality, though, when you're developing a system that's going to be managed by regular users rather than IT professionals, the odds that the average user is going to actually be bothered to copy those keys between the server and client are small, hence why Wi-Fi doesn't do that and uses a password-based authentication method instead. It took something like a decade to get the average person to stop leaving their Wi-Fi access point completely unsecured. TLS-PSK isn't supposed to be used with password-based secrets, but there is TLS-SRP for that. – reirab Feb 11 '21 at 14:54
349
  • ECB should not be used if encrypting more than one block of data with the same key.

  • CBC, OFB and CFB are similar, however OFB/CFB is better because you only need encryption and not decryption, which can save code space.

  • CTR is used if you want good parallelization (ie. speed), instead of CBC/OFB/CFB.

  • XTS mode is the most common if you are encoding a random accessible data (like a hard disk or RAM).

  • OCB is by far the best mode, as it allows encryption and authentication in a single pass. However there are patents on it in USA.

The only thing you really have to know is that ECB is not to be used unless you are only encrypting 1 block. XTS should be used if you are encrypting randomly accessed data and not a stream.

  • You should ALWAYS use unique IV's every time you encrypt, and they should be random. If you cannot guarantee they are random, use OCB as it only requires a nonce, not an IV, and there is a distinct difference. A nonce does not drop security if people can guess the next one, an IV can cause this problem.
Erwan Legrand
  • 3,672
  • 24
  • 26
myforwik
  • 3,764
  • 1
  • 13
  • 4
  • 66
    [CBC, OFB and CFB](http://en.wikipedia.org/wiki/Cipher_modes) are far from identical. – Jonathan Leffler Oct 17 '10 at 02:46
  • 23
    CTR is amenable to parallelization because you can split the message into chunks, each chunk having a range of counter values associated with it, and encrypt (or decrypt) each chunk independently. By contrast, CFB relies on the output from the previous block as one of the inputs to the next, so it is rigorously sequential and inherently non-parallelizable. Similar for the other modes mentioned. – Jonathan Leffler Oct 17 '10 at 02:47
  • 10
    Even if you are encrypting only one block, ECB should not be used if you will be encrypting that one block more than once (even possibly more than once) with the same key. – yfeldblum Nov 24 '10 at 13:53
  • 26
    ...how does an answer that says "CBC, OFB and CFB are identical" not have a single downvote? – Michael Mrozek Feb 26 '12 at 20:39
  • 2
    OFB and CFB are very nice because they are meant for streaming. No need to track of block size, especially useful if you are doing on-the-fly encryption/decryption. Also, no need for special buffer logic during transmission (think of packet fragmentation). – m33lky Mar 11 '12 at 03:10
  • 1
    Also consider CCM, it's a slower but unencumbered mode with properties similar to OCB. – Jeffrey Hantin Oct 11 '12 at 06:08
  • 32
    [GCM](http://en.wikipedia.org/wiki/Galois/Counter_Mode) is very similar to OCB (performance and other properties), but it is not encumbered by any patents, so it is the best choice. The only downside is the fact that the implementation is highly complex – but you don't have to worry about that if you use a library. – ntoskrnl Aug 24 '13 at 17:50
  • 6
    In response to OCB being "by far the best": OCB can only encrypt 64GB of data with the same key without leaking information. [https://en.wikipedia.org/wiki/OCB_mode#Attacks] – Calder Oct 25 '13 at 21:28
  • by the way CTR also allows for a non-random but unique nonce, like a plain counter. – My1 Feb 27 '17 at 10:25
  • In addition to paralleling, CTR also supports random access if you're using a plain counter or similar. – iBug Apr 22 '19 at 04:57
45

A formal analysis has been done by Phil Rogaway in 2011, here. Section 1.6 gives a summary that I transcribe here, adding my own emphasis in bold (if you are impatient, then his recommendation is use CTR mode, but I suggest that you read my paragraphs about message integrity versus encryption below).

Note that most of these require the IV to be random, which means non-predictable and therefore should be generated with cryptographic security. However, some require only a "nonce", which does not demand that property but instead only requires that it is not re-used. Therefore designs that rely on a nonce are less error prone than designs that do not (and believe me, I have seen many cases where CBC is not implemented with proper IV selection). So you will see that I have added bold when Rogaway says something like "confidentiality is not achieved when the IV is a nonce", it means that if you choose your IV cryptographically secure (unpredictable), then no problem. But if you do not, then you are losing the good security properties. Never re-use an IV for any of these modes.

Also, it is important to understand the difference between message integrity and encryption. Encryption hides data, but an attacker might be able to modify the encrypted data, and the results can potentially be accepted by your software if you do not check message integrity. While the developer will say "but the modified data will come back as garbage after decryption", a good security engineer will find the probability that the garbage causes adverse behaviour in the software, and then he will turn that analysis into a real attack. I have seen many cases where encryption was used but message integrity was really needed more than the encryption. Understand what you need.

I should say that although GCM has both encryption and message integrity, it is a very fragile design: if you re-use an IV, you are screwed -- the attacker can recover your key. Other designs are less fragile, so I personally am afraid to recommend GCM based upon the amount of poor encryption code that I have seen in practice.

If you need both, message integrity and encryption, you can combine two algorithms: usually we see CBC with HMAC, but no reason to tie yourself to CBC. The important thing to know is encrypt first, then MAC the encrypted content, not the other way around. Also, the IV needs to be part of the MAC calculation.

I am not aware of IP issues.

Now to the good stuff from Professor Rogaway:

Block ciphers modes, encryption but not message integrity

ECB: A blockcipher, the mode enciphers messages that are a multiple of n bits by separately enciphering each n-bit piece. The security properties are weak, the method leaking equality of blocks across both block positions and time. Of considerable legacy value, and of value as a building block for other schemes, but the mode does not achieve any generally desirable security goal in its own right and must be used with considerable caution; ECB should not be regarded as a “general-purpose” confidentiality mode.

CBC: An IV-based encryption scheme, the mode is secure as a probabilistic encryption scheme, achieving indistinguishability from random bits, assuming a random IV. Confidentiality is not achieved if the IV is merely a nonce, nor if it is a nonce enciphered under the same key used by the scheme, as the standard incorrectly suggests to do. Ciphertexts are highly malleable. No chosen ciphertext attack (CCA) security. Confidentiality is forfeit in the presence of a correct-padding oracle for many padding methods. Encryption inefficient from being inherently serial. Widely used, the mode’s privacy-only security properties result in frequent misuse. Can be used as a building block for CBC-MAC algorithms. I can identify no important advantages over CTR mode.

CFB: An IV-based encryption scheme, the mode is secure as a probabilistic encryption scheme, achieving indistinguishability from random bits, assuming a random IV. Confidentiality is not achieved if the IV is predictable, nor if it is made by a nonce enciphered under the same key used by the scheme, as the standard incorrectly suggests to do. Ciphertexts are malleable. No CCA-security. Encryption inefficient from being inherently serial. Scheme depends on a parameter s, 1 ≤ s ≤ n, typically s = 1 or s = 8. Inefficient for needing one blockcipher call to process only s bits . The mode achieves an interesting “self-synchronization” property; insertion or deletion of any number of s-bit characters into the ciphertext only temporarily disrupts correct decryption.

OFB: An IV-based encryption scheme, the mode is secure as a probabilistic encryption scheme, achieving indistinguishability from random bits, assuming a random IV. Confidentiality is not achieved if the IV is a nonce, although a fixed sequence of IVs (eg, a counter) does work fine. Ciphertexts are highly malleable. No CCA security. Encryption and decryption inefficient from being inherently serial. Natively encrypts strings of any bit length (no padding needed). I can identify no important advantages over CTR mode.

CTR: An IV-based encryption scheme, the mode achieves indistinguishability from random bits assuming a nonce IV. As a secure nonce-based scheme, the mode can also be used as a probabilistic encryption scheme, with a random IV. Complete failure of privacy if a nonce gets reused on encryption or decryption. The parallelizability of the mode often makes it faster, in some settings much faster, than other confidentiality modes. An important building block for authenticated-encryption schemes. Overall, usually the best and most modern way to achieve privacy-only encryption.

XTS: An IV-based encryption scheme, the mode works by applying a tweakable blockcipher (secure as a strong-PRP) to each n-bit chunk. For messages with lengths not divisible by n, the last two blocks are treated specially. The only allowed use of the mode is for encrypting data on a block-structured storage device. The narrow width of the underlying PRP and the poor treatment of fractional final blocks are problems. More efficient but less desirable than a (wide-block) PRP-secure blockcipher would be.

MACs (message integrity but not encryption)

ALG1–6: A collection of MACs, all of them based on the CBC-MAC. Too many schemes. Some are provably secure as VIL PRFs, some as FIL PRFs, and some have no provable security. Some of the schemes admit damaging attacks. Some of the modes are dated. Key-separation is inadequately attended to for the modes that have it. Should not be adopted en masse, but selectively choosing the “best” schemes is possible. It would also be fine to adopt none of these modes, in favor of CMAC. Some of the ISO 9797-1 MACs are widely standardized and used, especially in banking. A revised version of the standard (ISO/IEC FDIS 9797-1:2010) will soon be released [93].

CMAC: A MAC based on the CBC-MAC, the mode is provably secure (up to the birthday bound) as a (VIL) PRF (assuming the underlying blockcipher is a good PRP). Essentially minimal overhead for a CBCMAC-based scheme. Inherently serial nature a problem in some application domains, and use with a 64-bit blockcipher would necessitate occasional re-keying. Cleaner than the ISO 9797-1 collection of MACs.

HMAC: A MAC based on a cryptographic hash function rather than a blockcipher (although most cryptographic hash functions are themselves based on blockciphers). Mechanism enjoys strong provable-security bounds, albeit not from preferred assumptions. Multiple closely-related variants in the literature complicate gaining an understanding of what is known. No damaging attacks have ever been suggested. Widely standardized and used.

GMAC: A nonce-based MAC that is a special case of GCM. Inherits many of the good and bad characteristics of GCM. But nonce-requirement is unnecessary for a MAC, and here it buys little benefit. Practical attacks if tags are truncated to ≤ 64 bits and extent of decryption is not monitored and curtailed. Complete failure on nonce-reuse. Use is implicit anyway if GCM is adopted. Not recommended for separate standardization.

authenticated encryption (both encryption and message integrity)

CCM: A nonce-based AEAD scheme that combines CTR mode encryption and the raw CBC-MAC. Inherently serial, limiting speed in some contexts. Provably secure, with good bounds, assuming the underlying blockcipher is a good PRP. Ungainly construction that demonstrably does the job. Simpler to implement than GCM. Can be used as a nonce-based MAC. Widely standardized and used.

GCM: A nonce-based AEAD scheme that combines CTR mode encryption and a GF(2128)-based universal hash function. Good efficiency characteristics for some implementation environments. Good provably-secure results assuming minimal tag truncation. Attacks and poor provable-security bounds in the presence of substantial tag truncation. Can be used as a nonce-based MAC, which is then called GMAC. Questionable choice to allow nonces other than 96-bits. Recommend restricting nonces to 96-bits and tags to at least 96 bits. Widely standardized and used.

TheGreatContini
  • 5,791
  • 1
  • 18
  • 25
  • This is a logical for for the Documentation section, the [Encryption topic](http://stackoverflow.com/documentation/encryption/topics() is a great fit. – zaph Mar 07 '17 at 22:17
  • 1
    GCM mode: Given that most on SO have little to no knowledge of encryption, will not use any mode correctly, generally not using authentication and often using ECB mode GCM mode is probably they best choice *here*. Unfortunately the lack of platform implementations, in some cases (iOS) no vendor support, poor vetting in many cases lack of hardware support it is currently problematic. Otherwise it is good for the uninitiated in encryption since it has authentication built in and seems to be the future. – zaph Mar 07 '17 at 22:29
  • 3
    CTR mode: I disagree with CTR mode as the best choice because of so many failures in practice, mainly IV reuse. Even Microsoft has screwed this up at least a couple of times. – zaph Mar 07 '17 at 22:30
  • @zaph All modes have problems with IV re-use. Why is CTR worse than any other mode in this situation? – TheGreatContini Mar 07 '17 at 22:39
  • 1
    CBC mode: Probably the most common mode and most used mode on SO, ECB (which should not be used) excepted. Major usage flaws are a non-random IV but we are seeing more correct usages with a CSPRNG. Padding Oracles, while an issue, are easily remediated by simply ignoring and not returning padding errors. Some implementations (e.g. Common Crypto) do not report padding errors in an essentially successful way of avoiding them at the API level. – zaph Mar 07 '17 at 22:40
  • 1
    IMO CTR is worse because it is a simple xor where as CBC has propagation from block to block as do several other modes. It may seem easy but there have been major failures in mass market code. – zaph Mar 07 '17 at 22:45
  • @zaph: In regard to GCM being the best choice, I disagree. The fragility of GCM is documented all over the web. If you re-use an IV with GCM, attacker recovers key. If you re-use an IV with CBC, attacker can maybe (in some circumstances) launch an attack that recovers plaintext, but not the key. There is a world of difference between these two scenarios. – TheGreatContini Mar 07 '17 at 23:04
  • No argument. IMO what we need is a standard that can be implemented that includes a random IV, authentication, versioning, padding and an option for key derivation. IOW putting together all the pieces that we know is necessary. The casual user (common developer) should not have to be bothered with the things and given a chance to get them wrong. GCM is a step in the right direction but not fully baked. – zaph Mar 07 '17 at 23:18
  • I would also like to see key locker/keychain integration along as we see on a couple of platforms. A user would specify a key name, encryption algorithm and the data. The key could be returned for decryption on another device. – zaph Mar 07 '17 at 23:21
  • I don't understand your comments about GCM being insecure and key recovery, the encryption is simply CTR mode with auth data and tag which you rate "Overall, usually the best and most modern way to achieve privacy-only encryption". See: [GCM mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode) – zaph Mar 07 '17 at 23:53
  • @zaph See [this paper](https://eprint.iacr.org/2016/475.pdf) for information about recovering keys when IVs are reused in GCM. I see crypto problems all the time in my daily code review duty, and the #1 issue that comes up over and over again is hardcoded IVs. GCM is completely destroyed when this happens. CBC on the other hand leaks information but does not allow key recovery. That is why I do not recommend GCM. – TheGreatContini Mar 08 '17 at 02:55
  • Thanks for the paper link. But how is this different from CTR mode nonce reuse? It seems the same argument can be made against AES-CTR which is the encryption GCM uses. – zaph Mar 08 '17 at 03:05
  • 1
    @zaph No, AES-GCM is very different than AES-CTR (AES-CTR has no Galois multiplication). If you are claiming that one can recover keys when an IV is reused for AES-CTR, then you would be the first to be making such a claim, and the burden would be upon you to provide evidence. Honestly, I can promise you that that claim simply is not true. – TheGreatContini Mar 08 '17 at 03:08
  • See also [here](http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/comments/800-38_Series-Drafts/GCM/Joux_comments.pdf): the attack on IV reuse works on the authentication tag, which does not exist for normal CTR mode. This attack is unique to GCM and does not apply to CTR. – TheGreatContini Mar 08 '17 at 03:17
  • 1
    From reading the linked paper it seems that only the authentication key is obtained, not the encryption key from nonce reuse. That does not seem to be the claim in the comments here that the encryption key is obtained. While obtaining the authentication key allows tampering with the message it does not allow recovering the message. Please point out where I may be wrong. – zaph Mar 08 '17 at 05:47
  • @zaph: You are correct, the authentication key is obtained, not the encryption key. – TheGreatContini Mar 08 '17 at 20:52
  • I literally just recovered a key when using AES_CTR and an IV twice to demonstrate it could be done. It's trivial. NEVER reuse an IV. Just don't ever do it. Really. Ever. – Erik Aronesty Jul 18 '18 at 22:24
  • @ErikAronesty You were able to recover an AES key from an AES-CTR's cipher stream? So, you basically broke AES? You should publish your findings. – jschultz410 Jan 14 '21 at 10:38
  • 1
    @jschultz410 not worth publishing. i didn't break AES. I broke AES *used incorrectly*. Reusing an IV in AES land is well known to be insecure – Erik Aronesty Jan 14 '21 at 17:31
  • @jschultz410 here's a link to why: https://crypto.stackexchange.com/questions/2991/why-must-iv-key-pairs-not-be-reused-in-ctr-mode – Erik Aronesty Jan 14 '21 at 17:33
  • @ErikAronesty Yes, using AES-CTR with the same IV twice on different data allows someone to trivially get a good look at the unencrypted data (their XOR). But you said you "recovered a key when using AES_CTR and an IV twice." Recovering the encryption key used by AES from AES-CTR, even when the same IV is used multiple times, means that you were able to recover AES's key from one cipher steam. You know the cipher stream generated by the IV (because you can XOR out the chosen plaintext from the ciphertext) and from there you recovered the key, which is completely breaking AES. – jschultz410 Jan 20 '21 at 23:42
  • @jschultz410 sorry, i recovered the plaintext, not the key. in this case the plaintext *was* a private key, but that's not relevant. – Erik Aronesty Jan 21 '21 at 14:15
31
  1. Anything but ECB.
  2. If using CTR, it is imperative that you use a different IV for each message, otherwise you end up with the attacker being able to take two ciphertexts and deriving a combined unencrypted plaintext. The reason is that CTR mode essentially turns a block cipher into a stream cipher, and the first rule of stream ciphers is to never use the same Key+IV twice.
  3. There really isn't much difference in how difficult the modes are to implement. Some modes only require the block cipher to operate in the encrypting direction. However, most block ciphers, including AES, don't take much more code to implement decryption.
  4. For all cipher modes, it is important to use different IVs for each message if your messages could be identical in the first several bytes, and you don't want an attacker knowing this.
Theran
  • 3,706
  • 17
  • 31
  • To support your Point 1 (+1 for that btw): http://www.codinghorror.com/blog/archives/001267.html – Michael Stum Aug 03 '09 at 05:55
  • 1
    You shouldn't start CTR with a random number, since that has a small-but-increasing chance of colliding with part of a previous message. Instead monotonically increment it (this may mean remembering where you are up to in persistent storage), and re-key if (when) you run out of counter. – caf Aug 03 '09 at 11:27
  • @Theran - point 2 - a different random number for each message? No, I think that is not correct. I am under the impression that starting the counter always at zero is just fine. @caf, I think when Theran says "message" he does not mean "block". Of course the counter gets incremented for each block of a particular message that run through the cipher. What Theran seems to be saying is that each message must start with a different initial value for the counter. And I think this is not correct. – Cheeso Aug 03 '09 at 11:51
  • 1
    re: point 3 - I have read papers that say, for example, CTR mode is smaller to implement because the decrypt is the same transform as encrypt. Therefore half the code. But as I say, not relevant on a server-class machine. – Cheeso Aug 03 '09 at 11:53
  • Yes, I misspoke. It's the IV/nonce that should change for CTR mode, but that gets combined with the counter before encrypting, so I tend to just think of it as a random starting point for the counter. As far as only having to use the cipher in the encrypting direction saving space, for many ciphers you only have to reverse the subkeys to decrypt. AES is a bit bulky for decrypting, but it's not like you can implement it on a uC with 128 bytes of RAM anyways. The subkeys take more RAM than that! – Theran Aug 04 '09 at 03:50
  • @Cheeso: If you are sending multiple messages with the same key (like in multiple packets of TLS/IPSec/...), these messages should not all have a zero initialization vector (but an incrementing or random one). If you change the key anyways for each message (like in OpenPGP), you can start with 0 without problems. – Paŭlo Ebermann Oct 25 '11 at 13:54
  • to clarify, salts are allowed to be the same, nonces are not allowed to be the same but can be produced in a predictable manner (eg sequentially) and IVs are not the same and not produced in a predictable manner – devnul3 Jan 20 '12 at 21:56
13

Have you start by reading the information on this on Wikipedia - Block cipher modes of operation? Then follow the reference link on Wikipedia to NIST: Recommendation for Block Cipher Modes of Operation.

dbreaux
  • 4,709
  • 1
  • 20
  • 56
KTC
  • 8,805
  • 5
  • 30
  • 37
  • 7
    This answer does not meet quality standards of Stackoverflow: please assume, in your answer, that all external links will have gone dead, and summarise – if not outright copy – the relevant information, ideally in a way designed to answer the original question best. – mirabilos Apr 04 '14 at 12:29
  • 5
    @mirabilos Coming along nearly 5 years later referring to norms and standards that didn't exist at the time, really? I especially like talking about dead links when both here are actually still very much live, and given the site in question are likely to remain so for another 5 years. Oh well. – KTC Apr 04 '14 at 20:59
  • 3
    @mirabilos You *may* come correct *arguably*, but your complaint against an answer that **appeared to have been made** 5 years ago where norms were different is not applicable. You should have just admitted your mistake. Even if that's not the case and that you're instead implying that it should be updated or changed, it's still not obligatory. The answer sufficed from how it was. – konsolebox Jan 05 '15 at 04:51
  • 1
    @KTC Except when the government shuts down and the site is offline. Your answer could have been useful information, but at the moment, is completely missing. So the reader of this question and it's answers is still left wondering both what was updated in 2014 (due to an incomplete answer) and the current status (due to a government shutdown of the NIST website). I'd love to add the missing information, however... – G DeMasters Jan 20 '19 at 07:30
  • Update, if you don’t want downvotes. They should feel free to suggest and comments are specifically for that purpose. – Константин Ван May 13 '21 at 13:12
11

You might want to chose based on what is widely available. I had the same question and here are the results of my limited research.

Hardware limitations

STM32L (low energy ARM cores) from ST Micro support ECB, CBC,CTR GCM
CC2541 (Bluetooth Low Energy) from TI supports ECB, CBC, CFB, OFB, CTR, and CBC-MAC

Open source limitations

Original rijndael-api source  - ECB, CBC, CFB1
OpenSSL - command line CBC, CFB, CFB1, CFB8, ECB, OFB
OpenSSL - C/C++ API    CBC, CFB, CFB1, CFB8, ECB, OFB and CTR
EFAES lib [1] - ECB, CBC, PCBC, OFB, CFB, CRT ([sic] CTR mispelled)  
OpenAES [2] - ECB, CBC 

[1] http://www.codeproject.com/Articles/57478/A-Fast-and-Easy-to-Use-AES-Library

[2] https://openaes.googlecode.com/files/OpenAES-0.8.0.zip

Mark Lakata
  • 18,024
  • 5
  • 88
  • 112
  • 1
    ST Micro: EBC should be ECB; FYI: e.g. STM32L4A6 supports 128-bit and 256-bit AES, with ECB, CBC, CTR, GCM, as well as Galois message authentication code (GMAC) or cipher message authentication code mode CMAC chaining algorithms are also supported by hardware. – Tom Kuschel Mar 20 '18 at 11:12
-4

I know one aspect: Although CBC gives better security by changing the IV for each block, it's not applicable to randomly accessed encrypted content (like an encrypted hard disk).

So, use CBC (and the other sequential modes) for sequential streams and ECB for random access.

chris166
  • 4,735
  • 4
  • 22
  • 25
  • Ah, right, of course. The CBC XORs the prior ciphertext block with the plaintext block before encryption. The first block uses the IV. So to decrypt any block, you have to have successfully decrypted all prior blocks. ok, that's a good insight. – Cheeso Aug 03 '09 at 11:36
  • 6
    No, you only have to have access to the prior _ciphertext_, which doesn't require decrypting any previous blocks. – caf Aug 03 '09 at 13:57
  • Ah, well that means CBC is just fine with random access, doesn't it? – Cheeso Sep 18 '09 at 01:37
  • 4
    @Cheeso: CBC is fine for random read access, but not for random write access. Use CTR there. – Paŭlo Ebermann Oct 25 '11 at 13:56
  • 3
    @PaŭloEbermann For random access CTR isn't a good idea, since it allows severe attacks if an attacker observes two versions of the ciphertext. Use XTS or a tweakable blockcipher instead. – CodesInChaos Dec 11 '12 at 15:31
  • 1
    There is absolutely no reason to use ECB anywhere – Antti Haapala Oct 16 '17 at 13:20
  • ECB mode shouldn't ever really be used anywhere. The only place I've ever used it is to encrypt a single block using a cipher. For example, using OpenSSL's generic symmetric encryption API (EVP), but actually wanting to get the raw result from a single (e.g. - AES) block encryption. This can allow you to implement some form of CTR mode yourself. You could use this to generate random-ish streams of data, such as unpredictable IVs, from a single random key for example. Yes, you could instead call the block cipher function directly, but the EVP API allows you to swap ciphers with ease. – jschultz410 Jan 14 '21 at 11:18