In the previous article I introduced the AES block cipher. This, however, is not too much use on its own. AES encrypts a single 128 bit (16 byte) block. In almost every situation there will be a requirement to encrypt a much larger amount of data. This is solved by using AES in a “mode of operation”.
Several modes exist for using AES block cipher on larger data sets. Several of these have been specified by NIST as standards. The first and most obvious one is known as AES-ECB (Electronic code book). This should really not exist as a standard as it is a terrible idea to use in every situation. Basically it just divides the larger data set into 16 bytes chunks and encrypts each block. The problem with this is that any time the same block of input appears, exactly the same output will be produced. For example if you had a file with large runs of all zeros in it, then you would see a repeating pattern on 16 bytes recurring in the output. So never use ECB, there are plenty of good modes to choose from.
Today I am going to talk about AES-CTR (AES in “counter” mode). This is actually my favourite mode. It turns AES into a stream cipher which is very easy to work with, it can be used on any sized data. It is also more convent to use than RC4 because you can jump to any offset within the output stream and start from there. With RC4 you would have to “spin” through all the previous stream to get to a specific point.
AES CTR is very simple mode. Basically you have a counter which you store in a 128 bit block and you then encrypt that block with AES, that is your first 16 bytes of stream output. You then increment the counter and encrypt to produce the second block, and so on. To add another level of convenience and speed the counter block is also used as an “Initialisation vector” (iv). This allows someone to create an entirely new stream without having to reinitialise the AES key (this is a somewhat expensive procedure).
NIST don’t actually specify how you should combine an IV and the counter, but suggest a few ways. The method I like best is to split the block into two halves. The first half is the 64bit IV. The second half is the 64bit block counter (store in big endian form). This is the method that openssl uses, and the method I chose to use. The advantage of this method over xoring the IV and counter together is that it is guaranteed that you will never “overlap” by having particular chosen IVs and counters. Remember that this is a stream cipher and just like RC4 if you ever reuse the stream you have removed all security. However with AES CTR it is only necessary to have the a unique set of BOTH Key and IV. Therefore the same Key can be reused with unique IVs. Similarly you may not want to bother with the IV at all and only use unique keys. Personally if I am in a situation where I will be generating new keys for each use, I will generate a key 64 bits larger than AES needs and use the last 64 bits as the IV.
Public Domain source code for AES-CTR
These depend on the AES block cipher files:
I have made a simple program called AesCtrOutput that takes a key and and IV in hex form and produces the specified number of bytes out in hex on stdout.
The syntax for this program is pretty simple
Syntax AesCtrOutput <Key> <IV> <NumBytes> <Key> - 128, 192, or 256 bit written as hex <IV> - 64 bit written as hex <NumBytes> - Number of bytes of stream to output
>AesCtrOutput.exe 0102030405060708a1a2a3a4a5a6a7a8 b1b2b3b4b5b6b7b8 48 7f1e34c4f33ee8dc162af7fbed6f317aa5806d244dd86557268be2296708ef7327aa4e5ed5780a3c070209ea2db04d79
This result can be confirmed as being the same as openssl by using the following command:
> openssl enc -aes-128-ctr -K 0102030405060708a1a2a3a4a5a6a7a8 -iv b1b2b3b4b5b6b7b8 -in zero.bin -out output.bin
If zero.bin is a file contain 48 zero bytes then output.bin will be created as 48 bytes with the same bytes as in the AesCtrOutput.exe example.
I have made a .zip file containing all the source for AES and AESCTR along with those two sample programs and a unit test set. The root of the folder contains a CMakeLists.txt file for building with CMake.
This is free and unencumbered software released into the public domain.