- From: Zooko Wilcox-OHearn <zooko@leastauthority.com>
- Date: Fri, 14 Sep 2012 09:01:19 -0600
- To: "public-webcrypto@w3.org" <public-webcrypto@w3.org>
Folks: I think there's some confusion about terminology here, but terminology is important! Misuse of ECB mode is one of the most common security flaws in code written by non-specialists, and it is typically a fatal flaw. Choosing our words carefully in our API spec and in our docs might help. Suppose you have a function that encrypts an input with a fixed AES key, like this: encryptor = window.crypto.createEncrypter(someAlgorithmSpec, aesKey1); encryptor.processData(inputData); Okay, now if inputData is exactly 16 bytes (one AES block), then it is clear what to do — encrypt the inputData with AES and emit the resulting ciphertext. If the inputData is 15 bytes then it is probably a good idea to raise an exception. (It might be tempting to automatically pad with zero bytes on the right, but then on subsequent decryption the programmer wouldn't know how many of the trailing zero bytes were provided by the initial input and how many were added by the processData() function.) But what if the inputData is 32 bytes, or some other multiple of 16 bytes? If you go ahead and encrypt the first block with aesKey1, and then encrypt the second block with aesKey1, then your function is implementing ECB mode, and "someAlgorithmSpec" should probably be something like { name: "AES-ECB" }. ECB mode is inherently insecure — once you encrypt the second block with the same AES key that you used to encrypt the first block, then it is not safe to expose both of the resulting ciphertext blocks to an enemy cryptanalyst. If instead, you handle a 32-byte input by raising an exception, then your function is implementing bare AES, and perhaps it shouldn't have an "algorithm spec" at all, because it isn't an encryption function the way AES-CTR, AES-CBC, and AES-ECB are. Instead maybe it could be a different API entirely, something like: aesFunc = window.crypto.createPrimitive({ name: "AES"}, aesKey1); aesFunc.processData(inputData); Now I have three assertions to make here, and you may disagree with some of them while accepting others, so I'll enumerate them. 1. ECB mode is a different beast from an AES function, with different security implications. 2. ECB mode is often misused by non-experts, resulting in insecure systems. 3. ECB mode is almost never used by experts, although a bare AES function often is. For example, the Bitlocker example suggested by Vijay: http://download.microsoft.com/download/0/2/3/0238acaf-d3bf-4a6d-b3d6-0a0be4bbb36e/BitLockerCipher200608.pdf The definition of IV_s in section 4.2 is as follows: IVₛ := E(Kₐₑₛ, e(s)) E() is the AES encryption function, and e() is an encoding function that maps each sector number s into a unique 16-byte value. When it says "the AES encryption function", it means the bare function that maps a key and a 16-byte plaintext block to a a 16-byte ciphertext block. (By the way, the author of Bitlocker—Niels Ferguson—is an expert indeed. Of the limited cryptography that I know, I learned much of it from Niels's writings and his personal instruction.) Okay, those are my assertions. Now I have a few recommendations: 1. Distinguish between AES-ECB and bare AES in docs and names. 2. Standardize the bare AES block encryption function. It is very useful. (If it isn't provided by the spec then programmers could kludge it by using AES-CBC mode on a single input block and fixing the IV to all zeroes. Thanks to David-Sarah Hopwood for suggesting this kludge.) 3. Include AES-CTR mode among the recommended algorithms. CTR mode is great! 4. I think I would recommend excluding AES-ECB mode entirely from the spec. I admit that there could exist cases where it could be useful. The only such case I can think of is the one Ryan suggested: efficiently implementing a non-standard CTR mode (where the counter doesn't increment normally, but increments some other bits than the lowest-order bits, or otherwise modifies the counter value in some deterministic way for each block). However, that is only a hypothetical case. I don't think I've seen a real-world case of ECB mode being used for anything correctly, and I've seen many cases of ECB mode being used incorrectly and resulting in security failures. Regards, Zooko Wilcox-O'Hearn
Received on Friday, 14 September 2012 15:01:50 UTC