init/fscrypt_init_extensions: support setting v2 encryption policies
Support setting v2 encryption policies on init-created directories. The policy version to set is gotten from a new field in /data/unencrypted/mode, which is the file that's used to pass the encryption options from vold to init. Also don't bother falling back to defaults if fields are missing from this file, since it's re-written on every boot by vold. Bug: 140500999 Test: tested as series; see If64028d8580584b2c33c614cabd5d6b93657f608 Change-Id: Ia9c5d4b80199686799e3ac80de78a50ed3bdabf4
This commit is contained in:
parent
d964376a92
commit
eaadc9d426
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/parseint.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
#include <cutils/properties.h>
|
||||
|
@ -163,33 +164,59 @@ int fscrypt_set_directory_policy(const std::string& dir) {
|
|||
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) {
|
||||
std::string ref_filename = std::string("/data") + ref_basename;
|
||||
std::string policy;
|
||||
if (!android::base::ReadFileToString(ref_filename, &policy)) {
|
||||
std::string key_ref;
|
||||
if (!android::base::ReadFileToString(ref_filename, &key_ref)) {
|
||||
LOG(ERROR) << "Unable to read system policy to set on " << dir;
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto type_filename = std::string("/data") + fscrypt_key_mode;
|
||||
std::string modestring;
|
||||
if (!android::base::ReadFileToString(type_filename, &modestring)) {
|
||||
LOG(ERROR) << "Cannot read mode";
|
||||
auto options_filename = std::string("/data") + fscrypt_key_mode;
|
||||
std::string options_string;
|
||||
if (!android::base::ReadFileToString(options_filename, &options_string)) {
|
||||
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) {
|
||||
LOG(ERROR) << "Invalid encryption mode string: " << modestring;
|
||||
if (parse_encryption_options_string(options_string, &contents_mode, &filenames_mode,
|
||||
&policy_version)) {
|
||||
LOG(ERROR) << "Invalid encryption options string: " << options_string;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result =
|
||||
fscrypt_policy_ensure(dir.c_str(), policy.c_str(), policy.length(), modes[0].c_str(),
|
||||
modes.size() >= 2 ? modes[1].c_str() : "aes-256-cts");
|
||||
fscrypt_policy_ensure(dir.c_str(), key_ref.c_str(), key_ref.length(),
|
||||
contents_mode.c_str(), filenames_mode.c_str(), policy_version);
|
||||
if (result) {
|
||||
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());
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue