/* * EncFS Java Library * Copyright (C) 2013 encfs-java authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. */ package org.mrpdaemon.sec.encfs; import java.util.Arrays; /** * Common class for filename encryption strategies. */ abstract class BasicFilenameEncryptionStrategy extends FilenameEncryptionStrategy { BasicFilenameEncryptionStrategy(EncFSVolume volume, String volumePath, EncFSFilenameEncryptionAlgorithm algorithm) { super(volume, volumePath, algorithm); } /** * Actual encryption to be implemented by the subclass. */ protected abstract byte[] encryptConcrete(EncFSVolume volume, byte[] paddedDecFileName, byte[] fileIv) throws EncFSCorruptDataException; /** * Filename encryption implementation. */ protected String encryptImpl(String fileName) throws EncFSCorruptDataException { EncFSVolume volume = getVolume(); String volumePath = getVolumePath(); EncFSConfig config = volume.getConfig(); byte[] decFileName = fileName.getBytes(); byte[] paddedDecFileName = getPaddedDecFilename(decFileName); byte[] chainIv = EncFSCrypto.computeChainedIV(volume, volumePath, config); byte[] mac16 = getMac16(volume, paddedDecFileName, chainIv); byte[] macBytes = EncFSCrypto.getMacBytes(mac16); byte[] fileIv = EncFSCrypto.computeFileIV(chainIv, macBytes); byte[] encFileName = encryptConcrete(volume, paddedDecFileName, fileIv); return getBase256Filename(mac16, encFileName); } /** * Filename padding implementation hook for subclasses. */ protected abstract byte[] getPaddedDecFilename(byte[] decFileName); /** * Returns the base 256 filename for the given encrypted filename. */ private String getBase256Filename(byte[] mac16, byte[] encFileName) { // current versions store the checksum at the beginning (encfs 0.x // stored checksums at the end) byte[] base256FileName = new byte[encFileName.length+2]; base256FileName[0] = mac16[0]; base256FileName[1] = mac16[1]; System.arraycopy(encFileName, 0, base256FileName, 2, encFileName.length); byte[] fileNameOutput = EncFSBase64.encodeEncfs(base256FileName); return new String(fileNameOutput); } /** * Returns the mac16 of the given file name. */ private byte[] getMac16(EncFSVolume volume, byte[] paddedDecFileName, byte[] chainIv) { if (volume.getConfig().isChainedNameIV()) { return EncFSCrypto.mac16(volume.getMAC(), paddedDecFileName, Arrays.copyOf(chainIv, chainIv.length)); } else { return EncFSCrypto.mac16(volume.getMAC(), paddedDecFileName); } } }