diff --git a/briar-api/src/org/briarproject/api/crypto/AuthenticatedCipher.java b/briar-api/src/org/briarproject/api/crypto/AuthenticatedCipher.java
index 6f60ed0526c2fe714cb80c7418ee0d3db95b2b69..8256b31febcf73f4311bc0c5e01bffaf1c7a2738 100644
--- a/briar-api/src/org/briarproject/api/crypto/AuthenticatedCipher.java
+++ b/briar-api/src/org/briarproject/api/crypto/AuthenticatedCipher.java
@@ -2,14 +2,12 @@ package org.briarproject.api.crypto;
 
 import java.security.GeneralSecurityException;
 
-/** An authenticated cipher that supports additional authenticated data. */
 public interface AuthenticatedCipher {
 
 	/**
-	 * Initializes this cipher with a key, an initialisation vector (IV) and
-	 * additional authenticated data (AAD).
+	 * Initializes this cipher with a key and an initialisation vector (IV).
 	 */
-	void init(boolean encrypt, SecretKey key, byte[] iv, byte[] aad)
+	void init(boolean encrypt, SecretKey key, byte[] iv)
 			throws GeneralSecurityException;
 
 	/** Encrypts or decrypts data in a single-part operation. */
@@ -17,8 +15,8 @@ public interface AuthenticatedCipher {
 			int outputOff) throws GeneralSecurityException;
 
 	/** Returns the length of the message authentication code (MAC) in bytes. */
-	int getMacLength();
+	int getMacBytes();
 
 	/** Returns the block size of the cipher in bytes. */
-	int getBlockSize();
+	int getBlockBytes();
 }
diff --git a/briar-core/src/org/briarproject/crypto/AuthenticatedCipherImpl.java b/briar-core/src/org/briarproject/crypto/AuthenticatedCipherImpl.java
index d001b60c5441d4f90fbeb074874485c8a4f984e0..d840313846210a7b3085f273fe47851f00202857 100644
--- a/briar-core/src/org/briarproject/crypto/AuthenticatedCipherImpl.java
+++ b/briar-core/src/org/briarproject/crypto/AuthenticatedCipherImpl.java
@@ -6,18 +6,22 @@ import org.briarproject.api.crypto.AuthenticatedCipher;
 import org.briarproject.api.crypto.SecretKey;
 import org.spongycastle.crypto.DataLengthException;
 import org.spongycastle.crypto.InvalidCipherTextException;
+import org.spongycastle.crypto.engines.AESLightEngine;
 import org.spongycastle.crypto.modes.AEADBlockCipher;
+import org.spongycastle.crypto.modes.GCMBlockCipher;
+import org.spongycastle.crypto.modes.gcm.BasicGCMMultiplier;
 import org.spongycastle.crypto.params.AEADParameters;
 import org.spongycastle.crypto.params.KeyParameter;
 
 class AuthenticatedCipherImpl implements AuthenticatedCipher {
 
+	private static final int MAC_BYTES = 16;
+
 	private final AEADBlockCipher cipher;
-	private final int macLength;
 
-	AuthenticatedCipherImpl(AEADBlockCipher cipher, int macLength) {
-		this.cipher = cipher;
-		this.macLength = macLength;
+	AuthenticatedCipherImpl() {
+		cipher = new GCMBlockCipher(new AESLightEngine(),
+				new BasicGCMMultiplier());
 	}
 
 	public int process(byte[] input, int inputOff, int len, byte[] output,
@@ -36,10 +40,11 @@ class AuthenticatedCipherImpl implements AuthenticatedCipher {
 		}
 	}
 
-	public void init(boolean encrypt, SecretKey key, byte[] iv, byte[] aad)
+	public void init(boolean encrypt, SecretKey key, byte[] iv)
 			throws GeneralSecurityException {
 		KeyParameter k = new KeyParameter(key.getBytes());
-		AEADParameters params = new AEADParameters(k, macLength * 8, iv, aad);
+		// Authenticate the IV by passing it as additional authenticated data
+		AEADParameters params = new AEADParameters(k, MAC_BYTES * 8, iv, iv);
 		try {
 			cipher.init(encrypt, params);
 		} catch(IllegalArgumentException e) {
@@ -47,11 +52,11 @@ class AuthenticatedCipherImpl implements AuthenticatedCipher {
 		}
 	}
 
-	public int getMacLength() {
-		return macLength;
+	public int getMacBytes() {
+		return MAC_BYTES;
 	}
 
-	public int getBlockSize() {
+	public int getBlockBytes() {
 		return cipher.getUnderlyingCipher().getBlockSize();
 	}
 }
diff --git a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
index 5612c407769787fd131893587e45798395047aa7..5474bcbec856f3dac9ae532024ee0d974de60f50 100644
--- a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
+++ b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
@@ -41,9 +41,6 @@ import org.spongycastle.crypto.engines.AESLightEngine;
 import org.spongycastle.crypto.generators.ECKeyPairGenerator;
 import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
 import org.spongycastle.crypto.macs.HMac;
-import org.spongycastle.crypto.modes.AEADBlockCipher;
-import org.spongycastle.crypto.modes.GCMBlockCipher;
-import org.spongycastle.crypto.modes.gcm.BasicGCMMultiplier;
 import org.spongycastle.crypto.params.ECKeyGenerationParameters;
 import org.spongycastle.crypto.params.ECPrivateKeyParameters;
 import org.spongycastle.crypto.params.ECPublicKeyParameters;
@@ -57,7 +54,6 @@ class CryptoComponentImpl implements CryptoComponent {
 	private static final int CIPHER_KEY_BYTES = 32; // 256 bits
 	private static final int AGREEMENT_KEY_PAIR_BITS = 384;
 	private static final int SIGNATURE_KEY_PAIR_BITS = 384;
-	private static final int MAC_BYTES = 16; // 128 bits
 	private static final int STORAGE_IV_BYTES = 16; // 128 bits
 	private static final int PBKDF_SALT_BYTES = 16; // 128 bits
 	private static final int PBKDF_TARGET_MILLIS = 500;
@@ -299,9 +295,7 @@ class CryptoComponentImpl implements CryptoComponent {
 	}
 
 	private AuthenticatedCipher getAuthenticatedCipher() {
-		AEADBlockCipher a = new GCMBlockCipher(new AESLightEngine(),
-				new BasicGCMMultiplier());
-		return new AuthenticatedCipherImpl(a, MAC_BYTES);
+		return new AuthenticatedCipherImpl();
 	}
 
 	public void encodeTag(byte[] tag, SecretKey tagKey, long streamNumber) {
@@ -318,6 +312,8 @@ class CryptoComponentImpl implements CryptoComponent {
 	}
 
 	public byte[] encryptWithPassword(byte[] input, String password) {
+		AuthenticatedCipher cipher = getAuthenticatedCipher();
+		int macBytes = cipher.getMacBytes();
 		// Generate a random salt
 		byte[] salt = new byte[PBKDF_SALT_BYTES];
 		secureRandom.nextBytes(salt);
@@ -329,15 +325,14 @@ class CryptoComponentImpl implements CryptoComponent {
 		byte[] iv = new byte[STORAGE_IV_BYTES];
 		secureRandom.nextBytes(iv);
 		// The output contains the salt, iterations, IV, ciphertext and MAC
-		int outputLen = salt.length + 4 + iv.length + input.length + MAC_BYTES;
+		int outputLen = salt.length + 4 + iv.length + input.length + macBytes;
 		byte[] output = new byte[outputLen];
 		System.arraycopy(salt, 0, output, 0, salt.length);
 		ByteUtils.writeUint32(iterations, output, salt.length);
 		System.arraycopy(iv, 0, output, salt.length + 4, iv.length);
 		// Initialise the cipher and encrypt the plaintext
-		AuthenticatedCipher cipher = getAuthenticatedCipher();
 		try {
-			cipher.init(true, key, iv, null);
+			cipher.init(true, key, iv);
 			int outputOff = salt.length + 4 + iv.length;
 			cipher.process(input, 0, input.length, output, outputOff);
 			return output;
@@ -347,22 +342,23 @@ class CryptoComponentImpl implements CryptoComponent {
 	}
 
 	public byte[] decryptWithPassword(byte[] input, String password) {
+		AuthenticatedCipher cipher = getAuthenticatedCipher();
+		int macBytes = cipher.getMacBytes();
 		// The input contains the salt, iterations, IV, ciphertext and MAC
-		if(input.length < PBKDF_SALT_BYTES + 4 + STORAGE_IV_BYTES + MAC_BYTES)
+		if(input.length < PBKDF_SALT_BYTES + 4 + STORAGE_IV_BYTES + macBytes)
 			return null; // Invalid
 		byte[] salt = new byte[PBKDF_SALT_BYTES];
 		System.arraycopy(input, 0, salt, 0, salt.length);
 		long iterations = ByteUtils.readUint32(input, salt.length);
 		if(iterations < 0 || iterations > Integer.MAX_VALUE)
-			return null; // Invalid
+			return null; // Invalid iteration count
 		byte[] iv = new byte[STORAGE_IV_BYTES];
 		System.arraycopy(input, salt.length + 4, iv, 0, iv.length);
 		// Derive the key from the password
 		SecretKey key = new SecretKey(pbkdf2(password, salt, (int) iterations));
 		// Initialise the cipher
-		AuthenticatedCipher cipher = getAuthenticatedCipher();
 		try {
-			cipher.init(false, key, iv, null);
+			cipher.init(false, key, iv);
 		} catch(GeneralSecurityException e) {
 			throw new RuntimeException(e);
 		}
@@ -370,7 +366,7 @@ class CryptoComponentImpl implements CryptoComponent {
 		try {
 			int inputOff = salt.length + 4 + iv.length;
 			int inputLen = input.length - inputOff;
-			byte[] output = new byte[inputLen - MAC_BYTES];
+			byte[] output = new byte[inputLen - macBytes];
 			cipher.process(input, inputOff, inputLen, output, 0);
 			return output;
 		} catch(GeneralSecurityException e) {
diff --git a/briar-core/src/org/briarproject/crypto/StreamDecrypterImpl.java b/briar-core/src/org/briarproject/crypto/StreamDecrypterImpl.java
index b27b0cf9e44c33b0933f775696690b0aab1e58b6..e950fff2f6ed42978722f30e3e90841310d13175 100644
--- a/briar-core/src/org/briarproject/crypto/StreamDecrypterImpl.java
+++ b/briar-core/src/org/briarproject/crypto/StreamDecrypterImpl.java
@@ -21,7 +21,7 @@ class StreamDecrypterImpl implements StreamDecrypter {
 	private final InputStream in;
 	private final AuthenticatedCipher frameCipher;
 	private final SecretKey frameKey;
-	private final byte[] iv, aad, header, ciphertext;
+	private final byte[] iv, header, ciphertext;
 
 	private long frameNumber;
 	private boolean finalFrame;
@@ -32,7 +32,6 @@ class StreamDecrypterImpl implements StreamDecrypter {
 		this.frameCipher = frameCipher;
 		this.frameKey = frameKey;
 		iv = new byte[IV_LENGTH];
-		aad = new byte[IV_LENGTH];
 		header = new byte[HEADER_LENGTH];
 		ciphertext = new byte[MAX_FRAME_LENGTH];
 		frameNumber = 0;
@@ -52,9 +51,8 @@ class StreamDecrypterImpl implements StreamDecrypter {
 		}
 		// Decrypt and authenticate the header
 		FrameEncoder.encodeIv(iv, frameNumber, true);
-		FrameEncoder.encodeIv(aad, frameNumber, true);
 		try {
-			frameCipher.init(false, frameKey, iv, aad);
+			frameCipher.init(false, frameKey, iv);
 			int decrypted = frameCipher.process(ciphertext, 0, HEADER_LENGTH,
 					header, 0);
 			if(decrypted != HEADER_LENGTH - MAC_LENGTH)
@@ -78,9 +76,8 @@ class StreamDecrypterImpl implements StreamDecrypter {
 		}
 		// Decrypt and authenticate the payload and padding
 		FrameEncoder.encodeIv(iv, frameNumber, false);
-		FrameEncoder.encodeIv(aad, frameNumber, false);
 		try {
-			frameCipher.init(false, frameKey, iv, aad);
+			frameCipher.init(false, frameKey, iv);
 			int decrypted = frameCipher.process(ciphertext, HEADER_LENGTH,
 					payloadLength + paddingLength + MAC_LENGTH, payload, 0);
 			if(decrypted != payloadLength + paddingLength)
diff --git a/briar-core/src/org/briarproject/crypto/StreamEncrypterImpl.java b/briar-core/src/org/briarproject/crypto/StreamEncrypterImpl.java
index 475c62f59fe8cec9994f8115ca8369b9c2465cbf..ce06b09c410207bb38957647c979d73dee3cdbbd 100644
--- a/briar-core/src/org/briarproject/crypto/StreamEncrypterImpl.java
+++ b/briar-core/src/org/briarproject/crypto/StreamEncrypterImpl.java
@@ -20,7 +20,7 @@ class StreamEncrypterImpl implements StreamEncrypter {
 	private final OutputStream out;
 	private final AuthenticatedCipher frameCipher;
 	private final SecretKey frameKey;
-	private final byte[] tag, iv, aad, plaintext, ciphertext;
+	private final byte[] tag, iv, plaintext, ciphertext;
 
 	private long frameNumber;
 	private boolean writeTag;
@@ -32,7 +32,6 @@ class StreamEncrypterImpl implements StreamEncrypter {
 		this.frameKey = frameKey;
 		this.tag = tag;
 		iv = new byte[IV_LENGTH];
-		aad = new byte[IV_LENGTH];
 		plaintext = new byte[HEADER_LENGTH + MAX_PAYLOAD_LENGTH];
 		ciphertext = new byte[MAX_FRAME_LENGTH];
 		frameNumber = 0;
@@ -55,9 +54,8 @@ class StreamEncrypterImpl implements StreamEncrypter {
 				paddingLength);
 		// Encrypt and authenticate the header
 		FrameEncoder.encodeIv(iv, frameNumber, true);
-		FrameEncoder.encodeIv(aad, frameNumber, true);
 		try {
-			frameCipher.init(true, frameKey, iv, aad);
+			frameCipher.init(true, frameKey, iv);
 			int encrypted = frameCipher.process(plaintext, 0,
 					HEADER_LENGTH - MAC_LENGTH, ciphertext, 0);
 			if(encrypted != HEADER_LENGTH) throw new RuntimeException();
@@ -70,9 +68,8 @@ class StreamEncrypterImpl implements StreamEncrypter {
 			plaintext[HEADER_LENGTH + payloadLength + i] = 0;
 		// Encrypt and authenticate the payload and padding
 		FrameEncoder.encodeIv(iv, frameNumber, false);
-		FrameEncoder.encodeIv(aad, frameNumber, false);
 		try {
-			frameCipher.init(true, frameKey, iv, aad);
+			frameCipher.init(true, frameKey, iv);
 			int encrypted = frameCipher.process(plaintext, HEADER_LENGTH,
 					payloadLength + paddingLength, ciphertext, HEADER_LENGTH);
 			if(encrypted != payloadLength + paddingLength + MAC_LENGTH)
diff --git a/briar-tests/src/org/briarproject/crypto/TestAuthenticatedCipher.java b/briar-tests/src/org/briarproject/crypto/TestAuthenticatedCipher.java
index 0271975bd43f5b64368486dbfdb2c5f0d9f0f64e..018db0b6c24c95018fe907d3a854af4341c8944a 100644
--- a/briar-tests/src/org/briarproject/crypto/TestAuthenticatedCipher.java
+++ b/briar-tests/src/org/briarproject/crypto/TestAuthenticatedCipher.java
@@ -13,7 +13,7 @@ class TestAuthenticatedCipher implements AuthenticatedCipher {
 
 	private boolean encrypt = false;
 
-	public void init(boolean encrypt, SecretKey key, byte[] iv, byte[] aad)
+	public void init(boolean encrypt, SecretKey key, byte[] iv)
 			throws GeneralSecurityException {
 		this.encrypt = encrypt;
 	}
@@ -35,11 +35,11 @@ class TestAuthenticatedCipher implements AuthenticatedCipher {
 		}
 	}
 
-	public int getMacLength() {
+	public int getMacBytes() {
 		return MAC_LENGTH;
 	}
 
-	public int getBlockSize() {
+	public int getBlockBytes() {
 		return BLOCK_BYTES;
 	}
 }