Understanding AES Operation Modes
Published: 2023-06-30 21:04:52



The Advanced Encryption Standard (AES) is a widely used symmetric encryption algorithm that ensures the confidentiality and integrity of data. While AES itself provides robust encryption, different operation modes can enhance its functionality and address specific requirements in various applications. In this blog post, we will explore several AES operation modes and their unique characteristics.

We'll use the following key and plaintext for the examples below
```python
key = b'0123456789ABCDEF'
plaintext = b'thisisapassword'
```

### ECB Mode: Electronic Code Book Mode

The Electronic Code Book (ECB) mode is the simplest operation mode for AES. It divides the plaintext into blocks of fixed size and encrypts each block independently using the same key. However, this mode has a significant limitation: identical plaintext blocks result in identical ciphertext blocks, which may leak information.

```python
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad, unpad

# Create an AES cipher object with a key
cipher = AES.new(key, AES.MODE_ECB)

# Encrypt a plaintext
ciphertext = cipher.encrypt(pad(plaintext, AES.block_size))

# Decrypt the ciphertext
decrypted = unpad(cipher.decrypt(ciphertext), AES.block_size)
```

### CBC Mode: Cipher Block Chaining Mode

Cipher Block Chaining (CBC) mode addresses the vulnerability of ECB mode by introducing feedback from the previous ciphertext block into the encryption process. Each plaintext block is XORed with the previous ciphertext block before encryption, adding randomness and preventing identical plaintext blocks from producing identical ciphertext blocks.

```python
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad, unpad
from Cryptodome.Random import get_random_bytes

# Create an AES cipher object with a random initialization vector (IV)
cipher = AES.new(key, AES.MODE_CBC, iv=get_random_bytes(AES.block_size))

# Encrypt a plaintext
ciphertext = cipher.encrypt(pad(plaintext, AES.block_size))

# Decrypt the ciphertext
decrypted = unpad(cipher.decrypt(ciphertext), AES.block_size)
```

### CFB Mode: Cipher FeedBack Mode

Cipher FeedBack (CFB) mode converts a block cipher into a stream cipher by allowing the encryption of individual bytes rather than fixed-size blocks. It uses the previous ciphertext segment as the input for the encryption process, generating a keystream that is XORed with the plaintext to produce the ciphertext.

```python
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad, unpad
from Cryptodome.Random import get_random_bytes

# Create an AES cipher object with a random initialization vector (IV)
cipher = AES.new(key, AES.MODE_CFB, iv=get_random_bytes(AES.block_size))

# Encrypt a plaintext
ciphertext = cipher.encrypt(plaintext)

# Decrypt the ciphertext
decrypted = cipher.decrypt(ciphertext)
```

### OFB Mode: Output FeedBack Mode

Output FeedBack (OFB) mode is similar to CFB mode but operates as a stream cipher. It generates a keystream by encrypting the previous ciphertext segment and XORing it with the plaintext to produce the ciphertext. Unlike CFB mode, OFB mode doesn't require padding.

```python
from Cryptodome.Cipher import AES
from Cryptodome.Random import get_random_bytes

# Create an AES cipher object with a random initialization vector (IV)
cipher = AES.new(key, AES.MODE_OFB, iv=get_random_bytes(AES.block_size))

# Encrypt a plaintext
ciphertext = cipher.encrypt(plaintext)

# Decrypt the ciphertext
decrypted = cipher.decrypt(ciphertext)
```

### CTR Mode: Counter Mode

Counter (CTR) mode transforms a block cipher into a stream cipher. It generates a keystream by encrypting a counter value concatenated with a nonce, and then XORs it with the plaintext to produce the ciphertext

. The same keystream can be used for encryption and decryption.

```python
from Cryptodome.Cipher import AES
from Cryptodome.Util.Counter import Counter

# Create a counter object with a unique nonce and initial counter value
ctr = Counter.new(nbits=128, nonce=get_random_bytes(8))

# Create an AES cipher object with the counter object
cipher = AES.new(key, AES.MODE_CTR, counter=ctr)

# Encrypt a plaintext
ciphertext = cipher.encrypt(plaintext)

# Decrypt the ciphertext
decrypted = cipher.decrypt(ciphertext)
```

### GCM Mode: Galois Counter Mode

Galois Counter Mode (GCM) combines AES encryption with authentication, providing both confidentiality and integrity of the data. It uses a counter mode for encryption and an additional authentication tag that verifies the integrity of the ciphertext.

```python
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad, unpad
from Cryptodome.Random import get_random_bytes

# Create an AES cipher object with a random initialization vector (IV)
cipher = AES.new(key, AES.MODE_GCM, nonce=get_random_bytes(12))

# Encrypt a plaintext
ciphertext, tag = cipher.encrypt_and_digest(pad(plaintext, AES.block_size))

# Decrypt the ciphertext
decrypted = unpad(cipher.decrypt_and_verify(ciphertext, tag), AES.block_size)
```

### XTS Mode: XEX-based Tweaked CodeBook Mode with CipherText Stealing

XTS mode is commonly used for disk encryption. It applies two AES keys to each plaintext block, providing confidentiality and protection against manipulation. One key encrypts the data, while the other key encrypts the index value of the block.

```python
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad, unpad
from Cryptodome.Random import get_random_bytes

# Create an AES cipher object with two keys and a sector size
cipher = AES.new((key1, key2), AES.MODE_XTS, sector_size=512)

# Encrypt a plaintext
ciphertext = cipher.encrypt(pad(plaintext, 512))

# Decrypt the ciphertext
decrypted = unpad(cipher.decrypt(ciphertext), 512)
```

### References

https://www.veracrypt.fr/en/Modes%20of%20Operation.html
https://stackoverflow.com/questions/1220751/how-to-choose-an-aes-encryption-mode-cbc-ecb-ctr-ocb-cfb
https://www.cryptopp.com/wiki/XTS_Mode
https://security.stackexchange.com/questions/101995/explanation-of-the-xts-encryption-mode