diff --git a/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java b/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java index 84b773262..c9c7dcb81 100644 --- a/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java +++ b/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java @@ -423,6 +423,7 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration { final InputStream in = new SeekableByteChannelInputStream(encryptedFile); byte[] buffer = new byte[CONTENT_MAC_BLOCK + 32]; int n = 0; + long blockNum = 0; while ((n = IOUtils.read(in, buffer)) > 0) { if (n < 32) { throw new DecryptFailedException("Invalid file content, missing MAC."); @@ -430,6 +431,8 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration { // check MAC of current block: if (authenticate) { + contentMac.update(iv); + contentMac.update(longToByteArray(blockNum)); contentMac.update(buffer, 0, n - 32); final byte[] calculatedMac = contentMac.doFinal(); final byte[] storedMac = new byte[32]; @@ -444,6 +447,7 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration { final int plaintextLengthWithoutPadding = (int) Math.min(plaintext.length, fileSize - bytesDecrypted); // plaintext.length is known to be a 32 bit int plaintextFile.write(plaintext, 0, plaintextLengthWithoutPadding); bytesDecrypted += plaintextLengthWithoutPadding; + blockNum++; } destroyQuietly(fileKey); @@ -521,6 +525,7 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration { final InputStream in = new SeekableByteChannelInputStream(encryptedFile); byte[] buffer = new byte[CONTENT_MAC_BLOCK + 32]; int n = 0; + long blockNum = startBlock; while ((n = IOUtils.read(in, buffer)) > 0 && bytesWritten < length) { if (n < 32) { throw new DecryptFailedException("Invalid file content, missing MAC."); @@ -528,6 +533,8 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration { // check MAC of current block: if (authenticate) { + contentMac.update(iv); + contentMac.update(longToByteArray(blockNum)); contentMac.update(buffer, 0, n - 32); final byte[] calculatedMac = contentMac.doFinal(); final byte[] storedMac = new byte[32]; @@ -546,6 +553,7 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration { plaintextFile.write(plaintext, offset, currentBatch); bytesWritten += currentBatch; + blockNum++; } return bytesWritten; } finally { @@ -593,12 +601,16 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration { // writing ciphered output and MACs interleaved: final byte[] buffer = new byte[CONTENT_MAC_BLOCK]; int n = 0; + long blockNum = 0; while ((n = IOUtils.read(in, buffer)) > 0) { final byte[] ciphertext = cipher.update(buffer, 0, n); out.write(ciphertext); + contentMac.update(iv); + contentMac.update(longToByteArray(blockNum)); contentMac.update(ciphertext); final byte[] mac = contentMac.doFinal(); out.write(mac); + blockNum++; } destroyQuietly(fileKey); @@ -623,4 +635,8 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration { return plaintextSize; } + private byte[] longToByteArray(long lng) { + return ByteBuffer.allocate(Long.SIZE).putLong(lng).array(); + } + }