fixed random access positioning

This commit is contained in:
Sebastian Stenzel
2016-02-20 14:10:46 +01:00
parent 3a82dfb23f
commit 7f313772e5
5 changed files with 127 additions and 25 deletions
@@ -14,6 +14,10 @@ public class AuthenticationFailedException extends CryptoException {
super();
}
public AuthenticationFailedException(String message) {
super(message);
}
public AuthenticationFailedException(Throwable cause) {
super(cause);
}
@@ -14,6 +14,10 @@ abstract class CryptoException extends RuntimeException {
super();
}
public CryptoException(String message) {
super(message);
}
public CryptoException(Throwable cause) {
super(cause);
}
@@ -23,6 +23,7 @@ public class FileContentCryptorImpl implements FileContentCryptor {
public static final int PAYLOAD_SIZE = 32 * 1024;
public static final int NONCE_SIZE = 16;
public static final int MAC_SIZE = 32;
public static final int CHUNK_SIZE = NONCE_SIZE + PAYLOAD_SIZE + MAC_SIZE;
private final SecretKey encryptionKey;
private final SecretKey macKey;
@@ -46,7 +47,7 @@ public class FileContentCryptorImpl implements FileContentCryptor {
assert cleartextChunkStart <= cleartextPos;
long chunkInternalDiff = cleartextPos - cleartextChunkStart;
assert chunkInternalDiff >= 0 && chunkInternalDiff < PAYLOAD_SIZE;
long ciphertextChunkStart = chunkNum * (NONCE_SIZE + PAYLOAD_SIZE + MAC_SIZE);
long ciphertextChunkStart = chunkNum * CHUNK_SIZE;
return ciphertextChunkStart + chunkInternalDiff;
}
@@ -55,7 +56,7 @@ public class FileContentCryptorImpl implements FileContentCryptor {
if (header.remaining() != getHeaderSize()) {
throw new IllegalArgumentException("Invalid header.");
}
if (firstCiphertextByte % (NONCE_SIZE + PAYLOAD_SIZE + MAC_SIZE) != 0) {
if (firstCiphertextByte % CHUNK_SIZE != 0) {
throw new IllegalArgumentException("Invalid starting point for decryption.");
}
return new FileContentDecryptorImpl(encryptionKey, macKey, header, firstCiphertextByte, authenticate);
@@ -8,8 +8,9 @@
*******************************************************************************/
package org.cryptomator.crypto.engine.impl;
import static org.cryptomator.crypto.engine.impl.FileContentCryptorImpl.CHUNK_SIZE;
import static org.cryptomator.crypto.engine.impl.FileContentCryptorImpl.MAC_SIZE;
import static org.cryptomator.crypto.engine.impl.FileContentCryptorImpl.PAYLOAD_SIZE;
import static org.cryptomator.crypto.engine.impl.FileContentCryptorImpl.NONCE_SIZE;
import java.io.IOException;
import java.io.UncheckedIOException;
@@ -35,7 +36,6 @@ import org.cryptomator.io.ByteBuffers;
class FileContentDecryptorImpl implements FileContentDecryptor {
private static final int NONCE_SIZE = 16;
private static final String HMAC_SHA256 = "HmacSHA256";
private static final int NUM_THREADS = Runtime.getRuntime().availableProcessors();
private static final int READ_AHEAD = 2;
@@ -45,7 +45,7 @@ class FileContentDecryptorImpl implements FileContentDecryptor {
private final ThreadLocal<Mac> hmacSha256;
private final FileHeader header;
private final boolean authenticate;
private ByteBuffer ciphertextBuffer = ByteBuffer.allocate(NONCE_SIZE + PAYLOAD_SIZE + MAC_SIZE);
private ByteBuffer ciphertextBuffer = ByteBuffer.allocate(CHUNK_SIZE);
private long chunkNumber = 0;
public FileContentDecryptorImpl(SecretKey headerKey, SecretKey macKey, ByteBuffer header, long firstCiphertextByte, boolean authenticate) {
@@ -53,7 +53,7 @@ class FileContentDecryptorImpl implements FileContentDecryptor {
this.hmacSha256 = hmacSha256;
this.header = FileHeader.decrypt(headerKey, hmacSha256, header);
this.authenticate = authenticate;
this.chunkNumber = firstCiphertextByte / PAYLOAD_SIZE; // floor() by int-truncation
this.chunkNumber = firstCiphertextByte / CHUNK_SIZE; // floor() by int-truncation
}
@Override
@@ -84,7 +84,7 @@ class FileContentDecryptorImpl implements FileContentDecryptor {
private void submitCiphertextBufferIfFull() throws InterruptedException {
if (!ciphertextBuffer.hasRemaining()) {
submitCiphertextBuffer();
ciphertextBuffer = ByteBuffer.allocate(NONCE_SIZE + PAYLOAD_SIZE + MAC_SIZE);
ciphertextBuffer = ByteBuffer.allocate(CHUNK_SIZE);
}
}
@@ -155,7 +155,8 @@ class FileContentDecryptorImpl implements FileContentDecryptor {
mac.update(nonce);
mac.update(inBuf.asReadOnlyBuffer());
if (!MessageDigest.isEqual(expectedMac, mac.doFinal())) {
throw new AuthenticationFailedException();
chunkNumberBigEndian.rewind();
throw new AuthenticationFailedException("Auth error in chunk " + chunkNumberBigEndian.getLong());
}
}