Skip to content
Snippets Groups Projects
Commit 6965f809 authored by akwizgran's avatar akwizgran
Browse files

Don't create tag ciphers and tag keys unnecessarily.

parent 1762eaf3
No related branches found
No related tags found
No related merge requests found
......@@ -26,15 +26,26 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
public ConnectionReader createConnectionReader(InputStream in,
byte[] secret, boolean initiator) {
// Derive the keys and erase the secret
ErasableKey tagKey = crypto.deriveTagKey(secret, initiator);
ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator);
ByteUtils.erase(secret);
// Create the reader
Cipher tagCipher = crypto.getTagCipher();
AuthenticatedCipher frameCipher = crypto.getFrameCipher();
FrameReader encryption = new IncomingEncryptionLayer(in, tagCipher,
frameCipher, tagKey, frameKey, !initiator, MAX_FRAME_LENGTH);
return new ConnectionReaderImpl(encryption, MAX_FRAME_LENGTH);
if(initiator) {
// Derive the frame key and erase the secret
ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator);
ByteUtils.erase(secret);
// Create a reader for the responder's side of the connection
AuthenticatedCipher frameCipher = crypto.getFrameCipher();
FrameReader encryption = new IncomingEncryptionLayer(in,
frameCipher, frameKey, MAX_FRAME_LENGTH);
return new ConnectionReaderImpl(encryption, MAX_FRAME_LENGTH);
} else {
// Derive the tag and frame keys and erase the secret
ErasableKey tagKey = crypto.deriveTagKey(secret, initiator);
ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator);
ByteUtils.erase(secret);
// Create a reader for the initiator's side of the connection
Cipher tagCipher = crypto.getTagCipher();
AuthenticatedCipher frameCipher = crypto.getFrameCipher();
FrameReader encryption = new IncomingEncryptionLayer(in, tagCipher,
frameCipher, tagKey, frameKey, MAX_FRAME_LENGTH);
return new ConnectionReaderImpl(encryption, MAX_FRAME_LENGTH);
}
}
}
......@@ -26,16 +26,26 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
public ConnectionWriter createConnectionWriter(OutputStream out,
long capacity, byte[] secret, boolean initiator) {
// Derive the keys and erase the secret
ErasableKey tagKey = crypto.deriveTagKey(secret, initiator);
ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator);
ByteUtils.erase(secret);
// Create the writer
Cipher tagCipher = crypto.getTagCipher();
AuthenticatedCipher frameCipher = crypto.getFrameCipher();
FrameWriter encryption = new OutgoingEncryptionLayer(out, capacity,
tagCipher, frameCipher, tagKey, frameKey, initiator,
MAX_FRAME_LENGTH);
return new ConnectionWriterImpl(encryption, MAX_FRAME_LENGTH);
if(initiator) {
// Derive the tag and frame keys and erase the secret
ErasableKey tagKey = crypto.deriveTagKey(secret, initiator);
ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator);
ByteUtils.erase(secret);
// Create a writer for the initiator's side of the connection
Cipher tagCipher = crypto.getTagCipher();
AuthenticatedCipher frameCipher = crypto.getFrameCipher();
FrameWriter encryption = new OutgoingEncryptionLayer(out, capacity,
tagCipher, frameCipher, tagKey, frameKey, MAX_FRAME_LENGTH);
return new ConnectionWriterImpl(encryption, MAX_FRAME_LENGTH);
} else {
// Derive the frame key and erase the secret
ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator);
ByteUtils.erase(secret);
// Create a writer for the responder's side of the connection
AuthenticatedCipher frameCipher = crypto.getFrameCipher();
FrameWriter encryption = new OutgoingEncryptionLayer(out, capacity,
frameCipher, frameKey, MAX_FRAME_LENGTH);
return new ConnectionWriterImpl(encryption, MAX_FRAME_LENGTH);
}
}
}
}
\ No newline at end of file
......@@ -25,26 +25,44 @@ class IncomingEncryptionLayer implements FrameReader {
private final AuthenticatedCipher frameCipher;
private final ErasableKey tagKey, frameKey;
private final byte[] iv, aad, ciphertext;
private final int maxFrameLength;
private final int frameLength;
private boolean readTag, lastFrame;
private long frameNumber;
private boolean readTag, lastFrame;
/** Constructor for the initiator's side of a connection. */
IncomingEncryptionLayer(InputStream in, Cipher tagCipher,
AuthenticatedCipher frameCipher, ErasableKey tagKey,
ErasableKey frameKey, boolean readTag, int maxFrameLength) {
ErasableKey frameKey, int frameLength) {
this.in = in;
this.tagCipher = tagCipher;
this.frameCipher = frameCipher;
this.tagKey = tagKey;
this.frameKey = frameKey;
this.readTag = readTag;
this.maxFrameLength = maxFrameLength;
this.frameLength = frameLength;
iv = new byte[IV_LENGTH];
aad = new byte[AAD_LENGTH];
ciphertext = new byte[frameLength];
frameNumber = 0L;
readTag = true;
lastFrame = false;
}
/** Constructor for the responder's side of a connection. */
IncomingEncryptionLayer(InputStream in, AuthenticatedCipher frameCipher,
ErasableKey frameKey, int frameLength) {
this.in = in;
this.frameCipher = frameCipher;
this.frameKey = frameKey;
this.frameLength = frameLength;
tagCipher = null;
tagKey = null;
iv = new byte[IV_LENGTH];
aad = new byte[AAD_LENGTH];
ciphertext = new byte[maxFrameLength];
ciphertext = new byte[frameLength];
frameNumber = 0L;
readTag = false;
lastFrame = false;
}
public int readFrame(byte[] frame) throws IOException {
......@@ -70,9 +88,9 @@ class IncomingEncryptionLayer implements FrameReader {
// Read the frame
int ciphertextLength = 0;
try {
while(ciphertextLength < maxFrameLength) {
while(ciphertextLength < frameLength) {
int read = in.read(ciphertext, ciphertextLength,
maxFrameLength - ciphertextLength);
frameLength - ciphertextLength);
if(read == -1) break; // We'll check the length later
ciphertextLength += read;
}
......@@ -96,7 +114,7 @@ class IncomingEncryptionLayer implements FrameReader {
}
// Decode and validate the header
lastFrame = FrameEncoder.isLastFrame(frame);
if(!lastFrame && ciphertextLength < maxFrameLength)
if(!lastFrame && ciphertextLength < frameLength)
throw new EOFException();
int payloadLength = FrameEncoder.getPayloadLength(frame);
if(payloadLength > plaintextLength - HEADER_LENGTH)
......
......@@ -23,35 +23,54 @@ class OutgoingEncryptionLayer implements FrameWriter {
private final AuthenticatedCipher frameCipher;
private final ErasableKey tagKey, frameKey;
private final byte[] iv, aad, ciphertext;
private final int maxFrameLength;
private final int frameLength;
private boolean writeTag;
private long capacity, frameNumber;
private boolean writeTag;
/** Constructor for the initiator's side of a connection. */
OutgoingEncryptionLayer(OutputStream out, long capacity, Cipher tagCipher,
AuthenticatedCipher frameCipher, ErasableKey tagKey,
ErasableKey frameKey, boolean writeTag, int maxFrameLength) {
ErasableKey frameKey, int frameLength) {
this.out = out;
this.capacity = writeTag ? capacity - TAG_LENGTH : capacity;
this.capacity = capacity - TAG_LENGTH;
this.tagCipher = tagCipher;
this.frameCipher = frameCipher;
this.tagKey = tagKey;
this.frameKey = frameKey;
this.writeTag = writeTag;
this.maxFrameLength = maxFrameLength;
this.frameLength = frameLength;
iv = new byte[IV_LENGTH];
aad = new byte[AAD_LENGTH];
ciphertext = new byte[frameLength];
frameNumber = 0L;
writeTag = true;
}
/** Constructor for the responder's side of a connection. */
OutgoingEncryptionLayer(OutputStream out, long capacity,
AuthenticatedCipher frameCipher, ErasableKey frameKey,
int frameLength) {
this.out = out;
this.capacity = capacity;
this.frameCipher = frameCipher;
this.frameKey = frameKey;
this.frameLength = frameLength;
tagCipher = null;
tagKey = null;
iv = new byte[IV_LENGTH];
aad = new byte[AAD_LENGTH];
ciphertext = new byte[maxFrameLength];
ciphertext = new byte[frameLength];
frameNumber = 0L;
writeTag = false;
}
public void writeFrame(byte[] frame, int payloadLength, int paddingLength,
boolean lastFrame) throws IOException {
int plaintextLength = HEADER_LENGTH + payloadLength + paddingLength;
int ciphertextLength = plaintextLength + MAC_LENGTH;
if(ciphertextLength > maxFrameLength)
if(ciphertextLength > frameLength)
throw new IllegalArgumentException();
if(!lastFrame && ciphertextLength < maxFrameLength)
if(!lastFrame && ciphertextLength < frameLength)
throw new IllegalArgumentException();
// If the initiator's side of the connection is closed without writing
// any payload or padding, don't write a tag or an empty frame
......
......@@ -75,7 +75,7 @@ public class FrameReadWriteTest extends BriarTestCase {
ByteArrayOutputStream out = new ByteArrayOutputStream();
FrameWriter encryptionOut = new OutgoingEncryptionLayer(out,
Long.MAX_VALUE, tagCipher, frameCipher, tagCopy, frameCopy,
true, FRAME_LENGTH);
FRAME_LENGTH);
ConnectionWriter writer = new ConnectionWriterImpl(encryptionOut,
FRAME_LENGTH);
OutputStream out1 = writer.getOutputStream();
......@@ -88,7 +88,7 @@ public class FrameReadWriteTest extends BriarTestCase {
// Read the tag and the frames back
ByteArrayInputStream in = new ByteArrayInputStream(output);
FrameReader encryptionIn = new IncomingEncryptionLayer(in, tagCipher,
frameCipher, tagKey, frameKey, true, FRAME_LENGTH);
frameCipher, tagKey, frameKey, FRAME_LENGTH);
ConnectionReader reader = new ConnectionReaderImpl(encryptionIn,
FRAME_LENGTH);
InputStream in1 = reader.getInputStream();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment