diff --git a/briar-core/src/net/sf/briar/crypto/CryptoComponentImpl.java b/briar-core/src/net/sf/briar/crypto/CryptoComponentImpl.java
index 4063ddf3ef93113831d6e63c5f7540850252a776..35558c540fcc88007a01e6155043686ad9e6d641 100644
--- a/briar-core/src/net/sf/briar/crypto/CryptoComponentImpl.java
+++ b/briar-core/src/net/sf/briar/crypto/CryptoComponentImpl.java
@@ -29,11 +29,13 @@ import net.sf.briar.util.ByteUtils;
 import org.spongycastle.crypto.AsymmetricCipherKeyPair;
 import org.spongycastle.crypto.BlockCipher;
 import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.Mac;
 import org.spongycastle.crypto.agreement.ECDHCBasicAgreement;
 import org.spongycastle.crypto.digests.SHA384Digest;
 import org.spongycastle.crypto.engines.AESFastEngine;
 import org.spongycastle.crypto.generators.ECKeyPairGenerator;
 import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
+import org.spongycastle.crypto.macs.CMac;
 import org.spongycastle.crypto.modes.AEADBlockCipher;
 import org.spongycastle.crypto.modes.GCMBlockCipher;
 import org.spongycastle.crypto.params.ECKeyGenerationParameters;
@@ -44,7 +46,6 @@ import org.spongycastle.util.Strings;
 
 class CryptoComponentImpl implements CryptoComponent {
 
-	private static final int CIPHER_BLOCK_BYTES = 16; // 128 bits
 	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;
@@ -392,25 +393,31 @@ class CryptoComponentImpl implements CryptoComponent {
 		return output;
 	}
 
-	// Key derivation function based on a block cipher in CTR mode - see
+	// Key derivation function based on a PRF in counter mode - see
 	// NIST SP 800-108, section 5.1
 	private byte[] counterModeKdf(byte[] secret, byte[] label, long context) {
 		if(secret.length != CIPHER_KEY_BYTES)
 			throw new IllegalArgumentException();
 		if(Arrays.equals(secret, BLANK_SECRET))
 			throw new IllegalArgumentException();
-		// The label and context must leave a byte free for the counter
-		if(label.length + 4 >= CIPHER_BLOCK_BYTES)
+		if(label[label.length - 1] != '\0')
 			throw new IllegalArgumentException();
-		byte[] counter = new byte[CIPHER_BLOCK_BYTES];
-		System.arraycopy(label, 0, counter, 0, label.length);
-		ByteUtils.writeUint32(context, counter, label.length);
-		BlockCipher cipher = new AESFastEngine();
-		cipher.init(true, new KeyParameter(secret));
-		byte[] output = new byte[CIPHER_KEY_BYTES];
-		for(int i = 0; i * CIPHER_BLOCK_BYTES < output.length; i++) {
-			counter[counter.length - 1] = (byte) i;
-			cipher.processBlock(counter, 0, output, i * CIPHER_BLOCK_BYTES);
+		Mac prf = new CMac(new AESFastEngine());
+		prf.init(new KeyParameter(secret));
+		int macLength = prf.getMacSize();
+		byte[] mac = new byte[macLength], output = new byte[CIPHER_KEY_BYTES];
+		byte[] contextBytes = new byte[4];
+		ByteUtils.writeUint32(context, contextBytes, 0);
+		for(int i = 0; i * macLength < CIPHER_KEY_BYTES; i++) {
+			prf.update((byte) i); // Counter
+			prf.update(label, 0, label.length);
+			prf.update(contextBytes, 0, contextBytes.length);
+			prf.update((byte) CIPHER_KEY_BYTES); // Output length
+			prf.doFinal(mac, 0);
+			int bytesNeeded = CIPHER_KEY_BYTES - i * macLength;
+			int bytesToUse = Math.min(bytesNeeded, macLength);
+			System.arraycopy(mac, 0, output, i * macLength, bytesToUse);
+			ByteUtils.erase(mac);
 		}
 		return output;
 	}