#include <klay/filesystem.h>
#include "../file-footer.h"
+#include "../ext4-tool.h"
#include "dmcrypt-engine.h"
destroyCryptoBlkDev(DM_LABEL);
}
-
-#define CRYPT_INPLACE_BUFSIZE 4096
-#define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / 512)
-
-void DMCryptEngine::encryptInPlace(const std::string &dst_blkdev,
- const std::string &src_blkdev,
- const long src_blkdev_size)
+void DMCryptEngine::encryptInPlace(const std::string &src_blkdev,
+ const std::string &dst_blkdev,
+ const bool isFastEncEnabled)
{
- // TODO(seok85.hong): support fast-encryption
-
- char buff[CRYPT_INPLACE_BUFSIZE];
+ Ext4Tool ext4tool(src_blkdev);
- off64_t numblocks = src_blkdev_size / CRYPT_SECTORS_PER_BUFSIZE;
- off64_t remainder = src_blkdev_size % CRYPT_SECTORS_PER_BUFSIZE;
- off64_t total = numblocks + remainder;
+ const unsigned int SRC_BLOCK_SIZE = ext4tool.getBlockSize();
+ const unsigned int SRC_TOTAL_BLOCK_COUNT = ext4tool.getTotalBlockCount();
+ char buff[SRC_BLOCK_SIZE] = {0, };
runtime::File dst(dst_blkdev, O_WRONLY);
runtime::File src(src_blkdev, O_RDONLY);
- for (off64_t n = 0; n < total; n++) {
- src.read(buff, CRYPT_INPLACE_BUFSIZE);
- dst.write(buff, CRYPT_INPLACE_BUFSIZE);
- progressBar.update(n, total, 1);
+ for (unsigned int n = 0; n < SRC_TOTAL_BLOCK_COUNT; n++) {
+ if (isFastEncEnabled && ext4tool.isUsedBlock(n) == false)
+ continue;
+
+ src.lseek(n * SRC_BLOCK_SIZE, SEEK_SET);
+ dst.lseek(n * SRC_BLOCK_SIZE, SEEK_SET);
+
+ src.read(buff, SRC_BLOCK_SIZE);
+ dst.write(buff, SRC_BLOCK_SIZE);
+
+ progressBar.update(n, SRC_TOTAL_BLOCK_COUNT, 1);
}
progressBar.done();
}
// should be encrypted here.
const std::string crypto_blkdev = createCryptoBlkDev(source, DM_LABEL, sanitized_key, cryptInfo.getFileSystemSize(), cryptInfo.getCryptoTypeName());
+ bool isFastEncEnabled = true;
+ if (options == OPTION_INCLUDE_UNUSED_REGION)
+ isFastEncEnabled = false;
+
+ INFO("FastEncryption: " + std::string(isFastEncEnabled ? "Enabled" : "Disabled"));
+
// We always do In-place encryption
- encryptInPlace(crypto_blkdev, source, cryptInfo.getFileSystemSize());
+ encryptInPlace(source, crypto_blkdev, isFastEncEnabled);
// remove crypto type device mapper
destroyCryptoBlkDev(DM_LABEL);
// should be encrypted here.
const std::string crypto_blkdev = createCryptoBlkDev(source, DM_LABEL, sanitized_key, cryptInfo.getFileSystemSize(), cryptInfo.getCryptoTypeName());
+ bool isFastEncEnabled = true;
+ if (options == OPTION_INCLUDE_UNUSED_REGION)
+ isFastEncEnabled = false;
+
+ INFO("FastEncryption: " + std::string(isFastEncEnabled ? "Enabled" : "Disabled"));
+
// We always do In-place encryption
- encryptInPlace(source, crypto_blkdev, cryptInfo.getFileSystemSize());
+ encryptInPlace(crypto_blkdev, source, isFastEncEnabled);
// remove crypto type device mapper
destroyCryptoBlkDev(DM_LABEL);
unsigned int getSupportedOptions();
private:
- void encryptInPlace(const std::string &dst_blkdev,
- const std::string &src_blkdev,
- const long src_blkdev_size);
+ void encryptInPlace(const std::string &src_blkdev,
+ const std::string &dst_blkdev,
+ const bool isFastEncEnabled);
private:
std::string source, destination;
../server/engine/ecryptfs-engine.cpp
../server/key-manager/key-generator.cpp
../server/key-manager/anti-forensics.cpp
+ ../server/ext4-tool.cpp
../server/progress-bar.cpp
../server/progress-vconf-backend.cpp
)
if (system(cmd.c_str())) {}
// make filesystem(ext4) and write test file
- cmd = "/usr/sbin/mkfs.ext4 -j ";
+ cmd = "/usr/sbin/mkfs.ext4 -j -b 4096 ";
+ // cmd = "/usr/sbin/mkfs.ext4 -j -b 2048 ";
+ // cmd = "/usr/sbin/mkfs.ext4 -j -b 1024 "; // has problem now
cmd += test_real_blkdev; // "/dev/loop0"
if (system(cmd.c_str())) {}
}
}
-// TODO(seok85.hong): is numblocks + remainder less than fast-encryption enabled count?
-
-// When we try to dcrypt using wrong key, our encrypted partition will be broken.
-// so, we should do this test at last test case
-TESTCASE(DMCryptEncryptButDecryptWithWrongKey)
+TESTCASE(DMCryptFastEncryptMountUnmountFastDecrypt)
{
try {
// ode::cryptInfo.init(test_real_blkdev, "aes-cbc-essiv:sha256");
const std::string keystring = "01020304050607080910111213141516";
const ode::DMCryptEngine::data key32bit(keystring.begin(), keystring.end());
- const std::string wrongkeystring = "SIZE_IS_SAME_BUT_WRONG_DECKEY___";
- const ode::DMCryptEngine::data wrongkey32bit(wrongkeystring.begin(), wrongkeystring.end());
ode::DMCryptEngine engine(test_real_blkdev, test_real_mntpoint, progressBar);
- engine.encrypt(key32bit, OPTION_INCLUDE_UNUSED_REGION);
-
- // check the encryption result of test_real_blkdev(/dev/loop0)
- // at this time, if we mount /dev/loop0 forcely, we can't mount them...
+ engine.encrypt(key32bit, (~OPTION_INCLUDE_UNUSED_REGION)); // disable fast-encryption
+ engine.mount(key32bit, 0);
{
- int ret = ::mount(test_real_blkdev.c_str(), test_real_mntpoint.c_str(), "ext4", 0, 0);
- if ((ret != -1) || (runtime::Error::lastErrorCode() != EINVAL)) {
- // we expected ret value is EINVAL (mount failure in man page of mount)
- std::cout << "expected: EINVAL" << "\n";
- std::cout << "real : " << runtime::GetSystemErrorMessage() << "\n";
- TEST_FAIL("Unexpected result from cryptsetup status");
- }
- }
- // decrypt with WRONG KEY
- engine.decrypt(wrongkey32bit, OPTION_INCLUDE_UNUSED_REGION);
+ // we should find test file (file name: ABC, body: DEF) in mount-point
+ std::string cmd = "cat " + test_real_mntpoint + "/ABC";
+ FILE *fp = popen(cmd.c_str(), "r");
+ if (!fp)
+ TEST_FAIL("Can't get test file body");
- // check the decryption result of test_Real_Blkdev(/dev/loop0)
- // at this time, if we mount /dev/loop0 forcely, we can't mount them...
- {
- int ret = ::mount(test_real_blkdev.c_str(), test_real_mntpoint.c_str(), "ext4", 0, 0);
- if ((ret != -1) || (runtime::Error::lastErrorCode() != EINVAL)) {
- // we expected ret value is EINVAL (mount failure in man page of mount)
- std::cout << "expected: EINVAL" << "\n";
- std::cout << "real : " << runtime::GetSystemErrorMessage() << "\n";
- TEST_FAIL("Unexpected result from cryptsetup status");
+ std::vector<std::string> answer = {
+ "DEF",
+ };
+
+ char buff[128] = {0, };
+ for (auto &a : answer) {
+ if (fgets(buff, 128, fp) == nullptr) {
+ pclose(fp);
+ TEST_FAIL("Can't read test file body from buffer");
+ }
+
+ std::string ret = buff;
+ ret.erase(std::remove(ret.begin(), ret.end(), '\n'), ret.end());
+
+ if (ret.compare(a)) {
+ pclose(fp);
+ std::cout << "expected: " << a << "\n";
+ std::cout << "real : " << ret << "\n";
+ TEST_FAIL("Unexpected result from test file body");
+ }
}
+ pclose(fp);
}
+ engine.umount();
+ engine.decrypt(key32bit, (~OPTION_INCLUDE_UNUSED_REGION)); // disable fast-encryption
+ //
} catch (runtime::Exception &e) {
TEST_FAIL(e.what());
}