/** * @param uncompressedBytesWithHeader * @param blockType * @param headerBytes * @throws IOException */ protected void compressAfterEncoding( byte[] uncompressedBytesWithHeader, BlockType blockType, byte[] headerBytes) throws IOException { this.uncompressedBytesWithHeader = uncompressedBytesWithHeader; Encryption.Context cryptoContext = fileContext.getEncryptionContext(); if (cryptoContext != Encryption.Context.NONE) { // Encrypted block format: // +--------------------------+ // | byte iv length | // +--------------------------+ // | iv data ... | // +--------------------------+ // | encrypted block data ... | // +--------------------------+ cryptoByteStream.reset(); // Write the block header (plaintext) cryptoByteStream.write(headerBytes); InputStream in; int plaintextLength; // Run any compression before encryption if (fileContext.getCompression() != Compression.Algorithm.NONE) { compressedByteStream.reset(); compressionStream.resetState(); compressionStream.write( uncompressedBytesWithHeader, headerBytes.length, uncompressedBytesWithHeader.length - headerBytes.length); compressionStream.flush(); compressionStream.finish(); byte[] plaintext = compressedByteStream.toByteArray(); plaintextLength = plaintext.length; in = new ByteArrayInputStream(plaintext); } else { plaintextLength = uncompressedBytesWithHeader.length - headerBytes.length; in = new ByteArrayInputStream( uncompressedBytesWithHeader, headerBytes.length, plaintextLength); } if (plaintextLength > 0) { // Set up the cipher Cipher cipher = cryptoContext.getCipher(); Encryptor encryptor = cipher.getEncryptor(); encryptor.setKey(cryptoContext.getKey()); // Set up the IV int ivLength = iv.length; Preconditions.checkState(ivLength <= Byte.MAX_VALUE, "IV length out of range"); cryptoByteStream.write(ivLength); if (ivLength > 0) { encryptor.setIv(iv); cryptoByteStream.write(iv); } // Encrypt the data Encryption.encrypt(cryptoByteStream, in, encryptor); onDiskBytesWithHeader = cryptoByteStream.toByteArray(); // Increment the IV given the final block size Encryption.incrementIv(iv, 1 + (onDiskBytesWithHeader.length / encryptor.getBlockSize())); } else { cryptoByteStream.write(0); onDiskBytesWithHeader = cryptoByteStream.toByteArray(); } } else { if (this.fileContext.getCompression() != NONE) { compressedByteStream.reset(); compressedByteStream.write(headerBytes); compressionStream.resetState(); compressionStream.write( uncompressedBytesWithHeader, headerBytes.length, uncompressedBytesWithHeader.length - headerBytes.length); compressionStream.flush(); compressionStream.finish(); onDiskBytesWithHeader = compressedByteStream.toByteArray(); } else { onDiskBytesWithHeader = uncompressedBytesWithHeader; } } this.blockType = blockType; }
protected void incrementIv(int v) { Encryption.incrementIv(iv.get(), 1 + (v / encryptor.getBlockSize())); }