W3C home > Mailing lists > Public > public-webcrypto@w3.org > September 2012

Re: Support for ECB

From: Zooko Wilcox-OHearn <zooko@leastauthority.com>
Date: Fri, 14 Sep 2012 09:01:19 -0600
Message-ID: <CAM_a8JxZ7LOnE6M9TnmMqG0RJo9qNxQM9jZ9+1wJSkRd9adGiA@mail.gmail.com>
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 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Friday, 14 September 2012 15:01:50 GMT