diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterImpl.java
index cb708eb4cf54ab2a913248fa891fc49776afbe1f..59afd8531f6f3cdc011b2da46d5d6994dbb0bcd2 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/StreamEncrypterImpl.java
@@ -62,6 +62,8 @@ class StreamEncrypterImpl implements StreamEncrypter {
 	@Override
 	public void writeFrame(byte[] payload, int payloadLength,
 			int paddingLength, boolean finalFrame) throws IOException {
+		if (payloadLength < 0 || paddingLength < 0)
+			throw new IllegalArgumentException();
 		if (payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
 			throw new IllegalArgumentException();
 		// Don't allow the frame counter to wrap
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/crypto/StreamEncrypterImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/crypto/StreamEncrypterImplTest.java
index 8ed35336d4523771f65848eb82fa3f5b7fb317b1..c13749f684170dcc55593cb616fc23f5e9331938 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/crypto/StreamEncrypterImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/crypto/StreamEncrypterImplTest.java
@@ -9,9 +9,13 @@ import java.io.ByteArrayOutputStream;
 
 import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
 import static org.briarproject.bramble.api.transport.TransportConstants.MAC_LENGTH;
+import static org.briarproject.bramble.api.transport.TransportConstants.MAX_FRAME_LENGTH;
+import static org.briarproject.bramble.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH;
 import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_IV_LENGTH;
+import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_LENGTH;
 import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
 import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
 
 public class StreamEncrypterImplTest extends BrambleTestCase {
 
@@ -30,6 +34,58 @@ public class StreamEncrypterImplTest extends BrambleTestCase {
 		payload = TestUtils.getRandomBytes(payloadLength);
 	}
 
+	@Test(expected = IllegalArgumentException.class)
+	public void testRejectsNegativePayloadLength() throws Exception {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
+
+		s.writeFrame(payload, -1, 0, false);
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testRejectsNegativePaddingLength() throws Exception {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
+
+		s.writeFrame(payload, 0, -1, false);
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testRejectsMaxPayloadPlusPadding() throws Exception {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
+
+		byte[] bigPayload = new byte[MAX_PAYLOAD_LENGTH + 1];
+		s.writeFrame(bigPayload, MAX_PAYLOAD_LENGTH, 1, false);
+	}
+
+	@Test
+	public void testAcceptsMaxPayloadIncludingPadding() throws Exception {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
+
+		byte[] bigPayload = new byte[MAX_PAYLOAD_LENGTH];
+		s.writeFrame(bigPayload, MAX_PAYLOAD_LENGTH - 1, 1, false);
+		assertEquals(TAG_LENGTH + STREAM_HEADER_LENGTH + MAX_FRAME_LENGTH,
+				out.size());
+	}
+
+	@Test
+	public void testAcceptsMaxPayloadWithoutPadding() throws Exception {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
+
+		byte[] bigPayload = new byte[MAX_PAYLOAD_LENGTH];
+		s.writeFrame(bigPayload, MAX_PAYLOAD_LENGTH, 0, false);
+		assertEquals(TAG_LENGTH + STREAM_HEADER_LENGTH + MAX_FRAME_LENGTH,
+				out.size());
+	}
+
 	@Test
 	public void testWriteUnpaddedNonFinalFrameWithTag() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();