Label keys with all the possible FBE prefixes that might apply

We don't know which FS and kernel version is going to want these keys,
so put them in the kernel three times with all three possible prefixes.

Test: Marlin set up before this change successfully boots after it.
Change-Id: I6ccfe0894551ba068de9bf5e23fe4fd1e10e36b1
gugelfrei
Paul Crowley 7 years ago
parent ce02449264
commit cd8bfe3d7f

@ -73,9 +73,16 @@ static bool fillKey(const std::string& key, ext4_encryption_key* ext4_key) {
return true; return true;
} }
std::string keyname(const std::string& raw_ref) { static char const* const NAME_PREFIXES[] = {
"ext4",
"f2fs",
"fscrypt",
nullptr
};
static std::string keyname(const std::string& prefix, const std::string& raw_ref) {
std::ostringstream o; std::ostringstream o;
o << "ext4:"; o << prefix << ":";
for (auto i : raw_ref) { for (auto i : raw_ref) {
o << std::hex << std::setw(2) << std::setfill('0') << (int)i; o << std::hex << std::setw(2) << std::setfill('0') << (int)i;
} }
@ -98,37 +105,42 @@ bool installKey(const std::string& key, std::string* raw_ref) {
ext4_encryption_key ext4_key; ext4_encryption_key ext4_key;
if (!fillKey(key, &ext4_key)) return false; if (!fillKey(key, &ext4_key)) return false;
*raw_ref = generateKeyRef(ext4_key.raw, ext4_key.size); *raw_ref = generateKeyRef(ext4_key.raw, ext4_key.size);
auto ref = keyname(*raw_ref);
key_serial_t device_keyring; key_serial_t device_keyring;
if (!e4cryptKeyring(&device_keyring)) return false; if (!e4cryptKeyring(&device_keyring)) return false;
key_serial_t key_id = for (char const* const* name_prefix = NAME_PREFIXES; *name_prefix != nullptr; name_prefix++) {
add_key("logon", ref.c_str(), (void*)&ext4_key, sizeof(ext4_key), device_keyring); auto ref = keyname(*name_prefix, *raw_ref);
if (key_id == -1) { key_serial_t key_id =
PLOG(ERROR) << "Failed to insert key into keyring " << device_keyring; add_key("logon", ref.c_str(), (void*)&ext4_key, sizeof(ext4_key), device_keyring);
return false; if (key_id == -1) {
PLOG(ERROR) << "Failed to insert key into keyring " << device_keyring;
return false;
}
LOG(DEBUG) << "Added key " << key_id << " (" << ref << ") to keyring " << device_keyring
<< " in process " << getpid();
} }
LOG(DEBUG) << "Added key " << key_id << " (" << ref << ") to keyring " << device_keyring
<< " in process " << getpid();
return true; return true;
} }
bool evictKey(const std::string& raw_ref) { bool evictKey(const std::string& raw_ref) {
auto ref = keyname(raw_ref);
key_serial_t device_keyring; key_serial_t device_keyring;
if (!e4cryptKeyring(&device_keyring)) return false; if (!e4cryptKeyring(&device_keyring)) return false;
auto key_serial = keyctl_search(device_keyring, "logon", ref.c_str(), 0); bool success = true;
for (char const* const* name_prefix = NAME_PREFIXES; *name_prefix != nullptr; name_prefix++) {
// Unlink the key from the keyring. Prefer unlinking to revoking or auto ref = keyname(*name_prefix, raw_ref);
// invalidating, since unlinking is actually no less secure currently, and auto key_serial = keyctl_search(device_keyring, "logon", ref.c_str(), 0);
// it avoids bugs in certain kernel versions where the keyring key is
// referenced from places it shouldn't be. // Unlink the key from the keyring. Prefer unlinking to revoking or
if (keyctl_unlink(key_serial, device_keyring) != 0) { // invalidating, since unlinking is actually no less secure currently, and
PLOG(ERROR) << "Failed to unlink key with serial " << key_serial << " ref " << ref; // it avoids bugs in certain kernel versions where the keyring key is
return false; // referenced from places it shouldn't be.
if (keyctl_unlink(key_serial, device_keyring) != 0) {
PLOG(ERROR) << "Failed to unlink key with serial " << key_serial << " ref " << ref;
success = false;
} else {
LOG(DEBUG) << "Unlinked key with serial " << key_serial << " ref " << ref;
}
} }
LOG(DEBUG) << "Unlinked key with serial " << key_serial << " ref " << ref; return success;
return true;
} }
bool retrieveAndInstallKey(bool create_if_absent, const std::string& key_path, bool retrieveAndInstallKey(bool create_if_absent, const std::string& key_path,

@ -36,7 +36,6 @@ struct ext4_encryption_key {
uint32_t size; uint32_t size;
}; };
std::string keyname(const std::string& raw_ref);
bool randomKey(std::string* key); bool randomKey(std::string* key);
bool installKey(const std::string& key, std::string* raw_ref); bool installKey(const std::string& key, std::string* raw_ref);
bool evictKey(const std::string& raw_ref); bool evictKey(const std::string& raw_ref);

Loading…
Cancel
Save