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

Commit 57467074 authored by David Anderson's avatar David Anderson Committed by Gerrit Code Review
Browse files

Merge "libdm: Add dm-crypt and dm-default-key support to libdm."

parents b4631fc7 e17405fd
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

#include "libdm/dm_target.h"

#include <stdio.h>
#include <sys/types.h>

#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/parseint.h>
@@ -193,5 +196,30 @@ bool DmTargetSnapshot::ParseStatusText(const std::string& text, Status* status)
    return true;
}

std::string DmTargetCrypt::GetParameterString() const {
    std::vector<std::string> argv = {
            cipher_,
            key_,
            std::to_string(iv_sector_offset_),
            device_,
            std::to_string(device_sector_),
    };

    std::vector<std::string> extra_argv;
    if (allow_discards_) extra_argv.emplace_back("allow_discards");
    if (allow_encrypt_override_) extra_argv.emplace_back("allow_encrypt_override");
    if (iv_large_sectors_) extra_argv.emplace_back("iv_large_sectors");
    if (sector_size_) extra_argv.emplace_back("sector_size:" + std::to_string(sector_size_));

    if (!extra_argv.empty()) argv.emplace_back(std::to_string(extra_argv.size()));

    argv.insert(argv.end(), extra_argv.begin(), extra_argv.end());
    return android::base::Join(argv, " ");
}

std::string DmTargetDefaultKey::GetParameterString() const {
    return cipher_ + " " + key_ + " " + blockdev_ + " " + std::to_string(start_sector_);
}

}  // namespace dm
}  // namespace android
+23 −0
Original line number Diff line number Diff line
@@ -438,3 +438,26 @@ TEST(libdm, DmSnapshotOverflow) {
        ASSERT_EQ(status.error, "Invalid");
    }
}

TEST(libdm, CryptArgs) {
    DmTargetCrypt target1(0, 512, "sha1", "abcdefgh", 50, "/dev/loop0", 100);
    ASSERT_EQ(target1.name(), "crypt");
    ASSERT_TRUE(target1.Valid());
    ASSERT_EQ(target1.GetParameterString(), "sha1 abcdefgh 50 /dev/loop0 100");

    DmTargetCrypt target2(0, 512, "sha1", "abcdefgh", 50, "/dev/loop0", 100);
    target2.SetSectorSize(64);
    target2.AllowDiscards();
    target2.SetIvLargeSectors();
    target2.AllowEncryptOverride();
    ASSERT_EQ(target2.GetParameterString(),
              "sha1 abcdefgh 50 /dev/loop0 100 4 allow_discards allow_encrypt_override "
              "iv_large_sectors sector_size:64");
}

TEST(libdm, DefaultKeyArgs) {
    DmTargetDefaultKey target(0, 4096, "AES-256-XTS", "abcdef0123456789", "/dev/loop0", 0);
    ASSERT_EQ(target.name(), "default-key");
    ASSERT_TRUE(target.Valid());
    ASSERT_EQ(target.GetParameterString(), "AES-256-XTS abcdef0123456789 /dev/loop0 0");
}
+9 −1
Original line number Diff line number Diff line
@@ -43,12 +43,20 @@ class DmTable {
    // successfully removed.
    bool RemoveTarget(std::unique_ptr<DmTarget>&& target);

    // Adds a target, constructing it in-place for convenience. For example,
    //
    //   table.Emplace<DmTargetZero>(0, num_sectors);
    template <typename T, typename... Args>
    bool Emplace(Args&&... args) {
        return AddTarget(std::make_unique<T>(std::forward<Args>(args)...));
    }

    // Checks the table to make sure it is valid. i.e. Checks for range overlaps, range gaps
    // and returns 'true' if the table is ready to be loaded into kernel. Returns 'false' if the
    // table is malformed.
    bool valid() const;

    // Returns the toatl number of targets.
    // Returns the total number of targets.
    size_t num_targets() const { return targets_.size(); }

    // Returns the total size represented by the table in terms of number of 512-byte sectors.
+54 −0
Original line number Diff line number Diff line
@@ -241,6 +241,60 @@ class DmTargetSnapshotOrigin final : public DmTarget {
    std::string device_;
};

class DmTargetCrypt final : public DmTarget {
  public:
    DmTargetCrypt(uint64_t start, uint64_t length, const std::string& cipher,
                  const std::string& key, uint64_t iv_sector_offset, const std::string& device,
                  uint64_t device_sector)
        : DmTarget(start, length),
          cipher_(cipher),
          key_(key),
          iv_sector_offset_(iv_sector_offset),
          device_(device),
          device_sector_(device_sector) {}

    void AllowDiscards() { allow_discards_ = true; }
    void AllowEncryptOverride() { allow_encrypt_override_ = true; }
    void SetIvLargeSectors() { iv_large_sectors_ = true; }
    void SetSectorSize(uint32_t sector_size) { sector_size_ = sector_size; }

    std::string name() const override { return "crypt"; }
    bool Valid() const override { return true; }
    std::string GetParameterString() const override;

  private:
    std::string cipher_;
    std::string key_;
    uint64_t iv_sector_offset_;
    std::string device_;
    uint64_t device_sector_;
    bool allow_discards_ = false;
    bool allow_encrypt_override_ = false;
    bool iv_large_sectors_ = false;
    uint32_t sector_size_ = 0;
};

class DmTargetDefaultKey final : public DmTarget {
  public:
    DmTargetDefaultKey(uint64_t start, uint64_t length, const std::string& cipher,
                       const std::string& key, const std::string& blockdev, uint64_t start_sector)
        : DmTarget(start, length),
          cipher_(cipher),
          key_(key),
          blockdev_(blockdev),
          start_sector_(start_sector) {}

    std::string name() const override { return "default-key"; }
    bool Valid() const override { return true; }
    std::string GetParameterString() const override;

  private:
    std::string cipher_;
    std::string key_;
    std::string blockdev_;
    uint64_t start_sector_;
};

}  // namespace dm
}  // namespace android