Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9fd008e9 authored by Eric Biggers's avatar Eric Biggers Committed by android-build-merger
Browse files

Merge changes from topic "fscrypt-key-mgmt-improvements"

am: 736557c5

Change-Id: I94242353fb404e2979cf6e90e778d3d00f0a2653
parents 8df5dd0a 736557c5
Loading
Loading
Loading
Loading
+19 −5
Original line number Original line Diff line number Diff line
@@ -112,13 +112,16 @@ const std::array<const char*, 3> kFileNamesEncryptionMode = {
};
};


void ParseFileEncryption(const std::string& arg, FstabEntry* entry) {
void ParseFileEncryption(const std::string& arg, FstabEntry* entry) {
    // The fileencryption flag is followed by an = and the mode of contents encryption, then
    // The fileencryption flag is followed by an = and 1 to 3 colon-separated fields:
    // optionally a and the mode of filenames encryption (defaults to aes-256-cts).  Get it and
    //
    // return it.
    // 1. Contents encryption mode
    // 2. Filenames encryption mode (defaults to "aes-256-cts" or "adiantum"
    //    depending on the contents encryption mode)
    // 3. Encryption policy version (defaults to "v1". Use "v2" on new devices.)
    entry->fs_mgr_flags.file_encryption = true;
    entry->fs_mgr_flags.file_encryption = true;


    auto parts = Split(arg, ":");
    auto parts = Split(arg, ":");
    if (parts.empty() || parts.size() > 2) {
    if (parts.empty() || parts.size() > 3) {
        LWARNING << "Warning: fileencryption= flag malformed: " << arg;
        LWARNING << "Warning: fileencryption= flag malformed: " << arg;
        return;
        return;
    }
    }
@@ -137,7 +140,7 @@ void ParseFileEncryption(const std::string& arg, FstabEntry* entry) {


    entry->file_contents_mode = parts[0];
    entry->file_contents_mode = parts[0];


    if (parts.size() == 2) {
    if (parts.size() >= 2) {
        if (std::find(kFileNamesEncryptionMode.begin(), kFileNamesEncryptionMode.end(), parts[1]) ==
        if (std::find(kFileNamesEncryptionMode.begin(), kFileNamesEncryptionMode.end(), parts[1]) ==
            kFileNamesEncryptionMode.end()) {
            kFileNamesEncryptionMode.end()) {
            LWARNING << "fileencryption= flag malformed, file names encryption mode not found: "
            LWARNING << "fileencryption= flag malformed, file names encryption mode not found: "
@@ -151,6 +154,16 @@ void ParseFileEncryption(const std::string& arg, FstabEntry* entry) {
    } else {
    } else {
        entry->file_names_mode = "aes-256-cts";
        entry->file_names_mode = "aes-256-cts";
    }
    }

    if (parts.size() >= 3) {
        if (!android::base::StartsWith(parts[2], 'v') ||
            !android::base::ParseInt(&parts[2][1], &entry->file_policy_version)) {
            LWARNING << "fileencryption= flag malformed, unknown options: " << arg;
            return;
        }
    } else {
        entry->file_policy_version = 1;
    }
}
}


bool SetMountFlag(const std::string& flag, FstabEntry* entry) {
bool SetMountFlag(const std::string& flag, FstabEntry* entry) {
@@ -288,6 +301,7 @@ void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) {
            entry->key_loc = arg;
            entry->key_loc = arg;
            entry->file_contents_mode = "aes-256-xts";
            entry->file_contents_mode = "aes-256-xts";
            entry->file_names_mode = "aes-256-cts";
            entry->file_names_mode = "aes-256-cts";
            entry->file_policy_version = 1;
        } else if (StartsWith(flag, "max_comp_streams=")) {
        } else if (StartsWith(flag, "max_comp_streams=")) {
            if (!ParseInt(arg, &entry->max_comp_streams)) {
            if (!ParseInt(arg, &entry->max_comp_streams)) {
                LWARNING << "Warning: max_comp_streams= flag malformed: " << arg;
                LWARNING << "Warning: max_comp_streams= flag malformed: " << arg;
+1 −0
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ struct FstabEntry {
    off64_t reserved_size = 0;
    off64_t reserved_size = 0;
    std::string file_contents_mode;
    std::string file_contents_mode;
    std::string file_names_mode;
    std::string file_names_mode;
    int file_policy_version = 0;
    off64_t erase_blk_size = 0;
    off64_t erase_blk_size = 0;
    off64_t logical_blk_size = 0;
    off64_t logical_blk_size = 0;
    std::string sysfs_path;
    std::string sysfs_path;
+47 −2
Original line number Original line Diff line number Diff line
@@ -467,6 +467,7 @@ source none2 swap defaults forcefdeorfbe=
    }
    }
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ(1, entry->file_policy_version);
    EXPECT_EQ("", entry->key_loc);
    EXPECT_EQ("", entry->key_loc);
}
}


@@ -682,6 +683,7 @@ source none0 swap defaults forcefdeorfbe=/dir/key
    EXPECT_EQ("/dir/key", entry->key_loc);
    EXPECT_EQ("/dir/key", entry->key_loc);
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ(1, entry->file_policy_version);
}
}


TEST(fs_mgr, ReadFstabFromFile_FsMgrOptions_FileEncryption) {
TEST(fs_mgr, ReadFstabFromFile_FsMgrOptions_FileEncryption) {
@@ -698,14 +700,18 @@ source none6 swap defaults fileencryption=ice:blah
source none7       swap   defaults      fileencryption=ice:aes-256-cts
source none7       swap   defaults      fileencryption=ice:aes-256-cts
source none8       swap   defaults      fileencryption=ice:aes-256-heh
source none8       swap   defaults      fileencryption=ice:aes-256-heh
source none9       swap   defaults      fileencryption=ice:adiantum
source none9       swap   defaults      fileencryption=ice:adiantum
source none10      swap   defaults      fileencryption=ice:adiantum:
source none10      swap   defaults      fileencryption=aes-256-xts:aes-256-cts:v1
source none11      swap   defaults      fileencryption=aes-256-xts:aes-256-cts:v2
source none12      swap   defaults      fileencryption=aes-256-xts:aes-256-cts:v2:
source none13      swap   defaults      fileencryption=aes-256-xts:aes-256-cts:blah
source none14      swap   defaults      fileencryption=aes-256-xts:aes-256-cts:vblah
)fs";
)fs";


    ASSERT_TRUE(android::base::WriteStringToFile(fstab_contents, tf.path));
    ASSERT_TRUE(android::base::WriteStringToFile(fstab_contents, tf.path));


    Fstab fstab;
    Fstab fstab;
    EXPECT_TRUE(ReadFstabFromFile(tf.path, &fstab));
    EXPECT_TRUE(ReadFstabFromFile(tf.path, &fstab));
    ASSERT_EQ(11U, fstab.size());
    ASSERT_EQ(15U, fstab.size());


    FstabEntry::FsMgrFlags flags = {};
    FstabEntry::FsMgrFlags flags = {};
    flags.file_encryption = true;
    flags.file_encryption = true;
@@ -715,66 +721,105 @@ source none10 swap defaults fileencryption=ice:adiantum:
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("", entry->file_contents_mode);
    EXPECT_EQ("", entry->file_contents_mode);
    EXPECT_EQ("", entry->file_names_mode);
    EXPECT_EQ("", entry->file_names_mode);
    EXPECT_EQ(0, entry->file_policy_version);


    entry++;
    entry++;
    EXPECT_EQ("none1", entry->mount_point);
    EXPECT_EQ("none1", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ(1, entry->file_policy_version);


    entry++;
    entry++;
    EXPECT_EQ("none2", entry->mount_point);
    EXPECT_EQ("none2", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ(1, entry->file_policy_version);


    entry++;
    entry++;
    EXPECT_EQ("none3", entry->mount_point);
    EXPECT_EQ("none3", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("adiantum", entry->file_contents_mode);
    EXPECT_EQ("adiantum", entry->file_contents_mode);
    EXPECT_EQ("adiantum", entry->file_names_mode);
    EXPECT_EQ("adiantum", entry->file_names_mode);
    EXPECT_EQ(1, entry->file_policy_version);


    entry++;
    entry++;
    EXPECT_EQ("none4", entry->mount_point);
    EXPECT_EQ("none4", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("adiantum", entry->file_contents_mode);
    EXPECT_EQ("adiantum", entry->file_contents_mode);
    EXPECT_EQ("aes-256-heh", entry->file_names_mode);
    EXPECT_EQ("aes-256-heh", entry->file_names_mode);
    EXPECT_EQ(1, entry->file_policy_version);


    entry++;
    entry++;
    EXPECT_EQ("none5", entry->mount_point);
    EXPECT_EQ("none5", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("ice", entry->file_contents_mode);
    EXPECT_EQ("ice", entry->file_contents_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ(1, entry->file_policy_version);


    entry++;
    entry++;
    EXPECT_EQ("none6", entry->mount_point);
    EXPECT_EQ("none6", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("ice", entry->file_contents_mode);
    EXPECT_EQ("ice", entry->file_contents_mode);
    EXPECT_EQ("", entry->file_names_mode);
    EXPECT_EQ("", entry->file_names_mode);
    EXPECT_EQ(0, entry->file_policy_version);


    entry++;
    entry++;
    EXPECT_EQ("none7", entry->mount_point);
    EXPECT_EQ("none7", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("ice", entry->file_contents_mode);
    EXPECT_EQ("ice", entry->file_contents_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ(1, entry->file_policy_version);


    entry++;
    entry++;
    EXPECT_EQ("none8", entry->mount_point);
    EXPECT_EQ("none8", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("ice", entry->file_contents_mode);
    EXPECT_EQ("ice", entry->file_contents_mode);
    EXPECT_EQ("aes-256-heh", entry->file_names_mode);
    EXPECT_EQ("aes-256-heh", entry->file_names_mode);
    EXPECT_EQ(1, entry->file_policy_version);


    entry++;
    entry++;
    EXPECT_EQ("none9", entry->mount_point);
    EXPECT_EQ("none9", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("ice", entry->file_contents_mode);
    EXPECT_EQ("ice", entry->file_contents_mode);
    EXPECT_EQ("adiantum", entry->file_names_mode);
    EXPECT_EQ("adiantum", entry->file_names_mode);
    EXPECT_EQ(1, entry->file_policy_version);


    entry++;
    entry++;
    EXPECT_EQ("none10", entry->mount_point);
    EXPECT_EQ("none10", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ(1, entry->file_policy_version);

    entry++;
    EXPECT_EQ("none11", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ(2, entry->file_policy_version);

    entry++;
    EXPECT_EQ("none12", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("", entry->file_contents_mode);
    EXPECT_EQ("", entry->file_contents_mode);
    EXPECT_EQ("", entry->file_names_mode);
    EXPECT_EQ("", entry->file_names_mode);
    EXPECT_EQ(0, entry->file_policy_version);

    entry++;
    EXPECT_EQ("none13", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ(0, entry->file_policy_version);

    entry++;
    EXPECT_EQ("none14", entry->mount_point);
    EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags));
    EXPECT_EQ("aes-256-xts", entry->file_contents_mode);
    EXPECT_EQ("aes-256-cts", entry->file_names_mode);
    EXPECT_EQ(0, entry->file_policy_version);
}
}


TEST(fs_mgr, ReadFstabFromFile_FsMgrOptions_MaxCompStreams) {
TEST(fs_mgr, ReadFstabFromFile_FsMgrOptions_MaxCompStreams) {
+39 −12
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@


#include <android-base/file.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/strings.h>
#include <cutils/properties.h>
#include <cutils/properties.h>
@@ -163,33 +164,59 @@ int fscrypt_set_directory_policy(const std::string& dir) {
    return err;
    return err;
}
}


static int parse_encryption_options_string(const std::string& options_string,
                                           std::string* contents_mode_ret,
                                           std::string* filenames_mode_ret,
                                           int* policy_version_ret) {
    auto parts = android::base::Split(options_string, ":");

    if (parts.size() != 3) {
        return -1;
    }

    *contents_mode_ret = parts[0];
    *filenames_mode_ret = parts[1];
    if (!android::base::StartsWith(parts[2], 'v') ||
        !android::base::ParseInt(&parts[2][1], policy_version_ret)) {
        return -1;
    }

    return 0;
}

// Set an encryption policy on the given directory.  The policy (key reference
// and encryption options) to use is read from files that were written by vold.
static int set_policy_on(const std::string& ref_basename, const std::string& dir) {
static int set_policy_on(const std::string& ref_basename, const std::string& dir) {
    std::string ref_filename = std::string("/data") + ref_basename;
    std::string ref_filename = std::string("/data") + ref_basename;
    std::string policy;
    std::string key_ref;
    if (!android::base::ReadFileToString(ref_filename, &policy)) {
    if (!android::base::ReadFileToString(ref_filename, &key_ref)) {
        LOG(ERROR) << "Unable to read system policy to set on " << dir;
        LOG(ERROR) << "Unable to read system policy to set on " << dir;
        return -1;
        return -1;
    }
    }


    auto type_filename = std::string("/data") + fscrypt_key_mode;
    auto options_filename = std::string("/data") + fscrypt_key_mode;
    std::string modestring;
    std::string options_string;
    if (!android::base::ReadFileToString(type_filename, &modestring)) {
    if (!android::base::ReadFileToString(options_filename, &options_string)) {
        LOG(ERROR) << "Cannot read mode";
        LOG(ERROR) << "Cannot read encryption options string";
        return -1;
    }
    }


    std::vector<std::string> modes = android::base::Split(modestring, ":");
    std::string contents_mode;
    std::string filenames_mode;
    int policy_version = 0;


    if (modes.size() < 1 || modes.size() > 2) {
    if (parse_encryption_options_string(options_string, &contents_mode, &filenames_mode,
        LOG(ERROR) << "Invalid encryption mode string: " << modestring;
                                        &policy_version)) {
        LOG(ERROR) << "Invalid encryption options string: " << options_string;
        return -1;
        return -1;
    }
    }


    int result =
    int result =
            fscrypt_policy_ensure(dir.c_str(), policy.c_str(), policy.length(), modes[0].c_str(),
            fscrypt_policy_ensure(dir.c_str(), key_ref.c_str(), key_ref.length(),
                                  modes.size() >= 2 ? modes[1].c_str() : "aes-256-cts");
                                  contents_mode.c_str(), filenames_mode.c_str(), policy_version);
    if (result) {
    if (result) {
        LOG(ERROR) << android::base::StringPrintf("Setting %02x%02x%02x%02x policy on %s failed!",
        LOG(ERROR) << android::base::StringPrintf("Setting %02x%02x%02x%02x policy on %s failed!",
                                                  policy[0], policy[1], policy[2], policy[3],
                                                  key_ref[0], key_ref[1], key_ref[2], key_ref[3],
                                                  dir.c_str());
                                                  dir.c_str());
        return -1;
        return -1;
    }
    }