init_cipher(EVP_CIPHER_fetch(NULL, opts.str, NULL), {} );
}
- padding = 4 << (ctx->flags & FSCRYPT_POLICY_FLAGS_PAD_MASK);
key_size = opts.key_size;
iv_size = opts.iv_size;
EVP_CIPHER_CTX_free(cipher_ctx);
}
+int FSCryptFNameDenc::get_encrypted_name_length(const int& plain_size) const
+{
+ int padding_size = ctx->get_filename_padding_bytes();
+ int padded_size = (plain_size + padding_size - 1) & ~ (padding_size - 1);
+ if (padded_size > NAME_MAX) {
+ padded_size = NAME_MAX;
+ }
+ return padded_size;
+}
+
int FSCryptFNameDenc::get_encrypted_fname(const std::string& plain, std::string *encrypted, std::string *alt_name)
{
auto plain_size = plain.size();
- int dec_size = (plain.size() + padding - 1) & ~(padding - 1); // FIXME, need to be based on policy
- if (dec_size > NAME_MAX) {
- dec_size = NAME_MAX;
- }
+ auto filename_padded_size = get_encrypted_name_length(plain_size);
- char orig[dec_size];
+ char orig[filename_padded_size];
memcpy(orig, plain.c_str(), plain_size);
- memset(orig + plain_size, 0, dec_size - plain_size);
+ memset(orig + plain_size, 0, filename_padded_size - plain_size);
char enc_name[NAME_MAX + 64]; /* some extra just in case */
- int r = encrypt(orig, dec_size,
+ int r = encrypt(orig, filename_padded_size,
enc_name, sizeof(enc_name));
if (r < 0) {
int FSCryptFNameDenc::get_encrypted_symlink(const std::string& plain, std::string *encrypted)
{
auto plain_size = plain.size();
- int dec_size = (plain.size() + 31) & ~31; // FIXME, need to be based on policy
+ auto symlink_padded_size = get_encrypted_name_length(plain_size);
- char orig[dec_size];
+ char orig[symlink_padded_size];
memcpy(orig, plain.c_str(), plain_size);
- memset(orig + plain_size, 0, dec_size - plain_size);
+ memset(orig + plain_size, 0, symlink_padded_size - plain_size);
fscrypt_slink_data slink_data;
- int r = encrypt(orig, dec_size,
+ int r = encrypt(orig, symlink_padded_size,
slink_data.enc, sizeof(slink_data.enc));
if (r < 0) {
memset(dest->__reserved, 0, sizeof(dest->__reserved));
memcpy(dest->master_key_identifier, master_key_identifier.raw, sizeof(master_key_identifier.raw));
}
+
+ uint8_t get_filename_padding_bytes() const {
+ uint8_t padding_bits = flags & FSCRYPT_POLICY_FLAGS_PAD_MASK;
+ uint8_t padding_bytes = 4 << padding_bits;
+ return padding_bytes;
+ }
};
using FSCryptPolicyRef = std::shared_ptr<FSCryptPolicy>;
std::vector<char> key;
FSCryptIV iv;
- int padding = 1;
int key_size = 0;
int iv_size = 0;
int get_encrypted_symlink(const std::string& plain, std::string *encrypted);
int get_decrypted_symlink(const std::string& b64enc, std::string *decrypted);
+private:
+ int get_encrypted_name_length(const int& plain_size) const;
};
using FSCryptFNameDencRef = std::shared_ptr<FSCryptFNameDenc>;
ceph_shutdown(cmount);
}
+// this test verifies that fuse client doesn't support falloate ops
+// FALLOC_FL_COLLAPSE_RANGE, FALLOC_FL_COLLAPSE_RANGE, FALLOC_FL_INSERT_RANGE
+// if this test fails, it means that these ops has been impleneted AND we must reject these ops for encrypted files
+// see https://www.kernel.org/doc/html/v4.18/filesystems/fscrypt.html Access Semantics section
+TEST(FSCrypt, FallocateNotImplemented) {
+ struct ceph_fscrypt_key_identifier kid;
+ struct ceph_mount_info *cmount;
+ int r = init_mount(&cmount);
+ ASSERT_EQ(0, r);
+
+ // init fscrypt on dir
+ string dir_path = "dir1";
+ ceph_mkdir(cmount, dir_path.c_str(), 0777);
+ int fd = ceph_open(cmount, dir_path.c_str(), O_DIRECTORY, 0);
+ r = ceph_add_fscrypt_key(cmount, fscrypt_key, sizeof(fscrypt_key), &kid, 1299);
+ struct fscrypt_policy_v2 policy;
+ policy.version = 2;
+ policy.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS;
+ policy.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS;
+ policy.flags = FSCRYPT_POLICY_FLAGS_PAD_32;
+ memcpy(policy.master_key_identifier, kid.raw, FSCRYPT_KEY_IDENTIFIER_SIZE);
+ r = ceph_set_fscrypt_policy_v2(cmount, fd, &policy);
+ ceph_close(cmount, fd);
+
+ //add file to fscrypt enabled directory and write some data to the file
+ string file_name = "file1";
+ string file_path = "";
+ file_path.append(dir_path);
+ file_path.append("/");
+ file_path.append(file_name);
+ fd = ceph_open(cmount, file_path.c_str(), O_RDWR|O_CREAT|O_TRUNC, 0600);
+ r = ceph_write(cmount, fd, fscrypt_key, sizeof(fscrypt_key), 0);
+ ASSERT_EQ(32, r);
+
+ // try to fallocate opened file with non supported flags
+ r = ceph_fallocate(cmount, fd, FALLOC_FL_COLLAPSE_RANGE, 0, 64);
+ ASSERT_EQ(-EOPNOTSUPP, r);
+ r = ceph_fallocate(cmount, fd, FALLOC_FL_ZERO_RANGE, 0, 64);
+ ASSERT_EQ(-EOPNOTSUPP, r);
+ r = ceph_fallocate(cmount, fd, FALLOC_FL_INSERT_RANGE, 0, 64);
+ ASSERT_EQ(-EOPNOTSUPP, r);
+
+ // cleanup
+ ceph_close(cmount, fd);
+ ceph_unlink(cmount, file_path.c_str());
+ ceph_rmdir(cmount, dir_path.c_str());
+
+ ceph_shutdown(cmount);
+}
+
int main(int argc, char **argv)
{
int r = update_root_mode();