/* * (non-Javadoc) * * @see java.io.FileInputStream#skip(long) */ @Override public long skip(long n) throws IOException { long bytesSkipped = 0; int toSkip; int bytesRead; byte[] skipBuf = new byte[config.getBlockSize()]; if (n < 0) { throw new IOException("Negative skip count"); } while (bytesSkipped < n) { toSkip = (int) Math.min(n - bytesSkipped, config.getBlockSize()); bytesRead = this.read(skipBuf, 0, toSkip); bytesSkipped += bytesRead; if (bytesRead == -1) { return -1; // Already at EOF } else if (bytesRead < toSkip) { return bytesSkipped; // Hit EOF now } } return bytesSkipped; }
/** * Create a new EncFSInputStream for reading decrypted data off a file on an EncFS volume * * @param volume Volume hosting the file to read * @param in Input stream to access the raw (encrypted) file contents * @param volumePath Volume path of the file being decrypted (needed for externalIVChaining) * @throws EncFSCorruptDataException File data is corrupt * @throws EncFSUnsupportedException Unsupported EncFS configuration * @throws IOException File provider returned I/O error */ public EncFSInputStream(EncFSVolume volume, InputStream in, String volumePath) throws EncFSCorruptDataException, EncFSUnsupportedException { super(in); this.volume = volume; this.config = volume.getConfig(); this.blockSize = config.getBlockSize(); this.numMACBytes = config.getBlockMACBytes(); this.numRandBytes = config.getBlockMACRandBytes(); this.blockHeaderSize = this.numMACBytes + this.numRandBytes; this.blockBuf = null; this.bufCursor = 0; this.blockNum = 0; if (config.isUniqueIV()) { // Compute file IV byte[] fileHeader = new byte[EncFSFile.HEADER_SIZE]; try { in.read(fileHeader); } catch (IOException e) { throw new EncFSCorruptDataException("Could't read file IV"); } byte[] initIv; if (config.isExternalIVChaining()) { /* * When using external IV chaining we compute initIv based on * the file path. */ initIv = EncFSCrypto.computeChainIv(volume, volumePath); } else { // When not using external IV chaining initIv is just zero's. initIv = new byte[8]; } try { this.fileIv = EncFSCrypto.streamDecode(volume, initIv, fileHeader); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { throw new EncFSCorruptDataException(e); } catch (BadPaddingException e) { throw new EncFSCorruptDataException(e); } } else { // No unique IV per file, just use 0 this.fileIv = new byte[EncFSFile.HEADER_SIZE]; } }